IWETHEY v. 0.3.0 | TODO
1,095 registered users | 1 active user | 0 LpH | Statistics
Login | Create New User
IWETHEY Banner

Welcome to IWETHEY!

New I've decided to write it all down
My philosophies and opinions on software development/architecture. I've kicked off a weblog at [link|http://ventedspleen.weblogger.com|http://ventedspleen.weblogger.com] (link is now fixed) to try to nail down just why I have the opinions I do. At the moment I'm still focusing on languages but I expect to move beyond that at some point.

Anybody wanting to contribute or comment is most welcome.
Expand Edited by tuberculosis Aug. 17, 2001, 04:39:46 PM EDT
New I get an error
When I try to access [link|http://ventedspleen.weblogs.com|[link|http://ventedspleen.weblogs.com|http://ventedspleen.weblogs.com]]. Is there a specific page in the URL?
New Doh! This one
[link|http://ventedspleen.weblogger.com/|[link|http://ventedspleen.weblogger.com/|http://ventedspleen.weblogger.com/]]
New Pet peeves
Operator overloading in C++.

Idiots writing C++ code that doesn't properly take care of memory (you know, blah = new blahclass without delete blah)

Undocumented sources - not the source itself (although people who write code without a single comment are hurting themselves and others), but where the code came from, if anywhere. Combine that with making your own code unattributable by not providing a minimal header.

Re-inventing the wheel, when there are several types of wheels out there to pick from. OK, OK, it isn't always possible to reuse code and sometimes actually harmful, but it would be just plain stupid to write a string class from scratch in C++. Even if you don't want the templatized standard library string, there are many implementations to choose from.

Most of these are C++ examples, because I've been working on a library that exhibits many of these features.
The first time I encountered setjmp() was in an Amiga program ported from Unix. "Hmm, what's setjmp()?" I said, pulling up the man page. I read the man page. "*GASP* GLARGGGPPPHHTT!!! ARGHJKLKJ#@%!^&^U!" I exclaimed, and rolled my chair over backwards as I fainted.
New Well, if you just want to list those
I'll wrap the whole thing up in "People who use C++ to write application code".

Done.

setjump is a perfectly good routine. Its used for exception handling in Objective C and it works OK. It just happens to break what C++ crowd is pleased to call their "runtime architecture".
New I don't care what the C++ crowd calls it
Setjmp is a miserable solution to a built-in language problem - this is from a C perspective. C programs also use it for exception handling, though probably much less coherently than Objective C. I don't think I've ever seen a C++ program use it.
The first time I encountered setjmp() was in an Amiga program ported from
Unix. "Hmm, what's setjmp()?" I said, pulling up the man page. I read the man
page. "*GASP* GLARGGGPPPHHTT!!! ARGHJKLKJ#@%!^&^U!" I exclaimed, and rolled my
chair over backwards as I fainted.
New Argh!
Operator overloading in C++ is one of the few things about it that's any good. It's very useful in numerical work.
New Well hang in there
because its coming to Java I think. Although, if they make the same compromises they made with the Generic extensions (templates), its going to be horribly inefficient for numerics work.
New Two uses
Complex numbers and strings.

Can't think of any other reasonable uses. To have a language specification that builds an item on two rare uses is crazy.
French Zombies are zapping me with lasers!
New "Boy, what a lot of typing that was!"
I find that comment about a Java fragment to be off target. What is more important is how easy it is to read. A program with any longevity will be read much more often than it is written or modified. For another thing, it seems to discourage comments. After all, they take time and space and typing as well.

The question to answer is "How clear is that?".
Alex

Only two things are certain: the universe and human stupidity;
and I'm not certain about the universe.
-- Albert Einstein (1879-1955)
New Re: "Boy, what a lot of typing that was!"
> For another thing, it seems to discourage comments.

The problem is meaningless comments, or worthless comments. Basic coments saying the purpose of the routine/function/subroutine/class seem to be a lost art.. That's probably true in the smalltalk/Objective C/Common Lisp world as well as in C/C++.
French Zombies are zapping me with lasers!
New Thats a good point
I think I may go back and change that - because the clarity thing is definitely a big deal.
New Nice rants.
I like the off-by-1 discussion. It reminds me of why I now avoid C if I can. But to see Java as no better... !

Icon gets closer to Smalltalk in that regard. To loop over all items in a colletion you do every item := !collection do { ... } Hey presto: no off-by-1 errors! The other Smalltalk examples aren't as elegant in Icon as they are in Smalltalk - but that's okay. Icon is in the gap between C and Smalltalk.

Wade, who was deep in Icon programming last night and was quite enjoying it.

"All around me are nothing but fakes
Come with me on the biggest fake of all!"

New Re: I've decided to write it all down
Not all statically typed languages share the defects you observe in C++ and Java. For example, in OCaml a) there are no type declarations -- all types are inferred, b) there is no null belonging to all types (since this makes the type system unsound), and c) there are no casts, since the type system is expressive enough to make them unnecessary.

