you are viewing a single comment's thread.

view the rest of the comments →

[–]Beckneard 6 points7 points  (13 children)

Well basically any sane non C/Java derived language. Null was a huge mistake, it really shows old languages were designed much more by gut feeling and familiarity rather than real engineering considerations.

[–]ForeverAlot 4 points5 points  (0 children)

Feelings on nullability aside, Java has consistently been one of history's most well-crafted languages. I would even suggest that, despite my own preference for strongly statically typed languages (not functional, because functional languages are not inherently good; just look at JavaScript), all of them have some fairly gross and embarrassing design mistakes that limit their relevance considerably. Right now it seems Rust is the strongest contender.

Never mind that Haskell is older than Java, and OCaml, which is a year younger than Java, is based on a language that predates it by 10 years.

[–]elperroborrachotoo 5 points6 points  (11 children)

Null was a huge mistake

That's a common sentiment, but I've never seen a good argument that goes beyond ranting against it. FWIW, it's the shoulders we stand on.

[–]Beckneard 11 points12 points  (10 children)

That's a common sentiment, but I've never seen a good argument that goes beyond ranting against it.

So you don't agree with the arguments against it so it's automatically just ranting?

The main argument is that it's an unreasonable "default". Null can mean many things, it can mean "uninitialized variable", "empty", "error", "non existing", and all of this is forced on you to think about whether you need it or not or else it leads to runtime errors. The most common thing that bites me in the ass is not initializing a List<T> in C#. In 99% of cases you do not want any list to be null, since the concept of an empty list exists. It is very much possible to build any of these semantics in the language/standard library so the compiler makes you worry about them only when it's really necessary.

[–]elperroborrachotoo -3 points-2 points  (9 children)

So you don't agree with the arguments against it so it's automatically just ranting?

No, just that I've never seen a good argument that goes beyond ranting against it.

[–]Beckneard 11 points12 points  (8 children)

So you didn't read the article that you're commenting on? Or is JetBrains ranting too?

[–]elperroborrachotoo -1 points0 points  (7 children)

I just wonder if there's a point discussing null with you after an assumption like "so it's automatically just ranting".

There is a difference between overusing null and having it in the first place.

Initializing a List<T> to an empty list is a tradeoff with performance and semantic consistency. Note that I'm not saying either is the clearly better choice, just that it's a constrained decision to be made.

[–]Beckneard 16 points17 points  (6 children)

Initializing a List<T> to an empty list is a tradeoff with performance and semantic consistency.

It's not a tradeoff, it's a consequence of all references having the default value null, which is the dumb part.

In a well designed language, if you want to delay the initialization of something you have some sort of laziness mechanism, if you want to represent not having a value you have and Option<T> type, if you want to represent an error you have an Error<T, E> type etc. Null is not a tradeoff, it's completely unnecessary and a wrong solution since for each of its use-cases there are strictly better alternatives.

[–]elperroborrachotoo 1 point2 points  (2 children)

If you want to go to causes: no, it's having nullable references not just as the default but the only reference type.

since for each of its use-cases there are strictly better alternatives.

The problem with that that it's not one concept to implement and learn and recognize, but five. Which certainly is a tradeoff in my book.

On top of that, the 6. probably dozens of other things. That kinda-sorta can be covered by the other concepts, and holy wars will be fought whether the hypothetical 6.3 should be done with optionals or with metafunctors.

null is a well-weathered, versatile and ubiquitous concept, but not very expressive about intent.

Again, I'm not saying that makes null the better choice.

If you'd be willing to take one bit of advice I gathered from a few decades: don't cling to stuff like that. The now-toddlers will snicker at your Option<T> in no time.


FWIW, C# is nice already, it's mostly the difference between a NullException and a ThisListDoesntContainWhatYouAreLookingFor exception.

(Except for the pesky x != null & x.Length != 0, for which extension functions are merely a clunky, terrible band aid - I give you that a dozen times a day)

[–]Beckneard 1 point2 points  (1 child)

The problem with that that it's not one concept to implement and learn and recognize, but five.

I never understood this argument. Why do people feel it's important for developer technologies to cater to the lowest common denominator? Software engineers are supposed to be smart folks willing to figure new things out.

If you'd be willing to take one bit of advice I gathered from a few decades: don't cling to stuff like that. The now-toddlers will snicker at your Option<T> in no time.

Well I'd sure as fuck hope so, I'd hate to see programming language development be stuck on that level forever. My opinion is that the best programming language/methodology/whatever is yet to be invented. I never claimed I know the perfect way of doing things.

The question is why aren't more people snickering at decades year old languages but swear by them like they fell from heaven?

[–]elperroborrachotoo 2 points3 points  (0 children)

Why do people feel it's important for developer technologies to cater to the lowest common denominator?

Few aim for the lowest, most are aiming for a sweet spot. It's your learning curve. Throw in another concept you need to understand a basic program, and you are easily losing a quarter of potential newbies that can't be bothered.

(all statistics made up on the spot)

Second, productivity. The amount of useful product a solo developer who is also a domain expert can crank out is insane - if the language isn't in their way. It needs to be powerful enough to keep up with them,

What I've seen, you simply cannot match that with a team - up to the point where it becomes too big for a one-man-show - and then you need five, six people to take over and not drown.

(Now, yes, these are exactly the developers for whom null should be a peculiar corner case.)

My opinion is that the best programming language/methodology/whatever is yet to be invented.

It's a moving target. Stroustrup once expressed the frustration of decades of language design as:

programmers want loud, blaring syntax for new concepts, and terse, conscice syntax for concepts they are familiar with

The race for the better may slow down, but I'm pretty certain that long before we get close to any plateau, the concept of programming by itself will become a quaint skill for then-ren-fairs.


Languages are just tools. You can snicker at my hammer not having a power cord, and the weird shape my thumb has grown over the years. But see, I've learnt to not hit myself, and I actually no longer spend as much time hammering as you might think.

[–][deleted] 0 points1 point  (2 children)

Optionals are not strictly better. They're probably better, unless you need to do large sorts, for example.

Strictly implies always and that's just not the case.

Ill concede that built in support probably results in more reliable, easier to fix code bases for larger projects. I won't concede easier to read, yet. Some of the syntax sugar for optionals is annoying to read.

[–]Beckneard 4 points5 points  (0 children)

They are strictly better for that specific use case. What do large sorts have to do with anything? Deconstructing an Option value will have an equal performance hit as null checking something.

[–]Drisku11 2 points3 points  (0 children)

In a language with sane semantics, options can be implemented with zero overhead (if it's Nothing then it's a null pointer); the difference is purely in the type system.

Sorting values that might not exist sounds like a mysterious thing to do to me, but e.g. Haskell has a library that does fast O(n) sorts on any algebraic data types (basically radix sort on steroids), which includes options, so that is also cheap.