Newest at the top
| 2026-04-09 12:22:33 +0000 | <merijn> | Milan_Vanca: Eventually as evaluation procedes parts of the original graph become unreachable (and thus eligible for GC) |
| 2026-04-09 12:22:03 +0000 | <merijn> | refers to the result (regardless of how you reach x) |
| 2026-04-09 12:21:57 +0000 | <merijn> | Milan_Vanca: basically we start out with a graph of expressions with main as root, which references x and 'one_hour_long', where 'one_hour_long' in turn also references x (which is a subgraph of '4' '+' and '1'), as code gets evaluated these graphs expand and collapse as we force new computation. Starting to evaluate 'x' first materialises this subgraph of 4+1, once that evaluation is complete 'x' just |
| 2026-04-09 12:21:16 +0000 | uli-fem | (~uli-fem@115.128.112.118) |
| 2026-04-09 12:19:55 +0000 | <merijn> | Milan_Vanca: No |
| 2026-04-09 12:19:50 +0000 | <Milan_Vanca> | Does it matter if X is defined in another module? |
| 2026-04-09 12:19:49 +0000 | <merijn> | Milan_Vanca: It helps to think of a haskell program as a data structure that is mutated |
| 2026-04-09 12:16:35 +0000 | synchromesh | (~john@2406:5a00:2412:2c00:e029:fa8c:cb38:398f) synchromesh |
| 2026-04-09 12:16:05 +0000 | synchromesh | (~john@2406:5a00:2412:2c00:8174:9ae9:efe0:c152) (Read error: Connection reset by peer) |
| 2026-04-09 12:14:56 +0000 | <Milan_Vanca> | It knows it can reuse the same x even when it is in different function |
| 2026-04-09 12:14:28 +0000 | <Milan_Vanca> | So x is computed once and kept for first 30 mins..hmmmm.. interesting. |
| 2026-04-09 12:12:47 +0000 | <merijn> | Milan_Vanca: 'x' becomes unreachable (an thus GC-able) after the first 30 minutes elapse |
| 2026-04-09 12:12:16 +0000 | <merijn> | Milan_Vanca: Once the heap is full and GC is triggered it copies all live data (that is, data that is still reachable from the currently evaluating code) and copies that to a new heap. Then the old heap is reset |
| 2026-04-09 12:12:13 +0000 | <Milan_Vanca> | Guyz.. what about this example https://paste.tomsmeding.com/TvkbD7xi |
| 2026-04-09 12:11:36 +0000 | <merijn> | Milan_Vanca: Basically, GHC uses a "copy & compact" GC strategy. Which means it only cares (and scales in) live data |
| 2026-04-09 12:10:58 +0000 | <Milan_Vanca> | I am aware of GC and their purpose.. and all these questions stem from this fact :) |
| 2026-04-09 12:10:29 +0000 | <mauke> | :-) |
| 2026-04-09 12:10:24 +0000 | <merijn> | mauke: Well, if you wanna be pedantic it's "no longer makes unavailable for release" ;) |
| 2026-04-09 12:10:10 +0000 | <mauke> | haskell doesn't do timely destruction |
| 2026-04-09 12:10:09 +0000 | machinedgod | (~machinedg@d172-219-48-230.abhsia.telus.net) machinedgod |
| 2026-04-09 12:09:58 +0000 | <mauke> | s/releases/makes available for release/ |
| 2026-04-09 12:09:38 +0000 | <merijn> | Milan_Vanca: But that's pretty much how it works in any garbage collected languages, that's not really specific to Haskell :) |
| 2026-04-09 12:09:12 +0000 | <merijn> | correct |
| 2026-04-09 12:09:04 +0000 | <Milan_Vanca> | I gues compiler sees that x is not used after one_hour_long and so releases it as soon as it finish printing of x? |
| 2026-04-09 12:08:02 +0000 | <Milan_Vanca> | Sorry to bother you with these stupid questions but I have found no tutorial on this matter. |
| 2026-04-09 12:07:44 +0000 | uli-fem | (~uli-fem@115.128.112.118) (Ping timeout: 268 seconds) |
| 2026-04-09 12:07:42 +0000 | <Milan_Vanca> | Will https://paste.tomsmeding.com/XLBvdfd1 will x be in memory while one_hour_long computation runs? |
| 2026-04-09 12:05:08 +0000 | <tomsmeding> | here x is a global variable, so it never goes out of scope, so it lives forever (until the GC decides that it's pointless keeping it around because nothing references it any more) |
| 2026-04-09 12:04:39 +0000 | <tomsmeding> | on a higher level: x is a monomorphic variable, so its value will live (once computed) until it goes out of scope -- or potentially for even longer if GHC decides so |
| 2026-04-09 12:04:37 +0000 | <merijn> | mauke: It's a CAF, those can be GCed just fine if nothing references them anymore |
| 2026-04-09 12:04:13 +0000 | <merijn> | mauke: Yes |
| 2026-04-09 12:03:50 +0000 | <tomsmeding> | they can be, yes |
| 2026-04-09 12:03:43 +0000 | <mauke> | are those ever released? |
| 2026-04-09 12:03:37 +0000 | <mauke> | also, x is a global variable |
| 2026-04-09 12:03:22 +0000 | <tomsmeding> | Milan_Vanca: the recursive function 'main' has a reference to x, and main stays alive (because it loops), so its reference to x also stays alive, so the GC does not remove x |
| 2026-04-09 12:02:41 +0000 | uli-fem | (~uli-fem@115.128.112.118) |
| 2026-04-09 12:02:21 +0000 | <tomsmeding> | apparently GHC does decide to keep `x` in your print x >> print x example; click Core here: https://play.haskell.org/saved/4XJoAJ1A |
| 2026-04-09 12:02:08 +0000 | <mauke> | import Debug.Trace (trace); x :: Int; x = trace "computing x" (4 + 1) |
| 2026-04-09 12:01:44 +0000 | <merijn> | `x` is not polymorphic and not "function-like" so the MMR doesn't apply |
| 2026-04-09 12:01:33 +0000 | <mauke> | you can test it, btw |
| 2026-04-09 12:01:18 +0000 | <merijn> | No |
| 2026-04-09 12:01:09 +0000 | <Milan_Vanca> | This must be recomputed multiple times right? |
| 2026-04-09 12:01:00 +0000 | <Milan_Vanca> | There is recursion.. and there is only one reference to x |
| 2026-04-09 12:00:44 +0000 | <Milan_Vanca> | I thought so.. what about this example https://paste.tomsmeding.com/C5RBYVCY |
| 2026-04-09 11:59:46 +0000 | <tomsmeding> | because once a value has no references to it any more, the garbage collector (GC) cleans it up |
| 2026-04-09 11:59:44 +0000 | <mauke> | yes |
| 2026-04-09 11:59:34 +0000 | <tomsmeding> | until you don't have any references to it any more |
| 2026-04-09 11:59:13 +0000 | <Milan_Vanca> | So basically If instead of X I allocated gigantic bytestring.. it would be ketp in memory for whole time program is running? |
| 2026-04-09 11:57:29 +0000 | <tomsmeding> | (there's enough unpredictability as it is) |
| 2026-04-09 11:57:11 +0000 | <tomsmeding> | there could be, if you interpret the semantics loosely, but that would result in extremely unpredictable performance and memory use and hence GHC does not do that |