Hacker News new | past | comments | ask | show | jobs | submit login

Probably for the same reason that they call their unions "enums" or their heap blocks "boxes". Standardization of jargon has never been a thing with rust, just roll with it.



Well, enums aren't unions, they're tagged unions. And other languages call boxed values by that name too.


Stop it, they're unions. :) Among the target market, people are going to intimately familiar with the use of "enum" and "union" from the C language. Rust's concept of a single object that can store exactly one of several types of sub-objects matches one quite closely, and not the other. Having a runtime tag and affirmative checking doesn't change the nature of the thing. We don't call "cars" something different when we add cruise control or anti-lock brakes.

"Enumerate" in English is just a fancy word for "count" -- it means to assign numbers to a bunch of things. Which is exactly what the C concept did. The Rust usage (to mean "something that can be in one of a few different states") is new, though Java has something fairly close too.

It was a poor choice, sorry. Likewise being deliberately difficult with "trait" vs. "interface" (picking Self's jargon instead of the term that literally everyone already knows from decades of OOP) didn't serve you well. Thus we have blog posts like this needing to tell us what we probably should have been able to figure out from context.

Finally, regarding "box" vs. "block". Other languages (C# is the only one that comes to mind off-hand) have used the idea of "boxing" to imply the allocation of space for and copying of pass-by-reference data. That's sort of a different notion than simple heap allocation, so it sort of gets its own jargon I guess. I didn't complain anyway. But with Rust, a "box" really is used to refer to a dynamic heap block in any context. We sort of already had a perfectly good word for that.

Pretentious jargon isn't the worst crime in the world, but I do think Rust seems needlessly complicated in the way it likes to play Shakespeare with existing concepts.


But a Rust enum is equivalent to a C-style one in the basic case. Rust's is just able to do more as well to support the common idiom of tagged unions. Unions themselves cannot be expressed safely in Rust, so it'd do little good IMHO to have different terms for them. I guess you could say that they should have avoid "enum" and went with "data" as in Haskell, but then people would complain that the basic ADTs are just enums and wonder why they can't just use "enum" like before!


I don't really want to argue about enum vs. union, because as far as I'm concerned they're pretty much equally accurate or inaccurate. Enums in C carry tags, but no data. Unions in C carry data, but no tags. Rust ADTs carry both (or one, or neither). So "enum" or "union" are pretty much equally good/bad names as far as I'm concerned. Consensus was in favor of "enum", so we went with it. Swift did too, so the small amount of emerging consensus as to what to call ADTs in C-like languages is nice.

> Likewise being deliberately difficult with "trait" vs. "interface" (picking Self's jargon instead of the term that literally everyone already knows from decades of OOP) didn't serve you well.

But "trait" is the right term. I would agree with you if Rust traits couldn't have implementations via default methods, but they do, and interfaces usually can't (except in Java 8). Interfaces strongly suggest, well, interface, as opposed to implementation; however, traits mix and match both. You can perfectly well have traits that exist only to provide "mixin"-style implementations.

In earlier versions of Rust, traits were called interfaces (and there were separate constructs to provide implementations of interfaces), but one of the design simplifications was to unify all those concepts into one: the trait.

> Finally, regarding "box" vs. "block". Other languages (C# is the only one that comes to mind off-hand) have used the idea of "boxing" to imply the allocation of space for and copying of pass-by-reference data. That's sort of a different notion than simple heap allocation, so it sort of gets its own jargon I guess. I didn't complain anyway. But with Rust, a "box" really is used to refer to a dynamic heap block in any context.

Sorry, I just have to disagree here. I don't think anything would be simpler if the keyword were "block":

    let x: Block<f32> = block 3.0;
"Block" as a verb doesn't mean "allocate" in the same way that "box" does: if anything, "block" implies something related to putting threads to sleep for I/O. And as a type, "block" sounds like a code block—i.e. something like a lambda. Ruby uses "block" for this, for instance.


> And as a type, "block" sounds like a code block—i.e. something like a lambda. Ruby uses "block" for this, for instance.

As does, notably, Objective-C, like Ruby due to the Smalltalk heritage.

I've never heard the term "block" used to refer to heap allocations, so I don't think it would really help.


> regarding "box" vs. "block". Other languages > (C# is the only one that comes to mind off-hand)

F# actually uses box much like Rust does:

    // box an int
    let o = box 1
Examples: http://fsharpforfunandprofit.com/posts/cli-types/

MSDN: https://msdn.microsoft.com/en-us/library/ee340516.aspx


I guess we'll have to agree to disagree here. I think what you consider 'pretentious jargon' really depends on what kinds of languages you've used and the way you think about them. I think calling enums unions would have been a very big mistake, as they would mislead C programmers. Even you say that they're 'quite close', but they're not the same thing.


I, uh, don't really follow that logic. A Rust enum isn't even "quite close" to a C enum, yet you used a colliding term. Surely a C programmer who would have been mislead about the fact that a union type is runtime-tagged and checked is going to be very misled that an "enum" has no numeric value and can contain variable state at runtime.


  >  A Rust enum isn't even "quite close" to a C enum
This is incorrect. The following Rust enum compiles down to a single byte, whose variants are represented by the numbers 0, 1, and 2:

  enum Foo {
      Zero,
      One,
      Two
  }
You can even give them all numeric values explicitly:

  enum Bar {
      Ten = 10,
      Eighty = 80,
      TwoHundred = 200
  }
And you can also just tell it where to start and let it count from there:

  enum Qux {
      Five = 5,
      Six,
      Seven
  }
If you throw the #[repr(C)] attribute on any of these then Rust will make sure to size them as C would on your particular platform (on my machine this attribute inflates them from 8 bits to 64 bits), making them usable directly from C as well.


I guess my ultimate point is that _everything_ is a colliding term in some way, with some language. Rust isn't C, so you can't assume that things map 1:1 to C.

Names are hard.


I'll have to admit enums are where I gave up the first time I read the Rust tutorial. They seem almost completely unrelated to enums in C and other languages.


Because they are enums done right. Enums in C and many other languages are often just a helpers to define integer constants (or abused in this way) and can be evil.


> They seem almost completely unrelated to enums in C and other languages.

They're not. Payload-less enums devolve to C enums. Rust's enum simply build the enum+union enumeration pattern into the language, and allow leaving out the "union" part.


Right, because they're unions. :)

Just go back to that tutorial with your C hat on and substitute the word "union" for "enum" and I promise it will all make sense. All your intuition about C unions will cross over just fine, and the new Rust rules (they're tagged at runtime and the compiler enforces that you can only ever use fields of a runtype-checked subtype) are straightforward extensions.

Likewise the linked blog post begins, comfortingly, with "Traits are interfaces". Once you get beyond the new jargon, you find it wraps a concept which is 95% compatible with something you've been using for years.

That the Rust team seems to find no value in this kind of naming, preferring the excess precision that comes with Create-Your-Own-Name, is what I was calling "pretentious jargon" in a previous post in the thread. It's really not that bad (I mean really, they're just names), but it doesn't speak well to where the designers heads were when they invented this stuff.

Really, that's what's starting to creep my out about Rust. Just like C++ 30 years ago, it seems like Rust has caught itself up in an internal rush (among its rock-star language nerd designers) for Masterpiece Status and sort of forgotten the goal of creating a practical tool for working programmers... At some point in the near future I have to wonder if we're going to start seeing blog posts about choosing a "sane subset" of Rust with which to develop software.


> and sort of forgotten the goal of creating a practical tool for working programmers

This is blatantly false. I've been in touch with Rust development for quite some time, and pragmatism has been paramount in all design decisions. Suggesting otherwise on the basis of disagreeing with some naming choices is complete nonsense.


  > it seems like Rust has caught itself up in an internal 
  > rush (among its rock-star language nerd designers) for 
  > Masterpiece Status and sort of forgotten the goal of 
  > creating a practical tool for working programmers
This is complete hogwash. Just because you disagree with the chosen terminology doesn't justify attacks on the character of the Rust developers.


Sigh... it's an opinion. I even used "seems". I was around when we all watched C++ go from "exciting new tool we should all use" to "wait, does anyone else understand that new stuff because I don't anymore". This feels exactly the same.

I'm no dummy, yet Rust is just confusing as hell sometimes. And you guys frankly don't seem to care (again: note marker "seems" to indicate a personal opinion and not a "character attack"). That turns me off. It turns lots of people off. And I don't see any significant effort being made at making it an easy tool to learn and use.


> And I don't see any significant effort being made at making it an easy tool to learn and use.

Just to name a few off the top of my head:

1. Lots of focus on friendly compiler error messages, including typo correction, automatic lifetime suggestions, and error message explanations.

2. A strong worse-is-better approach in many aspects of the language design, such as preventing reference-counted cycles (we don't try to), numeric overflow (we don't try except in debug mode), typeclass decidability (it's deliberately undecidable in corner cases to avoid complex rules), prevention of deadlocks (we don't try), userland threads (we don't implement them anymore), asynchronous I/O (it's out of the domain of libstd for now), etc.

3. Blog posts like this one to introduce aspects of Rust, as well as the tutorial.

4. The Cargo package manager, as well as crates.io.

5. Naming conventions designed to fit well with C, for example choosing "enum" over "data"/"datatype" as in ML, "trait" over "class" as in Haskell (since the latter means something totally different), but modified in some cases to avoid leading programmers of C-like languages astray (for example, "interface" changing to "trait"). This naming process has taken time, but I think Rust is in a pretty good place now. There are obviously disagreements as to the naming, but we can't please everybody.

Certainly we weren't perfect, but there was a lot of effort put into making Rust as easy to use as possible.


I'm updating one year old Rust code currently, it's pretty obvious a tremendous amount of work has gone toward making it a more usable language. Yet it is not a small one, so some effort to master it is to be expected...


> Just go back to that tutorial with your C hat on and substitute the word "union" for "enum" and I promise it will all make sense. All your intuition about C unions will cross over just fine, and the new Rust rules (they're tagged at runtime and the compiler enforces that you can only ever use fields of a runtype-checked subtype) are straightforward extensions.

This is not true. Rust enums allow you to match on which of the types you have. C unions do not. If you want to implement a switch statement over the possible members of a C union, you need to put it inside a struct with a type field. You don't need to do so in Rust, and you can't do so and have it compile.

(That said, if your real complaint is that the official docs on enums are confusing, I'd certainly agree with that.)


> (That said, if your real complaint is that the official docs on enums are confusing, I'd certainly agree with that.)

I'd love more specifics about which docs, if you have some time.


I hestiate to speak because everyone will turn it gray, but it's worth pointing out that the whole idea of enums having C-like "discriminants", which like four people have yelled at me about, is entirely missing from the book.

I had to go look it up in the reference, where it is sort of hidden too.


I just sent in this PR, is this helpful? https://github.com/rust-lang/rust/pull/25348

Specifically I ended up rewriting most of the enum page: https://github.com/geofft/rust/blob/trpl-fix-enums/src/doc/t...

I think there's more that can be done (e.g. the book doesn't document that if every variant of an enum is data-less, you can cast it to an integer), but hopefully this is a start.


trpl/enums.md is super weird, and also in the wrong order (the book documents enums before structs, and way before tuple structs, whereas enums are IMO easiest explained once you've already explained structs). I was going to send you a PR tomorrow or so. :)


Fair enough. Tomorrow is basically the deadline before 1.0 though, so send it early :)


And I guess by "standardization" you mean use a C-like name, even though it is inaccurate and misleading and the data type declaration is taken from another language family (ML)?

(I agree that "enum" is a wrong name to use, but apparently for different reasons.)




Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact

Search: