Logs: liberachat/#haskell
| 2021-07-05 09:17:52 | <int-e> | typical compiler writer attitude :P |
| 2021-07-05 09:18:07 | → | Xe joins (~cadey@tailscale/xe) |
| 2021-07-05 09:18:08 | → | merijn joins (~merijn@83-160-49-249.ip.xs4all.nl) |
| 2021-07-05 09:18:23 | → | Katarushisu joins (~Katarushi@cpc152083-finc20-2-0-cust170.4-2.cable.virginm.net) |
| 2021-07-05 09:19:20 | <nshepperd> | imo t diverges in the process of attempting to manifest x |
| 2021-07-05 09:19:22 | × | Erutuon quits (~Erutuon@user/erutuon) (Ping timeout: 240 seconds) |
| 2021-07-05 09:20:10 | <int-e> | Anecdote: Once upon a time, I wanted to see if C compilers optimized tail recursion. So I wrote code like int f(int x) { return f(x); } int main() { printf("%d\n", f(42)); }... and icc at the time produced a terminating program (no stack overflow, it printed 0, I think) |
| 2021-07-05 09:21:21 | <int-e> | Or no, it must have been a void function. Anyway, I /think/ the compiler saw a function with no side effects, and decided to elide the call completely. |
| 2021-07-05 09:21:30 | <nshepperd> | certainly control flow never reaches g |
| 2021-07-05 09:22:12 | × | Obo quits (~roberto@70.pool90-171-81.dynamic.orange.es) (Ping timeout: 252 seconds) |
| 2021-07-05 09:22:16 | × | amahl quits (~amahl@dsl-jklbng12-54fbca-64.dhcp.inet.fi) (Remote host closed the connection) |
| 2021-07-05 09:22:19 | <int-e> | nshepperd: as long as we agree that it's not captured in the usual denotational semantics I'm happy |
| 2021-07-05 09:22:22 | → | samhh joins (~samhh@90.252.112.94) |
| 2021-07-05 09:23:00 | <nshepperd> | icc revealed the forbidden integer at the end of time |
| 2021-07-05 09:23:11 | × | merijn quits (~merijn@83-160-49-249.ip.xs4all.nl) (Ping timeout: 252 seconds) |
| 2021-07-05 09:23:30 | → | amahl joins (~amahl@dsl-jklbng12-54fbca-64.dhcp.inet.fi) |
| 2021-07-05 09:23:33 | <int-e> | Somehow, later versions of icc didn't do that. |
| 2021-07-05 09:23:51 | → | Obo joins (~roberto@89.37.95.174) |
| 2021-07-05 09:25:04 | <int-e> | I forgot when it was too, definitely more than 10 years ago. |
| 2021-07-05 09:26:29 | × | samhh quits (~samhh@90.252.112.94) (Client Quit) |
| 2021-07-05 09:27:32 | <nshepperd> | considering bottom to be an inhabitant of (# #) does seem like the most parsimonious way to describe the difference between undefined, const (# #), and your f |
| 2021-07-05 09:27:51 | <nshepperd> | even though you can never actually 'get' a bottom |
| 2021-07-05 09:28:19 | <boxscape> | hm would it be fair to say that `x` in the above paste is an expression without a value? |
| 2021-07-05 09:28:56 | <boxscape> | (If we don't go down that parsimonious route) |
| 2021-07-05 09:32:05 | <int-e> | Or a value without representation? Does it still have to pay taxes? |
| 2021-07-05 09:32:22 | <boxscape> | hmm |
| 2021-07-05 09:32:47 | <boxscape> | well, even the value (# #) :: (# #) doesn't have a runtime representation |
| 2021-07-05 09:33:12 | <int-e> | It does, but it's empty ;) |
| 2021-07-05 09:33:58 | ← | viole parts (~viole@user/viole) (WeeChat 2.9) |
| 2021-07-05 09:34:00 | <boxscape> | int-e: I've been going with the terminology the docs use for Proxy#, where they say "A Proxy# is not only unboxed, it also has a polymorphic kind, and has no runtime representation, being totally free. " |
| 2021-07-05 09:34:53 | → | __monty__ joins (~toonn@user/toonn) |
| 2021-07-05 09:35:01 | <boxscape> | (and Proxy# has the same kind as (# #)) |
| 2021-07-05 09:35:23 | <boxscape> | (...modulo the parameter) |
| 2021-07-05 09:35:37 | <int-e> | Oh, there's this more sensible option: it's a non-value without representation. |
| 2021-07-05 09:35:51 | <boxscape> | mhm |
| 2021-07-05 09:35:57 | × | PsixisP quits (~psixisp@user/psixisp) (Quit: WeeChat 3.2) |
| 2021-07-05 09:36:05 | <int-e> | lazy evaluation deals with a lot of non-values that do have a representation, as thunks. |
| 2021-07-05 09:36:21 | <boxscape> | fair point |
| 2021-07-05 09:36:30 | → | Ariakenom joins (~Ariakenom@c83-255-154-140.bredband.tele2.se) |
| 2021-07-05 09:37:37 | → | jippiedoe joins (~david@2a02-a44c-e14e-1-79f5-6f49-ac21-8a38.fixed6.kpn.net) |
| 2021-07-05 09:38:34 | <nshepperd> | maybe it's the function arrow -> that should have the special denotational treatment for (# #) |
| 2021-07-05 09:38:58 | <nshepperd> | ghc docs call (# #) unlifted, and they must be right |
| 2021-07-05 09:39:04 | → | dragestil joins (~quassel@user/dragestil) |
| 2021-07-05 09:40:21 | <int-e> | "they must be right" is borderline religious |
| 2021-07-05 09:40:33 | <boxscape> | it doesn't have kind `TYPE (BoxedRep Lifted), which makes it unlifted |
| 2021-07-05 09:41:11 | <boxscape> | but it does sound borderline religious :) |
| 2021-07-05 09:41:46 | × | laguneucl quits (~Pitsikoko@2a02:587:dc0b:0:d8f7:cdfe:4658:bec4) (Ping timeout: 240 seconds) |
| 2021-07-05 09:45:11 | × | dragestil quits (~quassel@user/dragestil) (Ping timeout: 252 seconds) |
| 2021-07-05 09:47:24 | <nshepperd> | () -> |
| 2021-07-05 09:48:02 | <nshepperd> | () -> (# #) may have three values, but data Foo = Foo (# #) has two, not three |
| 2021-07-05 09:48:55 | <int-e> | nshepperd: Uhm... surely I can take my x and write "Foo x" |
| 2021-07-05 09:49:21 | <int-e> | Since the data constructor Foo isn't strict. |
| 2021-07-05 09:51:19 | <nshepperd> | that will diverge just as instantly as doing anything else with x |
| 2021-07-05 09:51:27 | <int-e> | Ah this is confusing. I can write it, but it'll be indistinguishable from _|_ |
| 2021-07-05 09:52:26 | <nshepperd> | let x = f () in Foo x is bottom |
| 2021-07-05 09:52:32 | <int-e> | OKay, I agree that data Foo = Foo (# #) isn't different from data Foo = Foo. |
| 2021-07-05 09:52:53 | <int-e> | (in terms of which values it has) |
| 2021-07-05 09:53:01 | × | Ariakenom quits (~Ariakenom@c83-255-154-140.bredband.tele2.se) (Read error: Connection reset by peer) |
| 2021-07-05 09:53:03 | <int-e> | (or rather, how many of them) |
| 2021-07-05 09:55:03 | × | chris_ quits (~chris@81.96.113.213) (Remote host closed the connection) |
| 2021-07-05 09:55:35 | → | Ariakenom joins (~Ariakenom@c83-255-154-140.bredband.tele2.se) |
| 2021-07-05 09:55:44 | → | chris joins (~chris@81.96.113.213) |
| 2021-07-05 09:55:46 | → | chrysanthematic joins (~chrysanth@user/chrysanthematic) |
| 2021-07-05 09:55:48 | chris | is now known as Guest4897 |
| 2021-07-05 09:56:17 | <int-e> | Maybe being allowed to write let x = () is bad, it should really be let !x = f () when f returns an unboxed tuple. |
| 2021-07-05 09:56:25 | × | chrysanthematic quits (~chrysanth@user/chrysanthematic) (Client Quit) |
| 2021-07-05 09:57:04 | <nshepperd> | if that would apply for all unlifted types it would look a bit unwieldy |
| 2021-07-05 09:58:05 | <int-e> | but it's more honest about the semantics |
| 2021-07-05 09:58:54 | → | merijn joins (~merijn@83-160-49-249.ip.xs4all.nl) |
| 2021-07-05 09:59:05 | <int-e> | I mean, no, I'm not proposing to change this in ghc. I'm just trying to pinpoint my confusion and see how it could be reduced. |
| 2021-07-05 09:59:26 | → | warnz joins (~warnz@2600:1700:77c0:5610:20b2:48fc:c4b7:f8df) |
| 2021-07-05 10:00:20 | × | Guest4897 quits (~chris@81.96.113.213) (Ping timeout: 272 seconds) |
| 2021-07-05 10:00:24 | → | SoF joins (~skius@user/skius) |
| 2021-07-05 10:00:35 | <boxscape> | wouldn't `Foo (# #)` be more similar to a function `(# #) -> ()` than to `() -> (# #)`? (Though I think both function types have three values) |
| 2021-07-05 10:00:36 | <int-e> | It wouldn't even help much anyway... instead of having a let binding, I could write Foo (f ()) and that would have the same problem. |
| 2021-07-05 10:00:55 | <int-e> | boxscape: Yes. |
| 2021-07-05 10:01:20 | → | hseg joins (~gesh@185.120.126.10) |
| 2021-07-05 10:01:59 | <int-e> | boxscape: Okay, but Foo is a data constructor; you know which of the three values you're dealing with. |
| 2021-07-05 10:02:28 | <hseg> | Just saw a new-to-me error, need guidance: |
| 2021-07-05 10:02:49 | <hseg> | am derivingVia a class with associated types |
| 2021-07-05 10:02:55 | <hseg> | and got "Reduction stack overflow"? |
| 2021-07-05 10:03:10 | <int-e> | boxscape: So... actually... no. We have Foo :: (# #) -> Foo, where Foo is isomorphic to (). |
| 2021-07-05 10:03:12 | <hseg> | (wrapping around HashMap, am deriving SetContainer) |
| 2021-07-05 10:03:17 | <hseg> | (from mono-traversable) |
| 2021-07-05 10:03:31 | <boxscape> | hseg: sounds like an infinite loop at the type level? |
| 2021-07-05 10:03:40 | <hseg> | seems so |
| 2021-07-05 10:03:55 | <hseg> | though am puzzled at why it would be there |
| 2021-07-05 10:04:00 | × | warnz quits (~warnz@2600:1700:77c0:5610:20b2:48fc:c4b7:f8df) (Ping timeout: 252 seconds) |
| 2021-07-05 10:04:38 | <boxscape> | can you share code? |
| 2021-07-05 10:04:39 | <int-e> | boxscape: What do you mean by `Foo (# #)`, is it a value or the declaration of the constructor as part of the datatype defintion? |
| 2021-07-05 10:05:00 | <boxscape> | int-e: I suppose I really meant the type `Foo` |
| 2021-07-05 10:05:18 | → | Codaraxis joins (~Codaraxis@user/codaraxis) |
| 2021-07-05 10:05:33 | <hseg> | it's basically newtype CM k v = CM (HashMap k v) deriving SetContainer via (HashMap k v) |
| 2021-07-05 10:05:57 | <hseg> | can try bisecting a mwe if that doesn't repro for you |
| 2021-07-05 10:06:45 | <hseg> | checking the SetContainer (HashMap k v) instance I see no reason for looping either |
| 2021-07-05 10:07:03 | <int-e> | what is SetContainer? |
| 2021-07-05 10:07:05 | <hseg> | like, i'd expect the derived instance to just copy the synonym |
| 2021-07-05 10:07:09 | <hseg> | from mono-traversable |
| 2021-07-05 10:07:15 | <hseg> | https://hackage.haskell.org/package/mono-traversable-1.0.15.1/docs/Data-Containers.html |
| 2021-07-05 10:08:39 | <hseg> | oh wait |
All times are in UTC.