2

I'm going through Vavr Usage Guide's section about performing side-effects with Match and other "syntactic sugar" as they call it. Here is the example given there:

Match(arg).of(
    Case($(isIn("-h", "--help")), o -> run(this::displayHelp)),
    Case($(isIn("-v", "--version")), o -> run(this::displayVersion)),
    Case($(), o -> run(() -> {
        throw new IllegalArgumentException(arg);
    }))
);

and then it goes into discussing how run should not be run outside of lambda body, etc.

IMHO, something was lacking in the explanation to give me full clarity, i.e. is run an existing method on some Vavr interface (which I couldn't find) or should it be my own method in the surrounding code base?

So I endeavored and spelled out the above example just slightly to be something that I can run and see the results of it:

@Test public void match(){

String arg = "-h";

        Object r = Match(arg).of(
                Case($(isIn("-h", "--help")), o -> run(this::displayHelp)),
                Case($(isIn("-v", "--version")), o -> run(this::displayVersion)),
                Case($(), o -> run(() -> {
                    throw new IllegalArgumentException(arg);
                }))
            );

        System.out.println(r);
    }

    private Void run(Supplier<String> supp) {
        System.out.println(supp.get());
        return null;}

    private String displayHelp() {return "This is a help message.";}
    private String displayVersion() {return "This is a version message.";}

Could someone please confirm that I'm on the right track with how this was envisioned to function by Vavr's designers or did I totally go off on a tangent in which case I'd appreciate some guidance as to how it should be.

Thank you in advance.

Updated:

import static io.vavr.API.run;

    @Test public void match1() {

            String arg = "-h";

            Object r = Match(arg).of(
                    Case($(isIn("-h", "--help")), o -> run(this::displayHelp)),
                    Case($(isIn("-v", "--version")), o -> run(this::displayVersion)),
                    Case($(), o -> run(() -> {
                        throw new IllegalArgumentException(arg);
                    }))
                );

            System.out.println("match: " +r);
        }

        //private Void run(Supplier<Void> supp) {supp.get();}

        private void displayHelp() {System.out.println("This is a help message.");}
        private void displayVersion() {System.out.println("This is a version message.");}
Simeon Leyzerzon
  • 18,658
  • 9
  • 54
  • 82

1 Answers1

6

It's io.vavr.API.run. According to the Javadoc, you're supposed to import the basic VAVR functionality via

import static io.vavr.API.*;

The run function calls a Runnable (a function () -> void) once and returns (Void)null. It's used because

Case($(isIn("-h", "--help")), o -> this.displayHelp())

does not work when displayHelp() is void, since void isn't a well-behaved type in Java. Specifically, Supplier<void> and Function<?, void> do not work. Additionally,

Case($(isIn("-h", "--help")), this.displayHelp())

would execute displayHelp() before the match, so the matching is useless. This rules out all three (ignoring argument number) overloads of Case. run fixes this, because Supplier<Void> and Function<?, Void> are possible, and taking a Runnable means the action can be deferred until the argument to Case is needed.

HTNW
  • 27,182
  • 1
  • 32
  • 60
  • Ah, so if I am understanding you correctly what you suggesting is that my initial rendition is superfluous as I re-implemented the existing `io.Vavr.API.run() ` and instead the code should be something like in `match1()` method (see question update)? And the side-effect producing methods are strictly for side-effects, no return value from them is expected? – Simeon Leyzerzon Feb 06 '18 at 13:56
  • 3
    You’re new code is correct, but there is no reason not to have a return value. If there is no return value (which is undesirable, since it implies side effects) run is used to get around Java’s irregularities. If there is a return value (which is desirable, and is the usual case), just don’t use run. – HTNW Feb 06 '18 at 15:25