Default argument values for blocks

Hi --

···

On Wed, 12 Oct 2005, Yukihiro Matsumoto wrote:

Hi,

In message "Re: Default argument values for blocks" > on Wed, 12 Oct 2005 06:40:07 +0900, "David A. Black" <dblack@wobblini.net> writes:

>> foo = ->(foo="bar"){puts foo}

>Is this definitely going to remain? (Please say no.... :slight_smile:

It is, but appearance may be changed. But I haven't got the better
one.

I definitely think a keyword would be better than -> .

David

--
David A. Black
dblack@wobblini.net

Yukihiro Matsumoto wrote:

Hi,

>> foo = ->(foo="bar"){puts foo}

>Is this definitely going to remain? (Please say no.... :slight_smile:

It is, but appearance may be changed. But I haven't got the better
one.

What about either

   block = lambda(foo = 'bar') { puts foo } # Implicit

or

   block = lambda(foo = 'bar') {|foo| puts foo } # Explicit

Or is -> solving an entirely different problem? (If so, would
you mind stating the problem again or pointing me to an earlier
discussion?)

              matz.

E

···

In message "Re: Default argument values for blocks" > on Wed, 12 Oct 2005 06:40:07 +0900, "David A. Black" <dblack@wobblini.net> writes:

by that you mean it is a 'real' method - not a proc object?

i like -> btw. though =>> has a bit more 'weight'.

regards.

-a

···

On Wed, 12 Oct 2005, Yukihiro Matsumoto wrote:

Hi,

In message "Re: Default argument values for blocks" > on Wed, 12 Oct 2005 02:40:48 +0900, "Ara.T.Howard" <Ara.T.Howard@noaa.gov> writes:

>> foo = ->(foo="bar"){puts foo}

>-> means lambda?

Yes, as in Perl6. "lambda" here means lambda in other languages, not
the lambda method in Ruby.

--

email :: ara [dot] t [dot] howard [at] noaa [dot] gov
phone :: 303.497.6469
Your life dwells amoung the causes of death
Like a lamp standing in a strong breeze. --Nagarjuna

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

And here I was wishing for \(foo="bar") {}, the way Haskell does it :slight_smile:
(Seriously - I've always found that the best of all the lambda
notations)

martin

···

Thomas <sanobast-2005a@yahoo.de> wrote:

> What of &?
>
> a.each( &->(foo="bar"){puts foo} ) # Ick.
>
> Can we drop?
>
> a.each( ->(foo="bar"){puts foo} ) # Better.

I was dreaming for a long time of a ruby dialect that has all these
fancy arrows haskell has. Everybody proposing arrows, please (try to)
read some haskell code.

But seriosly, I personally would prefer something in the line lambda(x,
y=1) {...} as it was proposed by other people too.

Selon Thomas <sanobast-2005a@yahoo.de>:

I was dreaming for a long time of a ruby dialect that has all these
fancy arrows haskell has. Everybody proposing arrows, please (try to)
read some haskell code.

I have and can only concur. The arrows make things pretty confusing in most
places.

But seriosly, I personally would prefer something in the line lambda(x,
y=1) {...} as it was proposed by other people too.

The problem is that "collection.each lambda(foo="bar") {puts foo}" has to be the
ugliest and most long-winded thing I've seen in a long time. It's OK for making
a Proc, but to use as a block it's just plain wrong.

However, it's nearly impossible a problem to solve. Any solution will probably
look rather awful. We just need to find the least offensive one :slight_smile: . Unless one
finds a way to parse "{|foo="bar"| puts foo}" correctly. That'd be the best
solution.

The => in the hash syntax is IMHO already one kind of arrow too much.

Hasn't a change been accepted that allows one to use ":" as an alternative to
"=>" in hashes?

Hey, what about ":(foo="bar"){puts foo}"? It's still not beautiful but it's
still less annoying, and in Ruby we are already used to see colons at the
beginning of a word. Of course, overloading ":" may not be considered a good
idea, but it shouldn't be a parsing problem as this one would always be
followed by a "(" (and that doesn't happen with symbols). And:

collection.each:(foo="bar"){puts foo}

isn't that bad :slight_smile: .

···

--
Christophe Grandsire.

http://rainbow.conlang.free.fr

It takes a straight mind to create a twisted conlang.

Why not \ as in Haskell instead? Looks much more like the actual letter
lambda (which is what motivated its use in Haskell) and is two
keystrokes less to type (counting the shift for >).

martin

···

Yukihiro Matsumoto <matz@ruby-lang.org> wrote:

Hi,

In message "Re: Default argument values for blocks" > on Wed, 12 Oct 2005 02:40:48 +0900, "Ara.T.Howard" <Ara.T.Howard@noaa.gov> writes:

>> foo = ->(foo="bar"){puts foo}

>-> means lambda?

Yes, as in Perl6. "lambda" here means lambda in other languages, not
the lambda method in Ruby.

Hi,

Other than syntax, what's the difference between this and the
Proc that comes from the lambda method? Maybe how return,
break, etc is handled?

They are same, same class, same behavior, except for full argument
syntax of method arguments.

In addition to handling defaults in arguments, I think these
issues need to be addressed in blocks/lambdas:

- all variables in the defining scope of a block/lambda are
prevented from being GCed by the block/lambda (because of the
#binding). This can easily result in a leaky program if not
careful. I discussed several solutions to this in a previous
thread.

I think this issue should _not_ be solved by making new lambda-like
object, but something like making eval a keyword, so that non
referenced local variable can be erased unless eval is called within
the scope.

- a facility for making variables local (regardless of whether
a variable of the same name exists in the defining scope).
This would also be good to have for a begin-end type block (I'd
like to have it for making inlined macros where I don't want to
worry about what variables are already used). I discussed
several solutions for this in another thread.

In 1.9, you can declare block local variables explicitly, by the
syntax:

  foo {|a; b, c| ...} # b and c are block local

so that

  b=1
  5.times{|i;b|
    b=5 # modifying in-block "b"
    p [i,b]
  }
  p b # outer "b" remain unchanged

Also, I saw some slides for ruby 2 back in 2003 showing that
arguments will always be local to the block and other variables
in the block will be in the same scope as the defining scope.
I think always making arguments local is a good thing, but
never localizing the other variables will be problematic if
another local variable facility is not provided.

See above.

              matz.

···

In message "Re: Default argument values for blocks" on Wed, 12 Oct 2005 10:01:44 +0900, Eric Mahurin <eric_mahurin@yahoo.com> writes:

Hi,

···

In message "Re: Default argument values for blocks" on Wed, 12 Oct 2005 10:13:31 +0900, "David A. Black" <dblack@wobblini.net> writes:

I definitely think a keyword would be better than -> .

Maybe. Some prefer verbosity to clarity. So what keyword you think
"the best"?

              matz.

Hi,

>-> means lambda?

Yes, as in Perl6. "lambda" here means lambda in other languages, not
the lambda method in Ruby.

by that you mean it is a 'real' method - not a proc object?

By that I mean, it is a syntax, which gives you a Proc object.

i like -> btw. though =>> has a bit more 'weight'.

It depends on your taste.

              matz.

···

In message "Re: Default argument values for blocks" on Wed, 12 Oct 2005 10:39:39 +0900, "Ara.T.Howard" <Ara.T.Howard@noaa.gov> writes:

Selon Martin DeMello <martindemello@yahoo.com>:

And here I was wishing for \(foo="bar") {}, the way Haskell does it :slight_smile:
(Seriously - I've always found that the best of all the lambda
notations)

I wouldn't mind that one. "\" isn't too instrusive, and as a LaTeX fan I'm quite
used to it. But see my former post on the subject.

···

--
Christophe Grandsire.

http://rainbow.conlang.free.fr

It takes a straight mind to create a twisted conlang.

Selon Martin DeMello <martindemello@yahoo.com>:

Why not \ as in Haskell instead? Looks much more like the actual letter
lambda (which is what motivated its use in Haskell) and is two
keystrokes less to type (counting the shift for >).

Well, keystrokes are keyboard-dependent. At home, to get a \ I have to do an
Alt-Gr (Dutch keyboard:
http://www.microsoft.com/globaldev/keyboards/kbdne.htm\). So for me the gain in
only one keystroke, and Alt-Gr / on this keyboard is not always an easy task :wink:

Christophe Grandsire wrote:

Hey, what about ":(foo="bar"){puts foo}"? It's still not beautiful but it's
still less annoying, and in Ruby we are already used to see colons at the
beginning of a word. Of course, overloading ":" may not be considered a good
idea, but it shouldn't be a parsing problem as this one would always be
followed by a "(" (and that doesn't happen with symbols). And:

collection.each:(foo="bar"){puts foo}

isn't that bad :slight_smile: .

+1

Hi,

Why not \ as in Haskell instead? Looks much more like the actual letter
lambda (which is what motivated its use in Haskell) and is two
keystrokes less to type (counting the shift for >).

A backslash is the most unfortunate character, which is caught by yen
sign problem. In Japanese encoding, appearance of the character
varies font to font. On some font (e.g. on my Emacs) it is shown as a
backslash, on other font (e.g. on my Firefox), it is shown as a
Japanese currency sign, Yen (two dashes over captal Y). Indeed, a
backslash can reminds me lambda, but yen sign does not have any clue
for lambda. This must be a tiny problem for non Japanese.

              matz.

···

In message "Re: Default argument values for blocks" on Wed, 12 Oct 2005 20:46:53 +0900, Martin DeMello <martindemello@yahoo.com> writes:

Hi,

···

In message "Re: Default argument values for blocks" on Wed, 12 Oct 2005 20:42:06 +0900, Christophe Grandsire <christophe.grandsire@free.fr> writes:

Hey, what about ":(foo="bar"){puts foo}"? It's still not beautiful but it's
still less annoying, and in Ruby we are already used to see colons at the
beginning of a word. Of course, overloading ":" may not be considered a good
idea, but it shouldn't be a parsing problem as this one would always be
followed by a "(" (and that doesn't happen with symbols). And:

collection.each:(foo="bar"){puts foo}

isn't that bad :slight_smile: .

I have never thought of that. Hmm, let me think about it during the
conference trip. I'm leaving tomorrow morning.

              matz.

Christophe Grandsire wrote:

Selon Thomas <sanobast-2005a@yahoo.de>:

I was dreaming for a long time of a ruby dialect that has all these
fancy arrows haskell has. Everybody proposing arrows, please (try to)
read some haskell code.

I have and can only concur. The arrows make things pretty confusing in most
places.

But seriosly, I personally would prefer something in the line lambda(x,
y=1) {...} as it was proposed by other people too.

The problem is that "collection.each lambda(foo="bar") {puts foo}" has to be the
ugliest and most long-winded thing I've seen in a long time. It's OK for making
a Proc, but to use as a block it's just plain wrong.

So do not use it as a block. This syntax only solves the default args (etc.)
problem but does not in any way invalidate the block syntax (which, as Matz
has pointed out many times, is not going anywhere).

   collection.each {|foo| puts foo}

and

   block = lambda(foo = 'bar') { puts foo }

However, it's nearly impossible a problem to solve. Any solution will probably
look rather awful. We just need to find the least offensive one :slight_smile: . Unless one
finds a way to parse "{|foo="bar"| puts foo}" correctly. That'd be the best
solution.

The => in the hash syntax is IMHO already one kind of arrow too much.

Hasn't a change been accepted that allows one to use ":" as an alternative to
"=>" in hashes?

Hey, what about ":(foo="bar"){puts foo}"? It's still not beautiful but it's
still less annoying, and in Ruby we are already used to see colons at the
beginning of a word. Of course, overloading ":" may not be considered a good
idea, but it shouldn't be a parsing problem as this one would always be
followed by a "(" (and that doesn't happen with symbols). And:

collection.each:(foo="bar"){puts foo}

isn't that bad :slight_smile: .
--
Christophe Grandsire.

E

"Christophe Grandsire" <christophe.grandsire@free.fr> wrote in message

collection.each:(foo="bar"){puts foo}

+1

Hi --

However, it's nearly impossible a problem to solve. Any solution will probably
look rather awful. We just need to find the least offensive one :slight_smile: . Unless one
finds a way to parse "{|foo="bar"| puts foo}" correctly. That'd be the best
solution.

The => in the hash syntax is IMHO already one kind of arrow too much.

Hasn't a change been accepted that allows one to use ":" as an alternative to
"=>" in hashes?

Hey, what about ":(foo="bar"){puts foo}"? It's still not beautiful but it's
still less annoying, and in Ruby we are already used to see colons at the
beginning of a word. Of course, overloading ":" may not be considered a good
idea, but it shouldn't be a parsing problem as this one would always be
followed by a "(" (and that doesn't happen with symbols). And:

collection.each:(foo="bar"){puts foo}

isn't that bad :slight_smile: .

But it's so arbitrary. Surely there's no general principle of "being
used to" a given punctuation mark that makes it acceptable for
something like this.

I don't mean to jump on your idea specifically. The whole thread
seems to be about which arbitrary bit of punctuation might be least
ugly. I'm totally unconvinced that default values for block variables
are worth doing any of them.

David (in San Diego! :slight_smile:

···

On Wed, 12 Oct 2005, Christophe Grandsire wrote:

--
David A. Black
dblack@wobblini.net

Hi --

Hi,

>I definitely think a keyword would be better than -> .

Maybe. Some prefer verbosity to clarity. So what keyword you think
"the best"?

In this case I think verbosity *is* clarity :slight_smile: The -> thing really
has a "line-noise" quality that looks very out of place to me.

I could imagine using the lambda modification posted earlier:

   block = lambda(a,b=1) { ... }

for those few times when this would be necessary.

Another idea, since I think at least 99% of this is about
define_method, would be to make some kind of special case treatment
for define_method. But I can't think of a good way to do that.

David

···

On Wed, 12 Oct 2005, Yukihiro Matsumoto wrote:

In message "Re: Default argument values for blocks" > on Wed, 12 Oct 2005 10:13:31 +0900, "David A. Black" <dblack@wobblini.net> writes:

--
David A. Black
dblack@wobblini.net

>In addition to handling defaults in arguments, I think these
>issues need to be addressed in blocks/lambdas:
>
>- all variables in the defining scope of a block/lambda are
>prevented from being GCed by the block/lambda (because of
the
>#binding). This can easily result in a leaky program if not
>careful. I discussed several solutions to this in a
previous
>thread.

I think this issue should _not_ be solved by making new
lambda-like
object, but something like making eval a keyword, so that non
referenced local variable can be erased unless eval is called
within
the scope.

I agree. In addition to eval within the block (or even a
method that calls eval), you also have the issue that sometimes
people (including me) have wanted to call eval with
Proc#binding and want access to variables outside the block. I
think the majority of the time that is wanted is when the
binding is from the caller, so those variables won't want to be
GCed yet anyways. One of the solutions I gave was to have all
of the variables not directly referenced in the block be weak
references in Proc#binding, so that GC wouldn't be prevented.
GCing those unused variables would delete the weak references
in Proc#binding. I think this solution would maintain the best
compatibility/flexibility and still solve the problem.

>- a facility for making variables local (regardless of
whether
>a variable of the same name exists in the defining scope).
>This would also be good to have for a begin-end type block
(I'd
>like to have it for making inlined macros where I don't want
to
>worry about what variables are already used). I discussed
>several solutions for this in another thread.

In 1.9, you can declare block local variables explicitly, by
the
syntax:

  foo {|a; b, c| ...} # b and c are block local

so that

  b=1
  5.times{|i;b|
    b=5 # modifying in-block "b"
    p [i,b]
  }
  p b # outer "b" remain unchanged

EXCELLENT!

Would you consider having something like a begin/end block
having this ability too?

b=1
begin(b)
  b=5
  p b # => 5
end
p b # => 1

Or maybe if "eval" became a keyword like you mentioned above
and it could also take a block, you could do this instead:

b=1
eval {|;b|
  b=5
  p b # => 5
}
p b # => 1

I'm wanting to avoid the method calls to do this. If eval was
a keyword (or non-redefinable), the above could accomplish it
because it could be in-lined (like begin-end).

>Also, I saw some slides for ruby 2 back in 2003 showing that
>arguments will always be local to the block and other
variables
>in the block will be in the same scope as the defining
scope.
>I think always making arguments local is a good thing, but
>never localizing the other variables will be problematic if
>another local variable facility is not provided.

See above.

It doesn't look like arguments are local yet and all variables
inside the block that are not used yet outside are treated
local:

b=1
i=2
5.times { |i;b|
  b=5
  c=6
  p [i,b]
}
p [i,b] # => [4, 1] # i changed, b not
p c # undefined local variable or method

···

--- Yukihiro Matsumoto <matz@ruby-lang.org> wrote:

__________________________________________________
Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around

and how I whould have to write that c is global?

     foo { | a,b, global c | }
     foo { | a, b, <c> | }

Please don't misunderstand my suggestion.
I have no idea if it's possible or not,
but it looks pretty to me :slight_smile:

regards
Karl-Heinz

···

On 12.10.2005, at 03:17, Yukihiro Matsumoto wrote:

In 1.9, you can declare block local variables explicitly, by the
syntax:

  foo {|a; b, c| ...} # b and c are block local