Rename: ADT => enum

727 views
Skip to first unread message

Evan Czaplicki

unread,
Aug 28, 2014, 4:39:40 PM8/28/14
to elm-d...@googlegroups.com
So Laszlo shared this idea with me today: what if data was renamed to enum? And what if instead of saying algebraic data types we said enums?

enum Maybe a = Just a | Nothing

The idea is that it's type where you can enumerate all the possible values. If you didn't enumerate it, you can't use it. I think this captures the fact that ADTs are "closed" in a really concise way.

This also builds off people's existing knowledge of enums. It lets us say, "Elm does enums right" or "it's like Java enums but way more useful." Immediately people know what it is and see that it's an improvement over what they are using.

This terminology is also used by Haxe and Swift. I'd like to look into both a bit more. It looks like Swift does some weird / possibly useful stuff.

What do you think of this? Since 0.13 has slipped a couple weeks I was thinking this should be in there.


Notes on context and motivation:

We just had a thread about how to nicely represent many different things with the same type. Coming from an OO language, the intuitive thing is to use records. They seem like objects and they say they are extensible, but they don't fill the same role exactly. The name "algebraic data type" in no way indicates that it is going to solve this problem.

Along with this other thread where I got concerned about alienating and bizarre names, I started thinking about what we could call ADTs instead. Weirdly, Laszlo brought it up right after that :)

As I thought through this idea, I also realized that I could not explain why it is called an algebraic data type. What is the algebraic part? Wikipedia did not have the answer, nor do I remember it from any university class or book or anything. I just accepted that that was the name of it.


John Mayer

unread,
Aug 28, 2014, 4:40:24 PM8/28/14
to elm-d...@googlegroups.com

Also used by Rust. +1

--
You received this message because you are subscribed to the Google Groups "Elm Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elm-discuss...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Janis Voigtländer

unread,
Aug 28, 2014, 4:45:33 PM8/28/14
to elm-d...@googlegroups.com
> As I thought through this idea, I also realized that I could not
> explain why it is called an algebraic data type. What is the
> algebraic part? Wikipedia did not have the answer, nor do I remember
> it from any university class or book or anything. I just accepted
> that that was the name of it.



Evan Czaplicki

unread,
Aug 28, 2014, 4:53:09 PM8/28/14
to elm-d...@googlegroups.com
Janis, makes sense, thanks :)

Joey Eremondi

unread,
Aug 28, 2014, 5:55:01 PM8/28/14
to elm-d...@googlegroups.com
I'm not a fan, because to me enum is very different. The idea of an enum that can take arguments doesn't make sense to me. They're called enum because you can enumerate all values.

So having something like

    enum Day = Monday | Tuesday | ... | Sunday

make sense, since you can enumerate all the days.
But it doesn't match something like this:

    enum TextureInfo = SolidColor Color | Textured Texture

I can't enumerate all possible values of this type.

Don't get me wrong, I'm not against having a different name. I'd even be okay if enum was a special case that had no argument. (Maybe there are some cool optimizations that come with this, I don't know.) But the concepts aren't the same. Enums feel more like constants with nice names, where you know how many of them there are. ADTs are more powerful.

John Mayer

unread,
Aug 28, 2014, 6:02:05 PM8/28/14
to elm-d...@googlegroups.com

> They're called enum because you can enumerate all values.

I don't follow your argument, you seem to be saying that "enumerate" is not a good word for describing the act of defining a closed, finite set of constructors?

John Mayer

unread,
Aug 28, 2014, 6:03:36 PM8/28/14
to elm-d...@googlegroups.com

Said differently: Who ever said it's about enumerating values; it's just a quirk of Java that enums are all arity zero.

Joey Eremondi

unread,
Aug 28, 2014, 6:21:24 PM8/28/14
to elm-d...@googlegroups.com, john.p....@gmail.com
Yeah, what I'm saying that I think enum implies arity 0, or at least best matches the concept of it.

I'm wondering if this is one of those things where if we're similar, but not the same as C-like languages, with our nomenclature, if it will make it more confusing?

But if we make it very clear that what's enumerable is the constructors, and not the values of the type, then it could work, I hadn't thought of it from that angle.

John Mayer

unread,
Aug 28, 2014, 6:24:52 PM8/28/14
to elm-d...@googlegroups.com

Since I've been doing a lot of rust recently, this was a good explanation:

http://doc.rust-lang.org/tutorial.html#data-structures

Paul Chiusano

unread,
Aug 28, 2014, 6:56:43 PM8/28/14
to elm-d...@googlegroups.com, john.p....@gmail.com
Please, no!!

How about just call it a 'data type'? The 'algebraic' is just a bit of jargon that doesn't really add much. (Okay, there are some deep connections, but no need to mention that if you don't want.) That's all it is - a data type. That it happens to be represented as a sum of products is not something that needs to be part of the name.

Also, IMO 'enum' is a poor choice for the keyword, precisely because data types in Elm are *not* the same thing as enums in, say, Java. Using a different keyword is a clue to the learner that they should be on the lookout for new concepts. (Moreover, for people who are already familiar with the concept, using the same keyword ties it to their existing knowledge.) I'd save the "enums on steroids" descriptions for informal documentation, blog posts, and the like.

Paul

Ray Racine

unread,
Aug 28, 2014, 7:17:40 PM8/28/14
to elm-discuss
What Paul said.  I got the whole we want to make Elm as non-scary as possible for the standard Web developer, but I think this is a case of the pendulum over swinging the other way.  An ADT is not the same thing as historical enums as used in programming languages for decades and calling them enums doesn't make them so.  It would be less confusing to come up with a whole new name for them ... maybe FuzzyWuzzy or something ...

John Mayer

unread,
Aug 28, 2014, 7:45:10 PM8/28/14
to elm-d...@googlegroups.com
Regarding "don't dumb it down", I don't think we're losing any conceptual complexity, and enum is a hell-of-a-lot-more informative keyword than data, not to mention "data" is a much more useful identifier that we can free up. Doing this wouldn't be to dumb it down, but rather to elicit the recall of a familiar concept, namely, that of the enumeration of a closed set which is often used in patterns such as the switch or case statement.

Regarding "they're not real enums", I think that we (the larger we, as in all modern programmers) get to define what our terms mean and break tradition. With the recent trend of modern languages of having associated data in enums, I think we have the opportunity to voice an opinion from the functional programming side of the fence of: "Yeah, good idea! Enums aren't just tags, they're tagged unions! (We were right all along!) ". I honestly wouldn't be surprised if, say, Java 8 or the next C# decided to add associated values to their enums.

Ray Racine

unread,
Aug 28, 2014, 9:38:29 PM8/28/14
to elm-discuss
Our point of departure stems for the very root of "what is an enum" and their semantics and use in traditional and modern languages.  Of course you can always take some traditional meaning and overload it with some new definition but unless the advantage is distinct versus the cost of confusion I don't see the value.   There are so many, IMHO, more important things for Elm to embrace or prioritize then gratuitous changes on par with data Maybe a = Just a | Nothing vs. enum Maybe a = Just a | Nothing.  Is anything truly gained here?

Just the other day I was mass search and replacing a goodly number of files to deal with div -> // and (.) -> <<.    At some point for Elm these things are become dog chasing tail in a spin dizzy.  That said, ideally I'd like to see these sort of things collected together and get them all said and done in one maneuver and freeze the core.  Its just as hard for someone to adopt Elm if their impression is that people are still toying around with the languages basic syntax and core prelude definitions.

Max Goldstein

unread,
Aug 28, 2014, 10:11:42 PM8/28/14
to elm-d...@googlegroups.com
I see Ray's point about the need for stability but I don't want Elm to get too tied down yet. As has been mentioned, Swift and Rust's concepts of enums have parameters, and it's strictly more powerful that not having parameters. ("They're not real enums" indeed.) No one is criticizing their case statements for not having automatic fall-through; the point being that we shouldn't bind ourselves to languages patterns from the 70s, whether C or ML. (C actually has two "sum types", enums and unions, and I would argue that they should be combined as we are doing.) So yes, I support this change.

At the risk of pointing out what you already know, ADTs/enums share a reciprocal relationship. Sum types can be created using one of many types, but consumers must be ready to handle one of any type. "Product types" (Elm records, C structs) require terms of all types at creation, but consumers have their choice of type to extract.

Ray Racine

unread,
Aug 28, 2014, 10:29:38 PM8/28/14
to elm-discuss
In many (most) languages an Enum type entails some kind of ordinality.  pred, succ comparison, partial ordering semantics and list/for comprehension ability etc.  Witness Scala's case classes as ADTs, yet, found the need to ordinal value Enums as well.  If anything i'd like to see ADTs remain as 'data ...'  reserve enums for the future to be added as "sort of like ADTs, but with a type -> Int association'.  To me (and I know this is not true in every language) it ain't an enum without an associated ordinal relation on the type values.


On Thu, Aug 28, 2014 at 10:11 PM, Max Goldstein <maxgol...@gmail.com> wrote:
I see Ray's point about the need for stability but I don't want Elm to get too tied down yet. As has been mentioned, Swift and Rust's concepts of enums have parameters, and it's strictly more powerful that not having parameters. ("They're not real enums" indeed.) No one is criticizing their case statements for not having automatic fall-through; the point being that we shouldn't bind ourselves to languages patterns from the 70s, whether C or ML. (C actually has two "sum types", enums and unions, and I would argue that they should be combined as we are doing.) So yes, I support this change.

At the risk of pointing out what you already know, ADTs/enums share a reciprocal relationship. Sum types can be created using one of many types, but consumers must be ready to handle one of any type. "Product types" (Elm records, C structs) require terms of all types at creation, but consumers have their choice of type to extract.

--

Paul Chiusano

unread,
Aug 28, 2014, 10:40:28 PM8/28/14
to elm-d...@googlegroups.com
Another rather unscientific data point: I was actually trying to explain this issue to my wife (who is not a programmer). Her response: "what is 'enum'"? At which point it dawned on me that the term 'enum' is totally meaningless programmer jargon - unless you are a programmer, you are not even going to know what 'enum' is short for. 'data', on the other hand, has a colloquial meaning which happens to coincide very well with what the keyword is doing - describing some data! 

'enum' is yet another example of programmers choosing dumb abbreviations for things, in the same tradition as the `creat` system call, Haskell's `putStrLn` [1], Ruby `puts`, `printf`, etc.

The other thing that I (personally) dislike about 'enum' or 'enumeration' is that it is associated with the *act* of naming the elements of some collection. As in, I will now enumerate the numbers from 1 to 100. It puts the focus on the procedure, rather than on the thing being described. 'data' has a more declarative connotation - I am merely describing the possible forms of some data, in a declarative way, not giving a procedure. I guess this is somewhat subjective, though.

Also, I second what Ray said - I think it kind of sends a bad message when breaking changes are casually introduced (or even suggested) at the last minute for a release, *especially* when the change is more a matter of personal taste and doesn't add any new functionality or features that benefit users.

Paul :)

[1]: Paul Phillips, one of the Scala developers, has a funny tweet about this - https://twitter.com/extempore2/status/446312485977468928

Eric West

unread,
Aug 28, 2014, 10:48:51 PM8/28/14
to elm-d...@googlegroups.com
Just chiming in to say I REALLY like it. The little bit I've used Rust's enums, they were intuitive. Elm has been wonderful for me precisely because Evan has used familiar language, and been so careful to separate concepts from the language previously used to describe those concepts. And that he's been so brilliant in tying new concepts in to old ideas I'm already very comfortable with. I've tried learning Haskell half a dozen times, and everything about that community constantly screams at me: "You don't belong here. You don't know enough math. You don't have enough degrees. You aren't educated enough."  I'm actually well educated, but my degrees are in philosophy and literature, I'm a professional programmer but entirely self-taught. I'm not one of those liberal arts people who take an obstinate pride in their innumeracy, but math as it was taught in school never clicked for me.  For most of my life, I was extremely interested in programming but always scared away by people who tried to make programming and math the same thing, despite many early successes as a child and teenager.

I've realized there are skills one can gain from doing lots of math that are useful in programming, but those skills are the same ones I learned by doing formal logic in my philosophy courses.  The math itself, that I need to do to write a web server or layout a web page, even pretty low-level stuff like writing a tool to extract EXIF data from images in binary format, rarely involves pure math any harder than the stuff I learned in seventh or eighth grade. Instead, I work in the realm of concepts. Concepts that can be understood via a mathematical model, I'm sure, but concepts that can be understood using other logically consistent model. I know there are realms of programming where numbers need to be manipulated with high-level math. But for most of what we do, it's not math we draw on but formal logic, of which math is one expression.

I finally realized this a few years ago, and began teaching myself programming. I now do it professionally. But every time I tried to follow my interest in functional programming, I found myself faced with a community that made it very clear (with the language they used, with the highly mathematical examples (every damn intro to Haskell I ever read started with either a Factorial function or a Fibonacci one. And yet never in my job have I ever needed a function to compute either of those things), with the sense of condescension I felt every time anyone tried to suggest as much. "Well, if you cared about the quality of your programs, you'd get over it and just learn this stuff. You must like writing bugs."

Elm feels completely different. This has been a really long, off-topic rant from somebody who isn't active in here often, but only to say once again 2 thumbs way up on this one.

Max Goldstein

unread,
Aug 28, 2014, 10:58:24 PM8/28/14
to elm-d...@googlegroups.com
In many (most) languages an Enum type entails some kind of ordinality.  ... To me (and I know this is not true in every language) it ain't an enum without an associated ordinal relation on the type values.

Well, you're in luck: have a look at this other thread where I propose making ADTs/enums comparable. The one catch is that all parameter types also have to be comparable, but we already have recursive comparable types that are statically inferable. I can see succ and pred being useful in some cases, but (1) how do they behave when the value constructor takes parameters (2) what happens when you try to take the successor of the last element, does it runtime error, or are we stuck with Maybes? So, I'm skeptical of some succ and pred, but supportive of pairwise comparison.

As to Paul's point on enum being "totally meaningless programmer jargon" - well, I'd rather have a term that means nothing than a term that means the wrong thing. ADTs are not data, they are structure for data, and it would be helpful to have the identifier freed up. "Data" is an extremely nebulous concept; is your data tabular, hierarchal, numeric? But "enum" conveys a fixed number of forms; in the U.S. the federal government's powers are "enumerated", meaning they are listed explicitly and anything it is not specifically able to do it is not able to do. Similarly, an enum's possible forms are listed and it can never take a form other than one of those. And if it's jargon, I'd prefer jargon used by the imperative languages whose users we are trying to steal than by Haskell and theorists.

Yeah, we're still messing with the language. If you can't handle that, either don't upgrade or don't use Elm. We're very far away from 1.0.

Eric: thanks for chiming in. You're exactly the type of person Evan is working very hard to attract.


Paul Chiusano

unread,
Aug 28, 2014, 11:48:04 PM8/28/14
to elm-d...@googlegroups.com
Eric, first of all, it is awesome that Elm has gotten you interested in this stuff! I mean that sincerely.

Now, just to clarify, are you saying that you are vastly in favor of changing the keyword "data" to the keyword "enum"? Or just that you like the idea of informally calling them "enums" rather than "algebraic data types"? (Or are you just saying you like Evan's general philosophy of really trying to make the language as accessible as possible, have a friendly culture, etc.)

Paul :)

Paul Chiusano

unread,
Aug 29, 2014, 12:04:45 AM8/29/14
to elm-d...@googlegroups.com
As to Paul's point on enum being "totally meaningless programmer jargon" - well, I'd rather have a term that means nothing than a term that means the wrong thing...

Okay, I think we've both made our case at this point. Even though I disagree, I understand where you are coming from. :) I'll try to keep quiet for the rest of this thread, and Evan can decide what he'd like to do.

Paul :)

Eric West

unread,
Aug 29, 2014, 12:16:25 AM8/29/14
to elm-d...@googlegroups.com
Yes I like the idea of changing the keyword data to enum. I read his initial post in the thread and it was like a light bulb going off for me it just made so much sense, from my perspective. As someone said previously, they aren't "data" they are a structure for it. But they are enumerable, in that they are a fixed structure. When I first tried to figure out what the keyword data was for, and found out I use that to create an Algebraic Data Type, I had zero idea what the hell that statement even meant. Am I doing some sort of mathematical analysis of the data in my json with this? Enum gets me that little bit closer to what it really is, and even if these enums differ from the ones I know from java in important ways, at least I'm not struggling to push through terminology that immediately makes my eyes want to glaze over. I don't know that enum is the perfect term here, but it makes more sense than "data" does, and it has some precedence in other emerging languages as others have pointed out. Finally, yes, as much as I wrote what I said in support of the idea on the table in the thread, my post was also intended to encourage this community to continue on in the direction it has taken, and to thank Evan for working so hard to lead the community that way.

Alex Neslusan

unread,
Aug 29, 2014, 12:26:39 AM8/29/14
to elm-d...@googlegroups.com
A slight aside building on that, but that's what people mean when they say things like "zippers are the derivative of a data type" http://en.wikipedia.org/wiki/Zipper_(data_structure)#Zipper_contexts_and_differentiation

Anyway, I think this is probably a good change. 

Janis Voigtländer

unread,
Aug 29, 2014, 1:50:49 AM8/29/14
to elm-d...@googlegroups.com
Even after all the discussion, I don't really mind whether the keyword is data or enum. But since the discussion was around what concepts programmers seem to tend to associate with "enumeration", and around what other modern languages do/have in terms of "improved enums", two things that might be worth considering:

1. Recursion. I'm surprised this was not mentioned at all. For me, that's what makes "algebraic data types" interesting and going beyond "fanciful variant types". Any thoughts on how well the ability to define data/enum types in Elm recursively goes with what "imperative programmers" associate with the concept of enumerations?

2. "Just fanciful constants". For imperative programmers there seems to be the concept of "enums are for naming constants". Integer constants in C, and potentially other types of constants in more modern languages.

Rust and Swift were mentioned as modern languages which also use enum as a keyword, for something more powerful than C-like enums. So I briefly looked around.

After five minutes of googling for Rust and enums, my impression is that Rust enums do not support recursive definition out of the box, but can be used for recursive structures via indirection (like linked lists in C using pointer types in a record).

After five minutes of googling for Swift and enums, my impression ist that Swift enums do not support recursive definition either (though probably one can achieve recursion using the same indirection trick). Also, the way enums are promoted in Swift seems to be geared a lot towards the "you can give names to Int or other constants" concept, plus "but in Swift you can do a bit more with them". That's both from the Apple developer page introducing enums and a few blog posts. As a typical example, the sentence "I’m used to thinking of enums exactly as that – enums where I can specify values that are mapped into number." in one such post (which then goes off to show that Swift enums enable more than that, namely storing stuff in the variants).

No idea how much this contributes to the discussion/decision, but there you have it. :)

For me, the recursion aspect would be the more relevant one. Is the fact that one can define data (or then, enum) types recursively in Elm a too big deviation from what the imperative programmers expect/know of enums (even in modern languages like Rust/Swift)? A deviation so big that using the same keyword would create more confusion than guidance for those programmers?




2014-08-28 22:39 GMT+02:00 Evan Czaplicki <eva...@gmail.com>:

Janis Voigtländer

unread,
Aug 29, 2014, 2:09:07 AM8/29/14
to elm-d...@googlegroups.com
Ha, just to make an alternative proposal that would address the concerns a) that it would be nice to free data as an identifier, and b) that enum feels not very declarative (in one of the messages in the discussion):

What about renaming data to type, and type to something else (e.g., alias, which is more accurate anyway)?





2014-08-28 22:39 GMT+02:00 Evan Czaplicki <eva...@gmail.com>:

Brian Slesinsky

unread,
Aug 29, 2014, 3:16:04 AM8/29/14
to elm-d...@googlegroups.com
I think enum is okay. Enums have always been associated with switch statements and extending them to full pattern matching seems natural.

Jeff Smits

unread,
Aug 29, 2014, 3:23:54 AM8/29/14
to elm-discuss
Enum looks a little strange with recursive data types that Janis mentioned. But Haxe allows recursive enums too. It's not a big stretch. And algebraic data type looks very foreign next to most of the more friendly terms used in Elm.
So I vote for changing ADT to enumeration and data to enum as proposed.

On Fri, Aug 29, 2014 at 9:16 AM, Brian Slesinsky <bsles...@gmail.com> wrote:
I think enum is okay. Enums have always been associated with switch statements and extending them to full pattern matching seems natural.

John Nilsson

unread,
Aug 29, 2014, 4:46:17 AM8/29/14
to elm-d...@googlegroups.com
Besides enums I think ADT also looks a lot like interfaces in languages like Java. Interfaces in the sense that it's a type stipulating the contraints on which an object implementing dynamic dispatch as a response to messages must support. So it could also make sense to just call it interface.

Unlike message dispatching in Java, ADTs support first class messages as 'data'. So the same type can be used to reason about message passing in the more distributed and asynchronous style of the actor model. Which I guess can come in handy for a language focusing on FRP.

Another view is that and ADT types the input to an interpreter. A function dispatching on that type would be the interpreter. It is true though that ADTs, don't stipulate the type returned from dispatching on the values. I'm not sure if there is any such type system, but it seems to me that the value of being _statically_ enumerable is that the type system should also be able to not only support function types like ADT1 -> ADT2 but also enumerate the cases one by one in the type to directly match how an interface type in Java is both enumerable and encodes the return type for each case.

The benefit of ADTs vs interfaces is exactly that they aren't complete though. This means that in theory we should be able to have language constructs allowing us to compose interfaces instead of declaring them. I'm seeing something akin to extensible records, but for extensible ADTs and extensible interpreters, this then would relate ADTs to subtyping in the same manner as extensible records relates to subtyping.

It is possible that records are just a special case of the above. A type for an interpreter of all arity 0 input is exactly the same as a record type no?

BR,
John




On Thu, Aug 28, 2014 at 10:39 PM, Evan Czaplicki <eva...@gmail.com> wrote:
So Laszlo shared this idea with me today: what if data was renamed to enum? And what if instead of saying algebraic data types we said enums?

enum Maybe a = Just a | Nothing

The idea is that it's type where you can enumerate all the possible values. If you didn't enumerate it, you can't use it. I think this captures the fact that ADTs are "closed" in a really concise way.

This also builds off people's existing knowledge of enums. It lets us say, "Elm does enums right" or "it's like Java enums but way more useful." Immediately people know what it is and see that it's an improvement over what they are using.

This terminology is also used by Haxe and Swift. I'd like to look into both a bit more. It looks like Swift does some weird / possibly useful stuff.

What do you think of this? Since 0.13 has slipped a couple weeks I was thinking this should be in there.


Notes on context and motivation:

We just had a thread about how to nicely represent many different things with the same type. Coming from an OO language, the intuitive thing is to use records. They seem like objects and they say they are extensible, but they don't fill the same role exactly. The name "algebraic data type" in no way indicates that it is going to solve this problem.

Along with this other thread where I got concerned about alienating and bizarre names, I started thinking about what we could call ADTs instead. Weirdly, Laszlo brought it up right after that :)

As I thought through this idea, I also realized that I could not explain why it is called an algebraic data type. What is the algebraic part? Wikipedia did not have the answer, nor do I remember it from any university class or book or anything. I just accepted that that was the name of it.


John Nilsson

unread,
Aug 29, 2014, 4:56:54 AM8/29/14
to elm-d...@googlegroups.com
Not sure how it relates to the discussion, but it seems relevant. General recursion in this manner will probably change into something different pretty soon anyway

It seems to me that we are heading into the direction of better separation of data and codata, and with that recursion and corecursion. This all seems especially relevant to elm which already does this kind of separation in some ways.


BR,
John

Janis Voigtländer

unread,
Aug 29, 2014, 5:30:15 AM8/29/14
to elm-d...@googlegroups.com
*Not* something wanted for Elm, I think, but: If you are interested in more compositional (subtyping-like) dealing with ADTs, the Data types à la carte approach is for you. (Very popular in Haskell research land, but requiring all the "overly fancy types" stuff that Elm tries to avoid for a while longer at least.)

Janis Voigtländer

unread,
Aug 29, 2014, 5:35:44 AM8/29/14
to elm-d...@googlegroups.com
About the "pretty soon", hmm. Discussion of data vs. codata, and about possible language-level distinction between them, has been around for decades. There is renewed interest in them in the last few years due to the advent of Epigram, Agda, and the like (where the distinction makes more sense due to totality constraints, and is more needed as well). But for Haskell, for example, it's not going to happen. General recursion is there to stay.

UEHARA Junji

unread,
Aug 29, 2014, 5:52:20 AM8/29/14
to elm-d...@googlegroups.com
What about renaming data to type, and type to something else (e.g., alias, which is more accurate anyway)?

I thought same thing. but ADT is not covers following types in Elm.

- extensible record type
- tuple type

Tuples might be regarded as an ADT type with type constructor(,,),(,,,,).

But extensible record can not be regarded as ADT, isn't it? or it is a special form of ADT?

If not, IMHO, I thought 'type' is too general for the keyword.

--
UEHARA Junji

Evan Czaplicki

unread,
Aug 29, 2014, 5:57:03 AM8/29/14
to elm-d...@googlegroups.com
I really love this community! Seeing people with diverse backgrounds talking through stuff is really amazing and always grows my perspective :)

Andrew just pointed out that Kotlin also has enums that are equivalent to ADTs. I suspect you have to do some extra work to make Rust ADTs recursive because they make memory management explicit and as as a result, recursion requires some programmer choices. Not sure if it's the same in Swift.

I had a legitimate brain storm about this last night, like a stormy brain. Ignoring the word algebraic, what is a data type? A type for data? Isn't that just a type? What if an ADT has a function in it? Is that thing still data? If functions are data, why be particular about the word in ADT? If functions are not data, is an ADT always an data type? What's the connection between data types and type-level values? Is it a type with data associated with it?

I got to a point where I couldn't believe I never questioned this term before given it seems to have so many holes.

Janis Voigtländer

unread,
Aug 29, 2014, 6:01:26 AM8/29/14
to elm-d...@googlegroups.com
Fair enough (type can currently be used to alias any type, including things that are not data or enum).

On the other hand, one could dispute the usefulness (or, if less radical, only the name) of the type keyword in its current role anyway.

The following is current Elm:

type Pos = (Int,Int)

twelve = 7+5

Why is this not the following instead, which would be simpler?

Pos = (Int,Int)

twelve = 7+5

That is, why is a keyword necessary to say that Pos = ... is a type definition? The lexical structure should be enough to determine that.

Janis Voigtländer

unread,
Aug 29, 2014, 6:10:58 AM8/29/14
to elm-d...@googlegroups.com
People use "algebraic data type" for all kinds of things, with or without function types. But there is precise terminology to delineate the cases if one wants to. Specifically, an algebraic data type is called "regular" if it does not contain embedded functions (in terms of the algebra, it means it consists only of sums and products, but specifically not of exponentials with non-constant exponent, which would correspond to arbitrary functions). There is also "polynomial", which is a further specialization of "regular". But people are sloppy, so I think they often say just "algebraic data type" for "regular/polynomial algebraic data type". That's maybe why such uncertainty can arise. ("Is it still an ADT if there are functions inside?" etc.)

Anyway, this is probably not something you want to factor into the choice of the keyword replacement for data.

Having seen some cases like Haxe etc. now, using enum seems fine to me.

Evan Czaplicki

unread,
Aug 29, 2014, 6:23:30 AM8/29/14
to elm-d...@googlegroups.com
Ray, I want to apologize for putting people through some big find-and-replace adventure with this release. I really do appreciate that that sucks.

That said, I believe really strongly that you must rip the bandaid off as soon as possible. There is no better time to change it than now. Or better yet, the previous release. Did you know that Elm strings used to be linked lists like in Haskell? I felt like changing it was a big decision, lots of code might break. It feels like weird trivia now: "did you know Elm strings used to be really silly? Why did I think that was a good idea?" The longer you wait, the more intractable this stuff becomes (e.g. Python and Java).

I see this kind of change as an investment in growing our community. We all pay the cost of messing with our code so that more people can read it and get excited about what they can do with Elm. If we can save an hour or a day or a week or a month of someone's time just by changing a keyword, I think that's pretty important. If we can use words that more fully communicate their meaning and value or get people excited, a 1 minute glance at some Elm blog post is more likely to turn into an advocate of Elm. Every blogger or company that talks publicly about getting excited about Elm and how Elm improves on existing stuff is a really big deal at this stage! If I knew more about marketing stuff, I might start talking about User Acquisition Funnels.

Evan Czaplicki

unread,
Aug 29, 2014, 6:30:53 AM8/29/14
to elm-d...@googlegroups.com
Janis, thanks for explaining regular vs polynomial vs exponential. I had not heard these terms before, but it makes things way more systematic and coherent for me :)

Janis Voigtländer

unread,
Aug 29, 2014, 6:33:14 AM8/29/14
to elm-d...@googlegroups.com
So, when it comes to keyword naming, why is type called type?

Okay,

type Pos = (Int,Int)

introduces a type.

But, by that reasoning,

enum Color = Red | Blue

also introduces a type, so shouldn't it then be

type enum Color = Red | Blue

instead?

Also, enum Color = ... is trying to tell us *what* kind of a type we are getting, namely an enumeration. But why, then, isn't type Pos = ... giving us similar useful information? Could it tell us more than that we are going to get a type? (Which kind of type? A record type? Or an enumeration? Or something else?) Apparently, it can't, because it *isn't* really *giving* us a type. It is only aliasing an existing type. But then, shouldn't the keyword reveal that information, rather than just being "type"?

So, instead of

enum Color = Red | Blue
type Pos = (Int,Int)

(or the same with data instead of enum), I think each of the following alternatives would be better:

1.
enum Color = Red | Blue
alias Pos = (Int,Int)

