Macros in Ruby

In article <138135881306.20040805010035@soyabean.com.au>, Gavin

> Between Ruby and Lisp? To tell the truth I'm not entirely sure. The
> pickaxe book does a lousy job explaining the differences between blocks
> and proc objects. I'm still not sure why Ruby needs two concepts when
> Lisp and other languages get by with one. I also don't know why Ruby
> uses that weird yield syntax.

On the one hand you advocate macros to make syntax more expressive; on
the other you advocate rolling everything back into anonymous
functions with no visual distinctions. *shrug*

Well, what are the differences between blocks and proc objects? As far
as I can tell the only difference is that proc objects are explicitly
declared in method argument lists and are first class objects. Blocks,
on the other hand, are not listed in the method list (unless you use
&block to create a proc) and called using yield.

How does that make the language more expressive?

Which do you prefer?

   (1..10).map { |n| n ** 2 }

   (1..10).map( lambda { |n| n ** 2 } )

(If the latter, then I guess nothing further can be said.)

Blocks are something that are used _all the time_ in Ruby. Perhaps
more than you appreciate. They are semantically the same as explicit
blocks, but the syntax is optimised for the common use. And it's not
limiting:

  square = lambda { |n| n ** 2 }
  (1..10).map(&square)

Please remember Joel's "percent-case" solution, extensively using
blocks. That was nothing if not expressive. Ruby can be bent into
1000 different shapes, primarily thanks to blocks. Those shapes would
be possible without them (just use explicit lambdas) but not nearly as
appealing, and therefore people wouldn't bother, and the world would
be poorer.

Implicitly passing arguments seems actively bad and using "yield lhs
rhs" seems worse than using "compare.call lhs rhs".

Same comments as above apply. "Yield" is the perfect English word to
describe the behaviour.

For some words from the source, I recommend you look up Matz's
interviews with Bill Venners on artima.com.

Ruby is a lot of things, but it's not a LISP/Dylan wanna-be. You do
yourself no favours by insisting on looking at it from that angle.

Cheers,
Gavin

···

On Thursday, August 5, 2004, 7:11:29 AM, Jesse wrote:

Sinclair <gsinclair@soyabean.com.au> wrote:

On Wednesday, August 4, 2004, 10:41:43 PM, Jesse wrote:

surrender_it@yahoo.it (gabriele renzi @ google) writes:

def_with_docstring(Object, "foo", "returns arg", "arg", "arg")
  
Object.new.foo("hi") # => "hi"

Yes, I am aware you can do more sophisticated implementation so you
can make the above nicer. Yet, as nice as it will be, it won't be as
simple as the example with macro; there will be quirkiness caused by
the language syntax.

not that much, did you see the MetaTags system or the various
implementations of docstrings?

Something on the lines of:

doc 'this things does foo'
def foo
...
end

More like:
      class_info <<-DOC
        !Class: MyClass
        !Desc: This class does something
      
        !attr a: A: The "A" attribute
        !attr b: B
      DOC
      class MyClass
        ...
      end

and this is what the doc has to say about the '!Class' tag:

   !Class - A string indicating the fully-qualified class name. This
             is a required field.

Robert's example is about similar to what MetaTags does. Thus, they
both make one to repeat one self; you have to say: "this docstring is
for this method of this class", even if the information is available
nearby. I think this counts as quirkiness.

My point was not whether it is possible to do something in Ruby. The
point was to show Rando Christensen that macro can be used to enhance
clarity as well as to obfuscate, and that some things are easier done
with macro then without. I think my example shows that with macro, you
can extend the language naturally (instead of having to repeat
yourself if done within the language's limitation).

For example, rake has this in its documentation: "NOTE: Because of a
quirk in Ruby syntax, parenthesis are required on rule when the first
argument is a regular expression."

IIRC this is related to bison not being good enough :slight_smile:

Somewhere, somehow, there will always be deficiencies. With macro, you
can alleviate those somewhat. Not that I think macro would help rake
in the above case since that is a syntax problem, rather than semantic
problem (I have no idea if macro can save you from invalid syntax
since the only macro system I've used is lisp's where the syntax is
not as rich as ruby's and also doesn't work if you have an invalid
syntax anyway).

I am not advocating for macro in Ruby. I am neutral; I do not care if
there is macro or not. If there is macro, then that's great, although
there are only so many legitimate usages. If there isn't, it is also
not such a big of a loss since there are only few legitimiate usages.

Even the above example (repeating yourself), can be somewhat
eliminated with the help of a good editor.

Have a nice day, thanks for the input! I didn't know about MetaTags
before. Thank you.

YS.

"David A. Black" <dblack@wobblini.net> writes:

def foo(arg)
    "This method will return <code>arg</code>"
    arg
end

You can already do that, if you don't mind a warning with -w :slight_smile: But

Hi David,

My example is incomplete. There should be this following that:

docstring(:foo) #=> "This method will return <code>arg</code>"

assuming you intend a macro to let you do things that are otherwise
illegal syntax, that's where the problem arises of having everyone's

In my reply to gabriele, I mentioned that I do not know if macro can
save one from an invalid syntax since my experience with macro is
limited to CL's and elisp's macros which won't work if the syntax is
invalid.

Rather, what the example above shows that with macro you can change
the semantic of method definition, i.e.: if there is a string at the
top of the method body, take that as the docstring for that method,
instead of giving a warning about unused literal.

Sorry, I am unable to come up with a likely macro definition that
would allow the above example to be true. I had difficulty imagining
how you can define such macro in ruby; my imagination is lacking.

I also believe that macro, like any other tool, can be used for good
or evil. More importantly, I do not care if Ruby has macro or not,
although now that I have more time to think since my reply to
gabriele, I am leaning toward leaving things the way it is (without
macro) since macro is susceptible to being abused.

Good day,
YS.

In article <161164987028.20040805090540@soyabean.com.au>, Gavin

Which do you prefer?

   (1..10).map { |n| n ** 2 }

   (1..10).map( lambda { |n| n ** 2 } )

I prefer a light-weight syntax for something as commonly used as
anonymous functions. On the other hand, I still don't know why {|n| n
** 2} can't simply create a proc object.

Please remember Joel's "percent-case" solution, extensively using
blocks. That was nothing if not expressive.

Yes, a beautiful example of the flexibility of Ruby. But I don't see
how having both blocks and proc objects improves Ruby's expressiveness.

Ruby can be bent into
1000 different shapes, primarily thanks to blocks.

Plenty of languages have blocks, but fewer languages could build
declarative structures as nicely as Joel was able to do. You also need
instance_eval and it helps a lot if the syntax is fairly free-form so
you can omit parenthesis in function calls.

> Implicitly passing arguments seems actively bad and using "yield lhs
> rhs" seems worse than using "compare.call lhs rhs".

Same comments as above apply. "Yield" is the perfect English word to
describe the behaviour.

Sure, it's a good word to describe what the interpreter will do when it
hits that line, but it completely fails to describe the more important
semantic behavior. And if the language already has proc objects why
bother supporting yield?

  -- Jesse

···

Sinclair <gsinclair@soyabean.com.au> wrote:

Jesse Jones wrote:

Yes, a beautiful example of the flexibility of Ruby. But I don't see
how having both blocks and proc objects improves Ruby's expressiveness.

It doesn't. You could drop the implicitly passed blocks and always deal with an explicit &block argument and not miss a bit of expressiveness There is a performance difference difference however, and I suspect that is the real reason why the yield syntax is supported (i.e. to avoid the overhead of reifying blocks into full fledged objects). Perhaps a future optimization will make the &block syntax as efficient as the implicit yield syntax. When that happens, the "block" concept can retreat to the interior of the interpretor (where it belongs) and not haunt developers with this weird "almost a proc, but not quite" semantics. At least that's my view.

Actually what surprises me most about Ruby's one-block per method technique is how flexible it turns out to be. One would think that having the ability to pass multiple blocks would be big improvement, but I suspect that the improvement in flexibility is merely incremental.

