Тёмный

Conor Hoekstra - Concepts vs Typeclasses vs Traits vs Protocols - Meeting C++ 2020 

Meeting Cpp
Подписаться 32 тыс.
Просмотров 5 тыс.
50% 1

Conor Hoekstra - Concepts vs Typeclasses vs Traits vs Protocols - Meeting C++ 2020
Slides: slides.meetingcpp.com
Survey: survey.meetingcpp.com

Опубликовано:

 

12 сен 2024

Поделиться:

Ссылка:

Скачать:

Готовим ссылку...

Добавить в:

Мой плейлист
Посмотреть позже
Комментарии : 32   
@simonfarre4907
@simonfarre4907 3 года назад
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.
@yotty97
@yotty97 2 года назад
C++ has this too, headers vs implementation,
@Hichigo68
@Hichigo68 3 года назад
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
@steffahn
@steffahn 3 года назад
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.
@HendrikNiemeyer
@HendrikNiemeyer 3 года назад
only a minor comment: Rust has "const" keyword but it is the equivalent of "constexpr" (more or less) in C++.
@5h0rtr0und
@5h0rtr0und 3 года назад
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!
@brandonlewis2599
@brandonlewis2599 2 года назад
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.
@vasanthkumar3685
@vasanthkumar3685 3 года назад
Finally I watched a talk from start to end.
@hungbiu8609
@hungbiu8609 3 года назад
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.
@VamoAComeLaPapa
@VamoAComeLaPapa 3 года назад
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
@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
@yotty97
@yotty97 3 года назад
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.
@bobbills5312
@bobbills5312 3 года назад
@@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?
@RitobanRoyChowdhury
@RitobanRoyChowdhury 3 года назад
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.
@yotty97
@yotty97 3 года назад
@@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.
@yotty97
@yotty97 3 года назад
@@RitobanRoyChowdhury can Rust have both have disjoint (OR) and conjoint (AND) relations between concepts?
@gtdcoder
@gtdcoder 3 года назад
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_report
@code_report 3 года назад
Ah, I don't know how I missed this. Will make sure to clarify in subsequent talks.
@improvedspoon
@improvedspoon 3 года назад
@@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.
@gtdcoder
@gtdcoder 3 года назад
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.
@AlexHajdu
@AlexHajdu 3 года назад
Thanks, very informative...
@gtdcoder
@gtdcoder 3 года назад
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.
@movesemantics5991
@movesemantics5991 3 года назад
Rust's generics work the same way C++'s tempates work. That is, they work by monomorphization.
@code_report
@code_report 3 года назад
First 😂
@MeetingCPP
@MeetingCPP 3 года назад
Fool... :P
@Yupppi
@Yupppi 9 месяцев назад
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.
@skyletoft
@skyletoft 3 года назад
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
@baranc3kyt
@baranc3kyt 3 года назад
Can I ask you, how can I create beautiful animated transition between two code snippet? What presentational tool did you use? Thanks
@igorzhukov8687
@igorzhukov8687 3 года назад
Nice
@fredhair
@fredhair 3 года назад
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..!
@stephenjames2951
@stephenjames2951 3 года назад
Mute not mutt