Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

holes in the syntax

4 views
Skip to first unread message

Roedy Green

unread,
Jul 5, 2005, 11:27:27 PM7/5/05
to
// for each loop gotchas

// In Java 1,5+ you can write a for each loop
// over an array or iterable collection

String[] mystrings = new String[ 50 ];

for ( String s : mystrings )
{
System.out.println ( s );
}

// This is shorthand for:

for ( int i=0; i<mystrings.length; i++ )
{
System.out.println ( mystrings[i] );
}

// However the following code won't compile
// because String is not iterable

String mystring = "happy birthday";

for ( char c : mystring )
{
System.out.println ( c );
}

// you have to write it out longhand

for ( int i=0; i<mystring.length; i++ )
{
System.out.println ( mystring.charAt( i ) );
}

// Further the following code will not compile

string[] mystrings = new String[ 50 ];

for ( int i : mystrings)
{
System.out.println ( mystrings[i] );
}

// you have to write it out longhand

for ( int i=0; i<mystrings.length; i++ )
{
System.out.println ( mystrings[i] );
}


--
Bush crime family lost/embezzled $3 trillion from Pentagon.
Complicit Bush-friendly media keeps mum. Rumsfeld confesses on video.
http://www.infowars.com/articles/us/mckinney_grills_rumsfeld.htm

Canadian Mind Products, Roedy Green.
See http://mindprod.com/iraq.html photos of Bush's war crimes

George Cherry

unread,
Jul 5, 2005, 11:55:46 PM7/5/05
to

"Roedy Green" <loo...@mindprod.com.invalid> wrote in message
news:smimc11n5jbichbjb...@4ax.com...

> // for each loop gotchas
>
> // In Java 1,5+ you can write a for each loop
> // over an array or iterable collection
>
> String[] mystrings = new String[ 50 ];
>
> for ( String s : mystrings )
> {
> System.out.println ( s );
> }
>
> // This is shorthand for:
>
> for ( int i=0; i<mystrings.length; i++ )
> {
> System.out.println ( mystrings[i] );
> }
>
> // However the following code won't compile
> // because String is not iterable
>
> String mystring = "happy birthday";
>
> for ( char c : mystring )
> {
> System.out.println ( c );
> }

If you're hellbent on using the new foreach statement, you
could write the following. (BTW, I've hidden the '{'s at the
ends of lines; I hope you can find them.) : o )

public class TestForLoop {
public static void main(String[] args) {
String mystring = "Happy Birthday";
char[] a = mystring.toCharArray();
for (char ch : a) {
System.out.println(ch);
}
}
}


> // you have to write it out longhand
>
> for ( int i=0; i<mystring.length; i++ )
> {
> System.out.println ( mystring.charAt( i ) );
> }
>
> // Further the following code will not compile
>
> string[] mystrings = new String[ 50 ];
>
> for ( int i : mystrings)
> {
> System.out.println ( mystrings[i] );
> }

OR, you could write it as you wrote your first code snippet.
Why didn't you like it?

George W. Cherry

Chris Smith

unread,
Jul 6, 2005, 12:09:22 AM7/6/05
to
Roedy Green <loo...@mindprod.com.invalid> wrote:
> // However the following code won't compile
> // because String is not iterable
>
> String mystring = "happy birthday";
>
> for ( char c : mystring )

I don't see a lot of use for this. Maybe it's just me.

> // Further the following code will not compile
>
> string[] mystrings = new String[ 50 ];
>
> for ( int i : mystrings)

I DO see a lot of use for this, and it's something that I have found
myself wishing for very often. However, the syntax needs to be changed.
For example, if we accept your syntax then the following becomes
ambiguous:

int[] myInts = new int[] { ... };
for (int i : myInts) { ... }

Is i the index, or the value? Under your syntax, there's no way to
differentiate between the two. Perhaps we'd need something else, like
(just off-hand):

for (int [i] : myInts) { ... }
for (String s, int [i] : args) { ... }
for (String s, Iterator [iter] : myList) { ... }

I wouldn't particularly care whether it's possible to get the Iterator
for an array, or the int index for an Iterable, but it would be trivial
to provide those options anyway.

I've also very often wished for the following while converting older for
loops to the new syntax:

String[] elements;
String val;

for (val : elements)
{
if (isAcceptable(val)) break;
}

// do something with val

but for some reason, the new syntax requires you to declare the loop
variable inline within the for clause. I can't see any good reason for
that requirement.

Together, all of these improvements would basically eliminate situations
where you have to regress to the old for loop syntax even for simple
iterations over collections or arrays.

So basically, I agree!

--
www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation

Roedy Green

unread,
Jul 6, 2005, 2:29:47 AM7/6/05
to
On Tue, 5 Jul 2005 22:09:22 -0600, Chris Smith <cds...@twu.net> wrote
or quoted :

>I don't see a lot of use for this. Maybe it's just me.

It is not a big deal to write that long hand, but I have written
dozens of programs that read an entire file into memory then process
it char by char.

Roedy Green

unread,
Jul 6, 2005, 2:31:00 AM7/6/05
to
On Wed, 06 Jul 2005 06:29:47 GMT, Roedy Green
<loo...@mindprod.com.invalid> wrote or quoted :

>>I don't see a lot of use for this. Maybe it's just me.
>
>It is not a big deal to write that long hand, but I have written
>dozens of programs that read an entire file into memory then process
>it char by char.

I would still use the old from since you want the offset available
inside the loop, not just the char most of time even if just to give a
hint of where a problem occurred.

Lasse Reichstein Nielsen

unread,
Jul 6, 2005, 8:39:08 AM7/6/05
to
Roedy Green <loo...@mindprod.com.invalid> writes:

> // for each loop gotchas

> for ( String s : mystrings )

...


