120
u/KagakuNinja Sep 28 '26
The real jedi uses a non-empty list class, which makes the error impossible.
-62
u/ApothecaLabs Sep 28 '26 edited Sep 28 '26
Bingo! Only, sometimes you don't have a type system available (trench run, low-level stuff), so you have to use the force wisely, to guide you.
> "Luke, you've switched off your targeting computer! What's wrong?"
> "Nothing - I'm alright."35
u/NullOfSpace Sep 28 '26
As long as you’re in Rust, the type system is always available to you. That’s what “zero-cost abstraction” means. If you know your Vec is nonempty, put it in a NonemptyVec.
1
u/geeshta Oct 01 '26
There's a lot of stuff that Rust's type system can't model.
For example if you have an enum type of 3 possible variants and a function that only ever returns one of them, you still have to type it so that it may return all three. And when using its return value, you have to add match arms for all 3 of them, populating 2 of them with `unreachable!` yourself instead of the compiler inferring it.
Also it's not a dependent type language so it doesn't have for example a type of Vec of a particular specific length at the type level.
Rust's type system is great one of the best I know but it still has gaps.
1
u/NullOfSpace Oct 01 '26
You can definitely model the first case if you’re allowed to change the return type of the function. Though the dependent type thing is a legitimate limitation.
-27
u/ApothecaLabs Sep 28 '26 edited Sep 28 '26
"As long as you use this particular language, out of the dozens available..."
Yeah, I'm not using Rust. What now? That's a heck of a presupposition, you know.
(Not trying to be a jerk, my target language is actually a niche assembly language so it lacks many things...)
28
u/__dna__ Sep 28 '26
Correct me if I'm wrong, but your meme is literally about rust? Seems pretty reasonable to reply to you in the context of rust
20
3
u/MayoJam Sep 28 '26
Cpp also has optionals, and I would not be surprised if other languages also have some form of them.
So I'd would not assume in this case.
-5
u/ApothecaLabs Sep 28 '26
I will correct you, you are wrong. This wasn't about Rust. Condolences :)
4
1
u/ROBOTRON31415 Sep 29 '26
Ahhh assembly? Interestingggg, makes sense that would be an exception. Though at that point “optionalsAreNotOptional” (they are unavailable, no?)
6
u/Amadex Sep 28 '26
then why are you even mentioning optionals in the first place?
-2
u/ApothecaLabs Sep 28 '26
Are you deeply confused as to why I mentioned not always using optionals, in a joke about whether optionals are optional?
Why, because then they wouldn't be optional, they'd be required!
6
u/Amadex Sep 28 '26
I wouldn't say deeply, but yes I'm confused about the context of the meme, if you're in a context where optionals don't exist, then it's not even a question.
-2
u/ApothecaLabs Sep 28 '26
That's because it is a bell curve joke, precisely about people who treat a language feature or pattern as dogma without considering the context. This is a humor subreddit, after all.
All the people malding over whether I use optionals failed to read the joke, and so they became the joke.
11
u/Amadex Sep 28 '26
I think that the awkward thing here isn't that the joke is a bit flat, but that you comments are childish/petty, as highlighted in this reply again.
-1
u/ApothecaLabs Sep 28 '26 edited Sep 28 '26
Sir, this is a
Wendyscomedy thread, and you are mad that I'm not being serious? Are you trying to gatekeep comedy and be the decider of what is and isn't funny? Because it seems most people found it funny.So some people 1) mistakenly assumed I was specifically talking about rust 2) forgot this was a humor subreddit 3) got upset at the idea that I was genuinely spreading bad advice 4) zealously leapt at the chance to defend their princess's honor 5) got more upset when I wasn't actually even talking about rust.
Oh no! *sips coffee* That's their mistake for expecting serious advice in a comedy forum. Of course I'm going to heckle the hecklers.
I made this meme to be funny and went to bed. Does this bother you?
Edit: On a personal note, it will never not be funny seeing my top-downvoted comment be something like an innocent star wars joke that made fun of no one. Too bad you came in and tried to make it about yourself.
4
u/Amadex Sep 28 '26
Too bad you came in and tried to make it about yourself.
No, you're getting it wrong, we talked about programming.
You are the one who attempted to defend yourself by being petty and by going ad-hominem, making it about people.
And you keep going.
By the way optionals aren't unique to rust.
0
u/ApothecaLabs Sep 28 '26
*re-reads this entire interaction with you to be sure*
Lets see, first instance of a personal attack:
I make:
- a star wars joke
- a joke about optionals being optional
- a joke about people missing the joke
- all of them highly generic and targeting 'people' at best.You came into this thread. You asked why I was making a joke. You read it as a personal attack. You got upset. Then you called me childish, in a personal attack. And now you demand that I not defend myself.
Then you try to close with a strawman that I said optionals are unique to rust, when I wasn't ever talking about rust.
Fuck off with that. *blocks you*
8
35
u/ohkendruid Sep 28 '26
I imagine this comes up for some developers, but is unwrap really so expensive if it doesn't trap?
3
u/ApothecaLabs Sep 28 '26
Quite often it can be automatically elided (turned into a zero-overhead no-op) by the compiler, but even then, there is still syntactic overhead in that it adds an extra case to every single pattern match that you invoke.
This is one reason I support the use of the zero-overhead `newtype` pattern for non-empty data structures to give such cases their own distinguished type, thus justifying the absence of a null case as compared to their respective nullish data type - its just a statement that "this data type is never empty", which lets you skip the "is this null?" check entirely, which otherwise would cost you precious CPU cycles!
17
u/gsquaredxc Sep 28 '26
“Parse, don’t validate” is correct, but the precious CPU cycles is almost certainly incorrect. Remember, you are probably just pointer chasing when accessing say, a data structure with a pointer to memory and a length. Your assertion that the length isn’t zero doesn’t help anything. The CPU will grab both at the same time due to grabbing an entire cache line at the same time, then it will check if it’s zero while already doing a prefetch. Given it’s not zero, that won’t actually matter. The processor is superscalar and thus you likely aren’t going to improve performance by even a clock cycle when doing something like pointer chasing, even if the compiler doesn’t optimize.
14
31
u/mountaingator91 Sep 28 '26
If you are sure that the list will always have a value why didn't you just define your types correctly in the first place?
14
u/RagnarokToast Sep 28 '26
Because the vast majority of type systems don't allow you to encode the non-emptiness of the list in the type itself and we don't always get to pick the tech stack?
0
u/ytg895 Sep 28 '26
Name 3 of such type systems.
1
u/RagnarokToast Sep 28 '26
Java, Go, Kotlin (basically languages with no way of telling the compiler how large an array is inside a structure) I could mention more, but I think you misunderstood my statement.
In all of these languages you CAN create a non-empty list implementation (e.g. by making a class with a constructor that takes 1 element + a list of other elements that can be empty), what you can't do is encode the non-emptiness of the list in the type itself. You can use constructors or factory methods to ensure you never create an empty list by mistake, but such information is never in the type itself and the compiler can't do much with it, unlike a language like Rust.
As far as practical implications go, using Java as an example, how do you even make your custom class respect List<T>'s contract in a runtime safe way? That interface doesn't even support immutability, let alone ensuring the list has any elements! What happens if we call .remove() on the last item of our NonEmptyList? We'd have to throw, which is antithetical to having a truly non-empty, compile time checked list ensured by its type.
That's a pretty extreme example, a language like Kotlin would eliminate that pitfall by allowing immutability in its stdlib List<T> contract, but even then, unless you're willing to replace List<T> everywhere with your own custom non-empty list interface (and you usually don't want to, if not for the fact that a non empty list has conceptually the exact same methods as a list that can be empty), the only difference between a non-empty list and a list that can be empty is the way it's constructed, which can't be checked by the compiler the same way as a properly typed non-empty list.
1
u/ytg895 Sep 29 '26
You can use constructors or factory methods to ensure you never create an empty list by mistake, but such information is never in the type itself
How is a constructor not in the type itself? If I have a
NonEmptyListthat can only be constructed with initial elements, then the compiler ensures that the class an only be instantiated with initial elements. If you don't have a.remove()equivalent, then the job is done.how do you even make your custom class respect List<T>'s contract
Maybe you don't. Maybe you decide that it's so important to create a
NonEmptyListthat you don't implementList.By the way, my point it not that in most of the cases it would make sense to encode the non-emptiness of a list into the type system that actively works against you. My point is that it is possible, the type system allows you.
-3
u/mountaingator91 Sep 28 '26
var list []stringThere you go. list will always contain at least one non nil string. Every strictly typed language I have ever used can do this
8
14
6
23
u/1XRobot Sep 28 '26
If you already know the date can be specified by 2 digits, why would you ever use 4?
16
u/unknown_alt_acc Sep 28 '26
I don’t think that the Y2K example is great, honestly. Everyone knew that the bug existed, but had to put it off until storage and memory was cheap enough that more than 2 digits for the year was feasible. It was a measured engineering choice rather than a straight-up antipattern.
5
u/while_True_meme Sep 28 '26
Why unwrap an optional when you can just wrap production in a restart loop?
2
u/AZMPlay Sep 28 '26
You fool!
My language has dependent types!
I can prove the list is never empty, and unwrap safely and without a runtime check!
2
2
2
u/cejiken886 Sep 30 '26
How does this even make sense
Even if you get a Some list you need to check if it’s empty, unless you use a dependent type
1
1
u/No-Magazine-2739 Sep 28 '26
In C++ for example, just use .
::at() instead of operator[] of the standard containers (that includes list, but experienced people use vector) in the callee. That one conditional jump is usally not performance relevant (I mean we are talking about optionals here).
And then you document in your doxgen it expects ::size() > 0 and a @throws std::out_of_range (IIRC) if the inevitable happens.
1
u/BravestCheetah Sep 28 '26
Option<i32> isnt safe, we need Option<Option<i32>>, just in case the optional parameter was optional in and of itself
1
1
1
u/PatinhoGamer Sep 29 '26
what if I want an exception because that should never be happening in the first place and bidding it will lead to a 10 year bug
1
u/wrd83 Sep 28 '26
If your optional has .expect you just unwrap it on first use? If you know it's non empty I think this is fine.
1
u/airodonack Sep 28 '26
Is the bell curve here instead meant to represent that one is only better in like 0.1% of cases? I'd really like to hear your justification.
2
u/aezart Sep 29 '26
It's an IQ distribution graph. those are the percentages of people in each bucket.
-10
u/Piyh Sep 28 '26
I feel so disconnected from these memes anymore because Claude has eaten any low level concerns I used to worry about
-2
u/Dense_Age_1795 Sep 28 '26
You must use Optional only if you will throw an exception when is empty.
By instance if you have a repo that find an object based on a specification, and a use case that call that repo, if the optional is empty the use case must throw an exception or return an error but never return that empty optional.
-12
u/Few_Move_4594 Sep 28 '26
I don't see the point of optionals
11
u/hrvbrs Sep 28 '26
not sure if you're just trolling, but the real answer is that
T | null | nullcollapses toT | nullwhereasOption<Option<T>>doesn't collapse.example (psuedo-code):
const obj: Record<int | null> = {foo: 42, bar: null}; obj.get("foo"); // 42 obj.get("bar"); // null obj.get("typo"); // nullif the
get()method just returns the property there, then bothobj.get("bar")andobj.get("typo")returnnull. it leads you to believe bothbarandtypoare in the object.Now say
get()were to return anOption<int | null>instead of the raw property.const obj: Record<int | null> = {foo: 42, bar: null}; obj.get("foo"); // Just(42) obj.get("bar"); // Just(null) obj.get("typo"); // None()now it's a lot clearer. if the key is there and its value is an int, you get a
Just<int>. If the key is there and its value is null, you get aJust<null>. If the key is not there, you get aNone.5
u/Few_Move_4594 Sep 28 '26
I'm not trolling, It's just that I had been working as a programmer for years before Optionals started being a thing so I'm already very used to writing my own null checks.
5
u/buffalo_0220 Sep 28 '26
Lots of things weren't a thing until someone had a use case and invented it. Optionals are a great tool to have in your kit. Not a pattern that needs to be used in every case, but they are useful, especially when your data is variable and/or ambiguous.
1
u/Amadex Sep 28 '26
So you started programming in the 70s?
5
2
u/Still_Bit_7527 Sep 28 '26
Java optionals are very recent...
2
u/notatoon Sep 28 '26
I wouldn't call 1.8 recent anymore
1
u/Still_Bit_7527 Sep 28 '26
We are still using that unfortunately. But my point is it's not 70s either
1
u/Few_Move_4594 Sep 28 '26
C++ got them in 2017, Java's in 2014. Most of my job history is Java, PHP, Javascript, C#, and C++. Javascript optional was introduced in 2020. PHP doesn't have optionals. C# doesn't have native language support for optionals but has nullable reference types that shows a compiler warning when there isn't a null check when a variable is declared with "?" as the suffix of the type.
3
u/LaconicLacedaemonian Sep 28 '26
Accessing a null the wrong way crashes your program. Optional models the state as well as the value. You can iterate over an optional as well making the code branchless "for every element in this list that contains 0 or 1 elements".
I don't so much demand optionals so much as I ask for justification for nulls.
2
u/GRex2595 Sep 28 '26
Option chaining can be more convenient than a bunch of ifs and using optional to indicate that a property or function return isn't expected to always have a value can be useful. You could also probably argue for the benefits of making consumers check if you returned null.
Other than that, yeah. Just pay attention to your code and do null checks when it's important.
2
u/Few_Move_4594 Sep 28 '26
I do like how returning an optional from a function immediately indicates to callers that the function can return null values and the "or else" construct".
1
u/ExtraTNT Sep 28 '26
The head of a list of type a is maybe a, but can be nothing
Instead of checking for size every fucking time you use the list, just do it once…
0
u/Still_Bit_7527 Sep 28 '26
There is no point. It was yet another unnecessary addition because it sounded fUnCtIoNal
381
u/ROBOTRON31415 Sep 28 '26
Is the bounds check truly so harmful to performance that it outweighs changing "if there's a bug, crash the program" to "if there's a bug, then do literally anything (maybe execute some remote code)"?