Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Custom data types which accept only values enumerated by programmer. #9229

Closed
jesseray opened this issue Sep 16, 2013 · 6 comments
Closed

Custom data types which accept only values enumerated by programmer. #9229

jesseray opened this issue Sep 16, 2013 · 6 comments
Labels
A-type-system Area: Type system

Comments

@jesseray
Copy link

In Haskell (using GHC), you can write

data Tanks = 0 | 1 | 2 | 3 | 4

to define a new data type called Tanks that can have the value 0 or 1 or 2 or 3 or 4. When you define a variable of type Tanks, you must define it as having one of the values enumerated in the data type definition. If you try to use a value that is not enumerated in the data type definition, such as 5,

hearts :: Tanks
hearts = 5

the compiler will abandon compilation and display an error message that says (in essence) that the value is not acceptable.

By defining new data types that accept the enumerated values and no others, module developers can prevent other programmers from abusing their modules because the abuses will cause compiler errors. In this way, module developers increase the chances that, if the code compiles, the code works correctly.

Rust does not support this without workarounds.

A programmer could try to use an Enum, but these enumerate constructors with valid Rust identifiers, not values. As such, the programmer would need to define constructors to use as placeholders for each of the values they want enumerated. That would fill their modules with boilerplate code and make them unpleasant for other programmers to use. Hence, I do not consider this workaround viable.

The programmer could use a Struct with a private field and a Setter method which prevents the field from being given a value that the module developer does not want. This workaround involves much less boilerplate and the module remains pleasant for other programmers to work with. Hence, I do consider this workaround viable. Even so, when compared with the Haskell approach, it strikes me as avoidably ugly, because Haskell does not require any boilerplate code at all.

Can the Rust language and compiler be extended to allow programmers to define new data types that can have only the values enumerated by the programmer, but without boilerplate code?

@glaebhoerl
Copy link
Contributor

In Haskell (using GHC), you can write

data Tanks = 0 | 1 | 2 | 3 | 4

Huh? Not with my GHC.

@jesseray
Copy link
Author

You are right. I was misled by Making Our Own Types and Typeclasses, which says:

In a similar fashion, we can think of the Int type as being defined like this:

    data Int = -2147483648 | -2147483647 | ... | -1 | 0 | 1 | 2 | ... | 2147483647

That is false. According to The Haskell 98 Report, Section 4.2, the components to the right of the equal sign must be data constructors, not values. It turns out that we cannot think of the Int type as being defined that way. I hate when people teach a subject using falsehoods... (sigh)

In any case, I still think it would be a nice feature to have.

@catamorphism
Copy link
Contributor

Also see #1679 (a similar idea, though not quite the same).

@glaebhoerl
Copy link
Contributor

