Arc Forumnew | comments | leaders | submitlogin
2 points by nlavine 6149 days ago | link | parent

That is certainly the arc way to do it, but there's one thing I'm not sure about: do you want mac:let or let:mac? Or, in fact, would either one work? The problem I'm trying to get at is what happens to let's three arguments (symbol, value, body) when you compose mac with it. It seems like you really want mac to apply to only the value argument, which is not a straight composition.

I almost hate to get into this, but it seems to me that the real solution is first-class macros:

  (let my-macro (mac (x) `(prn ,x))
    ...)
I believe pg said that one of the things he gave up in the current implementation that he'd really like to have is first-class macros, and it may be that we can't get them in mzscheme without unacceptable performance loss, so perhaps maclet is the temporary solution, but this seems like the long-term way to go.


2 points by absz 6149 days ago | link

How about

  (mac mc args
    `(annotate 'mac (fn ,@args)))
? Then

  arc> (= m (mc (x) `',x))
  #3(tagged mac #<procedure>)
  arc> (m not-a-declared-symbol)
  not-a-declared-symbol
. Of course, the downside here is that, as you observe, we can't do

  arc> (let m (mc (x) `',x) (m not-a-declared-symbol))
  Error: "reference to undefined identifier: _not-a-declared-symbol"
or

  arc> ((mc (x) `',x) not-a-declared-symbol)
  Error: "reference to undefined identifier: _not-a-declared-symbol"
. My understanding is that the problem with the second is that (annotate 'mac ...) is not evaluated before not-a-declared-symbol:

  arc> ((mc (x) `',x) 'not-a-declared-symbol)
  (quote not-a-declared-symbol)
. We get the same output in the other case:

  arc> (let m (mc (x) `',x) (m 'not-a-declared-symbol))
  (quote not-a-declared-symbol)
. However, here I'm not sure why. So after working through this, I'm not actually sure what these results signify. But here they are. Make of them what you will.

-----

1 point by cadaver 6149 days ago | link

There was a post a while ago about how you might get first-class macros through lazy compilation: http://arclanguage.com/item?id=842

I'm not exactly sure if this is what you want. I believe there is a difference between macros that are only expanded once (in lazy compilation), and macros that are called each time the macro-expression is encountered. Though the latter case would only make sense if the macro exhibits side-effects, or depends on side-effects, or if the argument list to the macro may change. Not sure whether there is any benefit in that.

-----

2 points by cooldude127 6149 days ago | link

first-class macros would obviously solve this problem completely, that same way scheme eliminates the need for CL's flet and labels. it would be nice if we could just assign anonymous macros to bindings, but we can't do that yet.

the problem is that the composition just doesn't really make sense in this context, as you said. it doesn't translate the way composition should. in my opinion, maclet is deserving of it's own form.

-----

1 point by almkglor 6149 days ago | link

No, what I mean is, to overload mac:

  (let oldmac mac
   (= mac
        (annotate
           (fn x
              (if (and (is 1 (len x)) (acons (car x)))
                 (my-code ...)
                 (apply oldmac x)))
           'macro)))

-----