Newest at the top
| 2026-05-28 19:45:24 +0000 | weary-traveler | (~user@user/user363627) (Ping timeout: 244 seconds) |
| 2026-05-28 19:43:25 +0000 | <int-e> | It's still relevant semantically I guess. Explains why it doesn't matter which of the mutually recursive values you evaluate first. |
| 2026-05-28 19:42:42 +0000 | <int-e> | jaror: That bisection isn't attractive as an actual translation because it would duplicate computations. |
| 2026-05-28 19:37:05 +0000 | <jaror> | Should be just fine even with typed Core |
| 2026-05-28 19:36:14 +0000 | <jaror> | I think this is called Bekić's bisection lemma: https://en.wikipedia.org/wiki/Beki%C4%87's_theorem |
| 2026-05-28 19:35:05 +0000 | <int-e> | Yeah in practice that desugaring is more about translating mutual recusion into a single fixed point. And GHC doesn't even do that; STG has a recursive let (and at the Cmm level that recusion is built into thunks with mutual references on the heap) |
| 2026-05-28 19:33:44 +0000 | <lortabac> | probably impossible with a typed Core |
| 2026-05-28 19:27:08 +0000 | <int-e> | lortabac: This is the hard part of the question whether `fix` and `letrec` can be defined in terms of each other. |
| 2026-05-28 19:27:03 +0000 | TimWolla | (~timwolla@2a01:4f8:150:6153:beef::6667) TimWolla |
| 2026-05-28 19:26:42 +0000 | <geekosaur> | (and IIRC `fix` is defined in terms of `let`?) |
| 2026-05-28 19:25:59 +0000 | <geekosaur> | the Haskell-level `fix` isn't, but `let` is defined as `letrec` in Haskell so must have `fix` semantics |
| 2026-05-28 19:25:45 +0000 | <lortabac> | interesting |
| 2026-05-28 19:24:46 +0000 | <int-e> | yes |
| 2026-05-28 19:24:32 +0000 | <lortabac> | int-e: "where fix is the least fixpoint operator" -> it seems to assume that fix is a primitive |
| 2026-05-28 19:24:27 +0000 | peterbecich | (~Thunderbi@71.84.33.135) (Ping timeout: 265 seconds) |
| 2026-05-28 19:22:24 +0000 | <int-e> | lortabac: check out the (semi-formal) translation in https://www.haskell.org/onlinereport/exps.html#sect3.12 |
| 2026-05-28 19:21:59 +0000 | <c_wraith> | for the purpose of being an intermediate representation... yeah, you could unify them at that point. |
| 2026-05-28 19:21:07 +0000 | ouilemur | (~jgmerritt@user/ouilemur) ouilemur |
| 2026-05-28 19:20:37 +0000 | <lortabac> | ah ok, I see what you mean |
| 2026-05-28 19:20:27 +0000 | <lortabac> | desugaring happens later |
| 2026-05-28 19:20:26 +0000 | <c_wraith> | their type checking behavior is part of the semantics of the construct. |
| 2026-05-28 19:20:04 +0000 | <lortabac> | I may be missing something. The typechecker knows whether it's a 'let' or a lambda and can decide whether to generalize or not |
| 2026-05-28 19:20:00 +0000 | <c_wraith> | I'd argue that if you need special rules for type checking them differently, you haven't implemented one in terms of the other. |
| 2026-05-28 19:19:52 +0000 | TimWolla | (~timwolla@2a01:4f8:150:6153:beef::6667) (Quit: Bye) |
| 2026-05-28 19:19:37 +0000 | ouilemur | (~jgmerritt@user/ouilemur) (Ping timeout: 272 seconds) |
| 2026-05-28 19:18:45 +0000 | <c_wraith> | the thing is, Haskell requires both of those behaviors. (as specified) |
| 2026-05-28 19:18:27 +0000 | <lambdabot> | In the expression: (f 1 :: Int, f 2 :: Double) |
| 2026-05-28 19:18:27 +0000 | <lambdabot> | In the expression: f 2 :: Double |
| 2026-05-28 19:18:27 +0000 | <lambdabot> | Couldn't match expected type ‘Double’ with actual type ‘Int’ |
| 2026-05-28 19:18:26 +0000 | <c_wraith> | > (\f -> (f 1 :: Int, f 2 :: Double)) (+1) |
| 2026-05-28 19:18:08 +0000 | <lortabac> | the real issue is that you need at least one of 'fix' or 'let' as a primitive |
| 2026-05-28 19:17:43 +0000 | <lortabac> | this doesn't sound like a hard blocker |
| 2026-05-28 19:17:30 +0000 | <lortabac> | can't you typecheck before desugaring? |
| 2026-05-28 19:17:19 +0000 | <lambdabot> | (2,3.0) |
| 2026-05-28 19:17:18 +0000 | <c_wraith> | > let f = (+1) in (f 1 :: Int, f 2 :: Double) |
| 2026-05-28 19:16:19 +0000 | <c_wraith> | you can't define let in Haskell (as standardized) because it has a special rule in type checking. |
| 2026-05-28 19:15:14 +0000 | <int-e> | (that's the easy part of course) |
| 2026-05-28 19:14:57 +0000 | <lambdabot> | fix f = let x = f x in x |
| 2026-05-28 19:14:57 +0000 | <int-e> | @src fix |
| 2026-05-28 19:14:27 +0000 | target_i | (~target_i@user/target-i/x-6023099) target_i |
| 2026-05-28 19:13:07 +0000 | <lortabac> | or can you define 'let' with 'fix', and 'fix' with 'let'? It seems hard |
| 2026-05-28 19:12:20 +0000 | <lortabac> | I suppose you would need 'fix' as a primitive |
| 2026-05-28 19:11:49 +0000 | <lortabac> | can 'let' in Haskell be implemented by desugaring to lambda application? |
| 2026-05-28 19:11:23 +0000 | <lortabac> | actually it's a good question |
| 2026-05-28 19:10:06 +0000 | euphores | (~SASL_euph@user/euphores) euphores |
| 2026-05-28 19:00:03 +0000 | lisbeths | (uid135845@id-135845.lymington.irccloud.com) lisbeths |
| 2026-05-28 18:58:29 +0000 | poscat | (~poscat@user/poscat) poscat |
| 2026-05-28 18:53:27 +0000 | bggd | (~bgg@user/bggd) (Ping timeout: 252 seconds) |
| 2026-05-28 18:48:41 +0000 | bggd | (~bgg@user/bggd) bggd |
| 2026-05-28 18:48:41 +0000 | bggd | (~bgg@2a01:e0a:fd5:f510:c9c9:a53e:abaa:714) (Changing host) |