
Why do people put ";" in do {}, or "," in data fields, at the beginning of the line? -- Daryoush Weblog: http://onfp.blogspot.com/

I started for cleaner diffs and easier editing - I can add/remove a
line at the end without editing any other line. Eventually I grew to
like the look of it.
Both styles are common, from what I can tell.
Antoine
On Wed, Dec 29, 2010 at 11:40 PM, Daryoush Mehrtash
Why do people put ";" in do {}, or "," in data fields, at the beginning of the line? -- Daryoush
Weblog: http://onfp.blogspot.com/
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

On Thu, 30 Dec 2010, Antoine Latter wrote:
I started for cleaner diffs and easier editing - I can add/remove a line at the end without editing any other line. Eventually I grew to like the look of it.
That's not true. As long as the comma is used as separator one line can affect an adjacent one. If the comma is written on the end of a line, then removing the last line means altering the line before. If the comma is at front of a line, then removing the first line requires altering the second one. Really different is only the usage of the comma as terminator. Actually this is possible in import and export statements, but not in constructor enumerations. http://www.haskell.org/haskellwiki/Terminator_vs._separator

On Thu, Dec 30, 2010 at 8:15 AM, Henning Thielemann
On Thu, 30 Dec 2010, Antoine Latter wrote:
I started for cleaner diffs and easier editing - I can add/remove a line at the end without editing any other line. Eventually I grew to like the look of it.
That's not true. As long as the comma is used as separator one line can affect an adjacent one. If the comma is written on the end of a line, then removing the last line means altering the line before. If the comma is at front of a line, then removing the first line requires altering the second one.
By 'end' I meant 'last line' - I suppose a list does have two ends :-)
Really different is only the usage of the comma as terminator. Actually this is possible in import and export statements, but not in constructor enumerations.

Why do people put ";" in do {}, or "," in data fields, at the beginning of the line? -- It reflects the parse tree better by putting the combining operators (e.g. ';' and ',') at the left and their operands (or combined subtrees) indented to the right. IOW, this formating style rotates
On 12/29/10 22:40, Daryoush Mehrtash wrote: the parse tree: o_ / \ / \ s1 s2 for operator o_ and subtrees, s1 and s2, -90 degrees and replaces the connecting edges with indentation: s1 o_ s2 now, it surrounds that with the begin(b_) and end(e_) delimiters: b_ s1 o_ s2 e_ For example, in the case of a tuple with arguments, a1 and a2, this would appear: ( a1 , a2 ) This also improves readability in a similar way that bulleted list items in a text document improve readability. For example: * s1 * s2 is easier to read than: s1 s2 because the reader knows that * begins an item and he only has to search a given column for the beginning of the next item. However, some people object to this style because it requires too much vertical space as compared to: ( a1, a2 ) HTH -regards, Larry

On Thu, Dec 30, 2010 at 07:04:11AM -0600, Larry Evans wrote:
On 12/29/10 22:40, Daryoush Mehrtash wrote:
Why do people put ";" in do {}, or "," in data fields, at the beginning of the line? -- It reflects the parse tree better by putting the combining operators (e.g. ';' and ',') at the left and their operands (or combined subtrees) indented to the right.
I will take this opportunity to mention again a related pet peeve of mine that I originally griped about ages ago: http://www.mail-archive.com/haskell-cafe@haskell.org/msg02231.html Even nowadays, Haddock deliberately generates the following layout for long function types: openTempFile :: FilePath -> String -> IO (FilePath, Handle) The layout draws special attention to the first argument type, whereas the other argument types are indistinguishable from the return type. The following is much clearer: openTempFile :: FilePath -> String -> IO (FilePath, Handle) (Possibly with the arrows aligned.) I can't understand how the "arrows first" convention still lingers so strongly when it is (to me) so obviously wrong and misleading. Please, folks, at least pay a thought to what different indentation and line continuation styles express before adopting one. Lauri

On Thu, 30 Dec 2010, Lauri Alanko wrote:
Even nowadays, Haddock deliberately generates the following layout for long function types:
openTempFile :: FilePath -> String -> IO (FilePath, Handle)
The layout draws special attention to the first argument type, whereas the other argument types are indistinguishable from the return type. The following is much clearer:
openTempFile :: FilePath -> String -> IO (FilePath, Handle)
(Possibly with the arrows aligned.)
+1 GHC also formats type signatures in errors and warnings in the misleading way. In case of Haddock comments I understand that the comment must be close to the argument type. That is openTempFile FilePath -- ^ filename, of course -> String -> IO (FilePath, Handle) would not work. But {- ^ filename -} would work.

On 12/30/10 08:17, Henning Thielemann wrote:
On Thu, 30 Dec 2010, Lauri Alanko wrote:
Even nowadays, Haddock deliberately generates the following layout for long function types:
openTempFile :: FilePath -> String -> IO (FilePath, Handle)
The layout draws special attention to the first argument type, whereas the other argument types are indistinguishable from the return type.
Lauri, I assume then that you want to draw special attention to the return type instead of the first argument type.
The following is much clearer:
openTempFile :: FilePath -> String -> IO (FilePath, Handle)
(Possibly with the arrows aligned.)
So, with this "operator postfix" formatting, the special attention to the return type is achieved by *not* suffixing it with ->. However, to see that it's not suffixed with ->, your eyes have to scan to the right for the whole line until you don't find the ->. Oh, but wait, if the return type is an elaborate type expression, that takes up more than say, 60 spaces, then I would want to format it over more than one line. Yes, that would be rare, but possible. Now you'd have to scan not 1 but 2 lines to find (or rather not find) the ->. OK, but then why not just find the last argument and forget about finding the missing postfix ->? Well, in that case, the "operator prefix" formatting would serve just as well. The attachment contains ret_{post,pre} declaration which provide a concrete example. Maybe I'm just used to the prefix formatting, but I do find ret_pre easier to read than the ret_post. I find it more readable because I just have to search, in a given column, for the last ->, and then I know the following is the return type.
+1
GHC also formats type signatures in errors and warnings in the misleading way.
In case of Haddock comments I understand that the comment must be close to the argument type.
Henning, I guess you're saying Haddock puts -> first on the line in order to make the comment as close as possible to the argument type.
That is
openTempFile FilePath -- ^ filename, of course -> String -> IO (FilePath, Handle)
would not work. But {- ^ filename -} would work.
So, Haddock would format this(after adding comments for other args) as: [1]: openTempFile :: FilePath -- ^ filename, of course -> String -- ^ comment for 2nd arg. -> IO (FilePath, Handle) -- ^ comment for 3ird arg However, you and Lauri would prefer (IIUC): [2]: openTempFile:: FilePath {- ^ filename, of course -} -> String {- ^ comment for 2nd arg. -} -> IO (FilePath, Handle) -- ^ comment for 3ird arg or, to retain the same comment types: [3]: openTempFile:: FilePath -- ^ filename, of course -> String -- ^ comment for 2nd arg. -> IO (FilePath, Handle) -- ^ comment for 3ird arg OK, but then there's more vertical space used, so maybe [2] is better; however, [2] separates the operator, -> from it's operands by the the comment. Maybe you could justify this by saying the operator is not important for readability; however, in my reply to Lauri, I indicated it was easier to find the last argument if the operators were prefixed, as was illustrated by the ret_{post,pre} declarations in the attachment. Likewise, I find it easier to find the last argument with [1] rather than either [2] or [3]. -regards, Larry

