looping through a list, starting at 1

C

Chris Riesbeck

Since I see postincrement a lot more than I see preincrement and since
i++ is idiomatic in that construct, when seeing ++i I tend to stop and
wonder whether the writer intended something else. So I suppose it might
matter if engendering a sense of distrust or unease in maintenance
programmers matters.

Makes no difference in this context for C and Java. In C++, an
overloaded postfix ++ for a user data structure typically has to create
and return a temporary, so modern C++ guides often recommend getting
into the ++i habit, and using i++ only when you really need it. But no
recommendation to rename the language to ++C yet.
 
S

Stefan Ram

Chris Riesbeck said:
But no recommendation to rename the language to ++C yet.

»Around 1983 Rick Mascitti suggested C++. It's a pun
off of the ++ operator in C, which deals with
incrementing something (although it is semantically
problematic since it should really be ++C)«

http://www.comeaucomputing.com/techtalk/

»The name C++ and its runner up ++C are fertile sources
for jokes and puns - almost all of which were known and
appreciated before the name was chosen. The name C++ was
suggested by Rick Mascitti. It was first used in
December of 1983.«

http://www2.research.att.com/~bs/bs_faq.html
 
M

markspace

So what operator should have been used for String concatenation, instead
of overloading "+"?


I think the obvious interpretation of my comment should be "user defined
operator overloading."
 
E

Eric Sosman

So what operator should have been used for String concatenation, instead
of overloading "+"?

(Aside: I know of a language that used "||" for this purpose.)

This "overload" is feeble at best: "+" is overloaded six ways,
"-" five, "*", "/", "%", "++", "--", "<", "<=", ">", and ">=" four
each. "==" and "!=" and "=" and "." and "instanceof" are overloaded
to an infinite degree (countable, I think). So what?
 
S

Stefan Ram

Eric Sosman said:
This "overload" is feeble at best: "+" is overloaded six ways,
"-" five, "*", "/", "%", "++", "--", "<", "<=", ">", and ">=" four
each. "==" and "!=" and "=" and "." and "instanceof" are overloaded
to an infinite degree (countable, I think). So what?

The JLS 3 defines »overloading« for methods in 8.4.9 and 9.4.2
and for constructors in 8.8.8. So one cannot derive from the
JLS that any operator in Java is overloaded at all.

One also might define it semantically as »having several
different meanings (depending on the static argument type)
when expressed in the English language«.

Then, »+« has two overloads »plus« and »concatenated with«,
but one might get by with counting only one overload »plus«
when one can mentally subsume string concatenation under the
English conjunction of »plus«.

»+« for strings has something natural, given then it makes
»length« to be similar to a kind of

http://en.wikipedia.org/wiki/Ring_homomorphism

(not precisly), given that

length( s + s1 )= length( s )+ length( s1 ),
length( s + "" )= length( s )+ 0,

and, with Perl's »x« operator (written as »*« below), for
an int value i, even

length( s + s + ... + s [i times] )= length( s * i )
length( s + s1 * i )= length( s )+ length( s1 )* i,
length(( s + s1 )* i )=( length( s )+ length( s1 ))* i
length( "" * i )= 0 * i, and possibly more

hold.
 
R

Raymond Tong

If the List has implemented RandomAccess interface, the latter
approach (i.e. calling get(i)) is preferred.
Otherwise, the former (i.e. getting the iterator) is preferred.

e.g. ArrayList implemented RandomAccess which backed by Array.
Calling get(i) simply return the array element. But has little
overhead on creating the Iterator instance.

e.g. LinkedList does NOT implement RandomAccess
Calling get(i) needed to iterate from the first node until (i)th
element.
But create the Iterator once would same time for a large size list.

In conclusion, depeneds on the implementation of your list.
if (list instanceof RandomAccess) {
// latter
} else {
// former
}
 
R

RedGrittyBrick

We could use '.'

Then we could use '->' for method invocation.

And '::' for class namespace separators (or whatever they are called).

;-)
Why should the appropriateness of an operator overloading be affected by
who did it?

It shouldn't but I imagine markspace's objection might have been that
whilst we all learn about the varied uses of '+' at the start of
learning Java, I expect it can be a little perplexing when you encounter
a '+' that makes no sense until you find where the original programmer
defined an overload of that operator. Even worse might be a '+' that
apparently makes sense but where you do not realise that the operator
has been overloaded. Is this possible?
 
R

Raymond Tong

