Arc Forumnew | comments | leaders | submitlogin
3 points by Pauan 3848 days ago | link | parent

"While I appreciate 'defs, it's a non-answer. The even/odd example I posted and the evenp/oddp example dido posted are idiomatic Arc code. While you and I don't care much about Arc compatibility, it's something dido wants for Arcueid, so these examples should work without modification."

For this example, let's suppose there was a file "foo.arc" that contained idiomatic Arc code that implements evenp/oddp. This code works in Arc 3.1. It will work in my system as well, because undefined symbols automatically create new boxes. Basically, it'll work, but name collisions are possible, just like in Arc 3.1.

If you then write a new file "bar.arc" that uses hyper-static idioms (var, defs, etc.), it can import "foo.arc" and everything will work fine. "foo.arc" will clobber any existing evenp/oddp definitions, but "bar.arc" will not clobber "foo.arc". And of course "bar.arc" can use "w/include" and "w/exclude" to prevent "foo.arc" from clobbering things.

If you wanted to make it so that "foo.arc" behaves correctly without needing to use "w/include" and "w/exclude", you would indeed need to rewrite it to use "defs". But it's still usable even without a rewrite. So it's a perfectly graceful degradation.

My system is designed so that it can correctly use all existing Arc 3.1 code, while new code is written with the hyper-static idioms. Then, slowly, old code can be migrated to use hyper-static scope, until eventually you could make Arc purely hyper-static.

There's three issues I see with my proposal:

1) If you're writing Arc code in a hyper-static fashion, you really want "arc.arc" to be changed to be hyper-static. But old Arc code will need the non-hyper-static "arc.arc". I think the simplest solution to this is to have two versions of "arc.arc", one that uses hyper-static scope, and one that doesn't. Then you would need to make sure to load the non-hyper-static version before loading Arc 3.1 code. This could be automated a tiny bit by using a macro, something like "w/arc3".

2) "load" occurs at run-time, which is why my definition of "w/include" needed to use "eval". Nulan doesn't have this problem because file importing occurs at compile-time. Perhaps the best way to solve this is to keep "load" as-is, and add in a new "import" macro that does all its work at compile-time.

3) If you think (eventually) making Arc purely hyper-static is a bad thing, you won't like my proposal.


"Am I getting this right? This sounds very workable. :) And whaddayaknow, Nulan works. ^_-"

Yes, that's more or less correct. The one detail that's different is... Nulan doesn't have a "get-variable-box" function. The reason is because "quote" internally uses (the equivalent of) "get-variable-box". So in Nulan, rather than using "get-variable-box", you'd just use "quote". And if you want to break hygiene, you'd explicitly use the "sym" function.

1 point by rocketnia 3848 days ago | link

I mostly followed along, but I don't understand "It will work in my system as well, because undefined symbols automatically create new boxes." You were talking about having them create new boxes at assignment time, and I was recommending compiling-a-reference-time instead so that we don't get an unbound variable error in the first definition.


1 point by Pauan 3848 days ago | link

How it works is, anytime the compiler sees an undefined symbol, it creates a new box for it like as if it had been created with "var".

Another way to think about it is... the compiler would replace this:

  (= foo (fn () ... bar ...))
  (= bar (fn () ... foo ...))
With this:

  (var bar)
  (var foo)
  (= foo (fn () ... bar ...))
  (= bar (fn () ... foo ...))
What happened is, when it encountered the undefined variable "bar", it created a new box for it. Then it encountered the undefined variable "foo", so it created a new box for it. Then it did the assignments like normal.

Given how you said "compiling-a-reference-time", I think we're talking about the same thing. Why did you mention assignment time?


3 points by rocketnia 3848 days ago | link

"Why did you mention assignment time?"

We've just had a long exchange about you creating boxes at assignment time and me using compiling-a-reference time instead. Here's a recap:


You: Here's how you do it. The definition of "=" is the same: if the variable exists, mutate it, otherwise create a new variable. But now you add in a new primitive called "var"[...]

Me: The behavior I'd use is that any compile-time variable access (even under a lambda) creates a new, uninitialized variable binding if a binding doesn't already exist.

You: Yeah I'd do that too, if I wanted to graft dynamic variables onto a hyper-static system. But since Arc uses dynamic variables, I proposed to graft hyper-static onto it instead.

Me: How do you make the even/odd code work? Under the approach you described, the first line refers to an undefined variable (odd), and I interpret that as an error. I was recommending a fix.

You: Easy: I have a macro called "defs" that handles mutual recursion

Me: While I appreciate 'defs, it's a non-answer. The even/odd example [...] should work without modification.

You: It will work in my system as well, because undefined symbols automatically create new boxes.


At least we seem to be agreeing now. ^_^;


3 points by Pauan 3848 days ago | link

Ah, sorry, huge miscommunication and misunderstanding on my part. I've actually been agreeing with you all along.

A large part of the problem is that I've been thinking about my proposal as two separate parts: one part deals with backwards compat with Arc, and the other part describes a hyper-static system for Arc.

When I was talking about "defs", I was talking about the hyper-static part. But you were talking about the backwards compat part. Hilarity (?) ensues.


1 point by rocketnia 3848 days ago | link

Okay, we're on the same page now then. ^_^

Having both kinds of scope as options would be great.