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

Generics - Is this possible?

2 views
Skip to first unread message

lstephen

unread,
Apr 15, 2008, 3:34:07 AM4/15/08
to
Hi,

I'm looking at the signature for something like a 'map' function.

For List it may be something like:

List<B> map(List<A> a, UnaryFunction<A, B> f)

But, I want I'd rather it not be List specific, so I was after
something like:

T<B> map(T<A> a UnaryFunction<A, B> f)

But, the compiler doesn't like this ;)

Any ideas on how or whether this is possible?

Thanks,
Levi

Lew

unread,
Apr 15, 2008, 9:49:48 AM4/15/08
to
lstephen wrote:
> Hi,
>
> I'm looking at the signature for something like a 'map' function.

'map' is a somewhat unfortunate variable name, since you aren't actually
associating it with the wildly popular 'Map' type.

> For List it may be something like:
>
> List<B> map(List<A> a, UnaryFunction<A, B> f)
>
> But, I want I'd rather it not be List specific, so I was after
> something like:
>
> T<B> map(T<A> a UnaryFunction<A, B> f)
>
> But, the compiler doesn't like this ;)
>
> Any ideas on how or whether this is possible?

What you want to accomplish is possible, what you're trying to say isn't.
You're trying to indicate a type parameter that takes a type parameter; that
doesn't exist. Type parameters exist to restrict the range of acceptable
types; what you wrote, 'T<A>', is equivalent to merely 'T'.

What is the restriction that you actually want to place on T? Do you want it
to be a Collection?

public static <A, B>
Collection <B> xform( Collection <A> a, UnaryFunction <A, B> f )

(untried, untested, uncompiled, one of several solutions that differ subtly in
semantics)

If you have a class called 'UnaryFunction', shouldn't it overload its "unary
function" method with one that takes a Collection? Having a "friend" method
like that shown breaks encapsulation.

--
Lew

Larry A Barowski

unread,
Apr 15, 2008, 10:20:11 AM4/15/08
to

"lstephen" <levi.s...@gmail.com> wrote in message
news:888f9f6a-2fcd-4a74...@b5g2000pri.googlegroups.com...

If that were possible, java.util.Collections would not
need the methods synchronizedList, synchronizedSet,
and synchronizedSortedSet. It would only need
synchronizedCollection.


Andreas Leitgeb

unread,
Apr 15, 2008, 11:33:46 AM4/15/08
to
Lew <l...@lewscanon.com> wrote:

> lstephen wrote:
>> For List it may be something like:
>> List<B> map(List<A> a, UnaryFunction<A, B> f)
>> But, I want I'd rather it not be List specific, so I was after
>> something like:
>> T<B> map(T<A> a, UnaryFunction<A, B> f)

If you won't specify anything about T itself, you
wouldn't be able to do anything at all with it.
Inside your "map" method, T would be like Object,
and that has no method to retrieve any "A" from it :-)

> public static <A, B>
> Collection <B> xform( Collection <A> a, UnaryFunction <A, B> f )

> (untried, untested, uncompiled, one of several solutions [...])

Another problem is, that xform has the "burden" of picking some
implementation of a Collection, an instance of which it then
returns, filled with all the "B"-objects.

> If you have a class called 'UnaryFunction', shouldn't it overload its "unary
> function" method with one that takes a Collection? Having a "friend" method
> like that shown breaks encapsulation.

That would just shift the problems from xform to UnaryFunction's
overloaded(or just additional) method. If "UnaryFunction" was
an interface, it would mean that any implementation would also
need to care for an implementation of the Collection-handling
method.
Imho "map" or "xform" are rather the type of methods that
would belong into a "Collections"-like toolkit class.

Jan Thomä

unread,
Apr 15, 2008, 12:30:00 PM4/15/08
to
On Tue, 15 Apr 2008 10:20:11 -0400 Larry A Barowski wrote:
> If that were possible, java.util.Collections would not
> need the methods synchronizedList, synchronizedSet,
> and synchronizedSortedSet. It would only need
> synchronizedCollection.

On a side note, something like this is possible in C#:


// function that creates a T
public T create<T>() {
return new T();
}

and you can call this like: Foo foo = create<Foo>(); Doesn't work for java
though, but nicely shows the different approach in C#...

lsch...@d.umn.edu

unread,
Apr 15, 2008, 12:53:08 PM4/15/08
to

I've implemented a functional library that addresses this issue. I
just use the Iterable<T> type unless the operation specifically
depends on list ordering. Here's a skeleton of my class declarations
adapted to your notation. Note, my implementation uses lazy
evaluation so you can do things like sum up an infinite list.

For example, I can create a Range class that takes a starting and
finishing value and implements Iterable<Integer>. I can write code
like this:

Range r = new Range(0, Integer.MAX_VALUE);
UnaryFunction sqr = new Square();

Iterable<Integer> squares = map( sqr, r );

for ( Integer x : squares )
{
// do something
if ( x > 100 )
break;
}


Here is the code outline:

public class UnaryFunction<R, T> {
public R eval( T arg ) { ... }
}

public static <R, T> Iterable<R> map( final UnaryFunction<R, T> f,
final Iterable<? extends T> list )
{
return new Iterable<R>() {
public Iterator<R> iterator() {
return map_iterator( f, list.iterator() );
}
}
}

private static <R, T> Iterator<R> map_iterator( final UnaryFunction<R,
T> f, final Iterator<? extends T> iterator )
{
return new Iterator<R>()
{
public boolean hasNext() {
return list.hasNext();
}
public R next() {
return f.eval( list.next() );
}
public void remove() {
throw new UnsupportedOperationException();
}
};
}

Andreas Leitgeb

unread,
Apr 15, 2008, 4:20:22 PM4/15/08
to
lsch...@d.umn.edu <lsch...@d.umn.edu> wrote:
> public static <R, T> Iterable<R> map(
> final UnaryFunction<R, T> f,
> final Iterable<? extends T> list )

I'm just curious, why you chose to return an
Iterable, rather than an Iterator.

I haven't found any standard class that would
take an Iterable as argument, so the only thing
to do with the returnvalue is to obtain an
Iterator... did I miss something?

Even if you obtain an Iterator more than once,
each such Iterator will just recalculate the
same values.

Patricia Shanahan

unread,
Apr 15, 2008, 4:32:05 PM4/15/08
to
Andreas Leitgeb wrote:
...

> I haven't found any standard class that would
> take an Iterable as argument, so the only thing
> to do with the returnvalue is to obtain an
> Iterator... did I miss something?
...

There is one thing you can do with an Iterable but not an Iterator - use
it in an enhanced for-loop.

Patricia

Roedy Green

unread,
Apr 15, 2008, 4:34:01 PM4/15/08
to
On Tue, 15 Apr 2008 00:34:07 -0700 (PDT), lstephen
<levi.s...@gmail.com> wrote, quoted or indirectly quoted someone
who said :

>But, I want I'd rather it not be List specific, so I was after
>something like:

What methods are you planning to use inside your map method? If it is
to be used on List, it must either be the List, Collection or Iterable
methods. So you must pass something of type of one of those three.

Java is a strongly typed language!
--

Roedy Green Canadian Mind Products
The Java Glossary
http://mindprod.com

Peter Duniho

unread,
Apr 15, 2008, 4:34:42 PM4/15/08
to
On Tue, 15 Apr 2008 13:20:22 -0700, Andreas Leitgeb
<a...@gamma.logic.tuwien.ac.at> wrote:

> lsch...@d.umn.edu <lsch...@d.umn.edu> wrote:
>> public static <R, T> Iterable<R> map(
>> final UnaryFunction<R, T> f,
>> final Iterable<? extends T> list )
>
> I'm just curious, why you chose to return an
> Iterable, rather than an Iterator.

I can't speak for the previous poster. But a class that implements
Iterable can be used in a for() statement, which is often a very nice
convenience. His post even includes a specific example of that usage:

for (Integer x : map(sqr, r))
{
// ...
}

Where the generic "map()" method returns an Iterable<R> (where R is
Integer in this example).

Pete

Andreas Leitgeb

unread,
Apr 15, 2008, 4:52:34 PM4/15/08
to
Patricia Shanahan <pa...@acm.org> wrote:
> Andreas Leitgeb wrote:
>> ..., so the only thing

>> to do with the returnvalue is to obtain an
>> Iterator... did I miss something?
> There is one thing you can do with an Iterable but not an Iterator - use
> it in an enhanced for-loop.

Heck, I really missed *something* :-}

Thanks also to Peter Duniho.

Patricia Shanahan

unread,
Apr 15, 2008, 6:19:17 PM4/15/08
to

Incidentally, does anyone understand *why* it has to be an Iterable, not
an Iterator? Of course, an Iterator based for loop would only process
the elements from the Iterator's current position on.

Patricia

Peter Duniho

unread,
Apr 15, 2008, 6:36:21 PM4/15/08
to
On Tue, 15 Apr 2008 15:19:17 -0700, Patricia Shanahan <pa...@acm.org> wrote:

> Incidentally, does anyone understand *why* it has to be an Iterable, not
> an Iterator? Of course, an Iterator based for loop would only process
> the elements from the Iterator's current position on.

