Arc Forumnew | comments | leaders | submitlogin
1 point by shader 6003 days ago | link | parent

Aren't the "only" differences between macros and functions the time of evaluation, the fact that they don't evaluate arguments, and the fact that they return code to be evaluated instead of a value?

What if we made those traits optional modifiers, similar to the * shown here, so that the programmer would have complete control over how the function operated? Then we could make functions that return code, but evaluate arguments, or avoids argument evaluation but returns a value, etc. And we could flag our functions to say whether they should be evaluated at compile time, or only at run time.

Any common patterns of modifiers could be abstracted by a "macro." So a function that ran at compile time, didn't eval args, and returned code, would be "(mac," whereas a function that evaluated arguments, returned a value, and ran at run time would be "(def" etc. etc. We could make more for other varieties of functions.

This doesn't make code shorter necessarily, but gives greater flexibility when defining functions.

Now, what did I forget that makes this obviously a bad idea?

If I understand it right, the [] syntax requires a function of a certain signature. Interesting idea.



1 point by almkglor 6003 days ago | link

> Now, what did I forget that makes this obviously a bad idea?

Interesting, so we can get something that runs at compile time, evals the args (which we presumably evaluate in the runtime environment) and returns a value.

Oh, you can't get the runtime environment at compile time yet? Hmm.

> If I understand it right, the [] syntax requires a function of a certain signature. Interesting idea.

No, it transforms it to a function with that signature:

  (defho foo ([hmm (it)])
    hmm)
  =>
  (mac foo (hmm)
    `(foo-internal (fn (it) ,hmm)))
  (def foo-internal (hmm)
    hmm)

  (macex '(foo it))
  =>
  (foo-internal (fn (it) it))

-----

1 point by shader 6003 days ago | link

lol, I realize that you could try and apply those three at the same time, but the "compile time" modifier was supposed to be used by the programmer to tell arc that it was safe to do just such a thing. Other wise, it would be evaluated at run time. So while you could use those three at once, it would like you say have an undefined consequence.

Basically, I thought that it might be useful to have functions that didn't eval all their args. At that point, they're only a few steps away from macros, and I thought it would be cool if we could unify them.

>transforms to a function Just shows I didn't understand it right. :) That makes more sense, but I'm still not sure I understand it. Oh well.

Does your p-m:def support matching based on function sigs?

-----

1 point by almkglor 6003 days ago | link

> Basically, I thought that it might be useful to have functions that didn't eval all their args.

  (def foo-internal (x y z)
    (do-something x y z))

  (mac foo (x y z)
    ; eval x, don't eval y, eval z
    `(foo ,x ',y ,z))
> Does your p-m:def support matching based on function sigs?

Yes, although I'm not sure I quite understand what you're asking.

For example factorial works out like this:

  (p-m:def factorial
    "a factorial function"
    (1)  1
    (N)  (* N (factorial:- N 1)))

-----

1 point by shader 6003 days ago | link

Actually, what I meant by match on function sigs was: while writing a higher order function that wants a function as an input, can you require that it be a function that's signature implies one var, two vars, a list etc?

As to the non-evaling functions, I suppose we could have a macro that defined a macro / function combination; the resulting macro would expand into a call to the function with ' before each item in the arg list.

Oh, and I think that `(foo ,x ... is supposed to be `(foo-internal ,x ... Otherwise you have an infinitely recursive macro. :)

-----

1 point by almkglor 6003 days ago | link

> can you require that it be a function that's signature implies one var, two vars, a list etc?

Nope ^^

> Oh, and I think that `(foo ,x ... is supposed to be `(foo-internal ,x ... Otherwise you have an infinitely recursive macro. :)

Yep ^^

-----