Programming Language for Old Timers


by David A. Moon
February 2006 .. September 2008

Comments and criticisms to dave underscore moon atsign alum dot mit dot edu.


Previous page   Table of Contents   Next page


Method Heads

A method head is used in the def and defprotocol definition statements and in the require statement to identify a method. It consists of a name and a parameter list, generally with types declared for some or all of the parameters. The syntactic type method-head is defined in the compiler module for this purpose. It parses into a method-head object which has slots name and parameter-list.

A method head can be written either in the form of a function call or in the form of a prefix or infix operator or macro call. An optional assignment right-hand-side parameter can be appended. Thus a method head can resemble any of the ways that a function invocation can be written. Result parameters can also be appended to the operator and macro call forms.

There are five syntactic forms of method-head accepted. They are displayed here as PLOT patterns without conversion to LL(1) form, for ease of readability. The syntactic types infix-macro, infix-operator, macro-call, prefix-operator, and variable used here are defined in the Expression Syntax section.

  ?:variable ( ?:parameter-list )
  [ ~^ := ?assignment is typed-variable ]

  ?:prefix-operator ?argument is paren-typed-variable
  [ ~^ := ?assignment is typed-variable  ]
  [ ~^ , result: { ?result is typed-variable & ~^ , }+ ]

  ?lhs is paren-typed-variable ?:infix-operator ?rhs is paren-typed-variable
  [ ~^ := ?assignment is typed-variable  ]
  [ ~^ , result: { ?result is typed-variable & ~^ , }+ ]

  ?:macro-call
  [ ~^ := ?assignment is typed-variable ]
  [ ~^ , result: { ?result is typed-variable & ~^ , }+ ]

  ?lhs is paren-typed-variable ?:infix-macro ...
  [ ~^ := ?assignment is typed-variable ]
  [ ~^ , result: { ?result is typed-variable & ~^ , }+ ]

The above syntax uses the following syntactic type, which is NOT exported from the PLOT module.

defparser paren-typed-variable
  ?:typed-variable | ( ?:typed-variable ) => typed-variable

This allows a parameter of an operator to be enclosed in parentheses in a method head. This can improve readability and also addresses a syntactic ambiguity in the def statement when defining a method for the = operator.

The first form is the usual form, in which the name and parameter-list are specified in function-call syntax. The name must be denatured with \ if it is the name of an operator or macro. If an assignment is specified it is appended to the parameter list as an additional required parameter (no optional, key, or rest parameters are allowed, but see special rule below) and the name becomes the function name concatenated with :=.

The remaining forms allow methods for operators to be identified using the operator syntax by which they would be called, instead of standard function call syntax.

In the prefix-operator form, the prefix-operator is the name and the parameter list has one required parameter which is the given argument. If an assignment is specified it is appended to the parameter list as a second required parameter and the name becomes the prefix-operator concatenated with :=. If results are specified they are appended to the parameter list.

In the infix-operator form, the infix-operator is the name and the parameter list has two required parameters which are the lhs and rhs typed-variables. If an assignment is specified it is appended to the parameter list as a third required parameter and the name becomes the infix-operator concatenated with :=. If results are specified they are appended to the parameter list.

In the macro-call form, the expansion of the macro must be an invocation whose function is a name. That name is the name of the method head. The arguments of the invocation are converted to a parameter list as follows: An argument expression that is a name becomes a parameter by that name. An argument expression that is a quotation of a name becomes a keyword with that name; it must be one of the keywords optional:, key:, or rest:. An argument expression that is an invocation of the is operator must have a name as its first argument; it becomes a parameter by that name with the type-specifier that corresponds to the second argument. An argument expression that is an invocation of the = operator must have a name or an invocation of is as its first argument; the second argument is the default value for the parameter specified by the first argument. In this way, a macro or infix-operator-macro can parse any syntax that involves expressions as if it was being called, but the expansion of the macro can be translated back to a parameter list. If an assignment is specified it is appended to the parameter list as an additional required parameter (no optional, key, or rest parameters are allowed, but see special rule below) and the name becomes the function name in the invocation concatenated with :=. If results are specified they are appended to the parameter list.

The infix-macro form is similar to the macro-call form. The lhs argument to the macro expander is the lhs variable, enclosed in an invocation of the is operator if there is a type-specifier.

There is a special rule for the case where an assignment is specified, the assignment's type is unspecified or is anything, and the parameter-list contains a rest parameter. In this case, the assignment variable is discarded and the parameter-list is not allowed to contain optional or key parameters. The method is assumed to use the last element of the value of the rest parameter as a new value to be assigned, and to use the remaining elements of the value of the rest parameter as part of the specification of where to make the assignment. This is the only case where an assignment can be specified and the parameter list can contain other than required parameters.


Previous page   Table of Contents   Next page