Arc Forumnew | comments | leaders | submitlogin
1 point by greatness 6098 days ago | link | parent

IF is a macro because you don't always want to evaluate all of it's arguments...


3 points by kens 6098 days ago | link

I don't want to be pedantic, but 'if' is a special form and not a macro:

  arc> if
  Error: "reference to undefined identifier: _if"
  arc> and
  #3(tagged mac #<procedure>)
It's the basis for other "partial evaluation" macros.

My foundation documentation (http://arcfn.com/foundation-doc.html) lists the special forms.

-----

2 points by greatness 6097 days ago | link

err, I was refering to the way it executed. I believe On Lisp implemented an if macro.

-----

2 points by Darmani 6096 days ago | link

A conditional such as if can only be implemented as a macro if it expands to another conditional such as cond, which must be implemented as a special form.

In Arc, if is just a special form.

-----

3 points by absz 6096 days ago | link

I think the logic is to make if a "primitive macro," the way + is a primitive function. Just as you can't define + in terms of Arc functions, you can't define if in terms of Arc macros. Nevertheless, (isa + 'fn), and so the thinking is that (isa if 'mac) makes sense.

There are valid reasons not to do things this way, of course. For instance, what's so powerful about macros is that they literally expand into a code tree, which (as you observed) if can't do. For that reason, why not have (isa if 'form) (or 'prim, or 'special, or something similarly descriptive)? Then you have first-class special forms without literally making them macros. This would be a big improvement over the current state of affairs:

  arc> (type if)
  Error: "reference to undefined identifier: _if"

.

-----

1 point by mecon 6096 days ago | link

That's what i meant.

-----

1 point by zxquarx 6096 days ago | link

If can be implemented as a primitive function instead of a special form given the fn operator. It could take three arguments: a condition, a then function, and an else function and then call the appropriate function. An example implementation is:

(def if2 (cond then else) (if cond (then) (else)))

If2 would be given as a primitive function and its implementation would be hidden like that of cons is. Given access to if2, a basic if construct is:

(mac basic-if (cond then (o else)) `(if2 ,cond (fn () ,then) (fn () ,else)))

This would make code walkers easier because they wouldn't have to know about as many special forms.

-----