Skip to content

Modelling Expressions using a single Functional Interface with default methods returning lambda expressions

Notifications You must be signed in to change notification settings

FreeFries/Interpreter

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 

Repository files navigation

How do you model an expression ?

Just recently I was posed with the following question above for a challenging and exciting role

     +
    / \
   *  1
 / \
6  3

(6 * 3) + 1 = 19 

At the end of this exercise the solution proposed to me was to use an interface with a common eval() method where

  • NodeValue(s) are 6, 3, & 1
  • Op Nodes were * (multiply) & + (Addition) thus we modelled NodeMulti & NodeAdd and this gave us the traditional DSL expression below as

Approach I

int answer = new NodeAdd(
                             new NodeMulti( new NodeValue(6),new NodeValue(3)),
                             new NodeValue(1)
                             ).eval();

Approach II using a SAM Functional Interface with default methods only

This other alternative by just using a Functional Interface (which Node.java is), default methods and Java 8's Lambdas to make your code more concise, with much fewer lines (less to test) and closer to the expression you are trying to model which is what I have tried to do, hopefully. It is still and extension of Approach I

So if you look at Node.java you will see the default methods multi(),add() returning lambda expression(s)

Snippet below is from NodeDriver.java which shows how simple lambdas expression writing for developers.

        Node v6 = () -> 6;
        Node v3 = () -> 3;
        Node v1 = () -> 1;

        Node d = () -> 0 ;  // dummy node to evaluate your final answer 
                            // also acts like store for the final Node expression to be evaluate.

        Node exprsn = d.add( d.multi(v6,v3), v1) ;

        int answer2 = exprsn.eval();  

The default methods of multi() & add() actually return lambda expressions - thus the beauty of this is you are actually dealing with little code blocks that you can effectively "transport" to your final calling method eval() !

See Node.java which is all you need!

() -> (n.eval() * o.eval()) // for multiplication where n & o are the nodes passed in 

() -> (a.eval() + b.eval()) // for addition where a & b are the nodes passed in

Both solutions are formed on the basis of the following pattern(s) ....

Wikipedia - Interpreter Pattern

And, it also has elements of the Composable Decorator Pattern in this post ....

Yegor Bugayenko post on Composite Pattern

About

Modelling Expressions using a single Functional Interface with default methods returning lambda expressions

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages