0

When everything seems to be a collection, how do you enforce rules for members of said collection without the use of an interface?

As far as I am aware, in languages that don't fully support OOP features (like JS) you cannot control that each member must either be of certain type / return a certain type / structure. It can just be put inside the collection without any boundaries.

So, where as in an OOP paradigm, if your object uses an interface, your collection will always have its members following the same rules, in a non-OOP paradigm, you just can't do that unless you litter code with if statements.

Let's create examples for both words. First, OOP, using PHP:

interface MemberInterface
{
    public function parseInput($input): string;
    public function getInput(): string;
}

An interface for my collection. My collection is an array inside an object that ensures the rules of the interface are respected by using dependency injection:

class Collector
{
    private array $members;

    public function addMember(MemberInterface $member) {
        $this->members[] = $member;
    }

    public function getMembers() {
        return $this->members;
    }
}

Now, every time I query Collector->getMembers() I am assured that I will get members with behavior that is predictable due to them respecting the interface (because otherwise they won't be in the collection).

Now let's look at how you'd naively do it in a functional manner, using JS:

let collection = {};

collection.member_one = {
    function parseInput(input) {
        //
    },
    function getInput() {
        //
    }
}

Now, let's assume we have a piece of (pseudo) code that depends on this collection's members functions:

Collection->getMember('member_one')->getInput()

What do we get?

+--------+------------+
|  PHP   | JavaScript |
+--------+------------+
| String | ?          |
+--------+------------+

JavaScript cannot ensure that, at the moment of adding that member to the collection its return is of a certain (either simple or complex) type as such, it makes it impossible to depend on because you don't know what you'll get.

Sure, you can litter your code with tons of checks but that's not exactly desirable.

How do non-OOP people go about solving this issue?

  • What rules? What arrays? How do interfaces matter here? – Telastyn Aug 31 at 5:24
  • @Telastyn Updated to be as concise as possible but I mean...the question is the question, I think it's pretty straight-forward with the new updates. – coolpasta Aug 31 at 5:41
  • Did you mean to say "dynamic" instead of "functional"? Because in a statically typed functional language you can absolutely declare that collection members must be of a certain type, just like in a statically typed OO language. – JacquesB Aug 31 at 6:24
  • @JacquesB I didn't mean to even say functional, sorry. I meant to say that languages such as JS don't have interfaces that allow you to dictate behavior of members. – coolpasta Aug 31 at 6:27
  • @DocBrown I've updated the question with examples. – coolpasta Aug 31 at 6:27
5

Gross...

So this isn't an OO thing. Pretty much any modern language supports typed collections. Hell, most of the ancient ones did too. You just say vector<string> or List<string> or List of string or [string] and you're done. If anything, functional languages are more likely to have strong typing that enforce your collections only contain the stuff they're supposed to.

Languages like php and javascript with dynamic typing allow this sort of flexibility because it speeds development since you don't have to placate the typechecker - or so the argument goes. This sort of problem is sometimes solved there by unit testing or littering a bunch of checks everywhere. But usually it's simply not solved. These languages are usually designed for and used in quick one-off scripts. If you put the wrong data into the array then your script blows up and you hammer on it until it doesn't blow up. Most command line shells for example use dynamic typing.

When things get more complex, more programmers get involved, or you're doing something where you really need to know what type is in the array, programmers tend to migrate towards languages with stronger type systems. (Except for Javascript, where browser lock-in has slowed migration to things like Typescript).

  • How about return types / declaring the body of these members? – coolpasta Aug 31 at 6:43
  • @coolpasta - I have no idea what you're asking. – Telastyn Aug 31 at 6:45
  • You can love them or hate them, but PHP and Javascript are definitely not just used in in quick one-off scripts. Nevertheless, good answer. – Doc Brown Aug 31 at 6:50
  • This answer is a bit confusing because the question uses PHP as an example of a explicitly typed language in contrast to JS, but you are lumping them together as dynamically typed! Actually PHP supports optional type annotations, which is what is used in the example. – JacquesB Aug 31 at 9:38
  • @JacquesB - except PHP's arrays are not explicitly typed. They're not even arrays. They're bags of whatever. – Telastyn Aug 31 at 18:04
2

You question is actually not related to OO versus functional at all. It is about type systems. (And to be clear, JavaScript is OO.) In statically typed languages and languages with type annotations, you can declare that a parameter must be of a certain type. This is not possible in languages like JavaScript with no explicit typing.

So the answer to your question is basically "they don't". Typically they worry about the behavior of things, rather than type of things. Ensuring that a collection only contains things of a certain type is irrelevant if the program exhibit the behavior it is supposed to.

Also note that explicit typing does not give the guarantees you suggest. You state "I am assured that I will get members with behavior that is predictable due to them respecting the interface". In fact an interface does not guarantee any form of behavior, only that a method with a certain name and signature exist. In JavaScript, you will just check for the existence of this method by calling it.

For example. if you have a complex calculation, explicit typing can guarantee that that output is...a number. But not that the calculation is actually correct. You need something like unit testing to verify correct behavior.

1

In functional-programming those things are usually called typeclasses.

Let's look at some haskell code:

> let a = [3, 4, 5]

So this is a list of numbers, but how do we express that those are numbers? Let's look at the type:

> :t a
a :: Num t => t

That Num t is the key. It tells us that the actual type parameter t is constrained through the Num typeclass. That it, functions defined on Num work on it. So this list can be summed (without ifs):

> sum a
12
  • Well, that wraps it up. They're interfaces...but for cool people. How about return types as per my updated question? – coolpasta Aug 31 at 6:28
  • I answered before your update to the question. I don't really know neither PHP nor JS. If you are looking specifically at those languages, I unfortunately can not help. – Robert Bräutigam Aug 31 at 6:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.