4 ms·
I'm not sure I understand you. is_blocked(user, other_user) seems like it’s still object-oriented to me. Oh sure it has terrible syntax, but we’re still d
by geocar 6y ago
I'm not sure I understand you.
is_blocked(user, other_user)
seems like it’s still object-oriented to me. Oh sure it has terrible syntax, but we’re still designing our application with encapsulation and if this is CL and “is-blocked” is a generic then it’s how you would write this in an CLOS-style OOP — it would just be written (is-blocked user other-user)
On the other hand:
other_user.id in user.blocks
is what I would imagine a non-OOP version might look like, because it’s not dynamic and not encapsulated. If we were to write it:
in(other_user.id, user.blocks)
or:
(in (other-user :id) (user :blocks))
I also still think these functions are better than the object-oriented ones: they’re faster, and it’s clear to the reader if you can get the ids without the object (say by pushing this into your query) you will save a lot of runtime and programmer-time.
I also think if you make decisions based on what is popular (e.g. for startups), instead of actually thinking about it, you are subscribing to dogma. Maybe sometimes not-thinking is good, but it seems possible that what you think of as a “start up” has largely only existed in the short time period that object languages were in vogue. Why do you think this is causal? Do you think if go (for example) becomes popular we won’t have startups any more?
- kstenerud 6y agoThey also force you to reach into the implementation's data structure directly (the "blocks" container), whereas the message-oriented one allows you to refactor without having to visit every call site and also potentially need to rework any other accesses that are doing more than just checking for membership. Message passing allows much more fine-grained access controls to the implementation, and in many cases that's highly desirable, especially as the implementation gets more complex and the purposes of accessing the data more specific, and excess coupling more problematic.
- bionhoward 6y agoknow any good examples of fine grained access control in message passing systems? sounds compelling for a current project
- kstenerud 6y agoMessage passing is the basic idea behind all method calls in OO languages, and the premise behind APIs to libraries, systems, etc. It's just a formalisation for how to make requests and communicate with another system. Even HTTP is message oriented: You can send GET, POST, DELETE etc to an HTTP server without knowing HOW it will do it. You can't browse the filesystem or read byte x of a file or anything because it's access controlled behind the interface. It's the same in programs: You have primitives, but you generally hide them behind higher level APIs, or in the case of OO you encapsulate data and behaviour together in one place to (hopefully) make it easier for a human to conceptualise what's going on. OO is no silver bullet; it's just one way among many of organising your interfaces and data, and to make combinable components that increase the expressivity and thus power of your codebase. In the previous example, client code was looking inside data "user" to check if a particular thing exists in its "blocks" data, but it would be better to work at a higher conceptual level, such as a function/method/message called "has this user blocked user X? (returns yes or no)". Then when someone reads that code later, they can at-a-glance see what the program is doing conceptually, rather than scanning around to figure out what the code is doing with "blocks" and work out what it's attempting to accomplish.
- geocar 6y agoI'm trying not to speculate about what 3pt14159 meant just because what you said makes sense to me, because I also think it's clear you mean something else. Or put another way, I think agreeing that message-passing is useful is not an endorsement of OOPL: After all, Erlang supports message-passing.
- TomSwirly 6y ago> I'm not sure I understand you. `is_blocked(user, other_user)` seems like it’s still object-oriented to me. In OO, the object exposes what services it offers. But in your code fragment, there is no way for a new implementation of `user` to override `is_blocked` - in most languages. (C++ has ADL/Koenig resolution https://en.wikipedia.org/wiki/Argument-dependent_name_lookup https://en.wikipedia.org/wiki/Argument-dependent_name_lookup which actually does let you do this generically at compile time.)
- dragonwriter 6y ago> In OO, the object exposes what services it offers. In modular, especially statically typed, functional programming, modules identify what services they offer, and what data items those services consume, and the concerns of specification of data types and provision of services are decoupled.
- nybble41 6y ago> in most languages I'm pretty sure the language being referenced was Common Lisp, which supports multiple dispatch (in CLOS). In a multiple-dispatch OOP system methods can be specialized based on any argument—this is somewhat like ADL in C++ but more generalized. Ergo, a new implementation of 'user' can override or extend more generic versions of 'is_blocked'.