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

"and evanrmurphy for getting me thinking about fexprs[2]"

I've been coming to the conclusion that although macros are great, they have some pretty severe limitations, due to them always being expanded at compile-time. So I'd be very interested to see if fexprs would be a good fit for Arc.

What I think would be neat is if macros were expanded at compile-time as much as possible, and when they can't be expanded at compile-time, they'll revert back to interpreting at run-time. Then, you can get full macro speed most of the time, but it would still allow you to do things like, say, use `apply` on a macro, or pass it as an argument to `map`, etc.

Alternatively, you could just not have macros, only having fexprs, and then try to optimize fexprs in various ways. I doubt it'd be as fast as expanding macros at compile-time, but... who knows, it might still be Fast Enough(tm).

Anyways, I think it's good for us to experiment with fexprs more, and see how things turn out.


In fact, because of the severe problems with macros, I independently came up with a pattern that rocketnia had already discovered: thunks. By wrapping every argument to a function in a thunk, you basically turn them into ghetto fexprs. So rather than doing this:

  (foo a b c)
You'd do this:

  (foo (fn () a) (fn () b) (fn () c))
But obviously that's a total pain, so what I did was rename "foo" to "foofn", and then have a macro called "foo". So that way, this:

  (foo a b c)
Would expand into this:

  (foofn (fn () a) (fn () b) (fn () c))
As near as I can tell, this is pretty much hygienic macros, since foofn is an ordinary function that has lexical scope. It's not nearly as clean or expressive as fexprs, but it's a cool little hack that can help work around the limitations of macros.

But, if we get to the point where a significant number of macros are basically just expanding into thunks... then I think we'd be better off having fexprs.

2 points by bogomipz 4725 days ago | link

About thunks; this is actually a situation where statically typed languages have the potential to do something interesting that is hard in dynamically typed systems.

If foo takes an argument that should be a zero arity function that returns a number, and you write:

  (foo (+ x y))
The compiler could recognize that the expression you used for the argument can be converted into a function with the correct signature. I think I have heard of languages on the JVM that do this, not sure which.

Also note that Smalltalk-80 is very much designed around the principle of thunks. E.g:

  a > b ifTrue: [Transcript show: 'A is great!']