2.
type enum Color = Red | Blue
type alias Pos = (Int,Int)

3.
type enum Color = Red | Blue
type Pos = (Int,Int)

I actually prefer the first one. And it does free type as an identifier, which probably does come in handy more often than the identifier alias.

Janis Voigtländer

unread,
Aug 29, 2014, 6:40:06 AM8/29/14
to elm-d...@googlegroups.com
You're welcome. Though, now I think I may well have mixed up the precise meaning of "regular" and "polynomial". It might be exactly the other way round than I wrote in my previous email. Anyway, one of the two allows things like

data T = ... | C (Bool -> T) | ...

(i.e., functions with a constant type as domain, but not arbitrary functions), while the other does not even allow those kinds of functions, but only things like

data T = ... | C T T T | ...

The terminology comes from "polynomial functors" etc., and is heavily used in the data-type-generic programming literature for Haskell. They have techniques that work only for "regular algebraic data types", other techniques that work also for slightly stronger variaties of algebraic data types, etc. So they need language to distinguish between these different classes of types.

John Mayer

unread,
Aug 29, 2014, 6:43:36 AM8/29/14
to elm-d...@googlegroups.com

> That is, why is a keyword necessary to say that Pos = ... is a type definition? The lexical structure should be enough to determine that.

I think that this is worth exploring. We probably get it for free because type identifiers are capitalized.

Alexey Zlobin

unread,
Aug 29, 2014, 6:47:01 AM8/29/14
to elm-d...@googlegroups.com
Don't see any problem with `data` keyword. You write 'data' and then define a datatype. It's doesn't bring any useless associations. It's does more or less the same thing as in other similar languages.

As I understood the initial proposal it's 'algebraic' word what causes problems. So why don't get rid of it in docs rather than change syntax?

Renaming 'type' to 'alias' sounds more useful. It's doesn't really allow to define a type, but only introduces a new name.

Janis Voigtländer

unread,
Aug 29, 2014, 6:55:42 AM8/29/14
to elm-d...@googlegroups.com
A counter argument (to my own proposal): this can lead to confusing error messages. If I make a capitalization error, something I meant as a type definition might be read by the compiler as a value/function definition, and the outcome in terms of what the compiler reports may be not very helpful.

So it does make sense to use keywords to distinguish between definitions of values/functions and types. And since we are most often defining more values/functions than types in a program, we prefer to use keywords for type definitions. So, rather have

alias/type Pos = (Int,Int)

twelve = 7 + 5

than

Pos = (Int,Int)

value/function twelve = 7 + 5

Janis Voigtländer

unread,
Aug 29, 2014, 6:57:12 AM8/29/14
to elm-d...@googlegroups.com
But I do stand by my proposal that alias is the better keyword than type.

Evan Czaplicki

unread,
Aug 29, 2014, 7:07:21 AM8/29/14
to elm-d...@googlegroups.com
I agree that dropping the word type is intriguing, but I also feel that redundancy can be really helpful when skimming. I do like that it makes a more obvious connection between a type that takes arguments and a function that takes arguments.

Against type enum:
One thing I like about enum is that it does not commit to saying "we are defining a type". Defining an ADT creates both a type and a set of constructors. Having enum as a blanket name for this seems nice to me. "When you enumerate things, it creates a type and some constructors."

Other thoughts:
I have considered type alias before, but had some reservations because I wasn't sure if newtype was going to be a thing or not and didn't want to make . I'm pretty sure that optimization is safe to do on normal ADTs in Elm because of strictness, so I think it'd be unnecessary.

I think alias is a bit weird in that it is more general than we want. alias foo = bar is logically consistent, but we want this to only be about types.

I've also considered having a record keyword (like in Agda iirc), especially considering that record constructors are a thing in Elm.

I also wonder how this all fits with the type-directed macros proposal?

Daniël Heres

unread,
Aug 29, 2014, 7:41:17 AM8/29/14
to elm-d...@googlegroups.com
I don't like enum, because data types are not only about enumeration.

Another thought: what about using : for data types and = for a type alias? : helps to understand that you're talking about a type, and you can read = as "equal to".

Maybe a : Nothing | Just a

Color : Red | Blue

Pos = (Int, Int)
Daniël Heres

Janis Voigtländer

unread,
Aug 29, 2014, 7:48:38 AM8/29/14
to elm-d...@googlegroups.com
Good point about enum not only introducing a type.

About newtype, I also don't see need for their existence (in contrast to Haskell).

About alias foo = bar, yes, but my argument here would be that for values/functions we do not use keywords, since they are what we are binding more often (than types) in a program.

About alias generally, I had not thought about record types in that context. It is true that having a record system, one will probably use the keyword often in circumstances one would simply not have in Haskell, and in which (in Elm) the connotation of alias is not perfect. What do you mean by "record constructors"? Do you mean the type "constructor" Point in type Point = { x:Float, y:Float } ?

Maybe a special record keyword would indeed be better. Is there a clear syntactic or semantic distinction between a) current uses of type that would more appropriately be uses of record, and b) current uses of type that wouldn't meaningfully be uses of record, because they are really just aliasing of existing types?

About possible interactions with type-directed macros/deriving, good question. Here's a thing to consider: If you write

type Point = { x:Float, y:Float } deriving JSON

do you expect the JSON functionality to only be made available for values explicitly types as p : Point, or also for values q that just happen to be exactly records with exactly x and y fields of type Float (but with no nominal typing as Point)? If the latter, is this really going to work in the compiler? If the former, then type Point = ... deriving JSON will really introduce a new type, not just an alias. Since then the JSON functionality wouldn't apply to any old q : { x:Float, y:Float }, only to q : Point.

Evan Czaplicki

unread,
Aug 29, 2014, 8:26:07 AM8/29/14
to elm-d...@googlegroups.com
About alias generally, I had not thought about record types in that context. It is true that having a record system, one will probably use the keyword often in circumstances one would simply not have in Haskell, and in which (in Elm) the connotation of alias is not perfect. What do you mean by "record constructors"? Do you mean the type "constructor" Point in type Point = { x:Float, y:Float } ?
 
Yeah, the fact that such a declaration creates a function (Point : Float -> Float -> Point).

Maybe a special record keyword would indeed be better. Is there a clear syntactic or semantic distinction between a) current uses of type that would more appropriately be uses of record, and b) current uses of type that wouldn't meaningfully be uses of record, because they are really just aliasing of existing types?

The only difference is that creating a type alias for a record also produces a constructor.

One vague solution is to have something like this:

type Point = { x:Float, y:Float } deriving New

Point.New : Float -> Float -> Point

Where the deriving mechanism will give a static error if you try it on something that's not a record.

About possible interactions with type-directed macros/deriving, good question. Here's a thing to consider: If you write

type Point = { x:Float, y:Float } deriving JSON

do you expect the JSON functionality to only be made available for values explicitly types as p : Point, or also for values q that just happen to be exactly records with exactly x and y fields of type Float (but with no nominal typing as Point)? If the latter, is this really going to work in the compiler?

I'm not sure I see the problem for the compiler. I imagine it generating functions like this:

Point.Json.encode : { x:Float, y:Float } -> String
Point.Json.decode : String -> Maybe { x:Float, y:Float }

Or maybe where Point.Json.encode uses an open record { r | x, y } instead of demanding exactly { x, y }. In any case, I don't see anything that'd require anything nominal in the types. Does that make sense?

If the former, then type Point = ... deriving JSON will really introduce a new type, not just an alias. Since then the JSON functionality wouldn't apply to any old q : { x:Float, y:Float }, only to q : Point.
 
I think all creation of new types should happen with ADTs. If you want a new version of points, it should be:

enum Point = Point { x:Float, y:Float }

And since we know there's only one constructor, we can unbox everything. No need to tag stuff.

My questions about type-directed macros are around these issues:
  • What happens if some record field has a type that does not derive the thing we need?
  • What does deriving do with ADTs exactly?
  • How do you actually create a new macro?

Max Goldstein

unread,
Aug 29, 2014, 8:49:13 AM8/29/14
to elm-d...@googlegroups.com
Janis, as you mention it's possible to have terms of a record type that are not aliased. The record type, with the braces and colons, always existed, and now we have a one token name for it, so it's an alias. We could already write terms of this type. But when we define an enum/ADT, we can now write new terms, not just new types, so it makes sense to say we created a new type. This is blurred by the fact that record aliases also introduce constructors, so we do have one new term, but it's still a shortcut for creating terms we already could create, just more verbosely. -- I'm sure you knew all that, but maybe seeing it presented this way can make you think about it a bit differently.

I would expect terms of an unaliased record type to also inherit the JSON properties; it feels more like type and less like newtype in Haskell. It modifies the old unaliased type, and the alias points to that and gets modified by reference, as it were. Before you freak out about modifying types, it all happens statically.

I am against alias as you'd think it could work on terms or functions. I have no stance on dropping the keyword entirely and going only on the capitalization of the first letter. I am opposed to using colon for ADTs/enums; Maybe does not have type Nothing or Just, that's exactly backwards, and it looks weird to see the annotation with a definition below (or a port keyword).

I also echo Evan's thoughts on, wow, what a diverse and engaged community!

Dylan Just

unread,
Aug 29, 2014, 9:48:04 AM8/29/14
to elm-d...@googlegroups.com
Regarding type aliases. I think it's best when types are first class, and a type alias is just an assignment. See Idris.

e.g. 
x : Type
x = Maybe String


Regarding the 'data' keyword:

I'm a java programmer by trade. I've seen the term "enum" in Java in a few contexts:
1. A java enum is a form of a closed sum type. It is a like a very restricted ADT where each data constructor is just a single value.
2. An "enumeration" - Enumeration<T>, Enumerable<T> - some structure that can be sequentially traversed.

There is a relationship between the two, in that a java enum can be traversed, but otherwise the two are distinct. A little confusing and overloaded. Elm's data keyword does not create something that matches either of these, though it may match what other languages call an enum. It does, however, match what is known as an algebraic data type.

Whatever keyword syntax you use - I don't really mind, just avoid verbosity. Why not just remove the "data" and "type" keywords altogether? 

In discussion, teaching and documentation, I do prefer people to use more established and precise terminology. Not that I can call out one set of terminology as The Official Computer Science Jargon, just that our industry has too much trouble with inconsistent sets of terminology as it is. I think "enum" is a term that has had far too many different definitions, whereas ADT is more precise and more accurately describes what Elm does.

This reminds me of the discussion of the command and command syntax proposals, where I was thoroughly confused by different names for things. I think I figured out that a "command" was a Promise or Futures and "command syntax" was a Monad comprehension relaxed to a "Bind" (a Monad without a "point" operation). 

If you are going to diverge from terminology various communities are used to, the "FAQ by Language" page could do with some more info (http://elm-lang.org/learn/FAQ.elm). I think this page could be split into two, so that the Learn page has two links: "Elm for JavaScript programmers" and "Elm for Haskell programmers", just to make it more prominent. "FAQ by language" wasn't immediately obvious to me when looking for this info. 

Paul Chiusano

unread,
Aug 29, 2014, 10:26:47 AM8/29/14
to elm-d...@googlegroups.com
A bit more context - data types a la carte is a "historically important" paper in the Haskell world, but it's quite cumbersome, which is why hardly anyone actually uses it. It's also often way overkill. I wrote some stuff about that here.[1]

I think it's really important to give proper context when linking people to FP research or fancy techniques.[2] IMO one of the problems with Haskell's culture is the tendency to reflexively point newcomers to fancy techniques or ideas whenever they seem even tangentially related. When this is done without at least providing the "proper context", it can be really alienating for newcomers IMO.

Paul :)

Janis Voigtländer

unread,
Aug 29, 2014, 11:22:53 AM8/29/14
to elm-d...@googlegroups.com
About the "why nominal" question (or, what might be problematic with the unaliased record type also inheriting the JSON properties), that's what I tried to point out in the other thread:

Say we have

type AddAnInt r = { r | i : Int } deriving JSON
type AddAFloat r = { r | f : Float } deriving JSON

This should give two encode functions of the two types:

f : ( r -> String ) -> { r | i : Int } -> String
g : ( r -> String ) -> { r | f : Float } -> String

Now I want to JSON encode the following value:

anIntAndAFloat : { i : Int, f : Float}

Its type is equal to both AddAnInt { f : Float } and  AddAFloat { i : Int }.

So, will the compiler turn my attempt to JSON encode anIntAndAFloat into a call of f or into a call of g?

If you implement deriving JSON in the compiler, you can make sure that it makes no difference. But in general, giving the power of type-directed macros to the programmer, I see no way how you can guarantee that f derived for AddAnInt and g derived for AddAFloat (possibly for other functionality than JSON encoding) are always coherent in a suitable way. The only way out, it seems, would be nominal rather than structural typing. (Or, equivalently, allowing deriving only on enum, not on type. Like type classes can only be instantiated on data/newtype, not on type, in Haskell.)


Message has been deleted

Janis Voigtländer

unread,
Aug 29, 2014, 11:31:32 AM8/29/14
to elm-d...@googlegroups.com
I specifically wrote "popular in Haskell research land", and as a matter of fact there are still frequent papers using it (also beyond Haskell, for dependently typed languages). So "hardly anyone actually uses it" is not true in the context I was giving.

Also, I warned quite specifically that this is fancy etc. But John was asking for that kind of extensionality (subtyping on ADTs).

So what "proper context" was missing?

Micah Cowan

unread,
Aug 29, 2014, 12:43:56 PM8/29/14
to elm-d...@googlegroups.com
Just throwing my 2¢ in, but i think "enum" is a poor idea, mostly for
reasons previously described. Sure, it _can_ define enumerations, but
it also defines plenty of things that are clearly not enumerations (or
at least not finite ones - how do you enumerate a type that has
"String" as a parameter?). I confess I don't understand Rusts' choice
of the word.

"data" may be mildly off - if I knew nothing of Haskell I might expect
it to actually be a definition of some data, and not of a type. But
"type" is already taken of course, and meanwhile what we have now
matches Haskell's idiom quite well. Given that Elm (at least as
currently designed) mimics Haskell quite closely in syntax, it seems
to me that departing from it should be reserved for cases where a
clear advantage can be gained in doing so. Elm isn't Haskell, and if
it wants to rewrite its syntax so we don't use "data" any more, that's
fine... but it's also not Rust, and using a random Rust term smack dab
in the middle of Haskell-y syntax makes little sense to me, unless
there's a clear reason to do so.

(Apologies, snipped history: none of it seemed necessary for inclusion
with the response.)

-mjc

Micah Cowan

unread,
Aug 29, 2014, 12:44:53 PM8/29/14
to elm-d...@googlegroups.com
My apologies, I somehow failed to notice the subject change; this
should've gone on the other thread. :-P

-mjc

Paul Chiusano

unread,
Aug 29, 2014, 2:46:17 PM8/29/14
to elm-d...@googlegroups.com
That is true. I guess what struck me was this statement of yours -

> If you are interested in more compositional (subtyping-like) dealing with ADTs, the Data types à la carte approach is for you.

That sounds kind of like an endorsement to me, when perhaps you just meant there was a line of research that might be of interest. Perhaps you think you were being clear enough, but I think it could have been clearer. :) IMO, it really cannot hurt to be totally explicit about why exactly you are referencing the work / technique and what the reader might get from it. Furthermore, I like to know if the person pointing to the work has real personal experience with it (have they actually written real code with it). And if you're not willing / able to give this context, I'd rather see some extra disclaimers to that effect ("I've heard of XYZ, not sure how/if it relates precisely in this situation, but it could be worth checking out") or some such.

This is just my personal opinion about communication style when it comes to these things. I hope you weren't offended that I sorta got on my soapbox in reply to your original msg!

Paul :)

Evan Czaplicki

unread,
Aug 29, 2014, 2:57:29 PM8/29/14
to elm-d...@googlegroups.com
Janis, I talked through the type-derived macros idea with Andrew and Laszlo today and I think we figured it out for the most part. I'll update the design document to reflect these ideas and follow up in the other thread you started.

Thanks for helping push this idea! It has been stalled for a while and needed exactly this kind of questioning :)

Janis Voigtländer

unread,
Aug 29, 2014, 3:54:53 PM8/29/14
to elm-d...@googlegroups.com
All is fine. :)

To answer your questions:

In fact, it was an endorsement, by a researcher, for research work.

I haven't programmed with the data types a la carte approach beyond toy problems.

But rest assured, I know the work well enough (having evaluated academic papers in this line of research for journals etc.) to not just point to it on a whim.

I was referencing it precisely for the reason my statement indicated. John was not a novice asking for advice on a specific programming problem. I think he was asking about general approaches to compositional handling of ADTs. The data types a la carte approach is the closest thing I think there is in typed FP languages. What you describe in your blog post is something that works for specific problems, but not a first-class composition or extension principle. So my hope for John would indeed be that he finds answers in the line of work I mentioned. That wasn't just tossed out because it might be tangentially related.

So no extra disclaimers were needed beyond those I did already give. :)

Paul Chiusano

unread,
Aug 29, 2014, 4:09:57 PM8/29/14
to elm-d...@googlegroups.com
Cool. Thanks for the additional color / clarification... I just realized my reply might have come across that I assumed you were someone who didn't know what you were talking about and were just referencing something that sounded cool - that is not the case. I was kind of just ranting in the abstract about a general problem I've perceived in the Haskell community, if that makes sense. :) Okay, I'll stop rambling now.. :)

Wrt DTALC, if you like, please feel free to leave a comment on the blog post, it might be fun to continue the discussion there.

Paul :)

Joey Eremondi

unread,
Aug 29, 2014, 5:05:13 PM8/29/14
to elm-d...@googlegroups.com
If I've been following this thread correctly, there's general agreement that we can change from the 'data' keyword, but mixed responses as to whether enum should replace it.
So, what are the alternatives?

I was thinking of something like "optiontype" or "uniontype", since they express the main idea that you can combine multiple types.
But they don't express the enum-style use of constructors very well.

Maybe "casetype"? To show how it expresses multiple cases, and that it directly corresponds to the case expression?

John Nilsson

unread,
Aug 29, 2014, 6:13:49 PM8/29/14
to elm-d...@googlegroups.com
For what it's worth. Thanks for the pointers, both of you! ;)

BR,
John

Sent from Mailbox

Dobes Vandermeer

unread,
Aug 29, 2014, 8:12:51 PM8/29/14
to elm-d...@googlegroups.com

I think algebraic data type refers to both type products (records) and type sums (whatever this thing is you are talking about).

I'm not sure enum is better than whatever you have now, but it's OK.  I do think it makes one think there are a small fixed number of them, based on their use in C and Java and other places.

"union" is also a common word for this, although people usually think of untagged unions first.

"tagged" could be used in place of "union" as a shorthand for "tagged union".

Just brainstorming ...

Alex Shroyer

unread,
Aug 29, 2014, 11:02:16 PM8/29/14
to elm-d...@googlegroups.com
Why swap data for enum? enum is a term almost devoid of meaning for non-programmers, and on top of that it means quite different things in several major languages. You may as well swap it out for one of these, which are all "friendlier" than enum, and in my opinion equally descriptive:

* thing
* name
* group

...which is to say, I do not want enum in Elm.

Besides, C/C++ programmers will try to iterate over them and wonder why they can't be cast to integers.

Janis Voigtländer

unread,
Aug 30, 2014, 12:30:49 AM8/30/14
to elm-d...@googlegroups.com
I like tagged.

Max Goldstein

unread,
Aug 30, 2014, 1:28:40 PM8/30/14
to elm-d...@googlegroups.com
I suspect the Haskell type theorists will not like group one bit. As for tagged, I might suggest tag, but that seems like a useful identifier to have free.

