
Hi all, I've been sitting on this for four months for various reasons, but Neil and Duncan keep prodding me to send it, so here it is. The numbers in the mail are probably out of date by now, due to the start of the base splitup and general development, but I'm too lazy to update them. Thanks Ian ------------------ Hi all, My last attempt to write a contentious mail was a miserable failure, so I'm giving it another go. I've written up my description and rationale for what makes good Haskell style. The full thing is at http://urchin.earth.li/~ian/style/haskell.html but I'll copy the conclusion here: * Don't leave trailing white space in your code * Don't use tabs * Aim to keep lines under 80 characters * Use the CamelCase variable naming convention * Don't use explicit braces and semicolons There are also some tips on configuring vim to help out at http://urchin.earth.li/~ian/style/vim.html I think it would be great if we could agree on this (or perhaps some other) set of style guidelines for the core libraries, and encourage their use for other libraries. Future library submissions would be required to follow the guide, and the existing codebase could either be updated as other changes are made, or en masse just before the GHC 6.8 fork (to avoid unnecessary patch merging work). Just to help motivate the "Don't use tabs" point: I think someone was saying that they thought that base should use tabs, as that is what the existing code base uses. Here are some stats which show that that doesn't seem to be the case; it's hard to draw strong conclusions without actually manually looking at a large proportion of the library, but the indication is that 4 spaces is the dominant indentation. I've attached the script that made the stats. Total files: 162 Files where some lines start tab: 121 Files where some lines start 4 spaces: 133 Files where some lines start 8 spaces: 100 Percentage files where some lines start tab: 74% Percentage files where some lines start 4 spaces: 82% Percentage files where some lines start 8 spaces: 61% Non-blank lines: 47493 Lines that start white (white lines): 20584 Lines that start tab: 4239 Lines that start 4 spaces: 10691 Lines that start 8 spaces: 4509 Percentage non-blank lines start tab: 8% Percentage non-blank lines start 4 spaces: 22% Percentage non-blank lines start 8 spaces: 9% Percentage white lines start tab: 20% Percentage white lines start 4 spaces: 51% Percentage white lines start 8 spaces: 21% And a few more stats, just for interest really: Lines that have a tab after a space: 203 Lines that have a tab after a non-white character: 2401 Percentage non-blank lines have a tab after a space: 0% Percentage non-blank lines have a tab after a non-white character: 5% Thanks Ian, Neil and Duncan

Ian Lynagh wrote:
* Don't leave trailing white space in your code * Don't use tabs * Aim to keep lines under 80 characters * Use the CamelCase variable naming convention * Don't use explicit braces and semicolons
I'm with you all except for the 4th one:
* Use the CamelCase variable naming convention
I'm rather attached to the convention I use, which is - CamelCase for exported identifiers - underscores otherwise (I'm pretty sure I don't use it consistently, so don't bother to dig up counter-examples though). Why do I like this? Ideally we'd have an IDE which would colour my exported identifiers differently, but since I don't use such an IDE the CamelCase distinction gets some of the benefit. CamelCase for exported identifiers is already an established convention (which should really be part of a library API style guide), which leaves us with underscores for local identifiers. Yes I'm aware that a single-word identifier is the same in both conventions; it's not perfect. Cheers, Simon

On Wed, 1 Aug 2007, Simon Marlow wrote:
I'm rather attached to the convention I use, which is
- CamelCase for exported identifiers - underscores otherwise <snip> Yes I'm aware that a single-word identifier is the same in both conventions; it's not perfect.
How about _nonexportedIdentifier or something similar? -- flippa@flippac.org A problem that's all in your head is still a problem. Brain damage is but one form of mind damage.

Philippa Cowderoy wrote:
On Wed, 1 Aug 2007, Simon Marlow wrote:
I'm rather attached to the convention I use, which is
- CamelCase for exported identifiers - underscores otherwise <snip> Yes I'm aware that a single-word identifier is the same in both conventions; it's not perfect.
How about _nonexportedIdentifier or something similar?
Leading underscores are used in pattern matches to indicate to GHC that unused names like '_foo' should not cause a warning to be printed. Otherwise the warning is turned off by using just '_' but that erases the readability of using an actual name. Thus: take _ [] = [] -- no warning take n [] = [] -- warning that n is unused take _n [] = [] -- no warning

I've been using Haskell daily for a long time, and I didn't know about that underscore convention. I knew about _ being an unspecified dummy variable, but I didn't know you are allowed to follow it with a meaningful name. Guess I have some reading to do. :) -----Original Message----- From: libraries-bounces@haskell.org [mailto:libraries-bounces@haskell.org] On Behalf Of Chris Kuklewicz Sent: Wednesday, August 01, 2007 11:31 AM To: Philippa Cowderoy Cc: libraries@haskell.org; Simon Marlow Subject: Re: Good Haskell Style Philippa Cowderoy wrote:
On Wed, 1 Aug 2007, Simon Marlow wrote:
I'm rather attached to the convention I use, which is
- CamelCase for exported identifiers - underscores otherwise <snip> Yes I'm aware that a single-word identifier is the same in both conventions; it's not perfect.
How about _nonexportedIdentifier or something similar?
Leading underscores are used in pattern matches to indicate to GHC that unused names like '_foo' should not cause a warning to be printed. Otherwise the warning is turned off by using just '_' but that erases the readability of using an actual name. Thus: take _ [] = [] -- no warning take n [] = [] -- warning that n is unused take _n [] = [] -- no warning _______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries

-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On 1 aug 2007, at 16.50, Simon Marlow wrote:
* Use the CamelCase variable naming convention
I'm rather attached to the convention I use, which is
- CamelCase for exported identifiers - underscores otherwise
(I'm pretty sure I don't use it consistently, so don't bother to dig up counter-examples though).
Why do I like this? Ideally we'd have an IDE which would colour my exported identifiers differently, but since I don't use such an IDE the CamelCase distinction gets some of the benefit. CamelCase for exported identifiers is already an established convention (which should really be part of a library API style guide), which leaves us with underscores for local identifiers.
Yes I'm aware that a single-word identifier is the same in both conventions; it's not perfect.
I don't like that convention. It makes the code look really ugly. I agree, that it'd be a good idea to have a visual indication what is exported and what is not, but i'd strongly opt for something less obtrusive. In any case, though, this is something this should be done consistently or not at all; maybe we need some sort of haskell- lint? So, if leading underscores are used already, what about trailing underscores? myPublicFunction :: Foo -> Bar -> Baz myPublicFunction f b = myInternalHelperFn_ (helper_ f b) versus yPublicFunction :: Foo -> Bar -> Baz myPublicFunction f b = my_internal_helper_fn (helper f b) it's also much easier to fix when actually exporting the identifier. Just my 2 cents / Thomas -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.5 (Darwin) iQEVAwUBRrC0nSuNq1ISBIDTAQKHdgf/WmuXYK/Se0PSfUZ4b6g6ZyouHpzCEz47 zEyrCxxEu8zInAsY0JAF8Iyfx0C1XTDNKLvq08pZhHmBGLF3nN2e8f1fRjm24wbx UCxHK1vh8+aV5UnhS+DNoWi8kS6M5z2rezPohs3VI2H10SJKdsYYTJ3UdI+WPmlq W3Pjcd6wfAoAF+l5e/AOu1TsQi5bi5yPeMzBncxNLA+UAuyQ+ud0jf4AgtfJ6Xz4 BKjq+YYpzpY+O3/VIFz6JSsV99QRcsP69qLPDTwyhXtfTCEUawSG8XEu4K9gSMvj scWAopz9ymd8QdDt4OcvZ/qb3cr9/z1vWF38KLMv95u459fM12dvMA== =XpJV -----END PGP SIGNATURE-----

On Wed, 1 Aug 2007, Thomas Schilling wrote:
So, if leading underscores are used already, what about trailing underscores?
I often use them where someone else would use ' as prime because my text editor's syntax highlighting is less than perfect. Also, there's an existing convention in the monad libraries using trailing underscores. -- flippa@flippac.org "The reason for this is simple yet profound. Equations of the form x = x are completely useless. All interesting equations are of the form x = y." -- John C. Baez

On Wed, Aug 01, 2007 at 03:50:26PM +0100, Simon Marlow wrote:
Ian Lynagh wrote:
* Don't leave trailing white space in your code * Don't use tabs * Aim to keep lines under 80 characters * Use the CamelCase variable naming convention * Don't use explicit braces and semicolons
I'm with you all except for the 4th one:
Likewise.
* Use the CamelCase variable naming convention
I'm rather attached to the convention I use, which is
- CamelCase for exported identifiers - underscores otherwise
(I'm pretty sure I don't use it consistently, so don't bother to dig up counter-examples though).
I'm with you on this. I prefer underscores in general, and find it helpful to use them in ways distinct from CamelCase. For instance, the new "Repository" API in darcs is all CamelCase, but less portable functions (sometimes exported, but always deprecated for use in darcs commands--except in exceptions such as get) use underscores. I'd say that we ought only to have the convention that exported functions are CamelCase, and let folks do whatever they want inside a module. -- David Roundy Department of Physics Oregon State University

On Wed, Aug 01, 2007 at 03:50:26PM +0100, Simon Marlow wrote:
Ian Lynagh wrote:
* Don't leave trailing white space in your code * Don't use tabs * Aim to keep lines under 80 characters * Use the CamelCase variable naming convention * Don't use explicit braces and semicolons
I'm with you all except for the 4th one:
* Use the CamelCase variable naming convention
I'm rather attached to the convention I use, which is
- CamelCase for exported identifiers - underscores otherwise
(I'm pretty sure I don't use it consistently, so don't bother to dig up counter-examples though).
I almost do this, I use underscores for CAFs and very simple names (often one word) for non-exported functions, but I try to keep them local, in where or let clauses rather than at the top level. non-exported top-level functions just are not all that common. In any case, I was never a fan of style guidelines. well, not entirely true, I am very much in favor of people publishing their guidelines to give others inspiration and to learn from like Ian did. I was never in favor of trying to get people to come to a consensus on one, many man-hours that could have been spent writing delicious code has been whittled away in pursuit of conformity for conformities sake. Though, there certainly are technical (rather than aesthetic) reasons for a lot of these things that some might consider style, such as the whitespace ones above and indentation patterns that allow easy editing. John -- John Meacham - ⑆repetae.net⑆john⑈

On Wed, 2007-08-01 at 15:19 +0100, Ian Lynagh wrote:
Hi all,
I've been sitting on this for four months for various reasons, but Neil and Duncan keep prodding me to send it, so here it is.
And if we can get vague consensus we should put this guide on the haskell.org wiki. Duncan

Ian Lynagh wrote:
* Don't leave trailing white space in your code * Don't use tabs * Aim to keep lines under 80 characters * Use the CamelCase variable naming convention * Don't use explicit braces and semicolons
May I add: * put a final newline in your file http://haskell.org/haskellwiki/Programming_guidelines#File_Format Cheers Christian

* Don't leave trailing white space in your code * Don't use tabs * Aim to keep lines under 80 characters * Use the CamelCase variable naming convention * Don't use explicit braces and semicolons
These rules seem reasonable to me, but I would finesse the second point. Whilst tabs are undesirable in code, I do often find it useful to precede _eol_ comments with tabs. "function | guard = body\t\t-- eol comment" Tabs help to align the beginning of such comments nicely; they help to avoid random misalignments due to minor editing of code; and in this location they can never change the meaning of the code. Regards, Malcolm

Hi,
* Don't leave trailing white space in your code * Don't use tabs * Aim to keep lines under 80 characters * Use the CamelCase variable naming convention * Don't use explicit braces and semicolons
I like using underscores in values, and CamelCase in types---I find that the extra space makes the identifiers more readable. Despite the fact that I tend to write code that follows these conventions (except for bullet 4), I find the rules to be extremely arbitrary and I do not think that they should be given any special status. -Iavor PS: While we are discussing style, what should be the blessed amount of indentation ;-) I vote for 2 spaces.

On Wed, Aug 01, 2007 at 01:06:07PM -0700, Iavor Diatchki wrote:
Hi,
* Don't leave trailing white space in your code * Don't use tabs * Aim to keep lines under 80 characters * Use the CamelCase variable naming convention * Don't use explicit braces and semicolons
I like using underscores in values, and CamelCase in types---I find that the extra space makes the identifiers more readable. Despite the fact that I tend to write code that follows these conventions (except for bullet 4), I find the rules to be extremely arbitrary and I do not think that they should be given any special status.
The use of tabs can easily make code unreadable on other developers' editors. It's a bad idea, not an arbitrary convention. Keeping the line width down is useful for making code readable on folks with smaller monitors or larger fonts. And note that it says "Aim", which means that if it impairs readability in the judgement of the developer, it's not a violation. Trailing white space doesn't particularly hurt, except if you're using version control, in which case any removal of white space is liable to conflict with actual coding changes, so it's better to have a policy that it shouldn't be included. I've certainly never heard of a scenario in which trailing white space is beneficial. The last one "Don't use explicit braces and semicolons" does seem a bit arbitrary and heavy-handed. I'd rather not use them myself, but wouldn't complain of a developer who does so.
PS: While we are discussing style, what should be the blessed amount of indentation ;-) I vote for 2 spaces.
That's certainly something that shouldn't be in a coding guide. -- David Roundy Department of Physics Oregon State University

David Roundy
Trailing white space doesn't particularly hurt, except if you're using version control, in which case any removal of white space is liable to conflict with actual coding changes, so it's better to have a policy that it shouldn't be included.
This is surely an issue with either the language definition or the version control system. In general, we ought to aim for a state of affairs where every requirement we make is mechannically checked. In this particular case, I'd say that the version control system ought to be more syntactically aware when looking for differences¹, for example by removing all trailing space before doing comparisons (and making sure that anything extracted from the repo has none).
I've certainly never heard of a scenario in which trailing white space is beneficial.
Neither have I, but since it's invisible, asking that it not be there without providing automatic mechanical assistance is to add a tedious burden. [1] this isn't the only place where a version control system that understood more of the language would be useful: for example, rather than having to specify a regexp, I'd like darcs replace to pick one (from a configuration file?) depending on language. -- Jón Fairbairn Jon.Fairbairn@cl.cam.ac.uk

On Thu, Aug 02, 2007 at 11:48:37AM +0100, Jon Fairbairn wrote:
[1] this isn't the only place where a version control system that understood more of the language would be useful: for example, rather than having to specify a regexp, I'd like darcs replace to pick one (from a configuration file?) depending on language.
This latter bit is pretty easily added, but I doubt many people have repositories in which they use darcs replace often on multiple languages, so it seems like it ought to be pretty low-priority. -- David Roundy Department of Physics Oregon State University

David Roundy
On Thu, Aug 02, 2007 at 11:48:37AM +0100, Jon Fairbairn wrote:
[1] this isn't the only place where a version control system that understood more of the language would be useful: for example, rather than having to specify a regexp, I'd like darcs replace to pick one (from a configuration file?) depending on language.
This latter bit is pretty easily added, but I doubt many people have repositories in which they use darcs replace often on multiple languages, so it seems like it ought to be pretty low-priority.
I wasn't particularly thinking of multiple languages. The default is wrong for Haskell, for example, so I have to put something in _darcs/prefs/defaults. Surely it would be better to do that once and for all? -- Jón Fairbairn Jon.Fairbairn@cl.cam.ac.uk

Jon Fairbairn wrote:
David Roundy
writes: On Thu, Aug 02, 2007 at 11:48:37AM +0100, Jon Fairbairn wrote:
[1] this isn't the only place where a version control system that understood more of the language would be useful: for example, rather than having to specify a regexp, I'd like darcs replace to pick one (from a configuration file?) depending on language. This latter bit is pretty easily added, but I doubt many people have repositories in which they use darcs replace often on multiple languages, so it seems like it ought to be pretty low-priority.
I wasn't particularly thinking of multiple languages. The default is wrong for Haskell, for example, so I have to put something in _darcs/prefs/defaults.
And it's not there when darcs-getting a repository of Haskell code, which is rather irritating since contributed patches SHOULD use the appropriate convention (for patch commutation as well as correctness of replacement). Although, I'm not sure how this can be fixed in the darcs model of looking at things? Isaac

Jon Fairbairn wrote:
David Roundy
writes: Trailing white space doesn't particularly hurt, except if you're using version control, in which case any removal of white space is liable to conflict with actual coding changes, so it's better to have a policy that it shouldn't be included.
This is surely an issue with either the language definition or the version control system. In general, we ought to aim for a state of affairs where every requirement we make is mechannically checked. In this particular case, I'd say that the version control system ought to be more syntactically aware when looking for differences¹, for example by removing all trailing space before doing comparisons (and making sure that anything extracted from the repo has none).
I've certainly never heard of a scenario in which trailing white space is beneficial.
Neither have I, but since it's invisible, asking that it not be there without providing automatic mechanical assistance is to add a tedious burden.
sed -e 's/[ \t]+$//' Cheers Ben

Benjamin Franksen
Jon Fairbairn wrote:
David Roundy
writes: I've certainly never heard of a scenario in which trailing white space is beneficial.
Neither have I, but since it's invisible, asking that it not be there without providing automatic mechanical assistance is to add a tedious burden.
sed -e 's/[ \t]+$//'
Not the whole story, surely; you must want me to do something like create sort-it: #!/bin/bash find /home/jf -name \*.hs -o -name \*.lhs | xargs -IX sed -i.bak -e 's/[ \t]+$//' X and put it in a my crontab to run once a day? Otherwise it's not automatic. Only, strangely enough, what you wrote doesn't work (s/-e/-r/). -- Jón Fairbairn Jon.Fairbairn@cl.cam.ac.uk

Jon Fairbairn wrote:
Benjamin Franksen
writes: Jon Fairbairn wrote:
David Roundy
writes: I've certainly never heard of a scenario in which trailing white space is beneficial.
Neither have I, but since it's invisible, asking that it not be there without providing automatic mechanical assistance is to add a tedious burden.
sed -e 's/[ \t]+$//'
Not the whole story, surely;
No, of course not.
you must want me to do
I don't want you to do anything at all. I merely wanted to illustrate that getting rid of trailing whitespace is easily automated. Well, let's say half-automated: you still need to push the button.
something like create sort-it:
#!/bin/bash find /home/jf -name \*.hs -o -name \*.lhs | xargs -IX sed -i.bak -e 's/[ \t]+$//' X
and put it in a my crontab to run once a day? Otherwise it's not automatic.
No crontab entry needed here (wouldn't help, by the way, since you probably want to record on the same day you wrote something). Also not necessary to recurse over whole home directory. It needs to be done only right before darcs-record-ing changes and only for the standard libraries. As has been noted by someone else, darcs even helps you by highlighting trailing whitespace in hunks, in case you forgot to run your script over the source files. I agree that a darcs prehook (if they existed) would be an even nicer solution.
Only, strangely enough, what you wrote doesn't work (s/-e/-r/).
Sorry, I didn't test the code. Forgot to add the usual disclaimer... ;-) (Always bugs me that sed and grep have these half-regexes as default.) Cheers Ben

Benjamin Franksen
I don't want you to do anything at all. I merely wanted to illustrate that getting rid of trailing whitespace is easily automated. Well, let's say half-automated: you still need to push the button.
[...]
No crontab entry needed here
The code was ironic ;-)
I agree that a darcs prehook (if they existed) would be an even nicer solution.
Quite. My point that computers are /for/ making things automatic. If they can remember to press the button, why should I have to? Or, less petulantly, being human I will inevitably forget sometimes (resulting in problems), where the machine wouldn't. -- Jón Fairbairn Jon.Fairbairn@cl.cam.ac.uk

On Wed, 2007-08-01 at 13:06 -0700, Iavor Diatchki wrote:
Despite the fact that I tend to write code that follows these conventions (except for bullet 4), I find the rules to be extremely arbitrary and I do not think that they should be given any special status.
But isn't that just the nature of a standard? A good common style helps people communicate and share their code. Of course we cannot force a style upon anyone, however many authors *want* to use a style that many other people use because it will make their code more accessible. So for their benefit we can try to elevate some common set of rules and say if you want to follow a style, follow this one. Then as a bonus the style that we pick can be somewhat less than totally arbitrary and have some practical justification like Ian's arguments about tabs and layout etc. So the value of this discussion is in trying to find a style that is sufficiently common or well justified that we can promote it as a recommended style to exiting and new coders.
PS: While we are discussing style, what should be the blessed amount of indentation ;-) I vote for 2 spaces.
So do I, but this is probably an even more contentious issue :-). Duncan