What surprises me about Ruby is the about of expressiveness you get, even though you are limited to only one block per method call. You would think that having the ability to pass multiple closures to a method would be a big improvement,

> Plenty of languages have blocks, but fewer languages could build
> declarative structures as nicely as Joel was able to do. You also need
> instance_eval and it helps a lot if the syntax is fairly free-form so
> you can omit parenthesis in function calls.

All those help. I've used both Lisp and Forth and really admire their ability to create tailored languages for a domain. I think Ruby comes close to their level of flexibility, but does it with different tools that either Forth or Lisp (i.e. macros and run-time code generation).

···

--
-- Jim Weirich jim@weirichhouse.org http://onestepback.org
-----------------------------------------------------------------
"Beware of bugs in the above code; I have only proved it correct,
not tried it." -- Donald Knuth (in a memo to Peter van Emde Boas)

Hi,

Which do you prefer?

   (1..10).map { |n| n ** 2 }

   (1..10).map( lambda { |n| n ** 2 } )

shouldn't that be '(1..10).map( &lambda { |n| n ** 2 } )'?

I prefer a light-weight syntax for something as commonly used as anonymous
functions. On the other hand, I still don't know why {|n| n ** 2} can't
simply create a proc object.

It can! Wether or not a proc object gets created depends on the
called method. If that method uses yield, then no object is
created. If however it captures a block using the '&' operator,
then a Proc object gets created.

On the other hand, a Proc created this way is different from one
created using Proc.new or lambda.

The difference which I can think of are:
- Argument passing, a block isn't strict about the arguments
  it gets passed, (i.e. it can take any argument). A Proc
  object in contrast is strict (like methods). The reason I
  can think of is that it is often usefull not to get all arguments
  in a block, i.e. 3.times{ puts "Hi, world!" }

- The place where return goes to: in a block 'return' returns
  from the method in which it is defined. In a lambda (Proc)
  it returns from the lambda expression.

Please remember Joel's "percent-case" solution, extensively using
blocks. That was nothing if not expressive.

Yes, a beautiful example of the flexibility of Ruby. But I don't see how
having both blocks and proc objects improves Ruby's expressiveness.

Well, it is very expressive to be able to 'return' from a block.
That 's one of those thing I find uncomfortable in lisp and
scheme. Sure, there is a good reason there is no 'return' in
scheme: every statement is an expression, it wouldn't know where
to return from.
I find it much more practical in Ruby, (with some gotha's, like
LocalJumpError).

Also block make it possible to do 3.times { puts "hello"} as
explained above. That's more expressive than having to type
3.times { |i| puts "hello"}

Sure, it's a good word to describe what the interpreter will do when it
hits that line, but it completely fails to describe the more important
semantic behavior. And if the language already has proc objects why
bother supporting yield?

  -- Jesse

I believe yield is there historically. In early versions of Ruby
yield used to be the only way to pass arguments to blocks. Then
in was unified with Proc objects. I may be totally mistaken about
this.

The other thing is performance. Creating a proc object is quite
expensive.

Also, but perhaps less important, it is a little easier to
type yield, than to create block, and use block.call every
time.

I hope this explains a little why I find Ruby's way very
expressive. I believe Ruby isn't semantically as clean as
Scheme or SmallTalk. (I don't think lisp is semantically very
clean). However for me it has the right mix of being consistent
and being practical.

Regards,
KB

···

On Thu, 05 Aug 2004 03:30:33 +0000, Jesse Jones wrote:

Remember how the lambda method works: it takes a block parameter and
creates an object out of it. IMO this is very clean; blocks are the
basic building block and procs and bindings are built on top of them.

As to why we cannot remove the call to the lambda method, consider:
  1. Ruby does have blocks, and
  2. Ruby does not require parens for method calls.

If I write:

  (1..10).map { |n| n ** 2 }

Should this be interpreted as:

  (1..10).map(lambda { |n| n ** 2 })

or as:

  (1..10).map do |n| n ** 2; end

