Great video! Just a little note: the vars and vals are marked by the compiler as Covariant and/or Contravariant just because they generate the getters and setters automatically. Variance does not apply to variables or constants, it does only to parametric types.
Talking about cryptic compiler errors. I programmed template meta programming in C++ on a CBuilder compiler back in the day 🙄 Now I am scared of nothing 😆
While Scala's syntax is far easier to understand than Java's when it comes to variance, my head is still spinning trying to grasp the bigger picture. I'll revisit this video again and read the docs until I do.
The gap in thinking going from being confused about the method problems such as the list.add, is I'm probably not going to be thinking a list should be allowed to change in the first place. I may be tunnel-visioned on the task at hand and creating a list that could become other types of lists feels like it's creeping away from me. I might also think that if I assign a List[Cat] to a reference of List[Animal], I immediately lose the specificity of Cat from the value and it's just a list of animals from then on, but I'm coming from a background of JS and TS so that's probably why. That a reference of type List[Animal] being given a value of type List[Cat] is valid, when I add a Dog to the list, it can't be aware of the specificity of the value being [Cat] since the reference is of [Animal]. Thus the method can't know to error after being used 'incorrectly' as my intuition says. It's blind of the value. Or maybe in other words, we told the compiler to trust us by making it covariant. So if the method can't error when my intuition says it should, that's the disconnect. In my head 'It should prevent me from doing this' but it can't. Instead, the method should return a new list of a new type, thus S >: T. Sometimes we write the code, and sometimes the code writes us, because logic.
28:49 - ok, I'm happy that this is the hardest, because I expected it will get only worse and worse, so maybe I don't have to go back to Java ... Don't use T,R,S it is Java convention: class Delegate[CC[A]
FP beginner here. Would it make sense to think about variance position as specifying "monadic inheritance", i.e. how a monad of a type (M[A], M[B]) is related to itself when holding a related type (M[B
Ok, I see. It's because not every Thing[T] is a monad, since they would need to be able to unwrap & wrap their contents and not every container is capable of doing that, correct? Then I have to rephrase my question: would it make sense to think about variance as specifying "inheritance" of a wrapping type that holds two related wrapped types (= how W[A] is related to W[B
The problem is that your method needs to return type S, not type Dog (even though both are subtypes of Animal). If the `rescueAnimal` method was typed with Cat (which is also a subtype of Animal), then returning a Dog is wrong.
Great video! Just a little note: the vars and vals are marked by the compiler as Covariant and/or Contravariant just because they generate the getters and setters automatically. Variance does not apply to variables or constants, it does only to parametric types.
One of the best videos out there, period.
Much appreciated! Share this with whoever you think might find it useful!
Thank you for ur support and blogs.
Thank you for such grate video. To my opinion you have a grate skill which allows you to explain really hard things in a simple way!!!
Everybody who digs into this topic already appreciated Animals, Dogs, and Cats.
Talking about cryptic compiler errors.
I programmed template meta programming in C++ on a CBuilder compiler back in the day 🙄
Now I am scared of nothing 😆
MyList
MyList2
MyListC
😌I can see your naming conventions are variant as well 😆. Thanks for the video ^^
I'm having a Tim and Eric "The Universe" monent watching this. What a beautiful mindblow
Thank you, sir for the very good lesson!!!
Glad you liked it!
Please make a video about variance for function types!
Functions are contravariant in arg types (because of the contravariant position) and covariant in return types (because of the covariant position)
While Scala's syntax is far easier to understand than Java's when it comes to variance, my head is still spinning trying to grasp the bigger picture. I'll revisit this video again and read the docs until I do.
HOLY SHIT IT CLICKED
That's the goal!
I could not got much, 90% went top of my head.
Start with basic generics first, then learn what variance is, then go back here.
Really useful and easy to follow video, thanks!
Glad it helped!
Awesome! 👍
what is an example in which using contravariance is worth the complexity?
Any generic consumer type should be contravariant, e.g. Function, ActorRef.
The gap in thinking going from being confused about the method problems such as the list.add, is I'm probably not going to be thinking a list should be allowed to change in the first place. I may be tunnel-visioned on the task at hand and creating a list that could become other types of lists feels like it's creeping away from me.
I might also think that if I assign a List[Cat] to a reference of List[Animal], I immediately lose the specificity of Cat from the value and it's just a list of animals from then on, but I'm coming from a background of JS and TS so that's probably why.
That a reference of type List[Animal] being given a value of type List[Cat] is valid, when I add a Dog to the list, it can't be aware of the specificity of the value being [Cat] since the reference is of [Animal]. Thus the method can't know to error after being used 'incorrectly' as my intuition says. It's blind of the value. Or maybe in other words, we told the compiler to trust us by making it covariant.
So if the method can't error when my intuition says it should, that's the disconnect. In my head 'It should prevent me from doing this' but it can't. Instead, the method should return a new list of a new type, thus S >: T.
Sometimes we write the code, and sometimes the code writes us, because logic.
28:49 - ok, I'm happy that this is the hardest, because I expected it will get only worse and worse, so maybe I don't have to go back to Java ...
Don't use T,R,S it is Java convention:
class Delegate[CC[A]
You wrote MyList[T] - isn't this a Java naming convention for type parameters? I read that in Scala we should use A,B,C,...
You can name them however you like. You can do MyList[Thing], and Thing is the name of the type parameter.
badass scala developer :D
thanks for this tricky topic explanation
hi , could u please help here: "How do you unit test a function that returns a function?"
Probably a subject for a future video :)
@@rockthejvm I am waiting for that video :)
It started to click when I thought of somebody who likes to eat fruit vs someone who likes to eat banana. FruitEater vs. BananaEater
FP beginner here. Would it make sense to think about variance position as specifying "monadic inheritance", i.e. how a monad of a type (M[A], M[B]) is related to itself when holding a related type (M[B
Variance per se has nothing to do with monads. Am I understanding the question correctly?
Ok, I see. It's because not every Thing[T] is a monad, since they would need to be able to unwrap & wrap their contents and not every container is capable of doing that, correct?
Then I have to rephrase my question: would it make sense to think about variance as specifying "inheritance" of a wrapping type that holds two related wrapped types (= how W[A] is related to W[B
@@pymath5771 Yes, that's better.
Nice. video, thanks, Daniel!
But, I don't understand one things:
trait VetC[-T] {
// S is sub type of T
def rescueAnimal[S
The problem is that your method needs to return type S, not type Dog (even though both are subtypes of Animal). If the `rescueAnimal` method was typed with Cat (which is also a subtype of Animal), then returning a Dog is wrong.
wow excellent explanation thank you :)
Awesome
Thanks!
11:40 - I stopped the video here to thing about it. But I automatically added type in IntelliJ and it told me Dog!
The IDE can only do so much before the code actually compiles. The code will not compile in this case.
𝚝𝚑𝚒𝚜 𝚒𝚜 𝚊 𝙶𝙰𝙳𝚃 𝚜𝚔𝚘𝚕𝚎𝚖
you serious or it's a "compiler warning nobody understands"? because I've seen the GADT skolem term used for that too 😅
@@rockthejvm the latter 😁I'm hoping one of these teach me what the hell that means one day 🤔