Re: [stack] Parameters: ordered versus named

Stevan Apter <[email protected]>
Newsgroups gmane.comp.lang.concatenative
Message-ID <[email protected]>
off the top of my head, i can imagine a construct like this
(i'm assuming iverson notation, in which the combinator is
what he would call a conjunction):

O is a combinator that takes a subset of a permutation
of the names of the arguments of f (on the left) and a
lambda containing those arguments (on the right), and
returns a function which binds those arguments to values.

    f:{[a;b;c]a+b*c}

    f . 10 20 30
  610

    (`c`b`a O f) . 10 20 30
  230

then, for example,

    (`c`a O f) . 10 20

returns a function of one argument b in which c is bound to
10 and a to 20.

my first reaction is that i shouldn't know anything about f
except the mapping of arguments to result, least of all what
names the programmer chose for the arguments.  my second
reaction is that every function should be documented, and
that it might be thought that well-chosen argument names
should be exposed to the user of the function.

what about primitives, like -?  i suppose the language could
just say that every primitive of one argument names its
argument x, of two x and y, &c.  then

    2(`y`x O -)3
  1

it's not hard to write O in k.

----- Original Message ----- 
From: "Manfred Von Thun" <[email protected]>
To: <[email protected]>
Sent: Friday, September 07, 2007 3:06 AM
Subject: [stack] Parameters: ordered versus named


For a long time I have been interested in the difference
between the standard kind of lambda calculus languages
and the concatenative languages. Only recently did it
occur to me that there is a third class which has been around
for some time. The three differ in how they treat actual
and formal parameters in definitions of functions and in
calls of functions. At one extreme are the concatenative
languages, at the other extreme those in the third class.
The standard lambda calculus languages are half way
between these two extremes.

Most programming languages belong in the class of
lambda calculus languages. Definitions look more or
less like this:

DEFINE foo(x,y,z)        # head of definition
   = ...x...y...z...          # body of definition


So there is a list of formal parameters (x,y,z) in the
head, and an expression ...x...y...z... which is the body.
In the body each of the formal parameters occurs one
or more times, or even not at all. The various occurrences
can be in any order. (This is one of the strengths of
lambda calculus notation.) Once you have written the
entire definition, you can change your mind about the
parameter list: you can change it to (y,z,x) and there
is no need to change the body in any way. In a call
to the function, foo(a,b,c), with actual parameters (a,b,c)
the values of the actual parameters are given to the
corresponding formal parameters. Of course the effect
of the call depends on whether the original definition with
(x,y,z) or the revised definition with (y,z,x)  is in force.
The order of the actual parameters is taken to match
the order of the formal parameters. To summarise:
In the body the formal parameters are used as names,
irrespective of their order in the parameter list;
in a call the order of the actuals and the formals are
the same, irrespective of the names of the formals.

In concatenative languages there are no formal parameter
lists. Definitions look like this:

DEFINE foo                        # head of definition
  =  ...dup...swap... pop...   # body of definition

Instead of  being able to refer to the actual parameters
by the name of the corresponding formal parameter,
it is now necessary to take the actual parameters as
they are on the stack, and do some shuffling to get
everything right in the body. Once you have written the
entire definition, you cannot just change the parameter
list because there isn¹t one. You also have to change the body of
the definition. In a call the order of the actual parameters
on the stack has to be in the order in which the body
of the definition expects them. To summarise:
In the body of the definition there is an expected order
of the  actual parameters on the stack; in a call
the actual parameters have to be in the in the order
in which the body expects them.

So at the one extreme we can have the concatenative
method: there are no names, body and call
are done by order (on the stack). In the middle we have the
standard lambda calculus notation: there are names
which are used in the body, but calls use positions
that match the order of the formals in the parameter
list. At the other extreme there should be languages
which do not use  order at all but rely on names both
in the body and in calls. Are there such beasts?

In such languages definitions would again look as in
lambda calculus languages:

DEFINE foo(x,y,z)        # head of definition
   = ...x...y...z...          # body of definition

As before, you can change the order of the parameters
without any need to change the body of the definition.
But a call would look quite different: instead of relying
on the order of the formal parameters, use their names
as assignment statements, and make the assignments
in any order. Hence any of the following would be OK
as a call:

foo(x=a; y=b; z=c)
foo(y=b; z=c; x=a)
foo(z=c; y=b; x=a)

and so forth, a total of six possible combinations. All such
calls would be equivalent. To summarise: body and call
are done by using the names of the formal parameters.
My understanding is that there are some languages which
allow this kind of notation (Common Lisp ?, Ada ?) but
I cannot remember any details --- anyone?? But as far
as I know these languages use standard positional notation
by default and allow this other notation only as a
convenient variation. I have never heard of a language
in which this way of calling is standard. Anyone??

BEGIN COMMENT:
These languages can allow default parameters, and
definitions would look like this:

DEFINE foo(x=1,y=0,z=5)        # head of definition
   = ...x...y...z...          # body of definition

Calls can then omit giving a value to a particular formal
parameter, in which case the default is used. Example:

foo(x=42,z=3)   is  equivalent to foo(z=3,x=42,y=0)

In Unix just about all of the utilities have many parameters
which default to sensible values. Consequently casual
users rarely need to know about them, but they
are there to be modified if one needs it.
END COMMENT

So, we seem to have three possiblities:
(1) bodies and calls rely on position
(2) bodies rely on names, calls rely on position
(3) bodies and calls rely on names

Nice to know that concatenative languages are pure,
isn¹t it. I thought this grouping of classes of languages
might be of interest to other language smiths.

  - Manfred



[Non-text portions of this message have been removed]
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.