Re: Java / Ruby comparison
Posted: Jan 5, 2006 6:40 PM
> I strongly disagree. Readability assumes so many things.
> Readability necessarily impacts your ability to hold some
> number of things in short-term memory. And the reverse is
> also true: how many things you can hold in memory will
> impact how "readable" a passage is to you.
Variable names are inexact. Types can help qualify any information that the variable names might impart.
int lat, lon;
is very different from
double lat, lon;
> It doesn't tell you anything more about
> the meaning of those variables, how they're intended to be
> used, what their value boundaries are (except implicitly
> and I'll say why in a moment). If you have ever tried to
> understand some C code implementing a geographic
> transform, say from State Plane to UTM, you will clearly
> know that type declarations offer almost nothing to
> readability. There is a ton of context that tells you
> about those variables. For example, the function name, the
> algorithm, the use of the variables together, the
> operations performed on them. The declaration of the type
> adds so little, if anything, to all this.
It might seem to add little to you, but it tells me something about the types of calculations to expect to see. It also tells me how to manage injecting new code.
Whether or not you feel this adds value for you, is a matter of preference, education, or knowledge of the subject matter.
What types of math intensive applications do you have experience with? I'd be interested in know how complex these applications are to better understand how you perceive the impact types might have on your typing in math expressions. If the type names on the variables are more effort than the expressions you type, then that's a very interesting application/module/library that I'd like to know more about.
> In a statically typed system like C or Java there are
> several things with which you as the code writer
> and reader must continually wrangle:
> 1. The proper "class" for a declared variable, e.g.
> numerical versus string.
> 2. The proper size for the type, e.g. byte, int, double.
> 3. The proper "higher" type for the result of an
> operation, e.g. int + double = double.
> Note that 1 and 2 usually act like a unit when you think
> about defining a number versus a string variable. However,
> it's hardly so trivial. The various sizes of numeric types
> hardly conveys much meaning but imposes a huge burden on
> the programmer to continually be considering boundary
> conditions that are entirely irrelevant to the algorithm
> but critical to the compiler given it's type system.
There are distinct advantages to the programmers ability to control the complexity of the programs execution through the use of types. For example, time the execution of a FFT using double values in java vs implementing the same algorithm using BigDecimal. This would demonstrate the difference if we just dropped type designations for numeric values and implemented infinite precision math as the native implementation.
This is still an important issue in my mind. I have a Java application that does GSM VOIP compression (http://javecho.dev.java.net) to provide a realtime voice communications system. I'd be interested in see Ruby or Python implementations of this kind of mathematically complex algorithms to get an idea about how their untyped math systems would perform.
> When you read the code, even though the types have been
> explicitly stated, you still have to think of all the
> other issues I mentioned above (or some subset of them) to
> understand the code. And if readability is not directly
> aimed at understanding, then what really is readability?
One of the things about typing is that you can confine an algorithm to using only methods in a superclass. This is often an important part of OO design. This also applies to limiting the exposure of your interface implementation to just the methods in the interface. Java provides this type of control through the type system, and with a security manager active, you can control the access that the reflection API yields to foreign code as well.
> All the foregoing is mostly concerned with very
> rudimentary types like numbers and strings. When you start
> talking about objects, I think static typing even lends
> less understanding. If you have an object and you say
> obj.method, what can happen? The object may not
> have such a method, or you may have misunderstood what you
> thought method did and you don't get the result
> you're after. Both those can easily be tested for. All the
> other content is there and is just as critical, if not
> more so, to understanding the intention of what's being
> done than the type label of the object reference
As I said above, typing helps control the visibility of parts of your implementation in Java. The fact that Ruby and Python have no security built into the language is perhaps one of the reasons why users of those languages don't understand some of the finer points of final classes and immutable implementations.
In Java, we have javadoc that is meant to detail exactly what the outcome of calling that method will be. In other languages, and IDEs supporting those languages, similar facilities are available. I don't know whether Ruby or Python has such context sensitive information available.
Does it? When you are writing Ruby code, how do you correlate your use of an API with the actual implementation details. Do you memorize all the APIs you use, or do you have some type of integrated or secondary documentation system that you access?
> Again, the issue of the threshhold for readability comes
> up. If I use a type label for an object, say BlueWidget,
> but you don't know what that is, you have to go read about
> it. The label won't tell you anything. If there is no type
> label and all you have is obj.method, you still
> have to read something (e.g. a nearby comment, search for
> method in the class browser). Either way, the burden is
> about the same, and this assumes you haven't got a clue
> what you're looking at (except that you know the language)
> when you start reading. That, in itself, is a low
> percentage case, I'd say.
In Java IDEs, type information controls, through polymorphism based analysis, which set of methods you can see in IDEs providing code completion. The names of methods with matching prefixes are displayed and it all works easily.
I don't generally use a fancy IDE, so I have a Folder in my Windows-XP taskbar that pops up a list of javadoc sources that I can select from to get the javadocs for a particular package. From there, I can find the class and look at the methods to find the one that I need.
I, in general, don't fight with the java APIs in a way that your simple confusion base examples are based.
Most of your arguments go on about how typing doesn't solve all problems. It's not meant to solve all problems. It's one of the portions of the total language system that provide the set of features particular to a language.
My experience with first C, then my own dynamic language, then Java have convinced me that the benifits of typing in Java are a good and useful part ofthe language.
> With dynamic typing in the situation above, your
> familiarity quickly grows and you have to look up less and
> less as you learn about the classes being used. More
> importantly, the emphasis switches to how objects are
> interacting, or being acted on, rather than on type
Again, you seem to expect types to solve all types of problems summarily Types can help reduce the choices you have to consider, which can make programming faster. They can also keep you from having methods names with slight variations because you don't have polymorphism. And, they can remove ugly type checking in cases where you decided to keep the same name for a single argument method that handles multiple types of arguments.
In dynamic languages, type polymorphism for overrides like this require type checks, or method name changes. This, I think adds some of the confusion regarding locating the correct method or reading the code that you talk about above.
> With static typing, you are continually confronted with
> questions about picking the right type label for your
> variable and what the programmer intended in picking his.
> You have to worry about casting or declaring a variable as
> a base type of several derived types, etc. And the fact
> that you now have this label doesn't help you to
> understand much about the intent as the code starts
> calling methods on that object.
I disagree that the type doesn't help. The specific types that you seem to allude to are native types in Java such as int vs double. This is informative and necessary for particular types of algorithms.
Casting in Java that is aimless, or confusing, will decrease as people make more use of Generics. It typically only collections or other generic packaging classes that have this issue. It's a known quantity. I've found 2 different long standing bugs, but in dead code, by using generics in Java.
I've found some miss used collections that had duplicate uses where I had intended separation that generics revealed. The type system is a testing system that you can take advantage of without having to write tests. In the case of Generics, you are adding more information for the test system to look at.
> Reading code that has explicit type labels imposes the,
> often superfluous, task of putting into my short term
> memory that a is an int or something so I can then get on
> to look at what operations are performed or methods called
> on a. That additional effort often reduces readability for
What happens with me is that the shorter variable names and types are, the more likely I am to forget. They say that most people can put 5-7 things in their short term memory.
It takes about 30 seconds for things in your short term memory to migrate to longer term memory. So, small amounts of information that convey a large amount of information are important.
Your examples of int vs double vs no-type are really not providing much convincing force. These are in fact the least of the advantage to the type system in Java any ways. The use of types for polymorphic overrides, the use of types for subclass access and interface implementation access control are important parts of the whole package.
> More importantly, when writing code I'm confronted
> with a number of concerns that are probably irrelevant for
> my problem domain; I shouldn't care how many bytes the
> compiler has to allocate for my numeric types so I can add
> a couple of numbers. And the more distracted the code
> writer's mind is, the more likelihood he will introduce
> bugs. Or so it seems reasonable to me. How many times do
> distracted people have accidents compared to those clearly
> thinking and carefully concentrating on the task at hand?
But that is not a related argument. Distraction and confusion comes from multiple sources. If the concepts of typing are confusing to you, then you may well have problems developing in a typed language. But, there are so many other sources of confusion, including the lack of types which help you to understand the scope of the reference to a particular variable.
Without interfaces in Ruby, you wouldn't be concerned with limiting scope of access to certain parts of your object. Without typing, you wouldn't be familar with the benefits of superclass restrictions to help manage the linkage between callers and callees which is an important part of managing the ability of replacing one implementation of an API with another.
In particular, consider the JDBC api in Java. The fact that there is an interface for Connection, Statement, ResultSet, etc allows for me to write a database independent application from a software interface perspective.
Bugs in implementation might cause me to use particular logic to manage the impact of those bugs on my software, but that would happen without types.
The types provide the ability for me to easily try a different implementation, at will. You'll need a template class or some other standard definition in a non-typed/typeless language. That is a type definition.
> Of course, if that consideration is important, critically
> so, as in, it goes to the core of the algorithm itself,
> then I'll probably be writing C code and it will be
> important for me to pay attention to these points. Most of
> the time, my experience has been that worrying about types
> is more trouble than it's worth. Now, an interesting
> language might dispense with labeling all rudimentary
> types like numerics and strings and reserve the types for
> classes. But I don't see this gaining much over a simple
> comment or two. And then, when it's totally clear from
> context, I don't have to type a type label.
Again, I appreciate your sticking with a single example, but you aren't providing any convincing arguments about how the lack of numeric based typing (or other native types) would NOT impact the performance or portability of the software to different systems.
I'm just not seeing how there could not be an impact. I care about performance and I care about portability. Java's type system lets me manage those issues explicitly.
I'd really like to see a VOIP application in Ruby with the codec written using Ruby. Do you know of such a thing that I could look at and play with?