Ruby-dev summary 26468-26661

Yukihiro Matsumoto wrote:

Hi,

>> I like it! Looks much more uniform and consistent with function
>> syntax than {|...| ...}
>
>I assume you mean method syntax. But why is that important? Until
>this new syntax was posted, I'd never heard anyone complain that they
>found it hard to recognize {|...| } as a code block. Now there seems
>to be a retroactive sentiment in the air that the block syntax is, and
>always has been, obscure or garbled.

lambda is an anonymous function, so that it requires full syntax of
function/method argument, including optional arguments, keyword
arguments, block arguments etc., not just parallel assignment as in
plain block parameters.

>If uniformity is important maybe def should be redesigned:
>
> def x |a,b,c=1|
> end

Stop joking. :wink:
Unlike others, I have never given uniformity a top priority.

If lambda === Method (minus context), I don't think he would be joking.

  def x |a,&b|
    b[a]
  end

  x(1) def |a|
    a+1
  end

But that does nothing to solve | ambiguity. So forget 'em and go back
to parens:

  def x(a,&b)
    b[a]
  end

  x(1) def n(a,b)
    a+1
  end

Such that #def returns a lambda/Method. The name of the lambda, n,
would be local to the block, and while usually extraneous, it can be
useful as a reference to the block itself.

  [:a,:b,:c].each def n(i)
    p n.count;
  end
  #=> 1 2 3

That still leaves { } notation. If { == def and } == end, as D. Black
"jests", at first it seems ambiguous. But actually I don't think it is.

  x(1) { n(a,b) a+1 }

is decernable from:

  x(1) { n(a,b) ; a+1 }

for example.

Yet I agree, over unifority can be hard on the eyes. Which is why #do
makes a good substitute for #def in block contexts.

T.

···

In message "Re: ruby-dev summary 26468-26661" > on Thu, 4 Aug 2005 22:38:06 +0900, "David A. Black" <dblack@wobblini.net> writes:

Hi,

···

In message "Re: ruby-dev summary 26468-26661" on Fri, 5 Aug 2005 10:09:55 +0900, Ezra Zygmuntowicz <ezra@yakima-herald.com> writes:

I think one of the first things that attracted me to ruby is the {|
x>...} syntax. So please leave my happy little blocks alone. Or at
least leave them as an option.

Don't worry. The block syntax will not be changed. Never.

              matz.

One could disambiguate this the same way it is done with methods:

{ () (a) }

like in

def anonymus() (a) end

or one could use a differnt pair of symbols, though I don't really like that.

{ <a, b=12> a+b }

Though it's easier to type on a german keyboard. (Thats also one of
the reasons I thoroughly dislike any use of the backslash \. Its just
really inkonvenient to me :wink:

regards,

Brian

···

On 04/08/05, David A. Black <dblack@wobblini.net> wrote:

Hi --

On Thu, 4 Aug 2005, [ISO-8859-1] Brian Schröder wrote:

> [snip]
>
> Then why don't we use two different delimiters, e.g. (,) which would
> even unify with method declaration.
>
> { (a, b=12) a+b }
> is quite clear, and counting nesting parenthesis has to be done in any
> parser so this
>
> { (a=12, (b,c) = [1,2]) a+b**c }
> is also possible

