wart> (mac foo(a b) `(cons ,a ,b))
wart> (mac bar(a b) (prn `(cons 3 ,@(foo a b)))) ; prn for debugging
wart> ((fn(x) (bar x x)) 'abc)
(cons 3 x . x)
004cell.cc:158 car of non-cons: x
004cell.cc:158 car of non-cons: x
(3 . abc)
My bar example is poorly constructed; besides that I think you're right.
wart> (mac foo(a b) `(cons ,a ,b))
wart> (mac bar(a b) `(cons 3 ,(foo a b)))
wart> ((fn(x) (bar x x)) 'abc)
005types.cc:263 can't coerce symbol abc to function
There was a typo in grandparent, so let me summarize the correct versions:
wart> (mac foo(a b) `(cons ,a ,b))
wart> (mac bar(a b) `(cons 3 ,@(foo a b)))
wart> ((fn(x) (bar x x)) @'(abc))
(3 . abc)
wart> (mac foo(a b) `(cons ,a ,b))
wart> (mac bar(a b) `(cons 3 ,(foo a b)))
wart> ((fn(x) (bar x x)) @'(abc))
005types.cc:263 can't coerce symbol abc to function ; no change
I think you're asking what happens to (''a b c). Hmm, I don't translate that to ''(a b c). It seems to be acting like (a b c). Does that seem right?
---
Another potential concern: I'm using a single boolean to track whether we encounter a '', and I reset it before unquote's eval and check it after. I think it might need to be a stack of booleans to handle nested expressions, but I've not been able to come up with a failing test case.
" '' is an internal detail. The reader provides no way to type it in. If you ever see it printed at the REPL, that's a bug."
If unquote adds a '', then `,'foo should return ''foo, right? Then 'write should write ''foo at the REPL.
In order to weasel out of anything that stripped '' from the arguments to a function, I tried putting `, around the whole command, in the hopes that it would somehow manipulate the state of the don't-strip-'' flag(s) for the duration of the command.
In any case, there's no reason foo should be called, is there? O_o
In other news, this might be an easy test case for the scope of the don't-strip-'' flag. If your implementation sets it to true on the way in and false on the way out, then it'll become false on the way out of the inner `, , rather than recovering its previous value of true.
"If unquote adds a '', then `,'foo should return ''foo, right?"
Unquote doesn't add '', @ does. Perhaps that changes your example?
"In any case, there's no reason foo should be called, is there? O_o"
:) Yeah that's a bug with my paren inference; it was implicitly wrapping the expression in parens. I'd never seen backquote-comma before. Here's a temporary workaround:
wart> (list `,(write `,'foo))
foo(foo) ; ignore the (foo) -- it's the return value