[stack] Parameters: ordered versus named
Manfred Von Thun <[email protected]>
| Newsgroups | gmane.comp.lang.concatenative |
|---|---|
| Message-ID | <C30743C1.B6C%[email protected]> |
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]