红宝石块不是一流的

发布于 2024-11-19 22:50:35 字数 142 浏览 3 评论 0原文

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

同样,我认为块实际上应该是 lambda,从而摆脱对繁琐语法的需要,例如 proc {...}.call 或 &proc 或 lambda 或 Proc.new。这也将消除对产量的需求。

From a language design perspective, why aren't ruby blocks first-class?

Similarly, I think blocks should actually be lambdas, thereby getting rid of the need for cumbersome syntax such as proc {...}.call or &proc or lambda or Proc.new. This would get rid of the need for yield too.

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

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

发布评论

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

评论(3

攒眉千度 2024-11-26 22:50:35

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

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

def test_yield
  yield
end

def test_block &block
  block.call
end

la = lambda {}

def test_lambda l
  l.call
end

然后,前两个使用空块进行基准测试,而第三个每次调用使用新的 la 或使用相同的 la 进行基准测试,并注意产量快了多少每种情况都会发生。原因是,显式的 &block 变量创建了一个 Proc 对象,就像 lambda 一样,而仅仅生成则不然。

一个副作用(我实际上发现它的用途,通过使用 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_given?当 foo 调用它时发送到 main,并且当它在 bar 中求值时发送到 bar 而不是 baz。

From a language design perspective, why aren't ruby blocks first-class?

Mostly for performance reasons, in as far as I'm aware. Consider:

def test_yield
  yield
end

def test_block &block
  block.call
end

la = lambda {}

def test_lambda l
  l.call
end

Then, benchmark with an empty block for the first two, vs the third with a new la per call or with the same la, and note how much faster the yield goes in each case. The reason is, the explicit &block variable creates a Proc object, as does lambda, while merely yielding doesn't.

A side-effect (which I've actually found uses for, to recursively pipe passed blocks through the use of a proc object), is you cannot yield in a proc or lambda outside some kind of enclosing scope:

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

This is because, as I've come to understand it (I lost a lot of hair due to this, until it ticked), block_given? is sent to main when foo calls it, and to bar rather that baz when it gets evaluated in bar.

完美的未来在梦里 2024-11-26 22:50:35

lambdaproc (和块)具有不同的语义。 Procs/blocks 具有非本地返回并且对数量不太挑剔; lambda 的行为更像方法。在我看来,这种区别是有用的,procs/blocks/lambdas 不应该像你建议的那样统一。

lambda and proc (and block) have different semantics. Procs/blocks have non-local returns and are less picky about arity; lambdas are more method-like in their behaviour. In my opinion this distinction is useful and procs/blocks/lambdas should NOT be unified as you suggest.

灼疼热情 2024-11-26 22:50:35

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'

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

Ruby methods are not functions or first-class citizens because they cannot be passed to other methods as arguments, returned by other methods, or assigned to variables. Ruby procs are first-class, similar to JavaScript’s first-class functions

The following code demonstrates how Ruby methods cannot be stored in variables or returned from methods and therefore do not meet the ‘first-class’ criteria:

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'

a programming language is said to have first-class functions if it treats functions as first-class citizens. Specifically, this means the language supports passing functions as arguments to other functions, returning them as the values from other functions, and assigning them to variables or storing them in data structures.

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