this post was submitted on 17 Nov 2024
113 points (96.7% liked)

Programmer Humor

32483 readers
447 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



you are viewing a single comment's thread
view the rest of the comments
[–] NorthWestWind@lemmy.world 12 points 19 hours ago (3 children)
[–] ornery_chemist@mander.xyz 3 points 6 hours ago

Hence, Clojure. It's not just functions that implement IFn... as the string of "cannot cast to clojure.lang.IFn" errors that I get because I couldn't be bothered to validate my data's shape is eager to inform me.

[–] Ephera@lemmy.ml 13 points 15 hours ago* (last edited 15 hours ago) (1 children)

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

[–] mbtrhcs@feddit.org 6 points 6 hours ago

That's not quite right. In bytecode, lambdas are significantly more efficient than anonymous class instances. So while the lambda implementation is semantically equivalent, characterizing it like you have is reductive and a bit misleading.

[–] LodeMike@lemmy.today 2 points 16 hours ago* (last edited 16 hours ago) (1 children)

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

[–] firelizzard@programming.dev 1 points 6 hours ago* (last edited 6 hours ago) (1 children)
[–] LodeMike@lemmy.today 1 points 5 hours ago

Golang uses modules, not classes. Each of which may have its own main file.