4 ms·
I've never liked classical OOP much, but multiple dispatch is a lovely paradigm. One doesn't define _classes_ per se, but rather just plain old boring structs.
by ced 8y ago
I've never liked classical OOP much, but multiple dispatch is a lovely paradigm. One doesn't define _classes_ per se, but rather just plain old boring structs.
struct Player
xp::Int
end
struct Monster
hp::Int
end
function hit(p::Player, m::Monster)
p.xp += 10
m.hp -= 20
end
The nicest thing is how one one doesn't need inheritance to "add a method" to an object. One just defines my_function(s::String) to be whatever, and it doesn't interfere with anyone else's code.
- donatj 8y agoRoughly that exact design but with classes was my instant thought.
- jcelerier 8y ago> One doesn't define _classes_ per se, but rather just plain old boring structs. in which language are there differences between classes and structs ?
- stevelosh 8y agoCommon Lisp http://www.lispworks.com/documentation/lw70/CLHS/Body/m_defstr.htm http://www.lispworks.com/documentation/lw70/CLHS/Body/m_defs... http://clhs.lisp.se/Body/m_defcla.htm http://clhs.lisp.se/Body/m_defcla.htm
- ygra 8y agoOf the languages i know, C++ and C# come to mind. Granted, in C++ the differences are fairly minor and inconsequential at runtime.
- wffurr 8y ago"struct" here is meant in the same sense that the author of the post refers to "PoD objects". Just data in public fields. Whereas a "class" is usually thought of as private data exposed only through methods. There is no language that enforces this distinction; it's purely by convention. C++ makes it a little simpler by having a different default access level. In any case, you are being needlessly pedantic and missing the point.
- deleted 8y ago[deleted]
- leiroigh 8y agoAbove example is from julia. Julia structs have C layout and have no member functions. The analog of "classes" in julia are "abstract types"; e.g. `AbstractArray{T}` is anything that implements the AbstractArray interface and holds objects of type T. Abstract types have no instances (all objects have a concrete type, that may be a subtype of an abstract type). Binary compatibility between class and superclass is a cool feature in many OOP languages. This allows fast dynamic dispatch via vtable and lots of shared binary code for non-virtual methods (you can always memory pun from class to superclass). Julia does not support that feature: your different methods can share source code, but they get compiled separately. This is good for performance (more aggressive inlining) and bad for compiling small shared libraries (it is very painful to create julia apps/libs that work without invoking the JIT-compiler at runtime; can be done via custom sysimg). In some sense, julia is not very well suited to closed source business models.
- matwood 8y agoYou're describing the Anemic Domain Model which is quite useful.
- iguy 8y agoAs a non-OOP-thinker, this seems completely natural to me. The verb hit doesn't belong completely to one noun, so it shouldn't be forced to live within the struct/class with the data (which really is about only that noun). What problem is solved by forcing the function to belong to one of the actors, as in joe.hit(tiger).with(sword) or something? People say things about encapsulation, but it seems here that hit may change the state of Player, Monster and Weapon, so their states can't be fully private. In this code you can also have hit(p::Player, w::Door), if this were not allowed then perhaps you'd have to have separate hit_player_monster and hit_player_door functions... is that the problem?
- jbverschoor 8y agoOk nice, then you get a huge if tree for all different monsters and weapons.
- ubercow13 8y agoHow's that any different to a 'classical OOP' approach?
- wffurr 8y agoYou can have free functions that operate on your classes instead of shoehorning every operation into one class or another or creating new ones from whole cloth just to hold a function (e.g. the Hit class mentioned earlier). Writing methods makes it easy to add new types but not methods; you have to change every class to implement a new method. Writing functions makes it easy to add new function, but you have to update every function for a new type. Each has its place, and issues arise when certain languages (e.g. Java) or paradigms ("classical" OOP) make it impossible to use one or the other style.
- ced 8y agoWhat do you mean? It wouldn't be "if". You'd just have function hit(p::Player, m::Goblin) ... end function hit(p::Player, o::Ogre) ... end In Julia, there's limited inheritance, so you could group monsters in a hierarchy to limit the redundancy (eg. Goblin <: Monster <: Creature). Or you can use multiple dispatch like a trait system, to get even greater flexibility.