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 +0000 | Enrico63 | (~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 +0000 | haritz | (~hrtz@user/haritz) haritz |
| 2026-04-09 11:45:59 +0000 | haritz | (~hrtz@2a01:4b00:bc2e:7000:d5af:a266:ca31:5ef8) (Changing host) |
| 2026-04-09 11:45:59 +0000 | haritz | (~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 +0000 | troydm | (~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 +0000 | myme | (~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... |