Re: [Haskell-cafe] Fractional/negative fixity?

Hello Dan, Saturday, November 4, 2006, 5:07:15 AM, you wrote:
Here's an idea that (I think) is useful and backwards compatible: fractional and negative fixity.
yes, i think the same. for example, once i've tried to define postfix 'when' operator like those in perl/ruby print msg `on` mode==debug but failed because my code frequently contains '$' and there is no way to define operation with a lower precedence really, there is another alternative to solve my particular problem: make `op` applications having fixed -1 precedence. such applications look "heavyweight" and once i have a wonderful debugging story just because for my eyes it was obvious that (a `div` b+1) means "do add before div" -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com

haskell-prime-bounces@haskell.org wrote:
Hello Dan,
Saturday, November 4, 2006, 5:07:15 AM, you wrote:
Here's an idea that (I think) is useful and backwards compatible: fractional and negative fixity.
yes, i think the same. for example, once i've tried to define postfix 'when' operator like those in perl/ruby
print msg `on` mode==debug
but failed because my code frequently contains '$' and there is no way to define operation with a lower precedence
really, there is another alternative to solve my particular problem: make `op` applications having fixed -1 precedence. such applications look "heavyweight" and once i have a wonderful debugging story just because for my eyes it was obvious that (a `div` b+1) means "do add before div"
I'd support fractional and negative fixity. It's a simple change to make, but we also have to adopt http://hackage.haskell.org/cgi-bin/haskell-prime/trac.cgi/wiki/FixityResolut... I've added the proposal to the end of that page. In fact, the page already mentioned that we could generalise fixity levels, but it didn't mention fractional or negative values being allowed. Cheers, Simon

On Tue, 7 Nov 2006, Simon Marlow wrote:
I'd support fractional and negative fixity. It's a simple change to make, but we also have to adopt
http://hackage.haskell.org/cgi-bin/haskell-prime/trac.cgi/wiki/FixityResolut...
I've added the proposal to the end of that page. In fact, the page already mentioned that we could generalise fixity levels, but it didn't mention fractional or negative values being allowed.
Maybe that page could also mention earlier proposals and the solutions without precedence numbers. I prefer the non-numeric approach with rules like "(<) binds more tightly than (&&)", because it says what is intended and it allows to make things unrelated that are unrelated, e.g. infix operators from different libraries. Consequently a precedence relation to general infix operators like ($) and (.) had be defined in each library.

Henning Thielemann wrote:
On Tue, 7 Nov 2006, Simon Marlow wrote:
I'd support fractional and negative fixity. It's a simple change to make, but we also have to adopt
http://hackage.haskell.org/cgi-bin/haskell-prime/trac.cgi/wiki /FixityResolution
I've added the proposal to the end of that page. In fact, the page already mentioned that we could generalise fixity levels, but it didn't mention fractional or negative values being allowed.
Maybe that page could also mention earlier proposals and the solutions without precedence numbers. I prefer the non-numeric approach with rules like "(<) binds more tightly than (&&)", because it says what is intended and it allows to make things unrelated that are unrelated, e.g. infix operators from different libraries.
This is a much more heavyweight change, and its not a clear win. Yes I agree that in some ways it's strange to enforce a total order between unrelated things, but on the other hand it's very convenient, and easy to understand. Currently the default fixity is infixl 9. That is, if you don't declare a fixity, you automatically get a fixity that can be used relative to every other operator. This is quite useful - I bet if we made it mandatory to declare all the relative fixities then we'd need to add fixity declarations to lots of code. I forsee this being quite tiresome. If you'd like to make a concrete proposal, then feel free to do so and I'll make sure it gets onto the wiki. Cheers, Simon

On Tue, 7 Nov 2006, Simon Marlow wrote:
This is a much more heavyweight change, and its not a clear win.
Haskell 2 ? :-)
If you'd like to make a concrete proposal, then feel free to do so and I'll make sure it gets onto the wiki.
What about the one of Jón Fairbairn ? http://www.haskell.org/pipermail/haskell-cafe/2006-October/018925.html

On 2006-11-07 at 18:30+0100 Henning Thielemann wrote:
On Tue, 7 Nov 2006, Simon Marlow wrote:
This is a much more heavyweight change, and its not a clear win.
Haskell 2 ? :-)
If you'd like to make a concrete proposal, then feel free to do so and I'll make sure it gets onto the wiki.
What about the one of Jón Fairbairn ? http://www.haskell.org/pipermail/haskell-cafe/2006-October/018925.html
The proposal to which that message refers was made before Haskell really existed: we didn't know the concrete syntax of the language, so I used arbitrary keywords. Even if we look at Phil Wadler's subsequent tidying up of it, I'm not at all sure how it fits with the language as it stands now. So while it might make a reasonable starting point, I don't think it yet counts as a concrete proposal! I must say though, that I don't like the reasoning that we can put in fractional fixities because it's a small change. The way to hell is through a series of small steps. If using integers to express fixities is a bit of a hack, switching to rational numbers is a hack on top of a hack. Jón -- Jón Fairbairn Jon.Fairbairn at cl.cam.ac.uk

