return in Monad class necessary?

I wonder whether it is a typical mistake of beginners to write 'return' within a do-block (that is, not at the end) and if it is possible to avoid this mistake by clever typing. In a proper monad 'return' can be fused with subsequent actions, and thus it is not necessary within a sequence of actions. However, although sensible, 'return' is also not required at the end of a block. Has someone already thought about a replacement for monads?

Hello Henning, Monday, November 26, 2007, 9:48:29 PM, you wrote:
I wonder whether it is a typical mistake of beginners to write 'return' within a do-block (that is, not at the end)
don't forget that `return` is also used to force evaluation: do let n = a+b return $! n writeChan c (n,1) -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com

I wonder whether it is a typical mistake of beginners to write 'return' within a do-block (that is, not at the end) and if it is possible to avoid this mistake by clever typing. In a proper monad 'return' can be fused with subsequent actions, and thus it is not necessary within a sequence of actions. However, although sensible, 'return' is also not required at the end of a block. Has someone already thought about a replacement for monads? I also made that mistake in the beginning, I used return instead of lets. I don't think it's a big problem, most users will find out once
On 26 nov 2007, at 19:48, Henning Thielemann wrote: they've got some more experience, and it doesn't really do any harm. -chris

On Tue, 2007-11-27 at 00:15 +0100, Chris Eidhof wrote:
I wonder whether it is a typical mistake of beginners to write 'return' within a do-block (that is, not at the end) and if it is possible to avoid this mistake by clever typing. In a proper monad 'return' can be fused with subsequent actions, and thus it is not necessary within a sequence of actions. However, although sensible, 'return' is also not required at the end of a block. Has someone already thought about a replacement for monads? I also made that mistake in the beginning, I used return instead of lets. I don't think it's a big problem, most users will find out once
On 26 nov 2007, at 19:48, Henning Thielemann wrote: they've got some more experience, and it doesn't really do any harm.
I may be mistaken, but I'm pretty sure he's talking about something different. Basically, where 'return' is confused for C's return. I have seen this occasionally in #haskell or on the mailinglist, but it doesn't seem to be a big issue. It doesn't come up all that often and it's usually quickly resolved.

Chris Eidhof wrote:
On 26 nov 2007, at 19:48, Henning Thielemann wrote:
I wonder whether it is a typical mistake of beginners to write 'return' within a do-block (that is, not at the end) and if it is possible to avoid this mistake by clever typing. In a proper monad 'return' can be fused with subsequent actions, and thus it is not necessary within a sequence of actions. However, although sensible, 'return' is also not required at the end of a block. Has someone already thought about a replacement for monads?
I also made that mistake in the beginning, I used return instead of lets. I don't think it's a big problem, most users will find out once they've got some more experience, and it doesn't really do any harm.
It might be possible for the compiler to emit a warning when a return is used in the middle of a do block as the top level operator on a line. OTOH, that still wouldn't catch something like "when (x == 0) (return ())" which doesn't do what an imperative programmer expects. Reinier

On 27 nov 2007, at 10:14, Reinier Lamers wrote:
Chris Eidhof wrote:
On 26 nov 2007, at 19:48, Henning Thielemann wrote:
I wonder whether it is a typical mistake of beginners to write 'return' within a do-block (that is, not at the end) and if it is possible to avoid this mistake by clever typing. In a proper monad 'return' can be fused with subsequent actions, and thus it is not necessary within a sequence of actions. However, although sensible, 'return' is also not required at the end of a block. Has someone already thought about a replacement for monads?
I also made that mistake in the beginning, I used return instead of lets. I don't think it's a big problem, most users will find out once they've got some more experience, and it doesn't really do any harm.
It might be possible for the compiler to emit a warning when a return is used in the middle of a do block as the top level operator on a line. OTOH, that still wouldn't catch something like "when (x == 0) (return ())" which doesn't do what an imperative programmer expects. Well, there are two things about the return:
First, some people want to use return just as an imperative programmer would use it: to exit from a function. So the programmer doesn't expect the commands after that return are executed. Second, the problem I had was that I didn't know how to do computations with the data I got from the monad, for example:
main = do myLine <- getLine reversed <- return $ unwords $ reverse $ words myLine putStrLn reversed
Instead of the 3rd line I could have written
let reversed = unwords $ reverse $ words myLine
This is another problem, but it doesn't affect the computation, whereas the first problem is more serious. -chris

On Nov 27, 2007 4:45 AM, Chris Eidhof
First, some people want to use return just as an imperative programmer would use it: to exit from a function. So the programmer doesn't expect the commands after that return are executed.
This is more a problem with the name. I doubt this particular problem would
arise if return were called something like "pure" (like the equivalent in
Applicative).
I suspect the solution here is better documentation. There are logical
reasons for return to be called "return". We just need to point out to new
programmers that it's not the same as return in other languages. Much like
how Haskell's classes are not like the classes in object-oriented languages.
Incidentally, lots of early monad papers use names like "unit". When did
Haskell settle on the name "return"? My guess is that it has something to do
with the old monad comprehension syntax.
--
Dave Menendez

Hi Henning,
I wonder whether it is a typical mistake of beginners to write 'return' within a do-block (that is, not at the end) and if it is possible to avoid this mistake by clever typing.
There are legitimate uses of return inside a do, see: http://www.cs.york.ac.uk/fp/darcs/catch/catch_1/Analyse/Fix.hs The code has a bit like: x <- return $ apply x addReq (\y -> y{requiredBy = Set.insert k (requiredBy y)}) x <- return $ apply x delReq (\y -> y{requiredBy = Set.delete k (requiredBy y)}) i.e. modify x, which you can't do with let's because of the scoping (they are really let-rec's). I often use return to do binding and name shadowing in do blocks. Having said that, when I was learning Haskell, I didn't know you could put let in a do block, and did use the return for all variables! Thanks Neil

On 26 Nov 2007, at 10:48 AM, Henning Thielemann wrote:
I wonder whether it is a typical mistake of beginners to write 'return' within a do-block (that is, not at the end) and if it is possible to avoid this mistake by clever typing. In a proper monad 'return' can be fused with subsequent actions, and thus it is not necessary within a sequence of actions. However, although sensible, 'return' is also not required at the end of a block. Has someone already thought about a replacement for monads?
As has been said, this isn't a big issue, and return is quite useful. Furthermore, I can think of several cases where it would be awkward (to say the least) to dispense with return, and it's an invaluable base case for inductive definitions, e.g. of liftMn (which would have to replace it, I suppose). And besides that, if there is one thing Haskellers believe more than anything else, it must surely be that every associative operator deserves a unit... jcc
participants (8)
-
Bulat Ziganshin
-
Chris Eidhof
-
David Menendez
-
Derek Elkins
-
Henning Thielemann
-
Jonathan Cast
-
Neil Mitchell
-
Reinier Lamers