To the point that "enum means nothing to non-programmers": To what extent are we trying to attract non-programmers, and to what extent are we attracting programmers from other languages? I would say it's primarily, but not exclusively, the latter. Also, data doesn't just mean nothing, it means the wrong thing. enum might have little meaning to non-programmers, but it's used in the same way as other modern languages (Swift, Ruse) and as a logical extension on C-style languages. If "enums are ADTs" is the new, emerging consensus, we do ourselves a disservice by picking out a new name like tagged. Name intuitions are a double-edged sword: ideally you can pick a name that builds on the user's intuition, but it's better to pick out a meaningless name than fight existing ideas. 

Janis Voigtländer

unread,
Aug 30, 2014, 1:41:58 PM8/30/14
to elm-d...@googlegroups.com
The "going with the crowd" (Haxe, Rust, ...) argument might be what decides in the end for pragmatic reasons. But assuming for a moment that this were not an issue, here an experiment:

tagged Color = Red | Blue | Green

tagged Tree a = Leaf a | Node (Tree a) (Tree a)

-- I'd like to make sure that the following two types are always semantically distinguished:
tagged ScreenPos = { x : Float, y : Float }
tagged GamePos = { x : Float, y : Float }

-- That's why there aren't defined as:
type Pos = { x : Float, y : Float }

In each except the first case (Color), it reads much better with tagged than with enum. And even in the first case, tagged is not all too bad.

Also, even though that might seem obscure, I like that both tagged and type start with t. :)
 


2014-08-30 19:28 GMT+02:00 Max Goldstein <maxgol...@gmail.com>:
I suspect the Haskell type theorists will not like group one bit. As for tagged, I might suggest tag, but that seems like a useful identifier to have free.

To the point that "enum means nothing to non-programmers": To what extent are we trying to attract non-programmers, and to what extent are we attracting programmers from other languages? I would say it's primarily, but not exclusively, the latter. Also, data doesn't just mean nothing, it means the wrong thing. enum might have little meaning to non-programmers, but it's used in the same way as other modern languages (Swift, Ruse) and as a logical extension on C-style languages. If "enums are ADTs" is the new, emerging consensus, we do ourselves a disservice by picking out a new name like tagged. Name intuitions are a double-edged sword: ideally you can pick a name that builds on the user's intuition, but it's better to pick out a meaningless name than fight existing ideas. 

--

Janis Voigtländer

unread,
Aug 30, 2014, 1:43:32 PM8/30/14
to elm-d...@googlegroups.com
Of course, it needs to be

tagged ScreenPos = ScreenPos { x : Float, y : Float }
tagged GamePos = GamePos { x : Float, y : Float }

instead of

tagged ScreenPos = { x : Float, y : Float }
tagged GamePos = { x : Float, y : Float }

Jeff Smits

unread,
Aug 30, 2014, 1:44:53 PM8/30/14
to elm-discuss
I agree. The tagged keyword is the best suggestion I've seen so far.

Justin Kaeser

unread,
Aug 30, 2014, 1:52:43 PM8/30/14
to elm-d...@googlegroups.com
I think it would be kind of nice to have enum as a keyword for ADTs that also derive an ordering automatically, and fails if this is not possible, while keeping data (or something else) for the general case. But then again, that's two keywords for almost the same thing.

Dobes Vandermeer

unread,
Aug 30, 2014, 2:08:57 PM8/30/14
to elm-d...@googlegroups.com
Hi Max,

I don't think that "enums are ADTs" is a new emerging consensus.  A google for "enum" turns up mostly language features that map from an identifier to a number or at least a constant object with an associated identifier.  CS students who have already learned Java, C#, C, C++ and so on will think of "enum" this way initially.  However, I don't think it's hard to learn.

I suppose "data" is short for "data type" which and is the same as Haskell.  Given Elm's general Haskell-ish-ness I think the consistency with Haskell is probably worth something, at least some group will be familiar with this convention, and probably Haskell programmers is the group that will generally find Elm the least confusing.

So, if it were me I'd just leave it alone.  The current syntax is not worse than the new proposal of "enum".

I think "tagged" is interested and I wish Haskell had done it that way to begin with it.  But it is coining a new keyword... no not a big win.



On Sat, Aug 30, 2014 at 10:28 AM, Max Goldstein <maxgol...@gmail.com> wrote:
I suspect the Haskell type theorists will not like group one bit. As for tagged, I might suggest tag, but that seems like a useful identifier to have free.

To the point that "enum means nothing to non-programmers": To what extent are we trying to attract non-programmers, and to what extent are we attracting programmers from other languages? I would say it's primarily, but not exclusively, the latter. Also, data doesn't just mean nothing, it means the wrong thing. enum might have little meaning to non-programmers, but it's used in the same way as other modern languages (Swift, Ruse) and as a logical extension on C-style languages. If "enums are ADTs" is the new, emerging consensus, we do ourselves a disservice by picking out a new name like tagged. Name intuitions are a double-edged sword: ideally you can pick a name that builds on the user's intuition, but it's better to pick out a meaningless name than fight existing ideas. 

--

Brian Slesinsky

unread,
Aug 30, 2014, 3:53:25 PM8/30/14
to elm-d...@googlegroups.com
It could also be "tagtype":

tagtype Color = Red | Blue | Green

tagtype Tree a = Leaf a | Node (Tree a) (Tree a)

I think this gets things across pretty well: we're introducing a new type whose alternative values are distinguished using tags.

Of course this assumes we want people to be using "tag" to speak of the constructors, and this term is ambiguous when we're speaking of HTML tags as well.

I think fundamentally we need to distinguish between a closed set of alternatives defined in a single file (enum or ADT) versus an open, extendable set of alternatives (interfaces, subclasses, or even just a Lisp list where the first element is a tag). Tags are not necessarily a closed set like enums are. Note that custom tags are being added to HTML so this is not a closed set either, and XML tags have always been an open set.

So I think I still like enum better since most programmers will know it's a type, it's closed, and you shouldn't use it for an open set. Looked at that way, the Color example looks a bit dubious.

- Brian

--
You received this message because you are subscribed to a topic in the Google Groups "Elm Discuss" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/elm-discuss/UaYVp2-Xleo/unsubscribe.
To unsubscribe from this group and all its topics, send an email to elm-discuss...@googlegroups.com.

Martin DeMello

unread,
Aug 30, 2014, 4:37:54 PM8/30/14
to elm-d...@googlegroups.com
I do like enum for its "going with the crowd" aspect. I also like a more extreme version of Janis's earlier suggestion - just use "type" for all sorts of type declarations (adts, records, tuples) and let the parser sort them out.

If you do want to use a different keyword for sum types, and dislike enum for whatever reason, I'd suggest "variant". I'm not really a fan of "tagged"; it just feels more like CS jargon than all the other options, but that's just a personal preference. As a new keyword it'd work fine once people got used to it, and it's very easy to explain the reasoning behind it so that people new to all this get it.

martin



On Sat, Aug 30, 2014 at 10:41 AM, Janis Voigtländer <janis.voi...@gmail.com> wrote:

Alex Neslusan

unread,
Aug 31, 2014, 11:56:21 AM8/31/14
to elm-d...@googlegroups.com
I don't understand why you're using the word "tagged" here. It doesn't make sense to me, conceptually, as a tag.

Ray Racine

unread,
Aug 31, 2014, 1:43:44 PM8/31/14
to elm-discuss
On Thu, Aug 28, 2014 at 10:58 PM, Max Goldstein <maxgol...@gmail.com> wrote:

Yeah, we're still messing with the language. If you can't handle that, either don't upgrade or don't use Elm. We're very far away from 1.0.

After further objective reflection and explorations I think you are correct.  I need to use something now and having things in the still messing around with the language phase (which I completely understand) is too unstable a footing to build upon.   Still a very cool project overall.  Good luck.

Janis Voigtländer

unread,
Aug 31, 2014, 2:59:47 PM8/31/14
to elm-d...@googlegroups.com
In the example, the type { x : Float, y : Float } is "tagged" in two different ways, once with ScreenPos and once with GamePos. The outcome is that these become types that are distinguished by the compiler. So it cannot happen that you accidentally pass an x,y pair that is meant as an in-game position to a function that expects screen positions (imagine that these are two different coordinate systems for some reason, making conversions necessary -- if you just used the type { x : Float, y : Float } or aliases of it, you might accidentally forget some conversions and the type checker has no chance to tell you; but if the types are "tagged", the compiler will notice when you forget a conversion).

But in other consideration, Brian's warning about possible confusion in Elm's use context, with HTML tags etc., makes sense as a reason against the use of tagged as the keyword.



Joey Eremondi

unread,
Aug 31, 2014, 3:27:53 PM8/31/14
to elm-d...@googlegroups.com
This is why I was a fan of "case type" . Conveys the same idea, but less confusing or jargony, and has the nice symmetry with the case keyword.

Alexander Berntsen

unread,
Sep 1, 2014, 6:04:33 AM9/1/14
to elm-d...@googlegroups.com
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

- -n on the data -> enum proposal, where n is as high a number as you
can conceive of.

A better option would be data -> type, and type -> alias.
- --
Alexander
alex...@plaimi.net
https://secure.plaimi.net/~alexander
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2
Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/

iF4EAREIAAYFAlQERK0ACgkQRtClrXBQc7VvwgD9GGWPOxO5Z1TDbAF7wjSr8AOj
o6EGIdh8bJvw74K0eLEBALec66L4Ictsp11IPW3knGCvjlWtvnI19++/lO2bUO5r
=hkw2
-----END PGP SIGNATURE-----

Conrad Parker