> // This is shorthand for:
>
> for ( int i=0; i<mystrings.length; i++ )

> // However the following code won't compile


> // because String is not iterable
>
> String mystring = "happy birthday";
>
> for ( char c : mystring )

Ofcourse, you could make something iterable, like:
---
class StringCharIterable implements Iterable<Character> {
public StringCharIterable(String string) { ... }
public Iterator<Character> iterator() { return someIterator... }
}
---
But that's going through hoops to make it simple ... or something.


What I think you miss (as I do) is the concept of being indexable.
That's what arrays are, and a lot of other things too. So if there
were an interface:
---
package java.lang;
interface Indexable<T> {
int length(); // or getLength() or size() or ...
T get(int index);
}
---
then the "foreach in array" loop could be generalized to "foreach
in Indexable".

That would also be a great time to generalize square-bracket notation
so that
Indexable<T> foo;
...
T thingie = foo[4];
would be allowed. With an WritableIndexable you could even generalize
foo[4] = someT;

But that's an old dream ... having operators correspond to interfaces,
so they can be used with different classes, not just the build in ones.

/L
--
Lasse Reichstein Nielsen - l...@hotpop.com
DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleDOM.html>
'Faith without judgement merely degrades the spirit divine.'

Roedy Green

unread,
Jul 6, 2005, 2:17:22 PM7/6/05
to
On Wed, 06 Jul 2005 14:39:08 +0200, Lasse Reichstein Nielsen
<l...@hotpop.com> wrote or quoted :

>That would also be a great time to generalize square-bracket notation
>so that
> Indexable<T> foo;

I proposed that too in my ideas for a future Java I wrote some years
ago : http://mindprod.com/jgloss/bali.html


We invent a syntax for a new specific purpose [] without thinking what
it means in general, and it takes decades to logically and
consistently extend it.

for each was a big leap. The next will be using [] for all indexable
things. The next after that will be considering things other that
ints as indexes-keys.

Tim Tyler

unread,
Jul 9, 2005, 9:48:54 AM7/9/05
to
Roedy Green <loo...@mindprod.com.invalid> wrote or quoted:

> for each was a big leap. The next will be using [] for all indexable


> things. The next after that will be considering things other that
> ints as indexes-keys.

Of course, languages such as Python, PHP and Ruby have been doing all
these things for ages.
--
__________
|im |yler http://timtyler.org/ t...@tt1lock.org Remove lock to reply.

Dale King

unread,
Jul 15, 2005, 8:04:15 PM7/15/05
to
Roedy Green wrote:
>
> // However the following code won't compile
> // because String is not iterable
>
> String mystring = "happy birthday";
>
> for ( char c : mystring )
> {
> System.out.println ( c );
> }
>
> // you have to write it out longhand
>
> for ( int i=0; i<mystring.length; i++ )
> {
> System.out.println ( mystring.charAt( i ) );
> }

I agree. I suggest you submit an RFE asking for the foreach syntax to
also work with CharSequence which is the interface implemented by
String, CharBuffer, StringBuffer, and StringBuilder.

--
Dale King

Chris Uppal

unread,
Jul 16, 2005, 3:12:38 AM7/16/05
to
Dale King wrote:

> I agree. I suggest you submit an RFE asking for the foreach syntax to
> also work with CharSequence which is the interface implemented by
> String, CharBuffer, StringBuffer, and StringBuilder.

I'd hope that Sun would not be keen to encourage the idea that the 'char'
elements of a CharSequence have any particular meaning. What's so special
about UTF16 code points that you want to iterate over them ? I'd rather see a
way of iterating over the Unicode /characters/ in the sequence (currently there
does not appear to be any simple way of doing so that is not O(n^2) -- if I've
missed something I'd be pleased to hear it).

It might be worth adding that Unicode does not really "want" to work with
individual characters anyway (not even Unicode characters), but would "rather"
work with meaningful subsequences (that often would be one character long --
but not always).

-- chris


Dale King

unread,
Jul 16, 2005, 12:44:33 PM7/16/05
to

That is a good point. Iterating over code points is a better abstraction.

--
Dale King

Roedy Green

unread,
Jul 16, 2005, 4:50:48 PM7/16/05
to
On Sat, 16 Jul 2005 16:44:33 GMT, Dale King
<Dale...@insightbb.nospam.com> wrote or quoted :

>That is a good point. Iterating over code points is a better abstraction.

Could you give an example of where the two would differ and what your
proposed iteration would look like?

Dale King

unread,
Jul 17, 2005, 10:26:44 PM7/17/05
to
Roedy Green wrote:
> On Sat, 16 Jul 2005 16:44:33 GMT, Dale King
> <Dale...@insightbb.nospam.com> wrote or quoted :
>
>
>>That is a good point. Iterating over code points is a better abstraction.
>
> Could you give an example of where the two would differ and what your
> proposed iteration would look like?

Basically it would iterate and return code points as in int values
instead of 16-bit chars.

This basically reflects the fact that Unicode is now bigger than 16 bits
now. It takes two surrogate java char values to represent some symbols.
So if the string contained two surrogate char values that encoded a
character outside of the basic multilingual plane (for example an old
Persian character, see
http://www.unicode.org/charts/PDF/Unicode-4.1/U41-103A0.pdf) then this
would return that as one 32-bit value instead of the two surrogates.

--
Dale King

Roedy Green

unread,
Jul 18, 2005, 2:16:07 AM7/18/05
to
On Mon, 18 Jul 2005 02:26:44 GMT, Dale King
<Dale...@insightbb.nospam.com> wrote or quoted :

>


>Basically it would iterate and return code points as in int values
>instead of 16-bit chars.

If you wrote:

for ( char c : someString )

or

for ( int codepoint : someString )

you should be able to do it either way.

0 new messages