Arc Forumnew | comments | leaders | submitlogin
3 points by rocketnia 4828 days ago | link | parent

But now (call f x) will try to call a macro called f before it looks for the lexical binding.

Hmm... I'm totally guessing, but this might do the trick:

  -(defmacro call(f &rest args)
  +(defmacro call(f &rest args &environment env)
     (cond
  -    ((macp f)   `(,f ,@args))
  +    ((and (symbolp f) (macro-function f env))   `(,f ,@args))
       ((compose-form-p f)   (expand-composition f args))
       (t  `(call-fn (fslot ,f) ,@args))))
If I'm not mistaken, this looks up f in the lexical environment now, so it should also allow 'call to work with lexically scoped macros.

More information about &environment: http://www.ai.mit.edu/projects/iiip/doc/CommonLISP/HyperSpec...



1 point by akkartik 4828 days ago | link

Great idea, thanks!!

But it doesn't seem to quite work:

  $ sbcl
  * (macro-function 'unless)
  #<FUNCTION (MACRO-FUNCTION UNLESS) {1000ADDAB9}>
  * (macro-function 'foo)
  NIL
  * (let ((unless 34)) (macro-function 'unless))
  #<FUNCTION (MACRO-FUNCTION UNLESS) {1000ADDAB9}>
  * (defmacro macp(x &environment env) (macro-function x env))
  MACP
  * (let ((unless 34)) (macp unless))
  #<FUNCTION (MACRO-FUNCTION UNLESS) {1000ADDAB9}>
  * (let ((unless 34)) (macp foo))
  NIL
Hmm, it's possible it'll only work for dynamically generated macros.. Or am I doing something wrong?

-----

1 point by rocketnia 4828 days ago | link

Remember, you're in a lisp-2. Try this:

  (macrolet ((unless() nil)) (macp unless))  ; should be truthy
  (flet ((unless() nil)) (macp unless))      ; should be falsy
Come to think of it, I don't remember what problem we were trying to solve here. XD Functional position won't use regular local variables anyway....

-----

1 point by akkartik 4828 days ago | link

Lol.

I have a macro called call. Given (call f arg), I would like to return:

if f is a local lambda, (call-fn f arg)

if f is a macro, (f arg)

otherwise, (call-fn f arg)

So yes, it probably isn't possible after all..

-----

1 point by rocketnia 4826 days ago | link

Hmm. Maybe you could shoot for two ssyntaxes, so that it's possible to explicitly override whatever the default rules would do:

  f.arg -> (call f arg)
  f@arg -> (f arg)

-----

1 point by akkartik 4826 days ago | link

Yeah, that may be a good option.

-----

1 point by akkartik 4827 days ago | link

http://blog.jayfields.com/2011/02/clojure-and.html

-----