Only the language designers could tell you the actual reason why. But I
would agree with anyone who felt it wise to not allow user code access to
the actual iterator being used for the loop. The potential for adding
bugs seems to me to outweigh any potential convenience. It keeps the
semantics of the for(:) syntax nice, simple, and easy-to-predict.

Pete

lstephen

unread,
Apr 15, 2008, 7:19:55 PM4/15/08
to
On Apr 16, 5:34 am, Roedy Green <see_webs...@mindprod.com.invalid>
wrote:

> On Tue, 15 Apr 2008 00:34:07 -0700 (PDT), lstephen
> <levi.step...@gmail.com> wrote, quoted or indirectly quoted someone

> who said :
>
> >But, I want I'd rather it not be List specific, so I was after
> >something like:
>
> What methods are you planning to use inside your map method? If it is
> to be used on List, it must either be the List, Collection or Iterable
> methods. So you must pass something of type of one of those three.

Sorry, I wasn't clear that map would have more than one
implementation. I'm enjoy playing around with translating concepts
from one language to others. In this case it's the Functor type class
from Haskell. So map would be an abstract method of a Functor class.
Then I could create ListFunctor, SetFunctor, MapFuctor etc. Then to
take more from Haskell MaybeFunctor, EitherFunctor etc.
So there is no practical problem to solve, just experimenting.

>
> Java is a strongly typed language!

Yep. I'm trying to express that if you pass in a List<A> you would get
back a List<B>, pass in Set<A> you get back Set<B>. i.e., the type of
collection you pass in, is what you get back.


> --
>
> Roedy Green Canadian Mind Products
> The Java Glossaryhttp://mindprod.com

Thanks,
Levi

lstephen

unread,
Apr 15, 2008, 7:23:08 PM4/15/08
to
On Apr 16, 1:53 am, lscha...@d.umn.edu wrote:
>
>
> I've implemented a functional library that addresses this issue. I
> just use the Iterable<T> type unless the operation specifically
> depends on list ordering.

Thanks for the example. I was experimenting with functional like
concepts, but I wanted to be more specific that Iterable, i.e., if you
pass in List<A> you get back List<B>, if you pass in a Set, you get
back a Set etc. Also I was hoping this would allow map to be used on
non collection types (e.g., something like Haskell's Maybe or Either
but translated to Java.)

As I mentioned elsewhere there is no practical reason for me doing
this, just experimenting :)

Thanks,
Levi

lstephen

unread,
Apr 15, 2008, 7:26:22 PM4/15/08
to
On Apr 15, 10:49 pm, Lew <l...@lewscanon.com> wrote:
> lstephen wrote:
> > Hi,
>
> > I'm looking at the signature for something like a 'map' function.
>
> 'map' is a somewhat unfortunate variable name, since you aren't actually
> associating it with the wildly popular 'Map' type.
>
> > For List it may be something like:
>
> > List<B> map(List<A> a, UnaryFunction<A, B> f)
>
> > But, I want I'd rather it not be List specific, so I was after
> > something like:
>
> > T<B> map(T<A> a UnaryFunction<A, B> f)
>
> > But, the compiler doesn't like this ;)
>
> > Any ideas on how or whether this is possible?
>
> What you want to accomplish is possible, what you're trying to say isn't.
> You're trying to indicate a type parameter that takes a type parameter; that
> doesn't exist.

By doesn't exist, do you mean not possible in Java?

> Type parameters exist to restrict the range of acceptable
> types; what you wrote, 'T<A>', is equivalent to merely 'T'.
>
> What is the restriction that you actually want to place on T? Do you want it
> to be a Collection?

The restriction I want to place on T is that it's a generic class that
takes one type parameter.

>
> public static <A, B>
> Collection <B> xform( Collection <A> a, UnaryFunction <A, B> f )
>
> (untried, untested, uncompiled, one of several solutions that differ subtly in
> semantics)

Yep, I could definately cover the most common case by using Iterable
or Collection, but I was trying to see how general I could make this.


>
> If you have a class called 'UnaryFunction', shouldn't it overload its "unary
> function" method with one that takes a Collection? Having a "friend" method
> like that shown breaks encapsulation.

UnaryFunction wouldn't be passed a collection, it would be passed an
element form a collection - it wouldn't even know the element was part
of a collection.

>
> --
> Lew

lstephen

unread,
Apr 15, 2008, 7:28:26 PM4/15/08
to
On Apr 15, 11:20 pm, "Larry A Barowski"
<ThisisLarrybarAtEngDotAuburnDotLearninginstitution> wrote:
> "lstephen" <levi.step...@gmail.com> wrote in message

Good point. I think this is a strong indication that the answer is no.

Thanks,
Levi

Patricia Shanahan

unread,
Apr 15, 2008, 7:41:55 PM4/15/08
to

I certainly agree that not allowing user code access to the actual
iterator would be desirable, if it were possible. It isn't. The
following, horrible, program prints "1", then "3", then gets a
java.util.NoSuchElementException.

import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

public class WildFor {
public static void main(String[] args) {
List<Integer> myList = Arrays.asList(1, 2, 3, 4, 5);
RememberingIterable<Integer> myIterable =
new RememberingIterable<Integer>(myList);
for (Integer i : myIterable) {
myIterable.getLastIterator().next();
System.out.println(i);
}
}

static class RememberingIterable<T> implements
Iterable<T> {
private Iterable<T> baseIterable;

private Iterator<T> lastIterator;

public RememberingIterable(Iterable<T> iterable) {
baseIterable = iterable;
}

public Iterator<T> iterator() {
lastIterator = baseIterable.iterator();
return lastIterator;
}

public Iterator<T> getLastIterator() {
return lastIterator;
}
}

}

Peter Duniho

unread,
Apr 15, 2008, 8:53:47 PM4/15/08
to
On Tue, 15 Apr 2008 16:41:55 -0700, Patricia Shanahan <pa...@acm.org> wrote:

> I certainly agree that not allowing user code access to the actual
> iterator would be desirable, if it were possible. It isn't.

But it would be if Java supported using an Iterator in the for() statement.

> The
> following, horrible, program prints "1", then "3", then gets a
> java.util.NoSuchElementException.

Right. But if you can provide an actual iterator in the for() statement,
then the code has access to the iterator implicitly. It wouldn't be
nearly so much work to reproduce the example of bad usage you provided if
Java allowed an Iterator instead of an Iterable implementation in the
for() statement. Your example would instead look like this:

import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

public class WildFor {
public static void main(String[] args) {
List<Integer> myList = Arrays.asList(1, 2, 3, 4, 5);

Iterator<Integer> myIterator = myList.iterator();

for (Integer i : myIterator) {
myIterator.next();
System.out.println(i);
}
}

I don't know if that's why Java doesn't allow that, but it sure seems like
a good enough reason to me. :)

Pete

Patricia Shanahan

unread,
Apr 15, 2008, 8:58:22 PM4/15/08
to
Peter Duniho wrote:
> On Tue, 15 Apr 2008 16:41:55 -0700, Patricia Shanahan <pa...@acm.org> wrote:
>
>> I certainly agree that not allowing user code access to the actual
>> iterator would be desirable, if it were possible. It isn't.
>
> But it would be if Java supported using an Iterator in the for() statement.
>
>> The
>> following, horrible, program prints "1", then "3", then gets a
>> java.util.NoSuchElementException.
>
> Right. But if you can provide an actual iterator in the for()
> statement, then the code has access to the iterator implicitly. It
> wouldn't be nearly so much work to reproduce the example of bad usage
> you provided if Java allowed an Iterator instead of an Iterable
> implementation in the for() statement. Your example would instead look
> like this:
...

The point is that not allowing Iterator does not prevent access to it,
just makes it a bit harder. Meanwhile, it also makes legitimate uses harder.

Patricia

Peter Duniho

unread,
Apr 16, 2008, 12:03:04 AM4/16/08
to
On Tue, 15 Apr 2008 17:58:22 -0700, Patricia Shanahan <pa...@acm.org> wrote:

> The point is that not allowing Iterator does not prevent access to it,
> just makes it a bit harder.

I never said the Java rules did prevent access to the iterator.

> Meanwhile, it also makes legitimate uses harder.

That's a good thing. It helps prevent illegitimate and/or erroneous uses.

Anyway, like I said, you'd have to ask the folks who actually designed
Java to know the answer to your question. However, I believe that the
very issues covered in this part of the sub-thread are in fact a very good
reason for only allowing an Iterable as the argument in the for(:)
statement.

Pete

thufir

unread,
Apr 16, 2008, 5:30:56 AM4/16/08
to
On Tue, 15 Apr 2008 00:34:07 -0700, lstephen wrote:


> For List it may be something like:
>
> List<B> map(List<A> a, UnaryFunction<A, B> f)


would you flesh this example out?

thanks,

Thufir

Hendrik Maryns

unread,
Apr 16, 2008, 5:53:56 AM4/16/08
to
lsch...@d.umn.edu schreef:

> On Apr 15, 2:34 am, lstephen <levi.step...@gmail.com> wrote:
>> <snip request for map>

