[Haskell-cafe] Are explicit exports and local imports desirable in a production application?
Simon Peyton Jones
simonpj at microsoft.com
Fri Sep 18 07:48:11 UTC 2020
| For explicit exports, I often leave them off for convenience during
| development, but put them in when it settles down. I don't think it
| unlocks any optimization in code generation
Actually, it does make a difference to optimisation. If a function is known not to be exported, then GHC knows every one of its call sites. Eg so
* It may be called only once, and can be inlined (regardless of size)
at that call site.
* If we get a worker/wrapper split, we'll inline the wrapper at all the
call sites. If it's not exported, GHC can discard the wrapper.
* CalledArity analysis can be much more aggressive when it can see all
call sites.
I don't know anyone who has measured the perf or binary-size benefits of limiting export lists. It's probably not huge. But it's not zero.
Simon
| -----Original Message-----
| From: Haskell-Cafe <haskell-cafe-bounces at haskell.org> On Behalf Of Evan
| Laforge
| Sent: 18 September 2020 02:58
| To: Isaac Elliott <isaace71295 at gmail.com>
| Cc: Olaf Klinke <olf at aatal-apotheke.de>; Haskell Cafe <haskell-
| cafe at haskell.org>
| Subject: Re: [Haskell-cafe] Are explicit exports and local imports desirable
| in a production application?
|
| On Thu, Sep 17, 2020 at 3:08 PM Isaac Elliott <isaace71295 at gmail.com> wrote:
| >
| > I don't think that it's unreasonable in general to expect people to
| explore a codebase via IDE tooling. But given Haskell's current situation on
| that front, I currently agree with your approach to Haskell imports/exports.
| >
| > Ignat, I agree with you that explicit imports/exports involve unnecessary
| typing. I call this "busywork". Explicit exports still seem valuable for
| encapsulation, avoiding name clashes, and in the case of GHC they unlock a
| bit more optimisation.
| >
| > In this case I think that we should automate that busywork, and hopefully
| the recent Haskell IDE work gives us a path in that direction.
|
| I mention this every time it comes up, but you can automate it right
| now, and I've been doing it for the last 10 years or so, no IDE
| needed. The tool I wrote is called fix-imports, but there are a
| number of others floating around. So I don't agree that writing
| imports is busywork, you never had to write that stuff in the first
| place, if you really didn't want to.
|
| Another benefit of qualifications for navigation is that they can
| disambiguate tags. Fancier IDE-like tools could do that without the
| qualification, but tags are here now and I think they actually work
| better. Actually on further thought, the same thing that
| disambiguates based on qualification could also easily disambiguate
| without it, so maybe this is not a real benefit after all. I just
| happened to set up the former and not the latter :) My first step
| looking at any third-party code is to tags the whole lot but for
| whatever reason I still much prefer qualifications. Few people use
| them though.
|
| For explicit exports, I often leave them off for convenience during
| development, but put them in when it settles down. I don't think it
| unlocks any optimization in code generation, but it does make rebuilds
| faster because it won't change the hi file if you changed a
| non-exported non-inlined function. You also get unused warnings.
| When I add the export list, I often append '#ifdef TEST , module
| This.Module #endif' so that tests still have total visibility. I
| prefer this to the Internal module approach because I don't like
| zillions of modules with the same name, and I don't want to have to
| structure code to the whims of tests, and I like to get unused symbol
| warnings from ghc without having to go to weeder.
|
| One benefit to explicit exports that surprises me is the trivial
| detection of unused functions. On several occasions I have done extra
| work or even just extra thinking to try to preserve a caller, only to
| find out that due to the changes I just made, it has no other users
| and I could have just deleted it without thinking hard. Yes, a simple
| grep would have revealed that, but I will instantly notice ghc saying
| unused symbol and I might not think to insert manual greps into my
| planning process. Often it's a whole chain of callers that can be
| deleted, and ghc will find those all immediately.
| _______________________________________________
| Haskell-Cafe mailing list
| To (un)subscribe, modify options or view archives go to:
| https://nam06.safelinks.protection.outlook.com/?url=http%3A%2F%2Fmail.haskel
| l.org%2Fcgi-bin%2Fmailman%2Flistinfo%2Fhaskell-
| cafe&data=02%7C01%7Csimonpj%40microsoft.com%7C722f388e97ba432419d308d85b
| 7673dd%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637359911600724047&s
| data=M4h%2F%2FjCg7iLdpoIYrgcThIMAtCRNdlYSdbPW%2BtDXKV0%3D&reserved=0
| Only members subscribed via the mailman list are allowed to post.
More information about the Haskell-Cafe
mailing list