Code style guide?

Hi everyone, Do we have a general notion of what we consider best practices for contributed code to Cabal? Perhaps we should formalise something? One of the reasons I wanted to get the wiki back online was in the hope that it had some pointers, but it doesn't seem to. (I've started migrating stuff anyway: have a look at https://github.com/haskell/cabal/wiki/Migration-from-trac for status). For example, many of the Cabal modules have explicit, and therefore quite long, import lists, with no clear organisation, and hence when adding new imports I have to read the entire list to make sure they are not already there, and then wonder where makes sense to insert them. Usually I just make something up with no pattern to it, and hence perpetuate the problem. I am happy to start things off with a proposal if no-one else wants to do the writing. Regards, Ben Millwood (benmachine)

On Mon, Mar 18, 2013 at 5:15 PM, Ben Millwood
Hi everyone,
Do we have a general notion of what we consider best practices for contributed code to Cabal? Perhaps we should formalise something?
One of the reasons I wanted to get the wiki back online was in the hope that it had some pointers, but it doesn't seem to. (I've started migrating stuff anyway: have a look at https://github.com/haskell/** cabal/wiki/Migration-from-trachttps://github.com/haskell/cabal/wiki/Migration-from-tracfor status).
For example, many of the Cabal modules have explicit, and therefore quite long, import lists, with no clear organisation, and hence when adding new imports I have to read the entire list to make sure they are not already there, and then wonder where makes sense to insert them. Usually I just make something up with no pattern to it, and hence perpetuate the problem.
My experience is that without an automated tool or editor command to organize the headers humans are unlikely to do it. A quick google search didn't turn up any vim or emacs commands for this relating to haskell. Jason

On Mon, Mar 18, 2013 at 06:08:35PM -0700, Jason Dagit wrote:
On Mon, Mar 18, 2013 at 5:15 PM, Ben Millwood
wrote: Hi everyone,
Do we have a general notion of what we consider best practices for contributed code to Cabal? Perhaps we should formalise something?
One of the reasons I wanted to get the wiki back online was in the hope that it had some pointers, but it doesn't seem to. (I've started migrating stuff anyway: have a look at https://github.com/haskell/** cabal/wiki/Migration-from-trachttps://github.com/haskell/cabal/wiki/Migration-from-tracfor status).
For example, many of the Cabal modules have explicit, and therefore quite long, import lists, with no clear organisation, and hence when adding new imports I have to read the entire list to make sure they are not already there, and then wonder where makes sense to insert them. Usually I just make something up with no pattern to it, and hence perpetuate the problem.
My experience is that without an automated tool or editor command to organize the headers humans are unlikely to do it. A quick google search didn't turn up any vim or emacs commands for this relating to haskell.
We have http://hackage.haskell.org/package/stylish%2Dhaskell which is integrated into Chris Done's extensions to the emacs haskell-mode: https://github.com/haskell/haskell-mode. -Brent