If it were possible to merge blocks and proc objects without
introducting ambiguity and without losing backward compatibility, it
might not be a bad idea. I do not think this is possible, though.

Paul

···

On Thu, Aug 05, 2004 at 12:31:30PM +0900, Jesse Jones wrote:

In article <161164987028.20040805090540@soyabean.com.au>, Gavin
Sinclair <gsinclair@soyabean.com.au> wrote:

> Which do you prefer?
>
> (1..10).map { |n| n ** 2 }
>
> (1..10).map( lambda { |n| n ** 2 } )

I prefer a light-weight syntax for something as commonly used as
anonymous functions. On the other hand, I still don't know why {|n| n
** 2} can't simply create a proc object.

That's possible, but not in a block passing way (if that is
what you mean). You can always create a closure using
lambda and pass it to the method like any other value.

Regards,
KB

···

On Thu, 05 Aug 2004 13:24:16 +0900, Jim Weirich wrote:

What surprises me about Ruby is the about of expressiveness you get, even
though you are limited to only one block per method call. You would think
that having the ability to pass multiple closures to a method would be a
big improvement,

"Kristof Bastiaensen" <kristof@vleeuwen.org> schrieb im Newsbeitrag
news:pan.2004.08.05.09.55.29.582255@vleeuwen.org...

Hi,

>> Which do you prefer?
>>
>> (1..10).map { |n| n ** 2 }
>>
>> (1..10).map( lambda { |n| n ** 2 } )

shouldn't that be '(1..10).map( &lambda { |n| n ** 2 } )'?

>
> I prefer a light-weight syntax for something as commonly used as

anonymous

> functions. On the other hand, I still don't know why {|n| n ** 2}

can't

> simply create a proc object.

It can! Wether or not a proc object gets created depends on the
called method. If that method uses yield, then no object is
created. If however it captures a block using the '&' operator,
then a Proc object gets created.

On the other hand, a Proc created this way is different from one
created using Proc.new or lambda.

The difference which I can think of are:
- Argument passing, a block isn't strict about the arguments
  it gets passed, (i.e. it can take any argument). A Proc
  object in contrast is strict (like methods). The reason I
  can think of is that it is often usefull not to get all arguments
  in a block, i.e. 3.times{ puts "Hi, world!" }

I don't know what exactly you mean by this. Argument passing is the same
for blocks and procs IMHO. Can you explain the difference?

- The place where return goes to: in a block 'return' returns
  from the method in which it is defined. In a lambda (Proc)
  it returns from the lambda expression.

Ah, thanks for reminding me! That's IMHO the single most crucial
difference between blocks and procs created from blocks vs. stand alone
lambdas / procs. And it's a really important difference!

Kind regards

    robert

>
>> Please remember Joel's "percent-case" solution, extensively using
>> blocks. That was nothing if not expressive.
>
> Yes, a beautiful example of the flexibility of Ruby. But I don't see

how

> having both blocks and proc objects improves Ruby's expressiveness.
>
>

Well, it is very expressive to be able to 'return' from a block.
That 's one of those thing I find uncomfortable in lisp and
scheme. Sure, there is a good reason there is no 'return' in
scheme: every statement is an expression, it wouldn't know where
to return from.
I find it much more practical in Ruby, (with some gotha's, like
LocalJumpError).

Also block make it possible to do 3.times { puts "hello"} as
explained above. That's more expressive than having to type
3.times { |i| puts "hello"}

> Sure, it's a good word to describe what the interpreter will do when

it

···

On Thu, 05 Aug 2004 03:30:33 +0000, Jesse Jones wrote:
> hits that line, but it completely fails to describe the more important
> semantic behavior. And if the language already has proc objects why
> bother supporting yield?
>
> -- Jesse

I believe yield is there historically. In early versions of Ruby
yield used to be the only way to pass arguments to blocks. Then
in was unified with Proc objects. I may be totally mistaken about
this.

The other thing is performance. Creating a proc object is quite
expensive.

