Skip to content

Instantly share code, notes, and snippets.

@masak
Created November 5, 2012 16:43
Show Gist options
  • Save masak/4018222 to your computer and use it in GitHub Desktop.
Save masak/4018222 to your computer and use it in GitHub Desktop.
discussion on #scheme
17:19 < mark_weaver> masak: In Scheme, a single macro invocation can expand into several procedures. furthermore, a macro can
expand into another macro use, which later expands into something different. in general, macro expansion
can split up and combine pieces of code into a very different arrangement. the lexical contours can only
be determined after macro expansion.
17:20 < LeoNerd> Ooooh.. that's another good point
17:21 < mark_weaver> masak: therefore, it seems to me that you're very much on the wrong track.
17:21 < masak> interesting. I will try to process this.
17:21 < mark_weaver> I suggest that you read some papers on hygienic macros. let me dig up some references.
17:21 < LeoNerd> Yah; I'm still with "macros are sort of like rewrites of the source code" in CPP-style.. only nicer
17:21 < masak> mark_weaver: excellent. that was my next question :)
17:22 < masak> I'm not immediately swayed or worried by "macros can expand into other macros". as far as I can see, my model
covers that too.
17:23 < masak> there will be some tricky bits involving things actually *declared* inside a quasi. they have to be sandboxed
and the declarations have to actually happen at macro expansion.
17:23 < LeoNerd> The thing with a macro is that, similar to a C-style macro, you ought to be able to just expand that and
somehow dump the resulting source code, and it still mean the same without having the macro in it
17:23 < LeoNerd> (Give or take the deparsing variable names thing)
17:23 < masak> LeoNerd: that sounds like unhygienic macros to me.
17:23 -!- jrslepak [[email protected]] has joined #scheme
17:24 < mark_weaver> masak: here are a few recommended papers to read:
17:24 < mark_weaver> http://mumble.net/~jar/pubs/scheme-of-things/easy-macros.ps
17:24 < mark_weaver> http://www.cs.indiana.edu/~dyb/pubs/LaSC-5-4-pp295-326.pdf
17:24 < mark_weaver> http://srfi.schemers.org/srfi-72/srfi-72.html
17:24 < mark_weaver>
17:25 < masak> thank you.
17:25 < Gmind> is that someone making a lisp ?
17:26 < masak> who, me? not unless you listen to those who claim that Perl 6 is an implementation of M-expressions :P
17:27 < mark_weaver> masak: here's another thing to think about: in scheme, a single identifier that gets passed as an argument
to a macro can turn into multiple distinct variables (or even quoted datums) in the expanded code.
17:27 -!- Fare [[email protected]] has quit [Ping timeout: 240 seconds]
17:28 < mark_weaver> for example, I can define a macro: (define-syntax-rule (with-incremented v expr) (let ((v (+ v 1))) expr))
17:28 < masak> yes, we have that too. since the macro parameters are assumed to be AST objects, which can contain arbitrary
code.
17:28 < mark_weaver> so, I can use it like this for example: (let ((v 1)) (+ v (with-incremented v (* v v))))
17:29 < mark_weaver> and that expands to this: (let ((v 1)) (+ v (let ((v (+ v 1))) (* v v))))
17:29 < mark_weaver> notice how the 'v' passed to the macro turns into two distinct variables in the generated code.
17:30 -!- kilimanjaro [~kilimanja@unaffiliated/kilimanjaro] has quit [Ping timeout: 246 seconds]
17:30 < masak> ah. yes.
17:30 < mark_weaver> there's an inner 'v' and an outer 'v'. and the 'v' in 'expr' will end up referring to the inner 'v'.
17:30 < mark_weaver> but there's no way to know which 'v' the one in 'expr' refers to until after the code has been expanded.
17:30 < mark_weaver> how can you model handle this?
17:31 < masak> this is exactly what my ASTs-as-closures are achieving. see the example under "How closures cause hygiene" at
https://gist.github.com/abd360db840a0719da2f
17:33 -!- ijp [[email protected]] has joined #scheme
17:33 < mark_weaver> I'm sorry, I don't have time to learn and understand your model. But I can raise some issues that you
might not have thought about.
17:33 < Gmind> ( I'm making one implementation, so.. just listen to you guys for some ideas... )
17:33 < masak> mark_weaver: indeed. thanks for your input so far. it is very useful.
17:33 < masak> mark_weaver: I will follow up by reading your suggested material.
17:33 < mark_weaver> I'll give you one more example to think about, and to make sure your macros can handle it:
17:34 < LeoNerd> masak: Well.. yes.. but given the existence of some syntax to notate introduced symbols (such as my crazy
#:foo:123 ), you can basically do it
17:34 < mark_weaver> (define-syntax-rule (with-and-without-incremented v expr) (list 'v expr (let ((v (+ v 1))) expr)))
17:34 < masak> LeoNerd: as long as I don't have to deparse the code, it seems I will not have to invent symbols at all.
17:35 < LeoNerd> Yeah, that was my point :)
17:35 < LeoNerd> If you want to consider the macro expansion phase as purely a code-rewriting trick, with the output still a
plain-text syntax of a Scheme program, you do have to deparse it at the end
17:35 < mark_weaver> here, 'v' ends up referring to three very different things in the expanded code, and the 'v' in 'expr'
ends up referring to two different bindings of 'v'.
17:35 < LeoNerd> So you need a way to notate those invented symbol names somehow
17:36 -!- hkBst [~marijn@gentoo/developer/hkbst] has quit [Quit: Konversation terminated!]
17:36 < masak> mark_weaver: let's see... 'v is always just the symbol, right? it doesn't even have anything to do with bindings.
17:36 < mark_weaver> 'v' ends up in a quoted datum first, and then it is used as a new for a new lexical variable. and there
are two copies of 'expr' in the expanded code, and the 'v' in one of those copies refers to a different
variable than the 'v' in the other copy.
17:37 < mark_weaver> s/new/new name/
17:37 < masak> hm. I can see why our model confuses you. it's different enough in places for there not to be a straight
translation of concepts, I think.
17:38 < masak> nevertheless, I will save this conversation so that I can refer back to it later.
17:38 < masak> it's a big help.
17:38 < mark_weaver> masak: can your model handle my 'with-and-without-incremented' macro properly?
17:39 < masak> I don't know because I don't understand it offhand.
17:39 < masak> need to mull over it a bit.
17:39 -!- phao [[email protected]] has joined #scheme
17:39 < mark_weaver> keep in mind, btw, that in the (let ((v (+ v 1))) ...) the inner 'v' variable is getting initialized to
one plus the outer 'v' variable.
17:39 < masak> right.
17:42 < masak> again, thanks. I will process all this and then maybe come back for more.
17:42 < mark_weaver> masak: okay, happy hacking!
17:43 < masak> I was told there was a risk I might get flamed for asking insolent questions in here, but you people seem a
friendly bunch.
17:43 < masak> LeoNerd++ mark_weaver++ Gmind++
17:43 < LeoNerd> :)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment