Conor Hoekstra - Concepts vs Typeclasses vs Traits vs Protocols - Meeting C++ 2020 Slides: slides.meetingcpp.com Survey: survey.meetingcpp.com
Пікірлер: 31
@simonfarre49073 жыл бұрын
Rust's decision to split implementation and definition can not be overstated how amazing that is. When browsing codebases, it becomes so easy to get an overview of the type, since its members is separated from its member functions. This, has saved me countless of hours getting the mental model of a type down to where you know it by heart.
@yotty972 жыл бұрын
C++ has this too, headers vs implementation,
@steffahn3 жыл бұрын
On the syntax side, note that Rust also has a syntax similar to the “shape auto s” of C++ that you liked so much, i.e. “s: impl Shape”. It also has a syntax similar to the “if (shape!(T))” in D, i.e. “where T: Shape”. One thing in Rust and Haskell is that type-classes / traits can be implemented in a different module or even a different crate/package than the type definition (of Circle/Rectangle). I’m curious if something like this is possible in Swift, that would be some interesting information. (It couldn’t be the ": Shape" syntax in the "class" declaration itself, because that’s not separate from the definition of the respective class). Finally, I think that the difference between (C++ and D) vs. (Rust, Swift and Haskell) is also noteworthy, that e.g. in C++ whenever your type has the appropriate methods, it automatically meets the concept, vs. in e.g. Rust where you only implement a trait by explicitly implementing it (i.e. without the change from “impl Circle” to “impl Shape for Circle”, the type “Circle” would still NOT be a Shape, even if it had all the right methods. And I find it a bit weird how your Haskell example uses named in the datatype definitions but only accesses them positionally afterwards. Even if it’s more ugly, you could use “Rectangle { w=w, h=h }” patterns instead. Or rely on the “{-# LANGUAGE NamedFieldPuns #-}” GHC extension for a “Rectangle { w, h }” pattern. I did particularly like how you explicitly mentioned it when you did present some statement or an intuition where you knew that (at least some) other people did/would call your view inaccurate, e.g. the comparison of types-values vs contraints-types, or your own vs. other people’s intuition about whether to call something a “constraint”. Otherwise, these might’ve been things I would’ve wanted to comment on as well.
@Hichigo683 жыл бұрын
Nice, just a small nitpick : Your shape C++ concept do not asks for concrete types (ie. std::floating_point vs float, and string concept instead of std::string), contrary to the other languages implementations : that may make them a bit more verbose. To check return types against exact types in C++, you can use the "std::same_as" concept, eg { s.name() } -> std::same_as
@HendrikNiemeyer3 жыл бұрын
only a minor comment: Rust has "const" keyword but it is the equivalent of "constexpr" (more or less) in C++.
@5h0rtr0und3 жыл бұрын
Amazing talk! Incredibly clear and informative! It's a shame you can only +1. How someone can down vote this, I have no idea. A great talk from Conor again!
@vasanthkumar36853 жыл бұрын
Finally I watched a talk from start to end.
@brandonlewis25993 жыл бұрын
Wow, this video clears up a lot of confusion I've had. The overlap between all these "feature", small-c "concepts", etc, has been clear. But the languages come from such different traditions, that it was hard to make sense of what things were truly equivalent.
@hungbiu86093 жыл бұрын
one class of constraint is specified without the class(struct) implement(satifies) the contraint mentioning the constraint: C++ concept, Go interface. However the other class requires it to be mentioned like the classic C++ inheriting from virtual base class. The difference is that the former introduces no dependencies between constraint construct and implementation while the latter does.
@VamoAComeLaPapa3 жыл бұрын
Hey @code_report! Congratulations for your excellent video! Thanks! Just a little suggestion, which perhaps you could add in a future review: A mention to the following paper that precedes the one of Philip Wadler: stepanovpapers.com/p59-kapur.pdf The paper was written in 1981 by Alex Stepanov, Dave Musser (and other collaborators) and in it they describe the ideas that we know today as C++ Concepts. These ideas were implemented in the Tecton language and over time refined and written into the Elements of Programming book. elementsofprogramming.com I have not found any previous references to the work of Alex Stepanov and Dave Musser, so I think they are pioneers in what we now call Generic Programming.
@edmundcape Жыл бұрын
Around min 35 - you can do more in a fn the more you constrain it. This is true because the starting point is the identity fn where all you can do is return the input. I.e do nothing because you know nothing about the value of “all types”. Add a single constraint (e.g., type class Display), now you can do what is allowed by that one type class. Add two constraints, you can do just a little bit more etc.. counterintuitive until you start with “what can I do in my function for all types”?… generally, not a lot. In Haskell, return input. In Rust, a -> b is a definable function so somewhat obfuscates the main thread. Not so in Haskell. - E
@yotty973 жыл бұрын
It appears (and correct me if i'm wrong) that most of the other examples of type-classes in languages other than c++ are just for specifying function signatures/interfaces. But C++ concepts are much more than that - you can actually specify anything in the requires clause and test if it compiles. This allows for much deeper expressions of the structure of a type than just the "signature" of member functions. Kinda curious why you didn't mention this? It's a much more powerful mechanism.
@bobbills53123 жыл бұрын
@@radbarij In my opinion, I think they are more powerful as a concept will work with existing classes or classes from a library, while protocols or the other will not??? not sure I guess you can do something to handle this cases where you have types from a lib that you can't modify and need to use with other library generic functions?
@RitobanRoyChowdhury3 жыл бұрын
No, those other languages also have various ways of describing more complicated type-classes. Rust has the `where` keyword, which can get super complex. My go-to example for how complex Rust's generics can get is the `nom` library's tag function: pub fn tag( pattern: O, count: C ) -> impl Fn((I, usize)) -> IResult where I: Slice + InputIter + InputLength + Clone, C: ToUsize, O: From + AddAssign + Shl + Shr + PartialEq, Most of C++'s concepts have corresponding rust traits -- `std::copyable` vs `Copy`, `std::equality_comparable` vs `Eq`, `std::destructible` vs `Drop`, `std::invocable` vs `Fn`, `FnMut`, and `FnOnce`. The C++ ones seem messier because of the sheer amount of legacy cruft that C++ has -- Rust doesn't need to distinguish between default_initializable, move_constructible, copy_constructible and assignable_from -- because it doesn't have constructors in the first place.
@yotty973 жыл бұрын
@@radbarij Look at how the random iterator concept is defined here en.cppreference.com/w/cpp/iterator/random_access_iterator Not only does it specify a function interface, it also specifies behavior: { i += n } -> foo, { j + n] } -> bar etc None of the other languages can do that, they only specify function interfaces. C++ concepts can do that too - but they can also do MORE.
@yotty973 жыл бұрын
@@RitobanRoyChowdhury can Rust have both have disjoint (OR) and conjoint (AND) relations between concepts?
@gtdcoder3 жыл бұрын
40:50 Swift does not have a "mutable" keyword. In the example, the immutability of the methods are determined by the "let" keywords on the member variables. Otherwise, the methods would be mutating by default.
@code_report3 жыл бұрын
Ah, I don't know how I missed this. Will make sure to clarify in subsequent talks.
@improvedspoon3 жыл бұрын
@@code_report it's worth noting though that Swift has "mutating" keyword, which is usable for methods of value types (so structs and enums) and allows those methods to modify properties or even assign to self of object on which they were called on.
@gtdcoder3 жыл бұрын
So Swift doesn't really default to immutability anymore than c++ does unless you are using structs.. At least c++ allows you to specify both methods and variables as const so even if you don't declare a variable as const, the compiler will still complain if you try to modify it in a const method. More importantly, c++ does default to value semantics for everything, which is essential when all your data is immutable. The whole point of immutability is to avoid conflicts between shared data, so being able to copy instead of passing-by-reference is essential. C++ defaults to value-semantics whereas with Swift, only structs and enums do.
@gtdcoder3 жыл бұрын
I think any discussion of generics should include a more detailed explanation of how they are implemented under-the-hood in various languages. Most languages use an approach similar to Java type-erasure, whereas C++ is completely compile-time polymorphism. This talk on meta-polymorphism is much more useful IMHO, Jonathan Bocarra - Meta Polymorphism.
@movesemantics59913 жыл бұрын
Rust's generics work the same way C++'s tempates work. That is, they work by monomorphization.
@AlexHajdu3 жыл бұрын
Thanks, very informative...
@code_report3 жыл бұрын
First 😂
@MeetingCPP3 жыл бұрын
Fool... :P
@Yupppi10 ай бұрын
This is the thing why I'm heavily undecided on if I like Rust or not. It's really nice until you decide to do that one convenient thing that has awful and lengthy, ugly syntax that makes you wish you never decided to try that.
@skyletoft3 жыл бұрын
nitpick: the name functions in rust really shouldn't return String, they should've returned &'static str so that it would just return a pointer to the hardcoded string in the binary instead of first copying that to the heap. If the user needs a String they should .to_string() it themselves. Most of the time you don't need a String
@baranc3kyt3 жыл бұрын
Can I ask you, how can I create beautiful animated transition between two code snippet? What presentational tool did you use? Thanks
@igorzhukov86873 жыл бұрын
Nice
@fredhair3 жыл бұрын
Good talk. Haven't used C++ much in past couple years tho I really like the C++20 ability to use auto instead of writing out template before each function.. heck this is so common I think we should replace auto with 'T' make T a keyword as an alias for a single template parameter. It's a silly idea but I'd like to omit the return type, return keyword and decltype() and just write T add(T l, T r) -> l+r; haha. C++ is very verbose at times (improving with each revision mostly.... ahem chrono). Wish I could mod my compiler or use some static analysis type tool to replace these little 'time savers' with compliant C++. Maybe I should write a terribly unsafe macro and see how it goes :S I'm only a hobbyist fortunately..!