From: Philip McGrath <philip@philipmcgrath.com>
To: jgart <jgart@dismail.de>, help-guix@gnu.org
Cc: Guix Help <help-guix@gnu.org>, "(" <paren@disroot.org>
Subject: Re: Don't Unquote Me
Date: Fri, 14 Oct 2022 19:40:31 -0400 [thread overview]
Message-ID: <3721504.MHq7AAxBmi@bastet> (raw)
In-Reply-To: <CNLWAUM86WTK.2A3LFL0OTPV5F@guix-framework>
[-- Attachment #1: Type: text/plain, Size: 4305 bytes --]
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
[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
next prev parent reply other threads:[~2022-10-14 23:41 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-10-14 4:03 Don't Unquote Me jgart
2022-10-14 6:59 ` (
2022-10-14 18:38 ` jgart
2022-10-14 19:32 ` (
2022-10-14 23:40 ` Philip McGrath [this message]
2022-10-15 15:05 ` Akib Azmain Turja
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=3721504.MHq7AAxBmi@bastet \
--to=philip@philipmcgrath.com \
--cc=help-guix@gnu.org \
--cc=jgart@dismail.de \
--cc=paren@disroot.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/guix.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.