For Programmers: Free Programming Magazines  


Home > Archive > Smalltalk > July 2004 > Re: Static vs. Dynamic typing (big advantage or not)---WAS: c.programming:









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author Re: Static vs. Dynamic typing (big advantage or not)---WAS: c.programming:
H. S. Lahman

2004-07-07, 4:03 pm

Responding to Marshall...

The static vs. dynamic typing debate is inherently unresolvable with
today's technologies and available data. If there were a clear winner
it would have been obvious somewhere in the 2+ decades the issue has
been debated.

Nonetheless I think the debate often gets mired in arcane language
issues and examples at the expense of a more megathinker view...

><snip>
> Static typing comes at a cost. It increases coupling, and rigidity.
> We accept this cost because of the safety. However, if our TDD
> tests
> are already providing that safety, we may decide to reconsider the
> cost.


I think this is a bit facile. It is well established in practice and
mathematically demonstrable that any testing effort benefits from having
multiple screens, even when the fault coverage of those screens largely
overlaps.

>
> <snip>
>
> Statically formed types (of statically typed languages)
> mostly solve problems created by statically formed
> types to begin with.


I also find this a bit facile. There is no question that static typing
places constraints on the software construction that can be annoying to
the developer. But I see that as a different issue than the problems
static typing solves.

Static typing provides an early, largely independent test screen that is
very much focused on the sorts of mechanical errors that plague human
activities (aka "assembly faults"). It also allows the production of
<somewhat> more efficient code.

The price of those benefits is that the developer has to sometimes "work
around" the type system. (How often is moot and that is one of the
reasons the debate is doomed to continue until someone collects some
real data.)

>
> <snip>
>
> Perhaps T1 > T2.
>
> <snip>
>
> Perhaps D1 > D2


The glib rejoinder here is that if developer effort were the primary
concern, one would be programming in an FPL rather than an OOPL in the
first place. The point is that the issue is far more complex than this.

In addition to the value of multiple screens, it is also well
established that it is valuable to find defects early, it is valuable to
focus on assembly faults, and it is valuable to provide cheap,
mechanical screens. Static type checking fairs well in almost any
objective view of testing software. The debate lies in the following
issues:

(1) How much additional effort, if any, is required deal with static
type systems. I know of no experimental data on this, so I don't see it
being quantified in my lifetime.

(2) Whether static testing becomes a crutch for sloppy development. The
reality is that the number of escapes from any test screen is directly
proportional to the number of defects detected. If developers get lazy
in writing code so that the compiler/interpreter is finding more
defects, that is a matter of developer discipline rather than a weakness
of static testing. IOW, monitor the process and make the developers
accountable.

(3) The cost of escapes. For complex software applications no system of
testing is perfect. (IMO, the best testing can possibly provide is
5-Sigma; one needs militant defect prevention to do better.) Basically
this comes down to evaluating the escapes w/ and w/o static testing to
determine if there is a difference in number, type, and repair cost.
Again, I know of no hard data on this, so I don't expect resolution in
my lifetime.

(4) Redundancy with dynamic type checking. The basic idea here is that
some form of type checking in inherently already done at run time in
languages where types are dynamic. There are lots of anecdotal examples
of errors that would be caught by static checking but would escape
dynamic type checking. Again, there is no solid experimental data to
indicate that the category of such defects is significant.

(5) The value of defect prevention. If the defects are not isolated in
static testing, how are they isolated? Clearly the combinatorial
problems of functional testing makes that problematic at best. Dynamic
type checking only covers some <undefined> fraction of the potential
problems per (4). So one is left with developer discipline in
practicing defect prevention to avoid inserting such defects into the
code at all. There are two problems here. The first is that it ignores
the value of multiple test screens. The second is that one still needs
to monitor the defect prevention process and the best way to do that is
via testing. So defect prevention really isn't an excuse for not
providing the test screen unless one can demonstrate the difference in
fault coverage between static and dynamic testing is insignificant.

[Apocryphal aside. Once one gets to 5-Sigma and beyond one is dealing
with ~ 1 defect/10 KLOC of code. To properly monitor the process one
must detect a reasonable sampling of all defect classes. So,
ironically, shops that use testing purely as a process monitoring tool
tend to do a lot more testing than shops that use testing as the primary
mechanism for achieving reliability. B-)]

(6) What creative angst the developer must pay to work around static
type systems. While I am sure this is an important issue to some, I
submit that is just an ego trip. IOW, keep focused on the prize: what
matters is that the customer gets correct, reliable, and cheap software
in a timely fashion. If some grunt work is required to get there, so be it.

While this analysis might seem to come down on the side of static
testing, the jury is still out because of the paucity of data to resolve
(1), (3), and (4). Until that data becomes available the debate will
remain a duel of opinions.


*************
There is nothing wrong with me that could
not be cured by a capful of Drano.

H. S. Lahman
hsl@pathfindermda.com
Pathfinder Solutions -- Put MDA to Work
http://www.pathfindermda.com
(888)-OOA-PATH




Thomas Gagne

2004-07-14, 8:58 am

Dmitry A. Kazakov wrote:
<snip>
>
>
> "Polymorphism" has also nothing to do with the original meaning of the
> words it is composed of. BTW these are Gr words, does OO based on Gr?
> (:-))
>


I don't know. Was Plato Gr?

<http://gagne.homedns.org/~tgagne/ar...tedParadigm.pdf>
Jeff Brooks

2004-07-15, 4:01 pm

Dmitry A. Kazakov wrote:

> They claimed that everything is an object. I asked them whether
> "everything" includes itself or all objects, they confirmed that.
>
> Again I do not know what they actually mean, because they refuse to define
> it formally. So yes, it is a guess, no matter how informed or not my
> opinion might be.


I didn't refuse to define anything. I just assume that developers will
understand the terms "object", and "everything".

Are you saying you don't understand those terms?

Jeff Brooks
Mark S. Hathaway

2004-07-15, 4:01 pm

Cristiano Sadun wrote:



What could the system care about our intentions.
I think static typing is to be explicit about
our intentions and having the compiler check it
thoroughly. That it's a pain in the ass to maintain
isn't the primary issue, but some do mention that.
Some would say it's primarily to help the compiler
set up variables & constants & types in order to
have everything in place before the algorithm kicks
in.

I'd really love to hear from those who don't favor
static type-checking on this issue.
[color=darkred]
[color=darkred]
> I'm not sure I follow. What I wanted to point out was that you can have
> OO without static typing and static typing without OO, (or not have both
> or have both, of course :-). With a vector spaces methapor, the two
> things are "orthogonal", that is.


Yes, I understand.

[color=darkred]
> For the very same reason for which you declare a variable besides
> defining it (if u want, for the same reason I and much of the industry
> found it better to do). Or why function prototypes where added to C/C++.
> And so on.
>
> Because it approximates the (ideal) idea of
>
> - telling the system what you want to do
> - doing it


Having to define even prototypes shows a defect, IMO.
Having to re-define anything in the code is a weakness,
a necessity of a compiler, but not good or essential
for a programmer to be explicit about what should be
done by a program.

> which allows the system to actively check that what you did what was you
> initially declared. In other words, intercepting errors (under the
> assumption that you don't want to lie to the system intentionally).


Flagging the type of some parameter or function would make
sense if you're doing static type-checking. Of course
that immediately begins to limit the use of the algorithm.

> Have you ever seen, say, two pilots in a airplane cockpit?


nitpicking: Pilot and co-pilot; not two pilots.

> They are
> trained to *say* to each other what they are doing: even when the
> commander has just ordered it himself to the copilot, the copilot says
> what he's going to do and *then* does it.


So, the static type-checking is to avoid...

Pilot says: "We're going down" to: Bones

Bones says: "Damn it Jim, I'm a doctor, not a co-pilot.
What would I know of this altimeter, emergency
frequency stuff?"

But, I have to wonder how trust-worthy such a system
would be if a person, not of co-pilot standard, were
put in that position in the first place.

> That kind of redundancy is present in pretty much every context where
> the price of a failure is high and helps a lot in reducing the risk of
> the failure occurring.
>
> Note that above I say "approximates" because type systems are a cheap
> substitutes for algebraic specifications: they don't allow you to give
> the system your *complete* intentions (as ADT do) - thus their usage
> doesn't guarantee that the system will intercept *every* misalignment
> between intention and action.
>
> Still they're better than nothing. Way better, as any "old C" to "new C"
> programmer exprienced back in the early 90s.
>
> Note that Robert's position that started the thread - "now if we had
> repeatable tests, we might need static typing much less" is meaningful
> because all you need is *some* redundancy, not necessarily ST
> redundancy. And what are tests, if another way (independent from the
> code) to tell the system what your intentions are?


[color=darkred]
> This is unclear to me. What do you mean by "handle"?


The type system allows the coercion to be done automatically,
so that the programmer doesn't have to explicitly, and perhaps
incorrectly, manipulate the types of those objects.

[color=darkred]
> Ah, ok. Not being myself in the first set, I cannot say much about it.
> :)


Speechless? Why, I'm ... speechless.

