Sunday, December 01, 2002


Connecting Objects.

I've just spent the past two hours with Together/J, creating a nice model of a timeline system I've been thinking about.  I'm happy with the way it's come together; all the relationships appear to be in the right place and it just screams "pretty" in UML, with nice annotations all over the place about the cardinality and nature of the relationships.  TJ has dutifully created all the requisite Collections objects for me, ensuring that I have a place for all the connections.

Which is exactly what's bothering me.  Sure, I want to model everything this way, so I can see the relationships on my diagram.  But I don't want to use that kind of connection management.  In my model, just about everything needs to know how it's connected to everything else.  When an object is removed, I want to quickly remove all trace of it from the model.  This is a very general problem that most applications come across, and most of the time (unless simplicity is an issue) I like to have a connection manager class that knows how to create, constrain, and remove the relationships between the objects in a model.  This makes most aspects of lifecycle management pretty easy. Any object can quickly find out what objects are related to it, how they're related, and they don't have to keep track of (or listen for) lifecycle events.  Only the relationship manager does that.

I wish my modeling tool supported this kind of thing.  It doesn't.  I wish Java had this pattern in it; it doesn't.  I am not a big fan of publish/subscribe.


4:02:17 PM    

Language Plugins.

Separation of language and runtime is a good thing, without a doubt. .NET gets this right -- compile with whatever language you want, run on the same platform. So far, so good. But we're coders. And what's more, we're coders who have gotten used to some pretty cool toys. I don't know about you, but I like having syntax highlighting, refactoring, and so forth available to me. It saves me a lot of time.

I'd like to see the Java platform (and .NET for that matter) support multiple languages more effectively. To do this and fully participate in a modern coder's style, a language plugin needs to do a lot more than just supply compilation from source text to some runtime format.

It seems to me that if a platform can support multiple languages it should fully define various levels of support from a language runtime. Categories of support include compilation, inclusion of debugging information, evaluation of expressions at runtime given a context, and universal data structures that correspond to syntactic elements, refactoring support, and intelligent code completion. Your FORTRAN language pack for the Java VM should be able to indicate to the runtime (and any IDE) which of the general extension categories it supports.

Most of the IDE vendors out there have created something like this for Java (and some, like TogetherSoft, have done it for other languages too). Many language people have done something similar for .NET, but the support doesn't seem to extend past compilation. I think the spec should be built into the platform. Languages will then be able to exhibit very advanced capabilities into a multitude of IDEs, and we'll all be better off.

I'll be able to do my functional programming under some neutral VM, and I won't lose my super-cool code completion and other features like it.

That's my language nirvana.
1:49:59 PM    


More Functional Java.

There are plenty of smart people in the functional world. There are plenty of extra cool languages out there (OCaml is one of the most interesting ones, as is Haskell). With Java I think we are in a kind of 90/10 situation -- what key functional features might we add to the language and VM specification that will really help us write better code?

Whatever we choose must have as minimal an impact on the language as possible. Strong typing is a considerable virtue, in my opinion. So are exceptions, so whatever functional notation we choose we will want to support exceptions fully.

class Example {
public function double ComputeThis(String p1, double p2) throws SomeException;
public function double SecondOrder(ComputeThis computerThis, double outer) throws SomeException;
} ;

In that example I'm declaring a first and second order function, both of which are declared to throw an exception. We can now call these functions at will and have them participate fully in the exception mechanism. If a function is defined to take another function, it must declare in its throws clause a superset of the exceptions that are thrown by the parameter function (I think).
1:34:03 PM    


Functional Java.

Joe's latest I think we're really getting at a similar thing : blocks and function pointers (and inner classes to a certain arguable extent) are closureish.

C# has a similar system (delegates) that allows member functions to be defined, however it doesn't support the notion of inline functions (shame).

Joe knocked one line out of my example that I think is somewhat important...you need to be able to declare higher-order functional types. That's just a function that takes a function that takes a function etc...these are pretty handy for solving certain types of problems. The point is, a function is defined in terms of its inputs and its output. Compatibility is pretty important -- the compiler can verify that two functional types are compatible quite easily.


12:34:14 PM