On 07/11/06, Jon Fairbairn
I must say though, that I don't like the reasoning that we can put in fractional fixities because it's a small change. The way to hell is through a series of small steps. If using integers to express fixities is a bit of a hack, switching to rational numbers is a hack on top of a hack.
Well, It's a _conceptually_ simple idea, one that doesn't make understanding the language much harder. Also, it provides an infinite space for fixities. I think the problem 'binds tighter than X but not as tight as Y', where X and Y are only fixity integer apart is somewhat common, and this would fix it. It would allow for extensibility into the future, where the operator space will only become more dense, and maintaining a complete order with only 10 integers to play will become more and more difficult. Allowing an infinite amount of operators to come between any two operators sounds like a solid design decision to me. -- -David House, dmhouse@gmail.com

David House schrieb:
Also, it provides an infinite space for fixities. I think the problem 'binds tighter than X but not as tight as Y', where X and Y are only fixity integer apart is somewhat common, and this would fix it. It would allow for extensibility into the future, where the operator space will only become more dense, and maintaining a complete order with only 10 integers to play will become more and more difficult. Allowing an infinite amount of operators to come between any two operators sounds like a solid design decision to me.
Yes, but allowing simply to specify some ordering relationship to existing operators is an even more solid one. Fractional fixities are overspecification, and this can hurt in scenarios like this one: Developer A creates an operator with this fixity declaration: infixl 6.25 +* Developer B has this: infixl 6.75 *+ (They don't use 6.5 because each has another operator at 6.5 already.) Now when some developer mixes +* and *+ in the same expression, the compiler will automatically assign a relative priority for the two operators, even though it's not at all clear whether the two operators have any relative precedence - it would be far preferable if the compiler simply declared nonpriority and emitted an error, forcing the programmer to clearly state what priorities he had in mind when writing down the expression. I know the above example is a bit far-fetched. And it's not a really important issue anyway. Regards, Jo

On Tue, 7 Nov 2006, David House wrote:
On 07/11/06, Jon Fairbairn
wrote: I must say though, that I don't like the reasoning that we can put in fractional fixities because it's a small change. The way to hell is through a series of small steps. If using integers to express fixities is a bit of a hack, switching to rational numbers is a hack on top of a hack.
Well, It's a _conceptually_ simple idea, one that doesn't make understanding the language much harder.
Also, it provides an infinite space for fixities. I think the problem 'binds tighter than X but not as tight as Y', where X and Y are only fixity integer apart is somewhat common, and this would fix it.
In school we learnt "dot operations (multiplication, division) bind more tightly than dash operations (addition, subtraction)". I imagine we would have learnt "dot operations have precedence 7, dash operations have precedence 6". :-)

Henning Thielemann wrote:
On Tue, 7 Nov 2006, Simon Marlow wrote:
I'd support fractional and negative fixity. It's a simple change to make, but we also have to adopt
http://hackage.haskell.org/cgi-bin/haskell-prime/trac.cgi/wiki/FixityResolut...
I've added the proposal to the end of that page. In fact, the page already mentioned that we could generalise fixity levels, but it didn't mention fractional or negative values being allowed.
Maybe that page could also mention earlier proposals and the solutions without precedence numbers. I prefer the non-numeric approach with rules like "(<) binds more tightly than (&&)", because it says what is intended and it allows to make things unrelated that are unrelated, e.g. infix operators from different libraries. Consequently a precedence relation to general infix operators like ($) and (.) had be defined in each library.
I think that computable real fixity levels are useful, too. A further step to complex numbers is not advised because those cannot be ordered. But to be serious, the non-numeric rule based approach yields lattice-valued fixity levels. If we use a CPO, we gain ultimate expressiveness by being able to express fixity levels as fixed points of continuous functionals! Regards, apfelmus

