Arc Forumnew | comments | leaders | submitlogin
17 points by absz 6126 days ago | link | parent

The macro you want is

  (mac check args
    `(do
        ,@(map [list 'report-result _ `',_] args)))
There are a couple of things wrong with your macro. The first is that your (list ,@args) is inside ,(each ...) which is inside `(do ...); you can only have as many unquotes (,s or ,@s) as you have quasiquotes (`s), and you have two within one. The second is that "each" is only run for its side-effects. The return value of "each" is always nil. Thus, even if your macro worked, it would expand to (do nil), which isn't what you want. To replace "each", you want (map func lst), which returns a list where func has been applied to each element of lst, e.g. (map - '(1 2 3)) returns '(-1 -2 -3). In my macro, the function returns a list of the form (report-result ARGUMENT 'ARGUMENT); the `',_ construct means "quote the value of _," since ,_ is within a `. Splicing this (map ...) into the (do ...) block will give you what you want. Is that clear?

Also, a handy tip for debugging macros: (macex1 '(an-expression ...)) will expand the first macro call in (an-expression), which can help you see what's going wrong.

I can't tell you if this is the right place to ask these questions, but having some place for them would definitely be a good thing. I'm usually happy to answer them, though.



5 points by projectileboy 6126 days ago | link

Enormously helpful. Thank you. Coming from Blub world, it's been hard for me to think functionally - making a distinction between returning values and side effects.

I don't understand your first point however, as this is a perfectly valid macro:

(mac double (x) `(+ ,x ,x))

-----

8 points by ryantmulligan 6126 days ago | link

Let me explain the "two within one" problem that you may be saying that you do not see.

  (mac check args                                 ;;no qq's
       `(do                                       ;; ` one qq
          ,(each arg (list ,@args)                ;; ,(,@) two escapes
             `(report-result ,arg ',arg))))       ;; `(, ',) two qq one escape
So on the line

  ,(each arg (list ,@args) 
you are doubly escaping something that is only quoted once.

-----

0 points by projectileboy 6126 days ago | link

Gotcha. Gracias.

-----

3 points by almkglor 6126 days ago | link

Nitpick. This is not a good definition (valid, but not good). The problem is something like this:

  (double (prn 3))
Try the above in your repl after entering the mac definition; then consider what must be done in order to protect the x. For example, you might notice that the macros in arc.arc have a lot of (w/uniq (...) `(let ...)) forms, even the arguably simpler ones.

-----

6 points by ryantmulligan 6126 days ago | link

Great reply, you are exactly what the Arc community needs to succeed!

-----