Jeff Brooks

2004-07-15, 4:01 pm

Chris Uppal wrote:

> Dmitry A. Kazakov wrote:
>
>
> (Technically, Smalltalk has a few concepts that are not represented as objects,
> and operations that are not represented as messages sent to objects --
> variables and assignment to variables are the best examples. But still there
> is a good sense in which everything in Smalltalk is an object.)


A variable is part of an object. All values in variables are objects.
The definition of the variables is an object. Even accessing the
variables can be done by sending messages to an object.

I think of variables as objects in Smalltalk.

Assignment isn't a message but the code that does the assignment is an
object.

I think your post will spawn a huge rant from Dmitry! O.o

> You haven't defined what you mean by "everything". The Smalltalk language
> doesn't include any concept of "everything" (but see below), and -- since there
> is no "everything" -- we can claim that "everything is an object" without ever
> representing "everything" itself. Anything that is represented in Smalltalk at
> all is represented as an object (subject to the opening caveat).


A debate about set theory and OO isn't useful because they are different
models. Neither is based on each other.

Jeff Brooks
Thomas Gagne

2004-07-21, 3:59 pm

Michael N. Christoff wrote:
> <nikodemus@random-state.net> wrote in message

<snip>
>
>
>
> Yeah, that's a really profound sounding line but I have not found much
> substance behind it. One could apply it to almost anything:
>
> "X prevents problems caused by X".
>
> The seeming self-reference makes it sound really deep.
>
> I have not read this entire thread but have yet to see a convincing and
> commonly occurring set of examples of how a type mismatch error (caught at
> compile time) is the result of using static types.
>


You've never declared a variable to be of type you /thought/ was compatible
with a type returned by a constructor and have the compiler complain? If the
variable was typed by the object assigned to it there'd be no compiler error.
Static typing catches the errors static typing creates. Catchy? I think so.

byte ba[] = new byte[20];
// ba = new byte[20];

ByteArrayInputStream bas = new ByteArrayInputStream(ba);
// bas = new ByteArrayInputStream(ba);

InputStreamReader r = new InputStreamReader(bas);
// r = new InputStreamReader(bas);

The commented code is easier to both read and write. Reading it is more
important because it will be read more often than written.

The error isn't in the intent of the operation (I want this variable to
reference an instance of ByteArray) it's in the declaration of the intent.
The assignment is both your intent and your declaration. The programmer
declares what they are going to do by doing it. Not by saying it then doing
it. How many times has a static type error changed the expression on the
right-hand side of the assignment vs. the left-hand side? Static typing
doesn't detect that what you did was wrong (the right-hand side) it complains
that what you said you'd do was wrong (the left-hand side).

I suspect people fond of the more verbose code may not have appreciated C's
-=, +=, etc. operators and would have instead preferred:

streamReaderPositionRelativeOffset = streamReaderPositionRelativeOffset +
someCrazyFunction(someValue);

And admire how specific it is and would be thankful the compiler caught the
transient typo and would advocate for it over:

streamReaderPositionRelativeOffset += someCrazyFunction(someValue);

Some newer static-typed languages are better at this than C++ and Java are.
They do this by inferring a great deal of information. Perhaps they'll
eventually infer enough it'll be just like using a dynamically typed language.
Thomas Gagne

2004-07-22, 3:57 am

Michael N. Christoff wrote:
<snip>
>
> It is catchy and in fact I do see the utility of allowing one to define a
> variable's type by assignment. However the problem I find more important is
> the lack of type specification in methods. If I type...
>
> X = new Car();
>
> that is one thing. It is clear that X is a Car since I can see it defined.
> However if I have a method...
>
> void loadCarOnRig(car)
>
> ...I don't have the luxury of being able to see what type the variable 'car'
> is. In the first case I have control of the situation, in the second I am
> left at the mercy of those who call me. This is, to me, the more important
> use of static types. So to summarize: phrase catchy?: yes, substance to
> phrase?: yes, but not (IMO) compelling.


"..in the second (case) I am left at the mercy of those who call me" is an
interesting perspective. You prefer callers at your mercy? How fair is that?
How OO is that? How reusable is that? Did its author really anticipate
every conceivable use of their object and its methods?

More self-referencing catchiness from July 14:

"It is not the responsibility of the receiver to determine the qualities of
the sender, but the privilege of the sender to determine the suitability of
the receiver.

"In other words (and other words are always necessary) the sender is
responsible, and should enjoy full freedom, for determining the suitability of
the *receiver* for accomplishing the task-at-hand. It is not the receiver's
role to 2nd-guess the sender's intentions."
Thomas Gagne

2004-07-23, 3:57 am

Michael N. Christoff wrote:
<snip>
> Sometimes the 'free and easy' solution is not the best. Why would I
> sacrifice a feasibly attainable extra level of safety in my code? Because
> attaining that extra level is not quite as easy as skipping it? Or because
> I can't program as freely? These are not vacuous points, but I would put
> them a few notches down the list from increased _provable_ safety in my
> client's software.
>


I must live in a vacuum. I can't imagine how one of my methods would be
passed an object that wasn't intended in production. Probably because the
code that calls the method was also in testing? Objects don't accidentally
appear in the wrong places. Cat's don't accidentally show up in collections
of Dog objects unless put there deliberately.

I can't find any extra safety, and it can't be proved that the bugs are there.
It's sounds like proving a negative. My software does expand relentlessly.
I realize other projects may have more rigourous requirements and
specifications than I'm accustomed to and perhaps in those cases (I haven't
enjoyed one of those yet) flexibility isn't required.

>
>
> suitability of
>
>
> receiver's
>
>
>
> This is a case of distributed knowledge. Let me ask you this: Who in this
> case is better equipped (has the appropriate knowledge) to determine the
> suitability of an object for the receiver? Is it the sender? Or is it the
> receiver?
>

The sender. Their knowledge is always more current and extensible than the
receivers. Who is better equipped to determine the utility of a screwdriver,
the screwdriver or the craftsman?
Thomas Gagne

2004-07-23, 3:58 pm

Gerry Quinn wrote:
> In article <WaKdneXN0JpV953cRVn-jA@wideopenwest.com>, tgagne@wide-open-
> west.com says...
>
>
>
> No bug appears unless put there 'deliberately', in some sense. Unless,
> as you say, you live in a vacuum.
>


The point being, static typing doesn't catch bugs, it catches typing errors,
so its usage doesn't /prove/ a program is bug-free or correct. Only testing
can approach any approximation of /proof/ a program works under a tested set
of circumstances.
Thomas Gagne

2004-07-28, 9:08 pm

Gerry Quinn wrote:
<snip>
>
> The world seems to be divided into those who formulate intentions and
> code accordingly, and those who throw code together and see if it works.


An interesting perspective.

I had always thought they were divided (mostly, anyway) into those who
engineer it and those that grow it. Or in a religious context, creationists
and evolutionists.

Software creationism requires omnipotence to both plan and construct software
perfectly suited for its task, perfectly efficient in its operation, and
elegant in its mathematical precision and sublimity.

Software evolution finds a design that works and incrementally adds to it,
keeping those features that work to its advantage and neglecting those that do
not.

In the middle are a few who give their creations a head start in life with as
good a design they may afford them (given the software's creators'
imperfections and limitations) then accelerate their evolution with paternal
guidance.

Each one has its place. The more finite the ecology (the more "knowns" or
"givens") the more appropriate it is to design-to-fit. In systems with more
unknowns or moving targets the ability to grow the software may be more
appropriate.