>
> I've implemented a functional library that addresses this issue. I
> just use the Iterable<T> type unless the operation specifically
> depends on list ordering. Here's a skeleton of my class declarations
> adapted to your notation. Note, my implementation uses lazy
> evaluation so you can do things like sum up an infinite list.

Very nice, but…

> private static <R, T> Iterator<R> map_iterator( final UnaryFunction<R,

Please, please don’t. It hurts me so much to see such beautiful code
and then not following naming conventions.

Sorry, had to get this off my heart.

H.
--
Hendrik Maryns
http://tcl.sfs.uni-tuebingen.de/~hendrik/
==================
http://aouw.org
Ask smart questions, get good answers:
http://www.catb.org/~esr/faqs/smart-questions.html

signature.asc

Peter Duniho

unread,
Apr 16, 2008, 12:44:42 PM4/16/08
to
On Wed, 16 Apr 2008 02:53:56 -0700, Hendrik Maryns
<gtw3...@sneakemail.com> wrote:

> [...]


>> private static <R, T> Iterator<R> map_iterator( final UnaryFunction<R,
>
> Please, please don’t. It hurts me so much to see such beautiful code
> and then not following naming conventions.

How do you know it's not following a naming convention? It might just not
follow the naming convention you like.

Frankly, I'm surprised at the zealousness with which a few people here
criticize people who follow a different naming convention than the one
they prefer.

Here's a hint: even within the Java SDK, there are multiple conventions
followed, and while they are all very similar to each other, there's no
reason that someone who finds a different convention useful and beneficial
should feel compelled instead to blindly follow Sun's preferences.

If it were so important that all Java code followed a specific convention,
the compiler would enforce it. If you're unable to participate in a
discussion in which some code doesn't follow the precise convention you
prefer, you need to get out more. :)

> Sorry, had to get this off my heart.

Ditto.

Pete

lstephen

unread,
Apr 16, 2008, 7:37:16 PM4/16/08
to

It would probably be something like (without compiling or testing it):

public interface UnaryFunction<A, B> {
B apply(A a);
}

public List<B> map(List<A> as, UnaryFunction<A, B> f) {
List<B> bs = new ArrayList<B>();
for (A a : as) {
bs.add(f.apply(a));
}
return bs;
}


>
> thanks,
>
> Thufir

Levi

Lew

unread,
Apr 16, 2008, 8:44:53 PM4/16/08
to
Peter Duniho wrote:
> On Wed, 16 Apr 2008 02:53:56 -0700, Hendrik Maryns
> <gtw3...@sneakemail.com> wrote:
>
>> [...]
>>> private static <R, T> Iterator<R> map_iterator( final UnaryFunction<R,
>>
>> Please, please don’t. It hurts me so much to see such beautiful code
>> and then not following naming conventions.
>
> How do you know it's not following a naming convention? It might just
> not follow the naming convention you like.
>
> Frankly, I'm surprised at the zealousness with which a few people here
> criticize people who follow a different naming convention than the one
> they prefer.

There is a standard naming convention in Java, published by Sun in 1999.
Ignore it at your peril.

> Here's a hint: even within the Java SDK, there are multiple conventions
> followed, and while they are all very similar to each other, there's no
> reason that someone who finds a different convention useful and
> beneficial should feel compelled instead to blindly follow Sun's
> preferences.

It's hardly blind. When i Rome, do as the Romans do.

> If it were so important that all Java code followed a specific
> convention, the compiler would enforce it. If you're unable to
> participate in a discussion in which some code doesn't follow the
> precise convention you prefer, you need to get out more. :)

Forget it, Pete. Java is a community, not just a language, and the community
has standards. The naming conventions in Java are well-established and you
violate them at your peril.

--
Lew

Peter Duniho

unread,
Apr 16, 2008, 9:56:10 PM4/16/08
to
On Wed, 16 Apr 2008 17:44:53 -0700, Lew <l...@lewscanon.com> wrote:

> There is a standard naming convention in Java, published by Sun in 1999.
> Ignore it at your peril.

Peril? Something bad will happen to me? What? What bad thing will
happen?

And I mean, other than Java zealots harrassing me about my naming.

>> Here's a hint: even within the Java SDK, there are multiple conventions
>> followed, and while they are all very similar to each other, there's no
>> reason that someone who finds a different convention useful and
>> beneficial should feel compelled instead to blindly follow Sun's
>> preferences.
>
> It's hardly blind. When i Rome, do as the Romans do.

That's actually a pretty dumb rule to follow generally. It has value in
specific scenarios, but it's no way to lead your life. I've been to
Rome. There are lots of things they do that I wouldn't do, even while in
Rome.

The fact is, there are a wide variety of naming conventions, and at least
for some people, some conventions have greater positive value that the
ones arbitrarily chosen by Sun for Java. When those conventions can be
used without being in conflict with other users, why should they not be
used?

Again that is, other than the possibility that some Java zealot might
harrass someone about them.

> Forget it, Pete. Java is a community, not just a language, and the
> community has standards.

Java _is_ "just a language". There may also be a "Java community", but
the language itself doesn't enforce any particular naming convention and
there's no requirement to comply with "community standards" in order to be
a successful Java programmer.

> The naming conventions in Java are well-established and you violate them
> at your peril.

Again with the peril...

Andreas Leitgeb

unread,
Apr 17, 2008, 3:19:57 AM4/17/08
to
Peter Duniho <NpOeS...@nnowslpianmk.com> wrote:
> On Wed, 16 Apr 2008 17:44:53 -0700, Lew <l...@lewscanon.com> wrote:
>> There is a standard naming convention in Java, published by Sun in 1999.
>> Ignore it at your peril.
> Peril? Something bad will happen to me? What? What bad thing will
> happen?
> And I mean, other than Java zealots harrassing me about my naming.

Zealots are not just here in c.l.j.p, but you may also meet some
in real world - e.g. those who review your code and rate it poorly.
The zealots *here* rather help you be prepared for the others :-)

RedGrittyBrick

unread,
Apr 17, 2008, 5:09:55 AM4/17/08
to

This is true but misses the point that if you wish to enlist the help of
the community in fixing some problem you are having with your Java
source code, you'll get a better response from the community if your
source code follows the community conventions that make it easier for
community members to follow.

Using underscore connected words instead of camelCase isn't much of a
hindrance, it's when people use wild indentation or initial upper-case
for variables that my reading speed tends to slow down dramatically. I
tend to lose motivation a bit when I think the author is wilfully making
it harder for helpers to help.

bI awrl menes beeYidIosYnCRAT.IC wern ryEtAng koid fore eeyore Owen
prusell Owen Lee.

When communicating with others, I think it helps to follow the conventions.

Just my EUR 0.00000002 worth.

--
RGB

Logan Shaw

unread,
Apr 19, 2008, 12:48:25 PM4/19/08
to
Peter Duniho wrote:
> On Tue, 15 Apr 2008 17:58:22 -0700, Patricia Shanahan <pa...@acm.org> wrote:
>
>> The point is that not allowing Iterator does not prevent access to it,
>> just makes it a bit harder.
>
> I never said the Java rules did prevent access to the iterator.
>
>> Meanwhile, it also makes legitimate uses harder.
>
> That's a good thing. It helps prevent illegitimate and/or erroneous uses.

Preventing legitimate uses is a good thing *only* to the extent that it's
necessary to prevent bad uses. I'm not entirely convinced that you can't
have both.

Is there a reason why an enhanced for loop couldn't be built to use either
an Iterator or an Iterable?

There are cases when we have a priori that an Iterator object exists.
For example, some API returns an Iterator. (There are other legit uses.)
In those cases, it would nice to be able to use the object at hand.

Then there are also cases where the Iterator object does not already
exist, and the existing form of the loop that takes Iterable would be
appropriate there.

- Logan

Patricia Shanahan

unread,
Apr 19, 2008, 4:37:32 PM4/19/08
to
Logan Shaw wrote:
...

> Is there a reason why an enhanced for loop couldn't be built to use either
> an Iterator or an Iterable?
>
> There are cases when we have a priori that an Iterator object exists.
> For example, some API returns an Iterator. (There are other legit uses.)
> In those cases, it would nice to be able to use the object at hand.
...

Here's a solution that I just worked out for my own use:

import java.util.Iterator;

/**
* Iterable whose iterator() method returns a
* specified Iterator.
* @param <T> The base type of the Iterator and Iterable.
*/
public class IteratorToIterable<T> implements Iterable<T> {
private Iterator<T> base;
/**
* Create an Iterable whose iterator method returns base.
* @param base
*/
public IteratorToIterable(Iterator<T> base){
this.base = base;
}
/**
* Get the Iterator passed to the constructor. The Iterator
* should be used only once.
*/
public Iterator<T> iterator() {
return base;
}
}

The intended use of this class is:

public static void main(String[] args) {

Iterator<Integer> it = getIterator();
for(Integer i: new IteratorToIterable<Integer>(it) ){
System.out.println(i);
}
}

Patricia

Logan Shaw

unread,
Apr 19, 2008, 4:56:02 PM4/19/08
to

Two comments:
(1) That is clever, it hurts my brain, AND IT WORKS.
(2) IteratorToIterable is wordy. How about "Reiteration"? :-)

- Logan

Andreas Leitgeb

unread,
Apr 19, 2008, 5:20:06 PM4/19/08
to
Patricia Shanahan <pa...@acm.org> wrote:
> Here's a solution that I just worked out for my own use:
> public class IteratorToIterable<T> implements Iterable<T> {
> [...]
> }

final Iterator<String> itStr= Arrays.asList("1","2","3").iterator();
for (String s:
new Iterable<String>() {
public Iterator<String> iterator() { return itStr; }
}
)
{
System.out.println(s);
}

Perhaps less elegant, but shorter :-)

Lew

unread,
Apr 19, 2008, 8:37:08 PM4/19/08
to

for ( String s : new String [] { "1","2","3", } )
{
System.out.println(s);
}

--
Lew

Patricia Shanahan

unread,
Apr 19, 2008, 10:17:30 PM4/19/08
to

Shorter in total code, but longer, especially if I pick a shorter name,
in the code in the using class. I don't really care about the length of
the implementing class, because it will go in my utilities package, and
be used anywhere I needed it.

However, the existence of yet another way of working around the lack of
for each for Iterator just emphasizes the fact that whatever problems it
has already exist. The lack just makes legitimate code that could use it
a bit more wordy.

Patricia

Patricia Shanahan

unread,
Apr 19, 2008, 10:23:08 PM4/19/08
to

I think you missed the context. We were discussing the situation in
which an Iterator is available but not an Iterable. I'm sure the itStr
declaration was just a way of getting into that situation, and Andreas
would not use such an indirect approach to iterate over an array.

Patricia

Peter Duniho

unread,
Apr 19, 2008, 10:51:22 PM4/19/08
to
On Sat, 19 Apr 2008 19:17:30 -0700, Patricia Shanahan <pa...@acm.org> wrote:

> [...]


> However, the existence of yet another way of working around the lack of
> for each for Iterator just emphasizes the fact that whatever problems it
> has already exist. The lack just makes legitimate code that could use it
> a bit more wordy.

We'll just have to agree to disagree. The fact that you have to jump
through hoops to get this to happen is a _good_ thing. The fact that you
_can_ jump through hoops proves absolutely nothing about whether the
language should have enabled the behavior without hoop-jumping.

I've yet to meet a language that absolutely prohibits what it "considers"
dangerous coding practices (inasmuch as a programming language considers
anything :) ). There's always some way around the nominal restrictions
(note that I'm talking about coding constructs here, not things like
security restrictions that might be imposed, sandboxing, etc.)

The nominal restrictions help prevent less-competent programmers from
accidently writing _wrong_ code. More competent programmers such as
yourself can get around these limitations, with the assumption that you
know what you're doing and won't write wrong code.

Pete

Lew

unread,
Apr 19, 2008, 11:07:23 PM4/19/08
to

Perhaps I did miss it, or perhaps I made a larger point about how the lack of
an Iterable may be much less of a problem in practice.

--
Lew

Patricia Shanahan

unread,
Apr 19, 2008, 11:45:25 PM4/19/08
to
Peter Duniho wrote:
...

> I've yet to meet a language that absolutely prohibits what it
> "considers" dangerous coding practices (inasmuch as a programming
> language considers anything :) ). There's always some way around the
> nominal restrictions (note that I'm talking about coding constructs
> here, not things like security restrictions that might be imposed,
> sandboxing, etc.)
...

How about goto, one of the oldest and most basic coding constructs?

Patricia

Peter Duniho

unread,
Apr 19, 2008, 11:59:28 PM4/19/08
to

How about it? Are you suggesting that Java doesn't have the equivalent?

If so, while I haven't explored the dark corners, I know that I have used
labeled breaks and continues in Java to accomplish exactly the same thing
I'd have used a goto for. I'm not aware of any flow of code that a goto
statement would allow that you couldn't do with some other, albeit more
complex, structured code. In fact, the labeled breaks and continues
aren't strictly speaking necessary.

Do you have an example of code that uses "goto" that you could not
accomplish in any other way? Or is that not what you're talking about?
If it's not, what are you talking about?

Pete

Arne Vajhøj

unread,
Apr 20, 2008, 7:18:09 AM4/20/08
to
Peter Duniho wrote:
> On Sat, 19 Apr 2008 20:45:25 -0700, Patricia Shanahan <pa...@acm.org> wrote:
>> Peter Duniho wrote:
>> ...
>>> I've yet to meet a language that absolutely prohibits what it
>>> "considers" dangerous coding practices (inasmuch as a programming
>>> language considers anything :) ). There's always some way around the
>>> nominal restrictions (note that I'm talking about coding constructs
>>> here, not things like security restrictions that might be imposed,
>>> sandboxing, etc.)
>> ...
>>
>> How about goto, one of the oldest and most basic coding constructs?
>
> How about it? Are you suggesting that Java doesn't have the equivalent?

goto is a reserved word in Java, but is not and never will be
implemented.

Arne

Andreas Leitgeb

unread,
Apr 20, 2008, 7:44:50 AM4/20/08
to
>>>> Patricia Shanahan <pa...@acm.org> wrote:
>>>>> Here's a solution that I just worked out for my own use:
>>>>> public class IteratorToIterable<T> implements Iterable<T> { [...] }
>>> Andreas Leitgeb wrote:
>>>> [anonymous Iterable-subclass whose .iterator() returns the iterator]
>> Lew wrote:
>>> [ misses the point, that we were starting from iterator, not iterable ]

> Patricia Shanahan wrote:
>> I'm sure the itStr declaration was just a way of getting into that
>> situation, and Andreas would not use such an indirect approach to
>> iterate over an array.
100% correct.

Lew <l...@lewscanon.com> wrote:
> Perhaps I did miss it, or perhaps I made a larger point about how the lack of
> an Iterable may be much less of a problem in practice.

I offer a different example:

for (String s: new Iterable<String>() {

public Iterator<String> iterator() { return new Scanner(System.in); }
}) {
System.out.println(s);
}

Scanner is an Iterator<String>, but not an Iterable.

Andreas Leitgeb

unread,
Apr 20, 2008, 7:56:50 AM4/20/08
to
Peter Duniho <NpOeS...@nnowslpianmk.com> wrote:
> I've yet to meet a language that absolutely prohibits what it "considers"
> dangerous coding practices (inasmuch as a programming language considers
> anything :) ).

I do think, that in Java the dangerous coding pracise of
pointer-arithmetics is really really prohibited :-)

Andreas Leitgeb

unread,
Apr 20, 2008, 9:07:13 AM4/20/08
to
Peter Duniho <NpOeS...@nnowslpianmk.com> wrote:
>> How about goto, one of the oldest and most basic coding constructs?
> How about it? Are you suggesting that Java doesn't have the equivalent?

The real pendant for goto would be a switch wrapped in an endless loop.

> Do you have an example of code that uses "goto" that you could not
> accomplish in any other way?

If you see forward jumps as structured "if", and backwards-jumps
as structured loops, then there can easily exist some mixture that
doesn't really map to a proper nesting of structured elements.
like jump into the middle of a loop, or jumping from one loop
to another or even from one subroutine to another.

I don't know if there are any theories about what spaghetti-code
can be structurized, and what (if any) not, or if there even exist
algorithms for this transformation.

Lew

unread,
Apr 20, 2008, 9:58:52 AM4/20/08
to
Andreas Leitgeb wrote:
>>> Lew wrote:
>>>> [ misses the point, that we were starting from iterator, not iterable ]

Lew <l...@lewscanon.com> wrote:


>> Perhaps I did miss it, or perhaps I made a larger point about how the lack of
>> an Iterable may be much less of a problem in practice.

In other words, for those who missed my point, the premise that we have to
start from an Iterator, not an Iterable, is itself of little significance
because in such situations it will be more feasible to recast the problem to a
more easily solved one. You, in practice, will not need these arcane
epicycles used in this thread to solve the problem that is easier to prevent
than solve.

My illustration illustrated that point, not missed yours. Got it now?

--
Lew

Peter Duniho

unread,
Apr 20, 2008, 1:34:38 PM4/20/08
to
On Sun, 20 Apr 2008 06:07:13 -0700, Andreas Leitgeb
<a...@gamma.logic.tuwien.ac.at> wrote:

> [...]


> I don't know if there are any theories about what spaghetti-code
> can be structurized, and what (if any) not, or if there even exist
> algorithms for this transformation.

Well, inasmuch as in theory, two languages that are both "Turing-complete"
should be able to implement identical algorithms, whether there's a
well-defined mapping process or not it should be obvious that you can
always come up with an equivalent. :)

And AFAIK, everyone agrees that Java is Turing-complete, as would a
variant of Java in which "goto" was implemented.

So, whether algorithms exist to perform the transformation between
implementations is irrelevant. We know we can perform the transformation,
even if just manually.

Pete

Daniel Pitts

unread,
Apr 20, 2008, 2:08:43 PM4/20/08
to
lstephen wrote:
> Hi,
>
> I'm looking at the signature for something like a 'map' function.

>
> For List it may be something like:
>
> List<B> map(List<A> a, UnaryFunction<A, B> f)
>
> But, I want I'd rather it not be List specific, so I was after
> something like:
>
> T<B> map(T<A> a UnaryFunction<A, B> f)
>
> But, the compiler doesn't like this ;)
>
> Any ideas on how or whether this is possible?
>
> Thanks,
> Levi
>
>
>

