There’s been a couple of reality-defying
pronouncements (second
one) from Sun folks. Who believes this junk?
I liked this quote from McNealy: “Somebody’s got to be in charge,
or nobody is”. Well, yeah, that’s a strength of our approach. Of
course, it really doesn’t make much sense to talk this way. Yes, it
is usually good to have some central group driving the evolution of a
piece of software. That’s a plus. But if that control is overly
tight, it becomes a minus. On top of that, “overly tight” changes
depending on the situation — there’s no single correct answer.
So, duh, one of the strengths of free software is that it lets
people experiment to try to find out what the “objective situation”
might be at the current moment.
Generics
Right there in the generics specification is some language
explaining that you can’t refer to members of a variable whose
declared type is a type variable, unless the member comes from
Object
. So much for my question and my reading skills.
Yet another goofy restriction though. Sigh. It seems to me that it
could equally well have been designed such that a type variable “looks
like” its collection of bounds, and ambiguity would be resolved with
respect to the set of inherited members. Then there would only be the
issue I raised before.
In other news, perhaps we’ll start a Classpath branch for
generics work soon.
C++
Working with C++ continues to be interesting. It is nicely
expressive, gcjx is about half the raw line count of the current
gcj. That isn’t a completely fair comparison though.
On the other hand, I continue to run into things that C++ can’t
do. For instance, you can’t have a string as a template argument.
This means strange workarounds in some places in gcjx. I still don’t
understand why you can mark a constructor as explicit
but
you can’t mark a cast operator that way. It seems to me that this
would be a nice way to avoid implicit casts.
Unfortunately some C++ lessons I’ve learned a bit late. E.g., if
you want to change the representation of some container, you’re best
off introducing a typedef early on and then using it religiously
wherever you use the container. Ideally you would have one such
typedef per field, I suppose. As it is now, if I want to refactor to
a different representation, I’m in for a lot of work.
You can sort of emulate C# properties by using C++ classes with
various overloaded operators. It isn’t the same since in C++ it is
the field’s type, not the field’s enclosing class, which determines
the triggers — but it is good enough for my purposes. I have a few
of these, where the gettor method is just operator()
,
supplying a function-like interface.
Why would you do something weird like this? It seems to me that
in the absence of good refactoring
tools (and other sorts of restructuring tools), your best bet is
to try to make the text of your program assume some general shape
which can be more easily manipulated. In this case, a method call is
more general than a field access.
Maybe that’s bonkers.
In a similar vein I have kept to the minimum number of global
variables. Right now there are eleven. Of course there could be just
one; ten of them are really just convenience things that I (currently)
“know” to be truly global across all compilations. My opinion is,
whenever you add a global variable or a static field, you are probably
making a mistake. Too bad g++ doesn’t have warnings to let me enforce
this.