2024/04/02

2024-04-02 00:04:10 +0200 <Inst> cool, thanks
2024-04-02 00:04:16 +0200plexom(~plexom@194.95.4.234)
2024-04-02 00:05:42 +0200plexom(~plexom@194.95.4.234) ()
2024-04-02 00:09:00 +0200lvdv(~lvdv@pa49-179-5-108.pa.nsw.optusnet.com.au)
2024-04-02 00:11:11 +0200 <Inst> thanks
2024-04-02 00:13:21 +0200sawilagar(~sawilagar@user/sawilagar) (Ping timeout: 255 seconds)
2024-04-02 00:25:36 +0200dostoyev1ky2(~sck@user/dostoyevsky2)
2024-04-02 00:26:48 +0200dostoyevsky2(~sck@user/dostoyevsky2) (Quit: leaving)
2024-04-02 00:27:29 +0200dostoyev1ky2(~sck@user/dostoyevsky2) (Client Quit)
2024-04-02 00:27:49 +0200dostoyevsky2(~sck@user/dostoyevsky2)
2024-04-02 00:43:11 +0200lvdv(~lvdv@pa49-179-5-108.pa.nsw.optusnet.com.au) (Ping timeout: 264 seconds)
2024-04-02 00:43:33 +0200bitdex(~bitdex@gateway/tor-sasl/bitdex)
2024-04-02 00:43:53 +0200sudden(~cat@user/sudden) (Ping timeout: 268 seconds)
2024-04-02 00:44:24 +0200acidjnk_new(~acidjnk@p200300d6e714dc028ca983f248aa2682.dip0.t-ipconnect.de) (Ping timeout: 255 seconds)
2024-04-02 00:45:32 +0200mqlnv(~tripod@47.154.25.27)
2024-04-02 00:51:47 +0200__monty__(~toonn@user/toonn) (Quit: leaving)
2024-04-02 00:53:53 +0200sudden(~cat@user/sudden)
2024-04-02 00:55:12 +0200mechap(~mechap@user/mechap) (Ping timeout: 255 seconds)
2024-04-02 01:03:30 +0200phma_(~phma@host-67-44-208-169.hnremote.net)
2024-04-02 01:03:56 +0200stiell_(~stiell@gateway/tor-sasl/stiell) (Remote host closed the connection)
2024-04-02 01:03:59 +0200phma(phma@2001:5b0:215a:b318:a23a:3f03:dc96:3e6d) (Read error: Connection reset by peer)
2024-04-02 01:04:36 +0200stiell_(~stiell@gateway/tor-sasl/stiell)
2024-04-02 01:08:40 +0200stiell_(~stiell@gateway/tor-sasl/stiell) (Remote host closed the connection)
2024-04-02 01:09:04 +0200stiell_(~stiell@gateway/tor-sasl/stiell)
2024-04-02 01:12:32 +0200JamesMowery(~JamesMowe@ip98-171-80-211.ph.ph.cox.net) (Quit: Goodbye)
2024-04-02 01:14:34 +0200JamesMowery(~JamesMowe@ip98-171-80-211.ph.ph.cox.net)
2024-04-02 01:17:42 +0200ec_(~ec@gateway/tor-sasl/ec)
2024-04-02 01:19:09 +0200ec(~ec@gateway/tor-sasl/ec) (Remote host closed the connection)
2024-04-02 01:25:23 +0200mei(~mei@user/mei) (Remote host closed the connection)
2024-04-02 01:27:21 +0200Cajun(~Cajun@user/cajun)
2024-04-02 01:27:42 +0200Cajun(~Cajun@user/cajun) (Client Quit)
2024-04-02 01:27:57 +0200mei(~mei@user/mei)
2024-04-02 01:32:12 +0200Tuplanolla(~Tuplanoll@91-159-69-59.elisa-laajakaista.fi) (Quit: Leaving.)
2024-04-02 01:34:24 +0200caconym5(~caconym@user/caconym)
2024-04-02 01:36:15 +0200caconym(~caconym@user/caconym) (Ping timeout: 260 seconds)
2024-04-02 01:36:15 +0200caconym5caconym
2024-04-02 01:42:35 +0200Maxdamantus(~Maxdamant@user/maxdamantus) (Ping timeout: 264 seconds)
2024-04-02 01:47:25 +0200Maxdamantus(~Maxdamant@user/maxdamantus)
2024-04-02 01:47:33 +0200destituion(~destituio@2001:4644:c37:0:6086:64f4:a213:b80d) (Ping timeout: 272 seconds)
2024-04-02 01:55:08 +0200KittyMcCatFaceShe
2024-04-02 01:58:00 +0200talismanick(~user@2601:644:937c:ed10::ae5)
2024-04-02 02:00:20 +0200destituion(~destituio@2a02:2121:655:c95b:9402:ea22:1848:e3db)
2024-04-02 02:05:49 +0200pavonia(~user@user/siracusa)
2024-04-02 02:10:02 +0200caconym(~caconym@user/caconym) (Read error: Connection reset by peer)
2024-04-02 02:10:17 +0200caconym(~caconym@user/caconym)
2024-04-02 02:20:55 +0200geekopurrgeekosaur
2024-04-02 02:38:13 +0200fererrorocher(fererroroc@gateway/vpn/protonvpn/fererrorocher) (Quit: WeeChat 4.2.1)
2024-04-02 03:08:07 +0200dbaoty(~dbaoty@tptn-04-0838.dsl.iowatelecom.net) (Quit: Leaving.)
2024-04-02 03:25:51 +0200machinedgod(~machinedg@d173-183-246-216.abhsia.telus.net) (Ping timeout: 256 seconds)
2024-04-02 03:32:07 +0200tertek(~tertek@user/tertek) (Quit: %quit%)
2024-04-02 03:32:28 +0200tertek(~tertek@user/tertek)
2024-04-02 03:33:10 +0200Achylles(~Achylles@45.182.57.3)
2024-04-02 03:33:23 +0200falafel_(~falafel@162.83.249.190)
2024-04-02 03:37:17 +0200FragByte_(~christian@user/fragbyte)
2024-04-02 03:37:35 +0200FragByte(~christian@user/fragbyte) (Ping timeout: 260 seconds)
2024-04-02 03:37:35 +0200FragByte_FragByte
2024-04-02 03:37:46 +0200Achylles_(~Achylles@45.182.57.3)
2024-04-02 03:41:03 +0200Achylles__(~Achylles@45.182.57.3)
2024-04-02 03:41:09 +0200xff0x(~xff0x@2405:6580:b080:900:2b2b:eb19:37de:d4bd) (Ping timeout: 256 seconds)
2024-04-02 03:41:40 +0200Achylles(~Achylles@45.182.57.3) (Quit: Leaving)
2024-04-02 03:41:43 +0200Achylles__(~Achylles@45.182.57.3) (Read error: Connection reset by peer)
2024-04-02 03:41:43 +0200Achylles_(~Achylles@45.182.57.3) (Read error: Connection reset by peer)
2024-04-02 03:45:59 +0200waleee(~waleee@h-176-10-144-38.NA.cust.bahnhof.se) (Ping timeout: 272 seconds)
2024-04-02 03:50:07 +0200otto_s(~user@p4ff2714c.dip0.t-ipconnect.de) (Ping timeout: 268 seconds)
2024-04-02 03:50:13 +0200Guest23(~Guest23@static.126144025125.cidr.jtidc.jp)
2024-04-02 03:51:31 +0200otto_s(~user@p4ff27c9e.dip0.t-ipconnect.de)
2024-04-02 03:53:43 +0200 <Guest23> I have a question.
2024-04-02 03:53:43 +0200 <Guest23> Is there any way to show `definition of self defined data type`?
2024-04-02 03:53:44 +0200 <Guest23> Like this
2024-04-02 03:53:44 +0200 <Guest23> ```
2024-04-02 03:53:45 +0200 <Guest23> data Mydata = Foo | Bar
2024-04-02 03:53:45 +0200 <Guest23> main = print Mydata
2024-04-02 03:53:46 +0200 <Guest23>        -- > "Mydata = Foo | Bar"
2024-04-02 03:53:46 +0200 <Guest23> ```
2024-04-02 03:54:24 +0200mei(~mei@user/mei) (Remote host closed the connection)
2024-04-02 03:56:31 +0200 <geekosaur> it might be possible via Genetics
2024-04-02 03:56:49 +0200 <geekosaur> er, Generics
2024-04-02 03:56:49 +0200mei(~mei@user/mei)
2024-04-02 03:57:58 +0200 <geekosaur> types are otherwise erased at runtime, so that information isn't available
2024-04-02 04:03:39 +0200iteratee_(~kyle@162.218.222.207)
2024-04-02 04:03:47 +0200iteratee(~kyle@162.218.222.207) (Read error: Connection reset by peer)
2024-04-02 04:10:57 +0200ski(~ski@ext-1-033.eduroam.chalmers.se) (Ping timeout: 255 seconds)
2024-04-02 04:14:27 +0200infinity0_(~infinity0@pwned.gg)
2024-04-02 04:14:27 +0200infinity0Guest4479
2024-04-02 04:14:27 +0200Guest4479(~infinity0@pwned.gg) (Killed (zinc.libera.chat (Nickname regained by services)))
2024-04-02 04:14:27 +0200infinity0_infinity0
2024-04-02 04:23:22 +0200ski(~ski@ext-1-033.eduroam.chalmers.se)
2024-04-02 04:25:54 +0200xff0x(~xff0x@125x103x176x34.ap125.ftth.ucom.ne.jp)
2024-04-02 04:30:27 +0200bitdex(~bitdex@gateway/tor-sasl/bitdex) (Remote host closed the connection)
2024-04-02 04:31:20 +0200rosco(~rosco@121.120.71.44)
2024-04-02 04:31:31 +0200bitdex(~bitdex@gateway/tor-sasl/bitdex)
2024-04-02 04:32:52 +0200bitdex(~bitdex@gateway/tor-sasl/bitdex) (Remote host closed the connection)
2024-04-02 04:33:59 +0200bitdex(~bitdex@gateway/tor-sasl/bitdex)
2024-04-02 04:39:29 +0200rosco(~rosco@121.120.71.44) (Quit: Lost terminal)
2024-04-02 04:40:46 +0200falafel_(~falafel@162.83.249.190) (Ping timeout: 264 seconds)
2024-04-02 04:48:23 +0200califax(~califax@user/califx) (Remote host closed the connection)
2024-04-02 04:48:47 +0200califax(~califax@user/califx)
2024-04-02 04:49:40 +0200califax(~califax@user/califx) (Remote host closed the connection)
2024-04-02 04:50:04 +0200califax(~califax@user/califx)
2024-04-02 04:51:45 +0200machinedgod(~machinedg@d173-183-246-216.abhsia.telus.net)
2024-04-02 04:54:21 +0200califax(~califax@user/califx) (Remote host closed the connection)
2024-04-02 04:54:41 +0200califax(~califax@user/califx)
2024-04-02 04:55:43 +0200Guest23(~Guest23@static.126144025125.cidr.jtidc.jp) (Quit: Client closed)
2024-04-02 05:00:53 +0200td_(~td@i53870937.versanet.de) (Ping timeout: 252 seconds)
2024-04-02 05:02:35 +0200td_(~td@i53870933.versanet.de)
2024-04-02 05:04:02 +0200califax(~califax@user/califx) (Remote host closed the connection)
2024-04-02 05:04:21 +0200califax(~califax@user/califx)
2024-04-02 05:15:13 +0200Square2(~Square@user/square)
2024-04-02 05:29:26 +0200aforemny(~aforemny@2001:9e8:6cd9:500:d9a4:1707:4c79:474) (Ping timeout: 256 seconds)
2024-04-02 05:29:37 +0200aforemny_(~aforemny@2001:9e8:6cfb:ec00:7756:c37a:675d:87ba)
2024-04-02 05:29:49 +0200ezzieyguywuf(~Unknown@user/ezzieyguywuf)
2024-04-02 05:33:33 +0200igemnace(~ian@user/igemnace)
2024-04-02 05:35:11 +0200erisco(~erisco@d24-141-66-165.home.cgocable.net) (Ping timeout: 260 seconds)
2024-04-02 05:35:17 +0200 <Inst> just curious, but how much vomit do existential types provoke?
2024-04-02 05:35:31 +0200erisco(~erisco@d24-141-66-165.home.cgocable.net)
2024-04-02 05:36:17 +0200 <Inst> it looks very useful, but it seems as though it's potentially a deathtrap
2024-04-02 05:39:03 +0200 <Inst> yup, seems to make the type checker go haywire
2024-04-02 05:48:28 +0200dsrt^(~cd@c-98-242-74-66.hsd1.ga.comcast.net) (Remote host closed the connection)
2024-04-02 05:52:18 +0200Square(~Square4@user/square)
2024-04-02 05:55:18 +0200Square2(~Square@user/square) (Ping timeout: 268 seconds)
2024-04-02 05:59:35 +0200ezzieyguywuf(~Unknown@user/ezzieyguywuf) (Remote host closed the connection)
2024-04-02 06:00:32 +0200ezzieyguywuf(~Unknown@user/ezzieyguywuf)
2024-04-02 06:01:38 +0200 <ski> haywire, how ?
2024-04-02 06:04:42 +0200ec_(~ec@gateway/tor-sasl/ec) (Ping timeout: 260 seconds)
2024-04-02 06:06:41 +0200ec_(~ec@gateway/tor-sasl/ec)
2024-04-02 06:46:47 +0200adanwan(~adanwan@gateway/tor-sasl/adanwan) (Remote host closed the connection)
2024-04-02 06:47:08 +0200adanwan(~adanwan@gateway/tor-sasl/adanwan)
2024-04-02 06:52:17 +0200adanwan(~adanwan@gateway/tor-sasl/adanwan) (Remote host closed the connection)
2024-04-02 06:52:33 +0200adanwan(~adanwan@gateway/tor-sasl/adanwan)
2024-04-02 07:05:45 +0200_ht(~Thunderbi@28-52-174-82.ftth.glasoperator.nl)
2024-04-02 07:23:20 +0200machinedgod(~machinedg@d173-183-246-216.abhsia.telus.net) (Ping timeout: 252 seconds)
2024-04-02 07:24:59 +0200xal(~xal@mx1.xal.systems) ()
2024-04-02 07:31:28 +0200euphores(~SASL_euph@user/euphores)
2024-04-02 07:53:41 +0200euphores(~SASL_euph@user/euphores) (Ping timeout: 240 seconds)
2024-04-02 08:00:04 +0200Sgeo(~Sgeo@user/sgeo) (Read error: Connection reset by peer)
2024-04-02 08:14:53 +0200xal(~xal@mx1.xal.systems)
2024-04-02 08:21:38 +0200peterbecich(~Thunderbi@047-229-123-186.res.spectrum.com)
2024-04-02 08:21:53 +0200michalz(~michalz@185.246.207.200)
2024-04-02 08:26:51 +0200peterbecich(~Thunderbi@047-229-123-186.res.spectrum.com) (Remote host closed the connection)
2024-04-02 08:28:08 +0200gmg(~user@user/gehmehgeh)
2024-04-02 08:28:15 +0200peterbecich(~Thunderbi@047-229-123-186.res.spectrum.com)
2024-04-02 08:33:03 +0200stiell_(~stiell@gateway/tor-sasl/stiell) (Remote host closed the connection)
2024-04-02 08:34:08 +0200stiell_(~stiell@gateway/tor-sasl/stiell)
2024-04-02 08:46:51 +0200lortabac(~lortabac@2a01:e0a:541:b8f0:55ab:e185:7f81:54a4)
2024-04-02 08:47:23 +0200acidjnk_new(~acidjnk@p200300d6e714dc8721a8bc0199a4b6df.dip0.t-ipconnect.de)
2024-04-02 08:49:36 +0200danza(~francesco@151.57.164.121)
2024-04-02 08:55:59 +0200peterbecich(~Thunderbi@047-229-123-186.res.spectrum.com) (Ping timeout: 268 seconds)
2024-04-02 08:57:34 +0200tromp(~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl)
2024-04-02 09:00:22 +0200CrunchyFlakes(~CrunchyFl@ip92348280.dynamic.kabel-deutschland.de) (Quit: ZNC 1.8.2 - https://znc.in)
2024-04-02 09:04:21 +0200CrunchyFlakes(~CrunchyFl@ip92348280.dynamic.kabel-deutschland.de)
2024-04-02 09:12:10 +0200bitdex(~bitdex@gateway/tor-sasl/bitdex) (Remote host closed the connection)
2024-04-02 09:13:11 +0200bitdex(~bitdex@gateway/tor-sasl/bitdex)
2024-04-02 09:17:31 +0200zetef(~quassel@5.2.182.99)
2024-04-02 09:26:10 +0200SurfBlueCrab(~SurfBlueC@nyc.nanobit.org)
2024-04-02 09:43:31 +0200oo_miguel(~Thunderbi@78-11-181-16.static.ip.netia.com.pl)
2024-04-02 09:44:11 +0200tzh(~tzh@c-73-164-206-160.hsd1.or.comcast.net) (Quit: zzz)
2024-04-02 09:49:12 +0200econo_(uid147250@id-147250.tinside.irccloud.com) (Quit: Connection closed for inactivity)
2024-04-02 09:51:17 +0200danza(~francesco@151.57.164.121) (Ping timeout: 240 seconds)
2024-04-02 09:53:20 +0200zetef(~quassel@5.2.182.99) (Ping timeout: 268 seconds)
2024-04-02 09:53:30 +0200CiaoSen(~Jura@2a05:5800:2b2:5300:e6b9:7aff:fe80:3d03)
2024-04-02 09:57:11 +0200machinedgod(~machinedg@d173-183-246-216.abhsia.telus.net)
2024-04-02 10:04:41 +0200zetef(~quassel@5.2.182.99)
2024-04-02 10:07:47 +0200remmie(ianremsen@tilde.team) (Ping timeout: 264 seconds)
2024-04-02 10:08:17 +0200igemnace(~ian@user/igemnace) (Read error: Connection reset by peer)
2024-04-02 10:09:49 +0200 <tomsmeding> Inst: you unpack existentials by pattern matching on the constructor containing them
2024-04-02 10:10:23 +0200 <tomsmeding> (which you can read as compatible with the CPS encoding by reading "pattern matching" and "constructor" as "application" and "function", respectively)
2024-04-02 10:10:44 +0200 <tomsmeding> you should not expect to be able to "return" an existentially quantified type from a function directly
2024-04-02 10:11:13 +0200 <tomsmeding> apart from that, they work fine, but this need to wrap things in a constructor makes things kind of verbose sometimes
2024-04-02 10:13:17 +0200danse-nr3(~danse-nr3@151.57.164.121)
2024-04-02 10:18:01 +0200zetef(~quassel@5.2.182.99) (Ping timeout: 272 seconds)
2024-04-02 10:19:31 +0200remmie(ianremsen@tilde.team)
2024-04-02 10:25:21 +0200igemnace(~ian@user/igemnace)
2024-04-02 10:29:23 +0200zetef(~quassel@5.2.182.99)
2024-04-02 10:34:52 +0200FragByte(~christian@user/fragbyte) (Ping timeout: 256 seconds)
2024-04-02 10:35:16 +0200remmie(ianremsen@tilde.team) (Ping timeout: 268 seconds)
2024-04-02 10:35:26 +0200FragByte(~christian@user/fragbyte)
2024-04-02 10:41:58 +0200chiselfuse(~chiselfus@user/chiselfuse) (Remote host closed the connection)
2024-04-02 10:42:47 +0200chiselfuse(~chiselfus@user/chiselfuse)
2024-04-02 10:43:09 +0200chiselfuse(~chiselfus@user/chiselfuse) (Remote host closed the connection)
2024-04-02 10:44:50 +0200tushar2(~tushar@103.176.64.116)
2024-04-02 10:45:04 +0200CiaoSen(~Jura@2a05:5800:2b2:5300:e6b9:7aff:fe80:3d03) (Ping timeout: 256 seconds)
2024-04-02 10:45:24 +0200lisbeths(uid135845@id-135845.lymington.irccloud.com)
2024-04-02 10:47:18 +0200Inst_(~Inst@120.244.192.126)
2024-04-02 10:47:49 +0200chiselfuse(~chiselfus@user/chiselfuse)
2024-04-02 10:48:19 +0200danse-nr3(~danse-nr3@151.57.164.121) (Ping timeout: 255 seconds)
2024-04-02 10:50:11 +0200Inst(~Inst@120.244.192.126) (Ping timeout: 260 seconds)
2024-04-02 10:51:37 +0200chiselfuse(~chiselfus@user/chiselfuse) (Remote host closed the connection)
2024-04-02 10:52:25 +0200stiell_(~stiell@gateway/tor-sasl/stiell) (Remote host closed the connection)
2024-04-02 10:52:49 +0200stiell_(~stiell@gateway/tor-sasl/stiell)
2024-04-02 10:52:51 +0200chiselfuse(~chiselfus@user/chiselfuse)
2024-04-02 10:54:42 +0200chiselfuse(~chiselfus@user/chiselfuse) (Remote host closed the connection)
2024-04-02 10:55:37 +0200danse-nr3(~danse-nr3@151.57.164.121)
2024-04-02 10:55:41 +0200 <carbolymer> what's the good list alternative which will store its length in the type?
2024-04-02 10:56:36 +0200 <carbolymer> this https://hackage.haskell.org/package/vec-0.5/docs/Data-Vec-Lazy.html#t:Vec ? Idk what's the best option out there
2024-04-02 10:57:59 +0200chiselfuse(~chiselfus@user/chiselfuse)
2024-04-02 10:59:09 +0200stiell_(~stiell@gateway/tor-sasl/stiell) (Remote host closed the connection)
2024-04-02 10:59:33 +0200stiell_(~stiell@gateway/tor-sasl/stiell)
2024-04-02 11:02:26 +0200danse-nr3(~danse-nr3@151.57.164.121) (Read error: Connection reset by peer)
2024-04-02 11:02:50 +0200danse-nr3(~danse-nr3@151.57.164.121)
2024-04-02 11:03:06 +0200ubert(~Thunderbi@2a02:8109:ab8a:5a00:5d4b:5ac:c6db:5974)
2024-04-02 11:04:24 +0200Rodney_(~Rodney@176.254.244.83) (Ping timeout: 260 seconds)
2024-04-02 11:10:25 +0200chiselfuse(~chiselfus@user/chiselfuse) (Remote host closed the connection)
2024-04-02 11:11:19 +0200chiselfuse(~chiselfus@user/chiselfuse)
2024-04-02 11:11:59 +0200CiaoSen(~Jura@2a05:5800:2b2:5300:e6b9:7aff:fe80:3d03)
2024-04-02 11:13:32 +0200Rodney_(~Rodney@92.40.181.27.threembb.co.uk)
2024-04-02 11:14:08 +0200remmie(ianremsen@tilde.team)
2024-04-02 11:14:49 +0200chiselfuse(~chiselfus@user/chiselfuse) (Remote host closed the connection)
2024-04-02 11:16:24 +0200chiselfuse(~chiselfus@user/chiselfuse)
2024-04-02 11:16:48 +0200CiaoSen(~Jura@2a05:5800:2b2:5300:e6b9:7aff:fe80:3d03) (Ping timeout: 256 seconds)
2024-04-02 11:22:11 +0200 <danse-nr3> not sure carbolymer, did not get beyond NonEmpty yet...
2024-04-02 11:22:22 +0200 <carbolymer> :)
2024-04-02 11:25:37 +0200 <danse-nr3> might be a debated topic where people tend to roll out their own solution
2024-04-02 11:29:28 +0200Rodney_(~Rodney@92.40.181.27.threembb.co.uk) (Read error: Connection reset by peer)
2024-04-02 11:32:21 +0200stiell_(~stiell@gateway/tor-sasl/stiell) (Remote host closed the connection)
2024-04-02 11:32:48 +0200stiell_(~stiell@gateway/tor-sasl/stiell)
2024-04-02 11:34:05 +0200lortabac(~lortabac@2a01:e0a:541:b8f0:55ab:e185:7f81:54a4) (Ping timeout: 240 seconds)
2024-04-02 11:35:01 +0200Rodney_(~Rodney@176.254.244.83)
2024-04-02 11:35:55 +0200todi(~todi@p57803331.dip0.t-ipconnect.de) (Ping timeout: 272 seconds)
2024-04-02 11:36:41 +0200jespada(~jespada@cpc121308-nmal25-2-0-cust15.19-2.cable.virginm.net) (Quit: Textual IRC Client: www.textualapp.com)
2024-04-02 11:40:42 +0200mmhat(~mmh@p200300f1c74dcfc3ee086bfffe095315.dip0.t-ipconnect.de)
2024-04-02 11:43:33 +0200jespada(~jespada@cpc121308-nmal25-2-0-cust15.19-2.cable.virginm.net)
2024-04-02 11:44:16 +0200lortabac(~lortabac@2a01:e0a:541:b8f0:55ab:e185:7f81:54a4)
2024-04-02 11:45:15 +0200tromp(~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…)
2024-04-02 11:48:35 +0200cfricke(~cfricke@user/cfricke)
2024-04-02 11:52:15 +0200tromp(~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl)
2024-04-02 11:53:18 +0200chiselfuse(~chiselfus@user/chiselfuse) (Ping timeout: 260 seconds)
2024-04-02 11:54:23 +0200todi(~todi@p57803331.dip0.t-ipconnect.de)
2024-04-02 11:55:07 +0200chiselfuse(~chiselfus@user/chiselfuse)
2024-04-02 11:56:03 +0200zetef(~quassel@5.2.182.99) (Ping timeout: 268 seconds)
2024-04-02 11:58:20 +0200 <carbolymer> yeah, but writing my own feels like kicking an already open doors
2024-04-02 12:01:57 +0200siw5ohs0(~aiw5ohs0@user/aiw5ohs0)
2024-04-02 12:02:06 +0200siw5ohs0(~aiw5ohs0@user/aiw5ohs0) (Leaving)
2024-04-02 12:05:59 +0200todi(~todi@p57803331.dip0.t-ipconnect.de) (Ping timeout: 264 seconds)
2024-04-02 12:13:34 +0200qqq(~qqq@92.43.167.61) (Read error: Connection reset by peer)
2024-04-02 12:15:49 +0200xff0x(~xff0x@125x103x176x34.ap125.ftth.ucom.ne.jp) (Ping timeout: 272 seconds)
2024-04-02 12:18:09 +0200qqq(~qqq@92.43.167.61)
2024-04-02 12:21:58 +0200robobub(uid248673@id-248673.uxbridge.irccloud.com) (Quit: Connection closed for inactivity)
2024-04-02 12:23:11 +0200lortabac(~lortabac@2a01:e0a:541:b8f0:55ab:e185:7f81:54a4) (Ping timeout: 268 seconds)
2024-04-02 12:30:00 +0200Lord_of_Life(~Lord@user/lord-of-life/x-2819915) (Ping timeout: 255 seconds)
2024-04-02 12:30:51 +0200Lord_of_Life(~Lord@user/lord-of-life/x-2819915)
2024-04-02 12:35:47 +0200zetef(~quassel@5.2.182.99)
2024-04-02 12:38:15 +0200tromp(~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…)
2024-04-02 12:39:53 +0200 <tomsmeding> one might also think of reducing dependencies, in light of the recent xz shenanigans :)
2024-04-02 12:46:38 +0200todi(~todi@p57803331.dip0.t-ipconnect.de)
2024-04-02 12:50:16 +0200danse-nr3_(~danse-nr3@151.57.194.26)
2024-04-02 12:51:01 +0200dbaoty(~dbaoty@tptn-04-0838.dsl.iowatelecom.net)
2024-04-02 12:53:11 +0200danse-nr3(~danse-nr3@151.57.164.121) (Ping timeout: 272 seconds)
2024-04-02 12:53:25 +0200lortabac(~lortabac@2a01:e0a:541:b8f0:55ab:e185:7f81:54a4)
2024-04-02 12:56:02 +0200tromp(~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl)
2024-04-02 12:56:43 +0200zetef(~quassel@5.2.182.99) (Remote host closed the connection)
2024-04-02 13:04:47 +0200todi(~todi@p57803331.dip0.t-ipconnect.de) (Ping timeout: 264 seconds)
2024-04-02 13:06:49 +0200zetef(~quassel@5.2.182.99)
2024-04-02 13:15:46 +0200lvdv(~lvdv@203.221.237.91)
2024-04-02 13:16:18 +0200xff0x(~xff0x@2405:6580:b080:900:ee6c:a70f:8c18:8e14)
2024-04-02 13:30:07 +0200todi(~todi@p57803331.dip0.t-ipconnect.de)
2024-04-02 13:33:31 +0200lvdv(~lvdv@203.221.237.91) (Ping timeout: 260 seconds)
2024-04-02 13:35:18 +0200lvdv(~lvdv@211.30.149.12)
2024-04-02 13:35:22 +0200danse-nr3_(~danse-nr3@151.57.194.26) (Read error: Connection reset by peer)
2024-04-02 13:36:37 +0200zetef(~quassel@5.2.182.99) (Ping timeout: 255 seconds)
2024-04-02 13:38:09 +0200meritamen(~meritamen@user/meritamen)
2024-04-02 13:41:58 +0200lvdv(~lvdv@211.30.149.12) (Ping timeout: 264 seconds)
2024-04-02 13:43:38 +0200lvdv(~lvdv@203.221.237.91)
2024-04-02 13:46:28 +0200zetef(~quassel@5.2.182.99)
2024-04-02 13:49:41 +0200rvalue(~rvalue@user/rvalue) (Read error: Connection reset by peer)
2024-04-02 13:50:11 +0200rvalue(~rvalue@user/rvalue)
2024-04-02 13:52:54 +0200tushar2(~tushar@103.176.64.116) (Quit: WeeChat 4.2.1)
2024-04-02 14:05:56 +0200zetef(~quassel@5.2.182.99) (Ping timeout: 252 seconds)
2024-04-02 14:07:43 +0200lvdv(~lvdv@203.221.237.91) (Ping timeout: 268 seconds)
2024-04-02 14:08:13 +0200 <Inst_> tomsmeding: but I can't actually pattern match on the contained data within my existential type, or rather, I have to treat it as generic
2024-04-02 14:08:45 +0200 <Inst_> data Foo where Whee :: forall a. Show a => a -> Foo
2024-04-02 14:08:48 +0200Inst_Inst
2024-04-02 14:08:56 +0200 <Inst> what :: Foo -> Int
2024-04-02 14:09:05 +0200 <Inst> what (Whee "Hello") = 3
2024-04-02 14:09:09 +0200 <Inst> doesn't typecheck
2024-04-02 14:09:19 +0200 <tomsmeding> I mean, well, yes
2024-04-02 14:09:23 +0200 <tomsmeding> that's what an existential is
2024-04-02 14:09:28 +0200 <tomsmeding> you don't know what the original type was :p
2024-04-02 14:09:51 +0200 <tomsmeding> the point of an existential is to allow this
2024-04-02 14:10:19 +0200lvdv(~lvdv@203.221.237.91)
2024-04-02 14:11:11 +0200 <tomsmeding> er wait
2024-04-02 14:11:14 +0200 <Inst> realistically I can only interact it with
2024-04-02 14:11:15 +0200lvdv(~lvdv@203.221.237.91) (Client Quit)
2024-04-02 14:11:17 +0200 <tomsmeding> yes
2024-04-02 14:11:21 +0200 <Inst> what (Whee a) = show a
2024-04-02 14:11:23 +0200 <tomsmeding> yes
2024-04-02 14:11:26 +0200 <Inst> or what (Whee ) = foo
2024-04-02 14:11:26 +0200 <tomsmeding> that's the point
2024-04-02 14:11:50 +0200 <tomsmeding> you can't pattern match on _types_ in haskell
2024-04-02 14:11:57 +0200danse-nr3(~danse-nr3@151.43.191.28)
2024-04-02 14:12:02 +0200 <tomsmeding> you can only pattern match on _constructors_ of a known data type
2024-04-02 14:12:15 +0200 <Inst> but the thing is basically coupled with typeclasses
2024-04-02 14:12:21 +0200 <tomsmeding> not necessarily
2024-04-02 14:12:28 +0200 <tomsmeding> data Foo where Whee :: a -> (a -> String) -> Foo
2024-04-02 14:12:35 +0200 <tomsmeding> no reason a type class needs to get involved
2024-04-02 14:12:40 +0200 <tomsmeding> it's just a natural match in some ways
2024-04-02 14:12:48 +0200 <Inst> I was thinking something like forall a. ToHTML a, or Widget a
2024-04-02 14:13:26 +0200 <tomsmeding> a value of type 'forall a. ToHTML a => a', where that 'forall' indicates an existential, is the same as 'HTML'
2024-04-02 14:14:27 +0200 <tomsmeding> i.e. if you're wanting to write 'data Thing = forall a. ToHTML a => Thing a' then instead just write 'newtype Thing = Thing HTML'
2024-04-02 14:14:46 +0200 <tomsmeding> nothing you can do with the former that you can't do with the latter
2024-04-02 14:14:53 +0200 <tomsmeding> and the code is simpler to boot
2024-04-02 14:15:28 +0200 <tomsmeding> in fact the former is very inflexible, you can do very little with it
2024-04-02 14:16:04 +0200 <tomsmeding> you can't do more with "a collection of things of which you know only that they can be converted to HTML" than with "a collection of HTML documents"
2024-04-02 14:23:45 +0200Maxdamantus(~Maxdamant@user/maxdamantus) (Ping timeout: 256 seconds)
2024-04-02 14:24:49 +0200lisbeths(uid135845@id-135845.lymington.irccloud.com) (Quit: Connection closed for inactivity)
2024-04-02 14:25:03 +0200 <Inst> i'm not sure if this is a plus or a minus, but this is really a problem Lisps don't have, and Haskell does, ideally, what I want is the ability to toHTML template objects
2024-04-02 14:25:17 +0200 <Inst> but have the objects compose
2024-04-02 14:26:12 +0200 <Inst> the interface would be Page {head = foo, body = bar}
2024-04-02 14:26:37 +0200 <Inst> then foo you'd be able to use nested record types etc to construct / decosntruct
2024-04-02 14:26:54 +0200 <Inst> more importantly, do it with body, then do script / style bs to inject CSS and so on
2024-04-02 14:32:32 +0200Maxdamantus(~Maxdamant@user/maxdamantus)
2024-04-02 14:33:16 +0200 <Inst> The idea is that you'd eventually end up with a widget ecosystem built around such a library, allowing users to just steal preexisting HTML presets etc
2024-04-02 14:33:22 +0200 <Inst> and it'd be a user language for the platform I want to use
2024-04-02 14:36:13 +0200pera_(~pera@8.29.109.183)
2024-04-02 14:36:37 +0200kuribas(~user@ip-188-118-57-242.reverse.destiny.be)
2024-04-02 14:37:25 +0200 <Inst> beating py in terms of scripting ergonomics is hard
2024-04-02 14:37:41 +0200 <Inst> but, say, JS / golden trio (html / css / js)? easy peasy
2024-04-02 14:37:46 +0200foul_owl(~kerry@185.216.231.179) (Read error: Connection reset by peer)
2024-04-02 14:40:04 +0200 <pera_> I have a general FP nomenclature question: is it correct to say "returned value" in the context of function application?
2024-04-02 14:42:22 +0200 <ski> perhaps it would be slightly better to say "result((ing) value)" (note that there is no `return' command to specify a computation yielding a designated value as result of a function application/call)
2024-04-02 14:43:13 +0200 <haskellbridge> <e​ldritchcookie> say how could i learn delimited continuations and more specifically control0# i think i understand callCC but control0 eludes me
2024-04-02 14:43:14 +0200 <pera_> ski: ah resulting sound much better, thanks
2024-04-02 14:43:34 +0200 <ski> but generally people are going to understand what you mean, probably (although newbies might still have confusions, due to the lack of such a `return'. there is no "if this happens, return this value, aborting the current computation that was doing something more")
2024-04-02 14:43:49 +0200 <tomsmeding> Inst: isn't the thing there "dictionaries first-class in the language"?
2024-04-02 14:43:59 +0200 <tomsmeding> "untyped objects" ~= "dictionaries"
2024-04-02 14:44:19 +0200michalz(~michalz@185.246.207.200) (Quit: ZNC 1.8.2 - https://znc.in)
2024-04-02 14:44:35 +0200michalz(~michalz@185.246.207.197)
2024-04-02 14:44:43 +0200 <pera_> ski: yeah I agree
2024-04-02 14:44:56 +0200 <ski> eldritchcookie : do you understand the CPS transform (at least the call-by-value version) ?
2024-04-02 14:46:22 +0200 <ski> pera_ : still .. i think it is helpful to be more pedantic with word choice, pertinent distinctions, with learners and newbies. one can afford to be more sloppy with language, with people who've already grasped the basics, the important concepts and categories that are relied on in a fundamental level
2024-04-02 14:46:40 +0200AlexZenon(~alzenon@94.233.240.255) (Quit: ;-)
2024-04-02 14:47:29 +0200 <haskellbridge> <e​ldritchcookie> i guess so for instace some time ago i made template haskell to generate functions that turned (a1 ->... -> an -> m ()) -> m () into Cont m () (a1,..,an)
2024-04-02 14:47:57 +0200AlexNoo(~AlexNoo@94.233.240.255) (Quit: Leaving)
2024-04-02 14:48:09 +0200 <tomsmeding> the idea of cps is simply "turn a1 -> ... -> an -> b into a1 -> ... -> an -> forall r. (b -> r) -> r"
2024-04-02 14:48:39 +0200 <tomsmeding> so `add (mul 2 3) 4` becomes `\k -> mul 2 3 (\prod -> add prod 4 k)`
2024-04-02 14:49:10 +0200 <tomsmeding> the typical idea being that calls to these continuations are tail calls
2024-04-02 14:49:46 +0200 <shapr> @quote
2024-04-02 14:49:46 +0200 <lambdabot> gFunk says: [the main advantage of functional programs are that they're] incorrect the first 1000 times you try to compile it!
2024-04-02 14:49:56 +0200 <haskellbridge> <e​ldritchcookie> yep and then you give it id to get the final result
2024-04-02 14:50:01 +0200 <tomsmeding> yes
2024-04-02 14:50:09 +0200meritamen(~meritamen@user/meritamen) (Quit: Client closed)
2024-04-02 14:50:51 +0200 <haskellbridge> <e​ldritchcookie> before trying to understand delimited continuations i thought i understood continuations
2024-04-02 14:51:23 +0200 <pera_> ski: absolutely, specially with a word like return that has quite a few meanings depending the context (call stack, statement, monad return, etc)
2024-04-02 14:53:44 +0200 <ski> Inst : "but I can't actually pattern match on the contained data within my existential type, or rather, I have to treat it as generic" -- yes. exactly like a polymorphic function (e.g. `mystery :: forall a. Int -> [a] -> [a]') can't pattern-match on the values of the type variable `a', having to treat them as "black boxen". that type is, to `mystery' (and other operations (being polymorphic, or) *producing*
2024-04-02 14:53:50 +0200 <ski> polymorphic values (values of type `forall a. ..a..') as output), abstract/forgotten/hidden/unknown/opaque/skolem
2024-04-02 14:53:53 +0200 <ski> Inst : the same holds for operations *consuming* "abstracted" values as input (values of type `exists a. ..a..'. any values of the abstract/forgotten/hidden/unknown/opaque/skolem type `a' here act like black boxen, can only be interrogated via relevant callbacks (including type class methods, if available), just like in the polymorphic case)
2024-04-02 14:54:44 +0200foul_owl(~kerry@185.219.141.164)
2024-04-02 14:55:44 +0200 <ski> tomsmeding : s/forall a. ToHTML a => a/exists a. ToHTML a *> a/
2024-04-02 14:58:26 +0200 <ski> Inst : "this is really a problem Lisps don't have, and Haskell does, ideally, what I want is the ability to toHTML template objects" -- meaning ?
2024-04-02 14:59:05 +0200 <ski> pera_ : i don't think it's wrong to use the term "return", just saying that one should be a bit careful that one doesn't accidentally lean into or cause (or be afflicted by) misconceptions
2024-04-02 14:59:16 +0200 <tomsmeding> ski: yes
2024-04-02 15:00:19 +0200 <ski> @get-shapr
2024-04-02 15:00:19 +0200 <lambdabot> shapr!!
2024-04-02 15:00:57 +0200 <shapr> you called?
2024-04-02 15:01:09 +0200 <ski> just saying hi :)
2024-04-02 15:01:17 +0200 <shapr> hi ski! long time no see in person
2024-04-02 15:01:47 +0200 <tomsmeding> (of course that's a builtin in lambdabot)
2024-04-02 15:01:53 +0200skigrins
2024-04-02 15:02:19 +0200 <ski> you're back in the U.S., iirc. hope you're doing well
2024-04-02 15:02:21 +0200 <shapr> I hosted lambdabot for the first seven years
2024-04-02 15:02:34 +0200 <shapr> ski: yes, I've been back in the US since 2007
2024-04-02 15:02:51 +0200 <ski> (mm, that's what i thought, but i haven't really been attempting to keep track)
2024-04-02 15:02:56 +0200 <shapr> yeah, no worries
2024-04-02 15:03:21 +0200 <ski> eldritchcookie : if you'd like, i could link you to two papers about CPS transformation
2024-04-02 15:03:40 +0200 <haskellbridge> <e​ldritchcookie> please do
2024-04-02 15:04:38 +0200bitdex(~bitdex@gateway/tor-sasl/bitdex) (Ping timeout: 260 seconds)
2024-04-02 15:04:40 +0200 <ski> now, maybe they'd be somewhat dense for you .. i dunno how used you are to reading research papers. but hopefully you'll at least be able to get something out of them, specifically in this case the basics of the CPS transformation
2024-04-02 15:05:02 +0200 <ski> (iirc the papers include some theorems and proofs which you can probably skip more or less)
2024-04-02 15:05:30 +0200byorgey(~byorgey@155.138.238.211)
2024-04-02 15:08:08 +0200meritamen(~meritamen@user/meritamen)
2024-04-02 15:08:52 +0200 <ski> eldritchcookie : "Abstracting Control" in 1990-06, and "Representing Control: A Study of the CPS Transformation" in 1992-12, both by Andrzej Filinski,Olivier Danvy, at <http://hjemmesider.diku.dk/~andrzej/papers/>
2024-04-02 15:09:15 +0200nickiminjaj(~nickiminj@user/laxhh)
2024-04-02 15:09:46 +0200Maxdamantus(~Maxdamant@user/maxdamantus) (Ping timeout: 255 seconds)
2024-04-02 15:10:00 +0200 <ski> btw, if you haven't seen the paper before, and you're not used to reading papers with type system stuff (although i can't recall offhand how much of that is in the above two papers), i can also suggest
2024-04-02 15:10:25 +0200 <ski> @where polymorphic-type-inference
2024-04-02 15:10:25 +0200 <lambdabot> "Polymorphic Type Inference" by Michael I. Schwartzbach in 1995-03 at <https://cs.au.dk/~mis/typeinf.p(s|df)>,<http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.57.1493>
2024-04-02 15:11:12 +0200 <ski> simply because it goes over some basics that's usually not spelled out, and also because it does bring up a bunch of interesting things
2024-04-02 15:15:22 +0200 <ski> also, the links at e.g. <https://web.archive.org/web/20180726144531/http://library.readscheme.org/> (in this case the continuations section) may also be interesting (<https://github.com/scheme-and-computer-science/library.readscheme.org/blob/master/page6.md> appears to be a separate archive of the papers on the site)
2024-04-02 15:15:44 +0200zetef(~quassel@5.2.182.99)
2024-04-02 15:16:08 +0200Maxdamantus(~Maxdamant@user/maxdamantus)
2024-04-02 15:18:04 +0200 <ski> in any case, the Filinski & Danvy papers above do mention `shift' and `reset', as well as `call/cc'
2024-04-02 15:19:04 +0200 <ski> eldritchcookie : you may also want to check out Oleg's site, specifically <https://okmij.org/ftp/continuations/>
2024-04-02 15:22:13 +0200 <ski> eldritchcookie : from one POV, continuations are supposed to be an abstraction that represents a point of control, that you can *jump* to (with parameters/arguments), but there's no such thing as a return. from that perspective, they're like `jmp' in assembler languages. whereas functions are *called* (with some parameters), and *returns* a result back to the caller (the discovery/invention of the
2024-04-02 15:22:19 +0200 <ski> subroutine, with explicit support for stacks, makes this correspond to `jsr'/`bsr'/`call' or similar, in assembler language)
2024-04-02 15:24:57 +0200 <ski> eldritchcookie : from a typeful perspective, continuations are about negation, logically speaking. a continuation accepting an `Int' is like an "anti-`Int'" (kinda think of particle and anti-particle). in practice, in an expression-oriented language, such a continuation could be specified as the (dynamic/computational) *context* surrounding some particular (subexpression yielding an) `Int' value, e.g. the
2024-04-02 15:25:03 +0200 <ski> dots context surrounding `6*7' in `..(6*7)'. that continuation could be assigned the type `Not Int'
2024-04-02 15:25:10 +0200Maxdamantus(~Maxdamant@user/maxdamantus) (Remote host closed the connection)
2024-04-02 15:26:13 +0200 <haskellbridge> <e​ldritchcookie> would it be better to say we have an Int in negative position so we can act as if we had an int?
2024-04-02 15:26:38 +0200 <ski> from this perspective, a function of type `a -> b' can be seen as expressing a continuation of type `Not (a,Not b)' (a continuation accepting two parameters, one being of type `a', and the other being a "return address" (a continuation) that will (presumably) be called with a `b')
2024-04-02 15:27:10 +0200 <ski> (note that, logically speaking (in classical logic), `A => B' (`A' implies `B'), is equivalent to `not (A and not B)'. this is not a coindicence)
2024-04-02 15:29:31 +0200 <ski> .. and, at the assembler, or machine code, level, this is the basics of how subroutines, and functions, work. you pass some parameter(s) in some registers (or perhaps on a stack), and you also pass a *return address* (commonly on stack, but could be in a register as well). this closely adheres to the `Not (a,Not b)' picture of `a -> b'. this still ignores various issues about lifetime/extent (such as stack
2024-04-02 15:29:37 +0200 <ski> allocation), and closing over the static/lexical environment (accessing non-local variables, "closures") ..
2024-04-02 15:29:38 +0200nickiminjaj(~nickiminj@user/laxhh) (Quit: My MacBook has gone to sleep. ZZZzzz…)
2024-04-02 15:30:00 +0200 <ski> "would it be better to say we have an Int in negative position" -- in which situation ?
2024-04-02 15:30:40 +0200 <ski> .. anyway, from the above POV, continuations are a *more* fundamental concept than functions, functions being a derived concept, defined in terms of continuations
2024-04-02 15:30:46 +0200 <ski> @where Io
2024-04-02 15:30:46 +0200 <lambdabot> Raphael L. Levien's language with continuations as fundamental structure, described in his paper "Io: a new programming notation" (1989-09-10) at <http://dl.acm.org/citation.cfm?id=70931.70934> and
2024-04-02 15:30:46 +0200 <lambdabot> in chapter 2 of Raphael A. Finkel's book `APLD', implementations `Amalthea',`Ganymede' - (perhaps you were looking for `@wiki Introduction to IO' ?)
2024-04-02 15:31:01 +0200 <ski> is a language that is based on continuations as the basic primitive
2024-04-02 15:32:09 +0200 <ski> (APLD is "Advanced Programming Language Design" by Raphael Finkel in 1996 at <https://web.archive.org/web/20150522052725if_/http://www.nondot.org/sabre/Mirrored/AdvProgLangDesi…>)
2024-04-02 15:33:20 +0200 <shapr> Does anyone know if servant is both http 1.1 and http 2 ?
2024-04-02 15:33:26 +0200 <ski> anyway .. denotational semantics tries to explain meaning of programming languages, by mapping phrases of programs into (traditional) mathematical structures .. and continuations are not a common structure that people consider in mathematics, whereas functions most definitely are
2024-04-02 15:34:01 +0200 <dmj`> shapr: warp is http2
2024-04-02 15:34:03 +0200koz(~koz@121.99.240.58) (Quit: ZNC 1.8.2 - https://znc.in)
2024-04-02 15:34:10 +0200 <shapr> ah, and servant runs on top of warp
2024-04-02 15:34:15 +0200 <shapr> dmj`: thanks!
2024-04-02 15:35:32 +0200tromp(~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…)
2024-04-02 15:35:48 +0200 <ski> eldritchcookie : this leads to the other POV here, namely *representing*/*encoding*/*simulating* continuations, via *functions*. instead of having `square :: Not (Int,Not Int)', you have `squareTupledCPS :: (Int,Int -> o) -> o' or `squareCurriedCPS :: Int -> (Int -> o) -> o', where we replace the continuations by functions returning a value of an (*arbitrary*, hence type variable) "answer" type, `o' (often
2024-04-02 15:35:50 +0200Maxdamantus(~Maxdamant@user/maxdamantus)
2024-04-02 15:35:54 +0200 <ski> `omega' in papers)
2024-04-02 15:36:12 +0200koz(~koz@121.99.240.58)
2024-04-02 15:38:32 +0200 <ski> (in terms of logic, this corresponds to embedding classical logic in what's called "minimal logic". if we replace `o' by a specific answer type like `Void' (having no defined value), then it becomes an embedding/translation into intuitionistic logic. the difference is that there's a polymorphic function `void :: Void -> a' allowing us to pretend a `Void' can give us a result of any type. in logical terms,
2024-04-02 15:38:38 +0200 <ski> this corresponds to saying "this case is therefore impossible, and so we don't need to consider it further")
2024-04-02 15:38:54 +0200 <ski> eldritchcookie : .. is this making any sense ?
2024-04-02 15:38:54 +0200gorignak(~gorignak@user/gorignak) (Quit: quit)
2024-04-02 15:39:53 +0200 <haskellbridge> <e​ldritchcookie> no, but i liked https://www.youtube.com/watch?v=TE48LsgVlIU&t=1s
2024-04-02 15:40:14 +0200 <ski> what about my request for clarification above, then ?
2024-04-02 15:42:21 +0200AlexZenon(~alzenon@94.233.240.255)
2024-04-02 15:42:32 +0200AlexNoo(~AlexNoo@94.233.240.255)
2024-04-02 15:42:32 +0200 <ski> (i guess i was focused for a while on attempting to give a "from the bottom up / first principles" general overview of what continuations and CPS are about, above. but people do learn best in different ways. perhaps you'd prefer starting from specific applications)
2024-04-02 15:43:22 +0200 <haskellbridge> <e​ldritchcookie> o you mean the Int in negative position thing? well normally we have covariant types in positive position but when it gets under the arrow it becomes contravariant and it is in negative postion so in way we Gain a Int similar to how a function Char -> Char -> Int gives and Int
2024-04-02 15:44:16 +0200 <haskellbridge> <e​ldritchcookie> negative means somewhere somehow we gain a value, positive mean somewhere somehow we consume a value
2024-04-02 15:44:21 +0200 <ski> being in positive position means the same as being covariant in that position, yes. and ditto for negative & contravariant. just different ways to express the same thing
2024-04-02 15:44:39 +0200fererrorocher(fererroroc@gateway/vpn/protonvpn/fererrorocher)
2024-04-02 15:45:02 +0200 <haskellbridge> <e​ldritchcookie> yep
2024-04-02 15:45:04 +0200 <kuribas> Does wreq support concurrency (green threads)?
2024-04-02 15:46:22 +0200 <kuribas> I am doing REST call within a spock request, will they block between requests?
2024-04-02 15:46:41 +0200 <ski> but it's important to understand that a type like `Char -> Chat -> Int' can be viewed from two directions. namely (a) from the direction of a producer/callee/implementor/"constructor", that therefore will get two `Char's, and will have to build an `Int' from them; resp. (b) from the direction of a consumer/caller/user/"de(con)structor", that will have to provide two `Char's to it, getting an `Int' back
2024-04-02 15:46:54 +0200 <haskellbridge> <e​ldritchcookie> probably? it seems to me that the default API is synchronous
2024-04-02 15:47:18 +0200 <ski> often when considering a type, we primarily have the producer perspective in mind, but the consumer perspective is just as important
2024-04-02 15:48:07 +0200 <ski> (again, you could reduce this to whether you're considering the type in a positive or negative context .. although that kinda assumes that the "toplevel" context that you're considering is positive by definition)
2024-04-02 15:48:21 +0200 <haskellbridge> <e​ldritchcookie> makes sense
2024-04-02 15:49:09 +0200 <haskellbridge> <e​ldritchcookie> not necessarily it is positive from the caller's perspective which is the one that makes most sense to use if you are the caller
2024-04-02 15:49:41 +0200 <ski> (when i'm e.g. talking about existentials, i try to directly make use of this duality, to spell out parallels between how `forall' is consumed and `exists' is produced, and similarly between how `forall' is produced and `exists' is consumed)
2024-04-02 15:50:14 +0200 <ski> yea .. but we shift perspective between caller and callee, all the time, when programming subsystems
2024-04-02 15:51:05 +0200 <ski> so .. i still don't really understand what you meant to ask, by "uld it be better to say we have an Int in negative position so we can act as if we had an int?"
2024-04-02 15:52:20 +0200gawen(~gawen@user/gawen) (Quit: cya)
2024-04-02 15:53:43 +0200gawen(~gawen@user/gawen)
2024-04-02 15:56:08 +0200 <ski> .. so go back to delimited/composable/sub -continuations, for a moment, those are what happens when in `foo :: T -> (U -> o) -> o', you change `o' from being abstract, a type variable (quantified by the implicit `forall' at the top of the type signature), replacing it with some concrete type, say `Bool', or `IO ()' or `[a]' (say `forall'ing this `a'). what this allows you to do is to *not* call the
2024-04-02 15:56:14 +0200 <ski> "continuation" (callback) *last*. iow, to *deviate* from "every call is a tail/last call", which otherwise is what CPS enforces. for this reason, this is also called nqCPS
2024-04-02 15:56:39 +0200 <haskellbridge> <e​ldritchcookie> no idea but i think i get it now i was so confused because i didn't know what was delimited, prompt delimits the monadic action which is given as argument
2024-04-02 15:57:12 +0200 <haskellbridge> <e​ldritchcookie> so control0 reifies from up to prompt
2024-04-02 15:57:49 +0200 <ski> an example would be to write a `product' function in CPS, but allow it to abort what it's doing, whenever it sees a zero in its input. instead of `product :: [Integer] -> (Integer -> o) -> o', you get `product :: [Integer] -> (Integer -> Integer) -> Integer', with the important case forcing `o' to be `Integer' being `product (0:_) k = 0', ignoring the continuation `k'
2024-04-02 15:59:20 +0200 <ski> this can also be used to incrementally generate partial results from the computation (like an "iterator"/"generator", more or less), or to send a request up to a surrounding handler, which may service that request and send back a response restarting the suspended computation. or doing other kinds of effects and stuff
2024-04-02 16:02:04 +0200 <ski> eldritchcookie : yes. with `1 + reset (10 + shift (\c -> c (c 100)))', `c' will be bound to `\x -> reset (10 + x)' (with a `reset' in the body of the captured delimited continuation !, and `1 + reset (10 + shift (\c -> c (c 100)))' will reduce to `1 + reset (c (c 10))' (with the dynamically nearest `reset' surrounding the `shift' *surviving* the extraction of the delimited context around the `shift' call !)
2024-04-02 16:03:02 +0200 <ski> the `control' & `prompt', and the `control0' versions, allow you to avoiding having these extra `reset's/`prompt's around
2024-04-02 16:04:05 +0200 <ski> but doing that, afaik, requires some kind of "stack marking", and can't just be done through a simple CPS transform, which will instead just give you the `shift' & `reset' behavior
2024-04-02 16:04:35 +0200 <ski> [| reset E |] = \k -> k ([| E |] (\x -> x))
2024-04-02 16:06:11 +0200 <ski> [| shift (\k -> E) |] = \k -> ([| E |] (\x -> x))
2024-04-02 16:08:39 +0200 <ski> is the CPS transform rules for those two constructs. we can clearly see that `shift' only passes a trivial continuation to `E' (corresponding to the `reset' lingering above); and that `reset' also passes the trivial continuation to `E', meaning that when we reach a `shift', it's as if the continuation `k' that it captures has a `reset' around it (can't access anything in the context outside that `reset')
2024-04-02 16:11:48 +0200 <ski> (then one can introduce additional complexity, by having multiple levels of continuations, and even dynamically generating new such ones .. but the basics above only consider one level of continuations)
2024-04-02 16:12:23 +0200 <ski> ("nqCPS" being short for "not-quite CPS")
2024-04-02 16:13:34 +0200meritamen(~meritamen@user/meritamen) (Quit: Client closed)
2024-04-02 16:18:30 +0200adanwan(~adanwan@gateway/tor-sasl/adanwan) (Quit: _)
2024-04-02 16:18:47 +0200adanwan(~adanwan@gateway/tor-sasl/adanwan)
2024-04-02 16:19:17 +0200tzh(~tzh@c-73-164-206-160.hsd1.or.comcast.net)
2024-04-02 16:20:17 +0200rvalue(~rvalue@user/rvalue) (Read error: Connection reset by peer)
2024-04-02 16:20:46 +0200rvalue(~rvalue@user/rvalue)
2024-04-02 16:21:05 +0200kuribas(~user@ip-188-118-57-242.reverse.destiny.be) (Remote host closed the connection)
2024-04-02 16:21:29 +0200kuribas(~user@ip-188-118-57-242.reverse.destiny.be)
2024-04-02 16:26:36 +0200 <kuribas> How does concurrency works for something like sqlite? I suppose without threading it's use green threads, which means all calls are blocked?
2024-04-02 16:27:20 +0200 <kuribas> Which is ok I suppose, since disk reads/writes are fast.
2024-04-02 16:27:53 +0200meritamen(~meritamen@user/meritamen)
2024-04-02 16:30:39 +0200 <tomsmeding> kuribas: be sure that you set SQLITE_CONFIG_SERIALIZED https://sqlite.org/c3ref/c_config_covering_index_scan.html
2024-04-02 16:30:55 +0200 <tomsmeding> assuming you don't have perfect information about the compile-time config of your sqlite binary
2024-04-02 16:34:36 +0200 <kuribas> tomsmeding: but I only need that if I use multiple OS threads, right?
2024-04-02 16:34:50 +0200 <kuribas> Not with green threads?
2024-04-02 16:36:01 +0200zetef(~quassel@5.2.182.99) (Ping timeout: 268 seconds)
2024-04-02 16:41:25 +0200danse-nr3(~danse-nr3@151.43.191.28) (Ping timeout: 246 seconds)
2024-04-02 16:41:59 +0200phma_phma
2024-04-02 16:42:43 +0200 <kuribas> More importantly, the http client (wrapped by Wreq) is non-blocking, right?
2024-04-02 16:44:10 +0200 <kuribas> Otherwise a 4 second call to another api will block the server.
2024-04-02 16:46:33 +0200nickiminjaj(~nickiminj@user/laxhh)
2024-04-02 16:49:40 +0200zetef(~quassel@5.2.182.99)
2024-04-02 16:50:41 +0200danse-nr3(~danse-nr3@151.43.191.28)
2024-04-02 16:52:58 +0200kuribas(~user@ip-188-118-57-242.reverse.destiny.be) (Remote host closed the connection)
2024-04-02 16:53:28 +0200kuribas(~user@ip-188-118-57-242.reverse.destiny.be)
2024-04-02 16:53:56 +0200nickiminjaj(~nickiminj@user/laxhh) (Quit: My MacBook has gone to sleep. ZZZzzz…)
2024-04-02 17:07:14 +0200meritamen(~meritamen@user/meritamen) (Quit: Client closed)
2024-04-02 17:08:05 +0200causal(~eric@50.35.88.207) (Quit: WeeChat 4.1.1)
2024-04-02 17:13:10 +0200tromp(~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl)
2024-04-02 17:17:56 +0200caconym4(~caconym@user/caconym)
2024-04-02 17:18:12 +0200random-jellyfish(~developer@2a02:2f04:11e:c600:2606:957e:b4af:5f60)
2024-04-02 17:18:12 +0200random-jellyfish(~developer@2a02:2f04:11e:c600:2606:957e:b4af:5f60) (Changing host)
2024-04-02 17:18:12 +0200random-jellyfish(~developer@user/random-jellyfish)
2024-04-02 17:18:55 +0200caconym(~caconym@user/caconym) (Ping timeout: 260 seconds)
2024-04-02 17:18:55 +0200caconym4caconym
2024-04-02 17:19:09 +0200Guest10(~Guest10@78.243.8.244)
2024-04-02 17:21:48 +0200Guest10(~Guest10@78.243.8.244) (Client Quit)
2024-04-02 17:22:56 +0200Guest10(~Guest10@78.243.8.244)
2024-04-02 17:23:22 +0200Guest10(~Guest10@78.243.8.244) (Client Quit)
2024-04-02 17:27:49 +0200 <Inst> ski: lisps can codewalk into generated code and substitute wildly, doing this via FP is much harder
2024-04-02 17:27:49 +0200lortabac(~lortabac@2a01:e0a:541:b8f0:55ab:e185:7f81:54a4) (Ping timeout: 268 seconds)
2024-04-02 17:28:06 +0200nickiminjaj(~nickiminj@188.146.120.15)
2024-04-02 17:28:06 +0200nickiminjaj(~nickiminj@188.146.120.15) (Changing host)
2024-04-02 17:28:06 +0200nickiminjaj(~nickiminj@user/laxhh)
2024-04-02 17:28:23 +0200 <Inst> the idea is that i want custom widget data types encapsulated by other widgets (probably of a differing type)
2024-04-02 17:29:45 +0200cfricke(~cfricke@user/cfricke) (Quit: WeeChat 4.1.2)
2024-04-02 17:30:28 +0200nickiminjaj(~nickiminj@user/laxhh) (Client Quit)
2024-04-02 17:42:38 +0200nickiminjaj(~nickiminj@188.146.120.15)
2024-04-02 17:42:38 +0200nickiminjaj(~nickiminj@188.146.120.15) (Changing host)
2024-04-02 17:42:38 +0200nickiminjaj(~nickiminj@user/laxhh)
2024-04-02 17:46:46 +0200nickiminjaj(~nickiminj@user/laxhh) (Client Quit)
2024-04-02 17:49:58 +0200Square2(~Square@user/square)
2024-04-02 17:50:08 +0200jamesmartinez(uid6451@id-6451.helmsley.irccloud.com) (Quit: Connection closed for inactivity)
2024-04-02 17:52:28 +0200kuribas(~user@ip-188-118-57-242.reverse.destiny.be) (Remote host closed the connection)
2024-04-02 17:52:43 +0200kuribas(~user@ip-188-118-57-242.reverse.destiny.be)
2024-04-02 17:53:08 +0200nschoe(~nschoe@2a01:e0a:8e:a190:8ccb:4735:e31a:8adf) (Quit: ZNC 1.8.2 - https://znc.in)
2024-04-02 17:53:25 +0200nschoe(~nschoe@2a01:e0a:8e:a190:9eab:1f62:ace9:e44f)
2024-04-02 17:53:31 +0200Square(~Square4@user/square) (Ping timeout: 246 seconds)
2024-04-02 18:06:23 +0200nickiminjaj(~nickiminj@user/laxhh)
2024-04-02 18:08:16 +0200nickiminjaj(~nickiminj@user/laxhh) (Client Quit)
2024-04-02 18:10:56 +0200danse-nr3(~danse-nr3@151.43.191.28) (Read error: Connection reset by peer)
2024-04-02 18:11:12 +0200danse-nr3(~danse-nr3@151.43.194.61)
2024-04-02 18:12:34 +0200Square2(~Square@user/square) (Ping timeout: 264 seconds)
2024-04-02 18:12:44 +0200nickiminjaj(~nickiminj@user/laxhh)
2024-04-02 18:13:17 +0200zetef(~quassel@5.2.182.99) (Ping timeout: 240 seconds)
2024-04-02 18:16:12 +0200kuribas(~user@ip-188-118-57-242.reverse.destiny.be) (Quit: ERC (IRC client for Emacs 27.1))
2024-04-02 18:30:03 +0200 <tomsmeding> @tell kuribas sure, you only need serialized sqlite if you have multiple OS threads, but who knows whether the GHC RTS will use multiple OS threads? Some user might pass +RTS -N2 to your program
2024-04-02 18:30:03 +0200 <lambdabot> Consider it noted.
2024-04-02 18:31:48 +0200danse-nr3(~danse-nr3@151.43.194.61) (Ping timeout: 255 seconds)
2024-04-02 18:40:05 +0200 <ski> Inst : "codewalk into generated code and substitute wildly" -- well, that's meta-programming (traversing and generating code sexps, quasi-quotation, and `eval' ior macros). if you want that in Haskell, seems you should look at Template Haskell ? .. or, use a shallow or deep embedding of a DSL, perhaps
2024-04-02 18:40:41 +0200 <ski> Inst : "i want custom widget data types encapsulated by other widgets (probably of a differing type)" -- elaborate ?
2024-04-02 18:40:51 +0200nickiminjaj(~nickiminj@user/laxhh) (Quit: My MacBook has gone to sleep. ZZZzzz…)
2024-04-02 18:45:47 +0200nickiminjaj(~nickiminj@188.146.120.15)
2024-04-02 18:45:47 +0200nickiminjaj(~nickiminj@188.146.120.15) (Changing host)
2024-04-02 18:45:47 +0200nickiminjaj(~nickiminj@user/laxhh)
2024-04-02 18:48:56 +0200nickiminjaj(~nickiminj@user/laxhh) (Client Quit)
2024-04-02 18:49:34 +0200 <Inst> i want to have a widget value that can take another widget value within its data structure, but widget is a typeclass, not a single type
2024-04-02 18:49:55 +0200sammelweis(~quassel@c-73-190-44-79.hsd1.mi.comcast.net)
2024-04-02 18:50:21 +0200 <ski> so use `exists a. Widget a *> a' ?
2024-04-02 18:52:33 +0200 <Inst> where did exists come from?
2024-04-02 18:52:51 +0200 <ski> "can take another widget value within its data structure, but widget is a typeclass, not a single type"
2024-04-02 18:53:26 +0200nickiminjaj(~nickiminj@188.146.120.15)
2024-04-02 18:53:26 +0200nickiminjaj(~nickiminj@188.146.120.15) (Changing host)
2024-04-02 18:53:26 +0200nickiminjaj(~nickiminj@user/laxhh)
2024-04-02 18:53:33 +0200 <ski> you want to be able to store another widget inside your outer widget, regardless of what type the inner/former one has, as long as that type is an instance of the `Widget' type class, no ?
2024-04-02 18:53:51 +0200 <geekosaur> you really do need to write actual Haskell at some point…
2024-04-02 18:54:47 +0200 <ski> (when you do, you'll start to notice some drawbacks with this approach. which is fine, it's a trade off. but you can do this, if you want to)
2024-04-02 18:55:09 +0200 <Inst> https://ghc.gitlab.haskell.org/ghc/doc/users_guide/exts/existential_quantification.html
2024-04-02 18:55:13 +0200g00gler(uid125351@id-125351.uxbridge.irccloud.com)
2024-04-02 18:55:18 +0200 <ski> yes ?
2024-04-02 18:55:28 +0200 <Inst> geekosaur: ?
2024-04-02 18:55:50 +0200 <geekosaur> "exists" and "*>" are syntax that ski wishes existed
2024-04-02 18:56:02 +0200 <Inst> yeah that was what confused me :(
2024-04-02 18:56:02 +0200 <ski> (fwiw, i consider the language extension `ExistentialQuantification' to be a misnomer. something like `ExistentialConstructors' would be more accurate, imho)
2024-04-02 18:57:22 +0200 <ski> yes, i'm using pseudo-Haskell to communicate the idea, because, imho, it is clearer to communicate and discuss it, in that way, than to immediately jump to how to express/encode it in current Haskell (there's also two main ways in which one can do this, not just one. `ExistentialQuantification' is one. CPS using `Rank2Types' is the other)
2024-04-02 18:57:43 +0200 <ski> if you're unclear about what i mean by `exists' and `*>', i'd be happy to elaborate
2024-04-02 18:59:08 +0200 <ski> (or, i guess, possibly using `PolymorphicComponents' in place of `Rank2Types' .. nitpicking myself. but i'd think that's seldom useful, in practice)
2024-04-02 18:59:58 +0200 <ncf> what's PolymorphicComponents?
2024-04-02 19:00:20 +0200 <Inst> *> is more confusing
2024-04-02 19:00:31 +0200 <ski> it's `data Foo = MkFoo (forall a. Bar a Int)', stuffing polymorphic things as components of data constructors
2024-04-02 19:00:33 +0200 <EvanR> you heard of caleskell? will this is haski
2024-04-02 19:00:33 +0200 <Inst> other than in the form >>
2024-04-02 19:01:00 +0200 <EvanR> if => is like a function, *> is like a pair
2024-04-02 19:01:12 +0200 <ski> (both `Rank2Types' and `PolymorphicComponents' are subsumed by `RankNTypes'. iirc, both implicitly enable the latter, nowadays. i'm just using these names, for extra precision)
2024-04-02 19:01:44 +0200 <EvanR> => is waiting for a typeclass dictionary, *> is holding a typeclass dictionary already, on the left
2024-04-02 19:01:49 +0200 <ncf> are you sure that's still a thing
2024-04-02 19:02:06 +0200 <Inst> ah
2024-04-02 19:02:10 +0200econo_(uid147250@id-147250.tinside.irccloud.com)
2024-04-02 19:02:34 +0200 <ncf> no PolymorphicComponents in https://downloads.haskell.org/ghc/latest/docs/users_guide/exts/table.html
2024-04-02 19:02:36 +0200 <EvanR> and yeah it's not actual haskell
2024-04-02 19:02:43 +0200 <EvanR> unfortunately
2024-04-02 19:03:14 +0200 <ski> Inst : a value of type `Cxt => T' is a value such that, if there happens to be an instance `Cxt' in scope, then that can be (implicitly) provided to this value, so that you can use this value as having type `T'. to construct a value of type `Cxt => T', you're free to assume that the user/caller/consumer/de(con)structor of your value will (implicitly) provide an instance of `Cxt', so that you can refer to its
2024-04-02 19:03:20 +0200 <ski> methods when computing your value of type `T'
2024-04-02 19:05:23 +0200 <ski> Inst : correspondingly (dually), a value of type `Cxt *> T' is a value that encapsulates *both* a value of type `T', and also (implicitly) encapuslates (provides) an instance of `Cxt' to the user/caller/consumer/de(con)structor of the whole value. an implementor/callee/producer/constructor of a value of type `Cxt *> T' has to both (implicitly) provide an instance of `Cxt', and a value of type `T'
2024-04-02 19:05:56 +0200 <Inst> ah i think that's what i'm missing
2024-04-02 19:07:11 +0200 <ncf> (in one sentence, Cxt *> - is the left adjoint to Cxt => -)
2024-04-02 19:07:54 +0200 <ski> Inst : in the dictionary-passing translation/implementation of type classes, type class constraints/contexts `Cxt' gets translated to corresponding data types, say `CxtDict' (e.g. `Eq a' would become `EqDict a', where `data EqDict a = MkEqDict { (==),(/=) :: a -> a -> Bool }'). then `Cxt => T' becomes `CxtDict -> T' (a function type, taking the dictionary for the constraint as input, returning the value of
2024-04-02 19:08:00 +0200 <ski> type `T' as output), and `Cxt *> T' becomes `(CxtDict,T)' (a pair type, bundling the constraint dictionary with the value)
2024-04-02 19:08:19 +0200dbaoty(~dbaoty@tptn-04-0838.dsl.iowatelecom.net) (Quit: Leaving.)
2024-04-02 19:08:23 +0200 <ski> in short, yes, "`*>' is to `(,)', as `=>' is to `->'"
2024-04-02 19:09:11 +0200ubert(~Thunderbi@2a02:8109:ab8a:5a00:5d4b:5ac:c6db:5974) (Remote host closed the connection)
2024-04-02 19:09:38 +0200 <Inst> actually, i understand what you mean by that, i was just thinking 'why can't i find a good frontend edsl written in haskell', then i realize that just means DOM, and Reflex already exists
2024-04-02 19:10:07 +0200 <EvanR> if you're playing (a,) then you can draw from the a pile to get an a, if you're playing a ->, you can discard an a
2024-04-02 19:10:32 +0200 <ski> and to be complete, i guess i should say that a value of type `forall a. ..a..' (a polymorphic value) is a value such that the caller/consumer/user/de(con)structor gets to pick whichever type they want to use for `a', and the callee/producer/implementor/producer must be prepared to handle any actual type being used for `a', and so can't assume anything about it (can't even inquire about which type was chosen)
2024-04-02 19:10:40 +0200euphores(~SASL_euph@user/euphores)
2024-04-02 19:12:56 +0200 <ski> while, for a value of type `exists a. ..a..' (an "abstracted" value) is a value such that the callee/producer/implementor/constructor gets to pick whichever type they want to use for `a', and the caller/consumer/user/de(con)structor must be prepared to handle any actual type being used for `a', and so can't assume anything about it (can't even inquire about which type was chosen)
2024-04-02 19:15:56 +0200 <ski> a function `foo :: Int -> exists a. Ord a *> (Map String a,Map a [a])' will pick some type `a', which may depend on the `Int' argument, such that the caller is guaranteed that the type is in `Ord', but otherwise knows nothing about it. all the `a's in the maps are of the same (unknown) type here, so can be compared to each other
2024-04-02 19:17:36 +0200 <ski> if you instead used `bar :: String -> IO (Map String (exists a. Widget a *> a))', then not only can the type `a' chosen depend on both the `String' argument, and on the I/O interaction leading up to the monadic result; the `a's can be different for different `String' keys in the map (because the `exists' is inside `Map', rather than outside it)
2024-04-02 19:17:45 +0200 <Inst> thanks for all the effort, i understand what you mean and how it's relevant to my concerns now
2024-04-02 19:19:17 +0200 <ski> with `baz :: forall a. C a => T a -> exists b. D a b *> U a b', `b' can depend both on the type `a' (chosen by the caller), and the input of type `T a'. and the chosen/provided instance of `D a b' can depend on the given (by the caller) instance `C a'
2024-04-02 19:21:06 +0200 <ski> if we want to express say `exists a. Ord a *> Map String a', then imagine if we could write
2024-04-02 19:21:59 +0200 <ski> data SomeMap = MkSomeMap (exists a. Ord a *> Map String a)
2024-04-02 19:22:14 +0200 <ski> this would mean that the data constructor has the following type signature
2024-04-02 19:22:25 +0200 <ski> MkSomeMap :: (exists a. Ord a *> Map String a) -> SomeMap
2024-04-02 19:22:59 +0200Kamuela(sid111576@id-111576.tinside.irccloud.com)
2024-04-02 19:23:47 +0200 <ski> however, generally, `(exists a. ..a..) -> ...' is equivalent to `forall a. (..a.. -> ...)', and `(... *> ...) -> ...' is equivalent to `... => (... -> ...)' (compare with currying, how `(...,...) -> ...' is equivalent to `... -> ... -> ...')
2024-04-02 19:23:53 +0200 <ski> therefore, this amounts to
2024-04-02 19:24:06 +0200 <ski> MkSomeMap :: forall a. ((Ord a *> Map String a) -> SomeMap)
2024-04-02 19:24:08 +0200 <ski> iow
2024-04-02 19:24:20 +0200 <ski> MkSomeMap :: forall a. (Ord a => (Map String a -> SomeMap))
2024-04-02 19:24:24 +0200 <ski> or just
2024-04-02 19:24:28 +0200 <ski> MkSomeMap :: forall a. Ord a => Map String a -> SomeMap
2024-04-02 19:24:34 +0200 <ski> without redundant brackets. or just
2024-04-02 19:24:39 +0200 <ski> MkSomeMap :: Ord a => Map String a -> SomeMap
2024-04-02 19:24:55 +0200 <ski> using implicit universal quantification of type variables at toplevel of type signatures
2024-04-02 19:24:56 +0200 <Inst> Mhm :)
2024-04-02 19:25:48 +0200 <ski> so, `MkSomeMap' is *polymorphic* (because it has a type `forall a. ..a..'), it's accept a `Map String a', for *any* type `a' the caller wants to use (as long as it's in the type class `Ord')
2024-04-02 19:26:36 +0200 <ski> however, `a' here does not appear in the result type. that is what makes this data constructor "existential" (which is a figure of speech here, not an exact statement. it's the argument type, namely `exists a. Ord a *> Map String a', that's existential, if anything)
2024-04-02 19:26:56 +0200 <ski> the *actual* syntax that the `ExistentialQuantification' extension (misnomer) gives you for this is
2024-04-02 19:27:15 +0200 <ski> data SomeMap = forall a. Ord a => MkSomeMap (Map String a))
2024-04-02 19:27:46 +0200 <ski> indicating that the `MkSomeMap' data constructor is polymorphic (the `forall'), specifically constrained polymorphic (the `=>')
2024-04-02 19:28:04 +0200 <ski> if you use `GADTs', you can alternatively declare the same thing instead as
2024-04-02 19:28:07 +0200 <ski> data SomeMap
2024-04-02 19:28:09 +0200 <ski> where
2024-04-02 19:28:14 +0200 <ski> MkSomeMap :: Ord a => Map String a -> SomeMap
2024-04-02 19:28:17 +0200 <ski> if you prefer
2024-04-02 19:29:16 +0200 <ski> to access the "existential", you must pattern-match on the `MkSomeMap' data constructor. your final result type can't depend on the hidden type `a' (and the associated `Ord a' constraint) that this pattern-matching brings into scope
2024-04-02 19:29:43 +0200 <ski> and to return such a value (or store it in a data structure), you must wrap with with the data constructor `MkSomeMap'
2024-04-02 19:30:03 +0200 <ski> so, whenever you intended `exists a. Ord a *> Map String a' in your original design, you will now instead write `MkSomeMap' in its place
2024-04-02 19:30:34 +0200 <ski> this is the first approach to express/encode existentials
2024-04-02 19:30:44 +0200 <Inst> ah, I see
2024-04-02 19:30:47 +0200arjun(~arjun@user/arjun)
2024-04-02 19:30:49 +0200 <ski> the second is, if you're trying to return `exists a. Ord a *> Map String a', like in
2024-04-02 19:31:03 +0200 <ski> foobar :: Map String Fribble -> exists a. Ord a *> Map String a
2024-04-02 19:31:31 +0200fererrorocher(fererroroc@gateway/vpn/protonvpn/fererrorocher) (Quit: WeeChat 4.2.1)
2024-04-02 19:32:19 +0200 <ski> what you do is you exploit that any type `...' is equivalent to `forall o. (... -> o) -> o' (this is CPS, Continuation-Passing Style) (it also happens to be equivalent to `exists s. (s,s -> ...)', but i'll not use that logical equivalence atm)
2024-04-02 19:32:26 +0200 <ski> so, we arrive at
2024-04-02 19:32:46 +0200 <ski> foobarWith :: Map String Fribble -> forall o. ((exists a. Ord a *> Map String a) -> o) -> o
2024-04-02 19:33:14 +0200 <ski> but, using the two equivalences that i mentioned first, above, this is amounts to
2024-04-02 19:33:32 +0200 <ski> foobarWith :: Map String Fribble -> forall o. (forall a. Ord a => Map String a -> o) -> o
2024-04-02 19:34:00 +0200 <ski> and, using that `... -> (forall a. ..a..)' is equivalent to `forall a. (... -> ..a..)', this becomes
2024-04-02 19:34:08 +0200 <ski> foobarWith :: forall o. Map String Fribble -> (forall a. Ord a => Map String a -> o) -> o
2024-04-02 19:34:11 +0200 <ski> or just
2024-04-02 19:34:14 +0200 <ski> foobarWith :: Map String Fribble -> (forall a. Ord a => Map String a -> o) -> o
2024-04-02 19:34:17 +0200 <ski> for short
2024-04-02 19:35:32 +0200 <ski> so, what has happened is that, instead of directly returning the result of type `Map String a', for *some* (unknown/hidden/forgotten/abstract/opaque/skolem) type `a' (such that `Ord a'), we take an extra callback parameter (the continuation), and instead of returning the result, we pass it to the continuation (whose eventual result of type `o' we'll just return)
2024-04-02 19:35:56 +0200igemnace(~ian@user/igemnace) (Quit: WeeChat 4.2.1)
2024-04-02 19:36:39 +0200 <ski> this approach to encoding existentials tend to be more useful, when the caller wants to unpack the existential directly after the call. while the "existential constructor" approach is better when the caller does not want to unpack directly, or when you want to store the abstracted value, of existential type, in some data structure
2024-04-02 19:36:47 +0200 <ski> Inst : and that's all
2024-04-02 19:39:41 +0200 <Inst> I see.
2024-04-02 19:41:54 +0200 <ski> (in practice, you'll of course jump directly to one or the other encoding, without going through the derivation steps, step by step. i only did that here, to help explain *why/how* these two encodings work, thinking of them as refactorings of the original pseudo-Haskell)
2024-04-02 19:43:19 +0200 <ncf> so what problem were we solving using existential types today
2024-04-02 19:43:40 +0200 <Inst> I don't remember either :)
2024-04-02 19:43:49 +0200 <ncf> ah, polymorphic widgets
2024-04-02 19:44:00 +0200 <ski> well, you were talking about widgets containing arbitrary widgets
2024-04-02 19:44:16 +0200 <ski> (not polymorphic. abstracted)
2024-04-02 19:44:48 +0200 <ncf> ...not not polymorphic? :)
2024-04-02 19:44:58 +0200 <ski> ("there exists a widget of some type here")
2024-04-02 19:45:19 +0200skipasses ncf through DNS (Double-Negation Shift)
2024-04-02 19:45:35 +0200 <Inst> what should I read to understand (more) of the basic Haskell type system, anyways?
2024-04-02 19:45:59 +0200 <ski> well .. maybe the report ?
2024-04-02 19:46:24 +0200 <ski> although .. i'd expect that a lot will make much more sense, if you practice what you're reading about, and experiment, play around, with it
2024-04-02 19:46:49 +0200 <ncf> some lecture notes about system F, maybe
2024-04-02 19:46:53 +0200machinedgod(~machinedg@d173-183-246-216.abhsia.telus.net) (Ping timeout: 268 seconds)
2024-04-02 19:47:22 +0200 <ski> any intro textbook should explain higher-order functions, polymorphism, parameterized data types, type classes and instances
2024-04-02 19:47:58 +0200 <ski> if you want to try to read a text about type systems, you could try
2024-04-02 19:48:03 +0200 <ski> @where polymorphic-type-inference
2024-04-02 19:48:04 +0200 <lambdabot> "Polymorphic Type Inference" by Michael I. Schwartzbach in 1995-03 at <https://cs.au.dk/~mis/typeinf.p(s|df)>,<http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.57.1493>
2024-04-02 19:48:28 +0200 <Inst> tbh all my knowledge of Haskell's type system has been based on trial and error and finding out what blows up in my face
2024-04-02 19:48:50 +0200 <ski> (the concrete syntax that is uses reminds more of Lisp (although not being sexpy), bu that's only a minor difference)
2024-04-02 19:49:03 +0200 <ski> different people learn best in different ways
2024-04-02 19:50:00 +0200 <Inst> wait, curious, technically
2024-04-02 19:50:08 +0200 <Inst> lisp is s-expressions, algol is m-expressions
2024-04-02 19:50:09 +0200 <Inst> haskell?
2024-04-02 19:50:53 +0200mesaoptimizer(~mesaoptim@user/PapuaHardyNet) (Ping timeout: 268 seconds)
2024-04-02 19:51:04 +0200 <EvanR> h expressions
2024-04-02 19:51:33 +0200 <geekosaur> once you desugar layout, haskell is closer to algol than to lisp
2024-04-02 19:53:10 +0200 <ski> (fwiw, DNS expresses that `forall n : Nat. not (not (P n))' entails `not not (forall n : Nat. P n)')
2024-04-02 19:53:25 +0200 <ski> @where liskell
2024-04-02 19:53:25 +0200 <lambdabot> a SExp syntax for Haskell, by therp : <http://clemens.endorphin.org/liskell> (broken),<https://web.archive.org/web/20081105133119/http://clemens.endorphin.org/liskell>,<http://clemens.endorphin.org/
2024-04-02 19:53:25 +0200 <lambdabot> ILC07-Liskell-draft.pdf>,<https://web.archive.org/web/20120609122549/http://www.liskell.org/>
2024-04-02 19:53:37 +0200 <Inst> yeah, i'm aware of it, as well as hackett
2024-04-02 19:53:43 +0200skinods
2024-04-02 19:55:04 +0200 <ski> Haskell's syntax is rather close to Miranda™'s. and not too different from ISWIM's (which used `where' in a similar fashion, iirc)
2024-04-02 19:56:08 +0200 <ski> ISWIM was the imagined language used by Peter Landin in his seminal paper "The Next 700 Programming Language", if i'm not mistaken
2024-04-02 19:57:18 +0200dcoutts(~duncan@cpc69402-oxfd27-2-0-cust903.4-3.cable.virginm.net) (Ping timeout: 255 seconds)
2024-04-02 19:57:55 +0200 <ski> (and recursive defining equations (or go back further to recurrence relations), e.g. as used by Skolem or Gödel, and not too dissimilar to defining a function by multiple equations, pattern-matching, in Haskell)
2024-04-02 20:02:54 +0200 <EvanR> n + k patterns get a lot of hate, but what more general idea was that driving toward
2024-04-02 20:03:50 +0200 <EvanR> n+k isn't a data construction form, but does it have to be
2024-04-02 20:04:21 +0200 <ski> pattern synonyms (more general than the current batch), which amounts to more or less the same as reverse modes for function (as in Mercury)
2024-04-02 20:04:23 +0200 <EvanR> some languages let you put a string concatenation pattern
2024-04-02 20:04:44 +0200 <ski> in Mercury, the function type declaration
2024-04-02 20:05:01 +0200 <ski> :- func list(A) ++ list(A) = list(A).
2024-04-02 20:05:16 +0200 <ski> has one (out of multiple) associated mode(s)
2024-04-02 20:05:32 +0200 <ski> :- mode in ++ out = in is semidet.
2024-04-02 20:06:04 +0200 <ski> expressing that if `Xs' is known and `Xs ++ Ys' is known, then that determines at most one value for `Ys', and therefore you can use that in pattern-matching like
2024-04-02 20:06:20 +0200 <ski> foo([2,3,5,7] ++ Rest) = ..Rest..
2024-04-02 20:06:37 +0200 <EvanR> reading that as "has one associated mode"
2024-04-02 20:06:49 +0200 <ski> yea, the "usual" (forward) mode is
2024-04-02 20:06:51 +0200 <Inst> EvanR: IIRC, ViewPatterns was descirbed as "N+K patterns are back!"
2024-04-02 20:06:56 +0200 <ski> :- mode in ++ in = out is det.
2024-04-02 20:07:21 +0200 <ski> (`det' means exactly one solution. `semidet' is at most one. `multi' is at least one. `nondet' is any number of solutions)
2024-04-02 20:07:42 +0200 <ski> unfortunately, `ViewPatterns' can't take inputs
2024-04-02 20:07:52 +0200 <ski> i'd like to be able to declare something like
2024-04-02 20:08:24 +0200 <ski> pattern Append :: Eq a => [a] -> () => [a] -> [a]
2024-04-02 20:09:19 +0200 <ski> pattern Append [ ] ys = ys
2024-04-02 20:09:20 +0200 <ski> pattern Append (x:xs) ys = ((x ==) -> True) : Append xs ys
2024-04-02 20:10:08 +0200 <ski> er, sorry, i meant of course `PatternSynonyms', not `ViewPatterns'
2024-04-02 20:10:43 +0200pavonia(~user@user/siracusa) (Quit: Bye!)
2024-04-02 20:11:01 +0200 <ski> where the general format of the type signature is `pattern PatSyn :: InCxt => InParm -> ... -> OutCxt => OutParm -> ... -> Scrut'
2024-04-02 20:11:50 +0200 <ski> (and you can pattern-match as usual on the input parameters, with multiple defining equations, and guards if you want to)
2024-04-02 20:21:11 +0200nickiminjaj_(~nickiminj@user/laxhh)
2024-04-02 20:25:07 +0200nickiminjaj(~nickiminj@user/laxhh) (Ping timeout: 260 seconds)
2024-04-02 20:34:58 +0200dcoutts(~duncan@cpc69402-oxfd27-2-0-cust903.4-3.cable.virginm.net)
2024-04-02 20:50:29 +0200waleee(~waleee@h-176-10-144-38.NA.cust.bahnhof.se)
2024-04-02 20:53:24 +0200xal(~xal@mx1.xal.systems) ()
2024-04-02 20:53:41 +0200xal(~xal@mx1.xal.systems)
2024-04-02 21:01:13 +0200 <Inst> so, identity, maybe, nonempty, and list?
2024-04-02 21:03:14 +0200euphores(~SASL_euph@user/euphores) (Quit: Leaving.)
2024-04-02 21:04:04 +0200gmg(~user@user/gehmehgeh) (Remote host closed the connection)
2024-04-02 21:04:46 +0200xal(~xal@mx1.xal.systems) ()
2024-04-02 21:04:50 +0200g00gler(uid125351@id-125351.uxbridge.irccloud.com) (Quit: Connection closed for inactivity)
2024-04-02 21:04:59 +0200gmg(~user@user/gehmehgeh)
2024-04-02 21:05:15 +0200gmg(~user@user/gehmehgeh) (Remote host closed the connection)
2024-04-02 21:05:50 +0200xal(~xal@mx1.xal.systems)
2024-04-02 21:06:09 +0200gmg(~user@user/gehmehgeh)
2024-04-02 21:07:05 +0200xal(~xal@mx1.xal.systems) (Client Quit)
2024-04-02 21:10:37 +0200euphores(~SASL_euph@user/euphores)
2024-04-02 21:11:40 +0200target_i(~target_i@user/target-i/x-6023099)
2024-04-02 21:15:11 +0200gentauro(~gentauro@user/gentauro) (Read error: Connection reset by peer)
2024-04-02 21:17:32 +0200nickiminjaj_(~nickiminj@user/laxhh) (Read error: Connection reset by peer)
2024-04-02 21:18:17 +0200nickiminjaj(~nickiminj@188.146.120.15)
2024-04-02 21:18:17 +0200nickiminjaj(~nickiminj@188.146.120.15) (Changing host)
2024-04-02 21:18:17 +0200nickiminjaj(~nickiminj@user/laxhh)
2024-04-02 21:21:03 +0200gentauro(~gentauro@user/gentauro)
2024-04-02 21:22:50 +0200xal(~xal@mx1.xal.systems)
2024-04-02 21:24:36 +0200lortabac(~lortabac@2a01:e0a:541:b8f0:55ab:e185:7f81:54a4)
2024-04-02 21:24:54 +0200pera_(~pera@8.29.109.183) (Quit: leaving)
2024-04-02 21:35:06 +0200AlexZenon(~alzenon@94.233.240.255) (Ping timeout: 268 seconds)
2024-04-02 21:37:03 +0200 <ski> Inst : you could think of them list that, sure
2024-04-02 21:39:35 +0200tromp(~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…)
2024-04-02 21:40:19 +0200fererrorocher(fererroroc@gateway/vpn/protonvpn/fererrorocher)
2024-04-02 21:41:55 +0200AlexZenon(~alzenon@94.233.240.255)
2024-04-02 21:51:11 +0200tromp(~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl)
2024-04-02 21:52:04 +0200random-jellyfish(~developer@user/random-jellyfish) (Ping timeout: 255 seconds)
2024-04-02 21:56:17 +0200nickiminjaj(~nickiminj@user/laxhh) (Quit: My MacBook has gone to sleep. ZZZzzz…)
2024-04-02 21:57:28 +0200euphores(~SASL_euph@user/euphores) (Ping timeout: 246 seconds)
2024-04-02 22:00:32 +0200fererrorocher(fererroroc@gateway/vpn/protonvpn/fererrorocher) (Quit: WeeChat 4.2.1)
2024-04-02 22:07:19 +0200fererrorocher(fererroroc@gateway/vpn/protonvpn/fererrorocher)
2024-04-02 22:08:03 +0200random-jellyfish(~developer@user/random-jellyfish)
2024-04-02 22:08:50 +0200mima(~mmh@87-99-53-133.internetia.net.pl)
2024-04-02 22:09:09 +0200mima(~mmh@87-99-53-133.internetia.net.pl) (Client Quit)
2024-04-02 22:10:25 +0200mei(~mei@user/mei) (Remote host closed the connection)
2024-04-02 22:10:38 +0200phma(~phma@host-67-44-208-169.hnremote.net) (Read error: Connection reset by peer)
2024-04-02 22:10:55 +0200mei(~mei@user/mei)
2024-04-02 22:11:34 +0200phma(phma@2001:5b0:211c:a48:b538:9e99:373e:ab2f)
2024-04-02 22:12:42 +0200_ht(~Thunderbi@28-52-174-82.ftth.glasoperator.nl) (Quit: _ht)
2024-04-02 22:13:37 +0200nickiminjaj(~nickiminj@user/laxhh)
2024-04-02 22:19:13 +0200nickiminjaj(~nickiminj@user/laxhh) (Quit: My MacBook has gone to sleep. ZZZzzz…)
2024-04-02 22:28:04 +0200tromp(~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…)
2024-04-02 22:30:16 +0200nickiminjaj(~nickiminj@user/laxhh)
2024-04-02 22:31:34 +0200xal(~xal@mx1.xal.systems) ()
2024-04-02 22:33:46 +0200sammelweis(~quassel@c-73-190-44-79.hsd1.mi.comcast.net) (Quit: https://quassel-irc.org - Chat comfortably. Anywhere.)
2024-04-02 22:42:07 +0200mmhat(~mmh@p200300f1c74dcfc3ee086bfffe095315.dip0.t-ipconnect.de) (Quit: WeeChat 4.2.1)
2024-04-02 22:43:33 +0200lortabac(~lortabac@2a01:e0a:541:b8f0:55ab:e185:7f81:54a4) (Ping timeout: 268 seconds)
2024-04-02 22:43:50 +0200nickiminjaj(~nickiminj@user/laxhh) (Quit: My MacBook has gone to sleep. ZZZzzz…)
2024-04-02 22:44:12 +0200xal(~xal@mx1.xal.systems)
2024-04-02 22:47:34 +0200xal(~xal@mx1.xal.systems) (Client Quit)
2024-04-02 22:47:47 +0200nickiminjaj(~nickiminj@188.146.120.15)
2024-04-02 22:47:47 +0200nickiminjaj(~nickiminj@188.146.120.15) (Changing host)
2024-04-02 22:47:47 +0200nickiminjaj(~nickiminj@user/laxhh)
2024-04-02 22:49:11 +0200tromp(~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl)
2024-04-02 22:49:35 +0200nickiminjaj(~nickiminj@user/laxhh) (Client Quit)
2024-04-02 22:52:54 +0200xal(~xal@mx1.xal.systems)
2024-04-02 22:53:04 +0200mesaoptimizer(~mesaoptim@user/PapuaHardyNet)
2024-04-02 22:55:59 +0200nickiminjaj(~nickiminj@user/laxhh)
2024-04-02 22:59:29 +0200tromp(~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…)
2024-04-02 22:59:55 +0200nickiminjaj(~nickiminj@user/laxhh) (Client Quit)
2024-04-02 23:00:46 +0200nickiminjaj(~nickiminj@user/laxhh)
2024-04-02 23:07:27 +0200machinedgod(~machinedg@d173-183-246-216.abhsia.telus.net)
2024-04-02 23:08:21 +0200sprout_(~quassel@84-80-106-227.fixed.kpn.net)
2024-04-02 23:10:19 +0200sprout(~quassel@2a02-a448-3a80-0-7de0-65dd-3177-b6a5.fixed6.kpn.net) (Ping timeout: 260 seconds)
2024-04-02 23:10:28 +0200sprout_sprout
2024-04-02 23:12:10 +0200mei(~mei@user/mei) (Remote host closed the connection)
2024-04-02 23:14:47 +0200mei(~mei@user/mei)
2024-04-02 23:16:29 +0200machinedgod(~machinedg@d173-183-246-216.abhsia.telus.net) (Ping timeout: 252 seconds)
2024-04-02 23:17:10 +0200michalz(~michalz@185.246.207.197) (Quit: ZNC 1.8.2 - https://znc.in)
2024-04-02 23:17:28 +0200tromp(~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl)
2024-04-02 23:21:55 +0200adanwan_(~adanwan@gateway/tor-sasl/adanwan)
2024-04-02 23:22:18 +0200adanwan_(~adanwan@gateway/tor-sasl/adanwan) (Remote host closed the connection)
2024-04-02 23:22:42 +0200adanwan_(~adanwan@gateway/tor-sasl/adanwan)
2024-04-02 23:23:02 +0200adanwan(~adanwan@gateway/tor-sasl/adanwan) (Ping timeout: 260 seconds)
2024-04-02 23:26:03 +0200sawilagar(~sawilagar@user/sawilagar)
2024-04-02 23:26:48 +0200gmg(~user@user/gehmehgeh) (Quit: Leaving)
2024-04-02 23:40:42 +0200arjun(~arjun@user/arjun) (Quit: Quit!)
2024-04-02 23:42:31 +0200tromp(~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…)
2024-04-02 23:51:12 +0200myxos(~myxos@065-028-251-121.inf.spectrum.com) (Remote host closed the connection)
2024-04-02 23:57:30 +0200tromp(~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl)
2024-04-02 23:57:56 +0200target_i(~target_i@user/target-i/x-6023099) (Quit: leaving)
2024-04-02 23:58:11 +0200Midjak(~MarciZ@82.66.147.146)
2024-04-02 23:59:31 +0200dolio(~dolio@130.44.134.54) (Quit: ZNC 1.8.2 - https://znc.in)