3 ms·
Actually, almost of those are just function calls. Some of them happen during the compile phase, some during runtime. Things that happen at compile-time, say a
by emidln 9y ago
Actually, almost of those are just function calls. Some of them happen during the compile phase, some during runtime. Things that happen at compile-time, say a let function call[0] e.g.
(let ((x 23)
(y 42))
(+ x y))
will return data as a return and compilation will continue (or stop because some sort of error/exception occurs).
The important bit is at compile-time, a function invocation passes the rest of the form to the function as arguments without first evaluating them. Thus there is no syntax for quoting the list of binding forms. At runtime, a function invocation passes the rest of the form to the function as arguments but will evaluate all arguments before doing so. Knowing what is and isn't a macro is a bit tricky in some lisps (and in others there are sigils, reified tables listing the macro symbols, or metadata to let you know what you're dealing with).
The only distinct syntax elements you provided are:
quote - 'small
strings - "hi"
function call - (function arg0 arg1 argN)
dotted pair - (datum . 10)
sharp dispatch - #%datum
Lisps do have syntax. Some provide notations for alternate data types like keywords or fixnums; data structures other than lists like hashes, sets, vectors, etc; or ways of dispatching at read-time. It is worth pointing out that all of the things you mentioned as syntax (which certainly are syntax in most other languages) are merely function calls in lisp.
[0] There isn't a significant difference between a macro and a special form here. One is looked up in the application or prelude and is written in lisp, the other is provided by the compiler and possibly not written in lisp.
- jcrites 9y agoMost 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/