2026/04/09

Newest at the top

2026-04-09 11:50:18 +0000 <tomsmeding> Freakie: we're talking about the semantic level here, where reading the value from memory doesn't count as recomputation
2026-04-09 11:50:06 +0000 <Milan_Vanca> ?
2026-04-09 11:49:59 +0000 <mauke> Freakie: ???
2026-04-09 11:49:55 +0000 <Freakie> (I think)
2026-04-09 11:49:53 +0000 <Freakie> if it can't fit in the registers it will have to be recomputed
2026-04-09 11:49:44 +0000 <tomsmeding> if x :: Num a => a, or Show a => [a], or something like that, then it will (likely!) be recomputed
2026-04-09 11:49:43 +0000 <Freakie> it's also tricky because if you assume *any* number of instructions you can't say anything register allocation
2026-04-09 11:49:33 +0000Enrico63(~Enrico63@host-212-171-80-94.pool212171.interbusiness.it) Enrico63
2026-04-09 11:49:24 +0000 <tomsmeding> if x :: Int, then x will be computed only once
2026-04-09 11:49:11 +0000 <tomsmeding> Milan_Vanca: no, you cannot say anything about your example unless you know what the type of x is
2026-04-09 11:49:03 +0000 <mauke> what
2026-04-09 11:48:51 +0000 <Milan_Vanca> tomsmeding showed that x will be computed only once.. so first 2 will be reused then forgoten then recomputed?
2026-04-09 11:48:29 +0000 <Freakie> tomsmeding we're not strictly talking purity here though
2026-04-09 11:48:12 +0000 <mauke> first what?
2026-04-09 11:48:04 +0000 <Milan_Vanca> the same as first one
2026-04-09 11:48:03 +0000 <tomsmeding> if x has a monomorphic type, reused; if x has a polymorphic type with type class constraints, recomputed (likely)
2026-04-09 11:47:40 +0000 <mauke> Milan_Vanca: depends on the type of x
2026-04-09 11:47:37 +0000 <tomsmeding> Freakie: yes, because without IO, everything is pure and hence deterministic
2026-04-09 11:47:29 +0000 <Milan_Vanca> what about main = do print x; print x; ... lot of other code; print x will last x be kept or recomputed?
2026-04-09 11:47:24 +0000 <tomsmeding> in which case, well, you're using unsafePerformIO, you better know what you're doing
2026-04-09 11:47:23 +0000 <Freakie> would it have to use unsafePerformIO?
2026-04-09 11:47:10 +0000 <tomsmeding> Freakie: the only way I can make sense of that is `unsafePerformIO (uniform <$> newStdGen)` or whatever the precise API is of System.Random
2026-04-09 11:46:21 +0000 <tomsmeding> at which point, `x' :: Int` and is a normal variable, so that `print x' >> print x'` will definitely compute x only once
2026-04-09 11:46:00 +0000 <tomsmeding> then GHC can decide to do common subexpression elimination, and rewrite that to `main = let x' = x dNumInt in print x' >> print x'`, but GHC may or may not decide to do this
2026-04-09 11:45:59 +0000haritz(~hrtz@user/haritz) haritz
2026-04-09 11:45:59 +0000haritz(~hrtz@2a01:4b00:bc2e:7000:d5af:a266:ca31:5ef8) (Changing host)
2026-04-09 11:45:59 +0000haritz(~hrtz@2a01:4b00:bc2e:7000:d5af:a266:ca31:5ef8)
2026-04-09 11:45:26 +0000 <mauke> Freakie: ?
2026-04-09 11:45:25 +0000 <tomsmeding> assuming you mean `print (x :: Int)`, that compiles to something like `main = print (x dNumInt) >> print (x dNumInt)`, where dNumInt is the "Num Int" type class dictionary (evidence)
2026-04-09 11:45:14 +0000 <Freakie> if x is a value from a non-deterministic monad it should be recomputed
2026-04-09 11:44:50 +0000 <mauke> but it sounds like you're talking about the result of a function
2026-04-09 11:44:35 +0000 <mauke> functions are also reused
2026-04-09 11:44:31 +0000 <Milan_Vanca> yeah but in example of main = do print x; print x it is always same right? should not be reevaluated?
2026-04-09 11:44:30 +0000 <Freakie> I mean if called with the same type argument it should reuse the expression?
2026-04-09 11:44:22 +0000 <tomsmeding> what GHC _could_ do is reuse x when used twice at the same type; whether that actually happens depends on what GHC's optimiser decides to do, no guarantees
2026-04-09 11:44:20 +0000 <mauke> well...
2026-04-09 11:43:53 +0000 <tomsmeding> Milan_Vanca: indeed, because it _cannot_ be reused: its value is different at different types 'a'!
2026-04-09 11:43:42 +0000 <tomsmeding> thus it's really a function: from the "Num a" evidence to the resulting value; the `=>` arrow should be read as a function arrow here
2026-04-09 11:43:26 +0000 <Milan_Vanca> so x in your example is function and wont be reused?
2026-04-09 11:43:18 +0000 <tomsmeding> there we have `x :: Num a => a`, and x's value is different for each type you can fill in for `a`
2026-04-09 11:42:56 +0000 <tomsmeding> variables can be secretly functions if they are actually polymorphic with a typeclass argument, such as `x = 4`
2026-04-09 11:42:48 +0000 <mauke> (where "secretly a function" is that class constraints thing I was talking about)
2026-04-09 11:42:02 +0000 <tomsmeding> Milan_Vanca: using a variable name multiple times does not result in its definition being computed multiple times, except when that variable is secretly a function
2026-04-09 11:41:30 +0000 <mauke> you never "need" do notation
2026-04-09 11:41:28 +0000 <Freakie> to answer your question though, pure expressions will only be evaluated once (heavy_pi :: Double etc)
2026-04-09 11:41:01 +0000troydm(~troydm@user/troydm) (Quit: What is Hope? That all of your wishes and all of your dreams come true? To turn back time because things were not supposed to happen like that (C) Rau Le Creuset)
2026-04-09 11:41:00 +0000 <Freakie> you need do notation when in the IO monad
2026-04-09 11:39:51 +0000 <Milan_Vanca> maybe i am missing "do"
2026-04-09 11:39:09 +0000myme(~myme@2a01:799:d5e:5f00:374a:96c4:fb0d:7007) myme
2026-04-09 11:38:58 +0000 <Milan_Vanca> heavy_pi :: Double main = print heavy_pi; print heavy_pi...