Newest at the top
2025-04-01 17:41:29 +0200 | <tomsmeding> | I guess this particular point cannot be proved nor disproved, though, because the spec is just that they behave the way they do |
2025-04-01 17:41:27 +0200 | <lambdabot> | *Exception: Prelude.undefined |
2025-04-01 17:41:26 +0200 | <int-e> | > let !x = undefined in 42 |
2025-04-01 17:40:42 +0200 | <tomsmeding> | talking about an implicit ~ means that you're implicitly (!) assuming that patterns are strict by default |
2025-04-01 17:40:15 +0200 | <tomsmeding> | I guess |
2025-04-01 17:40:07 +0200 | <int-e> | because T (!(x,y)) is treated like to ~(T (!(x,y))) |
2025-04-01 17:39:54 +0200 | CiaoSen | (~Jura@2a02:8071:64e1:da0:5a47:caff:fe78:33db) CiaoSen |
2025-04-01 17:39:47 +0200 | <tomsmeding> | the behaviour _is_ consistent with the docs, but it's a bit subtle |
2025-04-01 17:39:12 +0200 | <tomsmeding> | (see above) |
2025-04-01 17:39:04 +0200 | <int-e> | tomsmeding: right, but for `let` they behave differently: https://paste.tomsmeding.com/sQ0J5fNj |
2025-04-01 17:38:47 +0200 | <lambdabot> | () |
2025-04-01 17:38:46 +0200 | <tomsmeding> | > let Identity (!x) = undefined in () |
2025-04-01 17:38:40 +0200 | <lambdabot> | () |
2025-04-01 17:38:38 +0200 | <tomsmeding> | > let Identity !x = undefined in () |
2025-04-01 17:38:34 +0200 | <lambdabot> | *Exception: Prelude.undefined |
2025-04-01 17:38:33 +0200 | <tomsmeding> | > let !(Identity x) = undefined in () |
2025-04-01 17:38:30 +0200 | <EvanR> | now it's any pattern |
2025-04-01 17:38:29 +0200 | <lambdabot> | () |
2025-04-01 17:38:27 +0200 | <tomsmeding> | > let Identity x = undefined in () |
2025-04-01 17:38:26 +0200 | <EvanR> | earlier x was a placeholder for any variable |
2025-04-01 17:38:14 +0200 | <EvanR> | lol |
2025-04-01 17:38:11 +0200 | <int-e> | sorry |
2025-04-01 17:38:10 +0200 | <int-e> | EvanR: ah my `x` is a placeholder for a pattern |
2025-04-01 17:38:08 +0200 | <EvanR> | because foo is evaluated |
2025-04-01 17:38:05 +0200 | <tomsmeding> | with let bindings, an outermost ! specifically has additional semantics of making the binding strict instead of lazy |
2025-04-01 17:37:48 +0200 | <EvanR> | how is that different from case foo of x -> |
2025-04-01 17:37:47 +0200 | <tomsmeding> | if T is a newtype then `case _ of T (!x) -> _` is the same as `case _ of !(T x) -> _` is the same as `case _ of T x -> _` because there is no distinct `T _|_` thunk |
2025-04-01 17:37:20 +0200 | <int-e> | a non-recursive let x = foo in ... is more or less case foo of ~x -> ... |
2025-04-01 17:37:20 +0200 | <EvanR> | still |
2025-04-01 17:37:17 +0200 | <EvanR> | or we're just talking about let bindings |
2025-04-01 17:37:01 +0200 | <tomsmeding> | oh right, exactly because of what I just said |
2025-04-01 17:36:55 +0200 | <EvanR> | what implicit outermost ~ |
2025-04-01 17:36:32 +0200 | mari-estel | (~mari-este@user/mari-estel) mari-estel |
2025-04-01 17:36:27 +0200 | <int-e> | those top-level ! override an implicit outermost ~ |
2025-04-01 17:36:11 +0200 | <int-e> | tomsmeding: yes, and they are different too |
2025-04-01 17:35:57 +0200 | <tomsmeding> | int-e: should they? |
2025-04-01 17:35:32 +0200 | <tomsmeding> | top-level bang patterns have the additional effect of making the whole binding strict |
2025-04-01 17:35:07 +0200 | <tomsmeding> | in a let, that is |
2025-04-01 17:35:00 +0200 | <tomsmeding> | non-top-level bang patterns only have an effect if the pattern as a whole is used |
2025-04-01 17:34:51 +0200 | <int-e> | but for a newtype T, !(T x) and T (!x) should be different |
2025-04-01 17:34:47 +0200 | <lambdabot> | "hi" |
2025-04-01 17:34:45 +0200 | <tomsmeding> | > let (x,!y) = ("x", undefined) in "hi" |
2025-04-01 17:34:41 +0200 | <lambdabot> | "hi *Exception: Prelude.undefined |
2025-04-01 17:34:39 +0200 | <tomsmeding> | > let (x,!y) = ("x", undefined) in "hi " ++ x |
2025-04-01 17:34:15 +0200 | <int-e> | (empirically) |
2025-04-01 17:34:15 +0200 | <EvanR> | ok so we're not lisp yet |
2025-04-01 17:34:06 +0200 | <tomsmeding> | yes, that's how ghc interprets it |
2025-04-01 17:34:04 +0200 | <EvanR> | lol |
2025-04-01 17:34:00 +0200 | <int-e> | EvanR: it's equivalent to let !x = ... |
2025-04-01 17:34:00 +0200 | <tomsmeding> | ambiguous |