Logs on 2024-11-14 (liberachat/#haskell)
| 00:01:19 | × | falafel quits (~falafel@2600:1700:99f4:2050:41b3:d17e:817a:4e83) (Ping timeout: 260 seconds) |
| 00:10:06 | × | acidjnk_new3 quits (~acidjnk@p200300d6e7283f717cba866c0fa9f7cd.dip0.t-ipconnect.de) (Read error: Connection reset by peer) |
| 00:10:17 | → | alexherbo2 joins (~alexherbo@2a02-8440-3117-f07c-987b-fc29-77ee-addd.rev.sfr.net) |
| 00:11:02 | <Leary> | jackdk: I doubt there's anything like an 'idiom' for this. Does `class HasField f r (Field f r) => HasFieldF f r where { type Field f r }; instance HasField f r t => HasFieldF f r where { type Field f r = t }` work? |
| 00:14:53 | × | Tuplanolla quits (~Tuplanoll@91-159-69-59.elisa-laajakaista.fi) (Quit: Leaving.) |
| 00:16:38 | × | Lord_of_Life quits (~Lord@user/lord-of-life/x-2819915) (Ping timeout: 245 seconds) |
| 00:17:43 | <glguy> | jackdk: You could do something like this: https://bpa.st/AYDQ |
| 00:18:38 | → | Lord_of_Life joins (~Lord@user/lord-of-life/x-2819915) |
| 00:20:20 | × | arahael quits (~arahael@user/arahael) (Quit: Lost terminal) |
| 00:25:58 | × | sprotte24 quits (~sprotte24@p200300d16f059400e8d39b8ffa006815.dip0.t-ipconnect.de) (Quit: Leaving) |
| 00:26:14 | × | xff0x quits (~xff0x@2405:6580:b080:900:ca42:e655:d7e4:ec2b) (Ping timeout: 272 seconds) |
| 00:32:10 | × | peterbecich quits (~Thunderbi@syn-047-229-123-186.res.spectrum.com) (Ping timeout: 252 seconds) |
| 00:35:18 | <jackdk> | Leary: alas no: "The RHS of an associated type declaration mentions out-of-scope variable ‘t’ All such variables must be bound on the LHS"; glguy: Yeah, recursing through the `Rep` seems like the best bet. Thanks to you both. |
| 00:36:34 | × | MironZ3 quits (~MironZ@nat-infra.ehlab.uk) (Quit: Ping timeout (120 seconds)) |
| 00:36:34 | → | Square joins (~Square@user/square) |
| 00:39:10 | × | tromp quits (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Read error: Connection reset by peer) |
| 00:43:55 | → | MironZ3 joins (~MironZ@nat-infra.ehlab.uk) |
| 00:44:15 | → | ljdarj1 joins (~Thunderbi@user/ljdarj) |
| 00:47:34 | × | ljdarj quits (~Thunderbi@user/ljdarj) (Ping timeout: 265 seconds) |
| 00:47:34 | ljdarj1 | is now known as ljdarj |
| 00:48:46 | × | athostFI quits (~Atte@176-93-56-50.bb.dnainternet.fi) (Read error: Connection reset by peer) |
| 00:49:48 | <jle`> | does anybody know if there has been any updates on https://github.com/haskell/cabal/issues/9577 ? is there a good way to get haddock to do multiple sublibraries? |
| 00:50:03 | <glguy> | getting ready for aoc? ;-) |
| 00:51:19 | <geekosaur> | https://github.com/haskell/cabal/pull/9821 maybe? |
| 00:51:52 | <jle`> | glguy: heh how did you guess |
| 00:52:04 | <jle`> | i am merging all of my aoc libs into a single master cabal project |
| 00:52:14 | <glguy> | jle`: I can't think of any other reason to use multiple sublibraries ^_^ |
| 00:52:38 | <geekosaur> | amazonka and recent HLS use them |
| 00:52:59 | <geekosaur> | HLS for all its plugins, amazonka for all its generated service packages |
| 00:53:06 | <glguy> | geekosaur: Maybe someone used those libraries to solve an aoc problem then |
| 00:53:09 | <Leary> | jle`: There's some discussion on it here: https://discourse.haskell.org/t/best-practices-for-public-cabal-sublibraries/10272 |
| 00:53:26 | <jle`> | geekosaur: ah that does seem promising, do you know if it's in any cabal releases? |
| 00:54:06 | <geekosaur> | not yet but it should be in 3.14.1.0 |
| 00:54:16 | <geekosaur> | which is due around when ghc 9.12.1 GA is |
| 00:54:32 | <jle`> | ooh, that's in a matter of days right? |
| 00:54:36 | <geekosaur> | the release process has already begun |
| 00:54:47 | <jle`> | woo hoo |
| 00:55:19 | <jle`> | rate of cabal improvements has been amazing |
| 01:14:21 | → | peterbecich joins (~Thunderbi@syn-047-229-123-186.res.spectrum.com) |
| 01:18:56 | → | xff0x joins (~xff0x@fsb6a9491c.tkyc517.ap.nuro.jp) |
| 01:21:07 | × | ljdarj quits (~Thunderbi@user/ljdarj) (Quit: ljdarj) |
| 01:27:07 | × | CrunchyFlakes_ quits (~CrunchyFl@ip1f13e94e.dynamic.kabel-deutschland.de) (Ping timeout: 264 seconds) |
| 01:28:51 | × | yin quits (~z@user/zero) (Read error: Connection reset by peer) |
| 01:29:30 | → | zero joins (~z@user/zero) |
| 01:33:06 | × | califax quits (~califax@user/califx) (Remote host closed the connection) |
| 01:43:43 | → | califax joins (~califax@user/califx) |
| 01:45:51 | → | jero98772 joins (~jero98772@190.158.28.32) |
| 01:47:45 | × | telser quits (~quassel@user/telser) (Quit: https://quassel-irc.org - Chat comfortably. Anywhere.) |
| 01:55:16 | × | jero98772 quits (~jero98772@190.158.28.32) (Ping timeout: 244 seconds) |
| 02:00:23 | × | housemate quits (~housemate@146.70.66.228) (Quit: "I saw it in a tiktok video and thought that it was the most smartest answer ever." ~ AnonOps Radio [some time some place] | I AM THE DERIVATIVE I AM GOING TANGENT TO THE CURVE!) |
| 02:13:26 | → | Smiles joins (uid551636@id-551636.lymington.irccloud.com) |
| 02:14:45 | × | machinedgod quits (~machinedg@d108-173-18-100.abhsia.telus.net) (Ping timeout: 246 seconds) |
| 02:30:17 | → | myxos joins (~myxos@syn-065-028-251-121.res.spectrum.com) |
| 03:06:25 | × | alexherbo2 quits (~alexherbo@2a02-8440-3117-f07c-987b-fc29-77ee-addd.rev.sfr.net) (Remote host closed the connection) |
| 03:13:00 | → | arahael joins (~arahael@user/arahael) |
| 03:16:04 | → | arahael_ joins (~arahael@user/arahael) |
| 03:29:59 | × | td_ quits (~td@i53870901.versanet.de) (Ping timeout: 260 seconds) |
| 03:31:21 | → | td_ joins (~td@i5387092A.versanet.de) |
| 03:46:17 | × | Pozyomka quits (~pyon@user/pyon) (Quit: Reboot.) |
| 03:52:54 | → | agent314 joins (~quassel@static-198-44-129-53.cust.tzulo.com) |
| 04:09:25 | → | bitdex joins (~bitdex@gateway/tor-sasl/bitdex) |
| 04:10:33 | × | agent314 quits (~quassel@static-198-44-129-53.cust.tzulo.com) (Ping timeout: 276 seconds) |
| 04:12:25 | → | divya joins (~user@139.5.11.223) |
| 04:19:01 | → | mange joins (~user@user/mange) |
| 04:19:01 | × | mange quits (~user@user/mange) (Excess Flood) |
| 04:25:13 | × | mc47 quits (~mc47@xmonad/TheMC47) (Remote host closed the connection) |
| 04:25:33 | → | mc47 joins (~mc47@xmonad/TheMC47) |
| 04:27:30 | × | divya quits (~user@139.5.11.223) (Remote host closed the connection) |
| 04:30:03 | → | Pozyomka joins (~pyon@user/pyon) |
| 04:30:40 | → | mange joins (~user@user/mange) |
| 04:31:26 | × | mange quits (~user@user/mange) (Client Quit) |
| 04:32:37 | × | pavonia quits (~user@user/siracusa) (Quit: Bye!) |
| 04:36:48 | → | housemate joins (~housemate@146.70.66.228) |
| 04:37:01 | × | stiell_ quits (~stiell@gateway/tor-sasl/stiell) (Ping timeout: 260 seconds) |
| 04:41:15 | → | stiell_ joins (~stiell@gateway/tor-sasl/stiell) |
| 04:54:07 | → | vanishingideal joins (~vanishing@user/vanishingideal) |
| 05:06:35 | × | mikko quits (~mikko@user/mikko) (Ping timeout: 255 seconds) |
| 05:13:50 | → | agent314 joins (~quassel@static-198-44-129-53.cust.tzulo.com) |
| 05:14:44 | → | visilii_ joins (~visilii@213.24.127.47) |
| 05:14:54 | × | visilii quits (~visilii@213.24.133.209) (Ping timeout: 276 seconds) |
| 05:36:59 | → | Guest16 joins (~Guest16@2401:4900:65c9:bca3:883d:d42c:cc19:7f95) |
| 05:37:48 | <Guest16> | hi |
| 05:37:56 | <Guest16> | Does anyone know why http://wiki.haskell.org/ is down |
| 05:39:54 | <Axman6> | There's been issues with the machine it runs on lately, which I believe are proving to be quite hard to fix. sm I think knows more (there's also #haskell-infrastructure) |
| 05:41:03 | <probie> | Guest16: https://mail.haskell.org/pipermail/haskell-cafe/2024-November/136929.html |
| 05:41:44 | <Guest16> | thank you |
| 05:52:22 | × | peterbecich quits (~Thunderbi@syn-047-229-123-186.res.spectrum.com) (Remote host closed the connection) |
| 05:52:41 | × | Guest16 quits (~Guest16@2401:4900:65c9:bca3:883d:d42c:cc19:7f95) (Quit: Client closed) |
| 05:58:06 | → | takuan joins (~takuan@178-116-218-225.access.telenet.be) |
| 06:00:42 | <haskellbridge> | <sm> https://github.com/haskell/haskell-wiki-configuration/issues/43 |
| 06:02:55 | → | misterfish joins (~misterfis@84.53.85.146) |
| 06:04:06 | → | michalz joins (~michalz@185.246.207.203) |
| 06:08:06 | × | philopsos quits (~caecilius@user/philopsos) (Quit: Lost terminal) |
| 06:08:12 | → | peterbecich joins (~Thunderbi@syn-047-229-123-186.res.spectrum.com) |
| 06:12:25 | × | Smiles quits (uid551636@id-551636.lymington.irccloud.com) (Quit: Connection closed for inactivity) |
| 06:16:45 | × | Square quits (~Square@user/square) (Remote host closed the connection) |
| 06:17:09 | → | Square joins (~Square@user/square) |
| 06:25:25 | × | peterbecich quits (~Thunderbi@syn-047-229-123-186.res.spectrum.com) (Ping timeout: 248 seconds) |
| 06:31:18 | → | Square2 joins (~Square4@user/square) |
| 06:34:04 | × | Square quits (~Square@user/square) (Ping timeout: 252 seconds) |
| 06:51:43 | → | alp joins (~alp@2001:861:e3d6:8f80:c4b2:beb0:f361:d694) |
| 06:57:54 | × | hellwolf quits (~user@0e2f-3a3b-aecf-adb3-0f00-4d40-07d0-2001.sta.estpak.ee) (Ping timeout: 246 seconds) |
| 06:58:37 | → | divya joins (~user@139.5.11.223) |
| 06:59:20 | × | divya quits (~user@139.5.11.223) (Quit: ERC 5.6.0.30.1 (IRC client for GNU Emacs 30.0.91)) |
| 07:00:12 | → | divya joins (~user@139.5.11.223) |
| 07:00:12 | × | tv quits (~tv@user/tv) (Read error: Connection reset by peer) |
| 07:06:51 | × | Sgeo quits (~Sgeo@user/sgeo) (Read error: Connection reset by peer) |
| 07:09:38 | × | Xe quits (~cadey@perl/impostor/xe) (Ping timeout: 248 seconds) |
| 07:09:59 | × | Xe_ quits (~Xe@perl/impostor/xe) (Ping timeout: 252 seconds) |
| 07:16:08 | → | Xe joins (~Xe@perl/impostor/xe) |
| 07:17:18 | → | Cadey joins (~cadey@perl/impostor/xe) |
| 07:30:14 | → | acidjnk joins (~acidjnk@p200300d6e7283f73687bc11ede7922f8.dip0.t-ipconnect.de) |
| 07:34:21 | → | petrichor joins (~znc-user@user/petrichor) |
| 07:45:10 | × | vanishingideal quits (~vanishing@user/vanishingideal) (Ping timeout: 265 seconds) |
| 07:45:17 | → | ubert joins (~Thunderbi@178.165.164.236.wireless.dyn.drei.com) |
| 07:51:11 | × | ft quits (~ft@p4fc2a216.dip0.t-ipconnect.de) (Quit: leaving) |
| 07:51:35 | → | vanishingideal joins (~vanishing@user/vanishingideal) |
| 07:51:46 | → | lortabac joins (~lortabac@2a01:e0a:541:b8f0:55ab:e185:7f81:54a4) |
| 07:53:54 | → | kuribas joins (~user@2a02:1808:84:5008:bc1f:a609:eab5:5cb9) |
| 07:55:57 | × | ubert quits (~Thunderbi@178.165.164.236.wireless.dyn.drei.com) (Quit: ubert) |
| 07:58:52 | × | kuribas quits (~user@2a02:1808:84:5008:bc1f:a609:eab5:5cb9) (Remote host closed the connection) |
| 07:59:05 | → | kuribas joins (~user@2a02:1808:84:5008:61f:fb32:d5a4:cce1) |
| 08:00:02 | × | caconym quits (~caconym@user/caconym) (Quit: bye) |
| 08:00:39 | → | caconym joins (~caconym@user/caconym) |
| 08:01:47 | → | kuribas` joins (~user@ip-188-118-57-242.reverse.destiny.be) |
| 08:03:43 | × | kuribas quits (~user@2a02:1808:84:5008:61f:fb32:d5a4:cce1) (Ping timeout: 264 seconds) |
| 08:08:39 | × | vanishingideal quits (~vanishing@user/vanishingideal) (Ping timeout: 252 seconds) |
| 08:10:24 | → | vanishingideal joins (~vanishing@user/vanishingideal) |
| 08:16:00 | → | falafel joins (~falafel@2600:1700:99f4:2050:1cad:26ba:1279:135d) |
| 08:16:18 | → | tv joins (~tv@user/tv) |
| 08:22:38 | × | mceresa quits (~mceresa@user/mceresa) (Remote host closed the connection) |
| 08:22:47 | → | mceresa joins (~mceresa@user/mceresa) |
| 08:25:02 | × | misterfish quits (~misterfis@84.53.85.146) (Ping timeout: 255 seconds) |
| 08:27:15 | → | Smiles joins (uid551636@id-551636.lymington.irccloud.com) |
| 08:38:42 | × | falafel quits (~falafel@2600:1700:99f4:2050:1cad:26ba:1279:135d) (Remote host closed the connection) |
| 08:51:18 | → | hellwolf joins (~user@2001:1530:70:545:809e:22e1:baa3:1e4c) |
| 08:58:59 | → | machinedgod joins (~machinedg@d108-173-18-100.abhsia.telus.net) |
| 09:02:51 | × | alphazone quits (~alphazone@2.219.56.221) (Ping timeout: 246 seconds) |
| 09:05:57 | × | Maxdamantus quits (~Maxdamant@user/maxdamantus) (Ping timeout: 248 seconds) |
| 09:08:06 | × | rvalue quits (~rvalue@user/rvalue) (Read error: Connection reset by peer) |
| 09:08:36 | → | rvalue joins (~rvalue@user/rvalue) |
| 09:13:18 | → | misterfish joins (~misterfis@31-161-39-137.biz.kpn.net) |
| 09:14:38 | → | CrunchyFlakes joins (~CrunchyFl@ip1f13e94e.dynamic.kabel-deutschland.de) |
| 09:19:37 | → | Maxdamantus joins (~Maxdamant@user/maxdamantus) |
| 09:24:45 | × | vanishingideal quits (~vanishing@user/vanishingideal) (Quit: leaving) |
| 09:31:28 | → | chele joins (~chele@user/chele) |
| 09:32:08 | × | alp quits (~alp@2001:861:e3d6:8f80:c4b2:beb0:f361:d694) (Remote host closed the connection) |
| 09:32:14 | × | tzh quits (~tzh@c-76-115-131-146.hsd1.or.comcast.net) (Quit: zzz) |
| 09:32:25 | → | alp joins (~alp@2001:861:e3d6:8f80:c18:bc99:f25e:38cc) |
| 09:41:23 | → | tromp joins (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) |
| 09:42:06 | → | favalex joins (~favalex@176.200.207.41) |
| 09:50:16 | → | mari-estel joins (~mari-este@user/mari-estel) |
| 09:53:06 | × | favalex quits (~favalex@176.200.207.41) (Quit: Client closed) |
| 10:05:52 | → | mari18976 joins (~mari-este@user/mari-estel) |
| 10:07:14 | × | hgolden quits (~hgolden@2603:8000:9d00:3ed1:6c70:1ac0:d127:74dd) (Ping timeout: 260 seconds) |
| 10:08:17 | × | mari-estel quits (~mari-este@user/mari-estel) (Ping timeout: 248 seconds) |
| 10:10:27 | → | mari-estel joins (~mari-este@user/mari-estel) |
| 10:10:45 | × | mari18976 quits (~mari-este@user/mari-estel) (Read error: Connection reset by peer) |
| 10:12:07 | → | mari24610 joins (~mari-este@user/mari-estel) |
| 10:14:04 | → | lxsameer joins (~lxsameer@Serene/lxsameer) |
| 10:15:10 | × | xff0x quits (~xff0x@fsb6a9491c.tkyc517.ap.nuro.jp) (Ping timeout: 252 seconds) |
| 10:15:12 | × | mari-estel quits (~mari-este@user/mari-estel) (Ping timeout: 276 seconds) |
| 10:20:44 | → | mari-estel joins (~mari-este@user/mari-estel) |
| 10:23:39 | × | mari24610 quits (~mari-este@user/mari-estel) (Ping timeout: 276 seconds) |
| 10:24:27 | → | ash3en joins (~Thunderbi@149.222.147.110) |
| 10:27:17 | → | Digitteknohippie joins (~user@user/digit) |
| 10:27:49 | × | Digit quits (~user@user/digit) (Ping timeout: 260 seconds) |
| 10:28:05 | × | ash3en quits (~Thunderbi@149.222.147.110) (Client Quit) |
| 10:32:25 | × | Smiles quits (uid551636@id-551636.lymington.irccloud.com) (Quit: Connection closed for inactivity) |
| 10:33:37 | Digitteknohippie | is now known as Digit |
| 10:49:20 | → | mikko joins (~mikko@user/mikko) |
| 10:57:08 | × | mari-estel quits (~mari-este@user/mari-estel) (Remote host closed the connection) |
| 10:57:18 | → | mari-estel joins (~mari-este@user/mari-estel) |
| 10:58:42 | × | mari-estel quits (~mari-este@user/mari-estel) (Remote host closed the connection) |
| 10:58:53 | → | mari-estel joins (~mari-este@user/mari-estel) |
| 11:00:01 | → | Smiles joins (uid551636@id-551636.lymington.irccloud.com) |
| 11:05:29 | → | mari96334 joins (~mari-este@user/mari-estel) |
| 11:06:53 | × | mari96334 quits (~mari-este@user/mari-estel) (Remote host closed the connection) |
| 11:07:05 | → | mari89179 joins (~mari-este@user/mari-estel) |
| 11:07:42 | × | mari-estel quits (~mari-este@user/mari-estel) (Ping timeout: 252 seconds) |
| 11:11:27 | → | xff0x joins (~xff0x@ai080132.d.east.v6connect.net) |
| 11:22:06 | → | jero98772 joins (~jero98772@190.158.28.32) |
| 11:26:32 | → | __monty__ joins (~toonn@user/toonn) |
| 11:38:40 | → | mari-estel joins (~mari-este@user/mari-estel) |
| 11:40:42 | × | mari89179 quits (~mari-este@user/mari-estel) (Ping timeout: 252 seconds) |
| 11:42:19 | → | mari29333 joins (~mari-este@user/mari-estel) |
| 11:43:13 | × | mari-estel quits (~mari-este@user/mari-estel) (Read error: Connection reset by peer) |
| 11:43:53 | → | mari-estel joins (~mari-este@user/mari-estel) |
| 11:46:03 | × | mari-estel quits (~mari-este@user/mari-estel) (Client Quit) |
| 11:47:34 | × | mari29333 quits (~mari-este@user/mari-estel) (Ping timeout: 260 seconds) |
| 11:52:05 | → | pavonia joins (~user@user/siracusa) |
| 11:57:24 | <hellwolf> | Is "IOPhobia" pathological case? After decades of programming, I find pure joy in writing main part of the code that deals with zero IO. And only Haskell can guarantee that, to the extent that I am questioning if I am sick. |
| 11:58:54 | × | jero98772 quits (~jero98772@190.158.28.32) (Remote host closed the connection) |
| 12:00:04 | × | caconym quits (~caconym@user/caconym) (Quit: bye) |
| 12:01:18 | <Rembane> | hellwolf: Nah, it's sound. Not having to deal with side effects makes code so much easier to write, read and test. |
| 12:02:11 | → | caconym joins (~caconym@user/caconym) |
| 12:03:23 | <hellwolf> | I hesitate to make a connetion with germophobia, since I personally am an opposite of a germophobia. |
| 12:04:00 | <Leary> | hellwolf: Welcome to the oasis of sanity. |
| 12:04:09 | <Rembane> | Some germs are quite good to not be in contact with IMO |
| 12:05:28 | <hellwolf> | like unsafePerformIO? |
| 12:07:45 | × | acidjnk quits (~acidjnk@p200300d6e7283f73687bc11ede7922f8.dip0.t-ipconnect.de) (Ping timeout: 248 seconds) |
| 12:09:11 | × | misterfish quits (~misterfis@31-161-39-137.biz.kpn.net) (Ping timeout: 252 seconds) |
| 12:09:23 | → | mari-estel joins (~mari-este@user/mari-estel) |
| 12:13:49 | <dminuoso> | unsafePerformIO is indeed quite unsafe. :-) |
| 12:16:33 | hellwolf | like when label is truth for to itself. |
| 12:17:57 | <dminuoso> | It was a simple case of something like `replicate n (unsafePerformIO (newIORef []))`, which GHC happily refactored into `let x = unsafePerformIO (newIORef []) in replicate n x` |
| 12:18:14 | × | housemate quits (~housemate@146.70.66.228) (Quit: "I saw it in a tiktok video and thought that it was the most smartest answer ever." ~ AnonOps Radio [some time some place] | I AM THE DERIVATIVE I AM GOING TANGENT TO THE CURVE!) |
| 12:18:15 | <dminuoso> | (In reality the code was far more sophisticated, so it was neither obvious how or why this happened) |
| 12:18:46 | <dminuoso> | I mean actually there was a `traverse_` in there too. |
| 12:19:48 | <dminuoso> | Yeah I think it was something like `unsafePerformIO (traverse_ (\_ -> newIORef []) xs)` and GHC successfully floated that IORef out |
| 12:20:06 | <dminuoso> | Ill have to dig through the commit history to find this one. |
| 12:20:14 | <hellwolf> | which code base? |
| 12:20:26 | <dminuoso> | An internal compiler of ours. |
| 12:20:32 | <dminuoso> | No, those examples I named are both wrong. Mmm. |
| 12:22:02 | <dminuoso> | hellwolf: Anyway, IO can still be a useful tool, especially if you want any kind of introspectability of whats going on (say logging or debugging) |
| 12:22:21 | <dminuoso> | Pure code is often cumbersome to debug |
| 12:22:42 | <dminuoso> | Consider something like GHC, where large portions work in IO |
| 12:23:59 | → | mari59415 joins (~mari-este@user/mari-estel) |
| 12:24:25 | × | arahael_ quits (~arahael@user/arahael) (Quit: leaving) |
| 12:25:23 | → | arahael_ joins (~arahael@user/arahael) |
| 12:26:03 | × | mari-estel quits (~mari-este@user/mari-estel) (Ping timeout: 252 seconds) |
| 12:26:39 | × | tromp quits (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…) |
| 12:27:19 | <hellwolf> | runTrace your_pure_fn your_trace_filters ...currying your_pure_fn_args... |
| 12:28:06 | <dminuoso> | What is `runTrace` supposed to be here? |
| 12:28:25 | <hellwolf> | that'd be my ideal way of trace into your pure fn in a principled way. I am entirely sure how feasible/difficult it could be; I did somethings that involve some aspects of such a thing. |
| 12:28:32 | → | misterfish joins (~misterfis@31-161-39-137.biz.kpn.net) |
| 12:28:48 | <hellwolf> | sorry, typed too slow. I meant to propose a hypothetical |
| 12:31:46 | × | haskellbridge quits (~hackager@syn-024-093-192-219.res.spectrum.com) (Remote host closed the connection) |
| 12:31:51 | <lortabac> | "Pure code is often cumbersome to debug" *with GHC* |
| 12:32:28 | <lortabac> | I don't think we should see lack of observability as an intrinsic property of pure computations |
| 12:32:36 | → | haskellbridge joins (~hackager@syn-024-093-192-219.res.spectrum.com) |
| 12:32:36 | ChanServ | sets mode +v haskellbridge |
| 12:32:42 | <mari59415> | no mentions about pure code being amounts easier to test |
| 12:33:53 | <hellwolf> | But I find the habit of spending more time in thinking then examining into what happened is a better use of time. Of course, on the contrary, Linus, notoriously, promoted the idea of printf debugging. So I guess the tool influence on how you do troubleshooting. |
| 12:34:38 | <hellwolf> | exactly, mari59415, it is a problem most applicable to impure code. For pure code, you write properties (which means thinking a lot about what you are writing.) |
| 12:35:34 | → | mari-estel joins (~mari-este@user/mari-estel) |
| 12:36:10 | <hellwolf> | fwiw, @dminuoso, I had a small example here https://discourse.haskell.org/t/variable-arity-currying-helper/10659 that decorates "let foo' = curry' (MkFn foo)" but that assumes all arguments is "showable". to make it runTrace, you'd need to have a default instance for all types, and then overlapping instance for Show, Num, Functor, etc. |
| 12:37:49 | × | mari59415 quits (~mari-este@user/mari-estel) (Read error: Connection reset by peer) |
| 12:38:40 | <mari-estel> | huh properties help equally with pure and monadic |
| 12:38:40 | <mari-estel> | prints or traces are a good way to collect test samples while troubleshooting |
| 12:41:35 | <hellwolf> | Does Trace.trace help? |
| 12:41:53 | <hellwolf> | Debug.Trace (trace) |
| 12:43:13 | → | mari73904 joins (~mari-este@user/mari-estel) |
| 12:44:19 | × | mari-estel quits (~mari-este@user/mari-estel) (Read error: Connection reset by peer) |
| 12:44:51 | → | mari-estel joins (~mari-este@user/mari-estel) |
| 12:45:55 | <kuribas`> | The problem is that the GHC debugger follow the imperative model for debugging (stepping through, etc..) |
| 12:46:10 | <kuribas`> | A more useful pure debugger would allow you to choose which expression to evaluate. |
| 12:46:40 | <kuribas`> | I the end, lazyness doesn't specify an order for execution. |
| 12:47:00 | <kuribas`> | As long as the semantics are preserved. |
| 12:47:01 | × | mari-estel quits (~mari-este@user/mari-estel) (Client Quit) |
| 12:47:50 | × | mari73904 quits (~mari-este@user/mari-estel) (Ping timeout: 255 seconds) |
| 12:48:41 | <__monty__> | That would also cause confusion though. Since sometimes referential transparency is a lie. And it's easy to convince yourself that the expressions must surely be evaluating in the order you think they are. |
| 12:58:57 | <kuribas`> | __monty__: how can it be a lie with "pure" code? |
| 12:59:08 | <kuribas`> | Assuming it doesn't use unsafePerformIO. |
| 12:59:51 | → | alphazone joins (~alphazone@2.219.56.221) |
| 13:02:26 | <__monty__> | There's the rub : ) |
| 13:05:11 | <haskellbridge> | <hellwolf> the lie is limited to the extent that, if your program is not total, would the debugger hurt your bottom where you intend to leave it so. |
| 13:12:04 | <kuribas`> | > head [1, undefined] |
| 13:12:05 | <lambdabot> | 1 |
| 13:12:30 | <kuribas`> | If you would evaluate the second element of the list, the debugger should not halt the whole expression. |
| 13:13:44 | <bailsman> | Huh, are mutable vectors a scam? `VM.iforM_ mv $ \i x -> VM.write mv i (updateValue x)` is considerably slower for simple objects, and barely faster than `map updateValue` even for large complex objects. |
| 13:14:28 | <geekosaur> | they will definitely have costs you don't incur with immutable vectors |
| 13:15:25 | <bailsman> | So the use cases are considerably more niche than I thought. Like if you need to exchange two elements or something, the pure version would have to copy the entire thing and the mutable version only two elements. But for most cases, it's a bait? |
| 13:16:30 | <bailsman> | If you expect to touch every element, just use map. |
| 13:16:51 | <geekosaur> | pretty much |
| 13:17:21 | <geekosaur> | it's still going to do copies, I think, and more of them the more elements you touch. but I'mnot sure how that plays out for vector |
| 13:18:05 | <geekosaur> | for Array it's split into "cards" and modifications within a single card are batched so only a single copy needs to be done by the mutator, AIUI |
| 13:18:13 | <bailsman> | I tried look at it with -ddump-simpl and the mutable version doesn't compile to simple code at all. What should be like 5 assembly instructions turns into several pages of assembly. |
| 13:18:30 | <geekosaur> | but that's built into GC and I don't think vector can take advantage of it |
| 13:18:58 | <bailsman> | I think if you need a mutable algorithm maybe you should do a CFFI or something. |
| 13:24:13 | → | alexherbo2 joins (~alexherbo@2a02-8440-3313-668b-a9ec-921f-0511-ee3f.rev.sfr.net) |
| 13:32:56 | × | weary-traveler quits (~user@user/user363627) (Remote host closed the connection) |
| 13:33:10 | → | tromp joins (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) |
| 13:35:46 | → | acidjnk joins (~acidjnk@p200300d6e7283f73687bc11ede7922f8.dip0.t-ipconnect.de) |
| 13:38:28 | → | mari-estel joins (~mari-este@user/mari-estel) |
| 13:48:24 | × | misterfish quits (~misterfis@31-161-39-137.biz.kpn.net) (Ping timeout: 276 seconds) |
| 13:50:45 | → | weary-traveler joins (~user@user/user363627) |
| 13:56:06 | × | bitdex quits (~bitdex@gateway/tor-sasl/bitdex) (Quit: = "") |
| 14:01:26 | → | ash3en joins (~Thunderbi@149.222.147.110) |
| 14:05:34 | × | ash3en quits (~Thunderbi@149.222.147.110) (Client Quit) |
| 14:06:31 | × | L29Ah quits (~L29Ah@wikipedia/L29Ah) (Ping timeout: 265 seconds) |
| 14:10:02 | <dminuoso> | bailsman: Do you have the actual code and the generated core to look at? |
| 14:16:32 | × | mari-estel quits (~mari-este@user/mari-estel) (Quit: errands) |
| 14:18:37 | → | Sgeo joins (~Sgeo@user/sgeo) |
| 14:30:28 | → | mari-estel joins (~mari-este@user/mari-estel) |
| 14:35:09 | → | ash3en joins (~Thunderbi@149.222.147.110) |
| 14:35:40 | × | alexherbo2 quits (~alexherbo@2a02-8440-3313-668b-a9ec-921f-0511-ee3f.rev.sfr.net) (Remote host closed the connection) |
| 14:35:45 | × | ash3en quits (~Thunderbi@149.222.147.110) (Client Quit) |
| 14:35:59 | → | alexherbo2 joins (~alexherbo@2a02-8440-3313-668b-a9ec-921f-0511-ee3f.rev.sfr.net) |
| 14:36:27 | × | yaroot quits (~yaroot@2400:4052:ac0:d901:1cf4:2aff:fe51:c04c) (Read error: Connection reset by peer) |
| 14:36:41 | → | yaroot joins (~yaroot@2400:4052:ac0:d901:1cf4:2aff:fe51:c04c) |
| 14:39:55 | × | Cadey quits (~cadey@perl/impostor/xe) (Quit: WeeChat 4.4.2) |
| 14:41:12 | × | weary-traveler quits (~user@user/user363627) (Quit: Konversation terminated!) |
| 14:47:02 | → | billchenchina joins (~billchenc@2a0d:2580:ff0c:1:e3c9:c52b:a429:5bfe) |
| 14:48:48 | <bailsman> | Plain old lists are consistently the fastest. I find that somewhat confusing, since in imperative languages linked lists are often slow. |
| 14:49:41 | <geekosaur> | if all you're doing is iterating through them, consider that ghc is optimized for that case: think of a list as a loop encoded as data |
| 14:49:51 | <hellwolf> | I mean, if you need to do a log of random indexing, it got to be slow. but for stream processing, it is probably the most efficient |
| 14:50:23 | <geekosaur> | allocation, gc, and iteration are all optimized because it's so common |
| 14:50:37 | <haskellbridge> | <Bowuigi> Reasoning imperatively in functional languages leads to bad performance in general |
| 14:50:40 | → | misterfish joins (~misterfis@31-161-39-137.biz.kpn.net) |
| 14:51:04 | → | ph88 joins (~ph88@2a02:8109:9e26:c800:7ee4:dffc:4616:9e2a) |
| 14:52:00 | <bailsman> | I thought I needed to do a lot of random indexing. But, now I'm not sure if I shouldn't instead redesign everything so that it does not require random access. |
| 14:52:55 | <haskellbridge> | <Bowuigi> Have you tried any functional random access data structures? |
| 14:53:14 | <haskellbridge> | <Bowuigi> Data.Map is the first one that comes to mind |
| 14:53:38 | <bailsman> | Data.Vector.Map over a vector is consistently 4x slower than regular map over []. (Data.Map is 10x slower) |
| 14:54:06 | → | hgolden joins (~hgolden@2603:8000:9d00:3ed1:6c70:1ac0:d127:74dd) |
| 14:54:11 | <hellwolf> | "data Array i e" is also under rated. |
| 14:54:16 | <geekosaur> | right, map's going to be one of those cases that [] will work very well for |
| 14:55:03 | <geekosaur> | it actually compiles down to a tight loop in most cases, not the C-style linked list you might expect |
| 14:55:14 | <ph88> | when i have some code more or less in the shape of this thing https://hackage.haskell.org/package/containers-0.7/docs/Data-Tree.html#t:Tree how can i write code that changes `a` with State but there are two points to change it, when going down (into the leafs) and going up (back to the root)? also known as visitor pattern |
| 14:55:38 | <geekosaur> | ph88, are you aware of tree zippers? |
| 14:55:42 | <ph88> | no |
| 14:55:53 | <geekosaur> | sadly the first reference that comes to mind is on the wiki… |
| 14:56:06 | <bailsman> | I have some parts right now that use random access. But was thinking maybe I don't want to pay a 4x performance penalty just for random access. |
| 14:56:08 | <hellwolf> | (wiki has been fixed) |
| 14:56:16 | <geekosaur> | just found that, yes |
| 14:56:29 | <geekosaur> | actually hgolden in #h-i said there are still some style issues |
| 14:56:30 | <bailsman> | Awesome! Thank you to whoever fixed it |
| 14:56:30 | <geekosaur> | https://wiki.haskell.org/Zipper |
| 14:56:57 | <geekosaur> | it uses a tree as the example data structure, where most of them focus on lists which are the easiest case |
| 14:57:50 | <haskellbridge> | <Bowuigi> Gérard Huet's pearl "The Zipper" is also good if you don't mind OCaml |
| 14:58:09 | <bailsman> | What do you mean by tight loop? Surely it still has to allocate all the elements for the new list? |
| 14:58:25 | <bailsman> | Or does it turn into an in-place algorithm? |
| 14:58:44 | <geekosaur> | if your generation and consumption are written correctly, they get pipelined |
| 14:59:04 | <bailsman> | I don't know what any of those words mean |
| 14:59:10 | <ph88> | wiki got a makeover? i remember being it uglier |
| 14:59:34 | <geekosaur> | ph88, that's what I meant by style but also a mediawiki upgrade is what started the whole outage thing |
| 14:59:42 | <bailsman> | I am just doing [SmallRecord] -> [SmallRecord] by updating a field in the record |
| 14:59:43 | <haskellbridge> | <Bowuigi> GHC does dark magic to not actually use a linked list |
| 15:00:07 | <geekosaur> | bailsman, construction of the list vs. mapping through the list |
| 15:00:40 | <geekosaur> | in the optimal case, the list is never constructed as such, elements are fed directly to map as they are created |
| 15:01:05 | <bailsman> | Hey, no, that's cheating. Then I've written my benchmark wrong |
| 15:01:11 | <bailsman> | I need to benchmark the list already existing |
| 15:01:46 | <bailsman> | It has to actually be stored and loaded from memory to be a fair comparison. |
| 15:02:19 | <bailsman> | Why is understand performance of things so difficult aaargh |
| 15:02:30 | <EvanR> | yes, when you "write C in any language" in haskell, it's not optimal. Surprise |
| 15:02:33 | <geekosaur> | because everyone wants speeeeeeed |
| 15:02:59 | <EvanR> | haskell is weird that way. But it's actually not smart to write C in any language generally |
| 15:03:18 | <geekosaur> | (including C /gd&r) |
| 15:03:24 | → | weary-traveler joins (~user@user/user363627) |
| 15:03:33 | <bailsman> | EvanR: That would be helpful advice if I automatically understood how to write idiomatic-and-perforant code in Haskell - but unfortunately that wisdom is as yet inaccesible to me :P |
| 15:03:49 | <EvanR> | advice: forget anything you know about C and C++ and learn haskell |
| 15:04:02 | <EvanR> | also forget python for good measure |
| 15:04:47 | <geekosaur> | I think maybe if you want to understand idiomatic-and-performant, it might be worth looking at Chris Okasaki's thesis on functional data structures |
| 15:04:53 | <haskellbridge> | <Bowuigi> Because it is different to what you are used to. Functional languages can do optimizations that imperative langs can't, like list/fold/map/hylo fusion (AKA removing intermediate computations while traversing or creating stuff), safe(-ish) inlining, laziness stuff, etc |
| 15:05:47 | <geekosaur> | IIRC it's in OCaml instead of Haskell so it won't cover things like laziness, but it'll still teach you the zen of functional programming |
| 15:06:43 | <bailsman> | How do I force it to actually create the list? `smallRecs = force [... | ... <- ...]` did not change anything, map is still as fast as it was before. Maybe it wasn't cheating? |
| 15:06:57 | <haskellbridge> | <Bowuigi> Laziness is something you will want to learn at some point but for now you can use "{-# LANGUAGE Strict #-}" if you don't want laziness |
| 15:07:23 | <bailsman> | Or did the compiler optimize that out |
| 15:07:27 | <EvanR> | why are we trying to cripple haskell again by "actually creating lists" and enabling Strict xD |
| 15:08:02 | → | L29Ah joins (~L29Ah@wikipedia/L29Ah) |
| 15:08:14 | <geekosaur> | there's multiple levels of cheating |
| 15:08:18 | <geekosaur> | build/foldr is one |
| 15:08:20 | <haskellbridge> | <Bowuigi> You can force the first constructor (IIRC) with "seq", every constructor with "length" and the entire thing with "deepseq". Yeah Haskell has evaluation control |
| 15:08:48 | <geekosaur> | optimizing lists by treating them as loops is another |
| 15:08:52 | <ph88> | geekosaur, i was mistaken, i have actually not one data structure to fit all of the tree but multiple like `data Program = Program a [Statement]` and `data Statement = Statement a Expression` (dummy examples). Can tree zippers work with this? or do i need another technique? |
| 15:09:51 | <geekosaur> | I don't know of any examples, but that doesn't seem much different from (say) a zipper for red-black trees |
| 15:10:04 | <haskellbridge> | <Bowuigi> You might need the slightly more general idea of the "derivative of a data structure" but it is essentially the same idea |
| 15:10:43 | <bailsman> | doing smallRecsDeep = smallRecs `deepseq` smallRecs did not change anything either |
| 15:11:03 | × | Square2 quits (~Square4@user/square) (Ping timeout: 246 seconds) |
| 15:11:06 | <geekosaur> | right, I'm not sure it's the place to start buit the fundamentals of the zipper technique are http://strictlypositive.org/diff.pdf |
| 15:11:06 | <bailsman> | the benchmark is using `nf` so that should be forcing both the source list and the destination list to be actually created now, right? But it's exactly as fast as before |
| 15:11:37 | <EvanR> | that's just a definition, it would have to be evaluated to cause the normal form to be realized |
| 15:11:54 | <geekosaur> | given the stuff in that paper you should be able to construct a derivative-based zipper for any list-like or tree-like structure |
| 15:12:13 | <EvanR> | it might also be that the non deepseq version was "just as slow" for some reason |
| 15:12:16 | <haskellbridge> | <Bowuigi> I think that usage of deepseq means "fully evaluate smallRecs when smallRecs is evaluated" but I am probably wrong |
| 15:12:28 | <lortabac> | Bowuigi: probably worth mentioning that the Strict pragma only makes user definitions strict. So the rest of the ecosystem (including lists) will still be lazy |
| 15:12:51 | <geekosaur> | not even that, actually. "strict" in Haskell means WHNF |
| 15:13:00 | <geekosaur> | not `rnf` |
| 15:13:02 | <lortabac> | it won't magically make Haskell a strict language |
| 15:13:33 | <haskellbridge> | <Bowuigi> So it is StrictData but also for functions? Huh |
| 15:13:40 | <lortabac> | geekosaur: if you only use functions and data types that you define it shouldn't make a difference I guess |
| 15:13:56 | <haskellbridge> | <Bowuigi> Oh well, you can't make Haskell strict on a single pragma then |
| 15:14:27 | <bailsman> | How do I write this benchmark to ensure the list is already created when map runs and not streamed |
| 15:14:33 | <bailsman> | and the output list is created as well |
| 15:14:33 | <geekosaur> | and you really don't want to because a fair amount of the Prelude assumes laziness and will bottom if you somehow forced them to be strict |
| 15:14:38 | <haskellbridge> | <Bowuigi> AutomaticBang might have been a clearer name lol |
| 15:15:06 | <bailsman> | When I hear someone say AutomaticBang something different comes to mind than was probably intended |
| 15:15:25 | <haskellbridge> | <Bowuigi> Fair enough |
| 15:15:43 | × | acidjnk quits (~acidjnk@p200300d6e7283f73687bc11ede7922f8.dip0.t-ipconnect.de) (Ping timeout: 264 seconds) |
| 15:16:01 | <lortabac> | AutomaticExclamationMark |
| 15:16:20 | × | mari-estel quits (~mari-este@user/mari-estel) (Quit: on the move) |
| 15:16:33 | <bailsman> | Did I write this correctly? https://paste.tomsmeding.com/B6koT8Nx |
| 15:16:48 | <bailsman> | In my real-world-use-case I'm pretty sure the lists are going to have to be loaded from memory and cannot be streamed. |
| 15:16:58 | <haskellbridge> | <Bowuigi> bailsman foldr/build uses a rule so just creating the list on a function on a function that is not inlined (with "{-# NOINLINE createList #-}") may work, I don't have a GHC at hand to test though |
| 15:17:04 | <EvanR> | in IO somewhere realList <- evaluate (force list) |
| 15:17:09 | <geekosaur> | consider that loading can be streamed |
| 15:17:10 | <EvanR> | should do it |
| 15:17:14 | <geekosaur> | as can writing |
| 15:17:39 | <geekosaur> | in fact that's where streaming frameworks came from |
| 15:18:18 | <bailsman> | geekosaur: I'm fine that it streams loading and writing. But streaming the list generator into the update and never actually constructing the intermediate list is cheating for the purposes of the benchmark, since that won't be possible in the real use case. |
| 15:18:20 | <EvanR> | usually when you load a big list of stuff from I/O, the whole list will exists just because |
| 15:18:26 | <EvanR> | unless you use lazy I/O which is weird |
| 15:19:25 | <EvanR> | (this is not the case for writing a big list out to I/O, this is a case where you can get streaming, which is good) |
| 15:19:34 | <geekosaur> | or a streaming framework (conduit, pipes, streamly, …) |
| 15:19:55 | → | acidjnk joins (~acidjnk@p200300d6e7283f73687bc11ede7922f8.dip0.t-ipconnect.de) |
| 15:20:27 | <geekosaur> | anyway if you really want to know if the compiler is "cheating", look at the Core (intermediate representation language, use `-ddump-ds -ddump-to-file`) |
| 15:20:43 | <geekosaur> | or for quick and dirty, play.haskell.org has a button to generate Core |
| 15:21:54 | <geekosaur> | sorry, `-ddump-simpl` |
| 15:22:01 | <haskellbridge> | <Bowuigi> If it is fusing anything it will be fairly obvious there. Reading Core is very necessary for doing very fast Haskell code |
| 15:22:18 | <bailsman> | Using `smallRecs <- evaluate $ force [... | ... <- ...]` makes no difference whatsoever. Map is still faster 4x, absolutely no difference in performance. So can I now conclude it was not cheating? |
| 15:23:32 | <EvanR> | no you should still read the Core dump |
| 15:24:05 | <EvanR> | haskell is so high level you can't conclude anything from the source code |
| 15:24:15 | <EvanR> | on the subject of low level optimizations |
| 15:24:21 | <bailsman> | I printed the -ddump-simpl output to a file but I have no real clue how to interpret what I'm looking at |
| 15:24:31 | <EvanR> | I think there was a core primer somewhere |
| 15:24:50 | <EvanR> | but essentially it's a simplified low level language that haskell is translated to |
| 15:25:01 | <EvanR> | before it's compiled and assembled |
| 15:25:05 | <bailsman> | The pure function just translates to: updatePure_r2HI = map @SmallRecord @SmallRecord updateValue_r2HH |
| 15:25:24 | <bailsman> | sorry list function, I guess they're all pure except the mutable vector one |
| 15:25:39 | <EvanR> | @SmallRecord is a type, updateValue_r2HH should be another thing defined in the dump somewhere |
| 15:25:39 | <lambdabot> | Unknown command, try @list |
| 15:26:07 | <bailsman> | EvanR: I posted the source code of my benchmark here. https://paste.tomsmeding.com/B6koT8Nx |
| 15:26:13 | <bailsman> | please point out any beginner mistakes there |
| 15:26:42 | <bailsman> | All are using the same updateValue function. |
| 15:26:49 | <EvanR> | trying to +1 everything in the collection? |
| 15:28:39 | <EvanR> | it's not clear what defaultMain and bench do |
| 15:28:44 | × | Inst_ quits (~Inst@user/Inst) (Ping timeout: 272 seconds) |
| 15:29:18 | × | kuribas` quits (~user@ip-188-118-57-242.reverse.destiny.be) (Remote host closed the connection) |
| 15:29:31 | <EvanR> | or `nf' ? |
| 15:29:37 | <bailsman> | I copied that from some example code to do a benchmark somewhere |
| 15:29:46 | <bailsman> | I don't understand either but it printed some numbers to my console output |
| 15:29:48 | → | Inst joins (~Inst@user/Inst) |
| 15:31:16 | × | alexherbo2 quits (~alexherbo@2a02-8440-3313-668b-a9ec-921f-0511-ee3f.rev.sfr.net) (Remote host closed the connection) |
| 15:31:36 | → | alexherbo2 joins (~alexherbo@2a02-8440-3313-668b-a9ec-921f-0511-ee3f.rev.sfr.net) |
| 15:32:01 | <EvanR> | well that will have a big effect on performance |
| 15:32:27 | <EvanR> | code doesn't do anything in isolation, the evaluation is on demand |
| 15:32:33 | <bailsman> | I'd like to understand exactly what's going on to make map so much faster. |
| 15:33:36 | <EvanR> | well, mapping a list to get another list is much simpler than building a big tree or copying a vector so you can mutate it |
| 15:33:49 | <bailsman> | Why is it simpler? It's the same operation |
| 15:33:57 | <EvanR> | even simpler if the source list already exists and doesn't need to be evaluated |
| 15:33:58 | <bailsman> | It should be harder because you need to allocate and create a linked list |
| 15:34:44 | <bailsman> | My intuitions are completely wrong, but I don't know exactly why. |
| 15:35:07 | <ph88> | geekosaur, i went back and forth with chatgpt for a bit. Could you take a peek at this document, specifically on line 490 https://bpa.st/MSVA it made an example with tree zippers to implement something for each type, which i don't want. Is there a way to use tree zippers without resorting to generic programming solutions such as GHC.Generics, syb, lens or Data.Data ? |
| 15:35:20 | <EvanR> | you may or may not be allocating any list nodes due to fusion, but even if you did, that's 1 node per item. Meanwhile the IntMap has a more complex structure and the Vector is larger, even if you ignore the fact that you have to copy it |
| 15:35:31 | <bailsman> | Why is the vector larger? |
| 15:35:46 | <EvanR> | it's larger than 1 list node |
| 15:35:55 | <bailsman> | but there's only 1 of them, not 1 million |
| 15:36:40 | <EvanR> | and 1 megabyte chunk of Vector might not play as nice with the GC |
| 15:37:04 | <EvanR> | it goes back to how your "bench" thing is processing the final list, 1 by 1, it's nicer on the GC |
| 15:37:56 | <haskellbridge> | <flip101> Bowuigi: could you please take a look as well? |
| 15:38:01 | → | philopsos joins (~caecilius@user/philopsos) |
| 15:38:45 | <bailsman> | I'm expecting the vector version to compile to something like `nv = new Vector(v.length); for (int i = 0; i < v.length; ++i) nv[i] = updateValue(v[i])`. One allocation, extremely simple update. Whereas the linked list version has to allocate 1M nodes and set up each of their 'next' pointers, so it seems like it should be doing more work. |
| 15:38:58 | <EvanR> | and again, the benchmark code might have gotten optimized so there are no list nodes, other than the source list |
| 15:39:07 | <bailsman> | How do I prevent it from doing that? |
| 15:39:24 | <EvanR> | go to the benchmark code and cripple that |
| 15:39:37 | <EvanR> | fully evaluated the final list before doing whatever it does with it |
| 15:39:46 | <bailsman> | Isn't that what I'm doing already? |
| 15:39:52 | <bailsman> | That's what the nf was for right? |
| 15:40:04 | <EvanR> | I have no idea, I don't see what nf is or bench is |
| 15:40:20 | <EvanR> | right now all I see is "map updateValue someList" |
| 15:41:16 | <EvanR> | finalList <- evaluate (force (map updateValue someList)) ought to slow it down more |
| 15:41:23 | <bailsman> | nf :: NFData b => (a -> b) -> a -> Benchmarkable |
| 15:41:39 | <EvanR> | I'm not familiar with Benchmarkable |
| 15:42:07 | <EvanR> | if nf works, computes full normal form, sounds bad for performance |
| 15:42:16 | <EvanR> | in the case of list |
| 15:42:26 | <geekosaur> | ph88, it's doable without any of those but it's harder since you have to write it all yourself. those libraries exist for a reason |
| 15:43:17 | <EvanR> | when I was tooling with the profiling and performance I would make sure to write my own main IO action so I know what what's |
| 15:43:32 | <EvanR> | control what ultimately is demanding evaluation |
| 15:43:39 | <geekosaur> | especially when you have multiple data types |
| 15:43:53 | <bailsman> | Anyway, I guess we can assume that it isn't cheating, it is actually constructing the intermediate list, and most of the performance difference is going to come from map being a builtin and the vector code not compiling to anything nearly as simple as what I expected. So it's not map being fast, it's map being slowish, and vector being slower, I think. |
| 15:44:05 | <ph88> | geekosaur, doable .. would i have to write code for each data type? |
| 15:44:14 | <geekosaur> | exactly, yes |
| 15:44:17 | × | misterfish quits (~misterfis@31-161-39-137.biz.kpn.net) (Ping timeout: 248 seconds) |
| 15:44:34 | <ph88> | that's going to take so much time, the AST is absolutely huge |
| 15:44:43 | <geekosaur> | that's where generics or syb come in, they generate the necessary code for you |
| 15:44:49 | <EvanR> | 4x faster isn't that much of a difference, it seems plausible you're creating the whole structure for everything. It's not like a 1000x speedup that you'd normally see when you switch from full evaluation to lazy evaluation |
| 15:45:50 | <ph88> | geekosaur, do you think it's still worth to use zippers but then to combine them with a generic approach? i am not sure whether i can go up and down with other approaches such as lens or GHC.Generics |
| 15:46:30 | × | tromp quits (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…) |
| 15:46:34 | <EvanR> | bailsman, Vector shines when you start with combine chains of operations together, it fuses away intermediate vectors |
| 15:46:45 | <bailsman> | I only do one operation. |
| 15:46:55 | <EvanR> | so you won't see that benefit there |
| 15:46:58 | <geekosaur> | you're conflating things, syb/generics/uniplate are mechanism, lens uses the mechanism. and lens should indeed be able to navigate up/down |
| 15:47:46 | <EvanR> | again, "I don't know how this benchmark library works, but I'll assume a bunch of conclusions" isn't as good as writing your own code then profiling |
| 15:48:08 | <EvanR> | and looking at the core, of your own code |
| 15:53:17 | <geekosaur> | ph88, it's easier to replace lens there with something else (such as a zipper) than it is to replace the generics mechanism needed to make lens/a zipper/whatever useful |
| 15:54:05 | <geekosaur> | if, as you say, "that's going to take so much time, the AST is absolutely huge", you need generics of some variety to escape that |
| 15:54:18 | <geekosaur> | that's why generics packages exist |
| 15:54:45 | <ph88> | why would i want this? "it's easier to replace lens there with something else (such as a zipper)" |
| 15:55:03 | <ph88> | i have neither, and i like something to traverse while not having to write traversal code for each type |
| 15:55:26 | <ph88> | as i understood it can be ghc.generics with zipper, or lens or maybe something else |
| 15:55:35 | <geekosaur> | then use generics to derive the traversal (all of the generics packages do so in some fashion) |
| 15:56:11 | <ph88> | and you still recommend to do the traversal with zipper yes? (with code derived with generics) |
| 15:56:27 | <geekosaur> | although the default traversals are all of the Traversable variety, unlike a zipper which lets you move at will |
| 15:56:38 | <geekosaur> | which it sounded like you wanted |
| 15:56:55 | <geekosaur> | if you just want something Traversable-style, any generics library will give you that |
| 15:56:59 | <ph88> | what if i don't only want to change the variable `a` but i also want to inspect the nodes and modify/replace them ? |
| 15:57:24 | <ph88> | can zipper do this too ? |
| 15:57:24 | <geekosaur> | that'd be a zipper |
| 15:57:30 | <ph88> | ok cool, thanks geekosaur ! |
| 15:57:58 | <geekosaur> | you can do anything to the focused node including remove or replace it, and moving the zipper will reknit the tree |
| 15:58:42 | × | lortabac quits (~lortabac@2a01:e0a:541:b8f0:55ab:e185:7f81:54a4) (Quit: WeeChat 4.4.2) |
| 15:58:51 | <geekosaur> | even if it won't work with your structure as is, the wiki page I pointed you to earlier describes what you can do with a zipper |
| 15:59:12 | <geekosaur> | and the tree example is probably closer to your actual AST than a list zipper example would be |
| 16:00:06 | <bailsman> | To test my theory, I wrote a C version of the benchmark. Updating a linked list by allocating nodes one by one and copying over the values takes 14ms, approximately as long as Haskell takes to do map. Updating 1M records inplace in an array takes 2ms. |
| 16:00:30 | <bailsman> | So I think I'm concluding that map is "the best you can do in haskell" because it's optimized and a builtin, and any attempt to do in place algorithms is just going to be massively slow. |
| 16:00:31 | <EvanR> | that's... not going to be an apples to apples comparison |
| 16:00:38 | <EvanR> | are you allocating nodes with malloc |
| 16:00:57 | <EvanR> | allocating nodes in haskell is much faster |
| 16:01:08 | <bailsman> | No it isn't. |
| 16:01:22 | <EvanR> | yes it is |
| 16:01:56 | <geekosaur> | bailsman, what do you think is going on during an allocation? |
| 16:02:06 | <geekosaur> | because it's probably not what actually happens |
| 16:03:13 | <bailsman> | I agree - I'm not really sure. Some GC magic probably. But the point is that it's builtin and optimized, so it's much faster than trying to emulate in-place updates, which compiles to a morass of work and not 5 asm instructions like the c version. |
| 16:03:20 | <geekosaur> | not magic |
| 16:03:31 | <geekosaur> | the nursery/gen 0 is a bump-pointer allocator |
| 16:03:44 | <geekosaur> | gc only gets involved when the pointer reaches the end of the nursery |
| 16:04:50 | <EvanR> | "straight list processing and immutable structures are probably better in haskell than C-like mutable array munging" though is what I've been saying for days |
| 16:05:01 | <EvanR> | but the specific reasons are off |
| 16:06:10 | <EvanR> | before claiming stuff about what stuff compiles to you should check it |
| 16:06:20 | <bailsman> | To me the fact that the Haskell Vector is ~100ms, Haskell map is ~25ms, C allocate-new-linked-list-and-copy version is ~15ms, C array in place is ~2ms is suggestive of the fact that indeed allocating a list is slow, and it's indeed what Haskell is doing, but it's still better than trying to do an array in Haskell. |
| 16:06:59 | <EvanR> | the C version of linked list is just a bad thing to compare to haskell list unless you are careful to emulate what the haskell version did |
| 16:07:25 | <EvanR> | "they are both called list" isn't that inspiring |
| 16:08:09 | <EvanR> | list and arrays in haskell are both good for certain purposes |
| 16:08:44 | <EvanR> | in the case of list, usually not as a data structure |
| 16:08:53 | <EvanR> | but as a looping mechanism |
| 16:09:22 | <bailsman> | I agree with your conclusion - stop trying to be clever and just learn what idiomatic haskell code looks like. |
| 16:09:25 | <EvanR> | in the case of arrays, for lookup tables |
| 16:10:03 | <bailsman> | If you write idiomatic haskell, you get as-slow-as-you-would-expect, if you try to write in-place code, you get way-slower-than-you-would-expect. |
| 16:10:34 | <EvanR> | not necessarily, sometimes idiomatic haskell is faster |
| 16:11:19 | <EvanR> | in any case idiomatic haskell is a starting point for getting into the weeds for optimization |
| 16:12:30 | <Inst> | @bailsman |
| 16:12:30 | <lambdabot> | Unknown command, try @list |
| 16:12:36 | <Inst> | try compile with -fllvm |
| 16:14:34 | <bailsman> | Inst: I compiled my benchmark with -O2 -fllvm. Does not seem meaningfully different. Is -O2 the wrong optimization level? |
| 16:16:14 | <EvanR> | is llvm not the default now anyway |
| 16:16:16 | <Inst> | probably MY skill issue :( |
| 16:16:35 | <tomsmeding> | EvanR: it definitely is not |
| 16:16:39 | <EvanR> | ok |
| 16:19:01 | → | tromp joins (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) |
| 16:19:31 | <tomsmeding> | :) |
| 16:20:48 | → | aljazmc joins (~aljazmc@user/aljazmc) |
| 16:21:27 | <geekosaur> | llvm still lacks support for pre-CPSed code |
| 16:33:44 | <haskellbridge> | <Bowuigi> Now that everything is solved, it's time to move to something else |
| 16:34:26 | <haskellbridge> | <Bowuigi> It turns out that first class labels are just Proxy on a kind ranging over every possible label |
| 16:37:00 | → | Digitteknohippie joins (~user@user/digit) |
| 16:37:19 | × | Digit quits (~user@user/digit) (Ping timeout: 265 seconds) |
| 16:40:17 | <bailsman> | Hmmm. I had Claude.AI write an unboxed small record instance with 50+ lines of code (to my eyes absolutely horrific). Then, using Data.Vector.Unboxed.Mutable the performance is now approaching the C in-place update speed. I don't entirely trust that this won't segfault at some point, but if claude.ai did everything correctly then apparently it *is* possible to write inplace algorithms, you just |
| 16:40:18 | <bailsman> | need to write unboxed instances for all of your data types. |
| 16:41:51 | <geekosaur> | well, yes, that helps |
| 16:42:00 | <geekosaur> | otherwise it'll be chasing a lot of pointers |
| 16:42:20 | <haskellbridge> | <Bowuigi> Oh yeah unboxing and strict data type fields can help in optimizing in general |
| 16:42:44 | <bailsman> | It went from 4x slower to 10x faster than plain `map` |
| 16:44:33 | × | Digitteknohippie quits (~user@user/digit) (Ping timeout: 252 seconds) |
| 16:46:08 | → | Digit joins (~user@user/digit) |
| 16:58:01 | × | aljazmc quits (~aljazmc@user/aljazmc) (Remote host closed the connection) |
| 16:58:27 | → | aljazmc joins (~aljazmc@user/aljazmc) |
| 16:58:53 | → | housemate joins (~housemate@146.70.66.228) |
| 17:03:50 | mantraofpie_ | is now known as mantraofpie |
| 17:05:45 | × | machinedgod quits (~machinedg@d108-173-18-100.abhsia.telus.net) (Ping timeout: 252 seconds) |
| 17:10:17 | × | mantraofpie quits (~mantraofp@user/mantraofpie) (Quit: ZNC 1.9.1 - https://znc.in) |
| 17:10:57 | → | mantraofpie joins (~mantraofp@user/mantraofpie) |
| 17:11:25 | → | Inst_ joins (~Inst@user/Inst) |
| 17:12:03 | → | emfrom joins (~emfrom@37.168.28.138) |
| 17:13:09 | × | Inst quits (~Inst@user/Inst) (Ping timeout: 276 seconds) |
| 17:21:58 | × | emfrom quits (~emfrom@37.168.28.138) (Remote host closed the connection) |
| 17:22:11 | <bailsman> | Wait, so apparently I can derive the unboxed instances with minimal boilerplate (as tuples), and the pure world doesn't even need to know or care that I did that all. I can write it idiomatically. And it's now as fast as C |
| 17:22:15 | <bailsman> | why did nobody tell me :P |
| 17:23:30 | <bailsman> | Please tell me it's not going to segfault on me if I move forward with this in more complex examples |
| 17:25:10 | <tomsmeding> | bailsman: "please tell me" if you show the code, perhaps we can :) |
| 17:26:10 | <bailsman> | updateValue is pure. This is the 'inplace map': `runST $ do; mv <- VU.unsafeThaw v; VUM.iforM_ mv $ \i s -> VUM.write mv i $! updateValue s; VU.unsafeFreeze mv` |
| 17:26:43 | × | alexherbo2 quits (~alexherbo@2a02-8440-3313-668b-a9ec-921f-0511-ee3f.rev.sfr.net) (Remote host closed the connection) |
| 17:27:04 | → | alexherbo2 joins (~alexherbo@2a02-8440-3313-668b-a9ec-921f-0511-ee3f.rev.sfr.net) |
| 17:31:34 | <bailsman> | https://paste.tomsmeding.com/yaTzqQA3 |
| 17:31:59 | <bailsman> | more readable on multiple lines |
| 17:32:55 | <bailsman> | I should probably find a way to keep it mutable permanently rather than thawing and freezing |
| 17:33:13 | <tomsmeding> | bailsman: yes, mutating an immutable vector is sure to produce very strange issues |
| 17:33:32 | → | peterbecich joins (~Thunderbi@syn-047-229-123-186.res.spectrum.com) |
| 17:33:35 | <tomsmeding> | GHC assumes that immutable values don't change and sometimes optimises quite aggressively based on that assumption |
| 17:33:54 | <tomsmeding> | please don't do this :p |
| 17:34:19 | <tomsmeding> | work in ST and keep the thing mutable while you're mutating it |
| 17:34:51 | → | wootehfoot joins (~wootehfoo@user/wootehfoot) |
| 17:35:42 | <bailsman> | Even if I make sure that the code with mutable reference has fully evaluated before any code with immutable references tries to read? |
| 17:36:47 | <bailsman> | I actually really like the performance now - I'd like to fully understand the dragons on my path. |
| 17:37:26 | <geekosaur> | ST will ensure that for you |
| 17:37:43 | <bailsman> | Replacing the code with the safe versions of freeze and thaw makes it 3x slower |
| 17:38:56 | × | housemate quits (~housemate@146.70.66.228) (Quit: "I saw it in a tiktok video and thought that it was the most smartest answer ever." ~ AnonOps Radio [some time some place] | I AM THE DERIVATIVE I AM GOING TANGENT TO THE CURVE!) |
| 17:39:30 | × | tromp quits (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…) |
| 17:44:03 | → | ft joins (~ft@p4fc2a216.dip0.t-ipconnect.de) |
| 17:46:27 | → | tzh joins (~tzh@c-76-115-131-146.hsd1.or.comcast.net) |
| 17:47:10 | → | housemate joins (~housemate@146.70.66.228) |
| 17:50:58 | <tomsmeding> | bailsman: yes, depending on how you ensure that it is fully evaluated |
| 17:51:15 | <tomsmeding> | GHC may just decide that "fully evaluating" the values can also happen a bit later |
| 17:51:26 | <tomsmeding> | (again depending on the precise code) |
| 17:51:29 | <bailsman> | evaluate $ force |
| 17:51:32 | <tomsmeding> | in IO? |
| 17:51:35 | × | peterbecich quits (~Thunderbi@syn-047-229-123-186.res.spectrum.com) (Ping timeout: 255 seconds) |
| 17:51:42 | <bailsman> | sure |
| 17:51:47 | <tomsmeding> | (evaluate runs in IO) |
| 17:51:50 | <geekosaur> | evaluate has to be in IO |
| 17:51:51 | <tomsmeding> | yes IO sequences, so that's fine |
| 17:52:12 | <tomsmeding> | I would still not do this |
| 17:53:01 | <tomsmeding> | bailsman: try putting the whole mutable part in ST, so that you only have one unsafeThaw and one unsafeFreeze; presumably that should still be fast |
| 17:53:20 | <tomsmeding> | then change the unsafeThaw to thaw, because with the unsafeThaw + unsafeFreeze you're still in unsafe world |
| 17:54:10 | <tomsmeding> | perhaps you can ensure that you don't create the initial vector as immutable, but instead as mutable, so that you never have to thaw it |
| 17:54:16 | <bailsman> | The 'challenge' I have is I'm not sure how to store a mutable array outside the monad. Currently I'm freezing it, then doing writeIORef, then when it runs again I do readIORef followed by thaw. |
| 17:54:17 | <tomsmeding> | that would save the introduced copy |
| 17:54:18 | × | housemate quits (~housemate@146.70.66.228) (Read error: Connection reset by peer) |
| 17:54:30 | → | housemate joins (~housemate@146.70.66.228) |
| 17:54:32 | <tomsmeding> | the point is that a mutable array _must_ live inside the monad :p |
| 17:54:39 | <tomsmeding> | that's the whole point of the interface, and what makes it safe |
| 17:55:06 | <tomsmeding> | a mutable array is a _reference_, you only need a read-only reference to the MVector to be able to modify the underlying storage |
| 17:55:09 | <bailsman> | this part isn't safe. This is the fast part. The rest of my code I want to write idiomatically/pure. |
| 17:55:27 | <tomsmeding> | no code needs to _return_ an MVector, just create one, then pass it _to_ everything |
| 17:55:45 | <tomsmeding> | (think: there's already an "IORef" (ish) inside the MVector type) |
| 17:55:51 | <bailsman> | I need to store it somewhere between invocations from javascript :P |
| 17:56:01 | <tomsmeding> | O.o |
| 17:56:05 | <tomsmeding> | okay that changes the picture |
| 17:56:17 | <tomsmeding> | make it an IOVector instead of an STVector? |
| 17:56:35 | <tomsmeding> | I don't recall the JS FFI well, but can't exported haskell functions run in IO? |
| 17:56:41 | <tomsmeding> | then you can just put the IOVector wherever |
| 17:57:17 | <bailsman> | They totally can. I'm being called from javascript, that JSFFI function is in IO, currently I'm faking a global variable by doing unsafePerformIO (newIOREf ...) then reading/writing to the IORef |
| 17:57:26 | <tomsmeding> | that sounds like a decent plan |
| 17:57:36 | <tomsmeding> | just make that an IOVector, not an STVector :p |
| 17:57:45 | <tomsmeding> | never need to thaw/freeze it |
| 17:58:24 | <tomsmeding> | bailsman: make sure to put {-# NOINLINE #-} on that global variable |
| 17:58:44 | <bailsman> | yep I did that. So my global variable is a record with a bunch of vectors in it. I haven't figured out yet how to make those mutable. |
| 17:58:54 | <tomsmeding> | make them IOVectors? |
| 17:59:02 | bailsman | googles iovectors |
| 17:59:13 | <tomsmeding> | vector:Data.Vector.Mutable (IOVector) |
| 17:59:22 | <tomsmeding> | perhaps Data.Vector.Unboxed.Mutable |
| 17:59:47 | <bailsman> | and that means I can put them in a record and then I can writeIORef that record ? And everything works? |
| 17:59:56 | <tomsmeding> | don't writeIORef that record |
| 18:00:00 | <tomsmeding> | just read the IOVectors |
| 18:00:08 | <tomsmeding> | they're already references |
| 18:00:23 | <bailsman> | so I need to noinline unsafePerformIO the iovectors |
| 18:00:27 | <tomsmeding> | yes |
| 18:00:42 | → | JuanDaugherty joins (~juan@user/JuanDaugherty) |
| 18:01:04 | × | housemate quits (~housemate@146.70.66.228) (Remote host closed the connection) |
| 18:01:33 | → | housemate joins (~housemate@146.70.66.228) |
| 18:01:38 | × | housemate quits (~housemate@146.70.66.228) (Remote host closed the connection) |
| 18:01:43 | <bailsman> | I see. And then I just use them. And GHC understands that they were mutable the whole time and so it doesn't do anything unsafe. |
| 18:01:51 | <tomsmeding> | yes |
| 18:02:26 | → | visilii joins (~visilii@213.24.126.184) |
| 18:02:49 | × | visilii_ quits (~visilii@213.24.127.47) (Ping timeout: 260 seconds) |
| 18:06:26 | → | ljdarj joins (~Thunderbi@user/ljdarj) |
| 18:09:05 | → | peterbecich joins (~Thunderbi@syn-047-229-123-186.res.spectrum.com) |
| 18:09:33 | → | tromp joins (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) |
| 18:09:50 | × | alexherbo2 quits (~alexherbo@2a02-8440-3313-668b-a9ec-921f-0511-ee3f.rev.sfr.net) (Remote host closed the connection) |
| 18:11:58 | → | housemate joins (~housemate@146.70.66.228) |
| 18:25:51 | → | shapr joins (~user@2601:19c:417e:5434:4627:df70:3bf6:c2cb) |
| 18:26:17 | <shapr> | I'm writing a small blog post about using Haskell for "shell scripting", or maybe "how to run a Haskell source file" |
| 18:26:37 | <shapr> | The only two ways I know are: #!/usr/bin/env runhaskell |
| 18:27:49 | <shapr> | and something similar with cabal: https://github.com/shapr/randomtesting/blob/main/Hedgehog.hs#L3 |
| 18:27:58 | <shapr> | Am I missing anything? |
| 18:29:09 | × | hellwolf quits (~user@2001:1530:70:545:809e:22e1:baa3:1e4c) (Ping timeout: 246 seconds) |
| 18:29:19 | <tomsmeding> | documentation about the latter here: https://cabal.readthedocs.io/en/stable/cabal-commands.html#cabal-run |
| 18:29:38 | <shapr> | tomsmeding: thank you! |
| 18:30:24 | <tomsmeding> | similarly https://docs.haskellstack.org/en/stable/topics/scripts/ |
| 18:32:59 | <shapr> | I'll add that as well |
| 18:35:30 | <sm> | shapr: quite a bit, I must tell you :) |
| 18:36:09 | <shapr> | oh no, what else am I missing? |
| 18:36:57 | <sm> | stack scripts and cabal scripts are important for using deps / reproducibility / sharing, already mentioned by tomsmeding |
| 18:37:32 | <sm> | there have been lots of attempts to bridge haskell and scripting - https://hackage.haskell.org/packages/search?terms=shell probably includes some of them (sorry) |
| 18:37:52 | <sm> | https://chrisdone.github.io/hell is the most recent and a particularly interesting one IMHO |
| 18:38:41 | <shapr> | That makes the subject larger than I can put into a single blog post |
| 18:38:56 | <shapr> | tempting, but for now I'm gonna cover "how to run a Haskell source file like it's a shell script" |
| 18:39:01 | <sm> | Yeah. I hope you'll mention the issue of keeping it running beyond a single ghc release at least. Maybe another post :) |
| 18:39:17 | <shapr> | uh, what is that issue? |
| 18:39:26 | × | housemate quits (~housemate@146.70.66.228) (Quit: "I saw it in a tiktok video and thought that it was the most smartest answer ever." ~ AnonOps Radio [some time some place] | I AM THE DERIVATIVE I AM GOING TANGENT TO THE CURVE!) |
| 18:39:42 | <shapr> | tell me more? |
| 18:39:53 | <sm> | if you don't pin down ghc (& base) and any other deps your script uses, it's likely to break eventually (or possibly very soon), unlike normal shell scripts |
| 18:40:10 | <shapr> | oh, interesting |
| 18:40:23 | <sm> | just because of ghc's evolution and tight/fragile dependencies between haskell packages |
| 18:40:28 | <shapr> | Now that I know, I will mention this! |
| 18:41:33 | × | peterbecich quits (~Thunderbi@syn-047-229-123-186.res.spectrum.com) (Ping timeout: 276 seconds) |
| 18:41:37 | → | housemate joins (~housemate@146.70.66.228) |
| 18:41:40 | <sm> | (and, getting it working may require either some coding to update it, or installing a few gigabytes of old ghc and deps that may or may not run easily on your machine) |
| 18:41:53 | <sm> | sorry, I'm just giving the most negative (but real) case |
| 18:42:23 | <sm> | feel free to ignore me :) |
| 18:42:28 | × | housemate quits (~housemate@146.70.66.228) (Max SendQ exceeded) |
| 18:42:34 | <shapr> | I like to know all the bits around the edges! |
| 18:42:38 | shapr | hugs sm |
| 18:43:14 | → | housemate joins (~housemate@146.70.66.228) |
| 18:43:22 | sm | bounces |
| 18:45:17 | <sm> | other issues if scripts are to be shared: how to make a robust shebang line |
| 18:45:23 | × | housemate quits (~housemate@146.70.66.228) (Max SendQ exceeded) |
| 18:45:52 | <sm> | ah you showed one. If more arguments are needed, some platforms require env -S |
| 18:46:25 | <shapr> | What's env -S ? |
| 18:46:44 | → | housemate joins (~housemate@146.70.66.228) |
| 18:46:56 | <shapr> | The benefit of writing blog posts is that I learn so much! |
| 18:47:11 | <geekosaur> | (but some systems that require it don't have it. then again I'm not sure how many people run Illumos) |
| 18:47:21 | <sm> | I think env requires -S on *bsd (& mac) to allow extra arguments after the executable, GNU/linux doesn't. Or vice versa. |
| 18:47:33 | <geekosaur> | the former |
| 18:47:49 | <geekosaur> | historically the entire shebang line after the interpreter name was passed as a single parameter |
| 18:47:58 | <geekosaur> | -S word-splits the parameter |
| 18:48:11 | <sm> | 👍🏻 |
| 18:48:23 | <geekosaur> | (shebangs originated on BSD) |
| 18:48:42 | <shapr> | Yeah, I just realized I don't know whether # was a comment BEFORE it #! was the magic bytes for "this is an executable" |
| 18:48:53 | × | housemate quits (~housemate@146.70.66.228) (Max SendQ exceeded) |
| 18:49:01 | <geekosaur> | it was a comment… for csh |
| 18:49:21 | <shapr> | oh wow, so csh had # comments before #! was magic bytes? |
| 18:49:22 | <geekosaur> | on sh there was a libc hack, if exec() failed it retried it via sh |
| 18:49:24 | <sm> | just remember it's very easy to write a runhaskell script, add some standard-looking imports, then share it or come back in a few months and find it depends on packages which are no longer installed or installed but changed |
| 18:49:26 | <geekosaur> | yes |
| 18:49:32 | <shapr> | wow, thanks |
| 18:49:43 | <shapr> | sm: yeah, I'll mention that |
| 18:49:44 | → | housemate joins (~housemate@146.70.66.228) |
| 18:50:40 | <geekosaur> | back then sh's idea of a comment was :, and it was actually a null command so you needed to quote any special characters in the "comment" |
| 18:50:58 | sm | wonders what shebang line works in native windows shells (cmd, powershell) - none ? |
| 18:51:17 | <geekosaur> | I think powershell has something vaguely shebang-like, cmd doesn't |
| 18:51:24 | <geekosaur> | os/2 used to have EXTPROC |
| 18:51:53 | × | housemate quits (~housemate@146.70.66.228) (Max SendQ exceeded) |
| 18:52:03 | <shapr> | ooh this is a fun read https://en.wikipedia.org/wiki/Shebang_%28Unix%29#Version_8_improved_shell_scripts |
| 18:52:37 | <shapr> | I was a small child when #! was added |
| 18:53:44 | → | housemate joins (~housemate@146.70.66.228) |
| 18:54:33 | <sm> | I was a small child too when I was a lad |
| 18:54:36 | <shapr> | haha |
| 18:55:03 | sm | was 12 and about to see a computer next year |
| 18:55:08 | <geekosaur> | sophomore in high school |
| 18:55:17 | → | Tuplanolla joins (~Tuplanoll@91-159-69-59.elisa-laajakaista.fi) |
| 18:55:53 | × | housemate quits (~housemate@146.70.66.228) (Max SendQ exceeded) |
| 18:55:53 | <geekosaur> | banging on a TRS-80 Model I during off periods |
| 18:56:02 | <geekosaur> | teaching myself Z80 assembly language |
| 18:56:15 | <sm> | sweet. Commodore Pet & 6502 checking in! |
| 18:56:39 | <geekosaur> | I had that at home courtesy of my father |
| 18:56:44 | → | housemate joins (~housemate@146.70.66.228) |
| 18:56:47 | <sm> | ohhhh |
| 18:57:08 | <sm> | was he a scientist ? |
| 18:57:19 | <geekosaur> | well, OSI SuperBoard II (the mainboard minus components), then he bought the components separately and had someone at work wave-solder it all together |
| 18:57:25 | <tomsmeding> | sm: re base versions with scripts: a cabal script has a build-depends block at the top, so you can put a version constraint on that ;) |
| 18:57:31 | <tomsmeding> | (not that anybody does that) |
| 18:57:45 | <sm> | tomsmeding yes exactly, that's why stack/cabal scripts are important |
| 18:58:03 | <geekosaur> | salesman, actually, but for a company that sold electronic (for 1980 values of electronic) parts to industry |
| 18:58:14 | × | chele quits (~chele@user/chele) (Remote host closed the connection) |
| 18:58:19 | <sm> | nice |
| 18:59:10 | × | housemate quits (~housemate@146.70.66.228) (Max SendQ exceeded) |
| 18:59:40 | → | housemate joins (~housemate@146.70.66.228) |
| 19:01:39 | <sm> | stack provides the `script` command specifically for this purpose - it will shout at you if you leave anything unspecified, so you won't forget |
| 19:02:05 | × | housemate quits (~housemate@146.70.66.228) (Max SendQ exceeded) |
| 19:02:33 | → | housemate joins (~housemate@146.70.66.228) |
| 19:04:46 | × | housemate quits (~housemate@146.70.66.228) (Max SendQ exceeded) |
| 19:04:49 | → | Lestat9 joins (~Admin1@47.203.239.77) |
| 19:04:53 | × | JuanDaugherty quits (~juan@user/JuanDaugherty) (Quit: JuanDaugherty) |
| 19:05:14 | → | housemate joins (~housemate@146.70.66.228) |
| 19:07:29 | × | housemate quits (~housemate@146.70.66.228) (Max SendQ exceeded) |
| 19:07:57 | → | housemate joins (~housemate@146.70.66.228) |
| 19:08:49 | × | housemate quits (~housemate@146.70.66.228) (Remote host closed the connection) |
| 19:09:14 | → | housemate joins (~housemate@146.70.66.228) |
| 19:11:36 | × | housemate quits (~housemate@146.70.66.228) (Max SendQ exceeded) |
| 19:12:04 | → | housemate joins (~housemate@146.70.66.228) |
| 19:14:27 | × | housemate quits (~housemate@146.70.66.228) (Max SendQ exceeded) |
| 19:14:55 | → | housemate joins (~housemate@146.70.66.228) |
| 19:15:49 | × | housemate quits (~housemate@146.70.66.228) (Remote host closed the connection) |
| 19:16:14 | → | housemate joins (~housemate@146.70.66.228) |
| 19:16:38 | → | hellwolf joins (~user@da7f-daa3-a2f4-21df-0f00-4d40-07d0-2001.sta.estpak.ee) |
| 19:17:04 | <hellwolf> | basic question regarding cabal... if you specify a version that is not the "HEAD" of the package, would cabal be able to retrieve it from somewhere still? |
| 19:18:30 | × | Lestat9 quits (~Admin1@47.203.239.77) (K-Lined) |
| 19:18:44 | × | housemate quits (~housemate@146.70.66.228) (Max SendQ exceeded) |
| 19:25:15 | <sm> | sure.. all old versions are stored on hackage |
| 19:31:55 | <c_wraith> | ... give or take some that had security issues so bad it was determined no one should ever use that version |
| 19:39:58 | <geekosaur> | even those are on hackage, just flagged as deprecated |
| 19:40:17 | <geekosaur> | hackage is immutable append-only storage |
| 19:46:32 | <lxsameer> | I just found out about bluefin, and omg it's much much clearer that effectful for me, kudos!!! |
| 19:47:03 | <shapr> | So far, only problem is that using cabal as the interpreter directive takes about two minutes on first run, ouch |
| 19:48:35 | → | ljdarj1 joins (~Thunderbi@user/ljdarj) |
| 19:50:47 | <c_wraith> | I recently made my CI cache the cabal index as well as built packages. Turns out it can load from the cache *marginally* faster than from hackage. |
| 19:51:08 | <shapr> | tiny blog post: https://www.scannedinavian.com/how-to-run-haskell-source-files-like-shell-scripts.html |
| 19:52:06 | × | ljdarj quits (~Thunderbi@user/ljdarj) (Ping timeout: 265 seconds) |
| 19:52:06 | ljdarj1 | is now known as ljdarj |
| 19:52:30 | × | weary-traveler quits (~user@user/user363627) (Remote host closed the connection) |
| 19:52:31 | → | mantraofpie_ joins (~mantraofp@user/mantraofpie) |
| 19:52:46 | → | CoolMa7 joins (~CoolMa7@ip5f5b8957.dynamic.kabel-deutschland.de) |
| 19:52:48 | <c_wraith> | I may need to look into using the partial-hackage-mirror script in the cache as well. |
| 19:53:26 | × | mantraofpie quits (~mantraofp@user/mantraofpie) (Ping timeout: 260 seconds) |
| 19:53:30 | → | chexum_ joins (~quassel@gateway/tor-sasl/chexum) |
| 19:53:46 | mantraofpie_ | is now known as mantraofpie |
| 19:54:01 | × | chexum quits (~quassel@gateway/tor-sasl/chexum) (Ping timeout: 260 seconds) |
| 19:54:39 | × | shapr quits (~user@2601:19c:417e:5434:4627:df70:3bf6:c2cb) (Quit: walkies) |
| 19:55:50 | <hellwolf> | Cabal scripts is convenient, you just need to be aware of the junks it leave behind: ~/.cabal/script-builds/. I wish it has a convenient way of running the script in interpreting mode though, without creating any artifacts. |
| 19:55:58 | <hellwolf> | that'd be even more "script-ish" |
| 19:57:14 | → | sprotte24 joins (~sprotte24@p200300d16f0f4e0080b9b718c313bb1e.dip0.t-ipconnect.de) |
| 19:57:56 | <lxsameer> | why don't you folks nix? out of curiosity |
| 19:59:37 | × | tromp quits (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…) |
| 19:59:45 | <lxsameer> | * use nix |
| 20:00:02 | <c_wraith> | I like the theory, but every time I've tried to use it it's been immensely more complexity than benefit |
| 20:00:03 | × | caconym quits (~caconym@user/caconym) (Quit: bye) |
| 20:00:43 | → | caconym joins (~caconym@user/caconym) |
| 20:00:44 | × | hellwolf quits (~user@da7f-daa3-a2f4-21df-0f00-4d40-07d0-2001.sta.estpak.ee) (Quit: rcirc on GNU Emacs 29.4) |
| 20:00:57 | <lxsameer> | c_wraith: how come? |
| 20:01:00 | <c_wraith> | (Not helped by attempting to use NixOS at one of the few times it actually was installing broken stuff. Not fair, but I still associate that experience with nix) |
| 20:01:02 | → | hellwolf joins (~user@da7f-daa3-a2f4-21df-0f00-4d40-07d0-2001.sta.estpak.ee) |
| 20:01:31 | <geekosaur> | cabal rebuilds on first run and when the script changes. sadly its solver is really slow; people are working on that, though |
| 20:01:56 | ← | hellwolf parts (~user@da7f-daa3-a2f4-21df-0f00-4d40-07d0-2001.sta.estpak.ee) () |
| 20:01:58 | <geekosaur> | stack is much faster because instead of using a solver it gets fixed versions from the snapshot and `extra-deps` |
| 20:02:00 | → | hellwolf joins (~user@da7f-daa3-a2f4-21df-0f00-4d40-07d0-2001.sta.estpak.ee) |
| 20:02:23 | <geekosaur> | (consider that a solver in thsi case is a constraint satisfaction solver, so yes, it's pretty slow) |
| 20:02:40 | <lxsameer> | c_wraith: ahh I see. I use nix with cabal, the good thing is I use nix packages and it's pretty fast |
| 20:03:27 | → | ash3en joins (~Thunderbi@193.32.248.167) |
| 20:05:09 | <statusbot> | Status update: Wiki.haskell.org is serving content again, but the upgrade is ongoing and various configs/css still need to be restored. -- http://status.haskell.org/pages/incident/537c07b0cf1fad5830000093/6728f5b530789205372a3361 |
| 20:05:37 | <lxsameer> | geekosaur: I use cabal freeze, and the nix uses that file to setup the env for me. so far so good |
| 20:06:29 | × | agent314 quits (~quassel@static-198-44-129-53.cust.tzulo.com) (Ping timeout: 260 seconds) |
| 20:06:57 | → | housemate joins (~housemate@146.70.66.228) |
| 20:07:48 | × | housemate quits (~housemate@146.70.66.228) (Max SendQ exceeded) |
| 20:08:36 | → | housemate joins (~housemate@146.70.66.228) |
| 20:09:08 | × | billchenchina quits (~billchenc@2a0d:2580:ff0c:1:e3c9:c52b:a429:5bfe) (Ping timeout: 245 seconds) |
| 20:10:57 | × | housemate quits (~housemate@146.70.66.228) (Max SendQ exceeded) |
| 20:11:11 | → | shapr joins (~user@4.30.215.226) |
| 20:11:21 | × | ezzieyguywuf quits (~Unknown@user/ezzieyguywuf) (Ping timeout: 246 seconds) |
| 20:12:40 | → | housemate joins (~housemate@146.70.66.228) |
| 20:12:50 | × | wootehfoot quits (~wootehfoo@user/wootehfoot) (Read error: Connection reset by peer) |
| 20:13:15 | <jle`> | thanks statusbot |
| 20:14:08 | → | machinedgod joins (~machinedg@d108-173-18-100.abhsia.telus.net) |
| 20:14:22 | <hellwolf> | nix + cabal freeze file is underrated |
| 20:14:44 | × | housemate quits (~housemate@146.70.66.228) (Remote host closed the connection) |
| 20:14:53 | <hellwolf> | I am a reproducibility maximalist. |
| 20:14:54 | → | weary-traveler joins (~user@user/user363627) |
| 20:15:54 | <hellwolf> | (in fairness stack freezes a set for you, too) |
| 20:15:59 | hellwolf | sometimes living on the edge |
| 20:16:11 | → | guy joins (~guy@2a01:4b00:d007:ed00:81c3:85aa:e2c9:6027) |
| 20:16:23 | <c_wraith> | aw, darn. the partial-hackage-mirror script only grabs packages. It doesn't thin the index data. |
| 20:16:44 | <guy> | hi! i have made a recording describing haskell as a "nonliner graphically complete programming language" |
| 20:16:46 | <guy> | https://voca.ro/14nNu3Nm5FaV |
| 20:16:57 | <guy> | i was wondering if anyne would like to take a listen and we could have a discussion |
| 20:17:18 | <sm> | shapr: nice post. What's cabal doing in the two minutes ? |
| 20:18:29 | <shapr> | sm: I haven't looked, and I didn't see anything obvious in the docs for `cabal run` |
| 20:18:53 | <shapr> | sm: I'd guess it's doing `cabal update` and then `cabal build` but I wouldn't expect it to take that long? |
| 20:19:13 | <c_wraith> | two minutes is not improbable for `cabal update` with no previous state to add to |
| 20:19:16 | <hellwolf> | @shapr, you can use "#!/usr/bin/env -S cabal run -v1" |
| 20:19:16 | <lambdabot> | Unknown command, try @list |
| 20:19:20 | <hellwolf> | shapr, you can use "#!/usr/bin/env -S cabal run -v1" |
| 20:19:35 | <hellwolf> | or -v2 |
| 20:20:06 | <hellwolf> | most likely, it was building packages that you hadn't built for that version of GHC |
| 20:20:41 | <shapr> | Yeah, since I'm using NixOS and a just-created empty environment with `nix |
| 20:20:43 | <sm> | `stack script` can also take minutes, possibly many minutes, the first time you run a script, and it might appear hung for part of that time; adding --verbosity=info to the shebang line shows more progress output. Like cabal it could be building half of hackage (say your script uses pandoc or hakyll :). Unlike cabal it could be installing GHC, as well. |
| 20:20:43 | <shapr> | oops |
| 20:20:56 | <shapr> | `nix-shell -p cabal-install ghc` is what I used to test this. |
| 20:21:12 | <shapr> | sm: good point |
| 20:21:17 | → | guy15 joins (~guy@2a01:4b00:d007:ed00:81c3:85aa:e2c9:6027) |
| 20:21:35 | guy15 | is now known as guy_ |
| 20:21:38 | <guy_> | feel free to open up a dm conversation if your listening along and i can answer any questions you might want to keep off the main channel, otherwise i guess ill wait for about 20 mins to see if anyone makes it to the end of the voice note, and if anyone enjoys the theory and is interested in the work im doing |
| 20:21:41 | <sm> | more stack trivia: don't miss `stack script --compile`, which will auto (re)compile the script, or run the compiled version if it already exists, for instant startup |
| 20:22:07 | <guy_> | (here for anyone that cant see the scrollup https://vocaroo.com/14nNu3Nm5FaV) |
| 20:22:22 | <shapr> | guy_: I comprehend text the fastest, is there a transcript? |
| 20:22:22 | <c_wraith> | pandoc and hakyll are... yeah. I patched hakyll to not accidentally build warp in CI (why did that need a patch?) and ripped pandoc out of the build pipeline entirely. |
| 20:22:43 | shapr | worriedly checks his blog dependencies |
| 20:22:51 | <guy_> | shapr: not currently! it would be good if i had a voice to text tool, does anyone have a good tool for this? |
| 20:23:21 | <guy_> | it would be good to see what a GPT has to say on the subject |
| 20:23:33 | <shapr> | I don't have such a tool handy. |
| 20:23:34 | <c_wraith> | shapr: you might luckily be on an older version of hakyll that didn't accidentally build warp for a single data type import! |
| 20:23:53 | <haskellbridge> | <Bowuigi> guy_ The Whisper models are good |
| 20:23:55 | × | ash3en quits (~Thunderbi@193.32.248.167) (Quit: ash3en) |
| 20:23:59 | <sm> | c_wraith: similar - I abandoned hakyll and now always use pandoc via cli rather than importing |
| 20:24:03 | <guy_> | yeah, sorry about the format, thats currently the only available description i have |
| 20:24:29 | <guy_> | thanks haskellbridge, ill have a see if i can find an easy interface to see if i can get a trascript together |
| 20:25:03 | <haskellbridge> | <Bowuigi> There's a faster whisper project somewhere, lemme find the link |
| 20:25:08 | <c_wraith> | I thought about using shake instead of hakyll, but even for a small amount of code the porting process seemed huge. |
| 20:25:13 | × | guy quits (~guy@2a01:4b00:d007:ed00:81c3:85aa:e2c9:6027) (Ping timeout: 256 seconds) |
| 20:25:29 | <sm> | shake is what I switched to, I love it |
| 20:26:03 | <shapr> | I am using pandoc to convert org-mode to html, but it's not pulling in warp, whew. |
| 20:26:07 | <sm> | with a few caveats, like you can have only one shake file in a project directory and can run it only once at a time |
| 20:26:09 | <guy_> | hmm.. whisper is in pythos so thats inaccessible to me, i can find this blog post about a sort of haskell port |
| 20:26:09 | <guy_> | https://www.reddit.com/r/haskell/comments/102bxc1/voice_assistant_app_in_haskell/ |
| 20:26:14 | <guy_> | python* |
| 20:28:04 | <c_wraith> | also, I never really used make, so the process of learning how to use shake seemed large. Much of shake's documentation is very "you already know how to use make"-oriented. |
| 20:28:42 | <guy_> | says it only builds out of the box with nixos... https://gitlab.com/ludflu/vad-audio |
| 20:29:13 | <guy_> | never mind! it would be most simple if people could just listen to the recording, save the the hassle! https://vocaroo.com/14nNu3Nm5FaV |
| 20:30:00 | <guy_> | im going afk for ~20 mins to give people time to listen through, see you at about 10 too |
| 20:30:33 | <haskellbridge> | <Bowuigi> Yeah that's easier, otherwise try https://github.com/ggerganov/whisper.cpp which is not Python but C++ |
| 20:31:19 | <sm> | c_wraith I hear that. Even if you know make, Shake is not exactly a walk in the park to program, especially if you're not using regularly. |
| 20:31:48 | <sm> | but anything I have implemented in it has been rock solid and I never had to worry about it again |
| 20:31:58 | <c_wraith> | But it's not like I'm short on free time these days. I should take another shot at it. |
| 20:32:12 | → | peterbecich joins (~Thunderbi@syn-047-229-123-186.res.spectrum.com) |
| 20:33:01 | <sm> | https://github.com/simonmichael/hledger/blob/master/Shake.hs |
| 20:34:42 | <sm> | shapr: stack script example, if you want one ^ |
| 20:36:20 | <guy_> | https://neilmitchell.blogspot.com/2021/09/reflecting-on-shake-build-system.html |
| 20:38:38 | <shapr> | sm: I'll pitch that link into the poscript. Also, I linked to your mastodon in the post, do you have some other preferred link target? |
| 20:39:59 | <shapr> | guy_: oui, c'est ca |
| 20:40:19 | <shapr> | I should stick to Swedish, my French has rusted away. |
| 20:40:23 | <guy_> | https://www.reddit.com/r/haskell/comments/i97lz7/is_there_something_similar_to_hakyll_using_shake/ |
| 20:40:24 | <guy_> | this links; |
| 20:40:24 | <guy_> | rib (as a static site generator - sounds like a good alternative to hakyll) https://github.com/srid/rib |
| 20:40:25 | <guy_> | and |
| 20:40:25 | <guy_> | https://github.com/ChrisPenner/slick (which claims to be a simpler alternative to hakyll/jekyll) |
| 20:41:05 | <shapr> | Oh speaking of hakyll, I had a feature request to include the blog post body in my RSS feed. |
| 20:41:08 | <guy_> | the moustache specification markup seems interesting |
| 20:41:21 | <sm> | nice link guy_. I'd love to see Neil's latest build system, whatever it is |
| 20:41:35 | <guy_> | yeah, i wonder what he's up too! |
| 20:41:38 | <sm> | shapr thanks! https://joyful.com is the other |
| 20:41:59 | <sm> | probably not needed |
| 20:42:12 | <guy_> | sm: dead link |
| 20:42:40 | <sm> | holy.... ! thanks! |
| 20:42:49 | <guy_> | iv been away from the haskell comunity for a while, working on AGI research with sam altman and lex fridman |
| 20:42:51 | <guy_> | its been a blast |
| 20:43:08 | <shapr> | sm: oh no, website down? |
| 20:43:21 | <guy_> | just visiting #haskell to give some of this theory about "functor sheduling" and the implications it has on the haskell prelude |
| 20:43:28 | <sm> | Up but nicely blank. I didn't think you had to monitor a static website 😂 |
| 20:43:43 | <guy_> | "nonlinear graphically complete languages" i think is a really strong result |
| 20:44:03 | <guy_> | just off the back of some abstraction i developed for mixture models for the AGI |
| 20:44:30 | <sm> | guy_ maybe worth a post on the haskell discourse / reddit, you might get more input |
| 20:44:45 | <guy_> | the people i want to reach are right here im sure |
| 20:44:55 | <sm> | the idle chatters ? :) |
| 20:44:56 | <guy_> | kind of shy to release a voice note on the open internets |
| 20:45:32 | <sm> | the thing about a 20m voice memo is nobody has time for it probably, unless they know you / your work |
| 20:45:52 | <sm> | a youtube would get more listens |
| 20:45:54 | <guy_> | sm: i was kind of hoping someone could help me cobble it together for a PhD proposal im trying to submit to philip wadler. he insists he wont supervise anything to do with scientific computation, so im trying to make it a pure language consideration |
| 20:46:39 | <guy_> | sm: i used to chat here under the names fog and fen. i was often kicked for giving walls of text on the seti/geti methodology, so i thought a voice note would at least save the users from the normal deluge |
| 20:47:03 | <guy_> | here is the link again if anyones interest is piqued https://vocaroo.com/14nNu3Nm5FaV |
| 20:48:00 | <sm> | well, welcome back and thanks for not deluging :) |
| 20:48:05 | <guy_> | :-) |
| 20:49:39 | → | emfrom joins (~emfrom@78.243.183.111) |
| 20:51:07 | <shapr> | I love using nix to re-compile my blog on my beefy laptop and push only the compiled result to my server. Fast and easy updates are pleasant. |
| 20:53:32 | <guy_> | sounds like hotswapping... i was trying to use nix-copy-closure for this |
| 20:53:49 | <shapr> | yeah, similar |
| 20:54:12 | <shapr> | Would be nice if nixos ran on Erlang and I could do real hotswap |
| 20:55:13 | <c_wraith> | you can't really do perfect hot-swap of web sites anyway, unless every deploy has a different URL... and that's really bad for bookmarks. |
| 20:57:21 | <guy_> | i was talking to simon marlow about his work in hotswapping at facebook, i cant find much online but there is this |
| 20:57:21 | <guy_> | https://www.reddit.com/r/haskell/comments/1le4y5/the_haxl_project_at_facebook_slides_from_my_talk/ |
| 20:58:25 | <guy_> | it was dealing with the kind of issues where you might eg, have a saved data lib relavent to a previous build, and it somehow did some fancy versioning history to ensure reproducability, but the details escape me |
| 20:59:14 | <guy_> | like if you have a read and show instance for a save, but you change the datatype... |
| 21:00:09 | <guy_> | something like including the versioning considerations to ensure robust hotswapping... all very complicated, must have been about 7 years ago |
| 21:01:59 | <guy_> | ... |
| 21:03:26 | × | shapr quits (~user@4.30.215.226) (Ping timeout: 252 seconds) |
| 21:03:32 | <guy_> | so, its been about 20 mins since i linked the vocarro voice note (https://vocaroo.com/14nNu3Nm5FaV). has anyone had a chance to listen / is listening |
| 21:04:04 | <guy_> | would be cool to field some questions while i have it fresh in my memory |
| 21:05:01 | <haskellbridge> | <Bowuigi> Definitely interesting but I don't know enough graph theory to understand it lol |
| 21:05:47 | <guy_> | darn. i was hoping it was accessible |
| 21:07:23 | × | youthlic quits (~Thunderbi@user/youthlic) (Remote host closed the connection) |
| 21:07:25 | <haskellbridge> | <Bowuigi> I think it's fine though, my knowledge of graph theory is pretty much just the definitions of a graph and a DAG |
| 21:07:49 | → | youthlic joins (~Thunderbi@user/youthlic) |
| 21:07:49 | × | youthlic quits (~Thunderbi@user/youthlic) (Remote host closed the connection) |
| 21:08:14 | → | youthlic joins (~Thunderbi@user/youthlic) |
| 21:08:19 | <guy_> | i was hoping that the term "graphically complete language" would become widespread so that haskell could be exeplary as such |
| 21:08:22 | → | alphazone_ joins (~alphazone@2.219.56.221) |
| 21:08:53 | <guy_> | i didnt realise at the time there was this more complicated idea of the "graphically complete language" being *nonlinear* owing to local scoping considerations |
| 21:10:29 | <guy_> | the turing completeness is basically to do with the "linear"ization of the graph, putting it into a turing machine on a 1d (liniarized) turing tape. when you have local scoping, its something like a violation of the 1-1 nature of the traversable laws. i thought it was super interesting! |
| 21:11:11 | <guy_> | (thats a pretty good tldr tbh) |
| 21:11:12 | × | alphazone quits (~alphazone@2.219.56.221) (Ping timeout: 246 seconds) |
| 21:12:42 | <guy_> | like "if the variable x corresponds to some Int label on the turing tape, what happens when you locally reasign x within a local scope" |
| 21:12:43 | <guy_> | this kind of overwrite / reuse of a restricted cache of variable names is basically amounting to some "nonliner" concept |
| 21:13:13 | <guy_> | you end up getting something like seti+geti+rewrites |
| 21:14:02 | <guy_> | overwrites* (rewite is a protected word to do with dereferencing and the program monad) |
| 21:14:16 | <guy_> | but i dont want to ramble... thats why i made the voice note! |
| 21:15:43 | → | mange joins (~user@user/mange) |
| 21:16:08 | <guy_> | if anyone has any specific questions i can answer then it would avoid the ire of the moderator! |
| 21:16:48 | × | peterbecich quits (~Thunderbi@syn-047-229-123-186.res.spectrum.com) (Ping timeout: 246 seconds) |
| 21:18:22 | <guy_> | also, anyone interested in the AGI stuff can shoot me a DM aswell |
| 21:20:17 | × | lxsameer quits (~lxsameer@Serene/lxsameer) (Ping timeout: 252 seconds) |
| 21:21:02 | × | machinedgod quits (~machinedg@d108-173-18-100.abhsia.telus.net) (Ping timeout: 252 seconds) |
| 21:22:21 | × | dolio quits (~dolio@130.44.140.168) (Quit: ZNC 1.9.1 - https://znc.in) |
| 21:22:33 | <haskellbridge> | <Bowuigi> So linear here is not the type theoretic linearity right? |
| 21:26:17 | × | manwithluck quits (manwithluc@gateway/vpn/protonvpn/manwithluck) (Remote host closed the connection) |
| 21:26:42 | → | manwithluck joins (manwithluc@gateway/vpn/protonvpn/manwithluck) |
| 21:26:55 | → | machinedgod joins (~machinedg@d108-173-18-100.abhsia.telus.net) |
| 21:28:10 | <haskellbridge> | <Bowuigi> Oh also make a blog and post the usual introductory stuff there, way more compact and easier to follow |
| 21:28:29 | <haskellbridge> | <Bowuigi> I wanted to do that for my research but I got too lazy lol |
| 21:30:12 | → | dolio joins (~dolio@130.44.140.168) |
| 21:30:47 | <guy_> | too lazy!? |
| 21:31:02 | <guy_> | are you sure its not the ol' "not the secret societies responsibility" argument! |
| 21:31:17 | <guy_> | i was hopeing the advances in transparency and open society would maybe percolate through |
| 21:31:33 | × | CrunchyFlakes quits (~CrunchyFl@ip1f13e94e.dynamic.kabel-deutschland.de) (Quit: ZNC 1.8.2 - https://znc.in) |
| 21:31:53 | <guy_> | im always looking for keen people that can offer their services. better than being completely invisabailised imo |
| 21:32:52 | <guy_> | "type theoretic linearity". no thats about some kind of strict purity, right? like, variables used exactly once and then deleted? |
| 21:32:56 | → | shapr joins (~user@2601:19c:417e:5434:b5b7:a31:f560:51b7) |
| 21:33:09 | <guy_> | that was something i think we were working on in terms of a "strictly stateful" functional programming language |
| 21:33:29 | <guy_> | like how haskell has "all functions are bivariate functions" where partial application can return a new bivariate function |
| 21:33:53 | <guy_> | but now instead of a bivariate function a -> b, its the stateful function; s -> a -> (s,b) |
| 21:34:13 | <guy_> | since you can always have s~() you can basically make a totally stateful language |
| 21:34:29 | <guy_> | i think the "type theoretic linearity" can be used to great effect here, but i forget how! |
| 21:35:16 | <guy_> | (s,s->a->(s,b)) actually, since you need the state aswell |
| 21:35:34 | <guy_> | and then its weird because your functions are replaced by something that has concrete and variable data associated |
| 21:36:02 | <guy_> | i think basically, because the state is updated each time, thats where the linearity comes in |
| 21:36:10 | <guy_> | but yeah, totally different concept of linearity |
| 21:36:28 | <guy_> | its more like basically "because its foldable there is a toList" so its "linearizable" |
| 21:37:00 | <guy_> | seti+geti are abstractions extending around pattern matching on (:) where you get an extra piece of data |
| 21:37:36 | <guy_> | so when you put it into a list, with each value having the structure directing information aswell, then you can put it back from a list and rebuild the graph. like folding through the list with the seti constructor |
| 21:37:54 | <guy_> | the point here is that you can also overwrite data ie, have the same position mentioned several times |
| 21:38:13 | <guy_> | this is where the idea of "functor scheduling" which might not have visitation of each element only once |
| 21:38:27 | <guy_> | breaks the traversal laws and introduces the concept of "nonlinearity" |
| 21:38:34 | <guy_> | woot, i think i gave the text based version |
| 21:38:39 | <guy_> | stopping now for the deluge. |
| 21:38:41 | <guy_> | peace x |
| 21:38:42 | × | guy_ quits (~guy@2a01:4b00:d007:ed00:81c3:85aa:e2c9:6027) (Quit: Client closed) |
| 21:39:34 | → | guy joins (~guy@2a01:4b00:d007:ed00:81c3:85aa:e2c9:6027) |
| 21:43:53 | → | vanishingideal joins (~vanishing@user/vanishingideal) |
| 21:44:03 | <guy> | chatGPT does an okish job of groking the summary. but i think its way infirior to the voice note |
| 21:44:04 | <guy> | https://chatgpt.com/share/67366f04-9d30-800b-82c2-fe23ab9d5e09 |
| 21:45:10 | × | guy quits (~guy@2a01:4b00:d007:ed00:81c3:85aa:e2c9:6027) (Quit: Client closed) |
| 21:46:42 | × | dolio quits (~dolio@130.44.140.168) (Ping timeout: 252 seconds) |
| 21:51:00 | <haskellbridge> | <Bowuigi> Hmmm I think I get it now |
| 21:51:46 | <haskellbridge> | <Bowuigi> Yeah you definitely need a blog lol |
| 21:52:25 | × | Smiles quits (uid551636@id-551636.lymington.irccloud.com) (Quit: Connection closed for inactivity) |
| 21:57:14 | → | dolio joins (~dolio@130.44.140.168) |
| 21:58:28 | × | gorignak quits (~gorignak@user/gorignak) (Quit: quit) |
| 21:58:54 | → | JuanDaugherty joins (~juan@user/JuanDaugherty) |
| 22:06:25 | → | Everything joins (~Everythin@178-133-104-20.mobile.vf-ua.net) |
| 22:06:47 | → | peterbecich joins (~Thunderbi@syn-047-229-123-186.res.spectrum.com) |
| 22:12:41 | <carbolymer> | what's the difference between Foo1 and Foo2 here: https://paste.tomsmeding.com/HEZo1ic4 ? aren't they expressing the same thing basically? |
| 22:13:10 | → | tromp joins (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) |
| 22:16:00 | × | mc47 quits (~mc47@xmonad/TheMC47) (Remote host closed the connection) |
| 22:17:36 | → | CoolMa7_ joins (~CoolMa7@ip5f5b8957.dynamic.kabel-deutschland.de) |
| 22:19:15 | × | CoolMa7 quits (~CoolMa7@ip5f5b8957.dynamic.kabel-deutschland.de) (Ping timeout: 244 seconds) |
| 22:19:37 | → | gorignak joins (~gorignak@user/gorignak) |
| 22:21:47 | × | takuan quits (~takuan@178-116-218-225.access.telenet.be) (Remote host closed the connection) |
| 22:22:02 | × | peterbecich quits (~Thunderbi@syn-047-229-123-186.res.spectrum.com) (Ping timeout: 255 seconds) |
| 22:23:09 | × | CoolMa7_ quits (~CoolMa7@ip5f5b8957.dynamic.kabel-deutschland.de) (Remote host closed the connection) |
| 22:24:36 | × | emfrom quits (~emfrom@78.243.183.111) (Remote host closed the connection) |
| 22:37:39 | <geekosaur> | they are, and yes, they're essentially identical. one uses a functional dependency to establish a relationship between types, the other a type family that is associated with the typeclass ("associated type family") |
| 22:38:08 | <geekosaur> | many people consider the latter mroe principled, but functional dependencies have been around longer and most standard libraries still use them |
| 22:39:47 | <shapr> | geekosaur: do you think type families are more principled? |
| 22:40:22 | <geekosaur> | I think in some sense they fit Haskell better, because fundeps are a chunk of Prolog imported into the type system |
| 22:40:32 | shapr | thinks about that |
| 22:40:45 | <geekosaur> | I'm not sure they're more principled, since I'm not really a type theory or type level wonk |
| 22:40:56 | <shapr> | yeah, just curious what you thought |
| 22:41:50 | × | xff0x quits (~xff0x@ai080132.d.east.v6connect.net) (Ping timeout: 255 seconds) |
| 22:41:52 | <geekosaur> | I do sometimes wonder what the Haskell ecosystem would look like now if monads-tf had won out over monads-fd as the successor to mtl1 |
| 22:42:21 | × | Everything quits (~Everythin@178-133-104-20.mobile.vf-ua.net) (Ping timeout: 252 seconds) |
| 22:42:29 | × | michalz quits (~michalz@185.246.207.203) (Remote host closed the connection) |
| 22:42:52 | <geekosaur> | (IIRC there were a few problems with type families back then that meant the mtl folks went with monads-fd, including a bug in older ghcs) |
| 22:43:10 | <geekosaur> | (and maybe a performance issue) |
| 22:43:48 | <geekosaur> | …but that was over a decade ago. maybe it's time for mtl3: the type families edition |
| 22:44:02 | → | Everything joins (~Everythin@178-133-104-20.mobile.vf-ua.net) |
| 22:44:19 | <shapr> | The Revenge of, uh, something |
| 22:44:30 | <jackdk> | Just yesterday I wanted to turn a relation expressed in fundeps into a type-family-shaped thing and the best suggestion I got was "don't, pick over the type using generics instead" |
| 22:44:44 | <geekosaur> | I mean, we've already ditched backward compatibility in so many other ways, anyone who wants to stay with mtl+fundeps can keep using mtl2 |
| 22:45:01 | <geekosaur> | huh |
| 22:45:19 | <geekosaur> | does this mean there are still some issues with tyfams? |
| 22:45:26 | × | JuanDaugherty quits (~juan@user/JuanDaugherty) (Quit: JuanDaugherty) |
| 22:45:32 | <jackdk> | I had hoped that there was a decent idiom for writing a type family that could compute z from `class Foo x y z | x y -> z` but nobody could tell me one |
| 22:45:53 | <geekosaur> | (aside from the big one, that ghc isn't going to get actual type lambdas that way possibly ever) |
| 22:48:22 | × | tromp quits (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…) |
| 22:48:37 | <carbolymer> | thanks geekosaur. I've found some resources on tf vs fd: |
| 22:48:37 | <carbolymer> | https://gitlab.haskell.org/ghc/ghc/-/wikis/tf-vs-fd |
| 22:48:37 | <carbolymer> | https://wiki.haskell.org/Functional_dependencies_vs._type_families |
| 22:49:53 | <carbolymer> | jackdk: well why not: |
| 22:49:53 | <carbolymer> | class Foo' x y where |
| 22:49:53 | <carbolymer> | F x y :: Type |
| 22:50:18 | <carbolymer> | or `class (F x y ~ z) => Foo x y z where F x y :: Type` |
| 22:54:44 | → | xff0x joins (~xff0x@2405:6580:b080:900:4913:54f9:72cb:8a89) |
| 23:03:51 | <jackdk> | carbolymer: I don't understand your suggestion. The typeclass I want to type-family-ify exists and I cannot change it (concrete example: `GHC.Records.HasField`), but I want a type family that can select the field type. This example fails with "The RHS of an associated type declaration mentions out-of-scope variable ‘z’ All such variables must be bound on the LHS" https://www.irccloud.com/pastebin/4aygJmq9/MakeATypeFamily.hs |
| 23:06:26 | → | rvalue- joins (~rvalue@user/rvalue) |
| 23:07:19 | × | rvalue quits (~rvalue@user/rvalue) (Ping timeout: 260 seconds) |
| 23:10:34 | rvalue- | is now known as rvalue |
| 23:19:05 | <carbolymer> | jackdk: ah, you can't modify the original class - that' s though |
| 23:20:06 | <carbolymer> | s/though/tough |
| 23:24:54 | × | nek0 quits (~nek0@user/nek0) (Quit: The Lounge - https://thelounge.chat) |
| 23:26:44 | <carbolymer> | jackdk: maybe something in this direction https://paste.tomsmeding.com/Og2LnIpN ? |
| 23:29:03 | <jackdk> | The problem is I didn't know `a` at the time. (I was trying to write some servant-flavoured stuff, and wanted to provide an analogue to `ToServantApi` that extracted a single field). So I don't actually know the final type (because there are other TFs involved) but I know GHC does |
| 23:30:01 | × | aljazmc quits (~aljazmc@user/aljazmc) (Remote host closed the connection) |
| 23:30:32 | <carbolymer> | ah |
| 23:31:05 | → | ljdarj1 joins (~Thunderbi@user/ljdarj) |
| 23:34:10 | × | ljdarj quits (~Thunderbi@user/ljdarj) (Ping timeout: 244 seconds) |
| 23:34:10 | ljdarj1 | is now known as ljdarj |
| 23:41:13 | × | acidjnk quits (~acidjnk@p200300d6e7283f73687bc11ede7922f8.dip0.t-ipconnect.de) (Ping timeout: 245 seconds) |
| 23:45:54 | × | jle` quits (~jle`@2603:8001:3b02:84d4:71c9:147c:d31f:c8d0) (Ping timeout: 246 seconds) |
| 23:47:05 | → | jle` joins (~jle`@2603:8001:3b02:84d4:4ba:cd34:52ca:7a5) |
| 23:48:36 | <sm> | @where+ wiwik https://gotchamana.github.io/wiwinwlh What I Wish I Knew When Learning Haskell, Stephen Diehl |
| 23:48:37 | <lambdabot> | Good to know. |
| 23:48:39 | <sm> | found! |
| 23:49:10 | → | arthurvl joins (~arthurvl@77-174-49-144.fixed.kpn.net) |
| 23:56:35 | → | peterbecich joins (~Thunderbi@syn-047-229-123-186.res.spectrum.com) |
All times are in UTC on 2024-11-14.