On 1 aug 2007, at 22.06, Iavor Diatchki wrote:
Hi,
* Don't leave trailing white space in your code * Don't use tabs * Aim to keep lines under 80 characters * Use the CamelCase variable naming convention * Don't use explicit braces and semicolons
I like using underscores in values, and CamelCase in types---I find that the extra space makes the identifiers more readable. Despite the fact that I tend to write code that follows these conventions (except for bullet 4), I find the rules to be extremely arbitrary and I do not think that they should be given any special status.
Style rules will *always* be arbitrary. The sole point is to have *consistency*. You can always argue against decisions, there will hardly be any waterproof arguments (or rather Coq-proofed or sth.), but consistency is important and is absolutely appropriate for the libraries. This is not to say that this should be a the style for all Haskell programs written anywhere, but it would be good to have a normative style for the central libraries. Others then might adopt parts of this guide for their projects, or not. I am also pro enforced white space between binary operators (ie, "foo ++ bar" and "42 + 6 ^ (-5)" rather than "foo++bar" and "42+6^(-5)") and defined module orderings (ie, local first, external later, or the other way round.) In any case, stylistic standards are there to make the boring things easy to recognize (and hence ignore) and let you focus on the real meat. / Thomas

Oh, and while we're at arbitrary style rules, I have one more (with a reason though, to do so). I find this way of indenting "where" really annoying: fun :: Yawn -> Moo a -> Meep a fun y x = do unMoo x blah return it where blah = foo 42 it = blax &&& meee . y it should rather be fun :: Yawn -> Moo a -> Meep a fun y x = do unMoo x blah return it where blah = foo 42 it = blax &&& meee . y Even if the "where" is syntax-highlighted, it is still very hard to parse visually. In a completely unrelated issue, I think this is a very useful way to indent code: foo x y z = case x of Blab a b c -> ... Blib d e f g -> ... _ -> ... It helps avoiding parentheses and reduces line length (especially for longer function names). Compare this with: foo (Blab a b c) y z = ... foo (Blib d e f g) y z = ... foo x y z = ... / Thomas

Ian Lynagh wrote:
* Don't leave trailing white space in your code * Don't use tabs * Aim to keep lines under 80 characters * Use the CamelCase variable naming convention
Agreed. And newline at end of file. And prefer to indent an even number (normally an even number of spaces, but, an odd number when using birdtrack-literate-haskell '> foo = ...'). I am often quite arbitrary about anything more strictured than this, and prefer to lay it out depending on what seems most clear in the surrounding code (which, admittedly, usually assumes a monospace font).
* Don't use explicit braces and semicolons
Sometimes I use explicit semicolons, and even sometimes braces to make the bracketing more clear, when there are a lot of small cases, for example. But usually layout is better. A separate rule which I do try to stick to is, * don't depend on the width of non-space characters for layout : " \(let\|where\|do\|of\)[ ] such that the layout following them extends onto another line "; however this is a nuisance to check manually, (is more complicated when tabs are allowed), and GHC doesn't have a warning flag for it. Isaac

From: libraries-bounces@haskell.org [mailto:libraries-bounces@haskell.org] On Behalf Of Isaac Dupree
And prefer to indent an even number (normally an even number of spaces, but, an odd number when using birdtrack-literate-haskell '> foo = ...').
I moot that birdtrack-literate-haskell should be avoided, largely because (AFAICT) it is not supported by Haddock. Section 2.1 in the Haddock manual suggests that you can preprocess the .lhs source to make it palatable: http://www.haskell.org/haddock/haddock-html-0.8/invoking.html#cpp by saying (for example): ghc -E Main.lhs -o Main.hs However, this appears to discard all lines which do not start with >, which includes many comments (like the module header), which is not much use to Haddock. Currently, for many of Takusen's source files I run them through a custom preprocessor which converts them to regular .hs files, preserving all comments, and then feed these to Haddock. That's not to say that the birdtrack style is not useful; it's great for Oleg's expositional email-as-literate-source postings. However, having used it extensively in Takusen, I'm of the opinion that we should have started with regular .hs source. Alistair ***************************************************************** Confidentiality Note: The information contained in this message, and any attachments, may contain confidential and/or privileged material. It is intended solely for the person(s) or entity to which it is addressed. Any review, retransmission, dissemination, or taking of any action in reliance upon this information by persons or entities other than the intended recipient(s) is prohibited. If you received this in error, please contact the sender and delete the material from any computer. *****************************************************************

