3 ms·
Most of the examples I gave above are core syntax forms. They are defined in the language grammar and are not function calls or macros. See the Racket language
by jcrites 9y ago
Most of the examples I gave above are core syntax forms. They are defined in the language grammar and are not function calls or macros. See the Racket language reference [0]:
> A core syntactic form[] is parsed as described for each form in Syntactic Forms. Parsing a core syntactic form typically involves recursive parsing of sub-forms, and may introduce bindings that determine the parsing of sub-forms.
top-level-form = general-top-level-form
| (#%expression expr)
| (module id module-path
(#%plain-module-begin module-level-form ...))
| (begin top-level-form ...)
| (begin-for-syntax top-level-form ...)
general-top-level-form = expr
| (define-values (id ...) expr)
| (define-syntaxes (id ...) expr)
| (#%require raw-require-spec ...)
expr = id
| (#%plain-lambda formals expr ...+)
| (case-lambda (formals expr ...+) ...)
| (if expr expr expr)
| (begin expr ...+)
| (begin0 expr expr ...)
| (let-values ([(id ...) expr] ...)
expr ...+)
| (letrec-values ([(id ...) expr] ...)
expr ...+)
| (set! id expr)
| (quote datum)
| (quote-syntax datum)
| (quote-syntax datum #:local)
| (with-continuation-mark expr expr expr)
| (#%plain-app expr ...+)
| (#%top . id)
| (#%variable-reference id)
| (#%variable-reference (#%top . id))
| (#%variable-reference)
See section 1.2.3.2 which specifies the expansion steps. Note that the expansion model differentiates between handling transformers aka macros and core syntax forms.
To be fair, it seems that Scheme (R5RS) considers some of these forms to be "derived expression types" and specifies their definition using `define-syntax` [1]. However, its core syntax forms still include the following [2]:
expression = variable
| literal
| procedure call
| lambda expression
| conditional
| assignment
| derived expression
| macro use
| macro block
... and there's a whole sub-grammar for specifying transformers (macros):
<transformer spec> =
(syntax-rules (<identifier>*) <syntax rule>*)
<syntax rule> = (<pattern> <template>)
<pattern> = <pattern identifier>
| (<pattern>*)
| (<pattern>+ . <pattern>)
| (<pattern>* <pattern> <ellipsis>)
| #(<pattern>*)
| #(<pattern>* <pattern> <ellipsis>)
| <pattern datum>
<pattern datum> = <string>
| <character>
| <boolean>
| <number>
<template> = <pattern identifier>
| (<template element>*)
| (<template element>+ . <template>)
| #(<template element>*)
| <template datum>
<template element> = <template>
| <template> <ellipsis>
Being able to write or evaluate Scheme fully requires an understanding of all of these distinct syntax forms.
[0] https://docs.racket-lang.org/reference/syntax-model.html#%28part._fully-expanded%29 https://docs.racket-lang.org/reference/syntax-model.html#%28...
[1] http://www.schemers.org/Documents/Standards/R5RS/HTML/ http://www.schemers.org/Documents/Standards/R5RS/HTML/ [2] http://www.schemers.org/Documents/Standards/R5RS/HTML/ http://www.schemers.org/Documents/Standards/R5RS/HTML/