Skip to content

Functional Interfaces

tekdemo edited this page Oct 4, 2024 · 1 revision

Functional Interfaces

In Java, you can reference functions directly, just like you would variables. These are known as "functional interfaces", or sometimes "lambdas".

For an alternative document, consider WPILib's Documentation. https://docs.wpilib.org/en/stable/docs/software/basic-programming/functions-as-data.html

These functional interfaces are used all over WPILib, and allow shortcuts and more dynamic code handling through callbacks and polling.

Let's start by writing a simple function in a class:

public ExampleSystem extends Subsystem{
    public void doSomething(){
        System.out.println("hooray");
    }
}

This doSomething function can be described as meeting the requirements for the Runnable interface. A Runnable is simply shorthand for a function that takes no arguments, and does not return anything. If we were to then hop into RobotContainer, we could utilize this in a few ways

//Robotcontainer.java
joystick.a().onTrue(new InstantCommand(exampleSystem::doSomething));

What's happening is we simply pointed InstantCommand (which takes a Runnable object as the argument) to doSomething. Note the use of the :: rather than the ., which is the method reference operator. This ensures the compiler is grabbing the function interface, rather than trying to call the function.

With that done, we now can move onto Suppliers. These are functions that supply meaningful values. If this sounds like "return" statements, you're correct.

public ExampleSystem extends Subsystem{
    public boolean isNearby(){
        return localsensor.getDistance()<10;
    }
    public double getDistance(){
        return localsensor.getDistance();
    }
}

The function isNearby matches the requirement for BooleanSupplier, and getDistance matches the requirement for DoubleSupplier. BooleanSuppliers are easier to demonstrate, as Triggers use BooleanSuppliers as a condition for when to start and stop commands.

new Trigger(examplesystem::isNearby).onTrue(InstantCommand(exampleSystem::doSomething));

Next is a "Consumer" concept, which is any function that accepts one argument of a given type.

public ExampleSystem extends Subsystem{
    public void setTarget(double distance){
        //do something with distance
    }
}

While there's not a ton of easy examples for this, they do come up: Most notably, when

Clone this wiki locally