Logs on 2023-10-18 (liberachat/#haskell)
| 00:07:21 | → | zmt00 joins (~zmt00@user/zmt00) |
| 00:15:52 | × | emmanuelux quits (~emmanuelu@user/emmanuelux) (Quit: au revoir) |
| 00:19:59 | → | thegeekinside joins (~thegeekin@189.180.124.118) |
| 00:29:27 | × | jrm quits (~jrm@user/jrm) (Quit: ciao) |
| 00:30:21 | × | jespada quits (~jespada@cpc121308-nmal25-2-0-cust15.19-2.cable.virginm.net) (Ping timeout: 260 seconds) |
| 00:33:16 | → | jespada joins (~jespada@cpc121308-nmal25-2-0-cust15.19-2.cable.virginm.net) |
| 00:35:31 | → | jrm joins (~jrm@user/jrm) |
| 00:44:02 | → | danza joins (~francesco@ge-19-118-207.service.infuturo.it) |
| 00:44:28 | × | ddellacosta quits (~ddellacos@ool-44c738de.dyn.optonline.net) (Ping timeout: 248 seconds) |
| 00:45:10 | → | ddellacosta joins (~ddellacos@ool-44c738de.dyn.optonline.net) |
| 00:49:30 | → | Sciencentistguy6 joins (~sciencent@hacksoc/ordinary-member) |
| 00:51:45 | × | Sciencentistguy quits (~sciencent@hacksoc/ordinary-member) (Ping timeout: 255 seconds) |
| 00:51:46 | Sciencentistguy6 | is now known as Sciencentistguy |
| 00:53:14 | → | thyriaen joins (~thyriaen@2a01:aea0:dd4:7157:6245:cbff:fe9f:48b1) |
| 00:53:55 | → | danse-nr3_ joins (~francesco@ge-19-118-207.service.infuturo.it) |
| 00:55:59 | × | Lord_of_Life quits (~Lord@user/lord-of-life/x-2819915) (Ping timeout: 255 seconds) |
| 00:56:45 | → | Lord_of_Life joins (~Lord@user/lord-of-life/x-2819915) |
| 00:57:58 | × | whatsupdoc quits (uid509081@id-509081.hampstead.irccloud.com) (Quit: Connection closed for inactivity) |
| 00:58:45 | × | cpressey quits (~cpressey@host-2-102-14-126.as13285.net) (Quit: Client closed) |
| 01:01:01 | → | phma_ joins (phma@2001:5b0:211b:9d88:b368:1baa:7a2:22b7) |
| 01:04:32 | × | phma quits (~phma@host-67-44-208-18.hnremote.net) (Ping timeout: 255 seconds) |
| 01:05:20 | → | sm joins (~sm@plaintextaccounting/sm) |
| 01:07:14 | → | bitdex joins (~bitdex@gateway/tor-sasl/bitdex) |
| 01:07:36 | × | hiyori quits (~hiyori@user/hiyori) (Quit: Client closed) |
| 01:08:05 | × | danza quits (~francesco@ge-19-118-207.service.infuturo.it) (Ping timeout: 240 seconds) |
| 01:37:04 | × | otto_s quits (~user@p5b0445cd.dip0.t-ipconnect.de) (Ping timeout: 255 seconds) |
| 01:38:41 | × | chexum quits (~quassel@gateway/tor-sasl/chexum) (Ping timeout: 252 seconds) |
| 01:38:45 | → | otto_s joins (~user@p5b044495.dip0.t-ipconnect.de) |
| 01:39:09 | → | chexum joins (~quassel@gateway/tor-sasl/chexum) |
| 01:39:39 | × | thyriaen quits (~thyriaen@2a01:aea0:dd4:7157:6245:cbff:fe9f:48b1) (Quit: Leaving) |
| 01:44:26 | × | solrize quits (~solrize@2601:644:8501:aaf0::86ea) (Ping timeout: 260 seconds) |
| 01:52:07 | × | [itchyjunk] quits (~itchyjunk@user/itchyjunk/x-7353470) (Remote host closed the connection) |
| 01:56:26 | × | danse-nr3_ quits (~francesco@ge-19-118-207.service.infuturo.it) (Remote host closed the connection) |
| 01:56:49 | → | danse-nr3_ joins (~francesco@ge-19-118-207.service.infuturo.it) |
| 02:11:16 | × | td_ quits (~td@i53870913.versanet.de) (Ping timeout: 255 seconds) |
| 02:13:04 | → | td_ joins (~td@i5387093F.versanet.de) |
| 02:16:34 | × | eggplantade quits (~Eggplanta@2600:1700:38c5:d800:b915:f992:5adb:85e) (Remote host closed the connection) |
| 02:16:50 | → | eggplantade joins (~Eggplanta@2600:1700:38c5:d800:b915:f992:5adb:85e) |
| 02:26:58 | × | chexum quits (~quassel@gateway/tor-sasl/chexum) (Remote host closed the connection) |
| 02:27:06 | → | chexum joins (~quassel@gateway/tor-sasl/chexum) |
| 02:29:02 | × | xff0x quits (~xff0x@ai101218.d.east.v6connect.net) (Ping timeout: 255 seconds) |
| 02:30:06 | × | FinnElija quits (~finn_elij@user/finn-elija/x-0085643) (Killed (NickServ (Forcing logout FinnElija -> finn_elija))) |
| 02:30:06 | → | finn_elija joins (~finn_elij@user/finn-elija/x-0085643) |
| 02:30:06 | finn_elija | is now known as FinnElija |
| 02:38:44 | phma_ | is now known as phma |
| 02:43:21 | × | aforemny quits (~aforemny@i59F516F9.versanet.de) (Ping timeout: 260 seconds) |
| 02:44:07 | × | thegeekinside quits (~thegeekin@189.180.124.118) (Ping timeout: 255 seconds) |
| 02:47:51 | → | nate2 joins (~nate@c-98-45-169-16.hsd1.ca.comcast.net) |
| 02:50:35 | → | aforemny joins (~aforemny@i59F516FB.versanet.de) |
| 02:50:37 | × | danse-nr3_ quits (~francesco@ge-19-118-207.service.infuturo.it) (Remote host closed the connection) |
| 02:51:00 | → | danse-nr3_ joins (~francesco@ge-19-118-207.service.infuturo.it) |
| 02:51:31 | × | machinedgod quits (~machinedg@d198-53-218-113.abhsia.telus.net) (Ping timeout: 260 seconds) |
| 02:52:21 | → | Square joins (~Square@user/square) |
| 02:52:36 | × | nate2 quits (~nate@c-98-45-169-16.hsd1.ca.comcast.net) (Ping timeout: 258 seconds) |
| 03:02:16 | → | zer0bitz_ joins (~zer0bitz@user/zer0bitz) |
| 03:03:00 | → | Vajb joins (~Vajb@207.61.167.122) |
| 03:05:15 | × | zer0bitz quits (~zer0bitz@user/zer0bitz) (Ping timeout: 258 seconds) |
| 03:06:32 | × | Inst quits (~Inst@120.244.192.250) (Ping timeout: 246 seconds) |
| 03:10:17 | → | hiyori joins (~hiyori@user/hiyori) |
| 03:13:48 | × | Vajb quits (~Vajb@207.61.167.122) (Ping timeout: 248 seconds) |
| 03:17:53 | × | pretty_dumm_guy quits (trottel@gateway/vpn/protonvpn/prettydummguy/x-88029655) (Quit: WeeChat 3.5) |
| 03:20:32 | → | xff0x joins (~xff0x@125x103x176x34.ap125.ftth.ucom.ne.jp) |
| 03:24:04 | → | Square3 joins (~Square4@user/square) |
| 03:26:02 | → | danse-nr3__ joins (~francesco@151.57.110.75) |
| 03:26:56 | × | danse-nr3_ quits (~francesco@ge-19-118-207.service.infuturo.it) (Read error: Connection reset by peer) |
| 03:27:06 | × | aforemny quits (~aforemny@i59F516FB.versanet.de) (Ping timeout: 258 seconds) |
| 03:27:26 | → | aforemny joins (~aforemny@i59F516ED.versanet.de) |
| 03:29:00 | → | Vajb joins (~Vajb@207.61.167.122) |
| 03:29:30 | → | andydude joins (~andrewr@151.200.15.160) |
| 03:29:34 | × | ddellacosta quits (~ddellacos@ool-44c738de.dyn.optonline.net) (Ping timeout: 255 seconds) |
| 03:31:24 | → | ddellacosta joins (~ddellacos@ool-44c738de.dyn.optonline.net) |
| 03:45:54 | × | Vajb quits (~Vajb@207.61.167.122) (Ping timeout: 245 seconds) |
| 03:54:07 | × | Alleria quits (~JohnGalt@user/alleria) (Quit: Textual IRC Client: www.textualapp.com) |
| 03:54:42 | × | gdown quits (~gavin@h69-11-149-109.kndrid.broadband.dynamic.tds.net) (Ping timeout: 258 seconds) |
| 04:04:53 | × | euleritian quits (~euleritia@dynamic-046-114-200-236.46.114.pool.telefonica.de) (Read error: Connection reset by peer) |
| 04:05:11 | → | euleritian joins (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) |
| 04:06:35 | → | _ht joins (~Thunderbi@28-52-174-82.ftth.glasoperator.nl) |
| 04:07:11 | × | sabino quits (~sabino@user/sabino) (Quit: Lambda _ -> x) |
| 04:10:52 | × | gabiruh quits (~gabiruh@vps19177.publiccloud.com.br) (Ping timeout: 272 seconds) |
| 04:11:38 | → | gabiruh joins (~gabiruh@vps19177.publiccloud.com.br) |
| 04:21:27 | × | danse-nr3__ quits (~francesco@151.57.110.75) (Ping timeout: 255 seconds) |
| 04:33:58 | → | rosco joins (~rosco@yp-150-69.tm.net.my) |
| 04:40:13 | × | euleritian quits (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Ping timeout: 255 seconds) |
| 04:42:26 | → | danse-nr3 joins (~francesco@151.57.110.75) |
| 04:45:20 | → | euleritian joins (~euleritia@dynamic-046-114-200-236.46.114.pool.telefonica.de) |
| 04:47:25 | → | qqq joins (~qqq@92.43.167.61) |
| 04:53:43 | × | Square3 quits (~Square4@user/square) (Ping timeout: 255 seconds) |
| 04:55:35 | × | johnw quits (~johnw@69.62.242.138) (Quit: ZNC - http://znc.in) |
| 04:55:54 | × | euleritian quits (~euleritia@dynamic-046-114-200-236.46.114.pool.telefonica.de) (Ping timeout: 245 seconds) |
| 04:55:56 | × | sm quits (~sm@plaintextaccounting/sm) (Quit: sm) |
| 05:00:22 | → | euleritian joins (~euleritia@dynamic-046-114-200-236.46.114.pool.telefonica.de) |
| 05:03:53 | → | Unicorn_Princess joins (~Unicorn_P@user/Unicorn-Princess/x-3540542) |
| 05:04:44 | × | euleritian quits (~euleritia@dynamic-046-114-200-236.46.114.pool.telefonica.de) (Ping timeout: 248 seconds) |
| 05:05:52 | → | euleritian joins (~euleritia@dynamic-046-114-200-044.46.114.pool.telefonica.de) |
| 05:09:08 | → | vglfr joins (~vglfr@88.155.159.184) |
| 05:09:12 | ← | andydude parts (~andrewr@151.200.15.160) () |
| 05:14:39 | → | sm joins (~sm@plaintextaccounting/sm) |
| 05:19:13 | × | euleritian quits (~euleritia@dynamic-046-114-200-044.46.114.pool.telefonica.de) (Read error: Connection reset by peer) |
| 05:19:15 | → | takuan joins (~takuan@178-116-218-225.access.telenet.be) |
| 05:19:25 | × | sm quits (~sm@plaintextaccounting/sm) (Ping timeout: 258 seconds) |
| 05:19:30 | → | euleritian joins (~euleritia@77.22.252.56) |
| 05:24:12 | × | vglfr quits (~vglfr@88.155.159.184) (Read error: Connection reset by peer) |
| 05:24:34 | → | vglfr joins (vglfr@gateway/vpn/protonvpn/vglfr) |
| 05:25:23 | → | chomwitt joins (~chomwitt@2a02:587:7a17:8900:1ac0:4dff:fedb:a3f1) |
| 05:26:33 | × | rgw quits (~R@2605:a601:a0df:5600:88:c751:f921:bfac) (Read error: Connection reset by peer) |
| 05:28:54 | → | michalz joins (~michalz@185.246.207.221) |
| 05:37:09 | × | _ht quits (~Thunderbi@28-52-174-82.ftth.glasoperator.nl) (Quit: _ht) |
| 05:38:19 | → | johnw joins (~johnw@69.62.242.138) |
| 05:40:44 | × | rosco quits (~rosco@yp-150-69.tm.net.my) (Read error: Connection reset by peer) |
| 05:42:11 | × | euleritian quits (~euleritia@77.22.252.56) (Ping timeout: 255 seconds) |
| 05:42:34 | × | hugo quits (znc@verdigris.lysator.liu.se) (Ping timeout: 245 seconds) |
| 05:42:38 | × | vglfr quits (vglfr@gateway/vpn/protonvpn/vglfr) (Ping timeout: 255 seconds) |
| 05:42:54 | → | rosco joins (~rosco@193.138.218.161) |
| 05:42:59 | → | vglfr joins (~vglfr@88.155.159.184) |
| 05:47:55 | → | euleritian joins (~euleritia@dynamic-046-114-200-044.46.114.pool.telefonica.de) |
| 05:48:46 | → | whatsupdoc joins (uid509081@id-509081.hampstead.irccloud.com) |
| 05:50:38 | → | Inst joins (~Inst@120.244.192.250) |
| 05:52:33 | → | sm joins (~sm@plaintextaccounting/sm) |
| 05:54:56 | × | lisbeths quits (uid135845@id-135845.lymington.irccloud.com) (Quit: Connection closed for inactivity) |
| 05:55:31 | × | shriekingnoise quits (~shrieking@186.137.175.87) (Ping timeout: 255 seconds) |
| 05:56:56 | → | hugo joins (znc@verdigris.lysator.liu.se) |
| 05:57:40 | <dminuoso> | The only annoying part here is that it is not customizable. |
| 05:57:57 | <dminuoso> | So you are subject to someone elses opinion, as with any syntax highlighter or formatter. |
| 05:58:38 | → | Square3 joins (~Square4@user/square) |
| 06:05:25 | × | sm quits (~sm@plaintextaccounting/sm) (Ping timeout: 258 seconds) |
| 06:06:41 | → | acidjnk_new joins (~acidjnk@p200300d6e72b937894bacaba5afcc7b7.dip0.t-ipconnect.de) |
| 06:17:35 | × | bradparker quits (sid262931@id-262931.uxbridge.irccloud.com) (Ping timeout: 240 seconds) |
| 06:18:15 | × | rosco quits (~rosco@193.138.218.161) (Ping timeout: 240 seconds) |
| 06:20:07 | × | gooba quits (~gooba@90-231-13-185-no3430.tbcn.telia.com) (Ping timeout: 255 seconds) |
| 06:20:18 | → | rosco joins (~rosco@193.138.218.161) |
| 06:20:50 | → | bradparker joins (sid262931@id-262931.uxbridge.irccloud.com) |
| 06:24:43 | → | idgaen joins (~idgaen@2a01:e0a:498:fd50:fcc6:bb5d:489a:ce8c) |
| 06:31:58 | × | friendshipaka quits (~Friendshi@user/Friendship) (Read error: Connection reset by peer) |
| 06:32:18 | → | friendshipaka joins (~Friendshi@user/Friendship) |
| 06:33:37 | × | td_ quits (~td@i5387093F.versanet.de) (Ping timeout: 255 seconds) |
| 06:43:50 | → | gooba joins (~gooba@90-231-13-185-no3430.tbcn.telia.com) |
| 06:43:50 | → | td_ joins (~td@i5387091B.versanet.de) |
| 06:45:36 | × | p3n_ quits (~p3n@2a00:19a0:3:7c:0:d9c6:7cf6:1) (Quit: ZNC 1.8.2 - https://znc.in) |
| 06:46:31 | × | euleritian quits (~euleritia@dynamic-046-114-200-044.46.114.pool.telefonica.de) (Read error: Connection reset by peer) |
| 06:46:48 | → | euleritian joins (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) |
| 06:49:04 | → | p3n joins (~p3n@2a00:19a0:3:7c:0:d9c6:7cf6:1) |
| 06:49:21 | → | nate2 joins (~nate@c-98-45-169-16.hsd1.ca.comcast.net) |
| 06:53:51 | × | nate2 quits (~nate@c-98-45-169-16.hsd1.ca.comcast.net) (Ping timeout: 240 seconds) |
| 06:57:56 | → | fendor joins (~fendor@2a02:8388:1640:be00:aab:1226:f274:5021) |
| 07:03:56 | → | misterfish joins (~misterfis@84-53-85-146.bbserv.nl) |
| 07:04:24 | × | idgaen quits (~idgaen@2a01:e0a:498:fd50:fcc6:bb5d:489a:ce8c) (Quit: WeeChat 4.0.5) |
| 07:04:42 | → | lottaquestions joins (~nick@2607:fa49:503d:b200:641c:fc5a:8196:c097) |
| 07:05:54 | × | lottaquestions_ quits (~nick@2607:fa49:503d:b200:aeea:7f35:a3ca:4b4a) (Ping timeout: 245 seconds) |
| 07:09:04 | → | cpressey joins (~cpressey@host-2-102-14-126.as13285.net) |
| 07:09:28 | × | misterfish quits (~misterfis@84-53-85-146.bbserv.nl) (Ping timeout: 272 seconds) |
| 07:10:14 | → | misterfish joins (~misterfis@84-53-85-146.bbserv.nl) |
| 07:15:30 | → | gmg joins (~user@user/gehmehgeh) |
| 07:25:43 | × | danse-nr3 quits (~francesco@151.57.110.75) (Read error: Connection reset by peer) |
| 07:25:53 | → | danse-nr3 joins (~francesco@151.47.117.140) |
| 07:32:55 | → | CiaoSen joins (~Jura@2a05:5800:2b2:8d00:664b:f0ff:fe37:9ef) |
| 07:33:24 | × | hugo quits (znc@verdigris.lysator.liu.se) (Ping timeout: 245 seconds) |
| 07:35:03 | → | dcoutts joins (~duncan@net77-43-75-226.mclink.it) |
| 07:38:43 | → | mc47 joins (~mc47@xmonad/TheMC47) |
| 07:40:33 | → | hugo joins (znc@verdigris.lysator.liu.se) |
| 07:40:34 | → | Pickchea joins (~private@user/pickchea) |
| 07:40:54 | → | Jackneill joins (~Jackneill@20014C4E1E0E6F00DA1379EF70CDB149.dsl.pool.telekom.hu) |
| 07:43:28 | × | eggplantade quits (~Eggplanta@2600:1700:38c5:d800:b915:f992:5adb:85e) (Remote host closed the connection) |
| 07:44:05 | × | danse-nr3 quits (~francesco@151.47.117.140) (Ping timeout: 246 seconds) |
| 07:47:11 | × | misterfish quits (~misterfis@84-53-85-146.bbserv.nl) (Ping timeout: 255 seconds) |
| 07:50:33 | × | cpressey quits (~cpressey@host-2-102-14-126.as13285.net) (Ping timeout: 245 seconds) |
| 07:52:58 | → | danse-nr3 joins (~francesco@151.47.117.140) |
| 07:56:12 | → | machinedgod joins (~machinedg@d198-53-218-113.abhsia.telus.net) |
| 07:56:36 | → | chele joins (~chele@user/chele) |
| 08:00:32 | × | dcoutts quits (~duncan@net77-43-75-226.mclink.it) (Ping timeout: 246 seconds) |
| 08:02:13 | × | remexre quits (~remexre@user/remexre) (Ping timeout: 252 seconds) |
| 08:10:47 | × | econo_ quits (uid147250@id-147250.tinside.irccloud.com) (Quit: Connection closed for inactivity) |
| 08:11:51 | → | remexre joins (~remexre@user/remexre) |
| 08:14:54 | → | eggplantade joins (~Eggplanta@2600:1700:38c5:d800:b915:f992:5adb:85e) |
| 08:22:26 | <danse-nr3> | NonNull seems interesting hackage.haskell.org/package/mono-traversable-1.0.15.3/docs/Data-NonNull.html, wondering why it seems to exist only within mono-traversable |
| 08:24:51 | → | __monty__ joins (~toonn@user/toonn) |
| 08:34:19 | × | dsrt^ quits (~cd@76.145.193.217) (Remote host closed the connection) |
| 08:34:19 | × | cuiltb^ quits (~cd@76.145.193.217) (Remote host closed the connection) |
| 08:34:37 | → | dsrt^ joins (~cd@76.145.193.217) |
| 08:34:37 | → | cuiltb^ joins (~cd@76.145.193.217) |
| 08:35:55 | → | sm joins (~sm@plaintextaccounting/sm) |
| 08:36:34 | → | dcoutts joins (~duncan@net77-43-75-226.mclink.it) |
| 08:39:01 | → | misterfish joins (~misterfis@84-53-85-146.bbserv.nl) |
| 08:42:55 | × | billchenchina quits (~billchenc@2a0c:b641:7a2:230::10) (Ping timeout: 264 seconds) |
| 08:46:31 | × | dcoutts quits (~duncan@net77-43-75-226.mclink.it) (Ping timeout: 255 seconds) |
| 08:49:23 | zer0bitz_ | is now known as zer0bitz |
| 08:52:14 | × | zer0bitz quits (~zer0bitz@user/zer0bitz) () |
| 08:54:45 | → | kuribas joins (~user@ip-188-118-57-242.reverse.destiny.be) |
| 08:58:07 | → | zer0bitz joins (~zer0bitz@user/zer0bitz) |
| 08:58:46 | <Athas> | How do you install Accelerate nowadays? Which versions of GHC is it compatible with? Is there a shell.nix somewhere that just does everything for me? |
| 09:01:22 | × | Sgeo quits (~Sgeo@user/sgeo) (Read error: Connection reset by peer) |
| 09:03:49 | × | azimut quits (~azimut@gateway/tor-sasl/azimut) (Ping timeout: 252 seconds) |
| 09:07:07 | × | euleritian quits (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Ping timeout: 258 seconds) |
| 09:09:36 | <tomsmeding> | Athas: No explicit nix support (yet). The master branch versions (of accelerate{,-llvm{,-native,-ptx}}) are compatible with, I believe, 8.10 through 9.4 |
| 09:09:45 | <tomsmeding> | you'll need LLVM <= 14 |
| 09:09:48 | <tomsmeding> | er, <= 15 |
| 09:09:48 | → | Guest97 joins (~Guest97@163.116.195.115) |
| 09:09:52 | → | lortabac joins (~lortabac@89.207.171.151) |
| 09:10:17 | → | euleritian joins (~euleritia@dynamic-046-114-201-065.46.114.pool.telefonica.de) |
| 09:10:34 | × | Guest97 quits (~Guest97@163.116.195.115) (Client Quit) |
| 09:10:53 | → | dcoutts joins (~duncan@net77-43-75-226.mclink.it) |
| 09:11:17 | <tomsmeding> | (note that if you build 'accelerate' master with -fdebug, you'll need to add 'post-checkout-command: git submodule update --init --recursive' to the 'source-repository-package' cabal.project stanza) |
| 09:11:28 | <tomsmeding> | (the default is -f-debug) |
| 09:11:55 | → | cpressey joins (~cpressey@host-2-102-14-126.as13285.net) |
| 09:12:34 | × | sm quits (~sm@plaintextaccounting/sm) (Quit: sm) |
| 09:14:19 | <tomsmeding> | the hackage 1.3 versions still work, but require LLVM <= 12 (iirc) |
| 09:15:01 | <tomsmeding> | for GPU you'll need cuda <= 11, due to issues with c2hs/language-c |
| 09:15:51 | × | vglfr quits (~vglfr@88.155.159.184) (Ping timeout: 240 seconds) |
| 09:16:52 | × | lortabac quits (~lortabac@89.207.171.151) (Remote host closed the connection) |
| 09:17:14 | → | lortabac joins (~lortabac@89.207.171.151) |
| 09:19:04 | → | ubert joins (~Thunderbi@178.165.203.252.wireless.dyn.drei.com) |
| 09:21:37 | <Athas> | tomsmeding: what about the released versions? I always found it a bit difficult to figure out how to put together the half dozen different Accelerate repositories I need. |
| 09:21:55 | × | qqq quits (~qqq@92.43.167.61) (Ping timeout: 255 seconds) |
| 09:23:32 | <Athas> | Hm, the releases look three years old, so I suppose they are not representative anymore. |
| 09:25:57 | <tomsmeding> | Athas: the released versions work fine if you are okay with installing LLVM 12 :p |
| 09:26:21 | <tomsmeding> | 'accelerate' is the surface language plus the interpreter; the compiled backends are accelerate-llvm-native and accelerate-llvm-ptx |
| 09:27:13 | × | lortabac quits (~lortabac@89.207.171.151) (Remote host closed the connection) |
| 09:27:27 | × | tzh quits (~tzh@c-71-193-181-0.hsd1.or.comcast.net) (Quit: zzz) |
| 09:27:38 | → | lortabac joins (~lortabac@89.207.171.151) |
| 09:28:56 | <tomsmeding> | for the master branch versions, the package names are the same and live under github.com/AccelerateHS/ |
| 09:29:21 | × | rosco quits (~rosco@193.138.218.161) (Ping timeout: 258 seconds) |
| 09:31:14 | → | vglfr joins (~vglfr@88.155.159.184) |
| 09:34:01 | × | lortabac quits (~lortabac@89.207.171.151) (Ping timeout: 260 seconds) |
| 09:34:11 | <haskellbridge> | <Aquas> How does accelerate work? It interpretes its surface syntax to cuda C code via LLVM? |
| 09:34:31 | <tomsmeding> | basically |
| 09:34:48 | <tomsmeding> | the "interprets" is a reasonably complicated process, but yet : |
| 09:34:49 | <tomsmeding> | * :p |
| 09:34:55 | → | lortabac joins (~lortabac@89.207.171.151) |
| 09:35:07 | × | aforemny quits (~aforemny@i59F516ED.versanet.de) (Ping timeout: 255 seconds) |
| 09:36:28 | → | aforemny joins (~aforemny@i59F516FA.versanet.de) |
| 09:36:49 | <haskellbridge> | <Aquas> This sounds to be tweaking the GHC's compilation process. How does this work? |
| 09:37:00 | × | euleritian quits (~euleritia@dynamic-046-114-201-065.46.114.pool.telefonica.de) (Read error: Connection reset by peer) |
| 09:37:17 | → | euleritian joins (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) |
| 09:41:32 | <tomsmeding> | no, accelerate is "just" a library; by using the functions from the library, you're actually building a syntax tree instead of running the computations directly. (This is why you need to use 'run' to run the computation in the end.) This syntax tree then gets compiled as with a usual compiler, just at Haskell runtime. |
| 09:42:18 | × | cpressey quits (~cpressey@host-2-102-14-126.as13285.net) (Quit: Client closed) |
| 09:42:46 | × | lortabac quits (~lortabac@89.207.171.151) (Ping timeout: 260 seconds) |
| 09:42:52 | → | azimut joins (~azimut@gateway/tor-sasl/azimut) |
| 09:43:17 | → | lortabac joins (~lortabac@89.207.171.151) |
| 09:43:53 | <Athas> | It's essentially a JIT compiler. |
| 09:44:31 | <Athas> | That also means you can easily do interesting things like partial evaluation, where the Haskell level computation emits an Accelerate program. One of the Accelerate examples use this to specialise a ray tracer to a specific scene. |
| 09:47:09 | × | Inst quits (~Inst@120.244.192.250) (Ping timeout: 245 seconds) |
| 09:49:01 | → | Inst joins (~Inst@120.244.192.250) |
| 09:52:39 | <haskellbridge> | <Aquas> So LLVM is called at Haskell runtime? |
| 09:53:34 | × | lortabac quits (~lortabac@89.207.171.151) (Ping timeout: 255 seconds) |
| 09:54:42 | <Athas> | Yes. |
| 09:59:11 | <tomsmeding> | Aquas: you can also run the compilation process at Haskell compile time via TemplateHaskell by using runQ |
| 09:59:26 | <tomsmeding> | but personally I've never used that, so I'm not sure if that flow is still supported :D |
| 10:00:06 | × | Pickchea quits (~private@user/pickchea) (Quit: Leaving) |
| 10:07:27 | <Square> | in the middle of my nix build i see "uploading 'https://hydra.iohk.io/nix-cache-info'...". A bjt |
| 10:07:37 | <Square> | A bit sus. * |
| 10:10:22 | × | ft quits (~ft@p200300cf3f482500978224aa0512647c.dip0.t-ipconnect.de) (Quit: leaving) |
| 10:12:46 | × | xff0x quits (~xff0x@125x103x176x34.ap125.ftth.ucom.ne.jp) (Ping timeout: 255 seconds) |
| 10:14:55 | × | euleritian quits (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Read error: Connection reset by peer) |
| 10:15:46 | → | euleritian joins (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) |
| 10:25:15 | × | euleritian quits (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Read error: Connection reset by peer) |
| 10:25:44 | → | euleritian joins (~euleritia@dynamic-046-114-201-065.46.114.pool.telefonica.de) |
| 10:26:31 | × | aforemny quits (~aforemny@i59F516FA.versanet.de) (Ping timeout: 260 seconds) |
| 10:27:41 | → | aforemny joins (~aforemny@2001:9e8:6ce3:9f00:c447:f7a7:e738:aefa) |
| 10:28:40 | × | euleritian quits (~euleritia@dynamic-046-114-201-065.46.114.pool.telefonica.de) (Read error: Connection reset by peer) |
| 10:29:07 | → | euleritian joins (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) |
| 10:33:31 | × | euleritian quits (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Ping timeout: 260 seconds) |
| 10:34:07 | → | euleritian joins (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) |
| 10:39:28 | → | ubert1 joins (~Thunderbi@77.119.220.59.wireless.dyn.drei.com) |
| 10:40:04 | × | CiaoSen quits (~Jura@2a05:5800:2b2:8d00:664b:f0ff:fe37:9ef) (Ping timeout: 245 seconds) |
| 10:40:40 | × | ubert quits (~Thunderbi@178.165.203.252.wireless.dyn.drei.com) (Ping timeout: 255 seconds) |
| 10:40:40 | ubert1 | is now known as ubert |
| 10:41:01 | → | rosco joins (~rosco@193.138.218.161) |
| 10:41:29 | <Inst> | https://paste.tomsmeding.com/58hJ8xnN |
| 10:41:33 | <Inst> | any idea how to make this idiom fly? |
| 10:41:54 | → | cpressey joins (~cpressey@host-2-102-14-126.as13285.net) |
| 10:42:25 | <Inst> | and it's takne from a codewars kata, where it's all about overloading names to make an "English" expression work |
| 10:42:40 | <Inst> | the point is more, if you want multiple toplevel pure assignment |
| 10:43:02 | <Inst> | the verticalized list idiom doesn't work |
| 10:44:15 | × | coot quits (~coot@89-69-206-216.dynamic.chello.pl) (Ping timeout: 240 seconds) |
| 10:50:41 | <tomsmeding> | honestly I'd just `zero = ($ 0)` \n `one = ($ 1)` \n etc. :p |
| 10:50:50 | → | nate2 joins (~nate@c-98-45-169-16.hsd1.ca.comcast.net) |
| 10:50:57 | <tomsmeding> | if you want a bunch of names defined, define a bunch of names |
| 10:51:28 | <tomsmeding> | fancy haskell constructs are for manipulating data, not binders in haskell itself |
| 10:51:32 | <tomsmeding> | that's what TemplateHaskell is for |
| 10:52:02 | <tomsmeding> | this might not actually be that verbose in TH |
| 10:52:44 | → | pretty_dumm_guy joins (trottel@gateway/vpn/protonvpn/prettydummguy/x-88029655) |
| 10:53:52 | × | pretty_dumm_guy quits (trottel@gateway/vpn/protonvpn/prettydummguy/x-88029655) (Client Quit) |
| 10:55:36 | × | nate2 quits (~nate@c-98-45-169-16.hsd1.ca.comcast.net) (Ping timeout: 258 seconds) |
| 10:56:26 | × | stiell_ quits (~stiell@gateway/tor-sasl/stiell) (Remote host closed the connection) |
| 10:56:45 | × | danse-nr3 quits (~francesco@151.47.117.140) (Ping timeout: 258 seconds) |
| 10:56:58 | → | stiell_ joins (~stiell@gateway/tor-sasl/stiell) |
| 10:57:49 | × | pavonia quits (~user@user/siracusa) (Quit: Bye!) |
| 11:01:19 | × | stiell_ quits (~stiell@gateway/tor-sasl/stiell) (Remote host closed the connection) |
| 11:01:41 | → | stiell_ joins (~stiell@gateway/tor-sasl/stiell) |
| 11:02:25 | → | sm joins (~sm@plaintextaccounting/sm) |
| 11:03:48 | → | CiaoSen joins (~Jura@2a05:5800:2b2:8d00:664b:f0ff:fe37:9ef) |
| 11:05:04 | × | ggVGc quits (~ggVGc@a.lowtech.earth) (Quit: WeeChat 3.6) |
| 11:05:15 | <Square> | I believe there is a trick to create a proxy by using pure or return in some combination instead of Proxy :: Proxy MyType. Anyone know that one? I can't seem to recall how its done. |
| 11:05:17 | → | xff0x joins (~xff0x@ai101218.d.east.v6connect.net) |
| 11:05:55 | <Square> | oh, maybe it was from an value: pure value |
| 11:07:49 | <tomsmeding> | :t pure (undefined :: Int) :: Proxy Int |
| 11:07:50 | <lambdabot> | Proxy Int |
| 11:08:05 | <tomsmeding> | Square: Proxy implements Applicative, so 'pure :: a -> f a' becomes 'pure :: a -> Proxy a' |
| 11:08:26 | <Square> | right. Thanks |
| 11:08:31 | <tomsmeding> | but that really helps only if you already have an 'a' lying around |
| 11:08:48 | <tomsmeding> | (and it does not aid readability :p ) |
| 11:09:06 | <Square> | yeah, wish there was a shorter version directly from type |
| 11:10:14 | <ncf> | :t Proxy @Int |
| 11:10:15 | <lambdabot> | error: parse error on input ‘@’ |
| 11:11:04 | <Square> | sweet. I'll try that |
| 11:11:32 | <ncf> | TypeApplications |
| 11:13:47 | <albet70> | > fmap (+1) (Left 2) |
| 11:13:48 | → | arahael joins (~arahael@119-18-2-212.771202.syd.nbn.aussiebb.net) |
| 11:13:49 | <lambdabot> | Left 2 |
| 11:14:04 | → | nickiminjaj joins (~nickiminj@user/laxhh) |
| 11:19:16 | × | hiyori quits (~hiyori@user/hiyori) (Quit: Client closed) |
| 11:21:32 | × | eggplantade quits (~Eggplanta@2600:1700:38c5:d800:b915:f992:5adb:85e) (Ping timeout: 272 seconds) |
| 11:26:26 | × | dcoutts quits (~duncan@net77-43-75-226.mclink.it) (Ping timeout: 255 seconds) |
| 11:27:08 | × | cpressey quits (~cpressey@host-2-102-14-126.as13285.net) (Quit: Ping timeout (120 seconds)) |
| 11:28:08 | → | cpressey joins (~cpressey@host-2-102-14-126.as13285.net) |
| 11:31:07 | → | Vajb joins (~Vajb@207.61.167.122) |
| 11:32:06 | <tomsmeding> | > first (+1) (Left 2) |
| 11:32:08 | <lambdabot> | error: |
| 11:32:08 | <lambdabot> | • Couldn't match type ‘(b, d)’ with ‘Either a0 b0’ |
| 11:32:08 | <lambdabot> | Expected type: Either a0 b0 -> (b, d) |
| 11:32:16 | <tomsmeding> | er |
| 11:32:27 | <tomsmeding> | oh |
| 11:33:17 | <tomsmeding> | % Data.Bifunctor.first (+1) (Left 2) |
| 11:33:17 | <yahb2> | Left 3 |
| 11:33:51 | <tomsmeding> | why does lambdabot have arrows imported instead of bifunctors |
| 11:34:49 | × | hugo quits (znc@verdigris.lysator.liu.se) (Ping timeout: 255 seconds) |
| 11:37:16 | × | cpressey quits (~cpressey@host-2-102-14-126.as13285.net) (Quit: Client closed) |
| 11:37:40 | → | cpressey joins (~cpressey@host-2-102-14-126.as13285.net) |
| 11:39:28 | → | cpressey15 joins (~cpressey@host-2-102-14-126.as13285.net) |
| 11:40:01 | × | Vajb quits (~Vajb@207.61.167.122) (Ping timeout: 252 seconds) |
| 11:42:38 | × | cpressey quits (~cpressey@host-2-102-14-126.as13285.net) (Ping timeout: 245 seconds) |
| 11:42:56 | cpressey15 | is now known as cpressey |
| 11:45:15 | → | Square2 joins (~Square4@user/square) |
| 11:47:29 | × | Square quits (~Square@user/square) (Ping timeout: 255 seconds) |
| 11:47:30 | × | Square3 quits (~Square4@user/square) (Ping timeout: 272 seconds) |
| 11:50:01 | × | cpressey quits (~cpressey@host-2-102-14-126.as13285.net) (Quit: Ping timeout (120 seconds)) |
| 11:50:54 | → | hugo joins (znc@verdigris.lysator.liu.se) |
| 11:56:15 | × | aforemny quits (~aforemny@2001:9e8:6ce3:9f00:c447:f7a7:e738:aefa) (Ping timeout: 240 seconds) |
| 11:57:31 | <Inst> | hmmm |
| 11:57:39 | <Inst> | here's an idea for "IO monad sucks / Haskell syntax sucks" |
| 11:57:48 | <Inst> | you'd still want isMain for that |
| 11:57:58 | <Inst> | this is actually a pretty interesting idea for a library |
| 11:58:34 | <Inst> | but it's pretty much "OOP", unfortunately, i.e, trying to generate monadic types that are universally records |
| 11:58:42 | <Inst> | so you'd bypass the variadic function issue for Haskell |
| 11:59:03 | <Inst> | it'd be a pretty interesting basis for an alt prelude |
| 11:59:35 | <Inst> | the ability to do IO actions as getLine {text = hello} |
| 11:59:38 | <Inst> | nah, the syntax still sucks here |
| 12:00:22 | → | aforemny joins (~aforemny@2001:9e8:6ce4:a700:b6be:fb5b:7ea6:79a3) |
| 12:02:43 | <yushyin> | haskell syntax (extensions aside) is fine and clear |
| 12:08:36 | <Inst> | there is precisely one problem with Haskell syntax, imo, and that's the lack of variadics |
| 12:08:54 | <Inst> | it makes it harder to have ergonomic library API design |
| 12:09:22 | <Inst> | algol syntax languages have input("Enter name here: ") and input() at the same time |
| 12:09:39 | <Inst> | you have to do funky variadic function overloading with typeclasses to get that |
| 12:09:42 | → | danse-nr3 joins (~francesco@151.37.121.111) |
| 12:09:54 | <nullie> | wouldn't it become typing hell |
| 12:09:55 | <Inst> | being able to do foo bar baz and foo, and have both typecheck |
| 12:10:04 | <cheater> | What is Haskell? A miserable little pile of syntaxes. |
| 12:10:28 | <Inst> | the two ways to do it right now is to get a typeclass to overload |
| 12:10:39 | <Inst> | and do some weird crap with that |
| 12:10:48 | <Inst> | or to use a default record, and overload arguments onto the default record, but that's still painful |
| 12:10:52 | → | Vajb joins (~Vajb@207.61.167.122) |
| 12:11:13 | → | lortabac joins (~lortabac@37.169.5.141) |
| 12:11:15 | <Inst> | what we do right now is have variant functions, but that's unergonomic |
| 12:11:26 | → | qqq joins (~qqq@92.43.167.61) |
| 12:11:34 | <Inst> | getLinePrompt is a pain |
| 12:12:00 | <Inst> | unless there's more ways i'm unfamiliar with :( |
| 12:12:23 | <Inst> | @danse-nr3: do I know you by another name on Matrix? |
| 12:12:23 | <lambdabot> | Unknown command, try @list |
| 12:31:59 | × | lortabac quits (~lortabac@37.169.5.141) (Read error: Connection reset by peer) |
| 12:33:02 | × | Vajb quits (~Vajb@207.61.167.122) (Ping timeout: 255 seconds) |
| 12:42:32 | × | nickiminjaj quits (~nickiminj@user/laxhh) (Quit: My MacBook has gone to sleep. ZZZzzz…) |
| 12:43:33 | → | hgolden joins (~hgolden@2603-8000-9d00-3ed1-1ee4-1b7c-94a7-8fa7.res6.spectrum.com) |
| 12:51:57 | → | Vajb joins (~Vajb@207.61.167.122) |
| 12:52:07 | → | Square joins (~Square@user/square) |
| 13:00:19 | × | acidjnk_new quits (~acidjnk@p200300d6e72b937894bacaba5afcc7b7.dip0.t-ipconnect.de) (Ping timeout: 252 seconds) |
| 13:04:01 | → | cpressey joins (~cpressey@host-2-102-14-126.as13285.net) |
| 13:06:33 | <cpressey> | Hi, could anyone help me understand why the following is not a syntax error? |
| 13:06:36 | <cpressey> | > let 99 = 3 * 5 in 99 + 1 |
| 13:06:37 | <lambdabot> | 100 |
| 13:07:57 | <tomsmeding> | > let Just x = Just 42 in x |
| 13:07:58 | <lambdabot> | 42 |
| 13:08:16 | <tomsmeding> | > let (x, 42) = (10, 42) in x |
| 13:08:17 | <lambdabot> | 10 |
| 13:08:19 | <tomsmeding> | > let (x, 43) = (10, 42) in x |
| 13:08:21 | <lambdabot> | *Exception: <interactive>:3:5-22: Non-exhaustive patterns in (x, 43) |
| 13:08:31 | <tomsmeding> | cpressey: it's a degenerate pattern that happens to bind no variables |
| 13:09:13 | <tomsmeding> | the reason why it doesn't give a _runtime_ error about non-exhaustive patterns (because the pattern does, of course, not match) is laziness: the match is never evaluated because none of its bound variables are ever used |
| 13:09:22 | → | wib_jonas joins (~wib_jonas@business-37-191-60-209.business.broadband.hu) |
| 13:09:26 | <tomsmeding> | notwithstanding the fact that that is immediate because there _are_ no bound variables |
| 13:09:49 | <tomsmeding> | it's a cute one though :) |
| 13:10:06 | <tomsmeding> | could go on the haskell wtf list, after |
| 13:10:11 | <tomsmeding> | > let 2 + 2 = 5 in 2 + 2 |
| 13:10:12 | <lambdabot> | 5 |
| 13:10:39 | <tomsmeding> | cpressey: how did you find it |
| 13:11:00 | → | nickiminjaj joins (~nickiminj@83.5.236.254.ipv4.supernova.orange.pl) |
| 13:11:00 | × | nickiminjaj quits (~nickiminj@83.5.236.254.ipv4.supernova.orange.pl) (Changing host) |
| 13:11:00 | → | nickiminjaj joins (~nickiminj@user/laxhh) |
| 13:11:28 | <wib_jonas> | tomsmeding: I think that one just defines a (+) operator so that's less surprising |
| 13:11:43 | <tomsmeding> | for a haskell programmer it is indeed not surprising |
| 13:11:45 | <cpressey> | tomsmeding: the first version was "let 15 = 3 * 5 in 15 + 1" to see if Haskell would allow it |
| 13:11:52 | <tomsmeding> | right |
| 13:12:04 | <tomsmeding> | % :set -XBangPatterns |
| 13:12:05 | <yahb2> | <no output> |
| 13:12:10 | <tomsmeding> | % let !99 = 3 * 5 in 99 + 1 |
| 13:12:10 | <yahb2> | *** Exception: <interactive>:41:5-15: Non-exhaustive patterns in 99 |
| 13:12:15 | <tomsmeding> | right |
| 13:12:22 | <tomsmeding> | if you make the pattern strict, it fails at runtime :) |
| 13:12:27 | × | Vajb quits (~Vajb@207.61.167.122) (Ping timeout: 258 seconds) |
| 13:13:21 | <cpressey> | Anything to make it issue a warning at compile-time? To the effect that you have a pattern that doesn't have any variables? |
| 13:13:26 | <tomsmeding> | % :set -Wall |
| 13:13:26 | <yahb2> | <no output> |
| 13:13:32 | <tomsmeding> | % let 99 = 3 * 5 in () |
| 13:13:33 | <yahb2> | <interactive>:45:5: warning: [-Wunused-pattern-binds] ; This pattern-binding binds no variables: 99 = 3 * 5 ; ; <interactive>:45:5: warning: [-Wincomplete-uni-patterns] ; Pattern match(es)... |
| 13:13:38 | <tomsmeding> | cpressey: -Wall |
| 13:13:51 | <tomsmeding> | which everybody should use, as usual, and somehow not everybody does, as usual |
| 13:13:59 | <cpressey> | well, -Wincomplete-uni-patterns it seems, but yes, thank you :) |
| 13:14:05 | <tomsmeding> | % 2 |
| 13:14:05 | <yahb2> | <interactive>:47:1: warning: [-Wtype-defaults] ; • Defaulting the following constraints to type ‘Integer’ ; (Show a0) ; arising from a use of ‘Yahb2Defs.limitedPrint’ ; ... |
| 13:14:10 | <tomsmeding> | % :unset -Wall |
| 13:14:10 | <yahb2> | don't know how to reverse -Wall |
| 13:14:14 | <tomsmeding> | oh |
| 13:14:15 | <tomsmeding> | % :q |
| 13:14:15 | <yahb2> | <bye> |
| 13:14:17 | <tomsmeding> | % 1 |
| 13:14:18 | <yahb2> | 1 |
| 13:14:45 | <tomsmeding> | problem with -Wall in the interactive repl is that defaulting is damn useful in the repl and it throws warnings all over the place (as it should) |
| 13:15:19 | <tomsmeding> | cpressey: -Wunused-pattern-binds might be more specifically about this |
| 13:15:52 | <tomsmeding> | (it's so strange that it triggers _two_ warnings!) |
| 13:16:11 | <tomsmeding> | wow |
| 13:16:23 | <tomsmeding> | https://paste.tomsmeding.com/3xo5H8qf |
| 13:16:27 | <tomsmeding> | that's a _lot_ of output |
| 13:16:50 | <cpressey> | I tried it locally with ghci -Wall and it actually gave me 5 warnings |
| 13:17:00 | <tomsmeding> | see my paste, you can make it 6 |
| 13:17:19 | <tomsmeding> | only 4 on 8.10.7 though |
| 13:18:24 | <cpressey> | Ah, you've got a 1 on both sides, so you get overlapping patterns too |
| 13:18:56 | → | eggplantade joins (~Eggplanta@2600:1700:38c5:d800:b915:f992:5adb:85e) |
| 13:18:57 | <tomsmeding> | hm? same warnings if I do "in 2" |
| 13:19:27 | <tomsmeding> | ah the overlapping-patterns warning is there only if GHC doesn't have to do arithmetic to see that the match is redundant |
| 13:19:42 | <cpressey> | Ah ok |
| 13:19:43 | <tomsmeding> | if you replace the "99 = 1" by "99 = 1 * 1" it disappears |
| 13:19:49 | <tomsmeding> | fair enough |
| 13:35:22 | → | falafel joins (~falafel@62.175.113.194.dyn.user.ono.com) |
| 13:38:07 | × | arahael quits (~arahael@119-18-2-212.771202.syd.nbn.aussiebb.net) (Ping timeout: 255 seconds) |
| 13:43:09 | × | hugo quits (znc@verdigris.lysator.liu.se) (Ping timeout: 248 seconds) |
| 13:44:06 | → | Guest9 joins (~Guest9@ext-1-173.eduroam.chalmers.se) |
| 13:44:43 | <Guest9> | Hi! Is there any way to pass in arguments to the compiler during compile time? I run some TH code during compile time and I would like to pass in a configurable parameter. Naturally, `cabal build my-exe -- argument` does not work |
| 13:48:40 | <danse-nr3> | Inst: i don't think so, i don't hang out on matrix at the moment |
| 13:55:41 | <Inst> | thanks |
| 13:55:46 | <Inst> | hmmm, also: |
| 13:56:01 | → | acidjnk_new joins (~acidjnk@p200300d6e72b937894bacaba5afcc7b7.dip0.t-ipconnect.de) |
| 13:56:02 | × | sm quits (~sm@plaintextaccounting/sm) (Quit: sm) |
| 13:56:13 | <Inst> | still am trying to figure out how to implement varargs in haskell |
| 13:57:03 | <Inst> | could reuse the brace syntax for functions |
| 13:57:41 | <Inst> | and disambiguate vs record syntax by having it always default to be a secord function |
| 13:57:50 | <Inst> | *record function on the first brace |
| 13:58:22 | <Inst> | erm, record syntax |
| 13:58:36 | <Inst> | type system would be harder to do |
| 13:58:40 | <Inst> | implicit parameters? |
| 13:59:43 | × | notzmv quits (~zmv@user/notzmv) (Ping timeout: 264 seconds) |
| 14:00:55 | × | alphacentauri quits (alphacenta@gateway/vpn/protonvpn/alphacentauri) (Quit: WeeChat 4.1.0) |
| 14:01:53 | → | hugo joins (znc@verdigris.lysator.liu.se) |
| 14:04:09 | → | Simikando joins (~Simikando@adsl-dyn158.91-127-59.t-com.sk) |
| 14:04:10 | → | shriekingnoise joins (~shrieking@186.137.175.87) |
| 14:06:07 | <danse-nr3> | no i think it was discussed here not long ago, there is no idiomadic way |
| 14:09:07 | <Inst> | i'mm thinking language extensions |
| 14:09:31 | <Inst> | foo {} |
| 14:09:42 | <Inst> | foo :: bunch of implicit params go here => () -> a |
| 14:10:03 | <Inst> | the bigger question is how it'd be unhaskelly |
| 14:13:25 | → | thegeekinside joins (~thegeekin@189.180.124.118) |
| 14:17:44 | × | cpressey quits (~cpressey@host-2-102-14-126.as13285.net) (Quit: Ping timeout (120 seconds)) |
| 14:18:18 | <int-e> | > let start f = f []; push xs x f = f (x:xs); add (x:y:xs) f = f (x+y:xs); end xs = xs in start push 42 push 23 add push 11 add end |
| 14:18:19 | <lambdabot> | [76] |
| 14:19:39 | <danse-nr3> | neat! |
| 14:19:45 | <int-e> | Inst: What's the type of your function? |
| 14:19:55 | <probie> | Inst: how often do you need a true var args function? Still, you can look at how `Text.printf` is implemented |
| 14:21:43 | <int-e> | danse-nr3: It's the only example I know of of something that is kind of a varargs function but doesn't rely on type classes (only polymorphism). If you overdo it it'll seriously strain the type checker though. |
| 14:24:25 | <Inst> | int-e: it's more a question of how to build "accessible" libraries, i.e, people are used to having non-curried functions |
| 14:24:47 | <Inst> | the type would be implicit params => () -> something |
| 14:24:57 | <Inst> | you'd invoke via fun {args...} |
| 14:25:07 | <Inst> | the args would then get passed as implicit params with a default value |
| 14:25:46 | <Inst> | like i said, i'd just be more worried about it being unhaskelly because you'd essentially end up with a hybrid algol / ml syntax from it |
| 14:25:52 | <int-e> | I don't see how this is accessible. |
| 14:26:57 | <Inst> | it's more ergonomic for the library writer, and accessible to the end user because you don't need the typeclass overloading stuff anymore |
| 14:27:10 | <int-e> | [citation needed] |
| 14:27:42 | × | Guest9 quits (~Guest9@ext-1-173.eduroam.chalmers.se) (Quit: Connection closed) |
| 14:27:43 | <int-e> | Type errors are a boon. Variadic functions and types don't go together well. If you don't want types, don't use Haskell. |
| 14:27:59 | <Inst> | thanks <3 |
| 14:28:10 | <Inst> | i was asking about how this would be unhaskelly, you answered my question for me |
| 14:28:31 | <int-e> | (As people have pointed out, there are tricks to get variadic functions. Those invariably have quite terrible type errors when you hold them wrong.) |
| 14:28:40 | → | sm joins (~sm@plaintextaccounting/sm) |
| 14:29:10 | <Inst> | the only benefit of the system i'd propose would be that it'd reduce the chances of error when screwing up with variadic functions |
| 14:29:19 | <Inst> | the natural place for such functions would be in IO or IO surrogates |
| 14:29:27 | <int-e> | > printf "%f" id |
| 14:29:28 | <lambdabot> | error: |
| 14:29:28 | <lambdabot> | • Could not deduce (PrintfArg (a0 -> a0)) |
| 14:29:28 | <lambdabot> | arising from a use of ‘printf’ |
| 14:29:40 | <int-e> | (that's not even half the error) |
| 14:29:51 | <Inst> | i don't think anyone would want to use it outside IO etc |
| 14:31:20 | <danse-nr3> | when i came to haskell at first i missed variadic functions, now i struggle to imagine an use case for them... i always end up thinking: "so... we want a list?" |
| 14:31:43 | <Inst> | I only miss variadic functions when I look up a Haskell library and notice the API design |
| 14:31:58 | <Inst> | of course the library is perfectly fine and usable, but lack of variadics makes it harder to pick up |
| 14:32:30 | <Inst> | in fact there's a few functions that implement variadics that i feel, not necessarily know, is smelly |
| 14:32:38 | <Inst> | *a few libraries |
| 14:33:05 | × | misterfish quits (~misterfis@84-53-85-146.bbserv.nl) (Remote host closed the connection) |
| 14:33:49 | <Inst> | if such an extension existed, i'd actually want the extension split up, one for writing variadic functions, and another for calling them |
| 14:36:03 | <int-e> | I guess the answer to "what do people who really really want a variable number of arguments of varying types use" is something like HList. |
| 14:36:24 | × | Simikando quits (~Simikando@adsl-dyn158.91-127-59.t-com.sk) (Ping timeout: 258 seconds) |
| 14:36:59 | <int-e> | Or possibly something on top of Template Haskell. |
| 14:37:01 | <danse-nr3> | or a sum type. Varying types does not have to mean any type |
| 14:40:20 | × | wib_jonas quits (~wib_jonas@business-37-191-60-209.business.broadband.hu) (Quit: Client closed) |
| 14:49:42 | → | [itchyjunk] joins (~itchyjunk@user/itchyjunk/x-7353470) |
| 14:50:09 | → | idgaen joins (~idgaen@2a01:e0a:498:fd50:fcc6:bb5d:489a:ce8c) |
| 14:50:58 | × | danse-nr3 quits (~francesco@151.37.121.111) (Ping timeout: 258 seconds) |
| 14:52:22 | → | nate2 joins (~nate@c-98-45-169-16.hsd1.ca.comcast.net) |
| 14:53:58 | <probie> | I think you just want a list of a boring old sum type |
| 14:54:17 | <tomsmeding> | the only useful variadic function I know in C is printf |
| 14:54:21 | <tomsmeding> | (and friends) |
| 14:54:39 | <tomsmeding> | C and C++, that is |
| 14:54:59 | <tomsmeding> | it seems to me that all other useful cases of variadic functions are not actually variadic functions, they're simply ad-hoc overloading |
| 14:55:05 | <tomsmeding> | we don't do that in haskell |
| 14:55:25 | <tomsmeding> | granted, printf is useful and awkward in haskell. But that's a small price for getting, well, haskell |
| 14:56:12 | <tomsmeding> | execl() and friends do not count because seriously, use execv already |
| 14:56:43 | <tomsmeding> | (execl() and friends only exist in C because creating and filling an array in C is annoying) |
| 14:57:23 | × | nate2 quits (~nate@c-98-45-169-16.hsd1.ca.comcast.net) (Ping timeout: 255 seconds) |
| 14:57:29 | <tomsmeding> | well, I said "we don't do that in haskell" -- we have type classes for that |
| 14:57:44 | <tomsmeding> | but it's more structured than the bare-bones ad-hoc overloading you get in C++ |
| 14:59:51 | × | euleritian quits (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Ping timeout: 240 seconds) |
| 15:00:26 | → | euleritian joins (~euleritia@77.22.252.56) |
| 15:01:13 | → | vektor joins (~vektor@IP-045131036068.dynamic.medianet-world.de) |
| 15:04:45 | → | danse-nr3 joins (~francesco@151.37.121.111) |
| 15:05:09 | <vektor> | Is there a way to constrain a data type to only take type args of certain classes? Concretely, could I build a type Vector a that guarantees that a is always Num? Or always Show? I have a datatype that makes sense only with a small set of types 'a', but I want to be agnostic of the concrete type 'a' used there. The usual solution is to just carry |
| 15:05:09 | <vektor> | the class constraint in all relevant functions, but I found that dissatisfactory. |
| 15:06:38 | <vektor> | Mostly because in many functions I don't actually care about what 'a' is, but then 20 functions down from the last mention, I want to debug-print a value of a, and have to add Show a to 20 signatures, when in my mind it doesn't even make sense to have 'a' not be show. |
| 15:08:14 | <ncf> | ghc has something called the "stupid context" which i learnt about recently https://hackage.haskell.org/package/ghc-9.8.1/docs/src/GHC.Core.DataCon.html |
| 15:08:26 | <ncf> | is that what you're looking for? |
| 15:09:01 | × | azimut quits (~azimut@gateway/tor-sasl/azimut) (Ping timeout: 252 seconds) |
| 15:09:24 | <danse-nr3> | or is this a case for a plain constraint on a type parameter? |
| 15:09:56 | <EvanR> | check out this variadic printf: putStrLn [show 234, show 8.423, show True, show 'c'] |
| 15:10:10 | × | statusbot12 quits (~statusbot@ec2-34-198-122-184.compute-1.amazonaws.com) (Remote host closed the connection) |
| 15:10:11 | <EvanR> | er, throw a concat in there |
| 15:10:24 | → | statusbot joins (~statusbot@ec2-34-198-122-184.compute-1.amazonaws.com) |
| 15:10:26 | <EvanR> | or unlines |
| 15:10:27 | → | Achylles joins (~Achylles_@45.182.57.85) |
| 15:11:18 | <danse-nr3> | oh i see you want to have `data D = Show a => D a` for instance? Yeah makes sense i was looking for something similar some time ago |
| 15:11:54 | <ddellacosta> | existential types, but they have always seemed like more trouble than it's worth. Stupid context is interesting ncf , TIL, thanks |
| 15:11:56 | <EvanR> | Vector (String, a) |
| 15:12:14 | <EvanR> | very stupid context ^ |
| 15:12:49 | <EvanR> | data StringAnd a = StringAnd String a |
| 15:13:28 | <ncf> | er i guess it's not GHC-specific. it's right there in the haskell 98 report: data [context =>] simpletype = constrs |
| 15:14:21 | <EvanR> | somewhat more seriously, it would be nice if in debug mode you could just debug values without threading Show everywhere, like a built-in Show (similar to how Typeable is built-in now) |
| 15:14:30 | <[Leary]> | I think that "stupid context" is referring to DatatypeContexts, in which case it's entirely useless. Re existential, you don't actually need to hide a type to carry a constraint around, so that can solve the issue given a runtime cost, but may require the constraints be present in your type sigs anyway. |
| 15:15:15 | <EvanR> | idris has no issue displaying something for any term, even functions |
| 15:15:17 | <vektor> | danse-nr3: That's what I want, yeah. Basically, define `data D a = (Show a, Num a) => Constructor1 | Constructor2`, and then never have to worry about telling ghc that 'yes, a is in fact show and Num, don't worry your pretty little head about that part'. Is that what that does? |
| 15:16:56 | <vektor> | as for the concurrent suggestion of "stupid context", I wasn't quite able to make sense of that yet, but it seems to build upon danse's suggestion? THough the syntax used there is `data (Eq a, Ord b) => T a b = T1 a b | T2 a` |
| 15:16:59 | <ncf> | [Leary]: why is it entirely useless? |
| 15:17:14 | <danse-nr3> | so existential types suggested above by ddellacosta seem to be the solution |
| 15:17:40 | <[Leary]> | ncf: You can't actually /use/ the constraint, only impose it. |
| 15:18:15 | <ncf> | right |
| 15:20:25 | <EvanR> | by using the existential, I'm not sure how that accomplishes the goal of requiring support down the line but not specifying it in the users type signatures |
| 15:20:46 | <EvanR> | the users still can't be totally polymorphic, they have to specify your existential |
| 15:21:06 | <EvanR> | also, common wisdom is you don't want to accomplish this goal |
| 15:21:10 | → | ski joins (~ski@88.131.7.247) |
| 15:21:18 | <danse-nr3> | i just started reading, seems like the main usecase suggests that the costrained parameter is not exposed in the type |
| 15:22:20 | <ddellacosta> | yeah, I probably shouldn't have mentioned existential types, to echo what EvanR is saying |
| 15:22:23 | <EvanR> | you can't have quote most of your functions not care about the type in Vector a, but still call these inner functions that require special support |
| 15:22:48 | <EvanR> | since they actually do care |
| 15:23:02 | × | CiaoSen quits (~Jura@2a05:5800:2b2:8d00:664b:f0ff:fe37:9ef) (Ping timeout: 255 seconds) |
| 15:23:10 | <[Leary]> | vektor: You'd want `data T a b = (Eq a, Ord b) => T1 a b | Eq a => T2 a`. You /do/ have to satisfy the constraints upon constructing the data, but they're then made available upon pattern matching. |
| 15:23:29 | <vektor> | Ok, so DatatypeContexts and data (Show a) => D a seems to demand I carry the 'Show a' constraint everywhere I take my D a. That's the opposite of what I intended... |
| 15:23:39 | × | _xor quits (~xor@72.49.199.93) (Quit: Ping timeout (120 seconds)) |
| 15:23:50 | <vektor> | [Leary], I assume that syntax does the other thing then? :D |
| 15:24:02 | → | alphacentauri joins (alphacenta@gateway/vpn/protonvpn/alphacentauri) |
| 15:24:18 | → | _xor joins (~xor@72.49.199.93) |
| 15:26:05 | <EvanR> | you would have to put Vector (D a) everywhere instead, so I guess it saves some typing, but that doesn't make anything fully polymorphic. Another way to reduce typing is to make a synonym for (Show a, Num a) =>, so shorthanded would be something like SN a => |
| 15:27:33 | → | billchenchina joins (~billchenc@2a0c:b641:7a2:230::10) |
| 15:27:45 | <c_wraith> | vektor: the semantics of DatatypeContexts are *solely* that the constraint is added to the constructor. There's no provision that the constraint mean anything. This is why it's deprecated - it's useless. |
| 15:29:49 | <vektor> | Yeah, I vaguely remember attacking this same problem before and not making much progress. Ever since then, there's been a pesky "-XDatatypeContexts is deprecated" warning that I never really bothered to fix. I have been here before O.o |
| 15:31:20 | × | euleritian quits (~euleritia@77.22.252.56) (Ping timeout: 246 seconds) |
| 15:32:07 | × | falafel quits (~falafel@62.175.113.194.dyn.user.ono.com) (Ping timeout: 252 seconds) |
| 15:33:05 | <EvanR> | your original "problem" of putting constraints on operations that need them is actually the solution |
| 15:33:30 | → | euleritian joins (~euleritia@dynamic-046-114-202-144.46.114.pool.telefonica.de) |
| 15:33:37 | <EvanR> | the problem of debugging stuff though, there might be a better way to go about it |
| 15:33:40 | <tomsmeding> | yeah, the established alternative to DatatypeContexts is just putting the constraints on the operation |
| 15:34:15 | <tomsmeding> | "putting the constraint _in_ the data type" is making a GADT, like [Leary] suggested |
| 15:35:42 | → | Simikando joins (~Simikando@adsl-dyn158.91-127-59.t-com.sk) |
| 15:39:17 | <vektor> | Ok, I've messed about with what Leary suggested now. Running after the stack of compiler errors I inevitably get, my main observation is that I lose some of the "undesired" polymorphism. So when previously I could arrange constructors to create a value of type 'D a' and then later decide on which a to use, now I have to either decide on which a to |
| 15:39:17 | <vektor> | use, or carry the (Num a, Show a) constraint in places I previously didn't have to. Taking a step back, the constraint seems to no longer be needed in places that consumed or transformed D, but is now needed in places that create D. I guess that makes sense, no free lunch after all. |
| 15:40:01 | <EvanR> | you're basically bundling the dictionary with your value |
| 15:40:26 | <vektor> | sorry, what dictionary? |
| 15:40:33 | <EvanR> | sort of a Num a *> a, as opposed to Num a => a which is like a function waiting for a dictionary |
| 15:40:38 | × | nickiminjaj quits (~nickiminj@user/laxhh) (Quit: My MacBook has gone to sleep. ZZZzzz…) |
| 15:41:19 | <EvanR> | the dictionary is how type classes are implemented, it's a record of all the instance methods. GHC passes it around for you when there is ad-hoc polymorphism |
| 15:41:31 | × | Achylles quits (~Achylles_@45.182.57.85) (Quit: Leaving) |
| 15:42:02 | → | danse-nr3_ joins (~francesco@151.57.122.70) |
| 15:42:33 | × | danse-nr3 quits (~francesco@151.37.121.111) (Read error: Connection reset by peer) |
| 15:43:06 | → | econo_ joins (uid147250@id-147250.tinside.irccloud.com) |
| 15:44:34 | <ski> | `elem :: Eq a => a -> [a] -> Bool' is transformed into `elem :: EqDict a -> a -> [a] -> Bool', where `data EqDict a = MkEqDict {(==),(/=) :: a -> a -> Bool} is the dictionary/record/"vtable" that is the translation of `class Eq a of (==),(/=) :: a -> a -> Bool' |
| 15:46:57 | <EvanR> | when you build a GADT with constraints on the constructor, the dictionary is bundled. When you case analyze a GADT the dictionaries come out again |
| 15:47:20 | <ski> | vektor : .. and `data T a b = (Eq a, Ord b) => T1 a b | Eq a => T2 a' above would then get translated into `data T a b = T1 (EqDict a) (OrdDict b) a b | T2 (EqDict a) a' .. so when you're constructing `T1's and `T2's, you're packing those instance dictionaries into the data structure. and when you're pattern-matching, you're getting them back out again |
| 15:48:15 | <EvanR> | in light of all this, if you just need the Show constraint, it's clear that you could get the same effect by just bundling a String instead and skip the machinery xD |
| 15:49:17 | <ski> | (of course, an implementation is free to inline these dictionaries wherever it can .. but it can't do that, everywhere, due "polymorphic recursion" (technical term). and also due to a bunch of language extensions, should you turn any of them on) |
| 15:49:25 | <tomsmeding> | (in which case a smart constructor / pattern synonym might come in handy to avoid having to keep the String up to date manually) |
| 15:49:32 | <vektor> | Oh, dang. I had thought the Existential thing mapped the constraint over all constructors, but if I just put it once, it's just for the first somehow...? Color me thoroughly confused. |
| 15:49:55 | → | nickiminjaj joins (~nickiminj@83.5.236.254.ipv4.supernova.orange.pl) |
| 15:49:55 | × | nickiminjaj quits (~nickiminj@83.5.236.254.ipv4.supernova.orange.pl) (Changing host) |
| 15:49:55 | → | nickiminjaj joins (~nickiminj@user/laxhh) |
| 15:50:15 | × | eggplantade quits (~Eggplanta@2600:1700:38c5:d800:b915:f992:5adb:85e) (Remote host closed the connection) |
| 15:50:19 | <dolio> | Each constructor gets its own context. |
| 15:50:30 | → | eggplantade joins (~Eggplanta@2600:1700:38c5:d800:b915:f992:5adb:85e) |
| 15:50:39 | <ski> | vektor : in `data T ... = ... | Eq a => C ..a.. | ...', `Eq a' is attached only to the data constructor `C' there |
| 15:50:52 | <tomsmeding> | the first step in understanding all this is reading '->' for '=>'. (The 'data T a = Eq a => C a a' notation is a bit special; the GADT version, which is 'data T a where C :: Eq a -> a -> a -> T a', is clearer.) |
| 15:51:25 | <tomsmeding> | er, oops, Eq a => a -> a -> T a, of course :D |
| 15:51:54 | <vektor> | ski: Ahhh, I see. That's why it's not doing what I hoped. I can't eliminate the redundant constraints on functions working with my data type, because the constraints I baked into the data def only apply to the first constructor... |
| 15:52:31 | <EvanR> | if they only apply to the first constructor then fine? |
| 15:52:49 | <EvanR> | you still don't need more constraints on functions accepting the type |
| 15:53:48 | × | hugo quits (znc@verdigris.lysator.liu.se) (Ping timeout: 240 seconds) |
| 15:53:50 | <EvanR> | unless there are other arguments which need to be compatible for some reason and then we need examples |
| 15:54:16 | <vektor> | I mean, if I now write a prettyPrint :: D a -> String ... my expectation was that a (Show a) constraint wouldn't be necessary, as it's implied by the type: (D a) can not exist with an a that is not Show. That was the point of the exercise. |
| 15:54:27 | <ski> | vektor : mind, i didn't catch the start of this conversattion (e.g. hasn't seen any code snippets you might've shown) |
| 15:54:47 | <EvanR> | yes because you couldn't have constructed one |
| 15:55:17 | <EvanR> | no |
| 15:55:58 | <vektor> | EvanR: Are you saying if I apply the constraint to all constructors, the compiler would figure out that there can only ever be 'D a' if (Show a)? |
| 15:56:12 | ski | idly wonders how `D's defined |
| 15:56:16 | <EvanR> | data T a where C1 :: Show a => a -> T a; C2 a -> T a -- here, you can constraint a non-Show a. But you wouldn't be able to pretty print it, probably. So you could show "????" instead |
| 15:56:17 | <tomsmeding> | prettyPrint needs to get the 'show' method for 'a' from _somewhere_; if prettyPrint takes 'Show a =>', then it gets that method as an argument. If you put 'Show a =>' on a constructor of D, that constructor has the method in one of its fields. Either way prettyPrint gets the info. |
| 15:56:19 | → | hugo joins (znc@verdigris.lysator.liu.se) |
| 15:56:30 | <tomsmeding> | If you do neither of those things, it can't magically conjure up the method from somewhere :p |
| 15:56:59 | <EvanR> | vektor, no, this is much simpler than you are thinking |
| 15:58:00 | <tomsmeding> | the whole intuition of "types being a member of a type class" only exists during typeclass _resolution_, which is the phase where ghc turns code with '=>' into code with '->', explictly passing the dictionaries (containing the type class methods) around |
| 15:58:24 | <tomsmeding> | after that, type classes don't exist any more, there's just some additional records/dictionaries of stuff being passed around |
| 15:59:13 | <vektor> | ski, just to fill you in, I have a data type 'D a' (or actually 'Expr x a', and yes, it's a syntax tree of a DSL) where a is only ever instantiated with types with Show and Num. I want to put those constraints into the type of D, so I don't have to make them explicit every time I try to "traceShow" a value of type a. |
| 16:00:02 | × | ubert quits (~Thunderbi@77.119.220.59.wireless.dyn.drei.com) (Ping timeout: 246 seconds) |
| 16:00:13 | <EvanR> | put those constraints into constructors that hold the said types you want to show |
| 16:00:22 | × | alphacentauri quits (alphacenta@gateway/vpn/protonvpn/alphacentauri) (Quit: WeeChat 4.1.0) |
| 16:00:24 | <tomsmeding> | right, that's the only thing you can do here |
| 16:00:30 | <EvanR> | constructors you can show without that information... show them without the information and you don't need the constraints |
| 16:00:32 | <vektor> | ... a value of type a contained within a D or Expr x of course. A naked a would still need the Show a thing. But Basically, I want to make functions like prettyPrint (D a) -> String, where I can call show on values of a without the compiler yelling. |
| 16:00:33 | <ski> | vektor : you're using `GADTs' for that ? |
| 16:01:20 | <EvanR> | a "naked a" in isolation has no support for anything, you can't even print it |
| 16:01:21 | <vektor> | ski: nah, just plain ADT. |
| 16:01:27 | <ski> | vektor : are `x' and `a' indices of `Expr' ? or just parameters ? |
| 16:01:29 | <ski> | ok |
| 16:01:42 | <EvanR> | and contradicts that you only use it at types that support Show |
| 16:02:17 | <EvanR> | for the purposes of pretty printing another avenue is Generic, rather than Show |
| 16:02:23 | <vektor> | Don't worry about x, that's just dead weight. a is the numeric type in which Expr does its computations. I.e. I can switch from Float to Double by one function call. |
| 16:02:23 | ski | would still like to actually see this `Expr |
| 16:02:25 | <ski> | ' |
| 16:02:44 | × | Simikando quits (~Simikando@adsl-dyn158.91-127-59.t-com.sk) (Ping timeout: 272 seconds) |
| 16:05:04 | → | danse-nr3__ joins (~francesco@151.57.122.70) |
| 16:05:08 | × | eggplantade quits (~Eggplanta@2600:1700:38c5:d800:b915:f992:5adb:85e) (Remote host closed the connection) |
| 16:05:40 | × | danse-nr3_ quits (~francesco@151.57.122.70) (Read error: Connection reset by peer) |
| 16:05:48 | <vektor> | ski: https://paste.tomsmeding.com/6KsU2MIg - there you go. Shown here with the currently-workshopped "everything gets constraints" version. |
| 16:07:10 | × | Natch quits (~natch@c-9e07225c.038-60-73746f7.bbcust.telenor.se) (Ping timeout: 272 seconds) |
| 16:08:35 | <ski> | imho, you might be better off with `data WrappedExpr x a = (Num a,Show a) => WrapExpr (WrappedExpr x a)' (and deleting all the bundled constraints in `Expr') -- at least that way, you'd not be putting your constraints into every single node of your syntax tree (quite redundently, one could think) |
| 16:10:16 | → | Natch joins (~natch@c-9e07225c.038-60-73746f7.bbcust.telenor.se) |
| 16:10:37 | <ski> | .. and there's really no point in putting `Show a' constraints on the nodes that can't even contain any value of a type mentioning the `a' parameter (those data constructors are `ThetaI',`Uniform',`Normal',`Null',`Var',`TNull',`Call') |
| 16:10:42 | × | machinedgod quits (~machinedg@d198-53-218-113.abhsia.telus.net) (Ping timeout: 258 seconds) |
| 16:11:18 | <EvanR> | yes you can presumably print Null without any additional infor |
| 16:11:38 | <ski> | (i'm assuming `Value a's can actually contain `a's, since there's no other place in there where `a' could actually get used) |
| 16:11:41 | × | euleritian quits (~euleritia@dynamic-046-114-202-144.46.114.pool.telefonica.de) (Read error: Connection reset by peer) |
| 16:12:07 | → | euleritian joins (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) |
| 16:12:08 | → | ubert joins (~Thunderbi@77.119.220.59.wireless.dyn.drei.com) |
| 16:12:18 | <vektor> | I mean, I just blindly copy pasted those constraints everywhere in the hopes that some GHC-magic would activate and ghc would figure out that "oh, Expr x a implies that a is both show and num, anywhere I go, but I'm not sure it's materializing. |
| 16:12:28 | <EvanR> | which makes me think your actual objective is something else, given you wanted to trick GHC into thinking ^ |
| 16:12:29 | <ski> | @where DecoratingStructures |
| 16:12:29 | <lambdabot> | <http://web.archive.org/web/20051126143527/http://haskell.org/hawiki/DecoratingStructures> |
| 16:12:36 | <ski> | @where IndirectComposite |
| 16:12:36 | <lambdabot> | <http://web.archive.org/web/20051126141834/http://haskell.org/hawiki/IndirectComposite> |
| 16:12:49 | <vektor> | Yeah, as said, a is the numeric type of the execution, so Values are where a lives. |
| 16:12:58 | <EvanR> | GHC is not magic and the stuff involved here is purely mechanical |
| 16:13:30 | <EvanR> | obeying the usual laws of nature |
| 16:13:32 | <ski> | what you get out it what you put in |
| 16:13:38 | <vektor> | I'm starting to think I've found a thing that's cognitively simple to think about ("just put an implied "Show a, Num a" onto every Expr x a), but ghc doesn't really do it simply. |
| 16:14:09 | <ski> | vektor : what is the current problem you're experiencing (with this strategy you just described) ? |
| 16:18:44 | → | notzmv joins (~zmv@user/notzmv) |
| 16:19:41 | × | sm quits (~sm@plaintextaccounting/sm) (Quit: sm) |
| 16:22:43 | <vektor> | Bunch of edge cases that interface with Expr in funny ways, gimme a few minutes. |
| 16:22:50 | <EvanR> | if you put the constraints in the GADT, then yes logically the a in Expr x a are instances of Show and Num, assuming you managed to build an Expr x a. Anywhere you go. To prove it, pattern match the Expr |
| 16:23:04 | → | Simikando joins (~Simikando@adsl-dyn158.91-127-59.t-com.sk) |
| 16:24:07 | × | euleritian quits (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Ping timeout: 258 seconds) |
| 16:24:38 | <vektor> | Currently, I only have an ADT. That make a difference to your statement? |
| 16:24:44 | → | euleritian joins (~euleritia@dynamic-046-114-202-144.46.114.pool.telefonica.de) |
| 16:24:47 | → | sm joins (~sm@plaintextaccounting/sm) |
| 16:24:50 | <ski> | it's not going to give you `Num a' and `Show a' anytime you have a value of type `Expr x a'. you have to pattern-match, as EvanR says, to extract those constraints. only in the scope of that pattern-match are those constraints known / in force |
| 16:24:50 | ← | ozone parts (ozone@libera/bot/ozone) (Leaving the channel. /invite ozone again if needed) |
| 16:25:10 | <ski> | vektor : do you currently have what you showed in the paste ? |
| 16:25:41 | <vektor> | ski: Yeah, what's currently in the paste. I'm working on fixing the rest of the code to coordinate with it. |
| 16:25:47 | <ski> | i believe EvanR meant the syntax of putting `..constraints.. =>' before the data constructors, by "GADT" here |
| 16:27:56 | <vektor> | EvanR: Regarding the magic/mechanical comment, I'm quite aware, but I could've imagined GHC going "oh, all of these constructors have a subset of common constraints, let me take the intersection of all those and then you get them for free everywhere you meet an Expr x a. Not infeasible, afaict, but it would've surprised me if GHC just did that. |
| 16:27:57 | × | euleritian quits (~euleritia@dynamic-046-114-202-144.46.114.pool.telefonica.de) (Read error: Connection reset by peer) |
| 16:28:09 | → | falafel joins (~falafel@62.175.113.194.dyn.user.ono.com) |
| 16:28:20 | <ski> | yea, it doesn't |
| 16:28:21 | <EvanR> | I'm glad GHC doesn't do surprising things |
| 16:28:27 | → | euleritian joins (~euleritia@dynamic-046-114-202-144.46.114.pool.telefonica.de) |
| 16:28:43 | <EvanR> | I like my code to be unsurprising AF |
| 16:28:45 | <ski> | you only get the constraints associated with the data constructor, when you (sucessfully) match on that data constructor |
| 16:29:02 | → | zenstoic joins (uid461840@id-461840.hampstead.irccloud.com) |
| 16:29:30 | <EvanR> | I'm kind of amazed how far people can get with their compilers not understanding how they work |
| 16:29:38 | × | __monty__ quits (~toonn@user/toonn) (Ping timeout: 255 seconds) |
| 16:29:54 | <ski> | compilers are shiny toys |
| 16:32:04 | × | nickiminjaj quits (~nickiminj@user/laxhh) (Quit: My MacBook has gone to sleep. ZZZzzz…) |
| 16:32:09 | → | _ht joins (~Thunderbi@28-52-174-82.ftth.glasoperator.nl) |
| 16:32:41 | <vektor> | EvanR: Well, "understanding the compiler" and "getting somewhere with the compiler" exist in a symbiotic relationship. Have to encounter situations you don't understand to learn something, but also have to stay reasonably close to what you know to stay effective. Right now I'm exploring quite a lot, so compiler surprises are expected. |
| 16:33:15 | → | alphacentauri joins (alphacenta@gateway/vpn/protonvpn/alphacentauri) |
| 16:33:20 | <ski> | correct |
| 16:33:24 | <vektor> | But personally I've never complained about an "oh hey, ghc can derive that instance for me" moment. Some surprises are good. |
| 16:34:21 | → | nickiminjaj joins (~nickiminj@83.5.236.254.ipv4.supernova.orange.pl) |
| 16:34:21 | × | nickiminjaj quits (~nickiminj@83.5.236.254.ipv4.supernova.orange.pl) (Changing host) |
| 16:34:21 | → | nickiminjaj joins (~nickiminj@user/laxhh) |
| 16:35:15 | × | nickiminjaj quits (~nickiminj@user/laxhh) (Client Quit) |
| 16:36:36 | <EvanR> | I took your data type and wrote a function showE :: Expr x a -> String which makes use of show to print the Constant x (Value a). Of course, I have no way to do anything with the x |
| 16:37:02 | ← | L29Ah parts (~L29Ah@wikipedia/L29Ah) () |
| 16:37:17 | <vektor> | Cool. How's that look? |
| 16:37:29 | <EvanR> | the code for showE? |
| 16:37:31 | <vektor> | Yeah |
| 16:37:32 | × | hugo quits (znc@verdigris.lysator.liu.se) (Ping timeout: 248 seconds) |
| 16:37:45 | <EvanR> | showE (Constant x v) = show v |
| 16:38:41 | → | nickiminjaj joins (~nickiminj@83.5.236.254.ipv4.supernova.orange.pl) |
| 16:38:41 | × | nickiminjaj quits (~nickiminj@83.5.236.254.ipv4.supernova.orange.pl) (Changing host) |
| 16:38:41 | → | nickiminjaj joins (~nickiminj@user/laxhh) |
| 16:38:52 | <EvanR> | I defined a dummy type for Value a |
| 16:38:56 | <vektor> | Huh. Ok. So the moment I match a Constant x v, I get access to Show a, and can do show v... |
| 16:39:15 | <EvanR> | yes |
| 16:39:52 | <EvanR> | I guess it doesn't require GADTs after all |
| 16:39:57 | <vektor> | So with that, I can build a prettyPrinter that doesn't rely on Show a to work, because when the time comes that I need a Show a instance, I'm in your exact pattern above... |
| 16:40:15 | → | hugo joins (znc@verdigris.lysator.liu.se) |
| 16:40:28 | <ski> | as mentioned before, when you pattern-match, the constraints associated with the data constructor will be made available |
| 16:40:29 | <EvanR> | this all relies on Show |
| 16:41:16 | <EvanR> | you used it in the data type definition, you use it in the pretty printer, and whatever constructs Expr has to be working on Showable values |
| 16:41:31 | <EvanR> | at least for Constant expr |
| 16:42:01 | <EvanR> | Null doesn't need it |
| 16:42:09 | <vektor> | So I could sidestep the constraint (Show a) by just not building any Constants into the Expr... |
| 16:42:15 | → | __monty__ joins (~toonn@user/toonn) |
| 16:42:43 | <EvanR> | if you take away the constraint on stuff like Null yes |
| 16:42:53 | <vektor> | But the prettyPrinter :: Expr x a -> String does not need a Show a, because it gets that when it encounters a Constant. |
| 16:43:07 | <ski> | i guess you could provide an environment for constants |
| 16:43:09 | <vektor> | (that last one re: "this all relies on Show") |
| 16:43:53 | <EvanR> | you can and should eliminate some of these constraints to rely less on Show, since it's not doing anything for e.g. Null |
| 16:44:23 | × | vektor quits (~vektor@IP-045131036068.dynamic.medianet-world.de) (Quit: Client closed) |
| 16:45:38 | → | eggplantade joins (~Eggplanta@2600:1700:38c5:d800:b915:f992:5adb:85e) |
| 16:46:43 | → | b_jonas joins (~x@89.134.28.176) |
| 16:47:59 | → | dcoutts joins (~duncan@net77-43-75-226.mclink.it) |
| 16:50:07 | × | danse-nr3__ quits (~francesco@151.57.122.70) (Ping timeout: 264 seconds) |
| 16:51:03 | × | euleritian quits (~euleritia@dynamic-046-114-202-144.46.114.pool.telefonica.de) (Read error: Connection reset by peer) |
| 16:51:20 | → | euleritian joins (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) |
| 16:56:00 | → | tzh joins (~tzh@c-71-193-181-0.hsd1.or.comcast.net) |
| 16:56:00 | × | kuribas quits (~user@ip-188-118-57-242.reverse.destiny.be) (Remote host closed the connection) |
| 16:56:44 | × | eggplantade quits (~Eggplanta@2600:1700:38c5:d800:b915:f992:5adb:85e) (Remote host closed the connection) |
| 16:57:00 | → | eggplantade joins (~Eggplanta@2600:1700:38c5:d800:b915:f992:5adb:85e) |
| 16:57:12 | × | hugo quits (znc@verdigris.lysator.liu.se) (Ping timeout: 272 seconds) |
| 16:58:30 | × | billchenchina quits (~billchenc@2a0c:b641:7a2:230::10) (Remote host closed the connection) |
| 16:58:30 | → | cpressey joins (~cpressey@host-2-102-14-126.as13285.net) |
| 16:58:40 | × | sm quits (~sm@plaintextaccounting/sm) (Quit: sm) |
| 16:59:04 | → | danse-nr3__ joins (~francesco@151.57.122.70) |
| 17:05:34 | × | Pozyomka quits (~pyon@user/pyon) (Quit: Pozyomka, my beloved: https://i.imgur.com/BMmVfTq.png) |
| 17:06:10 | → | vektor joins (~vektor@IP-045131036068.dynamic.medianet-world.de) |
| 17:07:13 | × | eggplantade quits (~Eggplanta@2600:1700:38c5:d800:b915:f992:5adb:85e) (Remote host closed the connection) |
| 17:08:29 | → | Pozyomka joins (~pyon@user/pyon) |
| 17:10:35 | <vektor> | Huh. now I have my valMap :: (Num b, Show b) => (a->b) -> Value a -> Value b. I can't seem to find the right syntax to add those constraints to the Functor Value instance. |
| 17:11:21 | <ski> | you don't |
| 17:11:44 | <vektor> | Because it's not a functor, or because it doesn't need those constraints? |
| 17:12:30 | <ski> | `fmap :: forall a b. (a -> b) -> f a -> f b' (for some particular `f', `Value' in your case) promises to work for *all* types `a',`b', not just ones that happen to be instances of `Num' and `Show' |
| 17:13:03 | ncf | . o O ( exofunctors ) |
| 17:13:11 | <ski> | your `valMap' only (apparently) works for types `b' which are instances of `Num' and `Show' |
| 17:15:29 | → | hugo joins (znc@verdigris.lysator.liu.se) |
| 17:15:44 | <EvanR> | you said you will only ever use types a which have Num and Show instance. But fmap allows you to contradict that by possibly producing b (any b) |
| 17:15:47 | <ski> | vektor : did you add constraints on data constructors of `Value', as well ? |
| 17:16:13 | <EvanR> | even b that doesn't support Show or NUm |
| 17:16:26 | <vektor> | ski: Yeah, doing that right now. Seemed like the reasonable next step after convincing myself that prettyPrinting Expr works as intended. :) |
| 17:17:59 | <vektor> | EvanR, yeah kinda hoped if this worked truly as I intended, then fmap would basically be constrained to only working on with (Num b, Show b). |
| 17:18:08 | <EvanR> | fmap chr (MkValue 34) = ? |
| 17:18:33 | <EvanR> | how would it even work as you intended, is the thing |
| 17:18:45 | <EvanR> | I think the type system is catching a logic error here |
| 17:19:03 | <vektor> | what's ' chr' ? |
| 17:19:08 | <ski> | @type chr |
| 17:19:09 | <lambdabot> | Int -> Char |
| 17:19:10 | <ski> | > chr 34 |
| 17:19:11 | <EvanR> | maps a number to a Char |
| 17:19:12 | <lambdabot> | '"' |
| 17:19:25 | <vektor> | ahh, ok. |
| 17:19:29 | <EvanR> | using unicode |
| 17:19:32 | <ski> | > [chr n | n <- [64 .. 95]] |
| 17:19:33 | <lambdabot> | "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_" |
| 17:20:28 | <EvanR> | and Char isn't a Num |
| 17:20:38 | <vektor> | Well, I was expecting that to not type, I guess? The deeper into this rabbit hole of "just constrain the type param of this type to only work with certain types" goes, the weirder it gets. |
| 17:20:43 | × | rosco quits (~rosco@193.138.218.161) (Quit: Lost terminal) |
| 17:20:57 | <ski> | the type of `fmap' (which you can't change) ensures that it will type correctly |
| 17:21:21 | <ski> | (it promises to work for *all* types `a' and `b') |
| 17:21:52 | <EvanR> | vektor, you're right, it will only work for certain types |
| 17:22:05 | <vektor> | I mean, it isn't really that the fmap shouldn't type check, I was expecting Val Char to not type check. Like, in any context. Val Char isn't, therefore fmap chr someValue shouldn't....? |
| 17:22:07 | <ski> | result : since your `valMap' doesn't satisfy the promises that `fmap' makes, you can implement `fmap' by `valMap' |
| 17:22:21 | <ski> | er .. *can't* |
| 17:22:39 | <EvanR> | if Value is an instance of Functor, then fmap chr value does type check |
| 17:22:49 | <EvanR> | but as we see that makes no sense so it can't a Functor |
| 17:22:55 | <EvanR> | can't be |
| 17:23:21 | <ski> | vektor : "I was expecting Val Char to not type check. Like, in any context. Val Char isn't" -- which is why you can't implement `fmap' by `valMap' |
| 17:23:36 | × | Simikando quits (~Simikando@adsl-dyn158.91-127-59.t-com.sk) (Ping timeout: 260 seconds) |
| 17:24:46 | × | Square quits (~Square@user/square) (Ping timeout: 260 seconds) |
| 17:25:02 | <ski> | (because `fmap f (Val x)' is supposed to be `Val (f x)', therefore `fmap chr (Val 34)' would be `Val (chr 34)', iow `Val' applied to a `Char'. you can't prevent the user of `fmap' supplying a function `f' (namely `chr') whose result type is `Char') |
| 17:25:21 | × | Square2 quits (~Square4@user/square) (Ping timeout: 260 seconds) |
| 17:25:35 | <vektor> | Massive Is-Ought distinction here, of course. I was imagining (and I'm not convinced *yet* it can't be) a type system that just prevents types like "Value Char" from existing. Like... at a later point? You let me have my Functor Value, but when I actually use it to fmap chr, then the type systems sees that that would create (Value Char), which |
| 17:25:35 | <vektor> | violates my constraint on the type (Num a). Therefore, it breaks. |
| 17:26:27 | <EvanR> | I like how haskell is serious about the types, resulting in behavior that follows its own logic. Many languages with a type system violate their logic for reasons, making people disregard the value of logic |
| 17:26:28 | <vektor> | I get how not letting me have Functor Value upholds soundness here, but I can vaguely believe that that check could be, at least for the case I'm working with, delayed by one. |
| 17:26:30 | × | cpressey quits (~cpressey@host-2-102-14-126.as13285.net) (Quit: Client closed) |
| 17:27:10 | <EvanR> | you said you would only use types which are instances of Num |
| 17:27:19 | <EvanR> | which contradicts functor here |
| 17:27:50 | <EvanR> | so you are either saved from an error, or your original plan needs rethinking |
| 17:27:50 | <ski> | when you use `fmap chr blah', the type system only checks the types for `fmap',`chr',`blah' (and relevant instances in scope relating to types relevant to those). it does *not* check the implementation of any of `fmap',`chr',`blah' when type-checking. that would violate the interface abstraction that the type of the involved operations provides |
| 17:28:16 | <vektor> | EvanR: Re Logic: Absolutely. The reason this project is in haskell is because I wouldn't trust myself enough in python to keep this code base sane. Static guarantees are very nice indeed. |
| 17:29:38 | <EvanR> | kind of serious about the second part, for example this whole thing is about pretty printing expressions for debugging purposes. If that's the only reason for restricting to Num and Show, maybe you should step back |
| 17:29:52 | <EvanR> | maybe the parameters to Expr are more polymorphic than you thought |
| 17:30:29 | <EvanR> | putting constraints on operations not data by default leads you in that direction |
| 17:30:30 | ski | . o O ( s/polymorphic/parametric/ ) |
| 17:30:41 | <vektor> | ski: I understand that part. I understand why haskell does what it does here, but I could see a haskell that looks hat fmap chr blah and says "well, the type of that is Value Char. Value a has the constraint (Num a), and Char is not Num, therefore there's a type error here. Which means I could effectively fmap over Value only with operations f :: |
| 17:30:42 | <vektor> | (Num a, Num b) => a -> b, but it's not enforced by the fmap, but only by the resulting type. I'm well aware that's not how haskell does things. |
| 17:31:43 | <ski> | vektor : but that `chr' might be a parameter, which is only known to have type `x -> y' in this context, only in another context does `x' gets pinned down to `Int' and `y' to `Char' |
| 17:31:53 | <EvanR> | in java i would expect people to implement Functor anyway and just have it crash when someone calls in an fmap which makes no sense |
| 17:32:21 | <EvanR> | in haskell you don't let it go that far, ideally |
| 17:32:24 | <ski> | vektor : also "Char is not Num" is easily fixed (well, "fixed") |
| 17:33:56 | <ski> | @let instance Num Char where _ + _ = '+'; _ - _ = '-'; _ * _ = '*'; negate _ = '-'; abs _ = '|'; signum _ = 's'; fromInteger _ = 'n' |
| 17:33:57 | <lambdabot> | Defined. |
| 17:34:03 | <vektor> | EvanR: Yeah, I'm evaluating if I should step back and keep my code as is. The resulting trails of Show and Num everywhere are ultimately tolerable, and I'm unsure just how much technical debt I'm piling on with this change if I have to put another change onto the language. I'm coming to the conclusion that what I imagined was a simple fix isn't |
| 17:34:04 | <vektor> | so simple. |
| 17:34:05 | <ski> | there you go, `Char' is an instance of `Num' |
| 17:34:27 | → | eggplantade joins (~Eggplanta@2600:1700:38c5:d800:b915:f992:5adb:85e) |
| 17:34:37 | <vektor> | Curveball: Does it become a simple fix if I were to enumerate all possible acceptable types a? (Probably not, right?) |
| 17:34:37 | <[exa]> | ski: as an absolute bonus, (+) and (*) seem to be associative. |
| 17:34:49 | <EvanR> | vektor, actually, yes |
| 17:35:06 | <ski> | instances are OWA (Open-World Assumption), not CWA (Closed-World Assumption) (these are logic programming terminology. type classes are related to logic programming). you can't ensure noone won't later make a type an instance of a class |
| 17:36:09 | <vektor> | [exa] and while negate negate x =/= x, at least negate x == negate negate negate x. That's not too bad. |
| 17:36:43 | <EvanR> | implementing Num for Char just means you need to come up with another example re: Functor |
| 17:37:10 | <EvanR> | and there's no way to implement Num for literally all types |
| 17:37:15 | <ski> | [exa] : but distributive law fails .. dang |
| 17:37:18 | <vektor> | logic programming. Another field this small project of mine interfaces with that I understand not nearly enough of. Beyond the, ohh, half a dozen other computer science fields that the project interacts with, lol. |
| 17:37:43 | × | euleritian quits (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Ping timeout: 258 seconds) |
| 17:38:07 | <ski> | LP is a lovely paradigm |
| 17:38:20 | → | euleritian joins (~euleritia@dynamic-046-114-202-144.46.114.pool.telefonica.de) |
| 17:38:24 | ski | 's recently been reading about ordered linear logic programming |
| 17:39:43 | <vektor> | Now that I think about it, logic programming is probably, out of all the fields I should be knowing more about, the one field my project doesn't directly interface with, just kinda compete with in a way. Well, a flavor of logic programming anyway. |
| 17:39:52 | <ski> | vektor : just in case you didn't know, inference rules in type systems are basically logic programming clauses (rules and facts), making up a logic program (although it might not be to useful to execute, at least naively, depending) |
| 17:40:31 | → | L29Ah joins (~L29Ah@wikipedia/L29Ah) |
| 17:41:02 | <vektor> | When I was looking into type inference (the x in Expr x a is for type elaborations) I think I remember seeing a talk about someone who did exactly that; doing type inference as a logic program. |
| 17:41:02 | × | mc47 quits (~mc47@xmonad/TheMC47) (Remote host closed the connection) |
| 17:41:34 | <ski> | apart from the connection between type classes & instances and predicates & clauses that i already mentioned above |
| 17:42:18 | <vektor> | ski: Shouldn't it then be possible to simply assert "Value Char isn't" in that logic program and be done with it, making my vision of Utopia from above viable? It'd break anytime you fmap with something funny, but work as long as the fmap is from Num to Num. |
| 17:42:20 | <EvanR> | vektor, ok, maybe it's not so simple. But if you are thinking there are only 3 possible a, you can define data ConcreteExpr a where AExpr :: Expr A -> ConcreteExpr A; BExpr :: Expr B -> ConcreteExpr B; CExpr :: Expr C -> ConcreteExpr C, then ConcreteExpr a can only exist at those three types |
| 17:43:21 | <ski> | vektor : in case you're interested, i could suggest a couple of papers |
| 17:43:21 | <EvanR> | if A B and C are Num and Show, then functions on ConcreteExpr obviously know that |
| 17:43:22 | <ski> | @where polymorphic-type-inference |
| 17:43:22 | <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> |
| 17:43:25 | <ski> | @where on-understanding |
| 17:43:25 | <lambdabot> | "On Understanding Types, Data Abstraction, and Polymorphism" by Luca Cardelli,Peter Wegner in 1985-12 at <http://lucacardelli.name/Papers/OnUnderstanding.A4.pdf> |
| 17:43:27 | <vektor> | EvanR: Why do I have the feeling this sounds nice in a minimally working example, but is horrible once my 20 constructors of Expr get involved? :O |
| 17:43:29 | <ski> | @where on-understanding-revisited |
| 17:43:29 | <lambdabot> | "On Understanding Data Abstraction, Revisited" by William R. Cook in 2009-10 at <http://www.cs.utexas.edu/~wcook/Drafts/2009/essay.pdf> |
| 17:44:12 | <EvanR> | vektor, it's wrapping the large parameterized Expr type, not duplicating. But yes it could get hairy for other reasons. And you really lose out on generic programming that the usual way does by default |
| 17:44:18 | <vektor> | ski, my supervisor's reading 'recommendations' take precedence before yours, FYI. :) |
| 17:44:22 | <ski> | vektor : "the x in Expr x a is for type elaborations" -- yea, that's why i mentioned DecoratingStructures (and IndirectComposite), one and a half hour ago |
| 17:44:36 | <ski> | vektor : fair enough :D |
| 17:45:29 | <ski> | vektor : "Shouldn't it then be possible to simply assert \"Value Char isn't\" in that logic program" -- no, because it's OWA, doesn't deal in negative knowledge. knowledge can only be ("monotonically") added, not subtracted |
| 17:45:54 | <vektor> | Right, right. |
| 17:46:00 | ski | sees EvanR's suggesting real GADTs now |
| 17:46:01 | <vektor> | Did I mention I should know more about logic programming? |
| 17:46:14 | <vektor> | > * ski sees EvanR's suggesting real GADTs now |
| 17:46:14 | <vektor> | Lol |
| 17:46:15 | <lambdabot> | <hint>:1:1: error: parse error on input ‘*’ |
| 17:46:41 | <vektor> | quoting, not prompting, ya tin can. |
| 17:46:54 | <EvanR> | GADT LIFE |
| 17:46:59 | ski | can teen |
| 17:47:22 | → | Simikando joins (~Simikando@adsl-dyn158.91-127-59.t-com.sk) |
| 17:48:01 | <ski> | vektor : anyway, i happen to think the first paper above, by Schwartzbach, is a relatively soft intro to the basics of type inference. it for sure helped me a lot when i started learning about all this, years ago, all on my own |
| 17:48:05 | × | euleritian quits (~euleritia@dynamic-046-114-202-144.46.114.pool.telefonica.de) (Read error: Connection reset by peer) |
| 17:48:43 | → | euleritian joins (~euleritia@dynamic-046-114-202-144.46.114.pool.telefonica.de) |
| 17:49:46 | <vektor> | I've gotten most of Stephen Diehl's WriteYouAHaskell done already one way or another. Well, the parts that are published anyway. Some gaping holes there, and I'm doing some *unusual* things that don't fit neatly into an HM algorithm. |
| 17:49:53 | <vektor> | But I'll be sure to give it a look. |
| 17:52:17 | <[exa]> | vektor: "unusual things" ? |
| 17:52:22 | × | Simikando quits (~Simikando@adsl-dyn158.91-127-59.t-com.sk) (Ping timeout: 252 seconds) |
| 17:52:24 | <[exa]> | (/me curious) |
| 17:53:28 | <vektor> | My IRC chat indicates we DM'd before, so I'm pretty sure your curiosity has been fed to a degree a while back. :D |
| 17:53:34 | × | dcoutts quits (~duncan@net77-43-75-226.mclink.it) (Ping timeout: 272 seconds) |
| 17:55:03 | × | nickiminjaj quits (~nickiminj@user/laxhh) (Quit: My MacBook has gone to sleep. ZZZzzz…) |
| 17:55:24 | <vektor> | s/chat/client |
| 17:59:27 | × | danse-nr3__ quits (~francesco@151.57.122.70) (Ping timeout: 240 seconds) |
| 17:59:31 | <ski> | vektor : your `Expr' suggests you may be doing something with stochastic distributions ? |
| 17:59:57 | × | m1dnight quits (~christoph@78-22-4-67.access.telenet.be) (Quit: WeeChat 4.0.5) |
| 18:00:15 | → | m1dnight joins (~christoph@78-22-4-67.access.telenet.be) |
| 18:00:33 | → | dcoutts joins (~duncan@net77-43-75-226.mclink.it) |
| 18:00:37 | <vektor> | That's correct. |
| 18:01:36 | <EvanR> | vektor, if you derive Generic, then several pretty printer libraries will just work. Or you can make your own which uses Generic |
| 18:01:45 | <EvanR> | might be a shortcut |
| 18:03:29 | → | Simikando joins (~Simikando@adsl-dyn158.91-127-59.t-com.sk) |
| 18:07:47 | × | fendor quits (~fendor@2a02:8388:1640:be00:aab:1226:f274:5021) (Remote host closed the connection) |
| 18:09:54 | ← | L29Ah parts (~L29Ah@wikipedia/L29Ah) () |
| 18:10:54 | × | falafel quits (~falafel@62.175.113.194.dyn.user.ono.com) (Ping timeout: 245 seconds) |
| 18:11:07 | × | TimWolla quits (~timwolla@2a01:4f8:150:6153:beef::6667) (Ping timeout: 264 seconds) |
| 18:16:33 | → | __monty_1 joins (~toonn@user/toonn) |
| 18:16:49 | × | stiell_ quits (~stiell@gateway/tor-sasl/stiell) (*.net *.split) |
| 18:16:49 | × | gmg quits (~user@user/gehmehgeh) (*.net *.split) |
| 18:16:49 | × | FinnElija quits (~finn_elij@user/finn-elija/x-0085643) (*.net *.split) |
| 18:16:49 | × | chexum quits (~quassel@gateway/tor-sasl/chexum) (*.net *.split) |
| 18:16:49 | × | bitdex quits (~bitdex@gateway/tor-sasl/bitdex) (*.net *.split) |
| 18:16:49 | × | adanwan_ quits (~adanwan@gateway/tor-sasl/adanwan) (*.net *.split) |
| 18:16:49 | × | ChaiTRex quits (~ChaiTRex@user/chaitrex) (*.net *.split) |
| 18:16:49 | × | ec quits (~ec@gateway/tor-sasl/ec) (*.net *.split) |
| 18:16:49 | × | califax quits (~califax@user/califx) (*.net *.split) |
| 18:16:49 | × | chiselfuse quits (~chiselfus@user/chiselfuse) (*.net *.split) |
| 18:16:50 | × | vektor quits (~vektor@IP-045131036068.dynamic.medianet-world.de) (*.net *.split) |
| 18:18:13 | × | __monty__ quits (~toonn@user/toonn) (Ping timeout: 252 seconds) |
| 18:18:58 | × | Simikando quits (~Simikando@adsl-dyn158.91-127-59.t-com.sk) (Quit: Leaving) |
| 18:25:38 | × | dcoutts quits (~duncan@net77-43-75-226.mclink.it) (Ping timeout: 258 seconds) |
| 18:28:55 | × | phma quits (phma@2001:5b0:211b:9d88:b368:1baa:7a2:22b7) (Read error: Connection reset by peer) |
| 18:29:56 | → | phma joins (phma@2001:5b0:210b:f338:ff94:b91f:1e4:46fd) |
| 18:33:17 | → | Tuplanolla joins (~Tuplanoll@91-159-68-236.elisa-laajakaista.fi) |
| 18:35:28 | → | TimWolla joins (~timwolla@2a01:4f8:150:6153:beef::6667) |
| 18:37:29 | × | chele quits (~chele@user/chele) (Remote host closed the connection) |
| 18:37:59 | × | michalz quits (~michalz@185.246.207.221) (Ping timeout: 255 seconds) |
| 18:40:15 | → | michalz joins (~michalz@185.246.207.217) |
| 18:46:47 | → | L29Ah joins (~L29Ah@wikipedia/L29Ah) |
| 18:50:29 | → | Pickchea joins (~private@user/pickchea) |
| 18:53:31 | × | eggplantade quits (~Eggplanta@2600:1700:38c5:d800:b915:f992:5adb:85e) (Remote host closed the connection) |
| 18:53:53 | → | nate2 joins (~nate@c-98-45-169-16.hsd1.ca.comcast.net) |
| 18:55:30 | × | moni_ quits (~moni@cpe-174-106-185-141.ec.res.rr.com) (Remote host closed the connection) |
| 18:58:49 | × | nate2 quits (~nate@c-98-45-169-16.hsd1.ca.comcast.net) (Ping timeout: 255 seconds) |
| 19:02:05 | → | nickiminjaj joins (~nickiminj@83.5.236.254.ipv4.supernova.orange.pl) |
| 19:02:05 | × | nickiminjaj quits (~nickiminj@83.5.236.254.ipv4.supernova.orange.pl) (Changing host) |
| 19:02:05 | → | nickiminjaj joins (~nickiminj@user/laxhh) |
| 19:07:10 | → | ft joins (~ft@p3e9bc680.dip0.t-ipconnect.de) |
| 19:08:27 | × | euleritian quits (~euleritia@dynamic-046-114-202-144.46.114.pool.telefonica.de) (Read error: Connection reset by peer) |
| 19:08:44 | → | euleritian joins (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) |
| 19:12:28 | × | nickiminjaj quits (~nickiminj@user/laxhh) (Quit: Textual IRC Client: www.textualapp.com) |
| 19:14:57 | → | vektor joins (~vektor@IP-045131036068.dynamic.medianet-world.de) |
| 19:15:59 | → | eggplantade joins (~Eggplanta@2600:1700:38c5:d800:b915:f992:5adb:85e) |
| 19:16:54 | × | vektor quits (~vektor@IP-045131036068.dynamic.medianet-world.de) (Client Quit) |
| 19:26:04 | → | azimut joins (~azimut@gateway/tor-sasl/azimut) |
| 19:29:08 | → | harveypwca joins (~harveypwc@2601:246:c280:6a90:837d:db39:3eea:f7db) |
| 19:34:07 | × | eggplantade quits (~Eggplanta@2600:1700:38c5:d800:b915:f992:5adb:85e) (Remote host closed the connection) |
| 19:36:21 | → | machinedgod joins (~machinedg@d198-53-218-113.abhsia.telus.net) |
| 19:49:03 | → | califax joins (~califax@user/califx) |
| 19:52:27 | × | bjobjo quits (~bjobjo@user/bjobjo) (Quit: leaving) |
| 19:54:59 | → | CiaoSen joins (~Jura@2a05:5800:2b2:8d00:664b:f0ff:fe37:9ef) |
| 19:56:36 | → | ChaiTRex joins (~ChaiTRex@user/chaitrex) |
| 19:58:34 | → | chiselfuse joins (~chiselfus@user/chiselfuse) |
| 19:59:13 | → | ec joins (~ec@gateway/tor-sasl/ec) |
| 19:59:21 | → | stiell_ joins (~stiell@gateway/tor-sasl/stiell) |
| 19:59:27 | → | FinnElija joins (~finn_elij@user/finn-elija/x-0085643) |
| 20:00:11 | → | bitdex joins (~bitdex@gateway/tor-sasl/bitdex) |
| 20:04:10 | → | gmg joins (~user@user/gehmehgeh) |
| 20:05:04 | × | Inst quits (~Inst@120.244.192.250) (Ping timeout: 245 seconds) |
| 20:07:59 | × | ski quits (~ski@88.131.7.247) (Ping timeout: 258 seconds) |
| 20:09:12 | → | eggplantade joins (~Eggplanta@2600:1700:38c5:d800:b915:f992:5adb:85e) |
| 20:13:32 | × | eggplantade quits (~Eggplanta@2600:1700:38c5:d800:b915:f992:5adb:85e) (Ping timeout: 248 seconds) |
| 20:16:34 | × | vglfr quits (~vglfr@88.155.159.184) (Read error: Connection reset by peer) |
| 20:16:54 | → | vglfr joins (vglfr@gateway/vpn/protonvpn/vglfr) |
| 20:20:50 | × | Unicorn_Princess quits (~Unicorn_P@user/Unicorn-Princess/x-3540542) (Remote host closed the connection) |
| 20:22:21 | × | idgaen quits (~idgaen@2a01:e0a:498:fd50:fcc6:bb5d:489a:ce8c) (Quit: WeeChat 4.0.5) |
| 20:26:53 | × | zenstoic quits (uid461840@id-461840.hampstead.irccloud.com) (Quit: Connection closed for inactivity) |
| 20:28:50 | × | asivitz quits (uid178348@id-178348.tinside.irccloud.com) (Quit: Connection closed for inactivity) |
| 20:28:55 | → | Inst joins (~Inst@120.244.192.250) |
| 20:32:44 | × | vglfr quits (vglfr@gateway/vpn/protonvpn/vglfr) (Ping timeout: 255 seconds) |
| 20:37:07 | × | euleritian quits (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Read error: Connection reset by peer) |
| 20:37:28 | → | euleritian joins (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) |
| 20:44:32 | × | takuan quits (~takuan@178-116-218-225.access.telenet.be) (Remote host closed the connection) |
| 20:47:09 | __monty_1 | is now known as __monty__ |
| 20:47:25 | × | __monty__ quits (~toonn@user/toonn) (Quit: leaving) |
| 20:48:03 | → | vglfr joins (~vglfr@88.155.159.184) |
| 20:50:38 | × | oo_miguel quits (~Thunderbi@78-11-179-96.static.ip.netia.com.pl) (Ping timeout: 255 seconds) |
| 20:57:10 | × | Jackneill quits (~Jackneill@20014C4E1E0E6F00DA1379EF70CDB149.dsl.pool.telekom.hu) (Ping timeout: 252 seconds) |
| 21:02:30 | × | michalz quits (~michalz@185.246.207.217) (Remote host closed the connection) |
| 21:04:40 | → | shapr joins (~user@2600:1700:c640:3100:70ed:821a:ab80:9f0d) |
| 21:09:02 | × | _ht quits (~Thunderbi@28-52-174-82.ftth.glasoperator.nl) (Quit: _ht) |
| 21:09:05 | → | eggplantade joins (~Eggplanta@2600:1700:38c5:d800:b915:f992:5adb:85e) |
| 21:10:12 | → | Vajb joins (~Vajb@207.61.167.122) |
| 21:10:27 | × | tromp quits (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Read error: Connection reset by peer) |
| 21:10:49 | → | jmdaemon joins (~jmdaemon@user/jmdaemon) |
| 21:11:02 | × | Vajb quits (~Vajb@207.61.167.122) (Read error: Connection reset by peer) |
| 21:11:11 | → | Vajb joins (~Vajb@207.61.167.122) |
| 21:15:27 | → | logothesia joins (~logothesi@user/logothesia) |
| 21:15:39 | ← | logothesia parts (~logothesi@user/logothesia) () |
| 21:19:25 | → | mvk joins (~mvk@2607:fea8:5c9a:a600::900d) |
| 21:19:28 | × | mvk quits (~mvk@2607:fea8:5c9a:a600::900d) (Client Quit) |
| 21:21:05 | × | acidjnk_new quits (~acidjnk@p200300d6e72b937894bacaba5afcc7b7.dip0.t-ipconnect.de) (Ping timeout: 240 seconds) |
| 21:26:25 | × | jmdaemon quits (~jmdaemon@user/jmdaemon) (Ping timeout: 255 seconds) |
| 21:32:34 | × | harveypwca quits (~harveypwc@2601:246:c280:6a90:837d:db39:3eea:f7db) (Quit: Leaving) |
| 21:38:44 | → | falafel joins (~falafel@62.175.113.194.dyn.user.ono.com) |
| 21:39:01 | × | euleritian quits (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Ping timeout: 255 seconds) |
| 21:39:47 | → | euleritian joins (~euleritia@dynamic-046-114-202-144.46.114.pool.telefonica.de) |
| 21:46:41 | × | Pickchea quits (~private@user/pickchea) (Quit: Leaving) |
| 21:51:33 | → | sm joins (~sm@plaintextaccounting/sm) |
| 21:52:10 | → | jmdaemon joins (~jmdaemon@user/jmdaemon) |
| 21:57:07 | × | gmg quits (~user@user/gehmehgeh) (Quit: Leaving) |
| 21:59:32 | → | pavonia joins (~user@user/siracusa) |
| 21:59:49 | → | Guest|69 joins (~Guest|69@rn-nat-129-97-131-0.dynamic.uwaterloo.ca) |
| 21:59:57 | × | Guest|69 quits (~Guest|69@rn-nat-129-97-131-0.dynamic.uwaterloo.ca) (Client Quit) |
| 22:00:39 | → | mikoto-chan joins (~mikoto-ch@ip-212-239-236-59.dsl.scarlet.be) |
| 22:00:58 | × | jmdaemon quits (~jmdaemon@user/jmdaemon) (Ping timeout: 252 seconds) |
| 22:07:57 | × | sm quits (~sm@plaintextaccounting/sm) (Quit: sm) |
| 22:08:13 | → | stuu22 joins (~stuuu@2a01:c22:8486:1800:1511:8706:c3e7:eb57) |
| 22:10:05 | <stuu22> | hi, i have a stream of osc-messages. when i get the message "rec" i want to start making a list of all following messages until i get "stop". i want to use concurrency with forkIO.. any tips on how to handle the "rec"/"stop" thing? i had no luck with mvar so far |
| 22:10:52 | <stuu22> | without forkIO i had a working approach. but it is too slow then and messages get lost |
| 22:13:59 | → | Sgeo joins (~Sgeo@user/sgeo) |
| 22:16:26 | <Rembane> | stuu22: How many messages per time unit are we talking? |
| 22:18:10 | × | falafel quits (~falafel@62.175.113.194.dyn.user.ono.com) (Ping timeout: 255 seconds) |
| 22:18:17 | <stuu22> | hundreds i would say |
| 22:18:38 | <Rembane> | How big are they? |
| 22:18:39 | <ncf> | how many time units per hundred messages are we talking |
| 22:19:00 | <ncf> | or how many seconds per time unit i guess |
| 22:19:47 | <c_wraith> | If you just want to queue events for another thread to handle and aren't worried about memory use, Chan is the quick and easy answer. |
| 22:20:07 | <c_wraith> | If you *are* concerned about memory use while keeping up with a real-time stream... you're going to need some clever stuff.; |
| 22:20:21 | <stuu22> | it is TUIO so bundled osc messages, i track every finger joint of two hands |
| 22:20:40 | → | danza joins (~francesco@151.43.99.161) |
| 22:21:40 | <stuu22> | when my "rec" message is received i want to extract the values of the TUIO messages, store them in a list and re-send them to another application. |
| 22:21:51 | <c_wraith> | Try Control.Concurrent.Chan. If your consumers can't keep up, you're going to need to try buffering strategies. |
| 22:21:59 | <stuu22> | when i tried receiving without concurrency mmessages got lost |
| 22:22:38 | <stuu22> | okay! will have to read through it, as if you probably guessed: i am not a pro :) |
| 22:23:40 | <c_wraith> | fortunately it's a very small API. :) |
| 22:25:25 | <monochrom> | Ha! Applicative is a pretty small API too. Then everyone is confused. >:) |
| 22:25:32 | <stuu22> | i do wonder though about MVars, as they are kind of mutable? seems to go a bit against the overall concept. |
| 22:26:07 | × | troydm quits (~troydm@user/troydm) (Ping timeout: 264 seconds) |
| 22:26:20 | <c_wraith> | The trick with mutability in haskell is that it's not *functions* that cause it. |
| 22:26:27 | <c_wraith> | So functions remain pure |
| 22:26:41 | <c_wraith> | It's other stuff (*glares at IO*) that does the mutability |
| 22:27:34 | <stuu22> | but "even" once assigned variables in IO are immutable arent they? |
| 22:27:41 | <c_wraith> | variables are. |
| 22:27:52 | <c_wraith> | But a reference is a value, not a variable |
| 22:28:05 | <c_wraith> | You can change what the reference points to without changing any variable |
| 22:28:20 | <monochrom> | IORef and MVar are mutable. Sure, the "x = 0" kind of "variable" aren't. |
| 22:28:24 | <c_wraith> | (looking at the new contents requires an IO action) |
| 22:29:09 | <stuu22> | so MVar is the reference i point to different values? |
| 22:29:30 | <c_wraith> | Yes. |
| 22:29:38 | <c_wraith> | Something like Chan is a linked list of MVars |
| 22:30:32 | <c_wraith> | relatively easy to implement (for something that needs to deal with concurrent use), relatively simple to use.. But definitely not the fastest thing in the world. |
| 22:31:12 | → | waleee joins (~waleee@2001:9b0:21c:e600:f2f3:f744:435d:137c) |
| 22:32:42 | <stuu22> | ok, i dont think it has to be c-level fast. but actually the stored messages dont need to be MVar's. I do think more about a state that changes from "rec" to "stop" and back and forth. so while listening to messages via threads i just have to do different things during different states? |
| 22:33:52 | <c_wraith> | I was thinking of splitting more like - have one thread watch the input. When it sees a rec, start writing to a Chan until it sees a stop. Then another thread will read from the Chan and do whatever processing it needs to. |
| 22:34:22 | <c_wraith> | There are a *lot* of minor variations possible on this, depending on how you want to signal between threads. |
| 22:35:25 | <c_wraith> | But the main idea is to have one thread receiving events and queuing them if needed, then a second thread to process the queued events. |
| 22:36:39 | <stuu22> | thanks a lot! i hope i get it to work :) |
| 22:37:04 | <c_wraith> | ... and then there's the extra detail that you probably need to compile with the threaded runtime and then run it with multiple cores. Those aren't hard, but they're extra steps. |
| 22:37:59 | × | mikoto-chan quits (~mikoto-ch@ip-212-239-236-59.dsl.scarlet.be) (Ping timeout: 245 seconds) |
| 22:39:14 | <stuu22> | the more i think about this i dont get why i need the threads. in python with python-osc library it worked very good without threads (except python-osc uses some under the hood). but with hosc i had a huge package loss |
| 22:39:27 | <stuu22> | same with Max and Pure Data |
| 22:39:36 | → | jmdaemon joins (~jmdaemon@user/jmdaemon) |
| 22:40:12 | <c_wraith> | It probably comes down to vagaries of the stop-the-world garbage collector. |
| 22:40:40 | <c_wraith> | who knows? Maybe if you switch to the concurrent collector you can do it with only one thread. That might be worth a try. |
| 22:42:01 | × | Vajb quits (~Vajb@207.61.167.122) (Ping timeout: 255 seconds) |
| 22:42:06 | <stuu22> | fancy tip! |
| 22:48:28 | × | Maxdamantus quits (~Maxdamant@user/maxdamantus) (Ping timeout: 255 seconds) |
| 22:54:21 | × | danza quits (~francesco@151.43.99.161) (Ping timeout: 258 seconds) |
| 22:56:18 | × | waleee quits (~waleee@2001:9b0:21c:e600:f2f3:f744:435d:137c) (Ping timeout: 272 seconds) |
| 22:58:26 | → | waleee joins (~waleee@2001:9b0:21c:e600:f2f3:f744:435d:137c) |
| 23:06:53 | × | jmdaemon quits (~jmdaemon@user/jmdaemon) (Read error: Connection reset by peer) |
| 23:09:43 | × | Inst quits (~Inst@120.244.192.250) (Ping timeout: 252 seconds) |
| 23:12:59 | × | waleee quits (~waleee@2001:9b0:21c:e600:f2f3:f744:435d:137c) (Ping timeout: 245 seconds) |
| 23:18:47 | × | machinedgod quits (~machinedg@d198-53-218-113.abhsia.telus.net) (Ping timeout: 255 seconds) |
| 23:23:10 | → | waleee joins (~waleee@2001:9b0:21c:e600:f2f3:f744:435d:137c) |
| 23:32:25 | → | Inst joins (~Inst@120.244.192.250) |
| 23:34:22 | → | troydm joins (~troydm@user/troydm) |
| 23:37:31 | × | stuu22 quits (~stuuu@2a01:c22:8486:1800:1511:8706:c3e7:eb57) (Quit: Leaving) |
| 23:39:05 | × | CiaoSen quits (~Jura@2a05:5800:2b2:8d00:664b:f0ff:fe37:9ef) (Ping timeout: 240 seconds) |
All times are in UTC on 2023-10-18.