Syntax sugar idea for loops

I think Enumerable#each_with_index largely eliminates the need for such
syntactic sugar. Consider:

people.each_with_index do |person, i|
   puts "First person: #{person}" if i == 0
   row_class = i%2 == 0 ? "row1" : "row2"
   puts "<tr class=#{row_class}><td>#{person.name}</td>
   puts "Last person: #{person}" if i == people.length - 1
end

I suppose you could extend Fixnum within a loop to include extra methods
so that you could do something like this:

people.each_with_index do |person, i|
   puts "First person: #{person} if i.first?
   row_class = i.even? ? "row1" : "row2"
   puts "Last person: #{person} if i.last?
end

But that would mean making some serious modifications to Enumerable
(wouldn't it?). Not a bad idea, just not worth the added code
maintenance IMHO.

Regards,

Dan

···

-----Original Message-----
From: pmak@aaanime.net [mailto:pmak@aaanime.net]
Sent: Wednesday, March 30, 2005 11:30 AM
To: ruby-talk ML
Subject: Syntax sugar idea for loops

I was working with a proprietary programming language called
Traction <www.tractionsoftware.com>, and I noticed something
pretty cool they had in their loop constructs.

Consider the following Ruby code:

    every_other = true
    people.each do |person|
        every_other = !every_other
        row_class = every_other ? 'row1' : 'row2'
        puts "<tr class=#{row_class}><td>#{person.name}</td>
<td>#{person.email}</td></tr>"
    end

This code prints out an HTML table of peoples' names and
e-mail addresses. The <tr> tags alternate with having
class="row1" and class="row2", allowing every other row to be
colored differently.

Consider these two lines of the code, though:

    every_other = true
        every_other = !every_other

These lines could be replaced by syntax sugar. Traction has
the following "Special Loop Tags":

    <loop.first>: true if this is the first iteration of the loop
    <loop.inner> true if this is not the first or last
iteration of the loop
    <loop.odd> true if this is an odd iteration
    <loop.last>: true if this is the last iteration of the loop

(In the case of nested loops, they apply to the innermost
loop.) Maybe Ruby could use this sort of syntax sugar, too?
So in my example above, there would be a built-in variable
that replaces my "every_other" variable.

people.each_with_index do |person, i|
    puts "First person: #{person} if person == people.first
    row_class = i.even? ? "row1" : "row2"
    puts "Last person: #{person} if person == people.last
end

How about that?

···

On 30 Mar 2005, at 11:23, Berger, Daniel wrote:

From: pmak@aaanime.net [mailto:pmak@aaanime.net]

Consider the following Ruby code:

    every_other = true
    people.each do |person|
        every_other = !every_other
        row_class = every_other ? 'row1' : 'row2'
        puts "<tr class=#{row_class}><td>#{person.name}</td>
<td>#{person.email}</td></tr>"
    end

Consider these two lines of the code, though:

    every_other = true
        every_other = !every_other

These lines could be replaced by syntax sugar. Traction has
the following "Special Loop Tags":

    <loop.first>: true if this is the first iteration of the loop
    <loop.inner> true if this is not the first or last
iteration of the loop
    <loop.odd> true if this is an odd iteration
    <loop.last>: true if this is the last iteration of the loop

I think Enumerable#each_with_index largely eliminates the need for such
syntactic sugar. Consider:

people.each_with_index do |person, i|
   puts "First person: #{person}" if i == 0
   row_class = i%2 == 0 ? "row1" : "row2"
   puts "<tr class=#{row_class}><td>#{person.name}</td>
   puts "Last person: #{person}" if i == people.length - 1
end

I suppose you could extend Fixnum within a loop to include extra methods
so that you could do something like this:

--
Eric Hodel - drbrain@segment7.net - http://segment7.net
FEC2 57F1 D465 EB15 5D6E 7C11 332A 551C 796C 9F04

In data 3/30/2005, "Berger, Daniel" <Daniel.Berger@qwest.com> ha
scritto:

From: pmak@aaanime.net [mailto:pmak@aaanime.net]
Sent: Wednesday, March 30, 2005 11:30 AM
To: ruby-talk ML
Subject: Syntax sugar idea for loops

I was working with a proprietary programming language called
Traction <www.tractionsoftware.com>, and I noticed something
pretty cool they had in their loop constructs.

Consider the following Ruby code:

    every_other = true
    people.each do |person|
        every_other = !every_other
        row_class = every_other ? 'row1' : 'row2'
        puts "<tr class=#{row_class}><td>#{person.name}</td>
<td>#{person.email}</td></tr>"
    end

This code prints out an HTML table of peoples' names and
e-mail addresses. The <tr> tags alternate with having
class="row1" and class="row2", allowing every other row to be
colored differently.

Consider these two lines of the code, though:

    every_other = true
        every_other = !every_other

These lines could be replaced by syntax sugar. Traction has
the following "Special Loop Tags":

    <loop.first>: true if this is the first iteration of the loop
    <loop.inner> true if this is not the first or last
iteration of the loop
    <loop.odd> true if this is an odd iteration
    <loop.last>: true if this is the last iteration of the loop

(In the case of nested loops, they apply to the innermost
loop.) Maybe Ruby could use this sort of syntax sugar, too?
So in my example above, there would be a built-in variable
that replaces my "every_other" variable.

I think Enumerable#each_with_index largely eliminates the need for such
syntactic sugar. Consider:

people.each_with_index do |person, i|
  puts "First person: #{person}" if i == 0
  row_class = i%2 == 0 ? "row1" : "row2"
  puts "<tr class=#{row_class}><td>#{person.name}</td>
  puts "Last person: #{person}" if i == people.length - 1
end

I suppose you could extend Fixnum within a loop to include extra methods
so that you could do something like this:

people.each_with_index do |person, i|
  puts "First person: #{person} if i.first?
  row_class = i.even? ? "row1" : "row2"
  puts "Last person: #{person} if i.last?
end

But that would mean making some serious modifications to Enumerable
(wouldn't it?). Not a bad idea, just not worth the added code
maintenance IMHO.

Adding Enumerable#step (or maybe Array#step) might not
be a bad idea but I do not know how common that usage
might be.

Regards,

Dan

E

···

-----Original Message-----

"Berger, Daniel" <Daniel.Berger@qwest.com> schrieb im Newsbeitrag
news:8FE83020B9E1A248A182A9B0A7B76E7358B379@itomae2km07.AD.QINTRA.COM...

> From: pmak@aaanime.net [mailto:pmak@aaanime.net]
> Sent: Wednesday, March 30, 2005 11:30 AM
> To: ruby-talk ML
> Subject: Syntax sugar idea for loops
>
>
> I was working with a proprietary programming language called
> Traction <www.tractionsoftware.com>, and I noticed something
> pretty cool they had in their loop constructs.
>
> Consider the following Ruby code:
>
> every_other = true
> people.each do |person|
> every_other = !every_other
> row_class = every_other ? 'row1' : 'row2'
> puts "<tr class=#{row_class}><td>#{person.name}</td>
> <td>#{person.email}</td></tr>"
> end
>
> This code prints out an HTML table of peoples' names and
> e-mail addresses. The <tr> tags alternate with having
> class="row1" and class="row2", allowing every other row to be
> colored differently.
>
> Consider these two lines of the code, though:
>
> every_other = true
> every_other = !every_other
>
> These lines could be replaced by syntax sugar. Traction has
> the following "Special Loop Tags":
>
> <loop.first>: true if this is the first iteration of the loop
> <loop.inner> true if this is not the first or last
> iteration of the loop
> <loop.odd> true if this is an odd iteration
> <loop.last>: true if this is the last iteration of the loop
>
> (In the case of nested loops, they apply to the innermost
> loop.) Maybe Ruby could use this sort of syntax sugar, too?
> So in my example above, there would be a built-in variable
> that replaces my "every_other" variable.

I think Enumerable#each_with_index largely eliminates the need for such
syntactic sugar. Consider:

people.each_with_index do |person, i|
   puts "First person: #{person}" if i == 0
   row_class = i%2 == 0 ? "row1" : "row2"
   puts "<tr class=#{row_class}><td>#{person.name}</td>
   puts "Last person: #{person}" if i == people.length - 1
end

Yeah, "odd" and "even" are much too specific IMHO. Using the index is the
most general solution. That way you can do things like shown above plus:

people.each_with_index do |person, i|
   row_class = "row#{(i%2)+1}"
   puts "<tr class=#{row_class}><td>#{person.name}</td>
end

people.each_with_index do |person, i|
   row_class = case i % 3
     when 0; "rowx"
     when 1; "rowy"
     when 2; "rowz"
   end
   puts "<tr class=#{row_class}><td>#{person.name}</td>
end

ROW_CLASS = ["foo", "bar", "baz"]
....
people.each_with_index do |person, i|
   puts "<tr class=#{ROW_CLASS[i %
ROW_CLASS.size]}><td>#{person.name}</td>
end

The last one being the most efficient one I guess.

Kind regards

    robert

···

> -----Original Message-----

And you could of course do something like (hey is this a valid use for
@@vars or is there a better way? -- does Ruby have the C concept of a
local static variable?)

class Object
  @@nasty_bad_pseudo_global_hash = Hash.new(true)
  def alternate(*args)
    doit = @@nasty_bad_pseudo_global_hash[caller.first]
    @@nasty_bad_pseudo_global_hash[caller.first] = !doit
    yield(args) if doit
  end
end

(1..10).each do |i|
  alternate(i) { |x| puts x }
end

···

On Thu, 31 Mar 2005 04:37:42 +0900, Eric Hodel <drbrain@segment7.net> wrote:

On 30 Mar 2005, at 11:23, Berger, Daniel wrote:

>> From: pmak@aaanime.net [mailto:pmak@aaanime.net]
>>
>> Consider the following Ruby code:
>>
>> every_other = true
>> people.each do |person|
>> every_other = !every_other
>> row_class = every_other ? 'row1' : 'row2'
>> puts "<tr class=#{row_class}><td>#{person.name}</td>
>> <td>#{person.email}</td></tr>"
>> end
>>
>> Consider these two lines of the code, though:
>>
>> every_other = true
>> every_other = !every_other
>>
>> These lines could be replaced by syntax sugar. Traction has
>> the following "Special Loop Tags":
>>
>> <loop.first>: true if this is the first iteration of the loop
>> <loop.inner> true if this is not the first or last
>> iteration of the loop
>> <loop.odd> true if this is an odd iteration
>> <loop.last>: true if this is the last iteration of the loop
>
> I think Enumerable#each_with_index largely eliminates the need for such
> syntactic sugar. Consider:
>
> people.each_with_index do |person, i|
> puts "First person: #{person}" if i == 0
> row_class = i%2 == 0 ? "row1" : "row2"
> puts "<tr class=#{row_class}><td>#{person.name}</td>
> puts "Last person: #{person}" if i == people.length - 1
> end
>
> I suppose you could extend Fixnum within a loop to include extra
> methods
> so that you could do something like this:

people.each_with_index do |person, i|
    puts "First person: #{person} if person == people.first
    row_class = i.even? ? "row1" : "row2"
    puts "Last person: #{person} if person == people.last
end

How about that?

--
Eric Hodel - drbrain@segment7.net - http://segment7.net
FEC2 57F1 D465 EB15 5D6E 7C11 332A 551C 796C 9F04

True, odd and even are rather specific but is that such a bad thing,
really? If the odd-even semantics are a common need, why not add
support for it in the language? I mean, why else would Ruby have
Array.each etc. instead of for (i=0; i < x; i++) which is clearly more
powerful in terms of all the things you can do with it?

-Lasse-

···

On Thu, 31 Mar 2005 16:34:44 +0900, Robert Klemme <bob.news@gmx.net> wrote:

Yeah, "odd" and "even" are much too specific IMHO. Using the index is the
most general solution.

Nope. Only works if first and last items are unique.

  people = %w[George John Thomas George Bill George]

···

On Thu, 31 Mar 2005, Eric Hodel wrote:

people.each_with_index do |person, i|
    puts "First person: #{person} if person == people.first
    row_class = i.even? ? "row1" : "row2"
    puts "Last person: #{person} if person == people.last
end

How about that?

--
Relm

Internal and external iterators are equivalent given the existance
of continuations. It may be interesting to explore the possibilities
of representing flow control as an object. To start the debate...