However, { (a) } would be ambiguous. (I don't particularly mind living
without default values in blocks, but I think () wouldn't fly.)

--
http://ruby.brian-schroeder.de/

Stringed instrument chords: http://chordlist.brian-schroeder.de/

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

Hi,

>I have no clue about the Bison grammar underlying Ruby, but can't you
>"simply" say that if the first token after { is a |, you need to parse
>until the next | to get the block parameters?

It would be great if it's possible. But unfortunately I don't have
enough skills to accomplish this using yacc/bison.

Neither do I...

>Of course, you couldn't write { |x = 5|7 | true } then... *I* can live
>with that.

You can always use {|x=(5|7)| true }.

Good point.

···

In message "Re: ruby-dev summary 26468-26661" > on Fri, 5 Aug 2005 01:14:46 +0900, Christian Neukirchen <chneukirchen@gmail.com> writes:

matz.

--
Christian Neukirchen <chneukirchen@gmail.com> http://chneukirchen.org

I suprised no one's picked up on this.

  [:a,:b,:c].each do n(i)
    p n.count;
  end
  #=> 1 2 3

Seems like a very insteresting and useful notion to locally name the
block. And open up other possibilites like:

  [:a,:b,:c].each do n(i)
    if n.first?
       # ...
    end
  end
  #=> 1 2 3

T.

I think this looks the best to me.
-Ezra Zygmuntowicz
WebMaster
Yakima Herald-Republic Newspaper
ezra@yakima-herald.com
509-577-7732

···

On Aug 4, 2005, at 9:23 AM, Yukihiro Matsumoto wrote:

Hi,

In message "Re: ruby-dev summary 26468-26661" > on Fri, 5 Aug 2005 01:14:46 +0900, Christian Neukirchen > <chneukirchen@gmail.com> writes:

>I have no clue about the Bison grammar underlying Ruby, but can't you
>"simply" say that if the first token after { is a |, you need to parse
>until the next | to get the block parameters?

It would be great if it's possible. But unfortunately I don't have
enough skills to accomplish this using yacc/bison.

>Of course, you couldn't write { |x = 5|7 | true } then... *I* can live
>with that.

You can always use {|x=(5|7)| true }.

                            matz.

Don't worry. The block syntax will not be changed. Never.

                                                        matz.

Ok, that's good to hear. So, if a new lambda syntax is created,
it doesn't necessarilly need to work for block? That is, it won't
be an alternate syntax for defining blocks?

Is there a reason that this notation wouldn't/couldn't work
for defining lambdas?

  f = () { puts 5 } # () always required for a lambda. space doesn't matter
  f = (a){ puts a }
  f = (x, y=5) { ... }

And, if used as a block...

  func(a,b) (x=2*2) { ... }

···

--
Jim Freeze

Yukihiro Matsumoto ha scritto:

Hi,

>I have no clue about the Bison grammar underlying Ruby, but can't you
>"simply" say that if the first token after { is a |, you need to parse
>until the next | to get the block parameters?

It would be great if it's possible. But unfortunately I don't have
enough skills to accomplish this using yacc/bison.

jus to notice: there is a language named SuperCollider[1] which by some strange case
- has a rubyish syntax
- seem to be able to handle all this things:

    { stuff() } #block with no arguments

    {|i| stuff_with(i))} #block with argument

    { |a="", b=""| stuff_with(defaulted_args) } # block with default args

- has a "|" pairwise operator

My only experience with yacc/bison has been a (mini)pascal->c compiler so I'm definitely not intelligent enough to check this out, but maybe some wiser people can take a look.

[1] see http://c2.com/cgi/wiki?SuperCollider
     and SuperCollider download | SourceForge.net

···

In message "Re: ruby-dev summary 26468-26661" > on Fri, 5 Aug 2005 01:14:46 +0900, Christian Neukirchen <chneukirchen@gmail.com> writes:

That makes it seem like a very small sacrifice then. It's an edge case and there's a work-around, they way I read that. Works for me.

I too hate the -> (...) idea. I left Perl for Ruby. :wink:

James Edward Gray II

···

On Aug 4, 2005, at 11:23 AM, Yukihiro Matsumoto wrote:

>Of course, you couldn't write { |x = 5|7 | true } then... *I* can live
>with that.

You can always use {|x=(5|7)| true }.

Hi --

Hi --

[snip]

Then why don't we use two different delimiters, e.g. (,) which would
even unify with method declaration.

{ (a, b=12) a+b }
is quite clear, and counting nesting parenthesis has to be done in any
parser so this

{ (a=12, (b,c) = [1,2]) a+b**c }
is also possible

However, { (a) } would be ambiguous. (I don't particularly mind living
without default values in blocks, but I think () wouldn't fly.)

One could disambiguate this the same way it is done with methods:

{ () (a) }

like in

def anonymus() (a) end

But then you'd have empty parens all over the place. I guess there
aren't that many paramless blocks, but there are some, like:

   Hash.new { () } # ugh

or one could use a differnt pair of symbols, though I don't really like that.

{ <a, b=12> a+b }

   irb(main):005:0> def x(a = 1 > 0); p a; end
   => nil
   irb(main):006:0> x
   true

:slight_smile:

David

···

On Thu, 4 Aug 2005, [ISO-8859-1] Brian Schröder wrote:

On 04/08/05, David A. Black <dblack@wobblini.net> wrote:

On Thu, 4 Aug 2005, [ISO-8859-1] Brian Schröder wrote:

--
David A. Black
dblack@wobblini.net

Hi --

One could disambiguate this the same way it is done with methods:

{ () (a) }

like in

def anonymus() (a) end

(I can't reply to myself because of some weird encoding-related
problem that makes me unable to see my own text.)

I might be wrong in what I said about empty parens, or at least the
example I gave. I guess you could still do:

   Hash.new { }

and just not have an arglist at all.

I'm still not seeing a bit need for a change in this direction.

David

···

On Thu, 4 Aug 2005, [ISO-8859-1] Brian Schröder wrote:

--
David A. Black
dblack@wobblini.net

> Hi --
>
>
> > [snip]
> >
> > Then why don't we use two different delimiters, e.g. (,)
which would
> > even unify with method declaration.
> >
> > { (a, b=12) a+b }
> > is quite clear, and counting nesting parenthesis has to
be done in any
> > parser so this
> >
> > { (a=12, (b,c) = [1,2]) a+b**c }
> > is also possible
>
> However, { (a) } would be ambiguous. (I don't particularly
mind living
> without default values in blocks, but I think () wouldn't
fly.)

One could disambiguate this the same way it is done with
methods:

{ () (a) }

like in

def anonymus() (a) end

That doesn't sound bad and is consistent with "def". But, it
does introduce a backwards incompatibility when you have "{ (a)
}" in existing code.

or one could use a differnt pair of symbols, though I don't
really like that.

{ <a, b=12> a+b }

Definitely wouldn't work. Take a look at this:

{ <a, b=12 > a+b>2 }

Do you interpret it that way or this way:

{ < a, b=12>a+b > 2 }

Here is my proposal:

{ args : code }

Even if when you make the args : optional to preserve
compatibility, I think this would be parsable if you treat the
arg list (possibly with default expressions) like a normal
statment except that the delimiter is ":" instead of ";". This
should work because an arg list is a syntactically valid
statement. i.e.

a=1
other=[3,4]
a,b=2,*other

When the lexer finds a ":" instead of a ";" or newline as the
statement delimiter of first statement, it would treat that as
the arg list.

I like this because it gives the minimal amount of punctuation
for the arg list - one character as a delimiter.

···

--- Brian Schröder <ruby.brian@gmail.com> wrote:

On 04/08/05, David A. Black <dblack@wobblini.net> wrote:
> On Thu, 4 Aug 2005, [ISO-8859-1] Brian Schröder wrote:

____________________________________________________
Start your day with Yahoo! - make it your home page
http://www.yahoo.com/r/hs

It was brought up today at lunch by Hal
that we could always use paren' to denote
default arguments. I think it is a rare enough
event, and the method has little impact on
the language, that it may be the best idea yet.
<disclaimer>I'm not sure if Hal or someone else
came up with the idea first</disclaimer>

  x(a,b) { |y, (z=2)| .... }
  x(a,b) { |y, (z=5|7)| ... }
  mylambda = lambda { |(a=1), (b=2) ... }
  x(a,b, &mylambda)

···

--
Jim Freeze

Hi,

···

In message "Re: ruby-dev summary 26468-26661" on Fri, 5 Aug 2005 10:06:05 +0900, "Trans" <transfire@gmail.com> writes:

I suprised no one's picked up on this.

[:a,:b,:c].each do n(i)
   p n.count;
end
#=> 1 2 3

The meaning of above code is not obvious for me at all, besides its
syntax conflicts existing ones.

              matz.

Trans wrote:

Seems like a very insteresting and useful notion to locally name the
block. And open up other possibilites like:

  [:a,:b,:c].each do n(i)
    if n.first?
       # ...
    end
  end
  #=> 1 2 3

I'd insert an as:

[:a, :b, :c].each as n(i) do
   if n.first? then
     # ...
   end
end

Still needs getting used to it, though.

Jim Freeze wrote:

>
> Don't worry. The block syntax will not be changed. Never.
>
> matz.

Ok, that's good to hear. So, if a new lambda syntax is created,
it doesn't necessarilly need to work for block? That is, it won't
be an alternate syntax for defining blocks?

Is there a reason that this notation wouldn't/couldn't work
for defining lambdas?

  f = () { puts 5 } # () always required for a lambda. space doesn't matter
  f = (a){ puts a }
  f = (x, y=5) { ... }

And, if used as a block...

  func(a,b) (x=2*2) { ... }

My concern with this is admittedly a matter of wishful thinking, but I
would nonetheless like to see ruby with currying one day like this:

  def f(x,y)
    x + y
  end

  g = f(1)

  g(2) #=> 3

which means:

  f(1)(2) #=> 3

Your proposed block notation would make this impossible.

T.

Now that I've read on, I understand that this is for lambdas only and it bothers me a *little* less. I still would prefer we translate -> to a keyword though, if possible.

James Edward Gray II

···

On Aug 5, 2005, at 3:59 PM, James Edward Gray II wrote:

I too hate the -> (...) idea. I left Perl for Ruby. :wink:

Hi --

>> Hi --
>>
>>
>>> [snip]
>>>
>>> Then why don't we use two different delimiters, e.g. (,) which would
>>> even unify with method declaration.
>>>
>>> { (a, b=12) a+b }
>>> is quite clear, and counting nesting parenthesis has to be done in any
>>> parser so this
>>>
>>> { (a=12, (b,c) = [1,2]) a+b**c }
>>> is also possible
>>
>> However, { (a) } would be ambiguous. (I don't particularly mind living
>> without default values in blocks, but I think () wouldn't fly.)
>
> One could disambiguate this the same way it is done with methods:
>
> { () (a) }
>
> like in
>
> def anonymus() (a) end

But then you'd have empty parens all over the place. I guess there
aren't that many paramless blocks, but there are some, like:

   Hash.new { () } # ugh

Why should you write it like that. If there is no starting ( there is
no argument list. So

Hash.new { }

would work in this case.

You'd only need an () if the expression starts with a (.

But maybe there are better options.

regards,

Brian

> or one could use a differnt pair of symbols, though I don't really like that.
>
> { <a, b=12> a+b }

   irb(main):005:0> def x(a = 1 > 0); p a; end
   => nil
   irb(main):006:0> x
   true

Ahh, I didn't think of that, and I'm shure theres also a big flaw in
my other thoughts.

regards,

Brian

···

On 04/08/05, David A. Black <dblack@wobblini.net> wrote:

On Thu, 4 Aug 2005, [ISO-8859-1] Brian Schröder wrote:
> On 04/08/05, David A. Black <dblack@wobblini.net> wrote:
>> On Thu, 4 Aug 2005, [ISO-8859-1] Brian Schröder wrote:

--
http://ruby.brian-schroeder.de/

Stringed instrument chords: http://chordlist.brian-schroeder.de/

Just for the protocol, I'm also very happy with the way blocks work
right now. Though I wondered a bit that block parameters are written
with pipes instead of parents when I first came to ruby.

regards,

Brian

···

On 04/08/05, David A. Black <dblack@wobblini.net> wrote:

[snip]

I'm still not seeing a bit need for a change in this direction.

--
http://ruby.brian-schroeder.de/

Stringed instrument chords: http://chordlist.brian-schroeder.de/

Hi --

···

On Fri, 5 Aug 2005, Jim Freeze wrote:

It was brought up today at lunch by Hal
that we could always use paren' to denote
default arguments. I think it is a rare enough
event, and the method has little impact on
the language, that it may be the best idea yet.
<disclaimer>I'm not sure if Hal or someone else
came up with the idea first</disclaimer>

x(a,b) { |y, (z=2)| .... }
x(a,b) { |y, (z=5|7)| ... }
mylambda = lambda { |(a=1), (b=2) ... }
x(a,b, &mylambda)

Just thinking out loud, so to speak (so to speak [so to speak...]):

x(a,b) {|y, z(=2)| ... }

Sort of: "z (which defaults to 2)"

David

--
David A. Black
dblack@wobblini.net