11 ms·
What's the point of std:monostate? You can't do anything with it
- shadowgovt 2y agoSo... Isn't the fact that you can't default-construct that variant without `monostate` working-as-intended? Not everything can or should be default-constructed or default-constructible. That does complicate initialization sometimes (i.e. there are practical reasons to "suspend" construction until you have all the needed data), but you're not avoiding breaking type safety by adding a `monostate`, you're just giving yourself the "could be null" headache.
- vasilipupkin 2y agothis is crazy confusing stuff that should be banned by most sensible internal coding standards.
- pavlov 2y agoThere’s a secret competition between C++ and JavaScript to come up with more variants of nothing.
- shadowgovt 2y agoIf you like that, you'll love how many ways you can test for equality in LISP.
- MathMonkeyMan 2y agoThat always chafed me about Scheme. I see the utility of `eq?` and `eqv?`, but I'd prefer that there were only `equal?` and functions were defined to get an object's "id" or "numeric equivalency class," or whatever, instead of having different flavors of data structures that differ only for certain values.
- tuveson 2y agoDon’t forget good ole `=` for comparing numbers.
- koito17 2y agoEach equality function, at least in Common Lisp, has a distinct goal. Numbers use = if you don't care about type. For instance, the real number 0 and the complex number 0 + 0i would be treated equal by this function. Do you care about strict pointer equality? eq. Do you want to distinguish 0 and 0d0? eql. Do you care about isomorphism? equal. The only weird function to me would be equalp, given that it performs case-insensitive comparison of characters etc. Overall, I find complaints about the equality predicates to be based on a misunderstanding of the definition of "equality". Clojure goes the opposite direction and has a single = function that performs all sorts of reflection and deep comparisons; it's convenient in practice, but it's also easy to burn CPU cycles if you are e.g. comparing large collections and only care about pointer equality.
- DonHopkins 2y agoProof that Brendan Eich never really cared about equality. https://www.reddit.com/r/ProgrammerHumor/comments/225i15/proof_that_brendan_eich_never_really_cared_about/ https://www.reddit.com/r/ProgrammerHumor/comments/225i15/pro... (To contextualize and clarify: It's a classic old JavaScript joke about how Brendan Eich hates gay people getting married so much that he donated money to a political campaign against marriage equality, even though he enjoys the human right of marriage himself. Some bigots think they are more equal than others.)
- otabdeveloper4 2y agoMarriage isn't a human right. Just ask any "men's rights" activist.
- DonHopkins 2y agoWho cares what they think?
- shadowgovt 2y ago> Overall, I find complaints about the equality predicates to be based on a misunderstanding of the definition of "equality". It's more that LISP is the only language I know that exposes how complex the concept of equality actually is. All the other ones I use more-or-less make an implicit assumption that equality means one of the things that LISP offers but if you want the other definitions of equality you either have to build support for them by hand or call out to a library function that's going to use (static or dynamic) reflection to reduce the problem to the one kind of equality the language implements. (Apart from that, the only other complaint is that LISP being as old as it is, the default names for those equalities are too terse to self-describe. You just have to memorize which one is 'eq' and which one is 'eql', there's no way to guess looking at the names themselves).
- DonHopkins 2y agohttps://news.ycombinator.com/item?id=40192911 https://news.ycombinator.com/item?id=40192911 DonHopkins 85 days ago | parent | context | favorite | on: What if null was an Object in Java? Why stop at null, when you can have both null and undefined? Throw in unknown, and you've got a hat trick, a holy trinity of nothingness! Of course the Rumsfeld Matrix further breaks down the three different types of unknowns. https://en.wikipedia.org/wiki/There_are_unknown_unknowns https://en.wikipedia.org/wiki/There_are_unknown_unknowns >"Reports that say that something hasn't happened are always interesting to me, because as we know, there are known knowns; there are things we know we know. We also know there are known unknowns; that is to say we know there are some things we do not know. But there are also unknown unknowns—the ones we don't know we don't know. And if one looks throughout the history of our country and other free countries, it is the latter category that tends to be the difficult ones." -Donald Rumsfeld 1) Known knowns: These are the things we know that we know. They represent the clear, confirmed knowledge that can be easily communicated and utilized in decision-making. 2) Known unknowns: These are the things we know we do not know. This category acknowledges the presence of uncertainties or gaps in our knowledge that are recognized and can be specifically identified. 3) Unknown unknowns: These are the things we do not know we do not know. This category represents unforeseen challenges and surprises, indicating a deeper level of ignorance where we are unaware of our lack of knowledge. And Microsoft COM hinges on the IUnknown interface. https://en.wikipedia.org/wiki/Tony_Hoare#Research_and_career https://en.wikipedia.org/wiki/Tony_Hoare#Research_and_career >Speaking at a software conference in 2009, Tony Hoare apologized for inventing the null reference: >"I call it my billion-dollar mistake. It was the invention of the null reference in 1965. At that time, I was designing the first comprehensive type system for references in an object oriented language (ALGOL W). My goal was to ensure that all use of references should be absolutely safe, with checking performed automatically by the compiler. But I couldn't resist the temptation to put in a null reference, simply because it was so easy to implement. This has led to innumerable errors, vulnerabilities, and system crashes, which have probably caused a billion dollars of pain and damage in the last forty years." -Tony Hoare https://news.ycombinator.com/item?id=19568378 https://news.ycombinator.com/item?id=19568378 >"My favorite is always the Billion-Dollar Mistake of having null in the language. And since JavaScript has both null and undefined, it's the Two-Billion-Dollar Mistake." -Anders Hejlsberg >"It is by far the most problematic part of language design. And it's a single value that -- ha ha ha ha -- that if only that wasn't there, imagine all the problems we wouldn't have, right? If type systems were designed that way. And some type systems are, and some type systems are getting there, but boy, trying to retrofit that on top of a type system that has null in the first place is quite an undertaking." -Anders Hejlsberg
- ThrowawayTestr 2y agoMathematicians got nothing on lazy programmers
- immibis 2y agoVBA has 4 kinds. Null, Nothing, Missing, and Empty.
- loa_in_ 2y agoIt's probably more of use to compiler/runtime developers than end users if the language.
- jcelerier 2y agoIt's useful whenever you want a variant with a default state which is different from any value you'd actually put it it, to differentiate between e.g. std::variant<int, whatever> v; // v is zero and std::variant<int, whatever> v = 0; And don't want to pay the space and time overhead of wrapping in an std::optional which will use a whole other byte at least for not good reason
- glitchc 2y ago> And don't want to pay the space and time overhead of wrapping in an std::optional which will use a whole other byte at least for not good reason This. monostate's behavior should be captured in the std::optional spec. There's no need to create a new type.
- masklinn 2y agoThat is opposite of sense. monostate is a much more general concept, if you want to argue about the need for a new type, the answer is to remove optional because it’s a `variant<T, monostate>`. It doesn’t work the other way around.
- glitchc 2y agoThat's putting the cart before the horse. Languages are designed for developers to use, not compilers to optimize. The intention and use of std::optional is clear. Edit: My point, if not clear, is that the compiler should add the extra bit of code for when an optional is empty automatically, rather than requiring that an optional be defined (it's optional!) unless it is explicitly typed as monostate.
- 2y ago
- ramon156 2y agoSo the upside is that you can put it at the beginning of a function? Wild, bro
- Joker_vD 2y agoYou can also use it in any template without any trickery unlike void, which I am willing to bet was the actual rationale.
- meibo 2y agoThe article describes that as the main advantage, showing std::variant as an example.
- Smaug123 2y agoHaving access to the unit type is useful; I use it maybe once every couple of months in F# even if we restrict solely to the use-case "instantiate a generic with the unit type to indicate that no data is held here". (Of course, since F# also doesn't have a `void` type - a truly non-constructible data type is indeed very rarely useful! - F# uses `unit` in many places where C++ and C# use `void`.)
- lloydatkinson 2y agoSo it appears this follows the terrible C++ "naming things with the wrong name on purpose" trend, with the biggest example being naming a variable length array (a list, collection, etc) `std:vector` even though Vector was already a well known word with a very different meaning. The word/type they wanted for this was the Unit type: https://en.wikipedia.org/wiki/Unit_type https://en.wikipedia.org/wiki/Unit_type and in that list it even states the `std:monotype` is a Unit.
- codeflo 2y agoFunctor is one of the worst offenders IMO. In C++ lingo, it simply means "callable object".
- halayli 2y agoIn C++ lingo they are called function objects or callables, not functor. You might stumble on code here and there that suffix a class name with Functor but it's not that common.
- codeflo 2y agoMany blog posts and Stackoverflow questions about C++ cal them functors. Boost of all things uses the term in its definitions: https://www.boost.org/doc/libs/1_60_0/doc/html/function/reference.html#header.boost.function_hpp https://www.boost.org/doc/libs/1_60_0/doc/html/function/refe... It's common enough that articles have been written against this usage: https://web.archive.org/web/20170224220253/http://jackieokay.com/2017/01/26/functors.html https://web.archive.org/web/20170224220253/http://jackieokay... So this usage of functor may never have been "official", but it's widespread in the community.
- plorkyeran 2y agoI would say it was widespread, but it's now fallen out of favor. Alexandrescu got the name wrong 25 years ago† and that got embedded into early boost, but by the time that blog post was written I feel like I'd mostly stopped seeing it being used by C++ experts. † I don't know if the original mistake was his, but he certainly did a lot to spread it.
- nmeofthestate 2y agoAnother use of std::monostate is as a special "unset/don't care" value for a template parameter. eg template<typename T = std::monostate> class C { ... if constexpr (!std::is_same_v<T, std::monostate> { // T-related behaviour here } };
- amne 2y agoso "std::nothing" was taken? or "std::none" ? or anything else that would make it obvious this type is a fancy way to say void?
- rerdavies 2y agostd::void_t would have been nice.
- rwmj 2y agoOr "unit" in ML-derived languages and Haskell.
- fire_lake 2y agoI always think of unit as one - it has exactly one possible value. Void doesn’t exist in ML
- ackfoobar 2y agolog 1 = 0, so it has exactly zero bits of information.
- millimeterman 2y agoVoid definitely exists in ML. —- Haskell data Void (* Standard ML *) datatype void = Void of void
- masklinn 2y ago“Nothing” can easily be interpreted as an uninhabited type (regardless of its use in haskell). > a fancy way to say void? Less fancy and more workable. Had void been a proper type in the first place it would not have been needed (but also… void had the same issue as nothing, it sounds like an uninhabited type more than a unit type). Despite that, they could have called it Void, even if the standard library normally uses all lowercase.
- ackfoobar 2y ago
- revskill 2y agoIs it like a singleton without any method ?
- masklinn 2y agoSince it doesn’t have any data either (hence monostate) that’s not a useful distinction. It’s a singleton in the same way 1 is a singleton.
- formerly_proven 2y agoSeems almost intentionally confusingly written. Why not use void if monostate is like void? Ah, because monostate is actually entirely unlike void. void has zero values, mono state exactly one.
- leni536 2y agoYou can have as many monostate objects as you want.
- mananaysiempre 2y agovoid is kind of strange in C, because it looks like an empty type, but it still behaves as though it has a single instance (a unit type). For example, a function with an empty return type can’t return (it’d have to supply a value of it); a void function can. You can’t cast things to an empty type (otherwise you’d get a value of it), you can cast things to void. Void a unit type, not an empty type, it’s just a bad one.
- formerly_proven 2y agoIt would be somewhat more cohesive and less weird if we'd argued that the "void" return type means that a return value cannot be constructed which is taken to mean that the function has no return value, and simply returns without providing a value.
- mananaysiempre 2y agoTry as I may, I can’t make sense of that. I’ve read something like it in books on C, but I still can’t. Maybe I’m infected with set theory too deeply. In my mind, a computation (a “function”) must either return a value or hang/crash. If it appears as though it returns a member of ∅, it must hang/crash, because there are no members of ∅. If it returns a member of the single-element set, [1], it can return one, there’s just no use inspecting it afterwards (you know what it is already). (For what it’s worth, if you use a prover-adjacent language such as Agda or Idris, this is exactly how things are going to work there.)
- tpolzer 2y agoWhat's really weird to me is not that C++ has a unit type and picked a weird name for it (that's just C++). The weird thing is how many unit types it has: - std::nullopt_t - std::nullptr_t - std::monostate - std::tuple<> And I'm sure there's more.
- bombela 2y agoWhat about "void"?
- tines 2y agovoid isn’t a unit type (inhabited by a single value), it’s a “bot” type, I.e. no values inhabit it.
- remram 2y agoThat doesn't seem right to me. I can define a function returning "void", and it can terminate. I would expect that a function returning an uninhabited type can never complete.
- jey 2y agoAnd “bot” refers to the bottom type: https://en.wikipedia.org/wiki/Bottom_type https://en.wikipedia.org/wiki/Bottom_type
- gpderetta 2y agovoid is the unit type. The fact that it is not constructible is a wart of the language, inherited from C. It would be easy to fix and would simplify a significant amount of generic code. A function returning bottom cannot return, yet void foo() {} can. In fact it can even return the result of calling other void functions: void bar() { } void foo(){ return bar();} In generic code void is usually internally replaced by a proper, regular void_t unit type and converted back to void at boundaries for backward compatibility. [[noreturn]] void bar(); would be a candidate for a bottom-returning function, except that [[noreturn]] isn't really part of the type system.
- asylteltine 2y ago[dead]
- ape4 2y agoGood thing they made this instead of expanding the standard library to be more like Java's or Python's. It still only contains the most basic functions, and std::monostate ;)
- leecommamichael 2y agoRaymond is a very smart and productive person, and is not maligning C++ at all in this article. It makes me want to reassess my bittersweet perspective on the language.
- doctorpangloss 2y agoOn the flip side, it shows why so many people are excited about Rust. You can pick up literally any valuable thing off the ground that made the mistake of being built around C++, like CUDA, slap it on Rust, and people will both adopt it and be excited to contribute to it.
- furyofantares 2y agoGerard: But it doesn't do anything! Hans: No -- it does nothing. https://scryfall.com/card/wth/154/null-rod https://scryfall.com/card/wth/154/null-rod
- gpderetta 2y agoNo no, that's a void pointer .
- nostrademons 2y agoA "monostate" in the design-patterns lingo of 20 years ago was a class with only static member variables, basically where all state is shared state. It was supposed to be alternative to the Singleton pattern where you don't need all those .getInstance() calls and instead can just default-construct an instance, any instance, to get access to the shared state. It fell out of favor because usage was fairly error-prone and surprising to programmers who are not familiar with the pattern. Most people expect that when you create a new instance, you are actually creating new state, but monostate intentionally makes each new instance just a window on the shared global state. I would've thought that the C++ template class would be just a marker interface to use on a monostate, so that users of the class know that it has shared state. But it seems like usage patterns in the article are very different from that, and all the comments here are ignorant of the history of the monostate pattern and befuddled at its intended usage. Maybe it was added to the standard by someone familiar with the design pattern, but they didn't do a good job with education and documentation to explain to everyone else what it was for?
- quietbritishjim 2y agoThat just sounds like a different thing with the same name. It's nowhere close to the purpose of std::monostate.
- eequah9L 2y agoYeah. The design pattern sounds like there is one state, and it is shared. What STL has looks like, all instances look the same, hence only one state is possible. They are homonyms with slightly different etymologies.
- layer8 2y agoThat’s the GP’s point. It is strange that std::monostate was chosen as the name, given that the different Monostate pattern [0] was fairly well established in C++ circles. [0] https://wiki.c2.com/?MonostatePattern https://wiki.c2.com/?MonostatePattern (originally discussed in http://ftp.math.utah.edu/pub/tex/bib/cppreport.html#White:1996:ADU http://ftp.math.utah.edu/pub/tex/bib/cppreport.html#White:19...)
- kazinator 2y agoIt's poor name. If it has no members, it holds no bits. Therefore it has no state. It's not enough for an object to exist in order to hold state. It must be capable of distinguishing at least between two values, like true or false. If something doesn't hold state, the word state has no business in its name. This thing is just a counterpart to void that is a class. A better name would be voidclass or something along those lines. (There is a Monostate pattern, but that involves a class with state: just all the state is static. It's basically like a module with global variables. Completely different thing.)
- binary132 2y ago“True” and “False” sound like two states. This is just one. :)
- kazinator 2y agoYes, exactly like 640K sounds like a power of two, if you're a MS-DOS user. But in a way, this is right since: <no of bits> 2 = <no of states> When the number of bits is 0, 2^0 = 1: 1 state. A state machine with one state is certainly possible. Problem is we need 2 or more states to do anything useful with state. We can draw an initial state bubble in a state diagram and not add any states; it can even have transitions back to itself. So maybe monostate is not exactly a misnomer; it's just weird to mention state about something that is not useful for working with state.
- JackYoustra 2y agoThere's a fun thing like this in Swift too! `Void` is an empty tuple, and has all of the related constraints (can't conform to protocols, being the most salient one). If you have a type that has to conform to, say, `Equatable` or `Codable` you should instead use `Never?` which you can conform to most protocols via throwing `fatalError` on an extension of `Never` to the protocol. Anyway, I write basically this on my blog for a more thorough explanation: https://www.jackyoustra.com/blog/non-equatable-void https://www.jackyoustra.com/blog/non-equatable-void
- tymscar 2y agoLovely blog! If you would accept one suggestion, it would be to make it mobile friendly!
- JackYoustra 2y agoI'm glad to have a mobile reader :) I'll work on making it mobile friendly soon
- JackYoustra 2y agoShould be better now! Let me know if you have further concerns :)