Home liberachat/#haskell: Logs Calendar

Logs on 2025-01-31 (liberachat/#haskell)

00:00:31 rstromlund joins (~user@user/rstromlund)
00:00:41 <monochrom> Consider how "numbers" are taught beginning with natural numbers and, eventually, if you go to math grad school, ending with algebraic number fields. Not the other way round.
00:01:00 <dminuoso> monochrom: Sure, but that particular wikibooks article is not about promoting any learning process.
00:01:22 <dminuoso> If Monad tutorials started with just proclamining `Monads are just IO`, this would be a feasible strategy.
00:01:44 <dminuoso> As you could gradually introduce more instances and different "flavours"
00:02:54 <monochrom> That one I agree with you. It's the equivalent of a biology tutorial saying "natural selection is described as survival of fittest"
00:04:03 alfiee joins (~alfiee@user/alfiee)
00:05:18 × rstromlund quits (~user@user/rstromlund) (Ping timeout: 252 seconds)
00:08:34 × alfiee quits (~alfiee@user/alfiee) (Ping timeout: 260 seconds)
00:08:58 <euouae> dminuoso: I'm not trying to summarize all monads or anything of the short, just to adopt a mental mode
00:10:04 <dminuoso> euouae: Fair enough.
00:10:25 <euouae> obviously it's both tiresome to manually typecheck everything when reading code & provides no intuition. the megaparsec code I saw earlier with a bunch of >>= inside a do was clear in what it was doing: it was combining a bunch of parser combinators, starting from some initial string-to-be-parsed, and outputted either a parsed data structure or parser error
00:10:34 <dminuoso> The mental model I have settled on over the years is that `Monads` model sequencing.
00:10:39 merijn joins (~merijn@host-vr.cgnat-g.v4.dfn.nl)
00:10:43 <euouae> and it sort of occurred to me that a lot of uses of do/>>= are doing basically stuff like that
00:11:39 <dminuoso> Though Im a flexible, and I have some alternate intuitions that I can switch to depending on the problem.
00:12:02 <euouae> well sure, adopting just one is good enough for me. I'll adopt more if the need arises
00:12:10 × down200 quits (~down200@shell.lug.mtu.edu) (Ping timeout: 244 seconds)
00:12:50 <dminuoso> euouae: [] seems to breaks a state machine viewpoint.
00:13:12 <dminuoso> The monad instance of [] roughly models non-determinism (with a bit of squinting)
00:13:19 <euouae> if you can elaborate?
00:13:27 monochrm joins (trebla@216.138.220.146)
00:14:31 <dminuoso> (I say squinting because lists are not sets and have a bit more structure)
00:15:11 × merijn quits (~merijn@host-vr.cgnat-g.v4.dfn.nl) (Ping timeout: 252 seconds)
00:15:24 × monochrom quits (trebla@216.138.220.146) (Ping timeout: 260 seconds)
00:15:24 monochrm is now known as monochrom
00:15:52 <geekosaur> so, the list monad models a computation that gives you all possible solutions, whereas a Maybe version of the same computation gives you at most one solution (and can be thought of as "first solution, if any")
00:17:35 down200 joins (~down200@shell.lug.mtu.edu)
00:18:11 <dminuoso> euouae: Say if we imagine a chess computer, we could think of [move1, move2, move3, move4] as not a collection of possibilities, but rather some non-deterministic choice of *one* move.
00:18:24 ec joins (~ec@gateway/tor-sasl/ec)
00:18:34 <dminuoso> And >>= lets you take a further non-determistic choice
00:19:09 <euouae> Here's how lists are state machines: No input variable, only state; its output is the state. They compose funkily, but still.
00:19:23 <geekosaur> as dminuoso said, it's acting as a "poor man's set" (for technical reasons we can't actually make a Set a Monad); all the answers are equally ranked, their position in the list isn't relevant
00:19:52 <dminuoso> euouae: But its that *funkily* behavior that is the core essence of that instance.
00:20:02 <euouae> It is no less a state machine however
00:20:08 <euouae> a composable state machine, as I said above
00:20:41 <euouae> anyway, it's been said that everything can be considered a state machine, it's just a mental mode I have... I'm just glad I put it to some test and it didn't immediately collapse
00:20:44 bitdex joins (~bitdex@gateway/tor-sasl/bitdex)
00:21:37 <dminuoso> I mean if you insist on that state machine model, perhaps you could think of it as a non-deterministic state machine (along the lines of an NFA)
00:22:08 <dminuoso> Im not sure about the exact mental gymnastics required to see the state machine, but thats probably because Im flexed very differently
00:23:01 geekosaur wonders if it's the same viewpoint used with the comonad
00:23:07 <dminuoso> euouae: So here's why your state machine logic does not quite work out:
00:23:18 <euouae> As long as I can squeeze real-world results from my intuition I'm not too bothered by its rough edges
00:23:24 <dminuoso> euouae: `do x <- [1,2,3]; ...` -> how do you obtain the state?
00:24:01 <dminuoso> The non-determinism approach has the benefit of accurately modelling non-deterministic algorithms.
00:24:57 <dminuoso> In the above example, `x` represents some non-deterministic choice of [1,2,3]
00:25:01 <euouae> In `do x <- [1,2,3];` you're getting a slice of that funky composability
00:25:24 <dminuoso> euouae: But Im asking about where that state machine is. What's the state here?
00:25:38 <euouae> now x <- [1,1,1] does not have enough information for you to distinguish one 1 from another 1, even though they're positionally different
00:26:01 <euouae> I think I imagine state different from State or whatever
00:26:02 merijn joins (~merijn@host-vr.cgnat-g.v4.dfn.nl)
00:26:11 <euouae> The state is [1,2,3]
00:26:41 <dminuoso> euouae: Thats only true in the sense that the program has to store [1,2,3], but that could be said about *any* computation of anything.
00:27:03 <dminuoso> euouae: If we want to derive meaning of Monad, we must constrain to its interface
00:27:05 <dminuoso> % :t pure
00:27:06 <yahb2> pure :: Applicative f => a -> f a
00:27:11 <dminuoso> % :t (>>=)
00:27:11 <yahb2> (>>=) :: Monad m => m a -> (a -> m b) -> m b
00:27:36 <dminuoso> If you cannot put your "state" into relationship with that interface, your intuition has nothing to do with Monad, but with something else.
00:27:56 <dminuoso> These two functions, *together with some laws* are what Monad is. Nothing more, nothing less.
00:28:08 <euouae> Like I said, it's matching some usual applications of Monad like the parser combinators
00:28:25 <euouae> You want to content that it's not matching List. I agree, but at the same time, I am not too afraid to stretch my imagination and pretend it does
00:28:40 <euouae> As long as I can get somewhere with megaparsec :P
00:28:49 <euouae> anyway sorry for wasting your time... just thoughts
00:28:50 <dminuoso> euouae: Your intuitoin is absolutely great for megaparsec.
00:29:10 <dminuoso> But its not a good general intuition, it just does not work for list.
00:30:37 <dminuoso> euouae: In fact, megaparsec under the hood could be thought of StateT and ExceptT wired together - thats state looks so fitting, because it *does* use a state monad internally.
00:30:59 <euouae> What is the role of T in StateT? I haven't quite grasped that
00:31:02 <dminuoso> (Internally it uses a different representation for performance reasons, miond you)
00:31:04 × merijn quits (~merijn@host-vr.cgnat-g.v4.dfn.nl) (Ping timeout: 272 seconds)
00:31:12 <euouae> I haven't seen any examples either. I know a monad goes there, but State has it to be Identity
00:31:25 <hololeap> it stands for "transformer"
00:33:18 <dminuoso> euouae: And perhaps, for IO the state notion is not too shabby either as a first try by the way, if we think of the "real world" being the state. This is an intuition I can easily prove wrong, but I think I would rob you of some valuable learning process as monochrom as pointed out earlier.
00:33:43 <dminuoso> Given that you could just `launchMissiles` and change the state of the real world with IO.
00:34:33 <hololeap> I can't remember how to do 'unmtl' in #haskell
00:34:34 <euouae> I'm not sure what you mean by proving it wrong
00:34:55 <euouae> Is IO not a state
00:35:03 <dminuoso> euouae: There's a bunch of things you can do in IO that... isnt quite about changing the real world.
00:35:22 <dminuoso> Or you would need to do some more gymnastics.
00:35:25 <hololeap> IO being (State RealWorld a) is more of a mental model
00:35:44 <dminuoso> euouae: I dont want discredit this particular intuition, because I think it *is* a good starting point
00:36:12 <dminuoso> Just like we teach newtonian physics in school, despite general relativity being more accurate.
00:37:03 <dminuoso> euouae: Anyhow. Do try to build the state intuition around `>>=` and `pure` - and then test it in the future.
00:37:19 <euouae> yup. thank you
00:37:24 <euouae> but what is transformer?
00:37:49 <dminuoso> euouae: If we think of Monads not as "state" but as some generalized idea of effects, then transformers lets us combine different effects.
00:37:53 <euouae> With a State I know I have a 'state processor' and an 'output value' but what is the transformer for?
00:37:55 <dminuoso> THat may or may not make any sense to you.
00:38:20 <dminuoso> euouae: StateT allows you to drag some state around, while ExceptT allows you to throw exceptions.
00:38:33 <geekosaur> so, StateT doesn't just model state; it adds state to something. It transforms something else by adding state to it
00:38:35 <dminuoso> Them being transformers means you can layer them ontop of each other, giving you a Monad that has both state *and* exceptions.
00:39:00 <dminuoso> And if you add ListT (which adds non-determinism), you could have non-determinism, state and exceptions
00:39:17 <dminuoso> ANd you can layer it over IO to have state, non-determinism, exceptions and real world nuclear missile effects.
00:40:04 <dminuoso> euouae: Lets pick a more concrete examplee:
00:40:29 <dminuoso> euouae: Your megaparsec parser can run either in pure mode, or it can run together with IO.
00:40:55 <dminuoso> If you use it together with IO, you can interleave your parser with IO - say print statements or database calls
00:41:14 <dminuoso> The reason you can do this, is because all this parsing effect is in a transformer ParsecT which you can layer over any other monad.
00:41:25 merijn joins (~merijn@host-vr.cgnat-g.v4.dfn.nl)
00:41:46 <dminuoso> If you dont want IO, you can just layer it over `Identity`, which is sort of the "does nothing monad", giving you just the parsing effects.
00:42:06 <dminuoso> https://hackage.haskell.org/package/megaparsec-9.7.0/docs/Text-Megaparsec.html#t:Parsec
00:42:13 <dminuoso> type Parsec e s = ParsecT e s Identity
00:43:15 <dminuoso> You can also use `ParsecT e s IO`, then you can suddenly do `liftIO (putStrLn "Hello world")` in the middle of your parser. Note, that because megaparsec will do backtracking this will have some interesting/strange behavior... which is non-determinism in fact.
00:43:29 <dminuoso> (Assuming you use `try` of course)
00:44:15 <euouae> right
00:44:32 <euouae> I'm going to assume that it'll leak out the details of try
00:45:16 monochrm joins (trebla@216.138.220.146)
00:45:40 <euouae> I think my composable state machine intuition is running into trouble with StateT. Transformers seem like a different beast, I'll have to think about it more.
00:45:55 <euouae> But your example is very helpful, to keep in mind pure computation / IO stuff inside parsing
00:46:00 × merijn quits (~merijn@host-vr.cgnat-g.v4.dfn.nl) (Ping timeout: 252 seconds)
00:46:29 × monochrom quits (trebla@216.138.220.146) (Ping timeout: 260 seconds)
00:46:30 monochrm is now known as monochrom
00:48:52 mange joins (~user@user/mange)
00:48:53 <dminuoso> euouae: One last thing: That "funky composition" you talked about, that's where the monad lies. :-)
00:49:18 <dminuoso> Just keep that thought mind for the future
00:49:55 <dminuoso> % :t join
00:49:55 <yahb2> <interactive>:1:1: error: [GHC-88464] Variable not in scope: join
00:50:01 <dminuoso> % import Control.Monad
00:50:01 <yahb2> <no output>
00:50:03 <dminuoso> % :t join
00:50:03 <yahb2> join :: Monad m => m (m a) -> m a
00:50:58 <dminuoso> euouae: This is an alternate description of (>>=), and it perhaps visualizes nicely that there's a sort of composition idea going on.
00:51:10 <dminuoso> Anyway. This was just meant as a teaser.
00:51:47 rstromlund joins (~user@user/rstromlund)
00:52:28 alfiee joins (~alfiee@user/alfiee)
00:52:40 <int-e> @djinn ((((a -> r) -> r) -> r) -> r) -> (a -> r) -> r
00:52:41 <lambdabot> f a b = a (\ c -> c b)
00:53:06 × acidjnk_new3 quits (~acidjnk@p200300d6e7283f4679216c0ad7f4b91d.dip0.t-ipconnect.de) (Ping timeout: 246 seconds)
00:54:15 × xff0x quits (~xff0x@2405:6580:b080:900:704:c9bd:a645:9b1d) (Ping timeout: 276 seconds)
00:56:36 × alfiee quits (~alfiee@user/alfiee) (Ping timeout: 246 seconds)
00:56:40 × rstromlund quits (~user@user/rstromlund) (Ping timeout: 265 seconds)
00:56:47 merijn joins (~merijn@host-vr.cgnat-g.v4.dfn.nl)
01:01:09 × merijn quits (~merijn@host-vr.cgnat-g.v4.dfn.nl) (Ping timeout: 246 seconds)
01:02:24 × joeyadams quits (~joeyadams@syn-184-054-105-097.res.spectrum.com) (Quit: Leaving)
01:03:12 <hololeap> @unmtl StateT Int IO String
01:03:12 <lambdabot> Int -> IO (String, Int)
01:03:18 <hololeap> nice, there we go
01:12:12 × sprotte24 quits (~sprotte24@p200300d16f0f520069bfd2b9cee1df34.dip0.t-ipconnect.de) (Quit: Leaving)
01:12:20 merijn joins (~merijn@host-vr.cgnat-g.v4.dfn.nl)
01:16:32 × merijn quits (~merijn@host-vr.cgnat-g.v4.dfn.nl) (Ping timeout: 244 seconds)
01:18:49 rstromlund joins (~user@user/rstromlund)
01:20:44 × otto_s quits (~user@p5b0441ee.dip0.t-ipconnect.de) (Ping timeout: 260 seconds)
01:22:30 otto_s joins (~user@p5de2fd05.dip0.t-ipconnect.de)
01:24:26 monochrm joins (trebla@216.138.220.146)
01:25:58 × monochrom quits (trebla@216.138.220.146) (Ping timeout: 252 seconds)
01:25:58 monochrm is now known as monochrom
01:26:00 × bitdex quits (~bitdex@gateway/tor-sasl/bitdex) (Ping timeout: 264 seconds)
01:27:42 merijn joins (~merijn@host-vr.cgnat-g.v4.dfn.nl)
01:32:24 × merijn quits (~merijn@host-vr.cgnat-g.v4.dfn.nl) (Ping timeout: 260 seconds)
01:34:34 merijn joins (~merijn@host-vr.cgnat-g.v4.dfn.nl)
01:37:55 xff0x joins (~xff0x@fsb6a9491c.tkyc517.ap.nuro.jp)
01:38:26 × Sgeo quits (~Sgeo@user/sgeo) (Read error: Connection reset by peer)
01:38:57 × merijn quits (~merijn@host-vr.cgnat-g.v4.dfn.nl) (Ping timeout: 246 seconds)
01:38:58 × monochrom quits (trebla@216.138.220.146) (Ping timeout: 244 seconds)
01:39:26 monochrom joins (trebla@216.138.220.146)
01:41:13 alfiee joins (~alfiee@user/alfiee)
01:44:56 Sgeo joins (~Sgeo@user/sgeo)
01:45:59 × alfiee quits (~alfiee@user/alfiee) (Ping timeout: 265 seconds)
01:49:53 merijn joins (~merijn@host-vr.cgnat-g.v4.dfn.nl)
01:51:25 Square2 joins (~Square4@user/square)
01:54:28 × Square quits (~Square@user/square) (Ping timeout: 244 seconds)
01:54:44 × merijn quits (~merijn@host-vr.cgnat-g.v4.dfn.nl) (Ping timeout: 260 seconds)
02:04:16 × weary-traveler quits (~user@user/user363627) (Remote host closed the connection)
02:05:17 merijn joins (~merijn@host-vr.cgnat-g.v4.dfn.nl)
02:06:03 mikess joins (~mikess@user/mikess)
02:09:17 <euouae> why is `State s a` but `state :: a -> (a, s)`? the order is reversed
02:09:41 <euouae> sorry, I mean, state :: Monad m => (s -> (a, s)) -> StateT s m a
02:12:04 × merijn quits (~merijn@host-vr.cgnat-g.v4.dfn.nl) (Ping timeout: 260 seconds)
02:16:04 × Tuplanolla quits (~Tuplanoll@91-159-69-59.elisa-laajakaista.fi) (Quit: Leaving.)
02:23:20 merijn joins (~merijn@host-vr.cgnat-g.v4.dfn.nl)
02:25:04 × mikess quits (~mikess@user/mikess) (Ping timeout: 272 seconds)
02:26:30 × Sgeo quits (~Sgeo@user/sgeo) (Read error: Connection reset by peer)
02:29:10 Sgeo joins (~Sgeo@user/sgeo)
02:29:36 alfiee joins (~alfiee@user/alfiee)
02:31:58 × merijn quits (~merijn@host-vr.cgnat-g.v4.dfn.nl) (Ping timeout: 244 seconds)
02:33:37 Tikosh joins (~quassel@user/Tikosh)
02:34:24 × alfiee quits (~alfiee@user/alfiee) (Ping timeout: 260 seconds)
02:35:43 <Tikosh> https://www.youtube.com/watch?v=Qu0wtz6Z5RY
02:35:50 <Tikosh> oh sorry
02:35:56 <Tikosh> i thought this was gentoo-chat
02:36:00 <Tikosh> excuse me
02:43:07 merijn joins (~merijn@host-vr.cgnat-g.v4.dfn.nl)
02:46:01 monochrm joins (trebla@216.138.220.146)
02:47:28 × monochrom quits (trebla@216.138.220.146) (Ping timeout: 245 seconds)
02:47:29 monochrm is now known as monochrom
02:47:39 × merijn quits (~merijn@host-vr.cgnat-g.v4.dfn.nl) (Ping timeout: 260 seconds)
02:55:24 weary-traveler joins (~user@user/user363627)
02:55:54 × sarna quits (~sarna@d224-221.icpnet.pl) (Ping timeout: 252 seconds)
02:56:32 × rstromlund quits (~user@user/rstromlund) (Ping timeout: 252 seconds)
02:58:29 merijn joins (~merijn@host-vr.cgnat-g.v4.dfn.nl)
03:02:45 × merijn quits (~merijn@host-vr.cgnat-g.v4.dfn.nl) (Ping timeout: 248 seconds)
03:04:12 peterbecich joins (~Thunderbi@syn-047-229-123-186.res.spectrum.com)
03:04:44 × anpad quits (~pandeyan@user/anpad) (Quit: ZNC 1.8.2 - https://znc.in)
03:07:19 merijn joins (~merijn@host-vr.cgnat-g.v4.dfn.nl)
03:12:09 × merijn quits (~merijn@host-vr.cgnat-g.v4.dfn.nl) (Ping timeout: 260 seconds)
03:12:55 monochrm joins (trebla@216.138.220.146)
03:13:24 sarna joins (~sarna@d224-221.icpnet.pl)
03:14:03 × monochrom quits (trebla@216.138.220.146) (Ping timeout: 252 seconds)
03:14:04 monochrm is now known as monochrom
03:17:11 × Smiles quits (uid551636@id-551636.lymington.irccloud.com) (Quit: Connection closed for inactivity)
03:18:21 alfiee joins (~alfiee@user/alfiee)
03:22:33 × alfiee quits (~alfiee@user/alfiee) (Ping timeout: 246 seconds)
03:22:41 merijn joins (~merijn@host-vr.cgnat-g.v4.dfn.nl)
03:25:04 <monochrom> hololeap: @unmtl StateT s (ContT r IO) a
03:25:10 <monochrom> @unmtl StateT s (ContT r IO) a
03:25:10 <lambdabot> s -> (a -> s -> IO r) -> IO r
03:27:20 × merijn quits (~merijn@host-vr.cgnat-g.v4.dfn.nl) (Ping timeout: 252 seconds)
03:30:44 monochrm joins (trebla@216.138.220.146)
03:30:49 × monochrom quits (trebla@216.138.220.146) (Ping timeout: 260 seconds)
03:30:55 monochrm is now known as monochrom
03:31:25 <monochrom> The connection between the [] monad and state machines is at best this little: from the [] monad get the corresponding Kleisli arrow, then that would be nondeterministic state transition functions, i.e., of the form S -> [S].
03:32:34 <monochrom> But that is as quaint as saying: endofunctions S -> S "Is" deterministic state machines just because deterministic state transition functions are of the form S->S. Clearly, in both cases, you are still missing out on: Who is the initial state? Who are accept states?
03:33:07 <monochrom> I cannot accept (pun!) the confused conflation between state transition functions and state machines.
03:34:50 <monochrom> It's like saying that Int is (Int, Char) because Int is one field of (Int, Char).
03:38:04 merijn joins (~merijn@host-vr.cgnat-g.v4.dfn.nl)
03:43:04 × merijn quits (~merijn@host-vr.cgnat-g.v4.dfn.nl) (Ping timeout: 260 seconds)
03:44:33 × td_ quits (~td@i53870904.versanet.de) (Ping timeout: 252 seconds)
03:46:23 td_ joins (~td@i5387092E.versanet.de)
03:55:35 merijn joins (~merijn@host-vr.cgnat-g.v4.dfn.nl)
04:00:42 × machinedgod quits (~machinedg@d108-173-18-100.abhsia.telus.net) (Ping timeout: 272 seconds)
04:01:44 monochrm joins (trebla@216.138.220.146)
04:01:50 <euouae> so if you talk about state transition functions do you accept that monads are just composable state transition functions?
04:01:57 <euouae> and i.e. it applies to lists?
04:02:11 <euouae> as far as I can tell when you speak of the kleisli arrow you're just talking about lists of lists etc
04:03:38 × monochrom quits (trebla@216.138.220.146) (Ping timeout: 252 seconds)
04:03:38 monochrm is now known as monochrom
04:05:10 × merijn quits (~merijn@host-vr.cgnat-g.v4.dfn.nl) (Ping timeout: 265 seconds)
04:05:17 <monochrom> S->[S] is not list of list.
04:06:45 alfiee joins (~alfiee@user/alfiee)
04:06:47 <euouae> sure, [S]->[[S]] etc
04:06:58 <monochrom> And I don't see in what sense A -> Cont R A is state transition function.
04:07:28 <euouae> I'm not sure I follow but it's ok don't worry. I'm just doing some easy challenges on leetcode to get a grip on Haskell
04:07:40 × peterbecich quits (~Thunderbi@syn-047-229-123-186.res.spectrum.com) (Ping timeout: 252 seconds)
04:11:04 × alfiee quits (~alfiee@user/alfiee) (Ping timeout: 260 seconds)
04:15:57 merijn joins (~merijn@host-vr.cgnat-g.v4.dfn.nl)
04:20:34 × merijn quits (~merijn@host-vr.cgnat-g.v4.dfn.nl) (Ping timeout: 260 seconds)
04:25:40 aforemny joins (~aforemny@i577B135A.versanet.de)
04:26:14 × aforemny_ quits (~aforemny@2001:9e8:6ce3:9600:2c48:7088:cbda:dd4) (Ping timeout: 260 seconds)
04:30:17 × euleritian quits (~euleritia@ip4d17fae8.dynamic.kabel-deutschland.de) (Read error: Connection reset by peer)
04:30:33 euleritian joins (~euleritia@ip4d17fae8.dynamic.kabel-deutschland.de)
04:31:21 merijn joins (~merijn@host-vr.cgnat-g.v4.dfn.nl)
04:34:55 × euleritian quits (~euleritia@ip4d17fae8.dynamic.kabel-deutschland.de) (Read error: Connection reset by peer)
04:35:50 euleritian joins (~euleritia@ip4d17fae8.dynamic.kabel-deutschland.de)
04:35:53 × merijn quits (~merijn@host-vr.cgnat-g.v4.dfn.nl) (Ping timeout: 252 seconds)
04:43:01 × kritzefitz quits (~kritzefit@debian/kritzefitz) (Ping timeout: 248 seconds)
04:43:08 × pavonia quits (~user@user/siracusa) (Quit: Bye!)
04:46:43 merijn joins (~merijn@host-vr.cgnat-g.v4.dfn.nl)
04:48:55 monochrm joins (trebla@216.138.220.146)
04:50:36 × monochrom quits (trebla@216.138.220.146) (Ping timeout: 265 seconds)
04:50:37 monochrm is now known as monochrom
04:51:13 × merijn quits (~merijn@host-vr.cgnat-g.v4.dfn.nl) (Ping timeout: 245 seconds)
04:51:15 michalz joins (~michalz@185.246.207.221)
04:53:07 bitdex joins (~bitdex@gateway/tor-sasl/bitdex)
04:55:09 alfiee joins (~alfiee@user/alfiee)
04:55:16 merijn joins (~merijn@host-vr.cgnat-g.v4.dfn.nl)
04:59:13 × alfiee quits (~alfiee@user/alfiee) (Ping timeout: 244 seconds)
05:00:14 × merijn quits (~merijn@host-vr.cgnat-g.v4.dfn.nl) (Ping timeout: 272 seconds)
05:02:27 Digitteknohippie joins (~user@user/digit)
05:04:05 × tabaqui1 quits (~root@87.200.129.102) (Ping timeout: 244 seconds)
05:06:14 × Digit quits (~user@user/digit) (Killed (copper.libera.chat (Nickname regained by services)))
05:06:14 Digitteknohippie is now known as Digit
05:06:56 Guest8048 joins (~user@250.88.90.146.dyn.plus.net)
05:07:41 × Guest8048 quits (~user@250.88.90.146.dyn.plus.net) (Remote host closed the connection)
05:08:19 merijn joins (~merijn@host-vr.cgnat-g.v4.dfn.nl)
05:13:42 × califax quits (~califax@user/califx) (Remote host closed the connection)
05:13:59 califax joins (~califax@user/califx)
05:14:54 × merijn quits (~merijn@host-vr.cgnat-g.v4.dfn.nl) (Ping timeout: 246 seconds)
05:23:33 × monochrom quits (trebla@216.138.220.146) (Ping timeout: 248 seconds)
05:26:22 merijn joins (~merijn@host-vr.cgnat-g.v4.dfn.nl)
05:27:20 monochrom joins (trebla@216.138.220.146)
05:31:13 × merijn quits (~merijn@host-vr.cgnat-g.v4.dfn.nl) (Ping timeout: 265 seconds)
05:33:16 vanishingideal joins (~vanishing@user/vanishingideal)
05:37:22 takuan joins (~takuan@d8D86B601.access.telenet.be)
05:41:45 merijn joins (~merijn@host-vr.cgnat-g.v4.dfn.nl)
05:43:45 × Tikosh quits (~quassel@user/Tikosh) (Remote host closed the connection)
05:43:49 monochrm joins (trebla@216.138.220.146)
05:44:13 alfiee joins (~alfiee@user/alfiee)
05:44:44 × monochrom quits (trebla@216.138.220.146) (Ping timeout: 265 seconds)
05:44:45 monochrm is now known as monochrom
05:44:48 ensyde joins (~ensyde@2601:5c6:c200:6dc0::64a2)
05:46:44 × merijn quits (~merijn@host-vr.cgnat-g.v4.dfn.nl) (Ping timeout: 260 seconds)
05:48:29 × alfiee quits (~alfiee@user/alfiee) (Ping timeout: 260 seconds)
05:54:59 tnt2 joins (~Thunderbi@user/tnt1)
05:55:23 × rvalue quits (~rvalue@user/rvalue) (Read error: Connection reset by peer)
05:55:29 × tnt1 quits (~Thunderbi@user/tnt1) (Ping timeout: 260 seconds)
05:55:29 tnt2 is now known as tnt1
05:55:55 rvalue joins (~rvalue@user/rvalue)
05:57:07 merijn joins (~merijn@host-vr.cgnat-g.v4.dfn.nl)
06:01:42 × merijn quits (~merijn@host-vr.cgnat-g.v4.dfn.nl) (Ping timeout: 252 seconds)
06:03:22 monochrm joins (trebla@216.138.220.146)
06:03:32 × vanishingideal quits (~vanishing@user/vanishingideal) (Ping timeout: 252 seconds)
06:04:50 × monochrom quits (trebla@216.138.220.146) (Ping timeout: 244 seconds)
06:04:50 monochrm is now known as monochrom
06:09:19 merijn joins (~merijn@host-vr.cgnat-g.v4.dfn.nl)
06:13:43 × merijn quits (~merijn@host-vr.cgnat-g.v4.dfn.nl) (Ping timeout: 245 seconds)
06:15:48 × ft quits (~ft@p3e9bcd97.dip0.t-ipconnect.de) (Quit: leaving)
06:24:06 × weary-traveler quits (~user@user/user363627) (Remote host closed the connection)
06:24:42 merijn joins (~merijn@host-vr.cgnat-g.v4.dfn.nl)
06:24:48 Square joins (~Square@user/square)
06:26:18 × alp quits (~alp@2001:861:8ca0:4940:465c:30a2:2211:b30f) (Remote host closed the connection)
06:26:35 alp joins (~alp@2001:861:8ca0:4940:465c:30a2:2211:b30f)
06:28:54 × Square2 quits (~Square4@user/square) (Ping timeout: 260 seconds)
06:29:09 × merijn quits (~merijn@host-vr.cgnat-g.v4.dfn.nl) (Ping timeout: 248 seconds)
06:32:37 alfiee joins (~alfiee@user/alfiee)
06:33:09 × euleritian quits (~euleritia@ip4d17fae8.dynamic.kabel-deutschland.de) (Ping timeout: 252 seconds)
06:33:23 euleritian joins (~euleritia@dynamic-176-006-140-003.176.6.pool.telefonica.de)
06:36:53 × alfiee quits (~alfiee@user/alfiee) (Ping timeout: 252 seconds)
06:36:58 CiaoSen joins (~Jura@2a05:5800:263:8800:ca4b:d6ff:fec1:99da)
06:38:45 × tomboy64 quits (~tomboy64@user/tomboy64) (Ping timeout: 248 seconds)
06:40:05 merijn joins (~merijn@host-vr.cgnat-g.v4.dfn.nl)
06:42:24 tomboy64 joins (~tomboy64@user/tomboy64)
06:42:25 × tv quits (~tv@user/tv) (Read error: Connection reset by peer)
06:45:04 × merijn quits (~merijn@host-vr.cgnat-g.v4.dfn.nl) (Ping timeout: 260 seconds)
06:47:37 <euouae> heh, cool. I didn't expect to use the State monad so soon after I learned about it but the leetcode problem needed a list of primes
06:47:44 <euouae> and I implemented eratosthenes sieve: <https://paste.tomsmeding.com/vm6F8jXA>
06:48:19 <euouae> I'm happy with how this turned out, looks very natural
06:48:36 <euouae> I couldn't figure out if it could be done with list comprehension
06:52:03 anpad joins (~pandeyan@user/anpad)
06:54:35 <ski> cycle [x] = repeat x
06:54:59 <ski> you could just pass on the filtered list in an accumulator parameter of a recursive function
06:55:28 merijn joins (~merijn@host-vr.cgnat-g.v4.dfn.nl)
07:01:09 AlexNoo_ joins (~AlexNoo@5.139.233.186)
07:02:00 × AlexZenon quits (~alzenon@178.34.150.8) (Ping timeout: 246 seconds)
07:02:12 × merijn quits (~merijn@host-vr.cgnat-g.v4.dfn.nl) (Ping timeout: 252 seconds)
07:03:19 × AlexNoo quits (~AlexNoo@178.34.150.8) (Ping timeout: 260 seconds)
07:05:23 <euouae> that's true, but then how do you produce the infinite list? like (x : f rest)?
07:06:03 AlexZenon joins (~alzenon@5.139.233.186)
07:07:58 <dminuoso> euouae │ why is `State s a` but `state :: a -> (a, s)`? the order is reversed
07:08:05 × anpad quits (~pandeyan@user/anpad) (Quit: ZNC 1.8.2 - https://znc.in)
07:08:29 <dminuoso> The type order is often influenced by typeclasses you want to satisfy.
07:08:47 <euouae> right, for State. but why state?
07:09:23 <dminuoso> So consider `instance Functor (State s)`, we cannot write `instance Functor (State _ a)`, so we reorder the types accordingly.
07:09:40 <dminuoso> Sorry, that second one should have read `instance Functor (State _ s)`
07:10:20 merijn joins (~merijn@host-vr.cgnat-g.v4.dfn.nl)
07:10:20 <dminuoso> euouae: So the order of arguments usually follows convenience with related functions.
07:10:27 <dminuoso> And that can be quite subjective
07:10:54 <dminuoso> Say you envision `state` to be used with `fmap` to map over the *state*, because that's how you (the author) like to use it, and assume others to frequently use it too.
07:12:24 anpad joins (~pandeyan@user/anpad)
07:12:31 <dminuoso> Since fmap on a 2-tuple maps over the second argument (which too has to do with the fact that we cant just have `instance Functor (a,)` but are forced to have `instance Functor (a,)` if we were allowed to write sections in type (we have to specify write it as `instance Functor ((,) a) in reality)
07:13:22 <euouae> I'm actually not sure what fmap with state does, I'd have to think about it
07:13:29 <euouae> but OK if fmap is one of the reasons then I can see it
07:13:48 <dminuoso> Im not sure whether that was actually the reason, keep that in mind.
07:14:20 <dminuoso> euouae: One other fact that often influence parameter order, is which parameters you expect to be partially applied.
07:15:01 × merijn quits (~merijn@host-vr.cgnat-g.v4.dfn.nl) (Ping timeout: 248 seconds)
07:15:33 <dminuoso> Say if you have `f :: S -> T -> A -> X`, and for some reason its likely you or other users will use it as `x (f s t)`, this is far more comfortable than writing `x (\a -> f a s t)`, so you turn things around to enable more point-free notation
07:15:41 <glguy> The order is forced because it is intended to be a Monad
07:15:54 <dminuoso> glguy: They meant why `state :: a -> (a, s)` in particular.
07:16:10 × anpad quits (~pandeyan@user/anpad) (Client Quit)
07:16:45 <glguy> The tuple order? There's no reason one way or the other and you can find implementations using both
07:17:09 <dminuoso> Yeah. I guess no reason is also possible.
07:17:10 <ski> euouae : "like (x : f rest)?" -- yes
07:18:43 <dminuoso> glguy: In my experience the tuple order is usually picked based on how the author use fmap or sections with those tuples.
07:18:53 <dminuoso> Which can be very subjective, still.
07:20:01 <euouae> ski, isn't that less efficient?
07:20:08 <ski> than what ?
07:20:57 <euouae> than what I have, doesn't it get into N levels of stack frames?
07:21:17 <ski> dunno what you mean
07:21:21 alfiee joins (~alfiee@user/alfiee)
07:21:55 <ski> but doing `f ... = x : f (...)' is in general not inherently inefficient
07:22:03 <dminuoso> In Haskell, anyway.
07:22:14 <dminuoso> Or GHC Haskell, one should say.
07:22:18 <euouae> I don't know how evaluation works in Haskell well enough to understand that, but (x : f rest) is not tail-called, right? It must have O(n) memory for n steps
07:22:34 <euouae> on top of the O(n) for the list itself, so arguably doesn't matter
07:22:34 <ski> it'll produce the result `x', and then, if you decide to ask for more elements, only then will the recursive call computation happen
07:22:54 <dminuoso> euouae: In GHC Haskell, evaluation model works vastly different from traditional programming languages. We dont exactly push to a stack at the beginning of a function and pop at the end.
07:22:55 <ski> it's incremental, rather than tail-calling
07:23:21 <euouae> dminuoso: is there hope to understand it for non experts or is it too difficult?
07:23:39 <ski> think of the list generated as an iterator, if you like
07:23:58 <ski> the caller controls how much of it is materialized
07:24:03 <euouae> Oh I understand that much (i.e. what you explained here ski), but in general to understand the Haskell evaluation
07:24:13 <euouae> i.e. what happens under the hood via ghc
07:24:32 <dminuoso> euouae: Imagine the program was kept *textually* as you wrote it, and evaluation is just substitution.
07:24:42 <ski> GHC does lazy evaulation, meaning demand-driven, with caching of intermediate results
07:25:00 <euouae> What does caching mean?
07:25:31 <euouae> Why would it remember intermediate results? for what purpose?
07:25:41 merijn joins (~merijn@host-vr.cgnat-g.v4.dfn.nl)
07:25:42 <dminuoso> Consider `let x = <expensive computation> in (x, x)`
07:25:54 × alfiee quits (~alfiee@user/alfiee) (Ping timeout: 260 seconds)
07:26:07 monochrm joins (trebla@216.138.220.146)
07:26:09 × monochrom quits (trebla@216.138.220.146) (Ping timeout: 248 seconds)
07:26:21 <euouae> okay right. hm...
07:26:24 monochrm is now known as monochrom
07:26:48 <ski> it means that in `let x = 2 * 2 in x + x', first the `x + x' starts to happen, then that demands the result of `x', so `2 * 2' happens, result `4'. now it *remembers* (caches) that `x' resulted in `4', so that when the second `x' in `x + x' is checked, it reuses the `4', to compute `4 + 4', rather than performing the multiplication twice
07:27:05 <euouae> so about laziness, how exactly is it accomplished in ghc?
07:27:21 <euouae> does it keep track of the source code instead of computing it? and just computes when necessary?
07:27:22 <ski> same thing happens, if you define `f x = x + x', and then call `f (2 * 2)'
07:27:44 <ski> "does it keep track of the source code" -- no
07:27:51 <dminuoso> euouae: No, we encode the whole program into what we call a spineless tagless G-machine
07:27:58 <dminuoso> Which is a very efficient way of programming to native code.
07:28:04 <dminuoso> s/programming/translating/
07:28:18 <dminuoso> euouae: Semantically you can imagine it kept the source code and just substituted.
07:28:36 <dminuoso> With sharing whenever possible
07:28:41 <euouae> <https://www.microsoft.com/en-us/research/wp-content/uploads/1992/04/spineless-tagless-gmachine.pdf> is a good intro to that?
07:28:43 <euouae> I'm kind of curious
07:28:45 <dminuoso> (Well not quite *whenever* ...)
07:29:22 <dminuoso> euouae: Give it a try, and see how far you go. If your mind explodes, put the paper aside for a future read.
07:29:33 <ski> @where lazy
07:29:33 <lambdabot> "Lazy Evaluation of Haskell" by monochrom at <http://www.vex.net/~trebla/haskell/lazy.xhtml>; "The Incomplete Guide to Lazy Evaluation (in Haskell)" by apfelmus in 2015-03-07 at <https://apfelmus.
07:29:33 <lambdabot> nfshost.com/articles/lazy-eval.html>; "Laziness, strictness, guarded recursion" by bitemyapp at <https://github.com/bitemyapp/learnhaskell/blob/master/specific_topics.md#user-content-laziness-
07:29:33 <lambdabot> strictness-guarded-recursion>
07:29:39 <ski> check that first
07:29:47 <euouae> firstlink or all?
07:30:04 <ski> first link
07:30:26 <euouae> Alright, thank you. I've got some cool stuff for the days ahead.
07:30:34 × merijn quits (~merijn@host-vr.cgnat-g.v4.dfn.nl) (Ping timeout: 260 seconds)
07:31:23 <dminuoso> euouae: Ultimately we can achieve very good performance with our approach, sometimes comparable to C++ or Rust with careful programming (though to be honest even those languages require careful treatment to obtain optimal performance). STG is *that* good.
07:33:12 monochrm joins (trebla@216.138.220.146)
07:33:25 <dminuoso> (Though GHC has a lot of other tricks up its sleeve to make that possible, so its not just STG)
07:35:15 × monochrom quits (trebla@216.138.220.146) (Ping timeout: 244 seconds)
07:35:15 monochrm is now known as monochrom
07:37:44 Smiles joins (uid551636@id-551636.lymington.irccloud.com)
07:40:00 <euouae> neat, it's probably beyond what I can grasp but it's probably still worth looking into
07:41:03 merijn joins (~merijn@host-vr.cgnat-g.v4.dfn.nl)
07:46:21 × merijn quits (~merijn@host-vr.cgnat-g.v4.dfn.nl) (Ping timeout: 276 seconds)
07:49:36 × euouae quits (~euouae@user/euouae) ()
07:51:27 <dminuoso> % fromIntegral (0xffffff :: Word16) :: Word8
07:51:27 <yahb2> <interactive>:97:15: warning: [GHC-97441] [-Woverflowed-literals] ; Literal 16777215 is out of the Word16 range 0..65535 ; ; 255
07:51:52 × Square quits (~Square@user/square) (Ping timeout: 272 seconds)
07:52:03 <dminuoso> I'm staring at some Haskell code that explicitly masks with 0xff before fromIntegral, is that strictly necessary or can I rely on truncation like this?
07:54:31 falafel joins (~falafel@syn-076-093-010-089.res.spectrum.com)
07:56:25 merijn joins (~merijn@host-vr.cgnat-g.v4.dfn.nl)
07:58:51 tnt2 joins (~Thunderbi@user/tnt1)
07:59:02 × tnt1 quits (~Thunderbi@user/tnt1) (Ping timeout: 252 seconds)
07:59:02 tnt2 is now known as tnt1
08:00:02 × caconym quits (~caconym@user/caconym) (Quit: bye)
08:00:41 caconym joins (~caconym@user/caconym)
08:01:04 × merijn quits (~merijn@host-vr.cgnat-g.v4.dfn.nl) (Ping timeout: 260 seconds)
08:01:32 sord937 joins (~sord937@gateway/tor-sasl/sord937)
08:02:05 × euleritian quits (~euleritia@dynamic-176-006-140-003.176.6.pool.telefonica.de) (Read error: Connection reset by peer)
08:02:23 euleritian joins (~euleritia@ip4d17fae8.dynamic.kabel-deutschland.de)
08:05:03 ljdarj joins (~Thunderbi@user/ljdarj)
08:06:59 × rvalue quits (~rvalue@user/rvalue) (Read error: Connection reset by peer)
08:07:30 rvalue joins (~rvalue@user/rvalue)
08:09:45 alfiee joins (~alfiee@user/alfiee)
08:11:19 merijn joins (~merijn@host-vr.cgnat-g.v4.dfn.nl)
08:13:09 anpad joins (~pandeyan@user/anpad)
08:13:58 sawilagar joins (~sawilagar@user/sawilagar)
08:14:04 × alfiee quits (~alfiee@user/alfiee) (Ping timeout: 252 seconds)
08:15:48 × merijn quits (~merijn@host-vr.cgnat-g.v4.dfn.nl) (Ping timeout: 245 seconds)
08:16:57 eL_Bart0 joins (eL_Bart0@dietunichtguten.org)
08:21:01 × anpad quits (~pandeyan@user/anpad) (Quit: ZNC 1.8.2 - https://znc.in)
08:23:39 × tcard quits (~tcard@2400:4051:5801:7500:cf17:befc:ff82:5303) (Quit: Leaving)
08:24:38 × user__ quits (~user@user/fmira) (Remote host closed the connection)
08:25:18 merijn joins (~merijn@host-vr.cgnat-g.v4.dfn.nl)
08:25:37 acidjnk_new3 joins (~acidjnk@p200300d6e7283f830c2bc91cde612e63.dip0.t-ipconnect.de)
08:27:08 ash3en joins (~Thunderbi@2a03:7846:b6eb:101:93ac:a90a:da67:f207)
08:29:36 × emmanuelux quits (~emmanuelu@user/emmanuelux) (Quit: au revoir)
08:30:48 anpad joins (~pandeyan@user/anpad)
08:30:58 danza joins (~danza@user/danza)
08:32:40 × Googulator quits (~Googulato@2a01-036d-0106-1666-e945-fd21-b920-9aa7.pool6.digikabel.hu) (Ping timeout: 240 seconds)
08:36:56 tcard joins (~tcard@2400:4051:5801:7500:cf17:befc:ff82:5303)
08:39:50 × anpad quits (~pandeyan@user/anpad) (Quit: ZNC 1.8.2 - https://znc.in)
08:47:41 chele joins (~chele@user/chele)
08:48:10 × nullie quits (~nullie@nuremberg.nullie.name) (Read error: Connection reset by peer)
08:49:54 × falafel quits (~falafel@syn-076-093-010-089.res.spectrum.com) (Ping timeout: 260 seconds)
08:51:35 nullie joins (~nullie@nuremberg.nullie.name)
08:54:37 danz55770 joins (~danza@user/danza)
08:56:36 × danza quits (~danza@user/danza) (Ping timeout: 252 seconds)
08:58:03 anpad joins (~pandeyan@user/anpad)
08:58:29 alfiee joins (~alfiee@user/alfiee)
08:59:37 × danz55770 quits (~danza@user/danza) (Remote host closed the connection)
08:59:52 danza joins (~danza@user/danza)
08:59:55 AlexNoo__ joins (~AlexNoo@5.139.233.186)
09:00:11 AlexZenon_2 joins (~alzenon@5.139.233.186)
09:00:32 monochrm joins (trebla@216.138.220.146)
09:00:33 × monochrom quits (trebla@216.138.220.146) (Ping timeout: 248 seconds)
09:00:48 monochrm is now known as monochrom
09:01:42 × AlexZenon quits (~alzenon@5.139.233.186) (Ping timeout: 246 seconds)
09:02:45 × alfiee quits (~alfiee@user/alfiee) (Ping timeout: 246 seconds)
09:03:06 × AlexNoo_ quits (~AlexNoo@5.139.233.186) (Ping timeout: 246 seconds)
09:06:07 × CiaoSen quits (~Jura@2a05:5800:263:8800:ca4b:d6ff:fec1:99da) (Ping timeout: 252 seconds)
09:06:35 <c_wraith> depends on the type you're coming from, as it's going to depend on how fromInteger is implemented
09:07:12 × anpad quits (~pandeyan@user/anpad) (Quit: ZNC 1.8.2 - https://znc.in)
09:07:55 × nullie quits (~nullie@nuremberg.nullie.name) (Quit: WeeChat 4.2.2)
09:11:32 anpad joins (~pandeyan@user/anpad)
09:11:39 × anpad quits (~pandeyan@user/anpad) (Remote host closed the connection)
09:12:32 × Sgeo quits (~Sgeo@user/sgeo) (Read error: Connection reset by peer)
09:17:05 × danza quits (~danza@user/danza) ()
09:19:52 monochrm joins (trebla@216.138.220.146)
09:20:20 anpad joins (~pandeyan@user/anpad)
09:20:44 × ash3en quits (~Thunderbi@2a03:7846:b6eb:101:93ac:a90a:da67:f207) (Quit: ash3en)
09:20:59 × monochrom quits (trebla@216.138.220.146) (Ping timeout: 260 seconds)
09:21:00 monochrm is now known as monochrom
09:22:36 × anpad quits (~pandeyan@user/anpad) (Client Quit)
09:24:40 <c_wraith> err. that's backwards. The type you're coming from provides the toInteger implementation, which should always be exact. fromInteger depends on the destination type.
09:29:58 anpad joins (~pandeyan@user/anpad)
09:30:08 alecs joins (~alecs@nat16.software.imdea.org)
09:35:03 fp1 joins (~Thunderbi@wireless-86-50-140-50.open.aalto.fi)
09:36:05 × anpad quits (~pandeyan@user/anpad) (Quit: ZNC 1.8.2 - https://znc.in)
09:39:41 × tzh quits (~tzh@c-76-115-131-146.hsd1.or.comcast.net) (Quit: zzz)
09:40:06 × fp1 quits (~Thunderbi@wireless-86-50-140-50.open.aalto.fi) (Ping timeout: 276 seconds)
09:40:22 swamp_ joins (~zmt00@user/zmt00)
09:44:00 × zmt01 quits (~zmt00@user/zmt00) (Ping timeout: 276 seconds)
09:44:50 danza joins (~danza@user/danza)
09:46:53 alfiee joins (~alfiee@user/alfiee)
09:47:03 × xff0x quits (~xff0x@fsb6a9491c.tkyc517.ap.nuro.jp) (Ping timeout: 245 seconds)
09:47:59 <tomsmeding> dminuoso: what are the source and destination types? :p
09:48:17 <tomsmeding> oh the destination type is Word8? then what c_wraith said
09:51:08 × alfiee quits (~alfiee@user/alfiee) (Ping timeout: 244 seconds)
09:51:41 × econo_ quits (uid147250@id-147250.tinside.irccloud.com) (Quit: Connection closed for inactivity)
09:51:42 × alecs quits (~alecs@nat16.software.imdea.org) (Ping timeout: 252 seconds)
09:57:06 anpad joins (~pandeyan@user/anpad)
09:59:38 × anpad quits (~pandeyan@user/anpad) (Client Quit)
10:00:54 kritzefitz joins (~kritzefit@debian/kritzefitz)
10:03:22 anpad joins (~pandeyan@user/anpad)
10:07:36 CiaoSen joins (~Jura@2a05:5800:263:8800:ca4b:d6ff:fec1:99da)
10:24:05 ubert joins (~Thunderbi@2a02:8109:ab8a:5a00:a8f9:39f9:ef80:a859)
10:35:57 alfiee joins (~alfiee@user/alfiee)
10:39:00 × anpad quits (~pandeyan@user/anpad) (Ping timeout: 252 seconds)
10:40:13 × alfiee quits (~alfiee@user/alfiee) (Ping timeout: 244 seconds)
10:41:52 SlackCoder joins (~SlackCode@64-94-63-8.ip.weststar.net.ky)
10:43:03 anpad joins (~pandeyan@user/anpad)
10:46:59 × kmein quits (~weechat@user/kmein) (Quit: ciao kakao)
10:47:22 kmein joins (~weechat@user/kmein)
10:50:49 ash3en joins (~Thunderbi@2a03:7846:b6eb:101:93ac:a90a:da67:f207)
10:56:23 × kmein quits (~weechat@user/kmein) (Quit: ciao kakao)
10:56:44 kmein joins (~weechat@user/kmein)
11:00:15 monochrm joins (trebla@216.138.220.146)
11:01:09 × monochrom quits (trebla@216.138.220.146) (Ping timeout: 260 seconds)
11:01:09 monochrm is now known as monochrom
11:03:20 zmt01 joins (~zmt00@user/zmt00)
11:07:12 × swamp_ quits (~zmt00@user/zmt00) (Ping timeout: 276 seconds)
11:08:53 × mange quits (~user@user/mange) (Remote host closed the connection)
11:12:21 tv joins (~tv@user/tv)
11:18:46 JuanDaugherty joins (~juan@user/JuanDaugherty)
11:21:10 × auri quits (~auri@fsf/member/auri) (Quit: No Ping reply in 210 seconds.)
11:25:01 alfiee joins (~alfiee@user/alfiee)
11:25:26 ljdarj1 joins (~Thunderbi@user/ljdarj)
11:28:30 × ljdarj quits (~Thunderbi@user/ljdarj) (Ping timeout: 252 seconds)
11:28:30 ljdarj1 is now known as ljdarj
11:29:03 × alfiee quits (~alfiee@user/alfiee) (Ping timeout: 246 seconds)
11:37:33 × danza quits (~danza@user/danza) (Ping timeout: 252 seconds)
11:37:33 × nckx quits (nckx@libera/staff/owl/nckx) (Ping timeout: 608 seconds)
11:38:16 × ell quits (~ellie@user/ellie) (Quit: Ping timeout (120 seconds))
11:38:34 ell joins (~ellie@user/ellie)
11:38:37 × anpad quits (~pandeyan@user/anpad) (Quit: ZNC 1.8.2 - https://znc.in)
11:44:21 anpad joins (~pandeyan@user/anpad)
11:48:10 × troydm quits (~troydm@user/troydm) (Quit: What is Hope? That all of your wishes and all of your dreams come true? To turn back time because things were not supposed to happen like that (C) Rau Le Creuset)
11:51:00 × Digit quits (~user@user/digit) (Ping timeout: 244 seconds)
11:53:29 JuanDaugherty is now known as ColinRobinson
11:57:05 AkechiShiro joins (~licht@user/akechishiro)
11:59:21 Guest64 joins (~Guest64@2600:387:f:7e17::1)
12:00:21 × Guest64 quits (~Guest64@2600:387:f:7e17::1) (Client Quit)
12:00:28 Guest94 joins (~Guest64@2600:387:f:7e12::b)
12:04:12 × Guest94 quits (~Guest64@2600:387:f:7e12::b) (Client Quit)
12:04:31 Guest64 joins (~Guest64@2600:387:f:7e12::b)
12:04:47 jespada joins (~jespada@2800:a4:2213:dd00:8c24:32fa:8fb8:ea12)
12:05:22 <kaol> My favorite thing about ghci is :set -freverse-errors.
12:10:53 × Guest64 quits (~Guest64@2600:387:f:7e12::b) (Quit: Client closed)
12:13:13 <merijn> kaol: That's one of my default GHC settings :p
12:13:44 alfiee joins (~alfiee@user/alfiee)
12:15:16 <haskellbridge> <sm> interesting
12:15:32 <haskellbridge> <sm> why is it better ?
12:15:44 × ColinRobinson quits (~juan@user/JuanDaugherty) (Quit: praxis.meansofproduction.biz (juan@acm.org))
12:16:51 <kaol> Because lines earlier in a source file are more likely to cause further errors later.
12:17:24 <kaol> If there are a lot of errors they have all scrolled into oblivion.
12:18:14 xff0x joins (~xff0x@ai096095.d.east.v6connect.net)
12:18:19 × alfiee quits (~alfiee@user/alfiee) (Ping timeout: 260 seconds)
12:18:41 <kaol> And the first error is going to be in a fixed place in a regular terminal. With the default I have to scan vertically to even find it.
12:19:29 × monochrom quits (trebla@216.138.220.146) (Ping timeout: 248 seconds)
12:20:41 monochrom joins (trebla@216.138.220.146)
12:20:54 × SlackCoder quits (~SlackCode@64-94-63-8.ip.weststar.net.ky) (Quit: Leaving)
12:20:56 ft joins (~ft@p3e9bcd97.dip0.t-ipconnect.de)
12:22:16 __monty__ joins (~toonn@user/toonn)
12:26:09 L29Ah parts (~L29Ah@wikipedia/L29Ah) ()
12:36:37 × monochrom quits (trebla@216.138.220.146) (Ping timeout: 248 seconds)
12:39:27 × ash3en quits (~Thunderbi@2a03:7846:b6eb:101:93ac:a90a:da67:f207) (Quit: ash3en)
12:40:25 monochrom joins (trebla@216.138.220.146)
12:44:40 AlexNoo__ is now known as AlexNoo
12:48:04 laxmik joins (~laxmik@wifi-gate-eduroam.fzu.cz)
12:48:31 laxmik is now known as michals
12:49:36 × michals quits (~laxmik@wifi-gate-eduroam.fzu.cz) (Client Quit)
12:51:00 × iamsleepy quits (~weechat@2a01:4f9:3070:feff:a9de:dfff:cd7f:fdcd) (Read error: Connection reset by peer)
12:51:25 iamsleepy joins (~weechat@2a01:4f9:3070:feff:d8a:11d8:7a8b:29a2)
12:51:29 <dminuoso> c_wraith, tomsmeding: Mmm okay, this is not very satisfying. The actual answer is buried behind CMM implementation details of some primops then.
12:51:43 <dminuoso> Maybe I need to consult the Haskell Report.
12:52:10 <dminuoso> instance Num Word8 where
12:52:15 <dminuoso> fromInteger i = W8# (wordToWord8# (integerToWord# i))
12:53:43 × bitdex quits (~bitdex@gateway/tor-sasl/bitdex) (Remote host closed the connection)
12:54:08 bitdex joins (~bitdex@gateway/tor-sasl/bitdex)
12:54:50 <haskellbridge> <sm> kaol: I can't quite relate to that. I feel the first error is more likely to be the causative one, and I am generally using either VS code or ghcid which shows it
12:55:32 <dminuoso> And the Haskell Report has no guidance on the behavior of fromInteger either.
12:55:40 <dminuoso> I'm not impressed.
12:55:48 lortabac joins (~lortabac@2a01:e0a:541:b8f0:55ab:e185:7f81:54a4)
12:56:21 alexherbo2 joins (~alexherbo@2a02-8440-3504-8116-f81b-81aa-4344-3e67.rev.sfr.net)
12:57:16 <tomsmeding> kaol: this is what ghcid does correctly, it shows only the top screenful of errors :p
13:02:30 alfiee joins (~alfiee@user/alfiee)
13:03:34 <kaol> ghcid doesn't really fit my use patterns. Once I get it to compile I usually want to try out a few things with my new functions in the repl.
13:03:58 <haskellbridge> <sm> ghcid gets its own window, of course
13:04:17 <__monty__> You can invert the order of errors reported by GHC FYI.
13:05:08 <geekosaur> that was what started this thread
13:06:07 <__monty__> Ah, carry on.
13:06:39 × alfiee quits (~alfiee@user/alfiee) (Ping timeout: 244 seconds)
13:07:09 <kaol> I'm thinking of using inotify to use xdotool to send that :r up enter. Then I would have the code loaded in it already and not have to look at two windows and still do :r up enter.
13:08:08 <kaol> No wait, up enter is only relevat if I use history.
13:08:13 <geekosaur> that sounds like a hacky way to reinvent ghcid/ghciwatch
13:08:23 <kaol> ghcid is the hack.
13:09:02 <kaol> Give me something that integrates with the repl.
13:14:55 × jespada quits (~jespada@2800:a4:2213:dd00:8c24:32fa:8fb8:ea12) (Ping timeout: 244 seconds)
13:17:44 jespada joins (~jespada@2800:a4:2215:4d00:20a9:6cd:d7c4:a65f)
13:19:59 AlexZenon_2 is now known as AlexZenon
13:27:35 <haskellbridge> <sm> ghcid is a hack of the gods, then :)
13:27:39 <haskellbridge> <sm> love it
13:28:25 <haskellbridge> <sm> kaol: you might like this small improvement in .ghci, I find it very useful:
13:28:25 <haskellbridge> ... long message truncated: https://kf8nh.com/_heisenbridge/media/kf8nh.com/sCYnuCtwPTknTRbDePLKlYOX/yxjBbcu9HSA (3 lines)
13:29:01 × alexherbo2 quits (~alexherbo@2a02-8440-3504-8116-f81b-81aa-4344-3e67.rev.sfr.net) (Remote host closed the connection)
13:29:15 <haskellbridge> <sm> it means I can just CTRL-p, enter after a change
13:29:52 <haskellbridge> <sm> or up enter, as you say
13:30:24 × p3n quits (~p3n@2a00:19a0:3:7c:0:d9c6:7cf6:1) (Quit: ZNC 1.9.1 - https://znc.in)
13:31:14 × CiaoSen quits (~Jura@2a05:5800:263:8800:ca4b:d6ff:fec1:99da) (Ping timeout: 260 seconds)
13:31:30 <haskellbridge> <sm> what about https://hackage.haskell.org/package/rapid-0.1.5.3/docs/Rapid.html
13:31:52 swamp_ joins (~zmt00@user/zmt00)
13:32:24 tabaqui1 joins (~root@87.200.129.102)
13:35:19 × zmt01 quits (~zmt00@user/zmt00) (Ping timeout: 260 seconds)
13:36:48 × Smiles quits (uid551636@id-551636.lymington.irccloud.com) (Quit: Connection closed for inactivity)
13:42:35 × johnjaye quits (~pi@syn-035-146-235-019.res.spectrum.com) (Read error: Connection reset by peer)
13:44:59 johnjaye joins (~pi@syn-035-146-235-019.res.spectrum.com)
13:45:41 × hughjfch1 quits (~hughjfche@vmi2417424.contaboserver.net) (Quit: WeeChat 4.4.3)
13:46:16 hughjfch1 joins (~hughjfche@vmi2417424.contaboserver.net)
13:50:53 alfiee joins (~alfiee@user/alfiee)
13:50:59 weary-traveler joins (~user@user/user363627)
13:55:12 × lortabac quits (~lortabac@2a01:e0a:541:b8f0:55ab:e185:7f81:54a4) (Quit: WeeChat 4.4.2)
13:55:21 × alfiee quits (~alfiee@user/alfiee) (Ping timeout: 252 seconds)
13:57:45 machinedgod joins (~machinedg@d108-173-18-100.abhsia.telus.net)
13:59:45 × bitdex quits (~bitdex@gateway/tor-sasl/bitdex) (Quit: = "")
14:02:50 alexherbo2 joins (~alexherbo@2a02-8440-3504-8116-8987-9b89-16c5-ba01.rev.sfr.net)
14:03:08 Smiles joins (uid551636@id-551636.lymington.irccloud.com)
14:04:18 vektor joins (~vektor@IP-149249154134.pools.medianet-world.de)
14:12:17 × alp quits (~alp@2001:861:8ca0:4940:465c:30a2:2211:b30f) (Ping timeout: 252 seconds)
14:14:19 pavonia joins (~user@user/siracusa)
14:19:08 × alexherbo2 quits (~alexherbo@2a02-8440-3504-8116-8987-9b89-16c5-ba01.rev.sfr.net) (Remote host closed the connection)
14:22:23 alp joins (~alp@2001:861:8ca0:4940:6044:ccfa:bd56:f4d9)
14:27:19 × acidjnk_new3 quits (~acidjnk@p200300d6e7283f830c2bc91cde612e63.dip0.t-ipconnect.de) (Ping timeout: 252 seconds)
14:27:33 acidjnk_new3 joins (~acidjnk@p200300d6e7283f83edaedff6126e1841.dip0.t-ipconnect.de)
14:29:06 ash3en joins (~Thunderbi@2a03:7846:b6eb:101:93ac:a90a:da67:f207)
14:31:44 alexherbo2 joins (~alexherbo@2a02-8440-3504-8116-8987-9b89-16c5-ba01.rev.sfr.net)
14:33:25 p3n joins (~p3n@217.198.124.246)
14:34:38 × alp quits (~alp@2001:861:8ca0:4940:6044:ccfa:bd56:f4d9) (Remote host closed the connection)
14:35:01 alp joins (~alp@2001:861:8ca0:4940:54fd:6cb8:585b:9cc)
14:36:49 × vektor quits (~vektor@IP-149249154134.pools.medianet-world.de) (Quit: Client closed)
14:39:21 × alp quits (~alp@2001:861:8ca0:4940:54fd:6cb8:585b:9cc) (Ping timeout: 252 seconds)
14:39:38 alfiee joins (~alfiee@user/alfiee)
14:42:17 Sgeo joins (~Sgeo@user/sgeo)
14:44:10 × alfiee quits (~alfiee@user/alfiee) (Ping timeout: 272 seconds)
14:54:07 × alexherbo2 quits (~alexherbo@2a02-8440-3504-8116-8987-9b89-16c5-ba01.rev.sfr.net) (Remote host closed the connection)
15:04:19 Guest33 joins (~Guest33@151.73.135.114)
15:04:47 × Guest33 quits (~Guest33@151.73.135.114) (Client Quit)
15:06:34 × Putonlalla quits (~Putonlall@it-cyan.it.jyu.fi) (Quit: Leaving.)
15:07:27 slack1256 joins (~slack1256@179.60.70.224)
15:12:19 zmt01 joins (~zmt00@user/zmt00)
15:12:56 <slack1256> I have a codebase that uses implicit parameters with mutable variables (think queues). I want to migrate to effectful. The migration is happening all at once, I create a static effect per implicit parameter and I create a function like `withDB` to scope the blocks that require that parameter. Implicit parameter resist being constraints on instance heads, so I cannot define classes to have two versions of each function. What alternatives do I have to ab
15:12:56 <slack1256> stract over implicit parameters?
15:13:03 × johnjaye quits (~pi@syn-035-146-235-019.res.spectrum.com) (Quit: WeeChat 4.0.0-dev)
15:14:32 <dminuoso> slack1256: Can you elaborate on "Implicit parameter resist being constraints on instance heads, so I cannot define classes to have two versions of each function", perhaps with a code example?
15:15:10 <slack1256> dminuoso: Sure, give me a moment.
15:15:29 × swamp_ quits (~zmt00@user/zmt00) (Ping timeout: 260 seconds)
15:16:38 × zmt01 quits (~zmt00@user/zmt00) (Ping timeout: 244 seconds)
15:16:48 <geekosaur> "You can’t have an implicit parameter in the context of a class or instance declaration." (https://downloads.haskell.org/ghc/latest/docs/users_guide/exts/implicit_parameters.html#implicit-parameter-type-constraints)
15:17:51 × euleritian quits (~euleritia@ip4d17fae8.dynamic.kabel-deutschland.de) (Ping timeout: 252 seconds)
15:18:12 euleritian joins (~euleritia@dynamic-176-006-142-115.176.6.pool.telefonica.de)
15:22:42 <slack1256> https://pastebin.com/zX9KcNQu dminuoso
15:24:51 <dminuoso> slack1256: The thing I dont quite understand, are you not trying to migrate away from implicit parameters?
15:27:02 <slack1256> dminuoso: too much code already uses it on the codebase. We are in a middle of a sprint and other developers are making changes to their own modules. Changing them all in a big PR would cause a lot of conflicts when trying to merge.
15:28:57 <dminuoso> slack1256: Its hard to tell without a bit more context, unsure whether the example is contrived or whether this is truly just about database connection strings
15:29:04 alfiee joins (~alfiee@user/alfiee)
15:29:44 <geekosaur> tbh if you're using an effect system, its state abstraction is an IORef (because effect systems are fancy ReaderT, more or less) and switching to that is the saner option than implicit params anyway
15:29:59 <geekosaur> I don't think I've ever seen a use for implicit params that waasn't better served some other way
15:30:13 <geekosaur> and they break reasoning about code
15:33:15 × alfiee quits (~alfiee@user/alfiee) (Ping timeout: 252 seconds)
15:33:28 <dminuoso> slack1256: That said, Im not entirely sure you need any partial solution here. During migration you can also just have *both* some effect and an implicit parameter, just make sure you resolve them coherently until the implicit params are gone.
15:33:46 <dminuoso> So some parts just use the effect, others use implicit params.
15:34:08 <dminuoso> It's certainly not ideal, but no migration ever was.
15:36:04 <slack1256> dminuoso: "Resolve them coherently" is the problem, I have to do it by hand instaed of using typeclasses. I have to duplicate the callers of those functions, the different constraints bubble up. If I could abstract over implicit parameters with classes I could delegate this to the compiler to choose the right calling convention.
15:36:30 L29Ah joins (~L29Ah@wikipedia/L29Ah)
15:36:37 <dminuoso> slack1256: Again, hard to say without knowing more about your code - but ideally there wouldnt be many places where you resolve effects.
15:36:50 <dminuoso> Hard to imagine why there would be more than one.
15:36:57 vektor joins (~vektor@IP-149249154134.pools.medianet-world.de)
15:37:08 Guest37 joins (~Guest62@c-73-217-79-154.hsd1.co.comcast.net)
15:39:15 × hueso quits (~root@user/hueso) (Quit: No Ping reply in 180 seconds.)
15:41:24 hueso joins (~root@user/hueso)
15:43:05 × GoldsteinQ quits (~goldstein@goldstein.rs) (Quit: ZNC 1.8.2 - https://znc.in)
15:44:24 × ystael_ quits (~ystael@user/ystael) (Quit: Lost terminal)
15:45:18 vanishingideal joins (~vanishing@user/vanishingideal)
15:46:20 ystael joins (~ystael@user/ystael)
15:46:28 GoldsteinQ joins (~goldstein@goldstein.rs)
15:49:18 L29Ah parts (~L29Ah@wikipedia/L29Ah) ()
15:53:05 L29Ah joins (~L29Ah@wikipedia/L29Ah)
15:54:42 × acidjnk_new3 quits (~acidjnk@p200300d6e7283f83edaedff6126e1841.dip0.t-ipconnect.de) (Ping timeout: 252 seconds)
15:57:50 <ski> slack1256 : constraint synonyms ?
16:00:39 × GoldsteinQ quits (~goldstein@goldstein.rs) (Quit: ZNC 1.8.2 - https://znc.in)
16:03:20 GoldsteinQ joins (~goldstein@goldstein.rs)
16:03:31 × euleritian quits (~euleritia@dynamic-176-006-142-115.176.6.pool.telefonica.de) (Read error: Connection reset by peer)
16:03:49 euleritian joins (~euleritia@ip4d17fae8.dynamic.kabel-deutschland.de)
16:05:04 <slack1256> ski: Even with -XConstraintKinds we cannot use implicit parameters on instance heads...
16:07:57 <ski> hm, i see
16:09:10 × Guest37 quits (~Guest62@c-73-217-79-154.hsd1.co.comcast.net) (Ping timeout: 240 seconds)
16:09:41 <ski> hm, looks like `data Dict_XInt = (x :: Int) => WrapXInt' works, and i suppose one could then try `class XInt where xInt :: Dict_XInt' .. hmmm
16:10:15 <ski> (or `xInt :: ((x :: Int) -> o) -> o', skipping `Dict_XInt')
16:10:46 <ski> (ah .. `xInt :: ((x :: Int) => o) -> o')
16:15:15 Guest87 joins (~Guest92@14.194.140.178)
16:19:28 alfiee joins (~alfiee@user/alfiee)
16:22:06 × RMSBach quits (~guygastin@137.184.131.156) (Ping timeout: 252 seconds)
16:23:30 × alfiee quits (~alfiee@user/alfiee) (Ping timeout: 244 seconds)
16:27:26 zmt00 joins (~zmt00@user/zmt00)
16:30:26 Digit joins (~user@user/digit)
16:31:46 × ubert quits (~Thunderbi@2a02:8109:ab8a:5a00:a8f9:39f9:ef80:a859) (Ping timeout: 244 seconds)
16:32:28 × zmt00 quits (~zmt00@user/zmt00) (Ping timeout: 272 seconds)
16:34:03 Square joins (~Square@user/square)
16:35:24 × ash3en quits (~Thunderbi@2a03:7846:b6eb:101:93ac:a90a:da67:f207) (Ping timeout: 260 seconds)
16:35:41 ash3en joins (~Thunderbi@146.70.124.222)
16:36:52 × EvanR quits (~EvanR@user/evanr) (Quit: Leaving)
16:38:14 EvanR joins (~EvanR@user/evanr)
16:41:28 ash3en1 joins (~Thunderbi@2a03:7846:b6eb:101:93ac:a90a:da67:f207)
16:43:14 × ash3en quits (~Thunderbi@146.70.124.222) (Ping timeout: 272 seconds)
16:43:14 ash3en1 is now known as ash3en
16:45:05 × Guest87 quits (~Guest92@14.194.140.178) (Quit: Client closed)
16:46:19 × sp1ff quits (~user@c-67-160-173-55.hsd1.wa.comcast.net) (Read error: Connection reset by peer)
16:48:29 alp joins (~alp@2001:861:8ca0:4940:291:464f:2c61:f1c2)
16:57:36 lxsameer joins (~lxsameer@Serene/lxsameer)
16:58:16 <lxsameer> hey folks, how can I define a type alias for `(Foo x y) => x -> (x y, y)` type?
17:00:23 <merijn> lxsameer: Generally you'd keep the constraint out of the alias
17:01:00 <merijn> lxsameer: Because otherwise you're (intentionally or not) defining an existential
17:01:09 <merijn> eh, not existential
17:01:17 <merijn> rankn type, I meant
17:02:09 <lxsameer> merijn: ok i have to read more about it then
17:02:11 <lxsameer> thank you
17:02:55 peterbecich joins (~Thunderbi@syn-047-229-123-186.res.spectrum.com)
17:06:18 ubert joins (~Thunderbi@p200300ecdf4e6362e6b318fffe838f33.dip0.t-ipconnect.de)
17:06:48 × Smiles quits (uid551636@id-551636.lymington.irccloud.com) (Quit: Connection closed for inactivity)
17:08:12 <c_wraith> unless you have deep subsumption enabled, in which case it implicitly lifts the constraint to the top of the type
17:08:51 <c_wraith> I still can't believe that was GHC's default behavior for forever.
17:09:12 alfiee joins (~alfiee@user/alfiee)
17:11:21 <lxsameer> thank you
17:12:48 × ubert quits (~Thunderbi@p200300ecdf4e6362e6b318fffe838f33.dip0.t-ipconnect.de) (Ping timeout: 252 seconds)
17:13:29 × alfiee quits (~alfiee@user/alfiee) (Ping timeout: 260 seconds)
17:13:48 ubert joins (~Thunderbi@p200300ecdf4e6362e6fd4bc8009ee988.dip0.t-ipconnect.de)
17:14:33 × chele quits (~chele@user/chele) (Remote host closed the connection)
17:14:54 × machinedgod quits (~machinedg@d108-173-18-100.abhsia.telus.net) (Ping timeout: 252 seconds)
17:15:14 <ski> "you're (intentionally or not) defining an existential" -- unless you parameterize
17:17:51 × ljdarj quits (~Thunderbi@user/ljdarj) (Ping timeout: 265 seconds)
17:17:54 <ski> (iow, `type Blah x y = Foo x y => x -> (x y,y)' .. still, it's not too clear how useful this would be)
17:18:12 <ski> .. it seems like it would perhaps be useful to be able to declare a constraint as a presupposition of a synonym
17:19:04 <ski> type Foo x y => Blah x y = x -> (x y,y) -- if `Foo x y' holds, then `Blah x y' is an alias for `(x y,y)'
17:21:12 <ski> therefore `Blah x y -> Blah x y' means `(x -> (x y,y)) -> (x -> (x y,y))' with `Foo x y' as presupposition, so if that's the inferred type of a function binding, it'd get (assuming no further constraints on `x' and `y' generalized to `forall x y. Blah x y => (x -> (x y,y)) -> (x -> (x y,y))
17:21:17 <ski> '
17:22:23 <ski> er, s/Blah x y =>/Foo x y =>/
17:22:42 <ski> (if you'd use an explicit type signature, you'd still need to include the constraint `Foo x y' in `frob :: Foo x y => Blah x y -> Blah x y'
17:23:08 <ski> )
17:23:09 <ski> c_wraith : hm, subsumption worked something like the above ?
17:28:54 machinedgod joins (~machinedg@d108-173-18-100.abhsia.telus.net)
17:33:30 <EvanR> s/Blah/Foo, s/Foo/Blah, Blarg!
17:33:47 acidjnk_new3 joins (~acidjnk@p200300d6e7283f83f8f1a3a9ad07643b.dip0.t-ipconnect.de)
17:34:08 × urdh quits (~urdh@user/urdh) (Ping timeout: 245 seconds)
17:34:31 ljdarj joins (~Thunderbi@user/ljdarj)
17:39:09 × ensyde quits (~ensyde@2601:5c6:c200:6dc0::64a2) (Ping timeout: 260 seconds)
17:48:21 target_i joins (~target_i@user/target-i/x-6023099)
17:51:12 × peterbecich quits (~Thunderbi@syn-047-229-123-186.res.spectrum.com) (Ping timeout: 252 seconds)
17:51:12 × ash3en quits (~Thunderbi@2a03:7846:b6eb:101:93ac:a90a:da67:f207) (Quit: ash3en)
17:52:20 ash3en joins (~Thunderbi@2a03:7846:b6eb:101:93ac:a90a:da67:f207)
17:54:37 × sord937 quits (~sord937@gateway/tor-sasl/sord937) (Quit: sord937)
17:56:30 × jespada quits (~jespada@2800:a4:2215:4d00:20a9:6cd:d7c4:a65f) (Quit: My Mac has gone to sleep. ZZZzzz…)
17:57:21 × ash3en quits (~Thunderbi@2a03:7846:b6eb:101:93ac:a90a:da67:f207) (Ping timeout: 276 seconds)
17:57:28 ash3en1 joins (~Thunderbi@146.70.124.222)
17:58:06 × vektor quits (~vektor@IP-149249154134.pools.medianet-world.de) (Quit: Client closed)
17:58:37 alfiee joins (~alfiee@user/alfiee)
17:58:49 × tabaqui1 quits (~root@87.200.129.102) (Ping timeout: 260 seconds)
17:59:47 ash3en1 is now known as ash3en
18:00:32 vektor joins (~vektor@IP-149249154134.pools.medianet-world.de)
18:01:01 × L29Ah quits (~L29Ah@wikipedia/L29Ah) (Quit: Gateway shutdown)
18:02:48 × alfiee quits (~alfiee@user/alfiee) (Ping timeout: 246 seconds)
18:05:34 jespada joins (~jespada@2800:a4:2215:4d00:20a9:6cd:d7c4:a65f)
18:10:16 × Pozyomka_ quits (~pyon@user/pyon) (Quit: WeeChat 4.5.1)
18:12:36 × ash3en quits (~Thunderbi@146.70.124.222) (Ping timeout: 246 seconds)
18:14:29 Pozyomka joins (~pyon@user/pyon)
18:16:34 L29Ah joins (~L29Ah@wikipedia/L29Ah)
18:18:50 × Lord_of_Life quits (~Lord@user/lord-of-life/x-2819915) (Read error: Connection reset by peer)
18:22:23 Lord_of_Life joins (~Lord@user/lord-of-life/x-2819915)
18:27:09 tzh joins (~tzh@c-76-115-131-146.hsd1.or.comcast.net)
18:27:43 × Lord_of_Life quits (~Lord@user/lord-of-life/x-2819915) (Excess Flood)
18:28:03 gehmehgeh joins (~user@user/gehmehgeh)
18:28:13 Lord_of_Life joins (~Lord@user/lord-of-life/x-2819915)
18:28:40 × gmg quits (~user@user/gehmehgeh) (Remote host closed the connection)
18:32:13 ozkutuk joins (~ozkutuk@24.133.86.69)
18:35:24 × vektor quits (~vektor@IP-149249154134.pools.medianet-world.de) (Quit: Client closed)
18:42:38 × slack1256 quits (~slack1256@179.60.70.224) (Remote host closed the connection)
18:47:41 alfiee joins (~alfiee@user/alfiee)
18:48:35 Smiles joins (uid551636@id-551636.lymington.irccloud.com)
18:52:04 × alfiee quits (~alfiee@user/alfiee) (Ping timeout: 252 seconds)
18:53:56 alexherbo2 joins (~alexherbo@2a02-8440-3504-8116-5d7d-beeb-ea7b-ad40.rev.sfr.net)
18:53:56 × MyNetAz quits (~MyNetAz@user/MyNetAz) (Read error: Connection reset by peer)
18:57:09 × lxsameer quits (~lxsameer@Serene/lxsameer) (Ping timeout: 260 seconds)
18:58:46 L29Ah parts (~L29Ah@wikipedia/L29Ah) ()
19:00:57 MyNetAz joins (~MyNetAz@user/MyNetAz)
19:01:28 × TheCoffeMaker quits (~TheCoffeM@user/thecoffemaker) (Remote host closed the connection)
19:01:51 TheCoffeMaker joins (~TheCoffeM@user/thecoffemaker)
19:02:03 dsrt^ joins (~dsrt@108.192.66.114)
19:03:06 × alexherbo2 quits (~alexherbo@2a02-8440-3504-8116-5d7d-beeb-ea7b-ad40.rev.sfr.net) (Remote host closed the connection)
19:08:12 alexherbo2 joins (~alexherbo@2a02-8440-3503-94e0-1866-04f2-f81a-c1ec.rev.sfr.net)
19:10:09 × ncf quits (~n@monade.li) (Quit: Fairfarren.)
19:10:25 ncf joins (~n@monade.li)
19:10:39 × jespada quits (~jespada@2800:a4:2215:4d00:20a9:6cd:d7c4:a65f) (Quit: Textual IRC Client: www.textualapp.com)
19:11:36 Guest39 joins (~Guest39@cpc1-lich12-2-0-cust2633.3-2.cable.virginm.net)
19:17:53 jespada joins (~jespada@2800:a4:2215:4d00:9c45:c000:6937:52ff)
19:18:01 × jespada quits (~jespada@2800:a4:2215:4d00:9c45:c000:6937:52ff) (Client Quit)
19:30:17 × vanishingideal quits (~vanishing@user/vanishingideal) (Ping timeout: 265 seconds)
19:31:43 vanishingideal joins (~vanishing@user/vanishingideal)
19:32:46 ash3en joins (~Thunderbi@2a03:7846:b6eb:101:93ac:a90a:da67:f207)
19:33:37 L29Ah joins (~L29Ah@wikipedia/L29Ah)
19:39:06 alfiee joins (~alfiee@user/alfiee)
19:43:15 × alfiee quits (~alfiee@user/alfiee) (Ping timeout: 246 seconds)
19:47:54 × weary-traveler quits (~user@user/user363627) (Remote host closed the connection)
19:48:55 × merijn quits (~merijn@host-vr.cgnat-g.v4.dfn.nl) (Ping timeout: 244 seconds)
19:58:49 gehmehgeh is now known as gmg
20:00:04 merijn joins (~merijn@host-vr.cgnat-g.v4.dfn.nl)
20:00:07 × caconym quits (~caconym@user/caconym) (Quit: bye)
20:00:44 caconym joins (~caconym@user/caconym)
20:01:42 euouae joins (~euouae@user/euouae)
20:02:55 <euouae> I've been reading <https://www.vex.net/~trebla/haskell/lazy.xhtml> and what seems to me is that lazy evaluation in Haskell means that expressions are only evaluated enough to match patterns & guards
20:03:07 <euouae> Is that an accurate understanding?
20:05:17 × Guest39 quits (~Guest39@cpc1-lich12-2-0-cust2633.3-2.cable.virginm.net) (Quit: Client closed)
20:06:41 <mauke> probably also to lambda form for function application
20:06:59 <mauke> can't f x if f is still thunk
20:07:05 <euouae> Yeah I was thinking that also in terms of pattern matching too, is that wrong?
20:07:36 <euouae> e.g. `(\c _ -> c) 0 missiles` does not evaluate missiles because it fits into the hole
20:08:19 <Rembane> > (\c _ -> c) 0 undefined
20:08:20 <lambdabot> 0
20:08:34 <mauke> > undefined 42
20:08:35 <lambdabot> *Exception: Prelude.undefined
20:08:50 <mauke> I don't think there's any pattern matching here
20:09:09 <euouae> Oh you're saying `f` itself is lazily evaluated until a lambda form is exposed
20:09:25 <mauke> yes
20:09:37 <euouae> ah, thank you...
20:10:07 <mauke> otherwise lazy lambda calculus would never get anything done :-)
20:10:21 <Rembane> > (\(x:_) -> x) [0, undefined]
20:10:23 <lambdabot> 0
20:11:45 <mauke> oh, and there's a subtlety with newtype constructor patterns
20:12:23 <mauke> newtype Identity a = Identity a; ... case undefined of { Identity _ -> () } -- evaluates to ()
20:12:46 <mauke> even though it looks like we're matching on a constructor
20:12:55 <euouae> The subtlety is that newtype always matches?
20:13:08 <euouae> the article I linked above mentioned that newtype is an exception but did not say yet why
20:13:27 <mauke> at runtime, newtype patterns are no-ops
20:13:42 <mauke> since there's only one possible constructor, it has no representation at all
20:14:33 <mauke> .oO( and cannot be taxed )
20:15:15 <euouae> rebel newtype
20:16:46 <mauke> > case undefined of { Identity _ -> () }
20:16:48 <lambdabot> ()
20:16:59 <mauke> > Just undefined `seq` ()
20:17:00 <lambdabot> ()
20:17:06 <mauke> > Identity undefined `seq` ()
20:17:07 <lambdabot> *Exception: Prelude.undefined
20:18:50 Guest74 joins (~Guest74@81-231-8-142-no600.tbcn.telia.com)
20:20:01 <euouae> I don't exactly understand how sharing works, does GHC remember an expression?
20:20:16 <euouae> I mean, in formal lazy evaluation, what exactly is sharing?
20:20:22 <dminuoso> euouae: Have you seen any of the guides that include visualizations?
20:20:55 <euouae> I guess I'm realizing that it's impossible to share between two different scopes
20:20:59 <dminuoso> euouae: So sharing itself is implemented by just pointers pointing to the same thunk.
20:21:10 wootehfoot joins (~wootehfoo@user/wootehfoot)
20:21:11 <dminuoso> Literally to the same address in memory
20:21:16 <euouae> Or is sharing happening between two different scopes too?
20:21:22 <dminuoso> What do you mean by "scopes"?
20:21:33 <euouae> I guess there's no such thing
20:21:39 <euouae> Well I imagine the situation:
20:21:48 × ubert quits (~Thunderbi@p200300ecdf4e6362e6fd4bc8009ee988.dip0.t-ipconnect.de) (Remote host closed the connection)
20:21:55 <euouae> `f x` has to be evaluated. In different parts of the program there's `f x`, is that all shared?
20:21:56 <dminuoso> Say you have `let x = <expensive> in x + x`, then both references of `x` will point at the same location in memory.
20:22:05 <dminuoso> euouae: Maybe.
20:22:07 <dminuoso> It depends.
20:22:21 <euouae> I think for one thing, if these are different threads, I'm willing to bet it's not
20:22:37 <dminuoso> euouae: In GHC the simplifier has both reasons to *try* to do it, and reasons to try and not share.
20:22:37 <euouae> but for a single process, I'm also sure that GHC must have limited memory of how much should be shared?
20:23:06 <euouae> So, sharing seems to me to be strictly an optimization right? Or does it affect side-effects?
20:23:16 <dminuoso> Now thats an excellent question.
20:23:22 <dminuoso> In principle its optimization only.
20:23:45 <dminuoso> However, we have dirty little primitives that we can use to embed side effects into evaluation with, which makes the difference observable
20:24:04 ubert joins (~Thunderbi@p200300ecdf4e6362e6fd4bc8009ee988.dip0.t-ipconnect.de)
20:24:16 <dminuoso> But you can safely forget about those primitives after our discussion.
20:24:54 <dminuoso> Or actually, let me introduce you to one that is helpful to beginners:
20:24:56 <euouae> hm...
20:25:03 <dminuoso> Debug.Trace.trace
20:25:19 <dminuoso> That primitive attaches a string to some arbitrary thing, and when that thing gets evaluated the string gets printed.
20:25:29 <dminuoso> Which is highly useful for debugging pure code.
20:25:46 <dminuoso> However, because it gets triggered upon evaluation, any of the following scenarios can happen:
20:26:14 <dminuoso> It never gets printed, it gets printed once, or many times.
20:26:29 <dminuoso> Which for debugging is usually not an issue, of course.
20:26:45 <dminuoso> % import Debug.Trace
20:26:45 <yahb2> <no output>
20:27:39 <euouae> so Debug.Trace.Trace can show you the effect of sharing
20:27:41 <dminuoso> % let x = trace "demanded" (2.5 ^ 10) in (x, x)
20:27:41 <yahb2> demanded ; demanded ; (9536.7431640625,9536.7431640625)
20:27:48 <dminuoso> Here you can see sharing did not kick in
20:28:09 <euouae> How did you know that the expr wouldn't be shared
20:28:31 alfiee joins (~alfiee@user/alfiee)
20:28:38 <dminuoso> I tried it in a DM beforehand.
20:28:48 <mauke> % let x = trace "demanded" (2.5 ^ 10 :: Double) in (x, x)
20:28:48 <yahb2> demanded ; (9536.7431640625,9536.7431640625)
20:28:53 <mauke> hah
20:28:57 <euouae> but what made you think that arithmetic wouldn't work?
20:29:13 × tomboy64 quits (~tomboy64@user/tomboy64) (Read error: Connection reset by peer)
20:29:20 <dminuoso> euouae: Well to be fair I have some additional knowledge, but I dont want to ovecomplicate the discussion.
20:29:30 tomboy64 joins (~tomboy64@user/tomboy64)
20:29:37 <euouae> So it's pretty deep / internal
20:29:49 <mauke> <euouae> So, sharing seems to me to be strictly an optimization right? <- no, unwanted sharing can increase memory use a lot
20:30:01 <euouae> Well what if the expression has side effects? Does sharing get turned off?
20:30:04 <dminuoso> Sometimes sharing is great, sometimes you want everything inlined.
20:30:10 <euouae> or is it still anyone's game? maybe shared maybe not?
20:30:12 <dminuoso> euouae: expressions dont have side effects.
20:30:25 <mauke> dminuoso: except when they do, as you just demonstrated :-)
20:30:25 <euouae> ah interesting. let me digest that
20:31:06 <euouae> well, putStrLn "foo" has a side effect
20:31:14 <dminuoso> euouae: No it does not.
20:31:18 <mauke> as far as I know there is no specific protection here. ghc shares things or not; if you (unsafely) embed side effects in your expressions, you have to be ready to handle either case
20:31:21 <dminuoso> euouae: We have a primitive to force evaluation to prove this:
20:31:39 <dminuoso> % putStrLn () `seq` ()
20:31:39 <yahb2> <interactive>:109:10: error: [GHC-83865] ; • Couldn't match type ‘()’ with ‘[Char]’ ; Expected: String ; Actual: () ; • In the first argument of ‘putStrLn’, namely ‘()’ ; ...
20:31:50 <dminuoso> % putStrLn "hello world" `seq` ()
20:31:50 <yahb2> ()
20:32:01 <dminuoso> euouae: Here seq forces its first argument and returns the second.
20:32:07 <dminuoso> See how the evaluation did not cause any side effect?
20:32:21 <mauke> putStrLn is basically just a constructor. it builds an IO () value
20:32:29 <dminuoso> A good mind model is that IO is just a list of assembly instructions, and calculating the list of assembly instrutions is pure/side-effect free.
20:32:50 <dminuoso> i.e. calculating a list of assembly instructions is different from executing them.
20:32:53 × alfiee quits (~alfiee@user/alfiee) (Ping timeout: 248 seconds)
20:32:55 <mauke> that's a good model if you already know asm; not so much otherwise :-)
20:33:00 <euouae> Okay right (yeah I know asm)
20:33:10 <euouae> I see then, nothing special about IO
20:33:23 <dminuoso> euouae: its `trace` that is special. :-)
20:33:24 <euouae> Well, what is the unwanted sharing that increases memory?
20:33:56 <dminuoso> euouae: It can keep stuff alive in memory longer than you want to.
20:34:08 <euouae> Ah yeah that makes sense
20:34:20 <dminuoso> But not sharing can also waste memory in potentially having to keep it in memory multiple times..
20:34:36 <mauke> > let { x = [0 ..]; y = [0 ..] } in (x !! 10000) + (y !! 9999)
20:34:38 <lambdabot> 19999
20:34:38 <euouae> So when "executing" haskell code, theoretically you can imagine that all the grammatical expansions happen at runtime. Obviously "compiled" haskell code can do some of the work before hand
20:34:57 <dminuoso> euouae: You mean *evaluating* right?
20:34:58 <euouae> But feigning ignorance on compilation, it's fine to think of it as all interpreted at runtime right?
20:35:14 <dminuoso> euouae: But yes, you can imagine that substitution happens at runtime.
20:35:14 <mauke> in my example, if nothing is shared, the code can run in O(1) memory
20:35:16 <euouae> Yeah right, evaluating
20:35:25 <dminuoso> Yes, you can imagine this happens at runtime.
20:35:33 <euouae> dminuoso: I'm very prone to using the wrong terms all the time
20:35:35 <dminuoso> Of course *executing* IO also happens at runtime and is done by main.
20:35:51 <dminuoso> That is, main is the only thing (aside from some dark primitives) that can execute IO.
20:36:02 <mauke> I don't think that's the right way to think about it
20:36:05 <mauke> main is just a constant
20:36:20 <mauke> the runtime system grabs the value of main and runs the instructions you built
20:36:32 <euouae> Well GHC bootstraps some code before main to do the execution
20:36:36 <euouae> very similar to C etc
20:36:41 <mauke> yes
20:36:43 <dminuoso> euouae: Right.
20:36:58 <euouae> so what about threads? is sharing happening across threads?
20:37:11 <dminuoso> Oh you're really diving deep now.
20:37:15 <mauke> my point is that just as main() is a regular C function (has an address, can be called from inside the program, etc), so Haskell main is a regular IO () value and can be used as such
20:37:34 <mauke> euouae: yes
20:37:40 sprotte24 joins (~sprotte24@p200300d16f06b9001d5c2b08794be0ce.dip0.t-ipconnect.de)
20:37:49 <euouae> Oh it does? That can be bad
20:38:02 <euouae> I can see why memory can blow up then
20:38:02 <dminuoso> No, its all build to handle that.
20:38:12 <mauke> on a related topic, have you ever seen the <<loop>> exception?
20:38:18 <euouae> No
20:38:36 <mauke> > let x = head [x] in x
20:38:37 <dminuoso> euouae: First off, when switchinig between threads, entered thunks are blackholed.
20:38:38 <lambdabot> *Exception: <<loop>>
20:38:58 <dminuoso> euouae: That is, there is automatic protection that no two threads attempt to evaluate the same expression concurrently.
20:39:25 <dminuoso> And that all alone pretty much stops memory issues.
20:39:37 <mauke> I may be wrong on my terminology, but I think blackholing only happens in single-threaded mode
20:40:03 <dminuoso> See https://simonmar.github.io/bib/papers/multiproc.pdf
20:41:06 <mauke> huh, interesting
20:41:55 <mauke> anyway, the <<loop>> exception happens when evaluation of a thunk tries to re-enter the same thunk (i.e. you have a value that depends on itself)
20:41:58 euouae furiously types some notes of the previous discussion, needs more time to read the latest stuff being said
20:42:30 <mauke> this is implemented by temporarily switching the code pointer of a thunk to a subroutine that throws an exception
20:42:48 <mauke> at least in single-threaded mode
20:43:33 <mauke> in a multi-threaded environment, the first thread to reach a given thunk instead switches out the code pointer to an "enter waiting queue" subroutine
20:44:07 <mauke> so if another thread tries to evaluate the same thunk later, it will simply wait until the first thread is done computing a value
20:44:08 × alexherbo2 quits (~alexherbo@2a02-8440-3503-94e0-1866-04f2-f81a-c1ec.rev.sfr.net) (Remote host closed the connection)
20:44:25 <dminuoso> mauke: Okay, so there's two behaviors to blackhole.
20:44:33 <dminuoso> mauke: If the same thread enters a blackhole, that blackhole acts as loop detection.,
20:44:48 <dminuoso> If another thread enters a blackhole, it gets put on a list to be woken up later.
20:45:04 <dminuoso> So it gets woken up whenever the thunk finished.
20:45:18 <mauke> did they change that? I have a vague memory that <<loop>> detection didn't work in multi-thread mode
20:45:23 <dminuoso> The <<loop>> is just some opportunistic debugging helper, its not the core feature.
20:45:44 × dsrt^ quits (~dsrt@108.192.66.114) (Ping timeout: 252 seconds)
20:45:54 <dminuoso> (And it does not work reliably either for a bunch of reasons)
20:46:00 <mauke> i.e. in multi-thread mode a thread could re-enter the thunk and end up waiting for itself (deadlock)
20:46:05 <dminuoso> So consider it a bonus *if* it triggers.
20:48:08 <dminuoso> mauke: Im not sure how the threaded RTS changes, but blackholing should be needed for single threaded RTS too.
20:48:24 <dminuoso> Note that "threaded RTS" talks about OS threads
20:48:34 <dminuoso> While the other use of threads if about haskell threads.
20:49:09 <mauke> ah, right
20:49:12 <dminuoso> Even in single threaded RTS you will have concurrency.
20:49:44 <euouae> mauke, is <<loop>> possible because of sharing?
20:49:53 <euouae> sorry I'm reading from the top so I'm trying to catch up on what was said
20:50:25 <dminuoso> euouae: So roughly, if you have `let x = <expensive> in ..` then we can think of x being represented in memory as some memory region with a bunch of code
20:50:41 <dminuoso> euouae: and you demand that value by just jmp'ing into that memory region.
20:51:15 <euouae> interestingly `let x = head [x] in x` just hangs in ghci
20:51:39 <dminuoso> Now that entry code both checks for a particular mark BLACKHOLE to be set, if its set, you get a <<loop>> assuming this happened from within the same haskell thread.
20:51:48 <dminuoso> If not, it will set that mark.
20:51:58 <euouae> oh mauke's example relates to black holes? I'll read the whole convo then
20:52:24 <dminuoso> You can think of it as some kind of mutual exclusion lock, but with special logic to detect if the entry code recursed into itself.
20:52:42 <dminuoso> mauke: Yes. Its really just a kind of mutual exclusion lock for thunks.
20:53:08 <dminuoso> It was recognized we could use the same machinery to detect some forms of infinite loops
20:53:39 <ash3en> using jack midi with haskell: do i have to manage memory or something?
20:53:53 <ash3en> i mean the haskell library: https://hackage.haskell.org/package/jack-0.7.2.2/docs/Sound-JACK-MIDI.html
20:56:05 <dminuoso> euouae: https://gitlab.haskell.org/ghc/ghc/-/wikis/commentary/rts/storage/heap-objects
20:56:11 <dminuoso> Is a good website to remember.
20:56:29 <dminuoso> euouae: Start with the `Heap Objects` section
20:57:29 × sarna quits (~sarna@d224-221.icpnet.pl) (Ping timeout: 260 seconds)
20:57:48 <dminuoso> euouae: Note, that every object has a pointer to an info table, and that info table contains entry code. Evaluation is driven by just jumping into that entry code
20:58:16 sarna joins (~sarna@d224-221.icpnet.pl)
20:58:17 <dminuoso> See https://gitlab.haskell.org/ghc/ghc/-/wikis/commentary/rts/storage/heap-objects#black-holes for some details on blackhole
20:59:14 <euouae> yeah I was thinking that <<loop>> detection seems roughly like the halting prolbem
20:59:23 <euouae> so maybe it's not reliable, just a heuristic?
21:00:00 <dminuoso> euouae: Like I said: It can only detect a particular kind of infinite loop.
21:00:08 <euouae> right
21:00:09 <dminuoso> Its not even a heuristic.
21:00:43 <euouae> well eah, that's good, heuristics can misfire
21:01:09 <dminuoso> If it triggers, there's definitely an infinite loop and you can celebrate. :)
21:01:16 <mauke> if you encounter the buddha on the road, kill him
21:01:18 <dminuoso> But dont ever rely on it firing.
21:01:29 × kimiamania8 quits (~65804703@user/kimiamania) (Quit: PegeLinux)
21:01:35 <mauke> only in this case it's more like "if you encounter yourself on the road, kill the current thread"
21:01:53 kimiamania8 joins (~65804703@user/kimiamania)
21:02:02 <dminuoso> euouae: Like I said, the machinery was not build for loop detection but for preventing concurrent evaluation of the same thunk between two haskell threads.
21:02:30 CoolMa7 joins (~CoolMa7@ip5f5b8957.dynamic.kabel-deutschland.de)
21:03:50 × merijn quits (~merijn@host-vr.cgnat-g.v4.dfn.nl) (Ping timeout: 244 seconds)
21:04:17 <euouae> yup yup
21:04:21 × ubert quits (~Thunderbi@p200300ecdf4e6362e6fd4bc8009ee988.dip0.t-ipconnect.de) (Quit: ubert)
21:04:25 <monochrom> It helps avoid multiple threads doing redundant work. It is not even a 100% perfect lock, for no one needs one, in case two threads do happen to slip through and perform redundant work, it is just slower but still correct, this is an immutable language, evaluating x+y a million times does not change the answer.
21:04:29 <euouae> I've written & digested all that was said today, and thanks for more homework
21:04:38 ubert joins (~Thunderbi@p200300ecdf4e63626546ad8bed5a8da9.dip0.t-ipconnect.de)
21:04:54 <euouae> I am curious, you said single RTS still has haskell threads, were you referring to some concurrent library or what happens behind the scenes by ghc itself?
21:05:52 <mauke> the RTS does m:n threading anyway (running m haskell threads on n native threads), so n = 1 is supported as well
21:05:59 <euouae> what does RTS stand for?
21:06:03 <mauke> runtime system
21:06:03 <monochrom> The "threaded RTS" uses OS threads (so hopefully spreading out on more cores if you have them). The "unthreaded RTS" makes its own green threads, if you have heard of that word.
21:06:11 merijn joins (~merijn@host-vr.cgnat-g.v4.dfn.nl)
21:06:27 <euouae> yup I've heard of green threads, I'm just curious if Haskell has them behind the scenes or if it was in regards to the programmer's usage
21:06:31 <mauke> also a good term: event loop
21:06:54 <dminuoso> By the way, in reality whether or not a thunk gets marked as blackhole on entry depends on whether you opted into eager blackholing or use the default lazy blackholing
21:06:58 <monochrom> The good news is "why not both".
21:07:01 <dminuoso> Details are described in https://gitlab.haskell.org/ghc/ghc/-/blob/wip/T17910/rts/Updates.h
21:07:29 <monochrom> and yeah the threaded RTS simply distributes 10000 green threads over 4 OS threads.
21:07:46 <euouae> what does RTS stand for?
21:07:49 <monochrom> or s/4/whatever you say in -N/
21:07:51 <dminuoso> Runtime System
21:07:59 <euouae> Ok so it's the thing that runs the green threads or OS threads etc
21:08:11 <dminuoso> So one of the things that Haskell is rather unique in, is the way IO is handled.
21:08:33 <dminuoso> Most IO appears to be synchronous, but is done completely asynchronously with the RTS knowing about it.
21:08:49 <dminuoso> As a consequence, threads get scheduled accordingly whether IO calls are ready/finished
21:09:19 <dminuoso> So you kind of get the convenience of synchronous code, without having to coordinate/yield all over the place
21:12:07 <dminuoso> Now you would have this with plain OS threads too, but you will get much more context switches
21:12:19 <dminuoso> Whereas the RTS can just schedule other haskell threads instantly
21:12:57 <euouae> With all the links I have I'll probably need to study another 100 years before I come back
21:13:20 <euouae> I still haven't even touched the G-machine paper, now there's the comments in Update.h and that heap-objects commentary ;)
21:13:28 <monochrom> My sentiment is a bit different. Haskell "blocking" I/O : of course GHC scheduler turns it into nonblocking I/O and event loop :: Unix "blocking" syscalls : of course kernel scheduler turns it into nonblocking I/O and event loop, hell the kernel is the event loop.
21:13:36 × merijn quits (~merijn@host-vr.cgnat-g.v4.dfn.nl) (Ping timeout: 252 seconds)
21:14:17 <euouae> yeah but is the GHC scheduler used by the programmer? is it the only sheriff in town? Or is it used alongside other green thread schedulers by programmers?
21:14:30 <dminuoso> monochrom: In my eyes it all comes down to how many context switches you have to endure.
21:14:53 <dminuoso> If you rely on the kernel acting as the event loop, you will get TLB flushes and context flushes way more frequently
21:15:20 <dminuoso> Any of these blocking syscalls will give the scheduler a nudge
21:15:47 <euouae> I mean there's a reason why web servers have moved away from cgi
21:15:48 <dminuoso> s/context flushes/context switches/
21:16:29 <monochrom> "flush" is not a bad description :)
21:16:50 <dminuoso> euouae: At any rate, I think the core thing to take away is that expressions can be thought to be represented in memory, and evaluation is akin to just driving around the program and substituting, replacing expressions with their answers right in memory.
21:17:05 <monochrom> But I just mean that it is not difficult to understand.
21:17:08 <dminuoso> The STG is just a particular way to do that.
21:18:09 <dminuoso> Sharing works by just pointing to the same memory address.
21:18:36 alfiee joins (~alfiee@user/alfiee)
21:18:54 <euouae> thunk gets thrown around a lot as a term. I roughyl imagine it as an (un)evaluated haskell expression, is that accurate?
21:19:04 <monochrom> YES
21:19:14 × __monty__ quits (~toonn@user/toonn) (Quit: leaving)
21:19:20 <euouae> Does haskell have an IR or does it literally store Haskell code in memory?
21:19:25 merijn joins (~merijn@host-vr.cgnat-g.v4.dfn.nl)
21:19:33 <euouae> that needs parsing
21:19:39 <dminuoso> euouae: We encode it as STG.
21:19:44 <EvanR> haha like BASIC
21:19:47 <dminuoso> And that gets compiled further.
21:19:52 <EvanR> run the text code directly
21:20:04 <euouae> Ah cool. I had forgotten what question I had that led to your mention of STG, but I guess one IR is STG that is already motivating
21:20:13 <monochrom> Other terms thrown around and, one can bet, parroted not understood: isomorphic, strict, combinator.
21:20:16 <dminuoso> euouae: But if it helps, you could imagine it stored the Haskell code in memory.
21:20:24 <dminuoso> (for semantics)
21:20:40 <dminuoso> (just dont excercise that mind model when thinking about performance)
21:20:45 <euouae> rigth
21:20:52 remedan joins (~remedan@62.245.108.153)
21:21:47 <monochrom> Most BASIC implementations I have seen make at least a minimal attempt to store code more compact than actual text strings.
21:22:19 Tuplanolla joins (~Tuplanoll@91-159-69-59.elisa-laajakaista.fi)
21:22:27 byte joins (~mu@user/byte)
21:23:03 × alfiee quits (~alfiee@user/alfiee) (Ping timeout: 252 seconds)
21:23:11 <monochrom> For example "FOR" becomes one byte. And if you enter "10 FOR I = 1 TO 100" your spaces are dropped, all of them.
21:23:28 <byte> meow
21:23:52 × merijn quits (~merijn@host-vr.cgnat-g.v4.dfn.nl) (Ping timeout: 252 seconds)
21:23:56 <dminuoso> "Most BASIC implementations I have seen" - sounds like you are a BASIC connoisseur
21:23:57 <EvanR> monochrom, nice optimization
21:24:20 <EvanR> the language for lambda MOO did something like that
21:24:42 <euouae> I'll be back... with more questions. Got to go, thanks all
21:24:45 <EvanR> store the code in such a shorthand form for execution, then if you go to edit it, it is elaborated and auto formatting
21:24:46 × euouae quits (~euouae@user/euouae) ()
21:24:47 <EvanR> formatted
21:25:16 <dminuoso> Personally I often visualize evaluation in Haskell as a big fat arrow that moves around in my code and just inlines/replaces. :-)
21:25:33 <EvanR> yes!
21:26:00 <EvanR> that even works in IO, if you can visualize the IO effect happening
21:27:10 <dminuoso> Oh Im not sure I understand IO. I have unpacked IO before, unsafeCoerce#'ed state tokens, argued where and why unsafeDupableInlineIO should be used..
21:27:33 <dminuoso> But honestly, every time I look at those discussions or commit logs, I dont know why I said what I said... or did what I did.
21:28:01 <monochrom> You may also like: GHC shift-reset. >:)
21:28:02 <dminuoso> My programs have not crashed.. yet.
21:28:26 <dminuoso> Oh, delimited continuations - never understood what these are about.
21:29:21 <dminuoso> Every time I try and learn about them, I get confused by gibberish lisp
21:29:30 <monochrom> Algebraic effects perform better if you use shift-reset (for handlers) instead of being mathemtical and using algebraic data types.
21:29:37 sp1ff joins (~user@c-67-160-173-55.hsd1.wa.comcast.net)
21:29:52 × hgolden quits (~hgolden@2603:8000:9d00:3ed1:6ff3:8389:b901:6363) (Remote host closed the connection)
21:31:40 <monochrom> Maybe a good analogy is: free monads perform better if you use the CPS version. Now go one step further and use GHC-native continuations instead of functions.
21:32:12 <monochrom> perhaps s/functions/emulating continuations by functions/
21:32:33 <dolio> Who says using algebraic data types is mathematical?
21:33:04 <monochrom> :(
21:33:41 <dolio> Or, the particular implementation of algebraic data types you actually get.
21:33:48 <ski> ("your spaces are dropped, all of them" -- well, not on C64. but it does tokenize the keywords to single bytes)
21:34:47 merijn joins (~merijn@host-vr.cgnat-g.v4.dfn.nl)
21:35:07 hgolden joins (~hgolden@2603:8000:9d00:3ed1:6ff3:8389:b901:6363)
21:37:34 × Smiles quits (uid551636@id-551636.lymington.irccloud.com) (Quit: Connection closed for inactivity)
21:41:19 <EvanR> not state tokens
21:41:26 <EvanR> more like a free monad
21:41:51 <EvanR> mentally note the side effects of whatever library action, then replace with the result >>= the rest of the code
21:42:02 <EvanR> pure result >>= rest of the code
21:42:06 × ezzieyguywuf quits (~Unknown@user/ezzieyguywuf) (Quit: Lost terminal)
21:42:38 × CoolMa7 quits (~CoolMa7@ip5f5b8957.dynamic.kabel-deutschland.de) (Quit: Textual IRC Client: www.textualapp.com)
21:43:53 × takuan quits (~takuan@d8D86B601.access.telenet.be) (Remote host closed the connection)
21:44:44 × merijn quits (~merijn@host-vr.cgnat-g.v4.dfn.nl) (Ping timeout: 260 seconds)
21:45:49 <dolio> My point is, the math doesn't tell you how to implement it. It tells you what operations need to be implemented, and some equations they follow.
21:46:57 <dolio> The math says that a Church encoding is a valid implementation of an algebraic data type, even though it has different performance characteristics than usually expected.
21:47:27 <dolio> Because mathematicians foolishly ignore things like performance.
21:55:24 merijn joins (~merijn@host-vr.cgnat-g.v4.dfn.nl)
22:00:09 × merijn quits (~merijn@host-vr.cgnat-g.v4.dfn.nl) (Ping timeout: 252 seconds)
22:00:10 <ski> (iirc Jean-Yves Girard's "Proofs and Types" (translated and with appendices by Paul Taylor,Yves Lafont) in 1989,1990,2003 at <https://www.paultaylor.eu/stable/prot.pdf> talks a little about that topic)
22:00:47 Googulator joins (~Googulato@2a01-036d-0106-418c-6daf-e703-6cee-d20f.pool6.digikabel.hu)
22:08:21 alfiee joins (~alfiee@user/alfiee)
22:11:08 merijn joins (~merijn@host-vr.cgnat-g.v4.dfn.nl)
22:13:12 × alfiee quits (~alfiee@user/alfiee) (Ping timeout: 272 seconds)
22:15:21 ski . o O ( "Yield: Mainstream Delimited Continuations" by Roshan P. James,Amr Sabry in 2009 (?) at <https://legacy.cs.indiana.edu/~sabry/papers/yield.pdf> )
22:15:34 × merijn quits (~merijn@host-vr.cgnat-g.v4.dfn.nl) (Ping timeout: 252 seconds)
22:22:15 ubert1 joins (~Thunderbi@p200300ecdf4e63eb92aaad72729f1b5d.dip0.t-ipconnect.de)
22:22:30 × ubert quits (~Thunderbi@p200300ecdf4e63626546ad8bed5a8da9.dip0.t-ipconnect.de) (Ping timeout: 246 seconds)
22:22:30 ubert1 is now known as ubert
22:23:43 × wootehfoot quits (~wootehfoo@user/wootehfoot) (Read error: Connection reset by peer)
22:26:31 merijn joins (~merijn@host-vr.cgnat-g.v4.dfn.nl)
22:28:33 peterbecich joins (~Thunderbi@syn-047-229-123-186.res.spectrum.com)
22:30:58 × merijn quits (~merijn@host-vr.cgnat-g.v4.dfn.nl) (Ping timeout: 252 seconds)
22:35:33 L29Ah parts (~L29Ah@wikipedia/L29Ah) ()
22:36:47 jespada joins (~jespada@2800:a4:2215:4d00:f4db:a20a:5385:e4e)
22:37:02 × michalz quits (~michalz@185.246.207.221) (Remote host closed the connection)
22:40:07 fmira joins (~user@user/fmira)
22:41:53 merijn joins (~merijn@host-vr.cgnat-g.v4.dfn.nl)
22:46:21 × ozkutuk quits (~ozkutuk@24.133.86.69) (Quit: Leaving)
22:46:34 × merijn quits (~merijn@host-vr.cgnat-g.v4.dfn.nl) (Ping timeout: 260 seconds)
22:50:13 jespada_ joins (~jespada@2800:a4:2215:4d00:ec45:7066:f4f:e5b9)
22:51:50 × jespada quits (~jespada@2800:a4:2215:4d00:f4db:a20a:5385:e4e) (Ping timeout: 265 seconds)
22:51:55 × target_i quits (~target_i@user/target-i/x-6023099) (Quit: leaving)
22:52:34 × jespada_ quits (~jespada@2800:a4:2215:4d00:ec45:7066:f4f:e5b9) (Client Quit)
22:55:50 × Guest74 quits (~Guest74@81-231-8-142-no600.tbcn.telia.com) (Quit: Client closed)
22:57:16 merijn joins (~merijn@host-vr.cgnat-g.v4.dfn.nl)
22:57:46 alfiee joins (~alfiee@user/alfiee)
22:58:42 × ash3en quits (~Thunderbi@2a03:7846:b6eb:101:93ac:a90a:da67:f207) (Quit: ash3en)
23:01:07 × ubert quits (~Thunderbi@p200300ecdf4e63eb92aaad72729f1b5d.dip0.t-ipconnect.de) (Quit: ubert)
23:01:42 × merijn quits (~merijn@host-vr.cgnat-g.v4.dfn.nl) (Ping timeout: 246 seconds)
23:02:08 × alfiee quits (~alfiee@user/alfiee) (Ping timeout: 252 seconds)
23:07:32 merijn joins (~merijn@host-vr.cgnat-g.v4.dfn.nl)
23:08:01 ash3en joins (~Thunderbi@2a03:7846:b6eb:101:93ac:a90a:da67:f207)
23:08:02 × ash3en quits (~Thunderbi@2a03:7846:b6eb:101:93ac:a90a:da67:f207) (Client Quit)
23:11:39 × machinedgod quits (~machinedg@d108-173-18-100.abhsia.telus.net) (Ping timeout: 265 seconds)
23:11:45 × merijn quits (~merijn@host-vr.cgnat-g.v4.dfn.nl) (Ping timeout: 248 seconds)
23:12:40 merijn joins (~merijn@host-vr.cgnat-g.v4.dfn.nl)
23:14:08 L29Ah joins (~L29Ah@wikipedia/L29Ah)
23:17:09 × merijn quits (~merijn@host-vr.cgnat-g.v4.dfn.nl) (Ping timeout: 248 seconds)
23:19:39 × ChaiTRex quits (~ChaiTRex@user/chaitrex) (Remote host closed the connection)
23:20:08 ChaiTRex joins (~ChaiTRex@user/chaitrex)
23:22:24 machinedgod joins (~machinedg@d108-173-18-100.abhsia.telus.net)
23:28:07 merijn joins (~merijn@host-vr.cgnat-g.v4.dfn.nl)
23:28:30 × machinedgod quits (~machinedg@d108-173-18-100.abhsia.telus.net) (Ping timeout: 244 seconds)
23:32:33 × merijn quits (~merijn@host-vr.cgnat-g.v4.dfn.nl) (Ping timeout: 252 seconds)
23:43:30 merijn joins (~merijn@host-vr.cgnat-g.v4.dfn.nl)
23:45:00 × peterbecich quits (~Thunderbi@syn-047-229-123-186.res.spectrum.com) (Ping timeout: 265 seconds)
23:46:08 jinsun joins (~jinsun@user/jinsun)
23:46:50 alfiee joins (~alfiee@user/alfiee)
23:47:58 × merijn quits (~merijn@host-vr.cgnat-g.v4.dfn.nl) (Ping timeout: 252 seconds)
23:51:22 × alfiee quits (~alfiee@user/alfiee) (Ping timeout: 272 seconds)
23:52:04 ezzieyguywuf joins (~Unknown@user/ezzieyguywuf)
23:55:02 <Leary> kaol: Both ghcid and ghciwatch (given the right flags) allow you to effectively use the repl with `-- $> foo` comments in your code, though the latter is smarter about it---it actually loads the host module so its internals are in scope.
23:55:16 merijn joins (~merijn@host-vr.cgnat-g.v4.dfn.nl)

All times are in UTC on 2025-01-31.