On Nov 7, 2006, at 11:47 , apfelmus@quantentunnel.de wrote:
Henning Thielemann wrote:
On Tue, 7 Nov 2006, Simon Marlow wrote:
I'd support fractional and negative fixity. It's a simple change to make, but we also have to adopt
http://hackage.haskell.org/cgi-bin/haskell-prime/trac.cgi/wiki/ FixityResolution
I've added the proposal to the end of that page. In fact, the page already mentioned that we could generalise fixity levels, but it didn't mention fractional or negative values being allowed.
Maybe that page could also mention earlier proposals and the solutions without precedence numbers. I prefer the non-numeric approach with rules like "(<) binds more tightly than (&&)", because it says what is intended and it allows to make things unrelated that are unrelated, e.g. infix operators from different libraries. Consequently a precedence relation to general infix operators like ($) and (.) had be defined in each library.
I think that computable real fixity levels are useful, too. A further step to complex numbers is not advised because those cannot be ordered.
But ordering of the computable reals is not computable. So it could cause the compiler to loop during parsing. :) -- Lennart

On Tuesday 07 November 2006 17:32, Lennart Augustsson wrote:
On Nov 7, 2006, at 11:47 , apfelmus@quantentunnel.de wrote:
Henning Thielemann wrote:
On Tue, 7 Nov 2006, Simon Marlow wrote:
I'd support fractional and negative fixity. It's a simple change to make, but we also have to adopt
http://hackage.haskell.org/cgi-bin/haskell-prime/trac.cgi/wiki/ FixityResolution
I've added the proposal to the end of that page. In fact, the page already mentioned that we could generalise fixity levels, but it didn't mention fractional or negative values being allowed.
Maybe that page could also mention earlier proposals and the solutions without precedence numbers. I prefer the non-numeric approach with rules like "(<) binds more tightly than (&&)", because it says what is intended and it allows to make things unrelated that are unrelated, e.g. infix operators from different libraries. Consequently a precedence relation to general infix operators like ($) and (.) had be defined in each library.
I think that computable real fixity levels are useful, too. A further step to complex numbers is not advised because those cannot be ordered.
But ordering of the computable reals is not computable. So it could cause the compiler to loop during parsing. :)
-- Lennart
Ha! Well, as long as we're being pedantic, surely we wouldn't need any set larger than the rationals (which does have a decidable ordering)? Also, since I'm commenting anyway, I rather like the idea of specifying operator precedences via a partial order. However, I also feel that there needs to be some work done to make sure there aren't gremlins hiding in the details. Has anyone worked out the theory on this? How does associating to the right vs left play into the picture? How does it fit into the parsing technology? -- Rob Dockins Talk softly and drive a Sherman tank. Laugh hard, it's a long way to the bank. -- TMBG

On Nov 7, 2006, at 5:49 PM, Robert Dockins wrote: [On operator precedence]
Ha! Well, as long as we're being pedantic, surely we wouldn't need any set larger than the rationals (which does have a decidable ordering)?
Also, since I'm commenting anyway, I rather like the idea of specifying operator precedences via a partial order. However, I also feel that there needs to be some work done to make sure there aren't gremlins hiding in the details. Has anyone worked out the theory on this? How does associating to the right vs left play into the picture? How does it fit into the parsing technology?
Actually, we *do* use a DAG on operator precedence in the Fortress programming language (my day job). Our goal is to require parentheses when it is not blatantly obvious what is going on (eg because we're using operators from two libraries written in isolation). We can only use operators together in an expression without parentheses if there is an edge between them in the graph. Graph nodes are sets of operators with the "same" precedence (eg addition and subtraction). Among other things this means that if ++ has higher precedence than ==, and == has higher precedence than &&, we can't necessarily mix ++ and && in the same expression without parentheses. That said, this would be a pretty big change for Haskell, and would break existing code unless you somehow wired in the transitive closure of all the existing operators. As another message in this discussion (from Simon M?) mentioned, you might want to be able to specify the relationship between operators imported from different modules, because you *do* know that a well-known relationship exists. -Jan-Willem Maessen
-- Rob Dockins
Talk softly and drive a Sherman tank. Laugh hard, it's a long way to the bank. -- TMBG _______________________________________________ Haskell-prime mailing list Haskell-prime@haskell.org http://www.haskell.org/mailman/listinfo/haskell-prime

On Wednesday 08 November 2006 21:02, Jan-Willem Maessen wrote:
On Nov 7, 2006, at 5:49 PM, Robert Dockins wrote: [On operator precedence]
Ha! Well, as long as we're being pedantic, surely we wouldn't need any set larger than the rationals (which does have a decidable ordering)?
Also, since I'm commenting anyway, I rather like the idea of specifying operator precedences via a partial order. However, I also feel that there needs to be some work done to make sure there aren't gremlins hiding in the details. Has anyone worked out the theory on this? How does associating to the right vs left play into the picture? How does it fit into the parsing technology?
Actually, we *do* use a DAG on operator precedence in the Fortress programming language (my day job).
Huh... I didn't know that. Are there any good papers/documentation on the system you use?
Our goal is to require parentheses when it is not blatantly obvious what is going on (eg because we're using operators from two libraries written in isolation). We can only use operators together in an expression without parentheses if there is an edge between them in the graph. Graph nodes are sets of operators with the "same" precedence (eg addition and subtraction). Among other things this means that if ++ has higher precedence than ==, and == has higher precedence than &&, we can't necessarily mix ++ and && in the same expression without parentheses.
That said, this would be a pretty big change for Haskell, and would break existing code unless you somehow wired in the transitive closure of all the existing operators. As another message in this discussion (from Simon M?) mentioned, you might want to be able to specify the relationship between operators imported from different modules, because you *do* know that a well-known relationship exists.
So the Fortress system doesn't use transitivity automaticly? And what about operator parsing associativity? Do you require that all operators assigned to the same node in the DAG have the same associativity?
-Jan-Willem Maessen
-- Rob Dockins Talk softly and drive a Sherman tank. Laugh hard, it's a long way to the bank. -- TMBG

by all means, lets have warm fuzzy precedence declarations infix(nearly right) (exp (2*i*pi) + 1) :-) infix(mostly left) (((\x->cos x + i*(sin x)) (2*pi)) + 1) (-: who says that all the fun has to start in the type system?-) we would probably need to refer to hyperreals, in order to introduce infinitesimal differences between real precedence levels? oh, and let us not forget the early Basic's contribution to language design: renum (who could ever to without it!-) ah well, to justify the use of bandwith (and because you should never let your design decisions be influenced by someone making fun of any of the suggestions): - absolute numbers for operator precedence are a hack that reminds me strongly of my Basic times: I used steps of 100 starting with 1000 for line numbers, I used renum to make space for additions or to clean up (was that refactoring?-), but I was still happy to leave all that nonsense behind! - googling for "operator precedence relative" suggests that some parser generators already use something other that absolute preferences - prolog has more precedence levels, as well as simple declarations for pre- and postfix operators (fx, xf) sorry, I just couldn't resist any more;-) claus -- unsagePerformIO: some things are just not wise to do

