Arc Forumnew | comments | leaders | submitlogin
3 points by almkglor 6083 days ago | link | parent

The problem is the inherent difference between binding x in f where it is defined as opposed to binding x in f where it is called.

Dynamic binding fails in this condition:

  (let x 42
   (def set-x (new-x)
     (= x (+ new-x 1)))
   (def f ()
     x))
The point is that x does not have a local or a global lifetime. Instead, it has a local or a global scope. The lifetime of every variable is like that of any object: when everything that can access it is lost, it gets garbage collected. That's even more consistent: not only are values automatically managed, locations are automatically managed too.

Global variables are always accessible and therefore will never be destroyed. But local variables might die as soon as the function exits, or it might live on. The only functions that have the right to access them, however, are those that are defined specifically to be within its scope. This means we have automatic protection.

Granted, you want to release this protection; presumably you have some plan to have programmers explicitly ask for the protection. I've programmed in a language which supports both dynamic and syntactic binding, and I always prefer using the syntactic binding. This is because while hacking into some other function's global is cool, some day you are going to do this accidentally, and when that day comes, you'll know why a library that used to work suddenly fails.



1 point by jazzdev 6083 days ago | link

> This is because while hacking into some other function's global is cool, some day you are going to do this accidentally, and when that day comes, you'll know why a library that used to work suddenly fails.

Isn't that one of the goals of Arc? A hackable language?

That's a good reason if Arc is designed for average programmers, but pg says it is explicitly designed for good programmers.

-----

3 points by absz 6083 days ago | link

This, it seems to me, is a very different use of "hack." It's more akin to forbidding (scar 'blue 'red), though not quite as severe: the latter is something nonsensical, and though you could hack together a meaning for it, it would certainly break down. The former case hacks around the definition of a function, but is also certain to break. These uses of "hack" are the ugly kind, closer to "kludge", not the beautiful or powerful kind.

-----

2 points by almkglor 6083 days ago | link

LOL. This is where the semi-deliberate delicious ambiguity of "hack is kludge! what you mean? xy is x times y but 23 is not 2 times 3?" vs "hack is elegant! what you mean? e^(i*pi) = -1?" rears its ugly head.

-----

1 point by jazzdev 6083 days ago | link

>Dynamic binding fails in this condition:

  (let x 42
   (def set-x (new-x)
     (= x (+ new-x 1)))
   (def f ()
     x))
There are no free variables in set-x or f (except for +) so dynamic binding can't affect this (except for +).

I'm not advocating releasing any protection on lexical variables. I'm advocating a change in the semantics of free variables.

-----

4 points by almkglor 6083 days ago | link

Right. So tell me, suppose I have a very, very old piece of code, a classic, like this:

   (def map1 (f xs)
    " Return a sequence with function f applied to every element in sequence xs.
      See also [[map]] [[each]] [[mappend]] [[andmap]] [[ormap]] "
    (if (no xs)
        nil
        (cons (f (car xs)) (map1 f (cdr xs)))))
Now suppose in the future some random guy creates an application focused on cars. Since the guy knows he won't use 'car and 'cdr (car? cdr? pfft. that's so low-level! use proper let destructuring, foo!), he's quite willing to reuse the name 'car as a variable:

  (let car (get-user-car)
    (map1 color-wheel car!wheels))
Oops! map1's car function got overridden!

This is a rather contrived example, but hey, believe me: it'll happen, and it won't be as obvious as that. That's why dynamic variables are explicit in CL. That's why the default binding will be static.

Now if someone wants to explicitly have dynamic variables, it's already done. http://arclanguage.com/item?id=2497

-----

1 point by jazzdev 6083 days ago | link

>Now suppose...

  (let car (get-user-car)
    (map1 color-wheel car!wheels))
>Oops! map1's car function got overridden!

That's a good argument. I can see the havoc that would result.

Still, I'm willing to risk that so that I have the option to do something like:

  (with (ocar car car-counter 0)
    (let car (fn (xs) (++ car-counter) (ocar xs))
      (map1 color-wheel car!wheels))
    (prn "map1 called car " car-counter " times"))

-----