Live data from Hacker News

Sum Types in Julia and Rust

andreaskroepelin.de

31–40 of 70 posts

Re: Sum Types in Julia and Rust

#31
post #3

I may be wrong, but I don't think this is what people mean by 'sum types'. I was expecting union types (e.g., https://www.typescriptlang.org/docs/handbook/unions-and-inte... or https://dotty.epfl.ch/docs/reference/new-types/union-types.h... ) I guess enums are a type of sum type, but seems this is more specifically about enums

Even the word "enum" is quite overloaded; i.e. compare Swift's robust class-like enums with those of C or C++.

Re: Sum Types in Julia and Rust

#32
post #28

There are sum types, and product types, but what would "exponentiation types" look like?

Fixed-length sequences, but they would be constructed from a type and a non-negative integer, not from two types.

The sum of a type with m possible values and a type with n possible values has (m+n) possible values, the product of a type with m possible values and a type with n possible values has (m×n) possible values, a sequence of n items of a type with m possible values has m^n possible values.

Re: Sum Types in Julia and Rust

#33
post #16

Two thoughts: For this problem, I would use union types in Julia. Union types are a sort of sum, but they are amalgamated sums whilst sums types in PL semantics usually means disjoint sums. The difference is that disjoint sums 'mark' whether a value is of the left or right type, while with amalgamated sums the value may belong unmarked to the intersection. The distinction does not matter in the example the post gives…

Julia is a dynamic language, I don't think having the rigor of a compiled language (probably the most rigorous out there) is a reasonable expectation. It would be nice to have as an external linter service, probably.

It is possible to check type coverage for dynamically typed languages, if the compiler/interpreter has enough type information to infer what types need coverage. In the case of multimethods, Julia's compiler is given this information.

Re: Sum Types in Julia and Rust

#34
Someone Rustier than I am, what's the story with this enum solution when I want to add a _new_ star later? Can one implement this in a way that respects the open-closed principle?

Re: Sum Types in Julia and Rust

#35
post #34

Someone Rustier than I am, what's the story with this enum solution when I want to add a _new_ star later? Can one implement this in a way that respects the open-closed principle?

You can flag an enum as `non_exhaustive` to indicate that it might contain additional values in the future.

If you do that, then anyone writing the code must add code to handle other cases, or it's a compile error (i.e. you must match the enum as:

  #[non_exhaustive]
  enum Foo {
      CaseA,
      CaseB
  }

  let f : Foo = get_foo();

  match foo {
      CaseA => {},
      CaseB => {},
      // Exhaustive matching
      _ => {},
  }
https://doc.rust-lang.org/reference/attributes/type_system.h...

Re: Sum Types in Julia and Rust

#36
post #6

Earlier quoted context omitted.

I believe another word for enums (in the Rust sense, not in the C++ or Java sense) are tagged unions.

That's right. It's unfortunate that Rust calls them "enums", since as you noted that term already had a well-established meaning in other languages, and the concept that Rust calls "enums" also had several existing names (sum type, coproduct type, disjoint union, and, more generally, algebraic data type) in the literature and in prior languages. Language designers: stop changing the meanings of words! I know you mean…

Rust enums are also enums:

  enum Colour {
    Red,
    Blue,
    Green,
  }
is fine.

Re: Sum Types in Julia and Rust

#38
post #34

Someone Rustier than I am, what's the story with this enum solution when I want to add a _new_ star later? Can one implement this in a way that respects the open-closed principle?

You can flag an enum as `non_exhaustive` to indicate that it might contain additional values in the future. If you do that, then anyone writing the code must add code to handle other cases, or it's a compile error (i.e. you must match the enum as: #[non_exhaustive] enum Foo { CaseA, CaseB } let f : Foo = get_foo(); match foo { CaseA => {}, CaseB => {}, // Exhaustive matching _ => {}, } https://doc.rust-lang.org/refer…

But how can the PlayerClass trait methods get extended in the future without opening them back up to add cases to the match expression?

Re: Sum Types in Julia and Rust

#39
post #28

There are sum types, and product types, but what would "exponentiation types" look like?

Exponential types are functions [1]. The type A -> B could be written B^A. Interestingly, if you take functions to be lookup tables, then that's related to the number of possible unique lookup tables. First, notice that the type A + B has |A| + |B| values, the type A × B has |A| + |B| values and then we can see that A -> B has |B|^|A| values by remembering that functions can be seen as binary relations with the property of being functional. This means that there are |B|^|A| possible unique functions. Try an example by counting the number of functions from the set { 0, 1 } to { 2, 3, 4 }. You will see that there are 3^2 = 9 possible unique functions.

1. https://en.wikipedia.org/wiki/Function_type

Re: Sum Types in Julia and Rust

#40

fn greet (&self, other: &T); Yeah, this doesn't work, but the equivalent to what you are writing in Julia does: fn greet(&self, other: Box );

I’m not sure what is meant here, because that top example would compile.

edit - Alright I think I see what the original article was trying to express. In the original article that top example method was defined as part of a trait. Because that method is generic that would make the trait not object safe. On its own that is fine (this would still compile), but there was some previous example code which relied on this trait being object safe.

Post reply on HN