chsasank / llama.lisp

Lisp dialect designed for HPC and AI
GNU Lesser General Public License v2.1
15 stars 6 forks source link

Prelisp: support for keyword parameters #107

Open GlowingScrewdriver opened 1 week ago

GlowingScrewdriver commented 1 week ago

Consider the following Python function:

# In macro module
def include (headers, functions = [], structs = []):
    pass # Body

By design, either functions or structs can be unspecified (i.e. None). At present, the only way to specify structs in a macro call while leaving functions empty is the following:

; In source program
,(include (header-name) () (struct-name1 struct-name2))

This could be made much more elegant with the use of keyword arguments. Consider the following procedure definition, mimicking the macro, in Guile Scheme:

(define* (include headers #:key functions structs)
    '()) ; Body

This scheme procedure can be called as follows:

(include (header-name) #:structs (struct-name1 struct-name2))

The most obvious benefit offered by keyword arguments in this case is that the empty list () needn't be passed as a parameter; the functions parameter can simply be omitted. It is also important to note that while many members of the Scheme family offer keyword parameters, it is not part of the Scheme spec.

Adopting a similar pattern, the original macro call can be made to look like this:

; In source program
,(include (header-name) #:structs (struct-name1 struct-name2))
GlowingScrewdriver commented 1 week ago

A few more notes on the topic:

  1. I can think of an alternative syntax to the macro call, one which would be much simpler to implement and read:

    ; In source program
    ,(include (header-name) (#:structs (struct-name1 struct-name2)))

    The difference between this and the Guile implementation is that here, the keyword and value are specified as a pair and that pair is supplied as an argument, rather than they keyword and value being two separate arguments.

  2. A keyword can be detected by the keyword? Guile Scheme procedure, like this:

    (keyword? #:key-name) ; result: #t