2026/04/09

Newest at the top

2026-04-09 11:51:22 +0000 <tomsmeding> Milan_Vanca: precisely that code, without any type annotations?
2026-04-09 11:51:10 +0000 <Milan_Vanca> https://paste.tomsmeding.com/resvyMiU
2026-04-09 11:51:08 +0000 <Milan_Vanca> what about this?
2026-04-09 11:51:00 +0000 <tomsmeding> (that's like 4 abstraction levels down suddenly from what we were talking about_)
2026-04-09 11:50:39 +0000 <tomsmeding> if you want to know whether a memory read will occur, well, good luck reading the assembly, no guarantees
2026-04-09 11:50:38 +0000 <Freakie> i guess memoization invalidates what I just said yeah
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