How about this:

public static <A, B, T extends Collection<B>> T map(Iterable<A> source,
T dest, UnaryFunction<A, B> f) {
for (A a: source) {
dest.add(f.call(a));
}
return dest;
}

Example usage:

Set<Foo> foos = map(inputCollection, new HashSet<Foo>(), myFunction);

--
Daniel Pitts' Tech Blog: <http://virtualinfinity.net/wordpress/>

Andreas Leitgeb

unread,
Apr 20, 2008, 3:50:06 PM4/20/08
to
Lew <l...@lewscanon.com> wrote:
> In other words, for those who missed my point, the premise that we have to
> start from an Iterator, not an Iterable, is itself of little significance
> because in such situations it will be more feasible to recast the problem
> to a more easily solved one.

Can you explain me, how to do the recast, when starting from a Scanner?

Since those situations, where we do start with an Iterable are trivial,
it's not very interesting to deal with those in this thread.
Your point seems to be, that the situation "start with an iterator"
doesn't ever happen in practise, and the Iterable's iterator() call
is always just preceding the currently focussed snippet of code.

But there's also Scanner and there may be other Iterator-subclasses,
for iterating ressources that can be iterated only once. So starting
with an Iterator (and not an Iterable) is not just an artifical problem.

You obviously avoided to comment on the Scanner-example that I added
to my previous posting.

Andreas Leitgeb

unread,
Apr 20, 2008, 4:35:32 PM4/20/08
to
Peter Duniho <NpOeS...@nnowslpianmk.com> wrote:
> Well, inasmuch as in theory, two languages that are both "Turing-complete"
> should be able to implement identical algorithms, whether there's a
> well-defined mapping process or not it should be obvious that you can
> always come up with an equivalent. :)

Using turing-completeness for argumentation does not answer this problem.

Even if we assumed some "unlimited Java", the one existing implementation
(or even the nicest of all them) might just be an interpreter for the
verbatim original implementation.

Turing completeness of any structured target language is no proof that
a structured pendant exists for each spaghetti code.

Peter Duniho

unread,
Apr 20, 2008, 4:51:00 PM4/20/08
to
On Sun, 20 Apr 2008 13:35:32 -0700, Andreas Leitgeb
<a...@gamma.logic.tuwien.ac.at> wrote:

> Using turing-completeness for argumentation does not answer this problem.

Why not?

> Even if we assumed some "unlimited Java", the one existing implementation
> (or even the nicest of all them) might just be an interpreter for the
> verbatim original implementation.

Indeed it might. So? You could still do it in Java.

> Turing completeness of any structured target language is no proof that
> a structured pendant exists for each spaghetti code.

I think it is. I already acknowledged that there's no theoretical limit
on the complexity of the alternative solution.

At the same time, I am of the opinion that in the vast majority of cases,
the alternative, goto-free solution would _not_ be all that complex
anyway. This is especially true if you consider only examples where the
goto statement is used in what would be considered acceptable practices by
people not pre-disposed to hate goto (such as myself...I feel that you can
certainly abuse the goto statement, but it can also be used safely and
with good purpose, when applied judiciously to certain problems).

In other words, not only does theory tell us that you don't really need
the goto statement in Java, practice also tells us that as long as the
goto statement was only used responsibly in the first place, an
alternative "goto-free" representation of the algorithm will not be all
that far from the original "with goto" version anyway.

If you think you have a counter-example that disproves the latter opinion,
I'm more than happy to see it. Otherwise, I don't really see why you
think there's a point in arguing about it.

Pete

Lew

unread,
Apr 20, 2008, 6:03:06 PM4/20/08
to
Peter Duniho wrote:
> At the same time, I am of the opinion that in the vast majority of
> cases, the alternative, goto-free solution would _not_ be all that
> complex anyway. This is especially true if you consider only examples
> where the goto statement is used in what would be considered acceptable
> practices by people not pre-disposed to hate goto (such as myself...I
> feel that you can certainly abuse the goto statement, but it can also be
> used safely and with good purpose, when applied judiciously to certain
> problems).
>
> In other words, not only does theory tell us that you don't really need
> the goto statement in Java, practice also tells us that as long as the
> goto statement was only used responsibly in the first place, an
> alternative "goto-free" representation of the algorithm will not be all
> that far from the original "with goto" version anyway.

For a long time, when I used C professionally, I used to look for excuses to
use 'goto' in my code, just for grins and giggles. I think there might have
been one case where I didn't supplant it with a structured idiom for being
simpler to read and use, and I believe I goofed that one time.

--
Lew

lstephen

unread,
Apr 21, 2008, 3:29:46 AM4/21/08
to
On Apr 21, 3:08 am, Daniel Pitts

I agree that this covers the common case. But, I was looking for a way
to improve this in two ways.

1. the 'map' concept can be applied to other, non-collection, types
(e.g., Haskell's Maybe type)
2. I wanted to express the restriction that the type passed in was
what came back (e.g., If a Set was passed in, a Set would be returned)

Note that there would be more than one implementation of map around,
so the general type would only appear in the interface.

Thanks,
Levi

Andreas Leitgeb

unread,
Apr 21, 2008, 4:37:28 AM4/21/08
to
Peter Duniho <NpOeS...@nnowslpianmk.com> wrote:
>> Using turing-completeness for argumentation does not answer this problem.
> Why not?

Because we argue with two different meanings of "structured".
(Sorry I didn't notice that before - would have saved us some
iterations already)

Yours seems to be such that since Java has no goto, every legal
Java program is automatically "structured".

My definition of "structured" is a bit stricter, and would
exclude certain practices, like the one shown in this snippet:

int step=10;
while (step>0) {
switch (step) {
case 10: if (blah()) { step=30; continue; }
case 20: if (foo()) { step=0; break; }
case 30: if (snarf()) { step=10; continue; }
case 40: step=30; continue;
}
}
While it's legal Java code(-excerpt), it's not "structured"
according to my own humpty dumpty definition ;-)

I've looked at "http://en.wikipedia.org/wiki/Structured_programming"
but wasn't able to make out any sharp definition. The sample I
provided probably fits well to the "State machines" paragraph.
Quote: " It is possible to structure these systems by making each
state-change a separate subprogram..."
This could be interpreted, that such state-machine code is not yet
structured.

If there is some other "official" definition of "structured" that
supports your point, then, well, then you've won 10 points for
a correct statement, even though one of no use, due to my
(as it now appears) inexact question.

I'm interested, what others consider "structured" to mean.

Andreas Leitgeb

unread,
Apr 21, 2008, 5:00:34 AM4/21/08
to
Lew <l...@lewscanon.com> wrote:
> For a long time, when I used C professionally, I used to look for excuses to
> use 'goto' in my code, just for grins and giggles.

Since C/C++ do not have labelled loops like Java, an excuse for a use
for goto is not all that hard to find there. My C++ code contains some
gotos, and were I to convert it to Java, I could change most of them
to: "break thatOuterLoop;"

Hendrik Maryns

unread,
Apr 21, 2008, 6:27:20 AM4/21/08
to
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Patricia Shanahan schreef:

I would add

public static <T> Iterable<T> toIterable(Iterator<T> base) {
~ return new IteratorToIterable<T>(base);
}

(this is a pattern much seen in Jakarta Commons)
and then

| public static void main(String[] args) {
| Iterator<Integer> it = getIterator();

| for(Integer i: toIterable(it) ){
| System.out.println(i);
| }
| }

with a proper static import.

One could even just put that method somewhere in the class where one
wants to use it.

H.
- --
Hendrik Maryns
http://tcl.sfs.uni-tuebingen.de/~hendrik/
==================
http://aouw.org
Ask smart questions, get good answers:
http://www.catb.org/~esr/faqs/smart-questions.html
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.4-svn0 (GNU/Linux)
Comment: Using GnuPG with SUSE - http://enigmail.mozdev.org

iD4DBQFIDGwEe+7xMGD3itQRAkgEAJ9httlWOlSauKtrNvoXi5edXjtB8ACXUNF5
GnELu8MWNBn1IYW71SD7hg==
=jpMA
-----END PGP SIGNATURE-----

Hendrik Maryns

unread,
Apr 21, 2008, 6:36:22 AM4/21/08
to
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Patricia Shanahan schreef:

