Any "Pretty" Code Out There?
andhow writes "Practically any time I hear a large software system discussed I hear "X is a #%@!in mess," or "Y is unmanageable and really should be rewritten." Some of this I know is just fresh programmers seeing their first big hunk o' code and having the natural reaction. In other cases I've heard it from main developers, so I'll take their word for it. Over time, it paints a bleak picture, and I'd be really like to know of a counterexample. Getting to know a piece of software well enough to ascertain its quality takes a long time, so I submit to the experience of the readership: what projects have you worked on which you felt had admirable code, both high-level architecture and in-the-trenches implementation? In particular I am interested in large user applications using modern C++ libraries and techniques like exception handling and RAII."
Just kidding :))
BoD
I can almost hear the FOSS trolls approach...
-1 not first post
Hello World!!!
A Good Troll is better than a Bad Human.
The cruftiness of source code is directly proportional to the amount of time spent working on it times the number of people working on it.
Has someone created such a law before?
GLaDOS for President 2016! "Well here we are again. It's always such a pleasure." -- GLaDOS, 2011
I'm just a 15 year old with a basic knowledge of C++, I've cracked open some source packages to test how much I know from time to time and Amarok seemed fairly well done to me, though that is of course compared to other packages, I still hyad to do a little bit of searching around to understand it.
Also the Last.fm player seems fairly well done, though for both these programs I didn't look through the full code or change anything, so maybe I just happened to stumble across the only 2-3 human-readable source files?
Is an artist ever happy with a painting?
Trends and tastes change. If any coder is 100% happy with a project, they're in the wrong field.
Well, you'll always find people that say a code base is a mess when the better word would be different. I have a if statement with out { and } to close it... Is it needed in C++ for a single line? Nope - does it make it clearer and easier to read? Yes to me - and my friend Chris will tell you exactly the opposite...
And on a related note - why rewrite? Can't people ever just go for cleaning something up? No cause then you are just doing mindless reformatting - while if you rewrite, you can claim you make it better, faster, whatever... So of course people will say its better to rewrite...
Finally, all mature code is a mess. If I rewrite it, I concentrate on the core piece of functionality... That is going to be small, lean, pretty and fast... Then the code matures - it gains more features. It gains portability. It is being worked on by many... and suddenly your re-write is no better than the code you set out to replace.
Peter.
It's by Donald Knuth, it must be good (and it is).
"Practically any time I hear a large software system discussed I hear "X is a #%@!in mess,"
I get that with reading the next line you get the context, but was I the only one taken aback at this seemingly blatant flame of our beloved X?
*''I can't believe it's not a hyperlink.''
The boost libraries tend to be a pleasure to work with. BOOST::Python especially continues to surprise me by how much it 'just works'. That said, I haven't had much need to look at the source code itself, but there seems to be a strong desire in the boost community to do things in as clean a way as possible.
1) Cleaning up code is a job to do after the code is done.
2) The code is never done. Refer to rule one.
It is my experience that reading and understanding code is dramatically more difficult than writing code. It gets even more difficult if it isn't your own code. Commenting, design, layuot, good structure, documentation all reduce this fact but never remove it. I've seen plently of good programmers declare code "ugly" because it had a few warts but in reality they just couldn't understand it.
I find code can be exceptionally well presented but only if you look on a file by file basis.
Most projects have nice clean stable blocks which to look at you just know its right.
Other parts resemble a jungle and have no logical flow and are horrid.
Whenever I am building an algorithm, it goes through the numerous rebuilds, after initially getting it working each one has more and more order until it looks like it will win a race.
If the boss comes in and sees working code though, they don't understand this prettyness and will expect it to be shipped.
liqbase
public interface MessageStrategy {
public void sendMessage();
}
public abstract class AbstractStrategyFactory {
public abstract MessageStrategy createStrategy(MessageBody mb);
}
public class MessageBody {
Object payload;
public Object getPayload() { return payload; }
public void configure(Object obj) { payload = obj; }
public void send(MessageStrategy ms) {
ms.sendMessage();
}
}
public class DefaultFactory extends AbstractStrategyFactory {
private DefaultFactory() {}
static DefaultFactory instance;
public static AbstractStrategyFactory getInstance() {
if (null==instance) instance = new DefaultFactory();
return instance;
}
public MessageStrategy createStrategy(final MessageBody mb) {
return new MessageStrategy() {
MessageBody body = mb;
public void sendMessage() {
Object obj = body.getPayload();
System.out.println(obj.toString());
}
};
}
}
public class HelloWorld {
public static void main(String[] args) {
MessageBody mb = new MessageBody();
mb.configure("Hello World!");
AbstractStrategyFactory asf = DefaultFactory.getInstance();
MessageStrategy strategy = asf.createStrategy(mb);
mb.send(strategy);
}
}
I find the thing that really makes code unreadible is inconsistency. This is particularly true of languages like C++ where there is no well defined one true coding convention. If all your code is in house, this is not such a problem, because you can define your own coding convention and stick to it. If however you are relying on other libraries, chances are your going to end up with one library that names its function like_this, and one likeThis, and another fnct_LikeThis ...
Worse is when you don't even define a coding convention for the code you throw into the mix. Now you have libraries with inconsistent naming, and multiple developers all using their own favorite notation.
Additionally, their is inconsistency in the functioning of libraries. Some use function pointers, some work by inheritance, some (like glade) read the export list..
I'm not a huge Java fan, but I think they have maintainability down pat. Very consistent language, well defined coding convention, and a mature set of defacto tools (JUnit, javadoc, log4j, struts, spring, hibernate, etc..) make it a lot easier to jump into older code because everything feels familiar. In most other languages you have to spend quite a bit of time just decrypting the existing code, and then more time learning the particular API's they've chosen.
Not to blow my own horn, but I happen to think the DICOM medical imaging libraries that I maintain score pretty highly on code reuse, RAII, exceptions and general maintainability.
The more GOTOs the better!
Creationists are a lot like zombies. Slow, but powerful and numerous. And they all want to eat our brains.
The source for Tcl is widely considered by those who have worked with it to be unusually clean and clear.
I've been hacking on Remo Rickli's NEDI code (in Perl). The modules are well designed and the code itself is really beautiful; very well formatted and logically easy to follow (one would hope). I remember cracking open the tarball a while ago and being amazed...
The best I have seen are the JVMs from java 1.0 to java 6. Of course this doesn't qualify at the application level but it is still a great piece of software.
I have used other tools, namely Microsoft librairies and especially with MS librairies, the amount of time I have lost intrepreting strange results I was getting and fixing the problem was incredibly high. 7 times out of 10, the problem was a poor (buggy) implementation of what the library was supposed to do. And 3 times out of 10, it was OUR code, very frustrating and time consuming because you then have to PROOVE that the library is the problem and fill up a bug report.
With java, 99% of the time, OUR code is the problem. That's a great gain in productivity !
When I started with java, I was impressed by the structure of the JVM which I have studied extensively. I also liked the javadocs which I still use all the time given the high number of classes in java nowadays. I have never looked back since.
In our projects, to keep things clean and nicely organized, we just inspire ourselves from how it is done in the JVM source code and we do not try to re-invent the wheel with our own fancy way to do things.
Everything I write is lies, read between the lines.
What is RAll? I've never heard of that term before and quick search didn't show anything. Thanks!
Such a good reputation, in fact, that an entire book has been devoted to reading its source code. It has a reputation for correctness and portability (duh) and seems an interesting starting point.
Since I am only getting started in C programming, though, I can't recommend this book. Or the NetBSD source, either.
The right to offend is far more important than the right not to be offended. (Rowan Atkinson)
Ooops, I almost forgot:
/*
Hello World
Copyright 2002 MillionthMonkey
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
You're welcome, "World"!
I haven't worked on it much per se, but I really like the code in Angband. The style is generally consistant and easy to look at, not to mention quite well commented. Of course, it's also the first C code I ever looked at, so I'm probably a touch biased.
Angband.
We are currently in the beginning stages of a large project where I work. We are going to consolidate 2 Win32 apps (one C# and one Delphi) and 8 websites (all ASP classic) into 3 separate web applications (ASP.NET). We are also going to be re-writing most of our database stored procedures and restructuring pieces of the schema. You may be asking, why do all this? The reason is two-fold. The first is obvious: Not having to write the same or similar code multiple times in multiple languages. The second is even more important: Poor design of the existing system. There are a number of pieces of our current system that are so poorly designed that it is almost impossible to maintain them, let alone expand on them. At some point, a re-write becomes the best solution. The important thing to remember (in my opinion, anyways) is not just to re-write, but to re-design the system. Don't port broken logic and functionality to a new language. Take a step back, ask yourself what the problem you are really tring to solve is, and write the best possible solution. Well, that's my 2 cents!
the independent jpeg group's libjpeg is pretty well written in terms of style and design
TeX?
Can't say from personal experience, but I hear that the TeX source is a truly enlightning experience. Knuth is all for literate programming, you see.
At the company I work in, there is code that is generated to get a job done, and grows organically as it is required to do new things. That type of code always looks horrible, and anyone who sees it is tempted to rewrite it.
But we also have a lot of code generated for projects, that follow properly thought-out plans, and is subject to code reviews by all members of the programming team. Reviews enforce correct use of the agreed programming guidelines, including appropriate commentary and documentation.
I'm guessing that a lot of open-source software falls into the first category - tools to scratch specific itches, hacked to do more stuff, and then unleashed into the community.
In particular I am interested in large user applications using modern C++ libraries and techniques like exception handling and RAII."
This fulfills none of your requirements, but I am constantly hearing that Drupal is the final word in excellent code for PHP...
Check out the LLVM project, a compiler infrastructure package written in C++. It's a pleasure to hack on LLVM, but a nasty chore to hack on GCC.
It's code is pretty good. The quality and formatting standards are pretty high for the kernel, which shows in the research about bugs/line ratios too.
It takes a man to suffer ignorance and smile
Be yourself no matter what they say
I got to see an illegal copy of some propriety UNIX kernel code and it was a work of art.
That version of UNIX no longer exists... MSFT means computer to most people.
The only code I've looked at an thought, "Wow! this is really clean code" was the Enlightenment code.
Of, course, it *is* a complete rewrite of an old codebase - so it should be.
Mind you it's been a few years since then - it's probably a complete tangle now..
Considering the mess that is the FTP protocol, it's very pretty code for implementing that protocol.
At least, most of the time. There are times you see some code from another person and it can be very well done but appear a complete mess to you because everybody thinks different and when it comes to implementing code these differences can make you rewrite a whole system.
Having worked on large scale projects at different companies in many languages; Perl, C++, C, C#, Java, PHP, Python, Ruby and COBOL (yes, COBOL.) I can say that Ruby seems to have the best balance of power vs. cleanliness (although it lacks the built in functionality of Java or the sizeable Perl CPAN.) Java and C# manage complexity very well but lack the power of a scripting language. Python seems to be equal to Perl in its ability to manage complexity. It all comes down to programmer discipline. One company I worked for had two million lines of Perl in their main product! Because they had good programming practices it was very easy to maintain (OOP programmed and POD documentation for everything.) On the other hand, I've been handed Java code to maintain that was a mess. Poorly named methods, mysterious inheritance quirks and completely undocumented algorithms (i.e. lots of for loops with j and i variables.) To summarize with a famous quote "Developers! Developers! Developers! Developers!".
I have a theory that the truth is never told during the nine-to-five hours. - Hunter S. Thompson
This is a great question. In my experience many programs that work well often have code that is not pretty at first reading. The important thing I think is to understand both the code AND the environment in which the code was written. I think considering one without the other is pointless. Was the management geek averse? Were the engineers formally trained or did they learn by doing? Was there a time crunch, a big customer waiting without baited breath for the new piece of software? Did the developers focus on it working well with minimal configuration regardless of the elegance of the framework? Was the group all about mental masturbation and framework creation rather than implementation, testing and actually finishing something? I think it may be time for a kind of Natural Selection/Turing Test to asses the quality of a particular development approach: Imagine if you had a large sample of users. Now if all of these uses feel that the software performs exceptionally at its task that it is just flat-out awesome can we conclude that those who wrote it did an excellent job? If those that wrote the software did an excellent job, by this standard, then regardless of what approach they took, they produced great software, even if it did not follow one particular school of software development. The bottom line is that the environment and the approach play a role in selecting what software is "good". Another point to consider is that Software Engineering/Development is a relative child (Internet is 16 years old or thereabouts) compared with other more mature disciplines. Consider Electrical Engineering or Industrial Engineering, compare an Anti-Lock breaking system to a virus scanner or a modern UI with a modern speaker enclosure. Where is the "schematic diagram" for a program (and please don't say UML)? I follow the sort of evolutionary approach I guess. Design a good deal (use patterns and language facilities where appropriate), but focus on getting the thing working and working well; test it a lot, move it around as soon as you can (e.g. deploy it to a new environment), get it in front of judges(users) then enhance and test lots more, get it out there fast, but not totally kludged together. After a few iterations of this a real framework emerges (the kind software preachers say is there from the beginning) which should as soon as it is visible be implemented.
Having contributed code (the mysqli layer) to the Drupal PHP CMS, I can say that its code quality surpasses that of most other PHP projects, and is an example of good PHP workmanship.
emacs source. a work of art.
Or did you actually mean to assign the value of Mess to Maturity? ;)
From my project, I will give you a few examples of old code (horribly messy) vs new code (could be better but far less of an issue):
g er-smb/trunk/lsmb-request.plg er-smb/trunk/scripts/login.plg er-smb/trunk/UI/login.html
g er-smb/branches/1.2/menu.plg er-smb/branches/1.2/bin/login.pl
New code (not perfect by any means but not quite a F#$%*&^ mess).
Request handler: http://ledger-smb.svn.sourceforge.net/svnroot/led
Login Script: http://ledger-smb.svn.sourceforge.net/svnroot/led
Template: http://ledger-smb.svn.sourceforge.net/svnroot/led
Old code (calling it a F%$^&*g mess is being too kind...):
Request handler: http://ledger-smb.svn.sourceforge.net/svnroot/led
Login Script: http://ledger-smb.svn.sourceforge.net/svnroot/led
What, no template? Notice all those print statements?
LedgerSMB: Open source Accounting/ERP
There's a reason why they junked the code base for that browser.
And it wasn't just the browser. I've actually seen the code that Sun bought from Netscape - what Sun now sells as "Directory Server" and what used to be iPlanet, IIRC. Good fucking lord is that a TURD.
If anyone of you out there ever hires a coder with "Netscape" on their resume, you've got some serious 'splainin' to do...
Just about all code I have seen written in python is great looking stuff..mainly because of
the imposed indentation and clear language characteristics.
Got Code?
y4mdenoise is a temporal video denoiser I wrote some years back. Oh, if I only had time to continue working on it...I'd love to port it to Cell. Damn day jobs.
"Once we've identified and embraced our sickness, we'll have strength...and that's when we get dangerous." - John Waters
"X is a #%@!in mess," or "Y is unmanageable and really should be rewritten."
I see those all the time as comments in my own code.
Code of Fruit chess engine is very good. (and it's a very strong and simple engine) http://arctrix.com/nas/fruit/ Libego library (Go game angine) is nice as well. http://www.mimuw.edu.pl/~lew/ They say Netscape code is nice, but I can't find it ...
postfix (the mail program) looks pretty nice to me.
C++ has a mix of very low-level and high-level features. That, plus a plethora of side-effects and a huge range of features, means that your chances of a large "clean" C++ code base aren't great. Someone would have to enforce coding standards that limit the use of certain language features in order to get it to a maintainable state. Only then can a code base be well-maintained. If you like clean code, semantic complexity is your enemy, and C++ has highly complex semantics once all those overlapping features start interacting.
So there might be clean C++ apps out there, but it's going to be like the proverb about a dog walking on its hind legs.
Ruby or Python, on the other hand, are a different story.
Get your teeth into a small slice: the cake of liberty
God did an esquisite job on the human brain. It is well-structured and well-commented. However, I pissed him off once and he thus made me a mere mortal. Now I cannot understand any of it.
Table-ized A.I.
wins hands down. Contrary to popular belief, it's not about security, it's about quality. Security ensues.
Boost is what I call "template madness". It uses template metaprogramming to the max, which (in the real world) means three things:
(1) It's impossible to debug. You can't read the code. The debugger can't unravel the templated variables and stuff in any meaningful way for you. You can't even step through code, that's doing a supposedly simple operation like memory allocation!
(2) Some compilers will choke on the code, or compile it wrong in subtle ways due to differing interpretations of some obscure section of the enormous C++ language spec.
(3) The error messages from the compiler are useless. You have to run them through a filter to even figure out what they mean.
(3) Bugs in the library are very difficult to fix. Template metaprograms are essentially programs written in a functional language, except one that has horrible syntax. This is not the stuff that normal C++ programs are made of.
Your mileage may vary. My day job is working on a game engine for an upcoming Xbox360 game. Engines are hard enough without impractical crap like template metaprogramming in them. Give me straight-line C/C++ code any day.
Not that I've seen. I suppose in that mythical environment where programmers are always given time to do the job right, where requirements are always fully documented up front, and customers aren't allowed to change the spec at will ... sure, I imagine there's plenty of pretty code there. Now, I've never worked in such an environment, and I've taken over several large projects along the way and it was usually an ugly, thorny mess. Sometimes it's because the coders just didn't care, or just weren't very good, other times it's because they were barely given enough time to do the job, much less care about niceties.
The other problem is that code does evolve, does have to change to meet new requirements, and often there just isn't an elegant way to fit those changes into the existing architecture. Other times it's just "make the fix and get it out the door." Anyway you look at it, from an organizational and neatness perspective, code suffers entropy: it goes downhill from bad to worse. Maybe that's different in development environments that aren't subject to market pressures, but I wouldn't know. Research, or maybe government projects? I've been in the industrial sector most of my life and those kinds of projects work to schedules. Meet it or beat it.
Occasionally, codebase entropy can be reversed, but only temporarily and at great expense. Usually this is done when the disharmony has reached such proportions that the program can no longer be maintained.
The higher the technology, the sharper that two-edged sword.
it should be hard to read.
This is a sig. Deal with it.
10 PRINT "THIS IS PRETTY CODE!"
20 GOTO 10
Table-ized A.I.
My first large project I ever attempted (HERMES, now abandoned, http://hermesweb.sourceforge.net/ had, I believe, reasonably pretty code. Architecturally, there were some pretty parts too. But overall, the architecture was a mess simply because I didn't know better. I eventually abandoned it because I realized it was going to be impossible to fix the initial design mistakes without entirely replacing a large percentage of the code.
My current large project is LedgerSMB. This deals with an entirely different magnitude of mess. Essentially we forked from a codebase which we have come to understand is nearly unmaintailable and yet we *have* to replace all the code because we have lots of users on the software who rely on it. Hence we are refactoring with an axe.
The older codebase (SQL-Ledger/LedgerSMB 1.0/LedgerSMB 1.2) has a number of architectural limitations and issues, as well as a lot of evidence of an overall lack of architecture. If that weren't enough, the code is pretty problematic too. It could be worse (at least the codebase is reasonably readible if you put enough effort into it).
I think it hits about 75% of the software programming antipatterns mentioned on Wikipedia, and extends some of them in weird ways. For example instead of just magic strings, we have magic comments (comments which are actually part of the program code and which deletion causes problems). And we have function calls which pass by "reference-to-deferenced-reference." In perl terms \%$ref.
Hence we are moving everything to a new and *cleaner* architecture.
LedgerSMB: Open source Accounting/ERP
I find functional languages (lisp, haskell, etc) make cleaner code because, once you know them, they tend to promote readability.
Even though C/C++ were my first two languages, I never found the readability great. There are several factors - confusing/complex order of operations, shortened function names, lack of reusing code.
Even for the simplest pieces, I found that the code had to be read several times to be understood.
In my experience, it is C++ that ends up being a pile of spaghetti the more complex and demanding the task gets - it is not an easy thing to recoordinate the code once the task changes even slightly without resorting to kludges.
As large and old as it is, OpenSolaris has fairly readable code. Plus, most of it has comments explaining why it's done the way it is.
Maybe not
I've been using the SIP stack library reSIProcate http://www.resiprocate.org/ a lot this week, and in general it's a very nice real-world example of RAII and exception error-handling in C++. It has a bit of magic in its reliance on preprocessor macros for defining SIP header-specific methods from a single macro 'template' - but this seems to be the only way to use proper C++ typing to model the different parsed headers and keep things maintainable (although I'm aware people have tried to use mixins and roles in C++, i have no idea how well that works in practice). http://estacado.net/resip-dox/stack/classresip_1_1 SipMessage.html is an example of the doxygen for the fundamental class which describes a SIP message - browsing around the doxygen should given an idea of the rather nice RAII idiom they use, as well as the interesting usage of macros...
Picking a file entirely at random, http://svn.resiprocate.org/rep/resiprocate/main/re sip/stack/test/testUri.cxx is both a good example of RAII being used (from the user's perspective), and a fairly good example of a comprehensive C++ unit test (without any faffing around with a unit test framework). The class being tested is their class for expressing SIP URIs (surprise surprise).
:(){ :|:& };:
I've worked as a programmer for Autodesk for a few years. Autodesk has a number of very mature products, and a lot of very old code. Some of the projects have matured better than others and as a result there were some good lessons to be learned from those projects. A couple of things I picked up while I was there: - Anytime you touch a piece of code you should improve it. This will result in the software always improving over time, rather than degrading over time. - Always write the simplest code possible to solve a problem. That is don't over-engineer a solution by designing/building unnecessary elaborate flexible object models for requirements that *might* come down the road. - Assuming you have written the simplest code possible, and that you want to always *improve* the software... If you do get a requirement that the current code doesn't support w/o a kludge then immediately refactor it, but only as much as you need to solve the current problem.
I'm hesitant to say there is really any pretty C++ code out there, I do code security reviews for a living and have read a lot of code, and I don't think you can really have a useful C++ application that is also pretty. If I could ask Bjourne one question it would be 'Did you realize someone would have to read the code when the language was designed?' I mean things like placement news, templates, operator overloading, et cetera make the code horrible to read and are quite ugly imho.
"Pretty" is pretty subjective. Some see it as simple, clear, easy to read code. Myself, I find the more esoteric code "pretty" -- Malbolge, anyone?
0 /{mlk**1 0/.R,+O
(=`:9876Z4321UT.-Q+*)M'&%$H"!~}|Bzy?=|{z]KwZY44Eq
hKs_dG5[m_BA{?-Y;;Vb'rR5431M}/.zHGwEDCBA@98\6543W
It's pretty in that "sick cat curling up next to you" kind of way.
I agree completely on X. Y, I've never heard of but given the code I've written I wouldn't be surprised.
"Any app that doesn't need to be rewritten hasn't grown sufficiently beyond its original intent." - Jesse Litton, 1990
I was going to mention this myself.
Or is it the legs that do it for you?
"Pretty" is a relative term. Pretty code to me is robust, fast, maintainable, short, maintainable, readable, and maintainable: in that order.
Personally, I am a tits man.
I am very small, utmostly microscopic.
The flip-side to "pretty" code is good documentation. There are too few programmers out there who can both write elegant code and explain what it does just as elegantly. I have his "The Inform Designer's Manual, Fourth Edition" sitting on my shelf right now, and I can honestly say that it is the only manual that I have had the pleasure of describing as a "page turner".
The code itself is equally impressive. Satiated with (helpful) comments, compiles on virtually any platform, easy to read, follow, and modify as you see fit. There's also a separate "Technical Manual" for those who are interested in modifying the original code.
Let's see... Let's not forget nethack. They thought of everything. :)
http://www.nethack.org/
And then there are always those little tidbits of code like this inverse sqrt function that fall into the it just works category. Code that mere mortals such as myself can hardly comprehend - let alone write! http://www.math.purdue.edu/~clomont/Math/Papers/20 03/InvSqrt.pdf
"X is a #%@!in mess," Please leave x windows out of this! It works, Don't touch it
Some parts are NOT for newbie wimps, but the complex parts are well-justified. Most of the core code ("kernel" directory) is very clean and readable.
There are useful well-written abstractions, without the typical obfuscating layers of abstraction fluff.
The code is written to run fast, while still being portable and readable.
Static checking is all over, but not in-your-face annoying. Some of it involves compile-time assertions. Some of it involves a lint-like tool called "sparse" which makes sure that people don't do things like random math operations on bitmasks and wrong-endian data. Sparse also stops accidental (unsafe) use of user pointers from the kernel.
Of course there's a ton of "pretty" code out there.
;-)
Even though even great code bases can quickly turn into a mess by being maintained to hell by unsupervised maintenance programmers and lack of good programmers on the team. Let's be honest, maintenance is boring and which A+ programmer wants to do maintenance. And, let's not forget about stupid business decisions
Maybe you need to just find a boutique consulting company or a product development company that honors tech skills!
If you do want to see great code, look at the code of the Spring framework sometimes!
- jz
Hmm...
It is always better, in the long run, to design your "house" before you build it. Set some rules for yourself like a naming convention, a class structure that doesn't have too many levels, use templates, pseudo-code the application, type the pseudo-code into the objects, then begin coding. Keep your pseudo-code up-to-date with the actual code. Create a global error handler and use it to categorize and prioritize error resolution. Use CONSTANTS.
The pseudo-code is your documentation and design implementation. It can be extracted and used to recode quickly in a different language.
Getting a quick idea and diving into the code is a good way to get something done fast but don't expect it to be understood next time you look at it. You may re figure it out but having to figure it out is time wasted.
Pretty code, to me, is code that is not obfuscated, is well commented, well laid out, follows a predictable naming convention and accomplishes it's task with finesse and with a minimum of code.
YMMV
Codifex Maximus
Some of the best software for design, functionality and 'pretty' code that I've seen is Ogre3d, a cross platform rendering engine, It's hawt...
Postfix. It is well documented, variables given meaningful names - it's a pleasure to work with.
The best apps are the ones that were written to be extended. If I can write my own module that plugs into a codebase without touching that codebase then it doesn't matter what their code looks like.
... $obj27. (I hope there's a special place in hell for that guy)
That said, the last place I worked had some pretty decent code. A few perl modules I've worked on, such as HTML::Template were pretty nicely done as well.
My pointers for good code:
good indentation. Tabs are preferable but if you use spaces, use just spaces! I can't count the times where I opened a source file and one developer used spaces and another used tabs, or $obscure_editor which completely screws up the flow and makes it nearly impossible to figure out what block a particular line is supposed to be in.
Good variable naming schemes. The name of the variable should tell me something about what it contains. I'm sure every developer has run into the cute guy who thought it would be fun to start at $a and end at $z. Or $obj1, $obj2
Keep it simple. If $language has a short-cut for doing something, learn the shortcut instead of adding 40 lines for how it would be done in C. Don't reinvent the wheel. Also while speed is important, no one cares that your clever algorithm web app 2 nanoseconds faster than the built-in function would. It probably took you 3 extra days of time anyway.
Keep it consistent. If the developer before you used camel case and you don't like it. Suck it up and use camel case. Same for anything else. Code religion can be fought by the water color or in the coding guidelines meetings. In the source files it just creates a mess for everyone else.
The Anti-Blog
NetBSD has, in general, quite good code for both reading and understanding. Have a look!
At least you admit to being uninformed.
I haven't looked either, but I happen to know that BOOT::Python often does NOT work. It has thread-related problems.
At for the rest of BOOST, I've looked at a good chunk. BOOST makes decent programmers cry. The other follow-up post by the Anonymous Coward Xbox developer has it all correct.
I'll add:
BOOST is full of butt-ugly hacks. Check out the, uh, template things, named _0 through _9 being used as stand-in dummy arguments. Eeeeeew!!!
BOOST looks easy to dumb-ass programmers, but these programmers leave bugs that are difficult for expert programmers to find.
BOOST makes compilers run very very slow, and often breaks the optimizer anyway.
"only a smell in my opinion if they are hard to read"
A friend of mine used to say: "Source code is like shit, it stinks when it's not yours."
And did you exchange a walk on part in the war for a lead role in a cage? - Pink Floyd.
This is a really great question! But unfortunately I have no really good answers. Working code in the real world runs the gamut from brilliant to horrible. And to make matters worse, this range exists usually within a single project.
Sorting the wheat from the chaf (sp?) is a difficult task. This is made even more difficult by the fact that you will get as many definitions for "good code" as the number of people you ask. I've thought a lot about what good code means to me. And I've finally arrived at an answer I think is acceptable.
Good code is code that is easy to modify. The easier it is to modify, the better the code. By "easy to modify" I mean that taken any random problem, the path to making the existing code solve that problem is straight forward and obvious to implement.
Even with this definition I run into problems. Normally people find their own code easy to modify, and other people's code difficult to modify. Thus, I make the extra statement that the easier it is for other people to modify, the better the code.
This lets out a lot of "pretty code". Above, someone posted a really great solution to "Hello, world". It is, in fact, extremely pretty. But it is not the simplest solution and thus difficult to modify. I would not call it (nor do I expect the author would call it) "good code".
Unfortunately I would categorize many "modern libraries" in this same group. They are often extremely well written and very pretty. But using them increases the complexity of the code and the resultant program is not what I would call "good". Often *not* using those libraries results in simpler and better code. But judicious use of the appropriate libraries is also essential to writing good code.
So, I wouldn't spend too much effort looking for good code. In fact, good code is often hard to recognize unless one tries to modify it (at least if you use my definition). So a better approach would be to practice writing and modifying code. A good place to do that can be a coding dojo.
These are groups that have sprung up in the last few years that practice doing coding problems. Being able to study these scenarios is one of the most important things you can do to improve your coding ability, IMHO. Most of these dojos use a variant of extreme programming to practice. I believe this is also worth learning, whether or not you end up using the practices on your own.
Do a google search for coding dojo and check out what they are doing. I think this will be closer to what you are looking for.
I don't know about 'pretty', but the Lions' on 6th Ed. Unix is a great example of /clean/ code. I think of it as 'pretty clean'.
d p/1573980137/ref=pd_bbs_sr_1/002-4816217-2120035?i e=UTF8&s=books&qid=1184460207&sr=8-1
http://www.amazon.com/Lions-Commentary-Unix-John/
As for clean C++, it's harder to appreciate I think because C++ has a bit of overhead to it that makes the code appear more sprawling.. harder to appreciate I think. That said I feel that out of the many C++ apps I've written, large and small, there are a few I think are 'clean' and even, dare I say, almost 'elegant'. But it takes a lot of effort; one can spend a lot of time cleaning things up, and making comments 'just so'. I put the most effort into code that I know will be seen publicly, or might need to be handed off to others.. open source and team oriented work for hire especially.
init 11 - for when you need that edge.
"Pretty" is for weak warriors who want their mommies. Us Klingons have rules to keep the Klingon Spirit in our code:
# Specifications are for the weak and timid!
# This machine is a piece of GAGH! I need dual Pentium processors if I am to do battle with this code! You are MISTAKEN!! Only a most excellent machine could be worthy of being compared to a plate of gagh! How dare you! I am NOT mistaken. Machines should not be eaten, they are weapons, they should be hard and sharp, not soft and creepy!
# You cannot really appreciate Dilbert until you have heard it in the original Klingon.
# Indentation?! - I will show you how to indent when I indent your skull!
# What is this talk of "Release"? Klingons do not make software "releases". Our software "escapes", leaving a bloody trail of designers and quality assurance people in its wake!
# Klingon functions calls do not have "parameters" - They have "ARGUMENTS" and they ALWAYS WIN.
# "Debugging"? Klingons do not debug. Our software does not coddle the weak.
# I have challenged the entire quality assurance team to a Bat'leth contest. They will not concern us, again.
# A TRUE Klingon warrior does not comment his code!
# By filing this user request, you have challenged the honour of my family! PREPARE TO DIE!!
# You question the worthiness of my code? I should kill you where you stand!
# Our users will know fear, and cower before our software! Ship it! Ship it and let them flee like the dogs they are!!
# Sales people have no honor
# Four thousand lines of code may be typed in one night by a fast coder.
# A bug may become a feature in the time it takes to compile the code.
# Only a fool codes in an IDE.
(list commodered from c2.com during glorious battle)
Table-ized A.I.
I think the more convenient issue here is that programmers need to stop messing around with all there little "codes" and "programs", and just learn to speak binary. Get to the heart of the issue. 010100011101011011011100010110011 Run Jane, Run 0111011001010010101101101010110011110100 See Dick grow.
It's not big, and it's not c++, but I think the prototype Javascript library is a pretty good example of where brevity, functionality and "prettyness" should meet in code .
t ype.js
http://www.prototypejs.org/assets/2007/6/20/proto
-... ---
You lost "pretty" right there.
Neither "goto" nor "longjmp" could be so bad. Exception handling takes you up the call chain, over some arbitrary number of calls, right out through arbitrary locations in your code. Holy crap! The bug potential is amazing, as is the obfuscation.
If I do say so myself, SWISH++ has pretty code.
If you reply, do so only to what I explicitly wrote. If I didn't write it, don't assume or infer it.
I wrote a Perl filter that took C code as input, and applied all kinds of "unprettifications" to it (removing comments, collapsing variable declarations, introducing random curly-brace and indentation styles, removing whitespace or adding strange whitespace). The output looked like it had been written at 3am by a hung-over ex-FORTRAN engineer who had just discovered FORTH.
Then I demonstrated that a bunch of code checked into our system looked like it had *already* been run through this tool. After the public shaming, a couple of the offenders cleaned up their acts for a while, but they're back to their old tricks.
These days I'm working on a project where all the devs are really, really serious about the formatting and naming conventions. Some of the rules suck, in my opinion, but there's a lot to be said for consistency.
[In the 80s, HyperCard team at Apple used to regularly run their sources through a Pascal formatter. The code, in a friend's words, "looked ironed." Unfortunately I haven't run across any good C++ formatters.]
Any sufficiently advanced technology is insufficiently documented.
As soon as you go a fair bit beyond the trivial, code is just a mess. There really isn't a way around it. The only reason why people might think that this isn't the case is /because they are used to it/. And there is a significant difference between used to it, and clean.
I should point out that your DefaultFactory's singleton is not thread-safe, and the entire getInstance() method should be synchronized.
Good thoughts, except I don't accept your argument that mature code is a mess. If developers refactor while coding, mature feature-full code can be almost as elegant as the original code.
I do like that you mention differing syntactical preferences between developers. We have 3 people on our core team and we all have *very* different ideas about what code is elegant, in terms of: newlines, tabs/spaces, curly braces, etc. We do, however, have common ideas about what parts of our codebase are elegant / easy to work with, and what parts are a "mess." We all have the same sense of code smell.
The key thing is to make sure developers "refactor ruthlessly." If you keep your code clean and maintainable, you won't find yourself in the situation where you're considering completely rewriting it.
Also, if you have a good test suite, it makes it easier to refactor (or do big rewrites) as you'll be able to easily see what you broke. In theory, you'll know you're done when all of your tests pass again.
I have worked on several projects in several languages. In general, the code I have been given is of high quality. I might not have written it that way, but I have never had a problem reverse engineering it, understanding the design decisions, and make the corrections. I suspect if code, as all designs, were approached by engineers and not critics we would have much better products.
In fact the only bad code, as far as i am concerned, is when someone is trying to apply the latest and greatest paradigms without thought or rationale. I have certainly been guilty of this, and have written stuff as bad as the design pattern in this thread. Cleaver code is for contents, not professional efforts.
I suspect that rather than looking for pretty code, looking for code that teaches a technique would be time better spent.
"She's a scientist and a lesbian. She's not going to let it slide." Orphan Black
You missed a major WTF; HTML in the database layer and the author thinks his code is an example of good design practice. Ugly too When I'm logged into a server and need to diagnose a problem, lines that wrap on an 80 column term quickly become unreadable. Hell, I have to scroll sideways to read it in my fucking web browser.
cruftness = people * time is a reasonable approximation, I can confirm the same kind of stories. Even if the operating system and the projects software would be trustworthy, the consultants would probably %$^& the customers database too. Hurray for corporate politics.
Here is a little teaser though
If you are about to mod me down, keep in mind that this post was most likely sarcastic.
This is not surprising to me. If you play Graham Nelson's game "Curses", you can see that the man has a crazy ability to keep lots of things happening without making it look like a mess. His brain, and what he does with it, is amazing.
The brains of a chicken, coupled with the claws of two eagles, may well hatch the eggs of our destruction.
Sometime around 2000 I was asked to make a change to the way Postgres did something. At first I thought it would be difficult, given the size of the code and the amount of time I could realistically spend on it. It turned out that I could basically make the change blind -- the affected area of the program was nicely segregated from the rest.
This isn't really a "pretty code" scenario. It's actually a "pretty design" scenario. The difference being that the program was very easy to change once the affected area code was understood (which didn't take long either), rather than just having easily understood code. I've seen code that was so easy to understand that it read like english, but was so self-involved that, with only 150 lines, I didn't know how the program worked before spending a few hours on it.
10 PRINT "HELLO"
20 GOTO 10
It's pretty basic.
My experience has been that I've never seen pretty code outside an academic environment, where (surprise, surprise) you're sometimes graded on making your code (a) readable and (b) follow some sort of coding standard.
In the real life, which includes innumerable projects and as many customers, I've never seen pretty code. I've noticed that if there has a choice between prettifying the code and putting in more functionality or unit tests or making the interface more consistent, the team has not gone for the first choice.
I even had a project manager that answered me, when I wanted to spend time to make the code "better" and more manageable, told me to prove with numbers that it would give a positive ROI to refactor (we didn't have that word back then) the code. Otherwise, it was on to the next segment. Essentially it would have taken me longer to prove that I needed to refactor the code than it would have taken me to refactor it.
Of course, the next reply to this post would be, then why didn't you just refactor the code, then? Because (a) I still would have had to come up with the justification, not the code; and (b) I wanted to keep my job.
Aside: this is also the same project manager that told me to customize the process for the segment, then when it was late and didn't work correctly, because we were given a small amount of time to do it, he said we failed because we didn't follow the process.
Go figure.
DT
Is this thing on? Hello?
Check out the Delay Tolerant Networking reference implementation at DTNRG -- maybe not consistently formatted through and through, but overall design is solid. Full Disclosure: I am not one of the primary authors, but I have contributed a few items.
Having read some of Gregory Chaitin's stuff and having a background in electrical engineering Com stuff, I would imagine that the smallest and most efficient algorithm for any particular task would unfortunately be one that exhibits no patterns or regularity. Otherwise, further reductions could be made. Just as in data compression, the smallest representation is irreducibly complex for its size. In other words, the cleanliness of the code might often come at the expense of computational efficiency in order to abstract the process in a way that is clear to the reader/writer.
I can well imagine that a linker would choke on Boost.
For those with a Linux/BSD/Solaris system, try running the "nm" command against a solidly Boost-infected project. You're likely to find function names that are THOUSANDS of characters long.
Think about what that means for program start-up, at least if you call into a library. The runtime linker has to chew through all that gunk. I've run a profiler on this kind of code, and sure enough the start-up time was dominated by looking up all those giant symbols.
So ugly it's pretty.
REM grab http://download.microsoft.com/download/win95upg/to ol_s/1.0/W95/EN-US/olddos.exe
REM for the qbasic.exe
SCREEN 13
WINDOW (-2, -2)-(2, 2)
FOR x = -2 TO 2 STEP 4 / 320
FOR y = -2 TO 2 STEP 4 / 200
u = 0
v = 0
FOR i = 0 TO 256
REM (u+vi)^2=u*u-v*v +2uvi
ut = u * u - v * v + x
vt = 2 * u * v + y
u = ut
v = vt
c = i
IF (u * u + v * v) > 4 THEN i = 256
NEXT i
PSET (x, y), c
NEXT y
NEXT x
First, compare the way each author handled security disclosures.
Found nothing shameful? Did you see this about Postfix? http://cr.yp.to/maildisasters/postfix.html
Next, compare the number of false public statements made by each author.
Found nothing? Did you see this about Postfix's author? http://cr.yp.to/qmail/venema.html
And finally, compare the number of security flaws and their severity in Postfix compared to qmail.
Ultimately, do you support or condone the behavior documented at http://cr.yp.to/maildisasters/postfix.html
-- begin quote http://cr.yp.to/maildisasters/postfix.html --
IBM released Postfix with massive hype in mid-December 1998. ``IBM software to shield email from hackers,''
blared the Reuters headline. ``This will make IBM's and everyone's Internet activities more secure,'' IBM's network security research manager said in a prepared statement.
A few days later I glanced at the Postfix security documentation. ``No Postfix program is set-uid,'' the Postfix author wrote. ``Introducing the concept was the biggest mistake made in UNIX history. Set-uid (and its weaker cousin, set-gid)
causes more trouble than it is worth.''
This set off alarm bells in my head. ``Does postfix really use a world-writable directory
for people to drop off mail?'' I wrote in a 19981217 email message to another security expert.
``Is there anything that stops a user from making a hard link to another user's message, preventing postfix from delivering the message?''
In fact, when Postfix saw an extra hard link, not only would it fail to deliver the message, but it would actively remove the hard link, Any local attacker could trivially exploit this to anonymously destroy other users' incoming or outgoing messages. There was no way for the system administrator to find the culprit, and no way to recover the messages.
The Postfix author's reaction to my first public comments was outright denial. ... Bogus. ... Bogus. ... Bogus.'' He continued by giving an example of how an incompetent attacker might fail to destroy a file.
``Bernstein is wrong on all points,'' he said in a public statement in response to a summary of the problems. ``Bogus.
Several people pointed out his mistake, but he continued to deny the problem. ``In my opinion, no-one has brought forward a vulnerability worth mentioning,'' he said in a bugtraq message titled ``Claimed Postfix Vulnerabilities.''
I sent a detailed description of the vulnerability to bugtraq.
/var/spool/postfix/maildrop, and /etc/postfix/postfix-script, replacing 1777 by 1733.
The Postfix author finally admitted that the attack would destroy mail. However, he didn't post a security alert on the Postfix web pages. Instead he added a brief note to the middle of the ``Postfix Errata'' page:
A local user can hard link a maildrop queue file to another
directory within the same file system, causing the mail to not be
delivered. Workaround: chmod 1733
edit
When I saw this, I posted a note to comp.security.unix, explaining that this ``workaround'' simply didn't work. Any user could still anonymously destroy messages.
The Postfix author followed up, using the subject line of ``DAN BERNSTEIN'S CLAIM'' without admitting that my claims were correct, summarizing the problems as ``local users [can] play games with hard links'' without mentioning that these games
Phoenix Technologies used to make both BIOS and printer software. The printer software department split off and became a different company, and then I lost track of them...
They made printer software that went into virtually every printer not made by HP at the time. Canon, Ricoh, Lexmark, or whoever would come out with new hardware and license the software from Phoenix. Yep, some of my code is in every Lexmark printer right now.
They had a couple hundred thousand lines of code that did PCL, GL, and Postscript for the consumer market, and it was the most readable and well developed code I have seen. Comments were explanatory, variables were well named, and execution paths were well defined and easy to follow.
They really had their act together for testing as well, with an elaborate and comprehensive regression suite that checked *every* aspect of all of the [printer] languages, and a team of QA people who would go over the results nightly. I'm not making this up - you would come in to work in the morning and there would be maybe 5 E-mails from QA outlining bugs which were either in your code or assigned to you for reasonable reasons.
We did the software for the first Lexmark printer. The first internal release gathered 900 bug reports from QA. When we went to market there were 7 remaining, all of which were deemed inconsequential.
When you are in the commercial market making fixed-program computers (dishwashers, printers, cell phones, VCRs) you don't have security updates and new versions, and a recall is usually out of the question. It's much cheaper to do all of your QA up front and ship a quality product.
In my opinion we've grown sloppy in the programming business. I've been a contractor for the past 30 years and I haven't seen anyone else who comes close to true quality procedures. Even FAA safety certified stuff is usually hokey and obscure. Thank god we've still got human pilots.
Having seen the procedures firsthand I have an appreciation of how easy and valuable it all is. No one else seems to understand that, and so everyone keeps running around putting out fires and slipping deadlines.
There's a difference between a problem being difficult(anything NP-complete) and the language making a problem difficult.
Please, for the good of Humanity, vote Obama.
The interfaces are important to me. How well are they designed? Is the implementation clean yet expressive enough to expose all the necessary functionality?
Underneath, you can connect to the OS-dependent -- and often hideous -- code. What you provide as an API is what's important: the interface. Compare, for example, Be's API and the Windows API or X.
Of course, maintainability for what's underneath that interface is another issue altogether. I've had managers say, "Don't reinvent the wheel!" To which I want to reply, "Well, if you'd managed this properly before I got here, the wheels wouldn't be fucking square and I wouldn't have to reinvent them..."
The Bourne Shell must get some kind of mention here. What do you do if you prefer ALGOL to C? Why, #define your own syntax, and thus turn boring old C code into a thing of beauty.
Repton.
They say that only an experienced wizard can do the tengu shuffle.
SGIs Standard Template Library is always memorable to me as being written in a concise, pragmatic and elegant way. It's the sort of code that is self-explanatory, requiring very little comments. Sorry it's not a larger project, but it left quite an impression on me when I first went through it all those years ago.
Inside every beautiful person, there's an ugly person trying to get out.
Many pieces of old code aren't pretty for a fairly defined set of reasons:
1. a) Debugging Ensure you actually have an appropriate way of debugging the code. The systems I work with are embedded and run 7x24. People will say: it failed last week on Wednesday at 3:00 A.M., we got it working, but can you fix the problem? The problem may not actually be your code, it could be another piece of equipment. In any case, you need to figure this out from the logs. In my experience, many "pretty" programs are too small to justify extensive logging. After logging is included, the programs become less "pretty" but much more maintainable.
1. b) Refactoring after Debug Sometimes the results of the debug will show a major design error in the program. You now need to implement a major architectural change that really was not originally intended. You have good modular code when it can withstand these major design changes in a relatively smooth manner.
2. Failure to handle common areas of problems well These include:
2. a) Strings Does your program have the ability to smoothly handle unicode/UTF/HTML/locale specific strings? Every different language you port your application too, and every different program you talk with, will all have differing definitions of what is a string. My favorite test case is CNC (Computer Numerically Controlled) machinery. Some CNC machines expect embedded nulls inside the strings. The embedded null requirement affects a surprisingly large number of string libraries.
2. b) MessageBox() Invariably in a big program it will be unacceptable to allow it to hang on a modal dialog box like MessageBox(). How are you going to handle it? What if a library call executes a modal dialog box?
2. c) Handling Exceptions For a simple prototype program, handling exceptions is not a big deal. In a production application, all the exceptions must be handled appropriately and the program must be able to continue when exceptions occur. The error handling code often exceeds the size of the original program.
2. d) Third Party Libraries / Operating Systems (Windows) The amount of code devoted to covering up mistakes in other code is amazing. Unfortunately, unless coding on an open platform, one must accept the costs of the additional code. When starting a new project, I recommend thoroughly stress testing any new libraries that will be used. Thus one can find the killer bugs that significantly affect design decisions.
I would appreciate any feedback/additions to the items on this list.
The code at http://www.trading-shim.org/ is 'admirable code, both high-level architecture and in-the-trenches implementation.'
For the last couple of years I have worked closely with the lead architect (and implementer) on this FOSS project; full GPLv3 C++ sources; TeX documentation sources and architectural notes (in ongoing buildout and revision), mailing lists, bug tracker, project domain, and availablity of the code author for clarification and feedback all make for an admirable solution set in a non-trivial problem space.
That author, Bill Pippin, is a PhD in computer science (his earlier disseration, and the project's PDF are at: http://www.trading-shim.org/pdfs/), and his strong views on 'the singletree', as a method to drive a clean implementation. As explained at p 67 of the current documentation PDF, 'the singletree' represents a single root object, which permits avoiding the mess which the more common multiple static variables brings with it. As he notes:
Applying the singletree pattern eliminates the global, class, and local static variables that infest most programs, and allows the designer to restrict access to global state.
This has permitted fast development of very clean (and maintainable and extendible) C++ code in the complex problem domain of 'a command-line and dbms controlled interface to a socket-based API' upstream, which in turn probides access to comprehensive feeds and archives for tick and history data, and computer assisted financial market trading through the premiere electronic brokerage in its class.
The code is not for the faint of heart, nor for who are not yet fluent in C++, but its elegant software engineering techniques are used here and in his prior disseration work to control program complexity: in particular by demonstrating a non-trivial instance of the single-tree pattern, whereby all singleton types are parameterized and then stratified by their binding pattern. (from the README)
-- Russ Herold
"And don't forget that postfix is well-commented,"
In all fairness, nobody has ever cashed in on Bernstein's security guarentee. There have been some oopsies with postfix.
I think Bernstein's code is as nice as it gets. Course, Dan is polite to me too; so maybe I live in an alternative universe.
Need Mercedes parts ?
I know you don't want to hear this. Really, I understand. But...
Just about everything is going to be a "fucking mess". And yes, every now and then, you'll find something truly elegant -- and every now and then, you'll find something that you're amazed even compiles (if it does). But right there in the middle, it's always a fucking mess.
And, someone ran a study -- I forget when, or what study, but what they found was, essentially, the ratio of bugs to lines of code was about constant, no matter what the programming language. That means languages like C++ and Java, which tend to be verbose, are likely to have more bugs than a language like Python, simply because Python will get it done in less code. (Incidentally, it also means libraries are better, especially if you don't have to write them yourself, because that one function call counts as one line of code for your project.)
In short, the most reliable way to reduce the number of bugs in your code is not to write more elegant code (which, sometimes, just means more obscure bugs), but to write less code.
It's not always an option, because frankly, I haven't found a language out there that doesn't suck in some way. It seems to pivot around Java -- either things are easier and more abstract than Java, but lack low-level features, the most annoying being real OS-level threading (Python pretends, but the GIL kills it) -- or they're harder and less abstract, like C and C++, but suddenly vulnerable to stupid things like memory leaks (uncommon in high-level languages) and segmentation faults (actually impossible, except by a serious bug in the language itself or a C library you link to).
Don't thank God, thank a doctor!
Hydranode is extremely modular!...And that is why it died, there was no fixing to get the n00bs involved
Why can't they just leave a good thing alone?
Someone hit C with an ugly stick and called it a language. C++ was *never* a good thing.
Microsoft is to software what Budweiser is to beer.
Some of the most elegant and functional code I have ever seen was done in Python. Anything pythonic is rather elegant and beautiful. But whether it's pretty is in the eye of the beholder. I happen to think large parts of the GTK+ source code tree are very elegant, functional, and fairly easy to debug. But they are in C; they aren't pretty. Lots of cruft to make object-oriented construcs. But once you recognize the patterns, you'll see real elegance. The same for any language.
It's kind of like how the world is full of hot women, but very few of those are beautiful.
Keeping any sufficiently complex code base 'clean' is like battling entropy. Eventually any code base given enough changes becomes 'messy'.
I've found the best code is planned code. Code is best, when it's created by following a methodology. It's best when the code has been written in requirements and design documents and merely typed into source code. Code is best when it's been written twice. Code is often at it's worst when it's adversely affected by scope creep, programmers stumbling over a new architecture, or poor management.
Reading code is hard. Ever try to 'debug' a mathematical proof. Sure natural language is too ambiguous for most math.* That's why logic was invented (see the chapter on Leibnitz). Going from symbolism to natural language is hard, understanding context is even harder. Just ask anyone doing research in NLP.
*I'm not a logician, but as a side note, I've always found Raymond Smullyan's books on formal logic to be the 'prettiest' math books around. He has a naturally recursive mind.
What do you mean my sig is repetitive? What do you mean my sig is repetitive? What do you mean....
I've briefly played with Gnumeric a while ago and actually added a couple of minor features to it. Despite being an OO application written in C (Yes, this is possible, but the language doesn't help you at all), it was the most easy code that I've ever worked with. It was extremely easy to understand and find your way around.
However, the thread issues are with Python, not Boost. There's a more detailed description in the Python docs, but basically the Python interpreter isn't designed to run more than once in the same process.
ROMANES EUNT DOMUS
Drupal may be slightly less horrible than some other common PHP apps, but its still absolutely terrible.
...but I lost it. There was an article from 2 to 4 years ago in which clean code was discussed. This one guy wrote in to brag not about his own code, but about the code of the first seasoned developer he worked with. The guy was using some old language, but it had "if" statements and the like. Anyway, the guy had named his variables beautifully so that any given line of code read like a normal English sentence (almost). I discounted his implication that code could be "prettified" just by variable naming, but then the guy posted an example -- maybe 20 lines -- that he had kept all those years. And it REALLY WAS beautiful. It was so clean that a year or so ago I searched Slashdot to try to relocate that sample code. Never did find it.
My Greasemonkey scripts for Digg &
Read the Gang of 4 design patterns book...
Palm trees and 8
that he thought Bill Atkinson's MacPaint was the most beautiful program ever written. Hearing this, Andy Hertzfeld made it a priority to recover the source code from an old Macintosh diskette. He contacted me because he was a bit worried about Apple's reaction if he just released it on the net (since it was Apple property), and I advised him to get the Computer History Museum involved if he didn't want to take the risk. I believe that he donated the code, but I'm not sure what the Museum did to have it made available.
Tim O'Reilly @ O'Reilly Media, Inc. 1005 Gravenstein Highway North, Sebastopol, CA 95472 http://www.oreilly.com
Linux is nowhere close to clean, good code. Some parts are pretty good, but overall its rather poor. Compare the code of any hardware driver for instance between linux and say, netbsd. The linux version will be 2-5 times larger, and contain all sorts of non hardware specific functionality that should be seperated out and shared between all the similar drivers instead of being re-implimented 10 times.
So this post is perfectly timed. It's a collection of essays by leading software engineers about code they find especially beautiful.
h tml
Andy Oram, the editor, thought it would be poor form to make a post himself, but heck, I thought: this is very relevant. The table of contents for the book can be found at http://www.oreilly.com/catalog/9780596510046/toc.
It includes essays by Brian Kernighan, Jon Bentley, Tim Bray, Yukohiro Matsumoto, Simon Peyton-Jones, and many others. The code is intended not only to be beautiful but also instructive and in many cases re-usable.
We're hoping to build an ongoing site around the book so additional examples would be very welcome.
Tim O'Reilly @ O'Reilly Media, Inc. 1005 Gravenstein Highway North, Sebastopol, CA 95472 http://www.oreilly.com
First, create a code standard. This takes a whole team, and not one developer who has personal preferences they cannot back up with reasonably sound advantages.
Second, establish code reviews. If your code does not meet standard, you highlight the section, function, object, etc. and you schedule a refactoring task.
If you're not doing either, then sure, you're going to produce "cruddy" code. I'd say if you're not doing those two things, either you have a really small team that is just magically on the same page, or you're basically working without a real structure.
Code that someone, anyone, on the team is not going to like will occur under a lack of a proper team system. What is pretty to one developer is a kludge to another, I've found (over and over again). What is sleek and efficient to a developer with an embedded background, may be perceived as inflexible by someone with a web/server side or modular applications background. Also, just because a junior developer doesn't like some code, does not always mean he has headlights in his eyes, so to speak. If a developer wants to rewrite something because he doesn't understand it, sitting down and working out coding standards will prevent them from rewriting it some way that someone else won't like. It will help them get a better grasp of the code. But most importantly, if the code IS a kludge, then the team will have their attention brought to it.
Symbolics Genera.
Sure, there are many examples, however I will tell you that there's little or no universal agreement. For example, I know some folks that consider qmail to be a terrific program, at least in design and coding, but there are plenty of criticism of qmail.
I suggest getting a copy of Code Reading: The Open Source Perspective by Diomidis Spinellis. He at least will introduce readers to a number of different criteria by which code can be judged.
Comment removed based on user account deletion
Not a C++ project, but Solaris code is beautiful. Sun writes very concise and clear code. I've done work with the Solaris, BSD (several "modern" flavours) and Linux kernels. BSDs are pretty nice, but Solaris is simply a joy to work with. Everything is where you'd expect it, and when you get there, you see nothing more and nothing less.
Linux kernel code is like a pile of vomit with contributions made by a communist drinking game including someone every UN reconised country. Even worse, the Finn who started it couldn't hold his liquor.
And my experience was dealing with the rather messy job of packet capture and assembly.
-Former Linux Zealot.
I must say that if you want to see how code should be written take a look at Micrium uC/OS-II. Its beautiful! To bad the owner is a prick.
Another thing to consider is that for new/fresh programmers who just recently graduated college, many of them have spent the last 4 or more years studying the ideals of software (and database) design. In the "real world" things aren't always going to live up to the ideals taught in academia. For example the programming team may been required to sacrifice elegance to meet critical deadlines.
Ah, yes...the flamebait comment from the "expert" who doesn't understand how to use a powerful language feature. It never dies....
"(1) It's impossible to debug. You can't read the code. The debugger can't unravel the templated variables and stuff in any meaningful way for you. You can't even step through code, that's doing a supposedly simple operation like memory allocation!"
Well, rather than getting into a childish "can too!" debate with you, I'll posit that it must have been pretty damn hard to develop boost, if all of the things you mention were actually "impossible".
Better explanation: you don't know how to debug template code. Sad for you, but not a strike against the language.
"(2) Some compilers will choke on the code, or compile it wrong in subtle ways due to differing interpretations of some obscure section of the enormous C++ language spec."
Oooh...scary! Guess what, mate: some FORTRAN compilers choke on legitmate F77 code for the same reasons. This is nothing but a FUD tactic, dressed up as informed criticism.
Boost is well-tested against the major C++ compilers, and you can always find out the status of the various sub-libraries by going here.
"(3) The error messages from the compiler are useless. You have to run them through a filter to even figure out what they mean."
See #1, above.
"(3) Bugs in the library are very difficult to fix. Template metaprograms are essentially programs written in a functional language, except one that has horrible syntax. This is not the stuff that normal C++ programs are made of."
I think your second, third point says volumes about your problems: if you don't know how to use it, then it isn't "normal".
Sometimes, you have to learn new things to be productive in a new programming style. I could spend a great deal of time proving to you that there are many thousands of expert C++ developers who know how to do all of the things that you claim to be "impossible", but it isn't worth my time. I'm just hoping that a few knowledgeable developers will see this, and remove the ridiculous "Insightful" moderation from your rant....
Let's try not to let fact interfere with our speculation here, OK?
I know this really isn't code, but APIs mean a lot to - and I hate to say it but M$'s .Net APIs are really well laid out and designed. It allows for the code developed using them to be a lot cleaner and easier to read. Also, if you stick with their naming conventions the code is easy to read as well.
The Java API seems to have similar benefits, but I'm a lot less experienced with it, so I'm not a good source when it comes to Java.
Yeah, yeah - I said something pro M$, mod me down.
- I voted for Nintendo and against Bush
At least it is where I work. :-)
Here's an example of a recent SQL Server 2005 stored procedure named pivot_table.
CoderDudeSQLite has very good architecture, code (fully and relevantly commented), documentation and tests. Its bug tracking is also very good. Sure, it is not a very large code base with lots of developers but it is keeping clean in its evolution. Just compare it with Firebird (which has admittedly more features): Firebird code is such a mess, from top (architecture) to bottom (name of variables). I'm not advocating one software above the other, but just saying that comparing both is interesting and shows that it is possible to make good software robust and clean instead of poor and messy.
http://llvm.org/ is one of the better C++ projects I've seen. Quite large, but also clean and tidy.
Your code sucks, drupal is a mess. Being not quite as messy as phpbb doesn't make it "good". Mangling SQL with regexs? Really poorly written regexes at that! Drupal doesn't even have a seperation between display and database code, there's HTML pieces floating around in the database layer. That's the kind of thing that would get a junior code monkey fired here, its as far from good code as you can get.
Here's some code of mine.
"Pretty bad" that is...
That is all.
Most (if not all) OpenBSD code I have dealt with gives me a warm tingly feeling inside. It isn't C++, but they have their reasons.
Haskell is very pretty. No junk characters like curly braces or semi colons. Also- being as it is a functional programming language, it is also very elegant.
Laura Wingerd and Christopher Seiwald wrote an excellent chapter on this topic for O'Reilly's Beautiful Code book (just out). See Chapter 32, "Code in Motion". The code from their chapter is online here: http://www.perforce.com/beautifulcode/
http://www.red-bean.com/kfogel
Two interesting quotes:
...
"BOOST makes decent programmers cry."
- And as we all know: goatse.cx makes decent programmer's cry. Therefore, Boost *may* be like goatse.cx
"BOOST is full of butt-ugly hacks. Check out the, uh [...] Eeeeeew!!!"
- Yep, Boost is definitely like goatse.cx
I am anarch of all I survey.
When i was taking C courses at UC Berkeley the professor made a few rules:
As much as I thought this guy was a total asshole, he wrote damn good code.
I am personally just sick to death of this notion that you should just get it. Well commented code means you have a comment for everything even things you think are obvious. If you write code that is of any consequence there will be someone coming along after you that has to either maintain it, modify it or re-write some portion of it. Additionally at some point if you are a good programmer you will have to come after someone else and maintain, modify or rewrite their code.
Code style is another thing all together. Style Nazis have their place, an no its not sitting on the freeway tied up waiting for a semi to run them down. They exist to make sure code is clear and readable. I once worked on a project and there was a definite style Nazi working there. Her ONLY job was to enforce the style rules. She would check everything you wrote and would give you notes and your code would not be submitted for the nights build if you turned it in last minute or if your code didn't meet the style rules. Now this got me into the shit with my manager at least once, but I am a better programmer for it.
Every #include, #define, everything had to have a comment stating WHY it was included and a general note as to what it was supporting. They even had boiler plate for stdio! I know that seems WAY over the top, but there was not a module of code that I couldn't understand the basics of what it was doing in about 5 minutes just by reading the comments.
A lot of the code I see in CVS's and things like that is just pure garbage.
Don't EVEN get me started on what some of these Java monkeys do. Oy!
Hey KID! Yeah you, get the fuck off my lawn!
the short answer is "no."
http://worsethanfailure.com/Default.aspx This site is very funny and all about bad code!
That's for weens. For examples from real coders, look at the Shuttle launch software and Don Knuth's TeX.
They are both truly beautiful.
So I see that everyone and their mother (right upstairs) has an example of ugly code, or why something is not written as well as it could be. Plenty of mentions here of why decent programmers hate this or that (mostly well-reasoned), but no examples of good code that everyone can agree on. I can't claim to be a "good" or even "decent" coder, but I will refrain from knocking everyone else's code if I am not good enough to contribute to it. Enough with "You want ugly, check out project xxx," what do you actually have to offer that IS easy to read, comprehend, and debug? I know the concept of "pretty" code should not be so subjective that we can not agree on anything, so where is the good stuff we can all learn from????
This is a hacked account, for which the owner can not be held responsible.
after 30 years in the software business in silicon valley... my observation is that with time to market getting shorter and shorter, work hours getting longer and longer, generally speaking developers do not have the time to become masters of engineering discipline. on the other hand... because there is so much information available, and code, todays young developers are able to perform quite well. there is a down side, new technology development teams (i.e not applications or web development) don't have chops to deliver the because of a lack of solid engineering fundmentals.
10 goto 20 20 goto 10 http://worldwidewags.com/newdles/ Newdles is the prettiest code I've ever written, but I doubt anyone but me will see it before I die.
Has someone created such a law before?
Ward Cunningham calls it technical debt. It's what you accrue when you don't mercilessly simplify the design of your application every time you check in.
http://www.martinfowler.com/bliki/TechnicalDebt.ht ml
Oh, and boost::thread is also fucked up. If you want a thread to sleep for 1500 milliseconds, you have to
1) get the current time with boost::xtime
2) convert 1500 seconds into 1 second plus 500000000 nanoseconds (which takes about 10 lines of code and isn't included in boost libraries! WTF!) and add it to the time from 1)
3) call boost::thread::sleep
In comparison, in
Thread.sleep(1500)
What about Clean code? You know the types that doesn't have errors, or memory leaks? Heck why does a printer driver take 300mb? I remember when things used to be small. Lots of things now are huge, that do not necessarily have to be big.
SimonTek
I've always thought the KDE code was beautiful. Not in terms of stuff like code formatting, but in terms of C++ design. Even if you hate KDE as a user, it might be worth browsing the source.
-fb Everything not expressly forbidden is now mandatory.
Often when I am trying to learn a new set of calls in C (such as Sys V IPC), I will write modified hello world progras to explore them. The code is small, simple, and easy to adapt to all sorts of things (like server/client connections over UNIX sockets).
So... I am sure that some hello world programs do have security holes because they are inteded for testing purposes only. Of course, exploiting those are rather difficult...
LedgerSMB: Open source Accounting/ERP
All code is shitty code.
>The code from their chapter is online here:
:)
Oh boy, one of my pet peeves: The 80 column terminal combined with superfluous empty lines.
And the brackets are misplaced, too.
The sqlite source code is clean, well documented, and you can pretty much understand the entire system by reading the one "internal structure" document followed by 10 - 15 files of source code in the right order end-to-end.
These are the two well designed C++ libraries that i can always instantly remember.
http://validator.w3.org/check?uri=http%3A%2F%2Fwww.slashdot.org Errors found while checking this document as HTML5!
It's just occurred to me you are Tim O'Reilly. Wow, there are still some important folks that still post on
1), 2) and the first 3) are really compiler problems, and not associated with the code as such. Kind of like when the FSF decided to target platforms with 32 bit flat address space, at a time where 16-bit segments were the norm. It made their code prettier and easier to read, but in the short run less useful. I have no problems with that.
The second 3) is the real issue, template meta-programming tend to divide the user community into library users, and library writers. As losing as the users stay users, everything is fine, but in case of a bug in the library, users are suddenly writers.
I remember hearing that Samba has some pretty elegant code. Apparently several projects like talloc have also fallen out of it. Later versions also have very extensive test suites...
"As far as speed goes, the templated version wins..."
I'll bear that in mind every time I read about C++ compiles which take days/weeks to complete...
PS: +1 for not incorporating boost into the standard. It's unnecessary and won't make a single person's life any easier (I mean, people are using Boost without it).
No sig today...
> what projects have you worked on which you felt had admirable code,
> both high-level architecture and in-the-trenches implementation? In
> particular I am interested in large user applications using modern
> C++ libraries and techniques like exception handling and RAII."
The intersection of those sets is null. There is such a thing as pretty
code. None of it is written in C++.
while not in c++, it is a rather complex application, and very elegant imho. understanding it requires 3d background knowledge, but it is still very clean code.
I have always considered POVRay code to be very clean and elegant. One of the better examples on the Net.
The company I'm working for right now has a large very high quality code base, and rigorous code review standards internally. The code is almost all c++, but it is all very clean and readable, all unit tested, and what's more extremely well commented.
This is an area where high standards in what you allow developers to check in is important. Most shops do everything very add hoc and don't give developers any strict guidelines...
A lot of open source projects have a similar problem. Most of the open source projects I've worked on are totally uncommented and lack any kind of unit test or up to date architectural documentation. The linux kernel is a pretty good example of ugly code, largely because of lack of comments and documentation.
In open source, or in private companies, someone has to ultimately lay down the law and say what practices, like documentation and unit tests that are required. I think people are a little too worried in open source about scaring off the community with this stuff, but it's much more important to maintain a high quality code base.
Exceptions:
Unfortunately, not everyone can use exceptions since integrating with older code that is not exception safe is a problem i.e. if a function throws an exception in exception unsafe code, it will likely leak resources. A lot of older c++ code doesn't use exceptions for whatever reason, and you pretty much can't switch over once you've gone down that path.
RAII:
scoped_ptr is most of what you need to know about RAII... everyone should use it where appropriate, and it's part of the standard library in TR1. You can swap out the destructor if you are holding some other resource than memory, and in that way it also helps with exception safety.
... its really that simple. Every time I see code that I consider ugly (and I see a lot as a C++ contractor in Londons finance industry), its always because the person who wrote it left out something important in the design phase and it had to be hacked in later. Examples:
- If you don't know who owns the objects in your program and how long they live, your code will be full of special conditions in odd places.
- If you didn't realise the implications of having many threads running through your code, the locking will become an inconsistent mess.
- If you can't reliably know the state of an object without querying some related objects, the failure to encapsulate properly will spread throughout your code.
- If you don't enforce pre and postconditions at source, then they will be broken and fixes applied in multiple other places to work around this.
IMHO, sexy code has the following characteristics:
- Its readable. That is, well formatted (i.e. consistent), commented, uses meaningful abstractions and names.
- Its reserved. That is, it hides as much as possible about itself and takes care of the management for you.
- From the above, its replacable. The implementation can be improved without messing up others who use it.
You get the above for free if you talk through your design with others, especially other developers who will use your code (in ways you may not agree with). Any code that isn't a rats nest of special cases and interdependencies is sexy - because it can be improved easily.
Jon
I was pretty impressed with all the Plan 9 source code I looked at.
- Not a single line of code was written without source control and bug tracking in place
- The architecture was defined before code was written
- There were coding guidelines (style, etc.) that were ENFORCED
- All code was reviewed
- Incorrect documentation (including comments) were considered bugs of the hightest priority.
- etc...
You get the picture. Bottom line: at some point, I had to work on code that was three years old and that I had never worked on or seen before. It was an absolute pleasure to work on the code: Due to the style everything looked familiar, comments described WHAT the methods were doing, the architecture was clean, etc.Without good management that understood software development AND that was willing to impose some important rules, this would not have been necessary.
Under capitalism man exploits man. Under communism it's the other way around.
Garry Williams
I consider most of the code I write to be pretty.
t ar.gz
Here's a link to some source: http://www.mcternan.co.uk/ArmStackUnwinding/wind.
-- Mike
I have rewritten unp, which is a simple extraction utility, just to see how a clean implementation would differ from it. The result is a much shorter, and easy to comprehend application called e.
The main difference between the two implementations is a clear separation of concerns. While unp looks like one large blob of code with no clear structure, e has all the rules in one place, and application logic in another place. In unp this lack of separation has already led to duplicated code.
Open Source Alternatives
Hi
# CompilerError?
> This drives me nuts, a simple 200-line *.cpp file using boost::stateschart compiles
> for about 30 seconds,
What compiler are you using? I've observed *huge* differences (>300%) in compile time, depending on the make of the compiler and optimization settings. Also, I would be very interested in the 200 lines that cause such a long compile time. Optimizing the TMP part of statechart so that compile time is reduced has been on my TODO list for quite some time now. Reports of unbearable compile times would certainly increase the priority of that work item!
> and syntax errors result in 400+ character lines with recursive template codes etc
Have you had a look at http://www.boost.org/libs/statechart/doc/faq.html
Thanks & Regards,
Andreas
If you want something from the Java world just look at Spring http://www.springframework.org/. Its design and code are both great.
OpenLB is a beautiful piece of C+ code. Hard core C++ templates used for and how templates were really designed to be used. After looking at several other LB implementations, this was the nicest designed and by far and easiest to read to figure out what was going on.
What is the Lattice Boltzmann Method?
Really cool stuff!
-Don
Take a look and feel free: http://www.PieMenu.com
http://www.syllable.org/ ... a pleasure to work with.
I'm using g++ 4.1.2 (the default g++ in Ubuntu 7.04) with no optimization, as a debug build. I think the relatively small amount of RAM (512Mb) may be responsible since I use Eclipse as my main IDE and it usually takes 150-250 megs. OTOH the other project I mentioned also builds from Eclipse. I can mail you the source that results in insane compile times, my email is [my nickname on slashdot]@gmail.com# CompilerError and it confirms what I said - an error in code using the Boost library results in 6-8 long compiler errors and only one of them actually needs to be fixed.
I've looked at http://www.boost.org/libs/statechart/doc/faq.html
I've been thinking about this problem, as my friends and I are planning to start several programming projects.
Having only academic experience in programming (i.e. code written by a single person, and maintained by the same person; literally no team-work), we want to try to develop 'good' coding habits - which is why we are looking for a set of conventions that are successfully applied in the real world.
The ones we've found on various sites are very long and detailed; for example, this one looks good, but I'm not sure it is a good one to start with, as focusing on the rules will probably draw attention away from actually making a program that works.
Are there any 'light' standards that can be embraced by us at this stage?
The saddest poem
Because a fairly good developer can never really comprehend the idea of good design, and there are far more crappy developers out there than good ones, and great ones, not many at all. It takes discipline and talent to produce good design and without it you will be lost, no chance of recovery, sorry.
:(
That being said I've heard very good words about llvm (www.llvm.org) so go check that out if you are interested in possibly good code.
Design is really the key here, changing development methodologies, programming languages, or whatever won't buy you good design. Too bad today's tools for design is HORRIBLE
Perl has some wonderful examples:
[Both of these print "Just another Perl hacker" and exit]
Yes they do actually run without error. Try it.
Example 1.
[Edit Slashdot thinks I am using too many junk characters so check the code out here http://en.wikipedia.org/wiki/JAPH
it consists entirely of punctuation]
And for those who think perl is cartoon characters swearing:
Example 2.
not exp log srand xor s qq qx xor
s x x length uc ord and print chr
ord for qw q join use sub tied qx
xor eval xor print qq q q xor int
eval lc q m cos and print chr ord
for qw y abs ne open tied hex exp
ref y m xor scalar srand print qq
q q xor int eval lc qq y sqrt cos
and print chr ord for qw x printf
each return local x y or print qq
s s and eval q s undef or oct xor
time xor ref print chr int ord lc
foreach qw y hex alarm chdir kill
exec return y s gt sin sort split
With that in mind I'd take a look at http://code.google.com/projects.html...
> I think the relatively small amount of RAM (512Mb) may be responsible since I use Eclipse as my
# CompilerError and it confirms
> main IDE and it usually takes 150-250 megs.
In that case I'm not surprised, TMP code tends to use heaps of RAM for even moderately complicated problems.
> I can mail you the source that results in insane compile times, my email is
> [my nickname on slashdot]@gmail.com
Ok, I'll contact you offline.
> I've looked at http://www.boost.org/libs/statechart/doc/faq.html
> what I said - an error in code using the Boost library results in 6-8 long compiler errors and
> only one of them actually needs to be fixed.
Correct. My point was that it's often very easy to find that single line that needs fixing. Just work yourself up the instantiations until you find a line in your code (as opposed to library code).
Code is pretty or even beautiful when it matches the expectations. In particular, management thinks the code is beautiful if a programmer can spend a deterministic amount of time on a task and be done with it. The same programmer thinks the code is beautiful when he spent less time on it than he expected. A user of the program thinks the code is beautiful if it doesn't crash and doesn't waste the resources on his computer.
Check http://quantlib.org/ code. It is pretty good.
Slashdot = Sarcasm
CMU CLis a Common Lisp compiler/interpreter (written in cl). Its code is just beautiful - after about 1-2 months since my first contact with lisp I understand nearly everything at first glance. (SBCL also have very nice code). OpenBSD's code (written in C) is also very clear and pretty.
I've always been impressed by the BusLogic SCSI driver code in the Linux kernel. Anyone interested in what a good low-level, bit banging C program should look like should study its code carefully. Here is a randomly chosen snippet: /* /* /* Approximately 60 seconds. */ /* Approximately 1 second. */
The Modify I/O Address command does not cause a Command Complete Interrupt.
*/
if (OperationCode == BusLogic_ModifyIOAddress)
{
StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
if (StatusRegister.Bits.CommandInvalid)
{
BusLogic_CommandFailureReason = "Modify I/O Address Invalid";
Result = -1;
goto Done;
}
if (BusLogic_GlobalOptions.TraceConfiguration)
BusLogic_Notice("BusLogic_Command(%02X) Status = %02X: "
"(Modify I/O Address)\n", HostAdapter,
OperationCode, StatusRegister.All);
Result = 0;
goto Done;
}
Select an appropriate timeout value for awaiting command completion.
*/
switch (OperationCode)
{
case BusLogic_InquireInstalledDevicesID0to7:
case BusLogic_InquireInstalledDevicesID8to15:
case BusLogic_InquireTargetDevices:
TimeoutCounter = 60*10000;
break;
default:
TimeoutCounter = 10000;
break;
}
This is some seriously low-level stuff, and it reads like English text. It totally changed my ideas about what this kind of code should look like! It believe it was written by the late Leonard Zubkoff.
As the inventor of "literate programming"[1], early practitioner of open source, and author not just of The Art of Computer Programming and its included programs, but some extraordinarily elegant and widely used software systems himself (including TeX and METAFONT). How many people's programs are worth printing as hardcover books?
[1] mention also to Kernighan & Plauger's Software Tools.
you had me at #!
"Many of the well known people who used to post here have abandoned it in recent years so the feel of the place has changed. The only big name I still see around here is Jeremy Alison from Samba..."
Yes, but reflecting that change, we're getting new "well known" people like NewYorkCountryLawyer. Kind of dresses the place up.
I don't know about the code, but the most elegant system I have looked at in a long time is forthought, an early version of Forth used in the maing of Starflight on the PC.
x
Each forth word is a pointer to the code that executes it.
http://wiki.starflight3.org/sf1techforthought.ash
shows more detail, but the compiled code is as elegant as Kate Winslett in a period drama.
PLX technology (PLXTech.com) makes a PCI interface chip. When you download the driver for their chip you also get the source code. It is, in my opinion, one of the best written bits of code I've seen in a while. It's clean, well commented, and organized out in such a way that it is obvious where to look for features. As reference code goes it is hard to beat.
...almost always want to re-write old code from scratch.
Almost always without taking the time to understand what that old code does. Why? Because writing code is much easier than reading code. Reading code takes perseverance and ability to focus on large numbers of nit-picky details. Something our TV-age brains cannot easily do.
The result of throwing out the old code without understanding what it is accomplishing is not always positive from a business perspective.
Sure, sometimes crufty code is crap.
But sometimes, like on a terminal emulator project I worked on in the mid-90's, the cruft was a bunch of code, accumulated from 1985 to 1995, that actually emulated the bugs in the firmware of 10 different manufacturer's dumb terminals. The programmers who wrote the applications that ran on these dumb terminals relied upon these bugs in the firmware and when the bugs disappeared, the applications broke.
The company that tried to sell the "correct", "new", "elegant" terminal emulator hit a big solid brick wall called "market acceptance." The company that kept the cruft made roughly $4 million per year in profits and supported 25 employees' and their families for a decade while they developed new products.
So, before you look at code in a shipping product and say to yourself "this is crufty crap and should be re-written from scratch" ask yourself this question: "Do I really understand what this crufty crap is doing?"
Don't just thing pretty code makes a nice system. We recently rewrote a large system. While implementing I noticed that when you wanted to add something to the new system the infrastructure was already there and it was easy to conceptualize how to work the new functionality in. In our old system the code almost pushes you away. Trying to extend functionality almost always means a several day long refactor chain or just adding a new wart. I figure going forward the rewrite would pay for itself over the next two to three large requests for additional functionality so of course it got canceled and we were told to work in the old codebase. :/
Anyway my point is there is more to pretty than syntax and layout.
-CZ
I was in an embedded systems seminar hosted by Jack Ganssle (sp?) and he claimed that the eCos (embedded Configurable operating system) source code was some of the best code he had seen, especially given it's complexity.
http://en.wikipedia.org/wiki/Brooks_Law
I'm not so sure of that. I once looked over the Scorched Earth 3d code for a friend that was having trouble setting up a custom weapon file. At first, the code made no damn sense at all, but I could still tell it was very clean code.
After about half an hour, something suddenly clicked and I realized it wasn't just clean code, but an incredibly clean paradigm as well. I nearly had a code orgasm it was so sweet and perfect a style.
Just knowing how that code works has improved my programming. Hats off to the original writer.
Cruftiness is the quality of having cruft. Cruft is the stuff that accumulates on code over time. Cruft has no odor, but it stinks. Cruft has no mass, but it weighs the code down. Cruft can't be seen, but it's ugly. Cruft cannot be young, it's always old.
Hmmm... could it be that cruft is really a manifestation of dark energy being stored in another dimension of N-space?
Wouldn't that mean that cruft just might be a nearly infinite energy source? This could get real interesting!
I have no problem with your religion until you decide it's reason to deprive others of the truth.
As a total newbie to SBCL's source code, I was delighted to find it written in Common Lisp instead of bootstrapped through some other language. The code I was interested in patching was about 30 lines total, and comments explained how it worked. Great stuff.
There is no such thing as pretty code, just fuckable code; the type of code that you'll never really wanna look at for too long, but it's all right looking.
Peter Norvig, now CTO of Google, agrees with you. Coding, like writing, is best improved by an alternating diet of writing and reading good works. He collected a few of the best he'd found in a book called Paradigms of Artificial Intelligence Programming, available from his web site or from Amazon: http://norvig.com/paip.html
It talks about AI because it was the 80s (92 by the time it hit shelves) and AI was cool---but the applications involved are now just what we call computing. It's not perfect: fifteen years have passed since it was written. In that time, C++'s STL and Boost have caught up with many features of Common Lisp. Java's come along and done well. Other interactive dynamic languages than Lisp exist: Python, for example. So you'll have to do some translating in your head---but for the same reason that Cicero is read by students of English rhetoric, Norvig should be read by C++ and Java programmers seeking mastery.
-- Brian T. Sniffen
http://www.smk.co.za/
I know practically nothing about OS programming and my C / C++ has been rusting since University, but this guy writes code that even I can follow.
> BOOST is full of butt-ugly hacks. Check out the, uh, template things, named _0 through _9 being used as stand-in dummy arguments. Eeeeeew!!!
Yeah... That's a butt-ugly hack that's standard from 2009 and on.
> BOOST looks easy to dumb-ass programmers, but these programmers leave bugs that are difficult for expert programmers to find.
Learn your language and you'll understand it. Note, that refers to ISO C++, not Microsoft C++.
> BOOST makes compilers run very very slow, and often breaks the optimizer anyway.
They make heavy use of the optimizer. If your compiler runs very slow and has an optimizer that makes broken code, I'm not going to blame any code for that except the one IN the compiler. Your compiler should work, if it doesn't, then fix the compiler.
C++ and modern techniques like exception handling and RAII? Hahahaha. Do not expect any large scale good code in a krap language environment. If you want to see beautiful code then learn Lisp. The largest reason most projects of any size become code crap magnets is because there is far too little incentive and support to improve our tools.
10. All code everyone writes is crap and fundementally flawed.
.. design vs snazzy language features. Its sometimes hard to do but one needs to be aware of the global implications of relying on language feature x to keep the system managable when design y would preculde the need for x in the first place. (Ahmm OO whores this means you!)
The real question on prettyness is not how pretty it is but in a relative sense how crappy it is. Never waste your time by being happy with anyones code.
Authors who write code that blindly submit commands without checking their status just need to be fired outright. Some projects are hard enough without people on your own team working against you.
The same goes for people who rewrite code simply because it doesn't fit into their self righteous world view.
The best codes in medium scale applications I've seen all whore meta-data like their going out of style and seek to create frameworks that don't too specifically target the problem space.
High level design is much much more important than low level implementation. You can ususally salvage low level codes without much trouble. Design mistakes are much more costly.
I've seen too many problems arise from people with unbalanced views thinking
At the end of the day the ultimiate success in terms of complete lifecycle of a project trumps anyones personal views of the state of its codebase. If its successfull with low bug rates, maximizes profits and concidered a godsend to the end-user then it was a well written piece of crap. (GOTO 10)
I've always been pretty impressed reading through the code for the Standard Template Libraries. There's some absolutely brilliant, generally simple code there. Just about everybody that writes C++ for a living has used it at some point. It's easy to use, well documented, and general enough to use or modify-and-use in countless projects.
[no sig here, move along. (fnord)]
Some recent, low-level, high-quality kernel code I've seen: http://vmhack.acm.jhu.edu/source/xref/vmhack/linux -2.6.20.1/vmhack/resolve_page_fault.c
This was from a project that someone posted about in #mm, to rewrite the Linux memory manager.
Every unix will re-use pids in the same second. The assumption that you can't go through 64k pids in a second is a mistake. And good operating systems don't use sequential pids anyways.
I remember when that cute little home computer came out, and all the programs were just so. . , plinky.
Memory was a huge barrier, because you only had a small quantity of the stuff, and nobody understood the architecture of the system well enough to produce efficient programs.
But back then, there were no video card upgrades. No faster processors and mother boards being produces every three months. If you wanted higher speed and cooler graphics, you had to write your code in more ingenious ways.
And so that's what happened.
By the twilight years of the Color Computer, the games people were writing on that thing were unreal. I remember looking at a few and thinking to myself, "This is the same computer? Wow! Humans rock!"
When you reach the raw power limitations of your muscles but you still want to improve yourself in your combat skills, you take up Kung Fu. That's how it was in the old home computer days. Nowadays, though, (dang kids; I hadda walk fifty miles to school!) it seems that the bulk of improvement comes with the purchasing of increasingly large muscles.
This is not to say that there is no software innovation. Heck, id Software did some pretty amazing things with software ingenuity. But I do remember thinking during the first few years of the big PC revolution, after the 486 was reaching its twilight, "You know, all this hardware innovation is great and all. . , (big muscles are cool), but part of me wishes it would stop cold for six solid years just what would happen when the programmers were really pushed. --You know, to see what one of these machines is actually capable of doing.
-FL
Good operating systems use random pids. There is nothing that says pids must be sequential, and assuming such is a mistake.
Just kidding! :)) (as well)
"Not that the story need be long, but it will take a long while to make it short." Thoreau. Letter to a Friend. And there are variations of that quote, dating back to days of Cicero.
If you prefer ALGOL to C, then please code in ALGOL. #defining your own syntax absolutely kills readability and makes small stuff like bad indentation and erroneous comments pale in comparison.
As you note, the answer is mostly no. In my experience, it is the experienced people who are more likely to complain about code quality, as they can better recognize it and value it more. I just wrote an article about the need to make code more 'pretty': Why You Should Polish Your Code. One code base that has consistently impressed me is the Spring Application Framework, which is open source and written in Java (I'm primarily a Java developer). I've looked at other popular open source Java libraries and generally have not been impressed by their code quality, so I don't think that open source is any guarantee of prettier code.
I didn't have a look at the code myself, but the project matured for a while now and the statements on their website are fairly self-confident: [...]OGRE is different. OGRE is design-led rather than feature-led. Every feature that goes into OGRE is considered throughly and slotted into the overall design as elegantly as possible and is always fully documented, meaning that the features which are there always feel part of a cohesive whole. Quality is favoured over quantity, because quantity can come later - quality can never be added in retrospect. OGRE uses sound design principles learned, tried and tested many times in commercial-grade software - the object-orientation mentioned in it's moniker is just one of those approaches - frequent use of design patterns is another[...] ogre3d.org
http://www.gardenwithinsight.com/progman.htm
Very pretty Delphi code, especially compared to the spaghetti Fortran which was translated to Delphi for some of the underlying models. Notice how, say, all the simulation variables now have units appended to the end of the name, as in "rainfall_mm".
A 21st century issue: the irony of technologies of abundance in the hands of those still thinking in terms of scarcity.
I do cross-platform code, and I look at the assembly output.
By "breaks the optimizer" I wasn't meaning incorrect output. I mean the optimizer gives up on the tangled mess, producing a rather unoptimized result. This affects both gcc 4.1 and Visual Studio 200x. (2005 I think -- the one after 2003)
Maybe you have some exotic compiler from Intel or Sun that does everything perfectly and has no bugs. The two most popular compilers (gcc and Visual Studio) have big trouble. Heck, neither will even get std::min right; the plain C macro produces better assembly code.
BTW, you're kidding about "standard from 2009 and on", right? The committee has shown little sense of shame before, but seriously... that'd be way over the top. It's creepy and sad that I should even wonder that you might not be joking.
I work for a company called SevOne. We write network management software (backend in C and PHP, front-end all web-based and PHP). I think about 70% of the codebase is very well written (though not maintained). Considering the complicated nature of the software we write, I think it's really made a huge impact on hiring new people and having them get right into it. Though that 30% thats left over looks like I tried to open a JPEG file in NotePad++ :-(
it is not a very large code base with lots of developers
That may have something to do with it. :)
But seriously. I saw a Google Talk by lead developer Dr Richard Hipp, who struck me as an organised, methodical clear thinker who takes pride in shipping a product of high quality.
If I grow up, I want to be a developer like him.
you had me at #!
This question gets asked here from time to time. For example,
Where Can I Find Beautiful Code?
and when I asked it back in -- my god -- 1998:
Ask Slashdot:Programming Styles
Nice. Factory, Singleton, A sort of Strategy -- what a good program, that's excellent :)
;)
Perhaps, with a few refactorings, this could become the HelloWorld of tomorrow. You could declare an interface for MessageBody
And now, back to the real world.
SLOGEN [ http://ungdomshus.nu : Sebastian cover music]
What you're asking for is often called Golden Code or Golden Pages and usually exists within large software engineering companies. The problem with gaining access to such things is that they usually are considered very important to the organization who owns them, so they are not made public - they're more or less considered trade secrets, a guide to that particular company's proprietarily developed best practices.
The other problem with easy access to Golden Code is that it must be constantly maintained to remain... "golden." So even if someone were to post a great example online, they're probably not getting paid to do so, so it's probably going to lose its luster in a couple years. Companies who maintain Golden Code usually assign a particular product to be coded in a "golden" way and continuously maintained in that perfect state as an example to all. This requires a lot of money.
So the point is, if you want access to Golden Code, get hired at a big software company. There are a fair number of them out there if you look outside the most obvious markets. Enjoy.
e17 and the efl are some of the best code I've seen in years.
Other good code I've seen recently include pugs and parrot, but those are a bit more esoteric.
For C++: no. C++ doesn't really scale very well and doesn't share nicely. So no I can't think of any specific C++ examples. Nice language for relatively quick UI interface dev (but both C# and python are superior for prototyping except where scripts have too much overhead).
Some other languages (python for instance) tend to be clean code from design.
Now, C on the other hand...
- Linux kernel: absolutely beautiful.
- Gnome - clean, decent, nice. There are sections that still require work but for the most part it's a scalable reliable system.
- postgres - the underlying model takes getting used to but after that - very nice code.
- libJPEG - the origins for me of object-oriented C.
- MacOSX API (okay I really really really like it. It's still evolving but I very much enjoy the directions it's going)
for worst-ever code I'm nominating MFC++. My past experiences with it resulted in multiplied development time with many "artifacts".
You're probably one of those script-ruby-wiki-vandal-spam-botnet-evangelists aren't you? When I foolishly blurt out this new cool site you quietly infiltrate it accounts from your zombie bot army... Then one day you strike and destroy the inboxes and connectivity of 99% of the most important people in one strike. I wind up being disowned and the remaining 1% are forced to wander from IRC server to ICB server looking for a new home...
Besides, I'm no luminary so I am on the wrong side of the fence to know where everyone has gone (if they have indeed gone anywhere). Years from now we'll probably find that they're all on Facebook or something...
If Dan Bernstein worked for the fire service and you phoned to say your house was on fire, he would tell you your sprinkler system was configured wrong and hang up.
I wrote my first program at the age of six, and I still can't work out how this website works.
For readable code, I've always liked the PGP crypto code. The UI stuff is messy, but the underlying encryption code is art. The function names clearly describe what the functions do, the comments explain the algorithms and the logic of the design (not stupid stuff like "exit loop"), and the error handling makes it quite easy to find problems, and since it has been published so it can be machine readable (to deal with export regulations) the formatting is completely consistent, and when something is implemented using a clever algorithm in assembler, the comments almost always have the same algorithm in C (which helps portability) and then the simple algorithm in C as well.
I'd say that messy code is the result of high changing what you're trying to do. At one level it can be because one programmer loves globals while another one avoids them, but it can also happen at a structural level as a result fixing bugs if the bug forces a redesign of the structure of the program. I think that's part of the reason that UI code tends to be so ugly -- the goals and work flow change frequently.
OpenVPN is very well-written C -- clean and accessible. Likewise for glib (not glibc, glib), presuming one likes the fun it does with macros.
Windows NT source code
"I've often heard Java folks talk about re-factoring code and that's fine if no one is using your app, but in the event that folks and money are dependent on it, then re-factoring really just increases risk to all involved. The best possible outcome is that no one will notice the changes. "
yes : thing is though that refactoring without an aim is tinkering. you refactor the code because you want to change it, and you have to refactor to make "room" for that change. the existing unit tests (you have those, right?) tell you if yr changes have broken anything; and the new one you write fails (you hope/expect) because the feature you want to add doesnt exist yet. i don't see the risk under those circumstances. i _do_ agree that if you don't like the code, you should refactor it, but _only_ because you need to change it. "the best is the enemy of the good" : if it works, it's good. if is doesnt work - then its a whole new ball game, and i'd suggest refactoring to make the bad code easier to change now is both necessary and a boon to the next guy/gal who has to go in there.
i've a lot of tech lead experience and scars from this sort of thing : there's a happy medium between the pattern junky whose code never gets finished and generally looks a bit arcane, and the "can write it, can't design it" coder with 200 line methods and an approach to object orientation is er, functional decomposition. in my experience, i've spend more time refactoring to prise the latter "code fistula" apart.
The people that write and/or know great code don't have the time to waste posting about it here.
Does it hurt to hear them lying? Was this the only world you had?
Understanding how to program in C++ effectively is not one of these cases.
I'm a little biased, but I think the RSpec test description language (built on Ruby) encourages nice, legible test scripts. You get to use natural-looking language like this example:
@stack.peek.should == @last_item_added
"I call a baby goat a 'goatse.'" -- my non-Internet-savvy 6-year-old stepdaughter
Basically, I like assembler because you have to be a good programmer in order to get it right and UNDERSTAND the system. I can't do it myself though:
mov ax,cs
mov ds,ax
mov ah,9
mov dx, offset Hello
int 21h
xor ax,ax
int 21h
Hello:
db "Hello World!",13,10,"$"
Custom electronics and digital signage for your business: www.evcircuits.com
When working on Nachos - A very basic OS designed mainly for academic education purpose - I found it pretty neatly coded.
To be fair, your arguments are irrelevant: (1) You don't actually need to debug them. I mean, really, how many times do you have to debug a library(like STL)? Even if there's a bug in it, it's not yours to fix. (2) yea, yea, yea. A thousand times yea. Obviously C++ is so complex that it gives compiler writers headaches all the time. But is it C++'s fault really? The real problem is, if compiler can't catch up, then maybe it's the compilers we should blame. Or maybe we can simply wait and not blame anyone. Another cent on C++'s complexity, like Bjarn Stroustrup himself said, we need relatively complex language to deal with really complex problems. English is arguably one of the most complex languages in the world, but it's still popular and well served its purpose. (3) This is a point that has been brought up (and, of course, explained) like a thousand times, too. The problem is real, but the painkiller is coming soon. Concepts system in C++09 will relieve the pain. (4) Bug-fixing is always hard, whether we're dealing with template code or not. And for expert library develops, the major effort is probably not on rassling with templates, and even if it is, like I said previously, we need relatively complex languages to deal with really complex problems. On the other hand, a floating point arithmetic bug may take much more time to fix than a template syntax bug.
Take Gled (http://www.gled.org/ - a recent CVS snapshot is preferable), a distributed C++ application builder with OpenGL/OpenAL/FLTK interfaces, object persistence and excellent extensibility.
It certainly is not pretty the first time you look at it, that is probably true for any unique project, but if you look harder, you will see a strange tangle using ROOT, CINT the C++ interpreter, built-in C++ object dictionaries, elegant and fast network stack for object streaming and synchronization, and strangely effective remote procedure call interface. But my favourite is the auto-building FLTK gui.
While remotely involved, I do enjoy this code immensely.
Try building a new library for it and enjoy GUI-enabled objects in minutes... (There is even a scratch for a TA-like game in one of the demos, not yet playable.)
-Kvorg
Please correct me if I got my facts wrong.
I've was pretty impressed with how clean and straightforward the NetHack code looked.
That and of course anything that I've written.
So there you have it.
Excerpt:
I imagine that's as good as it gets for proper coding.
My programming education never made it past the C programming course I needed for my BSME. The fastcompany story looks relevent though.
Alcohol, Tobacco and Firearms should be the name of a store, not a government agency.
maybe Acme::bleach should be utilized...for really clean programs!
qmail is a piece of crap. The source code is completely unreadable, and it /* myrand - pseudo-random number */
seems to think that "getpid()" is a good source of random data.
int myrand(void)
{
if (myrand_initdone == 0)
mysrand(getpid() ^ time((time_t *) 0));
return (rand());
}
Source: postfix 2.4.3
Hello again
I've finally gotten around to compiling your example with MSVC. A complete compile link cycle takes 10 seconds on my 3.2GHz Pentium 4, with a very small bump (50MB) in the memory graph (my box has 1GB).
Regarding the large binary sizes you reported by private email:
With MSVC the executable is 200KB, but I do remember that I sometimes had very large binaries with mingw. I guess this is somehow connected with the compiler/linker taking so long. Might be worth reporting to the gcc developers. Unfortunately, I don't have much time to spend on statechart at the moment as my job is currently very demanding and I'm also in the process of moving to new hardware. So I'm afraid I won't be able to look into this more deeply in the next few weeks.
Andreas