Logs: freenode/#haskell
| 2021-03-13 18:18:54 | × | __minoru__shirae quits (~shiraeesh@109.166.56.41) (Ping timeout: 256 seconds) |
| 2021-03-13 18:18:57 | <int-e> | dmj`: it doesn't even have to be the optimizer; imagine _ / 0 = error "divide by 0"; a / b = ... |
| 2021-03-13 18:19:01 | → | minoru_shiraeesh joins (~shiraeesh@109.166.56.131) |
| 2021-03-13 18:20:53 | × | conal quits (~conal@192.145.118.125) (Quit: Computer has gone to sleep.) |
| 2021-03-13 18:21:49 | × | jumper149 quits (~jumper149@ip185225.wh.uni-hannover.de) (Quit: WeeChat 3.1) |
| 2021-03-13 18:22:04 | <monochrom> | I wonder if https://mail.haskell.org/pipermail/haskell-cafe/2011-April/091048.html counts >:) |
| 2021-03-13 18:22:21 | → | joebobjoe joins (~joebobjoe@unaffiliated/joebobjoe) |
| 2021-03-13 18:23:02 | × | carlomagno quits (~cararell@148.87.23.6) (Quit: Leaving.) |
| 2021-03-13 18:23:02 | → | jumper149 joins (~jumper149@ip185225.wh.uni-hannover.de) |
| 2021-03-13 18:23:18 | × | jumper149 quits (~jumper149@ip185225.wh.uni-hannover.de) (Client Quit) |
| 2021-03-13 18:23:55 | <monochrom> | To be fair I could not reproduce it with any type that is not as boring as (). |
| 2021-03-13 18:24:17 | → | jumper149 joins (~jumper149@ip185225.wh.uni-hannover.de) |
| 2021-03-13 18:24:39 | <c_wraith> | I bet you could get CSE to kick in if you had a separate use of length xs that had to be evaluated first |
| 2021-03-13 18:26:46 | × | coot quits (~coot@37.30.55.141.nat.umts.dynamic.t-mobile.pl) (Quit: coot) |
| 2021-03-13 18:27:58 | × | stree quits (~stree@68.36.8.116) (Ping timeout: 256 seconds) |
| 2021-03-13 18:28:46 | <dmj`> | monochrom: also, another "gotcha", Divide-by-zero isn't thrown unless its a Rational, otherwise, just NaN is returned (Double / Float). So not identical behavior for all Fractional instances. The plot thickens. |
| 2021-03-13 18:28:52 | × | jamm_ quits (~jamm@unaffiliated/jamm) (Remote host closed the connection) |
| 2021-03-13 18:29:08 | → | ddellacosta joins (~ddellacos@86.106.143.83) |
| 2021-03-13 18:29:18 | → | heatsink joins (~heatsink@2600:1700:bef1:5e10:c79:3d13:d977:c947) |
| 2021-03-13 18:30:21 | <dmj`> | int-e: sure that makes sense, unless 'a' had been evaluated elsewhere 'b' should be forced first because of the 0 check. I want to see where GHC is at liberty to choose. That example doesn't seem like GHC has a choice (assuming both 'a' and 'b' are thunks). |
| 2021-03-13 18:32:04 | <int-e> | dmj`: well with the floating point version it gets a choice |
| 2021-03-13 18:32:21 | <int-e> | as you just pointed out yourself |
| 2021-03-13 18:32:26 | × | tromp quits (~tromp@dhcp-077-249-230-040.chello.nl) (Remote host closed the connection) |
| 2021-03-13 18:32:43 | → | bobiusbillius joins (~bobiusbil@2a00:23c7:9909:5b01:9143:54d3:f1e8:156d) |
| 2021-03-13 18:32:58 | → | tromp joins (~tromp@dhcp-077-249-230-040.chello.nl) |
| 2021-03-13 18:33:58 | × | ddellacosta quits (~ddellacos@86.106.143.83) (Ping timeout: 276 seconds) |
| 2021-03-13 18:33:58 | × | tromp quits (~tromp@dhcp-077-249-230-040.chello.nl) (Read error: Connection reset by peer) |
| 2021-03-13 18:34:11 | × | jumper149 quits (~jumper149@ip185225.wh.uni-hannover.de) (Quit: WeeChat 3.1) |
| 2021-03-13 18:34:14 | → | tromp joins (~tromp@dhcp-077-249-230-040.chello.nl) |
| 2021-03-13 18:34:14 | × | heatsink quits (~heatsink@2600:1700:bef1:5e10:c79:3d13:d977:c947) (Ping timeout: 264 seconds) |
| 2021-03-13 18:35:28 | → | Sgeo joins (~Sgeo@ool-18b98aa4.dyn.optonline.net) |
| 2021-03-13 18:37:03 | <dmj`> | int-e: wouldn't it /not/ have a choice because it would evaluate the first case (_ / 0) -- thus forcing 'b' first. Order of the function definitions matters. |
| 2021-03-13 18:37:16 | → | tromp_ joins (~tromp@dhcp-077-249-230-040.chello.nl) |
| 2021-03-13 18:37:31 | → | jumper149 joins (~jumper149@ip185225.wh.uni-hannover.de) |
| 2021-03-13 18:37:36 | <dmj`> | if a / b was defined before _ / 0 then I'd believe it has a choice |
| 2021-03-13 18:37:39 | <int-e> | dmj`: there is no error case, division is just strict in both arguments. |
| 2021-03-13 18:37:54 | × | CaptainIRS quits (9d31f23d@157.49.242.61) (Quit: Connection closed) |
| 2021-03-13 18:38:09 | <int-e> | > undefined/0 :: Float |
| 2021-03-13 18:38:11 | <lambdabot> | *Exception: Prelude.undefined |
| 2021-03-13 18:38:34 | <int-e> | > 0/undefined :: Float |
| 2021-03-13 18:38:36 | <lambdabot> | *Exception: Prelude.undefined |
| 2021-03-13 18:38:47 | <monochrom> | > undefined/0 :: Rational |
| 2021-03-13 18:38:49 | <lambdabot> | *Exception: Prelude.undefined |
| 2021-03-13 18:38:57 | × | tromp quits (~tromp@dhcp-077-249-230-040.chello.nl) (Ping timeout: 264 seconds) |
| 2021-03-13 18:39:51 | × | jumper149 quits (~jumper149@ip185225.wh.uni-hannover.de) (Client Quit) |
| 2021-03-13 18:40:09 | → | stree joins (~stree@68.36.8.116) |
| 2021-03-13 18:40:16 | <int-e> | dmj`: in that imaginary example, yes, it would not get a choice |
| 2021-03-13 18:40:58 | <dmj`> | sure, its strict in both arguments. |
| 2021-03-13 18:41:07 | <dmj`> | > error "foo" / error "bar" |
| 2021-03-13 18:41:09 | <lambdabot> | *Exception: foo |
| 2021-03-13 18:41:21 | × | darjeeling_ quits (~darjeelin@122.245.218.92) (Ping timeout: 264 seconds) |
| 2021-03-13 18:41:51 | → | frozen_burnman joins (~frozen_bu@80-90-135-76.static.oxid.cz) |
| 2021-03-13 18:41:56 | <int-e> | ghc tends to be careful with that extra freedom offered by exchanging one bottom for another |
| 2021-03-13 18:42:23 | → | ADG1089__ joins (~aditya@106.212.74.137) |
| 2021-03-13 18:42:33 | <int-e> | I don't really know under what circumstances it does that. |
| 2021-03-13 18:43:12 | <tomsmeding> | there is https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/bugs.html#expressions-and-patterns |
| 2021-03-13 18:43:13 | → | jumper149 joins (~jumper149@ip185225.wh.uni-hannover.de) |
| 2021-03-13 18:43:25 | <tomsmeding> | though that's a bit more subtle than the discussion at hand, I think |
| 2021-03-13 18:43:43 | × | jumper149 quits (~jumper149@ip185225.wh.uni-hannover.de) (Client Quit) |
| 2021-03-13 18:43:50 | × | frozenErebus quits (~frozenEre@94.128.82.20) (Ping timeout: 256 seconds) |
| 2021-03-13 18:48:06 | → | marinelli joins (~marinelli@gateway/tor-sasl/marinelli) |
| 2021-03-13 18:49:08 | × | tromp_ quits (~tromp@dhcp-077-249-230-040.chello.nl) (Remote host closed the connection) |
| 2021-03-13 18:49:25 | <dmj`> | tomsmeding: yea, when it says, "This should call error, but it returns True", I don't agree with that statement. seq (f []) returns a partially applied function evaluated to whnf, but its not the application of the function. f [] :: b -> b, maybe it should say, "this seems like it should call error" |
| 2021-03-13 18:50:00 | <tomsmeding> | dmj`: ah, but f [] is defined as error, isn't it? |
| 2021-03-13 18:50:18 | <tomsmeding> | so evaluating f [] to WHNF using seq should technically speaking throw an error |
| 2021-03-13 18:50:34 | <tomsmeding> | note that evaluating function types to WHNF does actually do something: |
| 2021-03-13 18:50:41 | <tomsmeding> | > (undefined :: Int -> Int) `seq` () |
| 2021-03-13 18:50:42 | × | geekosaur quits (82650c7a@130.101.12.122) (Ping timeout: 240 seconds) |
| 2021-03-13 18:50:43 | <lambdabot> | *Exception: Prelude.undefined |
| 2021-03-13 18:51:49 | <tomsmeding> | an actual lambda object, or I guess a closure object in proper terminology, is the WHNF of a function type |
| 2021-03-13 18:51:51 | <dmj`> | that's different, you're unboxing undefined here. f [] is not fully applied to produce the undefined, despite the fact the argument is unused, it seems one needs to be applied. |
| 2021-03-13 18:52:12 | <tomsmeding> | dmj`: "f [] is not fully applied" -- isn't it? |
| 2021-03-13 18:52:20 | <dmj`> | tomsmeding: what's the type of f ? |
| 2021-03-13 18:52:28 | <dmj`> | tomsmeding: note the eta expansion |
| 2021-03-13 18:52:28 | <tomsmeding> | well, [a] -> b -> b |
| 2021-03-13 18:52:37 | <dmj`> | no 'b' was specified |
| 2021-03-13 18:52:59 | → | monadmatt joins (~user@119-17-128-101.771180.mel.nbn.aussiebb.net) |
| 2021-03-13 18:53:53 | <tomsmeding> | dmj`: would it be different if we had 'newtype Func b = Func (b -> b)', and 'f :: [a] -> Func b', where 'f [] = error "urk" ; f (x:xs) = Func (\x -> x)' ? |
| 2021-03-13 18:54:28 | → | darjeeling_ joins (~darjeelin@122.245.218.190) |
| 2021-03-13 18:54:32 | <tomsmeding> | there 'f [] `seq` True' should certainly error, right? |
| 2021-03-13 18:55:16 | <tomsmeding> | I guess same question if I wrote 'data' instead of 'newtype' |
| 2021-03-13 18:55:43 | <dmj`> | @def newtype Func b = Func (b -> b) |
| 2021-03-13 18:55:44 | <lambdabot> | Defined. |
| 2021-03-13 18:56:48 | <dmj`> | @def func' :: [a] -> Func b; func' [] = error "urk"; func' (x:xs) = Func (\x -> x) |
| 2021-03-13 18:56:50 | <lambdabot> | Defined. |
| 2021-03-13 18:57:10 | <dmj`> | > func' [] `seq` True |
| 2021-03-13 18:57:12 | <lambdabot> | *Exception: urk |
| 2021-03-13 18:57:21 | × | monadmatt quits (~user@119-17-128-101.771180.mel.nbn.aussiebb.net) (Ping timeout: 246 seconds) |
| 2021-03-13 18:57:38 | <c_wraith> | dmj`: whether or not you like it, eta expansion can actually remove bottoms in Haskell. It's not 100% valid as an optimization |
| 2021-03-13 18:57:44 | <tomsmeding> | because the WHNF of a Func is the constructor, which in this case evaluates to bottom |
| 2021-03-13 18:58:30 | <tomsmeding> | if it was 'data Func', that would be correct; now that it's 'newtype Func' the field of Func is strict, so it's not only the Func constructor but also the function inside of it that needs to be evaluated to get the WHNF of Func |
| 2021-03-13 18:58:34 | <dmj`> | tomsmeding: hmm, still don't think this is comparing apples to apples though, eta-expansion isn't happening in the same way with Func as it is with f :: [a] -> b -> b |
| 2021-03-13 18:58:37 | <tomsmeding> | not that it matters in this particular example |
| 2021-03-13 18:58:58 | <tomsmeding> | but then, how is the type (b -> b) any different from Func? |
| 2021-03-13 18:59:05 | <tomsmeding> | it's still a type that can have values |
| 2021-03-13 18:59:16 | <c_wraith> | It's different in how GHC optimizes it. |
| 2021-03-13 18:59:33 | <tomsmeding> | true, which ghc declares as a bug in its user's guide :) |
| 2021-03-13 18:59:36 | <tomsmeding> | though an intentional bug |
| 2021-03-13 19:00:07 | <dmj`> | tomsmeding: its different because Func is wrapping it right |
| 2021-03-13 19:00:09 | <koz_> | c_wraith: "eta expansion can actually remove bottoms" <-- Sir Mix-a-Lot is disappointed |
All times are in UTC.