News for hackers. Stuff that matters.
Re:Is your programming language unreasonable? (2015) by tzs on Saturday October 10, 2020 @12:07PM (#24739857)
In example #6, he gives this as the unreasonable approach:

  var repo = new CustomerRepository();
  var customer = repo.GetById(42);
  Console.WriteLine(customer.Id);
with the issue being customer can be null, which is not being accounted for. The reasonable approach he says is to use a sum type:

  var repo = new CustomerRepository();
  var customerOrError = repo.GetById(42);
  if (customerOrError.IsCustomer)
      Console.WriteLine(customerOrError.Customer.Id);
  if (customerOrError.IsError)
      Console.WriteLine(customerOrError.ErrorMessage);
Do most (or any) languages in which people take this approach actually enforce handling of all cases? Or could a programmer write that this way:

  var repo = new CustomerRepository();
  var customerOrError = repo.GetById(42);
  Console.WriteLine(customerOrError.Customer.Id);
and still have the same problem as the original?

It seems to me that the "reasonable" version is getting its reasonableness from naming the variable that gets the GetById return "customerOrError" which reminds the reader that there is an error case, not from the language having sum types. That's just a convention. Nothing stops you from naming it "customer" just like in the "unreasonable" language.

(I'd actually expect that from a lot of people, because you are probably going to have a lot more code in the case that you have gotten the Customer variant than in the Error variant case, and you probably don't want to be calling it customerOrError in the 99% of the code where you know that it is a Customer).

Re:Is your programming language unreasonable? (2015) by isaacabraham79 on Saturday October 10, 2020 @12:33PM (#24740049)
No. In languages like F#, you can encode in the type system that the result can be either a customer or an error. And the compiler won't let you "access" the customer until you've safely checked that the result is, indeed, the customer rather than an error.

In this way you end up encoding more intent within your types and behaviours rather than implicitly letting the consumer figure it out themselves.

Re:Is your programming language unreasonable? (2015) by scubbo on Sunday October 11, 2020 @02:34PM (#24747957)
> the compiler won't let you "access" the customer until you've safely checked that the result is, indeed, the customer rather than an error.

/u/anw's example shows that, in fact, the benefits of the type system are greater than that. Not only can the type system prevent you from accessing data before confirming that the data is present (which is, at the end of the day, not much better than an Optional type, already available in Java and others), but it can also prompt you to "handle" all possible cases.

Re:Is your programming language unreasonable? (2015) by whoisburbansky on Saturday October 10, 2020 @12:54PM (#24740213)
Adding to this, it's nice to have the compiler enforce these things rather than rely on the dev to see the variable name and treat it accordingly. In the latter case, you're one sleepy afternoon away from having things blow up in production because you "thought there was no way that that variable could be a null pointer"
Re:Is your programming language unreasonable? (2015) by masklinn on Saturday October 10, 2020 @02:51PM (#24740999)
> Do most (or any) languages in which people take this approach actually enforce handling of all cases?

In "most functional languages", your result would be a sum type which requires dispatching explicitly between one case or the other, aka you wouldn't have a pair of conditionals instead you'd have something along the lines

    switch (customerOrError) {
        case IsCustomer(customer):
            Console.WriteLine(customer.ID);
        case IsError(errorMessage):
            Console.WriteLine(errorMessage);
    }
so from `customerOrError` you wouldn't have any sort of direct access to the customer or error, you must go through a dispatching construct.

In OO languages lacking sum types this sort of constructs would generally be implemented through lambdas or some sort of visitor e.g.

    customerOrError.then(
        customer => { Console.WriteLine(customer.Id); },
        onError: errorMessage => { Console.WriteLine(errorMessage) }
    );
Re:Is your programming language unreasonable? (2015) by anw on Saturday October 10, 2020 @12:41PM (#24740117)
> Do most (or any) languages in which people take this approach actually enforce handling of all cases?

I'm not familiar with most languages, but I can state that Rust requires matching sum types to cover all possible variants. For example:

    enum Animal {
        Dog,
        Cat,
        Pigeon
    }
    let pet = Animal::Dog;
    let sound = match pet {
        Animal::Dog => String::from("ouaf"),
        Animal::Cat => String::from("miaou")
    };
This would not compile, because you've forgotten to cover the pigeon. You would need to either add one of the two lines below:

    Animal::Pigeon => String::from("rou rou")
or

    _ => String::from("eeeeeeeeeeeei")
The last line is a catch all, which would cover anything not checked for explicitly.
Re:Is your programming language unreasonable? (2015) by eyelidlessness on Saturday October 10, 2020 @07:16PM (#24742612)
> Do most (or any) languages in which people take this approach actually enforce handling of all cases? Or could a programmer write that this way: [...]

Any language that provides this sort of union type will error in some way if you try to access something that isn’t guaranteed to be on every type in the union. Some languages which support null checking will infer Customer to be nullable.

Re:Is your programming language unreasonable? (2015) by edflsafoiewq on Saturday October 10, 2020 @01:27PM (#24740416)
Typescript allows this

  const c = getCustomer();  // type is Customer | null
  const z : Customer = c;   // ERROR; incompatible types
  if (x === null) {
    // handle null
  } else {
    const y : Customer = c; // OK; knows c isn't null here
  }
Re:Is your programming language unreasonable? (2015) by throw_m239339 on Saturday October 10, 2020 @01:55PM (#24740628)
Well Typescript is really a static code analyser for Javascript and not a language, since it does nothing at runtime, and that's fine, its type system can catch a broad range of issues and improve code quality drastically. It's a huge godsend for big codebases. But afaik it doesn't guard against null by default.

A simpler example:

    declare type Foo = {name:String};
    declare function getFoo():Foo|null;

    const f = getFoo();
    if(f!==null) // mandatory or yields an error
        console.log(f.name);

But afaik it doesn't guard against null by default.