My career has only provided me examples of the latter. I suspect when
requirements don't change frequently there's a good chance software can be
designed more precisely and static typing may be a valuable programmer aid.
In other circumstances (those I'm familiar with) it has little practical value
and slows development as the maintenance of the typing system becomes an ends
to itself.
Mark S. Hathaway

2004-07-28, 9:08 pm

>>> On Sat, 24 Jul 2004 01:25:33 GMT, Jim Rogers

One would think a distance could be measured
best with data of fixed decimal type. I see
no problem with that.

[color=darkred]

Seems likely, though it's also easy to see how
a space travel program which involves humongous
distances would be difficult to test.

[color=darkred]
> Jim Rogers wrote:
>
> The individual units were unit tested by their development teams.
> This lead both teams to believe they had correct software.
> Unfortunately, there was insufficient integration testing. Integration
> testing was the only possible way to catch the problem since the
> development language did not provide a useful syntax for defining
> measurement units unambiguously.


Sounds like a management problem; insufficient oversight
of the entire program, and all that. But, I suspect it's
not so much management as the idea that Bob Martin touched
on -- piece-wise development and iterative development,
rather than one wholistic design which is fractured, so each
piece can be developed more conveniently.

[color=darkred]
> Design by contract would not have caught the problem. Values were witin
> expected ranges, they were simply interpreted wrong.


What language were they using? Didn't it allow them to
define user types like DistanceInMeters or DistanceInFeet?


[color=darkred]
> Functional programming would not have prevented the problem either.



Aah, 'nobody thought of it'... That implies there wasn't
a grand design wherein such things should be obvious to
the Grand Designer. Thus, you have multiple Software
Design Gods and various solutions. Then those software
solutions don't work together and there is no higher
Code Design God to whom the question is passed. It
just goes unnoticed.

[color=darkred]
> If one and only one of the teams defined the type used for units of
> measure, and both teams used that type, there would have been a
> clearer communication of which units of measure were being used.


"Clearer communications" implies some structure for the whole
set of teams and some project manager who might in some way be
responsible. But, usually those managers are to manage the
timetable, resources, scheduling, budget and such. They don't
always have some technical skill for oversight or even to
get their hands dirty with designing.


> Of course, the base problem in this case was a failure of requirements
> definition. The requirements document should have specified the units
> of measure to use in the calculations. One of the advantages to
> creating static and strong type definitions is that it forces developers
> to ask some of the unasked questions, such as which units of measure
> to use. In this manner many weaknesses in requirements can be revealed
> and therefore fixed.


A "requirements definition" would require that there is someone
or some group which has an idea of what is required. Without that
Grand View of the whole project you just have chaos.
Thomas Gagne

2004-07-28, 9:08 pm

Michael N. Christoff wrote:
<snip>
>
>
> This makes no sense, to me at least. How is the user of some software
> 'always' more knowledgeable than the person who wrote it? This implies that
> before you send an object to another bit of code, you have to analyze the
> receiver to the point where you know more about it than the authors
> themselves. Seems like a waste of time to me, when we could simply have the
> receiver specify what objects are appropriate. ie: everyone takes
> responsibility for their own code. Its almost a restatement of the idea
> behind encapsulation. My object has a protected state and I (the receiver)
> take responsibility for protecting that state. I do not pass off that
> responsibility to the users of my code. Also, there is the whole issue of
> the use of commercial closed source software where there is no way the
> sender could be more knowledgeable about the receiver than the receiver
> itself.
>


They don't have to know the receiver inside and out--only enough to know what
it's supposed to do, then they should be able to send it anything that meets
the /minimum/ requirements. In another subthread there's discussion about the
effort required in most statically typed languages to define what a minimum
interface is.

Don't limit consumers' knowledge of your objects to only a brief acquaintance.
They may be using it intimately for ws, months, or years. In that amount
of time they may have found more reasons and places to use it and perhaps have
become more intimate than even its parents. These are typically long-term
relationships and not one-night stands.

>
>
>
> This is a bad analogy. It is one of those things where a physical analogy
> does not map back into the actual situation: in this case software
> development. Instead of a screwdriver consider a DVD player. Who is better
> equipped to determine the suitability of a disk for a disk player, the user
> or the player?


The user. The DVDPlayer object may use an embedded object capable of reading
CDs but place an unnecessary restriction on the disk. The user, perhaps
through trial-and-error or by reading some other documentation or talking to
another user, discovers CDs *should* play just as well but are frustrated by
the player's insistence that only a DVD be inserted.

I like cassette players, too. They expect cassettes to be inserted, but
someone invented something that looks like a cassette but is really a CD
player that does some kind of magic so that the CD player's music comes
through your car's stereo system via the cassette player. Cool stuff. The
cassette designers probably hadn't anticipated that, but they didn't require
casettes actually have tape in them either, or that it would be an error after
playing in one direction for six days without rewinding or replacing the cassette.

How about light bulb sockets? Intended, perhaps, for incandescent lamps but
florescent lamps that resembled the incandescent fit as well -- because they
meet /minimum/ requirements. Or I can screw-in an outlet that fits the
sockets. Or I can stick my finger in and get a runtime exception (that which
doesn't kill us makes us stronger).

Unless you intend to open the player up to the point where
> 'your knowledge is more current and extensible than the designers of the DVD
> player', then the receiver is in a better position to decide.


There's an assumption here the DVD player's designers knew *everything
possible*. Basically, that's impossible for humans. Kinda like the ultimate
insult to reusability -- declaring a class final. National constitutions
provide mechanisms for their own modification but not so Java's String class.
It's creators were more inspired even than Madison, Jefferson, et al.

But just as
> in software development, if this level of knowledge was required before we
> could operate the typical devices we use in our daily lives, no one would
> have time to get anything done. That's why encapsulation and the sharing of
> responsibility are thought of so highly in OO software development.


I encapsulate so users don't /need/ to know how the internals work, not
because I don't want them to know or believe my code to be perfect and beyond
improvement (even as elegant and sublime as my objects are I /occasionally/
find imperfections so subtle their detection and repair is beyond that of most
mortals but required nonetheless).
Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com