Подтвердить что ты не робот

Что такое гражданская функция первого класса?

Что такое гражданская функция первого класса?

Поддерживает ли Java первую гражданскую функцию класса?

Edit:
Как упоминание о Wikepedia

Функции первого класса являются необходимостью для стиля функционального программирования.

Есть ли другое использование функций первого класса?

4b9b3361

Ответ 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 функционирует как граждане первого класса.

Возможность делать вещи выше, например, передавать функции, возвращать функции из функций очень эффективна и полезна. Это потому, что это позволяет нам обойти поведение не только данных.