I am trying to understand Interpreter Design Pattern in Java. I am getting the following code from Wikipedia. There is written
interface Expression {
public int interpret(Map<String,Expression> variables);
}
Could you explain me what is going on here with respect to Expression being the value of Map, which is inside in an Interface of Type Expression. Is it something like recursive calling ? Kindly explain.
To answer your question, Yes same function interpret() is called again and again but they are not of the same class. Hence it is not actually recursive function.
Used wiki code to explain the Interpreter pattern, but you need to go to and fro to wiki page to understand the whole picture,
http://en.wikipedia.org/wiki/Interpreter_pattern
Interpreter pattern is the one in which each and every variable and the operator in the given expression is represented as a separate class, and then the evaluation happens on the objects of these classes.
Expression - class, expression - ((y+z)-x)
In the case of the wiki example which you pointed out, when you call the constructor of Evaluator in the main(), only expression will be constructed (again its another Expression object) and saved in the syntaxTree reference variable of Evaluator.
To give a gist of whats happening there with expression: x y z + -
First variables x,y,z will be stored as such in the expressionStack variable
When you encounter +, (y+z) will be pushed into the expressionStack
After - token, ((y+z)-x) Expression object will be in the expressionStack (check the push and pop which is happening for the operator in Evaluator)
so once the constructor of Evaluator is done, you will have Expression object whose implementation is again an Expression denoted as ((y+z)-x).
Now comes the interesting part in main(), you are substituting values for the variable (x,y,z) using Number class and it happens in this order,
main () sentence.interpret(variables);
Evaluator.syntaxTree.interpret(variables);
Variable.interpret(variables) // Here the actual values(5,10,42) gets substituted for x, y, z.
and then the Expression is evaluated.
If you see interpret() of Variables class, it is slightly different where it gets the corresponding Number object of the variable, using the context passed. This is the actual substitution of variables to numbers using the context object passed in main(). This in turn calls the interpret() of Number which just returns the number and the operation happens as ((10+5)-42) = -27.
Advantage:
By using this technique you can keep on adding operations (plus, minus) without affecting the existing operations and one operation is independent of other. It is used in SQL queries and other interpreters.
Thanks,
Prasanna V.
An interface defines methods that a class has to implement if it has the interface.
class MathExpression implements Expression {
public int interpret(Map<String,Expression> variables) {
//insert code here
}
}
I wouldn't describe it as a recursive call. An accurate description is the interface is self-referencing itself in a method call.
Expression expression = new MathExpression();
expression.interpret(stringToExpressionMap);
The advantage of this is you can define a behavior in that class without having to know the specific implementation of that class.
Related
I have been learning java for past few months and just started to get into lambda functions. I recently switched my IDE and noticed a warning saying "Can be replaced with method reference" on codes like this.
List<Integer> intList = new ArrayList<>();
intList.add(1);
intList.add(2);
intList.add(3);
intList.forEach(num -> doSomething(num));
voiddoSomething(int num) {
System.out.println("Number is: " + num);
}
After some digging, I realized that instead of the line
intList.forEach(num -> doSomething(num));
I can just use
intList.forEach(this::doSomething);
This is just amazing. A few days ago I did not even knew about lambdas and was using for loops to do operations like this. Now I replaced my for loops with lambdas and even better, I can replace my lambdas with method references. The problem is that I don't really understand how all this works internally. Can anyone please explain or provide a good resource explaining how the doSomething function is called and the argument is passed to it when we use method reference?
The double-colon operator is simply a convenience operator for doing the same thing that your lambda is doing. Check out this page for more details: https://javapapers.com/core-java/java-method-reference/
The double colon is simply syntactic sugar for defining a lambda expression whose parameters and return type are the same as an existing function. It was created to to allow lambdas to more easily be added with existing codebases.
Calling the forEach method of a List<Integer> object takes as its parameter any object implementing the Consumer functional interface. Your lambda num -> doSomething(num) itself happens to fulfill the formal requirements of this interface.
Thus, you can use the double colon as syntactic sugar for that lambda expression.
In general, if you have an object obj with method func, which accepts parameters params... then writing obj::func is equivalent to the lambda (params...) -> obj.func(params...).
In your case, o is this (the current object), which has a method doSomething(), which takes an integer parameter, thus, this::doSomething is equivalent to num -> doSomething(num).
Given you've mentioned that it's only until recently you started getting into functional programming I'd like to keep things as simple and straightforward as possible, but note that with just the little code you've provided, we could derive a lot both from the high-level view of things as well the low-level view.
Can anyone please explain or provide a good resource explaining how
the doSomething function is called and the argument is passed to it
when we use method reference?
how the doSomething function is called is left to the library (internal iteration) regardless of whether we use a method reference or a lambda expression, so essentially we specify the what not the how meaning we provide to the forEach method a behaviour (a function) that we want to execute for each element of the source intList and not necessarily how it should go about its work.
This is then left to the library to apply (execute) the specified function of doSomething for each element of the source intList.
Method references can be seen as a shorthand for lambdas calling only a specific method. The benefit here is that by referring to a specific method name explicitly, your code gains better readability, therefore, making it easier to read and follow and in most cases reading code with method references reads as the problem statement which is a good thing.
It's also important to know that not any given function can be passed to the forEach terminal operation as every method that accepts a behaviour has a restriction on the type of function allowed. This is accomplished with the use of functional interfaces in the java.util.function package.
Lastly but not least, in terms of refactoring it's not always possible to use method references nor is it always better to use lambdas expressions over code that we used prior to Java-8. However, as you go on with your journey of learning the Java-8 features, a few tips to better your code are to try:
Refactoring anonymous classes to lambda expressions
Refactoring lambda expressions to method references
Refactoring imperative-style data processing to streams
I'm reading this fantastic article about Lambda Expressions and the following is uncleared to me:
Does Lambda Expression saves the value of the free-variables or refernse/pointer to each of them? (I guess the answer is the latter because if not, mutate free-variables would be valid).
Don't count on the compiler to catch all concurrent access errors. The
prohibition against mutation holds only for local variables.
I'm not sure that self experimenting would cover all the cases so I'm searching for a well defined rules about:
What free varibles can be mutated inside the Lambda Expression (static/properties/local variables/parameters) and which can be mutated out side while beeing used inside a Lambda Expression?
Can I mutate every free variable after the end of a block of a Lambda Expression after I used it (read or called one of his methods) inisde a Lambda Expression?
Don't count on the compiler to catch all concurrent access errors. The
prohibition against mutation holds only for local variables.
If
matchesis an instance or static variable of an enclosing class, then
no error is reported, even though the result is just as undefined.
Does the result of the mutation is undefined even when I use a synchroniziton algorithm?
Update 1:
free variables - that is, the variables that are not parameters and not defined inside the code.
In simple words I can conclude that Free variables are all the variables that are not parameters of the Lambda Expression and are not defined inside the same Lambda Expression ?
This looks like complicated "words" on a simpler topic. The rules are pretty much the same as for anonymous classes.
For example the compiler catches this:
int x = 3;
Runnable r = () -> {
x = 6; // Local variable x defined in an enclosing scope must be final or effectively final
};
But at the same time it is perfectly legal to do this(from a compiler point of view):
final int x[] = { 0 };
Runnable r = () -> {
x[0] = 6;
};
The example that you provided and uses matches:
List<Path> matches = new ArrayList<>();
List<Path> files = List.of();
for (Path p : files) {
new Thread(() -> {
if (1 == 1) {
matches.add(p);
}
}).start();
}
has the same problem. The compiler does not complain about you editing matches(because you are not changing the reference matches - so it is effectively final); but at the same time this can have undefined results. This operation has side-effects and is discouraged in general.
The undefined results would come from the fact that your matches is not a thread-safe collection obviously.
And your last point : Does the result of the mutation is undefined even when I use a synchroniziton algorithm?. Of course not. With proper synchronization updating a variable outside lambda(or a stream) will work - but are discouraged, mainly because there would be other ways to achieve that.
EDIT
OK, so free variables are those that are not defined within the lambda code itself or are not the parameters of the lambda itself.
In this case the answer to 1) would be: lambda expressions are de-sugared to methods and the rules for free-variables are the same as for anonymous classes. This has been discussed numerous times, like here. This actually answers the second question as well - since the rules are the same. Obviously anything that is final or effectively final can be mutated. For primitives - this means they can't be mutated; for objects you can't mutate the references (but can change the underlying data - as shown in my example). For the 3) - yes.
Your term “free variables” is misleading at best. If you’re not talking about local variables (which must be effectively final to be captured), you are talking about heap variables.
Heap variables might be instance fields, static fields or array elements. For unqualified access to instance variables from the surrounding context, the lambda expression may (and will) access them via the captured this reference. For other instance fields, as well as array elements, you need an explicit access via a variable anyway, so it’s clear, how the heap variable will be accessed. Only static fields are accessed directly.
The rules are simple, unless being declared final, you can modify all of them, inside or outside the lambda expression. Keep in mind that lambda expressions can call arbitrary methods, containing arbitrary code anyway. Whether this will cause problems, depends on how you use the lambda expressions. You can even create problems with functions not directly modifying a variable, without any concurrency, e.g.
ArrayList<String> list=new ArrayList<>(Arrays.asList("foo", "bar"));
list.removeIf(s -> list.remove("bar"));
may throw a java.util.ConcurrentModificationException due to the list modification in an ongoing iteration.
Likewise, modifying a variable or resource in a concurrent context might break it, even if you made sure that the modification of the variable itself has been done in a thread-safe manner. It’s all about the contracts of the API you are using.
Most notably, when using parallel Streams, you have to be aware that functions are not only evaluated by different threads, they are also evaluating arbitrary elements of the Stream, regardless of their encounter order. For the final result of the Stream processing, the implementation will assemble partial results in a way that reestablishes the encounter order, if necessary, but the intermediate operations evaluate the elements in an arbitrary order, hence your functions must not only be thread safe, but also not rely on a particular processing order. In some cases, they may even process elements not contributing to the final result.
Since your bullet 3 refers to “after the end of a block”, I want to emphasize that it is irrelevant at which place inside your lambda expression the modification (or perceivable side effect) happens.
Generally, you are better off with functions not having such side effects. But this doesn’t imply that they are forbidden in general.
Suppose I have a dumb Frege function that constructs a pair of Nums.
newPair :: (Num α, Num β) => α -> β -> (α, β)
newPair = (,)
-- alternatively -- newPair x y = (x, y)
Attempting to call this function from Java, however, a PreludeBase.CNum<α> and a PreludeBase.CNum<β> are demanded in addition to the expected Lazy<α> and Lazy<β>. Likewise with Show types, where
showSomething :: (Show α) => α -> String
showSomething = show
-- alternatively -- showSomething x = show x
would require a PreludeBase.CShow<α> in addition to the expected parameter.
What is the proper way to pass constrained Frege objects to and from Java?
Good question, since this is not explained in the wiki yet.
As in all cases like this, I recommend to use the
:java
command in the REPL. For example:
frege> newPair 1 2.3
frege> :java
You will then get a window that contains among all active definitions one that corresponds to this call. A simple text search can help find the place where newPair is called. This should help to resolve such issues most of the time.
In your case, the relevant part would look like:
Console.<Integer, Double>numPair(
PreludeBase.INum_Int.it,
PreludeBase.IReal_Double.it,
Thunk.<Integer>lazy(1),
Thunk.<Double>lazy(2.3))
Here is a short overwiew about how type classes and instances are named and how you can get at them.
module x.y.Z where
class Xable where ...
This results in a Java-interface with the fully qualified name
x.y.Z.CXable
And this:
module a.b.C where
import x.y.Z
data MyType ... = ....
instance Xable MyType where ...
results in some class
a.b.C.IXable_MyType /* implements CXable<TMyType> */
If your instance definition does not have constraints themselves, there will be a singleton instance that you can use.
a.b.C.IXable_MyType.it
Otherwise, you need to construct a new instance by passing all constraints as argument to the constructor. For example, the Show instance for
Maybe Int
would look something like this:
new IShow_Maybe(IShow_Int.it)
since the instance head lists a constraint for the Maybe element type:
instance Show a => Show (Maybe a)
Note that you need to know the actual type fully, you can't make a generic type class instance. This is never a problem in Frege itself, as all needed instances are passed to a polymorphic function from the caller. However, as it stands, we don't have constraints in native functions.
Should you need something like this, you can achieve the functionality in most cases by just passing the function you wanted to call as argument.
For example, this doesn't work:
pure native myMethod :: Show a => a -> ...
but this should:
pure native myMethod :: (a -> String) -> a -> ....
myMethod show (Just 47)
The example java code above also reveals that it is not always as easy as described. For example, it so happens that the Double type doesn't have a separate Num instance, but just one for Real which is a subclass of Num. Unfortunately, only the compiler has the knowledge of what instances are actually present for some type, and which ones are implicit, that is, provided by an instance for a sub-class. Again, the REPL is the best way to find this out.
I'll call a method with two arguments, but i'll use k++ like this:
polygon.addPoint((int)rs.getDouble( k++),(int)rs.getDouble( k++ ));
Actually i want to be sure that jvm executes first argument first, then the second one. If somehow the order will change, arguments would be passed wrong order.
Thanks a lot!
Yes, the arguments are guaranteed to be evaluated left-to-right. Any compiler complying to JLS rules should follow that. This is mentioned in JLS §15.7.4:
In a method or constructor invocation or class instance creation
expression, argument expressions may appear within the parentheses,
separated by commas. Each argument expression appears to be fully
evaluated before any part of any argument expression to its right.
Yes, Java guarantees that. However, this does not mean that using the code like that is a good idea: readers of your code may get thoroughly confused.
It is much cleaner to show the order explicitly:
int a = (int)rs.getDouble(k++);
int b = (int)rs.getDouble(k++);
polygon.addPoint(a, b);
Java does not support named parameters, so you are correct in understanding that parameters are read in position.
For example, a method with the signature (int, String) and a method with the signature (String, int) will never be confused with each other, Java takes the type and sequence of parameters into consideration when figuring out what method to call.
Likewise, in your method, you will always have parameters coming in in a predictable and uniform fashion.
For that reason, the first k++ will always execute first, and the second k++ always after that, and that is guaranteed behaviour.
One of my most common bugs is that I can never remember whether something is a method or a property, so I'm constantly adding or removing parentheses.
So I was wondering if there was good logic behind making the difference between calling on an object's properties and methods explicit.
Obviously, it allows you to have properties and methods that share the same name, but I don't think that comes up much.
The only big benefit I can come up with is readability. Sometimes you might want to know whether something is a method or a property while you're looking at code, but I'm having trouble coming up with specific examples when that would be really helpful. But I am a n00b, so I probably just haven't encountered such a situation yet. I'd appreciate examples of such a situation.
Also, are there other languages where the difference isn't explicit?
Anyways, if you could answer, it will help me be less annoyed every time I make this mistake ^-^.
UPDATE:
Thanks everyone for the awesome answers so far! I only have about a week's worth of js, and 1 day of python, so I had no idea you could reference functions without calling them. That's awesome. I have a little more experience with java, so that's where I was mostly coming from... can anyone come up with an equally compelling argument for that to be the case in java, where you can't reference functions? Aside from it being a very explicit language, with all the benefits that entails :).
All modern languages require this because referencing a function and calling a function are separate actions.
For example,
def func():
print "hello"
return 10
a = func
a()
Clearly, a = func and a = func() have very different meanings.
Ruby--the most likely language you're thinking of in contrast--doesn't require the parentheses; it can do this because it doesn't support taking references to functions.
In languages like Python and JavaScript, functions are first–class objects. This means that you can pass functions around, just like you can pass around any other value. The parentheses after the function name (the () in myfunc()) actually constitute an operator, just like + or *. Instead of meaning "add this number to another number" (in the case of +), () means "execute the preceding function". This is necessary because it is possible to use a function without executing it. For example, you may wish to compare it to another function using ==, or you may wish to pass it into another function, such as in this JavaScript example:
function alertSomething(message) {
alert(message);
}
function myOtherFunction(someFunction, someArg) {
someFunction(someArg);
}
// here we are using the alertSomething function without calling it directly
myOtherFunction(alertSomething, "Hello, araneae!");
In short: it is important to be able to refer to a function without calling it — this is why the distinction is necessary.
At least in JS, its because you can pass functions around.
var func = new Function();
you can then so something like
var f = func
f()
so 'f' and 'func' are references to the function, and f() or func() is the invocation of the function.
which is not the same as
var val = f();
which assigns the result of the invocation to a var.
For Java, you cannot pass functions around, at least like you can in JS, so there is no reason the language needs to require a () to invoke a method. But it is what it is.
I can't speak at all for python.
But the main point is different languages might have reasons why syntax may be necessary, and sometimes syntax is just syntax.
I think you answered it yourself:
One of my most common bugs is that I can never remember whether something is a method or a property, so I'm constantly adding or removing parentheses.
Consider the following:
if (colorOfTheSky == 'blue')
vs:
if (colorOfTheSky() == 'blue')
We can tell just by looking that the first checks for a variable called colorOfTheSky, and we want to know if its value is blue. In the second, we know that colorOfTheSky() calls a function (method) and we want to know if its return value is blue.
If we didn't have this distinction it would be extremely ambiguous in situations like this.
To answer your last question, I don't know of any languages that don't have this distinction.
Also, you probably have a design problem if you can't tell the difference between your methods and your properties; as another answer points out, methods and properties have different roles to play. Furthermore it is good practice for your method names to be actions, e.g. getPageTitle, getUserId, etc., and for your properties to be nouns, e.g., pageTitle, userId. These should be easily decipherable in your code for both you and anyone who comes along later and reads your code.
If you're having troubles, distinguishing between your properties and methods, you're probably not naming them very well.
In general, your methods should have a verb in them: i.e. write, print, echo, open, close, get, set, and property names should be nouns or adjectives: name, color, filled, loaded.
It's very important to use meaningful method and property names, without it, you'll find that you'll have difficulty reading your own code.
In Java, I can think of two reasons why the () is required:
1) Java had a specific design goal to have a "C/C++ like" syntax, to make it easy for C and C++ programmers to learn the language. Both C and C++ require the parentheses.
2) The Java syntax specifically requires the parentheses to disambiguate a reference to an attribute or local from a call to a method. This is because method names and attribute / local names are declared in different namespaces. So the following is legal Java:
public class SomeClass {
private int name;
private int name() { ... }
...
int norm = name; // this one
}
If the () was not required for a method call, the compiler would not be able to tell if the labeled statement ("this one") was assigning the value of the name attribute or the result of calling the name() method.
The difference isn't always explicit in VBA. This is a call to a Sub (i.e. a method with no return value) which takes no parameters (all examples are from Excel):
Worksheets("Sheet1").UsedRange.Columns.AutoFit
whereas this is accessing an attribute then passing it as a parameter:
MsgBox Application.Creator
As in the previous example, parentheses are also optional around parameters if there is no need to deal with the return value:
Application.Goto Worksheets("Sheet2").Range("A1")
but are needed if the return value is used:
iRows = Len("hello world")
Because referencing and calling a method are two different things. Consider X.method being the method of class X and x being an instance of X, so x.method == 'blue' would'nt ever be able to be true because methods are not strings.
You can try this: print a method of an object:
>>> class X(object):
... def a(self):
... print 'a'
...
>>> x=X()
>>> print x.a
<bound method X.a of <__main__.X object at 0x0235A910>>
Typically properties are accessors, and methods perform some sort of action. Going on this assumption, it's cheap to use a property, expensive to use a method.
Foo.Bar, for example, would indicate to me that it would return a value, like a string, without lots of overhead.
Foo.Bar() (or more likely, Foo.GetBar()), on the other hand, implies needing to retrieve the value for "Bar", perhaps from a database.
Properties and methods have different purposes and different implications, so they should be differentiated in code as well.
By the way, in all languages I know of the difference in syntax is explicit, but behind the scenes properties are often treated as simply special method calls.