+1 for stylish-haskell --- I have it enabled in my save-hook for most of my
patches. It would be good to check in a stylish haskell YAML dotfile into
the repo with some sane/uncontroversial settings (I like the horizontal
alignment but a lot of people don't), then make a one-time pass over the
repo. It will cause merge conflicts on any pending merge request however.
On Tue, Mar 19, 2013 at 3:23 PM, Brent Yorgey
On Mon, Mar 18, 2013 at 5:15 PM, Ben Millwood
Hi everyone,
Do we have a general notion of what we consider best practices for contributed code to Cabal? Perhaps we should formalise something?
One of the reasons I wanted to get the wiki back online was in the hope that it had some pointers, but it doesn't seem to. (I've started migrating stuff anyway: have a look at https://github.com/haskell/** cabal/wiki/Migration-from-trac< https://github.com/haskell/cabal/wiki/Migration-from-trac>for status).
For example, many of the Cabal modules have explicit, and therefore quite long, import lists, with no clear organisation, and hence when adding new imports I have to read the entire list to make sure they are not already there, and then wonder where makes sense to insert them. Usually I just make something up with no pattern to it, and hence perpetuate the
On Mon, Mar 18, 2013 at 06:08:35PM -0700, Jason Dagit wrote: problem.
My experience is that without an automated tool or editor command to organize the headers humans are unlikely to do it. A quick google search didn't turn up any vim or emacs commands for this relating to haskell.
We have
http://hackage.haskell.org/package/stylish%2Dhaskell
which is integrated into Chris Done's extensions to the emacs haskell-mode: https://github.com/haskell/haskell-mode.
-Brent
_______________________________________________ cabal-devel mailing list cabal-devel@haskell.org http://www.haskell.org/mailman/listinfo/cabal-devel
--
Gregory Collins

On Tue, 2013-03-19 at 00:15 +0000, Ben Millwood wrote:
Hi everyone,
Do we have a general notion of what we consider best practices for contributed code to Cabal? Perhaps we should formalise something?
One of the reasons I wanted to get the wiki back online was in the hope that it had some pointers, but it doesn't seem to. (I've started migrating stuff anyway: have a look at https://github.com/haskell/cabal/wiki/Migration-from-trac for status).
For example, many of the Cabal modules have explicit, and therefore quite long, import lists, with no clear organisation, and hence when adding new imports I have to read the entire list to make sure they are not already there, and then wonder where makes sense to insert them. Usually I just make something up with no pattern to it, and hence perpetuate the problem.
I am happy to start things off with a proposal if no-one else wants to do the writing.
Go for it! You'll also notice that the code uses different styles in different places (because of different authors). We've not gone through and tidied stuff up because we're lazy and because there never seems to be a good time to do it (it causes conflicts with patches people are working on). Duncan

On Tue, Mar 19, 2013 at 6:35 AM, Duncan Coutts wrote: Go for it! You'll also notice that the code uses different styles in different
places (because of different authors). We've not gone through and tidied
stuff up because we're lazy and because there never seems to be a good
time to do it (it causes conflicts with patches people are working on). If you need to write a style guide, why not use
https://github.com/tibbe/haskell-style-guide/blob/master/haskell-style.md
as a starting point. It's widely used in the Haskell community nowadays
(e.g. it's a common recommendation on IRC) and it's based on the coding
style of Duncan, Bryan, and Don for the most part.
-- Johan

On Tue, Mar 19, 2013 at 7:29 AM, Johan Tibell
On Tue, Mar 19, 2013 at 6:35 AM, Duncan Coutts < duncan.coutts@googlemail.com> wrote:
Go for it!
You'll also notice that the code uses different styles in different places (because of different authors). We've not gone through and tidied stuff up because we're lazy and because there never seems to be a good time to do it (it causes conflicts with patches people are working on).
If you need to write a style guide, why not use
https://github.com/tibbe/haskell-style-guide/blob/master/haskell-style.md
as a starting point. It's widely used in the Haskell community nowadays (e.g. it's a common recommendation on IRC) and it's based on the coding style of Duncan, Bryan, and Don for the most part.
There are a few recommendations in that guide that I'm not a fan of. Below are the main ones. This looks wrong to me: https://github.com/tibbe/haskell-style-guide/blob/master/haskell-style.md#ex... Partly because my default indent distance is 2 spaces, but also because I prefer the export list to be left aligned: module Data.Set ( -- * The @Set@ type Set , empty , singleton -- * Querying , member ) where I suspect that style is more common in the community overall. I'm not convinced that data types should have strict constructors by default. I agree it's the right thing in many cases, but I don't know how I feel about "strict by default" as a recommendation for beginners. It sounds like we're encouraging a cargo cult to me. I think it's better to educate people. Jason

Hi Jason,
On Tue, Mar 19, 2013 at 10:49 AM, Jason Dagit
There are a few recommendations in that guide that I'm not a fan of. Below are the main ones.
I'm confident that for each Haskell programmer out there there are a few recommendations that Haskell programmer is not a fan of. There are some things in there that I'm not a fan of, depending on the day of the week you ask me. Here's the thing about coding styles: having a consistent style is far more important for code comprehension than whether option A is en epsilon better than option B. There are several reasonable ways to format things. People will have preferences. Those preferences don't matter. Consistency does.
I'm not convinced that data types should have strict constructors by default. I agree it's the right thing in many cases, but I don't know how I feel about "strict by default" as a recommendation for beginners. It sounds like we're encouraging a cargo cult to me. I think it's better to educate people.
This is the conclusion I've reached from being the author of and contributing to many of our core libraries and from being one of the go-to person for performance related problems in Haskell. It's also the guideline used at least 1-2 Haskell companies I know of (i.e. among people that use Haskell in anger). The lazy default is too error prone, even for experienced Haskellers. Lazy fields force you to be careful. Having to be careful when programming is not good. It hurts your productivity. -- Johan

On Tue, Mar 19, 2013 at 07:29:27AM -0700, Johan Tibell wrote:
If you need to write a style guide, why not use
https://github.com/tibbe/haskell-style-guide/blob/master/haskell-style.md
as a starting point. It's widely used in the Haskell community nowadays (e.g. it's a common recommendation on IRC) and it's based on the coding style of Duncan, Bryan, and Don for the most part.
Sounds like a good place to start. My pet disagreement with it is everywhere that it allows the indentation of some code to depend on the *name* of the thing being defined. I always indent my code so that I can change names without reindenting anything. I like the import rules, though. Should probably clarify "standard library": do we mean boot packages, or the HP? In any case, it would be nice to get from the major contributors to Cabal a "yes" (even if it is a "yes but") or a "no" on the above style guide. My inclination with regards to newly enforcing it would be to fix code that you're visiting anyway – e.g. every time you add an import, re-organise the entire list. That way you minimise conflicts and everything gets done sooner or later. regards, Ben

