(define code
'(
function f1 < a b >
vars x y
begin
"..."
end
)
)
(define ,(cadr code) '()) ;first method
(define ,(list-ref code (+ (index-of code 'function) 1)) '()) ;second method
Why does the second method give the warning "define: not an identifier, identifier with default, or keyword for procedure argument" even though both ,(cadr code)
and ,(list-ref code (+ (index-of code 'function) 1))
return f1
?
The program is read, expanded and then evaluated. The unquote (,) syntax is handled by the reader. This means, that when you write:
(define ,(cadr code) '())
in you program, it is equivalent to writing:
(define (unquote (cadr code)) '())
Which we can write as:
(define (unquote [cadr code])
'())
So here you define a function named unquote
that takes one optional argument named cadr
. The default argument for cadr
is code
.
Now you write:
(define ,(list-ref code (+ (index-of code 'function) 1)) '())
which the reader turns into:
(define (unquote (list-ref code (+ (index-of code 'function) 1)))
'())
We see here that (list-ref code (+ (index-of code 'function) 1))
is highlighted with the error:
define: not an identifier, identifier with default, or keyword for procedure argument in:
This meant that define
expected an indentifier, or [identifier default] or an #: keyword.
If we check the grammar, we see:
(λ kw-formals body ...+)
kw-formals = (arg ...)
| (arg ...+ . rest-id)
| rest-id
arg = id
| [id default-expr]
| keyword id
| keyword [id default-expr]
So the error message just means that whatever follows the name of a function
needs to be one of the four case in the grammar for arg
.
Note: The unquote
character , is meant to be used inside a quasiquote (a backtick) [look unquote up in the docs].