Hm... yeah, that makes sense. Alrighty then, let's try to get `=` to desugar to a function, so we can get destructuring assignments. :P I figure (= '(a b) nil) could desugar to this:
(with (gs204 nil gs205 nil)
(= a gs204)
(= b gs205))
And then (= '(a b (c d)) '(1 2 (3 4))) could desugar to this:
(with (gs206 1
gs207 2
gs208 (3 4))
(= a gs206)
(= b gs207)
(= c gs208))
Hm... but that wouldn't work recursively, so it would only be one level of destructuring. In which case you might as well use something simpler:
It sounds like you're ending up with the same thing as setforms. That'll at least work, but it's not what I thought you meant by having '= desugar to a function.
I thought you meant something like this:
(= '(a b (c d)) '(1 2 (3 4)))
-->
(apply (fn (a b (c d))
(export-locals-to-parent-scope))
'(1 2 (3 4)))
And come to think of it, that's something which might actually make sense in an interpreter.
The setforms way is what I'd choose, at any rate. ^_^
That would work, yes, but it'd require adding an `export-locals-to-parent-scope` built-in (or similar), as you say. Preferably, I'd like to define it in a way that's compatible with pg-Arc.
It's not a big deal, though. In a worst-case scenario, we can define `=` so it does a single level of destructuring. That should be simple to add, even in pg-Arc, while still providing some usefulness.
P.S. `with` expands to a function, so technically it is desugaring to a function. :P Your idea is quite a bit shorter and simpler, though.
Also... this just reminded me of something: lambdas in JavaScript. If I recall, there was a proposal for "thin" functions in JS, which (among other things) would not have "var" scope:
function foo() {
(lambda {
var bar = 10;
})()
return bar;
}
foo() -> 10
Basically, any "var" statements would act as if the lambda wasn't even there, thus assigning them to the outer scope. After looking it up, it seems that "lambda" was changed to "#", which is quite a bit shorter (http://brendaneich.com/2011/01/harmony-of-my-dreams/).
A similar "thin-fn" form in Arc might be an interesting experiment: any assignments within the thin-fn would always assign to the outer scope. You could still assign locally, by using `let`, since that desugars to a "heavy" function:
(def foo (a)
((thin-fn (a)
(= a "foo")))
a)
(foo) -> "foo"
(def foo (a)
((thin-fn (a)
(let a nil
(= a "foo"))))
a)
(foo) -> nil
Then we could have `=` desugar to a thin-fn, which would work without needing an `export-locals-to-parent-scope` built-in. The advantage of this approach is that it's more general: other functions might be able to make use of thin-fn's too.
...but, Arc fn's already behave like the lambda proposal for JS, so the problems that JS is trying to solve simply don't exist in Arc. Thus, it's arguable whether Arc should have "even thinner" fn's or not.