Still no typedef

R

Robert M. Gary

I"m looking at 1.6 right now and am surprised we still don't have the
concept of typedef (as we do in C, C++). I use Generic's a lot and
often find that declaring an iterator for a Generic can take two lines
of code. In C++ we could take the big long string that includes the
iterator class, all its Generics (we called the template params in C+
+) and make it a single word to be used throughout the program. I was
so happy when Java finally decided to use Generics (since C++ has had
them forever) but thought it was a mistake to not include typedefs at
the same time.

-Robert
 
L

Lew

Hunter said:
So why don't you just use C++?

You don't need typedef in Java, so there'd be no point to it.

C++ doesn't have generics, it has templates. Not even close to the same thing.

C# has generics, and they're reifiable. Except for where reifiability is
important, they are a lot like Java generics.

Even being compile-time only, as Java generics are, they're still quite useful.

I have no idea what in blazes the OP is going on about with
In C++ we could take the big long string that includes the
iterator class, all its Generics (we called the template params in C+
+) and make it a single word to be used throughout the program.

None of that remark made any sense to me.

Types in Java are already one word. Generic types have two, typically, not
exactly a huge burden. Those "extra" words are not superfluous - they are the
nut of why we use generics in the first place, in that they are the words that
enforce type safety at compile time. If we want a "typedef" for a generic
type, we /could/ just use the raw type. Of course, then we'd have to add
whole extra *lines* of code to replace the type safety guaranteed by the
generic types.

This win goes to Java.

Now if the OP could show in concrete terms what a "typedef" might be in Java,
and how it would make any positive difference at all, we could have a
discussion. I am not seeing it - neither a reasonable definition of what a
"typedef" would be, nor how it would help.
 
L

lord.zoltar

Not to mention, typedef has limited uses and doesn't actually improve
code IMO.

I dunno... I thought they were somewhat useful, but to me they seemed
mostly like syntactic sugar. Maybe I never saw any brilliant examples
of usage.

I wonder if it would be possible to fake typedefs with Java
annotations...
 
R

Robert M. Gary

Hunter Gratzner wrote:
You don't need typedef in Java, so there'd be no point to it.

C++ doesn't have generics, it has templates. Not even close to the same thing.

Well, I don't really have time to teach you C++ templates in this
thread but I think if you did some research you would have a better
understanding of what they do. Besides, I already tought one class on
this at the University you could have attended that or you can do your
own research.
Now if the OP could show in concrete terms what a "typedef" might be in Java,
and how it would make any positive difference at all, we could have a
discussion. I am not seeing it - neither a reasonable definition of what a
"typedef" would be, nor how it would help.

I think as you gain experience in generics more in Java you will find
that by the time you delare the iterator, pass it a few classes for
its generic's parameters, then pass its contructor a container that
requires a couple of class for its generics description you will find
that declaring a single iterator can require more than one line of
code. Typedefs make this much cleaner.

-Robert
 
R

Robert M. Gary

So why don't you just use C++?

Ok, so if there are a lot of nice things in Java but one nice thing in
C++ you would prefer to use C++? I'm not following your logic.
I've been a software development architect for about 15 years now,
there are some places where C++ is nicer but a logical person would
not throw out the baby with the bath water.

-Robert
 
A

Andreas Leitgeb

I dunno... I thought they were somewhat useful, but to me they seemed
mostly like syntactic sugar. Maybe I never saw any brilliant examples
of usage.

After reading Robert's post, I actually found myself agreeing to him,
out of a sense of general typing lazyness.

If it were ever implemented, then either in terms of module-scoped
shortcut syntax (vaguely the same approach as "import")
e.g. this could look like:
import HashMap<String,Integer> as SIHashMap;
(not that it was even remotely likely to ever happen)

Another approach would be with a class that is auto-generated from the
generic class (and derives from it), and has all the parameter types
replaced by the given ones, and passes on all the c'tors to
the generic original.
This is something, a third-party tool could do, so one wouldn't
depend on what the Java-gods decide... but then again, it would
induce a little runtime-penalty (for the constructors), which is still
quite a high price for some mere source convenience...

Maybe I better not mention approaches boiling down to a preprocess...
(damn, too late :)
I wonder if it would be possible to fake typedefs with Java
annotations...
I have no idea, how this could work.
 
A

Arnauld.Loyer

I don't think it's a debate for the best language, just that declaring
some variable using generics can be quite long.

Map<String, Container<Entity, Comparator<Entity>>> myVariable=...
Iterator<Container<Entity, Comparator<Entity>>> iterator =
myVariable.values().iterator();

suppose the definition of Entity contains also some generics :
Entity becomes Entity<Node, RendererType>

the declaration of the Iterator becomes :

Iterator<Container<Entity<Node, RendererType>, Comparator<Entity<Node,
RendererType>>>>
iterator = ...

which becomes quite long :(


using a kinf of type def :

typedef Entity<Node, RendererType> nodeEntity;
typedef Container<nodeEntity, Comparator<nodeEntity>> containerEntity;

the iterator becomes :
Iterator<containerEntity> iterator = ...
shorter and more readable

Arnauld
 
L

Lew

Robert said:
Well, I don't really have time to teach you C++ templates in this
thread but I think if you did some research you would have a better
understanding of what they do. Besides, I already tought one class on
this at the University you could have attended that or you can do your
own research.

Quite all right, I have certainly used C++ templates plenty in my C++ programming.
I think as you gain experience in generics more in Java you will find
that by the time you delare the iterator, pass it a few classes for
its generic's parameters, then pass its contructor a container that
requires a couple of class for its generics description you will find
that declaring a single iterator can require more than one line of
code. Typedefs make this much cleaner.

I have been using generics for quite some time now. Since they came out, in
fact. I also constantly read material on their use, including frequent
re-reads of the Sun tutorials on the matter, and the JLS itself. My comments
were informed by that experience. Not that your /ad hominem/ remarks either
required a response or in any way addressed the points I made.

How about this declaration of an iterator and its use?

List <String> names = fillNames();
for ( String name : names )
{
System.out.println( name );
}

Yep. Generics sure made that verbose.

As I pointed out, the "extra" use of "String" (ooh, that one-word overhead!)
serves a purpose - to guarantee the type safety of the String operations.

You still haven't shown any example of how a Java "typedef" would work. How
about in the scenario I presented?
 
L

Lew

I don't think it's a debate for the best language, just that declaring
some variable using generics can be quite long.

Map<String, Container<Entity, Comparator<Entity>>> myVariable=...
Iterator<Container<Entity, Comparator<Entity>>> iterator =
myVariable.values().iterator();

suppose the definition of Entity contains also some generics :
Entity becomes Entity<Node, RendererType>

the declaration of the Iterator becomes :

Iterator<Container<Entity<Node, RendererType>, Comparator<Entity<Node,
RendererType>>>>
iterator = ...

which becomes quite long :(


using a kinf of type def :

typedef Entity<Node, RendererType> nodeEntity;

Type names should start with an upper-case letter.
typedef Container<nodeEntity, Comparator<nodeEntity>> containerEntity;

the iterator becomes :
Iterator<containerEntity> iterator = ...
shorter and more readable

public void shortcutMethod()
{
class NodeEntity extends Entity <Node, Renderer> {}
NodeEntity entity;
...
}

Only works with extendable classes, of course, and has consequences.

But why give up the documentation value of the generic types? That seems like
false economy to me.
 
W

Wojtek

I don't think it's a debate for the best language, just that declaring
some variable using generics can be quite long.

Ten years ago I would completely agree with you.

But not now. Modern IDEs remove the "I had to do a lot of typing" issue
with context sensitive variable and class help.

So the length of the line is moot. But the readability is sure
improved. Rather than chasing down where the typedef was defined to see
what it meant, you simply read the line. And it could be buried in any
of the many included header files.

And I did do C programming for many years.
 
A

Andreas Leitgeb

Wojtek said:
But not now. Modern IDEs remove the "I had to do a lot of typing" issue

Maybe they save the typing, but they don't help with
reading over that bulk lateron :)
So the length of the line is moot. But the readability is sure
improved. Rather than chasing down where the typedef was defined

Well, as you mentioned "Modern IDE"s: right-click -> view-definition
(or simply with vim: said:
And it could be buried in any
of the many included header files.

Fortunately not in Java :)
 
A

Andreas Leitgeb

Lew said:
How about this declaration of an iterator and its use?
List <String> names = fillNames();
for ( String name : names )

If all the uses were that short and simple, then there indeed
would not be any desire for a typedef-alike at all :)

