Personally I don't think the whitespace is that much of a problem. Certainly I don't think whitespace makes infix less readable; it probably makes it more readable if anything. And it don't think there is a terribly appreciable difference in typing or reading time because of the extra characters. (Arguably the space bar is the easiest key to hit on the entire keyboard.)
While I wouldn't necessarily miss punctuation characters that much, I don't really think it is worth it just to remove the whitespace from infix expressions. You could interpret +-/* as separate in infix expressions only, but I think that creates unnecessary uniformities in the language.
And I do think that math matters. Maybe there are a lot of areas in which you wouldn't really gain much with the infix notation, but exactly the opposite can be said for other fields. I've been working on simple 2D game in CL, and all the math expressions were getting a bit annoying. I would love to try rewriting it in Arc if Arc ever got bindings to any good game libraries.
Sorry for my repetitiveness (said the same elsewhere) but The Lisp Way when you need a domain-specific syntax is to implement that with a macro and then use the syntax wrapped by the macro. Then Peter does not need to rob Paul (in this case by impoverishing the Arc naming syntax to get math syntax).
If you will simply go without not having whitespace between operators, then you doesn't need to disallow cool characters in symbols or add macro calls in front of all the infix expressions in your code. Honestly, all you save in whitespace you probably spend immediately in having to make the call explicit. I like that the current system integrates infix math seamlessly with s-expressions, that's why I spent my time writing that code. (Admittedly, the infix parts aren't perfect, but the integration itself is fairly seamless.)
I did look at some of the CL infix packages. And if I didn't have programming assignments to work on I might consider porting one.
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.
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"
I think Unix is probably the best choice, because the official distribution is in Unix format and I imagine more people who use Arc use Unix than Windows.
I'm not sure how easy this is to manage in the text editors most people use, though, so it may not be worthwhile specifying it.
I was under the impression cadaver was talking about infix math, because looking in the second position for the functional argument allows infixy syntax analysis.
You could combine it with the dot operator of course but I wouldn't really see a reason for it. (Why would you use 3.+.4 instead of (3 + 4)?)
And actually, the example you gave doesn't quite work (because of quote, you can't actually put a symbol in the functional position using the . operator).
noprocrast mode is supposed to keep you from procrastinating by using the forum. It's probably not so useful here, but it's a carryover from news.yc.
If you turn it on, maxvisit is the maximum session length here. minaway is the minimum time away from the site before you can start a new session. The site'll catch you breaking the rules, but you can continue despite its warning not to.
Don't CL's and Scheme's do allow the user to specify the return value? Maybe this wouldn't necessarily be the case with each, but I think it is correct in spirit to allow the user to control the return value.
Which 1 and 2 are you referring to exactly? The only points I see right now are those in the previous discussion but those don't entirely make sense in view of your comments.
I was really glad when cadaver suggested this solution to infix syntax. I just don't like the look of expressions like
+[*[2; f[x/3]]; y]
even if your syntax allows you to shorten math expressions to (for example)
2*f[x/3]+y
because in my opinion you lose on everything else. But now I'm just rambling....
After a little adventure getting git to work, I added my code to the git repo. (Being new to git, I didn't know you have to add before you can commit, and you have to commit before you can push....)
Everyone feel free to make improvements as you see fit.
Nothing more than that user-code could redefine the arithmetic functions and do exactly the kind of analysis that your infix-eval already does in the core.
infix-eval is like an implicit function that gets added before every number-in-functional-position. If, like the arc1 comment suggests, a literal-in-functional-position gets applied to its first argument (swapped positions), then every infix expression that would have been handled with infix-eval could be handled by the first infix function:
(1 + 2 * 3)
is currently handled like:
([infix-eval] 1 + 2 * 3)
but could also be handled by the first +:
(+ 1 2 * 3)
The + is passed almost exactly the same info as infix-eval, except that has to account for itself being missing from the argument list.
EDIT: This would also take care of the case where you use infix notation within a prefix expression, e.g. (+ 1 2 * 3), which infix-eval would not get the opportunity to handle. Not sure whether that's important though.
Ok, I see what you are saying. It happens that + is already a scheme lambda wrapper around the scheme primitive +, so I guess you'd just modify the existing function. But you would have to add wrappers for the other primitives.
It seems a little strange to me to mix infix and prefix. But I don't see any reason to disallow it.
After a little work I got +-/* to handle infix evaluation themselves, allowing ar-apply to just switch the positions of the first two arguments. This allows user defined operators, but you have to be careful to make a base case for after infix to prefix conversion. For example:
In (3 % 4 + 5), % will get called twice, once to get the initial infix conversion going, and again after the expression has been converted to prefix. So if you don't have the second case, you'll just get into an infinite loop.
I'm still trying to work out what is the best way to allow user-defined precedence. In the above case, (3 % 4 + 5) will evaluate as (% 3 (+ 4 5)) not (+ (% 3 4) 5), because by default it is lowest precedence. I wrote a little set-precedence function that can be called to do the job:
(set-precedence % 2)
or
(set-precedence % *)
(The second version looks up the precedence of * and sets % to that precedence.)
But this method of setting precedence seems a little like a hack. And it doesn't play nicely with =. Any suggestions would be welcome.