Arc Forumnew | comments | leaders | submitlogin
1 point by drcode 6110 days ago | link | parent

I think this idea has some merit. However, I would argue it's still not arcish enough (but better than other ideas I've seen)

The basic issue I would have with this is that variable capture like this happens maybe in 1/1000 uses of macros (thought it's already happened once to me, so I agree with your concern is valid)

However, your solution would make 100% of macro definitions ungainly, which is too high a cost, IMHO.

The best solution I can think of is:

1. Use your carat idea, except don't waste a valuable non-alpha character. Instead have a function "only-top" that guarantees that a symbol used as a function refers only to a toplevel definition (which would work through a shadowed name at the definition point, though the name would be a collision-safe gensym mapped to the toplevel definition via a hash table- not a carat appended name)

2. Give a warning when arc detects a name collision with a local variable during macroexpansion

So if you write this:

  (def my-frob (x) ...)

  (mac my-macro (...) `(my-frob ...))

  (let my-frob ... (my-macro ...))
you would get an warning message:

  *Warning- expansion of my-macro causes collision of symbol MY-FROB*
You could remove the warning (if you don't want to change the local variable name) by changing the macro to:

  (mac my-macro (...) `(,(only-top 'my-frob) ...))
You would have some kind of similar method for hiding the error, in cases where the capture was actually desired.

With this solution, you could merily write macros without the cognitive load of an explicit name collision system, but still be safe from the problem when a rare name collision does occur.



2 points by kennytilton 6110 days ago | link

"variable capture like this happens maybe in 1/1000 uses of macros (thought it's already happened once to me, so I agree with your concern is valid)"

How did it happen?! Did you skip a uniq out of laziness, or did the lexical environment into which you expanded rebind an Arc keyword or one of your own function names or ____? Maybe lisp-1 necessitates hygiene, and lisp-1 is The Real Problem.

As a longtime very relaxed CLer I must say I completely do not appreciate the naming paranoia I have experience with Arc/Lisp-1. Funcall is precisely what problem? My massive codebase shows 340 defmacros and 201 funcalls, which if you think about it is an astonishing ratio. (Think "define" vs. "invoke".)

-----

1 point by drcode 6109 days ago | link

I'm talking about function name collision, because it's a Lisp-1.

...I don't consider Lisp-1 a problem. It more than makes up for the rare name collision...

-----

2 points by lisper 6110 days ago | link

> The basic issue I would have with this is that variable capture like this happens maybe in 1/1000 uses of macros (thought it's already happened once to me, so I agree with your concern is valid)

Have you written 1000 macros? If not I'd say you underestimate the odds. Also, whatever the odds are, they just get worse as the size of the code base increases.

> However, your solution would make 100% of macro definitions ungainly, which is too high a cost, IMHO.

But macros only make up a small percentage of typical code, so this might still be OK.

> The best solution I can think of is:

Two problems with this:

1. Issuing those warnings is not easy. It requires a code walker. If you're going to go to that much trouble you might as well implement real hygienic macros.

2. (only-top foo) seems even more ungainly to me than ^foo.

I personally don't think the ^foo idea is the perfect solution, but given that PG doesn't like hygiene or Lisp-2 it seems like a good alternative. Better than burying your head in the sand and hoping the problem doesn't happen IMHO.

-----

1 point by almkglor 6110 days ago | link

There's just a problem: an error occurs on the macro user which must be fixed by the macro writer. Assuming the macro is complex enough, the user may not care to try hacking the macro source to get at the symbol to be (only-top ...)'ed.

Hmm. Problems, problems. My rename-the-local-variables solution won't work very well for macros which accept literal, unquoted symbols.

-----

2 points by drcode 6110 days ago | link

Understood, but if the user has the problem and doesn't want to hack on the macro, all they'd have to do is rename their local variable, which would be an OK comprise I think.

-----

1 point by lisper 6110 days ago | link

Until the day you want to do this:

(mac1 ... (mac2 ...

and find that MAC1 has a name conflict with MAC2, and both MAC1 and MAC2 were written by someone else.

-----