Even if there were typedefs, anyone using them for that
example should be ... (* enter punishment of your choice :) *)
 
L

Lew

Andreas said:
Fortunately not in Java :)

Imports could be just as bad. If the typedef were importable, it'd be no more
useful for self-documenting code than a raw type is.

I don't think the verbosity of generic types is wasted or redundant or
unnecessary or even undesirable. The type arguments are the /raison d'être/
of generics, and they do often "alias" to single-letters, at least in the
declarations:

public class Foo< T extends Comparable<? super T> >
{
T member; // all the benefits of typedef in here
}

OK, let's return to the iterator example, which is verbose, I agree.

List <Foo<Comparator<Integer>> stuff
= new ArrayList <Foo<Comparator<Integer>> ();

Iterator <Foo<Comparator<Integer>> iter = stuff.iterator();

for ( Foo<Comparator<Integer> foo; iter.hasNext(); )
{
foo = iter.next(); // phew, by hear at least all that verbiage is gone
}

Of course, the syntactic sugar in this particular use case is already present
in the enhanced for loop. so typedef would only be useful for other iterator
scenarios, such as when you remove() or add() through an iterator. Let's
pretend this is that.

The typedef would add one line of code and reduce the generic overhead from
four repetitions to one.

typedef FooInt Foo<Comparator<Integer> FooInt;

List <FooInt> FooList stuff
= new ArrayList <FooInt> ();

Iterator <FooInt> iter = stuff.iterator();

for ( FooInt foo; iter.hasNext(); )
{
foo = iter.next(); // phew, by hear at least all that verbiage is gone
}

Of course, that only got rid of part of the overhead. Now we need another
typedef to get rid of the FooInt.

typedef FooInt Foo<Comparator<Integer> FooInt;
typedef List <FooInt> FooIntList;

FooIntList stuff
= new ArrayList <FooInt> ();

Iterator <FooInt> iter = stuff.iterator();

for ( FooInt foo; iter.hasNext(); )
{
foo = iter.next(); // phew, by hear at least all that verbiage is gone
}

Huh, that only got one out at the cost of one, plus a whole typedef line. The
same would happen for ArrayList <FooInt> and Iterator <FooInt>. Plus all
these typedef names would start to be an overhead of their own, having to
remember their meaning as well as the more common "List", "ArrayList" and
"Iterator".

List <Foo<Comparator<Integer>> stuff
= new ArrayList <Foo<Comparator<Integer>> ();

Iterator <Foo<Comparator<Integer>> iter = stuff.iterator();

for ( Foo<Comparator<Integer> foo; iter.hasNext(); )
{
foo = iter.next(); // phew, by hear at least all that verbiage is gone
}

In certain ways the original is clearer, at least to me. The words "List",
"ArrayList", "Iterator" and "Foo" leap out at me, and the generic stuff
remains noise until I focus on it, at which point it provides a nice safe
feeling of matching types. So in casual reading I see the raw types, and
algorithm is perfectly readable. In detailed reading the detail is only
slightly more dense than what a typedef would show.

So to typedefs in Java, I say, "Pllpppllplpllpppttthh!"
 
L

Lew

Andreas said:
If all the uses were that short and simple, then there indeed
would not be any desire for a typedef-alike at all :)

Even if there were typedefs, anyone using them for that
example should be ... (* enter punishment of your choice :) *)

