Project

General

Profile

Actions

Feature #12957

closed

A more OO way to create lambda Procs

Feature #12957: A more OO way to create lambda Procs

Added by justcolin (Colin Fulton) almost 10 years ago. Updated over 9 years ago.

Status:
Feedback
Assignee:
-
Target version:
-
[ruby-core:78202]

Description

Currently to create a lambda Proc one has to use lambda { } or -> { }. For doing metaprogramming it would be nice to have a more OO way to generate them. Something like LambdaProc.new. That way one could write:

class MetaThingy
  def initialize proc_class
    @anonymous_function = proc_class.new do
      # Some Code
    end
  end
end

and pass in either Proc or LambdaProc depending on their needs, instead of:

class MetaThingy
  def initialize proc_type
    @anonymous_function = case proc_type
                          when :proc
                            proc do
                              # Some Code
                            end
                          when :lambda
                            lambda do
                              # Some Code
                            end
                          end
    end
  end
end

This is not a common use case, but would help make the language more orthogonal.


Related issues 2 (1 open1 closed)

Related to Ruby - Feature #7314: Convert Proc to Lambda doesn't work in MRIAssignedmatz (Yukihiro Matsumoto)Actions
Related to Ruby - Feature #15973: Let Kernel#lambda always return a lambdaClosedmatz (Yukihiro Matsumoto)Actions

Updated by shyouhei (Shyouhei Urabe) almost 10 years ago Actions #1

Problem is, when you allow LambdaProc.new, that have to accept non-lambda procs, like LambdaProc.new(&nonlambda). This way, a proc would be converted from/between lambda and non-lambda.

This is not a good idea. Right now a lambda is born to be a lambda and there is no way to turn it into a proc. If such property breaks, a programmer cannot guarantee what to expect to a block they wrote's parameter, because that proc can later be changed into a lambda by someone else. And there is no way to detect such change from that block itself before it is called.

Updated by shyouhei (Shyouhei Urabe) almost 10 years ago Actions #2

  • Related to Feature #7314: Convert Proc to Lambda doesn't work in MRI added

Updated by dsisnero (Dominic Sisneros) over 9 years ago Actions #3 [ruby-core:79068]

I want this too

MyLambda = Class.new Proc

I want MyLambda{|x| x + 1}.lambda? to == true

I only want it when initializing the new lambdas. I want easy initialization with a block

Maybe allow Proc.new to accept true or false

class Proc

  def initialize(lmbda = false, &block)
       if lmbda
         __lambda__ = true
       end
       block = block
  end

end

then

class MyLambda
    def initialize(&block)
       super(true,&block)
    end
end

MyLambda.new{|x| x + 1}.lambda? == true

Updated by akr (Akira Tanaka) over 9 years ago Actions #4 [ruby-core:79154]

  • Status changed from Open to Feedback

It is not impossible to generate MyLambda.new {} as lambda.

% ruby -e '
class MyLambda
end
class << MyLambda
  alias new lambda
  public :new
end
x = MyLambda.new { p :foo }
p x.lambda?
x.call
'
true
:foo

I'm not sure this is enough for actual usages, though.

Updated by matz (Yukihiro Matsumoto) over 9 years ago Actions #5 [ruby-core:79156]

The code above does not return a MyLamnda instance.

Matz.

Updated by Eregon (Benoit Daloze) over 9 years ago Actions #6 [ruby-core:79244]

Actually, it is possible to create a single block of code that can be proc or lambda with #send:

> Kernel.send(:lambda) {}.lambda?
=> true
> Kernel.send(:proc) {}.lambda?
=> false

I was surprised as well this worked, the Kernel#lambda method is quite magic:
https://github.com/graalvm/truffleruby/pull/12#discussion_r96889356

Updated by shyouhei (Shyouhei Urabe) about 7 years ago Actions #7

  • Related to Feature #15973: Let Kernel#lambda always return a lambda added
Actions

Also available in: PDF Atom