Home liberachat/#haskell: Logs Calendar

Logs on 2021-09-21 (liberachat/#haskell)

00:03:33 <Cale> There's gi-gtk-hs, which has seemed pretty usable. I've barely been using it though, really, since we've just been drawing most of our UI with cairo :P
00:03:50 <sclv> and fltkhs too
00:04:06 <sclv> i don't consider the gtk stuff super cross platform based on past experience, but things may be substantially better now
00:04:40 <sm> monomer is the latest contender
00:05:02 <Cale> Coming at it from another angle, reflex-dom is another option
00:05:25 <Cajun> i tried to use monomer a while back and it was a bit broken to say the least
00:05:48 <sclv> hrm, hadn't seen it before, might have missed some announcements on it? on the face of it, claims a nice set of features
00:05:52 <sm> darn I was just thinking "no-one has panned it yet"
00:06:05 <sm> Cajun: do you mean, after you got it installed ?
00:06:17 <sclv> 😂
00:06:23 × vysn quits (~vysn@user/vysn) (Remote host closed the connection)
00:06:37 <Cale> (We use it to make apps for the Web, iOS and Android mobile devices from the same codebase, which are the three platforms anyone cares about these days.)
00:06:44 <Cajun> well that may not entirely be true, it seemed to be tuned for windows (it couldnt find the library on linux) and one of the dev's pushes to a library wasnt fully accepted yet
00:06:46 <sm> https://www.reddit.com/r/haskell/comments/p12pjs/ann_monomer_a_gui_library_for_haskell/, sclv
00:07:20 <Cajun> i havent checked on it since, but i really do hope it works well
00:07:25 <sm> ah, that's small stuff
00:07:50 <Cajun> small stuff that made it a pita to deal with, so i just dropped it and promised myself to try it again at a later date
00:08:07 <sm> sure, same here (it doesn't build on m1 yet)
00:08:18 <sm> s/small/fixable/
00:09:41 × Gurkenglas quits (~Gurkengla@dslb-002-207-014-195.002.207.pools.vodafone-ip.de) (Ping timeout: 264 seconds)
00:09:44 × Null_A quits (~null_a@2601:645:8700:2290:6daa:6a79:97ab:557) (Remote host closed the connection)
00:10:19 Null_A joins (~null_a@2601:645:8700:2290:6daa:6a79:97ab:557)
00:10:57 alx741 joins (~alx741@186.178.109.159)
00:11:02 <sclv> reading through monomer's docs i'm reminded again that the "elm architecture" seems to be just like a rebranded mvc
00:11:31 <sclv> which i didn't mind when it was in elm, but now seeing it as a term of the art in other contexts is frying my head a bit
00:11:58 Guest57 joins (~Guest57@134.3.172.96)
00:12:27 hexfive joins (~eric@50.35.83.177)
00:12:41 × merijn quits (~merijn@83-160-49-249.ip.xs4all.nl) (Ping timeout: 264 seconds)
00:13:20 × jespada quits (~jespada@2803:9800:9842:7a62:edd5:5e74:3ec2:1b19) (Quit: My MacBook has gone to sleep. ZZZzzz…)
00:17:58 × Guest57 quits (~Guest57@134.3.172.96) (Quit: Client closed)
00:20:04 × Null_A quits (~null_a@2601:645:8700:2290:6daa:6a79:97ab:557) (Remote host closed the connection)
00:20:40 Null_A joins (~null_a@2601:645:8700:2290:6daa:6a79:97ab:557)
00:22:36 yauhsien joins (~yauhsien@118-167-47-202.dynamic-ip.hinet.net)
00:22:49 × hexfive quits (~eric@50.35.83.177) (Quit: WeeChat 3.0.1)
00:25:04 × Igloo quits (~ian@matrix.chaos.earth.li) (Ping timeout: 252 seconds)
00:26:50 × yauhsien quits (~yauhsien@118-167-47-202.dynamic-ip.hinet.net) (Ping timeout: 252 seconds)
00:29:28 × FinnElija quits (~finn_elij@user/finn-elija/x-0085643) (Ping timeout: 252 seconds)
00:30:34 × Null_A quits (~null_a@2601:645:8700:2290:6daa:6a79:97ab:557) (Remote host closed the connection)
00:31:07 FinnElija joins (~finn_elij@user/finn-elija/x-0085643)
00:31:08 Null_A joins (~null_a@2601:645:8700:2290:6daa:6a79:97ab:557)
00:37:18 maroloccio joins (~marolocci@89-172-7-22.adsl.net.t-com.hr)
00:38:45 Izem parts (~Izem@bras-base-london1483w-grc-31-74-12-158-179.dsl.bell.ca) (Good Bye)
00:40:54 × Null_A quits (~null_a@2601:645:8700:2290:6daa:6a79:97ab:557) (Remote host closed the connection)
00:41:28 Null_A joins (~null_a@2601:645:8700:2290:6daa:6a79:97ab:557)
00:41:39 Igloo joins (~ian@matrix.chaos.earth.li)
00:42:37 <justsomeguy> I felt the same way when reading about "stateless" "declarative" configuration management platforms.
00:43:53 × cuz quits (~user@2601:182:cc02:8b0:88fe:7ac8:b1af:1fac) (Ping timeout: 264 seconds)
00:45:12 <Cale> You really need a way to structure the state in large interactive applications a bit better. Having the top level need to "know about" everything in the entire application is really not okay past a certain point.
00:46:25 <Cale> I think the right thing is for the accumulation of any given piece of state to happen just above every part of the application that cares about it, and no higher up than that.
00:47:03 <Cale> At least, that's a decent rule of thumb.
00:50:00 <Cale> "Everything potentially depends on everything else" is still bad, even if you can describe the relationship through time using a pure function.
00:51:14 × Null_A quits (~null_a@2601:645:8700:2290:6daa:6a79:97ab:557) (Remote host closed the connection)
00:51:48 Null_A joins (~null_a@2601:645:8700:2290:6daa:6a79:97ab:557)
00:57:21 × gioyik quits (~gioyik@gateway/tor-sasl/gioyik) (Ping timeout: 276 seconds)
01:01:25 lavaman joins (~lavaman@98.38.249.169)
01:01:34 × Null_A quits (~null_a@2601:645:8700:2290:6daa:6a79:97ab:557) (Remote host closed the connection)
01:02:08 Null_A joins (~null_a@2601:645:8700:2290:6daa:6a79:97ab:557)
01:02:43 × Guest4814 quits (~chris@81.96.113.213) (Remote host closed the connection)
01:03:40 chris joins (~chris@81.96.113.213)
01:03:44 chris is now known as Guest8879
01:06:46 <sm> +1!
01:08:05 × Guest8879 quits (~chris@81.96.113.213) (Ping timeout: 252 seconds)
01:11:16 × waleee quits (~waleee@h-98-128-228-119.na.cust.bahnhof.se) (Ping timeout: 252 seconds)
01:11:29 × xff0x quits (~xff0x@83.236.31.114) (Ping timeout: 264 seconds)
01:11:50 × favonia quits (~favonia@user/favonia) (Ping timeout: 246 seconds)
01:11:54 × Null_A quits (~null_a@2601:645:8700:2290:6daa:6a79:97ab:557) (Remote host closed the connection)
01:12:28 Null_A joins (~null_a@2601:645:8700:2290:6daa:6a79:97ab:557)
01:13:16 xff0x joins (~xff0x@2001:1a81:53a2:cb00:c07c:d089:8b2f:814c)
01:22:13 × Null_A quits (~null_a@2601:645:8700:2290:6daa:6a79:97ab:557) (Remote host closed the connection)
01:22:30 × alx741 quits (~alx741@186.178.109.159) (Quit: alx741)
01:22:47 Null_A joins (~null_a@2601:645:8700:2290:6daa:6a79:97ab:557)
01:23:49 gioyik joins (~gioyik@gateway/tor-sasl/gioyik)
01:25:08 × cheater quits (~Username@user/cheater) (Ping timeout: 246 seconds)
01:26:33 neurocyte0133 joins (~neurocyte@212.232.95.106)
01:26:33 × neurocyte0133 quits (~neurocyte@212.232.95.106) (Changing host)
01:26:33 neurocyte0133 joins (~neurocyte@user/neurocyte)
01:28:54 × neurocyte013 quits (~neurocyte@user/neurocyte) (Ping timeout: 260 seconds)
01:28:54 neurocyte0133 is now known as neurocyte013
01:30:30 × gioyik quits (~gioyik@gateway/tor-sasl/gioyik) (Ping timeout: 276 seconds)
01:31:55 cheater joins (~Username@user/cheater)
01:32:33 × Null_A quits (~null_a@2601:645:8700:2290:6daa:6a79:97ab:557) (Remote host closed the connection)
01:33:07 Null_A joins (~null_a@2601:645:8700:2290:6daa:6a79:97ab:557)
01:33:52 <justsomeguy> I think I've just started keeping a list of maintenance programmer adages, starting with your quote :^)
01:41:49 × brettgilio quits (~brettgili@x-node.gq) (Quit: Leaving...)
01:42:53 × Null_A quits (~null_a@2601:645:8700:2290:6daa:6a79:97ab:557) (Remote host closed the connection)
01:42:56 brettgilio joins (~brettgili@x-node.gq)
01:43:28 Null_A joins (~null_a@2601:645:8700:2290:6daa:6a79:97ab:557)
01:53:14 × Null_A quits (~null_a@2601:645:8700:2290:6daa:6a79:97ab:557) (Remote host closed the connection)
01:53:50 Null_A joins (~null_a@2601:645:8700:2290:6daa:6a79:97ab:557)
01:58:27 [itchyjunk] joins (~itchyjunk@user/itchyjunk/x-7353470)
02:00:52 yauhsien joins (~yauhsien@118-167-47-202.dynamic-ip.hinet.net)
02:03:06 favonia joins (~favonia@user/favonia)
02:06:51 × Null_A quits (~null_a@2601:645:8700:2290:6daa:6a79:97ab:557) (Remote host closed the connection)
02:09:06 merijn joins (~merijn@83-160-49-249.ip.xs4all.nl)
02:09:31 × Jonno_FTW quits (~come@api.carswap.me) (Changing host)
02:09:31 Jonno_FTW joins (~come@user/jonno-ftw/x-0835346)
02:10:48 × azimut_ quits (~azimut@gateway/tor-sasl/azimut) (Ping timeout: 276 seconds)
02:16:41 × yinghua quits (~yinghua@2800:2121:1400:1db:3d91:483:36a2:ad4f) (Quit: Leaving)
02:16:48 × td_ quits (~td@muedsl-82-207-238-087.citykom.de) (Ping timeout: 268 seconds)
02:18:20 td_ joins (~td@muedsl-82-207-238-060.citykom.de)
02:18:50 × tommd quits (~tommd@75-164-130-101.ptld.qwest.net) (Ping timeout: 260 seconds)
02:19:01 chris joins (~chris@81.96.113.213)
02:19:05 chris is now known as Guest3810
02:20:11 × Guest3810 quits (~chris@81.96.113.213) (Remote host closed the connection)
02:23:44 azimut joins (~azimut@gateway/tor-sasl/azimut)
02:27:11 × lavaman quits (~lavaman@98.38.249.169) (Remote host closed the connection)
02:30:02 × favonia quits (~favonia@user/favonia) (Ping timeout: 252 seconds)
02:36:41 × wroathe quits (~wroathe@user/wroathe) (Ping timeout: 264 seconds)
02:37:40 × Katarushisu quits (~Katarushi@cpc147334-finc20-2-0-cust27.4-2.cable.virginm.net) (Ping timeout: 240 seconds)
02:39:14 xiongxin joins (~quassel@119.123.103.94)
02:42:19 chris joins (~chris@81.96.113.213)
02:42:23 chris is now known as Guest8457
02:43:17 × merijn quits (~merijn@83-160-49-249.ip.xs4all.nl) (Ping timeout: 264 seconds)
02:43:54 × yauhsien quits (~yauhsien@118-167-47-202.dynamic-ip.hinet.net) (Remote host closed the connection)
02:44:53 × FinnElija quits (~finn_elij@user/finn-elija/x-0085643) (Ping timeout: 252 seconds)
02:45:29 yauhsien joins (~yauhsien@118-167-47-202.dynamic-ip.hinet.net)
02:46:29 FinnElija joins (~finn_elij@user/finn-elija/x-0085643)
02:50:23 × yauhsien quits (~yauhsien@118-167-47-202.dynamic-ip.hinet.net) (Ping timeout: 252 seconds)
02:53:10 wroathe joins (~wroathe@c-68-54-25-135.hsd1.mn.comcast.net)
02:53:10 × wroathe quits (~wroathe@c-68-54-25-135.hsd1.mn.comcast.net) (Changing host)
02:53:10 wroathe joins (~wroathe@user/wroathe)
02:54:37 Katarushisu joins (~Katarushi@cpc147334-finc20-2-0-cust27.4-2.cable.virginm.net)
02:57:41 × wroathe quits (~wroathe@user/wroathe) (Ping timeout: 264 seconds)
02:57:41 lavaman joins (~lavaman@98.38.249.169)
02:58:22 gioyik joins (~gioyik@gateway/tor-sasl/gioyik)
03:02:29 × lavaman quits (~lavaman@98.38.249.169) (Ping timeout: 264 seconds)
03:06:53 × MQ-17J quits (~MQ-17J@d192-24-122-179.try.wideopenwest.com) (Read error: Connection reset by peer)
03:07:14 MQ-17J joins (~MQ-17J@d192-24-122-179.try.wideopenwest.com)
03:11:53 × hiruji` quits (~hiruji@2606:6080:1001:f:ed79:9361:ea0e:3e88) (Ping timeout: 246 seconds)
03:14:24 Null_A joins (~null_a@2601:645:8700:2290:6daa:6a79:97ab:557)
03:15:23 Izem joins (~Izem@bras-base-london1483w-grc-31-74-12-158-179.dsl.bell.ca)
03:16:57 × statusbot quits (~statusbot@ec2-34-198-122-184.compute-1.amazonaws.com) (Read error: Connection reset by peer)
03:17:03 statusbot1 joins (~statusbot@ec2-34-198-122-184.compute-1.amazonaws.com)
03:17:29 wroathe joins (~wroathe@user/wroathe)
03:19:58 × raehik quits (~raehik@cpc95906-rdng25-2-0-cust156.15-3.cable.virginm.net) (Ping timeout: 252 seconds)
03:22:59 cjb41988 joins (~cjbayliss@user/cjb)
03:23:20 × cjb41988 quits (~cjbayliss@user/cjb) (Client Quit)
03:24:08 × Null_A quits (~null_a@2601:645:8700:2290:6daa:6a79:97ab:557) (Remote host closed the connection)
03:24:43 Null_A joins (~null_a@2601:645:8700:2290:6daa:6a79:97ab:557)
03:24:50 cjb84397 joins (~cjbayliss@user/cjb)
03:25:15 cjb is now known as Guest2446
03:25:15 cjb84397 is now known as cjb
03:25:16 × Guest2446 quits (~cjbayliss@user/cjb) (Ping timeout: 260 seconds)
03:26:00 wei2912 joins (~wei2912@112.199.250.21)
03:32:37 yauhsien joins (~yauhsien@118-167-47-202.dynamic-ip.hinet.net)
03:32:57 × justsomeguy quits (~justsomeg@user/justsomeguy) (Quit: WeeChat 3.2)
03:34:29 × Null_A quits (~null_a@2601:645:8700:2290:6daa:6a79:97ab:557) (Remote host closed the connection)
03:35:03 Null_A joins (~null_a@2601:645:8700:2290:6daa:6a79:97ab:557)
03:35:17 hiruji joins (~hiruji@user/hiruji)
03:37:17 × yauhsien quits (~yauhsien@118-167-47-202.dynamic-ip.hinet.net) (Ping timeout: 264 seconds)
03:38:07 × juhp quits (~juhp@bb42-60-204-249.singnet.com.sg) (Ping timeout: 265 seconds)
03:39:53 × machinedgod quits (~machinedg@135-23-192-217.cpe.pppoe.ca) (Ping timeout: 246 seconds)
03:43:48 Izem parts (~Izem@bras-base-london1483w-grc-31-74-12-158-179.dsl.bell.ca) (Good Bye)
03:46:03 × [itchyjunk] quits (~itchyjunk@user/itchyjunk/x-7353470) (Remote host closed the connection)
03:46:16 favonia joins (~favonia@user/favonia)
03:47:16 × Null_A quits (~null_a@2601:645:8700:2290:6daa:6a79:97ab:557) (Remote host closed the connection)
03:47:50 Null_A joins (~null_a@2601:645:8700:2290:6daa:6a79:97ab:557)
03:51:53 × Guest8457 quits (~chris@81.96.113.213) (Remote host closed the connection)
03:55:48 sagax joins (~sagax_nb@user/sagax)
03:57:29 neo1 joins (~neo3@cpe-292712.ip.primehome.com)
03:57:34 × zebrag quits (~chris@user/zebrag) (Quit: Konversation terminated!)
03:57:37 × Null_A quits (~null_a@2601:645:8700:2290:6daa:6a79:97ab:557) (Remote host closed the connection)
03:58:10 Null_A joins (~null_a@2601:645:8700:2290:6daa:6a79:97ab:557)
04:03:16 Izem joins (~Izem@bras-base-london1483w-grc-31-74-12-158-179.dsl.bell.ca)
04:07:56 × Null_A quits (~null_a@2601:645:8700:2290:6daa:6a79:97ab:557) (Remote host closed the connection)
04:08:31 Null_A joins (~null_a@2601:645:8700:2290:6daa:6a79:97ab:557)
04:14:51 × Guest372 quits (~xxx@47.245.54.240) (Remote host closed the connection)
04:15:58 × albet70 quits (~xxx@2400:8902::f03c:92ff:fe60:98d8) (Remote host closed the connection)
04:15:58 Guest372 joins (~xxx@47.245.54.240)
04:17:05 albet70 joins (~xxx@2400:8902::f03c:92ff:fe60:98d8)
04:19:34 × slowButPresent quits (~slowButPr@user/slowbutpresent) (Quit: leaving)
04:19:53 × maroloccio quits (~marolocci@89-172-7-22.adsl.net.t-com.hr) (Ping timeout: 264 seconds)
04:21:50 maroloccio joins (~marolocci@93-142-92-177.adsl.net.t-com.hr)
04:24:08 ubert joins (~Thunderbi@77.119.204.226.wireless.dyn.drei.com)
04:25:15 × Null_A quits (~null_a@2601:645:8700:2290:6daa:6a79:97ab:557) (Remote host closed the connection)
04:25:49 Null_A joins (~null_a@2601:645:8700:2290:6daa:6a79:97ab:557)
04:30:33 × gioyik quits (~gioyik@gateway/tor-sasl/gioyik) (Ping timeout: 276 seconds)
04:33:05 × doyougnu quits (~user@c-73-25-202-122.hsd1.or.comcast.net) (Ping timeout: 264 seconds)
04:35:35 × Null_A quits (~null_a@2601:645:8700:2290:6daa:6a79:97ab:557) (Remote host closed the connection)
04:36:05 × xiongxin quits (~quassel@119.123.103.94) (Ping timeout: 264 seconds)
04:36:10 Null_A joins (~null_a@2601:645:8700:2290:6daa:6a79:97ab:557)
04:39:38 merijn joins (~merijn@83-160-49-249.ip.xs4all.nl)
04:44:31 × shriekingnoise quits (~shrieking@186.137.144.80) (Quit: Quit)
04:45:56 × Null_A quits (~null_a@2601:645:8700:2290:6daa:6a79:97ab:557) (Remote host closed the connection)
04:46:30 Null_A joins (~null_a@2601:645:8700:2290:6daa:6a79:97ab:557)
04:48:02 lavaman joins (~lavaman@98.38.249.169)
04:49:20 <Izem> Are the items in parentheses sections? `showsTree (Branch l r) = ('<':) . showsTree l . ('|':) . showsTree r . ('>':)`
04:50:10 <awpr> yes, operator sections of `(:)`
04:50:59 <awpr> they could also be replaced with `showChar '<'`, for example
04:51:23 × wroathe quits (~wroathe@user/wroathe) (Ping timeout: 252 seconds)
04:52:37 xiongxin joins (~quassel@119.123.103.94)
04:52:53 × lavaman quits (~lavaman@98.38.249.169) (Ping timeout: 264 seconds)
04:56:03 × flouflou quits (~flouflou@modemcable032.110-177-173.mc.videotron.ca) (Quit: WeeChat 3.2)
04:56:16 × Null_A quits (~null_a@2601:645:8700:2290:6daa:6a79:97ab:557) (Remote host closed the connection)
04:56:50 Null_A joins (~null_a@2601:645:8700:2290:6daa:6a79:97ab:557)
04:57:05 yauhsien joins (~yauhsien@118-167-47-202.dynamic-ip.hinet.net)
04:59:16 <jle`> Izem: if it's easier to see, you can write it as ('<' :) . showsTree l . ('|' :) . showsTree r . ('>' :)
04:59:49 <Izem> yeah, good call
05:00:08 <Izem> (in this case not much difference because my client does not use monospace characters)
05:00:19 <jle`> i'll admit the '<': four symbols in a row did throw me off
05:00:31 <jle`> despite writing haskell for a while now
05:04:48 <Izem> I'll take a note when I write "Elements of Style" for Haskell ;)
05:05:44 × Izem quits (~Izem@bras-base-london1483w-grc-31-74-12-158-179.dsl.bell.ca) (Quit: Izem)
05:06:36 × Null_A quits (~null_a@2601:645:8700:2290:6daa:6a79:97ab:557) (Remote host closed the connection)
05:07:09 Null_A joins (~null_a@2601:645:8700:2290:6daa:6a79:97ab:557)
05:07:17 × yauhsien quits (~yauhsien@118-167-47-202.dynamic-ip.hinet.net) (Remote host closed the connection)
05:07:43 wroathe joins (~wroathe@c-68-54-25-135.hsd1.mn.comcast.net)
05:07:43 × wroathe quits (~wroathe@c-68-54-25-135.hsd1.mn.comcast.net) (Changing host)
05:07:43 wroathe joins (~wroathe@user/wroathe)
05:08:50 mikoto-chan joins (~mikoto-ch@ip-83-134-2-136.dsl.scarlet.be)
05:08:53 Guest68 joins (~Guest68@103.121.152.207)
05:12:17 × wroathe quits (~wroathe@user/wroathe) (Ping timeout: 252 seconds)
05:13:56 × merijn quits (~merijn@83-160-49-249.ip.xs4all.nl) (Ping timeout: 252 seconds)
05:21:18 gioyik joins (~gioyik@gateway/tor-sasl/gioyik)
05:26:53 × Null_A quits (~null_a@2601:645:8700:2290:6daa:6a79:97ab:557) (Remote host closed the connection)
05:27:27 Null_A joins (~null_a@2601:645:8700:2290:6daa:6a79:97ab:557)
05:31:00 × gioyik quits (~gioyik@gateway/tor-sasl/gioyik) (Ping timeout: 276 seconds)
05:35:01 × cjb quits (~cjbayliss@user/cjb) ()
05:37:12 × Null_A quits (~null_a@2601:645:8700:2290:6daa:6a79:97ab:557) (Remote host closed the connection)
05:37:38 juhp joins (~juhp@128.106.188.220)
05:37:46 Null_A joins (~null_a@2601:645:8700:2290:6daa:6a79:97ab:557)
05:44:11 <Axman6> > let (<') a b = a <> b in "hello"<'" "<'"world"
05:44:13 <lambdabot> <hint>:1:8: error: parse error on input ‘)’
05:44:14 × tzh quits (~tzh@c-24-21-73-154.hsd1.wa.comcast.net) (Quit: zzz)
05:44:44 <Axman6> pretty happy that didn't work tbh
05:45:39 <ldlework> > let (<:) a b = a < b in "hello" <: " " <: "world"
05:45:40 <lambdabot> error:
05:45:40 <lambdabot> • Couldn't match expected type ‘Bool’ with actual type ‘[Char]’
05:45:40 <lambdabot> • In the second argument of ‘(<:)’, namely ‘"world"’
05:46:18 <ldlework> > let (:<<) a b = a < b in "hello" :<< " " :<< "world"
05:46:20 <lambdabot> error:
05:46:20 <lambdabot> Not in scope: data constructor ‘:<<’
05:46:20 <lambdabot> Perhaps you meant one of these:
05:46:26 ldlework shrugs
05:46:44 <ldlework> oops
05:46:52 <ldlework> > let (:<<) a b = a <> b in "hello" :<< " " :<< "world"
05:46:53 <lambdabot> error:
05:46:53 <lambdabot> Not in scope: data constructor ‘:<<’
05:46:53 <lambdabot> Perhaps you meant one of these:
05:46:57 ldlework shrugs
05:47:03 <Axman6> can't start functions with :
05:47:13 <Axman6> only constructors
05:47:21 <ldlework> > let (<<:) a b = a <> b in "hello" <<: " " <<: "world"
05:47:22 <lambdabot> "hello world"
05:47:26 <ldlework> \o/
05:47:45 <Axman6> stop making the C++ devs feel comfortable
05:48:06 <ldlework> a friend of mine was dissing haskell because of all the wierd operators
05:48:19 <ldlework> and i'm like, dude, they're just functions, with non-alphanumeric names, that can be called infix
05:48:27 <ldlework> eventually he reduced his argument to "the names are dumb"
05:48:39 <ldlework> hehe
05:48:59 takuan joins (~takuan@178-116-218-225.access.telenet.be)
05:50:32 <awpr> tbf some of the names can get pretty crazy... `<<%@~` is a real operator in `lens`
05:51:08 <Axman6> but is a completely consistent operator, and I can probably figure out what it does even without its type
05:51:09 <awpr> I'm sure it means something if you've learned the symbolic etymology of the lens operators, but I haven't
05:51:13 × Null_A quits (~null_a@2601:645:8700:2290:6daa:6a79:97ab:557) (Remote host closed the connection)
05:51:40 <awpr> from scrolling I've gathered the @ is an indexed variant
05:51:41 × mikoto-chan quits (~mikoto-ch@ip-83-134-2-136.dsl.scarlet.be) (Ping timeout: 264 seconds)
05:51:47 Null_A joins (~null_a@2601:645:8700:2290:6daa:6a79:97ab:557)
05:51:58 <Axman6> ~ means apply a function, @ I think means apply to an indexed lens, and I thing << means return the value before the function was applied that the optic pointed to
05:52:16 <Axman6> % :t (<<%@~)
05:52:16 <yahb> Axman6: Over (Indexed i) ((,) a) s t a b -> (i -> a -> b) -> s -> (a, t)
05:53:37 <Axman6> yep - an indexed lens pointing to an a, a function whicht akes the index and the a and produces a b, that b is set in s to give a t and the original a is returned. Generalised x++ where you can choose what ++ is and change the type
05:54:27 <Axman6> jackdk will remember the day I replaced five lines of code using MonadState with a single line using the stateful version of this function which ended up being clearer too (IMO)
05:54:39 <Axman6> % :t (<<%@=)
05:54:39 <yahb> Axman6: MonadState s m => Over (Indexed i) ((,) a) s s a b -> (i -> a -> b) -> m a
05:55:32 <jackdk> oh yeah, indexed monadic state update, returning original result. The power of a consistent symbol language
06:00:50 × Guest68 quits (~Guest68@103.121.152.207) (Quit: Client closed)
06:00:54 × Null_A quits (~null_a@2601:645:8700:2290:6daa:6a79:97ab:557) ()
06:06:41 × xiongxin quits (~quassel@119.123.103.94) (Ping timeout: 264 seconds)
06:06:57 xiongxin joins (~quassel@113.116.32.188)
06:13:19 kuribas joins (~user@ptr-25vy0i747grimuk7ofw.18120a2.ip6.access.telenet.be)
06:15:01 lortabac joins (~lortabac@2a01:e0a:541:b8f0:4252:bf51:4908:8ea0)
06:17:13 bgamari_ joins (~bgamari@64.223.239.239)
06:17:25 × juhp quits (~juhp@128.106.188.220) (Quit: juhp)
06:17:39 juhp joins (~juhp@128.106.188.220)
06:18:42 × bgamari quits (~bgamari@71.241.201.27) (Ping timeout: 260 seconds)
06:26:45 <awpr> `profunctors` package synopsis: "Profunctors", package description: "Profunctors."
06:27:09 <awpr> cabal has a warning when uploading packages, "the description should be longer than the synopsis" :D
06:27:53 × xiongxin quits (~quassel@113.116.32.188) (Ping timeout: 246 seconds)
06:31:23 × neurocyte013 quits (~neurocyte@user/neurocyte) (Ping timeout: 246 seconds)
06:32:52 qbt joins (~edun@user/edun)
06:33:56 alzgh joins (~alzgh@user/alzgh)
06:40:34 tromp joins (~textual@dhcp-077-249-230-040.chello.nl)
06:43:11 <ldlework> awpr: I think they meant more like "functor" "monoid" etc
06:44:08 <ldlework> Which of course are not the names of the operators, but I knew what they meant.
06:47:05 yauhsien joins (~yauhsien@118-167-47-202.dynamic-ip.hinet.net)
06:47:53 <[exa]> awpr: that's mean, they made such an effort with the '.'
06:49:15 Gurkenglas joins (~Gurkengla@dslb-002-207-014-195.002.207.pools.vodafone-ip.de)
06:50:57 vaucouleur joins (~vaucouleu@78.194.70.105)
06:51:50 × yauhsien quits (~yauhsien@118-167-47-202.dynamic-ip.hinet.net) (Ping timeout: 252 seconds)
06:52:39 <c_wraith> Honestly, the profunctors package is in an awkward spot. It would be in base, if it wasn't for the usefulness of #. and .#
06:52:53 <c_wraith> No one quite wants to commit to putting hacks like that in base
06:53:11 xiongxin joins (~quassel@119.123.103.94)
06:53:24 <ldlework> profunctors - must be something to do with lifing a function over structure, but what
06:53:51 <ldlework> maybe they get paid to lift, that's why they're "pro"
06:54:35 <c_wraith> Profunctors are function-shaped functors. Contravariant in one type variable, covariant in the other.
06:54:39 dschrempf joins (~dominik@070-207.dynamic.dsl.fonira.net)
06:54:58 <awpr> profunctors are just functors from op(Hask) x Hask to Hask, what's the problem?
06:55:45 <ldlework> :S
06:55:51 <awpr> (I've always wanted to write my own needlessly inscrutable "what's the problem?" statement!)
06:56:00 <ldlework> function-shaped functors? But functors are already functions being lifted over structure.
06:56:18 <ldlework> Or do we mean, that the lhs of fmap is a function returning a function?
06:56:25 <c_wraith> neither.
06:56:28 <ldlework> I tried.
06:57:04 <c_wraith> It means that in Profunctor p => p a b, a is negative and b is positive, and you can map over either appropriately
06:57:19 <c_wraith> functions are a trivial example of that.
06:57:30 <ldlework> what's meant by negative/positive?
06:57:54 <ldlework> Or are we talking about something like Either's Left/Right?
06:58:06 <c_wraith> Nah, Either is positive in both
06:58:16 <ldlework> o_O
06:58:16 <c_wraith> that is, it can produce a value of those types
06:58:27 <c_wraith> it produces trivially by containing one of them.
06:58:45 <c_wraith> A type in a negative position is being consumed
06:58:56 <c_wraith> which basically means "an argument to a function"
06:59:15 <ldlework> So you're saying `b` is the type being produced, `a` is the type we're computing over?
06:59:33 <c_wraith> `a` is being consumed.
06:59:44 <ldlework> that's what i meant by being computed over I guess
06:59:49 <ldlework> not sure what other sense there is
06:59:53 <c_wraith> There's no guarantee it's related to the b value
07:00:14 <ldlework> Is there a trivial list/string example
07:00:20 <c_wraith> like... data Z a b = Z (a -> String) (Int -> b)
07:00:33 <c_wraith> there's no relationship between the a values and the b values
07:00:46 <c_wraith> they just are the right sorts of things
07:00:46 × vaucouleur quits (~vaucouleu@78.194.70.105) (Remote host closed the connection)
07:00:52 <ldlework> Then what are we doing with them
07:01:01 <c_wraith> Profunctor doesn't care.
07:01:08 <c_wraith> It just lets you map over each
07:01:22 <ldlework> How do you map over a function
07:01:56 <ldlework> IIRC, that just means to map over its output value right?
07:02:11 <c_wraith> actually, let me simplify that.
07:02:14 <ldlework> OK
07:02:20 <c_wraith> data Z a b = Z (a -> String) b
07:02:40 <ldlework> So would profunctor call a, disregard the string, and then return b?
07:02:52 <c_wraith> No, the a and b type variables are totally separate.
07:02:56 × nctcf^ quits (~nctcf@12.203.127.82) (Remote host closed the connection)
07:03:05 <c_wraith> Profunctor does not assume they're related.
07:03:07 <ldlework> they're not related in my description
07:03:17 <c_wraith> calling a function assumes they're related.
07:03:27 <ldlework> Z somFun someConst
07:03:35 <ldlework> someFun someA
07:03:37 <ldlework> then just return b
07:03:40 <ldlework> return someConst
07:03:43 <ldlework> how are they related?
07:04:30 <ldlework> i guess there's no point in calling `someFun someA` if it's output isn't used, and it has no effects though?
07:04:39 <c_wraith> exactly. That's why it doesn't do that.
07:05:32 <ldlework> I should probably learn what contravariance and covariance are
07:05:43 <c_wraith> it's basically just the direction of mapping.
07:06:33 <c_wraith> dimap :: (a -> b) -> (c -> d) -> Z b c -> Z a d ; dimap f g (Z h x) = Z (h . f) (g x)
07:07:21 <c_wraith> Contravariant means the map goes backwards.
07:08:02 <c_wraith> You see how there's an (a -> b) argument, but the type change is Z *b* c -> Z *a* d?
07:08:34 <c_wraith> the types change in the opposite direction as the conversion function
07:08:41 <ldlework> contramap :: (a0 -> a1) -> f a1 -> f a0
07:08:44 <ldlework> this is confusing indeed
07:09:03 <c_wraith> It only works with things that are function arguments or phantom
07:09:32 × neo1 quits (~neo3@cpe-292712.ip.primehome.com) (Read error: Connection reset by peer)
07:10:23 merijn joins (~merijn@83-160-49-249.ip.xs4all.nl)
07:10:24 <ldlework> I think I need to better my understanding of the Functor of functions
07:10:56 <c_wraith> write a Functor instance for data F a b = F (a -> b)
07:11:19 <c_wraith> or newtype, whatever :)
07:12:09 chele joins (~chele@user/chele)
07:14:46 <Guest372> :t withFile
07:14:47 <lambdabot> error:
07:14:47 <lambdabot> • Variable not in scope: withFile
07:14:47 <lambdabot> • Perhaps you meant one of these:
07:17:05 <Guest372> withFile :: FilePath -> IOMode -> (Handle -> IO r) -> IO r, why it uses (Handle -> IO r) -> IO r? not just IO r?
07:17:18 neo1 joins (~neo3@cpe-292712.ip.primehome.com)
07:17:32 <c_wraith> because the point is it closes the file when the function you pass to it completes
07:17:52 <Guest372> or just ContT r IO Handle?
07:17:53 max22- joins (~maxime@2a01cb08833598000f1fa44417d80ccf.ipv6.abo.wanadoo.fr)
07:18:11 <c_wraith> Because Codensity IO Handle is better. :P
07:18:19 dhouthoo joins (~dhouthoo@178-117-36-167.access.telenet.be)
07:19:05 <Guest372> close the file by the function you pass it or withFile itself?
07:19:30 <c_wraith> withFile closes the file when the function passed to it exits - normally or via exception
07:19:33 jstolarek joins (~jstolarek@erx128.neoplus.adsl.tpnet.pl)
07:19:52 yauhsien joins (~yauhsien@118-167-47-202.dynamic-ip.hinet.net)
07:20:25 <Guest372> aha, it will retur to withFile, that's I dont know
07:20:31 <c_wraith> And you're right about ContT being usable to flip that control flow back around. http://blog.sigfpe.com/2011/10/quick-and-dirty-reinversion-of-control.html
07:20:31 <Guest372> return
07:20:51 acidjnk joins (~acidjnk@p200300d0c703cb44319f4c33bc64626e.dip0.t-ipconnect.de)
07:21:02 <c_wraith> Codensity is a slightly less expressive monad that can be used in the same way: https://hackage.haskell.org/package/kan-extensions-5.2.3/docs/Control-Monad-Codensity.html#t:Codensity
07:24:02 Guest7264 joins (~Guest72@117.223.48.235)
07:24:14 × yauhsien quits (~yauhsien@118-167-47-202.dynamic-ip.hinet.net) (Ping timeout: 246 seconds)
07:24:16 <Axman6> but if you use ContT, the file will remain open until you run runContT right?
07:24:33 <Axman6> so if you need timely file closure, ContT is not the right thing to do
07:24:35 <awpr> it'll be opened and closed inside the runContT
07:24:48 <c_wraith> I mean, withFile isn't the right thing to do if you need timely file closure either
07:25:04 <Axman6> it is if you want the file to be closed before returning the r
07:25:15 <Axman6> which is not what will happen with ContT
07:25:48 <c_wraith> ContT doesn't change any logic
07:25:59 <c_wraith> It just lets you escape nesting
07:26:10 × Sgeo quits (~Sgeo@user/sgeo) (Read error: Connection reset by peer)
07:26:17 <c_wraith> If you don't want nested logic, don't use it
07:26:39 <Axman6> Don't you end up with the continuation that is passed to withFile being the entire rest of the ContT computation?
07:27:01 <c_wraith> Just like you end up needing to pass the entire function that processes the Handle to withFile
07:27:07 <c_wraith> It's the same thing
07:27:29 <awpr> oh, you're picturing using ContT as the monad for the entirety of some big chunk of the program
07:27:51 <awpr> yeah, that's how you get "open everything and release it all on exit"
07:28:59 <Axman6> do { withFile "foo" RW (\h -> hPut h "Hello!"); putStrLn "File is now closed") } vs do { h <- ContT (withFile "foo" RW); liftIO (hPut "foo"); putStrLn "File is still open here" }?
07:29:20 <Axman6> missing a liftIO but you get it
07:29:24 <awpr> yes, that's why you shouldn't use ContT that way :)
07:30:00 <awpr> if that's gonna be the return type of a withFile-alike, it should be used in as-small-as-possible ContT blocks wrapped in runContT
07:30:18 <c_wraith> You only really want to use it on something like withFile if you need multiple handles open at the same time to do something.
07:30:28 <awpr> +1 exactly
07:30:35 <c_wraith> And you don't want to write syntactically nested functions for it
07:31:02 rond_ joins (~rond_@2a02:a31a:a23c:f480:2fd7:e087:5546:a438)
07:31:09 <awpr> can think of ContT/Codensity as the monad of nested resource scopes in this context
07:31:33 <c_wraith> I've used them that way for FFI code.
07:31:58 <awpr> yeah, pretty great for that. I've _tried_ to use IxContT too, but it got tedious
07:33:31 <Axman6> I wou;dn't mind reading more about that technique, got any good links?
07:33:40 <ldlework> you all are on another level
07:34:20 <ldlework> really glad I spent 15 years doing Python, real glad
07:34:35 <Axman6> Now you have 15 years of bad ideas to unlearn though ;)
07:34:44 <ldlework> Yeah there was an /s there
07:34:47 <Guest372> about withFile s result type IO r, its coming from Handle -> IO r or withFile itself?
07:35:02 <Axman6> it can only come from the function you pass to it
07:35:15 <c_wraith> eh, whatever. I spent like 12 years doing BASIC before learning other languages. Despite Dijkstra's remarks, the language wasn't actively harmful.
07:35:31 <Axman6> there is no other possible way to return an r unless it throws an exception or never returns
07:35:51 <Guest372> but withFile will get control after the functuin is done
07:35:57 <Axman6> yes
07:36:14 <c_wraith> But it stores the result of your function. Then it closes the file. Then it returns what it stored.
07:36:38 <Guest372> why withFile doesn't return anything else, can it?
07:36:48 <Axman6> withFile is basically: withFile path mode f = do {h <- openHandle mode path; r <- f h; closeHandle h; return r }
07:37:13 <c_wraith> with some error handling thrown in, but that would just make it noisy and harder to read.
07:37:17 cfricke joins (~cfricke@user/cfricke)
07:37:31 <Axman6> (It's actual implementation is very different but that semantically what it does if f doesn't throw any exceptions)
07:37:48 <Guest372> can withFile return 0 or 1?
07:37:58 <Axman6> only if the function you pass it does
07:39:11 <Guest372> (Handle -> IO r) is a continuation, right?
07:39:29 <Axman6> yes
07:39:38 <c_wraith> well. not exactly.
07:39:39 <Guest372> and that closeHandle h; return r is contiuation too?
07:39:45 <c_wraith> it has the same type
07:39:49 <c_wraith> but it isn't a tail call
07:39:54 <Axman6> I wouldn't have said that, no
07:40:35 <Axman6> note that the return type of withFile is determined by the function, or continuation, that you pass it
07:40:37 <Guest372> that closeHandle and return is behind the contiuation
07:40:53 <Axman6> I think you're over complicating this - read the colde I wrote a bove
07:40:58 <Axman6> above*
07:41:36 <c_wraith> I think you're conflating something with the type of a continuation vs... a continuation.
07:41:58 <Guest372> confuse
07:42:36 <ldlework> Guest372: welcome to the club
07:42:42 <ldlework> we have drinks and snacks at the bar
07:43:07 <c_wraith> You've got a baseline assumption that calling a continuation is the last thing a function does.
07:43:26 <c_wraith> And that's fair - that's what a continuation *is* - where to go next.
07:43:54 <c_wraith> But you've mistaken withFile for being an example of using a continuation because it has the same type as stuff that does
07:44:09 <c_wraith> But it's different - it's more of a traditional callback
07:44:11 × merijn quits (~merijn@83-160-49-249.ip.xs4all.nl) (Ping timeout: 246 seconds)
07:45:00 <Guest372> but in that withFile code above, call f isn't the last thing to do, there are closeHandle
07:45:10 merijn joins (~merijn@83-160-49-249.ip.xs4all.nl)
07:45:13 <ldlework> Guest372: that's their point
07:46:02 <Cale> I think it's fine to think of it as a continuation of sorts. After all, you can use the Cont/ContT monad to work with such withFoo-style functions and handle all the nesting for you.
07:46:55 <c_wraith> it's fine until your definition of "continuation" forbids what it does, and you get confused.
07:47:41 <Guest372> Handle -> IO r inside withFile is a cotinuation?
07:47:41 <Cale> It's not an unbounded continuation-until-the-end-of-time sort of continuation, but one which specifies what happens up until the file gets closed (or whatever)
07:49:32 <Guest372> more confused, withFile will call f to handle its Handle, and when f is done, control return to withFile, then withFile close Handle
07:49:55 <ldlework> you don't seem confused at all!
07:49:59 <Guest372> f is not the last thing withFile do
07:50:10 <Guest372> f is a continuation?
07:50:17 <c_wraith> if your definition of continuation includes "the last thing a function does", then no, it's not.
07:50:22 <ldlework> lol
07:50:34 <c_wraith> If you relax the definition as Cale suggested, then sure.
07:51:11 <Guest372> whats the right definiton?
07:51:26 <Guest372> that most people using
07:52:23 <awpr> the ContT monad evidently uses the relaxed version. in the context of "CPS", it's the stricter version. I'm not sure I'd call either one "right" or "wrong", they're just two very similar concepts
07:52:46 × juhp quits (~juhp@128.106.188.220) (Quit: juhp)
07:53:00 juhp joins (~juhp@128.106.188.220)
07:53:41 <ldlework> So when you use a function functor, you are basically transforming a function of `a -> z0` to `a -> z1` ?
07:54:23 <Guest372> so turn that (Handle -> IO r) -> IO r to ContT r IO Handle, who will close the handle? withFile itself or ContT?
07:54:35 <ldlework> Oh that makes sense because that's what function composition does too
07:55:12 <ldlework> x :: a -> b, y:: b -> c, then y . x :: a -> c
07:58:29 <ldlework> Hmm, I just got to the end of the section that concludes: `To put another way: The type constructor (->) a z is covariant in its second argument.`
07:58:36 <ldlework> But I still dont understand what is meant by that.
07:58:44 × Guest7264 quits (~Guest72@117.223.48.235) (Quit: Client closed)
07:58:45 <c_wraith> all it means is that it maps "forwards"
07:59:07 <c_wraith> (a -> b) -> T a -> T b
07:59:26 <c_wraith> contravariant means the mapping goes backwards: (a -> b) -> T b -> T a
07:59:41 <c_wraith> covariant is much more common
07:59:54 <ldlework> how would the latter even work
08:00:09 <ldlework> if you have a -> b, you need an `a` on hand to pass
08:00:14 <ldlework> well a T a
08:00:21 <c_wraith> Not necessarily true!
08:00:22 <ldlework> but you got a T b instead
08:00:46 <c_wraith> newtype Predicate a = P (a -> Bool)
08:00:49 <awpr> `newtype Predicate a = Predicat
08:00:55 <awpr> ^ aborted
08:01:17 <ldlework> was that supposed to be clarifying? :P
08:01:22 <c_wraith> You don't have a value of type a in a Predicate a
08:01:35 <c_wraith> you have an empty spot that accepts an a
08:02:01 gioyik joins (~gioyik@gateway/tor-sasl/gioyik)
08:02:07 <c_wraith> So a function of type (a -> b) transforms something going into the empty spot.
08:02:43 <ldlework> I understand that a data type doesn't need to structurally compose every type in its type constructor
08:02:51 <ldlework> But I feel I'm no closer to understanding the backwards case
08:03:27 <awpr> maybe try implementing the forwards case for Predicate and see what goes wrong
08:04:19 <ldlework> what would I be implementing?
08:04:39 <awpr> `instance Functor Predicate` for example
08:04:41 <ldlework> just a function like Predicate a -> T Bool -> T a
08:04:50 <ldlework> oh so fmap
08:04:57 benin036932301 joins (~benin@183.82.205.89)
08:05:06 <Cale> Guest372: Of course it will still be withFile, but that will happen at the end after pretty much the rest of the action you're runContT'ing executes, and things start to unravel. Basically, when you write do v <- withFoo; ... in the ContT monad, it's like withFoo (\v -> ...)
08:05:55 hendursa1 joins (~weechat@user/hendursaga)
08:06:05 × phma quits (~phma@host-67-44-208-198.hnremote.net) (Read error: Connection reset by peer)
08:06:47 <Cale> Stuff like sequence in the Cont monad can be really useful if you want to get hold of an entire list of resources all at once
08:06:54 <Cale> :t runCont . sequence . map cont
08:06:55 <lambdabot> [(a -> r) -> r] -> ([a] -> r) -> r
08:07:00 × gioyik quits (~gioyik@gateway/tor-sasl/gioyik) (Ping timeout: 276 seconds)
08:07:01 phma joins (~phma@host-67-44-208-5.hnremote.net)
08:07:43 <Cale> ^^ take a list of withFoo-style functions, and a function which will get a list of their results, ... and basically nest them in the obvious way
08:08:57 × hendursaga quits (~weechat@user/hendursaga) (Ping timeout: 276 seconds)
08:09:15 <Cale> Of course, you could write this function by hand, but it'll be way harder to think about whether you got it right than this :)
08:09:17 <Guest372> you mean when runCotT is done, withFile close the file?
08:09:34 <ldlework> awpr: c_wraith: couldn't match type 'a' with 'b' in `instance Functor Pred where fmap f (P p) = P (f . p)`
08:10:16 <Cale> Guest372: Pretty much, once the action is done, all the with-style stuff you ran along the way will start to unravel in the same way as if you'd nested it all by hand.
08:10:34 <ldlework> I guess that's the problem you alluded to?
08:10:48 <awpr> my brain hurts trying to see how that error corresponds to that code; is it actually `p . f`?
08:10:55 <Cale> The Cont/ContT monad just takes care of the nesting for you, and makes it appear like it's flattened out
08:11:34 <awpr> oh, nvm, I can see where that error came from
08:11:42 <Guest372> Cale just like sugar syntax? nothing more?
08:11:44 <awpr> so, not exactly the error I was alluding to
08:11:55 <ldlework> awpr: http://logos.ldlework.com/caps/2021-09-21-08-11-52.png
08:12:13 <Cale> Guest372: Well, as I demonstrated there with sequence, it buys you a little more than syntax sugar, because you get to use all the stuff that works in any monad
08:12:26 <ldlework> awpr: where did i go wrong?
08:12:35 nschoe joins (~quassel@178.251.84.79)
08:12:50 <awpr> so you've got an `a` in the type that you want to end up being a `b`; the `a` is the input to the `p` function
08:12:56 __monty__ joins (~toonn@user/toonn)
08:13:28 <awpr> and you've got a function to apply, that you want to use to transform the `a` values, which are inputs to `p`
08:13:53 × cfricke quits (~cfricke@user/cfricke) (Ping timeout: 264 seconds)
08:15:50 <ldlework> awpr: so the inputs should go into ... `f`, which are then piped into `p`?
08:15:56 <awpr> yep
08:15:56 <ldlework> isn't that just function composition?
08:16:09 <awpr> also yes, it's just the other order of function composition
08:16:23 <ldlework> awpr: http://logos.ldlework.com/caps/2021-09-21-08-16-21.png
08:17:10 <awpr> yeah, there's what I was expecting to see: in `fmap`, the `f` function is _backwards_ from what it'd need to be to be able to transform the `a` type
08:17:25 × geekosaur quits (~geekosaur@xmonad/geekosaur) (Remote host closed the connection)
08:17:46 <awpr> you have an `a -> b` and an `a -> Bool`, and they just don't fit together
08:17:50 geekosaur joins (~geekosaur@xmonad/geekosaur)
08:17:51 <ldlework> awpr: oh, so this is why we need Profunctor and not just Functor?
08:18:09 <awpr> well, in this particular case, Contravariant instead of Functor
08:18:22 <ldlework> I see.
08:18:42 <awpr> now try `contramap :: (b -> a) -> Pred a -> Pred b`, with the same definition, and it should work
08:18:47 <ldlework> awpr: one day when you're not busy, want to collaborate on a draw.io diagram (or something) of the typeclass family tree?
08:19:01 <ldlework> i haven't been able to find a substantial one
08:19:12 <awpr> hmm, I thought there were a few of those scattered around
08:19:25 <ldlework> i found a couple, but they are only a handful of typeclasses
08:19:29 <awpr> https://wiki.haskell.org/Typeclassopedia
08:19:36 <awpr> that has a pretty substantial one
08:20:00 <awpr> hmm, no profunctor or contravariant, though
08:20:08 <ldlework> I was just gonna say that :P
08:20:30 <ldlework> awpr: would it be possible to generate this list from the haskell source code?
08:20:39 <ldlework> using some dumb grep/python or whatever
08:21:00 <ldlework> s/list/graph
08:21:14 <awpr> maybe, but there can be cases where something is sort of a superclass but doesn't actually say so in code
08:21:25 <ldlework> Oh rip
08:21:25 <awpr> like Applicative => Monad used to be that way a long time ago
08:21:30 <ldlework> Right
08:21:38 <ldlework> And monoid => Semigroup?
08:21:54 <awpr> yeah, in the other direction
08:21:56 <ldlework> awpr: maybe it would get 80% there
08:22:36 <ldlework> It'd also be kind of a map of what relations are left implicit today
08:22:51 <awpr> I'm also not sure how to represent the relationship between e.g. Functor, Contravariant, Bifunctor, Profunctor, Functor10, etc. visually. they're all very closely connected, but not by any superclass relationships
08:23:12 <ldlework> awpr: we can use different line types
08:23:30 <ldlework> awpr: are you saying there'd be no way to automatically associate Functor and Contravariant (for example)?
08:23:45 <awpr> yeah, not that I know of
08:23:55 <ldlework> aww, dreams dying over here
08:25:23 <ldlework> this idea of collaborating to make a full typeclass diagram has made me think of another idea, a realtime collaborative web-based PlantUML editor
08:25:35 <ldlework> man that'd be dope
08:26:26 × ubert quits (~Thunderbi@77.119.204.226.wireless.dyn.drei.com) (Ping timeout: 252 seconds)
08:26:28 michalz joins (~michalz@185.246.204.33)
08:27:09 × hnOsmium0001 quits (uid453710@id-453710.hampstead.irccloud.com) (Quit: Connection closed for inactivity)
08:27:51 <ldlework> awpr: now i'm annoyed lol
08:28:25 <merijn> contravariant functors and functors are kinda opposites
08:28:42 [exa] feels category diagrams incoming
08:28:45 <merijn> So you could have a mirror in the middle to "opposite world" and do that :p
08:29:14 <merijn> ldlework: See also comonad (does coapplicative exist? Presumably, but I don't think I've seen it...)
08:29:17 <awpr> yeah, we'd have to have product world and parametric world too though
08:29:41 <ldlework> let's do it
08:30:12 Guest372 parts (~xxx@47.245.54.240) ()
08:30:18 <[exa]> ldlework: uml kinda sucks for this stuff honestly, the major things are usually transformations and arrows, not objects
08:30:23 × benin036932301 quits (~benin@183.82.205.89) (Ping timeout: 246 seconds)
08:30:45 <awpr> yeah I think that kind of sums up my lack of optimism
08:31:07 <ldlework> [exa]: It's just that PlanUML is convienent because of it's text-based format
08:31:22 <ldlework> rather than dragging and clicking, i'm pretty sure it'd be sufficient to express some relationships
08:31:27 <[exa]> ldlework: I can argue that ascii art is a better text based format :]
08:31:35 <awpr> it'd be possible to throw things into a planar graph, but the useful relationships wouldn't be very visible
08:31:49 <[exa]> ldlework: anyway there's a TeX package for drawing this already
08:32:01 <awpr> a giant category theory diagram would do the trick, but it'd also be rather cluttered
08:32:05 <ldlework> Yeah I definitely want to go setup TeX right now :P
08:32:15 <ldlework> awpr: that's why there's zoom
08:32:26 <[exa]> zoom doesn't work for brains
08:32:47 <[exa]> you either get the idea at one level, or it's cluttered
08:32:58 ubert joins (~Thunderbi@77.119.204.226.wireless.dyn.drei.com)
08:32:59 <ldlework> mindmaps are pretty successful
08:33:11 <ldlework> we're making really generalized claims about tools that are clearly helpful to many people
08:33:18 <[exa]> yep. :]
08:33:28 <[exa]> mindmaps are about not missing the relations, useful for sure
08:33:46 <[exa]> still you don't remember "the shape of the mindmap" as something to guide your math/programming intuition right?
08:33:59 <ldlework> if we had a big planar map of the typeclass relations with different arrow types, or whatever
08:34:02 <awpr> if it could actually all fit into a pannable/zoomable map that labels category theory stuff with Haskell names, that'd be really cool. will have to think about whether it can be made to work
08:34:12 <ldlework> it'd be clearly useful/valuable in getting a vista
08:34:21 <[exa]> ldlework: did you see the one for number hierarchy?
08:34:24 <ldlework> especially if they linked out to typeopedia resources, etc
08:34:54 <[exa]> actually some dynamic graph drawing could be really cool
08:35:04 <awpr> things get _really_ stratified though when you start trying to be honest about category theory concepts in Haskell, though
08:35:04 <ldlework> awpr: if you'd be willing to help with the formal knowledge, I wouldn't be against exploring some custom options using React Flow
08:35:19 <ldlework> I've built such things before
08:35:39 <ldlework> Maybe we could do layers, where you could have controls on the right to toggle things on and off, etc
08:36:05 <awpr> like a profunctor is a Hask-enriched functor from the product category OpHaskxHask to Hask, and then there are ProfunctorFunctors which treat those as objects of their own category
08:36:15 <ldlework> awpr: in the end, i also have built things with threejs so if we needed to go three dimensional, it's a possibility :P
08:37:32 <awpr> I do find myself trying to visually build this stuff up in my head all the time... could be really cool to have it all there in one place
08:37:42 <ldlework> it really would be
08:38:07 benin036932301 joins (~benin@183.82.205.89)
08:38:27 <awpr> need to let the idea braise for a while / find time to be able to work on it
08:38:45 <ldlework> awpr: with plantuml, we could embed the lawful functions inside the objects too
08:38:59 <ldlework> I'm gonna recreate the typopedia diagram in plantuml just as a salespitch
08:40:04 <[exa]> ldlework: actually a nice opportunity to learn some haskell webbing, FRP or miso :D
08:40:59 <ldlework> [exa]: if i was gonna build a custom explorer i'd love to go the haskell route, but with work, i'd just need to snap it out using the tech i'm really comfortable with
08:41:04 bitdex joins (~bitdex@gateway/tor-sasl/bitdex)
08:41:33 <ldlework> I'd love to learn Reflex
08:42:35 <Cale> ldlework: Nice! Let me know how it goes.
08:44:49 <Cale> (I'm working for Obsidian Systems, and while Reflex is much more Ryan's doing than mine, it's definitely inspired by the work we did together on earlier FRP systems.)
08:47:07 <[exa]> ldlework: it would be interesting to also have the instances around (they make the classes work, right?). I was always kinda wondering how (or if) to correctly draw stuff like `instance Monoid a => Monoid (r -> a)` in this scheme, which I'd find pretty useful
08:49:49 lavaman joins (~lavaman@98.38.249.169)
08:50:50 × xiongxin quits (~quassel@119.123.103.94) (Ping timeout: 265 seconds)
08:50:54 xiongxin_ joins (~quassel@113.116.32.178)
08:54:41 × lavaman quits (~lavaman@98.38.249.169) (Ping timeout: 264 seconds)
08:57:13 <ldlework> http://logos.ldlework.com/caps/2021-09-21-08-57-09.png
08:57:19 <ldlework> Cale: [exa] awpr
08:58:06 × juhp quits (~juhp@128.106.188.220) (Quit: juhp)
08:58:19 juhp joins (~juhp@128.106.188.220)
09:00:16 <[exa]> ldlework: perhaps there would be a github CI renderer for this so it can be shared reasonably
09:00:38 × xiongxin_ quits (~quassel@113.116.32.178) (Ping timeout: 260 seconds)
09:00:39 <awpr> looks pretty good for the Hask->Hask subset of the world
09:00:57 <ldlework> there are a lot of options for styling, arrows, etc too
09:01:00 <ldlework> labels, and so on
09:01:35 × eggplantade quits (~Eggplanta@2600:1700:bef1:5e10:283f:384b:ba74:f15c) (Remote host closed the connection)
09:01:57 <awpr> things do start to go downhill slightly with all the dotted lines meaning different things, though -- e.g. Monoid -> Category is oidification, Applicative -> Traversal is like "this uses that", Monoid -> Applicative is "this is the tensor product used in constructing that", etc.
09:03:27 eggplantade joins (~Eggplanta@2600:1700:bef1:5e10:1c28:7782:3d08:8ee5)
09:03:27 <merijn> You do realise what happened the last time someone tried to make a single comprehensive document containing all math, yeah? :p
09:03:45 lavaman joins (~lavaman@98.38.249.169)
09:03:53 <awpr> somebody invented more math?
09:03:53 × lavaman quits (~lavaman@98.38.249.169) (Remote host closed the connection)
09:04:05 <ldlework> merijn: I just want a useful resource to give a vista for new haskell programmers that's all :P
09:04:07 <ldlework> (like me)
09:04:25 <ldlework> awpr: we can have specifically styled lines to mean specific things
09:06:07 <awpr> I've kinda gone off on a tangent into category theory land now. the UML-style diagram seems like it could be useful to a lot of people, but the thing I'm kinda excited about is a browseable category theory thing that points at some concrete thing and says e.g. "this is Functor"
09:06:52 <awpr> the planar graph version is much more tractable, at least
09:08:07 awpr just used the word "concrete" in a sentence about category theory...
09:08:09 <sshine> awpr, someone invented a meta-proof-system. this is only natural. I suppose Gödel was the first one to show that any cool enough concept devolves into meta-programming.
09:09:05 × eggplantade quits (~Eggplanta@2600:1700:bef1:5e10:1c28:7782:3d08:8ee5) (Ping timeout: 264 seconds)
09:11:32 × geekosaur quits (~geekosaur@xmonad/geekosaur) (Remote host closed the connection)
09:13:13 <awpr> for now though I've got to get some sleep -- I'll keep thinking about whether the whole world can fit into a diagram
09:14:47 <ldlework> http://logos.ldlework.com/caps/2021-09-21-09-14-43.png
09:16:35 yauhsien joins (~yauhsien@118-167-47-202.dynamic-ip.hinet.net)
09:18:42 <ldlework> I can't find anything on "Apply"
09:21:19 × yauhsien quits (~yauhsien@118-167-47-202.dynamic-ip.hinet.net) (Ping timeout: 252 seconds)
09:22:19 <Taneb> https://hackage.haskell.org/package/semigroupoids-5.3.2/docs/Data-Functor-Apply.html#g:2 ?
09:26:22 <merijn> ldlework: Because Apply is mostly lawless nonsense >.>
09:34:34 lavaman joins (~lavaman@98.38.249.169)
09:37:16 <ldlework> WIP https://i.imgur.com/oc17eZE.png
09:38:59 × lavaman quits (~lavaman@98.38.249.169) (Ping timeout: 246 seconds)
09:39:28 Brumaire joins (~quassel@37.165.26.197)
09:41:32 × dschrempf quits (~dominik@070-207.dynamic.dsl.fonira.net) (Quit: WeeChat 3.2.1)
09:42:54 × bastelfreak quits (~bastelfre@basteles-bastelknecht.bastelfreak.org) (Quit: WeeChat 3.2)
09:44:44 jacks2 joins (~bc8165b6@217.29.117.252)
09:45:03 <ldlework> [exa]: Cale thoughts?
09:45:32 <jacks2> hi. I want to put some haskell code in settings file that will be evaluated by haskell program. basically, I need to ship my program with ghci interpreter. what's the best way of achieving this?
09:46:11 <ldlework> jacks2: have you considered dhall instead?
09:46:17 <jacks2> (I don't care about security, this is a personal project used only by me)
09:46:19 bastelfreak joins (~bastelfre@basteles-bastelknecht.bastelfreak.org)
09:46:39 <ldlework> jacks2: there is https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/extending_ghc.html
09:46:54 × werneta quits (~werneta@70-142-214-115.lightspeed.irvnca.sbcglobal.net) (Remote host closed the connection)
09:47:13 <jacks2> ldlework, it looks interesting, but I already have a working settings file in a different format, I just need a way to interpret strings as haskell code
09:47:23 <ldlework> jacks2: look at the link I just sent :)
09:47:52 <jacks2> oh this is part of ghc now? nice
09:47:59 <jacks2> I recall using some third party library many years ago
09:48:37 <ldlework> jacks2: tell me you're making an Ansible alternative, but with Haskell
09:49:19 <jacks2> no :). just a quick and dirty program for my own use
09:54:41 kayprish joins (~kayprish@46.240.130.158)
09:54:49 <[exa]> ldlework: I'm doing something else now sorry :D looks good but I guess it's gonna get really cluttered when you start completing it
09:55:14 <ldlework> will just take massaging
09:59:14 mc47 joins (~mc47@xmonad/TheMC47)
10:00:06 on^ joins (~on@12.203.127.82)
10:00:56 × maroloccio quits (~marolocci@93-142-92-177.adsl.net.t-com.hr) (Quit: WeeChat 3.0)
10:02:31 <maerwald> ldlework: you mean propellor?
10:02:46 <maerwald> (I don't recommend it)
10:03:28 <maerwald> @hackage propellor
10:03:29 <lambdabot> https://hackage.haskell.org/package/propellor
10:03:49 × Brumaire quits (~quassel@37.165.26.197) (Ping timeout: 265 seconds)
10:03:57 <ldlework> maerwald: https://github.com/dhall-lang/dhall-haskell
10:04:20 <maerwald> ldlework: ?
10:04:22 <Cale> ldlework: Nice, what are you using to draw the stuff?
10:04:48 <ldlework> maerwald: I don't know what you meant by "you mean propeller?"
10:04:53 <ldlework> maerwald: oh ansible alternative
10:04:58 <ldlework> makes sense now :P
10:05:04 <ldlework> Cale: plantuml
10:05:59 × merijn quits (~merijn@83-160-49-249.ip.xs4all.nl) (Ping timeout: 252 seconds)
10:06:34 <dminuoso> You're shipping 1GiB of a compiler just to be able to read a settings file?
10:06:35 merijn joins (~merijn@83-160-49-249.ip.xs4all.nl)
10:06:37 <dminuoso> Mmm.
10:06:58 <dminuoso> Dhall would seem easier..
10:07:08 × kayprish quits (~kayprish@46.240.130.158) (Remote host closed the connection)
10:07:17 <ldlework> :D
10:11:53 × merijn quits (~merijn@83-160-49-249.ip.xs4all.nl) (Ping timeout: 246 seconds)
10:12:05 merijn joins (~merijn@83-160-49-249.ip.xs4all.nl)
10:17:29 × merijn quits (~merijn@83-160-49-249.ip.xs4all.nl) (Ping timeout: 264 seconds)
10:17:41 merijn joins (~merijn@83-160-49-249.ip.xs4all.nl)
10:22:44 × merijn quits (~merijn@83-160-49-249.ip.xs4all.nl) (Ping timeout: 246 seconds)
10:23:17 merijn joins (~merijn@83-160-49-249.ip.xs4all.nl)
10:25:03 xiongxin joins (~quassel@119.123.102.205)
10:30:05 oxide joins (~lambda@user/oxide)
10:33:41 × merijn quits (~merijn@83-160-49-249.ip.xs4all.nl) (Ping timeout: 264 seconds)
10:34:48 merijn joins (~merijn@83-160-49-249.ip.xs4all.nl)
10:34:49 × totbwf__ quits (sid402332@id-402332.uxbridge.irccloud.com) (Quit: Connection closed for inactivity)
10:38:06 × econo quits (uid147250@user/econo) (Quit: Connection closed for inactivity)
10:38:26 × bastelfreak quits (~bastelfre@basteles-bastelknecht.bastelfreak.org) (Quit: WeeChat 3.3)
10:38:42 bastelfreak joins (~bastelfre@basteles-bastelknecht.bastelfreak.org)
10:39:10 cfricke joins (~cfricke@user/cfricke)
10:40:17 × merijn quits (~merijn@83-160-49-249.ip.xs4all.nl) (Ping timeout: 264 seconds)
10:40:27 merijn joins (~merijn@83-160-49-249.ip.xs4all.nl)
10:50:29 × merijn quits (~merijn@83-160-49-249.ip.xs4all.nl) (Ping timeout: 264 seconds)
10:52:04 merijn joins (~merijn@83-160-49-249.ip.xs4all.nl)
10:53:11 × neo1 quits (~neo3@cpe-292712.ip.primehome.com) (Ping timeout: 246 seconds)
10:54:39 <ldlework> Is Monoid a (logical) superclass of Foldable?
10:55:33 <Las[m]> No
10:55:45 <dminuoso> They have different kinds, in fact.
10:55:47 <dminuoso> % :k Foldable
10:55:47 <yahb> dminuoso: (* -> *) -> Constraint
10:55:47 <Las[m]> They don't have the same kind first of all
10:55:49 <dminuoso> % :k Monoid
10:55:49 <yahb> dminuoso: * -> Constraint
10:56:19 <dminuoso> Though there is a sort of relationship.
10:56:40 <ldlework> in https://wiki.haskell.org/wikiupload/d/df/Typeclassopedia-diagram.png what are the dashed lines indicating
10:56:45 <dminuoso> % :t toList
10:56:45 <yahb> dminuoso: Foldable t => t a -> [a]
10:56:52 <ldlework> is it that functions of the typeclass use the other typeclass?
10:57:00 <dminuoso> We can think this function as the spiritual embodiment of Foldable
10:57:09 <dminuoso> And with some squinting we can think of lists as free monoids.
10:57:18 <dminuoso> Is that perhaps the relationship you're after?
10:57:38 <ldlework> dminuoso: I was just observing that some of Foldable's functions take Monoids
10:57:44 <dminuoso> Yes, it's a good observation.
10:57:56 <ldlework> fold :: Monoid m => t m -> m
10:58:04 <ldlework> So I was thinking of including a relation in my graph for that
10:58:29 <dminuoso> There's no straight relationship like that.
10:58:51 <ldlework> straight relationship?
10:59:27 <dminuoso> The best I can see is what I outlined earlier, thinking of `toList` as the (conceptual) characteristic method of Foldable, and thinking of a list as the free monoid.
10:59:33 <ldlework> I wonder if I should include each typeclasses' kind in the graph
10:59:53 <ldlework> dminuoso: what do you mean by "free" in "free monoid"
11:00:10 × Chai-T-Rex quits (~ChaiTRex@user/chaitrex) (Remote host closed the connection)
11:00:22 <dminuoso> "free" as in "without any extra luggage"
11:00:32 <dminuoso> unrestricted/free
11:00:38 <dminuoso> It's a term originating from math
11:00:40 Chai-T-Rex joins (~ChaiTRex@user/chaitrex)
11:00:58 alx741 joins (~alx741@186.178.109.159)
11:02:29 × merijn quits (~merijn@83-160-49-249.ip.xs4all.nl) (Ping timeout: 264 seconds)
11:02:29 <ldlework> dminuoso: would extra luggage be in the Semigroup direction, or the opposite direction of some other hypothetical typeclass that's a subclass of Monoid
11:02:40 <ldlework> The latter right?
11:02:54 <dminuoso> If you really want to know the gory details we'd have to dive a bit into category theory.
11:03:06 <dminuoso> Let me try and think of a handwaving way to explain this
11:03:39 merijn joins (~merijn@83-160-49-249.ip.xs4all.nl)
11:03:57 <ldlework> dminuoso: I have a category theory friend, and he can explain how a car works by simplifying it down and using metaphors, but he cannot explain category theory without using jargon / using metaphors ^_^
11:04:00 <dminuoso> A `free something` is the bare essential `something` that satisfies its laws, but nothing extra.
11:04:34 <dminuoso> A handwaving, perhaps suggestive way, is to think of a list as representing the mere monoidal structure
11:04:54 <ldlework> dminuoso: so a Semigroup would be a `degenerate monoid`, a monoid would be a `free monoid` and something who's superclass was Monoid would be a `restricted monoid` ?
11:05:02 <dminuoso> No rather
11:05:13 <dminuoso> Take the monoid of natural numbers under addition
11:05:18 <ldlework> Right
11:05:36 <ldlework> Semigroup of natural numbers + 0 for identity
11:05:43 <dminuoso> The monoid encompasses not just the operation (+) and its identity (0), but also the entirety of all elements.
11:05:55 <ldlework> the "domain"
11:06:01 eggplantade joins (~Eggplanta@2600:1700:bef1:5e10:1c28:7782:3d08:8ee5)
11:06:07 <dminuoso> In category theory there's a lot of structure simply because we cant just ignore those numbers.
11:06:28 jespada joins (~jespada@2803:9800:9842:7a62:edd5:5e74:3ec2:1b19)
11:06:55 <dminuoso> So we have these constructions in category theory that allow us to "forget structure", so if we forget as much about this monoid as possible, while still satisfying the monoidal laws
11:07:25 <dminuoso> Sorry no that is wrong
11:07:27 <dminuoso> So
11:07:47 <dminuoso> ldlework: imagine a transformation from the naturals under addition to just the set of naturals.
11:08:00 <dminuoso> ldlework: Notice how such a transformation would essentially "forget" about all the monoidal structure?
11:08:13 <ldlework> dminuoso: It's like how a Monoid is a "restricted semigroup" since it is the "Semigroup with extra baggage" (identity), no?
11:08:32 <dminuoso> Yes, absolutely.
11:08:42 <dminuoso> But for this purpose, we intend to forget the entirety of the monoidal structure
11:08:44 <dminuoso> not just the identity
11:08:59 <ldlework> so the semigroup bits too
11:09:02 <dminuoso> Yes.
11:09:05 × merijn quits (~merijn@83-160-49-249.ip.xs4all.nl) (Ping timeout: 264 seconds)
11:09:08 <dminuoso> Everything but the carrier set
11:09:11 <ldlework> why are we forgetting structure? I lost the thread.
11:09:18 <dminuoso> Dont worry about the details of why we do this.
11:09:24 <ldlework> XD
11:09:40 <dminuoso> We can make a construction, called a functor, that does this with any monoid
11:09:42 merijn joins (~merijn@83-160-49-249.ip.xs4all.nl)
11:09:54 <dminuoso> So given a particular monoid, it just strips away the monoidal structure and gives you back the carrier set
11:10:11 <ldlework> well if you fmap'd id into the monoid
11:10:13 <ldlework> right
11:10:22 × eggplantade quits (~Eggplanta@2600:1700:bef1:5e10:1c28:7782:3d08:8ee5) (Ping timeout: 260 seconds)
11:10:41 <dminuoso> Note that the "functor" is a different functor from our Haskell thing. A functor is just a way to transform one category into another. In our case, the category of monoids to the category of sets.
11:10:44 <ldlework> that would extract whatever is inside the structure
11:10:52 <ldlework> mm
11:10:57 <dminuoso> And we can also construct another functor in the other direction
11:11:08 <dminuoso> That is intrinsically related
11:11:17 <dminuoso> To the former functor (called the forgetful functor)
11:11:18 <ldlework> Now you have a Groupoid right
11:11:25 <ldlework> Since each morphism is an isomorphism
11:11:26 <dminuoso> Well the question is what does that functor even do
11:11:31 <dminuoso> So what we do is this:
11:11:42 yauhsien joins (~yauhsien@118-167-47-202.dynamic-ip.hinet.net)
11:11:57 <dminuoso> That functor maps a given set to the monoid [a], under which the unit is [] and the binary operation is ++
11:12:00 <dminuoso> It can map *every* set this way
11:12:17 <dminuoso> It turns out that these two functors have a deep relationship
11:12:45 <ldlework> you're basically just saying
11:12:49 <ldlework> you can put things into a list
11:12:51 <dminuoso> The former is called a forgetful functor (forgetting monoidal structure), the latter is called a free functor (adding the *bare* monoidal structure back, with no extra baggage)
11:12:55 <ldlework> and we can do list concatenation
11:13:08 <dminuoso> We still have monoidal shape in list concatenation
11:13:12 <dminuoso> but no meaning of that
11:13:59 <ldlework> OK, so you're outlining that with regards to structure, we have a way of taking a set and putting it into structure or taking it out of structure
11:14:27 <ldlework> where a set is some domain of values of a given type, like natural numbers
11:14:31 <dminuoso> Well, we have a way of forgetting concrete monoidal structure back to a set, and a way of adding *bare/essential* monoidal structure to a set.
11:14:39 <dminuoso> Sure, it could be any
11:15:05 × merijn quits (~merijn@83-160-49-249.ip.xs4all.nl) (Ping timeout: 264 seconds)
11:15:25 <ldlework> by emphasizing bare essential structure, you just mean, we're just putting the values back into the list (monoid), but no additional structure
11:15:33 merijn joins (~merijn@83-160-49-249.ip.xs4all.nl)
11:15:34 <dminuoso> This relationship between "free" and "forgetful" can be observed in Haskell, even.
11:16:10 <dminuoso> If we call the forgetful functor `U` that strips away the monoidal structure, and `F` that free functor, we express that relationship as:
11:16:19 × yauhsien quits (~yauhsien@118-167-47-202.dynamic-ip.hinet.net) (Ping timeout: 265 seconds)
11:16:23 <dminuoso> `F a -> b` is isomorphic to `a -> U b`
11:17:15 <dminuoso> Now, again ignoring gory details:
11:17:41 Everything joins (~Everythin@37.115.210.35)
11:17:51 <dminuoso> This eventually turns into Haskell by showing that `[a] -> b` being expressible by a function `a -> b`
11:17:54 <dminuoso> % :t foldMap
11:17:54 <yahb> dminuoso: (Foldable t, Monoid m) => (a -> m) -> t a -> m
11:18:05 <dminuoso> If you set `t ~ []`
11:18:18 raehik joins (~raehik@cpc95906-rdng25-2-0-cust156.15-3.cable.virginm.net)
11:18:35 × wei2912 quits (~wei2912@112.199.250.21) (Quit: Lost terminal)
11:18:57 Brumaire joins (~quassel@37.165.2.61)
11:19:23 <Cajun> so if you composed those functions ( `F a -> b` and `a -> U b` ) and assumed `a ~ b` you could get the "bare monoidal structure" from the forgetful functor?
11:19:42 <dminuoso> Those are not regular functions.
11:20:11 <dminuoso> Perhaps this was a bit misleading
11:20:30 <Cajun> ah category theory functors where its just some type to another, not a function?
11:20:50 × cheater quits (~Username@user/cheater) (Ping timeout: 246 seconds)
11:25:16 <dminuoso> The thing is, `F` is implicitly there in Haskell
11:25:54 <dminuoso> So we could roughly do this:
11:25:59 × Brumaire quits (~quassel@37.165.2.61) (Ping timeout: 265 seconds)
11:26:36 <dminuoso> % newtype Mon a = Mon [a]; instance Semigroup (Mon a) where Mon a <> Mon b = Mon (a ++ b); instance Monoid (Mon a) where mempty = Mon [];
11:26:36 <yahb> dminuoso: ; <interactive>:53:90: error: parse error on input `instance'
11:26:45 <dminuoso> % newtype Mon a = Mon [a]
11:26:45 <yahb> dminuoso:
11:26:49 <dminuoso> % nstance Semigroup (Mon a) where Mon a <> Mon b = Mon (a ++ b)
11:26:50 <yahb> dminuoso: ; <interactive>:55:27: error: parse error on input `where'
11:26:54 <dminuoso> % instance Semigroup (Mon a) where Mon a <> Mon b = Mon (a ++ b)
11:26:54 <yahb> dminuoso:
11:27:00 <dminuoso> % instance Monoid (Mon a) where mempty = Mon [];
11:27:00 <yahb> dminuoso:
11:27:30 <dminuoso> Mmm not quite
11:29:29 <dminuoso> ldlework: Anyway, at the end the key observation is: You can simply take a list of anything and make a minimal monoid with that. It adds monoidal structure, and nothing else.
11:29:54 <dminuoso> We dont even specify what `a ++ b` even means
11:32:37 <hpc> "We dont even specify what `a ++ b` even means" - leading with this would help a lot with future explanations
11:34:03 cheater joins (~Username@user/cheater)
11:36:07 gehmehgeh joins (~user@user/gehmehgeh)
11:38:32 <carbolymer> are async exceptions masked in "last" computation in `Control.Exception.bracket` ?
11:40:38 <dminuoso> carbolymer: Look at the implementation
11:41:40 <carbolymer> dminuoso: I'm looking and I feel a bit sick today and I'm not sure if it is:
11:41:40 <carbolymer> >restore ((thing a) `onException` after a)
11:41:40 <carbolymer> or
11:41:40 <carbolymer> >(restore (thing a)) `onException` after a
11:42:10 <dminuoso> https://hackage.haskell.org/package/base-4.15.0.0/docs/src/Control-Exception-Base.html#bracket
11:42:15 <dminuoso> r <- restore (thing a) `onException` after a
11:42:28 <carbolymer> what's the priority of operations?
11:42:48 <carbolymer> restore then onException?
11:43:05 <dminuoso> Not sure what you mean by priority
11:43:28 <carbolymer> which function is invoked last
11:43:47 <dminuoso> Why is the "order" relevant here?
11:43:57 <hpc> you mean fixity?
11:44:00 <carbolymer> yes
11:44:16 <carbolymer> dminuoso: because it answers the question if exceptions are masked in `after`
11:44:27 <dminuoso> Ah you're looking for how this is parsed.
11:44:29 geekosaur joins (~geekosaur@xmonad/geekosaur)
11:44:39 <dminuoso> (restore (thing a)) `onException` after a
11:44:40 <hpc> prefix binds tighter than infix, so f x `op` g y is always (f x) `op` (g y)
11:44:45 <carbolymer> dminuoso: thank you
11:44:52 <carbolymer> hpc: thx
11:44:57 <carbolymer> coffee does not work today
11:45:01 <shapr> not YET
11:45:08 shapr drinks much more coffee
11:45:24 <shapr> violence is like coffee
11:45:31 <shapr> neither of them type check
11:45:38 <hpc> english breakfast tea is the superior wakeup juice :D
11:46:06 <shapr> I choose four cups of death wish cold brew.
11:46:23 <dminuoso> carbolymer: Note, that `restore` does not unmask exceptions, it just restores the previous exception mask before `mask`
11:46:31 <dminuoso> Just adding that side note, in case you're using `bracket` in strange places
11:47:21 × bitdex quits (~bitdex@gateway/tor-sasl/bitdex) (Ping timeout: 276 seconds)
11:48:44 <ldlework> check this out https://i.imgur.com/HkcUQo3.png
11:48:50 <carbolymer> dminuoso: my team is balls deep in a strange issue, "/dev/random: hClose: does not exist (No such file or directory)" - comes from warp-tls, and it freezes processing threads (some resource contention?), and we have no idea why, also we're using ancient linux kernel 3.10
11:49:11 <carbolymer> dminuoso: also profiling makes this bug irreproducible...
11:49:26 bitdex joins (~bitdex@gateway/tor-sasl/bitdex)
11:49:28 <carbolymer> dminuoso: so yeah, we're probably onto some masking weirdness
11:50:01 × __monty__ quits (~toonn@user/toonn) (Quit: Kernel woes : s)
11:50:10 <carbolymer> ldlework: plantuml?
11:51:03 <Cajun> Idlework: seeing UML diagrams for haskell is weeeeird, ive only seen those for lenses! really cool though, it would be interesting to have a really big one of these automatically generated for a given project
11:51:40 <ldlework> carbolymer: yep
11:51:50 <carbolymer> ldlework: written by hand or generated?
11:52:00 × tromp quits (~textual@dhcp-077-249-230-040.chello.nl) (Quit: My iMac has gone to sleep. ZZZzzz…)
11:52:06 <ldlework> carbolymer: written by hand because many typeclasses don't have the proper relationships in code
11:52:44 <ldlework> awpr is going to help flesh it out, I'm just working out the plantuml conventions
11:52:49 <ldlework> i mean, anyone can help
11:52:59 <Cajun> although some parts are inconsistent with the parenthesis and tuples. Foldable as the tuple as `(,) a` and Monad as `((,) a)`
11:53:04 <ldlework> I just fixed that
11:53:08 <Cajun> :)
11:53:19 <ldlework> https://i.imgur.com/eplRSKd.png
11:53:48 viluon joins (uid453725@id-453725.helmsley.irccloud.com)
11:53:54 <Cajun> far right of Functor has a weird > on it
11:54:50 <ldlework> nice
11:55:27 <ldlework> https://i.imgur.com/Ce1zOGK.png
11:55:58 <ldlework> oop missing a comma, guh
11:56:18 <ldlework> Anyway, I eventually want to see how Reader and other typeclasses fit in here
11:58:26 × juhp quits (~juhp@128.106.188.220) (Quit: juhp)
11:58:39 juhp joins (~juhp@128.106.188.220)
12:00:47 × jonathanx quits (~jonathan@dyn-8-sc.cdg.chalmers.se) (Remote host closed the connection)
12:01:03 jonathanx joins (~jonathan@dyn-8-sc.cdg.chalmers.se)
12:06:31 lavaman joins (~lavaman@98.38.249.169)
12:10:07 <ldlework> If anyone wants to help add more typeclasses: https://github.com/dustinlacewell/haskell-typeclass-atlas
12:10:50 × lavaman quits (~lavaman@98.38.249.169) (Ping timeout: 252 seconds)
12:11:27 <ldlework> Cajun, [exa], Cale ^
12:19:45 tromp joins (~textual@dhcp-077-249-230-040.chello.nl)
12:20:49 [itchyjunk] joins (~itchyjunk@user/itchyjunk/x-7353470)
12:21:17 dminuoso is absolutely unsure what the relationship between Foldable and Ord is supposed to be
12:22:41 <ldlework> dminuoso: One of Foldable's methods depends on Ord
12:22:44 × MQ-17J quits (~MQ-17J@d192-24-122-179.try.wideopenwest.com) (Read error: Connection reset by peer)
12:22:48 <dminuoso> Ermm..
12:22:49 <ldlework> maximum/minimum
12:23:06 <ldlework> I'm new to haskell/category theory, so feel free to just chime in
12:23:08 <dminuoso> So?>
12:23:23 <ldlework> dminuoso: it's just meant to demonstrate such a relation
12:23:25 <dminuoso> That doesnt give any relationship between Foldable and Ord, really
12:23:31 <dminuoso> Any meaningful one, anyway
12:24:03 <dminuoso> But Im not sure what this diagram is trying to convey or help with
12:24:05 <ldlework> Like in another case you can easily see that you can use Foldable on Monoid objects
12:24:33 <ldlework> dminuoso: that's fine, others have expressed it could be useful, and personally I'm just looking for a nice reference
12:24:41 <dminuoso> What does "use Foldable on Monoid objects" even mean?
12:25:06 <ldlework> If you have a Monoid you can call `fold` on it
12:25:13 <dminuoso> No, you cant.
12:25:22 <dminuoso> % :t fold
12:25:22 shriekingnoise joins (~shrieking@186.137.144.80)
12:25:22 <yahb> dminuoso: (Foldable t, Monoid m) => t m -> m
12:25:31 <ldlework> Well rather, if you have a Foldable holding a Monad
12:25:38 <ldlework> Monoid*
12:25:41 <dminuoso> `t m` is not "a monoid"
12:25:53 <dminuoso> It's rather the foldable of a monoid can be mappended together.
12:25:54 <ldlework> it's a foldable structuring a monoid
12:25:57 <dminuoso> Sure.
12:26:05 <ldlework> spoke too soon :)
12:26:33 <dminuoso> Like I said, that relationship seems overly arbitrary
12:26:49 <dminuoso> As Monoid is not part of Foldable's description
12:26:56 × bitdex quits (~bitdex@gateway/tor-sasl/bitdex) (Quit: = "")
12:27:00 <ldlework> Sure, that's a different arrow :P
12:27:05 MQ-17J joins (~MQ-17J@8.21.10.6)
12:27:09 <dminuoso> It's rather that `an arbitrary Monoid` is used in some methods.
12:27:24 <ldlework> Foldable has a relation with Monoid that it doesn't have with, say, Applicative
12:27:29 <ldlework> dminuoso: yes
12:27:41 × benin036932301 quits (~benin@183.82.205.89) (Ping timeout: 264 seconds)
12:28:35 <dminuoso> Thing is, it's not really part of Foldable's identity
12:28:45 <ldlework> dminuoso: for context, awpr mentioned that there are some other relationships between typeclasses he wants to show, but as an ignorant neophyte, I don't know what they are - so in trying to accomplish my side of the goal of establishing some plantuml conventions, I just picked this arbitrary thing to test out alternative arrow styles on
12:28:48 <dminuoso> Foldable could be stripped to just `foldr` or `foldl`, or maybe `toListOf`
12:29:01 <dminuoso> So if you look at the *bare* minimum of a class, that's when you begin to realize its characteristics
12:29:16 <ldlework> dminuoso: I tried to think of a good place / good way to show the "minimal" functions but didn't think of anything good yet
12:29:28 <dminuoso> ldlework: you could perhaps make them bold?
12:29:31 <dminuoso> If that works
12:29:45 <ldlework> Yeah, I tried that, but it weakens the bolding in the title
12:29:56 <ldlework> I could make the titles a bigger fontsize
12:30:09 <ldlework> i wonder how underline looks
12:30:20 <dminuoso> ldlework: Anyway. The thing is, the relationship to Monoid is sort of accidental - in the sense that there's a bunch of people that frequently use Monoid to fold something together.
12:30:34 <dminuoso> but Foldable without `fold` and `foldMap` would be just as legit
12:30:41 <ldlework> dminuoso: sure, we're not trying to show the minimal possible amount of information
12:31:00 <ldlework> just trying to demonstrate some useful information among the major typeclasses
12:31:02 <ldlework> btw
12:31:04 <dminuoso> Well, what if there was a *function* using both Foldable and Comonad. Would that mean there had to be an arrow too?
12:31:06 yauhsien joins (~yauhsien@118-167-47-202.dynamic-ip.hinet.net)
12:31:12 <ldlework> if you have any recommendations for other typeclasses you'd like to see on an atlas like this
12:31:20 <ldlework> i'd be very happy to take those
12:31:34 × tromp quits (~textual@dhcp-077-249-230-040.chello.nl) (Quit: My iMac has gone to sleep. ZZZzzz…)
12:31:37 <dminuoso> ldlework: The key thing is, fold/foldMap being actual methods is rather a mechanism allowing for people to provide type specialized optimized versions.
12:31:48 <dminuoso> But its in no way some demonstration of a relationship
12:31:55 <dminuoso> Imagine if `fold` and `foldMap` were just top level functions
12:32:00 <dminuoso> Would you still draw that arrow?
12:32:05 <ldlework> dminuoso: it's just showing "there are some functions on this type, you can use with that type"
12:32:07 <ldlework> nothing more
12:32:17 <ldlework> so you can look at a glance, without inspecting all the functions first
12:32:27 <dminuoso> Sure. Would you draw the arrows if `fold/foldMap` were regular functions?
12:32:37 <ldlework> maybe?
12:32:47 <ldlework> it's not meant to reflect the platonic definition of the thing
12:32:51 <dminuoso> So do you intend to scrape the entirety of hackage to build that model?
12:33:02 <ldlework> no, as it says "subset"
12:33:23 pbrisbin joins (~patrick@pool-173-49-147-250.phlapa.fios.verizon.net)
12:33:46 <ldlework> a difficulty with communicating the minimal function set, is that some of them are defined as OR operators
12:33:59 <ldlework> like for Eq, {-# MINIMAL (==) | (/=) #-}
12:35:57 <ldlework> Could just have a section above the example instances I guess
12:36:05 × yauhsien quits (~yauhsien@118-167-47-202.dynamic-ip.hinet.net) (Ping timeout: 264 seconds)
12:37:11 tromp joins (~textual@dhcp-077-249-230-040.chello.nl)
12:37:40 yauhsien joins (~yauhsien@118-167-47-202.dynamic-ip.hinet.net)
12:37:43 slowButPresent joins (~slowButPr@user/slowbutpresent)
12:46:27 ub joins (~Thunderbi@77.119.204.226.wireless.dyn.drei.com)
12:47:31 doyougnu joins (~user@c-73-25-202-122.hsd1.or.comcast.net)
12:49:23 <ldlework> Added the required functions https://raw.githubusercontent.com/dustinlacewell/haskell-typeclass-atlas/master/atlas.png
12:50:03 wonko joins (~wjc@62.115.229.50)
12:51:05 × ub quits (~Thunderbi@77.119.204.226.wireless.dyn.drei.com) (Ping timeout: 264 seconds)
12:52:15 × jonathanx quits (~jonathan@dyn-8-sc.cdg.chalmers.se) (Remote host closed the connection)
12:52:32 jonathanx joins (~jonathan@dyn-8-sc.cdg.chalmers.se)
12:53:03 × tromp quits (~textual@dhcp-077-249-230-040.chello.nl) (Quit: My iMac has gone to sleep. ZZZzzz…)
12:53:46 × juhp quits (~juhp@128.106.188.220) (Quit: juhp)
12:53:59 juhp joins (~juhp@128.106.188.220)
12:56:47 waleee joins (~waleee@2001:9b0:216:8200:d457:9189:7843:1dbd)
13:04:06 × juhp quits (~juhp@128.106.188.220) (Quit: juhp)
13:04:22 juhp joins (~juhp@128.106.188.220)
13:04:44 × MQ-17J quits (~MQ-17J@8.21.10.6) (Ping timeout: 252 seconds)
13:04:55 <DigitalKiwi> ldlework: are you using haskell out of anger or joy (glad to see you here anyway)
13:05:03 MQ-17J joins (~MQ-17J@8.21.10.6)
13:05:09 <ldlework> joy
13:05:16 <ldlework> i'm pretty confused overall, but i like MLs
13:05:23 <DigitalKiwi> \o/
13:06:07 <ldlework> it's going to take me a really long to meaningfully absorb the principled mathematical stuff behind the typeclasses, but i am working at it
13:07:13 <ldlework> long time*
13:07:39 eggplantade joins (~Eggplanta@2600:1700:bef1:5e10:1c28:7782:3d08:8ee5)
13:07:41 <DigitalKiwi> have you https://github.com/hmemcpy/milewski-ctfp-pdf
13:08:04 <ldlework> no, still working through HFFP
13:08:58 spruit11 joins (~quassel@2a02:a467:ccd6:1:40b2:87e8:dd1:e5c1)
13:09:21 <ldlework> thanks for the link though
13:09:27 <DigitalKiwi> do you mean HPFP or a different one i don't know
13:09:35 × yauhsien quits (~yauhsien@118-167-47-202.dynamic-ip.hinet.net) (Remote host closed the connection)
13:09:48 <DigitalKiwi> oh a different one
13:10:11 <DigitalKiwi> or nvrm i have no idea lol
13:10:47 yauhsien joins (~yauhsien@118-167-47-202.dynamic-ip.hinet.net)
13:10:47 <ldlework> DigitalKiwi: Haskell From First Principles
13:10:51 × yauhsien quits (~yauhsien@118-167-47-202.dynamic-ip.hinet.net) (Remote host closed the connection)
13:11:47 × eggplantade quits (~Eggplanta@2600:1700:bef1:5e10:1c28:7782:3d08:8ee5) (Ping timeout: 246 seconds)
13:12:08 machinedgod joins (~machinedg@135-23-192-217.cpe.pppoe.ca)
13:14:18 yauhsien joins (~yauhsien@118-167-47-202.dynamic-ip.hinet.net)
13:14:29 × juhp quits (~juhp@128.106.188.220) (Quit: juhp)
13:14:37 <DigitalKiwi> lol i think we're talking about the same book but i read it as Haskell Programming from First Principles
13:14:42 juhp joins (~juhp@128.106.188.220)
13:15:38 <viluon> hi, a couple minutes ago I sent an email to haskell-cafe titled "Optimising ReadP," if anyone wants to discuss it here, I'd be happy to
13:15:49 tromp joins (~textual@dhcp-077-249-230-040.chello.nl)
13:17:38 <kuribas> can't wait for merijn to comment :)
13:19:28 × yauhsien quits (~yauhsien@118-167-47-202.dynamic-ip.hinet.net) (Remote host closed the connection)
13:19:48 <merijn> My main comment would be "don't bother, just nuke it from orbit" >.>
13:20:03 yauhsien joins (~yauhsien@118-167-47-202.dynamic-ip.hinet.net)
13:22:19 chris joins (~chris@81.96.113.213)
13:22:24 chris is now known as Guest3409
13:22:53 × spruit11 quits (~quassel@2a02:a467:ccd6:1:40b2:87e8:dd1:e5c1) (Quit: https://quassel-irc.org - Chat comfortably. Anywhere.)
13:25:05 × yauhsien quits (~yauhsien@118-167-47-202.dynamic-ip.hinet.net) (Ping timeout: 252 seconds)
13:29:49 × juhp quits (~juhp@128.106.188.220) (Quit: juhp)
13:30:04 juhp joins (~juhp@128.106.188.220)
13:35:10 × juhp quits (~juhp@128.106.188.220) (Quit: juhp)
13:35:20 <merijn> viluon: Basically, ReadP having garbage performance is well known and it's less effort to just port your parser to another parser combinator library then it is to optimise ReadP
13:35:24 juhp joins (~juhp@128.106.188.220)
13:36:06 <viluon> merijn: thanks, would you happen to know why is the performance so poor?
13:36:09 <geekosaur> ReadP's only saving grace is that it can easily be implemented using only features from base, so it can be used to implement Read instances
13:36:17 <merijn> viluon: Because ReadP supports ambiguous grammars
13:36:30 <merijn> viluon: So it it keeps all possible parse traces around
13:36:36 <viluon> ah
13:36:43 <merijn> viluon: It also operates on String which is a terrible datatype for parsing
13:36:54 <viluon> yes, `String` is awful
13:36:58 <viluon> could you recommend an alternative?
13:37:22 <merijn> viluon: megaparsec is the most feature complete one. Attoparsec is more minimal in case you don't care about error message quality.
13:37:36 <merijn> viluon: Parsec if you need to support ridiculously old code
13:37:42 gioyik joins (~gioyik@gateway/tor-sasl/gioyik)
13:37:48 <viluon> is there something even smaller than attoparsec?
13:37:51 <merijn> But in general megaparsec is the safe bet. Which also lets you parse Text directly
13:37:56 <merijn> viluon: Not really
13:38:00 <dminuoso> attoparsec already is fairly small
13:38:17 <dminuoso> It's dependency footprint is as limited as it can reasonably get
13:38:57 <merijn> But yeah, ReadP is mostly around for stuff like Read (which also has garbage performance >.>)
13:40:44 <merijn> viluon: Compare your numbers with stuff like: https://markkarpov.com/post/megaparsec-more-speed-more-power.html
13:42:03 <[itchyjunk]> wait, i confused myself. haskell functions can only ever take one argument. but i thought we said integers a functions that take no parameters?
13:42:20 <dminuoso> No, we never did.
13:42:25 <[itchyjunk]> oh..
13:42:31 <[itchyjunk]> weren't integers functions?
13:42:32 <dminuoso> And that statement is silly and nonsense.
13:42:34 <dminuoso> No.
13:42:46 <dminuoso> First, what do you mean by "integers" exactly?
13:42:50 <[itchyjunk]> 1
13:42:55 <dminuoso> The expression 1?
13:43:05 <dminuoso> So the expression 1 is a polymorphic value, it's not a function.
13:43:10 <dminuoso> It's type is `Num a => a`
13:43:37 <[itchyjunk]> hmmm
13:44:10 <dminuoso> A function is one that maps values of its domain onto values onto its codomain. For instance, a function `f :: Int -> Char` maps every value of type Int to some value of type Char.
13:44:16 wroathe joins (~wroathe@c-68-54-25-135.hsd1.mn.comcast.net)
13:44:16 × wroathe quits (~wroathe@c-68-54-25-135.hsd1.mn.comcast.net) (Changing host)
13:44:16 wroathe joins (~wroathe@user/wroathe)
13:44:21 <dminuoso> So you see, the phrase "function that takes no parameters" is nonsensical
13:44:41 <shapr> has anyone used dataflower at all?
13:45:07 <shapr> I see many opportunities for timely dataflow in my daily work, but probably would only try such a framework in Haskell
13:45:22 <merijn> [itchyjunk]: See also: http://conal.net/blog/posts/everything-is-a-function-in-haskell
13:46:15 <dminuoso> merijn is a manually driven car, just without any of the metal or plastic stuff.
13:46:32 × nvmd quits (~nvmd@user/nvmd) (Ping timeout: 252 seconds)
13:46:37 bontaq joins (~user@ool-45779fe5.dyn.optonline.net)
13:48:12 nvmd joins (~nvmd@user/nvmd)
13:49:12 jokleinn joins (~jokleinn@user/jokleinn)
13:49:27 <[itchyjunk]> merijn, the "7" being sugar notation for ()->7 being mentioned in that post, isn't that functional notation?
13:49:43 × zaquest quits (~notzaques@5.128.210.178) (Remote host closed the connection)
13:50:46 <[itchyjunk]> i'll read through this first
13:51:25 <merijn> [itchyjunk]: The post mentions that's nonsense too :p
13:51:32 <shapr> I have complaints about haddock, but hoogle still one of the most amazing things in Haskell
13:52:53 × favonia quits (~favonia@user/favonia) (Ping timeout: 264 seconds)
13:52:53 <[itchyjunk]> I'll have to remembe who i discussed it with..
13:53:02 <[itchyjunk]> i thought for sure i talked to someone about this ..
13:53:33 zaquest joins (~notzaques@5.128.210.178)
13:55:34 × tromp quits (~textual@dhcp-077-249-230-040.chello.nl) (Quit: My iMac has gone to sleep. ZZZzzz…)
13:56:29 × jstolarek quits (~jstolarek@erx128.neoplus.adsl.tpnet.pl) (Ping timeout: 264 seconds)
13:59:11 × MQ-17J quits (~MQ-17J@8.21.10.6) (Ping timeout: 252 seconds)
13:59:42 yauhsien joins (~yauhsien@118-167-47-202.dynamic-ip.hinet.net)
14:01:38 <[itchyjunk]> This reminds me of something else i was thinking off and getting really confused about
14:02:33 <[itchyjunk]> someone had told me scalars are just 1 dimentional matrices like [1] and it kinda made snese. but matrix multiplication and scalar multiplication are different beasts..
14:02:40 <[itchyjunk]> maybe i got bamboozeled there too
14:04:31 × nfd quits (~nfd@user/nfd) (Ping timeout: 265 seconds)
14:04:49 <opqdonut> but matrix multiplication for matrices of size 1x1 works exactly like scalar multiplication?
14:05:20 Izem joins (~Izem@bras-base-london1483w-grc-31-74-12-158-179.dsl.bell.ca)
14:06:13 × alx741 quits (~alx741@186.178.109.159) (Ping timeout: 252 seconds)
14:06:23 <opqdonut> even though matrix multiplication isn't commutative _in general_ there are classes of matrices where it is commutative. 1x1 matrices are one example. diagonal matrices are another
14:06:33 <[itchyjunk]> yes but i can take a scalar and multiply it to any sized matrix
14:06:41 <[itchyjunk]> but if 1 is [1], this stops working
14:06:56 <opqdonut> yeah scaling is different
14:07:24 <opqdonut> scaling shouldn't use the same symbol as multiplication, it doesn't even have the same type!
14:07:59 <opqdonut> and e.g. vector spaces have scaling but might not have multiplication
14:10:08 × nshepperd2 quits (~nshepperd@li364-218.members.linode.com) (Quit: Ping timeout (120 seconds))
14:10:22 nshepperd2 joins (~nshepperd@li364-218.members.linode.com)
14:10:53 × Guest3409 quits (~chris@81.96.113.213) (Remote host closed the connection)
14:11:11 SquidDev1 joins (~SquidDev@autoclave.squiddev.cc)
14:11:49 Nahra` joins (~user@static.161.95.99.88.clients.your-server.de)
14:12:16 × ouroboros quits (~ouroboros@user/ouroboros) (Ping timeout: 252 seconds)
14:12:18 Philonous_ joins (~Philonous@user/philonous)
14:12:19 ec joins (~ec@gateway/tor-sasl/ec)
14:12:49 × Nahra quits (~user@static.161.95.99.88.clients.your-server.de) (Ping timeout: 252 seconds)
14:12:49 × Philonous quits (~Philonous@user/philonous) (Ping timeout: 252 seconds)
14:12:49 × sweater quits (~sweater@206.81.18.26) (Ping timeout: 252 seconds)
14:13:20 joeyh_ joins (~joeyh@kitenet.net)
14:13:22 × jlamothe quits (~jlamothe@104.158.48.100) (Ping timeout: 252 seconds)
14:13:22 × jonatan quits (~nate@h85-8-60-194.cust.a3fiber.se) (Ping timeout: 252 seconds)
14:13:22 × clever quits (~clever@99.192.114.98) (Ping timeout: 252 seconds)
14:13:22 × SquidDev quits (~SquidDev@autoclave.squiddev.cc) (Ping timeout: 252 seconds)
14:13:22 × joeyh quits (~joeyh@kitenet.net) (Ping timeout: 252 seconds)
14:13:22 SquidDev1 is now known as SquidDev
14:13:54 jonatan joins (~nate@h85-8-60-194.cust.a3fiber.se)
14:14:14 jlamothe joins (~jlamothe@104.158.48.100)
14:14:30 sweater joins (~sweater@206.81.18.26)
14:14:46 × hendursa1 quits (~weechat@user/hendursaga) (Quit: hendursa1)
14:15:10 hendursaga joins (~weechat@user/hendursaga)
14:17:59 chris joins (~chris@81.96.113.213)
14:18:03 chris is now known as Guest250
14:18:27 ouroboros joins (~ouroboros@user/ouroboros)
14:18:48 × gioyik quits (~gioyik@gateway/tor-sasl/gioyik) (Ping timeout: 276 seconds)
14:19:07 alx741 joins (~alx741@186.178.109.225)
14:19:40 clever joins (~clever@99.192.114.98)
14:20:22 <viluon> merijn: I switched to attoparsec, getting the total runtime from 100 ms to 80. 21% of allocations happen in `decimal.step` (from `Data.Attoparsec.Text`), again a generic definition I cannot specialise as it lacks an `INLINE(ABLE)` pragma
14:20:51 <merijn> Which optimisation level?
14:21:05 × acidjnk quits (~acidjnk@p200300d0c703cb44319f4c33bc64626e.dip0.t-ipconnect.de) (Ping timeout: 246 seconds)
14:21:26 × Vajb quits (~Vajb@hag-jnsbng11-58c3a8-176.dhcp.inet.fi) (Read error: Connection reset by peer)
14:21:34 <merijn> And why do you think 1) inlining will avoid allocations and 2) the allocations need to be avoided to speed things up?
14:22:53 × Guest250 quits (~chris@81.96.113.213) (Ping timeout: 264 seconds)
14:23:24 gioyik joins (~gioyik@gateway/tor-sasl/gioyik)
14:24:56 × waleee quits (~waleee@2001:9b0:216:8200:d457:9189:7843:1dbd) (Ping timeout: 246 seconds)
14:24:59 Vajb joins (~Vajb@2001:999:63:cb56:7735:f6b9:cd89:d4c7)
14:26:07 chris joins (~chris@81.96.113.213)
14:26:11 chris is now known as Guest9962
14:27:09 waleee joins (~waleee@h-98-128-228-119.NA.cust.bahnhof.se)
14:27:21 maroloccio joins (~marolocci@93-142-92-177.adsl.net.t-com.hr)
14:27:52 <lortabac> merijn: inlining in GHC includes beta reduction, so it can save allocations in some cases
14:28:18 × n3t quits (n3t@s45.mydevil.net) (Read error: Connection reset by peer)
14:28:26 × shapr quits (~user@pool-100-36-247-68.washdc.fios.verizon.net) (Ping timeout: 246 seconds)
14:28:35 <viluon> merijn: oxygen (`-O2`). With `ReadP` (or rather the `Lex` utilities), specialising them to `Int` helped. Granted, `decimal.step` is only 8.9% of total time, bigger cost-centres are `>>=.\.succ'` (35.9% time, 30.5% alloc), `>>=.\` (16% time, 17.5% alloc), `fmap.\` (11.0% time, 9.6% alloc), and `fmap.\.succ'` (9.3% time, 11.1% alloc). These are all from `Data.Attoparsec.Internal.Types`.
14:28:36 <viluon> I don't have a good model of what optimisations could help here, getting one is part of the motivation for this experiment. I'm surprised that the potentially very powerful specialisation and inlining directives are so limited in practical uses.
14:29:23 n3t joins (n3t@s45.mydevil.net)
14:30:22 <viluon> in any case, I still think the parser creates a lot of garbage. I'd at least like to find out what that garbage is; I'll try heap profiling next.
14:30:41 × lbseale quits (~lbseale@user/ep1ctetus) (Ping timeout: 264 seconds)
14:31:08 <merijn> What's the problem with lots of garbage, though?
14:31:11 <merijn> Garbage is cheap
14:31:29 <merijn> So is allocation
14:31:34 <merijn> It's non-garbage you gotta worry about
14:31:41 × rond_ quits (~rond_@2a02:a31a:a23c:f480:2fd7:e087:5546:a438) (Quit: Client closed)
14:32:35 <viluon> I use `IntMap (Set Int)` to represent a directed graph
14:33:24 <merijn> Also, on what sorta input? You mention 80ms parse, why is that a problem?
14:33:35 <viluon> if the parser first builds the entirety of it as a `[(Int, Int)]` and then converts to the map with a `foldl'`, I wasted a lot of time allocating garbage and then traversing a cache-unfriendly data structure
14:33:49 <merijn> Like, there's a lot of missing information about what you're trying to optimise, with what goal
14:34:16 <merijn> viluon: Allocating garbage is cheap, though
14:34:34 <viluon> no it's not
14:34:39 <merijn> viluon: You gotta abandon any notion about cost of allocation you have from C/Rust
14:34:44 <viluon> the Rust implementation finishes this test case under 10ms
14:34:51 <merijn> GHC's alloation is *really* cheap
14:35:17 <merijn> The fact that the attoparsec parser is slower doesn't necessarily mean it's the allocation that's causing that
14:35:35 <merijn> Boxing alone will cost you a bunch of performance compared to Rust
14:35:53 <viluon> i don't really mind if it's allocation or some other thing, I just want to speed it up
14:36:02 <viluon> although I am interested in laziness pitfalls
14:36:21 <merijn> viluon: Well, you haven't pasted any code nor profiling output, so that's gonna limit how much useful feedback you get
14:36:58 <viluon> it's a topological sorting implementation that spends 80+% of the time loading input
14:37:02 lbseale joins (~lbseale@user/ep1ctetus)
14:37:40 <merijn> That's nice. But that's entirely useless information for getting feedback on how you might speed things up
14:37:52 Sgeo joins (~Sgeo@user/sgeo)
14:38:12 <viluon> alright, I'll share the code
14:38:29 <merijn> All I've seen is some random function names and allocation/time percentages. I mean, what do you expect people to comment on that?
14:38:51 flouflou joins (~flouflou@modemcable032.110-177-173.mc.videotron.ca)
14:38:57 × ec quits (~ec@gateway/tor-sasl/ec) (Ping timeout: 276 seconds)
14:39:12 <merijn> If you wanna be fast, you probably wanna use a Vector based datatype that's filled incrementally from attoparsec, rather than IntMap (Set Int)
14:39:15 <viluon> not random: they come from a supposedly widely used library
14:39:48 <viluon> "These are all from `Data.Attoparsec.Internal.Types`"
14:39:50 <merijn> viluon: Allocation percentage of "fmap" is meaningless without code
14:40:04 × lbseale quits (~lbseale@user/ep1ctetus) (Remote host closed the connection)
14:40:29 lbseale joins (~lbseale@user/ep1ctetus)
14:40:42 <viluon> here's the code: https://paste.tomsmeding.com/4G0bpLx7
14:41:23 <viluon> I don't want to sound ungrateful, I really appreciate you taking the time to answer my questions!
14:42:50 <merijn> viluon: Inst has boxed ints, which you probably don't want, that build in parse' also seems a candidate for a lot of blow up
14:43:14 <merijn> viluon: Can't you replace the Set with an (optionally) sorted unboxed Vector?
14:43:44 <viluon> it is inlined and uses a strict fold, `parse'` doesn't show up in top cost centres
14:44:33 <merijn> viluon: My point is that IntMap + Set is gonna be pretty horrible for accessing a static graph
14:44:49 <merijn> I'm pretty sure the Rust version doesn't do that and uses an array based representation like CSR
14:45:21 <merijn> And there's no real reason you couldn't use the same thing in Haskell
14:45:28 <viluon> sure, but does that matter?
14:45:45 <viluon> these are the top cost centres https://paste.tomsmeding.com/26S86CNo
14:46:57 ec joins (~ec@gateway/tor-sasl/ec)
14:47:02 <merijn> viluon: btw, note that your use of strict state is mostly useless as all the elements in the tuple are still lazy
14:47:52 <viluon> tbf, the test case I'm running this on may be one where the interesting portion of the digraph lies in a small connected component, so time is spent when processing input but most of it is ignored by the DFS
14:48:55 favonia joins (~favonia@user/favonia)
14:48:56 × Vajb quits (~Vajb@2001:999:63:cb56:7735:f6b9:cd89:d4c7) (Read error: Connection reset by peer)
14:49:27 <merijn> viluon: What's the output of running with: +RTS -sstderr
14:49:47 × jacks2 quits (~bc8165b6@217.29.117.252) (Quit: http://www.okay.uz/ (Session timeout))
14:49:48 Vajb joins (~Vajb@hag-jnsbng11-58c3a8-176.dhcp.inet.fi)
14:50:00 × gioyik quits (~gioyik@gateway/tor-sasl/gioyik) (Ping timeout: 276 seconds)
14:50:49 × Guest9962 quits (~chris@81.96.113.213) (Remote host closed the connection)
14:52:51 <viluon> here's the profiling result for a more comprehensive test case: https://paste.tomsmeding.com/RTMOuOID Rust 26.6 ms ± 1.7 ms, Haskell 1.058 s ± 0.054 s. Of course it's far from a fair comparison as both implementations use different approaches, but as the cost centres show, the majority of time is again spent in the parser
14:53:12 <viluon> I should profile the Rust implementation too I think
14:54:08 <merijn> Also, are you comparing apples-to-apples? Attoparsec Text does full unicode
14:54:24 <viluon> apples-to-apples? Definitely not
14:54:26 <merijn> If the Rust one is only doing ascii, you might wanna compare with the ByteString one
14:54:47 <merijn> Because a full unicode parser is obviously gonna be slower than a narrow ascii only one
14:55:26 <viluon> I don't care too much really, the Rust implementation isn't mine. A friend wrote it, then I wrote the Haskell one, and I'm embarrassed that mine is orders of magnitude slower
14:56:00 <viluon> but I also want to take this opportunity to investigate how often does laziness get in the way of productivity and get an idea of where could GHC improve its optimisation efforts
14:57:05 <viluon> here's the RTS report as you requested. Again, thanks for all your feedback, questions and suggestions! https://paste.tomsmeding.com/sie584Ts
14:57:32 × Izem quits (~Izem@bras-base-london1483w-grc-31-74-12-158-179.dsl.bell.ca) (Quit: Izem)
14:57:37 <merijn> Who says the problem here is laziness, though? Or allocation, or inlining as you implied at the start
14:57:40 <merijn> ok
14:57:44 <merijn> So, that is a clear sign
14:57:48 Izem joins (~Izem@bras-base-london1483w-grc-31-74-12-158-179.dsl.bell.ca)
14:57:55 <merijn> Productivity 57% <- this is garbage
14:58:07 Guest6237 joins (~chris@81.96.113.213)
14:58:11 hnOsmium0001 joins (uid453710@id-453710.hampstead.irccloud.com)
14:58:17 ysh joins (sid6017@id-6017.ilkley.irccloud.com)
14:58:21 <merijn> Productivity should be 80-90%. So that means you're keeping data alive too long
14:59:08 <viluon> > Who says the problem here is laziness, though? Or allocation, or inlining as you implied at the start
14:59:08 <viluon> I didn't, I'm trying to find out
14:59:10 <lambdabot> <hint>:1:38: error: parse error on input ‘,’
14:59:17 <viluon> whoops, sorry lambdabot
15:00:04 <merijn> viluon: anyway, so currently you're parsing the entire input into a list of Inst, then traversing the list with your solver
15:00:34 <merijn> That's a lot of data to be live, which would explain the garbage productivity
15:01:11 <merijn> So I would see what happens if you run the solver immediately when you finish parsing one Inst, so you only have 1 Inst at a time
15:01:22 <viluon> the list of problem instances (hence `Inst`) isn't longer than 100 elements
15:01:24 <merijn> i.e. parse Inst, solve, continue
15:01:27 × jonathanx quits (~jonathan@dyn-8-sc.cdg.chalmers.se) (Remote host closed the connection)
15:01:47 <merijn> viluon: But each of those elements has an "IntMap (Set Int)" they keep alive
15:01:53 <viluon> yes
15:02:14 × [itchyjunk] quits (~itchyjunk@user/itchyjunk/x-7353470) (Read error: Connection reset by peer)
15:02:23 × Guest6237 quits (~chris@81.96.113.213) (Ping timeout: 246 seconds)
15:02:26 <merijn> viluon: In GHC GC cost is proportional to amount of live data
15:02:54 ikex1 joins (~ash@user/ikex)
15:02:57 <merijn> So keeping those alive a long time increases the GC cost. If you can turn them into garbage asap (by solving immediately) GC cost goes down and productivity goes up
15:03:42 <merijn> Currently 40% of your runtime is running the GC
15:03:58 × ikex quits (ash@user/ikex) (Ping timeout: 252 seconds)
15:03:58 ikex1 is now known as ikex
15:04:08 <merijn> So you wanna improve the rate at which you turn things into garbage
15:04:17 <viluon> hmm, concerning
15:04:34 <viluon> "So I would see what happens if you run the solver immediately when you finish parsing one Inst, so you only have 1 Inst at a time" <- is there a way to do that without modifying the code?
15:05:21 <viluon> is there anything in my implementation that requires GHC to produce code that first parses everything and then processes one-by-one?
15:05:24 <merijn> viluon: On line 38, instead of returning the Inst, just call your solve function there?
15:05:35 <merijn> viluon: Yes
15:06:13 <merijn> viluon: Your "parse" has to consume the entire input and turn it into a list to know if the parse succeeds
15:06:57 <merijn> viluon: Alternatively you'd want one of the streaming libraries to interleave parsing Inst instance and solving them, which would also enforce the "1 element at a time"
15:07:15 x28girl joins (~x28girl@user/x28girl)
15:08:02 shapr joins (~user@pool-100-36-247-68.washdc.fios.verizon.net)
15:08:03 <merijn> viluon: For cases like this where you're mostly parsing a stream of inputs and processing them, streaming libraries like conduit/pipes/etc. help interleave the IO/parsing and processing
15:08:09 gioyik joins (~gioyik@gateway/tor-sasl/gioyik)
15:08:51 × ec quits (~ec@gateway/tor-sasl/ec) (Ping timeout: 276 seconds)
15:09:17 <merijn> (of course, that's a bit more boilerplate to set up)
15:09:31 eggplantade joins (~Eggplanta@2600:1700:bef1:5e10:1c28:7782:3d08:8ee5)
15:09:38 <viluon> I changed the definition of `solve` to `solve = fromMaybe [] . maybeResult . Attoparsec.parse (fmap solve' <$> parse) <$> Text.getContents`
15:10:15 × yauhsien quits (~yauhsien@118-167-47-202.dynamic-ip.hinet.net) (Remote host closed the connection)
15:10:19 <merijn> Not sure that's gonna help with the double fmap, but it might
15:10:49 yauhsien joins (~yauhsien@118-167-47-202.dynamic-ip.hinet.net)
15:11:38 <viluon> it did not
15:12:02 <viluon> but now there's no reason to parse everything at once, is there?
15:12:13 <monochrom> Absolutely no reason.
15:14:29 × eggplantade quits (~Eggplanta@2600:1700:bef1:5e10:1c28:7782:3d08:8ee5) (Ping timeout: 264 seconds)
15:15:00 <monochrom> Lately I wrote my own "parser" monad that restores laziness by sacrificing error checking. The use case is that there won't be parse errors anyway.
15:15:17 × maroloccio quits (~marolocci@93-142-92-177.adsl.net.t-com.hr) (Quit: WeeChat 3.0)
15:15:21 × gioyik quits (~gioyik@gateway/tor-sasl/gioyik) (Ping timeout: 276 seconds)
15:15:55 <monochrom> Therefore one point is that "String -> []/Maybe (String, a)" is reduced to "String -> (String, a)". (This is not compulsory.)
15:16:00 ec joins (~ec@gateway/tor-sasl/ec)
15:16:03 × oxide quits (~lambda@user/oxide) (Ping timeout: 265 seconds)
15:17:12 ub joins (~Thunderbi@77.119.204.226.wireless.dyn.drei.com)
15:17:42 oxide joins (~lambda@user/oxide)
15:18:04 <monochrom> The second point is I define "later (P f) = P (\s -> case f s of ~(s2, a) -> (s2, a))"
15:18:33 <monochrom> Note how it increases laziness at the right place.
15:19:01 Guest70 joins (~Guest70@p200300f7770a55e9b9601923eb36d679.dip0.t-ipconnect.de)
15:19:09 <monochrom> And it is analogous to unsafeInterleaveIO.
15:19:25 × yauhsien quits (~yauhsien@118-167-47-202.dynamic-ip.hinet.net) (Remote host closed the connection)
15:20:27 <monochrom> So now I can have my own lazier version of replicateM. rep n p = do { x <- p; xs <- later (rep (n-1) p); pure (x:xs) }
15:20:49 <ldlework> nerd
15:21:08 × wroathe quits (~wroathe@user/wroathe) (Ping timeout: 252 seconds)
15:21:16 <monochrom> This will run x<-p, jump ahead to "pure (x:xs)", and delay running rep (n-1) p until you force xs.
15:22:14 × ub quits (~Thunderbi@77.119.204.226.wireless.dyn.drei.com) (Ping timeout: 252 seconds)
15:22:17 × merijn quits (~merijn@83-160-49-249.ip.xs4all.nl) (Ping timeout: 264 seconds)
15:22:26 <monochrom> Alternatively, you can decide to make this pervasive, and build the ~(s2, a) lazy pattern right in the definition of >>=. This is what Control.Monad.Trans.State.Lazy does.
15:22:56 <monochrom> So every m>>=cb is effectively m>>=\a->later(cb a)
15:23:15 gioyik joins (~gioyik@gateway/tor-sasl/gioyik)
15:24:13 <viluon> merijn: any other suggestions? I don't want to introduce a streaming library for something that should not have these performance issues in the first place and I don't like the idea of changing my input parser into a solver – I want reusable code, and I'd like it to perform well when I compose it with other code. Sadly the optimiser is a black box and its decisions are unknowable to me
15:24:45 chris joins (~chris@81.96.113.213)
15:24:49 chris is now known as Guest8849
15:26:13 <viluon> oh wait, merijn is gone
15:28:21 × gioyik quits (~gioyik@gateway/tor-sasl/gioyik) (Ping timeout: 276 seconds)
15:30:14 × lortabac quits (~lortabac@2a01:e0a:541:b8f0:4252:bf51:4908:8ea0) (Quit: WeeChat 2.8)
15:30:19 mikoto-chan joins (~mikoto-ch@ip-83-134-2-136.dsl.scarlet.be)
15:34:12 × gehmehgeh quits (~user@user/gehmehgeh) (Ping timeout: 276 seconds)
15:35:18 gehmehgeh joins (~user@user/gehmehgeh)
15:35:33 × jpds quits (~jpds@gateway/tor-sasl/jpds) (Remote host closed the connection)
15:35:51 <Izem> How do you say `reads :: (Read a) => ReadS a` in English? reads has type ...
15:35:53 jpds joins (~jpds@gateway/tor-sasl/jpds)
15:36:39 <monochrom> ReadS a, but a has to be an instance of Read
15:36:39 × jpds quits (~jpds@gateway/tor-sasl/jpds) (Remote host closed the connection)
15:36:54 <monochrom> Frankly I wouldn't translate to English.
15:36:59 jpds joins (~jpds@gateway/tor-sasl/jpds)
15:37:03 × Guest70 quits (~Guest70@p200300f7770a55e9b9601923eb36d679.dip0.t-ipconnect.de) (Quit: Client closed)
15:37:08 × cfricke quits (~cfricke@user/cfricke) (Quit: WeeChat 3.2.1)
15:37:26 × jpds quits (~jpds@gateway/tor-sasl/jpds) (Remote host closed the connection)
15:37:34 <monochrom> It is fair to ask how to work with that type, and how to write your own.
15:37:46 jpds joins (~jpds@gateway/tor-sasl/jpds)
15:37:51 <monochrom> "how to translate to English" is an XY problem.
15:37:59 × jpds quits (~jpds@gateway/tor-sasl/jpds) (Remote host closed the connection)
15:38:04 wroathe joins (~wroathe@c-68-54-25-135.hsd1.mn.comcast.net)
15:38:04 × wroathe quits (~wroathe@c-68-54-25-135.hsd1.mn.comcast.net) (Changing host)
15:38:04 wroathe joins (~wroathe@user/wroathe)
15:38:18 jpds joins (~jpds@gateway/tor-sasl/jpds)
15:38:18 <monochrom> If programming were better off in English, we would all be in a #cobol channel already.
15:38:27 × jpds quits (~jpds@gateway/tor-sasl/jpds) (Remote host closed the connection)
15:39:05 jpds joins (~jpds@gateway/tor-sasl/jpds)
15:39:21 <monochrom> This is why I wrote http://www.vex.net/~trebla/haskell/prerequisite.xhtml
15:40:01 <monochrom> Use your algebra skills, so you are free of the clumsiness of English when code gets real.
15:41:12 × jpds quits (~jpds@gateway/tor-sasl/jpds) (Remote host closed the connection)
15:41:30 <monochrom> English is not compositional. Programming languages are. This is not just Haskell. You can also have "daunting" types and terms in Java and C.
15:41:32 jpds joins (~jpds@gateway/tor-sasl/jpds)
15:42:03 × x28girl quits (~x28girl@user/x28girl) (Remote host closed the connection)
15:42:47 x28girl joins (~x28girl@user/x28girl)
15:43:01 × wroathe quits (~wroathe@user/wroathe) (Ping timeout: 252 seconds)
15:43:05 × jpds quits (~jpds@gateway/tor-sasl/jpds) (Remote host closed the connection)
15:43:25 jpds joins (~jpds@gateway/tor-sasl/jpds)
15:43:33 × x28girl quits (~x28girl@user/x28girl) (Remote host closed the connection)
15:44:05 jakalx parts (~jakalx@base.jakalx.net) (Error from remote client)
15:45:27 chronon joins (~chronon@user/chronon)
15:45:33 × doyougnu quits (~user@c-73-25-202-122.hsd1.or.comcast.net) (Remote host closed the connection)
15:45:50 doyougnu joins (~user@c-73-25-202-122.hsd1.or.comcast.net)
15:49:46 <viluon> is there a way to get a more detailed heap profile? the cost centres in the default `-hc` report just end with `...`
15:49:56 merijn joins (~merijn@83-160-49-249.ip.xs4all.nl)
15:50:10 <viluon> wb merijn
15:50:50 × jokleinn quits (~jokleinn@user/jokleinn) (Ping timeout: 252 seconds)
15:50:54 × jpds quits (~jpds@gateway/tor-sasl/jpds) (Remote host closed the connection)
15:51:13 jpds joins (~jpds@gateway/tor-sasl/jpds)
15:51:27 jokleinn joins (~jokleinn@user/jokleinn)
15:51:47 × xiongxin quits (~quassel@119.123.102.205) (Quit: https://quassel-irc.org - Chat comfortably. Anywhere.)
15:51:48 × jpds quits (~jpds@gateway/tor-sasl/jpds) (Remote host closed the connection)
15:52:35 × qbt quits (~edun@user/edun) (Quit: Leaving)
15:53:09 yauhsien joins (~yauhsien@118-167-47-202.dynamic-ip.hinet.net)
15:53:18 jakalx joins (~jakalx@base.jakalx.net)
15:53:28 jpds joins (~jpds@gateway/tor-sasl/jpds)
15:54:32 yinghua joins (~yinghua@2800:2121:1400:1db:705e:acf0:71e7:8a79)
15:54:41 × merijn quits (~merijn@83-160-49-249.ip.xs4all.nl) (Ping timeout: 252 seconds)
15:55:40 × mikoto-chan quits (~mikoto-ch@ip-83-134-2-136.dsl.scarlet.be) (Ping timeout: 252 seconds)
15:56:14 mikoto-chan joins (~mikoto-ch@ip-83-134-2-136.dsl.scarlet.be)
15:56:45 __monty__ joins (~toonn@user/toonn)
15:58:32 × yauhsien quits (~yauhsien@118-167-47-202.dynamic-ip.hinet.net) (Ping timeout: 252 seconds)
16:03:50 gioyik joins (~gioyik@gateway/tor-sasl/gioyik)
16:04:29 × chele quits (~chele@user/chele) (Remote host closed the connection)
16:05:14 × Guest8849 quits (~chris@81.96.113.213) (Remote host closed the connection)
16:06:00 × pavonia quits (~user@user/siracusa) (Quit: Bye!)
16:08:17 lavaman joins (~lavaman@98.38.249.169)
16:12:42 chris joins (~chris@81.96.113.213)
16:12:46 chris is now known as Guest2529
16:12:50 × lavaman quits (~lavaman@98.38.249.169) (Ping timeout: 252 seconds)
16:14:30 × gioyik quits (~gioyik@gateway/tor-sasl/gioyik) (Ping timeout: 276 seconds)
16:17:14 × Guest2529 quits (~chris@81.96.113.213) (Ping timeout: 252 seconds)
16:17:19 zebrag joins (~chris@user/zebrag)
16:17:28 tzh joins (~tzh@c-24-21-73-154.hsd1.or.comcast.net)
16:19:07 gioyik joins (~gioyik@gateway/tor-sasl/gioyik)
16:28:42 tommd joins (~tommd@75-164-130-101.ptld.qwest.net)
16:31:02 nfd joins (~nfd@user/nfd)
16:31:15 cfricke joins (~cfricke@user/cfricke)
16:34:50 × nschoe quits (~quassel@178.251.84.79) (Ping timeout: 265 seconds)
16:35:14 nschoe joins (~quassel@178.251.84.79)
16:36:42 × jokleinn quits (~jokleinn@user/jokleinn) (Quit: WeeChat 3.2)
16:45:06 rond_ joins (~rond_@2a02:a31a:a23c:f480:2fd7:e087:5546:a438)
16:50:16 bonizzi joins (~bonizzi@2804:14c:65d3:4689:d52e:1289:d36a:ed19)
16:50:30 × juhp quits (~juhp@128.106.188.220) (Quit: juhp)
16:50:43 juhp joins (~juhp@128.106.188.220)
16:51:00 × on^ quits (~on@12.203.127.82) (Remote host closed the connection)
16:52:53 _ht joins (~quassel@82-169-194-8.biz.kpn.net)
16:57:04 × raehik quits (~raehik@cpc95906-rdng25-2-0-cust156.15-3.cable.virginm.net) (Ping timeout: 265 seconds)
16:57:45 raehik joins (~raehik@cpc95906-rdng25-2-0-cust156.15-3.cable.virginm.net)
16:57:52 × Izem quits (~Izem@bras-base-london1483w-grc-31-74-12-158-179.dsl.bell.ca) (Quit: Izem)
16:58:08 Izem joins (~Izem@bras-base-london1483w-grc-31-74-12-158-179.dsl.bell.ca)
17:00:41 eggplantade joins (~Eggplanta@2600:1700:bef1:5e10:1c28:7782:3d08:8ee5)
17:01:47 × cfricke quits (~cfricke@user/cfricke) (Ping timeout: 252 seconds)
17:02:12 × nschoe quits (~quassel@178.251.84.79) (Quit: https://quassel-irc.org - Chat comfortably. Anywhere.)
17:02:18 dsrt^ joins (~dsrt@12.203.127.82)
17:07:49 × geekosaur quits (~geekosaur@xmonad/geekosaur) (Remote host closed the connection)
17:10:01 geekosaur joins (~geekosaur@xmonad/geekosaur)
17:16:41 <dminuoso> monochrom: In English you can compose almost any two sentences, irrespective of whether it's sensible. There's also a man in the shadows with a gun in his eye.
17:17:54 <dminuoso> Izem: I would read that as: forall a, where Read a, reads has type ReadS a.
17:19:16 <dminuoso> monochrom: Im not sure how you teach Haskell, but I think having some uniform way to read out types can be useful at the beginning. It makes answering the question "what is the type of `xyz`" more sensible in a teaching scenario.
17:19:54 <monochrom> I teach how to break it up.
17:20:14 <dminuoso> I dont think of that above type signature as complicated enough to warrant breaking it up..
17:20:39 <monochrom> And the role of each part.
17:20:42 <Izem> dminuoso: Is a an instance of Read?
17:20:53 <dminuoso> Izem: It's *required* to have one.
17:21:01 × eggplantade quits (~Eggplanta@2600:1700:bef1:5e10:1c28:7782:3d08:8ee5) (Remote host closed the connection)
17:21:21 <dminuoso> Izem: The thing with type variables is, the caller/user picks them. They are free to pick *any* type they want for them, as long as the specified constraints are satisfied.
17:21:58 <dminuoso> So the user of `reads` can/has to pick any type they want, but their choice is limited to any type for which an `instance Read` exists.
17:22:20 <Izem> ok
17:22:24 <dminuoso> And its polymorphic. Hence my way of phrasing it "forall a, where Read a, reads has type ReadS a"
17:22:32 <dminuoso> similarly:
17:22:34 <dminuoso> % :t id
17:22:34 <yahb> dminuoso: a -> a
17:23:05 <dminuoso> Id say `id :: a -> a` as "forall a, id has type a to a"
17:23:07 <Izem> id is in the environment already?
17:23:21 <Izem> what does it do?
17:23:27 <monochrom> I teach =>-less types first. That already is a long story on its own. There is parametric polymorphism. There is X->Y and X1->X2->Y, and I spend time showing that it means X1->(X2->Y), how it plays well with (f x1) x2, why it is useful.
17:24:08 <dminuoso> Izem: `id` is a function that is made available in Prelude. It's one of the most simplistic functions you can think of, it just returns its argument.
17:24:20 <Izem> ok
17:24:25 <monochrom> After that, one is ready for classes and instances. After knowing classes and instances, "Read a =>" is not a mystery.
17:24:51 <awpr> personally I pronounce the typeclass constraint arrow and the function arrow both as just "arrow". they're almost the same thing anyway, just that => takes Constraints on the lhs, is invisible/auto-solved in expressions, and is very enthusiastic to specialize
17:24:56 <dminuoso> monochrom: Makes perfect sense. Perhaps I missed something, I had not conversed with Izem before.
17:25:00 <monochrom> My view is that a plea for "what is it in English" stems from having none of the above preparation at all.
17:25:05 <dminuoso> Judging by just that question, it seemed fair to ask.
17:25:26 <awpr> but admittedly for learning it's probably easier to think of constraints as restrictions on allowable types
17:25:27 <dminuoso> But if you have had prior interaction and knew their level of expertise (which perhaps is lower than I assumed)..
17:25:50 <monochrom> As I said, the real question behind is fair to ask. The translation quesiton is an XY problem. Lots of students do it.
17:27:03 asivitz joins (uid178348@id-178348.tinside.irccloud.com)
17:27:27 <dminuoso> awpr: Mmm, I dont think of the constraint arrow and function arrows as the same thing simply because they happen in different places.
17:27:36 <dminuoso> One is a type checker level thing, the other is a runtime thing.
17:27:47 <dminuoso> To equate them seems dangerously confusing.
17:27:56 <awpr> they're both a runtime thing, unless GHC optimizes the constraint away
17:28:21 <awpr> but GHC could equally well optimize away a function arrow, e.g. in spec-constr optimization
17:28:28 <dminuoso> No it's still a type checking thing.
17:28:34 econo joins (uid147250@user/econo)
17:28:40 <awpr> deciding what value to pass is a type-checker thing
17:29:08 <monochrom> At any rate, I had already provided a translation before I explained why I objected.
17:29:16 <awpr> actually receiving the instance dictionary is a runtime thing
17:29:23 <dminuoso> monochrom: oh, I think I missed that singular line when I scrolled.
17:29:29 × Izem quits (~Izem@bras-base-london1483w-grc-31-74-12-158-179.dsl.bell.ca) (Quit: Izem)
17:29:29 <monochrom> But here is the thing.
17:29:55 <dminuoso> awpr: instance dictionary is an implementation detail.
17:30:06 <awpr> heap object is an implementation detail
17:30:08 <monochrom> If you don't have the prerequisite, the translation adds no predictive power. It is "helpful" only in the sense that it makes you feel good.
17:30:13 <dminuoso> Yes, and I dont talk about heap objects. Your point being?
17:30:33 <monochrom> If you have the prerequisite, you won't be asking in the first place. My students certainly don't.
17:30:34 <awpr> they're still exactly the same construct at runtime, modulo optimizations
17:31:09 <awpr> the only difference is in how it's determined at a given callsite what argument is actually passed
17:31:37 <awpr> for (->) it's a visible argument, and for (=>) it's solved by constraint resolution
17:31:38 <monochrom> Even when they're lost, my students ask more to-the-point questions, such as "what does the 'Read a =>' thing mean" or "where can I find out more about Read".
17:31:38 Izem joins (~Srain@bras-base-london1483w-grc-31-74-12-158-179.dsl.bell.ca)
17:31:59 Izem parts (~Srain@bras-base-london1483w-grc-31-74-12-158-179.dsl.bell.ca) ()
17:32:33 <dminuoso> awpr: It starts being wrong already because of MMR.
17:32:55 <dminuoso> Which is not just some "modulo optimization", its a builtin language feature with defined semantics
17:32:55 lavaman joins (~lavaman@98.38.249.169)
17:33:56 <awpr> monomorphism restriction just constrains inferred types, no?
17:34:25 <awpr> if the monomorphism restriction affects an expression, then its type doesn't involve a constraint anyway
17:34:28 <dminuoso> It's to faciliate sharing
17:34:40 <dminuoso> hold on
17:34:52 <dminuoso> why doesnt it involve a constraint anyway?
17:35:01 × azimut quits (~azimut@gateway/tor-sasl/azimut) (Remote host closed the connection)
17:35:02 <awpr> because it's been monomorphized
17:35:06 <dminuoso> So?
17:35:19 <dminuoso> Num Int is a valid constraint to write, if you want.
17:35:22 azimut joins (~azimut@gateway/tor-sasl/azimut)
17:35:37 <awpr> yes, but that constraint isn't part of the inferred type, it's solved immediately
17:36:14 <dminuoso> So MMR makes this imaginary function go away?
17:36:15 ub joins (~Thunderbi@77.119.204.226.wireless.dyn.drei.com)
17:36:24 × gioyik quits (~gioyik@gateway/tor-sasl/gioyik) (Ping timeout: 276 seconds)
17:36:31 <dminuoso> So `Num Int => ...` is not a "function" but `Num a => ...` is?
17:36:54 <awpr> there are two expressions that are relevant: the thing that causes the Num constraint, and the larger expression affected by MMR
17:37:00 <dminuoso> I dont know, not sure what valuable insights you can gain from thinking of => as a function arrow.
17:37:26 MQ-17J joins (~MQ-17J@d192-24-122-179.try.wideopenwest.com)
17:38:48 jstolarek joins (~jstolarek@erx128.neoplus.adsl.tpnet.pl)
17:39:40 <awpr> the effect of MMR is just that the inferred type is monomorphized, which usually results in the constraint solver being able to solve and immediately apply the inner term's constraint, so that it doesn't get propagated as a constraint on the inferred type
17:39:59 <monochrom> There was a GHC bug. It was an accidental abstraction leak. It lets you write one of "Read a => String => a" or "Read a -> String -> a", I forgot which, but it was funny.
17:40:35 × ub quits (~Thunderbi@77.119.204.226.wireless.dyn.drei.com) (Ping timeout: 246 seconds)
17:41:12 <awpr> I guess that happened around the time GHC was changed to have Constraint be literally the same thing as Type internally?
17:41:59 gioyik joins (~gioyik@gateway/tor-sasl/gioyik)
17:43:00 <monochrom> Yeah something like that.
17:43:15 <monochrom> ConstraintKind
17:43:45 <monochrom> along with "kind is type too" etc
17:43:45 <awpr> as for what insights: to me it seems to make parametricity clearer. having a constraint doesn't reduce the strength of parametricity by "magic" because it "makes fewer types legal arguments", it just adds a record argument containing the instance methods to the polytype
17:46:37 <awpr> anyway I definitely think it's valuable to have the other view (constraints as limitations on polymorphism) as another angle, possibly even as the default way of looking at things, I just like to have both available
17:47:04 × kuribas quits (~user@ptr-25vy0i747grimuk7ofw.18120a2.ip6.access.telenet.be) (Quit: ERC (IRC client for Emacs 26.3))
17:50:22 <awpr> oh, I missed a key part of one message: `Num Int => ...` is also (using the term loosely) a function. it's just that GHC won't ever infer that type and make that function, instead it'll immediately solve `Num Int` and apply it to the subexpression that needed it. if you spell out that constraint, I'm not sure whether GHC will actually do what you said or just optimize it out of existence; I should check
17:50:46 merijn joins (~merijn@83-160-49-249.ip.xs4all.nl)
17:50:50 × juhp quits (~juhp@128.106.188.220) (Quit: juhp)
17:51:04 juhp joins (~juhp@128.106.188.220)
17:52:51 <monochrom> I unify "static" and "dynamic" with hugs and ghci
17:53:13 <awpr> yes, it will let you make that into an actual function: paste.tomsmeding.com/9DPBxuwa
17:53:22 <monochrom> @quote lambdabot runghc
17:53:22 <lambdabot> No quotes match. Listen, broccoli brains, I don't have time to listen to this trash.
17:53:34 <monochrom> @quote monochrom runghc
17:53:34 <lambdabot> monochrom says: just add #! /usr/bin/runghc to your haskell file. then type errors occur at runtime only.
17:53:56 <tomsmeding> or -fdefer-type-errors
17:54:06 × favonia quits (~favonia@user/favonia) (Ping timeout: 265 seconds)
17:54:16 <monochrom> Oh, it was a long time ago, -fdefer-type-errors did not exist.
17:54:59 <monochrom> Also, probably s/with/by/
17:55:05 <monochrom> This is why I hate English.
17:55:53 yauhsien joins (~yauhsien@118-167-47-202.dynamic-ip.hinet.net)
17:55:55 cfricke joins (~cfricke@user/cfricke)
17:56:08 <monochrom> awpr, did you need to turn on an extension, maybe FlexibleContext, to legalize Num Int?
17:56:16 <awpr> yep, exactly that
17:56:29 <awpr> ++'s'
17:56:58 <monochrom> This is why I hate meaningful names cast in English.
17:57:26 <awpr> GHC proposal: rename all language extensions into Lojban
17:57:39 <monochrom> Chinese is a bit better in this regard, free of that kind of hair splitting.
17:58:09 <awpr> no singular/plural distinction on the basic forms of nouns?
17:58:18 <monochrom> None.
17:58:26 <monochrom> And no preposition madness either.
17:58:27 <awpr> cool, same reason I reached for Lojban
17:59:14 <awpr> but I think Chinese might just slightly take the edge w.r.t. number of fluent speakers
18:00:41 × yauhsien quits (~yauhsien@118-167-47-202.dynamic-ip.hinet.net) (Ping timeout: 264 seconds)
18:00:47 <c_wraith> I've heard that Chinese has an issue with reading and writing not being symmetric. A lot more native speakers can read than can write. (It's much easier to recognize characters than to remember them without a visual prompt)
18:01:22 <gehmehgeh> Those Lojban language examples on Wikipedia look like something Cthulu would say :D
18:01:35 Brumaire joins (~quassel@81-64-14-121.rev.numericable.fr)
18:01:39 <gehmehgeh> (I hadn't heard about Lojban und thought I look it up)
18:01:58 <monochrom> I doubt it. I mean I doubt that it is more than other languages.
18:02:57 <geekosaur> it used to be called logban, iirc
18:03:04 <geekosaur> er, loglan
18:03:22 <monochrom> Any of you claim you have the same fluency in writing "zygomorphism" as you are fluent in reading it?
18:03:33 <c_wraith> synthetic words like that are easy to write
18:03:53 geekosaur has less problem reading or writing it than understanding it
18:03:55 <c_wraith> the difficulty in writing in English is when you *don't* know where the loan words originate
18:05:46 <geekosaur> yoğurt
18:06:17 <monochrom> OK, people mix up "effect" and "affect".
18:06:55 <gehmehgeh> inapt and inept :D
18:06:56 × MQ-17J quits (~MQ-17J@d192-24-122-179.try.wideopenwest.com) (Read error: Connection reset by peer)
18:07:27 MQ-17J joins (~MQ-17J@d192-24-122-179.try.wideopenwest.com)
18:07:28 <gehmehgeh> (Tought, inapt and inept at least sound different)
18:08:04 <monochrom> You know, to someone like me with ESL background, they sound too similar.
18:08:21 favonia joins (~favonia@user/favonia)
18:09:08 <monochrom> Generally we have difficulty distinguishing, or reproducing the difference of, "at" and "et".
18:09:30 <monochrom> Some of us can't even draw a line between "name" and "nam".
18:09:57 <monochrom> You will hear some of us saying "my nam is monochrom, I like to play gams".
18:11:05 <Rembane> manachram!
18:11:06 Rembane nods
18:12:46 <geekosaur> I find that interesting because, so far as English has reliable rules, that's one of them
18:14:09 <monochrom> But there is something about, it takes several years, and a very young and plastic brain, to train to recognize that there is a difference.
18:14:16 <monochrom> any difference.
18:14:53 <monochrom> I have trouble telling apart red hair and blonde hair. This is why I didn't see enough examples when I was a child.
18:15:03 <gehmehgeh> monochrom: what dialect/variant of the English language are you speaking?
18:15:27 <monochrom> s/why/because/
18:16:29 <monochrom> You will have trouble telling apart, say, Chinese faces from Japanese faces from Korean faces. This is because you didn't see enough examples when you were a child. East Asian people like me can tell them apart, we saw enough examples.
18:16:42 × gioyik quits (~gioyik@gateway/tor-sasl/gioyik) (Ping timeout: 276 seconds)
18:16:50 <gehmehgeh> monochrom: I think I can tell them apart, too.
18:16:53 <gehmehgeh> monochrom: I'm from Germany
18:17:19 <gehmehgeh> That is, generally. Some people have faces that could come from anywhere
18:17:19 × MQ-17J quits (~MQ-17J@d192-24-122-179.try.wideopenwest.com) (Read error: Connection reset by peer)
18:17:19 <monochrom> I don't know. I started in Hong Kong. I am in Canada. I have heard British, American, Canadian, perhaps also Singapore and Polish.
18:17:42 <ldlework> awpr: did you see the latest graph
18:17:45 <geekosaur> "American" has plenty of dialects all by itself
18:18:00 <gehmehgeh> Canadian being one of them ;)
18:18:31 <awpr> ldlework: I think so, with 14 classes and full method listings for them?
18:18:37 <monochrom> I had a prof from Singapore who pronouced "library" by putting the accent on the "y".
18:18:45 MQ-17J joins (~MQ-17J@d192-24-122-179.try.wideopenwest.com)
18:18:46 eggplantade joins (~Eggplanta@2600:1700:bef1:5e10:1c28:7782:3d08:8ee5)
18:18:56 <ldlework> yeah this one https://github.com/dustinlacewell/haskell-typeclass-atlas/blob/master/atlas.png?raw=true
18:19:05 <awpr> y
18:19:15 gioyik joins (~gioyik@gateway/tor-sasl/gioyik)
18:20:07 <monochrom> So imagine "comprehend" applied to "library"
18:24:18 <monochrom> Nice class atlas.
18:24:43 × merijn quits (~merijn@83-160-49-249.ip.xs4all.nl) (Ping timeout: 252 seconds)
18:25:28 <monochrom> Ugh where are Bounded, Enum, Show, Read? :)
18:26:26 × gehmehgeh quits (~user@user/gehmehgeh) (Quit: Leaving)
18:27:41 <zzz> what's a good resource to learn about kind signatures?
18:31:11 amahl joins (~amahl@dsl-jklbng12-54fbca-64.dhcp.inet.fi)
18:31:59 × MQ-17J quits (~MQ-17J@d192-24-122-179.try.wideopenwest.com) (Ping timeout: 252 seconds)
18:33:06 gehmehgeh joins (~user@user/gehmehgeh)
18:34:53 × lavaman quits (~lavaman@98.38.249.169) (Ping timeout: 264 seconds)
18:36:19 <Franciman> is there a way to make cabal output Core code of the files in the project?
18:37:02 <awpr> does `ghc-options: -ddump-simpl` work?
18:37:19 neurocyte013 joins (~neurocyte@212.232.95.106)
18:37:19 × neurocyte013 quits (~neurocyte@212.232.95.106) (Changing host)
18:37:19 neurocyte013 joins (~neurocyte@user/neurocyte)
18:37:56 MQ-17J joins (~MQ-17J@d192-24-122-179.try.wideopenwest.com)
18:41:48 × neurocyte013 quits (~neurocyte@user/neurocyte) (Client Quit)
18:43:09 neurocyte013 joins (~neurocyte@212.232.95.106)
18:43:09 × neurocyte013 quits (~neurocyte@212.232.95.106) (Changing host)
18:43:09 neurocyte013 joins (~neurocyte@user/neurocyte)
18:43:34 × viluon quits (uid453725@id-453725.helmsley.irccloud.com) (Quit: Connection closed for inactivity)
18:49:53 × MQ-17J quits (~MQ-17J@d192-24-122-179.try.wideopenwest.com) (Read error: Connection reset by peer)
18:49:56 × mikoto-chan quits (~mikoto-ch@ip-83-134-2-136.dsl.scarlet.be) (Quit: mikoto-chan)
18:50:14 MQ-17J joins (~MQ-17J@d192-24-122-179.try.wideopenwest.com)
18:53:01 × ubert quits (~Thunderbi@77.119.204.226.wireless.dyn.drei.com) (Remote host closed the connection)
18:56:21 × gioyik quits (~gioyik@gateway/tor-sasl/gioyik) (Ping timeout: 276 seconds)
18:56:44 × cfricke quits (~cfricke@user/cfricke) (Ping timeout: 252 seconds)
18:57:20 ubert joins (~Thunderbi@77.119.204.226.wireless.dyn.drei.com)
19:00:04 × oxide quits (~lambda@user/oxide) (Quit: oxide)
19:03:00 gioyik joins (~gioyik@gateway/tor-sasl/gioyik)
19:04:12 × Cajun quits (~Cajun@user/cajun) (Quit: Client closed)
19:07:39 × eggplantade quits (~Eggplanta@2600:1700:bef1:5e10:1c28:7782:3d08:8ee5) (Remote host closed the connection)
19:09:21 × gioyik quits (~gioyik@gateway/tor-sasl/gioyik) (Ping timeout: 276 seconds)
19:12:14 wroathe joins (~wroathe@c-68-54-25-135.hsd1.mn.comcast.net)
19:12:14 × wroathe quits (~wroathe@c-68-54-25-135.hsd1.mn.comcast.net) (Changing host)
19:12:14 wroathe joins (~wroathe@user/wroathe)
19:16:25 × favonia quits (~favonia@user/favonia) (Ping timeout: 252 seconds)
19:26:35 gioyik joins (~gioyik@gateway/tor-sasl/gioyik)
19:32:06 × gioyik quits (~gioyik@gateway/tor-sasl/gioyik) (Ping timeout: 276 seconds)
19:32:15 eggplantade joins (~Eggplanta@2600:1700:bef1:5e10:1c28:7782:3d08:8ee5)
19:33:29 dschrempf joins (~dominik@070-207.dynamic.dsl.fonira.net)
19:39:38 × dhouthoo quits (~dhouthoo@178-117-36-167.access.telenet.be) (Quit: WeeChat 3.2)
19:41:50 favonia joins (~favonia@user/favonia)
19:45:06 × Vajb quits (~Vajb@hag-jnsbng11-58c3a8-176.dhcp.inet.fi) (Read error: Connection reset by peer)
19:46:10 Vajb joins (~Vajb@hag-jnsbng11-58c3a8-176.dhcp.inet.fi)
19:46:11 × juhp quits (~juhp@128.106.188.220) (Quit: juhp)
19:46:24 juhp joins (~juhp@128.106.188.220)
19:46:44 Izem joins (~user@bras-base-london1483w-grc-31-74-12-158-179.dsl.bell.ca)
19:47:16 TranquilEcho joins (~grom@user/tranquilecho)
19:51:07 × bonizzi quits (~bonizzi@2804:14c:65d3:4689:d52e:1289:d36a:ed19) (Quit: Leaving)
19:51:31 × juhp quits (~juhp@128.106.188.220) (Quit: juhp)
19:51:44 juhp joins (~juhp@128.106.188.220)
19:53:05 × ubert quits (~Thunderbi@77.119.204.226.wireless.dyn.drei.com) (Quit: ubert)
19:53:17 ubert joins (~Thunderbi@77.119.204.226.wireless.dyn.drei.com)
19:53:49 × geekosaur quits (~geekosaur@xmonad/geekosaur) (Remote host closed the connection)
19:54:09 geekosaur joins (~geekosaur@xmonad/geekosaur)
19:55:04 × ubert quits (~Thunderbi@77.119.204.226.wireless.dyn.drei.com) (Remote host closed the connection)
19:55:53 <maerwald> monochrom: lol, senglish is awesome
19:56:00 <maerwald> can
19:57:20 yauhsien joins (~yauhsien@118-167-47-202.dynamic-ip.hinet.net)
19:59:53 gioyik joins (~gioyik@gateway/tor-sasl/gioyik)
20:00:03 <ixlun> Is there a 'standard' way of representing 0 with Rational?
20:00:17 <ixlun> I'm using `0 % 1`, but is there a standard?
20:01:41 <geekosaur> 0 % 1, or just write 0 and let Num literal magic do its thing
20:02:11 × yauhsien quits (~yauhsien@118-167-47-202.dynamic-ip.hinet.net) (Ping timeout: 252 seconds)
20:03:18 × ec quits (~ec@gateway/tor-sasl/ec) (Ping timeout: 276 seconds)
20:04:20 <ixlun> Ah, didn't know I could do `0 :: Rational` and that woeks. Neat!
20:04:24 × _ht quits (~quassel@82-169-194-8.biz.kpn.net) (Remote host closed the connection)
20:05:22 × juhp quits (~juhp@128.106.188.220) (Ping timeout: 252 seconds)
20:05:29 × wroathe quits (~wroathe@user/wroathe) (Ping timeout: 252 seconds)
20:06:17 × amahl quits (~amahl@dsl-jklbng12-54fbca-64.dhcp.inet.fi) (Quit: Leaving)
20:06:53 TDANG joins (~TDANG@inet-177-7.ets.org)
20:07:05 juhp joins (~juhp@128.106.188.220)
20:07:10 acidjnk joins (~acidjnk@p200300d0c703cb44319f4c33bc64626e.dip0.t-ipconnect.de)
20:07:17 × xff0x quits (~xff0x@2001:1a81:53a2:cb00:c07c:d089:8b2f:814c) (Ping timeout: 264 seconds)
20:07:39 xff0x joins (~xff0x@2001:1a81:53a2:cb00:fe64:bcbc:d8a9:c1f9)
20:07:41 ec joins (~ec@gateway/tor-sasl/ec)
20:10:49 pavonia joins (~user@user/siracusa)
20:12:17 <TDANG> hi everybody
20:12:37 <TDANG> I don't understand the : symbol
20:12:44 <TDANG> (single colon)
20:12:54 <c_wraith> What resources have you used for learning the language?
20:13:21 <TDANG> http://learnyouahaskell.com/
20:14:58 <c_wraith> It's covered in the "intro to lists" section. Did you get to that part?
20:16:54 <TDANG> great, I found it.
20:17:08 <c_wraith> (If you did and things don't make sense, that's fine. I'm just trying to get a baseline of what you're looking for)
20:17:13 <TDANG> I'll go with it. Thanks ;-)
20:17:35 × jstolarek quits (~jstolarek@erx128.neoplus.adsl.tpnet.pl) (Ping timeout: 252 seconds)
20:19:45 TDANG_ joins (~TDANG@cpe-107-15-144-45.nc.res.rr.com)
20:21:21 merijn joins (~merijn@83-160-49-249.ip.xs4all.nl)
20:21:41 × TDANG quits (~TDANG@inet-177-7.ets.org) (Ping timeout: 264 seconds)
20:21:58 wroathe joins (~wroathe@c-68-54-25-135.hsd1.mn.comcast.net)
20:21:59 × wroathe quits (~wroathe@c-68-54-25-135.hsd1.mn.comcast.net) (Changing host)
20:21:59 wroathe joins (~wroathe@user/wroathe)
20:25:17 × michalz quits (~michalz@185.246.204.33) (Remote host closed the connection)
20:26:50 × wroathe quits (~wroathe@user/wroathe) (Ping timeout: 265 seconds)
20:27:59 Pickchea joins (~private@user/pickchea)
20:33:41 × Izem quits (~user@bras-base-london1483w-grc-31-74-12-158-179.dsl.bell.ca) (Ping timeout: 264 seconds)
20:33:51 × ec quits (~ec@gateway/tor-sasl/ec) (Ping timeout: 276 seconds)
20:34:16 Tuplanolla joins (~Tuplanoll@91-159-69-50.elisa-laajakaista.fi)
20:39:10 Cajun joins (~Cajun@user/cajun)
20:39:37 nschoe joins (~quassel@2a01:e0a:8e:a190:1aae:e766:24c4:a2ba)
20:40:52 ec joins (~ec@gateway/tor-sasl/ec)
20:41:05 × ystael quits (~ystael@user/ystael) (Read error: Connection reset by peer)
20:43:43 × rond_ quits (~rond_@2a02:a31a:a23c:f480:2fd7:e087:5546:a438) (Quit: Client closed)
20:47:11 × juhp quits (~juhp@128.106.188.220) (Quit: juhp)
20:47:24 juhp joins (~juhp@128.106.188.220)
20:48:08 ystael joins (~ystael@user/ystael)
20:48:31 × takuan quits (~takuan@178-116-218-225.access.telenet.be) (Remote host closed the connection)
20:50:54 × favonia quits (~favonia@user/favonia) (Ping timeout: 260 seconds)
20:52:37 <monochrom> Oh hey, "newtype P m a = MkP{unP :: String -> m (String, a)}". If m is an instance of MonadPlus and Alternative, then P m is a parser monad! Typically m = [] or Maybe or Either X.
20:53:21 <awpr> > :i ST
20:53:23 <lambdabot> <hint>:1:1: error: parse error on input ‘:’
20:53:47 <monochrom> Sacrilegeous idea: Let me inflict this much generality on my students next time >:)
20:53:55 <awpr> ah, not MonadPlus
20:54:19 <monochrom> Heh, IO actually has a chance >:)
20:54:26 <awpr> oh duh, I meant STM, but that's also not MonadPlus
20:54:35 × Lord_of_Life quits (~Lord@user/lord-of-life/x-2819915) (Read error: Connection reset by peer)
20:55:01 <awpr> or... it is, but my ghci doesn't know it
20:55:25 <monochrom> I suppose I don't need MonadPlus. I just need Monad and Alternative.
20:55:31 Lord_of_Life joins (~Lord@user/lord-of-life/x-2819915)
20:55:32 × merijn quits (~merijn@83-160-49-249.ip.xs4all.nl) (Ping timeout: 252 seconds)
20:55:42 <awpr> so that would retry a transaction until the parse succeeded? :D
20:55:43 <monochrom> Oh heh yeah you need to import more modules, or use :info!
20:56:05 <awpr> oh, no, it would avoid retrying
20:56:08 <monochrom> Haha questionable use cases, but the math works out!
20:57:31 × juhp quits (~juhp@128.106.188.220) (Quit: juhp)
20:57:45 juhp joins (~juhp@128.106.188.220)
20:58:54 <awpr> now I'm picturing a compiler that just deadlocks until you update the file with correct input
20:59:57 <monochrom> Heh
21:02:47 × hiepph[m] quits (~hiepphmat@2001:470:69fc:105::e3a8) (Ping timeout: 240 seconds)
21:03:34 × Jon quits (jon@dow.land) (Quit: ZNC - http://znc.in)
21:03:46 hiepph[m] joins (~hiepphmat@2001:470:69fc:105::e3a8)
21:04:10 Jon joins (jon@dow.land)
21:04:20 × wonko quits (~wjc@62.115.229.50) (Ping timeout: 252 seconds)
21:05:03 × gioyik quits (~gioyik@gateway/tor-sasl/gioyik) (Ping timeout: 276 seconds)
21:06:00 Izem joins (~user@bras-base-london1483w-grc-31-74-12-158-179.dsl.bell.ca)
21:06:21 × ec quits (~ec@gateway/tor-sasl/ec) (Ping timeout: 276 seconds)
21:06:50 Lord_of_Life_ joins (~Lord@user/lord-of-life/x-2819915)
21:06:51 Izem parts (~user@bras-base-london1483w-grc-31-74-12-158-179.dsl.bell.ca) ()
21:07:47 × Lord_of_Life quits (~Lord@user/lord-of-life/x-2819915) (Ping timeout: 246 seconds)
21:08:06 Lord_of_Life_ is now known as Lord_of_Life
21:08:11 × Brumaire quits (~quassel@81-64-14-121.rev.numericable.fr) (Ping timeout: 252 seconds)
21:08:40 azeem joins (~azeem@2a00:801:3c7:f4f5:1ae6:c0ab:f962:792a)
21:09:57 Nosrep joins (~archbox@user/nosrep)
21:10:43 favonia joins (~favonia@user/favonia)
21:12:50 ec joins (~ec@gateway/tor-sasl/ec)
21:13:42 × MQ-17J quits (~MQ-17J@d192-24-122-179.try.wideopenwest.com) (Read error: Connection reset by peer)
21:14:06 MQ-17J joins (~MQ-17J@8.21.10.6)
21:19:01 × Everything quits (~Everythin@37.115.210.35) (Quit: leaving)
21:20:42 maroloccio joins (~marolocci@93-142-92-177.adsl.net.t-com.hr)
21:23:24 <monochrom> > let a \~ b = a-b in 5 \~ 3
21:23:25 <lambdabot> 2
21:24:10 <monochrom> This means "\~(a,b) -> (b,a)" is a parse error, the computer doesn't see it as "lambda, lazy pattern".
21:24:23 × jespada quits (~jespada@2803:9800:9842:7a62:edd5:5e74:3ec2:1b19) (Quit: My MacBook has gone to sleep. ZZZzzz…)
21:24:28 <monochrom> Hrm does Haskell accept zero-width space? >:)
21:24:44 <geekosaur> I thought someone tried that the other day and it didn't?
21:25:10 <hpc> > (\(~(a,b)) -> a) (1, 2)
21:25:12 <lambdabot> 1
21:25:29 <hpc> the lisp solution
21:25:32 <hpc> when in doubt, add parens
21:26:26 jespada joins (~jespada@2803:9800:9842:7a62:4d47:2975:7b31:a447)
21:26:26 <monochrom> Oh I guess "U+FEFF ZERO WIDTH NO-BREAK SPACE" is aka byte-order marker.
21:26:49 <awpr> ohhh that's clever, I hate it
21:27:15 × favonia quits (~favonia@user/favonia) (Ping timeout: 265 seconds)
21:27:25 <awpr> if some software isn't aware of BOMs, it harmlessly decays into a zero-width invisible character at the start of the document
21:27:56 <monochrom> Unless it's cassava, which is totally thrown off by that.
21:29:30 <monochrom> The tension here is that a lot of CSV-producing software honours the Windows convention of: 1. UTF-8 (that's good), 2. CRLF (that's fine, the CSV standard prescribe it anyway), 3. BOM (ugh).
21:29:31 × Vajb quits (~Vajb@hag-jnsbng11-58c3a8-176.dhcp.inet.fi) (Read error: Connection reset by peer)
21:29:46 Vajb joins (~Vajb@hag-jnsbng11-58c3a8-176.dhcp.inet.fi)
21:29:55 <geekosaur> the problem with BOM is it's not UTF8
21:30:22 <geekosaur> (as windows uses it, at least)
21:30:29 <awpr> wait do they not use the UTF-8 encoding of that character?
21:30:35 × flouflou quits (~flouflou@modemcable032.110-177-173.mc.videotron.ca) (Quit: WeeChat 3.2)
21:30:40 <geekosaur> nope
21:30:48 <geekosaur> it's UTF16
21:30:55 <awpr> just throw a singular completely irrelevant UCS-2 thing at the start of a UTF-8 file?
21:31:18 <geekosaur> windows was at the time trying to be sorta kinda utf16
21:31:39 <geekosaur> then went utf8 later but kept the same BONM it had been using
21:31:53 <awpr> I can't even fathom
21:32:13 <hpc> the codepoint is still valid, it's just not useful because there aren't multiple ways to write utf8
21:32:21 <hpc> so in that sense they're technically fine
21:32:21 gioyik joins (~gioyik@gateway/tor-sasl/gioyik)
21:32:25 <monochrom> They use the UTF-8 encoding of that character for UTF-8 files. Yes.
21:32:26 <cdsmith> Is there a way for a Haskell process to find the RTS args that were passed to it? They are removed from the normal System.Environment.getArgs.
21:32:36 <awpr> monochrom: oh, okay. seems alright then
21:32:40 <awpr> if unnecessary
21:32:47 <glguy> cdsmith: they are removed from getArgs
21:32:53 <monochrom> They then use the UTF-16?E of the character for UTF-16?E files, correspondinging.
21:32:53 <geekosaur> oh, they do now?
21:33:05 × pbrisbin quits (~patrick@pool-173-49-147-250.phlapa.fios.verizon.net) (Ping timeout: 264 seconds)
21:33:06 <geekosaur> at one point they weren't
21:33:13 <geekosaur> which was really annoying
21:33:33 <monochrom> They have always done, as far as I have worked with CSV files I have received since several years ago.
21:34:20 <monochrom> My own code does a BL.stripPrefix (BL.pack "\xef\xbb\xbf") bytes, I have never need to strip "\xfe\xff" or something.
21:34:47 <monochrom> Ah OK must be way before my time.
21:34:48 <cdsmith> glguy: Yes, I know. Was hoping there's some way to get them anyway.
21:34:53 × Gurkenglas quits (~Gurkengla@dslb-002-207-014-195.002.207.pools.vodafone-ip.de) (Ping timeout: 264 seconds)
21:35:21 × chomwitt quits (~chomwitt@2a02:587:dc15:500:12c3:7bff:fe6d:d374) (Read error: Connection reset by peer)
21:35:29 aliosablack joins (~chomwitt@2a02:587:dc15:500:12c3:7bff:fe6d:d374)
21:35:36 × ec quits (~ec@gateway/tor-sasl/ec) (Ping timeout: 276 seconds)
21:35:54 <monochrom> Does GHC.Environment.getFullArgs help?
21:36:25 <glguy> cdsmith: I think you'll need to start digging in something like this: https://hackage.haskell.org/package/base-4.15.0.0/docs/src/GHC-RTS-Flags.html#getRTSFlags
21:38:28 × nschoe quits (~quassel@2a01:e0a:8e:a190:1aae:e766:24c4:a2ba) (Quit: https://quassel-irc.org - Chat comfortably. Anywhere.)
21:39:01 merijn joins (~merijn@83-160-49-249.ip.xs4all.nl)
21:41:45 × shachaf quits (~shachaf@user/shachaf) (Ping timeout: 265 seconds)
21:42:22 shachaf joins (~shachaf@user/shachaf)
21:42:26 × aliosablack quits (~chomwitt@2a02:587:dc15:500:12c3:7bff:fe6d:d374) (Ping timeout: 246 seconds)
21:42:39 ec joins (~ec@gateway/tor-sasl/ec)
21:43:12 × gehmehgeh quits (~user@user/gehmehgeh) (Quit: Leaving)
21:43:53 × merijn quits (~merijn@83-160-49-249.ip.xs4all.nl) (Ping timeout: 264 seconds)
21:46:36 Lycurgus joins (~juan@98.4.112.204)
21:46:44 <cdsmith> glguy: Hmm, getting that back into String form looks challenging. C FFI might be a better bet at that point. :(
21:48:05 <cdsmith> Well, that's what I needed to know. Thank you. I think I need to find a different way.
21:48:09 <geekosaur> did you see monochrom's suggestion
21:48:11 <geekosaur> ?
21:48:31 <cdsmith> Oh, no!
21:48:31 <cdsmith> I'll look
21:49:00 <cdsmith> Perfect. Thanks monochrom
21:53:53 <glguy> To get just the RTS arguments: https://gist.github.com/glguy/7a5ae553f463aa7d2c7e786180b9d085 <_<
21:54:44 <monochrom> could be worse :)
21:54:46 <ldlework> glguy: do you use opengl with haskell
21:55:30 <geekosaur> actually, strictly speaking both of those only get RTS options from the command line, not $GHCRTS or compiled-in rtsopts
21:56:00 <ldlework> oh "good luck, guy" maybe, nm
21:56:31 <glguy> I think I have done some OpenGL from Haskell, but very little.
21:56:39 × eggplantade quits (~Eggplanta@2600:1700:bef1:5e10:1c28:7782:3d08:8ee5) (Remote host closed the connection)
21:58:34 × mousey quits (~sky@gateway/tor-sasl/mousey) (Remote host closed the connection)
21:58:55 yauhsien joins (~yauhsien@118-167-47-202.dynamic-ip.hinet.net)
21:59:05 Arathorn joins (~arathorn@2001:470:69fc:105::1f)
21:59:29 × cheater quits (~Username@user/cheater) (Ping timeout: 264 seconds)
22:00:04 × dschrempf quits (~dominik@070-207.dynamic.dsl.fonira.net) (Quit: WeeChat 3.2.1)
22:00:51 × max22- quits (~maxime@2a01cb08833598000f1fa44417d80ccf.ipv6.abo.wanadoo.fr) (Quit: Leaving)
22:02:54 cheater joins (~Username@user/cheater)
22:03:37 × yauhsien quits (~yauhsien@118-167-47-202.dynamic-ip.hinet.net) (Ping timeout: 252 seconds)
22:05:30 × ec quits (~ec@gateway/tor-sasl/ec) (Ping timeout: 276 seconds)
22:06:37 × __monty__ quits (~toonn@user/toonn) (Quit: leaving)
22:10:52 son0p joins (~ff@181.136.122.143)
22:12:37 ec joins (~ec@gateway/tor-sasl/ec)
22:15:37 × Vajb quits (~Vajb@hag-jnsbng11-58c3a8-176.dhcp.inet.fi) (Read error: Connection reset by peer)
22:16:48 × Pickchea quits (~private@user/pickchea) (Quit: Leaving)
22:18:17 Morrow joins (~MorrowM_@bzq-110-168-31-106.red.bezeqint.net)
22:26:26 werneta joins (~werneta@70-142-214-115.lightspeed.irvnca.sbcglobal.net)
22:28:14 eggplantade joins (~Eggplanta@2600:1700:bef1:5e10:1c28:7782:3d08:8ee5)
22:29:15 <cdsmith> glguy: Getting all arguments was actually perfect for my use. https://github.com/haskell/haskell-language-server/pull/2228
22:31:02 Vajb joins (~Vajb@hag-jnsbng11-58c3a8-176.dhcp.inet.fi)
22:33:21 <glguy> It seems like you'd want the arguments to not be interpreted by the wrapper and *only* passed through
22:34:35 <glguy> passing through the ones handled by the wrapper itself means that, for example, things that write to files (like -t) will cause two different runtimes to write to that file
22:40:55 wroathe joins (~wroathe@96-88-30-181-static.hfc.comcastbusiness.net)
22:40:55 × wroathe quits (~wroathe@96-88-30-181-static.hfc.comcastbusiness.net) (Changing host)
22:40:55 wroathe joins (~wroathe@user/wroathe)
22:48:06 <monochrom> w00t new ghcup
22:50:21 × ec quits (~ec@gateway/tor-sasl/ec) (Ping timeout: 276 seconds)
22:54:05 × nfd quits (~nfd@user/nfd) (Ping timeout: 264 seconds)
22:54:40 × Tuplanolla quits (~Tuplanoll@91-159-69-50.elisa-laajakaista.fi) (Quit: Leaving.)
22:55:13 × MQ-17J quits (~MQ-17J@8.21.10.6) (Ping timeout: 265 seconds)
22:55:46 × maroloccio quits (~marolocci@93-142-92-177.adsl.net.t-com.hr) (Quit: WeeChat 3.0)
22:56:57 ec joins (~ec@gateway/tor-sasl/ec)
22:58:37 MQ-17J joins (~MQ-17J@d192-24-122-179.try.wideopenwest.com)
23:12:55 × Lycurgus quits (~juan@98.4.112.204) (Quit: Exeunt)
23:18:22 <geekosaur> wee, big upgrade completed and xmonad now happily runniung based on 8.10.7 instead of 8.10.4
23:18:42 <geekosaur> other utils can wait, they'll rebuild as needed anyway
23:19:17 <geekosaur> cabal++
23:20:25 <hpc> cabal# .net
23:24:59 kimjetwav joins (~user@2607:fea8:235f:9730:158b:8b68:ef55:bdbf)
23:27:17 <shapr> yay xmonad!
23:28:01 hiruji` joins (~hiruji@72.74.190.75)
23:28:17 × acidjnk quits (~acidjnk@p200300d0c703cb44319f4c33bc64626e.dip0.t-ipconnect.de) (Ping timeout: 264 seconds)
23:28:17 × hiruji quits (~hiruji@user/hiruji) (Ping timeout: 264 seconds)
23:33:26 × mc47 quits (~mc47@xmonad/TheMC47) (Remote host closed the connection)
23:33:35 [itchyjunk] joins (~itchyjunk@user/itchyjunk/x-7353470)
23:35:12 × ec quits (~ec@gateway/tor-sasl/ec) (Ping timeout: 276 seconds)
23:36:11 × TranquilEcho quits (~grom@user/tranquilecho) (Quit: WeeChat 2.8)
23:37:58 × hiruji` quits (~hiruji@72.74.190.75) (Quit: ZNC 1.8.2 - https://znc.in)
23:38:16 hiruji joins (~hiruji@user/hiruji)
23:41:29 × wroathe quits (~wroathe@user/wroathe) (Ping timeout: 264 seconds)
23:42:08 × raehik quits (~raehik@cpc95906-rdng25-2-0-cust156.15-3.cable.virginm.net) (Ping timeout: 246 seconds)
23:42:10 ec joins (~ec@gateway/tor-sasl/ec)
23:42:19 × geekosaur quits (~geekosaur@xmonad/geekosaur) (Remote host closed the connection)
23:42:39 geekosaur joins (~geekosaur@xmonad/geekosaur)
23:42:48 raehik joins (~raehik@cpc95906-rdng25-2-0-cust156.15-3.cable.virginm.net)
23:43:08 × hiruji quits (~hiruji@user/hiruji) (Client Quit)
23:43:09 merijn joins (~merijn@83-160-49-249.ip.xs4all.nl)
23:49:25 × asivitz quits (uid178348@id-178348.tinside.irccloud.com) (Quit: Connection closed for inactivity)
23:51:06 × pretty_dumm_guy quits (trottel@gateway/vpn/protonvpn/prettydummguy/x-88029655) (Quit: WeeChat 3.3)
23:57:03 wroathe joins (~wroathe@c-68-54-25-135.hsd1.mn.comcast.net)
23:57:03 × wroathe quits (~wroathe@c-68-54-25-135.hsd1.mn.comcast.net) (Changing host)
23:57:03 wroathe joins (~wroathe@user/wroathe)

All times are in UTC on 2021-09-21.