Arc Forumnew | comments | leaders | submitlogin
1 point by akkartik 4447 days ago | link | parent

"What drawbacks are those?"

I get the sense that vau/wrap/unwrap are the 'structured' equivalents of caller-scope. They're more well-behaved, and they make it harder to do super ugly things like functions reaching in to modify their caller's scopes ^_^. This well-behavedness also makes it tractable to specify their semantics, prove theorems about the calculus, regularity, smoothness, being hygienic, and whatnot.



1 point by Pauan 4447 days ago | link

Actually, I see them as just being stylistic differences... Kernel already lets you mutate the caller's scope via $set! so I assume you're talking about the parent of the caller's scope... Yeah you can't do that, but you could make a language very similar to Kernel, with that one thing changed if you wanted to.

Or perhaps you're talking specifically about functions mutating their environment... well you can do that in Kernel too:

  (wrap ($vau ... env ...))
The above creates a function that has access to its dynamic scope. This isn't used most of the time in Kernel, but it is used in a couple places, like the "get-current-environment" function. Most of the time you would use $lambda.

I think the benefit of vau/wrap/unwrap is that it makes it super easy to coerce between functions/fexprs. It's also very clean and easy to reason about. But I don't see them as being necessarily more "well behaved" than wart's approach.

-----

1 point by akkartik 4447 days ago | link

"I think the benefit of vau/wrap/unwrap is that it makes it super easy to coerce between functions/fexprs."

Ah, this was what I was missing. This makes your position crystal clear, thanks.

-----

2 points by Pauan 4447 days ago | link

One other benefit: the environment argument is local, rather than a global hard-coded "caller-scope". This not only lets you write it shorter (such as "env") but also avoids collisions in the case of nested $vau's:

  ($vau ... env1
    ($vau ... env2
      ...))
I suppose in that one case, $vau is more well-behaved. You can emulate that behavior with let, though:

  (fn '...
    (let env1 caller-scope
      (fn '...
        (let env2 caller-scope
          ...)))
Which is admittedly verbose.

-----

1 point by akkartik 4447 days ago | link

Yeah, those are great examples.

For all my rhetoric about "give the programmer absolute powa!!1!" I'm uncomfortable making caller-scope too easy to use ^_^. It'll just be the next case of, "when I understand why I need this power, I'll mix it in."

-----