Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Colonectomy #118

Closed
wants to merge 3 commits into from
Closed

Colonectomy #118

wants to merge 3 commits into from

Conversation

halfaya
Copy link

@halfaya halfaya commented Apr 1, 2018

Remove one colon from the :: in type signatures. A serious proposal.

Rendered

@gelisam
Copy link

gelisam commented Apr 1, 2018

It is envisioned that within a few years the GHC codebase itself, libraries, and standard packages will all have been migrated to NCC.

I think that's unlikely. You'd need much bigger pressure than that, otherwise I suspect use of the Colonectomy extension will be just as rare as the UnicodeSyntax extension. It would still be nice to offer the choice I suppose.

@mrkgnao
Copy link

mrkgnao commented Apr 1, 2018

Does promoting the list cons constructor (i.e. ':: instead of ':) work out fine?

@barrucadu
Copy link

barrucadu commented Apr 1, 2018

How often does the use of :: confuse newcomers? It seems it would only confuse newcomers from Agda, ML, Coq, etc, which are already fairly atypical newcomers.

@chessai
Copy link

chessai commented Apr 1, 2018

It confuses people that come from Elm. I'm +1 on this, provided the promoted list cons constructor changes as well.

@gbaz
Copy link

gbaz commented Apr 1, 2018

We implemented the single-colon convention in ermine, which otherwise adhered very closely to haskell syntax. In that case I came to the conclusion that the payoff wasn't worth the cost, which came from A) context-switching between syntactic conventions, and B) having existing code snippets we wished to borrow and use fail to compile without a bit of extra work C) syntax-highlighting etc. for Haskell not working as well and directly with ermine files. You might say: "well, that cost seems minor." Sure. But the payoff was minor too, and in my experience, even more minor.

@halfaya
Copy link
Author

halfaya commented Apr 1, 2018

Thanks everyone for the comments. I'd like to mostly remove myself from the discussion as my own opinion should be clear, but I will address particular points.
@mrkgnao Great question. This does in fact work fine but I need to fix display of ':: (and likely :: as well). I've updated the document with a richer example.
@chessai Thanks, you've reminded me that in fact Purescript and Frege still adhere to the OCC, although they are very closely tied to Haskell. But it's worth noting in any case.
@gbaz Given that Ermine follows the NCC (and I assume is not changing that) I would think having Haskell follow it as well would be a boon! Your points about copy/paste and syntax highlighting are good and I've added them to objections in the document.

@Tritlo
Copy link
Contributor

Tritlo commented Apr 1, 2018

Another cost to be considered is that all printed resources would have to be updated as well. This would probably confuse newcomers to no end, since all their material (initially at least) would be wrong. I still think having the option to use NCC on a per-file basis would be nice, especially if one is coming from ML or Agda.

@abueide
Copy link

abueide commented Apr 1, 2018

@Tritlo A simple and clear compiler error that explains the change in meaning of the symbols would probably be sufficient to solve that cost. I don't see it being too big of a problem.

@treeowl
Copy link
Contributor

treeowl commented Apr 1, 2018

I oppose the proposal. I am certainly sympathetic to the view that Haskell got this one wrong. But I think this will lead to far too much confusion, especially for new users.

@nomeata
Copy link
Contributor

nomeata commented Apr 1, 2018

I am fully in support of this proposal. I was skeptical initially, bu what swayed me was the reference to analogous decisions made in C, and the quote from Kernighan and Ritchie. I am am looking forward to more proposals inspired by C.

I am aware that some people will have trouble adjusting to the new visual appearance. The proposal should recommend using a “legacy mode” font in their editor, that displays the unicode character “'U+003A COLON” as ::, making the transition easier.

While we are at it: forall a. is strange, we should use forall a, to avoid confusion with the function composition operator.

@parsonsmatt
Copy link
Contributor

parsonsmatt commented Apr 1, 2018

If we break every single Haskell source file, it better be For Great Good. This doesn't qualify, IMO.

Haskell is the only language in contemporary use to follow the OCC. Every other language follows the NCC.

Let's not forget PureScript. I'm curious how the total population of OCC languages compares to NCC languages -- if Haskell+PureScript represents a larger "market share" of developers than the NCC languages, then we shouldn't be too worried about our minority status there. After all, it is clear to me that sheer numbers determine correctness.

At some point it may then make sense to introduce another extension, perhaps with a boring name like OldColonConvention, to denote files still following the historical OCC.

Generally speaking, the extension Colonectomy would have a corresponding extension NoConlonectomy which would disable it. So the old syntax would be preserved using that one.