It depends on the implmentation of list.
If the list implements RandomAccess interface, it is recommended to
call get(i) instead of using iterator().

e.g. ArrayList implements RandomAccess interface and backed by Array.
Calling get(i) would simply return (i)th element in an array which is
quick.
Creating an iterator has little overhead on creating an instance of
Iterator object.

e.g. LinkedList does NOT implement RandomAccess.
Calling get(i) need to look from the fist node to (i)th element which
is slow if i is large.
Creating an iterator is one time action which save time for sequential
lookup.

if (list instanceof RandomAccess) {
// get(i)
} else {
// iterator
}
 
A

Andreas Leitgeb

markspace said:
See? This is why I'm against any kind of operator overloading in Java.

*All* generalizations are bad.

This little wart of idiomatic postIncr extended from primitives
(where it didn't really matter) to object types (where it does
matter) shouldn't be generalized to all operators.

(and the other "wart" about overloading << and >> for streams
in C++ is just subjective judgement. I don't find it all that
bad, myself. It fits well to the look of the symbol indicating
direction of data-flow, unlike e.g. mathematical ops, which
are "just" convention. )
Too much stupid out there.

Maybe Java just isn't for the masses -- they all have their
own mind on coding, not adhering to my own. (*irony*)
 
S

Stefan Ram

Patricia Shanahan said:
Why?
I'm dealing right now with some code that followed that
advice, so that changes will be needed throughout the code to
change the choice of List implementation. The only reason
random access is needed is because of code that could have
used iterator(), but didn't.

You remind me of:

»Imagine finding every 'switch' statement in a program
and editing it. With fewer conditionals and more
polymorphism, you change implementation by changing the
concrete classes. The abstract classes, and their
clients, avoid changes: OpenClosedPrinciple.

This is the heart of why ObjectOrientedProgramming is
better.«

http://c2.com/cgi/wiki?ReplaceConditionalWithPolymorphism
 
G

Gene Wirchenko

On 04/08/2011 22:46, Patricia Shanahan wrote:
[snip]
Why should the appropriateness of an operator overloading be affected by
who did it?
It shouldn't but I imagine markspace's objection might have been that
whilst we all learn about the varied uses of '+' at the start of
learning Java, I expect it can be a little perplexing when you encounter
a '+' that makes no sense until you find where the original programmer
defined an overload of that operator. Even worse might be a '+' that
apparently makes sense but where you do not realise that the operator
has been overloaded. Is this possible?

Of course.

Sincerely,

Gene Wirchenko
 
L

Lew

Volker said:
In that case, I'd go for something like

if (l instanceof RandomAccess) {

Tests on type like this are an antipattern.

Like many antipatterns there are occasions when one might consider its use anyway, but it's a red flag that we're probably going about things the wrong way.
 
L

Lew

Roedy said:
Stefan Ram wrote, quoted or indirectly quoted someone who said :

This one is clearer. The problem is most people will just glance at it
and read it as for( int i=0; i<l.zise(); i++ )

I think you mean i++ not ++i.

Huh??

Personally I find the prefix operator more accurately expresses the semantics of the loop.

Not that it makes a whole lot of difference, but why extract the previous value of 'i' for the garbage disposal when it's the subsequent value that's relevant?

There's absolutely nothing wrong with the pre-increment operator and an argument that it's actually superior for this idiom.
 
A

Andreas Leitgeb

Lew said:
Tests on type like this are an antipattern.
Like many antipatterns there are occasions when one might
consider its use anyway, but it's a red flag that we're
probably going about things the wrong way.

Are marker-interfaces (which RandomAccess is, iirc) already an
antipattern, or is there a different way to check for them,
or are marker-interfaces just one of the occasions where one
would just acknowledge and consciously ignore the red flag?

PS: I fully agree with your judgement *outside* the context
of marker-interfaces, and am eager to learn *inside* that
context.
 
A

Arved Sandstrom

Are marker-interfaces (which RandomAccess is, iirc) already an
antipattern, or is there a different way to check for them,
or are marker-interfaces just one of the occasions where one
would just acknowledge and consciously ignore the red flag?

PS: I fully agree with your judgement *outside* the context
of marker-interfaces, and am eager to learn *inside* that
context.

I don't see that marker interfaces are an anti-pattern. I believe that
Bloch's comments with respect to marker interfaces (Item 37 in Effective
Java) make sense: as he points out one ought to consider a marker
interface to be a type definition.

