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.