Home liberachat/#haskell: Logs Calendar

Logs: liberachat/#haskell

←Prev  Next→ 1,803,663 events total
2021-07-27 20:18:11 <Cale> and that saves us a bunch of trouble defining e.g. "forM" in every library we write
2021-07-27 20:18:23 <maerwald> never understood this argument
2021-07-27 20:18:24 <dsal> `return` is a bad name and often makes people think something is happening when something else is happening.
2021-07-27 20:18:29 <maerwald> rust is doing fine without this
2021-07-27 20:18:44 <dsal> I've had issues reading code that looked pretty weird and used return in a way where I had to make sure the author actually understood what was happening.
2021-07-27 20:18:50 <Cale> The reason for the monad abstraction to exist is the same as the reason for any abstraction to exist
2021-07-27 20:19:11 <maerwald> that's too vague for me :)
2021-07-27 20:19:12 <Cale> We define a lot of things which happen to be monads, it's nice to avoid repeating ourselves when the pattern exists.
2021-07-27 20:19:45 <maerwald> I'm just questioning that the whole expressivity monads give is actually a good idea to utilize
2021-07-27 20:19:47 chomwitt joins (~chomwitt@athedsl-32041.home.otenet.gr)
2021-07-27 20:19:57 <maerwald> at least on a general basis
2021-07-27 20:20:10 <maerwald> especially when it breaks your intuition about combinators
2021-07-27 20:20:16 × pschorf quits (~user@208.127.190.222) (Remote host closed the connection)
2021-07-27 20:20:17 × lavaman quits (~lavaman@98.38.249.169) (Ping timeout: 255 seconds)
2021-07-27 20:20:25 <Cale> Well, combinator libraries in general are a good idea. If your combinator library happens to define a monad, it's nice to recognise that.
2021-07-27 20:20:30 <maerwald> that expands more generally to type classes
2021-07-27 20:20:45 <monochrom> If you can bring your same argument against rings, fields, monoids, vector spaces, topologies... then perhaps it applies to monads too.
2021-07-27 20:20:49 × Guest966 quits (~Guest9@43.242.116.41) (Quit: Connection closed)
2021-07-27 20:20:55 <maerwald> you refactor your stuff, luckily it still compiles... but the underlying instance does something entirely different
2021-07-27 20:20:59 <maerwald> that's a lens moment
2021-07-27 20:21:17 <Cale> Well, that's what the monad laws are for
2021-07-27 20:21:24 <monochrom> It is both nice and useful to know that, for example, the binomial theorem works for all commutative rings, even though I will end up just using the real number ring anyway.
2021-07-27 20:21:26 <maerwald> oh, it's not a law problem
2021-07-27 20:21:29 <Cale> They tell you some refactorings it's okay to make
2021-07-27 20:21:35 <maerwald> lenses broke my code in a lawful way
2021-07-27 20:21:38 × Null_A quits (~null_a@2601:645:8700:2290:5520:ed9a:24da:3d0c) (Remote host closed the connection)
2021-07-27 20:21:40 × Obo quits (~roberto@70.pool90-171-81.dynamic.orange.es) (Quit: WeeChat 2.8)
2021-07-27 20:21:43 <maerwald> that didn't help
2021-07-27 20:21:57 <maerwald> typeclasses can do that
2021-07-27 20:22:14 <Cale> Well, it is important to know what you're doing, and I think using things which are overpowered relative to your needs is often a bad idea
2021-07-27 20:22:46 <dsal> I look at it like applicative functors are a newer thing that monads also are, and since `return = pure` in (hopefully) all the cases, using the less confusing name is better.
2021-07-27 20:22:48 <maerwald> they can cloud control flow and make behavior reasoning impossible... now you're just reasoning about abstractions and what you roughly think they do, instead of having the actual control flow in your head... most of the time this may work out
2021-07-27 20:22:51 <maerwald> but sometimes not
2021-07-27 20:22:58 <Cale> Lens has its places for good use, but I wouldn't recommend using it everywhere all the time.
2021-07-27 20:22:59 <dsal> > let f x = do { a <- if odd x then return 3 else return 6; return 4 } in f 1 :: Maybe Int -- because people write code like this and end up confused.
2021-07-27 20:23:01 <lambdabot> Just 4
2021-07-27 20:23:03 jmtd joins (jon@dow.land)
2021-07-27 20:23:11 × robertm quits (robertm@rojoma.com) (Ping timeout: 252 seconds)
2021-07-27 20:23:44 × Jon quits (jon@dow.land) (Ping timeout: 272 seconds)
2021-07-27 20:23:44 <Cale> dsal: Well, I think that's just getting used to what the monad laws say about return
2021-07-27 20:23:50 × mrmonday quits (~robert@what.i.hope.is.not.a.tabernaevagant.es) (Ping timeout: 250 seconds)
2021-07-27 20:24:05 jmtd is now known as Jon
2021-07-27 20:24:07 <maerwald> generics take this a step further... idk how to understand my own generics code without writing it again from scratch
2021-07-27 20:24:12 mrmonday joins (~robert@what.i.hope.is.not.a.tabernaevagant.es)
2021-07-27 20:24:29 <dsal> It's generally people who are somewhat new to the language and who have a lot of things to get used to. Telling them `return` does something entirely different than anything they've ever experienced just makes the curve steeper.
2021-07-27 20:24:37 <Cale> But also, it makes sense from the perspective that e.g. when you apply f to an odd number, return 3 is going to be the action which does nothing except to return 3
2021-07-27 20:24:41 <maerwald> so yeah... haskell has some nice properties wrt "reasoning", but it can break that easily
2021-07-27 20:24:49 <Cale> and a is the result of executing that, so a will be 3
2021-07-27 20:25:13 <Cale> dsal: It's only confusing if you're used to having all your shit wrapped in callCC implicitly :D
2021-07-27 20:25:27 × chomwitt quits (~chomwitt@athedsl-32041.home.otenet.gr) (Remote host closed the connection)
2021-07-27 20:25:32 <maerwald> whether you need to keep global variables in your head or odd class instance behavior, does it really matter?
2021-07-27 20:25:44 Null_A joins (~null_a@2601:645:8700:2290:5520:ed9a:24da:3d0c)
2021-07-27 20:26:05 × Vajb quits (~Vajb@hag-jnsbng11-58c3a1-224.dhcp.inet.fi) (Remote host closed the connection)
2021-07-27 20:26:13 × ukari quits (~ukari@user/ukari) (Ping timeout: 268 seconds)
2021-07-27 20:26:52 <dsal> Sure, but it confuses a lot of folks. `return` in a function doesn't cause the function to return and that surprises people.
2021-07-27 20:26:56 <dsal> I can't remember the exact case I saw like this, but I had to confirm that they actually understood that the code would continue processing effects after the `return` because it was weird looking code and it wasn't clear whether they understood it.
2021-07-27 20:26:58 <maerwald> we're almost there (talking about effects systems)
2021-07-27 20:27:06 <maerwald> (and how they will save us all)
2021-07-27 20:27:25 <dsal> It's kind of like using the word "peruse" in English. Its definition includes its antonym so you have to ask what people mean all the time and you might as well avoid using the word altogether so nobody's confused.
2021-07-27 20:27:27 <maerwald> but Cale prefers transformers anyway :p
2021-07-27 20:27:34 × gehmehgeh quits (~user@user/gehmehgeh) (Ping timeout: 244 seconds)
2021-07-27 20:27:48 gehmehgeh joins (~user@user/gehmehgeh)
2021-07-27 20:28:09 <Cale> dsal: I totally get that, but people who are trying to read Haskell as though it were e.g. Python, are going to be confused by much more than that anyway, and I think the name "return v" is a fine name for what action it denotes.
2021-07-27 20:28:39 <Cale> Once you understand that nothing possibly could have the effect that they expected, then it's not confusing at all that return doesn't have that effect
2021-07-27 20:29:13 roboguy_ joins (~roboguy_@2605:a601:ac0e:ae00:bc41:cf44:b56:1727)
2021-07-27 20:29:35 <Cale> The reason it's forbidden is that one of the monad laws effectively says you can chop a segment out of any do-block and move it into a new definition without changing the meaning
2021-07-27 20:29:56 <Cale> (that's what the associativity law basically means)
2021-07-27 20:30:15 <Cale> and so, that includes stuff with returns in it
2021-07-27 20:30:20 Vajb joins (~Vajb@hag-jnsbng11-58c3a1-224.dhcp.inet.fi)
2021-07-27 20:30:44 <dsal> The idea of what `return` does is similar to the idea of what `fail` does, though. `fail` gets to return early, so I can just evaluate stuff until I `return` or `fail`.
2021-07-27 20:30:44 bwe_ is now known as bwe
2021-07-27 20:30:52 × gehmehgeh quits (~user@user/gehmehgeh) (Remote host closed the connection)
2021-07-27 20:30:58 <dsal> Anyway, I find it confusing, but don't know why I'd actually *want* to use `return`. It's never made any code clearer for me.
2021-07-27 20:31:03 <Cale> It's not though...
2021-07-27 20:31:12 × drd quits (~drd@93-39-151-19.ip76.fastwebnet.it) (Ping timeout: 250 seconds)
2021-07-27 20:31:17 <Cale> fail will cause the entire computation to fail, sure.
2021-07-27 20:31:29 <Cale> But that's not the same as ending the present definition
2021-07-27 20:31:32 gehmehgeh joins (~user@user/gehmehgeh)
2021-07-27 20:31:43 <Cale> It extends arbitrarily far beyond that
2021-07-27 20:31:48 <dsal> Why not, though? What's the difference between Left and Right here?
2021-07-27 20:32:12 <Cale> Like, what you probably expect of your f from before is that 3 gets returned *from f*
2021-07-27 20:32:33 <Cale> Not that 3 gets returned from the entire final action of which f 1 was only possibly a small part
2021-07-27 20:32:33 × amk quits (~amk@176.61.106.150) (Remote host closed the connection)
2021-07-27 20:32:46 drd joins (~drd@93-39-151-19.ip76.fastwebnet.it)
2021-07-27 20:32:46 × LukeHoersten quits (~LukeHoers@user/lukehoersten) (Quit: My MacBook has gone to sleep. ZZZzzz…)
2021-07-27 20:32:48 × geekosaur quits (~geekosaur@xmonad/geekosaur) (Killed (NickServ (GHOST command used by allbery_b)))
2021-07-27 20:32:48 allbery_b joins (~geekosaur@xmonad/geekosaur)
2021-07-27 20:32:51 allbery_b is now known as geekosaur
2021-07-27 20:33:29 <Cale> i.e. you expect something like f x = callCC $ \ret -> if odd x then ret 3 else ret 6; return 4
2021-07-27 20:33:45 <dsal> Yeah, I think that's what people often expect.
2021-07-27 20:34:00 amk joins (~amk@176.61.106.150)
2021-07-27 20:34:04 <Cale> But if return behaved like Left, that's not what would happen
2021-07-27 20:34:12 <dsal> Nobody ever expects that with `pure` though.
2021-07-27 20:34:25 <Cale> Because if we had something like do f 1; f 2
2021-07-27 20:34:38 <Cale> then we might not expect 3 to be returned
2021-07-27 20:35:11 <Cale> The monad laws tell us that we're always allowed to inline the definition of f 1
2021-07-27 20:35:28 <dsal> Sure, I agree with that model. It's simply the word that's confusing.
2021-07-27 20:35:33 <dsal> I don't even have a good mental model for what `return` should mean (other than just aliasing it to `pure` in my head). I have a mechanical rewrite so that I don't think of anything being returned because the concept doesn't make sense.
2021-07-27 20:35:52 <lechner> dsal: in the two meanings of "peruse" I see a range of reading activities. it's the logical way to combine them
2021-07-27 20:35:54 <Cale> It might be confusing for all of a few minutes until someone tells you what return means

All times are in UTC.