Arc Forumnew | comments | leaders | submitlogin
1 point by cadaver 6122 days ago | link | parent

Since a number-in-functional-position introduces a context for its own s-expression (not for any of its sub-expressions), it would be possible to expand intrasymbol arithmetic, much like with the . and ! notations, only in infix-context.

  (1 + x/y        ;expanded: x / y
   + (w/bar func) ;not expanded, function call
This would effectively keep you from referring to any symbols that contain arithmetic operators from infix-context, but maybe this is not really such a problem.

For this to work you'd need truly first-class macros, since it is not possible to definitely detect infix-context at compile-time:

  (1 + x/y)           ;infix, but may be subject to macro expansion
  ((sqrt 16)*4 + x/y) ;need to decide at runtime
Being able to work with symbols, instead of the functions they are bound to, would also be better for precedence analysis, since infix is essentially a visual thing.


1 point by eds 6122 days ago | link

Possibly. But you still need whitespace in the first position in the call or Arc will try to evaluate the variable a+b rather than the expression (+ a b).

As for precedence analysis, you need some evaluation to happen in order to know that the object in the functional position is a number, after which all your symbols representing functions have been evaluated too.

But even if you did manage to get a hold of the symbols, you would have to make arbitrary decisions about what is an operator and what is a function. (Unless you start evaluating stuff, which gets us back to where we started.) For example, even though expt isn't defined as an operator in the current version, this expression still works:

  (2 expt 3)
You might not get proper precedence when using it like this, but at least it is interpreted correctly as a function.

-----

2 points by cadaver 6122 days ago | link

Regarding infix context

True, (a+b) has no infix context, havn't thought about that; seems not such a good idea after all.

--

Regarding symbol precedence

Getting hold of the symbols: it's the same with macros, you need some evaluation to happen to know that the object in the functional position is a macro. That's why I said truly first-class macros; the functional position is evaluated first and only then a decision is made to either evaluate the already compiled form in the case of a function call, or to macro-expand the uncompiled form in case of a macro expansion.

Arbitrary decisions about operator/function: macros have all the power, you can handle precedence exactly like in your current system, but get the precedence information by looking up a table with the symbols as keys. This will work exactly the same for functions and yield more predictable precedence for operators.

On the other hand, I'd prefer that functions with undefined precedence were forbidden wherever precedence matters, because it's very easy to unwittingly redefine a function that has precedence defined for it. By itself, (2 expt 3) is fine; no precedence handling necessary.

Think of it as: infix-functions make precedence invisible (masked through the binding, you see the symbol not the function); infix-symbols make precedence obvious.

EDIT: Actually, you wouldn't need first-class macros, if you could redefine "fn" and "set" to handle specially all functions that get bound/assigned to symbols that have some precedence defined for them.

There seems to be some difficulty doing this in arc1; "fn" and "set" are kind of special:

  arc> set
  Error: "reference to undefined identifier: _set"
  arc> fn
  Error: "reference to undefined identifier: _fn"

-----