unread,
Sep 1, 2014, 6:33:32 AM9/1/14
to elm-d...@googlegroups.com
I find enum a bit strange for single-constructor types (which I've ended up using when the compiler tells me my type alias must be a data constructor instead).

I think it'd be great to have a real 'enum' keyword for multi-constructor types which can be enumerated over (ie. non-recursive sum types). Just renaming 'data' to 'enum' without being able to enumerate anything seems a bit lame.

I don't think there's any need to worry about compat with the existing Haskell terminology. I'd also go with renaming 'data' to 'type' (because it actually introduces a type), type to alias, and keep enum for something more useful later.

Conrad.


Iain Ballard

unread,
Sep 1, 2014, 11:29:29 AM9/1/14
to elm-d...@googlegroups.com
I think I may be late to the discussion, but I'll throw my hat in the ring anyway (please excuse colouring for explanation)

When trying to name things for other people (i.e. to make them intuitive) try not to describe what they are, but instead hint at how they are used.

The way I tend to use ADTs is to model data and to enumerate structural relationships.

So I'd suggest that data, enum and struct are all 'what' and the how is:

model Maybe a = Just a | Nothing

And then I'd like to address a gripe with the way Haskell uses `=

model Maybe a
    with Just a | Nothing

Admittedly, that would need more than find & replace, but it feels much more like a constructor and it's cases.

Max Goldstein

unread,
Sep 1, 2014, 11:44:24 AM9/1/14
to elm-d...@googlegroups.com
My concern with data -> type, type -> alias is that maybe you want to introduce types in some other way, with a language feature not yet thought of. I dislike alias because it's not clear it's only for types, not terms.

You can have an enum with a single term in it in C. In fact, I've seen this used in APIs that will grow beyond that one option in the future. (SemVar vs. YAGNI, go!)

model is an interesting suggestion, but I feel that it's going to confuse the hell out of MVC people. I feel like it's the programmer's just to provide semantic abstractions and it's the language's job to provide many tools to do that. I decide what a model is, not the language; that's a high-level concept. model also doesn't seem ADT specific; should I be able to do model Point with {x : Float, y: Float} as well? If we do go this route, I suggest swapping with for as, which is already a reserved word, assuming it can be parsed unambiguously (I think it can).

I really like the ScreenPos and GamePos position. I was going to ask for some sugar for them, thinking you'd need to have a case statement, but if you're clever it's not so bad. Share-elm is down, so at the risk of a further tangent, this is as neat as I can get them:

type Position = {x:Float, y:Float}
data GamePos = GamePos Position

f : GamePos -> String
f (GamePos {x,y}) = show x ++ " " ++ show y

main = asText . f . GamePos <| Position 4 5

Evan Czaplicki

unread,
Sep 1, 2014, 7:22:40 PM9/1/14
to elm-d...@googlegroups.com
Model is very interesting! I think of that as a key part of Elm, so it's pretty cool to think of using it that way.

Iain, when you used GADTs in Haskell it actually looks more like what you are looking for:

model Maybe a where
    Just : a -> Maybe a
    Nothing : Maybe a

I had a cool conversation with someone who has studied semiotics. He hated enum because of the Java and C history combined with the massive number of Java and C programmers. He suggested we use a new word entirely so we can define its meaning and the culture around it. I don't know if I agree with him, but in reading on wikipedia, I found out that pragmatics sounds like a really cool thing.

I think it'd be a shame to give up model because it's a really handy word for Elm programs, but I also like it quite a lot. Let's keep brainstorming, I think we are making good progress!


--

Dobes Vandermeer

unread,
Sep 1, 2014, 10:21:21 PM9/1/14
to elm-d...@googlegroups.com
I like this idea of using "type" for all new types better than any other proposal so far, it has a kind of consistency to it.  To avoid ambiguity between sum types and aliases I suggest using "type X = type Y" for a type alias without any parens or brackets around the RHS.  This makes sense in my mind because the word "type" is a kind of prefix that says the next expression exists in the "type" namespace.

type ColorRec = { r : Float, g : Float, b : Float } -- Clearly an alias for a record type
type ColorTup = (Float,Float,Float)
type Color = Red | Green | Blue | Purple | ColorRec ColorRect | ColorTup ColorTup -- Clearly a sum type
type ColorList = [Color] -- Clearly a list type alias
type MyColor = type Color -- Use the "type" keyword to denote a type alias

Iain Ballard

unread,
Sep 2, 2014, 1:47:31 AM9/2/14
to Evan Czaplicki, elm-d...@googlegroups.com
Please excuse the stream of consciousness below.

Yes, I like the GADT syntax, it seems very clear what's going on even if it's a bit verbose. Makes a nice symmetry with typeclasses. I wonder if there is something similar to join records and funcs/tuples?

I agree that 'model' would be an unfortunate word to pollute with a keyword. Sigils $olve the problem in an ugl¥ way. Could we maybe make some words keywords only if they are in the leftmost column? Or would that be more confusing?

I did wonder about 'pattern' which then pairs with "pattern matching", but it doesn't seem to fit well. Ditto 'structure'.

Maybe 'type' keyword should have a second part 'type _' in ('model', 'alias'...)

Perhaps there is a join in type:

type Normal {x:Float, y:Float} a where
    Vector: a -> Normal a
    NullVec: Normal a

type Maybe a where
    ...

type JustRec {alpha:Int, beta:Int}

type HOTR (Normal a)=>{xy: a, w: Int} t where
    X: t -> ...

From: Evan Czaplicki
Sent: 02/09/2014 00:22
To: elm-d...@googlegroups.com
Subject: Re: Rename: ADT => enum

Model is very interesting! I think of that as a key part of Elm, so it's pretty cool to think of using it that way.

Iain, when you used GADTs in Haskell it actually looks more like what you are looking for:

model Maybe a where
    Just : a -> Maybe a
    Nothing : Maybe a

I had a cool conversation with someone who has studied semiotics. He hated enum because of the Java and C history combined with the massive number of Java and C programmers. He suggested we use a new word entirely so we can define its meaning and the culture around it. I don't know if I agree with him, but in reading on wikipedia, I found out that pragmatics sounds like a really cool thing.

I think it'd be a shame to give up model because it's a really handy word for Elm programs, but I also like it quite a lot. Let's keep brainstorming, I think we are making good progress!
On Mon, Sep 1, 2014 at 5:44 PM, Max Goldstein <maxgol...@gmail.com> wrote:
My concern with data -> type, type -> alias is that maybe you want to introduce types in some other way, with a language feature not yet thought of. I dislike alias because it's not clear it's only for types, not terms.

You can have an enum with a single term in it in C. In fact, I've seen this used in APIs that will grow beyond that one option in the future. (SemVar vs. YAGNI, go!)

model is an interesting suggestion, but I feel that it's going to confuse the hell out of MVC people. I feel like it's the programmer's just to provide semantic abstractions and it's the language's job to provide many tools to do that. I decide what a model is, not the language; that's a high-level concept. model also doesn't seem ADT specific; should I be able to do model Point with {x : Float, y: Float} as well? If we do go this route, I suggest swapping with for as, which is already a reserved word, assuming it can be parsed unambiguously (I think it can).

I really like the ScreenPos and GamePos position. I was going to ask for some sugar for them, thinking you'd need to have a case statement, but if you're clever it's not so bad. Share-elm is down, so at the risk of a further tangent, this is as neat as I can get them:

type Position = {x:Float, y:Float}
data GamePos = GamePos Position

f : GamePos -> String
f (GamePos {x,y}) = show x ++ " " ++ show y

main = asText . f . GamePos <| Position 4 5

--
You received this message because you are subscribed to the Google Groups "Elm Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elm-discuss...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to a topic in the Google Groups "Elm Discuss" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/elm-discuss/UaYVp2-Xleo/unsubscribe.
To unsubscribe from this group and all its topics, send an email to elm-discuss...@googlegroups.com.

Conrad Parker

unread,
Sep 2, 2014, 3:20:08 AM9/2/14
to elm-d...@googlegroups.com, Evan Czaplicki
On 2 September 2014 15:47, Iain Ballard <iain.b...@gmail.com> wrote:
Could we maybe make some words keywords only if they are in the leftmost column? Or would that be more confusing?

Maybe 'type' keyword should have a second part 'type _' in ('model', 'alias'...)

 I like this idea; I don't think it would be confusing.

We already have (as in haskell) special handling for "import" lines: you could use the variable name "qualified" anywhere else in the rest of the program, the word only means something special in "import qualified ...".

If we did use syntax like:

type model Color = Red | Green | Blue

it'd be obvious enough what's going on that using the variable name "model" elsewhere in the program wouldn't be confusing.

"type alias Point = (Int, Int)" reads nicely and it's clear what is going on.

If anything, this proposal would reduce the number of keywords (making "data" available!) and allow some scope to play with type syntax ("type alias", "type enum", "type struct", "type model" etc.)

Conrad.

Alex Shroyer

unread,
Sep 2, 2014, 10:11:52 AM9/2/14
to elm-d...@googlegroups.com
All this talk of adding or changing keywords is edging closer and closer to Java territory, where everything requires outlandishly long ceremonial constructor incantations like:

HammerBuildingFactoryDelegateManager myHammerBuildingFactoryDelegateManager = new HammerBuildingFactoryDelegateManager();

...except instead of objects it's with types:

type model alias enum      Color = Blue | Red
^^^^^^^^^^^^^^^^^^^^^      ^^^^^^^^^^^^^^^^^^
        noise           actual useful information

But Elm has type inference:

-- compiler should infer that these are ADTs simply by virtue of the | symbol:

Color = Blue | Red

Colorful hue = Blue hue | Red hue | Black

ColorList xs = Blue xs | Red xs


-- but it's also possible for the compiler to figure this out because its arguments are types:

Pair = P Int Float


-- or in desperation, just look for words starting with a capital letter:

Foo = Bar

Evan Czaplicki

unread,
Sep 2, 2014, 10:40:01 AM9/2/14
to elm-d...@googlegroups.com
The multi-keyword thing is also interesting. I don't think the Java comparison is fair given the actual proposal in this thread, but I wrote out some examples on my own and it is true that it makes things feel a bit heavy.

I think having no keyword or only one keyword is problematic. For example, is this an ADT or a type alias?

type Foo = String

I believe OCaml uses the case of things to disambiguate, but it requires that all of their types are lower case while their constructors are upper case. I think it makes types harder to read.

Here's another variation written out:

union Boolean a
    = Literal Bool
    | Not Boolean
    | And Boolean Boolean
    | Or Boolean Boolean

alias Point =
    { x : Float
    , y : Float
    }

I feel like the term union is not really used outside of C/C++ and it's easy enough to say we have tagged unions. It seems pretty nice right now. Very descriptive and accurate names. I also feel like union does not have the same baggage as enum. It's also a full word on it's own. It's also the same length as the word alias :)


