Home freenode/#haskell: Logs Calendar

Logs: freenode/#haskell

←Prev  Next→ 502,152 events total
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.