On Thu, 2007-08-02 at 08:51 +0100, Bayley, Alistair wrote:
From: libraries-bounces@haskell.org [mailto:libraries-bounces@haskell.org] On Behalf Of Isaac Dupree
And prefer to indent an even number (normally an even number of spaces, but, an odd number when using birdtrack-literate-haskell '> foo = ...').
I moot that birdtrack-literate-haskell should be avoided, largely because (AFAICT) it is not supported by Haddock.
Doesn't Cabal handle this transparently? I thought it did. If you find it doesn't please file a bug against Cabal. Duncan

I moot that birdtrack-literate-haskell should be avoided, largely because (AFAICT) it is not supported by Haddock.
Doesn't Cabal handle this transparently? I thought it did. If you find it doesn't please file a bug against Cabal.
Duncan
I didn't think it would work, because presumably it just invokes Haddock anyway. So I just tried it, and got: dist\build\tmp\Database\Enumerator.hs:"dist\\build\\tmp\\Database\\Enumerator.hs": 187:1: Parse error and the offending lines in this file are: #ifndef __HADDOCK__ deriving (Functor, Monad, MonadIO, MonadFix, MonadReader sess) #else -- Haddock can't cope with the "MonadReader sess" instance deriving (Functor, Monad, MonadIO, MonadFix) #endif so it would appear that __HADDOCK__ is not defined. But there's a bigger problem, in that this Enumerator.hs file is obviously the output of "ghc -E Enumerator.lhs -o Enumerator.hs", as it does not contain any of the original comments, which again is no good for Haddock. Am I using birdtrack-lhs the wrong way? I've written my Haddock comments like so: | Returns the number of rows affected.
execDML :: IE.Command stmt s => stmt -> DBM mark s Int
and: | Module : Database.Enumerator Copyright : (c) 2004 Oleg Kiselyov, Alistair Bayley License : BSD-style ... But now I'm thinking that perhaps I should have written:
--| Returns the number of rows affected. execDML :: IE.Command stmt s => stmt -> DBM mark s Int
which kinda defeats the purpose of the birdtrack style.IMO. Alistair

and the offending lines in this file are:
#ifndef __HADDOCK__ deriving (Functor, Monad, MonadIO, MonadFix, MonadReader sess) #else -- Haddock can't cope with the "MonadReader sess" instance deriving (Functor, Monad, MonadIO, MonadFix) #endif
so it would appear that __HADDOCK__ is not defined.
Sorry, I should have said, "so it appears that -cpp is not being used". Alistair

On Thu, 2007-08-02 at 13:58 +0100, Alistair Bayley wrote:
and the offending lines in this file are:
#ifndef __HADDOCK__ deriving (Functor, Monad, MonadIO, MonadFix, MonadReader sess) #else -- Haddock can't cope with the "MonadReader sess" instance deriving (Functor, Monad, MonadIO, MonadFix) #endif
so it would appear that __HADDOCK__ is not defined.
Sorry, I should have said, "so it appears that -cpp is not being used".
It uses -cpp if CPP is in the language extensions in the .cabal file. (At least that's what the code says it's supposed to be doing which is not a guarantee that it works). It does also define __HADDOCK__ when it uses cpp. Hmm, actually there is a problem here. Unlitting does indeed remove all the literate comments, so haddock will never see any markup that is put in the non-code part. To work with current haddock it'd have to be:
-- | This is a haddock comment foo = ...
because that's the only code haddock will see since unlitting turns a literate haskell file into a valid .hs file. It's a purely textual transformation and it's done by removing all the non > lines. Perhaps unlitting should be done by converting all literate comments into {- ... -} style comments. Then it'd probably work with haddock like you have it now: | haddock comment
foo = ...
since that'd become: {- | haddock comment -} foo = ... Or something like that. Perhaps that's worth investigating and adding to ghc/cpphs or Cabal's own existing pure Haskell impl of unlitting. Duncan

It uses -cpp if CPP is in the language extensions in the .cabal file.
So it does. So now Haddock completes, but produces very limited output.
Perhaps unlitting should be done by converting all literate comments into {- ... -} style comments.
Or something like that. Perhaps that's worth investigating and adding to ghc/cpphs or Cabal's own existing pure Haskell impl of unlitting.
As I alluded to earlier, I have a program which I wrote to do this. It prefixes "--" rather than enclosing in {- -}, and it's not perfect (there are a number of cases it doesn't handle, although I'm of the opinion that you shouldn't be doing whatever it fails on). I'm thinking it might be feasible to distribute this in the Takusen release and hook it into the cabal "setup haddock" command to preprocess the .lhs files. I have been tempted to run it over our .lhs once and for all, and convert everything to regular .hs files, but Oleg seems to like the birdtrack style, so we've decided to stick with it for now. Alistair

"Alistair Bayley"
It uses -cpp if CPP is in the language extensions in the .cabal file.
So it does. So now Haddock completes, but produces very limited output.
Perhaps unlitting should be done by converting all literate comments into {- ... -} style comments.
I have a programme (FishFeeder) that does this; it's a bit hacky, but I could post it here if someone was interested in taking it on.
As I alluded to earlier, I have a program which I wrote to do this. It prefixes "--" rather than enclosing in {- -},
Mine uses {- -} and escapes any such present in comments. Here is the first comment from the source, which is itself literate haddock: | Preprocess literate haskell with Haddockumentation in the literate comments for use with Haddock. So making things a bit prettier Assumes that there is at least one space after every \">\", and indents the \"{-\"s (but not the \"-}\"s) by that much so that Haddock doesn't give a parse error. This is a bit of a hack, but I reckon it's haddock's fault since comments shouldn't have any effect on layout.
and it's not perfect
I'd very be surprised if mine were!
(there are a number of cases it doesn't handle, although I'm of the opinion that you shouldn't be doing whatever it fails on). I'm thinking it might be feasible to distribute this in the Takusen release and hook it into the cabal "setup haddock" command to preprocess the .lhs files.
It would surely be better to distribute a tool (either with compilers or with haddock) so that it worked for anyone who likes literate haskell?
I have been tempted to run it over our .lhs once and for all, and convert everything to regular .hs files, but Oleg seems to like the birdtrack style, so we've decided to stick with it for now.
I much prefer the birdtrack style; it's a matter of taste, and there's nothing more likely to cause disaffection than insisting that someone abide by someone else's taste. I would hate to see it deprecated just because the tools were no good. -- Jón Fairbairn Jon.Fairbairn@cl.cam.ac.uk

On Thu, 2007-08-02 at 15:41 +0100, Jon Fairbairn wrote:
"Alistair Bayley"
writes: It uses -cpp if CPP is in the language extensions in the .cabal file.
So it does. So now Haddock completes, but produces very limited output.
Perhaps unlitting should be done by converting all literate comments into {- ... -} style comments.
I have a programme (FishFeeder) that does this; it's a bit hacky, but I could post it here if someone was interested in taking it on.
Sure why not. Post it. As I say, we've already got unlit code in Cabal. If anyone wants to then make a patch to Cabal's unlit code that'd be much appreciated. Then we can ask Alistair to use Takusen as a test case. Or we could see about getting it into cpphs's --unlit mode. Duncan

Duncan Coutts
On Thu, 2007-08-02 at 15:41 +0100, Jon Fairbairn wrote:
"Alistair Bayley"
writes: It uses -cpp if CPP is in the language extensions in the .cabal file.
So it does. So now Haddock completes, but produces very limited output.
Perhaps unlitting should be done by converting all literate comments into {- ... -} style comments.
I have a programme (FishFeeder) that does this; it's a bit hacky, but I could post it here if someone was interested in taking it on.
Sure why not. Post it. As I say, we've already got unlit code in Cabal.
OK, but as I said, it's hacky... -- Jón Fairbairn Jon.Fairbairn@cl.cam.ac.uk

| * Don't use tabs Is there an emacs mode or Lisp-blob that lets you use TAB to go to the next n-col boundary, but expands the jump into spaces. In emacs modes, TAB usually does all sorts of other snazzy things concerning layout, which I don't want. I just want something that behaves like old-fashioned TAB, but generates a file with spaces. Simon

On 2 aug 2007, at 09.50, Simon Peyton-Jones wrote:
Is there an emacs mode or Lisp-blob that lets you use TAB to go to the next n-col boundary, but expands the jump into spaces.
In emacs modes, TAB usually does all sorts of other snazzy things concerning layout, which I don't want. I just want something that behaves like old-fashioned TAB, but generates a file with spaces.
This should work: ;; tabs are evil, always use spaces instead (setq indent-tabs-mode nil) ;; in your haskell-mode-hook: (define-key haskell-mode-map [tab] 'indent-for-tab-command) Regards, / Thomas

Thomas Schilling wrote:
On 2 aug 2007, at 09.50, Simon Peyton-Jones wrote:
Is there an emacs mode or Lisp-blob that lets you use TAB to go to the next n-col boundary, but expands the jump into spaces.
In emacs modes, TAB usually does all sorts of other snazzy things concerning layout, which I don't want. I just want something that behaves like old-fashioned TAB, but generates a file with spaces.
This should work:
;; tabs are evil, always use spaces instead (setq indent-tabs-mode nil)
;; in your haskell-mode-hook: (define-key haskell-mode-map [tab] 'indent-for-tab-command)
While we're on emacs... I know I can colour trailing whitespace differently, but that's just annoying. What I want is: on lines that I edit, remove the trailing whitespace (and if I undo the edit, put the whitespace back too). Is there something that does that? I couldn't find it. Cheers, Simon

On 2 aug 2007, at 12.10, Simon Marlow wrote:
While we're on emacs... I know I can colour trailing whitespace differently, but that's just annoying. What I want is: on lines that I edit, remove the trailing whitespace (and if I undo the edit, put the whitespace back too). Is there something that does that? I couldn't find it.
The simplest thing I can think of, is to not remove whitespace at all, but to only remove it when you're saving the file. I know that some modes use such a save hook. It also wouldn't modify the actual file (ie, don't remove the whitespace until you save the file for the first time), as long as you edit it. The only time the spaces would be removed permanently were if you save the file, close the buffer, and then re-open the file. If I can come up with a simple solution, I'll let you know. / Thomas

Thomas Schilling wrote:
The simplest thing I can think of, is to not remove whitespace at all, but to only remove it when you're saving the file. I know that some modes use such a save hook. It also wouldn't modify the actual file (ie, don't remove the whitespace until you save the file for the first time), as long as you edit it. The only time the spaces would be removed permanently were if you save the file, close the buffer, and then re-open the file.
Picture mode removes trailing space when you exit it, so perhaps the function that does that is available to call upon saving. Dave

-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On 2 aug 2007, at 18.03, David Brown wrote:
Thomas Schilling wrote:
The simplest thing I can think of, is to not remove whitespace at all, but to only remove it when you're saving the file. I know that some modes use such a save hook. It also wouldn't modify the actual file (ie, don't remove the whitespace until you save the file for the first time), as long as you edit it. The only time the spaces would be removed permanently were if you save the file, close the buffer, and then re-open the file.
Picture mode removes trailing space when you exit it, so perhaps the function that does that is available to call upon saving.
Dave
Well, this works: (defun delete-trailing-space () "Deletes trailing space from all lines in buffer." (interactive) (or buffer-read-only (save-excursion (message "Deleting trailing spaces ... ") (goto-char (point-min)) (while (< (point) (point-max)) (end-of-line nil) (delete-horizontal-space) (forward-line 1)) (message "Deleting trailing spaces ... done."))) nil) ; indicates buffer-not-saved for write-file-hook (add-hook 'haskell-mode-hook 'my-haskell-mode-hook) ;; Make the hook a named function, so we can redefine it :: without having torestart emacs. (defun my-haskell-mode-hook () ... (add-hook 'write-file-hooks 'delete-trailing-space) ... )) But it has the problem that it will delete the whitespace also in the open buffer, so you have to re-insert the whitespace at the end of the line. I am just looking at how to modify the editing functions, to have this work more seamlessly. / Thomas -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.5 (Darwin) iQEVAwUBRrIDWiuNq1ISBIDTAQKE5wf/dSuD8pAIaaUj/R4qqB022Z0hfhLjxZpc 2oLNjYCWwYKbPu7NUOuQZ5KasP6A8yJstqZndpcllxNHimKAuqJ6CSGcEEswfpVL LX5yz9YctFvABXSF0n7zITaQACkkTSHiFPpv/7B6h6mUZYNq8aTpW+PjxGTWn1g3 r2aE5ihhMJZwH/ted+jvjWibf1tP8CtHXSQkzyJpDRGdVcpKogwoJ0HLdL/pA4Kg +Nc0rAST/zPGPIJPXsUq4LHyH5kMQcLrgtukwN43ijqOv1sGR4Yh6hlapi82nZ0i J0avFsi/6TibwrMgearo/WqU8gbrD4Nefl191vCmyWv5JUSAt/H6Gw== =/gC3 -----END PGP SIGNATURE-----

On Thu, 02 Aug 2007, Thomas Schilling
(defun delete-trailing-space ()
FYI: There is a standard function delete-trailing-whitespace which you could use.
(add-hook 'write-file-hooks 'delete-trailing-space)
And write-contents-hooks may be more appropriate. -- /NAD

On 6 aug 2007, at 17.12, Nils Anders Danielsson wrote:
On Thu, 02 Aug 2007, Thomas Schilling
wrote: (defun delete-trailing-space ()
Yes, thanks. That was also pointed out by Chris, in this thread.
FYI: There is a standard function delete-trailing-whitespace which you could use.
(add-hook 'write-file-hooks 'delete-trailing-space)
And write-contents-hooks may be more appropriate.
Thanks, I take a look. As Simon Marlow mentioned, this however does not solve our problem. I just fell into that trap myself, because I accidentally kept that hook on a file I was working on, and had a very hard time filtering out the actual changes when I recorded my darcs patch. Hooking this feature in with highlight-changes-mode might give us a way to find out which lines were actually modified, but even then the best way to integrate this would be with darcs or some darcs mode. I use darcsum.el, which works rather well, but is far from perfect. I take a look. Thanks, / Thomas

On Mon, 06 Aug 2007, Thomas Schilling
As Simon Marlow mentioned, this however does not solve our problem.
No, it does not solve Simon's problem, but it is a quick and simple solution which works well for files that are created and edited only by you. Furthermore a little white space in some patches may not be much of a problem. -- /NAD

Thomas Schilling wrote:
On 2 aug 2007, at 12.10, Simon Marlow wrote:
While we're on emacs... I know I can colour trailing whitespace differently, but that's just annoying. What I want is: on lines that I edit, remove the trailing whitespace (and if I undo the edit, put the whitespace back too). Is there something that does that? I couldn't find it.
The simplest thing I can think of, is to not remove whitespace at all, but to only remove it when you're saving the file. I know that some modes use such a save hook. It also wouldn't modify the actual file (ie, don't remove the whitespace until you save the file for the first time), as long as you edit it. The only time the spaces would be removed permanently were if you save the file, close the buffer, and then re-open the file.
If I can come up with a simple solution, I'll let you know.
I don't actually want it done on the whole file, which is why I asked for the behaviour only on lines that I edit. The idea is to be revision-control-friendly by not introducing unrelated formatting changes. You could start by removing all the trailing whitespace in all the sources in the repository, but I think that's unnecessary. Also I don't want to be forced to do this everywhere. Cheers, Simon

On Fri, 2007-08-03 at 09:07 +0100, Simon Marlow wrote:
I don't actually want it done on the whole file, which is why I asked for the behaviour only on lines that I edit. The idea is to be revision-control-friendly by not introducing unrelated formatting changes.
Ah, but actually it's even harder than that. You want to strip only lines that end up in the final diff, not merely ones that you edit (but may end up leaving the same). So actually perhaps it can be done on save by diffing the old saved version against the to-be-saved version and fixing the white space in those new lines that end up covered by the diff. Sounds like a task for Yi's Haskell mode, all it needs to do is import the darcs diff code... :-) Duncan

On Thu, Aug 02, 2007 at 11:10:22AM +0100, Simon Marlow wrote:
Thomas Schilling wrote:
On 2 aug 2007, at 09.50, Simon Peyton-Jones wrote:
Is there an emacs mode or Lisp-blob that lets you use TAB to go to the next n-col boundary, but expands the jump into spaces.
In emacs modes, TAB usually does all sorts of other snazzy things concerning layout, which I don't want. I just want something that behaves like old-fashioned TAB, but generates a file with spaces.
This should work:
;; tabs are evil, always use spaces instead (setq indent-tabs-mode nil)
;; in your haskell-mode-hook: (define-key haskell-mode-map [tab] 'indent-for-tab-command)
While we're on emacs... I know I can colour trailing whitespace differently, but that's just annoying. What I want is: on lines that I edit, remove the trailing whitespace (and if I undo the edit, put the whitespace back too). Is there something that does that? I couldn't find it.
This ought to be doable with a --prehook in darcs record, except that darcs doesn't yet support prehooks. It's nicer if done by the editor, though. -- David Roundy Department of Physics Oregon State University

Simon Marlow
While we're on emacs... I know I can colour trailing whitespace differently, but that's just annoying.
You could use something more discreet, like colored underlines.
What I want is: on lines that I edit, remove the trailing whitespace (and if I undo the edit, put the whitespace back too). Is there something that does that?
;; Difficulties are that a) in general changes doesn't necessarily ;; happen at the location of point, and OTOH b) commands can ;; temporarily move point behind the scenes, but c) we don't want ;; characters do disappear under our feet (point) . Try to do ;; something sensible. (defun line-delete-trailing-whitespace (beg end len) (unless (or (eolp) undo-in-progress) (save-excursion (end-of-line) (delete-char (- (skip-chars-backward " \t" end)))))) ;; Buffer local, use a mode hook (add-hook 'after-change-functions 'line-delete-trailing-whitespace nil t) ;; To see what's going on (setq show-trailing-whitespace t) -- Johan Bockgård

Ian Lynagh wrote:
* Don't leave trailing white space in your code * Don't use tabs * Aim to keep lines under 80 characters * Use the CamelCase variable naming convention * Don't use explicit braces and semicolons
"by giving a parse error if we break any of its rules" -- well, you hope, right? My own preferences: * Don't leave trailing white space in your code. * Use one tab to indent each level. Display them at 4 space boundaries. * Aim to keep lines under about 150 characters. * Use the CamelCase variable naming convention. * Use explicit braces and semicolons. Use "Allman" style. * Put a newline at the end of the file. * Prefix constructor names with "Mk" if there's only one in the type. * Move private definitions to other "where" clauses where possible. * Never use any unsafe functions (besides FFI). This is Haskell. * Compile with "-Wall -Werror". This implies lots of type signatures. For the time library source however I was rather closer to Ian's guidelines, just so as not to annoy people. I think it still has tabs though. -- Ashley Yakeley

On Thu, Aug 02, 2007 at 06:52:01PM -0700, Ashley Yakeley wrote:
Ian Lynagh wrote:
* Don't leave trailing white space in your code * Don't use tabs * Aim to keep lines under 80 characters * Use the CamelCase variable naming convention * Don't use explicit braces and semicolons
"by giving a parse error if we break any of its rules" -- well, you hope, right?
My own preferences: ... * Use one tab to indent each level. Display them at 4 space boundaries.
But this means that your code will have the possibility of layout bugs that not visible to the programmer, since according to the report a tab corresponds to eight spaces. Sounds like the worst of all possible worlds. -- David Roundy Department of Physics Oregon State University

David Roundy wrote:
* Use one tab to indent each level. Display them at 4 space boundaries.
But this means that your code will have the possibility of layout bugs that not visible to the programmer, since according to the report a tab corresponds to eight spaces. Sounds like the worst of all possible worlds.
No layout bugs: * Use explicit braces and semicolons. Use "Allman" style. -- Ashley Yakeley

Ashley Yakeley wrote:
No layout bugs:
* Use explicit braces and semicolons. Use "Allman" style.
I'm sure you could come up with a little better convention than this, but here you go (or does "Allman style" refer to something particular? if so, what?) : module Foo (bar, Baz(..)) where { import Prelude ; bar :: Ordering -> Bool ; bar x = case x of { LT -> True; _ -> False } ; data Baz a where { Oops :: Num a => Bool -> IO a -> Baz a ; Fine :: Baz () } } Oh by the way Ashley Y, have you seen my comment about the HaskellWiki at the end of http://haskell.org/haskellwiki/Talk:Haskell (I know this is off topic but I don't want to be spam-filtered or missed again!) Isaac

Isaac Dupree wrote:
* Use explicit braces and semicolons. Use "Allman" style.
I'm sure you could come up with a little better convention than this, but here you go (or does "Allman style" refer to something particular? if so, what?) :
http://en.wikipedia.org/wiki/Indent_style#Allman_style module Foo (bar, Baz(..)) where { import Prelude; bar :: Ordering -> Bool; bar x = case x of { LT -> True; _ -> False; }; data Baz a where { Oops :: Num a => Bool -> IO a -> Baz a; Fine :: Baz (); } } (but I've used spaces here)
Oh by the way Ashley Y, have you seen my comment about the HaskellWiki at the end of http://haskell.org/haskellwiki/Talk:Haskell (I know this is off topic but I don't want to be spam-filtered or missed again!)
OK, I'll fix it... -- Ashley Yakeley

Ashley Yakeley wrote:
Isaac Dupree wrote:
* Use explicit braces and semicolons. Use "Allman" style.
I'm sure you could come up with a little better convention than this, but here you go (or does "Allman style" refer to something particular? if so, what?) :
Okay, luckily Haskell generally allows extra semicolons, so that works :-) (in fact I believe the extra semicolons being allowed was important for flexible _layout_ rules, for use in combination with explicit semicolons, and thereby helped make sure that non-layout syntax was nice and flexible too!) Isaac
participants (23)
-
Alistair Bayley
-
Ashley Yakeley
-
Bayley, Alistair
-
Benjamin Franksen
-
bojohan+news@dd.chalmers.se
-
Chris Kuklewicz
-
Christian Maeder
-
David Brown
-
David Roundy
-
Duncan Coutts
-
Ian Lynagh
-
Iavor Diatchki
-
Isaac Dupree
-
John Meacham
-
Jon Fairbairn
-
kahl@cas.mcmaster.ca
-
Malcolm Wallace
-
Nils Anders Danielsson
-
Philippa Cowderoy
-
Seth Kurtzberg
-
Simon Marlow
-
Simon Peyton-Jones
-
Thomas Schilling