patch applied (haskell-prime-status): add ""Make $ left associative, like application"

Sterling Clover s.clover at gmail.com
Wed Apr 23 18:10:02 EDT 2008


I think there are some very valid concerns about this proposal, but  
just to add a small datapoint -- the associativity of $ was somewhat  
painful and counterintuitive to me when I was first learning Haskell,  
and the associativity of $! doubly so.

Code breakage issues aside, this seems very much the "right thing" to  
do. Haskell will *necessarily evolve* in a backwards-incompatible way  
at some point, with the move from Functional Dependencies. And  
meanwhile, changes to things such as the ByteString API have been  
taking place and causing breakage now for some time (although  
hopefully we've seen about the last of that). So the bigger issue  
seems to be -- if not Haskell', then when, precisely should a number  
of other issues with the core libraries be addressed, or should we  
let some things stay set in stone, even while other compatibility- 
breaking changes occur all around them?

--S

On Apr 23, 2008, at 4:42 PM, Niklas Broberg wrote:
> When I first saw this thread, my gut response was "Aw gawds no, don't
> touch my $ !!" I love $, I use it all the time, it really helps making
> code more readable and more nicely structured. I would really hate for
> someone to take that away from me.
>
> So when I came across this:
>
>>> This wouldn't work, you'd have to rewrite it as:
>>
>>>     withSomeResource foo .
>>>       withSomeOtherThing bar .
>>>         yetAnotherBlockStructured thing $ ...
>>
>>
>> it is very inconvenient - we should use either . or $ depending on
>>  that it's last block or not. imagine all the changes when editing  
>> the
>>  code
>
> ... my initial response to it was yeah, Bulat is right, that's rather
> inconsistent, and it would mean a lot of changes when editing (and
> it's ugly too!).
>
> But then I started questioning my own motives. What changes would that
> be? Changing a . to a $ if I decided to remove the previous last piece
> of the "pipeline"? Doesn't seem too hairy, and I have to do far worse
> than that already when refactoring. Inconsistent? Doesn't it actually
> make perfect sense that the actual application of the "pipeline" of
> functions to some value is handled differently? Like Cale said,
> wouldn't it actually be a Good Thing that we treated these things as
> composition chains instead of application chains? And I could no
> longer defend my own position, and so I started thinking for real.
>
> Refactoring doesn't become harder with this suggestion - it becomes
> easier in general, just as Dan points out in #1. And I know I've been
> bitten by his #2 a bunch of times, even if I haven't realized the
> source of the problem until I read this thread. It's messy having to
> use a lot of parenthesis just because some argument to a function
> isn't the last one, and I've found myself wishing for a way to get rid
> of them. I know I have at times refactored my function definitions,
> switching their arguments around just to get the one that would need
> the parenthesis to be the last one.
>
> So I dug through some of my code, picking large modules at random. As
> I said I use $ *a lot*, anywhere that I can get away with it. In the
> first 10 modules I looked at, I found one (1) place where I would need
> to change a $ to a . to make it work. So I went to look at a bigger
> module, and in what is possibly my largest self-contained module (1800
> loc including comments) I had 211 uses of $, and I would have had to
> change 23 of them into . instead to make it work with a
> left-associative version. All the ones where the left operand is just
> a function (like return) will still work. All the ones that are
> followed by a '\x -> ...' will still work. All the ones followed by a
> 'do ...' will still work. On the other hand, I found 10 places where I
> could immediately have gotten rid of some extra parentheses, and that
> just by searching for uses of fmap in the code!
>
> It should be said though that changing the associativity of $ doesn't
> make all code nice and clean. Consider for instance
>
> f (g (h x)) (k y)
>
> We could change that into one of
>
> f $ g (h x) $ k y
> f (g $ h x) $ k y
>
> but not get rid of the parenthesis altogether, i.e. uses of $ for
> different applications won't mix. But with right-associative $, the
> second one would be our only option, so at least we're no worse off
> than before, and perhaps it could be argued we are better off (in this
> kind of situation).
>
>
> I think it is reasonable to look closely at the motivations for
> wanting to retain the $ as is. Looking through this thread, I can find
> only a single complaint raised (albeit an important one), namely
> backwards compatibility. Yes, such a change would likely break quite a
> few my modules. But like Cale, I would never have expected H' to be
> fully backwards compatible with H98, and thus there would have to be
> some way to migrate anyway. This one seems pretty simple, just let the
> old Prelude be Haskell98.Prelude and import that in old code. Of
> course changes that break backwards compatibility should not be made
> frivolously, but I find it hard to buy having only that as an argument
> for a change that otherwise seems highly reasonable.
>
> We live in a beautiful statically typed world. If the proposed change
> was such that existing code would still compile, but with a different
> behavior, it would be really dangerous. That's clearly not the case
> here, there's no way that code that uses $-chaining would still
> compile if the associativity was changed, and any other use of $ would
> still compile and work as before. The type checker is there to help
> us, and it's literally a moment's work to clean up existing code to
> meet these standards. (And it's even faster to import
> Haskell98.Prelude if you're lazy).
>
> So come on, give me an argument for why $ should be right-associative
> instead of complaining about broken code (that I argue won't break
> even half as bad as some of you would have it). Is there really no
> reason at all why right-associative is to be preferred over
> left-associative? And if there is, why don't we hear it? Are you truly
> arguing this because you think there's a problem with left-associative
> $, or are you simply arguing because you want to stay with what you're
> used to?
>
> "The ability to think differently today from yesterday distinguishes
> the wise man from the stubborn." - John Steinbeck
>
> Cheers,
>
> /Niklas
>
>
> ps. Though to be honest I really don't see why we don't simply add
> another operator instead of changing an existing one... :-)
> _______________________________________________
> Haskell-prime mailing list
> Haskell-prime at haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-prime



More information about the Haskell-prime mailing list