Lennart Augustsson wrote:
On Nov 7, 2006, at 11:47 , apfelmus@quantentunnel.de wrote:
Henning Thielemann wrote:
On Tue, 7 Nov 2006, Simon Marlow wrote:
I'd support fractional and negative fixity. It's a simple change to make, but we also have to adopt [...]
I think that computable real fixity levels are useful, too. A further step to complex numbers is not advised because those cannot be ordered.
But ordering of the computable reals is not computable. So it could cause the compiler to loop during parsing. :)
Actually, that's one of the use cases ;) Regards, apfelmus

apfelmus@quantentunnel.de wrote:
I think that computable real fixity levels are useful, too.
Only finitely many operators can be declared in a given Haskell program. Thus the strongest property you need in your set of precedence levels is that given arbitrary finite sets of precedences A and B, with no precedence in A being higher than any precedence in B, there should exist a precedence higher than any in A and lower than any in B. The rationals already satisfy this property, so there's no need for anything bigger (in the sense of being a superset). The rationals/reals with terminating decimal expansions also satisfy this property. The integers don't, of course. Thus there's a benefit to extending Haskell with fractional fixities, but no additional benefit to using any larger totally ordered set. -- Ben

I'm surprised that no one has mentioned showsPrec and readsPrec. Anything more complicated than negative fixities would require their interfaces to be changed. -- Ben

On Fri, 10 Nov 2006, Ben Rudiak-Gould wrote:
I'm surprised that no one has mentioned showsPrec and readsPrec. Anything more complicated than negative fixities would require their interfaces to be changed.
Very true. Does it mean, that the Functional Graph Library has to become part of the Prelude?

Ben Rudiak-Gould wrote:
I'm surprised that no one has mentioned showsPrec and readsPrec. Anything more complicated than negative fixities would require their interfaces to be changed.
That's a fine point. So, as I see it the situation with this precedence stuff is that there were several vocal complaints about the proposal to extend precedences to allow negative and fractional precedence values, and not many proponents. The point about showsPrec/readsPrec means that the extension is not quite as minimal as we thought, and would probably break some existing code. Alternative schemes based on constructing a partial order between operators are being proposed, but these are out of the question for Haskell'. So the default option is to do nothing, leaving us with the devil we know. It's hard to guage the opinion of the community on these things, so if you strongly object to doing nothing, please speak up. Cheers, Simon
participants (12)
-
apfelmus@quantentunnel.de
-
Ben Rudiak-Gould
-
Bulat Ziganshin
-
Claus Reinke
-
David House
-
Henning Thielemann
-
Jan-Willem Maessen
-
Joachim Durchholz
-
Jon Fairbairn
-
Lennart Augustsson
-
Robert Dockins
-
Simon Marlow