Syntactically speaking :: is superior. It is two characters long, which lines up with -> and =>, the other operators commonly found in types. This permits the following signature with superior readability:

foo
  :: Monad m
  => Int
  -> Double
  -> m Char

The keen observer might ask, But what about the . in an explicit quantification? Indeed! We ought to make that syntax two characters as well, to better line up. I suggest forall x \/ Foo x => x. The \/ characters look kind of like a forall, so why not?

@nomeata
Copy link
Contributor

nomeata commented Apr 1, 2018

Haskell is the only language in contemporary use to follow the OCC. Every other language follows the NCC.

I just noticed that this prerequisite is not true. I recommend the original author to first ensure that Isabelle and Agda switches to NCC first; then we can follow.

@halfaya
Copy link
Author

halfaya commented Apr 2, 2018

@nomeata Thanks I didn't know about Isabelle, but you are right. Of course it's an old language, but still in use. However Agda follows the NCC as noted in the document. In a previous comment I noted that Purescript and Frege also follow Haskell's convention.

I was going to save this until tomorrow, since maybe no one will believe what I say today, but I want to reiterate that this is actually a serious proposal. I posted it on April Fool's Day because otherwise I feared no one would take it seriously! If there's an April Fool's Joke then it's a twist--the proposal in a way seems so outlandish that it should be a joke, but in fact it is not, and although I'm gratified most people are taking it seriously I'm a bit sad that some people were "fooled".

Anyway I'd like to continue the serious discussion going forward. Perhaps it is too much to hope that Haskell will evolve to following the NCC, but the less ambitious goal is to give people a choice, and if there really is enough passion to change things then crowdsourcing should move us closer. I understand the counterargument of confusion, and perhaps that's enough to scuttle the proposal, but I don't believe a per-file flag should be confusing (no more than any other extension which changes or enriches the syntax), and certainly no existing code will be broken so the change is absolutely safe.

@AntC2
Copy link
Contributor

AntC2 commented Apr 2, 2018

@Tritlo Another cost to be considered is that all printed resources would have to be updated as well.

We are already envisaging that: doing away with * in types, to use Type instead. I think there are a number of lexical bits that Haskell 1994 got wrong, as @treeowl mentions. Let's roll them all together into one big code-breaking change.

@parsonsmatt mentions forall. And I've never understood why existential quant also uses forall -- it seems to have been purely to avoid taking another reserved word.

I'd draw attention to the proposal for tight-binding . being reverse function apply; which is much more consistent with using . in Module.name syntax for: record.field (i.e. field is a function applying to record.) In fact I'd argue that . should never have been used for function composition.

EDIT: I've never liked the syntax for FunDeps. This

class C a b c d | a b -> c d  where ...

looks like we're applying a to b and c to d. We should use Mark P Jones original syntax

class C a b c d | {a, b} -> {c, d}  where ...

What's even more annoying is that Injective Type Families took over the same syntax; and introduced an extra type var for the result of the Family; and then found they've created a syntax ambiguity. I propose do away with this

type family F a b c = d | d -> a b c                 -- ?? apply a to b c ?? instead:

type family F a b c | (F a b c) -> {a, b, c }

@carlpaten
Copy link

@parsonsmatt:

Let's not forget PureScript. I'm curious how the total population of OCC languages compares to NCC languages -- if Haskell+PureScript represents a larger "market share" of developers than the NCC languages, then we shouldn't be too worried about our minority status there. After all, it is clear to me that sheer numbers determine correctness.

TypeScript and Scala are NCC, together they probably have more mass than the entire rest of the typed functional ecosystem combined.

@parsonsmatt
Copy link
Contributor

@AntC2 I actually would be in favor of rolling up a list of "Big Breaking Changes" which we'd implement all at once. Stuff like a more sensible Prelude, a reasonable/native String type, turning on all of PureScript's extensions by default, and maybe even syntactic changes like this would be cool.

A sed script could be distributed that would do most of the tedious work.

@chessai
Copy link

chessai commented Apr 2, 2018 via email

@goldfirere
Copy link
Contributor

