Functional Programming in Java

Now there are new fashionable languages ​​using the functional programming paradigm. However, in normal Java,
you can use functions to describe the behavior of objects. And you can do this completely in the framework of the Java syntax.

I published a Java library that allows you to bind objects through functions (see https://code.google.com/p/tee-binding/ )

image



Class Description


public class It ‹E›
- the main class, contains a reference to an object of any type and updates all communications when changing values ​​in one of the instances. Example
    It‹String› a1 = new It‹String›().value("A");
    It‹String› a2 = new It‹String›().value("B");
    System.out.println("a1: "+a1.value()+", a2: "+a2.value());
    a1.bind(a2);
    System.out.println("a1: "+a1.value()+", a2: "+a2.value());
    a1.value("C");
    System.out.println("a1: "+a1.value()+", a2: "+a2.value());
    a2.value("D");
    System.out.println("a1: "+a1.value()+", a2: "+a2.value());


result:

a1: A, a2: B
a1: B, a2: B
a1: C, a2: C
a1: D, a2: D


The Number, Note, Toggle classes are derivatives of the It class for storing values ​​of a specific type (for Double, String, and Boolean, respectively) and contain methods for specifying binding using functions. Example:

    Numeric c = new Numeric().value(0);
    Numeric f = c.multiply(9.0).divide(5.0).plus(32.0);
    System.out.println("f: " + f.value() + ", c: " + c.value());
    System.out.println("/let f = 100 ");
    f.value(100);
    System.out.println("f: " + f.value() + ", c: " + c.value());    
    System.out.println("/let c = 100 ");
    c.value(100);
    System.out.println("f: " + f.value() + ", c: " + c.value());


result:

f: 32.0, c: 0.0
/let f = 100 
f: 100.0, c: 37.77777777777778
/let c = 100 
f: 212.0, c: 100.0


as you can see, this is the function of converting the temperature from the Celsius scale to the Fahrenheit scale (F '= C' * 9/5 + 32). From the definition of a variable,
Numeric f = c.multiply(9.0).divide(5.0).plus(32.0);

this is quite obvious. It can also be noted that linking through a function is bidirectional.

Note: function pseudo-operators are calculated sequentially without taking into account the priority of operations.

For more complex cases, you can use the Fork class. It allows you to use conditions in the binding, for example:

    System.out.println("/n = -10");
    Numeric n = new Numeric().value(-10);
    Note r = new Note().bind(new Fork‹String›()
            .condition(new Toggle().less(n, -5))
            .then("Frost")
            .otherwise(new Fork‹String›()
                .condition(new Toggle().less(n, +15))
                .then("Cold")
                .otherwise(new Fork‹String›()
                    .condition(new Toggle().less(n, +30))
                    .then("Warm")
                    .otherwise("Hot")
                    )));
    System.out.println(r.value());
    System.out.println("/let n = +10");
    n.value(10);
    System.out.println(r.value());
    System.out.println("/let n = +20");
    n.value(20);
    System.out.println(r.value());
    System.out.println("/let n = +40");
    n.value(40);
    System.out.println(r.value());

result:
/n = -10
Frost
/let n = +10
Cold
/let n = +20
Warm
/let n = +40
Hot


The condition record is quite obvious, depending on the value of the variable n, the text Frost, Cold, Warm or Hot is entered into the variable r.

Library application


Unfortunately, binding and functions cannot be used directly. Consider the modifications necessary to apply binding in Swing:

class BindableLabel extends JLabel {
    private Note bindableValue = new Note().value("").afterChange(new Task() {
        @Override public void job() {
            if (bindableValue != null) {
            setText(bindableValue.value());
            }
        }
    });
    public Note bindableValue() {
        return bindableValue;
    }
    public BindableLabel() {
        super();
    }
}


This is a class extending standard JLabel. It allows you to update associate label text with a variable of type Note.
For editable Swing components, you'll also need to add a ChangeListener. An example of determining the behavior of components from a form in the screenshot:

    void bindComponents() {
        Numeric celsius = new Numeric().value(0);
        Numeric fahrenheit = celsius.multiply(9.0).divide(5.0).plus(32.0);
        fahrenheitSlider.bindableValue().bind(fahrenheit);
        fahrenheitSpinner.bindableValue().bind(fahrenheit);
        celsiusSlider.bindableValue().bind(celsius);
        celsiusSpinner.bindableValue().bind(celsius);


- as you can see, this takes only a few lines and when editing any value in the form (or moving the slider slider), the remaining components instantly update their state.

Also popular now: