holes in the syntax

R

Roedy Green

// 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 );
}

// 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 );
}

// you have to write it out longhand

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


--
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
 
G

George Cherry

Roedy Green said:
// 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 );
}

// 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 );
}


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

George W. Cherry

// you have to write it out longhand

for ( int i=0; i<mystrings.length; i++ )
{
System.out.println ( mystrings );
}
--
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
 
C

Chris Smith

Roedy Green said:
// 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 : myInts) { ... }
for (String s, int : 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
 
R

Roedy Green

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.

--
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
 
R

Roedy Green

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.

--
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
 
L

Lasse Reichstein Nielsen

Roedy Green said:
// 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
 
R

Roedy Green

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.

--
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
 
T

Tim Tyler

Roedy Green said:
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.
 
D

Dale King

Roedy said:
// 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.
 
C

Chris Uppal

Dale said:
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
 
D

Dale King

Chris said:
Dale King wrote:




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).

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

Roedy Green

D

Dale King

Roedy said:
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.
 
R

Roedy Green

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.



--
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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,051
Latest member
CarleyMcCr

Latest Threads

Top