--

Iain Ballard

unread,
Sep 2, 2014, 11:13:14 AM9/2/14
to elm-d...@googlegroups.com
union is nice -- types pretty well on qwerty ;-)

Some more brain-storming...


How about using the same symbols as for type declaration and function definition...

type Special : String           -- I'm an alias
type Foo     = String           -- I'm an ADT
type Maybe a = Just a | Nothing -- me too
type Point   : {x: Int, y:Int}  -- I'm the type of a record.

How about a very radical idea (more for arguments' sake):

module X where

import
    Json
    Javascript.Experimental as JSE
    Dict (empty,insert)

type
    Maybe a = Just a | Nothing
    Point = {x: Int, y: Int}

func : String -> String
func x = . . .

That looks like Pascal had a baby with Python :-(


--
You received this message because you are subscribed to a topic in the Google Groups "Elm Discuss" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/elm-discuss/UaYVp2-Xleo/unsubscribe.
To unsubscribe from this group and all its topics, send an email to elm-discuss...@googlegroups.com.

Zinggi

unread,
Sep 2, 2014, 5:02:23 PM9/2/14
to elm-d...@googlegroups.com
I like your radical idea a lot! It nicely separates code and types. Also, the import lines are very clean that way.

Jeff Smits

unread,
Sep 3, 2014, 5:51:00 AM9/3/14
to elm-discuss
It is an interesting proposal to strictly separate type "introductions" (i.e. declarations/definitions of new types/aliases) into a section.
I think it won't be in the way of how most people write their modules. If you want to compromise to cater people who introduce new types halfway down a module you can allow multiple type sections in a module.

If you're looking for experience uncluttering through sections, compare C++ with Java for class definitions. IIRC C++ has a public and a private section of a class definition where you define your public or private fields and methods, whereas Java has a heavier syntax by having you prefix every field and method definition with public or private. Of course there are different trade-offs there than there are with a separation between type and value sections, like moving a field/method between the public section and the private is more likely to happen than moving Elm code (verbatim) between the value section and the type section.
A question about this proposal: Should there be an obvious end to the type section and beginning of the value section through another keyword? Or is the indentation enough of a visual separation?

To voice my opinion on this: I like the separate sections approach. The only problem there still is, is telling apart aliases and ADTs with one constructor and no arguments.

BTW: the colon vs. equals sign approach to separating aliases and ADTs has been proposed earlier in the thread and pros/cons have been named.

Evan Czaplicki

unread,
Sep 3, 2014, 6:15:59 AM9/3/14
to elm-d...@googlegroups.com
I'm not planning to do the "sections" thing. I think there are two viable options for renaming data: enum or union.

Good parts of enum:
  • describes what you are doing
  • builds on prior knowledge
  • used in Swift, Rust, and Haxe and causes no problems for people there (folks just accept that it's more powerful according to someone knowledgable about Swift)
Bad parts:
  • Maybe does not sound as important as it really is, but ADT wasn't so good at that either.
  • Need to know that enum = ADT to read old papers (seems really trivial to me)
Good parts of union:
  • Not much cultural baggage, it is as important as we say it is
  • "tagged union" explains what it does and how it is implemented really concisely
Bad Parts:
  • No one knows what it is
  • It's sort of weird when you only tag one thing


Evan Czaplicki

unread,
Sep 3, 2014, 6:16:21 AM9/3/14
to elm-d...@googlegroups.com
Here is some example code of some different options.

Evan Czaplicki

unread,
Sep 3, 2014, 6:22:48 AM9/3/14
to elm-d...@googlegroups.com
I think (data => type, type => alias) is actually surprisingly nice. Here's further exploration of that route.

Max Goldstein

unread,
Sep 3, 2014, 8:29:44 AM9/3/14
to elm-d...@googlegroups.com
In addition to all of the great discussion, I think the names type constructor and value constructor should change as well. They don't appear in the language, just the documentation and discussions, but eliminating the term constructor where it has no (obvious?) relation to its OO meaning is a win. We might say instead that a union type consists of the union name and one or more tags with optional parameters specified as types. (tag might go better with union than enum but it seems like the one-tag use case is going to be common to prevent aliasing, e.g. the GamePos example above, and as mentioned a union with only one thing is weird.)

I strongly favor typealias over just alias, since otherwise you think you could do it with terms. If ADTs become just type, we don't have many good names to describe rename their constructors. So I'm hesitant on that route, but it's worth considering.

UEHARA Junji

unread,
Sep 3, 2014, 9:10:49 AM9/3/14
to elm-d...@googlegroups.com
Hi,
May I ask a question.

When the keyword change of (data => type, type => alias) is introduced
to Elm, What would be the name of the language construct which formerly known as ADT? For example, a newbie of Elm might write following code:

type Point = { x : Float, y : Float }

And he will get an error. How explain him the reason why this is error?
Something like this?:

  Hi, your code is error because 'type' defines only an ADT and give a
  name of it.  You can't apply 'type' to the type which is not ADT,
  specifically function type, tuple type, extensible record type, etc.

but of course we don't want to use the word ADT here.
Not only explanation, also in document, compiler error messages.
So, we need a name for the language construct which
formerly known as ADT even if we don't introduce a keyword.

And If conceptual new name of the ADT in document/error message/explanation
is 'enum type' or 'union type'IMHO, the syntax for it feels better if those are
'enum/union' than plain 'type'.

--
UEHARA Junji

Michael

unread,
Sep 3, 2014, 9:45:07 AM9/3/14
to elm-d...@googlegroups.com
type for ADT seems really sensible to me. You're making an ADT, so a new type, so type seems like it'd be easy to explain to a newbie.

typealias seems like a great specific name for what it does. It needs no explanation for what it does. I'd shy away from alias since it's a more general keyword. It would take explanation for why alias can only be used for types and not, say, changing the name of a function in wide scope for a let-expression.

data => type; type => typealias seems like a change for greater accessibility.

Alexander Noriega

unread,
Sep 3, 2014, 11:22:25 AM9/3/14
to elm-d...@googlegroups.com
My 2 cents: 

Not convinced at all by the arguments in favor of `enum`.  But I don't have a suggestion, because I don't know of a better word than `data` for defining shapes of data.

I introduce Elm to JS/HTML/CSS/PHP devs all the time. `data`: simple to explain. `enum`: totally alien, plus makes it sound like it's going to be a complicated thing.

IDK why the focus is the "problems" with the `data` keyword anyway.  For me, `type` being used for aliases is by far the main offender here. It is certainly the one generating the questions when I introduce Elm to anyone.

So I would replace `type`. With something like `typealias`, `alias`, `synonym`, etc.

`synonym Point = {x: Float, y: Float}`

Or something.

--Alexander

Brian Slesinsky

unread,
Sep 3, 2014, 11:42:36 AM9/3/14
to elm-d...@googlegroups.com


On Sep 3, 2014 8:22 AM, "Alexander Noriega" <lambd...@gmail.com> wrote:
>
> My 2 cents: 
>
> Not convinced at all by the arguments in favor of `enum`.  But I don't have a suggestion, because I don't know of a better word than `data` for defining shapes of data.
>
> I introduce Elm to JS/HTML/CSS/PHP devs all the time. `data`: simple to explain. `enum`: totally alien, plus makes it sound like it's going to be a complicated thing.

Is there some way we could test this rather than speculating?

>
> IDK why the focus is the "problems" with the `data` keyword anyway.  For me, `type` being used for aliases is by far the main offender here. It is certainly the one generating the questions when I introduce Elm to anyone.

For people who have used C before, changing "type" to "typedef" would make it more familiar. I doubt it would help people without that experience though.

Another thing to consider is that someone learning Elm first might then go on to learn other languages like Swift or C someday. So using these terms would make them more familiar when moving in the other direction.

Evan Czaplicki

unread,
Sep 3, 2014, 12:12:40 PM9/3/14
to elm-d...@googlegroups.com
Today I have been thinking that one way to sort it out is to try to write the learning resources for each name and see what it looks like. Looking at those documents side-by-side would probably show how we would be communicating as a community and help compare.

I'm not really sure how to gather data besides asking people, which I have been doing a lot of at ICFP so far. John suggested we do a poll of folks here, getting their background and a rating for each proposal. I think that's hard to do fairly without also providing the introductory materials for each set of terminology so we can see why those names are nice more deeply than the keywords themselves. I don't know how to do large tests on JS folks though, which I guess is the ideal thing to do.


--

Sean Corfield

unread,
Sep 3, 2014, 12:16:04 PM9/3/14
to elm-d...@googlegroups.com
At this point, seeing more code examples, I think I'd favor:

data => type
type => type alias

I don't like typealias because I just don't think it reads as easily - but I could live with it.

I don't like enum for most of the same reasons others have objected to it (it's jargon, it's an arbitrary shortening of a word, it has baggage from languages where enum is "just" a named constant).

I'd gotten used to data but agree with most of the points made in favor of type being more descriptive of what the construct does.

Sean
signature.asc

Micah Cowan

unread,
Sep 3, 2014, 12:32:31 PM9/3/14
to elm-d...@googlegroups.com
On Wed, Sep 3, 2014 at 9:15 AM, Sean Corfield <se...@corfield.org> wrote:
> At this point, seeing more code examples, I think I'd favor:
>
> data => type
> type => type alias
>
> I don't like typealias because I just don't think it reads as easily - but I
> could live with it.

Just throwing my support behind this as well. I've got no problem with
"typealias" really, but "type alias" probably is better, so long as it
doesn't result in "alias" being a reserved word in other contexts
(such as variable names).

-mjc

Brian Slesinsky

unread,
Sep 3, 2014, 2:14:36 PM9/3/14
to elm-d...@googlegroups.com

How about "datatype"?

--
You received this message because you are subscribed to a topic in the Google Groups "Elm Discuss" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/elm-discuss/UaYVp2-Xleo/unsubscribe.
To unsubscribe from this group and all its topics, send an email to elm-discuss...@googlegroups.com.
It is loading more messages.
0 new messages