Hacker News new | ask | show | jobs
by xavxav 1324 days ago
I know that this is a common wish, but anonymous sum types have pretty catastrophic impacts on type checking and lead to all sorts of bizarre corner cases like the following:

  let a = if cond {
    1 
  } else {
    1.0
  };
  
  a + 3
Now, the error would be pushed to the `+` operator because there isn't an `Add` for `f32 | u32`. Granted, this is a trivial example, and a programmer can easily see through it, but in general this can get very overwhelming and cause errors to leave their 'root cause'.
3 comments

Typescript seems to have no problem with it (nor do I suspect F#/OCaml):

  class A {
    x = 10;
    scale(n: number): void {
      this.x *= n;
    }
  }
  class B {
    y = 10;
    scale(n: number): void {
      this.y *= n;
    }
  }  
  var z: A | B;
  z = new A
  z.scale(2);
  z = new B
  z.scale(2);
I was also looking for Sum Types/anonymous enums[0].

[0] https://news.ycombinator.com/threads?id=karmakaze&next=33505...

One option might be to differentiate syntactically between branches of an if/match that are allowed to expand their type (to a union or to a bigger union) and those that are not. I am not sure how far that generalizes, though.
> Now, the error would be pushed to the `+` operator because there isn't an `Add` for `f32 | u32`.

Why not? It makes total sense for one to exist. This is something the language needs to deal with, not the programmer. But the programmer always sprinkle annotations so that errors can only reach so far.

> It makes total sense for one to exist.

I disagree: IME, when you add a float and an integer, you want to cast float to integer 50% of the time, and integer to float the remaining 50% of the time.

Even if it leads to more verbosity, I prefer arithmetic operations to be endomorphisms and use explicit casts.

I'm sure you can just use a linter or configure the compiler to error out in such a case if there are really no use-cases, no?
What do you mean? It already errors out if you try adding them together because it requires explicit casts. What the comment you're replying to is saying is that it's better to just explicitly cast than figure out what the compiler guesses.

    let x=19/10+0.5
I want to decide for myself if my result is 2.4, 1.5, 1, or 2 in the example above
The OP doesn't like that the error moves from the condition to the addition. And what I mean is that then just lint that there shouldn't be unions of number-types or so.
I think the ramifications of `Add` (and friends) for union types is interesting, but I think we can imagine alternatives that are clearly mistakes and so it seems like you're missing the point (... is my guess about the downvotes). Your last sentence makes an important point, though - relying on type inference always lets type errors propagate further than they would if everything was explicitly typed. Adding more annotations constrains that, although whether that would be sufficient is a more complicated discussion that's probably quite sensitive to the particulars of a given language.
Yeah that's true.

But also, for every developer with a couple of month experience, this is not a new problem. It happens all the time, be it missing some parens or a dot or a return / semicolon (depending on the language of course).

Usually it's very easy to hunt it down - you see "a + 1" and you say "wait, a should be an integer - why is it not" and then you go back from there. But in general I agree that it adds some time in such cases that would be resolved quicker with annotations everywhere.