2023/10/16

2023-10-16 00:00:12 +0200 <Inst> well, actually, multiple let blocks
2023-10-16 00:00:29 +0200 <Inst> erm, let expressions, multiple let expressions, order of definitions do matter :)
2023-10-16 00:00:52 +0200 <EvanR> are can't even tell if you're contradicting
2023-10-16 00:01:10 +0200 <Inst> name shadowing
2023-10-16 00:01:25 +0200 <Inst> but only across multiple let expressions
2023-10-16 00:01:27 +0200 <EvanR> I*
2023-10-16 00:01:38 +0200 <EvanR> what
2023-10-16 00:01:50 +0200 <EvanR> one where desugars to one let
2023-10-16 00:01:51 +0200 <monochrom> Yes the order of two blocks matters. But I bet EvanR was referring to within one single block.
2023-10-16 00:02:15 +0200 <Inst> yeah, i know, was just nitpicking, which i guess gets annoying fast :(
2023-10-16 00:02:25 +0200 <Inst> but i've seen people spam let as though it were JS
2023-10-16 00:02:52 +0200 <monochrom> Oh I have also seen people using JS as C, or C as JS.
2023-10-16 00:03:00 +0200 <EvanR> as soon as someone does let x = x + 1 in something and it totally doesn't work, they know something's different, we're not in kansas anymore
2023-10-16 00:03:05 +0200 <monochrom> This is a people problem.
2023-10-16 00:04:09 +0200 <EvanR> haskell 101 day 1 is haskell doesn't have assignment
2023-10-16 00:04:18 +0200 <monochrom> OK I lied as JS as C. But I have seen people using shell scripting as C or Python.
2023-10-16 00:04:44 +0200 <monochrom> Namely, when I taught shell scripting to students who have only seen Python and C. >:)
2023-10-16 00:05:03 +0200 <Inst> EvanR: I THINK, but am unsure, as to whether Chalmers is the one experimenting with IO first
2023-10-16 00:05:05 +0200 <geekosaur> they coud be usin it as algol 60 😛
2023-10-16 00:05:21 +0200 <monochrom> Very first mistake would be syntactic, for example "x = 1" instead of "x=1".
2023-10-16 00:05:53 +0200 <monochrom> And of course later there are more semantic mistakes about data types, how to concat two strings, etc.
2023-10-16 00:06:17 +0200 <EvanR> introducing IO as part of any other topic is easy, >> is an IO action combiner, >>= is the same thing but you can use the intermediate value (via callback), and you have whatever primitive actions
2023-10-16 00:06:28 +0200 <Inst> no, i mean, in total intro courses
2023-10-16 00:06:59 +0200 <EvanR> if necessary, do notation is a straightforward translation into >> and >>=
2023-10-16 00:07:11 +0200 <EvanR> all of the above is not even wrong
2023-10-16 00:09:03 +0200mikoto-chan(~mikoto-ch@ip-212-239-236-59.dsl.scarlet.be) (Ping timeout: 240 seconds)
2023-10-16 00:10:45 +0200 <Inst> well, someone stumbled into a discord while being totally confused because they didn't get it because let allowed them to pretend it was something else
2023-10-16 00:12:41 +0200 <EvanR> the only difference with javascript let is javascript is eager and evaluating expressions can cause side effects. If you're writing haskell code and don't know it's lazy and pure, I really think that's an unstable situation
2023-10-16 00:13:42 +0200 <Inst> yeah, I'm unsure as to what some people are doing, and if you look at Nick of NeoHaskell, he's going through insane lengths to hide what's going on to make it approachable
2023-10-16 00:14:10 +0200gmg(~user@user/gehmehgeh) (Quit: Leaving)
2023-10-16 00:14:18 +0200 <Inst> the let a = 3; let b = 4; a + b example was cribbed from him, but he added a return that had its definition overwritten to mean id
2023-10-16 00:14:21 +0200 <EvanR> there's that word again
2023-10-16 00:14:39 +0200 <EvanR> I wonder what "approachable" itself is hiding
2023-10-16 00:15:11 +0200 <EvanR> you're doing a good job anti-selling NeoHaskell
2023-10-16 00:15:24 +0200 <Inst> I'm not trying to sell it at this point
2023-10-16 00:18:43 +0200 <Inst> just trying to point out that, in search of accessibility, it's possible to hide that it's lazy and pure, with predictable results
2023-10-16 00:19:43 +0200 <EvanR> it's a theorem that any program that successfully evaluates to x with eager evaluation also evaluates to x with lazy evaluation, which is good
2023-10-16 00:20:08 +0200 <EvanR> so the hiding is 100% there
2023-10-16 00:21:23 +0200 <monochrom> Please don't make Haskell "approachable", at least not in your sense.
2023-10-16 00:21:27 +0200machinedgod(~machinedg@d198-53-218-113.abhsia.telus.net)
2023-10-16 00:21:30 +0200 <Inst> unsafeInterleaveIO
2023-10-16 00:21:44 +0200 <monochrom> You are instead always welcome to create another language to your liking.
2023-10-16 00:22:14 +0200 <monochrom> And then watch how people join your new community and then go on to change it to your disliking.
2023-10-16 00:23:30 +0200 <monochrom> Because obviously even under the banner of "more approachable" different people have opposite ideas.
2023-10-16 00:24:16 +0200 <cheater> my "approachable" is clearly superior to your "approachable"
2023-10-16 00:24:18 +0200 <monochrom> We know because even under the very simple "Simple Haskell" banner people already ground to a halt and have to accept that they have to leave it undefined.
2023-10-16 00:24:54 +0200 <Inst> ehhh, re NH: I was more expecting the project to fail, but Nick to produce some useful libraries before it went under
2023-10-16 00:25:15 +0200 <Inst> and some useful brainstorming for others to eventually sift through for good ideas
2023-10-16 00:25:56 +0200 <Inst> i got annoyed when I asked him whether he has some private deadlines, and he just claimed noope
2023-10-16 00:26:09 +0200 <Inst> re approachable, I don't really care about that that much anymore, I don't treat it as my problem
2023-10-16 00:26:18 +0200 <EvanR> going out on a limb thinking it would be easier to just use haskell than to create a language which is slightly different from haskell and rebuild the ecosystem
2023-10-16 00:26:37 +0200 <EvanR> and not sure what the benefit would be
2023-10-16 00:27:39 +0200Vajb(~Vajb@207.61.167.122)
2023-10-16 00:27:39 +0200 <Inst> the bigger problem with something like NH, is that it'd be a complicated social, not technical or design-oriented, problem
2023-10-16 00:27:50 +0200nate2(~nate@c-98-45-169-16.hsd1.ca.comcast.net)
2023-10-16 00:27:53 +0200 <Inst> that was what I was originally planning to post, not mentioning NH at all
2023-10-16 00:29:00 +0200 <Inst> like, my initial response was "screw NeoHaskell" because I thought Nick was a crazy person who wanted to try to split the community, and when I take a gander at NH server, I still feel that way once in a while
2023-10-16 00:29:56 +0200 <Inst> it requires careful management so that some kind of accessible Haskell dialect / prelude / GHC frontend doesn't ruin Haskell proper, but rather works as training wheels to access users Haskell has trouble serving
2023-10-16 00:30:25 +0200 <Inst> I don't get the feeling that thinking in this direction is happening with NH
2023-10-16 00:30:38 +0200 <EvanR> we do have like 100 alternative preludes, I guess 1 more can't hurt
2023-10-16 00:31:19 +0200 <Inst> it seems as though the discussion was toward GHC plugin
2023-10-16 00:31:29 +0200rawles(~rawles@user/rawles) (Quit: Textual IRC Client: www.textualapp.com)
2023-10-16 00:31:52 +0200 <Inst> I'd love, however, if all the concerns were properly addressed, to see Haskellers together try to design a Go
2023-10-16 00:31:58 +0200 <EvanR> if there are valuable changes to how GHC works which makes things actually easier, that should be included in actual GHC
2023-10-16 00:32:05 +0200 <Inst> I would prefer it not to be under NH banner
2023-10-16 00:32:33 +0200 <Inst> but with people I wouldn't have any questions about
2023-10-16 00:33:10 +0200nate2(~nate@c-98-45-169-16.hsd1.ca.comcast.net) (Ping timeout: 255 seconds)
2023-10-16 00:33:55 +0200jumper(~jumper@mobile-access-6df060-90.dhcp.inet.fi)
2023-10-16 00:34:31 +0200hugo(znc@verdigris.lysator.liu.se) (Ping timeout: 255 seconds)
2023-10-16 00:34:47 +0200 <Inst> as for Nick, his line is, he's doing it for himself and his friends, and seems to be just having an attitude of doing it for fun, as a personal project
2023-10-16 00:35:25 +0200 <monochrom> Go already exists. If I want to use it, I can already use it here and now. Why should Haskellers try to design a Go.
2023-10-16 00:35:53 +0200 <Inst> because Haskellers could, one, do it better, and two, hook it up into GHC ecosystem?
2023-10-16 00:35:54 +0200 <monochrom> Please stop advocating Haskell to become something else.
2023-10-16 00:35:58 +0200 <monochrom> Hell, please just stop.
2023-10-16 00:36:28 +0200 <EvanR> once again, Go and approachable keeps coming up in the same discussion. Like, was that a design goal of Go? Because that's contributing to my understanding that approachable = C syntax, and it would be a lot simpler to just call it that
2023-10-16 00:36:39 +0200aforemny(~aforemny@2001:9e8:6ce4:3000:710b:6622:3257:ead) (Quit: ZNC 1.8.2 - https://znc.in)
2023-10-16 00:36:44 +0200Tuplanolla(~Tuplanoll@91-159-68-236.elisa-laajakaista.fi) (Quit: Leaving.)
2023-10-16 00:36:48 +0200 <EvanR> C syntax is great but not for haskell
2023-10-16 00:37:05 +0200 <dibblego> it's great for Simon PJ :)
2023-10-16 00:37:11 +0200 <jumper> hi, may a newbie interject and ask a few questions about haskell syntax?
2023-10-16 00:37:50 +0200 <monochrom> As an anecdotal data point, I write and use some shell scripts instead of changing Haskell to be like shell scripts, I write and use some C programs instead of changing Haskell to become C (not even trying to become a better C).
2023-10-16 00:37:58 +0200aforemny(~aforemny@2001:9e8:6ce4:3000:fb34:5497:c705:b99)
2023-10-16 00:38:04 +0200 <monochrom> A better C is not going to look like Haskell at all.
2023-10-16 00:38:13 +0200 <Inst> Well, I tried, and the only reason I brought up the NH example was as something to be detested
2023-10-16 00:38:33 +0200 <EvanR> well the 2 minutes detesting is over for today I hope
2023-10-16 00:38:42 +0200 <monochrom> And depending on what "better" means, Go and Rust and even ATS already exist.
2023-10-16 00:38:47 +0200 <EvanR> jumper, go ahead!
2023-10-16 00:39:47 +0200 <jumper> EvanR, I'm a bit puzzled about arrows in Haskell, are they as a means for declaring the structure of a function or an implementational path
2023-10-16 00:40:02 +0200 <Inst> What do you mean by arrows?
2023-10-16 00:40:17 +0200 <jumper> f: a -> b -> c
2023-10-16 00:40:21 +0200 <monochrom> Do you have sample code to show what you mean?
2023-10-16 00:40:34 +0200emmanuelux(~emmanuelu@user/emmanuelux)
2023-10-16 00:40:48 +0200 <EvanR> at the type level the -> is the function type constructor, so A -> B is a type, where A and B are types
2023-10-16 00:41:05 +0200 <EvanR> it associates to the right, so a -> b -> c is to be construed as a -> (b -> c)
2023-10-16 00:41:16 +0200 <monochrom> OK I don't think I understand the question (are you sure you are not overthinking?), but I guess the answer is "just declaring".
2023-10-16 00:42:27 +0200 <jumper> so if I have: "myFunc :: Int -> Int", does it mean that myFunc returns Int?
2023-10-16 00:42:34 +0200 <monochrom> Yes
2023-10-16 00:42:34 +0200 <EvanR> yes
2023-10-16 00:42:52 +0200 <jumper> oh okay
2023-10-16 00:42:53 +0200 <EvanR> and takes an Int
2023-10-16 00:43:13 +0200 <EvanR> no more no less!
2023-10-16 00:43:38 +0200alphacentauri(alphacenta@gateway/vpn/protonvpn/alphacentauri) (Quit: WeeChat 4.0.5)
2023-10-16 00:43:59 +0200 <jumper> does haskell support the regular C type datatypes? char, short int, int, int long, float, double etc...
2023-10-16 00:44:30 +0200 <EvanR> those are represented in the Foreign.C.Types module, which is used for doing FFI to e.g. C libraries
2023-10-16 00:45:34 +0200 <Inst> you have some datatypes which are like that, though
2023-10-16 00:45:39 +0200 <EvanR> CChar, CShort, CInt, CLong, CFloat, CDouble, ...
2023-10-16 00:46:06 +0200Vajb(~Vajb@207.61.167.122) (Ping timeout: 260 seconds)
2023-10-16 00:46:21 +0200 <EvanR> Int, Float, and Double are standard haskell types which may or may not correspond to the C versions
2023-10-16 00:46:33 +0200 <monochrom> Or perhaps you just use native Haskell types: Char, Int, Integer, Float, Double, Complex Float, Complex Double.
2023-10-16 00:47:14 +0200 <jumper> Is it possible to ask questions about lambda calculus? I've read that it supposedly is Turing complete, but can't seem to be able to understand the syntax properly.
2023-10-16 00:47:15 +0200 <monochrom> I forgot Rational.
2023-10-16 00:47:20 +0200 <Inst> the funnier thing about Int, Integer (bigInt), Char, Float, etc... is that they're not even primitive, but I guess you're just getting into the lang
2023-10-16 00:47:22 +0200alphacentauri(alphacenta@gateway/vpn/protonvpn/alphacentauri)
2023-10-16 00:47:44 +0200hugo(znc@verdigris.lysator.liu.se)
2023-10-16 00:47:46 +0200 <EvanR> they're not technically primitive but close
2023-10-16 00:48:01 +0200 <Inst> they're just wrappers over actual primitives, and used as standard
2023-10-16 00:48:31 +0200 <EvanR> they're boxed which is important to know
2023-10-16 00:48:46 +0200 <monochrom> I am not sure why you brought that up. Especially given that you depict yourself as caring so much about pedagogy.
2023-10-16 00:48:50 +0200 <EvanR> when you're trying to do optimizations
2023-10-16 00:49:15 +0200 <EvanR> other than that, the wrapper isn't that interesting
2023-10-16 00:49:28 +0200 <monochrom> Premature getting into low-level details is the true cause of being unapproachable, obviously.
2023-10-16 00:49:57 +0200 <EvanR> in other languages I've noticed people really wanting to get directly into the low level
2023-10-16 00:50:12 +0200 <EvanR> and the lack of relative importance of low level details in haskell can be confusing
2023-10-16 00:50:22 +0200 <monochrom> Well you just can't do that for Haskell, or even Scheme, Prolog.
2023-10-16 00:50:37 +0200 <Inst> jumper: what specific questions might you have about lambda calculus?
2023-10-16 00:51:01 +0200 <monochrom> You learn a high-level language, you accept that you have to stay high level for the first 6 weeks or something.
2023-10-16 00:51:42 +0200 <EvanR> C being a high level language, I wish I had learned that first xd
2023-10-16 00:51:46 +0200 <monochrom> Even a C beginner cannot worry about cache locality that early.
2023-10-16 00:52:03 +0200 <EvanR> the portable assembly meme does a lot of damage
2023-10-16 00:52:30 +0200 <Inst> Well, the reason I brought that up was because there seemed to have been something wrong about the question "does Haskell support the regular C type datatypes"
2023-10-16 00:53:12 +0200 <jumper> Inst, the symbol '\' i'll use as lambda symbol. The syntax of "\i.o", as I've understood it, means 'i' as argument to be injected into the function, and 'o' being the "output/declaration" of the function
2023-10-16 00:53:28 +0200 <EvanR> turns out it does, but yeah you would use the usual haskell types usually
2023-10-16 00:53:32 +0200 <monochrom> Yes that's right.
2023-10-16 00:53:52 +0200 <jumper> Inst, but what confuses me is the possibility of having characters after the lambda function which imply either "True" or "False".
2023-10-16 00:54:00 +0200 <monochrom> You should think "anonymous function". I can write a function without giving it a name. THE END.
2023-10-16 00:54:47 +0200 <EvanR> unless you use parentheses, there's no "after the lambda function"
2023-10-16 00:54:55 +0200 <monochrom> So you don't have to write "f x = x + 1" if you don't feel like giving it the name "f". Just write "(\x -> x + 1)" in-place where you use it.
2023-10-16 00:54:57 +0200 <EvanR> \i . o x y z w is all inside the same lambda
2023-10-16 00:55:13 +0200 <Inst> say, \i.o, that's what we'd call "const o", no?
2023-10-16 00:55:22 +0200 <monochrom> Yeah add parentheses to help, if you need.
2023-10-16 00:55:23 +0200 <Inst> as in, if you apply the lambda \i.o to a value, you'll just get back o
2023-10-16 00:55:58 +0200 <monochrom> No, as in, "\foo . bar", place holders for actual code.
2023-10-16 00:56:19 +0200 <EvanR> o could contain i, or not
2023-10-16 00:56:39 +0200 <EvanR> if it does, replacing with const would fail
2023-10-16 00:56:39 +0200 <Inst> tbh, I'm not really qualified to discuss lambda calculus, others here are more conversant, but I'd like to ask
2023-10-16 00:56:54 +0200 <Inst> jumper: could you show me an example of having characters after the lambda function which imply either "True" or "False"?
2023-10-16 00:57:07 +0200 <Inst> /s/me/us
2023-10-16 00:57:48 +0200 <jumper> Inst, \ i . \ o . i o i
2023-10-16 00:58:52 +0200 <EvanR> it's a lambda nested within a lambda
2023-10-16 00:59:12 +0200 <monochrom> Wait, actually Haskell syntax is \i -> o, no?
2023-10-16 00:59:25 +0200 <jumper> but what about the 2 last characters, o and i
2023-10-16 00:59:35 +0200 <jumper> If I have: \i.o i o
2023-10-16 00:59:36 +0200 <EvanR> they're inside the inner lambda (the second lambda)
2023-10-16 01:00:02 +0200 <EvanR> (\i . \o . i) o i, now they're not
2023-10-16 01:00:15 +0200 <EvanR> and the second o is free
2023-10-16 01:00:19 +0200 <EvanR> and the second i
2023-10-16 01:01:13 +0200 <EvanR> and yeah the haskell version is \i -> o i o
2023-10-16 01:01:17 +0200 <jumper> EvanR, when you mean "free" what does it entail? Is there any operation to be done after?
2023-10-16 01:01:39 +0200 <EvanR> variables are either free variables or bound variables introduced by lambda
2023-10-16 01:02:34 +0200 <Inst> that's supposed to be Lambda Calculus
2023-10-16 01:02:34 +0200 <EvanR> by itself \i -> o i o is just a lambda, and we don't know what o is, so nothing can be done
2023-10-16 01:02:51 +0200 <geekosaur> you can't say anything about a free variable. you can substitute a bound variable
2023-10-16 01:02:51 +0200 <Inst> also, jumper, don't be scared, talk as much as you want, people here are generally helpful and friendly
2023-10-16 01:02:52 +0200hugo(znc@verdigris.lysator.liu.se) (Ping timeout: 252 seconds)
2023-10-16 01:03:29 +0200 <yin> λi.λo.ioi = \i -> \o -> (i o) i
2023-10-16 01:03:50 +0200YoungFrog(~youngfrog@39.129-180-91.adsl-dyn.isp.belgacom.be) (Ping timeout: 246 seconds)
2023-10-16 01:04:05 +0200Square(~Square@user/square)
2023-10-16 01:04:23 +0200 <Inst> jumper: just curious, what's the context of your questions? What do you know so far?
2023-10-16 01:04:40 +0200 <Inst> Are you studying Haskell and Lambda Calculus for a course? Or are you doing this on your own?
2023-10-16 01:05:36 +0200 <yin> which is the same as (\i o -> i o i)
2023-10-16 01:05:53 +0200 <jumper> Inst, beginner level, I just recently noticed the turing completeness of boolean algebra and want to understand the syntax
2023-10-16 01:06:17 +0200 <jumper> from the lower bools to the higher functional abstractions
2023-10-16 01:06:30 +0200 <yin> jumper: what languages are you most familiar with?
2023-10-16 01:06:38 +0200 <jumper> C and C++ is familiar to me
2023-10-16 01:06:45 +0200 <yin> javascript?
2023-10-16 01:06:50 +0200 <EvanR> expanding the bare lambda calculus a bit, you can see implied in \i -> 1 + i that without parentheses stuff to the right of -> is supposed to be all in the same lambda body, not (\i -> 1) + i, where i is free and comes out of nowhere
2023-10-16 01:06:51 +0200 <jumper> and assembler
2023-10-16 01:07:22 +0200 <ncf> turing completeness of boolean algebra??
2023-10-16 01:07:45 +0200 <EvanR> lambda calculus is turing complete and you can encode boolean algebra in it
2023-10-16 01:08:08 +0200 <EvanR> but that's not to say boolean algebra is turing complete
2023-10-16 01:08:36 +0200 <jumper> well not basic boolean algebra ofc
2023-10-16 01:09:04 +0200 <yin> i did wrote this when i was starting out, maybe you can find it useful: https://github.com/jrvieira/fun/blob/main/pwn.js
2023-10-16 01:14:30 +0200jumper(~jumper@mobile-access-6df060-90.dhcp.inet.fi) (Ping timeout: 258 seconds)
2023-10-16 01:16:30 +0200jumper(~jumper@mobile-access-2e844c-234.dhcp.inet.fi)
2023-10-16 01:16:56 +0200 <jumper> hello?
2023-10-16 01:17:07 +0200 <yin> hello
2023-10-16 01:17:52 +0200dsrt^(~cd@76.145.193.217) (Remote host closed the connection)
2023-10-16 01:17:52 +0200cuiltb^(~cd@76.145.193.217) (Remote host closed the connection)
2023-10-16 01:18:09 +0200cuiltb^(~cd@76.145.193.217)
2023-10-16 01:18:09 +0200dsrt^(~cd@76.145.193.217)
2023-10-16 01:18:27 +0200 <Inst> https://ircbrowse.tomsmeding.com/browse/lchaskell
2023-10-16 01:18:30 +0200 <Inst> if you missed anything
2023-10-16 01:18:53 +0200 <Inst> message sent by yin about 28 seconds after your last message
2023-10-16 01:19:06 +0200NinjaTrappeur(~ninja@about/aquilenet/vodoo/NinjaTrappeur) (Ping timeout: 258 seconds)
2023-10-16 01:21:18 +0200 <jumper> Should I fork my lambda calculus questions to #lambdacalculus?
2023-10-16 01:21:25 +0200YoungFrog(~youngfrog@39.129-180-91.adsl-dyn.isp.belgacom.be)
2023-10-16 01:21:47 +0200fweht(uid404746@id-404746.lymington.irccloud.com) (Quit: Connection closed for inactivity)
2023-10-16 01:22:43 +0200NinjaTrappeur(~ninja@about/aquilenet/vodoo/NinjaTrappeur)
2023-10-16 01:22:49 +0200 <jumper> Or is #haskell-offtopic better? The questions are kinda intermixed
2023-10-16 01:23:29 +0200 <Inst> #lambdacalculus is dead
2023-10-16 01:23:58 +0200 <Inst> monochrom has moderator access here, so if he feels your questions are off-topic, let him point it out
2023-10-16 01:24:36 +0200 <geekosaur> we do discuss lambda calculus here
2023-10-16 01:24:42 +0200 <Inst> and, lambda calculus is the first chapter of Haskell Programming from First Principles, so it's sort of relevant to Haskell?
2023-10-16 01:24:50 +0200 <geekosaur> and #lambdacalculus is a new channe, it'l grow faster if people use it
2023-10-16 01:25:45 +0200 <Inst> it's not registered?
2023-10-16 01:25:55 +0200 <geekosaur> that means little
2023-10-16 01:26:45 +0200Vajb(~Vajb@207.61.167.122)
2023-10-16 01:28:14 +0200 <geekosaur> hm, doesn't look like lisbeths is around right now
2023-10-16 01:30:59 +0200 <jumper> yin, is the => operator in js a similar construct to haskells arrow?
2023-10-16 01:31:00 +0200Vajb(~Vajb@207.61.167.122) (Read error: Connection reset by peer)
2023-10-16 01:31:19 +0200 <monochrom> No. Haskell's lambda.
2023-10-16 01:31:27 +0200 <jumper> oh
2023-10-16 01:31:43 +0200 <Inst> Haskell has like 3 syntactical arrows
2023-10-16 01:31:45 +0200 <monochrom> They write "x => x + 1", we write "\x -> x + 1", Python's is "lambda x: x + 1".
2023-10-16 01:31:50 +0200Vajb(~Vajb@207.61.167.122)
2023-10-16 01:32:17 +0200 <monochrom> A long time ago, JS's was "function (x) { return x+1; }" :)
2023-10-16 01:32:42 +0200 <monochrom> I bet you've also seen C++ lambdas.
2023-10-16 01:33:33 +0200 <jumper> monochrom, and in C++ it would be equivalent to, [](x){ return x + 1; }?
2023-10-16 01:33:43 +0200 <monochrom> Yeah.
2023-10-16 01:34:26 +0200 <Inst> you'll see -> and <- a lot, and they mean different things depending on the context
2023-10-16 01:35:09 +0200 <jumper> Inst, <-, a different operator all together?
2023-10-16 01:35:49 +0200 <geekosaur> it's sort of a lambda
2023-10-16 01:36:09 +0200 <geekosaur> foo <- bar, in a do expression, expands to: bar >>= \foo ->
2023-10-16 01:36:10 +0200 <jumper> but backwards?
2023-10-16 01:36:15 +0200 <jackdk> `<-` is used when desuraging `do`-notation, which creates a syntactic sugar: `x <- e` desugars into `e >>= \x -> ...`
2023-10-16 01:36:22 +0200 <monochrom> Let's not get ahead of ourselves.
2023-10-16 01:36:29 +0200 <jackdk> oh geekosaur is faster and monochrom is correct
2023-10-16 01:36:50 +0200 <Inst> yeah, not too advanced, i guess the point was to emphasize that talking about Haskell arrows is imprecise
2023-10-16 01:37:20 +0200 <jumper> What about => in haskell?
2023-10-16 01:37:45 +0200 <monochrom> A long time ago, Inst talked about teaching Haskell but had not learned Haskell. I thought, OK the only bad thing is thinking about teaching something else without having learnin it first, but I trust that at least they had already learned how to teach in general.
2023-10-16 01:37:59 +0200 <monochrom> Today, I see ample evidence that they don't even know how to teach.
2023-10-16 01:38:20 +0200 <geekosaur> sadly I'd say that's true of a lot of teachers
2023-10-16 01:39:11 +0200 <Inst> monochrom: thanks for the frank assessment :)
2023-10-16 01:40:37 +0200hugo(znc@verdigris.lysator.liu.se)
2023-10-16 01:41:02 +0200 <jumper> Is there some kind of a Rosetta stone for haskell?
2023-10-16 01:41:21 +0200 <geekosaur> I think Haskell's too different for one to be useful
2023-10-16 01:41:30 +0200 <geekosaur> I mean, what would the entry for assignment be?
2023-10-16 01:41:48 +0200 <jackdk> What sort of questions would you ask of that rosetta stone?
2023-10-16 01:42:12 +0200 <Inst> yeah, i mean, the way i should have addressed the question about C types, should have been, to ask what was meant by c types
2023-10-16 01:42:25 +0200 <monochrom> Cheat sheets though are possible, just aiming at reading the syntax quickly. I know of https://soupi.github.io/rfc/reading_simple_haskell/
2023-10-16 01:42:56 +0200 <monochrom> I think there are a few more cheat sheets out there. I just didn't care enough to bookmark them.
2023-10-16 01:43:21 +0200 <Inst> => is hard to explain, <- shouldn't have been brought up in detail, because it concerns some advanced stuff that's better for you to get to later
2023-10-16 01:44:29 +0200 <Inst> the arrow stuff, I should have just specified that -> gets used for separate things, and arrows as a term can mean different things in a Haskell context so using arrows to describe -> isn't accurate
2023-10-16 01:45:36 +0200 <jumper> Inst, I don't mind it, I actually prefer harder topics than novice learning curves
2023-10-16 01:46:53 +0200 <Inst> in the context of a type signature, like foo :: Int -> Int, you'll sometimes have lowercase things, for instance, id : a -> a
2023-10-16 01:47:09 +0200 <jumper> Is the => operator simply a declarative constraint?
2023-10-16 01:47:11 +0200 <Inst> this usually means that a can stand for any normal type
2023-10-16 01:47:22 +0200 <Inst> id :: a -> a
2023-10-16 01:47:51 +0200hugo(znc@verdigris.lysator.liu.se) (Ping timeout: 240 seconds)
2023-10-16 01:48:09 +0200 <Inst> the lowercase things are called type variables
2023-10-16 01:48:44 +0200 <Inst> sometimes, you'll see a type signature like "show :: Show a => a -> String"
2023-10-16 01:49:24 +0200 <Inst> what the => is doing is that it's indicating that what's on the left is the constraint on the allowed types for the type variables
2023-10-16 01:49:33 +0200 <geekosaur> re "advanced topics", monochrom and I prefer teaching >>= first
2023-10-16 01:49:51 +0200 <geekosaur> teach do notation once it will make sense
2023-10-16 01:50:25 +0200hugo(znc@verdigris.lysator.liu.se)
2023-10-16 01:50:56 +0200 <jumper> Inst, is haskell case insensitive?
2023-10-16 01:51:00 +0200Vajb(~Vajb@207.61.167.122) (Ping timeout: 255 seconds)
2023-10-16 01:51:12 +0200 <Inst> haskell is case sensitive
2023-10-16 01:51:18 +0200 <monochrom> Ugh there hasn't been a case insensitive language for a long long time...
2023-10-16 01:51:42 +0200 <Inst> monochrom: the hard thing for me, is, when a learner has a misconception, and you want to correct them
2023-10-16 01:52:06 +0200 <Inst> but to correct them, you want to delve into things that are probably not appropriate for them at their stage of learning
2023-10-16 01:52:34 +0200 <jumper> Inst, so your example "show :: Show a => a String", Show is other type declared somewhere else?
2023-10-16 01:53:12 +0200 <jumper> show :: Show a => a -> String *
2023-10-16 01:53:18 +0200 <Inst> Show is a constraint
2023-10-16 01:53:32 +0200 <jumper> yes, but the constraint is of type "Show"
2023-10-16 01:55:17 +0200 <geekosaur> calling it "type" is asking for confusion
2023-10-16 01:55:50 +0200 <Inst> well, it's not a type, it's a constraint, but i really shouldn't have brought that up, are you sure you're not doing this in an academic setting?
2023-10-16 01:56:26 +0200 <monochrom> Um let me correct all of you. >:)
2023-10-16 01:56:42 +0200 <monochrom> "Show" is not a constraint. It is [the name of] a type class.
2023-10-16 01:56:53 +0200 <monochrom> Now, "Show a", that's a constraint.
2023-10-16 01:57:27 +0200 <jumper> so function "show", has to have an "a" which is of type "Show"?
2023-10-16 01:57:42 +0200 <Inst> the a type has to be a member of the typeclass Show
2023-10-16 01:58:05 +0200 <Inst> typeclasses are a rabbit hole
2023-10-16 01:58:14 +0200 <Inst> do you really want to get into that?
2023-10-16 01:58:17 +0200 <jumper> wait so, Show::a?
2023-10-16 01:59:07 +0200 <geekosaur> no
2023-10-16 01:59:14 +0200 <Inst> easier way is whether or not you'll just accept that Show a is a constraint limiting the allowed types that the type variable a can be
2023-10-16 01:59:27 +0200 <Inst> if you don't, we have to go into typeclasses
2023-10-16 01:59:33 +0200 <geekosaur> there exists a `instance Show Foo` when `a` unifies with `Foo`
2023-10-16 02:00:11 +0200 <geekosaur> if there is no such instance for whatever type `a` works out to be, the `Show a` constraint fails
2023-10-16 02:00:46 +0200 <monochrom> You know, I'll just shameless plug my course notes last summer https://www.cs.utoronto.ca/~trebla/CSCC24-2023-Summer/ . Or you could study any other Haskell tutorials.
2023-10-16 02:00:46 +0200misterfish(~misterfis@87.215.131.102) (Ping timeout: 255 seconds)
2023-10-16 02:03:39 +0200 <jumper> #ifdef Show::a \n String show(a){...} \n #endif
2023-10-16 02:04:02 +0200 <jumper> show:: Show a => a -> String
2023-10-16 02:04:41 +0200bilegeek(~bilegeek@2600:1008:b02f:1011:22e7:78e8:8a34:1aa8)
2023-10-16 02:04:44 +0200 <monochrom> I'm afraid that analogy breaks in multiple ways.
2023-10-16 02:05:12 +0200 <monochrom> And by the time you successfully describe the one way it doesn't break and so it is what you mean,
2023-10-16 02:05:27 +0200 <monochrom> we may as well skip the analogy and just say directly what you mean.
2023-10-16 02:05:37 +0200 <Inst> so monochrom, you'd suggest this?
2023-10-16 02:05:38 +0200 <Inst> https://www.cs.utoronto.ca/~trebla/CSCC24-2023-Summer/04-haskell-types-2.html
2023-10-16 02:05:45 +0200 <Inst> that's the discussion of typeclasses
2023-10-16 02:05:49 +0200 <monochrom> That's what's wrong with all analogies. All of them. They are more like insider jokes.
2023-10-16 02:05:57 +0200 <monochrom> Yes.
2023-10-16 02:06:28 +0200 <monochrom> But earlier lectures also have lambdas and why we write like "Int -> Bool -> Char" and "f x y" and what they mean.
2023-10-16 02:08:30 +0200 <Inst> what would you do in that scenario, then? as in, you know the learner has a misconception, you want to tilt them in the right direction, but you're afraid of capsizing them into some rabbit hole?
2023-10-16 02:08:56 +0200 <monochrom> I don't have a general algorithm for that.
2023-10-16 02:09:15 +0200 <monochrom> From past experience, every individual case admits its own simple solution.
2023-10-16 02:09:28 +0200 <Inst> only after careful consideration of every individual case
2023-10-16 02:10:57 +0200 <monochrom> One example that comes to mind is someone wrote "x = 2*x + 1" and wondered why it didn't mean solving for x in the popular sense.
2023-10-16 02:11:31 +0200 <Inst> i've heard about that, i.e, assignment is actually alien to people learning programming for the first time
2023-10-16 02:11:35 +0200 <Inst> or rather, reassignment
2023-10-16 02:11:50 +0200 <monochrom> My solution did not even bring up "it does solve for x, but in the information order sense" (which would be technical true actually, see my "partial order theory of recursion blahblah")
2023-10-16 02:12:32 +0200 <monochrom> The simple solution was "recall zs = 0 : zs. so this is recursion. except x = 2*x + 1 is the non-terminating kind."
2023-10-16 02:13:25 +0200 <jumper> show :: Show a => a -> String != String show(Show.a){...} ?
2023-10-16 02:14:06 +0200 <monochrom> I think I don't know what "String show(Show.a){...}" means.
2023-10-16 02:14:40 +0200 <Inst> bleh, typeclasses is the easy way, which is why it was a mistake to get into this rabbit hole
2023-10-16 02:15:07 +0200 <Inst> class Show a where
2023-10-16 02:15:09 +0200 <Inst> ...
2023-10-16 02:15:12 +0200 <Inst> declaration of a typeclass
2023-10-16 02:15:38 +0200 <Inst> there's a type signature of show, there, should be show :: a -> String
2023-10-16 02:15:38 +0200 <geekosaur> jumper, there is no analogy that will help you
2023-10-16 02:15:39 +0200 <jumper> monochrom, is it even possible to describe it in C?
2023-10-16 02:15:45 +0200 <geekosaur> they're all going to be incorrect
2023-10-16 02:16:02 +0200 <Inst> instance Show Int where
2023-10-16 02:16:03 +0200 <Inst> ...
2023-10-16 02:16:23 +0200 <Inst> where it's an impleemntation of the function Show where a is Int
2023-10-16 02:16:47 +0200 <monochrom> Yes it is possible because Haskell can be compiled to C, so I could just show you the result of compilation. No it is useless, you wouldn't even learn Java by compiling to any other language.
2023-10-16 02:16:56 +0200 <Inst> if there's no instance Show Foo for your type
2023-10-16 02:17:11 +0200 <Inst> erm, the function show
2023-10-16 02:17:26 +0200 <Inst> not Show, because functions cannot start with a capital letter in Haskell
2023-10-16 02:17:45 +0200 <monochrom> Hell, you wouldn't even learn C++ by translating to C.
2023-10-16 02:18:12 +0200 <Inst> if there's no instance Show Foo for your type, your code won't compile because of the constraint
2023-10-16 02:18:17 +0200 <jumper> monochrom, eh, that's how I learned C++
2023-10-16 02:18:23 +0200 <monochrom> Despite even the fact that the 1st version of C++ was just a lot of C macros, or something close to that.
2023-10-16 02:18:26 +0200 <jumper> C with classes :D
2023-10-16 02:19:07 +0200 <monochrom> Did you actually translate C++ classes to classless C?
2023-10-16 02:19:11 +0200nitrix-or-treatnitrix
2023-10-16 02:19:32 +0200 <monochrom> Because I am not going to translate type class Haskell to type-class-less C either.
2023-10-16 02:19:33 +0200 <jumper> monochrom, the concept of a class I learned by making classes in C
2023-10-16 02:19:43 +0200 <Inst> I'm told there are some ancient courses where you learn C++ by implementing it in C, but that was back when C++ and C were more closely related
2023-10-16 02:19:45 +0200 <monochrom> OK so you did.
2023-10-16 02:20:01 +0200 <monochrom> Then look for "dictionary passing" I guess.
2023-10-16 02:20:47 +0200 <Inst> but where did I lose you, jumper?
2023-10-16 02:21:07 +0200 <jumper> Inst, what do you specifically mean?
2023-10-16 02:21:19 +0200 <monochrom> Perhaps insisting on a translation to a familiar language?
2023-10-16 02:21:32 +0200 <Inst> like, the explanation of how => is used to specify constraints on type variables?
2023-10-16 02:21:44 +0200 <monochrom> I mean, I am not exempt from that, either.
2023-10-16 02:21:51 +0200 <jumper> The concept "Constraint" is what I'm trying to define
2023-10-16 02:22:12 +0200 <monochrom> Just that I insist on translating to math (the denotational way), and therefore I have actually had great success.
2023-10-16 02:22:44 +0200 <Inst> the type variable a, in that type signature, can be any normal type
2023-10-16 02:23:05 +0200 <Inst> you're constrainting it because the code only makes sense if the constraint applies
2023-10-16 02:23:14 +0200 <monochrom> When I was young and arrogant, I even said the following:
2023-10-16 02:23:37 +0200 <Inst> if there's no implementation of Show and show for that type, what is the function supposed to do?
2023-10-16 02:23:39 +0200 <monochrom> "The language of CS is not C, or Pascal, or even Lisp Prolog etc. The language of CS is math."
2023-10-16 02:23:59 +0200 <jumper> monochrom, true
2023-10-16 02:24:09 +0200 <monochrom> Arrogant but actually right on and successful.
2023-10-16 02:24:44 +0200 <jumper> Inst, "a" is a type right? show :: Show a => a -> String
2023-10-16 02:24:55 +0200 <Inst> it's a type variable, which means, any "normal" type
2023-10-16 02:25:27 +0200 <Inst> Show a constrains a to mean "any type that has an instance declaration for Show"
2023-10-16 02:25:46 +0200[itchyjunk](~itchyjunk@user/itchyjunk/x-7353470) (Ping timeout: 260 seconds)
2023-10-16 02:26:44 +0200 <jumper> so "a Show" has to exist?
2023-10-16 02:27:22 +0200 <nitrix> Other way arounds, instances like Show Int, Show Float, etc have to exists to be able to use show on them.
2023-10-16 02:28:42 +0200 <nitrix> So Int would implement show :: Show Int => Int -> String, Float would implement show :: Show Float => Float -> String, so on.
2023-10-16 02:29:13 +0200 <Inst> ^^^
2023-10-16 02:29:49 +0200[itchyjunk](~itchyjunk@user/itchyjunk/x-7353470)
2023-10-16 02:29:51 +0200 <jumper> I'm blind, I'm not seeing the pattern. What is "Show"?
2023-10-16 02:30:03 +0200 <Inst> class Show where
2023-10-16 02:30:10 +0200 <Inst> excuse me
2023-10-16 02:30:13 +0200 <Inst> class Show a where
2023-10-16 02:30:19 +0200 <Inst> show :: a -> String
2023-10-16 02:30:34 +0200 <Inst> iirc, it's more complicated than that, but this is just a simplification
2023-10-16 02:30:34 +0200 <nitrix> `Show a` is a typeclass. `Show Int` is an instance of that typeclass. `Show` alone is more complicated, it's a type constructor.
2023-10-16 02:31:43 +0200 <Inst> show here is defined in the typeclass only by its type signature
2023-10-16 02:31:49 +0200 <Inst> you need an instance declaration
2023-10-16 02:31:53 +0200 <Inst> instance Show foo where
2023-10-16 02:32:03 +0200 <Inst> to have the actual function
2023-10-16 02:32:07 +0200eggplantade(~Eggplanta@2600:1700:38c5:d800:58fe:b85d:458c:ca9c) (Remote host closed the connection)
2023-10-16 02:32:30 +0200 <Inst> for that particular type
2023-10-16 02:33:00 +0200_xor7(~xor@72.49.199.93)
2023-10-16 02:33:48 +0200 <jumper> Inst, should I dissect this syntax that you wrote: "class Show a where \n show :: a -> String"? Am I understanding correctly that you're trying to refer that show is a member of Show?
2023-10-16 02:34:00 +0200 <Inst> it's a haskell typeclass, not an OOP class
2023-10-16 02:34:20 +0200 <Inst> it's closer to an interface, it's defining a bunch of names (values or functions)
2023-10-16 02:34:45 +0200 <Inst> the names are overloaded based on the type
2023-10-16 02:35:31 +0200 <nitrix> The type class represents a group of types and it comes with a contract. The types that wants to belong in that group have to implement the functions the specified in the contract.
2023-10-16 02:35:52 +0200_xor(~xor@72.49.199.93) (Ping timeout: 255 seconds)
2023-10-16 02:35:52 +0200_xor7_xor
2023-10-16 02:36:41 +0200 <nitrix> Here, types that wants to be be showable (printable to a string) needs to implement the instance with a reasonable show function.
2023-10-16 02:37:20 +0200 <Inst> it's sort of a mess, I really shouldn't have started this
2023-10-16 02:37:30 +0200 <Inst> nitrix: what jumper really wants to know right now is what => does in a Haskell context
2023-10-16 02:37:41 +0200 <Inst> he is really, really new
2023-10-16 02:38:17 +0200 <nitrix> Well, you're reasonably there already with the idea of constraining type variables to specific type classes.
2023-10-16 02:38:37 +0200 <geekosaur> if you really want to know, Show a => translates to the Show instance dictionary for type a
2023-10-16 02:38:40 +0200 <Inst> he doesn't know what a typeclass is, because he was asking about what the function arrow is
2023-10-16 02:39:17 +0200 <geekosaur> if you specify something like (Show a, Monad m) => then it translates to a tuple containinjg the Show instance dictionary for a and the Monad instance dictionary for m
2023-10-16 02:39:18 +0200 <nitrix> You can have more than one constraint also. sort :: Eq n, Ord n => [n] -> [n], etc.
2023-10-16 02:39:46 +0200 <nitrix> Forgot the parens.
2023-10-16 02:39:52 +0200 <Inst> in this case, Eq is actually easier to deal with, tbh
2023-10-16 02:40:02 +0200 <Inst> (==) is the member of Eq, jumper
2023-10-16 02:40:04 +0200 <geekosaur> and m will be determined at call sites and the appropriate instance declaration must be in scope
2023-10-16 02:40:16 +0200 <geekosaur> "a and m"
2023-10-16 02:40:17 +0200 <Inst> when you use ==, you're not calling a language primitive, but rather, you're calling a library-defined function
2023-10-16 02:40:27 +0200ddellacosta(~ddellacos@ool-44c738de.dyn.optonline.net)
2023-10-16 02:40:32 +0200 <Inst> the language starts by reading the types of the arguments to ==
2023-10-16 02:40:58 +0200 <Inst> then looks up the correct version of == for those types
2023-10-16 02:41:20 +0200 <Inst> anyways, this is one reason people are pissed off at me, monochrom
2023-10-16 02:41:26 +0200 <Inst> sorry, i should have just walked off
2023-10-16 02:41:58 +0200 <geekosaur> I think here the real problem is jumper is insisting we give them C
2023-10-16 02:42:02 +0200 <geekosaur> and we can't
2023-10-16 02:42:27 +0200 <geekosaur> well, we could, but it'd be a lot of code implementing the whole typeclass mechanism
2023-10-16 02:42:58 +0200 <nitrix> And the higher-kinded stuff too :]
2023-10-16 02:43:02 +0200 <nitrix> ,k (=>)
2023-10-16 02:43:24 +0200 <nitrix> I've been away from #haskell for so long, how do you trigger lambdabot again?
2023-10-16 02:43:26 +0200 <Inst> (=>) is raw syntax, isn't it?
2023-10-16 02:43:32 +0200 <geekosaur> :k (=>)
2023-10-16 02:43:33 +0200 <lambdabot> error: parse error on input ‘=>’
2023-10-16 02:43:51 +0200 <geekosaur> but as I suspected, it doesn';t do that because => is syntax, not an operator
2023-10-16 02:44:12 +0200 <nitrix> Interesting. I recall (=>) having some fancy Constraint -> * -> * kind.
2023-10-16 02:44:29 +0200 <nitrix> Maybe figuratively.
2023-10-16 02:44:47 +0200 <geekosaur> (what type does it need to be to support both Constraint => and (Constraint a, Constraint b) =>?)
2023-10-16 02:44:59 +0200 <geekosaur> or kind or sort or etc.
2023-10-16 02:45:11 +0200 <nitrix> Obviously we need kindclasses :P
2023-10-16 02:45:46 +0200 <monochrom> Unpopular opinion: I hate "typeclass", I prefer "type class". And the Haskell Report agrees.
2023-10-16 02:46:09 +0200 <Inst> btw, here's something interesting
2023-10-16 02:46:17 +0200 <Inst> at least in ghci, if you:
2023-10-16 02:46:19 +0200 <nitrix> I think I used to have an opinion on that but it's long gone.
2023-10-16 02:46:19 +0200 <Inst> data Foo = Foo
2023-10-16 02:46:26 +0200 <monochrom> Unpopular opinion #2: "The Maybe type" is OK. And the Haskell Report agrees. >:)
2023-10-16 02:46:28 +0200 <Inst> instance Show Foo where
2023-10-16 02:46:55 +0200 <Inst> then show Foo, at least in ghci, you hang
2023-10-16 02:47:00 +0200 <Inst> not even an exception
2023-10-16 02:47:19 +0200 <jumper> can Haskell be expressed through Python?
2023-10-16 02:47:22 +0200lisbeths(uid135845@id-135845.lymington.irccloud.com)
2023-10-16 02:47:25 +0200 <geekosaur> no
2023-10-16 02:47:29 +0200 <jumper> damn
2023-10-16 02:47:41 +0200 <geekosaur> or at least no more usefully than it can through C
2023-10-16 02:47:55 +0200 <Inst> wait, can typeclasses be expressed as C++ concepts?
2023-10-16 02:48:02 +0200 <monochrom> I translate Python to Haskell, for that subset of Python that is translatable to Haskell.
2023-10-16 02:48:03 +0200 <Inst> are you familiar with that?
2023-10-16 02:48:16 +0200 <monochrom> For the rest of Python, I just call it garbage and ignore. >:)
2023-10-16 02:48:54 +0200 <geekosaur> I'm not, I stopped bothering with C++ before they added concepts. Supposedly there are similarities though
2023-10-16 02:49:19 +0200 <Inst> https://en.cppreference.com/w/cpp/language/constraints
2023-10-16 02:49:21 +0200 <Inst> oh hey
2023-10-16 02:49:24 +0200 <Inst> this looks awfully familiar
2023-10-16 02:49:44 +0200 <jumper> C++11 please
2023-10-16 02:49:54 +0200 <jumper> D:
2023-10-16 02:50:28 +0200 <Inst> how about, let's leave it this way, Haskell has a really powerful type system, typeclasses, constraints, and => are part of Haskell's really powerful type system
2023-10-16 02:51:26 +0200 <monochrom> Inst: And if you "instance Eq Foo", then "Foo == Foo" also hangs. Do you now see why?
2023-10-16 02:51:26 +0200 <Inst> If you are really desperate, imo, I took a look at monochrom's lecture notes. Those are really good, and get to typeclasses really fast.
2023-10-16 02:52:05 +0200 <Inst> I don't, actually. The point is more, there's no implementation for either show or (==)
2023-10-16 02:52:13 +0200 <Inst> I'd have expected Haskell to throw an exception
2023-10-16 02:52:20 +0200 <monochrom> But there are default implementations. That's why.
2023-10-16 02:52:25 +0200 <Inst> ahhh
2023-10-16 02:52:27 +0200 <Inst> doip
2023-10-16 02:52:40 +0200 <monochrom> And there are static warnings.
2023-10-16 02:52:42 +0200 <jrm> Hi. I'm very new to Haskell and just at the 'playing around' stage, i.e., I have no clue what I'm doing. I just tested calculating a Fibonacci sequence with n=45 using C and Haskell. https://paste.tomsmeding.com/E9GhyxAC https://paste.tomsmeding.com/b5Tz9Pfa. On my laptop, the C program took 12.7 s and the Haskell program took 110 s to complete. Surely I must be doing something wrong for the Haskell program to take ~9 times longer.
2023-10-16 02:53:33 +0200 <geekosaur> I thought == lost its default when /= left the typeclass, because the default was in terms of /=
2023-10-16 02:54:28 +0200 <monochrom> Ah now I think I've heard that, but too recent.
2023-10-16 02:54:48 +0200 <geekosaur> jrm, you're doing it the slow way so it has to keep recalculating things. Haskell does not memoize automatically
2023-10-16 02:54:49 +0200 <monochrom> Was it in 9.4? I happen to have a 9.4 docker image...
2023-10-16 02:54:57 +0200 <geekosaur> I think so?
2023-10-16 02:55:05 +0200 <Inst> wait, is there a space leak there?
2023-10-16 02:55:43 +0200 <Inst> i mean Haskell taking 9 times longer suggests there's a space leak
2023-10-16 02:56:05 +0200 <Inst> geekosaur: the C program is also essentially the same algorithm and probably stack overflows for n=46 or something
2023-10-16 02:56:06 +0200 <monochrom> /= is still part of Eq in 9.4. I'll try 9.6.
2023-10-16 02:56:19 +0200Lord_of_Life(~Lord@user/lord-of-life/x-2819915) (Ping timeout: 245 seconds)
2023-10-16 02:56:47 +0200 <Inst> i'm more interested in the haskell program insofar as you'd want to ask how to get it not to space leak
2023-10-16 02:57:01 +0200 <geekosaur> yeh, just found that (sadly the docs went weird starting with 9.4)
2023-10-16 02:57:04 +0200Lord_of_Life(~Lord@user/lord-of-life/x-2819915)
2023-10-16 02:57:29 +0200 <geekosaur> it only suggests a time leak, not necessarily a space leak 🙂
2023-10-16 02:58:07 +0200 <monochrom> I had the 9.6 docker image but I deleted it to save disk space. I should steal more space from my unused Windows partition...
2023-10-16 02:58:23 +0200 <geekosaur> anyway it goes faster if you use a definition that memoizes instead of constantly recalculating (which will be slow, Haskell is not an especially fast language when it comes to brute-force computation)
2023-10-16 02:58:26 +0200 <monochrom> Hrm no change in 9.6.
2023-10-16 02:58:44 +0200 <monochrom> But yeah I think I heard that one day /= will be moving out...
2023-10-16 02:59:01 +0200 <monochrom> But really I'm still with 9.2 :)
2023-10-16 02:59:33 +0200 <monochrom> But OK, I see that ghcup is now recommending 9.4, I will migrate soon.
2023-10-16 02:59:57 +0200 <monochrom> But the C version is doing the same non-tail exponential recursion.
2023-10-16 03:00:10 +0200 <geekosaur> yes, the comment about brute force applies more
2023-10-16 03:00:14 +0200 <monochrom> I think I should first ask/remind "did you tell GHC to -O?"
2023-10-16 03:00:22 +0200 <geekosaur> memoization is how you defeat it 🙂
2023-10-16 03:00:50 +0200 <geekosaur> anyway: the way to speed this up is to memoize in some way or another, either caching in a Map or being clever
2023-10-16 03:00:59 +0200 <monochrom> But if someone points out "gcc changes it to memoization" I wouldn't be surprised. :)
2023-10-16 03:01:42 +0200 <geekosaur> @let fibs = 0 : 1 : zipWith (+) fibs (tail fibs)
2023-10-16 03:01:43 +0200 <lambdabot> Defined.
2023-10-16 03:02:36 +0200 <monochrom> Some years ago someone wrote "for i from 1 to N" and furiously complained that Haskell was slow. Turned out gcc cheated and compiled that loop to one single O(1) assignment i=N.
2023-10-16 03:02:42 +0200 <jrm> This Fibonacci example is in Chapter 6 of 'Programming in Haskell', 2nd Ed. by Graham Hutton.
2023-10-16 03:02:57 +0200 <Inst> that probably was me
2023-10-16 03:03:01 +0200 <jrm> To be clear, I'm not complaining. Just curious. :)
2023-10-16 03:03:03 +0200 <geekosaur> > fibs !! 45 -- hm, did I add one too many?
2023-10-16 03:03:03 +0200 <Inst> since I've done dumb crap like that
2023-10-16 03:03:04 +0200 <lambdabot> 1134903170
2023-10-16 03:03:14 +0200 <geekosaur> nope, that's it
2023-10-16 03:03:38 +0200 <geekosaur> and not even with optimization
2023-10-16 03:04:08 +0200 <Inst> no, but jrm's problem is actually interesting
2023-10-16 03:04:13 +0200 <Inst> it's not "this is the wrong fib algorithm"
2023-10-16 03:04:20 +0200 <Inst> it's more "why is this algorithm space leaking?"
2023-10-16 03:04:29 +0200 <monochrom> Decades ago I joked about "one day, the compiler is so smart, if you write bubble sort, the compiler will go 'I see you're sorting' and replace it with an actually good sorting algorithm, now you have trouble showing students empirical proof that bubble sort takes quadratic time".
2023-10-16 03:04:55 +0200 <monochrom> It is "comforting" to know that we are really getting closer to that dystopia.
2023-10-16 03:05:21 +0200 <jumper> Does Haskell have anything similar to "Perldoc" or "Pydoc"?
2023-10-16 03:05:28 +0200 <geekosaur> no, it's just recomputing the same things over and over. this is not a space leak
2023-10-16 03:05:36 +0200eggplantade(~Eggplanta@2600:1700:38c5:d800:9d50:ee50:b066:e718)
2023-10-16 03:05:37 +0200 <geekosaur> show me the space leak if you are so certain it has one
2023-10-16 03:05:44 +0200 <geekosaur> jumper: haddock
2023-10-16 03:05:52 +0200 <jumper> geekosaur, thanks
2023-10-16 03:05:59 +0200brandly(~brandly@c-73-68-15-46.hsd1.ma.comcast.net)
2023-10-16 03:06:23 +0200 <Inst> geekosaur: it's just the numbers that seem weird, naive bad algorithm in C should be only 2-5 times faster than a naive bad algorithm in Haskell
2023-10-16 03:07:05 +0200 <jrm> geekosaur: Wow, your implementation is blazing fast.
2023-10-16 03:07:30 +0200 <Inst> iirc, there are faster implementations, no?
2023-10-16 03:07:33 +0200 <monochrom> You know, I expect the Haskell version to use 4 times as much memory as the C version.
2023-10-16 03:07:50 +0200 <monochrom> 1. C int is half of Haskell Int. 32 bits vs 64 bits
2023-10-16 03:07:52 +0200 <geekosaur> sure, it's memoizing it since it's a top level definition with no parameters
2023-10-16 03:08:03 +0200 <monochrom> 2. Copying GC implies double buffering.
2023-10-16 03:08:18 +0200 <geekosaur> there is --nonmoving-gc
2023-10-16 03:09:21 +0200 <geekosaur> both your C and Haskell implementations repeatedly recalculate values. Haskell will always lose at that kind of brute force approach
2023-10-16 03:10:41 +0200 <geekosaur> the memoizing version computes each one once and remembers it instead of recomputing it, so it uses more space but is very fast
2023-10-16 03:11:36 +0200 <Inst> hmmm, i forget what the ratio is between the Haskell caching version and the C caching version
2023-10-16 03:11:53 +0200 <monochrom> This becomes a problem with benchmarking, especially standardized benchmarking.
2023-10-16 03:12:32 +0200 <monochrom> You probably write a deliberately brute-forcing or at least somewhat-dumb algorithm in hope of benchmarking.
2023-10-16 03:12:55 +0200billchenchina(~billchenc@2a0d:2580:ff0c:1:e3c9:c52b:a429:5bfe) (Remote host closed the connection)
2023-10-16 03:13:19 +0200 <monochrom> But commercial compilers have done "I see that your code is literally SPEC94 so I'm going to go ahead and cheat and just emit a O(1) x=finalAnswer instruction".
2023-10-16 03:14:12 +0200 <Inst> do people actually do this in Haskell?
2023-10-16 03:14:14 +0200 <Inst> https://www.nayuki.io/page/karatsuba-multiplication
2023-10-16 03:14:40 +0200 <jumper> are there Haskell newsgroups one could follow?
2023-10-16 03:15:04 +0200 <monochrom> Newsgroups! comp.lang.haskell exists actually.
2023-10-16 03:15:26 +0200 <monochrom> Hell, was created right at the time people left newsgroups in general haha
2023-10-16 03:15:54 +0200waleee(~waleee@h-176-10-137-138.NA.cust.bahnhof.se) (Ping timeout: 245 seconds)
2023-10-16 03:15:59 +0200 <Inst> Ummm, that's dead :(
2023-10-16 03:16:17 +0200 <Inst> from what I can tell, the most lively Haskell community left is discourse.haskell.org
2023-10-16 03:17:10 +0200 <monochrom> GHC uses GMP. GMP takes a look at the input size and chooses the right algorithm.
2023-10-16 03:17:17 +0200 <monochrom> for multiplication
2023-10-16 03:17:57 +0200 <Inst> wasn't there an attempt to replace gmp by native?
2023-10-16 03:18:06 +0200 <monochrom> On top of that, GHC takes a look at the number size and chooses between staying Int64 or using GMP.
2023-10-16 03:18:20 +0200 <monochrom> "It's telephone games all the way down"
2023-10-16 03:19:44 +0200\salt(~salt@cpe-172-248-205-14.socal.res.rr.com)
2023-10-16 03:19:53 +0200\salt(~salt@cpe-172-248-205-14.socal.res.rr.com) ()
2023-10-16 03:21:19 +0200eggplantade(~Eggplanta@2600:1700:38c5:d800:9d50:ee50:b066:e718) (Remote host closed the connection)
2023-10-16 03:21:30 +0200 <geekosaur> not an attempt, native mode has always existed, it's just slower than GMP. but there are commercial GHC users who won't touch GPL or LGPL, so they use the native backend
2023-10-16 03:21:34 +0200eggplantade(~Eggplanta@2600:1700:38c5:d800:9d50:ee50:b066:e718)
2023-10-16 03:21:49 +0200 <yin> monochrom: js's "fat arrow" lambdas *slightly* differ from anonymous functions of the style "function (x) { ..."
2023-10-16 03:21:57 +0200 <geekosaur> there was a recent rewrite that makes native significantly faster for everything except large multiplications iirc
2023-10-16 03:22:17 +0200 <monochrom> What is the difference?
2023-10-16 03:22:28 +0200 <geekosaur> ditched lists in favor of something sensible
2023-10-16 03:22:49 +0200 <monochrom> Err I mean for yin about JS function syntaxes :)
2023-10-16 03:22:57 +0200 <geekosaur> oh
2023-10-16 03:23:09 +0200 <monochrom> But yeah list is terrible :)
2023-10-16 03:23:27 +0200 <geekosaur> I still want to revive the old attempt at using libtommath (BSD license) as a backend, since it's been a good 15 years and I expect it to have improved
2023-10-16 03:23:54 +0200 <yin> monochrom: lexical scoping
2023-10-16 03:24:49 +0200 <yin> you can't create a closure with fat arrow
2023-10-16 03:25:12 +0200Vajb(~Vajb@207.61.167.122)
2023-10-16 03:25:33 +0200 <yin> i mean, you can
2023-10-16 03:25:39 +0200 <yin> but not in the same way
2023-10-16 03:25:47 +0200 <jumper> what's the >>== operator called?
2023-10-16 03:25:53 +0200 <geekosaur> "bind"
2023-10-16 03:25:54 +0200 <monochrom> bind
2023-10-16 03:25:55 +0200 <yin> "bind"
2023-10-16 03:27:44 +0200 <EvanR> >>=
2023-10-16 03:28:38 +0200 <EvanR> and what is the >> operator called
2023-10-16 03:30:24 +0200 <jackdk> "*>"
2023-10-16 03:30:28 +0200 <monochrom> "then" :)
2023-10-16 03:30:54 +0200 <monochrom> But far fewer people ask for names for >> or *>
2023-10-16 03:30:58 +0200 <EvanR> what about <<
2023-10-16 03:31:16 +0200 <[Leary]> "neht"
2023-10-16 03:31:29 +0200 <monochrom> People who actually don't mind using << have learned to not name operators. :)
2023-10-16 03:31:52 +0200 <Inst> << is also freaky, do you know why?
2023-10-16 03:32:02 +0200 <EvanR> skeptical, but why
2023-10-16 03:32:06 +0200 <monochrom> It is generally just beginners and COBOL people who insist on translating Haskell to English.
2023-10-16 03:32:17 +0200 <monochrom> I guess s/COBOL/COBOL-minded/
2023-10-16 03:32:26 +0200_xor(~xor@72.49.199.93) (Ping timeout: 255 seconds)
2023-10-16 03:32:52 +0200 <monochrom> Most programmers haven't even heard of COBOL, but make no mistake, they just didn't know they would love it.
2023-10-16 03:33:24 +0200 <Inst> first of all, it doesn't actually exist
2023-10-16 03:33:28 +0200 <yin> i wish i had learned lisp before learning haskell
2023-10-16 03:33:35 +0200 <EvanR> << doesn't actually exist?
2023-10-16 03:33:50 +0200 <monochrom> Judging from how the OOP extremists I mentioned would even reject "o2.m2(o1.m1())" and insist to write like "tmp = o1.m1(); o2.m2(tmp)".
2023-10-16 03:33:59 +0200 <Inst> https://hoogle.haskell.org/?hoogle=%3C%3C
2023-10-16 03:34:08 +0200 <geekosaur> there's the old joke that an OO COBOL would have been called ADD 1 TO COBOL GIVING COBOL
2023-10-16 03:34:16 +0200 <monochrom> haha
2023-10-16 03:34:42 +0200 <geekosaur> (which is actually redundant)
2023-10-16 03:34:49 +0200 <Inst> but <* is still freaky
2023-10-16 03:35:07 +0200 <Inst> putStr "Hello" <* putStr " World"
2023-10-16 03:35:32 +0200 <jumper> monochrom, why, I'd rather nest that write repetitive code
2023-10-16 03:35:37 +0200 <jumper> than*
2023-10-16 03:35:44 +0200_xor(~xor@72.49.199.93)
2023-10-16 03:35:52 +0200 <jackdk> Inst: that did exactly what I expected it to do?
2023-10-16 03:35:54 +0200zenstoic(uid461840@id-461840.hampstead.irccloud.com) (Quit: Connection closed for inactivity)
2023-10-16 03:36:00 +0200 <geekosaur> don't confuse results and effects
2023-10-16 03:36:14 +0200 <monochrom> "o2.m2(o1.m1())" looks dangerouly close to FP and/or math.
2023-10-16 03:36:25 +0200 <monochrom> You know that most programmers hate math, right?
2023-10-16 03:36:39 +0200 <jumper> nah
2023-10-16 03:36:41 +0200 <Inst> no, but you'd expect there to be a flip (>>) somewhere, no?
2023-10-16 03:37:16 +0200 <EvanR> I guess by the time =<< was catching on Monad had already been sort of upstaged by Applicative
2023-10-16 03:37:39 +0200 <monochrom> It is the only reason why Haskell beginners ask "how do I get rid of parentheses in f (g (x + 1))"
2023-10-16 03:37:41 +0200 <EvanR> and the AMP update
2023-10-16 03:38:01 +0200 <yin> :t Control.Arrow.<<^
2023-10-16 03:38:02 +0200 <lambdabot> error: parse error on input ‘Control.Arrow.<<^’
2023-10-16 03:38:04 +0200 <geekosaur> there was never really a call for it
2023-10-16 03:38:11 +0200 <yin> :t Control.Arrow.(<<^)
2023-10-16 03:38:12 +0200 <lambdabot> error:
2023-10-16 03:38:12 +0200 <lambdabot> Not in scope: data constructor ‘Control.Arrow’
2023-10-16 03:38:12 +0200 <lambdabot> No module named ‘Control’ is imported.
2023-10-16 03:38:22 +0200 <yin> welp
2023-10-16 03:38:34 +0200 <geekosaur> :t (Control.Arrow.<<^)
2023-10-16 03:38:35 +0200 <lambdabot> Arrow a => a c d -> (b -> c) -> a b d
2023-10-16 03:38:44 +0200 <jumper> how close is Haskell's syntax to pure mathematic syntax? Is APL closer?
2023-10-16 03:38:47 +0200otto_s(~user@p5de2f3ed.dip0.t-ipconnect.de) (Ping timeout: 260 seconds)
2023-10-16 03:39:02 +0200 <yin> APL is nowhere near?
2023-10-16 03:39:16 +0200 <geekosaur> APL is much closer, but different areas of math often have different syntax and APL's staked out matrix math
2023-10-16 03:39:18 +0200 <EvanR> APL and math have in common very dense syntax
2023-10-16 03:39:34 +0200 <EvanR> so maybe the question is about density
2023-10-16 03:39:40 +0200 <yin> what is "pure math syntax"?
2023-10-16 03:39:55 +0200 <monochrom> I am more interested in: Haskell semantics is closer to math semantics.
2023-10-16 03:40:07 +0200 <geekosaur> nonsensical. every area of math has its own syntax
2023-10-16 03:40:16 +0200otto_s(~user@p5de2fd40.dip0.t-ipconnect.de)
2023-10-16 03:40:37 +0200 <EvanR> if you don't have bottom, the semantics IS math
2023-10-16 03:40:56 +0200 <geekosaur> math can describe bottom
2023-10-16 03:40:57 +0200 <EvanR> the denotation of function type are math functions
2023-10-16 03:41:31 +0200 <geekosaur> the forms of math usually used with Haskell can't
2023-10-16 03:42:06 +0200 <geekosaur> I don't recall what you have to do to CT to make Hask (the "category" of Haskell types) meaningful
2023-10-16 03:42:25 +0200 <geekosaur> …in the presence of bottom
2023-10-16 03:43:04 +0200 <yin> can't any code that can produce an AST which can be interpreted considered a type of "math syntax"?
2023-10-16 03:43:11 +0200 <geekosaur> (noting "Fast and Loose Reasoning is Morally Correct")
2023-10-16 03:43:47 +0200 <EvanR> another adjustment to jumper's question is: if the meaning of lambdas-in-lambda-calculus is "functions" what is the domain and range of the functions
2023-10-16 03:44:21 +0200 <geekosaur> nonexistent in the untyped lambda calculus
2023-10-16 03:44:38 +0200 <geekosaur> STLC, now you can discuss them I think
2023-10-16 03:44:44 +0200 <EvanR> untyped can also mean "one master type"
2023-10-16 03:45:01 +0200 <yin> unotyped
2023-10-16 03:45:16 +0200 <monochrom> Yeah I go with "one master type" in the case of untyped lambda calculus.
2023-10-16 03:45:40 +0200 <monochrom> And it doesn't have to mean "the object language has syntax for referring to that master type".
2023-10-16 03:47:35 +0200 <monochrom> The object language doesn't let you talk about domains and codomains. But when you want to know about semantics, i.e., at the meta level, then you need to talk about it
2023-10-16 03:48:26 +0200 <monochrom> It did take almost forever for Dana Scott et. al to prove that the master type actually exists in the math sense!
2023-10-16 03:50:30 +0200talismanick(~user@2601:204:ef80:2980::b23e) (Ping timeout: 272 seconds)
2023-10-16 03:53:05 +0200 <jumper> outside from haskell, are there any communities one could participate in, if one is interested in automata theory, philosophy and literature intermixed with math?
2023-10-16 03:56:12 +0200Inst(~Inst@120.244.192.250) (Ping timeout: 272 seconds)
2023-10-16 04:01:36 +0200 <yin> #math maybe?
2023-10-16 04:04:15 +0200FinnElija(~finn_elij@user/finn-elija/x-0085643) (Killed (NickServ (Forcing logout FinnElija -> finn_elija)))
2023-10-16 04:04:15 +0200finn_elija(~finn_elij@user/finn-elija/x-0085643)
2023-10-16 04:04:15 +0200finn_elijaFinnElija
2023-10-16 04:07:27 +0200Vajb(~Vajb@207.61.167.122) (Ping timeout: 240 seconds)
2023-10-16 04:10:22 +0200hugo(znc@verdigris.lysator.liu.se) (Ping timeout: 255 seconds)
2023-10-16 04:26:44 +0200hugo(znc@verdigris.lysator.liu.se)
2023-10-16 04:29:36 +0200nate2(~nate@c-98-45-169-16.hsd1.ca.comcast.net)
2023-10-16 04:32:55 +0200Square(~Square@user/square) (Remote host closed the connection)
2023-10-16 04:33:19 +0200Lestat9(~Admin1@47.200.90.216)
2023-10-16 04:33:35 +0200 <lisbeths> monochrom: with syntax macros you can extend the grammar syntax or semantics of a language to any possible syntax that you can imagine
2023-10-16 04:34:40 +0200nate2(~nate@c-98-45-169-16.hsd1.ca.comcast.net) (Ping timeout: 255 seconds)
2023-10-16 04:40:02 +0200 <lisbeths> monochrom: typed lambda calculus is more similar to math because it is conistent rather than complete
2023-10-16 04:40:38 +0200 <lisbeths> sets can be implemented in untyped lambda calculus and sets can be implemented in typed lambda calculus
2023-10-16 04:41:36 +0200 <EvanR> Data.Sets?
2023-10-16 04:41:54 +0200 <lisbeths> zermelo frankl sets. any kind of sets
2023-10-16 04:42:09 +0200 <EvanR> how does that work
2023-10-16 04:42:37 +0200 <lisbeths> Anything which is mathematically complete has a subset which is an implementation of sets
2023-10-16 04:43:26 +0200srk(~sorki@user/srk) (Remote host closed the connection)
2023-10-16 04:43:44 +0200srk(~sorki@user/srk)
2023-10-16 04:51:50 +0200Lestat9(~Admin1@47.200.90.216) (Quit: Leaving)
2023-10-16 04:53:25 +0200bilegeek(~bilegeek@2600:1008:b02f:1011:22e7:78e8:8a34:1aa8) (Quit: Leaving)
2023-10-16 04:54:04 +0200jimmy(~jimmy@82.sub-174-215-177.myvzw.com)
2023-10-16 04:57:40 +0200sabino(~sabino@user/sabino) (Quit: Lambda _ -> x)
2023-10-16 04:58:01 +0200td_(~td@i53870930.versanet.de) (Ping timeout: 260 seconds)
2023-10-16 04:59:39 +0200td_(~td@i53870923.versanet.de)
2023-10-16 04:59:51 +0200machinedgod(~machinedg@d198-53-218-113.abhsia.telus.net) (Ping timeout: 260 seconds)
2023-10-16 05:02:32 +0200 <EvanR> so in the early days of trying to found mathematics using lambda calculus, one obvious test drive is to encode sets. It failed, so they just went with sets directly? xD (curry's paradox, or other logical flaw in ULC)
2023-10-16 05:03:11 +0200Square(~Square@user/square)
2023-10-16 05:06:15 +0200cyphase(~cyphase@user/cyphase) (Ping timeout: 240 seconds)
2023-10-16 05:07:21 +0200smalltalkman(uid545680@id-545680.hampstead.irccloud.com)
2023-10-16 05:10:43 +0200aforemny_(~aforemny@i59F516EC.versanet.de)
2023-10-16 05:11:20 +0200aforemny(~aforemny@2001:9e8:6ce4:3000:fb34:5497:c705:b99) (Ping timeout: 255 seconds)
2023-10-16 05:11:24 +0200Allak(~Admin1@47.200.90.216)
2023-10-16 05:12:23 +0200cyphase(~cyphase@user/cyphase)
2023-10-16 05:16:51 +0200img(~img@user/img) (Quit: ZNC 1.8.2 - https://znc.in)
2023-10-16 05:17:21 +0200img(~img@user/img)
2023-10-16 05:18:59 +0200img(~img@user/img) (Client Quit)
2023-10-16 05:19:54 +0200img(~img@user/img)
2023-10-16 05:22:50 +0200ddellacosta(~ddellacos@ool-44c738de.dyn.optonline.net) (Ping timeout: 246 seconds)
2023-10-16 05:23:22 +0200Allak(~Admin1@47.200.90.216) (Remote host closed the connection)
2023-10-16 05:27:55 +0200 <lisbeths> I think the reason why it failed is that it is inconsistent, EvanR
2023-10-16 05:34:17 +0200 <lisbeths> you can use untyped lambda calculus to implement typed lambda calculus
2023-10-16 05:36:42 +0200alphacentauri(alphacenta@gateway/vpn/protonvpn/alphacentauri) (Quit: WeeChat 4.0.5)
2023-10-16 05:44:39 +0200Square(~Square@user/square) (Quit: Leaving)
2023-10-16 05:44:43 +0200pavonia(~user@user/siracusa)
2023-10-16 05:45:59 +0200Square(~Square@user/square)
2023-10-16 05:49:11 +0200jumper(~jumper@mobile-access-2e844c-234.dhcp.inet.fi) (Quit: leaving)
2023-10-16 05:51:16 +0200Unicorn_Princess(~Unicorn_P@user/Unicorn-Princess/x-3540542)
2023-10-16 05:58:46 +0200alphacentauri(alphacenta@gateway/vpn/protonvpn/alphacentauri)
2023-10-16 06:01:50 +0200megaTherion(~therion@unix.io) (Quit: ZNC 1.8.2 - https://znc.in)
2023-10-16 06:02:15 +0200actioninja(~actioninj@user/actioninja)
2023-10-16 06:03:49 +0200megaTherion(~therion@unix.io)
2023-10-16 06:05:06 +0200dcoutts(~duncan@host86-146-194-46.range86-146.btcentralplus.com) (Ping timeout: 260 seconds)
2023-10-16 06:06:01 +0200_ht(~Thunderbi@28-52-174-82.ftth.glasoperator.nl)
2023-10-16 06:11:58 +0200jimmy(~jimmy@82.sub-174-215-177.myvzw.com) (Quit: Quit)
2023-10-16 06:21:07 +0200Square(~Square@user/square) (Remote host closed the connection)
2023-10-16 06:22:05 +0200qhong_(~qhong@rescomp-21-400677.stanford.edu)
2023-10-16 06:24:15 +0200qhong(~qhong@rescomp-21-400677.stanford.edu) (Ping timeout: 240 seconds)
2023-10-16 06:25:04 +0200Square(~Square@user/square)
2023-10-16 06:25:36 +0200megaTherion(~therion@unix.io) (Ping timeout: 260 seconds)
2023-10-16 06:25:53 +0200megaTherion(~therion@unix.io)
2023-10-16 06:26:18 +0200flocks(~flocks@134.122.90.60) (Ping timeout: 272 seconds)
2023-10-16 06:26:40 +0200srk_(~sorki@user/srk)
2023-10-16 06:26:56 +0200srk(~sorki@user/srk) (Ping timeout: 272 seconds)
2023-10-16 06:27:18 +0200orcus-(~orcus@mail.brprice.uk)
2023-10-16 06:27:56 +0200flocks(~flocks@134.122.90.60)
2023-10-16 06:28:12 +0200quintasan(~quassel@quintasan.pl) (Ping timeout: 272 seconds)
2023-10-16 06:28:12 +0200Dykam(Dykam@dykam.nl) (Ping timeout: 272 seconds)
2023-10-16 06:28:12 +0200orcus(~orcus@mail.brprice.uk) (Ping timeout: 272 seconds)
2023-10-16 06:28:13 +0200quintasan_(~quassel@quintasan.pl)
2023-10-16 06:28:23 +0200kantokuen(~kantokuen@user/kantokuen) (Quit: leaving)
2023-10-16 06:28:43 +0200Dykam(Dykam@dykam.nl)
2023-10-16 06:29:26 +0200srk_srk
2023-10-16 06:39:04 +0200michalz(~michalz@185.246.207.222)
2023-10-16 06:43:52 +0200dcoutts(~duncan@185.201.63.254)
2023-10-16 06:46:36 +0200kantokuen(~kantokuen@user/kantokuen)
2023-10-16 06:46:44 +0200brandly(~brandly@c-73-68-15-46.hsd1.ma.comcast.net) (Ping timeout: 255 seconds)
2023-10-16 06:47:48 +0200dcoutts(~duncan@185.201.63.254) (Remote host closed the connection)
2023-10-16 06:48:08 +0200dcoutts(~duncan@185.201.63.254)
2023-10-16 06:51:01 +0200L29Ah(~L29Ah@wikipedia/L29Ah) (Ping timeout: 255 seconds)
2023-10-16 07:09:22 +0200dcoutts(~duncan@185.201.63.254) (Ping timeout: 260 seconds)
2023-10-16 07:17:57 +0200takuan(~takuan@178-116-218-225.access.telenet.be)
2023-10-16 07:25:42 +0200Inst(~Inst@120.244.192.250)
2023-10-16 07:28:34 +0200[itchyjunk](~itchyjunk@user/itchyjunk/x-7353470) (Read error: Connection reset by peer)
2023-10-16 07:28:58 +0200Square3(~Square4@user/square)
2023-10-16 07:31:44 +0200Square(~Square@user/square) (Ping timeout: 255 seconds)
2023-10-16 07:43:57 +0200_ht(~Thunderbi@28-52-174-82.ftth.glasoperator.nl) (Quit: _ht)
2023-10-16 07:44:07 +0200hugo(znc@verdigris.lysator.liu.se) (Ping timeout: 255 seconds)
2023-10-16 07:57:47 +0200hugo(znc@verdigris.lysator.liu.se)
2023-10-16 08:00:32 +0200acidjnk(~acidjnk@p200300d6e7072f57652bd3d039ad030c.dip0.t-ipconnect.de)
2023-10-16 08:01:03 +0200Inst(~Inst@120.244.192.250) (Remote host closed the connection)
2023-10-16 08:01:22 +0200Inst(~Inst@120.244.192.250)
2023-10-16 08:03:32 +0200misterfish(~misterfis@87.215.131.102)
2023-10-16 08:20:39 +0200Inst(~Inst@120.244.192.250) (Ping timeout: 246 seconds)
2023-10-16 08:21:20 +0200misterfish(~misterfis@87.215.131.102) (Ping timeout: 246 seconds)
2023-10-16 08:21:47 +0200harveypwca(~harveypwc@2601:246:c280:6a90:837d:db39:3eea:f7db)
2023-10-16 08:26:22 +0200misterfish(~misterfis@g250100.upc-g.chello.nl)
2023-10-16 08:31:10 +0200nate2(~nate@c-98-45-169-16.hsd1.ca.comcast.net)
2023-10-16 08:36:06 +0200nate2(~nate@c-98-45-169-16.hsd1.ca.comcast.net) (Ping timeout: 258 seconds)
2023-10-16 08:39:22 +0200lortabac(~lortabac@2a01:e0a:541:b8f0:990f:a737:63e:2e4a)
2023-10-16 08:39:23 +0200Inst(~Inst@120.244.192.250)
2023-10-16 08:47:15 +0200paddymahoney(~paddymaho@cpe883d24bcf597-cmbc4dfb741f80.cpe.net.cable.rogers.com) (Remote host closed the connection)
2023-10-16 08:48:10 +0200michalz(~michalz@185.246.207.222) (Ping timeout: 252 seconds)
2023-10-16 08:48:54 +0200idgaen(~idgaen@2a01:e0a:498:fd50:fcc6:bb5d:489a:ce8c)
2023-10-16 08:58:24 +0200michalz(~michalz@185.246.207.197)
2023-10-16 08:59:07 +0200Inst(~Inst@120.244.192.250) (Ping timeout: 264 seconds)
2023-10-16 09:06:24 +0200fendor(~fendor@2a02:8388:1640:be00:aab:1226:f274:5021)
2023-10-16 09:06:47 +0200zaquest(~notzaques@5.130.79.72) (Remote host closed the connection)
2023-10-16 09:16:34 +0200gmg(~user@user/gehmehgeh)
2023-10-16 09:24:14 +0200bitdex(~bitdex@gateway/tor-sasl/bitdex) (Remote host closed the connection)
2023-10-16 09:24:19 +0200FinnElija(~finn_elij@user/finn-elija/x-0085643) (Remote host closed the connection)
2023-10-16 09:24:46 +0200FinnElija(~finn_elij@user/finn-elija/x-0085643)
2023-10-16 09:25:15 +0200bitdex(~bitdex@gateway/tor-sasl/bitdex)
2023-10-16 09:26:33 +0200vglfr(~vglfr@88.155.159.184) (Remote host closed the connection)
2023-10-16 09:27:05 +0200misterfish(~misterfis@g250100.upc-g.chello.nl) (Ping timeout: 258 seconds)
2023-10-16 09:27:19 +0200vglfr(~vglfr@88.155.159.184)
2023-10-16 09:31:21 +0200rgw(~R@2605:a601:a0df:5600:a4a0:a66c:3431:6e78) (Read error: Connection reset by peer)
2023-10-16 09:31:36 +0200vglfr(~vglfr@88.155.159.184) (Remote host closed the connection)
2023-10-16 09:32:16 +0200vglfr(~vglfr@88.155.159.184)
2023-10-16 09:37:31 +0200 <haskellbridge> <t​ewuzij> How does syntax macro looks like?
2023-10-16 09:38:25 +0200 <lisbeths> binary lambda calculus is an example of a language that can be extended to arbitrary syntaxes
2023-10-16 09:41:26 +0200danza(~francesco@151.57.115.67)
2023-10-16 09:42:27 +0200vglfr(~vglfr@88.155.159.184) (Remote host closed the connection)
2023-10-16 09:43:03 +0200vglfr(~vglfr@88.155.159.184)
2023-10-16 09:44:43 +0200hugo(znc@verdigris.lysator.liu.se) (Ping timeout: 255 seconds)
2023-10-16 09:44:50 +0200eggplantade(~Eggplanta@2600:1700:38c5:d800:9d50:ee50:b066:e718) (Remote host closed the connection)
2023-10-16 09:45:29 +0200fweht(uid404746@id-404746.lymington.irccloud.com)
2023-10-16 09:46:44 +0200danza(~francesco@151.57.115.67) (Ping timeout: 255 seconds)
2023-10-16 09:47:53 +0200misterfish(~misterfis@87.215.131.102)
2023-10-16 09:47:55 +0200Pickchea(~private@user/pickchea)
2023-10-16 09:54:18 +0200machinedgod(~machinedg@d198-53-218-113.abhsia.telus.net)
2023-10-16 09:55:13 +0200chele(~chele@user/chele)
2023-10-16 09:58:12 +0200fendor(~fendor@2a02:8388:1640:be00:aab:1226:f274:5021) (Remote host closed the connection)
2023-10-16 09:58:12 +0200fendor(~fendor@2a02:8388:1640:be00:aab:1226:f274:5021)
2023-10-16 09:58:12 +0200CiaoSen(~Jura@2a05:5800:2c0:1c00:664b:f0ff:fe37:9ef)
2023-10-16 09:58:34 +0200vglfr(~vglfr@88.155.159.184) (Ping timeout: 252 seconds)
2023-10-16 09:59:07 +0200azimut(~azimut@gateway/tor-sasl/azimut) (Ping timeout: 252 seconds)
2023-10-16 09:59:51 +0200califax(~califax@user/califx) (Ping timeout: 252 seconds)
2023-10-16 09:59:51 +0200ec(~ec@gateway/tor-sasl/ec) (Ping timeout: 252 seconds)
2023-10-16 09:59:51 +0200stiell_(~stiell@gateway/tor-sasl/stiell) (Ping timeout: 252 seconds)
2023-10-16 10:00:35 +0200FinnElija(~finn_elij@user/finn-elija/x-0085643) (Ping timeout: 252 seconds)
2023-10-16 10:00:35 +0200gmg(~user@user/gehmehgeh) (Ping timeout: 252 seconds)
2023-10-16 10:00:35 +0200chexum(~quassel@gateway/tor-sasl/chexum) (Ping timeout: 252 seconds)
2023-10-16 10:00:35 +0200ChaiTRex(~ChaiTRex@user/chaitrex) (Ping timeout: 252 seconds)
2023-10-16 10:01:03 +0200vglfr(~vglfr@88.155.159.184)
2023-10-16 10:01:29 +0200harveypwca(~harveypwc@2601:246:c280:6a90:837d:db39:3eea:f7db) (Quit: Leaving)
2023-10-16 10:02:42 +0200Sgeo(~Sgeo@user/sgeo) (Read error: Connection reset by peer)
2023-10-16 10:03:35 +0200aforemny_aforemny
2023-10-16 10:03:49 +0200hugo(znc@verdigris.lysator.liu.se)
2023-10-16 10:04:52 +0200paddymahoney(~paddymaho@cpe883d24bcf597-cmbc4dfb741f80.cpe.net.cable.rogers.com)
2023-10-16 10:05:43 +0200Inst(~Inst@120.244.192.250)
2023-10-16 10:06:37 +0200Square2(~Square4@user/square)
2023-10-16 10:08:35 +0200Square3(~Square4@user/square) (Ping timeout: 240 seconds)
2023-10-16 10:08:37 +0200stiell_(~stiell@gateway/tor-sasl/stiell)
2023-10-16 10:08:43 +0200chexum(~quassel@gateway/tor-sasl/chexum)
2023-10-16 10:09:10 +0200califax(~califax@user/califx)
2023-10-16 10:09:11 +0200ec(~ec@gateway/tor-sasl/ec)
2023-10-16 10:09:38 +0200FinnElija(~finn_elij@user/finn-elija/x-0085643)
2023-10-16 10:09:40 +0200azimut(~azimut@gateway/tor-sasl/azimut)
2023-10-16 10:10:42 +0200ChaiTRex(~ChaiTRex@user/chaitrex)
2023-10-16 10:11:06 +0200gehmehgeh(~user@user/gehmehgeh)
2023-10-16 10:12:07 +0200kantokuenkanto
2023-10-16 10:12:23 +0200patrl(~patrl@user/patrl) (Ping timeout: 255 seconds)
2023-10-16 10:12:23 +0200tomsmeding(~tomsmedin@2a01:4f8:c0c:5e5e::2) (Ping timeout: 255 seconds)
2023-10-16 10:12:23 +0200mcfrdy(~mcfrdy@user/mcfrdy) (Ping timeout: 255 seconds)
2023-10-16 10:12:38 +0200hugo(znc@verdigris.lysator.liu.se) (Ping timeout: 246 seconds)
2023-10-16 10:12:43 +0200tomsmeding(~tomsmedin@2a01:4f8:c0c:5e5e::2)
2023-10-16 10:12:43 +0200mcfrdy(~mcfrdy@user/mcfrdy)
2023-10-16 10:13:17 +0200dyniec(~dyniec@mail.dybiec.info) (Ping timeout: 255 seconds)
2023-10-16 10:13:17 +0200V(~v@ircpuzzles/2022/april/winner/V) (Ping timeout: 255 seconds)
2023-10-16 10:13:17 +0200mht-wtf(~mht@2a03:b0c0:3:e0::1e2:c001) (Ping timeout: 255 seconds)
2023-10-16 10:13:17 +0200kawzeg_(kawzeg@2a01:7e01::f03c:92ff:fee2:ec34) (Ping timeout: 255 seconds)
2023-10-16 10:13:44 +0200yahb2(~yahb2@2a01:4f8:c0c:5c7b::2) (Ping timeout: 255 seconds)
2023-10-16 10:13:57 +0200V(~v@ircpuzzles/2022/april/winner/V)
2023-10-16 10:14:21 +0200patrl(~patrl@user/patrl)
2023-10-16 10:14:56 +0200dyniec(~dyniec@mail.dybiec.info)
2023-10-16 10:15:05 +0200kawzeg_(kawzeg@2a01:7e01::f03c:92ff:fee2:ec34)
2023-10-16 10:15:14 +0200yahb2(~yahb2@2a01:4f8:c0c:5c7b::2)
2023-10-16 10:15:14 +0200ChanServ+v yahb2
2023-10-16 10:15:14 +0200hugo(znc@verdigris.lysator.liu.se)
2023-10-16 10:16:25 +0200califax(~califax@user/califx) (Remote host closed the connection)
2023-10-16 10:16:42 +0200califax(~califax@user/califx)
2023-10-16 10:17:04 +0200eggplantade(~Eggplanta@2600:1700:38c5:d800:9d50:ee50:b066:e718)
2023-10-16 10:18:37 +0200mht-wtf(~mht@2a03:b0c0:3:e0::1e2:c001)
2023-10-16 10:19:15 +0200Pickchea(~private@user/pickchea) (Quit: Leaving)
2023-10-16 10:21:32 +0200eggplantade(~Eggplanta@2600:1700:38c5:d800:9d50:ee50:b066:e718) (Ping timeout: 248 seconds)
2023-10-16 10:25:20 +0200danse-nr3(~francesco@151.57.115.67)
2023-10-16 10:30:50 +0200Guest61(~Guest34@194.61.40.138)
2023-10-16 10:32:10 +0200tzh(~tzh@c-71-193-181-0.hsd1.or.comcast.net) (Quit: zzz)
2023-10-16 10:35:23 +0200xdej(~xdej@quatramaran.salle-s.org)
2023-10-16 10:45:17 +0200idgaen(~idgaen@2a01:e0a:498:fd50:fcc6:bb5d:489a:ce8c) (Quit: WeeChat 4.0.5)
2023-10-16 10:49:48 +0200chele(~chele@user/chele) (Ping timeout: 240 seconds)
2023-10-16 10:50:53 +0200kuribas(~user@ip-188-118-57-242.reverse.destiny.be)
2023-10-16 10:56:26 +0200Jackneill(~Jackneill@20014C4E1E021C00C8911A68759FC1A4.dsl.pool.telekom.hu)
2023-10-16 11:02:25 +0200__monty__(~toonn@user/toonn)
2023-10-16 11:02:28 +0200chele(~chele@user/chele)
2023-10-16 11:03:27 +0200cpressey(~cpressey@host-92-21-195-194.as13285.net)
2023-10-16 11:04:13 +0200Sanguine_(~Sanguine@176.254.244.83)
2023-10-16 11:06:56 +0200Sanguine(~Sanguine@176.254.244.83) (Ping timeout: 255 seconds)
2023-10-16 11:10:32 +0200chele_(~chele@user/chele)
2023-10-16 11:11:53 +0200chele(~chele@user/chele) (Ping timeout: 255 seconds)
2023-10-16 11:18:19 +0200azimut(~azimut@gateway/tor-sasl/azimut) (Ping timeout: 252 seconds)
2023-10-16 11:20:02 +0200gehmehgeh(~user@user/gehmehgeh) (Quit: Leaving)
2023-10-16 11:20:40 +0200rawles(~rawles@user/rawles)
2023-10-16 11:22:44 +0200wootehfoot(~wootehfoo@user/wootehfoot)
2023-10-16 11:24:14 +0200Guest61(~Guest34@194.61.40.138) (Quit: Client closed)
2023-10-16 11:26:29 +0200eggplantade(~Eggplanta@2600:1700:38c5:d800:9d50:ee50:b066:e718)
2023-10-16 11:28:53 +0200ft(~ft@p3e9bc680.dip0.t-ipconnect.de) (Quit: leaving)
2023-10-16 11:34:34 +0200shapr(~user@2600:1700:c640:3100:bfe1:f742:1b66:58fa) (Remote host closed the connection)
2023-10-16 11:34:47 +0200shapr(~user@2600:1700:c640:3100:e051:bcd9:9086:b34f)
2023-10-16 11:51:41 +0200Inst(~Inst@120.244.192.250) (Ping timeout: 246 seconds)
2023-10-16 11:59:52 +0200Inst(~Inst@120.244.192.250)
2023-10-16 12:13:07 +0200econo_(uid147250@id-147250.tinside.irccloud.com) (Quit: Connection closed for inactivity)
2023-10-16 12:15:29 +0200CiaoSen(~Jura@2a05:5800:2c0:1c00:664b:f0ff:fe37:9ef) (Ping timeout: 246 seconds)
2023-10-16 12:15:33 +0200fendor(~fendor@2a02:8388:1640:be00:aab:1226:f274:5021) (Remote host closed the connection)
2023-10-16 12:19:54 +0200finn_elija(~finn_elij@user/finn-elija/x-0085643)
2023-10-16 12:19:54 +0200FinnElija(~finn_elij@user/finn-elija/x-0085643) (Killed (NickServ (Forcing logout FinnElija -> finn_elija)))
2023-10-16 12:19:54 +0200finn_elijaFinnElija
2023-10-16 12:21:26 +0200lisbeths(uid135845@id-135845.lymington.irccloud.com) (Quit: Connection closed for inactivity)
2023-10-16 12:26:58 +0200Nixkernal_(~Nixkernal@115.16.194.178.dynamic.wline.res.cust.swisscom.ch)
2023-10-16 12:27:52 +0200Nixkernal(~Nixkernal@115.16.194.178.dynamic.wline.res.cust.swisscom.ch) (Ping timeout: 260 seconds)
2023-10-16 12:30:05 +0200misterfish(~misterfis@87.215.131.102) (Ping timeout: 255 seconds)
2023-10-16 12:31:55 +0200misterfish(~misterfis@178.228.26.213)
2023-10-16 12:32:42 +0200nate2(~nate@c-98-45-169-16.hsd1.ca.comcast.net)
2023-10-16 12:36:58 +0200alphacentauri(alphacenta@gateway/vpn/protonvpn/alphacentauri) (Quit: WeeChat 4.0.5)
2023-10-16 12:38:04 +0200nate2(~nate@c-98-45-169-16.hsd1.ca.comcast.net) (Ping timeout: 272 seconds)
2023-10-16 13:02:21 +0200moni_(~moni@cpe-174-106-185-141.ec.res.rr.com)
2023-10-16 13:05:16 +0200mikoto-chan(~mikoto-ch@ip-212-239-236-59.dsl.scarlet.be)
2023-10-16 13:16:13 +0200Inst(~Inst@120.244.192.250) (Quit: Leaving)
2023-10-16 13:16:35 +0200moni_(~moni@cpe-174-106-185-141.ec.res.rr.com) (Ping timeout: 240 seconds)
2023-10-16 13:20:10 +0200vglfr(~vglfr@88.155.159.184) (Remote host closed the connection)
2023-10-16 13:21:07 +0200vglfr(~vglfr@88.155.159.184)
2023-10-16 13:21:36 +0200cfricke(~cfricke@user/cfricke)
2023-10-16 13:24:15 +0200moni_(~moni@cpe-174-106-185-141.ec.res.rr.com)
2023-10-16 13:24:31 +0200vglfr(~vglfr@88.155.159.184) (Remote host closed the connection)
2023-10-16 13:25:22 +0200vglfr(~vglfr@88.155.159.184)
2023-10-16 13:25:59 +0200danse-nr3(~francesco@151.57.115.67) (Ping timeout: 255 seconds)
2023-10-16 13:26:35 +0200mikoto-chan(~mikoto-ch@ip-212-239-236-59.dsl.scarlet.be) (Ping timeout: 240 seconds)
2023-10-16 13:28:33 +0200vglfr(~vglfr@88.155.159.184) (Remote host closed the connection)
2023-10-16 13:29:43 +0200vglfr(~vglfr@88.155.159.184)
2023-10-16 13:30:45 +0200chele_chele
2023-10-16 13:40:43 +0200ec(~ec@gateway/tor-sasl/ec) (Read error: Connection reset by peer)
2023-10-16 13:40:43 +0200bitdex(~bitdex@gateway/tor-sasl/bitdex) (Read error: Connection reset by peer)
2023-10-16 13:40:43 +0200ChaiTRex(~ChaiTRex@user/chaitrex) (Read error: Connection reset by peer)
2023-10-16 13:41:07 +0200ec(~ec@gateway/tor-sasl/ec)
2023-10-16 13:41:11 +0200ChaiTRex(~ChaiTRex@user/chaitrex)
2023-10-16 13:41:39 +0200bitdex(~bitdex@gateway/tor-sasl/bitdex)
2023-10-16 13:42:28 +0200pandeyan(~pandeyan@135-180-55-136.fiber.dynamic.sonic.net) (Quit: ZNC 1.8.2 - https://znc.in)
2023-10-16 13:44:27 +0200anpad(~pandeyan@user/anpad)
2023-10-16 13:44:43 +0200[itchyjunk](~itchyjunk@user/itchyjunk/x-7353470)
2023-10-16 13:47:56 +0200hugo(znc@verdigris.lysator.liu.se) (Ping timeout: 248 seconds)
2023-10-16 13:50:01 +0200misterfish(~misterfis@178.228.26.213) (Ping timeout: 260 seconds)
2023-10-16 13:54:42 +0200bitdex(~bitdex@gateway/tor-sasl/bitdex) (Quit: = "")
2023-10-16 13:57:24 +0200hiyori(~hiyori@user/hiyori) (Quit: Client closed)
2023-10-16 14:02:46 +0200hugo(znc@verdigris.lysator.liu.se)
2023-10-16 14:04:29 +0200vglfr(~vglfr@88.155.159.184) (Remote host closed the connection)
2023-10-16 14:05:10 +0200vglfr(~vglfr@88.155.159.184)
2023-10-16 14:09:00 +0200vglfr(~vglfr@88.155.159.184) (Remote host closed the connection)
2023-10-16 14:09:46 +0200vglfr(~vglfr@88.155.159.184)
2023-10-16 14:15:21 +0200misterfish(~misterfis@87.215.131.102)
2023-10-16 14:26:50 +0200danse-nr3(~francesco@151.47.97.45)
2023-10-16 14:52:13 +0200alphacentauri(alphacenta@gateway/vpn/protonvpn/alphacentauri)
2023-10-16 14:56:46 +0200misterfish(~misterfis@87.215.131.102) (Ping timeout: 272 seconds)
2023-10-16 15:00:58 +0200cfricke(~cfricke@user/cfricke) (Quit: WeeChat 4.0.4)
2023-10-16 15:01:03 +0200mikoto-chan(~mikoto-ch@ip-212-239-236-59.dsl.scarlet.be)
2023-10-16 15:02:12 +0200mikoto-chan(~mikoto-ch@ip-212-239-236-59.dsl.scarlet.be) (Client Quit)
2023-10-16 15:05:13 +0200vglfr(~vglfr@88.155.159.184) (Read error: Connection reset by peer)
2023-10-16 15:05:34 +0200vglfr(~vglfr@149.102.244.98)
2023-10-16 15:12:51 +0200wootehfoot(~wootehfoo@user/wootehfoot) (Ping timeout: 258 seconds)
2023-10-16 15:22:37 +0200ddellacosta(~ddellacos@ool-44c738de.dyn.optonline.net)
2023-10-16 15:25:16 +0200lisbeths(uid135845@id-135845.lymington.irccloud.com)
2023-10-16 15:30:21 +0200sabino(~sabino@user/sabino)
2023-10-16 15:39:40 +0200Simikando(~Simikando@adsl-dyn158.91-127-59.t-com.sk)
2023-10-16 15:40:11 +0200fendor(~fendor@2a02:8388:1640:be00:aab:1226:f274:5021)
2023-10-16 15:42:29 +0200cpressey(~cpressey@host-92-21-195-194.as13285.net) (Quit: Client closed)
2023-10-16 15:47:45 +0200shapr(~user@2600:1700:c640:3100:e051:bcd9:9086:b34f) (Remote host closed the connection)
2023-10-16 15:47:58 +0200shapr(~user@2600:1700:c640:3100:fc20:3b33:1ae3:ac4d)
2023-10-16 15:52:17 +0200fendor(~fendor@2a02:8388:1640:be00:aab:1226:f274:5021) (Remote host closed the connection)
2023-10-16 15:59:19 +0200notzmv(~zmv@user/notzmv)
2023-10-16 16:01:02 +0200L29Ah(~L29Ah@wikipedia/L29Ah)
2023-10-16 16:06:08 +0200Simikando(~Simikando@adsl-dyn158.91-127-59.t-com.sk) (Ping timeout: 246 seconds)
2023-10-16 16:12:46 +0200vglfr(~vglfr@149.102.244.98) (Ping timeout: 272 seconds)
2023-10-16 16:14:25 +0200vglfr(~vglfr@149.102.244.98)
2023-10-16 16:15:24 +0200Square2(~Square4@user/square) (Ping timeout: 240 seconds)
2023-10-16 16:15:26 +0200waleee(~waleee@2001:9b0:21c:e600:f2f3:f744:435d:137c)
2023-10-16 16:18:21 +0200swistak(~swistak@185.21.216.141) (Quit: bye bye)
2023-10-16 16:18:48 +0200swistak(~swistak@185.21.216.141)
2023-10-16 16:19:45 +0200Square2(~Square4@user/square)
2023-10-16 16:21:48 +0200infinity0(~infinity0@pwned.gg) (Remote host closed the connection)
2023-10-16 16:23:39 +0200Square(~Square@user/square)
2023-10-16 16:23:55 +0200infinity0(~infinity0@pwned.gg)
2023-10-16 16:26:27 +0200Simikando(~Simikando@adsl-dyn158.91-127-59.t-com.sk)
2023-10-16 16:33:02 +0200Square2(~Square4@user/square) (Ping timeout: 272 seconds)
2023-10-16 16:33:17 +0200gehmehgeh(~user@user/gehmehgeh)
2023-10-16 16:34:14 +0200nate2(~nate@c-98-45-169-16.hsd1.ca.comcast.net)
2023-10-16 16:37:07 +0200thegeekinside(~thegeekin@189.180.124.118)
2023-10-16 16:39:10 +0200nate2(~nate@c-98-45-169-16.hsd1.ca.comcast.net) (Ping timeout: 255 seconds)
2023-10-16 16:42:01 +0200todi(~todi@p4fd1a3e6.dip0.t-ipconnect.de) (Ping timeout: 255 seconds)
2023-10-16 16:46:20 +0200cpressey(~cpressey@host-92-21-195-194.as13285.net)
2023-10-16 16:47:48 +0200Simikando(~Simikando@adsl-dyn158.91-127-59.t-com.sk) (Ping timeout: 240 seconds)
2023-10-16 16:48:16 +0200sm(~sm@plaintextaccounting/sm)
2023-10-16 17:00:16 +0200hugo(znc@verdigris.lysator.liu.se) (Ping timeout: 260 seconds)
2023-10-16 17:01:56 +0200danse-nr3(~francesco@151.47.97.45) (Remote host closed the connection)
2023-10-16 17:02:16 +0200danse-nr3(~francesco@151.47.97.45)
2023-10-16 17:03:20 +0200vglfr(~vglfr@149.102.244.98) (Ping timeout: 255 seconds)
2023-10-16 17:03:59 +0200[_](~itchyjunk@user/itchyjunk/x-7353470)
2023-10-16 17:04:11 +0200vglfr(~vglfr@88.155.159.184)
2023-10-16 17:04:35 +0200[itchyjunk](~itchyjunk@user/itchyjunk/x-7353470) (Read error: Connection reset by peer)
2023-10-16 17:11:44 +0200ystael(~ystael@user/ystael)
2023-10-16 17:16:24 +0200chexum(~quassel@gateway/tor-sasl/chexum) (Remote host closed the connection)
2023-10-16 17:16:39 +0200chexum(~quassel@gateway/tor-sasl/chexum)
2023-10-16 17:17:22 +0200waleee(~waleee@2001:9b0:21c:e600:f2f3:f744:435d:137c) (Ping timeout: 272 seconds)
2023-10-16 17:18:06 +0200alphacentauri(alphacenta@gateway/vpn/protonvpn/alphacentauri) (Quit: WeeChat 4.0.5)
2023-10-16 17:20:53 +0200alphacentauri(alphacenta@gateway/vpn/protonvpn/alphacentauri)
2023-10-16 17:23:50 +0200fendor(~fendor@2a02:8388:1640:be00:aab:1226:f274:5021)
2023-10-16 17:24:08 +0200hugo(znc@verdigris.lysator.liu.se)
2023-10-16 17:25:29 +0200 <EvanR> monochrom, OO extremists insisting on tmp = o1.m1(); o2.m2(tmp); is new to me, but it's funny that is how we have to do stuff in haskell do notation. (idris has syntax which lets you nest them, result <- o2m2 !o1m1; ...
2023-10-16 17:27:01 +0200Inst(~Inst@120.244.192.250)
2023-10-16 17:28:31 +0200 <Inst> EvanR: why is hybridizing do notation and direct monadic bind considered smelly?
2023-10-16 17:28:39 +0200 <dolio> It isn't.
2023-10-16 17:29:00 +0200eggplantade(~Eggplanta@2600:1700:38c5:d800:9d50:ee50:b066:e718) (Remote host closed the connection)
2023-10-16 17:29:02 +0200 <Inst> Because you don't have to do it that way, you can still use function composition in Haskell to achieve the same result as in Idris
2023-10-16 17:29:07 +0200 <Inst> monadic chains, etc
2023-10-16 17:29:18 +0200eggplantade(~Eggplanta@2600:1700:38c5:d800:9d50:ee50:b066:e718)
2023-10-16 17:29:39 +0200todi(~todi@p4fd1a3e6.dip0.t-ipconnect.de)
2023-10-16 17:29:53 +0200 <EvanR> in the above case o1m1 isn't a function (unless you're talking about function monad)
2023-10-16 17:30:09 +0200 <c_wraith> EvanR: well... a = o1.m1(); b = o2.m2(); o3.m3(a, b); Because of side effects, you need to explicitly order them in general. (some languages provide more guarantees than C, but why take chances?)
2023-10-16 17:30:46 +0200phma(~phma@host-67-44-208-195.hnremote.net) (Read error: Connection reset by peer)
2023-10-16 17:30:49 +0200 <EvanR> yeah I'm down with that style
2023-10-16 17:30:55 +0200Square(~Square@user/square) (Ping timeout: 255 seconds)
2023-10-16 17:30:58 +0200 <EvanR> but don't blame it on OOP xD
2023-10-16 17:31:06 +0200 <c_wraith> I blamed it on side effects!
2023-10-16 17:31:33 +0200Inst(~Inst@120.244.192.250) (Client Quit)
2023-10-16 17:31:58 +0200phma(~phma@host-67-44-208-16.hnremote.net)
2023-10-16 17:32:26 +0200 <haskellbridge> <I​nst> yeah, but the order of effects is made explicit by >>=, no?
2023-10-16 17:32:37 +0200 <haskellbridge> <I​nst> the only problem in Haskell is that applicatives don't guarantee an order of effect
2023-10-16 17:32:41 +0200 <haskellbridge> <I​nst> which makes them potentially smelly
2023-10-16 17:32:53 +0200 <c_wraith> That's actually the whole point of Applicative.
2023-10-16 17:33:11 +0200 <c_wraith> The interface doesn't require ordering.
2023-10-16 17:33:37 +0200 <haskellbridge> <I​nst> I was just hoping you could do `liftA2 o3.m3 o1.m1 o2.m2`
2023-10-16 17:34:03 +0200 <haskellbridge> <I​nst> well, nope, fff, o3.m3(a,b) implies generated effects
2023-10-16 17:34:19 +0200econo_(uid147250@id-147250.tinside.irccloud.com)
2023-10-16 17:34:38 +0200 <haskellbridge> <I​nst> you could liftA2 (,) o1.m1 o2.m2 >>= o3.m3, which makes the effect sequence explicit, but w/e, sorry for getting involved
2023-10-16 17:37:49 +0200lortabac(~lortabac@2a01:e0a:541:b8f0:990f:a737:63e:2e4a) (Ping timeout: 252 seconds)
2023-10-16 17:38:52 +0200cpressey(~cpressey@host-92-21-195-194.as13285.net) (Quit: Client closed)
2023-10-16 17:43:39 +0200Inst(~Inst@120.244.192.250)
2023-10-16 17:45:48 +0200notzmv(~zmv@user/notzmv) (Ping timeout: 240 seconds)
2023-10-16 17:46:58 +0200 <probie> I'm not the biggest fan of `foo !bar !baz`, because it has different semantics to `let foo' = flip foo in foo' !baz !bar`
2023-10-16 17:50:29 +0200 <haskellbridge> <m​auke> That looks like a syntax error
2023-10-16 17:50:50 +0200 <probie> That's back in the context of "idris has syntax which lets you nest them"
2023-10-16 17:51:36 +0200 <probie> `foo !bar !baz` being `bar >>= \x -> baz >>= y -> foo x y`
2023-10-16 17:52:32 +0200 <probie> I'm just half an hour late to the discussion
2023-10-16 17:52:42 +0200 <haskellbridge> <m​auke> Ah, thanks
2023-10-16 17:53:45 +0200 <haskellbridge> <m​auke> Idiom bangs?
2023-10-16 17:54:10 +0200_ht(~Thunderbi@28-52-174-82.ftth.glasoperator.nl)
2023-10-16 17:54:42 +0200 <probie> http://docs.idris-lang.org/en/latest/tutorial/interfaces.html#notation
2023-10-16 17:58:22 +0200Simikando(~Simikando@adsl-dyn158.91-127-59.t-com.sk)
2023-10-16 18:01:23 +0200sabino1(~sabino@user/sabino)
2023-10-16 18:02:23 +0200danse-nr3_(~francesco@151.43.103.136)
2023-10-16 18:02:25 +0200sabino(~sabino@user/sabino) (Ping timeout: 255 seconds)
2023-10-16 18:04:34 +0200Simikando(~Simikando@adsl-dyn158.91-127-59.t-com.sk) (Remote host closed the connection)
2023-10-16 18:04:39 +0200danse-nr3(~francesco@151.47.97.45) (Ping timeout: 245 seconds)
2023-10-16 18:04:57 +0200Simikando(~Simikando@adsl-dyn158.91-127-59.t-com.sk)
2023-10-16 18:06:32 +0200sabino1sabino
2023-10-16 18:12:24 +0200cpressey(~cpressey@host-92-10-148-105.as13285.net)
2023-10-16 18:15:08 +0200notzmv(~zmv@user/notzmv)
2023-10-16 18:15:31 +0200machinedgod(~machinedg@d198-53-218-113.abhsia.telus.net) (Ping timeout: 260 seconds)
2023-10-16 18:17:12 +0200alphacentauri(alphacenta@gateway/vpn/protonvpn/alphacentauri) (Quit: WeeChat 4.0.5)
2023-10-16 18:17:23 +0200kuribas(~user@ip-188-118-57-242.reverse.destiny.be) (Quit: ERC (IRC client for Emacs 27.1))
2023-10-16 18:20:33 +0200azimut(~azimut@gateway/tor-sasl/azimut)
2023-10-16 18:20:38 +0200tzh(~tzh@c-71-193-181-0.hsd1.or.comcast.net)
2023-10-16 18:20:55 +0200alphacentauri(alphacenta@gateway/vpn/protonvpn/alphacentauri)
2023-10-16 18:23:53 +0200rgw(~R@2605:a601:a0df:5600:e1fd:3d46:eec0:9d00)
2023-10-16 18:27:00 +0200Simikando(~Simikando@adsl-dyn158.91-127-59.t-com.sk) (Quit: Leaving)
2023-10-16 18:37:29 +0200stackdroid18(14094@de1.hashbang.sh)
2023-10-16 18:40:33 +0200danse-nr3_(~francesco@151.43.103.136) (Remote host closed the connection)
2023-10-16 18:44:41 +0200glguy(g@libera/staff/glguy)
2023-10-16 18:44:59 +0200g(g@libera/staff/glguy) (Read error: Connection reset by peer)
2023-10-16 18:45:26 +0200ghoulguy(g@libera/staff/glguy) (Read error: Connection reset by peer)
2023-10-16 18:47:09 +0200rncwnd(~quassel@2a01:4f8:221:27c6::1)
2023-10-16 18:47:13 +0200glguyghoulguy
2023-10-16 18:47:52 +0200g(g@libera/staff/glguy)
2023-10-16 18:49:12 +0200dsrt^(~cd@76.145.193.217) (Ping timeout: 272 seconds)
2023-10-16 18:49:33 +0200cuiltb^(~cd@76.145.193.217) (Remote host closed the connection)
2023-10-16 18:49:40 +0200 <monochrom> I carefully chose my example! Of course f(m1a(), m1b()) would be ambiguos. But f(m1a()) isn't.
2023-10-16 18:49:51 +0200cuiltb^(~cd@76.145.193.217)
2023-10-16 18:50:03 +0200 <monochrom> Nor is f(g(h())).
2023-10-16 18:50:36 +0200 <c_wraith> my point was merely that style guides come from paranoia. Can it mess up in case A? then mandate it for case B, too
2023-10-16 18:50:52 +0200 <monochrom> Ah OK I agree. :)
2023-10-16 18:51:12 +0200 <monochrom> Extremism comes from paranoia too >:)
2023-10-16 18:51:38 +0200dsrt^(~cd@76.145.193.217)
2023-10-16 18:55:11 +0200eggplantade(~Eggplanta@2600:1700:38c5:d800:9d50:ee50:b066:e718) (Remote host closed the connection)
2023-10-16 18:58:06 +0200eggplantade(~Eggplanta@2600:1700:38c5:d800:8de0:2b83:d0e7:f73b)
2023-10-16 18:59:55 +0200 <haskellbridge> <I​nst> what do you mean by the point of applicative is that there's no specified order of effects?
2023-10-16 19:00:03 +0200 <haskellbridge> <I​nst> for instance, in monochrom's examples
2023-10-16 19:00:03 +0200stackdroid18(14094@de1.hashbang.sh) (Quit: hasta la vista... tchau!)
2023-10-16 19:00:15 +0200zenstoic(uid461840@id-461840.hampstead.irccloud.com)
2023-10-16 19:00:40 +0200 <haskellbridge> <I​nst> that might be manual bind onto liftA2
2023-10-16 19:02:26 +0200 <haskellbridge> <I​nst> for instance, i know how with the async applicative, the concurrency comes from not having to specify an order of effects
2023-10-16 19:05:49 +0200 <probie> Applicative consists of `pure` and `<*>`
2023-10-16 19:05:54 +0200 <probie> :t (<*>)
2023-10-16 19:05:55 +0200 <lambdabot> Applicative f => f (a -> b) -> f a -> f b
2023-10-16 19:06:11 +0200 <probie> :t (>>=)
2023-10-16 19:06:11 +0200 <lambdabot> Monad m => m a -> (a -> m b) -> m b
2023-10-16 19:06:21 +0200 <dolio> There is a specified order, though.
2023-10-16 19:06:39 +0200 <haskellbridge> <I​nst> i mean i know bind is a monad method
2023-10-16 19:08:17 +0200stefan-_(~cri@42dots.de) (Quit: ZNC 1.8.2+deb2build5 - https://znc.in)
2023-10-16 19:08:18 +0200stefan-__(~m-ohzqow@42dots.de) (Read error: Connection reset by peer)
2023-10-16 19:08:58 +0200stefan-_(~cri@42dots.de)
2023-10-16 19:09:21 +0200John_Ivan__(~John_Ivan@user/john-ivan/x-1515935) (Quit: Disrupting the dragon's slumber one time too often shall eventually bestow upon all an empirical and indiscriminate conflagration that will last for all goddamn eternity.)
2023-10-16 19:11:27 +0200 <haskellbridge> <I​nst> whoops, not async, i mean Concurrently
2023-10-16 19:16:16 +0200 <probie> It's 4am my time, so my brain has not yet turned on. But perhaps it might be useful to write a `Functor` and `Applicative` instance for `newtype Errors err a = Errors (Either (NonEmpty err) a)` with the expected semantics `Errors (Left e1) <*> Errors (Left e2) = Errors (Left (e1 <> e2))` and why you can't write a `Monad` instance for it
2023-10-16 19:16:43 +0200 <probie> It's not really "no specified order of effects" as much as "no dependency"
2023-10-16 19:18:40 +0200 <tomsmeding> you can write a Monad instance for it, it will just not give errors for the continuation of a bind if its left-hand side errored :p
2023-10-16 19:19:19 +0200 <haskellbridge> <I​nst> iirc, i noted that you can get a monad instance for Concurrently
2023-10-16 19:19:30 +0200chele(~chele@user/chele) (Remote host closed the connection)
2023-10-16 19:19:47 +0200 <probie> tomsmeding: Hence the "with the expected semantics..." constraint
2023-10-16 19:20:05 +0200 <tomsmeding> right
2023-10-16 19:20:08 +0200 <haskellbridge> <I​nst> since it's just a newtype around IO
2023-10-16 19:20:12 +0200 <haskellbridge> <I​nst> and it'd be lawful too
2023-10-16 19:21:03 +0200 <tomsmeding> you'd have to be careful to write things that you'd like to be concurrent using the applicative combinators, though
2023-10-16 19:22:03 +0200 <haskellbridge> <I​nst> i'm just wondering for what principle the monad instance is avoided, though
2023-10-16 19:22:24 +0200 <haskellbridge> <I​nst> in a mathematical sense, is Concurrently a Monad?
2023-10-16 19:22:31 +0200 <probie> I don't think it'd be lawful, since you probably wouldn't be able to satisfy `m1 <*> m2 = m1 >>= (\x1 -> m2 >>= (\x2 -> return (x1 x2)))`
2023-10-16 19:23:01 +0200 <haskellbridge> <I​nst> monad laws i'm not familiar with? !!
2023-10-16 19:23:21 +0200 <tomsmeding> I don't know anything about this particular functor we're talking about, but is the point just that independent effects are evaluated in parallel?
2023-10-16 19:23:23 +0200 <haskellbridge> <I​nst> i guess it'd break ap, but i'm not familiar with laws associated with that
2023-10-16 19:23:48 +0200 <tomsmeding> oh right, the effects would not be evaluated in the same order
2023-10-16 19:23:50 +0200 <haskellbridge> <I​nst> https://hackage.haskell.org/package/async-2.2.4/docs/Control-Concurrent-Async.html#t:Concurrently
2023-10-16 19:24:24 +0200 <tomsmeding> yeah a <*> b and (liftM2 ($) a b) would have the same _value_ result, but might execute effects in a different order
2023-10-16 19:24:30 +0200 <tomsmeding> after all, that's the whole point of Concurrently!
2023-10-16 19:24:45 +0200 <tomsmeding> so it's not _quite_ a lawful Monad
2023-10-16 19:24:51 +0200 <dolio> Sure it is.
2023-10-16 19:25:27 +0200 <tomsmeding> dolio: that equality in the law seems pretty strong
2023-10-16 19:25:47 +0200 <haskellbridge> <I​nst> it's an interesting edge case imo, i.e, you can have a lawful monad implementation, but the point is that the applicative implementation is both lawful and different. and the library authors elected to omit the monad implementation, probably for obvious reasons
2023-10-16 19:26:03 +0200 <haskellbridge> <I​nst> `m1 <*> m2 = m1 >>= (\x1 -> m2 >>= (\x2 -> return (x1 x2)))`
2023-10-16 19:26:10 +0200 <haskellbridge> <I​nst> which law is this?
2023-10-16 19:26:12 +0200 <dolio> You just define equality so that different concurrent executions resulting in the same value are considered equal.
2023-10-16 19:26:23 +0200 <dolio> Since that's the whole point of the thing.
2023-10-16 19:26:26 +0200stefan-_(~cri@42dots.de) (Quit: ZNC 1.8.2+deb2build5 - https://znc.in)
2023-10-16 19:26:38 +0200 <tomsmeding> Inst: see the "Furthermore, ..." in the haddocks for Monad
2023-10-16 19:27:00 +0200stefan-_(~cri@42dots.de)
2023-10-16 19:27:08 +0200 <tomsmeding> dolio: does the implementer of an _instance_ of Monad get to decide what the symbols in the laws of Monad mean?
2023-10-16 19:27:15 +0200 <tomsmeding> I'm not sure that's what the point of laws is :D
2023-10-16 19:27:16 +0200 <dolio> Yes, of course.
2023-10-16 19:28:15 +0200wootehfoot(~wootehfoo@user/wootehfoot)
2023-10-16 19:28:29 +0200 <tomsmeding> so I can write a Monad instance for my favourite data type, have it flaunt all reason, and declare it lawful because it satisfies the laws if you interpret equality as "tomsmeding thinks they look similar"?
2023-10-16 19:28:37 +0200 <tomsmeding> surely that's not what "lawful" means
2023-10-16 19:29:17 +0200 <dolio> You can do that if you want. No one will use it, because your criterion for equality is not useful.
2023-10-16 19:29:23 +0200 <tomsmeding> I mean, I agree that this discrepancy is the entire point of Concurrently, and I would not be against a Monad instance there
2023-10-16 19:29:44 +0200 <tomsmeding> dolio: do you also consider Validation to be a lawful Monad?
2023-10-16 19:29:59 +0200 <tomsmeding> (where (<*>) preserves more errors than `ap`)
2023-10-16 19:30:16 +0200 <Inst> that's an interesting limitation, never thought of that before
2023-10-16 19:30:45 +0200eggplantade(~Eggplanta@2600:1700:38c5:d800:8de0:2b83:d0e7:f73b) (Remote host closed the connection)
2023-10-16 19:31:01 +0200 <tomsmeding> also with this reasoning, classical ListT, which is considered "only a monad when wrapping a commutative monad", is actually always a monad if you consider equality modulo reordering of effects
2023-10-16 19:31:06 +0200 <dolio> It depends on the context. If getting all the errors matter, then no. If just getting some collection of errors is all that matters, then it's fine.
2023-10-16 19:31:35 +0200 <Inst> wait, so if you're working with values of type concurrently, can you place it into do notation?
2023-10-16 19:31:39 +0200 <tomsmeding> hm, I can live with context-dependent equality and hence context-dependent lawfulness
2023-10-16 19:31:44 +0200 <Inst> how about with -XApplicativeDo?
2023-10-16 19:31:52 +0200 <tomsmeding> Inst: with ApplicativeDo, yes
2023-10-16 19:31:59 +0200 <tomsmeding> as long as you don't introduce a data dependency
2023-10-16 19:32:07 +0200 <Inst> i mean, not for binding, but just for stringing...
2023-10-16 19:32:09 +0200 <tomsmeding> (which would require (>>=))
2023-10-16 19:32:13 +0200 <Inst> and iirc, isn't applicativeDo a misfeature?
2023-10-16 19:32:17 +0200 <tomsmeding> :t do 42
2023-10-16 19:32:18 +0200 <lambdabot> Num p => p
2023-10-16 19:32:25 +0200 <tomsmeding> what is a "misfeature"
2023-10-16 19:32:45 +0200 <Inst> i've heard it criticized for having a terrible desugaring algorithm that can result in very long compile times
2023-10-16 19:32:51 +0200 <tomsmeding> sure
2023-10-16 19:32:52 +0200 <dolio> All monads are not lawful if you look hard enough for reasons to disqualify them. You have to actually think about what matters.
2023-10-16 19:32:56 +0200 <tomsmeding> does that mean it's a "misfeature"?
2023-10-16 19:33:30 +0200 <tomsmeding> dolio: thanks, I hadn't considered this perspective on typeclass laws before
2023-10-16 19:33:34 +0200idgaen(~idgaen@2a01:e0a:498:fd50:fcc6:bb5d:489a:ce8c)
2023-10-16 19:33:41 +0200 <Inst> hmmm
2023-10-16 19:33:49 +0200 <tomsmeding> it does make communication harder, because people typically do not state what they use as "equality" when interpreting the laws for their instance
2023-10-16 19:35:08 +0200 <Inst> semanntically, then
2023-10-16 19:35:11 +0200 <geekosaur> ApplicativeDo isn't just potentially long compile times, it's also pickier than it needs to be and therefore small changes to code can break it (cause it to infer a Monad constraint instead)
2023-10-16 19:35:19 +0200 <geekosaur> But the concept is not bad
2023-10-16 19:35:20 +0200 <tomsmeding> though the informal default of "same result and same effects" is probably used by almost everyone unless stated otherwise
2023-10-16 19:35:32 +0200 <Inst> Concurrently is a Monad in the way we usually use the term, right?
2023-10-16 19:35:40 +0200 <tomsmeding> what is the way we usually use the term
2023-10-16 19:35:45 +0200 <tomsmeding> that's the whole point of this conversation :p
2023-10-16 19:36:02 +0200 <probie> "same effects" is rather hand-wavy, since we'd probably call sparking a new thread an effect, but maybe not an additional memory allocation?
2023-10-16 19:36:13 +0200 <tomsmeding> I was implicitly assuming a definition in which Concurrently is technically not a monad
2023-10-16 19:36:14 +0200 <Inst> a Monad, as we say it, means a type which can have a lawful instancing into the class Monad
2023-10-16 19:36:19 +0200 <tomsmeding> dolio was arguing that it should be context-dependent
2023-10-16 19:36:28 +0200 <tomsmeding> probie: true
2023-10-16 19:36:39 +0200 <tomsmeding> Inst: "lawful" is ambiguous
2023-10-16 19:36:48 +0200 <geekosaur> Inst, but the definition of "lawful" was in question a few minutes ago
2023-10-16 19:36:53 +0200 <tomsmeding> because there's various ways you can interpret the equalities
2023-10-16 19:37:02 +0200 <tomsmeding> that was the whole bloody conversation :p
2023-10-16 19:37:54 +0200stefan-__(~m-ohzqow@42dots.de)
2023-10-16 19:38:12 +0200 <Inst> i guess i'm having a different semantic argument
2023-10-16 19:38:38 +0200cpressey(~cpressey@host-92-10-148-105.as13285.net) (Quit: Client closed)
2023-10-16 19:38:51 +0200 <Inst> if you treat Concurrently as a newtype over IO, there exists a pair of an applicative and monad instances which satisfy the monad laws
2023-10-16 19:38:57 +0200 <EvanR> some definitions of equality are more equal than others
2023-10-16 19:39:12 +0200 <Inst> which is not concurrently's actual applicative instance
2023-10-16 19:39:32 +0200 <tomsmeding> Inst: you're now interpreting the equalities as requiring execution of effects in the same order
2023-10-16 19:39:37 +0200 <probie> `ZipList`s have the same problem
2023-10-16 19:40:06 +0200 <tomsmeding> the effects of the contained IO operations, that is
2023-10-16 19:40:08 +0200 <Inst> ugh, my definition of how we use the word Monad to describe types is now messed up :(
2023-10-16 19:40:26 +0200 <dolio> "To define a set we prescribe, at least implicitly, what we (the constructing intelligence) must do in order to construct an element of the set, and what we must do to show that two elements of the set are equal." -- Bishop
2023-10-16 19:40:31 +0200 <Inst> and i'd see it as requiring execution of effects in the same order
2023-10-16 19:40:45 +0200 <Inst> remember, in Haskell, there's an explicit notion of effect that can be contained by monadic types
2023-10-16 19:41:02 +0200 <Inst> so the effect is baked into the value
2023-10-16 19:41:24 +0200 <tomsmeding> Inst: I agree on one hand
2023-10-16 19:41:36 +0200 <probie> `Functor` is friendly because a type only admits one meaningful instance, `Applicative` on the other hand, doesn't have that limitation
2023-10-16 19:41:50 +0200 <tomsmeding> on the other hand, if you're using Concurrently, you're kind of explicitly waiving the guarantee that your effects are executed in a deterministic order
2023-10-16 19:42:17 +0200 <tomsmeding> a <*> b is not even equal to a <*> b because the effect order is nondeterministic
2023-10-16 19:42:30 +0200 <Inst> ugh, i'd probably need to spend a lot of time thinking about this
2023-10-16 19:42:34 +0200 <tomsmeding> let alone any non-tautological law :p
2023-10-16 19:42:53 +0200 <monochrom> Ugh, that should not be how you define "equal".
2023-10-16 19:42:57 +0200ursa-major(~ursa-majo@static-198-44-128-153.cust.tzulo.com)
2023-10-16 19:43:13 +0200 <tomsmeding> so if Concurrently is to be a lawful Applicative, with that same notion of equality (modulo effect reordering), it's also a Monad with the obvious implementation of (>>=) :p
2023-10-16 19:43:57 +0200 <monochrom> C programmers can be excused to say "rand() does not equal rand()" because by Sapir-Whorf they only know to compare return values of rand().
2023-10-16 19:44:09 +0200 <monochrom> (and because the "type" is "int".)
2023-10-16 19:44:43 +0200 <tomsmeding> oooh
2023-10-16 19:44:57 +0200 <monochrom> We have learned from Haskell that the true type is "IO Int" so rand == rand alright. Equality for IO Int means equivalent behaviour.
2023-10-16 19:45:00 +0200 <tomsmeding> monochrom: you're saying that it's a lawful applicative because both LHS and RHS of the laws have nondeterministic effect orders
2023-10-16 19:45:08 +0200 <tomsmeding> so they are indeed observationally equal
2023-10-16 19:45:23 +0200 <monochrom> To be sure it takes a lot of effort to write down the denotational semantics of IO but equality should be based on that.
2023-10-16 19:45:29 +0200 <Inst> afaik the nondeterministic effect is conceptualized and baked into the definition?
2023-10-16 19:46:12 +0200 <tomsmeding> Inst: which definition do you mean?
2023-10-16 19:46:23 +0200 <Inst> the definition of the value?
2023-10-16 19:46:26 +0200 <tomsmeding> which value
2023-10-16 19:46:32 +0200 <Inst> so then a <*> b <===> a <*> b
2023-10-16 19:46:39 +0200 <tomsmeding> right
2023-10-16 19:46:42 +0200 <monochrom> Nondeterminism does not change this consideration. You are comparing one set of all possible execution traces with another such set.
2023-10-16 19:46:54 +0200 <tomsmeding> right
2023-10-16 19:46:57 +0200 <probie> With `Concurrently`, you don't get equivalent behaviour as regular `IO`, because if in `f <*> g`, both `f` and `g` can raise exceptions, `IO` will always raise the exception for `f`, but `Concurrently` will non-deterministically return one of the exceptions for `f` or `g`
2023-10-16 19:47:11 +0200danza(~francesco@151.43.103.136)
2023-10-16 19:47:19 +0200 <tomsmeding> but if re-associate (<*>), you have the same non-determinism
2023-10-16 19:47:22 +0200 <tomsmeding> hence the Applicative laws hold
2023-10-16 19:47:39 +0200 <tomsmeding> yep, scratch the... some of my remarks above
2023-10-16 19:47:56 +0200 <tomsmeding> but under that reasoning surely 'm1 <*> m2 = m1 >>= (\x1 -> m2 >>= (\x2 -> return (x1 x2)))' doesn't hold
2023-10-16 19:48:06 +0200 <monochrom> (forkIO foo >> forkIO bar >> pure ()) = (forkIO bar >> forkIO foo >> pure()) because they are the same set of possible behaviours.
2023-10-16 19:48:15 +0200 <tomsmeding> because the LHS has executions that are impossible on the RHS
2023-10-16 19:48:49 +0200 <Inst> so, then, what is Concurrently?
2023-10-16 19:48:55 +0200 <tomsmeding> a lawful Applicative
2023-10-16 19:49:00 +0200 <Inst> is it defined by its specific applicative instance?
2023-10-16 19:49:01 +0200 <tomsmeding> and an almost-lawful Monad
2023-10-16 19:49:05 +0200 <tomsmeding> of course
2023-10-16 19:49:08 +0200 <Inst> or by any possible applicative instance?
2023-10-16 19:49:28 +0200 <tomsmeding> Data.Monoid.Sum and Data.Monoid.Product are different types because they have different Monoid instances
2023-10-16 19:49:38 +0200 <tomsmeding> even though the data types themselves are isomorphic
2023-10-16 19:49:48 +0200 <tomsmeding> ZipList and [] are not the same
2023-10-16 19:49:54 +0200 <Inst> okay, then, Concurrently cannot be a monad for breaking additional monad laws relating applicative to monad
2023-10-16 19:50:04 +0200 <tomsmeding> unless, that is, you don't care about the instances -- "sameness" may be context-dependent
2023-10-16 19:50:06 +0200 <Inst> this was insightful and interesting, thanks for the education
2023-10-16 19:50:12 +0200 <tomsmeding> yep
2023-10-16 19:50:41 +0200 <tomsmeding> though, still, I would have little objection to a Monad instance
2023-10-16 19:51:01 +0200 <Inst> just from a pragmatic point of view, i'd still object to it because it'd create unwanted expectations
2023-10-16 19:51:19 +0200 <tomsmeding> I mean, you'd need to document it
2023-10-16 19:51:24 +0200 <probie> I would strongly object, because it would almost always be an accident to use for `Concurrently`
2023-10-16 19:51:30 +0200 <tomsmeding> would it?
2023-10-16 19:51:45 +0200 <Inst> ummm, it'd be a footgun, no?
2023-10-16 19:51:59 +0200 <tomsmeding> hm, I guess because Concurrently is not a monad transformer, you can just runConcurrently every time you have a data dependency
2023-10-16 19:52:01 +0200 <probie> If you're using `Concurrently`, you probably not very far away from `IO`
2023-10-16 19:52:16 +0200 <probie> s/you probably/you are probably/
2023-10-16 19:52:23 +0200 <Inst> and if you're chaining it via XApplicativeDo, there is no way to tell when slight mistakes in coding cause ApplicativeDo to resort to monad desugaring
2023-10-16 19:52:30 +0200 <dolio> Given how ApplicativeDo works, you could easily be accidentally pessimising yourself if you didn't get errors when it flips over to Monad.
2023-10-16 19:52:38 +0200 <Inst> except when the benchmarks fail
2023-10-16 19:52:42 +0200 <tomsmeding> true
2023-10-16 19:52:53 +0200 <tomsmeding> good points
2023-10-16 19:53:08 +0200 <tomsmeding> I would perhaps just not use ApplicativeDo at all
2023-10-16 19:53:11 +0200 <tomsmeding> but it's a footgun for sure
2023-10-16 19:53:26 +0200 <monochrom> This is why for a Monad instance, we require that equation between <*> and >>= .
2023-10-16 19:53:52 +0200 <monochrom> OTOH once in a while there is an exceptional just cause to deviate...
2023-10-16 19:54:50 +0200 <monochrom> Then people start arguing elastic social convention vs inelastic sacred commandments.
2023-10-16 19:55:14 +0200 <Inst> and there is a very useful term for it, "unlawful monad"
2023-10-16 19:55:36 +0200 <monochrom> I got attracted to programming because I wanted to stay away from people issues. Turns out there is no escape. >:)
2023-10-16 19:56:04 +0200 <monochrom> Hell, to a 10% extent, even s/people issues/people/
2023-10-16 19:56:21 +0200 <tomsmeding> you failed, you're too active in #haskell
2023-10-16 19:56:34 +0200 <monochrom> Right? When a human says "yes", it doesn't even always mean "yes".
2023-10-16 19:56:59 +0200 <monochrom> But if the computer says "OK" then it really simply means "OK".
2023-10-16 19:57:03 +0200 <monochrom> Similarly, math.
2023-10-16 19:57:15 +0200 <Inst> "words are like nets, meaning is like fish"
2023-10-16 19:57:20 +0200 <tomsmeding> but what that "OK" in turn means might be surprising :p
2023-10-16 19:57:22 +0200 <Inst> you can spend all day trying to decipher what people really mean
2023-10-16 19:58:25 +0200 <Inst> also, with the runConcurrently stuff
2023-10-16 19:58:43 +0200 <tomsmeding> cabal, for a few versions, interpreted the exit status of a post-checkout-command in a cabal.project the wrong way round
2023-10-16 19:58:49 +0200 <tomsmeding> exit code 1 was success, exit code 0 was failure
2023-10-16 19:58:54 +0200 <tomsmeding> they fixed it recently
2023-10-16 19:59:01 +0200 <tomsmeding> OK doesn't always mean OK monochrom
2023-10-16 19:59:34 +0200 <tomsmeding> I now have some cabal.projects around that have a ! before their command, and I have to fix them up when working in that folder again
2023-10-16 19:59:34 +0200 <monochrom> OK computers have bugs. Or someone wrote the wrong message to print in the code.
2023-10-16 19:59:47 +0200 <Inst> put another way, the deep meaning of code is more visible than with people, because you have all the information needed to understand the actual computation
2023-10-16 19:59:56 +0200 <dolio> Haskell just doesn't give you enough machinery to specify what equality is, per Bishop.
2023-10-16 19:59:57 +0200eggplantade(~Eggplanta@2600:1700:38c5:d800:e9d7:8bce:4928:5b34)
2023-10-16 20:00:01 +0200 <Inst> meanwhile, modeling everything someone knows, everything they're thinking, etc, all that information is hidden
2023-10-16 20:00:18 +0200 <monochrom> I just mean a fairly bugless compiler/interpreter, when it says "syntax error" then I truly have a syntax error, if it says "no syntax error" then it truly means no syntax error.
2023-10-16 20:00:37 +0200jumper(~jumper@mobile-access-6df060-87.dhcp.inet.fi)
2023-10-16 20:01:01 +0200 <Inst> wb jumper, hope your questions get resolved adequately today :)
2023-10-16 20:01:27 +0200 <tomsmeding> monochrom: perhaps we can say: at least programs tend to strive towards this property
2023-10-16 20:01:34 +0200 <tomsmeding> people, not necessarily
2023-10-16 20:02:27 +0200qqq(~qqq@92.43.167.61)
2023-10-16 20:03:11 +0200 <monochrom> OK sometimes it's the flip side. What I say vs what the computer or human thinks I mean.
2023-10-16 20:03:24 +0200 <monochrom> Suppose I say "print x" but I didn't say "print y".
2023-10-16 20:03:35 +0200sm(~sm@plaintextaccounting/sm) (Ping timeout: 240 seconds)
2023-10-16 20:03:40 +0200 <jumper> Inst, function definitions in Haskell and function calls, are they similar as in math? f :: Int -> Int ; f i = i + 1 ; f 1
2023-10-16 20:03:47 +0200 <monochrom> A computer reliably predictably unwailining honours exactly that, no more no less.
2023-10-16 20:03:58 +0200 <Inst> i don't know, ask someone else :(
2023-10-16 20:04:06 +0200 <monochrom> Humans? They start second-guessing me and guess wrong.
2023-10-16 20:04:12 +0200danza(~francesco@151.43.103.136) (Read error: Connection reset by peer)
2023-10-16 20:05:11 +0200 <monochrom> Programming languages are a relief to me because I just have to say what I mean and not worry that it needs further "clarifications".
2023-10-16 20:05:31 +0200 <monochrom> With humans, it's telephone games all the way down.
2023-10-16 20:05:34 +0200tomsmeding. o O ( INTERCAL )
2023-10-16 20:06:16 +0200 <monochrom> But OK, eventually, one learns that a computer consists of a million layers of abstractions, so it is still telephone games all the way down. >:)
2023-10-16 20:06:16 +0200 <EvanR> jumper, don't get too caught up in concrete syntax too much
2023-10-16 20:06:48 +0200 <EvanR> sin pi, sin(pi), it's really not an interesting decision to dwell on
2023-10-16 20:06:52 +0200sm(~sm@plaintextaccounting/sm)
2023-10-16 20:07:11 +0200 <EvanR> it's parsed into the same thing
2023-10-16 20:07:33 +0200 <EvanR> (application of sin to pi)
2023-10-16 20:07:51 +0200 <monochrom> Actually, I put it wrong. I just have to know that the computer reliably takes what I say at face value and not try to "read between the lines" and start putting words into my mouth.
2023-10-16 20:09:42 +0200 <Inst> monochrom: there's possibly a cultural dimension to your criticism, but I think that's off-topic
2023-10-16 20:10:05 +0200 <monochrom> Yeah I was about to stop. But just one last erratum.
2023-10-16 20:11:50 +0200 <monochrom> It is impossible to answer "are they similar?" in most cases.
2023-10-16 20:11:51 +0200 <jumper> Is it possible in haskell to express \xy.x, that is, \x.\y.x, in Haskell aswell without the extra arrow? f :: x -> y -> x ;
2023-10-16 20:12:02 +0200 <monochrom> https://www.vex.net/~trebla/humour/tautologies.html #0
2023-10-16 20:12:12 +0200 <tomsmeding> :t \x y -> x
2023-10-16 20:12:13 +0200 <lambdabot> p1 -> p2 -> p1
2023-10-16 20:12:29 +0200 <EvanR> perhaps you want (x,y) -> x i.e. pass in a pair
2023-10-16 20:12:35 +0200 <EvanR> uncurrying
2023-10-16 20:12:41 +0200 <monochrom> Or perhaps equivalently, it is always trivial to answer, the correct answer is always "they are similar, but different :)"
2023-10-16 20:13:09 +0200 <EvanR> but if you want to express \x -> \y -> x, that is literally two arrows
2023-10-16 20:13:23 +0200 <tomsmeding> monochrom: that could be a tautology for the list, "These two things are similar but different"
2023-10-16 20:13:28 +0200glguy(g@libera/staff/glguy)
2023-10-16 20:13:34 +0200g(g@libera/staff/glguy) (Read error: Connection reset by peer)
2023-10-16 20:13:36 +0200g_(g@libera/staff/glguy)
2023-10-16 20:13:37 +0200g_g
2023-10-16 20:13:39 +0200 <monochrom> Haskell "\x y -> foo" is syntax sugar for "\x -> (\y -> foo)"
2023-10-16 20:13:40 +0200ghoulguy(g@libera/staff/glguy) (Read error: Connection reset by peer)
2023-10-16 20:13:46 +0200glguyghoulguy
2023-10-16 20:14:07 +0200 <geekosaur> is lambda calculus \xy.x even well formed?
2023-10-16 20:14:18 +0200 <EvanR> you can define that shorthand
2023-10-16 20:14:25 +0200 <monochrom> tomsmeding, I thought #0 already covers that :)
2023-10-16 20:14:48 +0200 <tomsmeding> yeah I guess true :p
2023-10-16 20:14:50 +0200 <Inst> i like the contradiction, i.e, the tautology list is basically why people try to read between the lines
2023-10-16 20:15:19 +0200 <monochrom> I think everyone defines "lambda x y . foo" or "lambda x, y . foo" to mean nested lambdas.
2023-10-16 20:16:19 +0200hiyori(~hiyori@user/hiyori)
2023-10-16 20:16:27 +0200 <monochrom> Including Church. He used the comma version.
2023-10-16 20:16:48 +0200 <monochrom> Actually maybe I don't actually remember whether he used comma or not.
2023-10-16 20:16:59 +0200 <monochrom> My thesis supervisor uses comma. :)
2023-10-16 20:18:39 +0200 <EvanR> \x y z . whatever is sugar for nested lambdas, because in LC every function takes one arugment. And then GHC baits and switches by compiling things to multi-arg functions after all!
2023-10-16 20:19:33 +0200 <monochrom> Well, you can't blame GHC for compiling to the von Neumann model which has no idea what lambda even means.
2023-10-16 20:19:33 +0200 <EvanR> what you see is what you get
2023-10-16 20:20:05 +0200 <monochrom> Alternatively, you can't blame GHC for trying to compile to faster code.
2023-10-16 20:20:51 +0200 <dolio> Church does not use commas, at least in the reprint book I have.
2023-10-16 20:21:15 +0200 <monochrom> Compiling to "function f(x) { return yet another function }" is going to give you dog slow code. Then everyone will complain "Haskell is not ready for prime time because it's too slow." Remember those days?
2023-10-16 20:22:15 +0200 <monochrom> Ah thanks dolio.
2023-10-16 20:22:29 +0200 <EvanR> now that it's fast, we need another reason it's not ready for prime time. Because avoid success
2023-10-16 20:22:45 +0200 <EvanR> avoiding success doesn't happen on its own
2023-10-16 20:22:56 +0200 <monochrom> Oh, the next "reason" was "toolchain" >:)
2023-10-16 20:23:13 +0200 <EvanR> there we go
2023-10-16 20:23:17 +0200 <monochrom> And then the next next reason was "two toolchains" >:D
2023-10-16 20:24:09 +0200acidjnk_new(~acidjnk@p200300d6e72b933890137bb0a9c5386a.dip0.t-ipconnect.de)
2023-10-16 20:24:47 +0200acidjnk(~acidjnk@p200300d6e7072f57652bd3d039ad030c.dip0.t-ipconnect.de) (Ping timeout: 246 seconds)
2023-10-16 20:26:02 +0200 <monochrom> Some time between them there was also "Windows".
2023-10-16 20:28:14 +0200 <jumper> have there been any trials to write an operating system using Haskell alone with some basic low level library support?
2023-10-16 20:29:02 +0200 <geekosaur> House
2023-10-16 20:29:09 +0200misterfish(~misterfis@84-53-85-146.bbserv.nl)
2023-10-16 20:30:33 +0200 <geekosaur> https://github.com/dls/house
2023-10-16 20:30:48 +0200 <geekosaur> also has haskellwiki and wikipedia entries
2023-10-16 20:30:55 +0200 <jumper> cool
2023-10-16 20:33:35 +0200 <ncf> > House (acronym for Haskell User's Operating System and Environment)
2023-10-16 20:33:37 +0200 <lambdabot> error:
2023-10-16 20:33:37 +0200 <lambdabot> Data constructor not in scope: House :: t0 -> terror:
2023-10-16 20:33:37 +0200 <lambdabot> Variable not in scope:
2023-10-16 20:33:39 +0200ncfsquints
2023-10-16 20:34:46 +0200Tuplanolla(~Tuplanoll@91-159-68-236.elisa-laajakaista.fi)
2023-10-16 20:34:56 +0200urdh(~urdh@user/urdh) (Quit: Boom!)
2023-10-16 20:35:01 +0200sm(~sm@plaintextaccounting/sm) (Quit: sm)
2023-10-16 20:35:17 +0200hiyori(~hiyori@user/hiyori) (Quit: Client closed)
2023-10-16 20:35:35 +0200hiyori(~hiyori@user/hiyori)
2023-10-16 20:35:38 +0200 <geekosaur> evidently is doesn't include a spell checker 😛
2023-10-16 20:35:45 +0200 <geekosaur> *ti
2023-10-16 20:35:46 +0200nate2(~nate@c-98-45-169-16.hsd1.ca.comcast.net)
2023-10-16 20:35:48 +0200 <geekosaur> *it
2023-10-16 20:35:51 +0200urdh(~urdh@user/urdh)
2023-10-16 20:36:01 +0200geekosaurlooks at fingers suspiciously
2023-10-16 20:37:10 +0200urdh(~urdh@user/urdh) (Client Quit)
2023-10-16 20:37:28 +0200emmanuelux_(~emmanuelu@user/emmanuelux)
2023-10-16 20:40:12 +0200nate2(~nate@c-98-45-169-16.hsd1.ca.comcast.net) (Ping timeout: 240 seconds)
2023-10-16 20:40:22 +0200emmanuelux(~emmanuelu@user/emmanuelux) (Ping timeout: 255 seconds)
2023-10-16 20:41:57 +0200urdh(~urdh@user/urdh)
2023-10-16 20:44:44 +0200danza(~francesco@151.47.109.198)
2023-10-16 20:49:35 +0200urdh(~urdh@user/urdh) (Quit: Boom!)
2023-10-16 20:52:09 +0200urdh(~urdh@user/urdh)
2023-10-16 20:53:37 +0200 <int-e> "-> terror", nice.
2023-10-16 20:54:11 +0200 <int-e> (no clue what happened to that newline)
2023-10-16 20:54:48 +0200 <Unicorn_Princess> what's the difference between {-# OPTIONS .. #-} and {-# OPTIONS_GHC .. #-}, and when should each be used? specifically for disabling warnings, in case the question is too big
2023-10-16 20:55:11 +0200 <Unicorn_Princess> (both seem to work)
2023-10-16 20:55:25 +0200actioninja(~actioninj@user/actioninja) (Quit: Ping timeout (120 seconds))
2023-10-16 20:55:26 +0200Katarushisu1(~Katarushi@cpc147790-finc20-2-0-cust502.4-2.cable.virginm.net) (Quit: Ping timeout (120 seconds))
2023-10-16 20:55:29 +0200 <int-e> I suspect that OPTIONS would apply to other Haskell compilers or interpreters too.
2023-10-16 20:55:50 +0200actioninja(~actioninj@user/actioninja)
2023-10-16 20:55:53 +0200 <geekosaur> not that there are any these days, but I'd still stick to OPTIONS_GHC
2023-10-16 20:55:55 +0200 <int-e> (Which used to be more numerous than they are today.)
2023-10-16 20:56:08 +0200hamess(~hamess@user/hamess)
2023-10-16 20:56:18 +0200 <ddellacosta> Unicorn_Princess: looks like they are the same, but OPTIONS is deprecated https://downloads.haskell.org/ghc/latest/docs/users_guide/exts/pragmas.html?highlight=pragmas#opti…
2023-10-16 20:56:40 +0200 <Unicorn_Princess> ah, thanks
2023-10-16 20:57:25 +0200 <Clint> it's been marked as deprecated for ages
2023-10-16 20:58:01 +0200Katarushisu1(~Katarushi@cpc147790-finc20-2-0-cust502.4-2.cable.virginm.net)
2023-10-16 21:02:38 +0200 <monochrom> Procrastination is universal. >:)
2023-10-16 21:02:59 +0200ft(~ft@p3e9bc680.dip0.t-ipconnect.de)
2023-10-16 21:07:44 +0200ursa-major(~ursa-majo@static-198-44-128-153.cust.tzulo.com) (Quit: WeeChat 4.0.5)
2023-10-16 21:08:21 +0200eggplantade(~Eggplanta@2600:1700:38c5:d800:e9d7:8bce:4928:5b34) (Remote host closed the connection)
2023-10-16 21:08:56 +0200eggplantade(~Eggplanta@2600:1700:38c5:d800:e9d7:8bce:4928:5b34)
2023-10-16 21:09:29 +0200 <Franciman> procrastination is final, all objects map to it
2023-10-16 21:10:26 +0200waleee(~waleee@2001:9b0:21c:e600:f2f3:f744:435d:137c)
2023-10-16 21:11:17 +0200danza(~francesco@151.47.109.198) (Ping timeout: 255 seconds)
2023-10-16 21:13:21 +0200eggplantade(~Eggplanta@2600:1700:38c5:d800:e9d7:8bce:4928:5b34) (Ping timeout: 260 seconds)
2023-10-16 21:16:03 +0200 <tomsmeding> I expect support for OPTIONS will never be removed, there is too much code using it :p
2023-10-16 21:16:28 +0200 <tomsmeding> and, until a new competing compiler arrives, there is little benefit in removing it
2023-10-16 21:21:34 +0200sm(~sm@plaintextaccounting/sm)
2023-10-16 21:21:52 +0200Unicorn_Princess(~Unicorn_P@user/Unicorn-Princess/x-3540542) (Remote host closed the connection)
2023-10-16 21:22:02 +0200 <EvanR> I approve of the portmanteau terror for type error
2023-10-16 21:22:13 +0200 <EvanR> very seasonal
2023-10-16 21:22:39 +0200 <juri_> so, what's the process for taking over a package that appears abandoned by it's maintainer? tl;dr: floating-bits is breaking me, because it is not compatible with newer GHCs.
2023-10-16 21:24:02 +0200 <geekosaur> https://wiki.haskell.org/Taking_over_a_package
2023-10-16 21:24:24 +0200 <tomsmeding> you even had the right search term already ;)
2023-10-16 21:24:53 +0200 <Clint> there's also https://github.com/haskell-infra/hackage-trustees/issues
2023-10-16 21:30:58 +0200cpressey(~cpressey@host-92-10-148-105.as13285.net)
2023-10-16 21:46:34 +0200benjaminl(~benjaminl@user/benjaminl) (Remote host closed the connection)
2023-10-16 21:46:53 +0200benjaminl(~benjaminl@user/benjaminl)
2023-10-16 21:47:03 +0200Yumemi(~Yumemi@2001:bc8:47a0:1b14::1) (Quit: .)
2023-10-16 21:47:29 +0200 <EvanR> there are various ways to implement a custom "app monad" with a bunch of features. Which one gives the most performance
2023-10-16 21:47:43 +0200 <EvanR> freer?
2023-10-16 21:47:55 +0200Yumemi(~Yumemi@chamoin.net)
2023-10-16 21:48:45 +0200 <EvanR> is that the one the church encodes the functor of actions
2023-10-16 21:49:58 +0200 <tomsmeding> are you looking for algebraic effects?
2023-10-16 21:50:26 +0200 <tomsmeding> if you're not doing algebraic effects, don't go with free monads
2023-10-16 21:51:11 +0200 <EvanR> is it slower
2023-10-16 21:51:15 +0200 <tomsmeding> yes
2023-10-16 21:51:19 +0200 <tomsmeding> ReaderT env IO
2023-10-16 21:51:24 +0200 <tomsmeding> is your friend if you want performance
2023-10-16 21:51:39 +0200 <EvanR> and use IO exceptions to do stuff like cancel a computation early?
2023-10-16 21:51:54 +0200 <tomsmeding> IO exceptions are faster than Either, yes
2023-10-16 21:52:10 +0200 <tomsmeding> if you're already in IO anyway
2023-10-16 21:52:23 +0200 <EvanR> what about env -> IO, is it even faster xD
2023-10-16 21:52:36 +0200 <tomsmeding> @unmtl ReaderT env IO
2023-10-16 21:52:36 +0200 <lambdabot> err: `ReaderT env IO' is not applied to enough arguments, giving `/\A. env -> IO A'
2023-10-16 21:52:40 +0200 <tomsmeding> @unmtl ReaderT env IO a
2023-10-16 21:52:40 +0200 <lambdabot> env -> IO a
2023-10-16 21:52:52 +0200 <tomsmeding> it's a newtype over the same thing, so same
2023-10-16 21:53:24 +0200 <monochrom> The only difference is what your code looks like.
2023-10-16 21:53:27 +0200 <EvanR> this isn't the answer I was expecting but I guess I'm not surprised
2023-10-16 21:53:38 +0200 <tomsmeding> EvanR: the reader monad _is_ r->
2023-10-16 21:53:40 +0200 <EvanR> simple haskell for the win
2023-10-16 21:54:01 +0200 <tomsmeding> when people talk about the venerable function monad for advanced point-free tricks, that's the reader monad
2023-10-16 21:54:04 +0200 <tomsmeding> just without the newtype wrapper
2023-10-16 21:54:43 +0200 <geekosaur> sanity wrapper 🙂
2023-10-16 21:55:34 +0200 <tomsmeding> > ((,) <$> (+ 1) <*> (* 2)) 10
2023-10-16 21:55:36 +0200 <lambdabot> (11,20)
2023-10-16 21:56:09 +0200 <tomsmeding> coerce (+ 1) :: Num a => Reader a a
2023-10-16 21:56:44 +0200 <EvanR> the dependency injection monad
2023-10-16 21:57:30 +0200 <Rembane> Enterprise Patterns for Haskell etc
2023-10-16 21:57:38 +0200 <monochrom> Abusing the (->) Functor, you can rewrite the functor law "fmap (f . g) = fmap f . fmap g" to "fmap (fmap f g) = fmap (fmap f) (fmap g)". >:)
2023-10-16 21:59:12 +0200 <tomsmeding> on a related note, if you want to fmap two functors deep, that's
2023-10-16 21:59:14 +0200 <tomsmeding> :t fmap fmap fmap
2023-10-16 21:59:15 +0200 <lambdabot> (Functor f1, Functor f2) => (a -> b) -> f1 (f2 a) -> f1 (f2 b)
2023-10-16 21:59:18 +0200 <EvanR> so if you don't want or need any IO, does that automatically make your app monad slower
2023-10-16 21:59:21 +0200 <tomsmeding> also known as fmap . fmap
2023-10-16 21:59:50 +0200 <EvanR> by implementing on the stuff IO does purely
2023-10-16 21:59:55 +0200 <EvanR> all the stuff
2023-10-16 22:00:36 +0200hugo(znc@verdigris.lysator.liu.se) (Ping timeout: 260 seconds)
2023-10-16 22:01:00 +0200 <tomsmeding> IO as a monad is essentially just `State ()`, except that there's no runIO (that's unsafePerformIO, but it's marked unsafe for a good reason) so there's only one so we have control over it
2023-10-16 22:01:50 +0200 <tomsmeding> all the impure stuff in IO is just unsafely calling side-effecting primops and relying on the guarantees of being a monad for overall purity
2023-10-16 22:03:08 +0200 <tomsmeding> EvanR: if you don't build on IO, then you don't have IORefs
2023-10-16 22:03:40 +0200 <tomsmeding> that 'env' typically contains a bunch of IORefs, making you a makeshift state monad, except with the state in IORefs
2023-10-16 22:04:36 +0200 <EvanR> and instead of exceptions you have Either
2023-10-16 22:04:40 +0200 <EvanR> or Maybe
2023-10-16 22:05:58 +0200 <tomsmeding> the reason why Either for exceptions is slower than using IO exceptions (or asynchronous exceptions, for that matter) is that using Either entails a conditional branch at every >>=
2023-10-16 22:06:01 +0200 <EvanR> on the IORef front I was under the impression that mutable variables takes a hit thanks to the GC, compared to like, updating an IntMap of stuff
2023-10-16 22:06:05 +0200 <tomsmeding> and that's a lot of additional conditional branches
2023-10-16 22:06:21 +0200 <tomsmeding> and also, potentially, a bunch of additional allocation if the Right constructors don't get eliminated
2023-10-16 22:06:36 +0200 <tomsmeding> potentially
2023-10-16 22:06:46 +0200 <tomsmeding> I don't know enough about the performance details there :D
2023-10-16 22:07:08 +0200 <tomsmeding> I just know that I once converted an interpreter from using Either to using asynchronous exceptions, and it was multiple times faster
2023-10-16 22:07:19 +0200 <tomsmeding> I felt gross but I did it anyway
2023-10-16 22:07:37 +0200 <EvanR> clearly you should have used CPS or something
2023-10-16 22:07:41 +0200 <tomsmeding> perhaps
2023-10-16 22:08:30 +0200hugo(znc@verdigris.lysator.liu.se)
2023-10-16 22:09:01 +0200 <EvanR> so maybe ContT trumps all in performance
2023-10-16 22:09:37 +0200 <tomsmeding> I have indeed been told at some point that newtype Error e a = Error (forall r. (e -> r) -> (a -> r) -> r) is more performant than Either
2023-10-16 22:09:41 +0200Jackneill(~Jackneill@20014C4E1E021C00C8911A68759FC1A4.dsl.pool.telekom.hu) (Ping timeout: 255 seconds)
2023-10-16 22:10:16 +0200 <EvanR> hell yes
2023-10-16 22:10:27 +0200 <EvanR> well it deserves a benchmark I guess
2023-10-16 22:11:09 +0200Torio(~Torio@static-245-43-225-77.ipcom.comunitel.net)
2023-10-16 22:11:15 +0200takuan(~takuan@178-116-218-225.access.telenet.be) (Remote host closed the connection)
2023-10-16 22:11:30 +0200sm(~sm@plaintextaccounting/sm) (Quit: sm)
2023-10-16 22:12:04 +0200sm(~sm@plaintextaccounting/sm)
2023-10-16 22:12:22 +0200pretty_dumm_guy(trottel@gateway/vpn/protonvpn/prettydummguy/x-88029655)
2023-10-16 22:12:42 +0200sm(~sm@plaintextaccounting/sm) (Client Quit)
2023-10-16 22:12:49 +0200Inst(~Inst@120.244.192.250) (Ping timeout: 252 seconds)
2023-10-16 22:14:08 +0200Torio(~Torio@static-245-43-225-77.ipcom.comunitel.net) (Quit: Leaving)
2023-10-16 22:14:31 +0200 <tomsmeding> but if so, why does GHC not convert it for us?
2023-10-16 22:14:48 +0200 <tomsmeding> f :: Error e a -> Either e a ; f (Error g) = g Left Right
2023-10-16 22:14:54 +0200 <tomsmeding> it's not like it's difficult
2023-10-16 22:15:02 +0200 <tomsmeding> you can still pattern-match
2023-10-16 22:15:35 +0200hugo(znc@verdigris.lysator.liu.se) (Ping timeout: 240 seconds)
2023-10-16 22:15:54 +0200 <tomsmeding> ah, because in general that introduces recomputation
2023-10-16 22:16:04 +0200 <tomsmeding> you're now call-by-name instead of call-by-need
2023-10-16 22:16:52 +0200 <tomsmeding> it only works as a monad because the "carrier" of the monad (I have no idea how that is called; I mean the 'Error e a' value) is threaded linearly through the computation, so you always invoke the function at most once
2023-10-16 22:17:40 +0200 <tomsmeding> that linear threading is there for the same reason that mutability can work in a monadic context
2023-10-16 22:17:41 +0200 <EvanR> unless you do recursion?
2023-10-16 22:17:48 +0200 <tomsmeding> hm?
2023-10-16 22:18:02 +0200 <EvanR> you can come back to the same action in a monadic program
2023-10-16 22:18:08 +0200 <tomsmeding> can you?
2023-10-16 22:18:08 +0200idgaen(~idgaen@2a01:e0a:498:fd50:fcc6:bb5d:489a:ce8c) (Quit: WeeChat 4.0.5)
2023-10-16 22:18:16 +0200 <tomsmeding> do you mean with mfix?
2023-10-16 22:18:24 +0200 <EvanR> main = print "Hello World" >> main
2023-10-16 22:18:29 +0200 <tomsmeding> that's not the same action
2023-10-16 22:18:34 +0200 <EvanR> o_O
2023-10-16 22:18:36 +0200 <tomsmeding> that's a different action each time, generated by the same code
2023-10-16 22:18:49 +0200 <EvanR> it's a CAF
2023-10-16 22:18:56 +0200 <EvanR> right
2023-10-16 22:18:59 +0200 <tomsmeding> sure, it's the same code
2023-10-16 22:19:14 +0200 <tomsmeding> but like, 'foo x = Right (x + 1) >>= foo'
2023-10-16 22:19:28 +0200 <tomsmeding> or even without the +1 so that it's really the same action each time
2023-10-16 22:19:30 +0200 <EvanR> that wouldn't be the same since x is changing
2023-10-16 22:19:33 +0200 <tomsmeding> sure
2023-10-16 22:19:38 +0200 <EvanR> rather, it's an argument
2023-10-16 22:19:40 +0200 <tomsmeding> 'foo = Right () >> foo'
2023-10-16 22:19:42 +0200 <tomsmeding> now happy? :p
2023-10-16 22:19:51 +0200 <EvanR> yeah there's only one foo
2023-10-16 22:19:53 +0200 <tomsmeding> yes
2023-10-16 22:20:02 +0200 <tomsmeding> but the Either is threaded linearly through the infinite computation
2023-10-16 22:20:22 +0200 <EvanR> and there ought to be one Right ()
2023-10-16 22:20:40 +0200 <tomsmeding> there's a Right (), which gets case-analysed in (>>), then the result ( () ) gets destroyed in this case and we continue with foo
2023-10-16 22:20:51 +0200 <tomsmeding> you don't case-analyse the same Either multiple times
2023-10-16 22:20:58 +0200 <tomsmeding> you create a new one each time before case-analysing it
2023-10-16 22:21:08 +0200 <EvanR> that doesn't seem right
2023-10-16 22:21:22 +0200 <tomsmeding> not after optimisations, of course
2023-10-16 22:21:29 +0200 <tomsmeding> naively
2023-10-16 22:21:42 +0200 <tomsmeding> I'm not talking about machine implementation here, I'm talking about semantics
2023-10-16 22:21:46 +0200 <EvanR> naively, foo is a single graph fragment not a function body
2023-10-16 22:21:49 +0200 <tomsmeding> call-by-name vs call-by-need vs call-by-value
2023-10-16 22:22:02 +0200 <EvanR> oh, you lost me there xD
2023-10-16 22:22:41 +0200 <tomsmeding> I mean the point is that if you do this: let Error g = ... in g a b + g c d + g e f
2023-10-16 22:22:46 +0200 <EvanR> call-by-whatever sounds more implementationy than the graph story
2023-10-16 22:22:49 +0200 <tomsmeding> then you're calling g multiple times
2023-10-16 22:23:28 +0200 <tomsmeding> whereas if you 'let e :: Either _ _ = ... in (case e of Left x -> a x ; Right y -> b y) + (case e of Left x -> c x; Right y -> d y) + ...'
2023-10-16 22:23:48 +0200 <tomsmeding> then you don't evaluate e multiple times, you evaluate it _once_
2023-10-16 22:23:59 +0200 <tomsmeding> the latter thing is what you want in call-by-need
2023-10-16 22:24:17 +0200 <tomsmeding> with the 'let Error g = ...' example you get call-by-name: every use of the variable recomputes its definition
2023-10-16 22:24:21 +0200 <tomsmeding> that's complete crap
2023-10-16 22:24:34 +0200 <tomsmeding> the reason Error works as a monad is that you _never_ case-analyse the same thing multiple times
2023-10-16 22:24:42 +0200 <EvanR> yeah you usually wouldn't do that g ab + g c d + g e f thing with monadic code, but you would possible recurse back to the same action
2023-10-16 22:24:44 +0200 <tomsmeding> the only time you case-analyse it is when passing it to >>=
2023-10-16 22:25:11 +0200 <tomsmeding> you _can't_ do that g a b + g c d + g e f thing with monad code precisely because of what I'm trying to say XD
2023-10-16 22:25:17 +0200 <tomsmeding> that's the point
2023-10-16 22:25:25 +0200 <tomsmeding> why Error works as a monad and not as an alternative Either
2023-10-16 22:25:30 +0200 <EvanR> yeah usually might be too conservative
2023-10-16 22:25:42 +0200 <EvanR> but you could recurse back to the same action
2023-10-16 22:26:02 +0200 <tomsmeding> and then you might case-analyse the result again
2023-10-16 22:26:12 +0200 <tomsmeding> but at that point the pure contents of the Right has already been evaluated
2023-10-16 22:26:15 +0200 <tomsmeding> it won't be evaluated again
2023-10-16 22:26:19 +0200 <tomsmeding> with the CPS version, it would
2023-10-16 22:27:28 +0200 <EvanR> unless the thing being returned from the Error function was in a closure and somehow arranged to be evaluated once only
2023-10-16 22:27:38 +0200 <tomsmeding> sure
2023-10-16 22:28:08 +0200dumptruckman(~dumptruck@143-42-184-47.ip.linodeusercontent.com) (Quit: ZNC - https://znc.in)
2023-10-16 22:28:25 +0200eggplantade(~Eggplanta@2600:1700:38c5:d800:e9d7:8bce:4928:5b34)
2023-10-16 22:28:36 +0200 <tomsmeding> but in general, to get to that point you either have to do some actual work (in putting lambdas in the right spot), or to rely on hoisting by GHC, which is an optimisation
2023-10-16 22:28:59 +0200 <EvanR> so the story I'm gathering is constructors are slow dumb and easy, CPS is fast advanced and tricky
2023-10-16 22:29:01 +0200wootehfoot(~wootehfoo@user/wootehfoot) (Read error: Connection reset by peer)
2023-10-16 22:29:07 +0200 <tomsmeding> ... kinda?
2023-10-16 22:29:34 +0200 <tomsmeding> CPS works well when you're tail-calling all the time
2023-10-16 22:29:43 +0200 <tomsmeding> as soon as you don't, you have to watch out
2023-10-16 22:29:46 +0200machinedgod(~machinedg@d198-53-218-113.abhsia.telus.net)
2023-10-16 22:30:01 +0200 <tomsmeding> this conversation is weird
2023-10-16 22:30:23 +0200 <tomsmeding> I started out not understanding something, then understanding it anyway a minute later, then spending a screenful of convo to try to explain what I just understood
2023-10-16 22:30:52 +0200 <tomsmeding> more than a screenful
2023-10-16 22:30:59 +0200dumptruckman(~dumptruck@23-239-13-136.ip.linodeusercontent.com)
2023-10-16 22:31:55 +0200_ht(~Thunderbi@28-52-174-82.ftth.glasoperator.nl) (Quit: _ht)
2023-10-16 22:32:12 +0200 <EvanR> and IO might be simpler and faster than everything
2023-10-16 22:32:20 +0200 <EvanR> sad state of affairs if true
2023-10-16 22:32:37 +0200 <tomsmeding> functional programming was not invented for performance
2023-10-16 22:33:30 +0200michalz(~michalz@185.246.207.197) (Remote host closed the connection)
2023-10-16 22:37:51 +0200hugo-(znc@verdigris.lysator.liu.se)
2023-10-16 22:38:34 +0200emmanuelux_(~emmanuelu@user/emmanuelux) (Quit: au revoir)
2023-10-16 22:40:49 +0200 <cpressey> I have an immensely hard time wrapping my head around so many of the things that have been said in this channel this evening
2023-10-16 22:41:16 +0200 <cpressey> There's a temptation to pick one, and ask "what do you mean by that"?
2023-10-16 22:41:31 +0200 <EvanR> lets at least hope it's mostly not wrong
2023-10-16 22:42:04 +0200 <Rembane> cpressey: Do it! If you're lucky you'll get an answer! :D
2023-10-16 22:42:07 +0200 <tomsmeding> cpressey: how many of those things have been said by me
2023-10-16 22:42:14 +0200 <EvanR> when it comes to trying to get the most performance out of haskell, I found it gets crazy fast
2023-10-16 22:42:37 +0200 <tomsmeding> amen
2023-10-16 22:42:39 +0200 <EvanR> but if the answer is "just do env -> IO a" then that's actually pretty simple and good
2023-10-16 22:42:51 +0200 <tomsmeding> iirc, in practice, kind of yes
2023-10-16 22:42:58 +0200 <tomsmeding> if you want effectful code
2023-10-16 22:43:21 +0200 <tomsmeding> for pure code that doesn't need monads in the first place, there's a whole other, orthogonal load of tricks and magic that you can use to make things faster
2023-10-16 22:43:45 +0200Carbon-lang(~Carbonlan@ip121.ip-149-56-160.net)
2023-10-16 22:43:54 +0200 <cpressey> See, things like "pure code that doesn't need monads"
2023-10-16 22:44:03 +0200 <tomsmeding> vague handwaving
2023-10-16 22:44:22 +0200 <tomsmeding> 99% of actual facts about performant code depend on the precise circumstance
2023-10-16 22:44:32 +0200Carbon-lang(~Carbonlan@ip121.ip-149-56-160.net) (Client Quit)
2023-10-16 22:44:33 +0200 <tomsmeding> so if you try to abstract over that, it gets vague fast
2023-10-16 22:44:46 +0200 <tomsmeding> if you pass around a few Eithers here and there, is that monadic code? hardly
2023-10-16 22:44:54 +0200 <tomsmeding> but if you do it enough, it might start to look like it
2023-10-16 22:45:20 +0200oo_miguel(~Thunderbi@78-11-179-96.static.ip.netia.com.pl) (Ping timeout: 255 seconds)
2023-10-16 22:45:28 +0200 <cpressey> If you use Either as a monad, that's monadic code, isn't it?
2023-10-16 22:45:41 +0200 <tomsmeding> luckily I said "orthogonal", because the "pure code tricks" apply always, and the monad tricks apply only if you're in a monad :D
2023-10-16 22:45:45 +0200 <tomsmeding> yes
2023-10-16 22:45:48 +0200lortabac(~lortabac@2a01:e0a:541:b8f0:263b:38d2:5b76:172d)
2023-10-16 22:45:49 +0200lortabac(~lortabac@2a01:e0a:541:b8f0:263b:38d2:5b76:172d) (Client Quit)
2023-10-16 22:45:59 +0200 <tomsmeding> that's actually an important example that we've been discussing
2023-10-16 22:46:25 +0200 <tomsmeding> but if you inline all the >>=s from Either and do the case analyses manually, is that monadic code?
2023-10-16 22:46:36 +0200 <tomsmeding> GHC doesn't really see the difference after a few inlining passes
2023-10-16 22:48:01 +0200 <cpressey> I assume by "inline >>=" you mean "expand >>= to its definition"?
2023-10-16 22:48:04 +0200 <tomsmeding> yeah
2023-10-16 22:48:47 +0200 <cpressey> Yeah, I don't know, if I write 4+4+4+4+4, am I doing multiplication?
2023-10-16 22:48:55 +0200 <tomsmeding> not really
2023-10-16 22:49:26 +0200 <tomsmeding> but for the purpose of optimisation, there's little difference between code using (>>=) from EIther and code that uses its expanded definition
2023-10-16 22:49:41 +0200fendor(~fendor@2a02:8388:1640:be00:aab:1226:f274:5021) (Remote host closed the connection)
2023-10-16 22:50:23 +0200 <tomsmeding> what is "monadic code" in this context is hard to put one's finger on without punting to "whatever is the set of circumstances where this particular change to the code's structure improves performance"
2023-10-16 22:50:28 +0200 <tomsmeding> which is as uninformative as it gets
2023-10-16 22:50:29 +0200 <EvanR> pure code and pure data is kind of haskell street jargon, a pure function is one which has no side effects and only depends on the input
2023-10-16 22:50:31 +0200 <cpressey> OK, never mind, the levels on which you are thinking about these concepts, are not the same levels I am thinking about them on.  Which is fine
2023-10-16 22:50:58 +0200 <EvanR> there's some kind of correlation between pure functions and pure other stuff that I never figured out, so it's probably bogus
2023-10-16 22:51:17 +0200 <tomsmeding> it's trying to abstract over things that don't _really_ allow abstracting over, because they're really more complex
2023-10-16 22:51:31 +0200 <tomsmeding> I don't really know, but suspect, that you're firmly in that land where things are more complex
2023-10-16 22:51:48 +0200 <tomsmeding> I've been trying to obstinately abstract anyway in order to extract some general guidelines
2023-10-16 22:51:49 +0200 <EvanR> monadic code and pure code is probably a bad distinction to try to draw
2023-10-16 22:52:15 +0200 <tomsmeding> it may be a helpful one for abstracting over certain classes of programs
2023-10-16 22:52:21 +0200 <cpressey> "Haskell street jargon", I like that.
2023-10-16 22:52:31 +0200 <tomsmeding> to learn a lesson about optimisation _once_ instead of again every time
2023-10-16 22:52:40 +0200 <tomsmeding> oh it's all street jargon for sure
2023-10-16 22:52:43 +0200 <cpressey> There is monadic code that is perfectly "pure" in the sense that it has no side effects.
2023-10-16 22:53:02 +0200 <cpressey> So to contrast "monadic" against "pure" seems to miss something.
2023-10-16 22:53:07 +0200 <EvanR> even IO code has no side effects, until it gets executed
2023-10-16 22:53:31 +0200 <tomsmeding> coming back to what dolio taught me earlier this evening: the definition of the words "pure", "monadic", etc. depend on context :D
2023-10-16 22:53:38 +0200 <tomsmeding> "effectful"
2023-10-16 22:54:32 +0200 <tomsmeding> is code using the Either monad pure? monadic? effectful?
2023-10-16 22:54:48 +0200 <EvanR> yes, yes, yes
2023-10-16 22:54:51 +0200 <tomsmeding> what if you expand >>= to its definition?
2023-10-16 22:54:58 +0200 <tomsmeding> EvanR: lol
2023-10-16 22:55:03 +0200 <tomsmeding> thank you
2023-10-16 22:55:30 +0200 <tomsmeding> the answers to these questions depend on what you're going to do with those answers
2023-10-16 22:55:35 +0200 <EvanR> the effects are directly modeled in the code rather than using magic beans
2023-10-16 22:56:00 +0200 <tomsmeding> you _can_ make these things precise, but sometimes that's very hard or even counterproductive
2023-10-16 22:56:10 +0200 <cpressey> I was going to say, Either can be defined entirely in Haskell; but IO (and others) can't.
2023-10-16 22:56:26 +0200 <tomsmeding> because they rely on GHC primitives?
2023-10-16 22:56:30 +0200 <EvanR> you can make something like IO with normal haskell, which is kind of where free monads live
2023-10-16 22:56:32 +0200 <tomsmeding> are they not Haskell?
2023-10-16 22:56:37 +0200 <cpressey> GHC is an implementation detail
2023-10-16 22:56:40 +0200 <tomsmeding> add "Haskell" to the list :D
2023-10-16 22:57:03 +0200 <EvanR> IO is abstract just because reasons, it could've had the primitives defined as constructors and exposed
2023-10-16 22:57:10 +0200Inst(~Inst@120.244.192.250)
2023-10-16 22:57:26 +0200 <EvanR> and the runtime interleaves execution with the followup computation either way
2023-10-16 22:57:35 +0200 <tomsmeding> cpressey: distinguishing Either from IO based on whether they can be defined in, say, Haskell2010 is a useful distinction sometimes
2023-10-16 22:57:42 +0200 <tomsmeding> it's not a useful distinction other times
2023-10-16 22:57:51 +0200 <Inst> so, about my issue with liftA2 having unpredictable order of effects, I guess the conclusion is:
2023-10-16 22:58:00 +0200 <cpressey> tomsmeding: Om
2023-10-16 22:58:09 +0200 <Inst> If a monad instance exists, the monad laws binding the applicative instance to monad means that the order of effects is predictable
2023-10-16 22:58:22 +0200 <Inst> if it doesn't exist, then there's more of a problem
2023-10-16 22:58:28 +0200 <tomsmeding> not more of a problem
2023-10-16 22:58:34 +0200 <EvanR> I thought Applicative also had an order of effects, or am I late to this party
2023-10-16 22:58:39 +0200 <tomsmeding> you just don't get a guarantee
2023-10-16 22:58:39 +0200 <Inst> well, just understand the applicative then
2023-10-16 22:58:41 +0200 <tomsmeding> EvanR: not from the laws
2023-10-16 22:58:47 +0200 <tomsmeding> from the Monad laws you get an order
2023-10-16 22:58:58 +0200 <Inst> also, I was sort of besotted with liftA2, iirc, it wasn't in Prelude for a while?
2023-10-16 22:59:12 +0200 <tomsmeding> ¯\_(ツ)_/¯
2023-10-16 22:59:19 +0200 <Inst> turns out it's easier to use foo <$> bar <*> baz because you can verticalize it more easily
2023-10-16 22:59:36 +0200 <Inst> looks way better, fits better if you're binding the result into something within do, etc
2023-10-16 22:59:37 +0200Pozyomka(~pyon@user/pyon)
2023-10-16 22:59:39 +0200 <EvanR> verticalization is not street jargon I know
2023-10-16 23:00:21 +0200 <tomsmeding> liftA2 foo bar
2023-10-16 23:00:21 +0200 <tomsmeding> baz
2023-10-16 23:00:37 +0200 <EvanR> good shot
2023-10-16 23:00:49 +0200tomsmeding. o O ( https://esolangs.org/wiki/Fish )
2023-10-16 23:00:51 +0200 <Inst> yeah but operators starting lines is a fairly common style
2023-10-16 23:01:05 +0200 <dolio> Applicatives have ordering. It's the order you write them in.
2023-10-16 23:01:25 +0200 <dolio> Applicatives are list-alike, and lists are ordered.
2023-10-16 23:01:54 +0200 <Inst> Concurrently, i.e, when the result comes back is unknown?
2023-10-16 23:02:05 +0200 <tomsmeding> dolio: the Applicative laws don't give guarantees about whether the effects of foo are evaluated before bar, or the other way round, in 'foo <*> bar', right?
2023-10-16 23:02:44 +0200 <monochrom> I don't think "Applicative is ordered" or "Applicative is unordered" has any meaning.
2023-10-16 23:03:07 +0200 <monochrom> If you know the actual instance, e.g., IO, then talk about it directly.
2023-10-16 23:03:21 +0200 <tomsmeding> and if you don't?
2023-10-16 23:03:45 +0200 <monochrom> Things like Tardis have shown that "order" is a tricky notion, even for Monad.
2023-10-16 23:04:02 +0200 <tomsmeding> hm, fair
2023-10-16 23:04:08 +0200 <tomsmeding> also Cont
2023-10-16 23:04:24 +0200 <dolio> Applicatives let you arrange things in sequences. What those sequences mean is open.
2023-10-16 23:04:37 +0200 <monochrom> And by the time it's Reader or (->), it's vanilla lazy evaluation again.
2023-10-16 23:05:30 +0200 <EvanR> <*> is infixl, : is infixr. So it's in the opposite order of list?
2023-10-16 23:05:36 +0200 <dolio> What monads add is nesting. f inside f instead of f beside f.
2023-10-16 23:06:22 +0200 <tomsmeding> EvanR: that's opposite associativity
2023-10-16 23:06:37 +0200 <monochrom> To the extent that the Applicative laws alone don't have a commutative law for liftA2, we agree.
2023-10-16 23:07:00 +0200 <monochrom> But some instances can have commutative laws or conditional commutative laws.
2023-10-16 23:07:33 +0200 <Inst> dolio: more, the ability to work with nesting
2023-10-16 23:07:36 +0200 <tomsmeding> it's funny talking about "order of effects" in Applicatives when the whole point about Applicative is that you explicitly get no language for talking about said order
2023-10-16 23:07:41 +0200 <Inst> join / flatten / mu
2023-10-16 23:07:46 +0200 <monochrom> Stepping back, this is what's wrong with using "plain English" to discuss programming.
2023-10-16 23:08:10 +0200 <monochrom> "order" has like a million unrelated meanings.
2023-10-16 23:08:35 +0200 <dolio> Lists aren't ordered. Only trees are ordered.
2023-10-16 23:09:15 +0200 <EvanR> > compare [1,2,3] [2,3,4]
2023-10-16 23:09:17 +0200 <lambdabot> LT
2023-10-16 23:09:52 +0200 <EvanR> > compare [1 :+ 1] [2 :+ 2]
2023-10-16 23:09:53 +0200 <lambdabot> error:
2023-10-16 23:09:53 +0200 <lambdabot> • No instance for (Ord (Complex Integer))
2023-10-16 23:09:53 +0200 <lambdabot> arising from a use of ‘compare’
2023-10-16 23:09:56 +0200 <EvanR> nvm
2023-10-16 23:10:05 +0200 <EvanR> lists aren't ordered
2023-10-16 23:10:10 +0200 <monochrom> Hell, s/to discuss programming// >:)
2023-10-16 23:10:52 +0200 <tomsmeding> monochrom: matches with a remark you made previously about people ;)
2023-10-16 23:11:03 +0200 <EvanR> plain English is doomed to failure. From now on we will only speak shakespearean
2023-10-16 23:11:13 +0200 <tomsmeding> Lojban
2023-10-16 23:11:26 +0200 <Inst> [whamlet|<p> Hello, world!</p>|]
2023-10-16 23:11:35 +0200 <darkling> EvanR: I believe you mean "henceforth", varlet!
2023-10-16 23:11:38 +0200 <Inst> oh, whoops
2023-10-16 23:12:15 +0200 <Inst> [whamlet|<p> To be, or not to be, that is the question </p>|]
2023-10-16 23:13:46 +0200 <monochrom> And reflecting to last night's conversation about type classes and their instances and their methods, a key point is that there are now two "membership" relations, not just one. If you assume just one, that explains getting confused.
2023-10-16 23:13:57 +0200 <monochrom> (All confusions are caused by wrong assumptions.)
2023-10-16 23:14:12 +0200cpressey(~cpressey@host-92-10-148-105.as13285.net) (Quit: Client closed)
2023-10-16 23:14:39 +0200 <monochrom> On one side, one membership relation is "Int is an instance of Eq". On the other side, the 2nd membership relation is "(==) is a method of Eq".
2023-10-16 23:15:12 +0200 <jumper> how and where would I use the bind operator? >>=, If I understood correctly, X >>= Y, X is bound to Y
2023-10-16 23:15:27 +0200 <monochrom> Until you accept that even in UML you can draw such a two-side diagram, harping the "plain English" word "member" is not going to help.
2023-10-16 23:16:13 +0200 <monochrom> You can use it like "getLine >>= putStrLn".
2023-10-16 23:16:31 +0200 <monochrom> It reads a line from stdin, then outputs it to stdout.
2023-10-16 23:16:54 +0200 <jumper> Wait, so it's simply an pipe?
2023-10-16 23:17:03 +0200 <EvanR> >> is an IO action combiner, sequentially combining two actions. But the first result is discarded
2023-10-16 23:17:09 +0200 <dolio> It's like reverse function application.
2023-10-16 23:17:10 +0200 <EvanR> >>= lets you use the first result
2023-10-16 23:17:24 +0200 <monochrom> It can do much more. That was just a basic example.
2023-10-16 23:17:54 +0200 <dolio> 'bind' presumably comes from the use where you do `m >>= \x -> ...`, where you're "binding" the result of m to the variable x.
2023-10-16 23:18:08 +0200 <jumper> But isn't getLine >>= putStrLn == putStrLn getLine ?
2023-10-16 23:18:15 +0200 <EvanR> it is not
2023-10-16 23:18:21 +0200 <dolio> The latter is a type error.
2023-10-16 23:18:24 +0200 <Inst> the latter is a type error
2023-10-16 23:18:29 +0200 <monochrom> It may or may not surprise you that [1,2,3] >>= replicate 5 can also have a meaning.
2023-10-16 23:19:05 +0200 <EvanR> :t putStrLn
2023-10-16 23:19:06 +0200 <lambdabot> String -> IO ()
2023-10-16 23:19:18 +0200 <monochrom> And with "plain human speak" being so bloody bendable, you may even call it "piping".
2023-10-16 23:19:27 +0200 <monochrom> > [1,2,3] >>= replicate 5
2023-10-16 23:19:28 +0200 <lambdabot> [1,1,1,1,1,2,2,2,2,2,3,3,3,3,3]
2023-10-16 23:19:47 +0200 <jumper> haskell: getLine >>= putStrLn, C: puts(gets());
2023-10-16 23:20:03 +0200__monty__(~toonn@user/toonn) (Quit: leaving)
2023-10-16 23:20:06 +0200 <monochrom> Well this is where C is sloppy and Haskell is more precise.
2023-10-16 23:20:26 +0200 <EvanR> putStrLn takes a String, not a function or an IO action
2023-10-16 23:20:26 +0200 <monochrom> "puts(gets())" is not supposed to make sense.
2023-10-16 23:20:31 +0200 <Inst> Which book are you working with again?
2023-10-16 23:20:33 +0200 <monochrom> At least, IMO.
2023-10-16 23:21:03 +0200 <jumper> monochrom: what you mean? I perfectly understand the nesting logic
2023-10-16 23:21:04 +0200 <monochrom> To be sure I have a selection bias. There is a reason I joined the Haskell community!
2023-10-16 23:21:16 +0200 <EvanR> jumper, do you understand the type mismatch
2023-10-16 23:21:46 +0200rawles(~rawles@user/rawles) (Textual IRC Client: www.textualapp.com)
2023-10-16 23:21:49 +0200 <jumper> EvanR: similar to datatype mismatches in C?
2023-10-16 23:22:04 +0200 <monochrom> Oh all of us understand the flawed logic of C or even in general of imperative programming.
2023-10-16 23:22:11 +0200 <monochrom> Doesn't mean we have to agree with it.
2023-10-16 23:22:31 +0200 <EvanR> you said putStrLn getLine, for that to work the type of getLine has to match the input type of function putStrLn
2023-10-16 23:22:38 +0200 <monochrom> I understand why thieves steal. They are still wrong.
2023-10-16 23:22:47 +0200 <jumper> EvanR: can I cast it? :)
2023-10-16 23:22:52 +0200 <Inst> :t getLine
2023-10-16 23:22:53 +0200 <lambdabot> IO String
2023-10-16 23:22:59 +0200 <EvanR> no and that's often wrong in C too
2023-10-16 23:23:13 +0200acidjnk_new(~acidjnk@p200300d6e72b933890137bb0a9c5386a.dip0.t-ipconnect.de) (Ping timeout: 252 seconds)
2023-10-16 23:23:33 +0200 <EvanR> it's like can I melt my lego bricks when they don't fit
2023-10-16 23:24:01 +0200 <EvanR> yes but it takes so much heat you burn yourself
2023-10-16 23:24:07 +0200 <jumper> does Haskell support void pointers?
2023-10-16 23:24:15 +0200 <geekosaur> jumper, if you're thinking in terms of casting then you're not getting it
2023-10-16 23:24:32 +0200 <geekosaur> really, do not try to treat Haskell as funny looking C, it won't work
2023-10-16 23:24:42 +0200 <monochrom> What do you need void pointers for?
2023-10-16 23:24:53 +0200 <geekosaur> @where cis194
2023-10-16 23:24:53 +0200 <lambdabot> <https://github.com/byorgey/haskell-course>,<https://www.seas.upenn.edu/~cis194/spring13/lectures.html>
2023-10-16 23:25:12 +0200 <monochrom> C offered them because C didn't have genericity. We can now do better. See Rust for example.
2023-10-16 23:25:28 +0200 <Inst> iirc, C / C++ experience, right?
2023-10-16 23:25:41 +0200 <geekosaur> it has to be like C or Python
2023-10-16 23:25:49 +0200 <monochrom> Yeah even in C++ you don't need void pointer any more.
2023-10-16 23:25:54 +0200 <geekosaur> jumper can't understand anything else, apparently
2023-10-16 23:26:03 +0200 <Inst> I think jumper said they learned C++11 via implementing it by C.
2023-10-16 23:26:14 +0200 <Inst> That has to be respected, because it's a hardcore way of learning C++
2023-10-16 23:26:15 +0200 <jumper> Inst: self learning
2023-10-16 23:26:23 +0200 <EvanR> implement haskell in C
2023-10-16 23:26:46 +0200 <mauke> one of the IOCCC winners is a haskell compiler :-)
2023-10-16 23:26:55 +0200 <monochrom> Perhaps read Hugs source code? It's a Haskell interpreter written in C.
2023-10-16 23:27:03 +0200 <monochrom> Hahaha that's epic.
2023-10-16 23:27:53 +0200 <monochrom> If pressed, I could write a toy Haskell implementation in C, but not to the point of meeting the IOCCC standard so that even I don't understand it. >:)
2023-10-16 23:28:44 +0200 <Inst> is this canonical?
2023-10-16 23:28:46 +0200 <Inst> https://github.com/haskell-implementations/hugs
2023-10-16 23:28:51 +0200 <mauke> jumper: are you familiar with javascript or promises/futures?
2023-10-16 23:29:32 +0200 <jumper> mauke: I haven't touched interpreted languages since python, JS background none existant, but I understand the syntax
2023-10-16 23:29:42 +0200 <monochrom> Inst: I think yes.
2023-10-16 23:30:09 +0200 <EvanR> if you only understand the concrete syntax of javascript, you don't understand javascript. Because it uses C syntax
2023-10-16 23:30:12 +0200 <monochrom> Oooohhhh this is going to be fun...
2023-10-16 23:30:29 +0200 <monochrom> Is math invented or discovered? Is Haskell compiled or interpreted? >:)
2023-10-16 23:31:11 +0200 <EvanR> languages keep using C syntax while being wildly different in various ways
2023-10-16 23:31:12 +0200 <mauke> is it possible to exceed the speed of c in a relativistic universe?
2023-10-16 23:31:27 +0200 <EvanR> different from C semantics
2023-10-16 23:31:33 +0200 <monochrom> Is it a half-empty glass or a half-full glass? Or is it half-empty and the other half is not even the right drink? >:)
2023-10-16 23:31:47 +0200 <monochrom> @quote monochrom speed
2023-10-16 23:31:47 +0200 <lambdabot> monochrom says: And so, I use formal logic all the time, and can still be very practical and speedy. This is contrary to most people's conventional wisdom. This is because they have only seen very
2023-10-16 23:31:47 +0200 <lambdabot> primitive formal logics, like if you have only seen assembly code, you think programming is undoable.
2023-10-16 23:31:51 +0200 <monochrom> err no
2023-10-16 23:31:55 +0200 <monochrom> @quote monochrom faster.than
2023-10-16 23:31:55 +0200 <lambdabot> monochrom says: einstein's theory implies that haskell cannot be faster than c
2023-10-16 23:32:49 +0200 <Inst> jumper, but, sorry, just want a bit more information, which book / course are you using to pick up Haskell?
2023-10-16 23:33:03 +0200 <jumper> Inst: none
2023-10-16 23:33:11 +0200 <mauke> jumper: sadly that doesn't give you the right mindset for a shortcut to IO semantics
2023-10-16 23:33:50 +0200 <jumper> Inst: reading Haskell documentation is usually the best source
2023-10-16 23:34:28 +0200 <mauke> conversely, reading Haskell source is often the best available documentation :-(
2023-10-16 23:34:36 +0200 <Inst> Wow, got to admire your courage.
2023-10-16 23:34:44 +0200 <monochrom> Wait, new Data.Functor has an unzip?!
2023-10-16 23:34:58 +0200 <EvanR> :t unzip
2023-10-16 23:34:59 +0200 <lambdabot> [(a, b)] -> ([a], [b])
2023-10-16 23:35:09 +0200phma(~phma@host-67-44-208-16.hnremote.net) (Read error: Connection reset by peer)
2023-10-16 23:35:30 +0200 <EvanR> Functor f => f (a,b) -> (f a, f b)?
2023-10-16 23:35:34 +0200phma(~phma@2001:5b0:210d:ff48:373f:c0e:f95b:a8f5)
2023-10-16 23:35:46 +0200 <monochrom> unzip :: Functor f => f (a, b) -> (f a, f b)
2023-10-16 23:35:54 +0200 <monochrom> Yeah. Interesting.
2023-10-16 23:35:55 +0200 <Inst> jumper; what do you mean by Haskell source?
2023-10-16 23:36:07 +0200 <EvanR> slowly we approach categorical linear algebra
2023-10-16 23:37:09 +0200 <EvanR> I'm surprised because unzip is one of those functions I would expect people to say don't generalize think of the noobs
2023-10-16 23:37:10 +0200 <jumper> Inst: Haskell wiki? Haskell.org?
2023-10-16 23:37:35 +0200 <jumper> Inst: The same way you learn assembler, manuals
2023-10-16 23:37:51 +0200 <monochrom> Prelude's unzip is still the list one.
2023-10-16 23:38:03 +0200 <EvanR> oh ok
2023-10-16 23:38:09 +0200 <EvanR> noobs protected
2023-10-16 23:38:52 +0200 <Inst> The problem with that is that you usually want to understand at least 50-60% of what you're reading
2023-10-16 23:39:08 +0200 <Inst> then try to guess the meaning of at least 30% of the remainder
2023-10-16 23:39:14 +0200 <Inst> if you start with insufficient reference points, it's much harde
2023-10-16 23:39:15 +0200 <Inst> *r
2023-10-16 23:39:26 +0200 <EvanR> Inst, are you trying to argue against reading haskell documentation
2023-10-16 23:39:34 +0200 <EvanR> is this a Nick thing again
2023-10-16 23:39:43 +0200 <jumper> Inst: sure, but that's where small examples come in, semantic dissection
2023-10-16 23:39:58 +0200 <mauke> :t (,) <$> (fst <$>) <*> (snd <$>)
2023-10-16 23:39:59 +0200 <lambdabot> Functor f => f (b1, b2) -> (f b1, f b2)
2023-10-16 23:40:26 +0200 <Inst> what i really want to ask is, how far do you understand typeclasses?
2023-10-16 23:40:48 +0200 <monochrom> 99.9% of such small examples and hypotheses can be trivially tested on ghci and you need no human to help.
2023-10-16 23:41:03 +0200acidjnk_new(~acidjnk@p200300d6e72b933890137bb0a9c5386a.dip0.t-ipconnect.de)
2023-10-16 23:42:13 +0200 <Inst> but if you're going that approach:
2023-10-16 23:42:14 +0200 <Inst> https://downloads.haskell.org/ghc/latest/docs/users_guide/
2023-10-16 23:42:25 +0200 <jumper> Already reading it
2023-10-16 23:42:31 +0200 <mauke> https://www.haskell.org/onlinereport/haskell2010/ if you're hardcore
2023-10-16 23:42:31 +0200 <Inst> https://www.haskell.org/onlinereport/haskell2010/
2023-10-16 23:43:12 +0200 <monochrom> The GHC User's Guide assumes that you already know Haskell.
2023-10-16 23:43:18 +0200 <EvanR> https://www.haskell.org/tutorial/ >:)
2023-10-16 23:43:23 +0200 <tomsmeding> none of these resources teach you functional programming
2023-10-16 23:43:37 +0200 <mauke> EvanR: hah, exactly what I expected behind that url :-)
2023-10-16 23:43:49 +0200Vajb(~Vajb@207.61.167.122)
2023-10-16 23:43:53 +0200 <tomsmeding> ah the tutorial might, though iirc "gentle" is not quite accurate
2023-10-16 23:43:54 +0200 <Inst> no, but it's really impressive if he can pull it off and just learn some dialect of Haskell from the docs alone
2023-10-16 23:43:59 +0200 <monochrom> I did learn from the Gentle Introduction.
2023-10-16 23:44:14 +0200 <monochrom> Actually I found it gentle too.
2023-10-16 23:44:31 +0200 <tomsmeding> the language specification and the GHC user's guide are very bad places to start if you've never done any functional programming
2023-10-16 23:44:37 +0200 <monochrom> Sure, if you have presumptions and prejudice, it is not gentle.
2023-10-16 23:44:53 +0200tomsmedinghas never read the "gentle introduction"
2023-10-16 23:45:05 +0200 <tomsmeding> so no opinion there
2023-10-16 23:45:11 +0200 <monochrom> But in the same way, if you make FP presumptions then go learn C, no C tutorial will be gentle either.
2023-10-16 23:45:27 +0200 <Inst> EvanR: I just was scared for jumper, but he seems really hardcore, learned C++ by implementing it via C, and now he wants to learn Haskell from the Haskell Report
2023-10-16 23:45:41 +0200 <tomsmeding> that ain't going to work
2023-10-16 23:45:41 +0200 <EvanR> I have no issue with the haskell report
2023-10-16 23:45:50 +0200 <Inst> Let him try
2023-10-16 23:45:56 +0200 <Inst> if he succeeds, he's a hero, let's celebrate him
2023-10-16 23:45:57 +0200 <EvanR> some people just like reading the material
2023-10-16 23:46:11 +0200 <EvanR> and don't need training wheels, or NeoHaskell, or whatever
2023-10-16 23:46:14 +0200 <Inst> if he fails, let's patch him up
2023-10-16 23:46:45 +0200 <EvanR> I wish other languages had a report
2023-10-16 23:46:51 +0200 <mauke> I learned C++ by reading The C++ Programming Language front to back
2023-10-16 23:46:54 +0200 <dolio> I think the gentle introduction kind of assumes you're already somewhat familiar with functional programming.
2023-10-16 23:47:00 +0200 <dolio> And it says so.
2023-10-16 23:47:03 +0200 <mauke> sadly it's all out of date now :-)
2023-10-16 23:47:04 +0200 <EvanR> yes
2023-10-16 23:47:05 +0200 <Inst> mauke: really?
2023-10-16 23:47:09 +0200 <monochrom> :(
2023-10-16 23:47:34 +0200 <monochrom> https://www.vex.net/~trebla/humour/programming_books.html >:)
2023-10-16 23:47:40 +0200 <EvanR> A gentle introduction assumes some exposure to functional programming already, and is somewhat out of date
2023-10-16 23:47:41 +0200 <mauke> Inst: pretty much, but I'd seen some examples of C++ features before
2023-10-16 23:48:07 +0200 <EvanR> and the CSS + banner image are not attractive!
2023-10-16 23:48:13 +0200 <EvanR> critical issues
2023-10-16 23:49:27 +0200acidjnk_new(~acidjnk@p200300d6e72b933890137bb0a9c5386a.dip0.t-ipconnect.de) (Ping timeout: 240 seconds)
2023-10-16 23:50:59 +0200 <mauke> if you know how C++ vtables are implemented (or can be implemented in C), then typeclasses as dictionary passing shouldn't be all that unfamiliar
2023-10-16 23:53:11 +0200machinedgod(~machinedg@d198-53-218-113.abhsia.telus.net) (Ping timeout: 260 seconds)
2023-10-16 23:54:46 +0200 <jumper> EvanR: yeah I got it, functions calls in haskell don't really work the same way as in C
2023-10-16 23:56:18 +0200 <mauke> true, but unrelated to the putStrLn getLine thing. that really is just a type mismatch
2023-10-16 23:56:43 +0200 <EvanR> putStrLn wants a String but getLine is not a String, it's an IO action
2023-10-16 23:57:01 +0200 <Inst> https://www.haskell.org/onlinereport/haskell2010/haskellch4.html#x10-750004.3 <-- typeclasses
2023-10-16 23:57:11 +0200 <mauke> it's semi-analogous to puts(gets) in C, but the difference is that C has (or at least had :-) a gets function that you could actually call
2023-10-16 23:57:15 +0200 <Inst> >>= is defined in a typeclass
2023-10-16 23:57:30 +0200 <mauke> getLine isn't a function at all
2023-10-16 23:57:31 +0200 <EvanR> Inst, I don't think anyone was asking about type classes today
2023-10-16 23:58:00 +0200 <EvanR> you can consider >>= to be an IO combiner for the purposes of getLine >>= putStrLn
2023-10-16 23:58:00 +0200 <Inst> yeah, i'll back off