Mixins do not imply an "is-a" semantics while using inheritance. They are like interfaces with default implementations. You can enforce a specific interface to be implemented in the descendant class by extending this interface in the mixin itself.
While they have the same name, the Mixins of Forge or Fabric are a completely different thing that have no real relation. This is talking about a design pattern while the Forge or Fabric mixins are a form of code injection that act closer to a decorator pattern than a mixin pattern. But really Fabric/Forge mixins are not a programming pattern, they're a specific feature, mixins are effectively a form of instrumentation in Fabric/Forge, whereas the mixin pattern in Computer Science is a specific programming patterns like inheritance or composition. Again despite the names they are largely unrelated to each other.
@@DreadKyller deeply they are the same thing. Yes, Spongepowered Mixin are a tool to modify bytecode and this video is about a trait-like design pattern to add functionality to a class. But what else Sponge's Mixins are? A tool to add/modify functionality of existing classes without the usage of inheritance. This is sort of stated in their repository: "Mixin is a trait/mixin framework for Java using ASM [...]"
If you could go over a comparison of this versus composition, as they seem like they're attempting the same thing, shared reusable pieces of logic without the need for complex hierarchy chains. What benefits does this have over traditional composition patterns?
This video just seems like your trying to build an ECS (Entity Component System) or Rust Traits, Java Interfaces or trying to do composition. Basically what my point is, is that there are many well established ways to achieve the same goals as mixins. Yes, mixins can save those few extra lines, but that's really the only advantage I see: a bit more readability. Generally Mixins can have lots of problems (Im using Java Mixins as an example here): Mixins rely on naming schemes in projects. This means, when a class / module / method is renamed, the mixin breaks. Any structural changes in the project result in mixins breaking. Mixins are usually byte-code inserts, which means they bypass compiler checks and might introduce breaking code. Also I believe what you implemented is just composition: One component that does Logging, the other that does File Reading.
missed you Gopher! Sad to see no daily uploads but i hope that means ur enjoying the holidays!! i really enjoy this type of video, can’t wait to see what type of content you’ll make this coming year
I’ve been trying to wrap my head around this idea (without putting too much effort, to be fair), and from this explanation I understand the “@“ decorators are basically syntactic sugar for all the boilerplate that would be needed from using [composition + dependency injection + inversion of control]. Ok, that seems nice.
Good video. I wish I had some more time to understand the final example, feels like it got cut off to meet the exact 3 minute mark. Perhaps immediately jumping into an example and narrating it would have saved more time at the start.
Similar, but not exactly. Mixins in Python are more like reusable code snippets added via inheritance, while C++ interfaces (i.e. pure virtual classes) define a contract that classes must implement. Mixins add behavior; interfaces enforce structure.
To clarify, I don't have an issue with the video. Maybe with the title though. I'm coming from Dart, where mixins have special syntax, which has made me confused for a long time because I couldn't see how they're different, and the video title has made me hope I'll finally understand it. But nope! Especially seeing you use inheritance to implement a mixin convinced me more that the Dart team has added them as a hack to enable multiple inheritance.
I think the core of my misunderstanding was that I was thinking about a **different category**. There is no difference between mixins and multiple inheritance **as a language mechanism**, but, **as patterns** they are different. So, while everyone was talking about a design pattern, I was thinking about the language mechanism. (This is reasonable though, because it was prompted by the language design that presented them as a separate mechanism)
@@splytrz Great insights, @splytrz! There's a distinction here; mixins as a pattern versus mixins as a language mechanism. I agree that under the hood, mixins rely on inheritance (i.e. often multiple inheritance). As a mechanism, they aren’t distinct. What sets mixins apart is their purpose / use case: they’re not about defining an ‘is-a’ relationship like traditional inheritance, but instead about injecting modular + reusable behavior into a class. Dart’s special syntax for mixins can make it feel like something entirely new, but it’s more about enforcing a lightweight way to share functionality without adding the complexity of full multiple inheritance. The main takeaway is that mixins represent a design philosophy rather than a fundamentally separate mechanism. Thanks for watching + great insights :)
@@TheCodingGopher I added a comment expanding on this. The example you provide is not distinct from inheritance (neither as a pattern nor as a language mechanism), and I've explained why in my comment and provided an alternative example that is distinct from inheritance. It is distinct from single inheritance, sure, but it quite literally is textbook multiple inheritance, and this is also explained in the python docs. So to say it's different from inheritance is incorrect, but to say it's different from traditional, single inheritance is correct.
Use composition when you need flexibility (e.g., swapping loggers at runtime), better encapsulation, or to avoid multiple inheritance issues (i.e. for Java). And generally, prefer mixins for Great lightweight, reusable functionality that directly integrates into the class / if you want to combine multiple behaviors like logging, notifications, or validation.
Depends on language, mixins are more like building finally class from lego parts or adding things to .prototype in JS. Interfaces/traits with implementation which you can't/won't change
@@guelakais1438 depends a bit on the language. There are subtle differences. Mixins are perhaps most similar to PHP traits, where you can add behavior to a class without actual inheritance. You can't use mixins or PHP traits as type arguments. Java interfaces and Rust traits can have both (limited) behavior and can be used as type arguments.
Not quite. Mixins are a way to add reusable behavior to classes through inheritance in OOP, while pytest fixtures are specifically designed for setting up / tearing down test preconditions in pytest. Fixtures are automatically injected into test functions (which is the core part of the pytest framework), whereas mixins are a more general programming construct used for sharing code across classes. They can overlap in functionality in some cases - but they're fundamentally different.
Thoughts on the new editing style?
i’m a fan of it 🙂↕️
I prefer the old style
The fade-in on the subtitles is quite distracting, I'd prefer them to just cut from one line to the next. Otherwise I like it!
Hate the fade in on the subtitles. Means I can't immediately read it
not a fan of these brainrot tiktok-style captions
This seems like composition but with extra steps
Yep, mixins are imo a really bad practice, especially when compared to the likes of composition.
Mixins do not imply an "is-a" semantics while using inheritance. They are like interfaces with default implementations. You can enforce a specific interface to be implemented in the descendant class by extending this interface in the mixin itself.
Thank you, very clear and simple explanation. Mixins look very similar to what PHP calls Traits.
My pleasure
I suppose it's kind of like Rust's traits. Maybe you could compare and contrast different languages and how they use the concept.
Yes, these are very similar. Though traits in Rust achieve the shared behavior without inheritance. That's a solid idea for a future video
This use case is covered by the traits in Rust and PHP, and interfaces with default implementations in Java.
Mixins are the foundations of modern Minecraft modding, but we just see it as bytecode modification framework.
:o
While they have the same name, the Mixins of Forge or Fabric are a completely different thing that have no real relation. This is talking about a design pattern while the Forge or Fabric mixins are a form of code injection that act closer to a decorator pattern than a mixin pattern. But really Fabric/Forge mixins are not a programming pattern, they're a specific feature, mixins are effectively a form of instrumentation in Fabric/Forge, whereas the mixin pattern in Computer Science is a specific programming patterns like inheritance or composition. Again despite the names they are largely unrelated to each other.
@@DreadKyller deeply they are the same thing. Yes, Spongepowered Mixin are a tool to modify bytecode and this video is about a trait-like design pattern to add functionality to a class.
But what else Sponge's Mixins are? A tool to add/modify functionality of existing classes without the usage of inheritance. This is sort of stated in their repository: "Mixin is a trait/mixin framework for Java using ASM [...]"
I always love your content, keep it up!
Cheers!
If you could go over a comparison of this versus composition, as they seem like they're attempting the same thing, shared reusable pieces of logic without the need for complex hierarchy chains. What benefits does this have over traditional composition patterns?
This video just seems like your trying to build an ECS (Entity Component System) or Rust Traits, Java Interfaces or trying to do composition. Basically what my point is, is that there are many well established ways to achieve the same goals as mixins. Yes, mixins can save those few extra lines, but that's really the only advantage I see: a bit more readability.
Generally Mixins can have lots of problems (Im using Java Mixins as an example here):
Mixins rely on naming schemes in projects. This means, when a class / module / method is renamed, the mixin breaks. Any structural changes in the project result in mixins breaking.
Mixins are usually byte-code inserts, which means they bypass compiler checks and might introduce breaking code.
Also I believe what you implemented is just composition: One component that does Logging, the other that does File Reading.
Reduce duplication by copy pasting the code at compile time
missed you Gopher! Sad to see no daily uploads but i hope that means ur enjoying the holidays!! i really enjoy this type of video, can’t wait to see what type of content you’ll make this coming year
🚀🚀!
I’ve been trying to wrap my head around this idea (without putting too much effort, to be fair), and from this explanation I understand the “@“ decorators are basically syntactic sugar for all the boilerplate that would be needed from using [composition + dependency injection + inversion of control]. Ok, that seems nice.
... seems like a mixture of an Aspect (as in AOP) combined with DI (Dependcy Injection.)
Good video. I wish I had some more time to understand the final example, feels like it got cut off to meet the exact 3 minute mark.
Perhaps immediately jumping into an example and narrating it would have saved more time at the start.
Its the cpp equivalent of interfaces
Similar, but not exactly. Mixins in Python are more like reusable code snippets added via inheritance, while C++ interfaces (i.e. pure virtual classes) define a contract that classes must implement. Mixins add behavior; interfaces enforce structure.
All right let's mixin
Let's go mixin
I'm still not convinced that mixin is distinct from inheritance. It's just a pattern that uses (multiple) inheritance.
To clarify, I don't have an issue with the video. Maybe with the title though.
I'm coming from Dart, where mixins have special syntax, which has made me confused for a long time because I couldn't see how they're different, and the video title has made me hope I'll finally understand it. But nope!
Especially seeing you use inheritance to implement a mixin convinced me more that the Dart team has added them as a hack to enable multiple inheritance.
I think the core of my misunderstanding was that I was thinking about a **different category**. There is no difference between mixins and multiple inheritance **as a language mechanism**, but, **as patterns** they are different.
So, while everyone was talking about a design pattern, I was thinking about the language mechanism. (This is reasonable though, because it was prompted by the language design that presented them as a separate mechanism)
@@splytrz Great insights, @splytrz! There's a distinction here; mixins as a pattern versus mixins as a language mechanism.
I agree that under the hood, mixins rely on inheritance (i.e. often multiple inheritance). As a mechanism, they aren’t distinct. What sets mixins apart is their purpose / use case: they’re not about defining an ‘is-a’ relationship like traditional inheritance, but instead about injecting modular + reusable behavior into a class.
Dart’s special syntax for mixins can make it feel like something entirely new, but it’s more about enforcing a lightweight way to share functionality without adding the complexity of full multiple inheritance. The main takeaway is that mixins represent a design philosophy rather than a fundamentally separate mechanism.
Thanks for watching + great insights :)
@@TheCodingGopher I added a comment expanding on this. The example you provide is not distinct from inheritance (neither as a pattern nor as a language mechanism), and I've explained why in my comment and provided an alternative example that is distinct from inheritance. It is distinct from single inheritance, sure, but it quite literally is textbook multiple inheritance, and this is also explained in the python docs. So to say it's different from inheritance is incorrect, but to say it's different from traditional, single inheritance is correct.
Any reason to use this over composition (e.g. make the logger class a field rather than inheriting from it)?
Use composition when you need flexibility (e.g., swapping loggers at runtime), better encapsulation, or to avoid multiple inheritance issues (i.e. for Java).
And generally, prefer mixins for Great lightweight, reusable functionality that directly integrates into the class / if you want to combine multiple behaviors like logging, notifications, or validation.
Isn't this C macro?
More like libs
to be honest: I don`t see the difference to interfaces or traits
Depends on language, mixins are more like building finally class from lego parts or adding things to .prototype in JS. Interfaces/traits with implementation which you can't/won't change
@@guelakais1438 depends a bit on the language. There are subtle differences. Mixins are perhaps most similar to PHP traits, where you can add behavior to a class without actual inheritance. You can't use mixins or PHP traits as type arguments. Java interfaces and Rust traits can have both (limited) behavior and can be used as type arguments.
so mixins are just pytest fixtures
Not quite. Mixins are a way to add reusable behavior to classes through inheritance in OOP, while pytest fixtures are specifically designed for setting up / tearing down test preconditions in pytest. Fixtures are automatically injected into test functions (which is the core part of the pytest framework), whereas mixins are a more general programming construct used for sharing code across classes.
They can overlap in functionality in some cases - but they're fundamentally different.
@@TheCodingGopher I might've been writing tests wrong)