什么是头等舱公民功能?

发布于 2024-10-20 05:25:12 字数 224 浏览 3 评论 0原文

什么是头等舱公民功能?

Java支持一等公民功能吗?

正如维基百科中提到的:

一流的函数是函数式编程风格的必要条件。

一等函数还有其他用途吗?

What is a first-class-citizen function?

Does Java support first-class-citizen functions?

As mentioned on Wikipedia:

First-class functions are a necessity for the functional programming style.

Is there any other use of first-class functions?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

凌乱心跳 2024-10-27 05:25:12

将过程视为“一流”的语言允许函数像任何其他值一样传递

像 Java 7(及更早版本)和 C 这样的语言“有点”具有这种功能:C 允许传递函数指针,但您不能在这些语言中动态定义函数并突然将其传递到其他地方。 Java 8 之前的版本可以用匿名类在一定程度上模拟这一点,但从技术上讲它并不具有一流的功能。

另一方面,C++、D、C#、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
}

用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
}

用C++编写:

#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.

用 Ja​​vaScript 编写:

function makeAdder(addend) {
    return function(x) {
        return addend + x;
    };
}

用 Ja​​vaScript 编写(ES2015 箭头函数语法):

const makeAdder = addend => x => addend + x;

用 Scheme 编写:

(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};
}

顺便说一句, “lambda”只是一个没有名称的函数。只有支持一等函数的语言才支持 Lambda。)

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.)

鸩远一方 2024-10-27 05:25:12

让我们考虑一下函数式编程范式的例子,其中函数是一等公民。当我们说函数是一等公民时,我们可以用函数做以下事情...

  • 函数可以分配给变量
  • 函数可以存储在数据结构中
  • 函数可以作为参数传递给其他函数
  • 函数可以从函数返回

在函数式编程语言中,可以执行上述操作。

现在,让我们尝试回答这个问题:java 是否支持(或)不支持一等公民函数。

在java中,方法相当于函数。使用方法不可能完成上述任何操作。但以上所有的事情对于 java 对象来说都是可能的。所以,对象是java中的一等公民。诚然,java8 支持使用函数式接口和 lambda 表达式将方法(准确地说是方法行为)传递给其他方法。但这并不意味着java具有一等公民的功能。

执行上述操作(例如传递函数、从函数返回函数)的能力非常强大且有用。这是因为,它允许我们传递行为而不仅仅是数据。

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.

娇纵 2024-10-27 05:25:12

第一类函数可以被传递。一个典型的例子是map函数。下面是 Scala 中对列表元素求平方的示例:

val square = (x:Int) => x*x

val squaredList = List(1,2,3,4).map(square _)
//--> List(1,4,9,16)

square 函数在这里是 map 方法的参数,该方法将其应用于每个元素。如果你想在 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://functionjava.org/ 或 http://functionj.sourceforge.net/ ,或者查看 Scala 语言。

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.

っ左 2024-10-27 05:25:12

维基百科定义非常好 - 它是一个可以像任何其他部分一样传递的函数的数据。 Java支持它们。最接近的是 Runnable 和 Callable 对象。

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.

若水微香 2024-10-27 05:25:12

上述@Alpine 问题的答案主要是定义什么是一等函数以及示例。但仍然存在一个问题:为什么要使用?

我将尝试以稍微不同的方式回答 Scala 中的好处,其中一等函数进一步用作高阶函数(map、flatMap)、部分应用函数和柯里化:

  1. 当我们专注于声明式编程时,< em>如何处理数据的部分作为实现细节留给map、flatMap,并更多地关注处理什么实际逻辑流。
    调用者可以指定应该做什么,并让高阶函数来处理实际的逻辑流程。

  2. 部分应用函数和柯里化:如果您想重用函数调用并保留一些参数以避免再次输入它们,该怎么办?

部分应用函数示例:

def factorOf(x: Int, y: Int) = y % x == 0
val multipleOf3 = factorOf(3, _: Int)
val y = multipleOf3(78)

柯里化示例:

def factorOf(x: Int)(y: Int) = y % x == 0
val isEven = factorOf(2) _
val z = isEven(32)

上面的示例向您展示了如何通过不传递所有参数来重用部分一流函数,并保持代码DRY原则。
这些是使用一流函数的一些好处,

更多详细信息请参考:https://www.oreilly.com/library/view/learning-scala

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:

  1. 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.

  2. 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

不可一世的女人 2024-10-27 05:25:12

不可以,例如,您不能将方法分配给变量或将其作为参数传递给另一个方法。

相反,您可以使用接口来包装预期的行为,或使用反射来具体化方法。

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.

聚集的泪 2024-10-27 05:25:12

函数是一等公民,这意味着您可以将函数传递到任何地方,就好像它是变量一样。

从 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.

,对象是 Java 中的一等公民。 一等公民是可以通行到任何地方的人。类似的是,国家的一等公民几乎可以去任何地方。

阅读:

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:

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文