Also, but perhaps less important, it is a little easier to
type yield, than to create block, and use block.call every
time.

I hope this explains a little why I find Ruby's way very
expressive. I believe Ruby isn't semantically as clean as
Scheme or SmallTalk. (I don't think lisp is semantically very
clean). However for me it has the right mix of being consistent
and being practical.

Regards,
KB

When I ported Diff::LCS, the Perl Algorithm::Diff version from which I
started used a hash of anonymous procs. I modified this to use a
callback *object*. I think that by the time you start needing multiple
procs, it's just as easy (or easier) to require an object that
encapsulates that.

-austin

···

On Thu, 5 Aug 2004 13:24:16 +0900, Jim Weirich <jim@weirichhouse.org> wrote:

Actually what surprises me most about Ruby's one-block per method
technique is how flexible it turns out to be. One would think that
having the ability to pass multiple blocks would be big improvement, but
I suspect that the improvement in flexibility is merely incremental.

What surprises me about Ruby is the about of expressiveness you get,
even though you are limited to only one block per method call. You
would think that having the ability to pass multiple closures to a
method would be a big improvement,

--
Austin Ziegler * halostatue@gmail.com
               * Alternate: austin@halostatue.ca

perhaps a shorthand:

   lambda{ puts 'lambda' } => Proc:0xb74041a0
   &{ puts 'lambda too' } => Proc:0xb74041a1

i'm probably missing something, but i don't think the syntax '&{' occurs
anywhere now and '&' is already synomynous with blocks/procs/etc.

-a

···

On Thu, 5 Aug 2004, Paul Brannan wrote:

On Thu, Aug 05, 2004 at 12:31:30PM +0900, Jesse Jones wrote:

In article <161164987028.20040805090540@soyabean.com.au>, Gavin
Sinclair <gsinclair@soyabean.com.au> wrote:

Which do you prefer?

   (1..10).map { |n| n ** 2 }

   (1..10).map( lambda { |n| n ** 2 } )

I prefer a light-weight syntax for something as commonly used as
anonymous functions. On the other hand, I still don't know why {|n| n
** 2} can't simply create a proc object.

Remember how the lambda method works: it takes a block parameter and
creates an object out of it. IMO this is very clean; blocks are the
basic building block and procs and bindings are built on top of them.

As to why we cannot remove the call to the lambda method, consider:
1. Ruby does have blocks, and
2. Ruby does not require parens for method calls.

If I write:

(1..10).map { |n| n ** 2 }

Should this be interpreted as:

(1..10).map(lambda { |n| n ** 2 })

or as:

(1..10).map do |n| n ** 2; end

If it were possible to merge blocks and proc objects without
introducting ambiguity and without losing backward compatibility, it
might not be a bad idea. I do not think this is possible, though.

Paul

--

EMAIL :: Ara [dot] T [dot] Howard [at] noaa [dot] gov
PHONE :: 303.497.6469
A flower falls, even though we love it;
and a weed grows, even though we do not love it. --Dogen

===============================================================================

Hi,

Which do you prefer?

   (1..10).map { |n| n ** 2 }

   (1..10).map( lambda { |n| n ** 2 } )

shouldn't that be '(1..10).map( &lambda { |n| n ** 2 } )'?

