Arc Forumnew | comments | leaders | submitlogin
2 points by CatDancer 5582 days ago | link | parent

Curiosity got the better of me, so I installed Common Lisp.

The (print "evaluated!") itself evaluates to "evaluated!", so here

  cl> (test-m t)
    "evaluated!"
what you're seeing is the value that 'm expands into, not the macro being expanded at that point. If you use something like,

  (defmacro m ()
    (print "evaluated!")
    42)
you'll be able to see what's happening more easily.


1 point by palsecam 5582 days ago | link

Hi hi, nice that you install Common Lisp by curiosity!

However, I don't understand what you want to demonstrate with your macros.

   cl> (defmacro m () (print "evaluated!") 42)
   M
   cl> (if t (m) 43)
   "evaluated"
   42
   cl> (if nil (m) 43)
   43
Ah maybe you mean, when defining the 'test-m function?

   cl> (test-m t)
   42    
Kind of "strange" there is no "evaluated", is this the point? This is a point.

-----

2 points by CatDancer 5582 days ago | link

Yes,

  cl> (test-m t)
  42
is the behavior that I'd expect to see, since the macro was expanded at compile time, when test-m was defined.

The behavior of 'if at the REPL is interesting, perhaps it is to support conditional compilation? However it is a special case, since only at the REPL would we be able to evaluate the test argument to the 'if before compiling the then or else forms. Doing so little as wrapping the 'if statement in a lambda causes the macro to be expanded regardless of the test argument:

  > ((lambda () (if t 3 (m))))
  "evaluated!"
  3

-----

1 point by palsecam 5582 days ago | link

OK here. You're right about the REPL vs normal time eval. The lambda example says everything.

So the 'each of my dreams will be very difficult to have :-D! Maybe with lazy evaluation/JIT compilation [hmmm maybe not needed, see edit below].

Thanks for everything CatDancer!

EDIT:

Lol this stuff has no end. CatDancer I really enjoy all this, but it is late here and I will have to go to bed, seriously!

OK, so no REPL.

In if.lisp:

   (defmacro m () (print "Hello via mac!") 42)

   (defmacro fm ()  ; remember, myeach would also be a macro...
     `(if (eq (read) 'CALLMAC)
        (m) 
        (print "Hello via func")))

   (fm)
On command-line:

   paul@polo-laptop:~ $ echo 'CALLMAC' | sbcl --script if.lisp
   "Hello via mac!" 
   paul@polo-laptop:~ $ echo 'no call' | sbcl --script if.lisp
   "Hello via func"
But yes, if 'fm is a function instead:

   paul@polo-laptop:~ $ echo 'no call' | sbcl --script if.lisp
   "Hello via mac!" 
   "Hello via func"

-----

2 points by CatDancer 5582 days ago | link

Oops, I should have said "top level" not "REPL". My mistake!

"Only at the top level would we be able to evaluate the test argument to the 'if before compiling the then or else forms".

> So the 'each of my dreams will be very difficult to have

Well you know, the Arc compiler knows whether a variable is in the lexical scope. So you could implement your myeach in ac.scm, not using macros, but instead compiling to Scheme.

Or... how about...

  (mac ech args `(each _ ,@args))
:-)

-----

1 point by palsecam 5582 days ago | link

No sorry me because my examples should be better. I use the command line but yes it's still "top level" and this is not enough to test this, right?

But here; OK, if 'fm is a function, the behaviour is "like in Arc". But if it's a macro, it seems to behave "like I want". Or is my example not good? (Sorry I'm really tired here, I can't even realize this :-D).

I mean, don't you think 'myeach as a CL macro would work?

> (mac ech args `(each _ ,@args))

Actually I'm currently using that. I'm just using the name 'each_ instead and define it using the macro currying stuff of twilightsentry (see id=10139, very interesting).

   arc> (= each_ (>_ each '_))
But still you know, one extra character ('_') to type... :-D

-----

2 points by CatDancer 5582 days ago | link

> But if it's a macro, it seems to behave "like I want". Or is my example not good?

Shall I wait until tomorrow to reply so that you can get some sleep? :)

Try

  ((lambda () (fm)))
you can see that only if (fm) is invoked directly from the top level will the macro expansion be avoided.

> I mean, don't you think 'myeach as a CL macro would work?

What you need, in CL or in Arc, is a way to tell if a variable is defined at macro expansion time. Suppose Arc could tell you at macro expansion time if a variable was defined. Then you could say

  (def myeach (first . args)
    (if (defined first)
      `(each _ ,first ,@args)
      `(each ,first ,@args)))
no magic needed in 'if, in either language :)

-----

1 point by palsecam 5582 days ago | link

> Shall I wait until tomorrow to reply so that you can get some sleep? :)

Lol, yes I definitely go to bed now :-)

> ((lambda () (fm))

Nice demonstration indeed.

> What you need, in CL or in Arc, is a way to tell if a variable is defined at macro expansion time.

Right. I may try to modify Arc in this purpose one of these days.

> no magic needed in 'if, in either language :)

Magic definitely sucks :-D!

Thanks a lot CatDancer!

-----