Tải bản đầy đủ (.pdf) (5 trang)

O''''Reilly Network For Information About''''s Book part 11 ppt

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (32.82 KB, 5 trang )






4.2. Basic Java Limitations
I've painted a picture of the average project. The average team builds or ports
applications that will deliver a web-based frontend on a relational database,
potentially with other less meaningful services. The team probably uses
increasingly agile princip
les, and likely wants to do unit testing. The team typically
works under short schedules and great pressures. And given more dynamic
alternatives, Java is not at all the language that I'd usually choose for such a
project, in such an environment:
 The many frameworks designed to simplify the Java development
experience do make experienced Java developers more productive, but make
the learning curve too steep for those new to Java.
 Compile-time checking of exception and types adds safety, but comes at a
cost of additional time and syntax.
 Java's inability to express structured data leads to an over-reliance on XML,
with the corresponding additional complexity and bloat.
 Java's many compromises, like primitives, make Java harder to learn and
more complex to write.
 Java is more dynamic than C++, but is nowhere near as dynamic as
languages like Smalltalk and Ruby. Java developers are finding
metaprogramming, but they're not able to execute on those ideas fast
enough.
 Java's long compile/deploy cycle is much longer than interpreted, dynamic
alternatives.
Taken alone, none of these issues hurts enough to matter. Taken together, Java
becomes much less productive for most developers.


Steve Yegge: Java's Limitations
Language expert and creator of Wyvern

Steve Yegge, a graduate of the University of Washington, spent five
years as an Assembly-language programmer at Geoworks and more than
six years as a software development manager at Amazon.com. Steve
somehow managed to find time to design, implement, and maintain a
massive multiplayer game called Wyvern (
with a half-million lines of Java and Python code.
What is your
experience
with Java?
SY: I was a card-carrying member of the Java
community from late 1996 through mid-2003. I
used Java to build a cool, multiplayer, user-
extensible online game. Java got me really far,
and I loved it for seven years.
Why did you
start looking at
other
languages?
SY: I simply hit a productivity wall. As my
code base grew, my innovation slowed, until
finally, tasks were taking me an order of
magnitude longer than I felt they should. I
stopped development for six months and did a
deep-dive investigation to figure out what the
heck was going wrong. It wasn't what I
expected. The problem was Java. I was pretty
unhappy about this. I'd invested an awful lot in

Java. AOP helped a little (albeit at a high entry
cost), but nowhere near enough. Nothing else
helped at all. What I needed was a new
language.
How does
Java hold you
back?
SY: First, Java offers an impoverished set of
abstractions. No first-class functions, no
reference parameters, no keyword or default
params, no destructuring bind or even parallel
assignment, no way to return multiple values
efficiently, no continuations, no user-defined
operators, no generators, no closures, no
tuples the list just goes on. Java's about 25
teeth shy of a full mouth.
Second, Java is entirely nonextensible. It can't
grow. There's no metaprogramming, no macros,
no templates, nothing that gives you syntactic
abstraction. So, Java's incompressible. Java
code is always filled with stuff that looks like
copy and paste, but you can't factor it out. Java
code and APIs always wind up bloated (and yet
oddly impressive looking).
Third, Java can express code, but not data.
You're stuck using property files, XML, and
other means of defining data. But the line
between code and data is blurrythink about
configuration, for example. So, the Java folks
are piling on framework after framework,

creating this huge pipeline of transformations
that can't be expressed in Java.
Fourth, Java's static type system sucks.
Actually, all static type systems suck, but Java's
is worse than most. It gives you only narrow
avenues along which you're permitted to think.
Java programmers must painstakingly learn to
pound star-
shaped pegs into square holes; this is
what design patterns are mostly about.
Fifth, Java has far too much nonessential
complexity. For instance, it now has four kinds
of types: primitives, classes, arrays, and enums.
All the type types have their own syntax and
semantics, which you must learn and then
handle in your APIs. It's not just types, either.
Java's entire syntax is large and bureaucratic.
Java's syntax is complex for no good reason.




.3. Typing
One of the most fiercely debated topics in programming languages is the benefit of
strong, static typing strategies. Java's strategy opts for as much compile-time
checking as possible. Let's take a quick overview of programming language design,
in layman's terms. Then, you can put Java into context. When building a language,
a designer needs to answer two typing questions relatively early in the design
process.
4.3.1. Strong Versus Weak Typing

Strong versus weak typing decides how a type is enforced, or interpreted. In a
weakly typed language (like C), variables can be coerced easily, or interpreted as
something else. A strongly typed language strictly enforces compatible types
across operations. It probably doesn't surprise you that Java is a strongly typed
language.
Ruby, Smalltalk, and Python also enforce strong typing, which might surprise you.
Many developers believe Smalltalk, Python, and Ruby are so productive because
they are weakly typed. They are misinformed. Consider this brief Ruby example:
irb(main):003:0> i=1
=> 1
irb(main):004:0> puts "Value of i:" + i
TypeError: cannot convert Fixnum into String
from (irb):4:in '+'
from (irb):4
In the first line, the undeclared variable i takes on the value of 1. At this time,
Ruby decides that i is a Fixnum. When Ruby interprets the third line, it sees the
+ operator after the string, and tries to concatenate i. Of course, Ruby doesn't
know how to concatenate an integer to a string, so it throws an error. That's clearly
an example of strong typing. (Actually, I've oversimplified things a little. You can
dynamically change the definition of Ruby classes and objects at runtime, and this
weakens the typing somewhat. Still, on a continuum from strong to weak typing,
Ruby would lean slightly to the strong side.)
In a similar situation, a language with weaker typing may instead coerce types to a
compatible form, as in C. Consider this example:
int a = 5;
float b = a;
In the second line, C coerces the value of the integer to float. Other examples
are even worse. In C++, the ( ) cast operator does not yield type safety, so you
could say, for example:
Cat *cat;

Dog *dog = (Dog *)cat;
These are legal C++ statements. Instead of reporting an error, C++ will happily go
on stomping through memory. Languages with very weak typing simply do not
capture typing errors, so the behavior of certain operations is undefined. Weaker
typing is sometimes convenient, and less predictable. As you've seen, typing is not
always black and white. It's also a highly contentious issue among language
experts. Strong versus weak typing is on a continuum. Some strongly typed
languages like Java allow loopholes by letting the user cast objects to another type.
Languages with the strongest possible typing allow no loopholes. Weaker typing
allows, and may even require, coercions. The weakest possible typing doesn't do
type checking at all at compile time or runtime, like Assembly language, for
example.
4.3.2. Static Versus Dynamic Typing
The more interesting question by far is when typing is enforced. Static typing
binds a type to an object, and language constructs like variables and parameters.
Dynamic typing binds a type to an object at runtime. Dynamic typing doesn't say
anything about a variable's container, or anything that a variable passes through.

×