@jesseray, you define a datatype by enumerating its constructors, but then those constructors are the values of that type. If I write data Foo = A | B | C, then the values of type Foo are A, B, and C. The analogy being made here is similar: 0, 1, 2 etc. can be thought of as constructors for the type Int, and hence its possible values. So when we write data Int = ... | -1 | 0 | 1 | 2 | ..., these are not already-existing values which we are referring to, rather we are bringing them into existence with our definition. (If this were valid syntax, which of course it's not.)

(The analogy does break down if you consider that 1, 2, 3 etc. are also values of type Integer, Int8, Int16, Int32, Word8 etc. which are all distinct types (numeric literals are in fact polymorphic), but it kind of works if you pretend that only Int exists.)

@emberian
Copy link
Member

Visiting for triage. I don't think this is important.

@Aatch
Copy link
Contributor

Aatch commented Mar 23, 2014

If anybody is still interested in this, an official RFC should be filed. https://github.com/rust-lang/rfcs/blob/master/active/0001-rfc-process.md

@Aatch Aatch closed this as completed Mar 23, 2014
Aaron1011 added a commit to Aaron1011/rust that referenced this issue Mar 7, 2021
Output of `git log --oneline  c68432f1e..970bc67c3`:

970bc67c3 (HEAD, origin/master, origin/auto-cargo, origin/HEAD) Auto merge of rust-lang#9243 - wickerwaka:configurable-env-doc, r=ehuss
4d7a29b75 Document the configurable-env usntable option
f7a7a3f91 Auto merge of rust-lang#9229 - alexcrichton:fix-borrow-mut, r=ehuss
3f2ece7a9 Fix a `BorrowMut` error when stdout is closed
7441e8c23 Auto merge of rust-lang#8825 - Aaron1011:feature/report-future-incompat, r=ehuss
139ed73f5 Add future-incompat tracking issue number.
9ea350368 Fix some minor formatting issues.
f03d47ce4 Address review comments
6177c6584 Implement future incompatibility report support
c69409658 Auto merge of rust-lang#9022 - nagisa:nagisa/manifest_path, r=alexcrichton
548300b20 Add the path to the manifest in json output
99e714c05 Auto merge of rust-lang#9230 - kornelski:nobinaries, r=alexcrichton
61a31bc5f Auto merge of rust-lang#9236 - kornelski:track-assert, r=Eh2406
3f7f0942c track_caller on custom assert functions
6977dee10 Explain `cargo install` is not for libraries
e4aebf0a0 Auto merge of rust-lang#9231 - joshtriplett:clear-to-eol-if-color, r=alexcrichton
b219f0eb7 Auto merge of rust-lang#9181 - jyn514:computer-says-no, r=ehuss
0b1816578 Remove unhelpful link to Cargo book
ea46f5ce3 Use ANSI clear-to-EOL if color is force-enabled
a6394bcc1 Remove unnecessary `config` argument to `Features::add`
3a86ecf2d Fix TODO about nightly features
09677c83c Be less unix-centric in error messages
ecfdced0d Fix test that assumed tests always were run on the stable channel
eba541994 Update comment in build_script_env
a5720117f Make `nightly_features_allowed` a field instead of a function
169b09ce7 Compute `enable_nightly_features` once instead of on each call
8fc86e155 Remove unused thread_locals
4b096beae Fix `masquerade_as_nightly_cargo` in work threads
e56417c8c Suggest RUSTC_BOOTSTRAP=crate instead of RUSTC_BOOTSTRAP=1
418129dae Downgrade error to a warning when `RUSTC_BOOTSTRAP` is set or this is the nightly channel
6c422a2c0 Restrict RUSTC_BOOTSTRAP in build.rs
m-ou-se added a commit to m-ou-se/rust that referenced this issue Mar 9, 2021
Update Cargo

Output of `git log --oneline  c68432f1e..970bc67c3`:

970bc67c3 (HEAD, origin/master, origin/auto-cargo, origin/HEAD) Auto merge of rust-lang#9243 - wickerwaka:configurable-env-doc, r=ehuss
4d7a29b75 Document the configurable-env usntable option
f7a7a3f91 Auto merge of rust-lang#9229 - alexcrichton:fix-borrow-mut, r=ehuss
3f2ece7a9 Fix a `BorrowMut` error when stdout is closed
7441e8c23 Auto merge of rust-lang#8825 - Aaron1011:feature/report-future-incompat, r=ehuss
139ed73f5 Add future-incompat tracking issue number.
9ea350368 Fix some minor formatting issues.
f03d47ce4 Address review comments
6177c6584 Implement future incompatibility report support
c69409658 Auto merge of rust-lang#9022 - nagisa:nagisa/manifest_path, r=alexcrichton
548300b20 Add the path to the manifest in json output
99e714c05 Auto merge of rust-lang#9230 - kornelski:nobinaries, r=alexcrichton
61a31bc5f Auto merge of rust-lang#9236 - kornelski:track-assert, r=Eh2406
3f7f0942c track_caller on custom assert functions
6977dee10 Explain `cargo install` is not for libraries
e4aebf0a0 Auto merge of rust-lang#9231 - joshtriplett:clear-to-eol-if-color, r=alexcrichton
b219f0eb7 Auto merge of rust-lang#9181 - jyn514:computer-says-no, r=ehuss
0b1816578 Remove unhelpful link to Cargo book
ea46f5ce3 Use ANSI clear-to-EOL if color is force-enabled
a6394bcc1 Remove unnecessary `config` argument to `Features::add`
3a86ecf2d Fix TODO about nightly features
09677c83c Be less unix-centric in error messages
ecfdced0d Fix test that assumed tests always were run on the stable channel
eba541994 Update comment in build_script_env
a5720117f Make `nightly_features_allowed` a field instead of a function
169b09ce7 Compute `enable_nightly_features` once instead of on each call
8fc86e155 Remove unused thread_locals
4b096beae Fix `masquerade_as_nightly_cargo` in work threads
e56417c8c Suggest RUSTC_BOOTSTRAP=crate instead of RUSTC_BOOTSTRAP=1
418129dae Downgrade error to a warning when `RUSTC_BOOTSTRAP` is set or this is the nightly channel
6c422a2c0 Restrict RUSTC_BOOTSTRAP in build.rs
flip1995 pushed a commit to flip1995/rust that referenced this issue Jul 28, 2022
…omparisons_doc, r=dswij

Update case_sensitive_file_extension_comparisons example

Closing rust-lang#9220

changelog: [`case_sensitive_file_extension_comparisons`]: update example
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-type-system Area: Type system
Projects
None yet
Development

No branches or pull requests

5 participants