I'm against this proposal as causing much upheaval for little gain. Of course I'd rather have just one colon (though having ::, -> and => all be two characters is quite nice), but this simply isn't worth it, to me. My 3-bedroom house is nearing its 170th birthday and has grown 4 chimneys over that time; currently 3 of the 4 are there for historical reasons only. These take up valuable space. But it's just too expensive to remove them! (I know; I've looked into it.) I say the same is true for that extra colon, sadly.

@contivero
Copy link

One of the things I love about the Haskell community is it's propensity to improve on the "good enough" when a "better" appears. AFAICT most of those opposing this proposal agree that : would be preferable, but argue that the cost is too high, or it would be confusing for newcomers.

Regarding newcomer confusion, this would stem mainly from the current Haskell literature using ::, but as stated in the proposal, most research literature, and other programming languages, use :. In particular, as @LilRed mentioned, I'd argue that the fact that (among other languages) TypeScript uses it, with its considerable userbase, makes :: more confusing for newcomers than vice-versa.

As for the costs of migrating current codebases to a new syntax, it doesn't seem as something a sed script couldn't handle. I might be wrong, but for me (and maybe I'm being too much of an idealist) legacy code has never been a compelling reason for not improving something.

At the very least, I'm glad this discussion is taking place, and hope that if we can all agree that some change to the language would be better, we take steps in that direction.

@nomeata
Copy link
Contributor

nomeata commented Apr 2, 2018

It is now April 2nd AoE, and this proposal is still open, so let me give a non-April-1st response:

To me, this proposal clearly does not pull the weight and complexity that it entails. It’d be like telling the English to start using , as the decimal separator … yes, would be nice if everybody uses the same, but the practical benefit is very low, and the effort and confusion is high.

The only way I could see this happening in Haskell is some hypothetical pragma DependendHaskellSyntax, which would imply a larger number of syntactical changes that actually make writing future dependent Haskell programs simpler (unified syntax for type families and normal functions, a single name space, etc.) If, as part of that, it is deemed beneficial to signal this change more prominently by also changing :: to :, then yes, maybe.

But on its own – thanks for asking, but no.

@halfaya
Copy link
Author

halfaya commented Apr 2, 2018

Since @goldfirere and @nomeata are against the proposal and are on the committee I suppose there is no hope, but again let me say that the proposal was serious, and I disagree with the objections "expensive" and "weight and complexity". As I tried to point out in the proposal, adding an extension to allow users to reverse the colon convention on a per-file basis is extremely simple to do and also safe. I suppose the point is that Haskell already has enough extensions, and adding one more, even if simple and straightforward, just to fix a syntactic flaw is not justified. I do agree it would potentially add confusion in the short term (and perhaps for quite a while), and perhaps that alone is enough to reject it.

I well know the failure of attempts at uniformization, having grown up in the 70s when US schools tried to teach the metric system (the fatal flaw there was that you were never taught to think in metric, rather only how to mechanically convert between the two systems). Still I'm ever the optimist, and I do think it's worth trying to push for a much simpler change in something we have control over. If "colonectomy" can be bundled with a larger set of improvements in the future, I'm all for it.

@Ericson2314
Copy link
Contributor

I like the idea of a slew of opt-in breaking syntactic changes in conjunction with dependent Haskell in preparation for a Haskell 2025 that will also include language levels. I think each constituent change should also get its own extension. Yes, this is goofy, but I hope it kicks us down the slippery slope of rethinking old uninteresting warts with the language.

And don't forget that Rust is NCC too.

@goldfirere
Copy link
Contributor

I'm in full agreement with @nomeata's point about a raft of changes all at once. I almost wrote that myself, but decided not to. And, by "full agreement", I mean that I fully agree with the comment there about "yes, maybe" -- I'm fully open to the idea of possibly supporting such a thing.

@chessai
Copy link

chessai commented Apr 2, 2018

April 1st turned out to be really bad timing for this proposal. I couldn't tell that certain comments were jokes.

@cgibbard
Copy link
Contributor

cgibbard commented Apr 2, 2018

April 1st was the only acceptable timing for this proposal imo.

@AntC2
Copy link
Contributor

AntC2 commented Apr 3, 2018

April 1st was the only acceptable timing

Indeed. My comment above was on the basis it was still April 1st in Glasgow/GMT (I forgot about daylight saving); and that @halfaya was engaged in some sort of double-bluff.

Like all spoofs, it had to have some sort of credibility in order to 'bite'. And it was an opportunity to vent/bikeshed about my least-favourite bits of syntax. If anybody took me seriously, I apologise and (in any case) withdraw.

@knupfer
Copy link

knupfer commented Apr 3, 2018

This could be implemented as a preprocessor, so we wouldn't need an extension (for now) and even older ghcs could use it.

@ivan-m
Copy link

ivan-m commented Apr 4, 2018

Unlike seemingly most others here, I like the fact that we have :: in type signatures rather than : as it stands out more. Maybe it's just the fact that I'm used to it, but I find that it helps differentiate the type signature better with the extra symbol (especially when it's attached to a point-free function definition).

@akhra
Copy link

akhra commented Apr 4, 2018

I have to chime in with @ivan-m here. In addition, I'm very happy to have single-character list deconstruction. (And construction, but that's really the lesser concern.)

@AntC2
Copy link
Contributor

AntC2 commented Apr 4, 2018

What does annoy me about list deconstruction is that you use [ ... ] most places for lists (including in type sigatures) but then have to switch to : for some de/constructions. That makes pattern matching look inconsistent. Consider

x = []                 -- construct empty list
x = [5, 6, 7, 8]       -- construct finite size list
x = [5 .. 8]           -- same
x = [5, 7 .. ]         -- construct infinite list

f [] = ...             -- deconstruct empty list
f [x, y, z, w] = ...   -- deconstruct finite size list
f (x: xs) = ...        -- deconstruct indefinite size list; where did the [ ... , ... ] go?

How about

f [] = ...
f [x, ..] = ...         -- pattern match the head, not currently legal syntax
f [x, xs@..]  = ...     -- as-pattern for the tail of the list
map g [] = []
map g [x, xs@..] = [g x, .. map g xs ]

IOW

(:) x xs = [x, .. xs]

@akhra
Copy link

akhra commented Apr 5, 2018

That's an interesting idea. I'm somewhere around +0.75 on it... I'm nervous that []'s special-cased syntax is going to turn out to have been a subtly terrible idea in general one day. But since we have it, this seems like a perfectly sensible addition. Worth making a separate proposal for it IMO.

One case that it may not be able to handle, which I actually wrote earlier this week while prototyping an idea:

xyzs@(x:xs@(y:ys@(z:zs)))

@AntC2
Copy link
Contributor

AntC2 commented Apr 5, 2018

Fair point. Note even in H98 you can write multiple as-patterns for the same component like

f (x: xs@foo@bar) = ...   -- xs is the same as foo, is the same as bar

And there's an extension about to land for pattern synonyms that allows more than a bare name to the left of @. So if we have in patterns

(x : xs@foo ) <===> [x, xs@foo@.. ]

Then this would follow that logic (just unwind from the inside out):

f xyzs@[x, xs@[y, ys@[z, zs@.. ]@.. ]@.. ] = ...

The presence of the comma followed by .. means it can't be syntactically confused with a double-nested list. OTOH even if the compiler can parse that, my head is hurting.

EDIT: added 'comma followed by' above in response to @tejon below. This should be valid, and is probably a more common use case than tejon's monster, and reads smoothly:

f xyzs@[x, y, z, zs@.. ] = ...

The rule is: inside [ ..., ..., .. ] (whether deconstructing or constructing), .. must be preceded by at least one , and must be at the end of the list. (We're trying to mimic : syntax, so there must be at least one element to the left of the ,, with the .. representing the tail.) All current syntax must be supported unchanged.

@akhra
Copy link

akhra commented Apr 5, 2018

The presence of the .. means it can't be syntactically confused with a double-nested list.

instance Enum a => Enum [a] where
  fromEnum = fromEnum . head
  toEnum n = [toEnum n ..]

foo = [[0..] ..] 
bar = join . drop 3 $ foo
baz = take 2 bar
-- bar = [4, 5]

I may or may not have cried a little while verifying that this works, but legal is legal.

@AntC2
Copy link
Contributor

AntC2 commented Apr 5, 2018

You should be arraigned for cruelty to lists ;-)

I think that's not a counter-example. (There's no ,.) I clarified my response above.

We should both be arraigned for hijacking @halfaya's proposal.

@aloiscochard
Copy link

aloiscochard commented Apr 5, 2018

I'm opposed to this proposal.

The benefit it brings are very low and arguably subjective, the cost OTOH is extremely high.

Even as an opt-in extension, I am still skeptical it would be really used in practice.

@ocharles
Copy link

ocharles commented Apr 5, 2018

I've always thought Haskell had too much syntax, but removing a single colon isn't quite what I meant.

@nomeata nomeata added the Dormant The proposal is not being actively discussed, but can be revived label May 5, 2018
@nomeata
Copy link
Contributor

nomeata commented May 5, 2018

Thing have become quiet here. @halfaya, do you still want to go forward with this or can we close it?

@halfaya
Copy link
Author

halfaya commented May 5, 2018

It sounds like there is no hope of it succeeding, so go ahead and close it.

@nomeata
Copy link
Contributor

nomeata commented May 5, 2018

Ok. Nevertheless, thanks for your contribution! (Most of my proposals don't get submitted either :-))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Dormant The proposal is not being actively discussed, but can be revived
Development

Successfully merging this pull request may close these issues.