Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
ruby块不是一流的_Ruby_Lambda_Language Design_Block - Fatal编程技术网

ruby块不是一流的

ruby块不是一流的,ruby,lambda,language-design,block,Ruby,Lambda,Language Design,Block,从语言设计的角度来看,为什么ruby块不是一流的呢 类似地,我认为块实际上应该是lambdas,这样就不需要像proc{…}.call或&proc或lambda或proc.new这样繁琐的语法。这也将消除对产量的需求 从语言设计的角度来看,为什么ruby块不是一流的呢 据我所知,主要是出于性能原因。考虑: def test_yield yield end def test_block &block block.call end la = lambda {} def test

从语言设计的角度来看,为什么ruby块不是一流的呢

类似地,我认为块实际上应该是lambdas,这样就不需要像proc{…}.call或&proc或lambda或proc.new这样繁琐的语法。这也将消除对产量的需求

从语言设计的角度来看,为什么ruby块不是一流的呢

据我所知,主要是出于性能原因。考虑:

def test_yield
  yield
end

def test_block &block
  block.call
end

la = lambda {}

def test_lambda l
  l.call
end
然后,对前两个使用空块进行基准测试,而对第三个使用新的
la
或相同的
la
进行基准测试,并注意每种情况下的收益率有多快。原因是,explicit&block变量会创建一个Proc对象,lambda也是,而仅仅是yielding不会

一个副作用(我实际上发现它的用途是通过使用proc对象递归地传递传递块)是,您不能在某种封闭范围之外的proc或lambda中屈服:

foo = proc { yield if block_given? }
foo.call { puts 'not shown' }

def bar
  baz = proc { yield if block_given? }
  baz.call
end

bar { puts 'should show' }

这是因为,正如我所理解的(我因此失去了很多头发,直到它滴答作响),block_给出了什么?foo调用main时发送到main,在bar中求值时发送到bar而不是baz。

lambda
proc
(和block)具有不同的语义。进程/块具有非本地返回,并且对算术不太挑剔;lambda的行为更像方法。在我看来,这种区别很有用,procs/blocks/lambda不应该像您建议的那样统一。

Ruby方法不是函数或一级公民,因为它们不能作为参数传递给其他方法,不能由其他方法返回,也不能分配给变量。Ruby进程是一流的,类似于JavaScript的一流函数

以下代码演示了Ruby方法如何不能存储在变量中或从方法返回,因此不符合“一流”标准:

class Dog
  def speak
    'ruff'
  end
end

fido = Dog.new
# Ruby methods cannot be stored in variables
# Methods are executed and variables only store values
x = fido.speak
# x stores the method's return value, not the method itself
x # => 'ruff'

# Methods cannot return other methods
# Methods can only return values from other methods
def hi
  Dog.new.speak
end
# hi returns the method's return value, not the method itself
hi # => 'ruff'

如果一种编程语言将函数视为一等公民,那么它就被称为具有一等函数。具体来说,这意味着该语言支持将函数作为参数传递给其他函数,将它们作为其他函数的值返回,并将它们分配给变量或将它们存储在数据结构中。

您认为块是,如果类
Proc
取名为
Block
,那么它就是Ruby中的第一个类?@Mladen Jablanović当然,对于语法(例如,如果{return o.x}发出了一声巨响)有一些说法。然而,我想问的是:块给我们带来了什么?块只是一种语法,一种将Proc传递给方法的便捷方式。进程在Ruby中是一流的。我不知道当你说“街区应该是一流的”时,你会期望什么。你能澄清一下吗?嗯,我每次都运行了一百万次,这就是我得到的结果:测试产量:0.5090551秒。。。测试块:1.667427751秒。。。测试λ:0.741804596秒。。。所以我怀疑积木是为了提高效率。另外,鉴于ruby的速度已经非常慢,我希望有一个好的语义。您忘记了一个测试:每次调用时动态创建lambda,这应该会得到与block case类似的结果。收益率是我玩过的最好的语义。啊,是的,我故意忽略了这一点,成本是对象创建,与&block习惯用法不同,显式。唉,由于嵌套的环境,lambda有足够的开销。它们也不应该是物体。实际上,&block习惯用法和lambda一样明确。它完全等同于:
def foo;block=Proc.new;block.call();结束
。和兰姆达差不多。(正如banister所指出的,proc和lambda之间唯一的区别是在算术和返回语句的处理方式上的挑剔。)如果你是说Matz,我不确定你希望得到什么。。。你问为什么块不是一流的对象;性能符合我的建议。批评这种语言或它的创造者没有多大意义。如果你不喜欢Ruby,有很多选择。:-)是的,我发现这个语义“剖析”既有启发性又很有趣:github.com/dmichael/closures-in-ruby。非局部返回可能有用,但似乎也很隐蔽。@Francis Haart:非局部返回非常适合模拟宏:
my_if(cond){return}