No. Jesse expressed a distaste for implicitly passed arguments (i.e.
a block being passed to the method as a hidden, or a special,
parameter. So I presented the above examples as two *different*
possible #map interfaces. In the first one, the block "parameter" is
implicit; in the second one, explicit.

I prefer a light-weight syntax for something as commonly used as anonymous
functions. On the other hand, I still don't know why {|n| n ** 2} can't
simply create a proc object.

It can! Wether or not a proc object gets created depends on the
called method. [...]

That's context-dependent. My impression is that Jesse thinks that
code snippet in *any* context should evaluate to a lambda.

On the other hand, a Proc created this way is different from one
created using Proc.new or lambda.

The difference which I can think of are:
- Argument passing, a block isn't strict about the arguments
  it gets passed, (i.e. it can take any argument). A Proc
  object in contrast is strict (like methods). The reason I
  can think of is that it is often usefull not to get all arguments
  in a block, i.e. 3.times{ puts "Hi, world!" }

- The place where return goes to: in a block 'return' returns
  from the method in which it is defined. In a lambda (Proc)
  it returns from the lambda expression.

Thanks for pointing these out; they didn't come to mind before.

<snip/>

Gavin

···

On Thursday, August 5, 2004, 7:56:34 PM, Kristof wrote:

On Thu, 05 Aug 2004 03:30:33 +0000, Jesse Jones wrote:

> - Argument passing, a block isn't strict about the arguments
> it gets passed, (i.e. it can take any argument). A Proc
> object in contrast is strict (like methods). The reason I
> can think of is that it is often usefull not to get all arguments
> in a block, i.e. 3.times{ puts "Hi, world!" }

I don't know what exactly you mean by this. Argument passing is the same
for blocks and procs IMHO. Can you explain the difference?

def foo; yield 1,2 end; foo { |a,b,c,d| }

=> nil

lambda{|a,b,c,d|}.call 1, 2

ArgumentError: wrong number of arguments (2 for 4)
        from (irb):2
        from (irb):2:in `call'
        from (irb):2

Proc.new{|a,b,c,d|}.call 1, 2

=> nil

RUBY_VERSION

=> "1.8.2"

RUBY_RELEASE_DATE

=> "2004-07-30"

···

On Thu, Aug 05, 2004 at 07:16:29PM +0900, Robert Klemme wrote:

--
Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com

Oh, it seems I was wrong (after looking it up with ri).
What I said in the previous post only applies to procs created
with lambda (including the return thing), not procs created with
Proc.new.
So I guess that Proc.new creates exactly the same Proc object
as a block does (in the case that a Proc object gets created
from a block). Only lambda expressions are different.
That would also mean that the best way to get rid of the
LocalJumpError problem is to use a lambda expression.

Here is an example about what I meant with argument passing:

b1 = Proc.new { |a,b|
   puts "a == #{a.inspect}, b == #{b.inspect}" }
b2 = lambda { |a,b|
   puts "a == #{a.inspect}, b == #{b.inspect}" }

b1[1]
b2[1]
#--- output: ----
a == 1, b == nil
/tmp/blocks.rb:5: wrong number of arguments (1 for 2) (ArgumentError)
        from /tmp/blocks.rb:5:in `'
        from /tmp/blocks.rb:9

···

On Thu, 05 Aug 2004 12:15:20 +0200, Robert Klemme wrote:

The difference which I can think of are: - Argument passing, a block
isn't strict about the arguments
  it gets passed, (i.e. it can take any argument). A Proc object in
  contrast is strict (like methods). The reason I can think of is that
  it is often usefull not to get all arguments in a block, i.e. 3.times{
  puts "Hi, world!" }

I don't know what exactly you mean by this. Argument passing is the same
for blocks and procs IMHO. Can you explain the difference?

#----------------

Sorry for the confusion.

Cheers,
KB

If you must have a shortcut, I think 'L' makes more sense.

  L { puts 'lambda' } => Proc:0xb74041a0

My aesthetic sense says that a shortcut is unnecessary because
creating explicit lambdas is uncommon (because Ruby has blocks, thank
goodness), and because when you do explicitly create lambdas, they're
usually so cool and saving so much other effort that I don't begrudge
them a few characters :slight_smile:

Gavin

···

On Friday, August 6, 2004, 12:11:27 AM, Ara.T.Howard wrote:

perhaps a shorthand:

   lambda{ puts 'lambda' } => Proc:0xb74041a0
   &{ puts 'lambda too' } => Proc:0xb74041a1

i'm probably missing something, but i don't think the syntax '&{' occurs
anywhere now and '&' is already synomynous with blocks/procs/etc.

Ara.T.Howard wrote:

perhaps a shorthand:

  lambda{ puts 'lambda' } => Proc:0xb74041a0
  &{ puts 'lambda too' } => Proc:0xb74041a1

i'm probably missing something, but i don't think the syntax '&{' occurs
anywhere now and '&' is already synomynous with blocks/procs/etc.

I've been in favor of this since the last rubyconf when I
discussed it with someone (can't recall who).

I don't think it's ever been an RCR though.

Hal

In article <60223680255.20040806012354@soyabean.com.au>, Gavin Sinclair

That's context-dependent. My impression is that Jesse thinks that
code snippet in *any* context should evaluate to a lambda.

No, my argument was that having lambda + Proc + method + block seemed
awfully confusing and I didn't see the justifications for doing so.

For example, some have said that blocks are there for performance
reasons which is a reasonable argument, but also seems like a bit of a
copout. It seems like it would be nicer to do these sorts of
optimzations automatically in the interpreter instead of cluttering up
the language with ways to indicate that the optimization is applicable.

Similarly return returning from a method within a block, but returning
from the closure in a lambda expression was touted as a benefit. But,
to me, it'd be cleaner to use one closure construct and reuse break
which already has the local escape semantics.

  -- Jesse

···

<gsinclair@soyabean.com.au> wrote:

"Mauricio Fernández" <batsman.geo@yahoo.com> schrieb im Newsbeitrag
news:20040805113529.GA14601@student.ei.uni-stuttgart.de...

> > - Argument passing, a block isn't strict about the arguments
> > it gets passed, (i.e. it can take any argument). A Proc
> > object in contrast is strict (like methods). The reason I
> > can think of is that it is often usefull not to get all arguments
> > in a block, i.e. 3.times{ puts "Hi, world!" }
>
> I don't know what exactly you mean by this. Argument passing is the

same

> for blocks and procs IMHO. Can you explain the difference?

>> def foo; yield 1,2 end; foo { |a,b,c,d| }
=> nil
>> lambda{|a,b,c,d|}.call 1, 2
ArgumentError: wrong number of arguments (2 for 4)
        from (irb):2
        from (irb):2:in `call'
        from (irb):2
>> Proc.new{|a,b,c,d|}.call 1, 2
=> nil
>> RUBY_VERSION
=> "1.8.2"
>> RUBY_RELEASE_DATE
=> "2004-07-30"

Thanks! Also:

irb(main):001:0> def foo(&b) b.call 1,2 end
=> nil
irb(main):002:0> foo {|a,b,c,d|}
=> nil

    robert

···

On Thu, Aug 05, 2004 at 07:16:29PM +0900, Robert Klemme wrote:

What I said in the previous post only applies to procs created
with lambda (including the return thing), not procs created with
Proc.new.

and is there any difference between lambda {...} and proc {...} ?

* Gavin Sinclair <gsinclair@soyabean.com.au> [Aug 05, 2004 17:40]:

> perhaps a shorthand:

> lambda{ puts 'lambda' } => Proc:0xb74041a0
> &{ puts 'lambda too' } => Proc:0xb74041a1

If you must have a shortcut, I think 'L' makes more sense.

  L { puts 'lambda' } => Proc:0xb74041a0

Or
  \ { puts 'lambda' } => Proc:0xb74041a0

which would make it act sort of like it does in Haskell. However, I
always figured

  proc{ puts 'proc or lambda' }

or

  lambda{ puts 'proc or lambda' }

was easy enough to understand. Having a special operator for it seems
utterly redundant, as Gavin says, since creating anonymous functions in
this manner is far from as common as in Haskell (and it's not very
common their either). And given that Scheme or Lisp that use them for
basically everything don't have a shorter notation (except for (define)
"rewriting") than (lambda) doesn't seem to warrant a shorter notation
for use in Ruby,
  nikolai

···

--
::: name: Nikolai Weibull :: aliases: pcp / lone-star / aka :::
::: born: Chicago, IL USA :: loc atm: Gothenburg, Sweden :::
::: page: www.pcppopper.org :: fun atm: gf,lps,ruby,lisp,war3 :::
main(){printf(&linux["\021%six\012\0"],(linux)["have"]+"fun"-97);}