Logs: liberachat/#haskell
| 2021-05-30 21:20:51 | <Philonous> | Yes, it seems to be a big hammer |
| 2021-05-30 21:21:08 | <dminuoso> | INLINABLE otoh is a good thing since it just *enables* optimizations without forcing/nudging GHC |
| 2021-05-30 21:21:15 | <dminuoso> | That might not occur |
| 2021-05-30 21:21:45 | <Philonous> | The way to know is to notice that the program isn't going fast enough and then looking at core? |
| 2021-05-30 21:21:59 | <Philonous> | If INLINEABLE is good, why is it not the default? |
| 2021-05-30 21:22:21 | × | ddellacosta quits (~ddellacos@89.46.62.235) (Remote host closed the connection) |
| 2021-05-30 21:22:42 | <geekosaur> | because sometimes it prevents other optimizations |
| 2021-05-30 21:23:39 | <Philonous> | Is there a book / paper / other resource that I can read about all of this? |
| 2021-05-30 21:24:03 | × | curiousgay quits (~quassel@178.217.208.8) (Quit: https://quassel-irc.org - Chat comfortably. Anywhere.) |
| 2021-05-30 21:24:08 | <davean> | ou generally only want to INLINE small things that don't depend on other things |
| 2021-05-30 21:24:13 | <davean> | thats the safe option generally |
| 2021-05-30 21:24:17 | <carter> | yeah, tiny wrappery stuff |
| 2021-05-30 21:24:27 | → | curiousgay joins (~quassel@178.217.208.8) |
| 2021-05-30 21:24:28 | <carter> | dont mark stuff inline/inlineable unless you have evidence its safe |
| 2021-05-30 21:24:45 | → | rahguzar joins (~rahguzar@dynamic-adsl-84-220-228-254.clienti.tiscali.it) |
| 2021-05-30 21:26:52 | → | chaosite joins (~chaosite@user/chaosite) |
| 2021-05-30 21:26:54 | × | alex3 quits (~Chel@BSN-77-82-41.static.siol.net) (Ping timeout: 268 seconds) |
| 2021-05-30 21:27:04 | <dminuoso> | Philonous: So GHC will put definitions of functions into interface files. However, without INLINABLE there's no guarantee of it happening (GHC will only do so its its small). |
| 2021-05-30 21:27:26 | × | hylisper quits (~yaaic@111.119.208.67) (Ping timeout: 265 seconds) |
| 2021-05-30 21:27:31 | <dminuoso> | With INLINABLE it will put the original definition (and potentially specialized versions), but those are pre-simplifier. |
| 2021-05-30 21:27:43 | <maerwald[m]> | Monad instances? |
| 2021-05-30 21:28:02 | <maerwald[m]> | I've seen INLINE there a lot |
| 2021-05-30 21:31:25 | × | jjhoo quits (~jahakala@dsl-trebng21-b048b5-171.dhcp.inet.fi) (Remote host closed the connection) |
| 2021-05-30 21:31:50 | × | chaosite quits (~chaosite@user/chaosite) (Ping timeout: 268 seconds) |
| 2021-05-30 21:33:43 | × | stefan quits (~stefan@p200300cd7715d600184e7fc6541c1028.dip0.t-ipconnect.de) (Quit: WeeChat 3.1) |
| 2021-05-30 21:34:03 | → | tromp joins (~textual@dhcp-077-249-230-040.chello.nl) |
| 2021-05-30 21:35:12 | → | dpl joins (~dpl@77-121-78-163.chn.volia.net) |
| 2021-05-30 21:35:42 | × | lu quits (~lu@user/lu) (Ping timeout: 264 seconds) |
| 2021-05-30 21:36:10 | × | junkicid` quits (~user@2a01:e0a:195:20c0:25dd:142f:ddb3:ffc5) (Ping timeout: 268 seconds) |
| 2021-05-30 21:36:47 | × | merijn quits (~merijn@83-160-49-249.ip.xs4all.nl) (Ping timeout: 268 seconds) |
| 2021-05-30 21:37:04 | × | chisui quits (~chisui@200116b8666f6c001b64469488b78d4f.dip.versatel-1u1.de) (Ping timeout: 250 seconds) |
| 2021-05-30 21:39:38 | → | alex3 joins (~Chel@BSN-77-82-41.static.siol.net) |
| 2021-05-30 21:44:05 | × | tromp quits (~textual@dhcp-077-249-230-040.chello.nl) (Quit: My iMac has gone to sleep. ZZZzzz…) |
| 2021-05-30 21:44:11 | → | pera joins (~pera@user/pera) |
| 2021-05-30 21:45:53 | × | Tuplanolla quits (~Tuplanoll@91-159-68-239.elisa-laajakaista.fi) (Quit: Leaving.) |
| 2021-05-30 21:47:03 | → | fizbin joins (~fizbin@c-73-33-197-160.hsd1.nj.comcast.net) |
| 2021-05-30 21:47:32 | <Philonous> | So, is the point of INLINE then to allow other optimizations to fire (e.g. case of known constructor or case merging). And if there's no optimization we specifically depend on, it's best not to INLINE? |
| 2021-05-30 21:48:32 | <dminuoso> | Philonous: INLINE is a very strong nudge for GHC to inline it, almost forcefully. |
| 2021-05-30 21:48:42 | × | fendor quits (~fendor@178.165.165.191.wireless.dyn.drei.com) (Remote host closed the connection) |
| 2021-05-30 21:49:05 | <dminuoso> | INLINABLE guarantees that interface files have definitions (+ possible specializations), such that they can be inlined cross module/package |
| 2021-05-30 21:49:46 | <dminuoso> | But INLINABLE it wont make GHC any more likely to inline a definition than without it. |
| 2021-05-30 21:50:20 | niko | is now known as o |
| 2021-05-30 21:50:37 | → | jpds joins (~jpds@gateway/tor-sasl/jpds) |
| 2021-05-30 21:50:56 | → | winter joins (~winter@2603-6011-f901-9e5b-0000-0000-0000-08cf.res6.spectrum.com) |
| 2021-05-30 21:51:07 | × | pbrisbin quits (~patrick@pool-72-92-38-164.phlapa.fios.verizon.net) (Ping timeout: 265 seconds) |
| 2021-05-30 21:51:14 | <Philonous> | dminuoso, Yes, I understand that much, I'm trying to get a feeling for when to use INLINE |
| 2021-05-30 21:53:59 | <dminuoso> | One important use case is if you have RULES mentioning bits in the definition of `f`. |
| 2021-05-30 21:54:25 | → | ddellacosta joins (~ddellacos@89.45.224.100) |
| 2021-05-30 21:54:46 | <dminuoso> | Then you might want to forcibly inline `f` via INLINE, so the RULES can fire |
| 2021-05-30 21:55:16 | × | coot quits (~coot@37.30.49.19.nat.umts.dynamic.t-mobile.pl) (Quit: coot) |
| 2021-05-30 21:55:22 | <dminuoso> | With INLINABLE (or nothing) you'd be at the mercy of inliner whether or not they can fire |
| 2021-05-30 21:57:21 | <dminuoso> | edwardk has something to say as well in this thread https://www.reddit.com/r/haskell/comments/cjkc3l/should_i_be_inlining_instance_implementations/evegaqv/ |
| 2021-05-30 21:57:41 | × | rahguzar quits (~rahguzar@dynamic-adsl-84-220-228-254.clienti.tiscali.it) (Ping timeout: 272 seconds) |
| 2021-05-30 21:59:20 | × | ddellacosta quits (~ddellacos@89.45.224.100) (Ping timeout: 265 seconds) |
| 2021-05-30 22:00:39 | <Philonous> | Thanks! |
| 2021-05-30 22:01:01 | × | hendursaga quits (~weechat@user/hendursaga) (Remote host closed the connection) |
| 2021-05-30 22:01:13 | → | Lycurgus joins (~juan@cpe-45-46-140-49.buffalo.res.rr.com) |
| 2021-05-30 22:01:49 | → | hendursaga joins (~weechat@user/hendursaga) |
| 2021-05-30 22:02:01 | × | xff0x quits (~xff0x@2001:1a81:5252:9d00:7ae5:3b91:ab39:a8b6) (Remote host closed the connection) |
| 2021-05-30 22:02:18 | → | xff0x joins (~xff0x@2001:1a81:5252:9d00:f476:7d38:9d5:54c9) |
| 2021-05-30 22:05:47 | × | geekosaur quits (~geekosaur@069-135-003-034.biz.spectrum.com) (Remote host closed the connection) |
| 2021-05-30 22:06:31 | × | dudek quits (~dudek@185.150.236.112) (Quit: Leaving) |
| 2021-05-30 22:07:23 | → | geekosaur joins (~geekosaur@069-135-003-034.biz.spectrum.com) |
| 2021-05-30 22:07:27 | <danso> | how would you design a compiler in haskell with a module system? |
| 2021-05-30 22:07:48 | <danso> | a compiler is maybe the classic example of a program as a pure function |
| 2021-05-30 22:07:59 | <danso> | source code input -> program output, no side effects |
| 2021-05-30 22:08:14 | <danso> | but i just realized mine will need to read the filesystem at some point if i'm going to implement modules :^/ |
| 2021-05-30 22:09:26 | × | space-shell quits (~space-she@88.98.247.38) (Quit: Connection closed) |
| 2021-05-30 22:10:43 | × | gehmehgeh quits (~user@user/gehmehgeh) (Quit: Leaving) |
| 2021-05-30 22:10:48 | <dminuoso> | danso: You could of course preload everything before-hand, but that might not scale well. |
| 2021-05-30 22:11:20 | <danso> | yeah, it seems not ideal to keep all the source code in memory at all times |
| 2021-05-30 22:11:20 | <[exa]> | danso: that's a highly impure view of pure functions |
| 2021-05-30 22:11:24 | × | fizbin quits (~fizbin@c-73-33-197-160.hsd1.nj.comcast.net) (Remote host closed the connection) |
| 2021-05-30 22:11:51 | <danso> | it also would mean the parser would have to do IO, or at least use the IO monad |
| 2021-05-30 22:11:51 | <dminuoso> | danso: Even in GHC there's a lot of IO going on, except the simplifer. The simplifier is really just a pipeline of `Core -> Core` functions :) |
| 2021-05-30 22:12:48 | <lucky> | top level part could be impure, handle each bit loaded purely, proceed to next step depending |
| 2021-05-30 22:12:54 | <[exa]> | danso: like, I see how you meant it, but really pure practical compilers are hard to find |
| 2021-05-30 22:13:09 | <dminuoso> | danso: Also, just because IO is present doesnt mean its pervasive. |
| 2021-05-30 22:13:16 | <lucky> | all of the impurity in my toy compiler is in a few dozen lines in Main.hs |
| 2021-05-30 22:13:27 | <dminuoso> | By necessity all Haskell programas have IO by virtue of main having type `IO a` |
| 2021-05-30 22:13:36 | <dminuoso> | But that doesnt mean you cant have pure parts in your program |
| 2021-05-30 22:13:38 | <lucky> | i load up stuff, throw it off to pure fns, collect it and proceed conditionally based on that in the top level IO |
| 2021-05-30 22:14:09 | <danso> | lucky, does yours support a module system? |
| 2021-05-30 22:14:18 | <lucky> | so I do have a function that goes Text -> Program whech Program is the unchecked AST after parsing |
| 2021-05-30 22:14:21 | <lucky> | which is pretty :) |
| 2021-05-30 22:14:33 | <lucky> | danso: no sir, can't offer specfic advice there, sorry |
| 2021-05-30 22:14:45 | <danso> | it sounds like yours and mine are in about the same place |
| 2021-05-30 22:14:57 | <danso> | a glorious place it is, but this feature threatens everything |
| 2021-05-30 22:15:32 | <lucky> | i'd just parse the module stuff, pass it up to top level as part of the result, and handle the conditional ugly real world there and try to contain it :) |
| 2021-05-30 22:15:50 | Lycurgus | is not sure a module system makes sense in hs world |
| 2021-05-30 22:16:19 | <lucky> | a compiler *in* haskell, i don't know that it's *for* haskell |
| 2021-05-30 22:16:25 | <dminuoso> | danso: So what GHC roughly does is this: Each module gets compiled into an object file and an interface file. The object file can be linked, and the interface file contains all the useful information for dependent modules. |
| 2021-05-30 22:16:30 | <lucky> | mine compiles C (ish) |
| 2021-05-30 22:17:02 | <dminuoso> | danso: So when GHC first generates an object and interface file for module A, and then processes a module B that depends on A, it then loads the interface file of A |
| 2021-05-30 22:18:03 | <dminuoso> | (And the interface file would contain information like what what values are exported, their types, etc) |
| 2021-05-30 22:18:24 | <danso> | dminuoso, that is helpful |
| 2021-05-30 22:18:36 | <danso> | so compile each file totally separately, and leave an object file that can be linked |
| 2021-05-30 22:19:19 | <danso> | and my small `main :: IO a` can load up only the relevant .hi files instead of loading the source code for every imported module and compiling it |
| 2021-05-30 22:19:36 | <dminuoso> | Indeed. This is also how C works, except the preprocessor is used with coding conventions (header files) to implement what GHC uses interface files for |
| 2021-05-30 22:19:41 | <dminuoso> | Right. |
All times are in UTC.