On Tue, Mar 19, 2013 at 07:29:27AM -0700, Johan Tibell wrote:
If you need to write a style guide, why not use
https://github.com/tibbe/haskell-style-guide/blob/master/haskell-style.md
as a starting point. It's widely used in the Haskell community nowadays (e.g. it's a common recommendation on IRC) and it's based on the coding style of Duncan, Bryan, and Don for the most part.
Okay, I've started actually applying this to a patch I'm working on, and I've come across the first situation it doesn't mandate a policy for: how to format import lists. There are at least two styles in Cabal code at the moment, e.g. the top of Distribution.Compate.TempFile looks like import System.FilePath ((>)) import Foreign.C (eEXIST) import System.IO (Handle, openTempFile, openBinaryTempFile) import Data.Bits ((.|.)) import System.Posix.Internals (c_open, c_close, o_CREAT, o_EXCL, o_RDWR, o_BINARY, o_NONBLOCK, o_NOCTTY) [...] whereas Distribution.Compat.CopyFile looks like import Control.Monad ( when ) import Control.Exception ( bracket, bracketOnError ) import Distribution.Compat.Exception ( catchIO ) import Distribution.Compat.Exception ( throwIOIO ) import System.IO.Error ( ioeSetLocation ) [...] I'm in favour of the first style, and if there's no objections, the patch I'm currently writing will be split into two commits, the first of which will beautify all the import lists I'm going to touch, and the second of which will apply my changes. -- Ben

On Thu, Mar 21, 2013 at 12:48 PM, Ben Millwood
I'm in favour of the first style, and if there's no objections, the patch I'm currently writing will be split into two commits, the first of which will beautify all the import lists I'm going to touch, and the second of which will apply my changes.
I am as well as it takes up much less space.

On Thu, Mar 21, 2013 at 01:21:11PM -0700, Johan Tibell wrote:
On Thu, Mar 21, 2013 at 12:48 PM, Ben Millwood
wrote: I'm in favour of the first style, and if there's no objections, the patch I'm currently writing will be split into two commits, the first of which will beautify all the import lists I'm going to touch, and the second of which will apply my changes.
I am as well as it takes up much less space.
I find it's also easier to read. It's very hard to scan and see which modules are imported in the style where import lists are interleaved with module names. -Brent

On Tue, 2013-03-19 at 07:29 -0700, Johan Tibell wrote:
On Tue, Mar 19, 2013 at 6:35 AM, Duncan Coutts
wrote:
Go for it!
You'll also notice that the code uses different styles in different places (because of different authors). We've not gone through and tidied stuff up because we're lazy and because there never seems to be a good time to do it (it causes conflicts with patches people are working on).
If you need to write a style guide, why not use
https://github.com/tibbe/haskell-style-guide/blob/master/haskell-style.md
as a starting point. It's widely used in the Haskell community nowadays (e.g. it's a common recommendation on IRC) and it's based on the coding style of Duncan, Bryan, and Don for the most part.
BTW, the main thing in that guide that I disagree with is the 4-space indentation. I always use 2, but at the top level there's a slight special case: foo :: a -> b foo x = bar x where bar y = ... We have to indent the body of the function here by 4 because the where has to be indented by 2, and the body has to be more than that, this is partly for clarity but also partly because of this problem: foo x = case x of This -> That -> where bar y = ... IIRC, historically in H98 this attached the where to the top level function foo, but these days with the modified layout rule, the where gets attached to the last branch of the case. Duncan
participants (6)
-
Ben Millwood
-
Brent Yorgey
-
Duncan Coutts
-
Gregory Collins
-
Jason Dagit
-
Johan Tibell