for () {
case for.special # Cant think of a better name right now :frowning:
when for.first
  ..
when for.last
  ..
  for.restart if error
else
   ...
   for.next
   puts "We get here, unlike the real next keyword"
end
}

Please note, I am -not- suggesting these for Ruby. I dont even like the
odd/even idea personally. Im brainstorming to see what is possible and
would like to see what others can come up with as well.

···

On Thu, 31 Mar 2005 16:54:25 +0900, Lasse Koskela <lasse.koskela@gmail.com> wrote:

On Thu, 31 Mar 2005 16:34:44 +0900, Robert Klemme <bob.news@gmx.net> wrote:
> Yeah, "odd" and "even" are much too specific IMHO. Using the index is the
> most general solution.

True, odd and even are rather specific but is that such a bad thing,
really? If the odd-even semantics are a common need, why not add
support for it in the language? I mean, why else would Ruby have
Array.each etc. instead of for (i=0; i < x; i++) which is clearly more
powerful in terms of all the things you can do with it?

--
spooq

"Lasse Koskela" <lasse.koskela@gmail.com> schrieb im Newsbeitrag
news:3975e2d105033023544bb28311@mail.gmail.com...

> Yeah, "odd" and "even" are much too specific IMHO. Using the index is

the

> most general solution.

True, odd and even are rather specific but is that such a bad thing,
really? If the odd-even semantics are a common need, why not add
support for it in the language?

Then I'd still prefer

class Fixnum
  def odd?() self % 2 == 1 end
  def even?() self % 2 == 0 end
end

over an iteration specific thing.

I mean, why else would Ruby have
Array.each etc. instead of for (i=0; i < x; i++) which is clearly more
powerful in terms of all the things you can do with it?

Yeah, true. But it's always balancing convenience vs. bloat: if you stick
too much convenience functionality into a language / library then it'll be
too bloated and there will be too many ways to do a single thing. I think
that odd and even for iterations is not general enough and this not used
too much. I may be wrong here though.

Kind regards

    robert

···

On Thu, 31 Mar 2005 16:34:44 +0900, Robert Klemme <bob.news@gmx.net> wrote:

Luke Graham wrote:

Yeah, "odd" and "even" are much too specific IMHO. Using the index is the
most general solution.

True, odd and even are rather specific but is that such a bad thing,
really? If the odd-even semantics are a common need, why not add
support for it in the language? I mean, why else would Ruby have
Array.each etc. instead of for (i=0; i < x; i++) which is clearly more
powerful in terms of all the things you can do with it?

Internal and external iterators are equivalent given the existance
of continuations. It may be interesting to explore the possibilities
of representing flow control as an object. To start the debate...

for () {
case for.special # Cant think of a better name right now :frowning:
when for.first
  ..
when for.last
  ..
  for.restart if error
else
   ...
   for.next
   puts "We get here, unlike the real next keyword"
end
}

Please note, I am -not- suggesting these for Ruby. I dont even like the
odd/even idea personally. Im brainstorming to see what is possible and
would like to see what others can come up with as well.

This seems to me like something of what generators are in python, which is just a function that yields instead of returns. I'm not an expert, but they are really powerful and useful for defining custom iterators and the like.

