Hacker Newsnew | past | comments | ask | show | jobs | submit | mrkeen's commentslogin

> First, the null pointer is essentially inevitable if you want to model the world, which has references (things containing denotations of other things).

I took major exception to this. The real world doesn't have non-things, and references do not demand to refer to non-things.

If your domain does actually have the concept of null, just make a type for it. Then you won't accidentally use a 6 or a "foo" where a null was demanded.


And I would just add:

Do we want to model the "real world"? This seems to hark back to that long-forgotten world of "animal-cat-dog" OO programming.


I spent the bulk of my career modelling a small part of the real world and OOP absolutely has a place in that.

Tony Hoare himself said that it wasn't needed in the type system he'd created. He added it because it was so easy to do so and couldn't resist the temptation.

OTOH seeing undefined method 'blah' for nil:NilClass isn't really any better.


The real world is full of relationships that may or may not exist. What’s the referent of “my spouse” if I’m unmarried?

Is your point here that every pointer type for which this can be the case should include an explicitly typed null value?


> What’s the referent of “my spouse” if I’m unmarried?

* It's the same referent as all the other things you don't have. Your struct has a Spouse, why does it not also have a RivieraChateau, a SantaClaus, BankAccountInSwissFrancs. If you can answer why you left those out, you know why to leave out Spouse.

* Why stick to 0-1 Spouses. As soon as you do that you're gonna need n Spouses, where some of them will have an ex- flag set, married from&to timestamps.

> Is your point here that every pointer type for which this can be the case should include an explicitly typed null value?

* It shouldn't make a difference whether it's a pointer or a reference or a value or a class. If you believe null is one of the Integers, you should also believe that null is one of the ints. Why should your domain change to accommodate C idioms.


Making it explicit wouldn’t be particularly problematic no? Option<&Spouse> in Rust terms. Or for this specific case, a GADT (Single | Married<&Spouse>)?

It could even use a special “NULL” address. Just don’t pollute every type with it.


Polluting every type with it is just a very bad implementation which has nothing in common with the concept of NULL as proposed by Tony Hoare in the paper "Record Handling".

The concept as proposed by Hoare is strictly necessary for things like partial relations, which are encountered very frequently in practice.

It is true however that a large number of programming languages have misused the concept of a NULL reference proposed by Hoare.

As you say, there must be distinct types that may have or may not have a "nothing" value.


> The concept as proposed by Hoare is strictly necessary for things like partial relations

I read the 'Partial Functional Relationships' section. There's nothing special there. It's just structs with nulls.

> Polluting every type with it I think you're reacting to the pollution of the syntax. Hoare already polluted the semantics: Every type can be null. You can't even model a NonNull<Spouse> because NonNull itself can be null.


Another example a web link that points to a page that no lnger exists.

It's a null pointer exception.


The benefit of values over classes is that they do not hide machinery.

If you x.getY(), is that a member access, a computed value, or a network fetch? Will it lazy-instantiate a log4j singleton and start spamming my IDE with red text? I refuse the OO dogma that x should be a black box, and I as the programmer on the outside should not concern myself with its implementation details.

Onto TFA's parser example:

  typedef struct Parser {
      // fields
  } Parser;

  Statement  parser_parse_statement(Parser *p);
  Expression parser_parse_expression(Parser *p);
  void       parser_expect(Parser *p, const char *message);
  void       parser_next(Parser *p);
  TokenKind  parser_current(const Parser *p);
> It sounds like “data should not have ‘behavior’” is being violated here, no? If not, what’s the difference between this module and a class?

Correct. You can write OO in any language, and this parser hides machinery and is acting like a class, not a value. Look at those voids - those methods either do nothing, or they modify the insides of the parser. I certainly can't combine them like I could with values, e.g.:

  Parser *p = choice (parse_statement, parse_expression);
The above cannot work - whose internal machinery should choice adopt?

It is much easier to parse without hidden machinery. Combine them like values, e.g.:

  Parser parser_block   = many (parse_statement);
  Parser parser_sum     = seperateWith (parser_plus, parser_product)
  Parser parser_product = separateWith (parser_times, parser_value)
  Parser parser_value   = choice (parser_literal, parser_variable)
No voids, no internal machinery, any parser_literal is the exact same thing as any other parser_literal.

Then just unhide the internal cursor or success/failure state (or whatever other machinery is hidden in there) and pass them in as values:

  (result, remainder_string) = run_parser (parser_block, input_string);

> just have the take! function return an optional map

A map of what ?


Because people like TFA pay them not to. It doesn't matter how much you hope Apple changes course - you vote with your wallet.

Yep, JavaScript got the bad version from Java too!

https://news.ycombinator.com/item?id=42816135


I read the article. Parent's comment about automation is spot on. TFA didn't describe any GUI interaction in detail, or even suggest that there was a way to achieve these goals without needing a meatbag to physically interact with the computer (and capture its output in /dev/meatbrain).

But at least TFA wrote up the criticism in text, even transcribing some of the screenshots.


It's too much of a stretch to call null an escape hatch, or to pretend that code reviews will somehow strip it out.

The OpenJDK HashMap returns null from get(), put() and remove(), among others. Is this just because it hasn't been reviewed enough yet?


> pretend that code reviews will somehow strip it out.

Code reviews 'somehow' strip out poorly thought out new uses of escape hatches.

For your example, it would be an use of get, put or remove without checking the result.


Just as bad if it's human. No information has been shared. The writer has turned idle wondering into prose:

> Once threads actually run concurrently, libraries (which?) that never needed locking (contradiction?) could (will they or won't they?) start hitting race conditions in surprising (go on, surprise me) places.


Property appreciates over time. It's a cheat-code for more money, not a wasteful expense.

It made no reference to the 'shared' in 'shared state'.

No mention of asynchrony, multithreading, or the race condition that TFA encountered.


The “attempt 2” was literally a state machine implementation which the author rejected because they didn’t know how to do it properly and so did it badly using a bunch of if then else logic.

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

Search: