Shouldn’t the syntax for type annotation be :: instead of : ?
Advantages of ::
Advantages of :
In Elm, a single colon : is used to separate declaration name from type annotation. Since Roc takes a lot of inspiration from Elm, and wants to be similar and easy to learn for people who already know Elm, chances are that this is the origin and reason behind the single colon in Roc, even if it is different from Haskell. I don't know why Elm decided to deviate from Haskell there though. Someone who knows Czaplicki may be able to answer that.
Advantages of :
2. Same as elm (the parent language of roc), typescript, go and scala
Andrew C said:
- I like that the type annotation is the same as the record field, it means that I can paste the type of a record and edit it to the values quickly, something that I find myself doing a lot in elm.
Oh I just meant the outer one, so e.g. using :: would be
amy :: { firstName : Str, lastName : Str }
amy = { firstName: "Amy", lastName: "Lee" }
Josh said:
Advantages of :
- Fewer keypresses/characters to get the job done :big_smile:
This is something that you'll type _a lot_, so this adds up. Normally syntax / keystrokes issues aren't worth worrying about too much, but if you multiply that little bit of effort times every single function ever defined in Roc, it begins to matter.
I vaguely remember seeing something a long time ago about this being the reason for Elm using : for types and :: for the rarely-used cons operator, which is opposite of Haskell.
Josh said:
Oh I just meant the outer one, so e.g. using :: would be
amy :: { firstName : Str, lastName : Str } amy = { firstName: "Amy", lastName: "Lee" }
Wouldn't that be really confusing? How do you remember whether you're supposed to use :: or : for a type? What about records inside records? I'm not keen on that mix, personally.
so as I understand it, Robin Milner used : in the original ML, which is what Standard ML and OCaml used too (and later Elm, Idris, and now Roc).
Miranda used :: instead. As I understand it, the motivation was to free up : for the cons operator, with the idea being that Miranda was very focused on laziness and had inferred types anyway, so the expectation was that people would be writing cons far more often than writing type annotations.
Haskell, being a direct descendant of Miranda, kept this - presumably because it's what everyone on the Haskell Committee was already familiar with. PureScript later kept it because (I assume, although I've never asked him directly) Phil was used to it from Haskell.
in that historical context, it seems like :: for types ended up being based on an expectation that turned out not to be true for the languages after Miranda (all of which write type annotations far more often than cons!) so I think it makes sense to stick with the original : for types :big_smile:
Delightful to have a little functional programming history, thank you! Miranda heavily inspired Orwell, the first functional programming language I learned before I switched to Gofer for the Eq and Ord type classes that made our printed fat easier to write, and later HUGS and eventually Haskell itself after it adopted type classes. I was surprised when elm (which does not have type classes) became my favourite programming language.
Roc has the potential to take over. As soon as there's a widows GUI program platform, it'll probably win. What you said, @Richard Feldman, in a recent podcast about Electron and Tauri being in a way objectionable because you're turning your gui into a document only to turn it back into a gui resonated with me.
I can't wait until I can write a gui using functional programming (with the elm architecture) but then _not_ have to write the IO end in another language for speed.
At the moment it's tempting to think that Tauri wouldn't need a very thick wrapper to become a roc platform, but having it sit on top of gtk or wx or some other desktop ui framework or something new and more functional is the dream.
I'm very excited for a viable Electron alternative in Roc! :smiley:
definitely a big project, but I think the payoff would be very much worth the effort
Current:
amy = { firstName : "Amy", lastName : "Lee" }
amy : { firstName : Str, lastName : Str }
Elm:
amy = { firstName = "Amy", lastName = "Lee" }
amy : { firstName : Str, lastName : Str }
Proposed:
amy = { firstName : "Amy", lastName : "Lee" }
amy :: { firstName : Str, lastName : Str }
IMHO the Elm approach is also nice, but the proposed change makes more sense for how Roc does other things like default record fields and opaque types...
\{ table = height, width, title? "oak", -> [...] #function accepting record with defaulted fields
table :: { height : Pixels, width : Pixels, title ? Str, -> [...] #and its type, proposed
Username := { firstName : Str, lastName : Str } #opaque type
So the operators for working with defs are = := :: and the operators for working with records are { } ? :
You'd never have to explain : being an oddball, both connecting a record key and value, and also annotating a def with a non-opaque type.
Interesting. Always surprising to see what people find odd or to have more friction. To me, :: just makes me think of templates and submodule selection. Nothing for type definitions. Just coming from different contexts.
What are the theoretically gains of the new syntax? Just not needing to explain : is used both in record definitions and record creation....oh, and type definition.
So instead of having 3 uses, we make the symbols distinct, but use more symbols?
Side thought, one potential gain of using = for record assignment is that it will make the record backpassing related syntax look more natural.... probably.
The only thing I don't like (although such a minor thing) is that : is used for type annotations inside a record and setting the value of a field in a record. = is much more intuitive, it just feels like the right symbol for the operation being done.
My background is mainly JS. I figure it would be the same for a lot of people. Having record field assignment be : makes it nice and comfy for a lot of people. Plus, I can always dbg print my records and copy-paste the result to a website / app that expects json, but allows the relaxed, javascript source code styled form as well with no " -s around the keys. I know it will be platform depended, but I think most of them will stick to the style that the source code is written in.
I haven't done any functional programming before, but : both for the type defs and the field assignement did't confuse me at all. Alas, typescript did that to me. Lots of :-s there.
when i encounter an exciting new minimalist language, i've got to bike shed any syntax nits right away. If and when it takes over the world, it'll clearly be too late to change such things, and then i'll be stuck with my regrets for not having said anything earlier. :laughing:
In my mind, : for both types and record fields is consistent, though I think I read : as "is a"
Last updated: Jun 16 2026 at 16:19 UTC