I had some classes (Combinators, see
http://mindprod.com/jgloss/combination.html) which were iterators and
wanted to use them like this as well. I ended up having them implement
both Iterator<T> and Iterable<T>, with the iterator() function just
{return this;}. Not very elegant, but works as expected. I do remember
somebody had some valid remarks against that practice though,
particularly multiple iterations are a problem.

H.
- --
Hendrik Maryns
http://tcl.sfs.uni-tuebingen.de/~hendrik/
==================
http://aouw.org
Ask smart questions, get good answers:
http://www.catb.org/~esr/faqs/smart-questions.html
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.4-svn0 (GNU/Linux)
Comment: Using GnuPG with SUSE - http://enigmail.mozdev.org

iD8DBQFIDG4me+7xMGD3itQRArFnAJ0WM6Uwa84QrOE5l8nJdY/AWHg2sQCeO27g
/eHR6veCu8CBwndouc6xUww=
=1I0b
-----END PGP SIGNATURE-----

Patricia Shanahan

unread,
Apr 21, 2008, 9:25:49 AM4/21/08
to
Hendrik Maryns wrote:
...

> I had some classes (Combinators, see
> http://mindprod.com/jgloss/combination.html) which were iterators and
> wanted to use them like this as well. I ended up having them implement
> both Iterator<T> and Iterable<T>, with the iterator() function just
> {return this;}. Not very elegant, but works as expected. I do remember
> somebody had some valid remarks against that practice though,
> particularly multiple iterations are a problem.
...

The multiple iterator() call issue is the reason why I prefer something
special that is applied only in the for statement. The limitations
should be stated in the documentation for the method or constructor.

Patricia

Peter Duniho

unread,
Apr 21, 2008, 12:56:48 PM4/21/08
to
On Mon, 21 Apr 2008 01:37:28 -0700, Andreas Leitgeb
<a...@gamma.logic.tuwien.ac.at> wrote:

> Peter Duniho <NpOeS...@nnowslpianmk.com> wrote:
>>> Using turing-completeness for argumentation does not answer this
>>> problem.
>> Why not?
>
> Because we argue with two different meanings of "structured".
> (Sorry I didn't notice that before - would have saved us some
> iterations already)

Why does it matter what the exact definition of "structured" is? Using
your definition doesn't change the point I made.

Pete

Daniel Pitts

unread,
Apr 21, 2008, 5:34:57 PM4/21/08
to
Why restrict that the type-in is the type-out? The method I suggested
allows the caller to specify the type-out. Maybe you want to convert a
List to a Set while applying this mapping, or visa versa.

Andreas Leitgeb

unread,
Apr 21, 2008, 5:32:01 PM4/21/08
to
Peter Duniho <NpOeS...@nnowslpianmk.com> wrote:

><a...@gamma.logic.tuwien.ac.at> wrote:
>> Because we argue with two different meanings of "structured".
> Why does it matter what the exact definition of "structured" is? Using
> your definition doesn't change the point I made.

My original question was, if any spaghetti code could be converted to
structured code, to which you argued somehow like, that since Java was
turing complete, a "structured"/goto-free program exists for every
machine-implementable algorithm, thus also for one already implemented
in spaghetti code. So far so good. But this conclusion doesn't
*necessarily* remain valid, if I "arbitrarily" restrict my set of
"acceptable" Java programs.
I don't remember exactly, how to prove turing-completeness. I vaguely
remember, that one needs to be able to code some abstract building blocks.
Maybe these building blocks can be also coded in (my type of) structured
code, and any combination/chaining of these building blocks also needs to
be "inside" that restricted set of acceptable programs. Perhaps it is,
then you'd be right afterall. It just isn't yet obvious to me.

Peter Duniho

unread,
Apr 21, 2008, 5:49:29 PM4/21/08
to
On Mon, 21 Apr 2008 14:32:01 -0700, Andreas Leitgeb
<a...@gamma.logic.tuwien.ac.at> wrote:

> Peter Duniho <NpOeS...@nnowslpianmk.com> wrote:
>> <a...@gamma.logic.tuwien.ac.at> wrote:
>>> Because we argue with two different meanings of "structured".
>> Why does it matter what the exact definition of "structured" is? Using
>> your definition doesn't change the point I made.
>
> My original question was, if any spaghetti code could be converted to
> structured code, to which you argued somehow like, that since Java was
> turing complete, a "structured"/goto-free program exists for every
> machine-implementable algorithm, thus also for one already implemented
> in spaghetti code. So far so good. But this conclusion doesn't
> *necessarily* remain valid, if I "arbitrarily" restrict my set of
> "acceptable" Java programs.

So it's really more about your assertion than mine, it seems to me.

My only point is that the lack of a "goto" statement isn't really a
problem. I don't know why if you accept the initial premise of "spaghetti
code", you somehow object to a similar implementation in Java not also
having "spaghetti-like" characteristics. My only point is that you can
translate code from a language using a "goto" in to a language that
doesn't have a "goto". I never said it would be pretty.

But beyond that, assuming one wasn't abusing the "goto" statement in the
first place (i.e. the code isn't actually "spaghetti-code"), there's no
reason the Java version shouldn't be reasonably elegant as well.

No offense, but given your arbitrary limitation on what Java
implementations you'd consider acceptable, I think your introduction of
"spaghetti-code", "goto"-using code is a bit of a straw man. That's the
problem with "spaghetti-code": it's ugly. It's going to be ugly whether
you write it with or without a "goto" statement. If you arbitrarily say
that the equivalent without a "goto" must not be ugly, you've already
prejudicially fixed the problem to prove your assertion.

In that context, I can't really disagree with your logic, any more than I
could disagree with someone telling me that a program written in Java must
be a Java program. But I'm not sure it's a useful thing to say.

Pete

Patricia Shanahan

unread,
Apr 21, 2008, 6:18:01 PM4/21/08
to
Andreas Leitgeb wrote:
...

> I don't remember exactly, how to prove turing-completeness. I vaguely
> remember, that one needs to be able to code some abstract building blocks.
> Maybe these building blocks can be also coded in (my type of) structured
> code, and any combination/chaining of these building blocks also needs to
> be "inside" that restricted set of acceptable programs. Perhaps it is,
> then you'd be right afterall. It just isn't yet obvious to me.
>

The main building blocks for emulating a TM are:

1. Conditional code execution. To remove this capability from Java, you
would have to do without "if", and anything else that can be used to
execute code conditionally based on a data value, such as "for",
"while", and "switch".

2. An array, or similar structure, with read and write access to a
"current" element, and ability to select the predecessor or successor of
the "current" element to be a the next "current" element. To remove that
capability from Java you would have to do without arrays, anything
implementing java.util.List, and java.io.RandomAccessFile.

3. Some means to execute code repeatedly, such as "for" or "while".

There are several independently developed concepts of algorithmic
computation that were shown, very early in the history of computer
science, to be equivalent. See
http://en.wikipedia.org/wiki/Church-Turing_thesis

Beyond that, given the equivalence of those models, and their
equivalence with the model represented by each general purpose
programming language ever developed, it appears that there is something
real and important about Turing-completeness. A language is unlikely to
be useful as a general purpose programming language without being
Turing-complete.

Of course, all this ignores the fact that any real computer is a finite
state automaton because there is a finite amount of material in the
accessible universe that could be used to build memory for it. It is
usually more useful to treat memory as unbounded.

Patricia

Andreas Leitgeb

unread,
Apr 22, 2008, 1:54:16 AM4/22/08
to
Peter Duniho <NpOeS...@nnowslpianmk.com> wrote:
><a...@gamma.logic.tuwien.ac.at> wrote:
> My only point is that the lack of a "goto" statement isn't really a
> problem.
> [...]

> No offense, but given your arbitrary limitation on what Java
> implementations you'd consider acceptable,...

Now we're at the point I was two steps before:
Yes, it *does* depend on the definition of "structured"
(and I didn't claim that mine was any more correct than
anyone else's. I just described it informally).

> If you arbitrarily say that the equivalent without a "goto"
> must not be ugly,

I didn't really *say* it. I effectively *asked* if all implementable
algorithms are also implementable without resorting to state-machine
emulation. Maybe the answer is no. Turing-completenesss does not
answer my question, because I can't say, if this limitation of mine
to allow only "nice" code is still turing complete. (this is of course
an equivalent question to my original one).

If it was, then all dirty-hack-code could be rewritten for "nice",
if it isn't, then hackers have an everlasting excuse to *sometimes*
write ugly code :-)

I find the question still interesting, but I understand, if no one
else does. So, unless there's a new insight to this, I suggest
we make an end-of-subthread now.

Peter Duniho

unread,
Apr 22, 2008, 2:22:10 AM4/22/08
to
On Mon, 21 Apr 2008 22:54:16 -0700, Andreas Leitgeb
<a...@gamma.logic.tuwien.ac.at> wrote:

> [...]


> I didn't really *say* it. I effectively *asked* if all implementable
> algorithms are also implementable without resorting to state-machine
> emulation.

Sorry...I didn't realize that was what you were asking. It's not how I
read the question you posed.

> Maybe the answer is no. Turing-completenesss does not
> answer my question, because I can't say, if this limitation of mine
> to allow only "nice" code is still turing complete. (this is of course
> an equivalent question to my original one).
>
> If it was, then all dirty-hack-code could be rewritten for "nice",
> if it isn't, then hackers have an everlasting excuse to *sometimes*
> write ugly code :-)

I doubt that's true. :) One of the biggest problems with spaghetti code
is that it's often wrong. That is, not only is it wrong from an elegance
point of view, it's literally a wrong implementation of some intended
solution. In most cases, it will contain genuine, harmful bugs, and even
when no such bugs exist, it's likely it won't be an efficient solution,
never mind maintainable.

In other words, even if you could prove that for some set of spaghetti
code there is no 1-for-1 literal equivalent in structured code (however
you choose to define that), I don't think you can conclude that there's a
justification for spaghetti code. You would have to demonstrate not only
that there's no 1-for-1 equivalent, but also that the exact spaghetti
implementation is in fact a requirement.

> I find the question still interesting, but I understand, if no one
> else does. So, unless there's a new insight to this, I suggest
> we make an end-of-subthread now.

I'm fine with that. :) It's not like I think we're going to come up with
a good argument in favor of spaghetti code in any case.

Pete

Andreas Leitgeb

unread,
Apr 22, 2008, 4:41:08 AM4/22/08
to
Peter Duniho <NpOeS...@nnowslpianmk.com> wrote:
> Sorry...I didn't realize that was what you were asking. It's not how I
> read the question you posed.

I now reread my sub-thread-starter posting, and admit, that
what I claimed there originally, was indeed correctly addressed
with your Turing argument. Only later did I exclude the
"while-switch" anti-sample.

> I don't think you can conclude that there's a justification for
> spaghetti code.

Spaghetti code wrapped/emulated in Java is still spaghetti code.

Unless we can prove, that "nice" Java is also Turing complete, it *is*
a justification, because using spaghetti code *may* be inevitable.

(In most of the practical cases, judged from experience, a "nice"
alternative does exist - for apt definitions of "practical" at
least :-)

Lew

unread,
Apr 22, 2008, 8:13:54 AM4/22/08
to
Andreas Leitgeb wrote:
> Spaghetti code wrapped/emulated in Java is still spaghetti code.

But very structured spaghetti code.

> Unless we can prove, that "nice" Java is also Turing complete, it *is*
> a justification, because using spaghetti code *may* be inevitable.

Java is Turing complete, as others in this thread have explained. Spaghetti
code is only inevitable at the hands of putz programmers.

--
Lew

Andreas Leitgeb

unread,
Apr 22, 2008, 8:47:09 AM4/22/08
to
Lew <l...@lewscanon.com> wrote:
> Andreas Leitgeb wrote:
>> Spaghetti code wrapped/emulated in Java is still spaghetti code.
> But very structured spaghetti code.

haha, good joke :-)

Andreas Leitgeb

unread,
Apr 22, 2008, 9:39:03 AM4/22/08
to
Lew <l...@lewscanon.com> wrote:
> Andreas Leitgeb wrote:
>> Spaghetti code wrapped/emulated in Java is still spaghetti code.
> But very structured spaghetti code.

I'd like to apologize for the other one of my followups on your
posting. - You may not have followed my whole discussion with
Pete.

If that's the case, and you're interested, then look at the code-sample in:
Message-ID: <slrng0oki...@gamma.logic.tuwien.ac.at>
or:
http://groups.google.com/group/comp.lang.java.programmer/msg/f1845edf8ece4b0f

If you consider that to be "very structured spaghetti code",
then accept my laughter. If you think Java-code of that type
can generally be un-spaghettified, you're welcome to join in
and share your recipes.

Peter Duniho

unread,
Apr 22, 2008, 12:46:15 PM4/22/08
to
On Tue, 22 Apr 2008 06:39:03 -0700, Andreas Leitgeb
<a...@gamma.logic.tuwien.ac.at> wrote:

> [...]


> If you consider that to be "very structured spaghetti code",
> then accept my laughter. If you think Java-code of that type
> can generally be un-spaghettified, you're welcome to join in
> and share your recipes.

You would have to first justify some spaghetti code as being a desirable
implementation of some goal or specification, before anyone would worry
about whether it can be "unspaghettified".

But even in that case, for an example as simple as the one you've
provided, I would think that a simple dictionary with integer keys and
some sort of interface implementation that returns the next execution key
for values, would satisfy a basic requirement to apply additional
structure to the code in an easily-applied way (that is, using a process
that can be applied generally).

Granted, doing so puts you that much closer to simply implementing some
sort of language interpreter. But the Java itself would be nicely
structured, which is the stated goal.

If there is really some point to such an arbitrarily unstructured
implementation, at some level you may always find some particular aspect
of the unstructured-ness, even if the implementation itself is
structured. After all, you seem to be assuming a problem description that
is itself unstructured.

Consider as an example a word processor. It would hardly be reasonably to
insist that the user create their document using structured input.
However, it's not hard at all to ensure that the language implementation
supporting the user's unstructured input is itself structured. You simply
need to be careful not to confuse the question of implementation with the
question of what problem you're ultimately solving.

Now, all that said, I believe that the following is a fair representation
of the code you posted:

while (true)
{
if (!blah() && foo())
{
break;
}

while (!snarf())
{
}
}

Translating one single example doesn't actually prove anything, except
possibly that coming up with code that's _really_ spaghettied beyond all
salvation is probably harder than one might think. :) But it should at
least suggest to you that even code that look unstructured may in fact
have structure after all.

Pete

Patricia Shanahan

unread,
Apr 22, 2008, 3:23:17 PM4/22/08
to
Andreas Leitgeb wrote:
...

> Unless we can prove, that "nice" Java is also Turing complete, it *is*
> a justification, because using spaghetti code *may* be inevitable.
...

Without a specification for "nice" Java, it is, of course, impossible to
prove *anything* about it.

Here's a challenge. Specify your "nice" Java, and I'll do one of the
following:

1. Prove that "Nice" Java is Turing complete, if we ignore the
finiteness of memory and disk space.

2. Identify a java.util class that is currently implemented in Java
without depending on native code and that I claim cannot be written in
"nice" Java.

Patricia

lstephen

unread,
Apr 22, 2008, 8:46:59 PM4/22/08
to
>
> Why restrict that the type-in is the type-out? The method I suggested
> allows the caller to specify the type-out. Maybe you want to convert a
> List to a Set while applying this mapping, or visa versa.

For me, I think it's mainly a conceptual thing. If you want to map and
convert a List to a Set, that seems more appropriately represented as
two operations.

e.g., map(list, function).toSet();


>
> --
> Daniel Pitts' Tech Blog: <http://virtualinfinity.net/wordpress/>

Levi

Andreas Leitgeb

unread,
Apr 23, 2008, 6:29:49 AM4/23/08
to
Patricia Shanahan <pa...@acm.org> wrote:

> Andreas Leitgeb wrote:
>> Unless we can prove, that "nice" Java is also Turing complete, it *is*
>> a justification, because using spaghetti code *may* be inevitable.
>
> Without a specification for "nice" Java, it is, of course, impossible to
> prove *anything* about it.

I feared/expected this question would come up some day :-)
So what are the criteria to determine merely Java-wrapped
spaghetti code from, well, the rest.

Obviously, it's not the "switch" as such, because that could be
equivalently done with a couple of "if"s, or even by invoking
overridden methods through an interface-typed variable, to
which instances of different Implementations get assigned
as a means of state-transition. Thus, even
while (state!=null) { state = state.transit(); }
could be just a cheap wrapper for spaghetti code.

If I were to restrict the loops to "provably" terminating (or
not terminating) ones (which I had in mind, previously), then
it would no longer determine spaghett'ity but only complexity
of the implemented problem. Especially my sample spaghetti
could turn out to be provable, for some implementations
of the called methods.

How could one even make a characterization of implementations of
statemachines, without making it a trivial one like "all are".

From "http://en.wikipedia.org/wiki/Structured_programming":

" Some programs, particularly parsers and communications protocols,
" have a number of states that follow each other in a way that is
" not easily reduced to the basic structures.

I wonder, if the "not easily" refers to the process of wrapping
them in a "goto-free" language (which I'd see as rather easy, as
long as the language provides variables, unpredetermined loops
and conditionals),
or if it refers to some concept that I'm still searching for.

Lew

unread,
Apr 23, 2008, 7:38:35 AM4/23/08
to
Andreas Leitgeb wrote:
> as a means of state-transition. Thus, even
> while (state!=null) { state = state.transit(); }
> could be just a cheap wrapper for spaghetti code.

That is not inherently spaghetti code. It seems to me that your thesis boils
down to the proposition that certain people can write lousy code in any
programming style. I would venture to say that that is a lot of people, based
on code that I've had to maintain over the years. I've also seen good
spaghetti code, too - the original Crowther & Woods /Adventure/ source (in
FORTRAN) is hopeless to read. I felt like I was lost in a maze of twisty
little passages, all alike.

Plugh.

--
Lew

Andreas Leitgeb

unread,
Apr 23, 2008, 7:37:18 AM4/23/08
to
Peter Duniho <NpOeS...@nnowslpianmk.com> wrote:
> You would have to first justify some spaghetti code as being a desirable
> implementation of some goal or specification,

If spaghetti code *were* a desirable implementation, there'd not be a
reason to convert it to anything else :-)

The question is rather why such an implementation even exists:
- it might have been written in a spaghetti language (and an
according programmer's mindset) in the first place.
(BASIC, FORTRAN, machine code, Java bytecode, ...)
- it was the "easiest" way to model some unstructured
specification, like a parser or network protocol.

What one can do about them, is to identify (as exactly as
worth the effort) all jump targets, and split the spaghetti
at those places into separate chunks.

In some cases, one can arrange these chunks as nested conditional
blocks and loops even with the restriction that no other conditions
and no other holders of state information may be used than
those in the original code)

That was my original idea of a "conversion" in contrast to
mere wrap-up.