For instance, consider the following two class declarations in OCaml:


class oned_point xarg =
object
val mutable x = xarg
\t
method get_x = x
method set_x d = x <- x + d
end

class twod_point xarg yarg =
object
val mutable x = xarg
val mutable y = yarg
\t
method get_x = x
method set_x d = x <- x + d
method get_y = y
method set_y d = y <- y + d
end


They should be pretty easy to read. The only novelty is the lack of explicit type declarations in the method, variable and constructor arguments. Now, consider a pair of functions

let distance_from_x_axis obj = abs(obj#get_x)
inferred type: < get_x : float; .. > -> float

let manhattan obj = abs(obj#get_x) + abs(obj#get_y)
inferred type: < get_x : int; get_y : int; .. > -> int = <fun>


The '#' notation is the same as the dot-notation in Java or C++ -- it denotes a message send. Notice that the type inference restricts the argument of distance_from_x_axis to objects with a get_x method. This is statically verified, but any object that has it is acceptable. At the interactive prompt:


# let o1 = new oned_point 9;;
val o1 : oned_point = <obj>

# let o2 = new twod_point 3 9;;
val o2 : twod_point = <obj>

# distance_from_x_axis o1;;
- : int = 9

# distance_from_x_axis o2;;
- : int = 3

# manhattan o2;;
- : int = 12

# manhattan o1;;
Characters 10-12:
This expression has type oned_point = < get_x : int; set_x : int -> unit >
but is here used with type < get_x : int; get_y : int; .. >
Only the second object type has a method get_y


The error in the call 'manhattan o1' is a compile time error -- the
expression was never executed.

This doesn't change the force of your argument much, though. If anything, it makes it more damning since there were superior type systems that Java ignored. :)
New I've read the previously posted rant
on why ocaml is an example of good static typing. I believe it to some extent, but I find the ocaml syntax incomprehensible. I think I need it broken down better as I lack the foundation to fully understand your example. For instance, can you explain to me exactly what the parts of this statement:

method set_x d = x <- x + d

mean? I get that its a method declaration for a method called set_x. I'm not quite sure what d is and I don't understand at all what d = x <- x + d is supposed to mean. It looks to me more like moveBy d than a moveTo d sort of thing with the + there.

Also, how does the language handle type widening or narrowing when the compiler can't get complete knowledge of all sections of code? For instance, in the case of dynamically loaded libraries or frameworks. Or is this just not possible?
New Just a guess
method set_x d = x <- x + d

I think the equivalent Python would be

def set_x (d):
        x = x + d
Jay O'Connor

"Going places unmapped
to do things unplanned
to people unsuspecting"
Expand Edited by Fearless Freep Aug. 17, 2001, 02:35:05 PM EDT
New Then its misnamed
if it adds d to x then its not setting x, its a moveXBy d.

Thats a little confusing to me so I wanted clarification.
New Re: Then its misnamed
Okay, I tried to post this a couple of days ago, but it didn't seem to
work. Here's the five-minute Caml lesson.

First, function definition: function bindings are introduced with a
'let' construct:

let add a b c = a + b + c

To call a function, you do this:

add 3 5 7
- : int = 15

Note that there are no parentheses -- simple juxtaposition will
do. Like all functional languages, Caml supports nested and
first-class functions, and uses tail-recursion to do looping.

let fib n =
let rec loop i a b =
if i = 0 then
a
else
loop (i-1) b (a+b)
in
loop n 1 1

fib 6
- : int = 13


Now, since Caml is functional, by default variables are immutable, and
can't be mutated. As a result, if you want a mutable variable, you need
to use a reference:

let x = ref 3
val x : int ref = {contents=3}

!x (* Dereference x *)
- : int = 3

x := !x + 3 (* Increment the value inside x *)

!x
- : int = 6


Now we come to one of the annoying redundancies in Ocaml syntax. The
':=' notation is not the only way to write mutation. When you have
records with mutable fields, then you can use the '<-' notation for
mutation as well:

type foo = {mutable bar: int}

let x = {bar = 6}

x.bar
- : int = 6

x.bar <- x.bar - 3 (* The record field is mutated *)

x.bar
- : int = 3

Now, the quick and dirty object tutorial. Here's a simple class

class foo =
object
val mutable x = 0 (* A mutable instance variable *)

method get_x = x (* A getter for the instance var x *)
end

let obj = new foo

obj#get_x (* Method call uses '#' instead of '.' *)

You can add arguments to the initalizer like so:

class point u v =
object
val mutable x = u
val mutable y = v

method get_x = x
method get_y = y

method move dx dy =
begin
x <- x + dx;
y <- y + dy;
end
end

let pt = new point 3 5

pt#get_x
- : int = 3

pt#move 4 5

(pt#get_x, pt#get_y)
- : int * int = 7, 10

New Posted a link...
...over on [link|http://lambda.weblogs.com/|Lambda weblogs]. One nice thing about Winer's discussion boards is that it allows you to keep track of who's [link|http://ventedspleen.weblogger.com/stats/referers|referring] to your board (Wonder if zIWETHEY tracks such things? - though I can see how some folks dislike such tracking mechanisms).

My only thought at the moment concerns the Open-Closed principle and the use of delegates/posing. What I am wondering is how you view the ability to test software when it's behavior can be modified? The main reason for the closed principle, as I see it, has to do with the knowledge that the software has been tested and you have confidence in it's algorithms. Once you start allowing a class to behave differently depending on the programmer/application, it becomes more difficult to nail down when a class is debugged and when it is not.
New Thanks
Its more fun when you get readers and besides, some of the feedback I've been getting here and elsewhere has made me either rethink and sometimes refine my positions.

On the Open-Closed Principle. In the whole, I don't think its an awful idea exactly. The idea being is you don't have to re-test what you didn't change. The flip side of this is that you *do* have to test anything you do change or anything that's new.

The assumption that is often made with these principles is that the original design is sound and a good fit for the problem domain. What about systems that need to evolve in environments where the current design doesn't fit the (recently changed) requirements very well?

In my rather advanced paranoia, I find myself factoring at a rather fine grained level to leave myself options in places where I'm not sure I'll need them. I consider this to be the essence of the architect's role - the preservation of options. After several years, my instincts have gotten pretty good, but I still get surprised every now and then.

Plus - how often have you had a system dumped into your lap that isn't in too good a shape and you still need to rev it to do some new kind of thing?

So I guess to sum up - the literature all assumes blank slate design or extensions of systems where the initial assumptions still hold. Thats all well and good - the real world isn't that neat. Our tools should be forgiving and help us recover from bad designs or sweeping changes in requirements. That would be the test of a good vs bad system for development of enterprise systems.

     I've decided to write it all down - (tuberculosis) - (19)
         I get an error - (ChrisR) - (1)
             Doh! This one - (tuberculosis)
         Pet peeves - (wharris2) - (5)
             Well, if you just want to list those - (tuberculosis) - (1)
                 I don't care what the C++ crowd calls it - (wharris2)
             Argh! - (deSitter) - (2)
                 Well hang in there - (tuberculosis)
                 Two uses - (wharris2)
         "Boy, what a lot of typing that was!" - (a6l6e6x) - (2)
             Re: "Boy, what a lot of typing that was!" - (wharris2) - (1)
                 Thats a good point - (tuberculosis)
         Nice rants. - (static)
         Re: I've decided to write it all down - (neelk) - (4)
             I've read the previously posted rant - (tuberculosis) - (3)
                 Just a guess - (Fearless Freep) - (2)
                     Then its misnamed - (tuberculosis) - (1)
                         Re: Then its misnamed - (neelk)
         Posted a link... - (ChrisR) - (1)
             Thanks - (tuberculosis)

What. He. Said.
84 ms