Что такое гражданская функция первого класса?
Что такое гражданская функция первого класса?
Поддерживает ли Java первую гражданскую функцию класса?
Edit:
Как упоминание о Wikepedia
Функции первого класса являются необходимостью для стиля функционального программирования.
Есть ли другое использование функций первого класса?
Ответы
Ответ 1
Язык, который считает процедуры "первоклассными" , позволяет передавать функции так же, как и любое другое значение.
Языки, такие как Java 7 (и более ранние) и C "вид", имеют такую возможность: C позволяет передавать указатели функций, но вы не можете динамически определять функцию на этих языках и внезапно передавать это где-то еще. Java до версии 8 может в определенной степени имитировать анонимные классы, но технически не обладает первоклассными функциями.
С другой стороны, С++, D, С#, Visual Basic.NET, Java 8+ и функциональные языки (например, Scheme и Haskell) позволяют вам передавать функции, подобные переменным. Например, приведенный ниже код возвращает функцию, которая добавляет addend
к ее вводу:
Написано в 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
}
Написан на С#:
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
}
Написан на С++:
#include <functional>
std::function<int(int)> make_adder(int addend)
{
return [=](int x)
{
return addend + x;
};
}
Написано в Scala:
def makeAdder(addend: Int) = (x: Int) => addend + x
Написано в Python:
def make_adder(addend):
def f(x):
return addend + x
return f
# or...
return lambda x: addend + x
Написано в Erlang:
make_adder(Addend) ->
fun(X) -> Addend + X end.
Написан на JavaScript:
function makeAdder(addend) {
return function(x) {
return addend + x;
};
}
Написано в JavaScript (синтаксис функции со стрелкой ES2015):
const makeAdder = addend => x => addend + x;
Написано на схеме:
(define (makeAdder addend)
(lambda (x)
(+ x addend)))
Написан в Haskell:
makeAdder :: Int -> (Int -> Int)
makeAdder addend = \x -> addend + x
Написано в Visual Basic 2008:
Function MakeAdder(addend As Integer) As Func(Of Integer, Integer)
Return Function(x) (x + addend)
End Function
Написано в Swift (как многословная, так и короткая реализация):
func makeAdder(append: Int) -> (x: Int) -> Int {
return { (x: Int) -> Int in
return x + append
};
}
func makeAdder(append: Int) -> (Int) -> Int {
return {$0 + append};
}
(Кстати, "лямбда" - это просто функция без имени. Lambdas поддерживается только на языках, поддерживающих первоклассные функции.)
Ответ 2
Функция первого класса может быть передана. Типичным примером является функция карты. Ниже приведен пример в Scala, который разбивает элементы списка:
val square = (x:Int) => x*x
val squaredList = List(1,2,3,4).map(square _)
//--> List(1,4,9,16)
Квадратная функция здесь является аргументом метода карты, который применяет его к каждому элементу. Если вы хотите сделать что-то подобное на Java, вы должны использовать метод, заключенный в класс, примерно так:
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);
Глядя на это, вы можете увидеть, что вы можете получить одну и ту же задачу, как это сделано на Java, но с большим объемом служебных данных и без "родной" поддержки по языку, но с помощью обходного пути (классы-оболочки). Поэтому Java не поддерживает функции первого класса, но может "имитировать" их.
Надеюсь, Java 8 будет поддерживать функции первого класса. Если вы хотите получить некоторую поддержку для этого сейчас, посмотрите http://functionaljava.org/ или http://functionalj.sourceforge.net/, или посмотрите на язык Scala.
Ответ 3
определение Википедии довольно хорошо - это функция, которая может передаваться как любая другая часть данных. Java не поддерживает их. Самое близкое к нему - объекты Runnable
и Callable
.
Ответ 4
Функции являются гражданами первого класса, поэтому вы можете передавать функцию в любом месте, как если бы она была переменной.
Из 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 a variale.
Objects
являются гражданами первого класса на Java. Гражданин первого класса - это тот, который может быть передан где угодно. Параллель от первого класса гражданина страны разрешена почти везде.
Чтение:
Ответ 5
Нет, вы не можете назначить метод переменной или передать его в качестве аргумента для другого метода, например.
Вместо этого вы можете использовать интерфейсы для обертывания предполагаемого поведения или отражения для методов подтверждения.
Ответ 6
Рассмотрим пример парадигмы функционального программирования, в которой функции являются гражданами первого класса. Когда мы говорим, что функции являются гражданами первого класса, мы можем выполнять следующие функции с помощью функции...
- Функция может быть назначена переменной
- Функция может храниться в структуре данных
- Функция может передаваться как аргумент для других функций
- Функция может быть возвращена из функций
В языках функционального программирования можно сделать вышеупомянутые вещи.
Теперь давайте попробуем ответить на вопрос, поддерживает ли java служебные функции первого класса (или).
В java методы эквивалентны функциям. Невозможно выполнить какие-либо из вышеперечисленных методов. Но все это возможно с помощью java-объектов. Таким образом, объекты являются гражданами первого класса в java. Разумеется, java8 поддерживает передачу методов (точнее, поведение метода) другим методам с использованием функциональных интерфейсов и лямбда-выражений. Но это не означает, что java функционирует как граждане первого класса.
Возможность делать вещи выше, например, передавать функции, возвращать функции из функций очень эффективна и полезна. Это потому, что это позволяет нам обойти поведение не только данных.