I feel that the burden of proof is on the typedef proponents to show how it
would serve in a more complex example. Nevertheless, I provided such an
example and how it actually does not favor typedef, in another part of this
thread.
 
D

Daniel Pitts

I don't think it's a debate for the best language, just that declaring
some variable using generics can be quite long.

Map<String, Container<Entity, Comparator<Entity>>> myVariable=...
Iterator<Container<Entity, Comparator<Entity>>> iterator =
myVariable.values().iterator();

suppose the definition of Entity contains also some generics :
Entity becomes Entity<Node, RendererType>

the declaration of the Iterator becomes :

Iterator<Container<Entity<Node, RendererType>, Comparator<Entity<Node,
RendererType>>>>
iterator = ...

which becomes quite long :(


using a kinf of type def :

typedef Entity<Node, RendererType> nodeEntity;
typedef Container<nodeEntity, Comparator<nodeEntity>> containerEntity;

the iterator becomes :
Iterator<containerEntity> iterator = ...
shorter and more readable

Arnauld
There is talk of using type inference to help reduce the verbosity of
generics.
 
W

Wojtek

Lew wrote :
Imports could be just as bad. If the typedef were importable, it'd be no
more useful for self-documenting code than a raw type is.

But header file can be really evil. Not only for typedefs, but also for
macros (#defines). You really need to know what is in a header file, or
else your program will behave in bizarre ways (I may have the syntax
wrong, its been a while):

-------------------------
// no ints allowed!
typedef int long
typedef LONG long
-------------------------

And before someone says "WHY would anyone do this?", I would reply that
it does happen. Someone started out with an int, and decided that a
long was needed, but was too lazy to go through all the code.

Now you as a maintenance programmer must find out just why an int is 64
bits long.
 
D

Daniel Pitts

Wojtek said:
Lew wrote :

But header file can be really evil. Not only for typedefs, but also for
macros (#defines). You really need to know what is in a header file, or
else your program will behave in bizarre ways (I may have the syntax
wrong, its been a while):

-------------------------
// no ints allowed!
typedef int long
typedef LONG long
-------------------------

And before someone says "WHY would anyone do this?", I would reply that
it does happen. Someone started out with an int, and decided that a long
was needed, but was too lazy to go through all the code.

Now you as a maintenance programmer must find out just why an int is 64
bits long.
I believe you just made "long" a reference to the type "int" and then to
the type "LONG".

I also don't think you can override types like that.

Although, the point about #define is a good one.

The truth is that someone started out with an int, but should have used
a specific value type that avoids primitive obsession.
<http://virtualinfinity.net/wordpress/program-design/2007/10/28/primitive-obsession/>
 
A

Andreas Leitgeb

Lew said:
I don't think the verbosity of generic types is wasted or redundant or
unnecessary or even undesirable. The type arguments are the /raison d'être/
of generics,

In my own opinion, the /raison d'être/ of generics is, that one writes code
once, "generically", and the user can still use it in a type-safe way on
a number of different Client-classes. It's certainly not the particular
syntax that completely describes the nature of the assembly at every
place of usage.
One can also give a name to a class, instead of completely re-specifying
it whereever one uses it. So why shoud it now be bad (apart from that
it's not possible in current and near-future Java) to give a name
to a certain generics-assembly?
OK, let's return to the iterator example, which is verbose, I agree.
List <Foo<Comparator<Integer>> stuff
= new ArrayList <Foo<Comparator<Integer>> ();
Iterator <Foo<Comparator<Integer>> iter = stuff.iterator();
for ( Foo<Comparator<Integer> foo; iter.hasNext(); )
The typedef would add one line of code and reduce the generic overhead from
four repetitions to one.
That's it.
typedef FooInt Foo<Comparator<Integer>> FooInt;
huh? why two FooInt's?
Of course, that only got rid of part of the overhead. Now we need another
typedef to get rid of the FooInt.
No need to get rid of that. If it's small enough, we really don't need to
overdo it.
 

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,770
Messages
2,569,584
Members
45,078
Latest member
MakersCBDBlood

Latest Threads

Top