Wow, optionals and variants are what I've always wanted and I had no idea. No mare enum/union non-sense and sentinel value non-sense.
@arisweedler47033 жыл бұрын
It was a bit hard to wrap my head around 13:20, but I figured it out smoothly eventually. An “instance of a function” draws a line from “a value in the world of args” to “a value in the world of results”. To describe a function in terms of types completely, you need an instance of the function for EVERY arg. A complete function has instances, and each instance line can end in different ways. So for every “value in the world of args”, you have additional types.
@arisweedler47033 жыл бұрын
Ramblings: The number of “types a function has” when the cardinality of is 1 . When the cardinality of is 2, you can pretend it is 2 uncurried functions. Both are equivalent (in terms of cardinality) to the first case. 1 value of argument to any value of the results function. Take the Cartesian product of these two functions. So… ^2. This pattern repeats. And you are left with the cardinality of a function’s type is ^. It’s cool. Because when there are two values for arguments, any single function draws two lines from the world of args to the world of results. And you can draw each line ways.
@arisweedler47033 жыл бұрын
If there is a pointer from a single instance of arg to each instance of result, there are result pointers. Or we can declare this to be a single “mega pointer” from arg to “world of results”. A function is a “mega pointer” from each value of arg to “the world of results”. |result| multiplied by itself |arg| times. Taken a step further… a function is a mega pointer from “the world of args” to “the world of results”. |result|^|args|. It’s interesting to think about currying now because if you could “de-curry” a function call with |arg|=2 into 2 function calls with |arg|=1, then this whole thing becomes a lot more clear!!! Each un-curried function has a mega pointer into .
@arisweedler47033 жыл бұрын
Ben Deane explains it again at 53:00 in the Q&A section
@LooJulian7 жыл бұрын
Safe brilliant sharing of talk. Thanks Ben Deane and all.
@gowtham2362 жыл бұрын
Terrific talk, highly recommend.
@jjurksztowicz8 жыл бұрын
Great talk, very applicable to other slightly less statically typed environments too.
@AdasPK7 жыл бұрын
That is one of the best talks I have seen!
@alexweej7 жыл бұрын
Great talk but the Q&A is, as always, really annoying when people don't get a mic...
@wpavada32478 жыл бұрын
This is applicable to reduce domain at compile time and also reduce testing process. We should not misunderstand this with run time verification(what i mean is still run time logic has to be tested).
@selvakumarjawahar8 жыл бұрын
very useful practical talk... good
@AxelStrem8 жыл бұрын
"functional programmers keep saying 'map' and 'filter'..." - but these functions actually are 'map' and 'filter', semantics are completely different from 'transform' and 'remove_if'
@TomaszWota8 жыл бұрын
Can you elaborate?
@AxelStrem8 жыл бұрын
What I mean is std::transform takes an output iterator and writes the transform result to wherever you want, including original container, so (in other words) it deals with "memory". Ben's transform on the other hand returns resulting container as a value, so it has this functional stateless taste to it, it deals with "values" - this is exactly what 'map' function does. Same goes for std::remove_if - it cannot even actually remove elements due to container/iterator separation, while Ben's remove_if gives you a filtered ready-to-use container.
@AxelStrem8 жыл бұрын
I don't want to pick on Ben though, the talk is pretty solid, I liked it:)
@TomaszWota8 жыл бұрын
Ah, yes, now that you've stated the obvious it indeed seems... obvious. Made me feel stupid, but in a good kind of way. Thanks. :) I liked it too, but I'm of two minds about the idea of "STL2" with variants and optionals all over the place. If it happened to provide better performance, or heck - at the very least not worse - sure, I think I'd go for it. I think I'd generalize the point to the whole standard library, actually. But I just can imagine the mess of having effectively two standard libraries - one with and one without the optionals/variants... Then the nightmarish visions appear: some functions having sentinel values/error codes, some setting errno, some returning variants or optionals, some throwing exceptions... The worst thing is we're already living the nightmare. :P Plus, I don't really see variants replacing exceptions. Although it is interesting to ponder.
@NebuPookins2 жыл бұрын
It's good that this topic is becoming more mainstream, but there are a few errors in his talk. For example, the type `void` in C++ has cardinality 1, not 0. A type with cardinality 0 is called a "bottom type", and is the subtype of all other types. I'm not a C++ guru, but my understanding is that C++ does not have a bottom type, although some of its functionality can be replicated with the `noreturn` attribute from C++11.
@cmdlp41787 жыл бұрын
What if the ``?:`` is improved that ``a ? b`` makes an ``optional`` and ``a : b`` returns the contents of a when not empty else b?
@TomaszWota8 жыл бұрын
More of things like this, please. :)
@Danielle_12347 жыл бұрын
Can someone explain to me why char f(bool) is 256^2 instead of 2*256? Am I misunderstanding that the number is supposed to represent the number of possible combinations? I can make a truth table that shows all possible combinations for char f(bool) and it comes out to 512 possibilities.
@xXH3ll5xB3llXx7 жыл бұрын
Each value of the bool can be mapped to any of 256 values and to get a complete function you can take any combination of two mappings. So for a given mapping of one value there are 256 possible mappings for the other giving 256 * 256 or 256^2 combinations.
@Danielle_12347 жыл бұрын
Oh, I see. It's counting the total possible number of functions, not the total number of input and output combinations.
@cgoobes6 жыл бұрын
I don't understand why this is significant. In the end, that function can map only one of 2 values to one of 256 outcomes. Only one input can exist at a time, and only one output can exist at a time, so 512 is the only meaningful number as it represents the total number of possible mappings.
@jakearkinstall16946 жыл бұрын
@cgoobes But the discussion is about how many possible functions there are that map one of two values to one of 256 values. Simplify this and turn it into a function from a bool to an enum{ A, B, C }. Here are the possible functions: 1) False => A, True => A 2) False => A, True => B 3) False => A, True => C 4) False => B, True => A 5) False => B, True => B 6) False => B, True => C 7) False => C, True => A 8) False => C, True => B 9) False => C, True => C Sure there is only one input at a time, and one output at a time, but that isn't relevant - and 6 isn't the meaningful number here. What you're doing is picturing a set of functions in a strange way: 1) False => A 2) False => B 3) False => C 4) True => A 5) True => B 6) True => C But none of these are functions, they're just statements in need of coupling.
@siergiejriaguzow17295 жыл бұрын
I'm also having problems with this combinatorics stuff but maybe this will help to understand: 1st function: f(false) - 122, f(true) -> 123 2nd function: f(false) - 122, f(true) - 124 3rd function f(false) - 122, (true) - 125 .. 256 functions like that. This already gives 256. But for another function it can be that for f(false) it will return 199 and same as the previous one for true. This gives another 255. Yet another function will return 255 for false and same results as the previous for true. So for each true -> N (256 combinations) there are false -> N (256 combinations) of functions which return same stuff for true. Hence 256^2. Easy. Eh.. Not really.
@Manquia8 жыл бұрын
When this enters the std I'll definitely give it a shot.
@ThrashAbaddon5 жыл бұрын
now it has
@danielrhouck7 жыл бұрын
You said you wouldn’t use the M-word, but then you did a couple times starting at 47:41 (which is in the Q&A, so it’s okay). Otherwise great talk!
@perfectionbox3 жыл бұрын
so i would use std::holds_alternative to test for a particular "enum" inside a variant? How much slower is that than just comparing an enum?
@chri86863 жыл бұрын
You can use holds_alternative to test for a specific type. If you want to process a variant, a more general approach is to use std::visit. Take a look at the function "overloaded" in the example on cppreference's std::visit page.
@fettyplayground72416 жыл бұрын
Brilliant talk.
@climatechangedoesntbargain91405 жыл бұрын
Thanks for the Phantom
@iforve7 жыл бұрын
Brilliant talk, thank you
@andik708 жыл бұрын
11:38 maybe you have to define the function with a 'noexcept'? Otherwise technically there are more possibilities.
@origamibulldoser16188 жыл бұрын
Was thinking the same thing. Anybody else look at that connection modelling class and go "this looks exactly like what I wrote yesterday." ?
@TomaszWota8 жыл бұрын
+1 for remembering about exceptions, however - with exceptions, as you very well know, technically the function doesn't properly return (a value) even though the stack unwinding happens. So I think this shouldn't be counted.
@anthonyhuang89146 жыл бұрын
eye-opened talk
@italoaugustooliveira96643 жыл бұрын
20:30 looks like a performance nightmare.
@bioai75075 жыл бұрын
thanks to ben
@babgab7 жыл бұрын
So many templates. Wonder how using variants and phantom types affects compile time?
@dlwatib5 жыл бұрын
My experience of writing code for compiled languages is that it's like working with a straitjacket on. My errors were rarely in the code itself, it was syntax errors in the arcane, inscrutable language used to express the types. The code he put up to express phantom types is complete gibberish to me. I don't think I've ever had a bug where I've said "I wish I had a type system to save me from making this same error in the future." I never mix up fixed point and floating point numbers, for instance. When I add a character to a number, it's deliberate, and getting the type system to understand my intention is just getting in the way of what I want to get done. I have, however, wished for more expressive loop constructors so I don't have to ever say again: for (i=0; i
@seditt51465 жыл бұрын
is... is this like a troll post or joke or something?
@tshev3 жыл бұрын
Not for every value of `double` you can compute min: kzbin.info/www/bejne/pZu9k3l_hriXopo
@MasterHigure6 жыл бұрын
25:30 While it's always nicer to have a compile-time check, this kind of thing (like sanitized vs unsanitized) is the point behind Hungarian notation. While it can't make the compiler check for you, correct Hungarian notation here would be to have some prefix on all unsafe string variable names (as well as functions returning unsanitized strings) and some other prefix on all sanitized string variables (and functions). This makes it as easy as it can be to spot that you're using an unsanitized string somewhere you shouldn't (and you can possibly even write tools to help you). Unfortunately, Hungarian notation has been gravely misunderstood, which is why so many hate it.
@TheR9715 жыл бұрын
So basically an unenforced, convention based monad? Why not go full monadic?
@dnaphysics8 ай бұрын
Disagree with "bool f(bool)" having only 4 values in C++. I say infinity, e.g. bool f(bool b) { return random()&b; } or bool f(bool b) { return date()&b; } A function can have an infinite number of definitions in C++.
@ShawnHCorey5 жыл бұрын
Picking nits: Making _Invalid_ States Unrepresentable Illegal should never be used unless it is against the law for real.
@TheR9715 жыл бұрын
The state is illegal in the laws you construct. In the end, I am the sovereign of my code laws!
@RogasTV7 жыл бұрын
No no no, this guy used The Idiotic Notation for members (m_)... it makes reading so less joyful.
@TheR9715 жыл бұрын
You are the first person I hear copmlain about the m_ notation! I find it quite nice personally as it makes me think less about naming.