On Thu, Dec 30, 2010 at 10:39:29AM -0600, Larry Evans wrote:
Lauri, I assume then that you want to draw special attention to the return type instead of the first argument type.
Only to the fact that the return type is of a different nature than the argument types, and that all the argument types are of the same nature. (More technically, the argument types occur in negative positions within the function type, whereas the return type occurs in a positive position.)
So, with this "operator postfix" formatting, the special attention to the return type is achieved by *not* suffixing it with ->.
Partly, but more by the fact that it is the last item in the list. Of course there are ways to make it even more prominent, e.g. by inserting an empty line before it. The arrows are not really essential for readability, although they can help a bit if they are aligned: openTempFile :: FilePath -> String -> IO (FilePath, Handle)
OK, but then why not just find the last argument and forget about finding the missing postfix ->? Well, in that case, the "operator prefix" formatting would serve just as well.
Except that it falsely suggests that the last argument types are of a similar nature as the return type. Here's what went in my head when I first read Haskell code: openTempFile :: FilePath -- All right, this first part is probably the argument. -> String -- this comes after the arrow, so this must be the return type. -> IO (FilePath, Handle) -- And then we have another return type? Huh? It took me quite a while to understand that -> associates to the right, because the layout so strongly suggested otherwise. Obviously, with time one can get used to anything, but I still stand by my opinion that the above convention is inherently misleading.
[1]: openTempFile :: FilePath -- ^ filename, of course -> String -- ^ comment for 2nd arg. -> IO (FilePath, Handle) -- ^ comment for 3ird arg
3rd arg? This is just the sort of lapse that the above syntax induces.
[2]: openTempFile:: FilePath {- ^ filename, of course -} -> String {- ^ comment for 2nd arg. -} -> IO (FilePath, Handle) -- ^ comment for 3ird arg
This is admittedly ugly. I'd prefer: openTempFile :: FilePath -> -- ^ foo String -> -- ^ bar IO (FilePath, Handle) -- ^ baz If Haddock doesn't support an intervening -> between the type and the documentation comment, it probably should. (Personally, I don't like end-of-line comments because they quickly run out of space and extending them to multiple lines is awkward. So maybe even better would be: openTempFile :: FilePath -> -- ^ foo String -> -- ^ bar IO (FilePath, Handle) -- ^ baz But this is no longer relevant to the issue at hand.) Lauri

On Thu, 30 Dec 2010, Lauri Alanko wrote:
Except that it falsely suggests that the last argument types are of a similar nature as the return type. Here's what went in my head when I first read Haskell code:
openTempFile :: FilePath -- All right, this first part is probably the argument. -> String -- this comes after the arrow, so this must be the return type. -> IO (FilePath, Handle) -- And then we have another return type? Huh?
It took me quite a while to understand that -> associates to the right, because the layout so strongly suggested otherwise. Obviously, with time one can get used to anything, but I still stand by my opinion that the above convention is inherently misleading.
I see it the same way. The arrow-prefix notation suggests left associativity for (->). Combining lines beginning from the bottom, e.g. -> IO (FilePath, Handle) or -> String -> IO (FilePath, Handle) does not make sense, thus the layout suggests to consider block prefixes, e.g. FilePath and FilePath -> String and FilePath -> String -> IO (FilePath, Handle) but these three are completely unrelated types. On the other hand the line FilePath -> suggests: "read on, this is only the first argument of something bigger, it is not a top-level FilePath declaration". The second line String -> suggests: "This is still not the result, just another argument." And so on. Since in this formatting prefix blocks like FilePath -> String -> make no sense, the layout suggests right associativity of (->).
[2]: openTempFile:: FilePath {- ^ filename, of course -} -> String {- ^ comment for 2nd arg. -} -> IO (FilePath, Handle) -- ^ comment for 3ird arg
This is admittedly ugly. I'd prefer:
openTempFile :: FilePath -> -- ^ foo String -> -- ^ bar IO (FilePath, Handle) -- ^ baz
If Haddock doesn't support an intervening -> between the type and the documentation comment, it probably should.
Haddock must respect the inner structure of types, since in the future (or is it already there?) you might be able to comment more parts of a type and then the position of comments is essential. E.g. arrow :: A {- ^ arrow argument -} :~> {- ^ our ingenious arrow -} B {- ^ arrow result -} foo :: Applicative f => f (A {- ^ first arg -} -> B {- ^ second arg -} -> C {- ^ result -}) pair :: (A {- ^ first element -}, B {- ^ second element -}) Maybe Haddock should have expected comments _before_ commented types. openTempFile :: -- ^ foo FilePath -> -- ^ bar String -> -- ^ baz IO (FilePath, Handle) openTempFile :: {- ^ foo -} FilePath -> {- ^ bar -} String -> {- ^ The result type is especially difficult to explain and thus needs two lines. -} IO (FilePath, Handle)
(Personally, I don't like end-of-line comments because they quickly run out of space and extending them to multiple lines is awkward. So maybe even better would be:
openTempFile :: FilePath -> -- ^ foo String -> -- ^ bar IO (FilePath, Handle) -- ^ baz
But this is no longer relevant to the issue at hand.)
I also do not like multi-line comments composed from single-line comments. Haddock parses them and they are used in a lot of libraries. But I find it cumbersome to prefix every line with double-dash.

On Thu, Dec 30, 2010 at 8:33 AM, Lauri Alanko
On Thu, Dec 30, 2010 at 07:04:11AM -0600, Larry Evans wrote:
On 12/29/10 22:40, Daryoush Mehrtash wrote:
Why do people put ";" in do {}, or "," in data fields, at the beginning of the line? -- It reflects the parse tree better by putting the combining operators (e.g. ';' and ',') at the left and their operands (or combined subtrees) indented to the right.
I will take this opportunity to mention again a related pet peeve of mine that I originally griped about ages ago:
http://www.mail-archive.com/haskell-cafe@haskell.org/msg02231.html
Even nowadays, Haddock deliberately generates the following layout for long function types:
openTempFile :: FilePath -> String -> IO (FilePath, Handle)
Aesthetics is a funny thing. I prefer writing my type signatures arrow-first if they grow too long. Antoine
The layout draws special attention to the first argument type, whereas the other argument types are indistinguishable from the return type. The following is much clearer:
openTempFile :: FilePath -> String -> IO (FilePath, Handle)
(Possibly with the arrows aligned.)
I can't understand how the "arrows first" convention still lingers so strongly when it is (to me) so obviously wrong and misleading. Please, folks, at least pay a thought to what different indentation and line continuation styles express before adopting one.
Lauri
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

On 30 December 2010 15:44, Antoine Latter
On Thu, Dec 30, 2010 at 8:33 AM, Lauri Alanko
wrote: Even nowadays, Haddock deliberately generates the following layout for long function types:
openTempFile :: FilePath -> String -> IO (FilePath, Handle)
Aesthetics is a funny thing. I prefer writing my type signatures arrow-first if they grow too long.
Me too: fooBar :: Foo a => Bar a -> Mu a -> Zot () Though in Lisk I don't have to think much about this: (:: foo-bar (=> ('foo a) (-> ('bar a) ('mu a) ('zot ())))) (:: foo-bar (=> ('foo a) (-> ('bar a) ('mu a) ('zot ()))))

Antoine Latter
openTempFile :: FilePath -> String -> IO (FilePath, Handle)
My main discomfort with this is not the result type, but that the first argument appears different from the rest. I much prefer having the :: be attached to the identifier. FWIW. -k -- If I haven't seen further, it is by standing in the footprints of giants

Lauri Alanko
The following is much clearer:
openTempFile :: FilePath -> String -> IO (FilePath, Handle)
(Possibly with the arrows aligned.)
I can't understand how the "arrows first" convention still lingers so strongly when it is (to me) so obviously wrong and misleading.
What about chains of $ in terms? (Both -> in types and $ in terms associate to the right. What about + - * / in terms, which associate to the left?) -- Edit this signature at http://www.digitas.harvard.edu/cgi-bin/ken/sig Where is Galt's Gulch?
participants (9)
-
Albert Y. C. Lai
-
Antoine Latter
-
Christopher Done
-
Chung-chieh Shan
-
Daryoush Mehrtash
-
Henning Thielemann
-
Ketil Malde
-
Larry Evans
-
Lauri Alanko