何时何地使用Lambda?

zen*_*ngr 28 ruby language-agnostic lambda

我试图理解为什么我们真的需要rubda(或任何其他语言)lambda或proc?

#method
def add a,b
  c = a+b
end

#using proc
def add_proc a,b
  f = Proc.new {|x,y| x + y }
  f.call a,b
end

#using lambda function
def add_lambda a,b
  f = lambda {|x,y| x + y}
  f.call a,b
end

puts add 1,1
puts add_proc 1,2
puts add_lambda 1,3
Run Code Online (Sandbox Code Playgroud)

我可以使用以下方法进行简单的添加:1.正常函数def,2.使用proc和3.使用lambda.

但是为什么以及在现实世界中使用lambda?任何无法使用函数和lambda应该使用的示例.

Ant*_*sky 20

确实,你不需要匿名函数(或lambdas,或任何你想称之为的东西).但也有很多东西你没有需要.您不需要类 - 只需将所有实例变量传递给普通函数.然后

class Foo
  attr_accessor :bar, :baz
  def frob(x)
    bar = baz*x
  end
end
Run Code Online (Sandbox Code Playgroud)

会成为

def new_Foo(bar,baz)
  [bar,baz]
end

def bar(foo)
  foo[0]
end
# Other attribute accessors stripped for brevity's sake

def frob(foo,x)
  foo[0] = foo[1]*x
end
Run Code Online (Sandbox Code Playgroud)

同样,除了with 和之外,你不需要任何循环.我可以继续下去.1 但是你用Ruby编写类.您希望能够使用循环,甚至可以使用循环,并且您希望能够使用循环而不是.loop...endifbreakwhilearray.each { |x| ... }unlessif not

就像这些功能一样,匿名功能可以帮助您优雅,简洁,明智地表达事物.能够写作some_function(lambda { |x,y| x + f(y) })比写作要好得多

def temp(x,y)
  x + f(y)
end
some_function temp
Run Code Online (Sandbox Code Playgroud)

必须中断代码流以写出一个deffed函数,然后必须给它一个无用的名称,当它在线编写操作时很明显.确实没有地方你必须使用lambda,但有很多地方我宁愿使用lambda.

红宝石解决了很多使用的λ-例块:所有的功能,如each,mapopen可以采取一个块作为参数基本上都采取了特例,匿名函数. array.map { |x| f(x) + g(x) }array.map(&lambda { |x| f(x) + g(x) })(&就像裸块一样)使lambda"特殊"成为一样.同样,你可以写出一个单独的def每一次,但为什么你会馈功能来?

支持这种编程风格的Ruby之外的语言没有块,但通常支持更轻量级的lambda语法,例如Haskell \x -> f x + g x或C#x => f(x) + g(x);2.每当我有一个需要采取一些抽象行为的函数时,比如map,或者each,或者on_clicked,我会感谢传递lambda而不是命名函数的能力,因为它更容易.最终,你不再认为它们有点特别 - 它们与数组的文字语法一样令人兴奋而不是empty().append(1).append(2).append(3).只是该语言的另一个有用的部分.


1:在简并的情况下,你真的只需要八条指令:+-<>[].,. <>沿阵列移动一个虚构的"指针"; +-递增和递减当前单元格中的整数; []执行非零循环; 并.,做输入和输出.其实,你真的只需要只是一个指令,如subleq a b c(减去ab并跳转到c如果结果小于或等于零).

2:我从未真正使用过C#,所以如果语法错误,请随意纠正.

  • 在第二个示例中只有一条指令,但不止一个符号.生活可以更简单.(http://esolangs.org/wiki/Iota)当然,那么(我认为)你最终会使用lambda函数... (2认同)

Dig*_*oss 6

块或多或少都是一样的

好吧,在Ruby中,通常不会使用lambda或proc,因为块大致相同并且更方便.

用途是无限的,但我们可以列出一些典型案例.人们通常将功能视为执行一部分处理的较低级别的块,可能通常编写并制作成库.

但通常人们想要自动化包装器并提供自定义库.想象一下,使HTTP或HTTPS连接或直接TCP连接的函数将I/O提供给其客户端,然后关闭连接.或者也许只是用普通的旧文件做同样的事情.

所以在Ruby中我们将函数放在一个库中并让它为用户提供一个块...客户端..."调用者"来编写他的应用程序逻辑.

在另一种语言中,这必须使用实现接口的类或函数指针来完成.Ruby有块,但它们都是lambda样式设计模式的例子.


小智 6

它归结为风格.Lambdas是一种陈述式的风格,方法是势在必行的风格.考虑一下:

Lambda,blocks,procs都是不同类型的闭包.现在的问题是,何时以及为何使用匿名闭包.我可以回答 - 至少在红宝石中!

闭包包含调用它们的词汇上下文.如果从方法中调用方法,则不会获得调用方法的上下文.这是由于对象链存储在AST中的方式.

另一方面,闭包(lambda)可以通过方法与词汇上下文一起传递,允许进行惰性求值.

lambdas自然也适用于递归和枚举.


Dan*_*nov 5

1)这只是一个方便.您不需要为某些块命名

special_sort(array, :compare_proc => lambda { |left, right| left.special_param <=> right.special_param }
Run Code Online (Sandbox Code Playgroud)

(想象一下,如果你必须命名所有这些块)

2)#lambda通常用于创建clojures:

def generate_multiple_proc(cofactor)
  lambda { |element| element * cofactor }
end

[1, 2, 3, 4].map(&generate_multiple_proc(2)) # => [2, 3, 5, 8]

[1, 2, 3, 4].map(&generate_multiple_proc(3)) # => [3, 6, 9, 12]
Run Code Online (Sandbox Code Playgroud)