What is a first class citizen function?
Does Java supports first class citizen function?
Edit:
As mention on Wikepedia
First class functions are a necessity
for the functional programming style.
Is there any other use of first class functions?
A language that considers procedures to be "first-class" allows functions to be passed around just like any other value.
Languages like Java 7 (and earlier) and C "kind of" have this capability: C allows function pointers to be passed around, but you can't dynamically define a function in those languages and suddenly pass that somewhere else. Java before version 8 can simulate this to a certain extent with anonymous classes, but it doesn't technically have first-class functions.
On the other hand, C++, D, C#, Visual Basic .NET, Java 8+, and functional languages (like Scheme and Haskell) do allow you to pass around functions like variables. For example, the code below returns a function that adds addend to its input:
Written in D:
int delegate(int) makeAdder(int addend) //Returns a function
{
return delegate int(int x) //Long way
{
return x + addend; //Notice that addend came from _outside_ the function
};
return (int x) { return x + addend; }; //Short way
return x => addend + x; //Super-short way, introduced in D 2.058
}
Written in C#:
Func<int, int> MakeAdder(int addend) //Returns a function
{
return delegate(int x) //The long way. Note: Return type is implicitly 'int'
{
return x + addend;
};
return x => x + addend; //Short way: x "goes to" (x + addend); inferred types
}
Written in C++:
#include <functional>
std::function<int(int)> make_adder(int addend)
{
return [=](int x)
{
return addend + x;
};
}
Written in Scala:
def makeAdder(addend: Int) = (x: Int) => addend + x
Written in Python:
def make_adder(addend):
def f(x):
return addend + x
return f
# or...
return lambda x: addend + x
Written in Erlang:
make_adder(Addend) ->
fun(X) -> Addend + X end.
Written in JavaScript:
function makeAdder(addend) {
return function(x) {
return addend + x;
};
}
Written in JavaScript (ES2015 arrow function syntax):
const makeAdder = addend => x => addend + x;
Written in Scheme:
(define (makeAdder addend)
(lambda (x)
(+ x addend)))
Written in Haskell:
makeAdder :: Int -> (Int -> Int)
makeAdder addend = \x -> addend + x
Written in Visual Basic 2008:
Function MakeAdder(addend As Integer) As Func(Of Integer, Integer)
Return Function(x) (x + addend)
End Function
Written in Swift (both verbose and short-hand implementations):
func makeAdder(append: Int) -> (x: Int) -> Int {
return { (x: Int) -> Int in
return x + append
};
}
func makeAdder(append: Int) -> (Int) -> Int {
return {$0 + append};
}
(By the way, a "lambda" is just a function without a name. Lambdas are only supported in languages that support first-class functions.)
Let us consider the example of functional programming paradigm in which functions are the first class citizens. When we say functions are the first class citizens, we can do the following things with the function...
Function can be assigned to a variable
Function can be stored in a data structure
Function can be passed around as an argument to other functions
Function can be returned from the functions
In functional programming languages, it is possible to do the above mentioned things.
Now, let us try to answer the question, whether java supports first class citizen functions (or) not.
In java, methods are equivalent of functions. It is not possible to do any of the above with methods. But all of the above are possible with java objects. So, objects are the first class citizens in java. Admittedly, java8 supports passing of methods (method behavior, to be precise) to other methods using functional interfaces and lambda expressions. But that does not mean that java has functions as first class citizens.
The ability to do above things such as passing around functions, returning functions from functions is very powerful and useful. This is because, it allows us to pass around the behavior not just the data.
A first class function can be passed around. A typical example is the map function. Here is an example in Scala that squares the elements of a list:
val square = (x:Int) => x*x
val squaredList = List(1,2,3,4).map(square _)
//--> List(1,4,9,16)
The square function is here an argument to the map method, which applies it to every element. If you want to do something like this in Java, you have to use a method wrapped in a class, something like this:
interface F<A,B>{ B apply(A a); }
static <A,B> List<B> map(List<A> list, F<A,B> f) {
List<B> result = new ArrayList<B>();
for(A a:list) result.add(f.apply(a));
return result;
}
//we have to "wrap" the squaring operation in a class in order to make it a function
F<Integer,Integer> square = new F<Integer,Integer>(){
Integer apply(Integer a) { return a*a; }
}
List<Integer> ints = Arrays.<Integer>asList(1,2,3,4);
List<Integer> squares = map(ints, square);
Looking at this you can see that you can get the same task somehow done in Java, but with more overhead, and without "native" support by the language, but by using a workaround (wrapper classes). So Java doesn't support first class functions, but can "simulate" them.
Hopefully Java 8 will support first class functions. If you want to have some support for this now, look at http://functionaljava.org/ or http://functionalj.sourceforge.net/ , or have a look at the Scala language.
The Wikipedia definition is pretty good—it's a function that can be passed around like any other piece of data. Java does not support them. The closest it has is Runnable and Callable objects.
The above answers for #Alpine questions are mostly defining what is First Class Functions along with examples. But still, one question remains why to use?
I'll try to answer the benefits a little differently in Scala where first-class functions are used further as higher-order functions(map, flatMap), Partially Applied Functions and Currying:
As we focus on declarative programming, the how part of processing the data is left as an implementation detail to map, flatMap, and focused more on handling the what actual logic flow.
A caller can specify what should be done and leave the higher-order functions to handle the actual logic flow.
Partially Applied Functions and Currying: What if you wanted to reuse a function invocation and retain some of the parameters to avoid typing them in again?
Partially Applied Function Example:
def factorOf(x: Int, y: Int) = y % x == 0
val multipleOf3 = factorOf(3, _: Int)
val y = multipleOf3(78)
Currying Example:
def factorOf(x: Int)(y: Int) = y % x == 0
val isEven = factorOf(2) _
val z = isEven(32)
The above examples show you how you can reuse the part of first-class functions by not passing all parameters and keep your code DRY principle.
These are few benefits for using first-class functions
Reference for more details: https://www.oreilly.com/library/view/learning-scala
No, you cannot assign a method to a variable or pass it as an argument to another method for example.
Instead you can use interfaces to wrap the intended behaviour, or reflection to reify methods.
Functions are first class citizen means you can pass function anywhere as if it's a variable.
From Scala
def isOdd(in: Int) = in % 2 == 1
val n = (1 to 10).toList
n.filter(isOdd)
see here: isOdd is a function. passed as if it's a variale.
Objects are first class citizen in Java. A first class citizen is the one that can be passed anywhere. The parallel is from a first class citizen of country are allowed almost everywhere.
Read:
When is a feature considered a “First class citizen” in a programming language/platform?
First-class object
First-class function
Related
I'm primarily a JavaScript developer, but am currently working on some Groovy code and haven't been able to figure out how to do something that's super-simple in JavaScript.
The JavaScript equivalent of what I'm trying to do follows.
I'm specifically trying to figure out the Java (or Groovy) equivalent of creating an object in JS (map in Java) out of just the existing variable names, e.g. {a, b, c} shorthand in the code snippet below. Any guidance will be much appreciated!
javaScriptExample()
function javaScriptExample () {
// the variables already exist in the program that I'm working in
const a = 'a'
const b = 'bee'
const c = 'see'
// ➡️ Here's where I'm stuck. ⬅️
// I simply want to be able to arbitrarily pass variable keys and values
// as a map to another function, _using just the variable keys_,
// e.g. the equivalent of JavaScript's `{a, b, c}` in the next call
doOtherStuffWithVariables({a, b, c})
}
function doOtherStuffWithVariables (obj) {
for (const key in obj) {
console.log(`variable ${key} has a value of "${obj[key]}" and string length of ${obj[key].length}`)
}
}
As stated, there is no shortcut in Groovy. But if you want/need this
syntax, you can achieve this with Groovy
Macros.
E.g. a very straight forward attempt:
#Macro
static Expression map(MacroContext ctx, final Expression... exps) {
return new MapExpression(
exps.collect{
new MapEntryExpression(GeneralUtils.constX(it.getText()), it)
}
)
}
Usage:
def a = 42
def b = 666
println(map(a,b))
// → [a:42, b:666]
Unfortunately there's no direct counterpart in Groovy or Java for object deconstruction in JS. Although you can use map literals to write a similar code:
def doStuff( Map obj ) {
obj.each{ key, val ->
println "variable $key has a value of '${val}' and string length of ${obj[key].size()}"
}
}
def example(){
def a = 'a'
def b = 'bee'
def c = 'see'
doStuff( a:a, b:b, c:c )
}
I am not sure what you exactly want to do, but afaik, there is nothing similiar in java.
You could use tho the "new" methods in the java collections library:
String a = "a";
String b = "b";
String c = "c";
Map.of("a", a, "b", b, "c", c);
List.of(a,b,c)
But you should keep in mind, those methods are returning unmodifiable objects.
JavaDoc: Returns an unmodifiable list containing three elements. See Unmodifiable Lists for details.
As already said, this is not possible in Groovy, because as soon as you use a variable a in your code, then the value of that variable is passed and the name is forgotten.
However, I have also a solution which involves an intermediate object holding the properties to be interrogated:
def toMap(obj) {
obj.properties.collectEntries {
[(it.key):it.value]
}
}
def ex =
new Expando().tap {
a = 'A'
b = 'B'
}
assert toMap(ex) == [a:'A', b:'B']
The involves the dynamically expandable object feature.
Let's say that I have function Object f(String a, String b) and I want to call two different functions that return Optional Strings to get the parameters for f Optional<String> getA() and Optional<String> getB(). I can think of two solutions but neither look all that clean, especially when you have even more parameters:
1:
return getA().flatMap(
a -> getB().map(
b -> f(a,b)).get()
2:
Optional<String> a = getA();
Optional<String> b = getB();
if(a.isPresent() && b.isPresent()) {
return f(a.get(), b.get());
}
Is there a cleaner way to do this?
You've just stumbled upon a concept called lifting in functional programming, that enables you to lift regular functions (e.g. A -> B) into new domains (e.g. Optional<A> -> Optional<B>).
There's also a syntactic sugar for flatMapping and mapping more comfortably called the do notation in Haskell and similar languages, and for comprehension in Scala. It gives you a way to keep the flow linear and avoid nesting (that you were forced to go through in your example 1).
Java, unfortunately has nothing of the sort, as its functional programming capabilities are meager, and even Optional isn't really a first-class citizen (no standard API actually uses it).
So you're stuck with the approaches you've already discovered.
In case you're curious about the concepts mentioned above, read on.
Lifting
Assuming you have:
public String f(A a, B b) {
return b + "-" + a;
}
With its Scala equivalent:
def f(a: A, b: B) = b + "-" + a
Lifting f into Option (same as Optional in Java) would look like this (using Scalaz library, see here for Cats)
val lifted = Monad[Option].lift2(f)
lifted is now a function equivalent to:
public Optional<String> f(Optional<A> a, Optional<B> b) {
if(a.isPresent() && b.isPresent()) {
return Optional.of(b + "-" + a);
}
return Optional.empty;
}
Exactly what you're looking for, in 1 line, and works for any context (e.g. List, not just Option) and any function.
For comprehension / Do notation
Using for comprehension, your example would look like this (I think, my Scala is weak):
for {
a <- getA();
b <- getB();
} yield f(a, b)
And again, this is applicable to anything that can be flatMapped over, like List, Future etc.
You could stream the arguments and apply the condition only once, but whether or not this is more elegant than your solutions is in the eye of the beholder:
if (Stream.of(a, b).allMatch(Optional::isPresent)) {
return f(a.get(), b.get());
}
I'm of the opinion that if there is no good way to use Optional, then there is no reason to try to use it anyway.
I find this to be cleaner and simpler than your option 2:
String a = getA().orElse(null);
String b = getB().orElse(null);
if(a != null && b != null) {
return f(a, b);
}
If you are sure that a and b are both present (as your final call to get in solution 1 seems to suggest), I think it is pretty straightforward:
return f(getA().orElseThrow(() -> new NoSuchElementException("a not present")),
getB().orElseThrow(() -> new NoSuchElementException("b not present")));
If you aren’t sure that both are present, I would prefer your solution 1. It exploits Optional the best. Only I would not call get at the end, but rather orElse or what makes sense in your situation, for example:
return getA()
.flatMap(a -> getB().map(b -> f(a,b)))
.orElse("Not both present");
There's a default method andThen() in the BiFunction interface (java.util.function package).
default <V> BiFunction<T,U,V> andThen(Function<? super R,? extends V> after)
The documentation says:
Returns a composed function that first applies this function to its input, and then applies the after function to the result. If evaluation of either function throws an exception, it is relayed to the caller of the composed function.
It's little confusing to understand what the explanation means. As per my understanding, a composed function is returned when the default andThen() method is invoked. This composed function is invoked on the types T and U that returns the type V. Finally, there's and after function that is invoked on the types R and V.
What's the need of this method? How does it actually fit in the picture?
It's little confusing to understand what the explanation means.
To explain it as simple as I can, the method andThen returns a function that first applies a given function to an input and then applies another function to the result of that application.
Assume we had two functions f and g , function f doing some logic and function g doing some other type of logic so when you compose f.andThen(g) that essentially means g(f(x)) i.e. we first apply the function given as argument f(x) and then apply the function g to the result.
Example:
BiFunction<Integer, Integer, Integer> f = Math::addExact;
Function<Integer, Integer> g = e -> e * 2;
System.out.println(f.andThen(g).apply(10,10)); // 40
We first call function f(10, 10) and then take the result of that which is 20, pass it to the function g(20) and that is executed multiplying 20 by 2 hence yielding 40.
To be honest the syntax to call a function in Java is not the best it can be so I can understand when someone looks at this the first time it might be difficult to grasp and gets harder to follow the more you compose functions, for example in C# one could simply do g(f(10, 10)) which visibly to the eye is easier to follow, read and understand.
What's the need of this method? How does it actually fit in the
picture?
In my experience, it's not common that I've composed functions as shown above but a typical scenario I could imagine is if you have various utility methods that do some logic where the result of one function is further passed to other functions for processing in which case you can then use function composition to create various transformation pipelines by composing the utility methods.
I think the main purpose of the andThen function is to make your code more readable and more functional.
Let's look at and example:
BiFunction<Integer, Integer, Integer> add = (x, y) -> x + y;
Function<Integer, Integer> negate = x -> -x;
BiFunction<Integer, Integer, Integer> newFunction = add.andThen(negate);
Guess what newFunction does? It adds andThen negates two numbers! See how similar to English this line is:
BiFunction<Integer, Integer, Integer> newFunction = add.andThen(negate);
If you call .apply(1, 2), you know you'd get -3.
Sure, you could do this without using andThen:
BiFunction<Integer, Integer, Integer> newFunction = (x, y) -> negate.apply(add.apply(x, y))
But look how unreadable that is!
Coding functionally can sometimes make things much easier to read and understand.
Consider f1.andThen(f2) :
First, f1 will take 2 elements and result in only 1
after that, f2 will take the result of f1 and tranform it to another result
BiFunction<Integer, Integer, Integer> plus10 = (i1, i2) -> i1 + i2 + 10;
Function<Integer, Integer> mult = i -> i * 5;
System.out.println(plus10.andThen(mult).apply(5, 6)); // (5+6+10) *5 = 105
It's a way to reduce computation
int val1 = plus10.apply(5, 6);
int res1 = mult.apply(val1);
int res2 = plus10.andThen(mult).apply(5, 6);
System.out.println(res1 == res2); //true
It's more and more usefull when you have several function to use, because there is the same method for Function, so you can chain them :
System.out.println(plus10.andThen(mult).andThen(mult).andThen(mult).apply(5, 6));
// (5+6+10)*5*5*5 = 2625
It's easier understood with an example:
BiFunction<Integer, Integer, String> f =
(n1, n2) -> String.format("result is %s", n1+n2);
And the "composed function" is:
BiFunction<Integer, Integer, String> f1 =
f.andThen(string -> string.toUpperCase());
Note that the second function still takes the same argument types as the first one, although it internally only needs a String to execute its logic.
Consider the invocation:
System.out.println(f1.apply(2, 3));
Which outputs RESULT IS 5, that is: it calls first function and then calls the second function with the result of the first. So it's simply understood as f1(f(x, y)) with the ultimate input being the input required by f, and the ultimate result being the result yielded by f1.
In this question the author uses the following example:
#Override
public final OptionalInt max() {
return reduce(Math::max); //this is the gotcha line
}
So in this case it looks as if max() is a proxy for Math.max on the instance of this class. However there are no arguments passed to max, so does java 8 compile this to something like (Pseudo code):
#Override
public final OptionalInt max(Integer a, Integer b) {
//If neither a or b are null
return new OptionalInt.of(Math.max(a,b));
//Otherwise return empty because we can't compare the numbers
return OptionalInt.empty()
}
Also how would one write the javadoc for something like this?
So in this case it looks as if max() is a proxy for Math.max on the instance of this class. However there are no arguments passed to max, so does java 8 compile this to something like (Pseudo code):
#Override
public final OptionalInt max(Integer a, Integer b) {
//If neither a or b are null
return new OptionalInt.of(Math.max(a,b));
//Otherwise return empty because we can't compare the numbers
return OptionalInt.empty()
}
Not quite :). Let's start by figuring out what the reduce operator actually does. The documentation explains that it performs a reduction on a sequence of numbers by applying an algorithm that is logically equivalent to the following:
public OptionalInt reduce(IntBinaryOperator op) {
boolean foundAny = false;
int result = 0;
for (int element : [this stream]) {
if (!foundAny) {
foundAny = true;
result = element;
}
else {
result = op.applyAsInt(result, element);
}
}
return foundAny ? OptionalInt.of(result)
: OptionalInt.empty();
}
Seems simple enough. If you can tell it how to take two numbers and 'reduce' or 'combine' them into one, then reduce knows how to extend that logic to reduce an entire sequence into a single number. It handles the edge cases and the aggregation for you. All it needs from you is a function that takes in two numbers and gives it one back. That function should conform to the functional interface IntBinaryOperator.
A functional interface is an interface that is meant to describe a single function. Specifically, it describes the argument types and the return type. The rest is largely superfluous. The signature for an IntBinaryOperator looks like this:
int applyAsInt(int left, int right);
You can provide a function that conforms to this specification in several ways. Prior to Java 8, you might have done something like this:
stream.reduce(
new IntBinaryOperator() {
public int applyAsInt(int a, int b) {
return b > a ? b : a;
}
}
);
Java 8 gives us a shorthand form for functional interfaces called lambda expressions. These are a bit more concise, and while they are conceptually similar to anonymous inner classes, they're not quite the same thing.
stream.reduce((a, b) -> b > a ? b : a);
Both functions above are equivalent: they take in two numbers and return the larger of the two. As it turns out, every standard programming library has a function that does exactly the same thing. In Java, that function is Math.max. So rather than writing this logic myself, I can delegate to Math.max:
stream.reduce((a, b) -> Math.max(a, b));
But wait! All reduce wants is a function that takes two numbers and returns one. Math.max does that, so do I even need to wrap it in a lambda? It turns out I don't; I can tell reduce to just call Math.max directly:
stream.reduce(Math::max);
This says "I know you want a function, so I'm show you by name where to find one that's already been written". The compiler knows that Math.max conforms to the (int, int) -> int specification we need, so it emits some bytecode telling the VM how to 'bootstrap' it once it's needed. When the JVM hits your call to reduce, it calls a special method that generates a wrapper class implementing IntBinaryOperator that delegates to Math.max in its implementation of applyAsInt. It only performs this 'bootstrapping' step once. Since calling Math.max doesn't rely on anything other than the two numbers that get passed in, it can cache that implementation and use it the next time you wind up on this code path.
Pre Java 8, this would have been written as:
public MyMathInteface {
OptionalInt max(Integer a, Integer b);
}
public static final MyMathInterface reducing = new MyMathInterface() {
#Override
public OptionalInt max(Integer a, Integer b) {
return OptionalInt.of(Math.max(a, b));
}
};
#Override
public final OptionalInt max() {
return reduce(reducing);
}
Then reduce would be defined as:
public static OptionalInt reduce(MyMathInteface toReduce) {
return toReduce.max(someValueA, someValueB);
}
So to answer your question, no arguments are passed to Math::max, because those values are retrieved by the reduce function. They could be constants or they could be retrieved from some other place.
In any case, the use of the max method in this way is called a method reference, that is where you do SomeObject::method. That :: operator creates a method reference. It returns a function, but does not call the function. The user (reduce) is responsible for calling the function.
Could someone explain my the differences between methods using lambda expressions and without using it?
On the example:
Function<Double, Double> function;
public void methodCounting() {
this.function = x -> x = x + 2;
}
public double methodCounting(double x) {
x = x + 2;
return x;
}
What do we gain?
Your second method accepts a double number and returns that number + 2.
Your first method defines a Function that accepts a Double number and returns a Double whose value is the original + 2. It doesn't, however, evaluate that Function.
In order to produce the output of the second method, you could later pass a value to that Function and evaluate it :
Double d = function.apply(x); // will assign x+2 to d
would behave similarly to
double d = methodCounting(x);
Lambda is new feature added in java 8 only for optimum performance and shorter code.
Java 8 provide support for lambda expressions only with functional interfaces.
Any Interface with single abstract method is called Functional Interface.
Functional Interface is also a new feature introduced in Java 8.
lambda expressions is implicitly generate function objects in a "more convenient way" please ref. above code.