
Hi all, I'd like to propose an inbuilt "assignment" operator for use within do-blocks. Here's a common pattern - do foo <- someaction do something with foo -- Here we "update" the value of foo let foo' = bar foo -- The code from this point onwards shouldn't use foo -- but there is no way to enforce that What I'd like to do instead is something like - let foo = bar foo But to Haskell this is a recursive definition instead of an update to the previous value. I can do this instead - foo <- return $ bar foo which works fine but (I assume) GHC currently can't optimise it for arbitrary monads. Also it won't necessarily work if the monad laws don't hold. It would be nice to have an "assignment arrow", say (<-=), which lets GHC optimise this, so - foo <-= bar foo ... desugars to something like - foo' (bar foo) where foo' foo = ... -- Anupam

On Wed, Aug 26, 2015 at 05:55:45PM +0530, Anupam Jain wrote:
Hi all,
I'd like to propose an inbuilt "assignment" operator for use within do-blocks.
Time to add your proposal here! https://wiki.haskell.org/Nitpicks Honestly, I feel it would break the way I read Haskell programs (i.e. no reassignment surprises).

It’s not re-assigment, it’s rather feature request for non-rec-let (as let in Haskell is recursive) and some pragma to say “yes, I do shadow name on purpose" For example fix f = let x = f x in x -- let is recursive niceTry f = noreclet x = f x in x -- Not in scope: ‘x’ - Oleg
On 26 Aug 2015, at 15:34, Francesco Ariis
wrote: On Wed, Aug 26, 2015 at 05:55:45PM +0530, Anupam Jain wrote:
Hi all,
I'd like to propose an inbuilt "assignment" operator for use within do-blocks.
Time to add your proposal here! https://wiki.haskell.org/Nitpicks
Honestly, I feel it would break the way I read Haskell programs (i.e. no reassignment surprises).
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe

On Wed, Aug 26, 2015 at 03:55:15PM +0300, Oleg Grenrus wrote:
It’s not re-assigment, it’s rather feature request for non-rec-let (as let in Haskell is recursive) and some pragma to say “yes, I do shadow name on purpose"
Ah, I see. Still I feel that, as much as it is easily rewriteable to a `lambda (etc etc` (which will shadow the first `a`) (let ((a 10) (a 5)) (a)) will bite you back as the val-exprs list grows.

On Wed, Aug 26, 2015 at 6:04 PM, Francesco Ariis
On Wed, Aug 26, 2015 at 05:55:45PM +0530, Anupam Jain wrote:
Hi all,
I'd like to propose an inbuilt "assignment" operator for use within do-blocks.
Time to add your proposal here! https://wiki.haskell.org/Nitpicks
I just requested access to the wiki.
Honestly, I feel it would break the way I read Haskell programs (i.e. no reassignment surprises).
How is this any worse than using `foo <- return $ bar foo` or `let foo = something completely unrelated`?

On Thu, Aug 27, 2015 at 06:51:57PM +0530, Anupam Jain wrote:
How is this any worse than using `foo <- return $ bar foo` or `let foo = something completely unrelated`?
I happen to prefer foo = something foo' = bar foo to foo = something foo <- return $ bar foo because if on line 147 I find `x = foo` then I have to scan the source file (or function) only to the point where I find `foo`, while with 'reassignment'/shadowing this doesn't hold. "The code from this point onwards shouldn't use foo but there is no way to enforce that" is indeed an annoyance, which can only be awkwardly expressed as: λ> (let a = 1 in 2) + a <interactive>:5:20: Not in scope: ‘a’ But don't mind me, I prefer to use `>>= \var ->` instead of do notation!
Time to add your proposal here! https://wiki.haskell.org/Nitpicks
I just requested access to the wiki.
Thank you for taking time to add your proposal and peace be upon William Yager for coming up with the List of Nitpicks, having them in one place is a great way to assess the issues in an organic manner.

IMO, having <- in do syntax look like assignment is bad enough as it is, no need to further enforce the illusion. The variable shadowing that effectively occurs in that example is still just as bad as regular shadowing. On Wed, Aug 26, 2015 at 05:55:45PM +0530, Anupam Jain wrote:
Hi all,
I'd like to propose an inbuilt "assignment" operator for use within do-blocks.
Here's a common pattern -
do foo <- someaction do something with foo -- Here we "update" the value of foo let foo' = bar foo -- The code from this point onwards shouldn't use foo -- but there is no way to enforce that
What I'd like to do instead is something like -
let foo = bar foo
But to Haskell this is a recursive definition instead of an update to the previous value.
I can do this instead -
foo <- return $ bar foo
which works fine but (I assume) GHC currently can't optimise it for arbitrary monads. Also it won't necessarily work if the monad laws don't hold.
It would be nice to have an "assignment arrow", say (<-=), which lets GHC optimise this, so -
foo <-= bar foo ...
desugars to something like -
foo' (bar foo) where foo' foo = ...
-- Anupam _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe

On Wed, Aug 26, 2015 at 8:14 PM, Tobias Dammers
IMO, having <- in do syntax look like assignment is bad enough as it is, no need to further enforce the illusion.
The syntax could be anything, it doesn't have to be an arrow. For example it could simply be an inbuilt function say `liftIdentity`. i.e. foo <- liftIdentity $ bar foo This makes sense if we think of every monad as a transformer around the Identity monad. Analogous to liftIO, except automatically defined for all Monads. Of course GHC would have to implement it in such a way so as to not use `return`.
The variable shadowing that effectively occurs in that example is still just as bad as regular shadowing.
I'm not sure how "shadowing" is bad. It is certainly safer than a string of foo, foo', foo'' etc.

On Wed, Aug 26, 2015 at 7:25 PM, Anupam Jain
What I'd like to do instead is something like -
let foo = bar foo
But to Haskell this is a recursive definition instead of an update to the previous value.
This is a chestnut at least two years old. Last time I remember, the discussion frothed under the rubric of "non-recursive let": https://mail.haskell.org/pipermail/haskell-cafe/2013-July/109116.html -- Kim-Ee

On Wed, Aug 26, 2015 at 9:39 PM, Kim-Ee Yeoh
On Wed, Aug 26, 2015 at 7:25 PM, Anupam Jain
wrote: What I'd like to do instead is something like -
let foo = bar foo
But to Haskell this is a recursive definition instead of an update to the previous value.
This is a chestnut at least two years old. Last time I remember, the discussion frothed under the rubric of "non-recursive let":
https://mail.haskell.org/pipermail/haskell-cafe/2013-July/109116.html
Thanks for linking to that discussion. However that discussion seems to be revolving around the non-recursive let. What I propose is only an extension to the do-notation desugaring, which seems more benign. I wrote this email yesterday when I ran into a rather hard-to-find bug because I used `foo` where I should have used `foo'`. I think it's an unnecessary wart that can easily go away with a little bit of syntactic sugar.

Looking at the nitpick list, I just remembered that there was a discussion about making let optional in do bindings a couple of years ago. https://mail.haskell.org/pipermail/haskell-cafe/2012-August/102741.html One of the major stumbling points was how recursive bindings should work. These these two proposals would combine nicely. adding a statement pat = exp that expresses a non-recursive let. Silvio

On 07.09.2015 22:18, Silvio Frischknecht wrote:
Looking at the nitpick list, I just remembered that there was a discussion about making let optional in do bindings a couple of years ago.
https://mail.haskell.org/pipermail/haskell-cafe/2012-August/102741.html
One of the major stumbling points was how recursive bindings should work. These these two proposals would combine nicely.
adding a statement
pat = exp
that expresses a non-recursive let.
Exactly! +1 from me. -- Andreas Abel <>< Du bist der geliebte Mensch. Department of Computer Science and Engineering Chalmers and Gothenburg University, Sweden andreas.abel@gu.se http://www2.tcs.ifi.lmu.de/~abel/
participants (7)
-
Andreas Abel
-
Anupam Jain
-
Francesco Ariis
-
Kim-Ee Yeoh
-
Oleg Grenrus
-
Silvio Frischknecht
-
Tobias Dammers