this post was submitted on 17 Nov 2024
76 points (95.2% liked)

Programmer Humor

32483 readers
233 users here now

Post funny things about programming here! (Or just rant about your favourite programming language.)

Rules:

founded 5 years ago
MODERATORS
 
class BaseFunction {
  static #allowInstantiation = false;

  constructor(...args) {
    if (!BaseFunction.#allowInstantiation) {
      throw new Error(
        "Why are you trying to use 'new'? Classes are so 2015! Use our fancy 'run' method instead!"
      );
    }
    for (const [name, validator] of this.parameters()) {
      this[name] = validator(args.shift());
    }
  }

  parameters() {
    return [];
  }

  body() {
    return undefined;
  }

  static run(...args) {
    BaseFunction.#allowInstantiation = true;
    const instance = new this(...args);
    BaseFunction.#allowInstantiation = false;
    return instance.body();
  }
}

class Add extends BaseFunction {
  parameters() {
    return [
      ["a", (x) => Number(x)],
      ["b", (x) => Number(x)],
    ];
  }

  body() {
    return this.a + this.b;
  }
}

console.log(Add.run(5, 3)); // 8



top 11 comments
sorted by: hot top controversial new old
[–] [email protected] 1 points 1 hour ago

JS disgusts me

[–] [email protected] 11 points 6 hours ago (1 children)

A true FP programmer would make it apply instead of run...

[–] [email protected] 1 points 45 minutes ago

Ahem, map...

And, of course, everything is a lazy list even if the functions can't handle more than one element in each list.

[–] [email protected] 5 points 6 hours ago

Dont look at C++ with std:: function

[–] [email protected] 5 points 7 hours ago

I'm pretty sure this post is designed to kill the soul. I am made slightly worse for witnessing this abortion of an implementation and I will never be quite the same again.

[–] [email protected] 2 points 6 hours ago

I think that's called a functor.

[–] [email protected] 24 points 13 hours ago

OP, what's your address? I have a "present" for you

[–] [email protected] 11 points 12 hours ago (2 children)
[–] [email protected] 9 points 9 hours ago* (last edited 9 hours ago)

Yep, some code examples from the official documentation. This:

printPersons(
    roster,
    (Person p) -> p.getGender() == Person.Sex.MALE
        && p.getAge() >= 18
        && p.getAge() <= 25
);

...is syntactic sugar for this:

interface CheckPerson {
    boolean test(Person p);
}

printPersons(
    roster,
    new CheckPerson() {
        public boolean test(Person p) {
            return p.getGender() == Person.Sex.MALE
                && p.getAge() >= 18
                && p.getAge() <= 25;
        }
    }
);

...which is syntactic sugar for this:

interface CheckPerson {
    boolean test(Person p);
}

class CheckPersonEligibleForSelectiveService implements CheckPerson {
    public boolean test(Person p) {
        return p.gender == Person.Sex.MALE &&
            p.getAge() >= 18 &&
            p.getAge() <= 25;
    }
}

printPersons(roster, new CheckPersonEligibleForSelectiveService());

The printPersons function looks like this:

public static void printPersons(List<Person> roster, CheckPerson tester) {
    for (Person p : roster) {
        if (tester.test(p)) {
            p.printPerson();
        }
    }
}

Basically, if you accept a parameter that implements an interface with only one method (CheckPerson), then your caller can provide you an object like that by using the lambda syntax from the first example.

They had to retrofit lambdas into the language, and they sure chose the one hammer that the language has.

Source: https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html

[–] [email protected] 2 points 9 hours ago* (last edited 9 hours ago)

Golang also does this, but it's not classes.

[–] [email protected] 4 points 13 hours ago

Amazing, lol