Arc Forumnew | comments | leaders | submitlogin
5 points by vrk 6158 days ago | link | parent

Is the prefix notation the biggest reason Lisp is not used more? No, I don't think so. Prefix, infix, or postfix is all a matter of what you are used to. It's possible to define the max operator as infix instead of prefix:

  (max 1 2) ; --> 2
  1 max 2   ; --> 2
It's associative (it's easy to prove). And after that you can do the regular stuff:

  1 max 3 max 2 max 5 ; --> 5 
Does this look natural? Usually max is more of a function, or in mathematics one usually writes

  max{ <some set> }
or with set comprehension

  max{ x : <some condition for x> } .
I find infix max easier in pen-and-paper calculations.

Coming back to Lisp and Arc, is familiarity the only reason you want infix math operators? The biggest benefit you get from prefix compared to infix is its regularity and uniformity. Control structures, function calls, and (now in Arc) array and hash table access are all identical. This means you can freely add not only new functions, but new control structures, without hacking the parser and the compiler.

One reason why this happens is that you don't have precedence levels. Precedence is always explicit (bar Arc's new intrasymbol operators, which are infix), and this is why Lisp mathematical functions, such as + and *, accept multiple arguments. The distinction between (+ 1 (+ 2 3)) and (+ (+ 1 2) 3) is useless and even harmful. It's best to write it (+ 1 2 3) or 1 + 2 + 3, because the operation is associative.

Aside from losing this, you also lose the concept that your whole program is a list. This stands at the heart of Lisp macros. How would you write macros for opaque infix blocks?



5 points by almkglor 6158 days ago | link

> Aside from losing this, you also lose the concept that your whole program is a list. This stands at the heart of Lisp macros. How would you write macros for opaque infix blocks?

The solution which dwheeler on the readable-discuss list supports is to simply have the reader translate infix to postfix. Syntax like {1 + 2 + 3} becomes readily translated into (+ 1 2 3). What's more, dwheeler suggests that precedence should not be supported at all: {1 + 2 * 3} is a badly formed expression that the reader will reject, you must use {1 + {2 * 3}}.

-----

1 point by vrk 6158 days ago | link

That's an interesting idea, but on the other hand, if you don't have precedence defined for the common cases, how are infix expressions better than prefix? Does it save typing and cognitive load?

  {1 + {2 * 3}}
  (+ 1 (* 2 3))
Maybe it's a bit clearer, as it's more familiar. Could this be extended to arbitrary two-parameter functions?

  (def foo (x y) ...)
  {x foo y}  ; --> (foo x y)
Why do I ask? Because then we would have a way to write

  ; "Object-oriented" method call
  {object -> method}

  ; Different kinds of assignments, common in C/C++/Java/etc.
  ; (Perhaps of little worth in Arc.)
  {x += 1}
  {x -= 1}
  {x |= bits}

  ; A "binding" operator, or Pascal-like assignment.
  {x := 1}

  ; An arbitrary relation.
  {a R b}

  ; Perl 6 pipe operator [1] look-alike.
  {{data ==> [...]} ==> processed}
[1] http://www.perl.com/pub/a/2003/04/09/synopsis.html?page=2

-----

3 points by almkglor 6158 days ago | link

> Maybe it's a bit clearer, as it's more familiar. Could this be extended to arbitrary two-parameter functions?

This is, in fact, the reason why dwheeler decided to eschew precedence - I kept pestering him that in the future I might want to create a 'convoke operator or some other arbitrarily-named relation. Basically any {_ sym _ [sym _]...} pattern gets converted to (sym _ _ ...)

The problem with supporting precedence is that you have to define it before someone starts mixing up the order of the symbols. And dwheeler wanted to do it at read time, so you had to have fixed precedence at read time. If someone randomly typed {x sym1 y sym2 z}, the reader wouldn't be able to know if it's (sym1 x (sym2 y z)) or (sym2 (sym1 x y) z). Initially we were thinking of supporting only +-*/ precedence and disallow mixing of other operators, but this started to get slippery: where do you draw the line where some operators are allowed to have precedence and others are not?

-----

2 points by jc 6151 days ago | link

This suggestion may be a bit un-Arc, but I'd prefer a "with-infix" macro implementing a well-defined sub-language than I would some kind of integration into the reader. An optional precedence list arg might be a good idea.

The problem there is, of course, that the s-exprs generated by the macro are essentially a black box, but in my thinking, if infix is being used minimally and purely for convenience's sake, it isn't necessary to make those s-exprs accessible to other macros (right?...).

-----