This generator is basically an open ended list of integers that vary by 2 ( I would like to say that I use ruby and not python, and I'm not really fluent in python. So if this is wrong, will someone correct me please? )

<snip python code>

def every_other(num):
  while 1:
    num += 2
    yield num

odds = every_other(3)

odds.next() #=> 5
odds.next() #=> 7
odds.next() #=> 9
odds.next() #=> 11
odds.next() #=> 13
odds.next() #=> 15

... and so on.

I really like the idea of generators, and think that something like them explicity might bee useful in ruby. I know it would be not-quite-trivial to write a generator class (and there might be one already,) but they are a nifty language feature that python has going for it.

···

On Thu, 31 Mar 2005 16:54:25 +0900, Lasse Koskela > <lasse.koskela@gmail.com> wrote:

On Thu, 31 Mar 2005 16:34:44 +0900, Robert Klemme <bob.news@gmx.net> wrote:

Luke Graham wrote:

Internal and external iterators are equivalent given the existance
of continuations. It may be interesting to explore the possibilities
of representing flow control as an object. To start the debate...

I wanted to jump into this thread, though my reply doesn't follow
Luke's directly.

I started a thread like this in summer of '02 -- I was looking at
some kind of iterator that would allow "normal" (internal) iteration
as well as external, and would have features like detecting even/odd,
first, and last.

An additional problem I wanted to solve was that an element in a
collection can't be replaced in that collection unless you know
the index, and thus you use each_with_index. And actually, I was
just thinking of arrays at that point, as hashes are a different
animal.

The thread is at:
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/46337
or search for "super-iterator"...

I've been thinking more about it, and I'd do it a little differently
now... maybe I'll get a chance to implement that soon.

Cheers,
Hal

"Jon Raphaelson" <jonraphaelson@gmail.com> schrieb im Newsbeitrag
news:424BBE2E.5000406@gmail.com...

Luke Graham wrote:
>
>>
>>>Yeah, "odd" and "even" are much too specific IMHO. Using the index

is the

>>>most general solution.
>>
>>True, odd and even are rather specific but is that such a bad thing,
>>really? If the odd-even semantics are a common need, why not add
>>support for it in the language? I mean, why else would Ruby have
>>Array.each etc. instead of for (i=0; i < x; i++) which is clearly more
>>powerful in terms of all the things you can do with it?
>
>
> Internal and external iterators are equivalent given the existance
> of continuations. It may be interesting to explore the possibilities
> of representing flow control as an object. To start the debate...
>
> for () {
> case for.special # Cant think of a better name right now :frowning:
> when for.first
> ..
> when for.last
> ..
> for.restart if error
> else
> ...
> for.next
> puts "We get here, unlike the real next keyword"
> end
> }
>
> Please note, I am -not- suggesting these for Ruby. I dont even like

the

> odd/even idea personally. Im brainstorming to see what is possible and
> would like to see what others can come up with as well.
>

This seems to me like something of what generators are in python, which
is just a function that yields instead of returns. I'm not an expert,
but they are really powerful and useful for defining custom iterators
and the like.

This generator is basically an open ended list of integers that vary by
2 ( I would like to say that I use ruby and not python, and I'm not
really fluent in python. So if this is wrong, will someone correct me
please? )

<snip python code>

def every_other(num):
while 1:
num += 2
yield num

odds = every_other(3)

odds.next() #=> 5
odds.next() #=> 7
odds.next() #=> 9
odds.next() #=> 11
odds.next() #=> 13
odds.next() #=> 15

.. and so on.

I really like the idea of generators, and think that something like them
explicity might bee useful in ruby. I know it would be not-quite-trivial
to write a generator class (and there might be one already,) but they
are a nifty language feature that python has going for it.

It's been done already for arbitrary Enumerations:
http://www.ruby-doc.org/core/classes/Generator.html

It's trivial for odd or even numbers.

    robert

···

> On Thu, 31 Mar 2005 16:54:25 +0900, Lasse Koskela > > <lasse.koskela@gmail.com> wrote:
>>On Thu, 31 Mar 2005 16:34:44 +0900, Robert Klemme <bob.news@gmx.net> wrote: