Naming conventions for Shake-duplicated base functions

15 views
Skip to first unread message

Neil Mitchell

unread,
Apr 26, 2016, 1:44:31 PM4/26/16
to shake-bui...@googlegroups.com
Currently Shake has a few functions that are like those in base, but
tracked. It also has some that are in base (or could be), but are
untracked. The naming conventions and types are somewhat random. As a
few examples:

* writeFile' is writeFile lifted into the Action monad.

* writeFileChanged is a variation on writeFile which could be in
MonadIO but is in Action.

* readFile' is a tracked version of readFile in base.

* doesFileExist is a tracked version of doesFileExist in System.Directory.

Clearly the readFile'/doesFileExist is a little inconsistent - the
original logic was that readFile is in the Prelude so it guarantees to
clash, while doesFileExist only clashes if you import
System.Directory. Both writeFile' and writeFileChanged could be in
MonadIO. I think I've tied myself into a mess over what would be the
ideal form to provide. So, questions:

* Should things that are able to be MonadIO be MonadIO?

* Should things that don't clash get 'd? e.g. writeFileChanged'?

* Should things that clash but not in the Prelude be 'd? e.g. doesFileExist?

I'm not really sure what the "best" option is, so welcome any thoughts
people have. The ticket that started this is
https://github.com/ndmitchell/shake/issues/443 - discussing the name
for getEnv like functionality.

(Of course, even if we can come up with the perfect scheme,
implementing it may have issues with reverse compatibility - but
important to know what the right scheme is and thus what the exception
is - at the moment I don't even know the rule!)

Thanks, Neil

Evan Laforge

unread,
Apr 26, 2016, 2:03:05 PM4/26/16
to Neil Mitchell, shake-bui...@googlegroups.com
I don't really like the ' convention because it's like appending a "2"
or a "New". If it means anything, it means "this is more strict than
the plain version." That said, I've come up with an equally terrible
convention, e.g. importsOf_ is in IO, and importsOf is in Action. If
we're going to have IO and Action versions, then I suggest at least a
suffix that implies it, e.g. doThing is in IO and doThingA is the
Action version. doThingTracked would be longer but not necessarily
clearer, since you'd just have to memorize what "tracked" means.

I use qualified imports so I don't have any prelude name collisions
problems. If I could convince the rest of the world to use qualified
imports then we could stop wasting time over these confounding issues
:)

Actually, when I have a DSL-esque module, I sometimes re-export the
most frequently used functions and types from a Global or Types
module, which is intended to be imported unqualified. For instance,
for shake that's ((?==), (?>), (?>>), (%>), need). Not separating has
always been a mistake, because unqualified import is all or nothing.

> * Should things that are able to be MonadIO be MonadIO?

This seems easy though: sure, why not?

Stefan Kersten

unread,
Apr 27, 2016, 7:58:06 AM4/27/16
to Neil Mitchell, shake-bui...@googlegroups.com
Hi,

On 26/04/16 19:44, Neil Mitchell wrote:
> Currently Shake has a few functions that are like those in base, but
> tracked. It also has some that are in base (or could be), but are
> untracked. The naming conventions and types are somewhat random. As a
> few examples:
>
> * writeFile' is writeFile lifted into the Action monad.
>
> * writeFileChanged is a variation on writeFile which could be in
> MonadIO but is in Action.
>
> * readFile' is a tracked version of readFile in base.
>
> * doesFileExist is a tracked version of doesFileExist in System.Directory.

And copyFile' is a tracked version of copyFile in System.Directory :)

> Both writeFile' and writeFileChanged could be in
> MonadIO. I think I've tied myself into a mess over what would be the
> ideal form to provide. So, questions:
>
> * Should things that are able to be MonadIO be MonadIO?

Yes, please! It would make them more versatile and the type is more
descriptive.

> * Should things that don't clash get 'd? e.g. writeFileChanged'?
>
> * Should things that clash but not in the Prelude be 'd? e.g. doesFileExist?

I agree with Evan that the cleanest solution would be to name tracked
functions as their IO counterparts and use qualified imports. A separate
module could be provided with postfixed functions intended for
unqualified import.

IMHO if a postfix is used (' or A), it should be applied to all tracked
functions, not only those that clash with Prelude (or other modules).

Thanks and best,
Stefan
Reply all
Reply to author
Forward
0 new messages