Is it possible to pull function arguments out of an enum?

Hello,

let’s say I have an enum and some functions, each pertaining to a member of that enum. (The real enum has 11 entries that are relevant for me, and the functions take two parameters each, always the same)

enum E {
    A_1,
    A_2,
    ...
    A_n;
}

T a_1(T x);
T a_2(T x);
...
T a_n(T x);

Is there any way to switch over enum E while not having to repeat the passing of the parameters? I.e. I want to avoid this:

T y = switch (e) {
    case A_1 -> a_1(x);
    case A_2 -> a_2(x);
    ...
    case A_n -> a_n(x);
}

and do something that looks a bit like this:

T y = switch (e) {
    case A_1 -> a_1;
    case A_1 -> a_2;
    ...
    case A_n -> a_n;
} (x);

If it doesn’t exist it’s not a big deal. I can compute the value x ahead of time and just pass it 11 times.

You can do something like this:

enum Foo {
  FOO_1 { String bar() {return "foo_1";} },
  FOO_2 { String bar() {return "foo_2";} },
  FOO_3 { String bar() {return "I love JLS 8.9.1";} };

  abstract String bar();
}

It works the way you expect it to. The precise semantics are in the JLS.

Basically, FOO_3.bar() will return the String specified there.

1 Like

Thanks, that would probably be what I would do if the enum didn’t get overwritten on the server. :grinning:

The idea is to have a formula creation factory method for each binary operation (including conversion of int to bool) so that I merely need to switch over the kind of the operation to get the desired behavior. It is not a big deal though.

I don’t quite see why you would want this in the project, thus in this case, I would recommend you change your approach. Your question has strong XY problem vibes :slightly_smiling_face:

What would that factory be for?

The real problem for me is that I can’t read the formula creation code easily:

Formula e; // condition, converted to bool (if applicable)
Statement s; // else body
Formula ifFalse= new BinaryOpFormula(BinaryOperator.AND, magic, magic);

So I created a factory class that produces formulas (while handling conversions for binary/unary operators automatically) and then the above horrible code is almost readable:

Formula ifFalse = fac.and(magic, magic);

Basically this way I can copy the definition of pc and vc nearly verbatim into the code, leaving less room for errors. The only thing that is annoying is that I have to pass the factory around and that I have to write out its name, but the benefit of readability trumps that.

If you have a factory class, you might want to

  • make all the methods static
  • import static ...FooFactory.* in your classes

I still don’t see why you need your switch. A binary(Formula, BinaryOperator, Formula) seems what you want, at this just copies the formula onwards.

The * import is actually great, it eliminated the need to pass the factory completely.

I think whether I take the second step and parametrize over the operator is a matter of taste, at least w.r.t. to the logical operators. Adding binary and an operator each time (assuming I do a static import of BinaryOperator.*) is still too verbose for the statement verification. Prefix notation is bearable for small formulas, such as those in the definition of pc and vc.
However all the other operators only occur in my switch, so I can bundle them. That would be the best of both worlds.

A common solution in languages with operator overloading would be to simply overload the usual boolean operators for formulas with the factory methods.

As one of Java’s philosophies is to be clear even if it is more verbose, Java does not allow for operator overloading.
Instead, one could define self factory methods.

a & (b | c)

becomes

a.and(b.or(c))

which is closer to infix notation and only has a slight overhead.

But as you noticed, the pc and vc formulas are simple enough and do not need such wrapper classes.

1 Like