in a recent blog entry where i wrote about successful open source code bases from the perspective of development (not usage; you can have god-awful code but very happy users, and vice versa), i just knew someone would say that $PET_LANGUAGE was the solution. in this case, it was a fellow named jonas and the pet language was python (who i assume hasn't read the bittorrent code).
like any tool, the quality and appropriateness of the tool impacts the quality of the product. writing large desktop libs and apps in C is really very silly in this day and age. writing apps in C++ is a lot better but can still be challenging, which is one reason Qt is such a god send (it makes using C++ really quite nice). and so we have languages like python, ruby, java and c# (plus 18 million other ones) that provide a more abstracted view of the landscape. for instance, often they won't make you (or, for that matter, allow you to) deal with memory management.
however, as the millions of horridly written visual basic apps out there attest to, giving people an easy language does not guarantee good code. not even enforcing white space usage like i'm a 3 year old who needs hand holding (yeah, i dislike that "feature" in python) is enough. because good code comes less from syntax and more from design and clarity of purpose.
a friend of mine was asked to take a look at a web app written in a modern high level language recently (no, not php) and was aghast to discover that it consisted of over 1,700 files. now this app is not that complex. i could maybe understand 100 files with a few hundred lines of code each for this particular app ... but ... 1,700?! holy crap batman!
so while it's easier (and therefore more likely) to fug things up with a harder to use tool (e.g. C) or a poorly chosen tool for the job (e.g. trying to write a web browser in bash script), having a nice tool to work with does not save the user from poor practice on the part of the craftsman.
(p.s. i'm also a proponent of moving to higher level languages for application development. but not because it means more easily maintained code. because it means fewer LOC, fewer opportunities for implementation errors, quicker devel turn around due to not having a compile/link stage and makes distribution easier as there is no platform-specific end product)
Thursday, November 17, 2005
Subscribe to:
Post Comments (Atom)

29 comments:
Do you think Perl is a good language to develop applications?
not even enforcing white space usage like i'm a 3 year old who needs hand holding (yeah, i dislike that "feature" in python) is enough.
You're assuming Python's white space requirement is there to increase readability. Most languages need syntax to indicate blocks of code - C++ uses brackets, Lisp uses parentheses, Python uses white space. Of course, a side effect of Python's choice is that code ends up layed out neater (not necessarily written neater, though).
Using white space means that blocks are defined by their layout, this is in the same vein as a statement made in SICP: "Programs should be written for people to read, and only incidentally for machines to execute."
It's like this, you're probably going to be indenting your code anyway, might as well use that for parsing out code blocks instead of requiring extra characters for the same effect.
Whoa 1700 files?? I sooo hope most of these were automatically generated source files.
I didn't want to come off as offering up $PET_LANGUAGE as a solution. I think we essentially agree, so perhaps if you reread my comment from this perspective you'll understand more what I was getting at.
Because programs with poor architecture have been developed in every language, I consider it a strawman argument to attack either existing or hypothetical projects that are difficult to understand.
My comment was not meant to be interpreted as "rewrite kicker in python and it'l be better", but I did insinuate that had it been written in $PET_LANGUAGE it would at least be less LOC, which itself would provide all sorts of benefits and probably make it easier to fix. Even if fixing it means throwing it out and re-designing it, doing so in $PET_LANGUAGE would probably be faster because it'd require less LOC and you could operate at a higher level of abstraction. You basically said this yourself in the last paragraph of this entry, and I stand by this claim.
It might end up (very likely, for such an application) that $PET_LANGUAGE does not give you the flexibility (due to limited bindigns) or speed required for your app, in which case the $PET_LANGUAGE implementation still offered a useful prototyping step and (hopefully) did not take too much development time in the process. If you were to re-write kicker now, I'm sure it would end up a ton better than its current iteration. The real hypothetical piece of the equation is: would you have realized it was necessary earlier if it was written in a higher level language, and would you have been more apt to enact the necessary code armageddon to fix it? If we agree that it would have been less LOC, the answer to these questions is "yes".
The area where we (might?) disagree is the impact of syntax. Brevity, concision, elegance... these are universally desired, and seemingly seldom achieved. Real features are often dismissed as syntactic sugar. Sometimes a lambda or a closure is just the right design choice to achieve legible, maintainable code.
perl: it's good for what it was ogrinally designed for. small scripts doing text processing related tasks. you can do other things with it, of course, but generally i find perl to be an abhorrent language for general purpose use.
matt: unfortunately, whitespace indentation does restrict how i write code and i don't need nor like that.
more over, i can't see whitespace. i find it much harder to read whitespace delineated languages than ones with explicit punctuation.
you may love it, i find it annoying.
jonas: you are still putting way too much faith in language capabilities. as i said, good tools allow a good craftsman to do a better job. but they hardly guarantee anything.
"Because programs with poor architecture have been developed in every language, I consider it a strawman argument"
architecture was the topic, however, and therefore the fact that there are poorly designed apps in every language sort of proves my contention that language is not important to the discussion.
nor is brevity that languages bring. you can give me 10k LOC app that is highly maintainable or a 1k LOC app that does the same thing that isn't.
it comes down to design, documentation and implementation clarity.
here's another example: variable naming. i can name variables nearly however i want in pretty much any language. python won't prevent me from using completely obtuse one letter variable names everywhere or shadowing variables with variables of the same name in the current scope. these practices lead to hard to understand and maintain code and no language out there helps me do a better job than i decide to do as a developer.
and no, one can't simply throw out an app and start over whenever one feels like it even if the investment is low. why? because once you have a user base you have a commitment to them. the feature set and UI become a sort of contract with them, and you pay when you break it.
with kicker, we had a contract with developers that said "these plugin classes will maintain binary compatibility" so those couldn't be changed either, even though they were/are rather broken in design IMO.
again, these are problems outside of languages.
i'm all for the use of higher level languages for app development, but not because it means better design (it doesn't; and that's the issue), not because it lets you start from scratch for less cost (remember this is about code transferability; i inherited kicker's code base, for instance) and not because it leads to better code documentation (that's not a feature found in the commonly used higher level languages).
hmm.. i should probably add re: kicker's binary compat commitment that it was the API not the "you don't have to recompile" issue that was most important.
one can look to superkaramba and it's python API and say the exact same thing regarding having to keep the API more or less as is for the lifespan of that version of the app.
unfortunately, whitespace indentation does restrict how i write code and i don't need nor like that.
Your original post argues that the features of higher level languages don't make code written in those languages inherently better/cleaner - instead, it's how you write code.
I understand having a preference against whitespace (or brackets, or parentheses), but how does this restrict your ability to write code?
matt: i think you're using the phrase "how you write code" to mean a couple of different things.
yes, the language one chooser does not inherently make the design of the app better (where "how you design an app" is one possible meaning of "how you write code")
whitespace enforcement doesn't prevent me from writing code, but it dictates how i actually type the characters that make up the symbols that make the code behind the app. and i like to be in control of how i type those characters.
imagine if blogger didn't let me start a new sentence unless i used an uppercase letter. i'd be doomed! ;)
haha, great analogy!
I get it now... =)
Aaron, could you give an example of code that you would (or do) write in a language in your choice that Python will reject?
Also, what would the 1700 file language be? (My guess -- Java)
P.S: I deleted & reposted cause I couldn't find a way to edit the post. Does blogger allow that?
Every language has significant problems, and applications that its better or worse suited for. But the issue here is specifically C++, the primary language for KDE.
I'll be honest. I don't have anywhere near your code experience. But I've spent the last summer coding C++, and I think coding any major project in it that doesn't need to be super performant (read: games, science apps) is braindead. QT & C++ together is so nice to code in because it's almost a different language. But under the rug C++ has enough ugliness that I couldn't seriously reccomend it to anyone.
Usually when C++ is touted as being easy to learn is because of the weird idea that it's easy for C coders to pick up -- which is just factually wrong. Yes, a C coder can start writing syntactically correct pseudo-C++ rather quickly, but it's going to be a long time before he writes anything of quality.
C++ makes even less sense for a major OOS project because volunteer involvement is key, and C++ has such a gigantic learning threshold. Consider:
Static class variables can be initialized inside the class body -- if they're ints. Just ints (check C++ FAQs, some other types might work too, point is, it's friggin' weird).
"Whitespace doesn't matter!" Unless you try to have a vector of vectors. std::vector<std::vector<int>> gives an error (because it interprets >> as an operator) while std::vector< std::vector<int> > does not.
"You can do everything you can with pointers with references! The era of pointers is dead!" Except have vectors of them.
You can use int myarray[3] = { 0, 2, 1 } syntax when declaring array, but at no other time. If you've previously declared the array and then try to assign it with that syntax, you get an error.
void f(int& x[10]); // Error, that's an array of references, not an array by reference
void f(int (&x)[10]); // Correct. Also wicked obfuscated looking.
The examples go on forever.... basically, from a usability standpoint, C++ is a failure. I'm unconvinced QT suitably fixes this well enough [i]and[/i] provides enough of a productivity boost to go ahead and make an app in C++, especially since QT bindings exist for other languages.
> could you give an example of
> code that you would (or do)
> write in a language in your
> choice that Python will reject?
python is a general purpose language, turing complete. you can code anything you want in it. it's not the language for performance critical code though.
but that's not the point at all here. i like higher level languages. but they don't help you design better applications. they make writing the code easier (usually, anyways), but that's a rather different issue.
what i don't like is how when you suggest that language choice isn't the only thing to consider in app development, that fans of higher level languages jump to their defense. it's mind boggling =)
> Also, what would the 1700 file
> language be?
it's an ASP app. double ugh.
> C++ makes even less sense for a
> major OOS project because
> volunteer involvement is key,
first, you vastly overrate the difficulty of C++. it is a very difficult language to become an absolute master of (because it's so huge), but one merely needs to be conversant in it. i've seen enough self-taught teenagers slinging C++ to know that getting conversant isn't _that_ hard.
but i think you underestimate the importance of having people who know the language: there are hundreds of thousands of C++ developers out there (millions?) and tons of Java programmers. there are relatively few Python, Ruby, etc developers, which makes them a very poor choices for a major open source project where you need lots of people involved. i won't even start into the issues surrounding libraries written in these languages =)
perhaps the two languages you might get away with are perl and php, but most (not all!) serious developers i know dislike both to one degree or another. this becomes a show stopper for basing a major open source project on them.
that said, for the "two guys working on a GUI app" scenario, i think python, ruby, etc are terrific choices. (though they've only become viable options in the last 5 years or so)
those two guys can still end up with really crappy design which dooms the project, however.
i know a couple of young coders here in town working on a mono (c#) project and they rewrote a few times each time running into dead ends. the language wasn't the problem, it was their design choices that kept biting them in the ass.
oh, and remember that high level languages are still crap for performance (it works for GUI app devel because nearly all the execution time is spent either waiting on the user or in the libraries it uses which are coded in C/C++).
> basically, from a usability
> standpoint, C++ is a failure.
uh-oh, you used a buzzword out of context. -2 points ;)
I am for one a big fan of Python, but I very much like to have an explicite block delimiter as an option or anything foolproof to ensure that the indentation doesn't go all kitchen sink. I mean, a brace is a brace, but tabs and spaces can be confused.
Python can certainly be used to make horrible code. I have just finished working for a certain large communications silicon provider, who had a test suite project including a complete mess of approx. 60,000 lines of python. There are some real issues with that sort of scaling in Python unless you are very diciplined in the way you code :)
For huge projects, it's important that you can partially evaluate what you code does without running it. A common feature in C and C++ is static type checking. Java has partial support for it. This feature ensures that you cannot assign a string to an int and avoids programming errors.
Using the -Wall flag when compiling is important because it catches bad programming practices.
What would be very useful for development of huge projects is code analysis tools and the possibility of defining conditions that the code must meet. Unit tests come some way in doing this and are an important tool. They still require running the test code though. A better way of doing these things is defining the input and output conditions of functions such that they can be checked at compile time.
E.g. one could annotate a C++ function that takes a "const char* ptr" such that ptr may never be 0. Then the compiler could perform compile-time checks to see if the code can guarantee that the pointer is never 0. Such conditions would have to be defined at function declaration time. Sanity checking is the most important feature for a good programming language.
So, unit tests are nice, compile-time unit tests are better.
Thinking about compile-time checks... why not use wrapper templates with assert statements. For example:
template <class T>
class nonnull {
T* ptr;
public:
nonnull(T* p) {
assert(p!=0);
ptr = p;
}
operator T*() {return ptr;}
};
Now you can define a function:
void
printString(nonnull<const char> s) {
printf("%s\n", s);
}
and you can be sure that the string is not null.
I have no idea how large the performance impact of such will be though.
I agree with everything that Aaron said in this post. I'd like to make another two points about python:
1) Have you ever tried to open a python script with an editor different from the one you originally used? Guess what... your program is completely screwed because the two editors will very likely treat tabs in a different way. Also having space controlling the flow of your code, means that you can completely alter the meaning of a block of code with _very_ little change
2) I really don't see how one could implement a complex system with a non statically typed language. Once the program begins to grow you really have to be uber-strict about coding and naming conventions if you want to keep things understandable
Actually, GCC can do compile-time checks for null pointers. Too bad it only works in C.
http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
void printString(const char **c) __attribute__ ((nonnull(1)));
void
printString(const char **c) {
printf("%s\n", *c);
}
Bruce Eckel has some interesting stuff on the Static vs. Dynamic problem here:
http://www.mindview.net/WebLog/log-0066
Also, inheriting code written in Python using spaces rather than tabs is a real PITA; I don't know where the fellow remarking about how differing rendering of tabs can mess up your code (the opposite, it lets you view code at the tabstop which you feel most comfortable with), but inheriting someone's python code that uses spaces causes the immediate headache of futzing with your editor to support this in a way that doesn't drive you crazy. This is true with adopting any existing projects coding style in any language though.
Other than that, I agree with you Aaron, that no current languages force good design principles, and personally I cannot immagine one could. I didn't mean to tie "kicker's failure" to some kind of dogmatic argument, only make the point that having less code to read could increase the speed of detection and resolution (if possible) of design failures. Again, I think we both essentially agree that less LOC is a good thing.
HLL's also have performance issues and will have these for the forseeable future, but looking at what some of the distributions have done with GUI configuration applets in a short ammount of time is really inspiring.
jonas: That was exactly what I meant, I should have explained myself better! :) While the tabs vs space issue can be annoying with every programming language, python is the only one that I know where it can actually alter the meaning of your program!
Also I find quite ridiculous the python attitude "We're all consenting adults here" so we don't need access control to data members (i.e.: python has very limited support for private variables). What does that mean? We're all consenting adults but we need someone forcing us to use the "right" indentation?
A few points...
I don't think I'm using 'usability' out of context. Programming Languages suffer froimm usability issues as much as normal applications do. The we're-all-geeks-here attitude hurts language development IMHO. Weird inconsistencies don't just raise the barrier to learn a language -- they also raise the barrier to remember it.
I also think you're vastly underestimating the complexity of C++. Most teenagers 'conversant' (I guess I qualify still, I'm 19) in C++ just went through a class that taught them C++ is C with classes. To do real work they're going to need to understand the intricacies of the differences between pointers, references, auto pointers, and some form of reference counting. They're also probably going to need to become familiar with Boost, because everytime I ask a question, I end up pointed to Boost. ;)
Just setting up a C++ project is a huge ordeal compared to writing a Python script. In python, I can just fire up emacs, type some text into the buffer, and with two keystrokes have it run. With C++ I can either go it straight text editor and have to create a bunch of folders myself, write a Makefile, etc. or use an IDE that will force me to go through the process of creating a project. In both cases, if I want to use some library on my system, like say OpenGL, or QT even, I'm going to have to futz around adding the right compiler/linker flags. Doing this in Visual Studio on windows was painfully unintuitive -- and KDevelop isn't any better about it.
I know that design is the biggest killer, not language. I learned that the hard way over the summer, redesigning the app twice requiring lots of recoding. I'm looking at more design challenges coming down the road, and I now know making bad choices can cause me a lot of pain later.
But in a good language, that pain should be minimal. A good language should minimize the cost of redesign because design is never correct the first time. Thus I think saying that higher level languages aren't any better because they can still make bad apps is somewhat of a strawman. You're right, they're not a 'silver bullet' per se. But they can lower the threshold of laziness that must be passed over by volunteer programmers to do redesign.
Do existing high level languages like Python, Ruby, etc. do this perfectly? No. But C++ is overwhelmingly horrible about it.
> To do real work they're going to
> need to understand the
> intricacies
in my experience in the industry, this is not true =) i wish everyone did understand those intricacies because it'd be a lot more fun, but many don't and they simply don't need to.
esp boost. hell, i've yet to use boost in a real app myself =)
> design is never correct the
> first time.
indeed
> But in a good language, that
> pain should be minimal.
agreed; which is why i'm in favour of those languages for application development. (i keep saying that, don't i? =)
but this assumes that the developer has first mastered the cardinal points of good design. without that it doesn't matter which language we use, really, since one might painlessly reinvent a poor design 10 times ;)
my contention is therefore that we ought to adopt some principles of design that create code bases that survive: clarity, simplicity, extensibility, documentation ...
> Thus I think saying that higher
> level languages aren't any
> better because they can still
> make bad apps is somewhat of a
> strawman.
actually, i never said they weren't any better for development. i specifically said that C++ is better than C but still challenging, and that higher level languages are easier. we both agree that this is a good thing for many open source projects where manpower is scarce. (assuming lots of people know the language, of course)
i simply noted that this is mostly besides the point when it comes to creating transferable code and therefore successful open source code bases.
"but this assumes that the developer has first mastered the cardinal points of good design. without that it doesn't matter which language we use, really, since one might painlessly reinvent a poor design 10 times ;)"
But my point is the cost of redesign is lower in other languages, so I think language choice is important. But again you've had more experience :)
"esp boost. hell, i've yet to use boost in a real app myself =)"
HOW? @_@ Either I'm vastly overestimating its usefulness or you've found some similarly useful library. Everytime I've asked a question in #C++ boost somehow ends up getting mentioned. boost::shared_ptr alone seems like almost a required part of the language given the inadequacies of auto_ptr.
I haven't taken a look at KDE's code -- is all memory freeing still being done by manual calls to delete somepointer? Everything I read describes that as the old-to-be-avoided-unsafe way.
@Jengu: as i said, Qt makes using C++ so much nicer. i've had shared pointers for years thanks to developing with Qt/KDE.
so no, i haven't needed to use boost because i'm pretty much exclusively doing Qt/KDE devel when working with C++.
Oh, didn't realize Qt was that comprehensive. I think of it primarily as a GUI toolkit.
More hacking to do...
Post a Comment