Home liberachat/#haskell: Logs Calendar

Logs on 2024-03-23 (liberachat/#haskell)

00:11:01 peterbecich joins (~Thunderbi@047-229-123-186.res.spectrum.com)
00:23:48 clairejoseph joins (~clairejos@69.80.12.40)
00:35:34 × peterbecich quits (~Thunderbi@047-229-123-186.res.spectrum.com) (Ping timeout: 255 seconds)
00:48:15 × waleee quits (~waleee@h-176-10-144-38.NA.cust.bahnhof.se) (Ping timeout: 272 seconds)
00:50:46 waleee joins (~waleee@h-176-10-144-38.NA.cust.bahnhof.se)
00:57:12 × clairejoseph quits (~clairejos@69.80.12.40) (Ping timeout: 250 seconds)
01:00:30 sroso joins (~sroso@user/SrOso)
01:13:58 × mmhat quits (~mmh@p200300f1c706a2a9ee086bfffe095315.dip0.t-ipconnect.de) (Quit: WeeChat 4.2.1)
01:15:35 × euleritian quits (~euleritia@77.22.252.56) (Read error: Connection reset by peer)
01:23:59 × mima quits (~mmh@aftr-62-216-211-172.dynamic.mnet-online.de) (Ping timeout: 252 seconds)
01:27:28 vnogueira_ joins (~vnogueira@user/vnogueira)
01:28:26 × vnogueira quits (~vnogueira@user/vnogueira) (Ping timeout: 260 seconds)
01:28:53 machinedgod joins (~machinedg@d173-183-246-216.abhsia.telus.net)
01:31:02 × qeef quits (~qeef@138-169-143-94.cust.centrio.cz) (Ping timeout: 264 seconds)
01:36:15 × vnogueira_ quits (~vnogueira@user/vnogueira) (Remote host closed the connection)
01:36:34 vnogueira joins (~vnogueira@user/vnogueira)
01:37:40 qeef joins (~qeef@138-169-143-94.cust.centrio.cz)
01:49:16 peterbecich joins (~Thunderbi@047-229-123-186.res.spectrum.com)
02:14:36 × qeef quits (~qeef@138-169-143-94.cust.centrio.cz) (Ping timeout: 252 seconds)
02:27:14 × otto_s quits (~user@p4ff277d6.dip0.t-ipconnect.de) (Ping timeout: 252 seconds)
02:28:49 euleritian joins (~euleritia@77.22.252.56)
02:29:12 otto_s joins (~user@p5b04451e.dip0.t-ipconnect.de)
02:37:47 son0p joins (~ff@152.203.80.45)
03:02:07 × peterbecich quits (~Thunderbi@047-229-123-186.res.spectrum.com) (Ping timeout: 260 seconds)
03:02:29 benkard joins (~mulk@p5b2dc71d.dip0.t-ipconnect.de)
03:03:26 × mulk quits (~mulk@p5b112e7d.dip0.t-ipconnect.de) (Ping timeout: 264 seconds)
03:03:26 benkard is now known as mulk
03:11:48 × komikat quits (~akshitkr@218.185.248.66) (Ping timeout: 252 seconds)
03:11:50 × komikat_ quits (~akshitkr@218.185.248.66) (Ping timeout: 264 seconds)
03:19:38 × mik3d quits (~mik3d@pool-173-61-131-199.cmdnnj.fios.verizon.net) (Remote host closed the connection)
03:34:29 × chiselfuse quits (~chiselfus@user/chiselfuse) (Remote host closed the connection)
03:34:48 bitdex joins (~bitdex@gateway/tor-sasl/bitdex)
03:39:06 × bitdex quits (~bitdex@gateway/tor-sasl/bitdex) (Remote host closed the connection)
03:40:07 bitdex joins (~bitdex@gateway/tor-sasl/bitdex)
03:40:15 chiselfuse joins (~chiselfus@user/chiselfuse)
03:41:12 × ec quits (~ec@gateway/tor-sasl/ec) (Remote host closed the connection)
03:41:46 ec joins (~ec@gateway/tor-sasl/ec)
03:44:14 × td_ quits (~td@i5387092D.versanet.de) (Ping timeout: 264 seconds)
03:45:44 td_ joins (~td@i53870906.versanet.de)
03:46:11 × waleee quits (~waleee@h-176-10-144-38.NA.cust.bahnhof.se) (Ping timeout: 245 seconds)
03:52:14 × szkl quits (uid110435@id-110435.uxbridge.irccloud.com) (Quit: Connection closed for inactivity)
04:03:49 sadie_ joins (~sadie@c-76-155-235-153.hsd1.co.comcast.net)
04:04:05 peterbecich joins (~Thunderbi@047-229-123-186.res.spectrum.com)
04:08:23 aforemny_ joins (~aforemny@i59F516EB.versanet.de)
04:09:18 × aforemny quits (~aforemny@2001:9e8:6ce7:be00:a07f:df32:373b:9c12) (Ping timeout: 255 seconds)
04:18:48 Guest52 joins (~Guest52@185.57.29.142)
04:45:28 × Square quits (~Square@user/square) (Ping timeout: 268 seconds)
05:02:06 ddellacosta joins (~ddellacos@ool-44c73d16.dyn.optonline.net)
05:12:54 × pastly quits (~pastly@gateway/tor-sasl/pastly) (Ping timeout: 260 seconds)
05:15:54 harveypwca joins (~harveypwc@2601:246:c200:2740:15b6:f225:14ff:9821)
05:21:34 pastly joins (~pastly@gateway/tor-sasl/pastly)
05:23:31 falafel joins (~falafel@2607:fb91:8aa:877b:e203:1c7d:5ebc:b59)
05:23:42 × Guest52 quits (~Guest52@185.57.29.142) (Ping timeout: 250 seconds)
05:29:34 × ddellacosta quits (~ddellacos@ool-44c73d16.dyn.optonline.net) (Quit: WeeChat 4.2.1)
05:33:41 × machinedgod quits (~machinedg@d173-183-246-216.abhsia.telus.net) (Ping timeout: 245 seconds)
06:10:02 × sroso quits (~sroso@user/SrOso) (Ping timeout: 264 seconds)
06:12:17 sroso joins (~sroso@user/SrOso)
06:17:11 × falafel quits (~falafel@2607:fb91:8aa:877b:e203:1c7d:5ebc:b59) (Ping timeout: 260 seconds)
06:21:51 takuan joins (~takuan@178-116-218-225.access.telenet.be)
06:29:06 gmg joins (~user@user/gehmehgeh)
06:30:08 zetef joins (~quassel@2a02:2f00:500b:ce00:aba1:3782:4e7c:41a)
06:31:57 <Inst> any people do prolog here?
06:32:15 <Inst> do you know if there's a way to multiply declare, i.e, state multiple facts to a predicate?
06:36:46 × gmg quits (~user@user/gehmehgeh) (Remote host closed the connection)
06:37:29 gmg joins (~user@user/gehmehgeh)
06:43:50 <Inst> ummm, back to Hasklel
06:43:52 <Inst> Haskell
06:44:28 <Inst> is for_ [1..100] \item -> print item intrinsically slow?
06:44:38 <Inst> because I know Haskell tends to be a bit slower with monadic effects
06:45:25 <mauke> shouldn't be
06:48:13 <Inst> using some time benchmarking
06:48:32 <Inst> 17 ms to for_ through 100 items
06:48:39 × Sgeo quits (~Sgeo@user/sgeo) (Read error: Connection reset by peer)
06:48:48 <Inst> python takes 53 ms, which is how it should be :3
06:48:55 <Inst> just, ghci :(
06:50:12 <Inst> wish someone would pay for an equivalent to utop :3
06:52:19 × bilegeek quits (~bilegeek@2600:1008:b04f:ac16:241:4e7b:fce9:569f) (Quit: Leaving)
07:00:30 × euleritian quits (~euleritia@77.22.252.56) (Read error: Connection reset by peer)
07:00:52 euleritian joins (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de)
07:01:33 <Inst> ouch, ocaml does it in 6 ms :(
07:06:20 <c_wraith> I mean, print *is* slow
07:07:01 <c_wraith> both show and putStrLn are not the fastest.
07:09:57 × adanwan_ quits (~adanwan@gateway/tor-sasl/adanwan) (Remote host closed the connection)
07:10:22 adanwan joins (~adanwan@gateway/tor-sasl/adanwan)
07:10:26 tromp joins (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl)
07:13:33 <sadie_> perhaps it's faster with Data.Text(.IO)
07:22:51 × zetef quits (~quassel@2a02:2f00:500b:ce00:aba1:3782:4e7c:41a) (Ping timeout: 245 seconds)
07:25:57 acidjnk joins (~acidjnk@p200300d6e70d3f39710acbcd8de4867e.dip0.t-ipconnect.de)
07:26:51 × tromp quits (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…)
07:28:56 todi joins (~todi@p57803331.dip0.t-ipconnect.de)
07:32:06 derpyxdhs joins (~Thunderbi@user/derpyxdhs)
07:35:41 × jrm quits (~jrm@user/jrm) (Quit: ciao)
07:36:07 jrm joins (~jrm@user/jrm)
07:36:37 <Inst> c does it in 3 seconds
07:36:42 <Inst> there's probably going to be a spoolup for RTS as well
07:36:53 <c_wraith> eh, it's miniscule.
07:37:04 <c_wraith> the problem is the combination of show and putStrLn
07:37:11 <c_wraith> they are both *slow*
07:37:58 × derpyxdhs quits (~Thunderbi@user/derpyxdhs) (Quit: derpyxdhs)
07:38:00 <Inst> oh
07:38:05 <Inst> maybe it's because I'm getting defaults to integer?
07:38:10 <c_wraith> no
07:38:15 <c_wraith> it's because of show and putStrLn
07:41:03 <Inst> I don't think so, change it to for_ ['0'..'9'] putChar
07:41:10 <Inst> still 16 ms
07:41:26 <c_wraith> yes, part of why putStrLn is so slow is that it calls putChar
07:41:59 <Inst> no, but the number of iterations was reduced from 100 to 10
07:42:03 <Inst> still same time
07:42:24 <c_wraith> Oh, maybe you're on an older version of GHC that doesn't quit immediately
07:42:38 <c_wraith> I think until the last release, it would wait a while before quitting.
07:43:30 <Inst> currently running 9.6.3
07:43:53 <c_wraith> that's definitely before the fix
07:44:33 <Inst> set to 9.8.1
07:45:28 <Inst> i loled
07:45:31 <Inst> 0.03 seconds
07:45:38 <Inst> erm, 3 ms, rather
07:45:40 target_i joins (~target_i@user/target-i/x-6023099)
07:46:18 <c_wraith> ah, that's better
07:46:32 <Inst> so roughly same order of magnitude now as ocaml
07:48:16 <ski> Inst : "do you know if there's a way to multiply declare, i.e, state multiple facts to a predicate?" -- just do it ?
07:48:54 <Inst> I'm going over adventures in prolog
07:49:08 <Inst> all I really need is pick up logic programming, then I'm bad at 4 programming paradigms ;)
07:49:18 <Inst> LogicT, here I come :3
07:49:47 <ski> you can just state multiple clauses (facts and rules) of the same predicate, in a row, just like stating multiple defining equations for a function, in Haskell
07:50:10 <Inst> no, but how do I avoid having to type out the predicate repeatedly?
07:50:36 <Inst> room(kitchen). room(office). ~~~> room([kitchen, office]).?
07:50:40 <ski> huh ? .. dunno what you mean
07:51:08 <Inst> I mean that I want something that's semantically equivalent to room(kitchen). room(office)., without having to type room twice
07:51:08 <ski> oh, no there's no way to abbreviate that, really. except by calling member/2 or something, but that does it at run-time
07:51:19 <Inst> oof :(
07:51:30 <ski> room(Room) :- member(Room,[kitchen,office]).
07:51:54 <ski> well, maybe you could do it with term_expansion/2, actually
07:52:07 <Inst> seems icky
07:52:17 <ski> (basically a kind of macro facility)
07:52:38 <Inst> everything is secretly just a macro :3
07:52:44 <ski> not really
07:52:45 mc47 joins (~mc47@xmonad/TheMC47)
07:53:03 <Inst> i mean you can think of any programming language as simply a macro to machine code or bytecode
07:53:26 <ski> .. even if you're using an interpreter ?
07:54:00 <Inst> :(
07:56:15 <Inst> I guess member/2 works, not sure if it's idiomatic
07:58:18 ski would probably just enumerate the cases as separate facts
08:02:52 <c_wraith> Inst: https://paste.tomsmeding.com/g2jJhUvK testing on my system shows that if the terminal speed isn't an issue, print takes more than double the time going via bytestring does. When the terminal is relevant, it's more like a 20% speed penalty. Also, terminal IO is a terrible thing to benchmark. :)
08:08:32 <Inst> I know, only time when Python beats C (at least in Windows) :;
08:09:01 × tzh quits (~tzh@c-73-164-206-160.hsd1.or.comcast.net) (Quit: zzz)
08:10:17 mima joins (~mmh@aftr-62-216-211-106.dynamic.mnet-online.de)
08:11:51 × sroso quits (~sroso@user/SrOso) (Ping timeout: 255 seconds)
08:13:59 sroso joins (~sroso@user/SrOso)
08:14:00 dunj3_ is now known as dunj3
08:16:08 Guest52 joins (~Guest52@185.57.29.142)
08:23:14 × dcoutts_ quits (~duncan@cpc69402-oxfd27-2-0-cust903.4-3.cable.virginm.net) (Ping timeout: 264 seconds)
08:26:58 danza joins (~francesco@an-19-165-10.service.infuturo.it)
08:30:49 <Inst> also, nice
08:30:54 <Inst> you can stuff a tuple
08:30:55 wootehfoot joins (~wootehfoo@user/wootehfoot)
08:31:08 <Inst> into member to get multi-arg predicates in
08:32:05 tromp joins (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl)
08:32:38 × Guest52 quits (~Guest52@185.57.29.142) (Ping timeout: 250 seconds)
08:33:01 × cyphase quits (~cyphase@user/cyphase) (Ping timeout: 255 seconds)
08:36:36 _ht joins (~Thunderbi@28-52-174-82.ftth.glasoperator.nl)
08:38:59 <ski> Prolog doesn't really have tuples
08:43:28 cyphase joins (~cyphase@user/cyphase)
08:56:41 <Inst> why is it wrong to try to abuse member this way?
08:57:00 <Inst> I assume there's a performance penalty, which is why you're suggesting term_expansion/2
08:59:57 <ski> it's not wrong, you should just be aware of what's happening
09:01:28 <ski> isRoom Kitchen = True
09:01:34 <ski> isRoom Office = True
09:01:41 <ski> isRoom _ = False
09:01:43 <ski> vs.
09:01:56 <ski> isRoom place = place `elem` [Kitchen,Office]
09:02:00 <ski> which do you prefer ?
09:03:01 <ski> (of course, that only covers the testing mode (+) of room/1, not the enumerating mode (-))
09:04:52 <danza> the latter is more readable
09:14:27 ss4 joins (~wootehfoo@user/wootehfoot)
09:14:49 <probie> but requires the compiler to do more work to produce equally performant code
09:16:31 × tromp quits (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…)
09:17:01 × peterbecich quits (~Thunderbi@047-229-123-186.res.spectrum.com) (Ping timeout: 245 seconds)
09:17:26 × wootehfoot quits (~wootehfoo@user/wootehfoot) (Ping timeout: 245 seconds)
09:18:22 × euleritian quits (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Read error: Connection reset by peer)
09:18:31 dcoutts_ joins (~duncan@cpc69402-oxfd27-2-0-cust903.4-3.cable.virginm.net)
09:18:33 euleritian joins (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de)
09:19:06 × rvalue quits (~rvalue@user/rvalue) (Quit: ZNC - https://znc.in)
09:20:48 × econo_ quits (uid147250@id-147250.tinside.irccloud.com) (Quit: Connection closed for inactivity)
09:20:55 Guest52 joins (~Guest52@185.57.29.142)
09:22:28 rvalue joins (~rvalue@user/rvalue)
09:28:54 waleee joins (~waleee@h-176-10-144-38.NA.cust.bahnhof.se)
09:31:12 <Inst> also, is it me or is logic programming just "everything is a list"?
09:31:21 <Inst> that's probably too simplified
09:31:56 <tomsmeding> the more basic data structures you have, the more pointlessly complicated the inference engine becomes
09:32:00 <Inst> the reason i'm abusing member this way is because I think of room(kitchen)... etc not as a series of predicates, but rather as a list
09:32:20 <tomsmeding> and the more semantics you have to keep in your head
09:32:22 <Inst> so it feels unnatural, same reason i barely use top-level pattern matching these days
09:32:28 <Inst> foo = /case, which is now GHC2023 <3
09:32:33 <Inst> \\case, rather
09:32:39 <Inst> \case, ffs
09:33:03 <tomsmeding> have you felt the need for \cases yet
09:33:13 <Inst> i barely know how to use cases :3
09:33:51 <ski> "everything is a list" -- nope
09:34:19 × ss4 quits (~wootehfoo@user/wootehfoot) (Read error: Connection reset by peer)
09:34:37 <Inst> there's more to it, like unification
09:34:50 <Inst> i was going to remark about how ridiculously powerful logic programming can feel
09:34:54 ski normally prefers matching in the definiendum in defining equations, rather than in `case' or `\' or `\case'
09:35:48 <Inst> location(X, kitchen), write(X), nl, fail.
09:35:49 <tomsmeding> I match on the LHS (sorry ski) in the generic case but use \case when I'm splitting on an intuitively many-constructor data type
09:36:05 <ski> (because it gives a more declarative, and orthogonal/separated, reading of the code)
09:36:27 <Inst> wait, i need a compound to simulate this properly
09:36:45 <Inst> but in Haskell it'd be:
09:36:50 <tomsmeding> like, if I split on an expression data type with 8 constructors but I also take 4 additional parameters, I find 'foo something and another thing = \case' much more readable
09:38:04 <ski> forall(( location(X,kitchen) ),( write(X),nl )). % Inst
09:38:23 <Inst> mapM_ (print . fst) $ filter (\(a,b) -> b == Kitchen) location
09:38:34 <ski> a forall/2 is commonly preferable to a (generic) failure-driven loop
09:38:42 × euleritian quits (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Ping timeout: 255 seconds)
09:38:53 × ChaiTRex quits (~ChaiTRex@user/chaitrex) (Remote host closed the connection)
09:39:00 <ski> (and forall/2 means implication .. but the implicit universal quantification is why it got that name)
09:39:13 euleritian joins (~euleritia@dynamic-176-006-196-018.176.6.pool.telefonica.de)
09:39:16 <Inst> the failure-driven loop feels more readable
09:39:28 ChaiTRex joins (~ChaiTRex@user/chaitrex)
09:39:31 <ski> it's more operational/procedural, less declarative/logical
09:39:39 × euleritian quits (~euleritia@dynamic-176-006-196-018.176.6.pool.telefonica.de) (Read error: Connection reset by peer)
09:39:49 <Inst> i mean the forall solution can be done in Haskell with functions, tbh
09:39:57 euleritian joins (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de)
09:39:59 <ski> tomsmeding : or one can declare a local helper function
09:40:05 <tomsmeding> true
09:40:05 <Inst> it's essentially equivalent to a function call
09:40:58 <tomsmeding> but then if the matching is on a GADT you need a type signature on said helper function, and you very quickly need ScopedTypeVariables :p
09:41:00 <tomsmeding> which is a bit overkill
09:41:19 <Inst> for_ location $ \(a,b) -> if b == Kitchen then print a else pure ()
09:41:24 <Inst> sort of more readable
09:41:30 <Inst> oh
09:41:37 <tomsmeding> :t when
09:41:38 <lambdabot> Applicative f => Bool -> f () -> f ()
09:41:54 <Inst> for_ location $ \(a,b) -> when (b == Kitchen) (print a)
09:42:10 <ski> for_ location \(thing,place) -> when (place == Kitchen) do print thing
09:42:20 <tomsmeding> ew, BlockArguments
09:43:24 <ski> (`forall(Antecedent,Consequent)' means `\+ ( Antecedent,\+ Consequent )', where (\+)/1 is negation(-as-failure))
09:43:38 <Inst> yeah i was instinctively going to refactor to unless, until i remmeber that when exists
09:44:04 <Inst> :hoogle
09:44:54 <ski> (==>) :: Logic m o a -> (a -> Logic m p o) -> Logic m p o -- my version of forall/2, in a Haskell eDSL
09:45:11 <tomsmeding> ski: /me trying to parse that with limited prolog experience; does that mean that if Consequent ever succeeds, the forall enumeration stops?
09:45:19 <Inst> actually sort of wishing we had a similar function
09:45:29 <tomsmeding> because Antecedent && not Consequent is then falsified, so the whole \+ is satisfied?
09:45:30 <ski> tomsmeding : yes
09:45:53 <tomsmeding> does 'nl' never succeed then
09:46:05 <tomsmeding> otherwise that forall looks different from Inst's for_
09:46:13 <Inst> (Foldable t, Applicative f) => (a -> Bool) -> t a -> (a -> f b) -> f ()
09:46:13 <ski> oh, sorry, misread you
09:46:22 <ski> tomsmeding : the other way around
09:46:51 <Inst> and of course
09:46:54 <Inst> (Foldable t, Applicative f) => (a -> Bool) -> t a -> (a -> f b) -> f b
09:46:58 × todi quits (~todi@p57803331.dip0.t-ipconnect.de) (Remote host closed the connection)
09:47:05 <ski> tomsmeding : if `Consequent' gives no solution, for any particular solution of `Antecedent', then the enumeration of `Antecedent' stops, and the whole implication goal fails
09:47:27 <ski> tomsmeding : whole implication only succeeds, if `Consequent' succeeds for every solution of `Antecedent'
09:47:32 <Inst> we don't have a function like that, right?
09:47:39 <tomsmeding> oh right
09:47:48 <tomsmeding> yeah my logic intuition is not procedural enough :p
09:47:56 <ski> (including if `Antecedent' has no solutions at all)
09:48:17 <mauke> why did the original haskell spec disallow block arguments?
09:48:32 × sroso quits (~sroso@user/SrOso) (Read error: Connection reset by peer)
09:48:38 wootehfoot joins (~wootehfoo@user/wootehfoot)
09:48:40 <ski> however, forall/2 can only be used to *check* (yes or no) whether the implication holds. it can't be used to compute and export information from it (unless you use side-effects, of course .. like in the write/1 and nl/0 example)
09:48:59 <ski> .. but, my `(==>)' version *can* export information !
09:49:31 <Inst> your Logic... wait, are you one of the maintainers on LogicT?
09:49:41 <ski> no
09:49:43 <Inst> i'm trying to feel around for the typing
09:49:52 <Inst> i know prolog is untyped
09:50:04 <ski> i made a different eDSL prototype, years ago
09:50:21 × euleritian quits (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Ping timeout: 245 seconds)
09:50:42 <ski> (.. using an unboundendly deep monad transformer stack consisting of `ContT' frames)
09:50:44 euleritian joins (~euleritia@dynamic-176-006-196-018.176.6.pool.telefonica.de)
09:50:57 <tomsmeding> O.O
09:51:36 <ski> for ordinary logic programming, you need two-level continuations, `ContT o (ContT p m) a'
09:51:40 × euphores quits (~SASL_euph@user/euphores) (Read error: Connection reset by peer)
09:52:03 <ski> but my version can "backtrack backtracking" (and "backtrack backtrack backtrackign", &c.) -- hence it needs unboundedly deep
09:52:15 <ski> @unmtl ContT o m a
09:52:15 <lambdabot> (a -> m o) -> m o
09:52:16 euphores joins (~SASL_euph@user/euphores)
09:52:22 <ski> @unmtl ContT o (ContT p m) a
09:52:22 <lambdabot> (a -> (o -> m p) -> m p) -> (o -> m p) -> m p
09:52:40 tomsmeding cowardly refuses to try to understand this on a saturday morning
09:52:44 <haskellbridge> <i​rregularsphere> ...backtrack backtracking? isn't that just forward tracking xD
09:53:09 <ski> ?- Xs = [1,4,2,9],( member(X,Xs) => X < 10 ).
09:53:12 <ski> true
09:53:15 <Inst> LP seems pretty amazing though, for how powerful it is with conditionals, however
09:53:16 <ski> ?- Xs = [1,4,2,9],( member(X,Xs) => X < 5 ).
09:53:18 <ski> false
09:53:23 × L29Ah quits (~L29Ah@wikipedia/L29Ah) (Ping timeout: 264 seconds)
09:53:40 <ski> ((=>)/2 there is implication, spelled forall/2 in e.g. SWI)
09:54:21 <tomsmeding> here you backtrack the backtracking you did in member/2 if it turns out the consequent doesn't hold?
09:54:22 <ski> ?- XYs = [(1,_),(4,_),(2,_),(9,_)],( member((X,Y),XYs) => square(X,Y) ).
09:54:22 <ski> XYs = [(1,1),(4,16),(2,4),(9,81)]
09:54:45 <ski> forall/2, defined in terms of (\+)/1 as above (negation-as-failure), *can't* do the last example above !
09:55:22 <ski> because it can't export information about what `Y' has been instantiated/bound to, by the square/2 call(s), from inside to outside the implication
09:55:57 <Inst> not sure if i'm being too annoying
09:56:09 <Inst> but can LP be thought of as conditionals on steroids?
09:56:25 <Inst> one comment I made to others is that haskell has excellent conditions compared to more traditional languages due to pattern matching and ADTs
09:56:49 <ski> note that `XYs = [(1,_),(4,_),(2,_),(9,_)],( member((X,Y),XYs) => square(X,Y) )' here amounts to `XYs = [(1,Y0),(4,Y1),(2,Y2),(9,Y3)],square(1,Y0),square(4,Y1),square(2,Y2),square(9,Y3) )'
09:57:16 <tomsmeding> ^H
09:57:36 sroso joins (~sroso@user/SrOso)
09:57:37 × rvalue quits (~rvalue@user/rvalue) (Quit: ZNC - https://znc.in)
09:57:41 Tuplanolla joins (~Tuplanoll@91-159-69-59.elisa-laajakaista.fi)
09:57:57 rvalue joins (~rvalue@user/rvalue)
09:57:57 <ski> in `( member((X,Y),XYs) => square(X,Y) )', my implementation associates `X' and `Y' with the components of a pair in `XYs', where `X' is instantiated to a number, and `Y' is aliased to the second component of the same pair. then `square(X,Y)' is called, instantiating `Y' to the square of `X'
09:58:10 L29Ah joins (~L29Ah@wikipedia/L29Ah)
09:58:56 <ski> then the member/2 call is backtracked, to generate the *next* solution for `X' and `Y'. so `X' will become uninstantiated, and then instantiated to a *different* number. and `Y' will become unaliased with the previous pair component, and aliased to another one
09:59:26 <ski> *despite* this, the instantiation in `XYs' of the second component of the previous pair, to the just computed square, *persists* !
09:59:31 <ski> Prolog can't do this
10:00:46 <ski> so, `Y' is aliased to a second component of a pair. then square/2 unifies `Y' with a number, and via the alias chain, that instantiates the pair component. then the alias of `Y' to that component is broken, but the instantiation of the component persists
10:01:14 <tomsmeding> sounds pretty coo]
10:01:16 <tomsmeding> *cool
10:01:24 <tomsmeding> I have zero use for something like this though :p
10:01:53 × danza quits (~francesco@an-19-165-10.service.infuturo.it) (Read error: Connection reset by peer)
10:01:58 <ski> "here you backtrack the backtracking you did in member/2 if it turns out the consequent doesn't hold?" -- well, yes .. but that doesn't really lead to anything interesting, in this example (because each number as just one square)
10:02:15 <ski> however, now consider ..
10:02:40 <ski> ?- XYs = [(_,1),(_,4),(_,9)],( member((X,Y),XYs) => square(X,Y) ).
10:02:45 <ski> XYs = [(1,1),(2,4),(3,9)] ;
10:02:48 <ski> XYs = [(1,1),(2,4),(-3,9)] ;
10:02:52 <ski> XYs = [(1,1),(-2,4),(3,9)] ;
10:02:54 <ski> XYs = [(1,1),(-2,4),(-3,9)] ;
10:02:58 <ski> XYs = [(-1,1),(2,4),(3,9)] ;
10:03:00 <ski> XYs = [(-1,1),(2,4),(-3,9)] ;
10:03:03 <ski> XYs = [(-1,1),(-2,4),(3,9)] ;
10:03:10 <ski> XYs = [(-1,1),(-2,4),(-3,9)]
10:03:15 tomsmeding got the point after the first two results :D
10:03:23 <tomsmeding> quirky
10:03:25 <ski> this is an example of "backtracking backtracking"
10:04:18 <ski> this example dynamically generates (/ operates in the same way as) a sequence of three calls to square/2, `square(X0,1),square(X1,4),square(X2,9)'
10:04:40 <ski> each square/2 call has two solutions, so we get `2 * 2 * 2' solutions, backtracking back and forth
10:05:43 <ski> in terms of (=>)/2, we first associate `X' and `Y' to the first pair, then compute `X' (instantiating that pair in `XYs'). then the same for the next pair, and the final pair
10:06:38 <ski> then, when we ask for the next solution, at the top-level, backtracking starts. we get back to the last square/2 call, and it generates its second solution. when we ask (`;') for the next solution, we backtrack back again, but the last call square/2 has no more solutions
10:07:35 <ski> so, we need to get to the next to last call. but this means we need to undo the *backtracking* that member/2 did .. because it was by backtracking member/2, that we found the three solutions (bindings to the three pairs in the list), which we then checked with square/2
10:07:45 <ski> that's what i mean by "backtracking backtracking"
10:08:40 <tomsmeding> what languages besides haskell would you dare implement this in
10:08:44 <ski> there's also another interesting component of this, in that, whenever we switch polarity/context, negating it, all uninstantiated variables automagically gets turned into constants (skolems). (and vice versa)
10:09:32 <ski> (generating new skolems at run-time here was inspired by lambdaProlog)
10:09:50 <ski> (more specifically, universal implication goals generate skolems)
10:10:46 <ski> (er .. universal quantification, i meant to say)
10:11:56 <ski> .. if i just wanted to be able to have implication goals `( foo => bar )', then three continuations levels would suffice. but since i wanted to be able to nest arbitrarily, like `( ( foo => bar) => baz )',&c., i needed unbounded number of levels
10:12:33 danza joins (~francesco@151.35.171.81)
10:12:59 <ski> newtype Logic m o a = L (forall n p. ContStack m n => ({- exit :: -} a -> ({- redo :: -} o -> n p) -> n p) -> ({- fail :: -} o -> n p) -> n p)
10:14:01 igemnace joins (~ian@user/igemnace)
10:16:13 <ski> tomsmeding : well, i guess SML or OCaml might've worked. or Scheme, perhaps
10:16:53 <tomsmeding> if you understand very well what you're doing
10:17:16 <ski> but .. of course, it helped to have this be quite typeful, having the type system yell at me when i deviated from the narrow path, with pitfalls on both sides of the trail
10:17:24 zer0bitz_ joins (~zer0bitz@user/zer0bitz)
10:18:02 <ski> .. this whole exercise came about, as a result of trying to port a Sudoko solver from Common Lisp, to Prolog
10:19:48 <ski> (and then generalizing array primitives, to multi-dimensional, and then being annoyed that one aspect of that didn't work as intended .. even with some low-level unsafe mucking with update-in-place (presumably code optimization got in the way). then the idea of backtracking backtracking came to me, and i just had to implement it)
10:21:22 <ski> imagine a tree, with solutions at the leaves (some nodes may have zero children, and are not leaves). finding all solutions can be done with DFS through the tree. going left-to-right. "backtracking backtracking" amounts to, sometimes, going right-to-left, instead, undoing part of the traversal you've already done
10:21:26 × euleritian quits (~euleritia@dynamic-176-006-196-018.176.6.pool.telefonica.de) (Read error: Connection reset by peer)
10:21:49 euleritian joins (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de)
10:21:52 × zer0bitz quits (~zer0bitz@user/zer0bitz) (Ping timeout: 268 seconds)
10:21:57 Lord_of_Life_ joins (~Lord@user/lord-of-life/x-2819915)
10:22:27 × Lord_of_Life quits (~Lord@user/lord-of-life/x-2819915) (Ping timeout: 252 seconds)
10:22:38 × dcoutts_ quits (~duncan@cpc69402-oxfd27-2-0-cust903.4-3.cable.virginm.net) (Ping timeout: 264 seconds)
10:23:33 <tomsmeding> where "normal" backtracking is merely going up and then again left-to-right in the next sibling?
10:24:10 <ski> yep
10:24:48 <ski> disjunction is concatenation, placing one tree beside another one (under a new root node, say)
10:24:55 Lord_of_Life_ is now known as Lord_of_Life
10:25:13 <ski> conjunction is grafting, putting a copy of the second conjunct, at each leaf of the first tree (conjunct)
10:25:27 tomsmeding . o O ( (>>=) )
10:25:31 <ski> right
10:25:52 <ski> this i also very closely related to arithmetic on natural numbers
10:26:05 <ski> disjunction is addition, conjunction is multiplication, implication is exponentiation
10:26:23 × euleritian quits (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Ping timeout: 264 seconds)
10:26:23 <ski> and the Church representation of naturals is two-level continuations
10:26:26 tromp joins (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl)
10:26:49 <ski> type ChurchNat = forall o. (o -> o) -> o -> o
10:27:20 euleritian joins (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de)
10:27:35 <ski> @unmtl ContT () (Cont o) ()
10:27:35 <lambdabot> (() -> (() -> o) -> o) -> (() -> o) -> o
10:31:36 × euleritian quits (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Ping timeout: 245 seconds)
10:31:56 <ski> m + n = \s f -> m s (n s f)
10:32:07 <ski> = \s -> m s . n s
10:32:22 <ski> m * n = \s f -> m (n s) f
10:32:30 <ski> = \s -> m (n s)
10:32:33 euleritian joins (~euleritia@dynamic-176-006-196-018.176.6.pool.telefonica.de)
10:32:36 <ski> = m . n
10:34:46 <ski> n ^ m = \s f -> m (\s' f' -> n s' f') s f
10:34:46 <tomsmeding> naming: data ? = Explicit | Implicit
10:34:53 <ski> n ^ m = \s f -> m n s f
10:34:58 <ski> n ^ m = m n
10:35:05 <tomsmeding> I always loved how those simplify
10:35:56 <ski> the definition of `+' and `*' works without the rank-2, but the definition of `^' doesn't, because it passes `o -> o' as the `o' type parameter of `m' (it adds another continuation level to the antecedent)
10:36:38 <mauke> data Plicit = Ex | In
10:36:49 <tomsmeding> that was my first thought as well but... er
10:37:14 ski . o O ( `Com :: Plicit' )
10:39:46 <ski> the s' above is a failure ("redo") continuation of `m', that it passes to its callback, in order for the callback to be able to backtrack, request the search for the next solution of `m'
10:40:37 <tomsmeding> ski: FYI I have stopped trying to properly understand this :)
10:40:39 <ski> but s' is passed in the argument position of *success* continuation to `n'. which means that when `n' (consequent) succeeds, we'll *fail* `m' (causing it to backtrack, possibly generating another solution and then invoking `n' again)
10:42:59 ski nods
10:43:19 <Inst> thanks ski
10:43:22 <Inst> for the forall
10:44:46 <Inst> put it into my prolog glorified hello world, feels a bit more fun
10:47:24 <ski> np
10:57:40 × euleritian quits (~euleritia@dynamic-176-006-196-018.176.6.pool.telefonica.de) (Read error: Connection reset by peer)
10:57:58 euleritian joins (~euleritia@dynamic-176-006-196-018.176.6.pool.telefonica.de)
10:58:21 × euleritian quits (~euleritia@dynamic-176-006-196-018.176.6.pool.telefonica.de) (Read error: Connection reset by peer)
10:58:40 euleritian joins (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de)
11:04:02 × tv quits (~tv@user/tv) (Ping timeout: 264 seconds)
11:10:38 × waleee quits (~waleee@h-176-10-144-38.NA.cust.bahnhof.se) (Ping timeout: 264 seconds)
11:17:08 tv joins (~tv@user/tv)
11:20:03 × euleritian quits (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Ping timeout: 260 seconds)
11:20:14 euleritian joins (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de)
11:24:02 × sroso quits (~sroso@user/SrOso) (Quit: Leaving :))
11:27:17 × Inst quits (~Inst@120.244.192.126) (Ping timeout: 272 seconds)
11:31:50 × wootehfoot quits (~wootehfoo@user/wootehfoot) (Read error: Connection reset by peer)
11:34:56 × euleritian quits (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Ping timeout: 245 seconds)
11:35:16 euleritian joins (~euleritia@dynamic-176-006-196-018.176.6.pool.telefonica.de)
11:38:36 mik3d joins (~mik3d@pool-173-61-131-199.cmdnnj.fios.verizon.net)
11:38:40 × mik3d quits (~mik3d@pool-173-61-131-199.cmdnnj.fios.verizon.net) (Remote host closed the connection)
11:38:55 mik3d joins (~mik3d@pool-173-61-131-199.cmdnnj.fios.verizon.net)
11:55:41 Inst joins (~Inst@2409:8900:15d7:9ecd:d952:d0b5:5dd6:eba8)
12:08:36 × danza quits (~francesco@151.35.171.81) (Ping timeout: 252 seconds)
12:15:04 Inst_ joins (~Inst@2409:8900:18e8:1b53:ba8d:1851:aecf:7a32)
12:17:27 × Inst quits (~Inst@2409:8900:15d7:9ecd:d952:d0b5:5dd6:eba8) (Ping timeout: 260 seconds)
12:31:17 × euleritian quits (~euleritia@dynamic-176-006-196-018.176.6.pool.telefonica.de) (Read error: Connection reset by peer)
12:31:36 euleritian joins (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de)
12:39:27 × mik3d quits (~mik3d@pool-173-61-131-199.cmdnnj.fios.verizon.net) (Read error: Connection reset by peer)
12:42:54 × ChaiTRex quits (~ChaiTRex@user/chaitrex) (Quit: ChaiTRex)
12:44:15 mik3d joins (~mik3d@pool-173-61-131-199.cmdnnj.fios.verizon.net)
12:47:39 × ec quits (~ec@gateway/tor-sasl/ec) (Remote host closed the connection)
12:48:12 ec joins (~ec@gateway/tor-sasl/ec)
12:51:53 × Inst_ quits (~Inst@2409:8900:18e8:1b53:ba8d:1851:aecf:7a32) (Remote host closed the connection)
12:53:43 × mik3d quits (~mik3d@pool-173-61-131-199.cmdnnj.fios.verizon.net) (Read error: Connection reset by peer)
12:54:56 × euleritian quits (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Read error: Connection reset by peer)
12:55:23 euleritian joins (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de)
12:59:40 × chexum quits (~quassel@gateway/tor-sasl/chexum) (Remote host closed the connection)
13:00:26 chexum joins (~quassel@gateway/tor-sasl/chexum)
13:06:57 waleee joins (~waleee@h-176-10-144-38.NA.cust.bahnhof.se)
13:07:09 dcoutts_ joins (~duncan@cpc69402-oxfd27-2-0-cust903.4-3.cable.virginm.net)
13:11:11 × chexum quits (~quassel@gateway/tor-sasl/chexum) (Remote host closed the connection)
13:11:28 chexum joins (~quassel@gateway/tor-sasl/chexum)
13:12:31 × euleritian quits (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Read error: Connection reset by peer)
13:12:46 euleritian joins (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de)
13:12:57 Inst_ joins (~Inst@2409:8900:18e8:1b53:ba8d:1851:aecf:7a32)
13:13:20 <Inst_> man, prolog is amazing
13:13:22 Inst_ is now known as Inst
13:13:32 <Inst> I mean, I should go try Mercury or something
13:13:37 <Inst> or Verse, for that matter, hahahaha
13:15:51 × Inst quits (~Inst@2409:8900:18e8:1b53:ba8d:1851:aecf:7a32) (Read error: Connection reset by peer)
13:15:58 Inst_ joins (~Inst@223.104.40.121)
13:21:17 × lvdv quits (~lvdv@203.7.118.37) (Ping timeout: 240 seconds)
13:23:15 × mzg quits (mzg@lazy.unconscious.biz) (Ping timeout: 255 seconds)
13:23:18 ph88 joins (~ph88@2a02:8109:9e26:c800:d827:6191:39c4:2643)
13:23:31 × ph88 quits (~ph88@2a02:8109:9e26:c800:d827:6191:39c4:2643) (Remote host closed the connection)
13:25:48 Inst_ is now known as Inst
13:25:49 × euleritian quits (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Read error: Connection reset by peer)
13:25:58 euleritian joins (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de)
13:26:12 × euleritian quits (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Read error: Connection reset by peer)
13:26:23 euleritian joins (~euleritia@dynamic-176-006-196-018.176.6.pool.telefonica.de)
13:26:55 Manideep joins (~Manideep@2401:4900:4fd5:1d80:31a2:32ee:6c3b:9ff6)
13:28:30 Manideep90 joins (~Manideep@2401:4900:4fd5:1d80:31a2:32ee:6c3b:9ff6)
13:31:11 × euleritian quits (~euleritia@dynamic-176-006-196-018.176.6.pool.telefonica.de) (Ping timeout: 264 seconds)
13:31:30 euleritian joins (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de)
13:31:34 Lycurgus joins (~georg@li1192-118.members.linode.com)
13:31:34 × Lycurgus quits (~georg@li1192-118.members.linode.com) (Changing host)
13:31:34 Lycurgus joins (~georg@user/Lycurgus)
13:33:56 ania123 joins (~ania123@94-43-231-47.dsl.utg.ge)
13:39:30 × Manideep90 quits (~Manideep@2401:4900:4fd5:1d80:31a2:32ee:6c3b:9ff6) (Quit: Client closed)
13:39:43 × Manideep quits (~Manideep@2401:4900:4fd5:1d80:31a2:32ee:6c3b:9ff6) (Quit: Client closed)
13:46:07 mik3d joins (~mik3d@pool-173-61-131-199.cmdnnj.fios.verizon.net)
13:49:19 × mik3d quits (~mik3d@pool-173-61-131-199.cmdnnj.fios.verizon.net) (Client Quit)
13:53:43 zer0bitz_ is now known as zer0bitz
13:59:48 × ania123 quits (~ania123@94-43-231-47.dsl.utg.ge) (Ping timeout: 250 seconds)
14:01:36 × Inst quits (~Inst@223.104.40.121) (Ping timeout: 245 seconds)
14:09:58 marinelli joins (~weechat@gateway/tor-sasl/marinelli)
14:15:49 shapr joins (~user@c-24-218-186-89.hsd1.ma.comcast.net)
14:19:18 × shapr quits (~user@c-24-218-186-89.hsd1.ma.comcast.net) (Remote host closed the connection)
14:19:51 × driib quits (~driib@vmi931078.contaboserver.net) (Quit: The Lounge - https://thelounge.chat)
14:22:09 driib joins (~driib@vmi931078.contaboserver.net)
14:28:29 Inst joins (~Inst@120.244.192.126)
14:29:16 × Inst quits (~Inst@120.244.192.126) (Remote host closed the connection)
14:29:42 Inst joins (~Inst@120.244.192.126)
14:36:02 <Inst> iirc Kmett mentioned he liked LogicT
14:36:50 <Inst> doesn't seem to be a lot of attention to LogicT
14:39:53 machinedgod joins (~machinedg@d173-183-246-216.abhsia.telus.net)
14:44:06 alexherbo2 joins (~alexherbo@2a02-8440-3441-13b3-f842-e4eb-f5b3-2e87.rev.sfr.net)
14:48:26 Square joins (~Square@user/square)
14:49:12 × Guest52 quits (~Guest52@185.57.29.142) (Ping timeout: 250 seconds)
14:49:50 ania123 joins (~ania123@94-43-231-47.dsl.utg.ge)
14:51:08 <ania123>  If we know n = N div 2^k and 2^k * (n mod 2) + N mod 2^k can we conclude N mod 2^(k+1)?
15:24:42 wootehfoot joins (~wootehfoo@user/wootehfoot)
15:25:34 × mc47 quits (~mc47@xmonad/TheMC47) (Remote host closed the connection)
15:46:39 × sadie_ quits (~sadie@c-76-155-235-153.hsd1.co.comcast.net) (Remote host closed the connection)
15:49:41 × euleritian quits (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Ping timeout: 240 seconds)
15:49:56 × machinedgod quits (~machinedg@d173-183-246-216.abhsia.telus.net) (Ping timeout: 245 seconds)
15:50:23 euleritian joins (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de)
15:57:16 × Inst quits (~Inst@120.244.192.126) (Remote host closed the connection)
15:57:43 Inst joins (~Inst@120.244.192.126)
16:11:59 × euleritian quits (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Read error: Connection reset by peer)
16:12:31 euleritian joins (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de)
16:15:12 tzh joins (~tzh@c-73-164-206-160.hsd1.or.comcast.net)
16:20:10 × otto_s quits (~user@p5b04451e.dip0.t-ipconnect.de) (Quit: leaving)
16:21:16 otto_s joins (~user@p5b04451e.dip0.t-ipconnect.de)
16:24:31 × otto_s quits (~user@p5b04451e.dip0.t-ipconnect.de) (Client Quit)
16:28:41 × ania123 quits (~ania123@94-43-231-47.dsl.utg.ge) (Quit: Client closed)
16:29:35 otto_s joins (~user@p5b04451e.dip0.t-ipconnect.de)
16:41:26 <Inst> btw, just to confirm
16:41:29 <Inst> I can liftIO into STM, right?
16:41:59 <Inst> oh, it's not MonadIO
16:42:16 <Inst> would require twiddling to make sure the IO action only fires if the STM action succeeds, which is probably not possible
16:49:06 × trev quits (~trev@user/trev) (Ping timeout: 252 seconds)
16:51:01 econo_ joins (uid147250@id-147250.tinside.irccloud.com)
16:51:07 L29Ah parts (~L29Ah@wikipedia/L29Ah) ()
16:53:38 Guest52 joins (~Guest52@185.57.29.142)
16:56:01 <monochrom> Any wish for injecting IO into STM leads to questionable semantics only. Don't even try.
16:56:11 <monochrom> Ugh pun on "try" hahaha.
17:02:29 <Inst> by the way, just curious
17:02:29 <Inst> https://www.fpcomplete.com/haskell/library/stm/
17:02:32 <Inst> what's happening here?
17:02:46 <Inst> it's a freakshow because there should be a new TVar being created every time
17:02:56 <Inst> but somehow replicateM_ etc is sharing the TVar
17:04:20 <monochrom> Huh that's a long article. How do I jump right to the code fragment you are talking about?
17:04:58 <Inst> oh, doip, it is creating a single TVar
17:05:05 <Inst> basics
17:05:38 <Inst> it's returning an IO action, of all things
17:06:27 <monochrom> Soon you will find that STM (IO X) is a liberating technique, too.
17:06:56 <Inst> Why does that sound sinister?
17:07:19 <Inst> so the IO action is containing the created TVar, and thus inheriting it
17:07:44 <Inst> this seems horrifically sinister
17:08:13 <monochrom> It is just, for example, [IO X] but s/[]/STM/
17:08:23 <monochrom> Or as you have seen, s/[]/IO/
17:09:26 <monochrom> In other FP languages, it is just [() -> X], STM (() -> X), and () -> (() -> X), respectively.
17:09:28 <Inst> wow, so this is a valid and horrifying way to work with mutables that feels so much like an OOP "new"
17:10:15 <Inst> private methods / properties!
17:10:39 <Inst> it doesn't help that i've been in poor emotional health recently, but thank you Haskell, for horrifying me even more
17:10:39 <monochrom> In this realm we call them closures.
17:10:54 <Inst> "a poor man's object, just as objects are a poor man's closures"
17:12:45 <monochrom> One person's horror movie is another person's comedy.
17:13:26 × ec quits (~ec@gateway/tor-sasl/ec) (Ping timeout: 260 seconds)
17:14:15 <monochrom> True story: I went to watch The Neon Demon. The only other audience in the theatre were two girls. At the most horrifying and gross scene, they laughed. I admire that.
17:14:19 ec joins (~ec@gateway/tor-sasl/ec)
17:17:22 <monochrom> Also, if you learn monads by way of (fmap, pure, join) rather than the usual >>=, then IO (IO X) is a necessity. join :: IO (IO X) -> IO X.
17:17:23 <Inst> it seems more reasonable to just build an object via record types and IO functions, then use lens / optics to manipulate them and call it a day
17:17:27 machinedgod joins (~machinedg@d173-183-246-216.abhsia.telus.net)
17:17:44 <Inst> join + fmap actually makes more sense and is more accessible
17:18:05 <monochrom> Sure. So you have IO MyRecord, no?
17:18:18 <Inst> If you need inheritance, just stack your objects together
17:18:28 <Inst> it's actually neater than 23482 method OOP objects in OOP languages
17:18:37 <monochrom> But MyRecord ≅ (X -> IO Y, A -> IO B, S -> IO T), no?
17:18:57 <Inst> or just IO foo, etc, operating on a TVar
17:19:04 <monochrom> Therefore you have IO (X -> IO Y, A -> IO B, S -> IO T), no?
17:19:19 <Inst> what are you implying?
17:19:20 <monochrom> Now how is that "better" than IO (IO Z)?
17:19:36 <Inst> don't worry, monochrom, my mirth is proportional to my horror
17:20:23 <monochrom> In fact, IO MyRecord is IO (IO Z) on steroid. It is not "simpler" or whatever euphemism.
17:20:36 <Inst> because of private methods and properties
17:20:54 <Inst> Someone really needs to write the blog post "Haskell is the best OOP language"
17:21:32 × igemnace quits (~ian@user/igemnace) (Read error: Connection reset by peer)
17:22:18 falafel joins (~falafel@2607:fb91:8aa:877b:ec1c:7577:7427:5731)
17:22:34 <monochrom> The only thing I can agree to is that by the time you have a 3-tuple it is probably better to change it to a user-defined named record type. (But even that depends on the actual situation.)
17:23:27 <monochrom> But don't lie to yourself. IO MyRecord is an extension of the IO (IO Z) idea, not a watering down.
17:23:56 emmanuelux joins (~emmanuelu@user/emmanuelux)
17:24:04 <Inst> it is, but if it's already essentially OOP, just do real OOP isntead of faking it
17:24:33 <monochrom> Oh I don't mind calling it OO.
17:24:44 <Inst> might as well add -XOverloadedRecordDot
17:25:23 <Inst> and I still think it's moral to have to jump through hoops to get your fake OOP objects instead of having first-class syntactical support
17:25:52 <c_wraith> there's nothing about OOP that requires dots.
17:27:15 <Inst> i actually use overloadedrecorddot a lot
17:27:28 <tomsmeding> what was that "rule" called again that if a name is longer than its definition, you can better just inline it?
17:27:40 <Inst> you have private properties and methods via the mutvar,
17:28:05 <c_wraith> tomsmeding: something about the Fairborn threshold?
17:28:16 zetef joins (~quassel@2a02:2f00:500b:ce00:aba1:3782:4e7c:41a)
17:28:22 <tomsmeding> fairbairn, thanks c_wraith
17:28:32 <monochrom> This is where I agree with https://cs.brown.edu/courses/csci1730/2012/ about ignoring "paradigms" "FP" "OOP" etc, and instead speak of more fine-grained constructs, e.g., closures, mutable states.
17:28:34 <c_wraith> I'm very bad at names
17:28:34 <ski> "real OOP" has little to do with concrete syntax
17:28:43 <tomsmeding> c_wraith: good enough to tickle my memory :)
17:29:57 <monochrom> I recommend watching at least the first lecture video, where the prof explains what's wrong with "paradigms" and what he does instead.
17:31:15 <monochrom> To a large extent, since then, I axiomatize "paradigm = religion". And in secular matters such as programming, I denounce religions.
17:34:08 <monochrom> In Haskell's STM and even IO, a closure over a mutable variable is a useful technique. (As with all techniques, use it with discretion.) It does not matter that people call that "OO" or "actor model" or "the way of the saviour" or "the way of the tempter".
17:35:01 <monochrom> But yeah, what's really wrong is the stance that if it is called "OO" then it must be in Java syntax.
17:37:52 enikar thinks smalltalk doesn't use dot to call a message of an object…
17:38:16 <monochrom> OCaml uses # instead of dot. :)
17:38:36 <ski> closing over lexical scope is one take on "OO". existentials is another. record types is a third
17:38:59 igemnace joins (~ian@user/igemnace)
17:39:00 <ski> enikar ifTrue: [ ... ] ifFalse: [ ... ]
17:39:13 <enikar> ski: yes ;)
17:40:52 <Inst> i mean if you're a pragmatist, and you find all this FP GUI stuff experimental and immature, you might as well switch to OOP-based GUI
17:41:13 <Inst> being able to use mutvars to implement objects is a plus, not a minus
17:41:24 <tomsmeding> GUI is still hard, though
17:42:29 <Inst> I just got a sort of horror of OOP from the Haskell community, so just seeing Snoyman using a closure to manage and hide TVars in STM was sort of a shock
17:42:32 <monochrom> I am beginning to feel that when I write in OO-GUI I am hand-compiling reactive programming to OO code.
17:43:12 <monochrom> And the only reason I tolerate that is only because OO-GUI libraries are more ready for production.
17:43:56 × igemnace quits (~ian@user/igemnace) (Quit: WeeChat 4.2.1)
17:43:59 <c_wraith> If only someone had started a 20-programmer full-time effort to build a good haskell GUI library 15 years ago. It might be starting to get decent by now!
17:44:34 ski reminisces Fudgets
17:44:45 <monochrom> And we all know how this kind of things is determined solely by historical accidents not technical merit.
17:45:17 <ski> "worse is better",&c.
17:46:01 <monochrom> For example, the only reason mutable state is dominant is because Turing and von Neumann were born 100 years ago rather than 100 years in the future.
17:46:24 <monochrom> Because without them, Church would be the only game in town.
17:46:46 <tomsmeding> are you sure?
17:46:54 <monochrom> >:)
17:47:01 <tomsmeding> I'm not saying you're wrong in general, but for this particular thing I doubt
17:47:28 <tomsmeding> surely someone would have figured out that register machines are useful to implement as hardware chips
17:48:22 <tomsmeding> the first technology has the advantage of more prior work, but a silicon processor based on functional concepts would have been... challenging
17:53:43 ski . o O ( "The Rise of Worse is Better" (in "Lisp: Good News, Bad News, How to Win Big") by Richard P. Gabriel in 1991 at <https://dreamsongs.com/RiseOfWorseIsBetter.html>,<https://dreamsongs.com/WorseIsBetter.html>,<https://dreamsongs.com/WIB.html> )
17:57:41 ph88 joins (~ph88@2a02:8109:9e26:c800:32fc:1140:12f0:2672)
18:05:19 × euleritian quits (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Ping timeout: 256 seconds)
18:06:02 × wootehfoot quits (~wootehfoo@user/wootehfoot) (Quit: Leaving)
18:06:47 <ph88> anyone know how to watch the hs and automatically build & run the program? I'm using stack
18:06:50 × chiselfuse quits (~chiselfus@user/chiselfuse) (Remote host closed the connection)
18:07:41 chiselfuse joins (~chiselfus@user/chiselfuse)
18:07:49 <monochrom> https://hackage.haskell.org/package/ghcide and give it the stack command.
18:08:37 <monochrom> It's a general "watch and run command" program that defaults to command=ghc but you can change it to anything.
18:09:28 × destituion quits (~destituio@2a02:2121:655:c95b:88d4:b861:7bfd:c1a4) (Ping timeout: 255 seconds)
18:09:41 euleritian joins (~euleritia@dynamic-046-114-095-014.46.114.pool.telefonica.de)
18:09:43 destituion joins (~destituio@2001:4644:c37:0:6086:64f4:a213:b80d)
18:10:41 wootehfoot joins (~wootehfoo@user/wootehfoot)
18:10:42 trev joins (~trev@user/trev)
18:11:39 <ph88> thanks !
18:14:48 <geekosaur> doesn't "stack watch" do that?
18:15:22 <monochrom> :(
18:15:35 <monochrom> "not on my watch" :)
18:16:10 <geekosaur> also are you confusing ghcide with ghcid?
18:16:36 <monochrom> Oh right! OOps sorry!
18:16:46 <geekosaur> ghcide is part og HLS
18:16:51 <monochrom> https://hackage.haskell.org/package/ghcid
18:16:59 × pavonia quits (~user@user/siracusa) (Quit: Bye!)
18:19:30 mechap joins (~mechap@user/mechap)
18:21:29 × zetef quits (~quassel@2a02:2f00:500b:ce00:aba1:3782:4e7c:41a) (Ping timeout: 272 seconds)
18:28:44 Sgeo joins (~Sgeo@user/sgeo)
18:29:46 peterbecich joins (~Thunderbi@047-229-123-186.res.spectrum.com)
18:41:00 <Inst> so, about STM
18:41:12 <Inst> I suppose you COULD attempt an unsafePerformIO read
18:41:52 <Inst> not sure if that's safe, though
18:42:08 <Inst> then you could attempt to run a retry, then return an IO action, and employ what Snoyman calls the join trick
18:42:11 <Inst> https://www.fpcomplete.com/haskell/library/stm/
18:42:20 <Inst> atomically :: STM a -> IO a
18:42:33 <Inst> then join to compress IO (IO a) into IO a at the end
18:43:04 <Inst> it only returns and runs if the STM succeeds, no?
18:43:12 <Inst> or am I mistaken somewhere here?
18:45:39 <[exa]> good evening all
18:46:02 <[exa]> Inst: what's the goal there?
18:46:05 shapr joins (~user@c-24-218-186-89.hsd1.ma.comcast.net)
18:46:06 <monochrom> Instead of a direct clumsy answer, I'll just show you this idiom:
18:46:47 <Inst> [exa]: I discovered that logic programming is cool, which sort of brought me into backtracking capabilities in Haskell in an attempt to learn how to mimic logic programming
18:46:55 <Inst> STM is interesting for that reason
18:46:58 <monochrom> join ( (foo >> pure (putStrLn x) `orElse` (bar >> pure (putStrLn y)) )
18:47:20 <monochrom> err
18:47:28 <monochrom> join (atomically ( (foo >> pure (putStrLn x) `orElse` (bar >> pure (putStrLn y)) ))
18:47:37 <[exa]> ah yeah logic programming is underappreciated.
18:47:53 <monochrom> equivalently, do-notation: a <- atomically ( (foo >> pure (putStrLn x) `orElse` (bar >> pure (putStrLn y)) ); a
18:48:27 <geekosaur> also iirc the RTS will abort if you use unsafePerformIO with STM
18:48:59 <geekosaur> (although maybe only if you use STM inside an unsafePerformIO)
18:50:32 <monochrom> One of those times when a long article is less efficient than just one line of code and "exercise for the reader: play with various foo and bar and learn what this idiom does for you".
18:50:51 <monochrom> Not to mention that playing is a better way to learn than reading.
18:51:57 <Inst> this is awesome
18:52:58 <monochrom> That idiom was what I had in mind when I said that STM (IO X) is useful. I did not really think of closures containing states.
18:53:15 <monochrom> But OK putStrLn contains states too, so meh.
18:53:27 <monochrom> (buffers, for starters)
18:53:55 <monochrom> Err no, that doesn't count. I had "pure" there heh.
18:58:45 zetef joins (~quassel@2a02:2f00:500b:ce00:aba1:3782:4e7c:41a)
19:00:09 × falafel quits (~falafel@2607:fb91:8aa:877b:ec1c:7577:7427:5731) (Remote host closed the connection)
19:02:02 × euleritian quits (~euleritia@dynamic-046-114-095-014.46.114.pool.telefonica.de) (Read error: Connection reset by peer)
19:02:12 falafel joins (~falafel@2607:fb91:8aa:877b:ec1c:7577:7427:5731)
19:02:21 euleritian joins (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de)
19:03:17 × tromp quits (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…)
19:07:11 × euleritian quits (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Ping timeout: 264 seconds)
19:09:34 euleritian joins (~euleritia@dynamic-046-114-095-014.46.114.pool.telefonica.de)
19:10:19 × vgtw quits (~vgtw@user/vgtw) (Quit: ZNC - https://znc.in)
19:20:16 × dsrt^ quits (~cd@c-98-242-74-66.hsd1.ga.comcast.net) (Remote host closed the connection)
19:20:43 thailigur joins (~thailigur@151.240.245.105)
19:20:58 × thailigur quits (~thailigur@151.240.245.105) (Client Quit)
19:26:39 × euleritian quits (~euleritia@dynamic-046-114-095-014.46.114.pool.telefonica.de) (Read error: Connection reset by peer)
19:26:58 euleritian joins (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de)
19:28:48 thailigur joins (~thailigur@185.110.188.241)
19:30:52 tromp joins (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl)
19:32:01 × falafel quits (~falafel@2607:fb91:8aa:877b:ec1c:7577:7427:5731) (Ping timeout: 245 seconds)
19:32:06 Daxson_ joins (~Daxson@176.254.244.83)
19:33:08 Silver_X joins (~Silver_X@182.178.246.138)
19:35:19 × Daxson quits (~Daxson@176.254.244.83) (Ping timeout: 268 seconds)
19:46:16 × target_i quits (~target_i@user/target-i/x-6023099) (Quit: leaving)
20:07:24 × thailigur quits (~thailigur@185.110.188.241) (Quit: Client closed)
20:07:51 × euleritian quits (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Ping timeout: 260 seconds)
20:08:47 euleritian joins (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de)
20:17:41 qeef joins (~qeef@138-169-143-94.cust.centrio.cz)
20:19:15 Daxson joins (~Daxson@176.254.244.83)
20:22:01 × Daxson_ quits (~Daxson@176.254.244.83) (Ping timeout: 245 seconds)
20:26:59 TonyStone joins (~TonyStone@074-076-057-186.res.spectrum.com)
20:29:19 a51 joins (a51@gateway/vpn/protonvpn/a51)
20:30:45 × ezzieyguywuf quits (~Unknown@user/ezzieyguywuf) (Ping timeout: 252 seconds)
20:30:56 × endojelly quits (~eselber_p@user/endojelly) (Ping timeout: 260 seconds)
20:32:34 ezzieyguywuf joins (~Unknown@user/ezzieyguywuf)
20:33:55 visilii joins (~visilii@188.254.126.99)
20:34:07 endojelly joins (~eselber_p@user/endojelly)
20:50:17 szkl joins (uid110435@id-110435.uxbridge.irccloud.com)
21:03:12 × tt1231 quits (~tt1231@2603-6010-8700-4a81-219f-50d3-618a-a6ee.res6.spectrum.com) (Read error: Connection reset by peer)
21:03:36 tt1231 joins (~tt1231@2603-6010-8700-4a81-219f-50d3-618a-a6ee.res6.spectrum.com)
21:05:01 × Lycurgus quits (~georg@user/Lycurgus) (Quit: leaving)
21:05:44 × Silver_X quits (~Silver_X@182.178.246.138) (Quit: Leaving)
21:06:28 todi joins (~todi@p57803331.dip0.t-ipconnect.de)
21:12:20 × tromp quits (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…)
21:13:11 tromp joins (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl)
21:13:47 × euleritian quits (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Read error: Connection reset by peer)
21:14:35 euleritian joins (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de)
21:22:52 × _ht quits (~Thunderbi@28-52-174-82.ftth.glasoperator.nl) (Remote host closed the connection)
21:30:46 tt12310 joins (~tt1231@075-185-104-199.res.spectrum.com)
21:33:43 × tt1231 quits (~tt1231@2603-6010-8700-4a81-219f-50d3-618a-a6ee.res6.spectrum.com) (Ping timeout: 268 seconds)
21:33:44 tt12310 is now known as tt1231
21:36:11 × TonyStone quits (~TonyStone@074-076-057-186.res.spectrum.com) (Ping timeout: 245 seconds)
21:40:45 Lycurgus joins (~georg@user/Lycurgus)
21:41:29 L29Ah joins (~L29Ah@wikipedia/L29Ah)
22:01:11 × euleritian quits (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Ping timeout: 245 seconds)
22:06:37 euleritian joins (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de)
22:16:27 × euleritian quits (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Ping timeout: 272 seconds)
22:25:16 euleritian joins (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de)
22:28:05 × qeef quits (~qeef@138-169-143-94.cust.centrio.cz) (Ping timeout: 240 seconds)
22:30:46 × peterbecich quits (~Thunderbi@047-229-123-186.res.spectrum.com) (Ping timeout: 245 seconds)
22:30:46 × euleritian quits (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Read error: Connection reset by peer)
22:31:39 euleritian joins (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de)
22:37:14 × tromp quits (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…)
22:52:03 tromp joins (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl)
22:57:00 × wootehfoot quits (~wootehfoo@user/wootehfoot) (Ping timeout: 255 seconds)
23:02:22 × tromp quits (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…)
23:04:37 peterbecich joins (~Thunderbi@047-229-123-186.res.spectrum.com)
23:11:58 × zetef quits (~quassel@2a02:2f00:500b:ce00:aba1:3782:4e7c:41a) (Remote host closed the connection)
23:12:45 × noumenon quits (~noumenon@113.51-175-156.customer.lyse.net) (Read error: Connection reset by peer)
23:16:21 × ph88 quits (~ph88@2a02:8109:9e26:c800:32fc:1140:12f0:2672) (Remote host closed the connection)
23:18:53 TonyStone joins (~TonyStone@074-076-057-186.res.spectrum.com)
23:19:15 × destituion quits (~destituio@2001:4644:c37:0:6086:64f4:a213:b80d) (Ping timeout: 256 seconds)
23:19:26 destituion joins (~destituio@2a02:2121:655:c95b:3078:92e:b911:97ff)
23:21:01 × euleritian quits (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Read error: Connection reset by peer)
23:21:09 euleritian joins (~euleritia@dynamic-046-114-095-014.46.114.pool.telefonica.de)
23:21:55 × euleritian quits (~euleritia@dynamic-046-114-095-014.46.114.pool.telefonica.de) (Read error: Connection reset by peer)
23:22:12 euleritian joins (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de)
23:34:50 × chiselfuse quits (~chiselfus@user/chiselfuse) (Remote host closed the connection)
23:34:56 × motherfsck quits (~motherfsc@user/motherfsck) (Ping timeout: 245 seconds)
23:35:28 chiselfuse joins (~chiselfus@user/chiselfuse)
23:44:45 × peterbecich quits (~Thunderbi@047-229-123-186.res.spectrum.com) (Ping timeout: 256 seconds)
23:50:06 × waleee quits (~waleee@h-176-10-144-38.NA.cust.bahnhof.se) (Ping timeout: 255 seconds)
23:51:57 × mechap quits (~mechap@user/mechap) (Quit: WeeChat 4.2.1)
23:54:17 mechap joins (~mechap@user/mechap)
23:55:57 × acidjnk quits (~acidjnk@p200300d6e70d3f39710acbcd8de4867e.dip0.t-ipconnect.de) (Ping timeout: 255 seconds)

All times are in UTC on 2024-03-23.