Where such a conversion is not possible, the only way left is to
introduce new state-information that vaguely represents the
instruction pointer for the original code.
That is: emulation/wrapping of the original.

> Now, all that said, I believe that the following is a fair representation
> of the code you posted:

Yes it is. (further shortened just for sake of short quotations)
> while (blah() || !foo() ) { while (!snarf()) {} }
Really nice: it doesn't require any extra state variables.

> Translating one single example doesn't actually prove anything, except
> possibly that coming up with code that's _really_ spaghettied beyond all
> salvation is probably harder than one might think. :)

How could one tell spaghetti code that allows this kind
of conversion from other that doesn't, and does this
other kind even provably exist?

> But it should at least suggest to you that even code that
> look unstructured may in fact have structure after all.

Indeed, I wasn't aware it would be so easy :-)

Andreas Leitgeb

unread,
Apr 23, 2008, 7:51:11 AM4/23/08
to
Andreas Leitgeb <a...@gamma.logic.tuwien.ac.at> wrote:
> Obviously, it's not the "switch" as such, ...

> How could one even make a characterization of implementations of
> statemachines, without making it a trivial one like "all are".

I now know why I failed: The restriction I had in mind wasn't
really on the resulting (Java) code, but on the structurization
itself:

If, for the conversion to "goto-free" a new explicit state-
variable is introduced that mimics the instruction pointer
in the spaghetti language, then it's wrappage, otherwise
it's structurization.

The result of a structurization may still show all signs of
statemachines or whatsoever, namely if the original spaghetti
code implemented such a machine (apart from having been
interpreted by one, e.g. the CPU).

Daniel Pitts

unread,
Apr 23, 2008, 10:36:53 AM4/23/08
to
I hate to say it, but that's just not the Java way.
When programming in Python, write Python, but in Java, write Java. :-)

I can see the usefulness of your "map" utility, but think about this...
The only way to pass in a "function" is to create a class that
implements your interface.
A for-each construct is fewer lines of code (and an easier-to-understand
construct)

Peter Duniho

unread,
Apr 23, 2008, 12:32:46 PM4/23/08
to
On Wed, 23 Apr 2008 04:37:18 -0700, Andreas Leitgeb
<a...@gamma.logic.tuwien.ac.at> wrote:

> Peter Duniho <NpOeS...@nnowslpianmk.com> wrote:
>> You would have to first justify some spaghetti code as being a desirable
>> implementation of some goal or specification,
>
> If spaghetti code *were* a desirable implementation, there'd not be a
> reason to convert it to anything else :-)

I think we're going in circles. My point with the phrase "desirable
implementation" was taking as granted your assumption that there's a
_reason_ the code is spaghetti code. That is, there's something about the
specification that, at least at first glance, seems to mandate spaghetti
code.

If we assume that assumption to be false, I take it as trivially true that
you can convert the spaghetti code to structured code, because by assuming
the previous assumption to be false, that's the same as saying that the
original specification can be described in a structured way.

By "desirable" I don't mean that I would actually like spaghetti code. I
simply mean that there's something about the problem specification that
led to the spaghetti code (as opposed to dealing with an incompetent
programmer...frankly, that latter situation is the only time I've actually
seen spaghetti code).

> [...]


> Where such a conversion is not possible, the only way left is to
> introduce new state-information that vaguely represents the
> instruction pointer for the original code.
> That is: emulation/wrapping of the original.

And that is a perfectly reasonable solution in a language without a "goto"
statement, IMHO. I personally would prefer such a solution in any case,
but I never once suggested that reimplementing spaghetti code without a
"goto" statement would make for attractive code. I only said that it
would be possible.

> [...]


> How could one tell spaghetti code that allows this kind
> of conversion from other that doesn't, and does this
> other kind even provably exist?

I don't know the answer to the question. My only real exposure to these
kinds of questions is the book "Gödel, Escher, Bach" and it's been some 20
years since I read it. :) These days, I'm much more aligned with the
practical side of things, and from the practical point of view, I don't
really care whether you can prove that unconvertable spaghetti code can
exist. In the real world, in practice, I have never seen spagehtti code
that _couldn't_ be converted, thus I don't worry very much about the lack
of a "goto" statement. :)

Pete

Andreas Leitgeb

unread,
Apr 23, 2008, 1:06:39 PM4/23/08
to
Lew <l...@lewscanon.com> wrote:
> Andreas Leitgeb wrote:
>> while (state!=null) { state = state.transit(); }
>> could be just a cheap wrapper for spaghetti code.

> That is not inherently spaghetti code.

I didn't say it was. But it *could* be - not really
spaghetti code, but a cheap wrapper for it.

> It seems to me that your thesis boils down to the proposition
> that certain people can write lousy code in any programming style.

The proposition itself is of course true, but that
wasn't a point which I was ever trying to make, or
intended to have my points boil down to.

In the end, it's about some state-variables that can be eliminated
by proper structuring, and others whose attempt for elimination has
not been successful (or not even been tried) so far.

Pete meanwhile showed successfully the elimination of the
state-variable from my own small wrapped-spaghetti example.

Andreas Leitgeb

unread,
Apr 23, 2008, 2:45:43 PM4/23/08
to
Peter Duniho <NpOeS...@nnowslpianmk.com> wrote:
> My point with the phrase "desirable implementation" was taking as
> granted your assumption that there's a _reason_ the code is
> spaghetti code.

I did address this aspect in the very next paragraph (which you didn't
quote): It might have been either historical reasons, or an utterly
unstructured specification.
Each of these reasons does not rule out the existence of a structured
solution, and still gives some reason to why a structured solution was not
originally achieved. The "incompetent programmer" is, of course, a third
possible reason, quite distinct from the former two.

>> Where such a conversion is not possible, the only way left is to
>> introduce new state-information that vaguely represents the
>> instruction pointer for the original code.
>> That is: emulation/wrapping of the original.
> And that is a perfectly reasonable solution in a language without a "goto"
> statement, IMHO. I personally would prefer such a solution in any case,

So, you find your translation of my sample less attractive than my sample?
Or did I just misunderstand the alternatives you had in mind for your
preference. There surely exist even less attractive solutions than
wrapping.

>> How could one tell spaghetti code that allows this kind
>> of conversion from other that doesn't, and does this
>> other kind even provably exist?

> I don't know the answer to the question. My only real exposure to these
> kinds of questions is the book "Gödel, Escher, Bach" and it's been some 20
> years since I read it. :)

But you do have that advantage :-) I think I tried once, but
found myself incapable of understanding it - my thoughts just
kept drifting away, until I gave up on it.

> In the real world, in practice, I have never seen spagehtti code
> that _couldn't_ be converted, thus I don't worry very much about
> the lack of a "goto" statement. :)

I do believe in a practical difference, whether such a conversion
takes an extra state-variable, or not. However, the lack of
"goto" in Java is indeed just a very minor syntactic issue.

Peter Duniho

unread,
Apr 23, 2008, 7:26:26 PM4/23/08
to
On Wed, 23 Apr 2008 11:45:43 -0700, Andreas Leitgeb
<a...@gamma.logic.tuwien.ac.at> wrote:

> Peter Duniho <NpOeS...@nnowslpianmk.com> wrote:
>> My point with the phrase "desirable implementation" was taking as
>> granted your assumption that there's a _reason_ the code is
>> spaghetti code.
>
> I did address this aspect in the very next paragraph (which you didn't
> quote): It might have been either historical reasons, or an utterly
> unstructured specification.

A "historical reason" doesn't justify spaghetti code. It might explain
it, but it doesn't justify it. An unstructured specification may or may
not imply a need for spaghetti code. It might just mean that the
specification needs fixing.

As I said, I've never seen spaghetti code that actually needed to be
spaghetti code. However, I'm not going to waste time saying it can't
exist, because I don't know that to be true for sure. But, inasmuch as
there might be code that _needs_ to be spaghetti code, that would imply
that the spaghetti implementation is "desirable".

That's all I mean. There's no point in you getting too hung up on that
point.

> [...]


>>> That is: emulation/wrapping of the original.
>> And that is a perfectly reasonable solution in a language without a
>> "goto"
>> statement, IMHO. I personally would prefer such a solution in any case,
>
> So, you find your translation of my sample less attractive than my
> sample?
> Or did I just misunderstand the alternatives you had in mind for your
> preference.

You misunderstand. My "preference" is in comparing spaghetti code to
structured code that implements within some interpretation of the
spaghetti code. In that scenario, I prefer the latter.

But I prefer neither over a truly structured solution, such as my revision
of your sample. And as I've said, so far I've yet to run into a problem
that could not be addressed in a structured way. That doesn't mean that
all problems can be address in a structured way, but if there are problems
that don't fit that description, I haven't run into them yet.

Pete

Andreas Leitgeb

unread,
Apr 24, 2008, 8:27:45 AM4/24/08
to
Peter Duniho <NpOeS...@nnowslpianmk.com> wrote:
> A "historical reason" doesn't justify spaghetti code. It might explain
> it, but it doesn't justify it.

With this meaning of "justify", the question about existence
of justified spaghetti code is identical to the question
I posed.

> You misunderstand. [...]
That's fine. I'd have been upset otherwise :-)

0 new messages