Arc Forumnew | comments | leaders | submitlogin
2 points by almkglor 4188 days ago | link | parent

Idea: define-for-syntax

Looking through how Chicken compiler works, it seems that Chicken detects syntax-case and friends, performing them at compile-time, However if a macro needs to use a function, the function should be defined using define-for-syntax. Perhaps our rules for macros:

1. Should be defined using 'mac

2. Any form that has a 'mac will be executed at compile-time, with the 'mac transformed to a macro definition:

  (let internal-fun
       (fn (x) `(foo ,x))
    (mac my-macro (z)
      (internal-fun z)))
3. Any functions that need to be used directly by macros must be added either in a 'let form like the above, or defined using 'def-syn.

Idea: Library

We probably need some sort of library system, like the part which handles 'ccc: add it only if it's needed, otherwise leave it out.

Hmm.

Idea: optional and varargs

It seems to me that optional variables might be implementable as varargs forms. Not sure though.

  (fn (foo (o niaw nil) (o grr niaw))
   (body foo niaw grr))

  =>

  (fn (foo . gs42)
    (with (niaw (if gs42 (car gs42) nil)
           gs42 (cdr gs42))
      (with (grr (if gs42 (car gs42) niaw)
             gs42 (cdr gs42))
        (body foo niaw grr))))
So all we need is to implement var-args, and special-case optional variables as above.


2 points by binx 4188 days ago | link

An extra hash argument can implement both optional and named args. Representing optional args as varargs would complicate the source transformation when they are used simultaneously in the same function.

-----

2 points by almkglor 4188 days ago | link

Not really:

  (fn (niaw (o hmm) . rest)
    (body niaw hmm rest))

  =>

  (fn (niaw . gs42)
    (with (hmm (if gs42 (car gs42) nil)
           gs42 (cdr gs42))
      (let rest gs42
        (body niaw hmm rest))))
It's not at all complicated: just make the last argument take the value of your temporary rest argument. Edit: This is what I did in creating the p-m macro, and it works.

I'm not sure how adding an extra hash would work well if I might pass several different functions, with different optarg names:

  (set p1
    (fn (hmm (o niaw))
      (body hmm niaw)))
  (set p2
    (fn (hmm (o arf))
      (body hmm arf)))
  (set p3
    (fn rest
      (body rest)))
  ((if (something)
       p1
     (something-else)
       p2
       p3)
  1 42)
Edit: My approach appears to be somewhat similar to what pg did in the Scheme version - cref ac-fn, ac-complex-fn, ac-complex-args, ac-complex-opt in ac.scm

Since code is spec (grumble) I think it might be better to follow mostly what pg did, although I dunno, not sure ^^. How can passing in a hash table seamlessly emulate the same functionality while improving performance?

-----

1 point by binx 4188 days ago | link

The define-for-syntax form is just a sub-feature of CL's eval-when, why don't us give a full eval-when support?

-----

1 point by almkglor 4188 days ago | link

Hmm. I'll think about that.

eval-when would be used, I think, only to differentiate between compile-time and run-time. It's not a part yet of ArcN. Hmm. Lemme think more deeply about this.

Edit: This seems like a good idea ^^

-----