As it is we already have a number of interfaces that have method
declarations, but they are actually the same declarations as that of a
parent. All these interfaces do is to refine a contract, and basically
create a new type just like a marker interface.

AHS
 
A

Andreas Leitgeb

Arved Sandstrom said:
I don't see that marker interfaces are an anti-pattern. I believe that
Bloch's comments with respect to marker interfaces (Item 37 in Effective
Java) make sense: as he points out one ought to consider a marker
interface to be a type definition.

That doesn't make sense to me...
I can trivially create a class that inherits Object and implements
RandomAccess and doesn't offer anything of the Collection-stuff.

How would I write a method (overload) that would only take an
object if it is both List and RandomAccess? (Afaik: no way, but
I might perhaps miss something.)

Lew's argument absolutely makes sense for other types:
Rather than checking for List l, whether (l instanceof ArrayList)
I'd rather make one overload for ArrayList and another one for List.
But I cannot do something like that to separate List&RandomAccess
from List.

It's not the "no-method"-ness of marker interfaces that matters here.
They are just a trick to implement what could otherwise be implemented
with a getter: bool supportsRandomAccess(). As they don't do it with
a method but with an interface, the syntactic way to obtain that "flag"
is using instanceof. I don't see why this would be red-flagged without
red-flagging that concept of marker-interfaces altogether.
 
L

Lew

Andreas said:
Are marker-interfaces (which RandomAccess is, iirc) already an
antipattern, or is there a different way to check for them,
or are marker-interfaces just one of the occasions where one
would just acknowledge and consciously ignore the red flag?

PS: I fully agree with your judgement *outside* the context
of marker-interfaces, and am eager to learn *inside* that
context.

I would need some time with an SSCCE to know if there's a better way in this example, but generally even with marker interfaces you want to lock the type down at compile time rather than with a run-time check. So if it's important that a method use a 'RandomAccess' argument, say, then you might want to declare it as 'method(RandomAccess arg)' and lock down your type assertions so that only the right type reaches the method. With generics you can use type intersections so that something has to be both 'List' and 'RandomAccess' (again, say) even to reach the call or the class or whatever.

It's the run-time type check that one often wishes to avoid. Of course, ifthe logic truly requires it, as it sometimes does, then the antipatternness goes away. I just find that use of 'instanceof' in the world of types and generics frequently signals incompletely thought-out type assertions.

If there were an SSCCE for the particular use case, one might be able to discern a less run-timeish way forward or one might not. I only wished to point out a general principle here.
 
A

Arved Sandstrom

That doesn't make sense to me...
I can trivially create a class that inherits Object and implements
RandomAccess and doesn't offer anything of the Collection-stuff.

How would I write a method (overload) that would only take an
object if it is both List and RandomAccess? (Afaik: no way, but
I might perhaps miss something.)

Pretty much in the standard way, which would take advantage of the
marker interface in a way suggested by Bloch: you create an interface
that extends List and RandomAccess, and concrete classes implement that.

Your method simply has the appropriate argument type, and is
compile-time checked.
Lew's argument absolutely makes sense for other types:
Rather than checking for List l, whether (l instanceof ArrayList)
I'd rather make one overload for ArrayList and another one for List.
But I cannot do something like that to separate List&RandomAccess
from List.

You can - see above. But if you wished to avoid 'instanceof' type
runtime checks, and work with overloads, your API for clients would have
to include that combination interface that client code which supplies
suitable objects agrees to implement.

Short of true multiple dispatch in Java I don't think this is a terrible
solution.
It's not the "no-method"-ness of marker interfaces that matters here.
They are just a trick to implement what could otherwise be implemented
with a getter: bool supportsRandomAccess(). As they don't do it with
a method but with an interface, the syntactic way to obtain that "flag"
is using instanceof. I don't see why this would be red-flagged without
red-flagging that concept of marker-interfaces altogether.
You are talking about runtime type checking and taking implementation
actions based on that knowledge. Your latter paragraph applies to that
situation. I haven't been treating that situation.

I specifically answered your question "Are marker-interfaces (which
RandomAccess is, iirc) already an antipattern". IMO they are not, for
reasons stated. But this non-anti-pattern explanation emphasizes their
use as compile-time new types. Their not inconsiderable utility here
stems from the fact that the marker interface guarantees a behaviour in
a documented contract - it's up to the implementor to meet those guarantees.

AHS
 

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,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top