
Douglas Philips wrote:
On 2007 Feb 2, at 11:25 PM, Brian Hulley indited:
Apart from the extra possibility for errors (yes I understood that you'd define it to not be an error but this doesn't change the fact that for people who always wrote their tuples using the normal mathematical convention not using an optional trailing comma it would be an error in their code)
Well it would now, but in my proposal it wouldn't be. So it would not make any correct code incorrect.
Of course, but when I said "error" I meant "error with respect to the intentions of the programmer" not "syntax error detected by the compiler". The problem with your proposal is that if optional trailing commas were allowed, if *I* wrote: (1,2,) by mistake, forgetting to add in the last element, the fact that the compiler would now treat the trailing comma as optional means it would now accept the code as being syntactically ok. If *you* wrote that same code, it *would* correspond to what you meant ie just (1,2), for me it would not because I'd have meant to write something like (1,2,3), so for me, instead of a nice simple syntax error I'd get a confusing type error possibly somewhere else in the code therefore my net productivity would be reduced. However a compiler option could be used to switch the optional trailing comma feature on and off and therefore suit everyone.
to go undetected, it would just substitute one inconsistency for another: as Malcolm pointed out the syntax (,,) represents the constructor for a 3-tuple therefore:
let a = (x,y,) -- in your proposal a 2-tuple let b = (,,) x y -- still a 3-tuple with a missing element
Prelude> :t (1,2,) 3 ERROR - Syntax error in expression (unexpected `)') Prelude> :t (1,2,) ERROR - Syntax error in expression (unexpected `)') Prelude>
Again, this would not break existing code, since there is no mechanism for section'd tuples.
What I meant was that the number of commas for a constructor is fixed: always 2 commas means a constructor for a 3-tuple. However you'd now have a choice of how many commas to use when writing out the "sugared" saturated application - either 2 or 3 commas. Which seems inconsistent, since in 5 years time someone used to always writing a pair like: let pair = (1,2,) -- trailing commas now very popular might quite sensibly want to write this as let pair = (,,) 1 2 (since the whole point of the (,,) syntax is that the number of commas is the same as that used when writing out the value in tuple notation) but we can't have a programmer choice when it comes to the constructor: the compiler writer must choose one way or the other. So I don't think there should be a choice in the sugar syntax either. Then if we choose to use (,,) to represent the pair constructor because of the popularity of trailing commas in the applied syntax, this would beg the question of what (,) would represent hence the "spectre" of introducing 1-tuples...
Also, I think in maths the convention is to use commas as separators when writing down coordinates etc.
??? I don't quite get the applicability here...
Perhaps it is not applicable, but I thought a guiding principle of Haskell syntax was to try and stay as close to normal mathematical notation where possible, and I remember learning 2d coordinates in school as (x,y) not (x,y,).
From a personal aesthetic point of view the appearance of a trailing comma is highly irritating to me like passing a shelf in a shop where someone has left a book "unsettled" with the cover twisted over the edge at an annoying angle and some pages crumpled up, that forces me to stop and fix it... :-)
Well, if we're going to bring personal points of view in, it highly pisses me off that in a construct such as: ( expr , expr , expr , expr , expr , ) I have to be vigilant to remove that trailing comma when it is in _no way_ ambiguous.
I know, I find the need to manually delete and insert commas extremely tedious as well. This is why I proposed: #( expr expr as sugar for (expr, expr), because it seems crazy to me that we've got all the machinery in place in the form of the layout rule yet we can only use it for a handful of built in constructs, when everywhere else we still need to juggle with commas and try to make parentheses as invisible as possible eg: bracket_ (enter a) (exit a) (do b c) -- looks like LISP... instead of just: #bracket_ enter a exit a do b c
[snip] I don't think we're ever going to get agreement on apparently irreconcilable personal aesthetics, but perhaps we can apply some principles, such as regularity and consistency and both get what we want?
The #( sugar would only go part of the way to address your proposal since it doesn't address tuples written inline. But a compiler option for allowing the optional trailing comma could be used so that people who prefer the existing syntax (and who might rely on the positive enforcement of "no trailing commas allowed" to catch some of their mistakes) would not be affected. Another possibility would be to allow trailing semicolons in the {;} syntax, then the #( sugar would work - you could just write: #( {a;b;c;}
Regarding import/export lists,... ... (Though the above is obviously too radical a departure for Haskell')
Perhaps too radical? but I like it. I am all for eliminating syntax noise whenever/wherever unambiguously possible, and for making what remains as _regular_ as possible. Sometimes it is the foolish inconsistencies which are the hobgoblins...
I agree. Some particularly warty hobgoblins are: (-1) as opposed to (+1) f (x+3) = g x but not f (x * 3) = g x though a problem with Haskell' is the conflict between the knowledge of these pesky warts and the desire to maintain backwards compatibility with H98, hence we may need to wait till the next major revision to see them finally vanquished. Best regards, Brian. -- http://www.metamilk.com