LWN.net Logo

It's a mistake to ignore the customer

It's a mistake to ignore the customer

Posted Dec 6, 2012 15:21 UTC (Thu) by jezuch (subscriber, #52988)
In reply to: It's a mistake to ignore the customer by david.a.wheeler
Parent article: GNU Guile 2.0.7 released

> After all, even 1K BASICs manage to support infix.

What I don't understand is why infix is so important. The only advantage of it I can think of is familiarity; in all other respects it's inferior to prefix and suffix notations. IMVHO, of course, but I think this opinion has a solid basis in reality ;)


(Log in to post comments)

It's a mistake to ignore the customer

Posted Dec 6, 2012 16:10 UTC (Thu) by renox (subscriber, #23785) [Link]

> The only advantage of it I can think of is familiarity; in all other respects it's inferior to prefix and suffix notations.

I agree but familiarity is very important.
So IMHO one interesting middle path for language designers is to respect the familiarity by using infix for "math" expressions and then use prefix or suffix (one or the other not both as C does) for everything else.

Nimrod ( http://nimrod-code.org ) is a bit like this: it has no postfix operators, only prefix and infix.

It's a mistake to ignore the customer

Posted Dec 6, 2012 16:28 UTC (Thu) by david.a.wheeler (guest, #72896) [Link]

The only advantage of (infix) I can think of is familiarity

Yes, the only advantage of infix is that nearly all educated people spend 10 to 18 years in school using infix for all arithmetic work. People who do more math-related things (e.g., programming) tend to have even more experience using infix notations than the average person. Practically all math texts (where you might get useful algorithms) use infix, too. If people spent 10 to 18 years in school exclusively using prefix or postfix instead of infix, and nearly all books used prefix or postfix, they would prefer prefix or postfix instead. But this is not reality.

Are you going to change all schools and math books, worldwide, to use infix? No?

Infix is not going away. And most humans do prefer the familiar.

A programming language is not just for the computer, it's also for the humans. Humans can learn to use prefix, but most humans prefer to use a notation similar to what they've used for 10 or more years. The Fortran developers figured out how to do infix years ago, it's time for Lisp implementations to catch up to the first version of Fortran :-).

It's a mistake to ignore the customer

Posted Dec 6, 2012 21:50 UTC (Thu) by dakas (guest, #88146) [Link]

Yes, the only advantage of infix is that nearly all educated people spend 10 to 18 years in school using infix for all arithmetic work. People who do more math-related things (e.g., programming) tend to have even more experience using infix notations than the average person. Practically all math texts (where you might get useful algorithms) use infix, too. If people spent 10 to 18 years in school exclusively using prefix or postfix instead of infix, and nearly all books used prefix or postfix, they would prefer prefix or postfix instead. But this is not reality.
The reality is that the most popular calculators for engineers have been HP for decades, postfix. According to your rationale, that should have been impossible. Have HP ignored their customers?

It's a mistake to ignore the customer

Posted Dec 7, 2012 5:43 UTC (Fri) by bronson (subscriber, #4806) [Link]

You clearly haven't seen calculator sales this decade or last. TI and Casio have absolutely crushed HP. Both are infix. Coincidence? (maybe, who knows...?)

Don't get me wrong, my HP 48 and RPN rocketed me through 4 years of EE. But most of the other pre-Es in my classes used TI-8x and Casio FX-xxx, I assume partly because they didn't require a tutorial to do the simplest things.

So, be careful rolling out the "most popular among X" argument. Not surprisingly, that almost always supports the infix crowd.

HP calculators

Posted Dec 7, 2012 15:05 UTC (Fri) by david.a.wheeler (guest, #72896) [Link]

I have an HP calculator that uses RPN. I love it.

However, almost no one else I know of can even USE it, nor are they interested in learning how. If I offered the calculator to them, they'd say no thank you, and get a calculator that supports infix instead. Most people will immediately reject something that doesn't support infix today.

It's time to support modern expectations.

It's a mistake to ignore the customer

Posted Dec 6, 2012 17:18 UTC (Thu) by etienne (subscriber, #25256) [Link]

> The only advantage of [infix] I can think of is familiarity

Just to add that the main disadvantage of infix is that you have to introduce operator precedence - and having "*" priority higher than "-" but only when "*" is used as multiply (and not content-of) and only when "-" is the substraction operator (and not a negative number).
Then you overload (in C++) those operator and cannot change the priority of those operators... Language grammar is complex for infix...
None of those problem exist with: prefix "(+ 3 (* 4 2))" or postfix "(3 (4 2)* )+" but infix "3 + 2 * 4" can be really complex (when overloading and not managing numbers).

It's a mistake to ignore the customer

Posted Dec 6, 2012 18:27 UTC (Thu) by vonbrand (subscriber, #4458) [Link]

"Precedence" is a red herring: The precedence of +-*/ is fixed, you can easily place "all others" in one (or two) categories). Yes, C went overboard with its 13 levels; APL went overboard the other way (all operators left associative with the same precedence).

Come on, parsing infix (precedence and all) is ridiculously easy. A nice, top-down parser for C is described in Fraser and Hanson's book on LCC.

It's a mistake to ignore the customer

Posted Dec 7, 2012 7:23 UTC (Fri) by mathstuf (subscriber, #69389) [Link]

I like Haskell's solution: custom defined operators with 10 available precedence levels (I forget exactly, but I remember 10) with the "standard" ones spaced out along it.

It's a mistake to ignore the customer

Posted Dec 7, 2012 9:39 UTC (Fri) by ekj (guest, #1524) [Link]

Isn't that terribly hard to read ?

How do you know what will happen with:

a + b [custom] c * d

Means:

(a+b) [custom] (c * d)

Or:

((a+b) [custom] c) * d

Or:

a + (b [custom] c) * d

It's a mistake to ignore the customer

Posted Dec 7, 2012 16:18 UTC (Fri) by mathstuf (subscriber, #69389) [Link]

Generally, the operators don't work just on numbers and so they don't mix much with the common ones much. Its to establish order within a class of operators (e.g., within the monad operators, arrow operators, and so on). If mathematical expressions tend to get passed in to them, make them lower precedence, otherwise you can play with the higher ones.

It's a mistake to ignore the customer

Posted Dec 7, 2012 10:12 UTC (Fri) by etienne (subscriber, #25256) [Link]

> Come on, parsing infix (precedence and all) is ridiculously easy.

It is not the parsing which is a problem, it is the description of functions.
In pre/post-fix notation, each operator is a function, so you have those functions - thinking in C:
number + ( number, number, ...);
number * ( number, number, ...);
boolean = ( number, number, ...);
boolean < ( number, number, ...);
boolean && ( boolean, boolean, ...);
There is nothing special at all about these functions, compared to any other functions like
boolean print ( ... );

I do not see how you can define a single and simple function type when you use infix, so that in a complex class tree you can derive a class and replace a random function with a simple "addition" or "greater_than". Maybe define a priority for each and every functions? Can this priority change at run-time? at instantiation time?

Note that I am using infix for my programming, so I deal with it...
Note also that I do not want to teach infix to someone writing from right to left, nor do I want to translate mathematics text into these kind of languages...

It's a mistake to ignore the customer

Posted Dec 6, 2012 20:37 UTC (Thu) by neilbrown (subscriber, #359) [Link]

> Just to add that the main disadvantage of infix is that you have to introduce operator precedence

I was thinking exactly the reverse - a significant *advantage* of infix is that it allows the use of precedence to reduce bracket-noise.

Some care is needed in choose the precedence levels of course but it isn't hard if you apply care.

I really do not want to try to write (let along read)

if a + 2 < b*3+1 and c & 4 == 4

in anything but precedence-aware infix notation.

It's a mistake to ignore the customer

Posted Dec 6, 2012 22:08 UTC (Thu) by dakas (guest, #88146) [Link]

I really do not want to try to write (let along read)
if a + 2 < b*3+1 and c & 4 == 4
in anything but precedence-aware infix notation.
Thanks for proving how problematic infix can be. That example does not look like you are aware that == has higher precedence than &. So you are arguing for something beyond your capabilities. How would it look in Scheme as presumably intended?
(if (and (< (+ a 2)
            (+ (* b 3) 1))
         (= (logand c 4) 4))
    ...)

It's a mistake to ignore the customer

Posted Dec 6, 2012 22:22 UTC (Thu) by Cyberax (✭ supporter ✭, #52523) [Link]

Thanks for pointing out stupidity of prefix syntax with your wonderful example of a one-liner turning into 5-liner.

It's a mistake to ignore the customer

Posted Dec 6, 2012 22:48 UTC (Thu) by dakas (guest, #88146) [Link]

It is a 4-liner, and the material corresponding to the one-liner takes 3 lines. If mathematicians preferred minimal line count above readable grouping, why would they use fractions rather than in-line divisions?

It's a mistake to ignore the customer

Posted Dec 6, 2012 23:09 UTC (Thu) by Cyberax (✭ supporter ✭, #52523) [Link]

Because paper is a bit different medium and by using vertical layout it's possible to present information more efficiently?

It's a mistake to ignore the customer

Posted Dec 6, 2012 23:54 UTC (Thu) by nybble41 (subscriber, #55106) [Link]

> (if (and (< (+ a 2) (+ (* b 3) 1)) (= (logand c 4) 4)) ...)

> if (a + 2 < b * 3 + 1 && (c & 4) == 4) {...}

At 56 characters, not counting the ellipsis, the Scheme example fits easily into one line. Personally, I would probably have split it across two lines in either language, but to each his own. Granted, the corrected C version is only 42 characters, but that is offset by the need to remember the precedence of each operator, and you just demonstrated how difficult that can be. The fully parenthesized C version

> if (((a + 2) < ((b * 3) + 1)) && ((c & 4) == 4)) {...}

is 52 characters, which isn't much shorter (or more readable) than the Scheme code.

It's a mistake to ignore the customer

Posted Dec 7, 2012 0:08 UTC (Fri) by Cyberax (✭ supporter ✭, #52523) [Link]

Nobody writes 2*3+1 as (2*3)+1 - everybody remembers THAT precedence rule.

So we realistically have: "if ((a+2 < b*3+1) && ((c&4) == 4)))" or 27 non-whitespace symbols. That's more compact and easier to understand.

And most people remember precedence rules of logical operators, so we have: "if (a+2 < b*3+1 && (c&4) == 4)" or 23 symbols.

Also, infix order has nice feature - it allows me to group relevant operations with whitespaces, with little "graphical" overhead.

It's a mistake to ignore the customer

Posted Dec 8, 2012 9:57 UTC (Sat) by nix (subscriber, #2304) [Link]

everybody remembers THAT precedence rule
I have fixed multiple bugs over the years caused by people thinking that + had higher precedence than *, or that C was strict left- or even right-associative. Yes, anyone with half a clue knows otherwise: but not every developer, alas, has half a clue to spare.

It's a mistake to ignore the customer

Posted Dec 8, 2012 13:51 UTC (Sat) by paulj (subscriber, #341) [Link]

Also, clue level can vary significantly, even with a fixed, given programmer. E.g. regular diurnal patterns (pre-coffee, post-lunch, pre-knocking-off-time), when extremely tired at the end of a too-long hacking session, or even programming while drunk. :)

It's a mistake to ignore the customer

Posted Dec 12, 2012 13:45 UTC (Wed) by HelloWorld (guest, #56129) [Link]

The solution to that isn't dumbing down the language but firing people who don't have half a clue.

It's a mistake to ignore the customer

Posted Dec 13, 2012 11:39 UTC (Thu) by dakas (guest, #88146) [Link]

The solution to that isn't dumbing down the language but firing people who don't have half a clue.
Scheme is the ultimately dumbed-down language for the computer, to the degree that it does not require a parser for interpreting, just an expression reader and an evaluator.

It is similarly dumbed-down to the human reader as commerce/Pidgin English is, meaning that it takes practice and control to consistently dumb down in the right manner. The purpose is having a common language for talking about programs shared between human and computer.

Using infix in Scheme is like Yodish Pidgin English. Sort of defeats the original purpose of human and computer sharing a language for talking about code rather than humans expressing themselves to one another.

It's a mistake to ignore the customer

Posted Dec 13, 2012 11:55 UTC (Thu) by mpr22 (subscriber, #60784) [Link]

What a wonderful instance of "Humans can do the work, so machines have time to think."

It's a mistake to ignore the customer

Posted Dec 13, 2012 17:26 UTC (Thu) by HelloWorld (guest, #56129) [Link]

> Scheme is the ultimately dumbed-down language for the computer,
No, it's not. As you were told multiple times by now, Scheme already has syntactic sugar for multiple constructs. 'x is (quote x), and (quote x) is (quote . (x . ())).

> Using infix in Scheme is like Yodish Pidgin English. Sort of defeats the original purpose of human and computer sharing a language for talking about code rather than humans expressing themselves to one another.
No, it doesn't. What makes Lisp Lisp is the ability to easily represent a program in the language's primary data structure and manipulate it. Infix syntax doesn't change that, it just makes things more readable. Again, you were told this multiple times, so I don't even know why I repeat it again. It's really a waste of time to argue with a stick-in-the-mud like you.

It's a mistake to ignore the customer

Posted Dec 13, 2012 18:38 UTC (Thu) by viro (subscriber, #7872) [Link]

Not quite. The problem, in a sense, is that the structure chosen for representing program makes sense for optimizing interpreter a bit, at the cost of being very unnatural. Subtrees are not subexpressions. Sure, that way you avoid digging in to find the node where you'll be doing reduction, but that doesn't come for free. As the matter of fact (and you damn well know that, seeing that you seem to be familiar with e.g. Haskell), the things can be done the other way round - with APPLY being the fundamental primitive and CONS expressed via it. The same "easily represent program in the language's primary data structure" thing holds for a lot more than just LISP, e.g. when the primary data structure *is* partially evaluated expression. That's not what makes LISP LISP; neither is the syntax, of course.

It's a mistake to ignore the customer

Posted Dec 7, 2012 0:22 UTC (Fri) by neilbrown (subscriber, #359) [Link]

> That example does not look like you are aware that == has higher precedence than &.

Sorry, but what language did you think I was using? Given that I used "and" and did not include () around the condition of the 'if', it certainly wasn't C. (It is missing a ':' at the end - sorry about that).

Much as I like C, it clearly got some precedence issues wrong. More modern languages do a much better job.

It's a mistake to ignore the customer

Posted Dec 7, 2012 7:21 UTC (Fri) by mathstuf (subscriber, #69389) [Link]

To be fair, there is a define for 'and' to '&&' in commonly included C headers (I forget which exactly). And since there's LISP floating around, parentheses sort of fade into the background after enough programming in it, so the error(s) made aren't completely obvious. The colon probably would have helped :) .

C alternative tokens

Posted Dec 7, 2012 16:42 UTC (Fri) by dtlin (✭ supporter ✭, #36537) [Link]

#include <iso646.h>
defines macros for C.  They're in C++ by default.

Precedence

Posted Dec 7, 2012 17:16 UTC (Fri) by david.a.wheeler (guest, #72896) [Link]

Poster said:

Just to add that the main disadvantage of infix is that you have to introduce operator precedence

No you don't. Infix means the operator is between the operands, that's all.

Precedence can a lot of create problems, and the SRFI-105 has a very simple solution: No built-in precedence. You can still have precedence, though. If you use multiple operations that require precedence, the whole expression is changed to "($nfx$ ...)". You can then define "$nfx$" to do whatever you want.

SRFI-105 contains a detailed rationale about its approach to precedence.

In practice, {3 - {4 * 5}} isn't hard to read at all, and sure beats (- 3 (* 4 5)).

It's a mistake to ignore the customer

Posted Dec 6, 2012 18:33 UTC (Thu) by dlang (✭ supporter ✭, #313) [Link]

> What I don't understand is why infix is so important. The only advantage of it I can think of is familiarity

this attitude (that familiarity doesn't matter) is a major problem infecting current Linux userspace development. Gnome, Systemd, Unity, Wayland, (KDE4 to a much lesser degree) are all doing things that assume that familiarity with the existing stuff doesn't matter and that anyone who objects is just a stick-in-the-mud who needs to get with the times.

It's hard to overstate the value of familiarity. Even if the existing tools are inefficient, if they are familiar to people, it can be really bad to change them.

outside of software, one common example is the DORVAK vs QWERTY keyboard debate. Some people argue that DORVAK is significantly better (I'm not one of them by the way), but QWERTY remains dominant, even in things like phone on-screen keyboards, for the simple reason that it's familiar to people.

It's a mistake to ignore the customer

Posted Dec 7, 2012 17:48 UTC (Fri) by sorpigal (subscriber, #36106) [Link]

Familiarity is a huge advantage that ought to outweigh almost anything. If, in the end, you have to spend a lot of time to understand how to write what you want, more time to read what you have written and even more time to read what someone else wrote, then you have consumed enormous amounts of time that could have been spent doing the actual work of telling the computer what to do. The time and attention of a developer is the single most valuable resource when developing just about any software today. Anything which decreases the amount of time it takes to understand a piece of code (whether writing or reading) increases productivity, all else being equal. It adds up.

maybe not only familiarity

Posted Dec 7, 2012 20:57 UTC (Fri) by tpo (subscriber, #25713) [Link]

People in support of infix in this thread are using "familiarity" as an argument whereas critics are arguing that infix is *one* aspect of the Scheme language that you have to familiarise yourself with.

I'd like to propose that infix (maybe as well as prefix) as a way of thinking and understanding may be rooted in the human brain itself.

I've just read the "DCI manifesto" on Artima, where the authors are arguing that humans are understanding in terms of things and behaviors. Consequently they propose to model "things" and "behaviors" separately.

As a functional language Scheme would be on the outmost "behavior" side of the possible spectrum. Under the above stated theory it would be a compliment to the human brain that it *is* able to manipulate a symbolic problem representation that is very much focused on only one side of "things and behaviors". On the other hand it would hint to why prefix notation is hard to handle for humans - it supposedly simply doesn't match the "natural" way a brain works.

I'm completely ignorant about that topic and respective research and as such could be completely wrong, however I think we should not stop our thinking at the relatively trivial "familiarity" argument but ask whether the problem could be rooted deeper than that.

[1] "The DCI Architecture: A New Vision of Object-Oriented Programming"
http://www.artima.com/articles/dci_vision.html

maybe not only familiarity

Posted Dec 10, 2012 8:38 UTC (Mon) by jezuch (subscriber, #52988) [Link]

> On the other hand it would hint to why prefix notation is hard to handle for humans - it supposedly simply doesn't match the "natural" way a brain works.

At best it's hard to handle for speakers of SVO languages. It's like arguing that Arabic (a VSO language, equivalent to prefix notation) or Japanese (a SOV language, equivalent to suffix notation) are "hard to handle" and "don't match the natural way a brain works". Try telling that to the Arabs and Japanese ;)

maybe not only familiarity

Posted Dec 10, 2012 9:24 UTC (Mon) by tpo (subscriber, #25713) [Link]

I'm not familiar with VSO languages: do they also, as Scheme does, put *all* verbs at the start of the sentence in case of nested statements? As in:

(do (another_do (yet_another_do (and_more_do (and_still_more_do arg arg

aka

verb1 verb2 verb3 verb4 verb5 subject1 object 1 subject2 object2 object2a

I honestly do not know, but I'd guess even a VSO language will not work that way as opposed to Lisp'ish languages?

maybe not only familiarity

Posted Dec 10, 2012 17:06 UTC (Mon) by nybble41 (subscriber, #55106) [Link]

Deeply nested expressions are a problem in any language, moreso in natural languages which are not traditionally formatted to highlight the subexpressions. If you find yourself writing such expressions in Scheme, you may want to look into refactoring the code, or at least taking advantage of the "nest" macro to flatten the expression. An example:

(do arg1
    (another_do
      (yet_another_do
        (and_more_do arg2
                     (and_still_more_do arg3 arg4)))))

is equivalent to:

(nest [(do arg1)
       (another-do)
       (yet-another-do)
       (and-more-do arg2)
       (and-still-more-do arg3)]
  arg4)

Copyright © 2013, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds