On Friday, October 14, 2022 3:32:55 PM EDT ( wrote: > On Fri Oct 14, 2022 at 7:38 PM BST, jgart wrote: > > > Nope; they're special built-in forms like ``lambda'' and ``define''. > > > > So, they are ordinary functions defined in guile? > > > > Or by built-ins you mean that they are implemented in C? > > > > I'll read through the guile source code a bit later ;() > > They are fundumental forms. You cannot define ``quote'' et al in terms of > any other feature. Just like there's no way to implement ``lambda'' in > Guile, because ``lambda'' is a fundumental form. So yes, they will be > implemented in C as part of the Guile core. > Well, `quasiquote`, `unquote`, and `unquote-splicing` can straightforwardly be defined as macros in a simpler core language that provides `quote`. That's how they are implemented in Racket. You can find the source, which is fairly close to portable Scheme, in: --8<---------------cut here---------------start------------->8--- less $(guix shell racket-minimal -- racket -e '(display (collection-file-path "qq-and-or.rkt" "racket/private"))') --8<---------------cut here---------------end--------------->8--- The only reason the implementation is a bit verbose is that is at quite an early step in building `racket/base` from the primitive `#%kernel` language understood by the core compiler and runtime system: the same file contains the implementation of `let`. (Similarly, you need one of `lambda` or `case-lambda` to be primitive, but not necessarily both.) The situation with `quote` is a bit trickier because `quote` encompasses a few different features. In practice, most languages in the Scheme family choose to implement `quote` as a primitive syntactic form (including Racket [1]), but many of its features, even those that seem quite magical, could be implemented as derived constructs with a sufficiently expressive macro system. For example, here's a portable implementation of the part of `quote` which creates a symbol corresponding to some syntactic identifier: --8<---------------cut here---------------start------------->8--- #!r6rs (import (rnrs)) (define-syntax quote-symbol (lambda (stx) (syntax-case stx () ((_ id) (identifier? #'id) #`(string->symbol #,(symbol->string (syntax->datum #'id))))))) (write (quote-symbol hooray)) --8<---------------cut here---------------end--------------->8--- You could get the right allocation behavior either by relying on "The Guaranteed Optimization Clause of the Macro-Writer's Bill of Rights"[2] or by using a macro system that provides functions like `syntax-local-lift-expression`[3]. The implementation above relies on the base language having a built-in notion of string literals, which feels a little like cheating because we typically explain the concept of literals in terms of `quote`. Indeed, in `#lang racket/base`, the expression: "hooray" expands to: (#%datum . "hooray") which then expands to: (quote "hooray") where the expander introduces `#%datum` with the lexical context of `"hooray"` to provide languages a means of hygienically interposing on the meaning of literal data. In other words, self-quoting literals are not primitive in Racket. For some deep thoughts along these lines, I highly recommend this mailing list post by Ryan Culpepper, who designed Racket's `syntax-parse`: https://groups.google.com/g/racket-users/c/HaSmcTN0SA4/m/1XYa-mL5AgAJ Returning to the original question, regardless of all of the above, you can tell that `quote` et al. can't be functions, primitive or derived, because of how evaluation works in Scheme-like languages. As an example, consider the expression: (quote (hello world)) If `quote` were bound to a function, to evaluate that expression, we would need to first evaluate `hello` and `world` and then apply the value of `hello` to the value of `world`. We'd then apply the value of `quote` to the result. Obviously that doesn't work: an essential aspect of `quote` is that it doesn't evaluate its subform. -Philip [1]: https://docs.racket-lang.org/reference/syntax-model.html#%28part._fully-expanded%29 [2]: https://www.youtube.com/watch?v=LIEX3tUliHw [3]: https://docs.racket-lang.org/reference/stxtrans.html#%28def._%28%28quote._~23~25kernel%29._syntax-local-lift-expression%29%29