Thanks Simon, this is an interesting and compelling interpretation. But I'm wondering whether it is enough to specify the dynamic semantics unambiguously.
Two examples: 1. let _ = undefined in () Intuitively, since we are talking about /strictness/, this should evaluate to bottom. However, it seems that your rule also admits () as an answer; it is equivalent to () under lazy evaluation *and* it does not create any thunks. 2. f g = g undefined When compiled lazily, this code doesn't construct any thunks: f = \r srt:SRT:[02v :-> undefined] [g_suM] g_suM undefined; So, under your rule, this is an admissible code for -XStrict, too. But we can hardly call it strict. On 12/12/2015 12:38 AM, Simon Peyton Jones wrote: > | As I said, I prefer this semantics mainly because it's easier to > | explain: all variables (and underscores) bound in a strict module refer > | to WHNF values. Do you have a similarly simple explanation for the > | semantics you're suggesting? > > Here's one, which is roughly what the current implementation does (modulo > bugs): > > * Code compiled under -XStrict constructs no thunks. > > So consider > > module M1 where data T = C Int Int > module M2 where f n = C (n+1) (n-1) > module M3 where g x = let C y z = f x in ... > > Look at M3. Usually we'd get a thunk for (f 4), but not with -XStrict. But > even with -XStrict in M3, y,z might be bound to thunks. > > If you compile M2 with -XStrict, function f won't build thunks for (n+1), > (n-1) but will evaluate them instead. > > If you compile M1 with StrictData, then C is made strict, so again M2 will > build no thunks even if M2 was compiled without -XStrict. > > I quite like this design. It's not clear to me that anything useful is > gained by forcing y and z in M3 before evaluating the body "...". > > > So Roman's design makes sense, but so does the implemented design (modulo any > bugs). The trouble is that the implemented design is not well described. > > Simon > > | -----Original Message----- > | From: ghc-devs [mailto:ghc-devs-boun...@haskell.org] On Behalf Of Roman > | Cheplyaka > | Sent: 11 December 2015 12:57 > | To: Johan Tibell <johan.tib...@gmail.com> > | Cc: ghc-devs@haskell.org > | Subject: Re: -XStrict: Why some binders are not made strict? > | > | On 12/11/2015 02:21 PM, Johan Tibell wrote: > | > If we force strictness all the way down it's not really call-by-value > | > either, because the caller doesn't know what to evaluate (I think). > | > | Not sure what you mean here. > | > | > In addition, making pattern matching strict in this way makes it hard to > | > mix and match strict and lazy data types (e.g. Maybe), because using a > | > lazy data type from another module will make it appear strict in your > | > code (hurting modularity). > | > | I don't think this is a case about modularity. A lazy Maybe value > | defined in a lazy module remains lazy; and you can pass it to lazy > | functions without forcing it. Only when you pattern match on it *in the > | strict module*, the evaluation happens. > | > | As I said, I prefer this semantics mainly because it's easier to > | explain: all variables (and underscores) bound in a strict module refer > | to WHNF values. Do you have a similarly simple explanation for the > | semantics you're suggesting? > | > | Roman >
signature.asc
Description: OpenPGP digital signature
_______________________________________________ ghc-devs mailing list ghc-devs@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs