No one should try to write beautiful code. Everyone should try to write code that works, reliably, keeping it simple. Then later on someone else will read your code and think how beautiful it is.
At the end of the day it's about how well you get the job done. There is no one true way on this matter. Getting the job done means different things to us solo hobby programmers than it does to a team developing a multi-million dollar project on a deadline.
How beautiful is your code?
Moderator: Ras
-
- Posts: 4675
- Joined: Mon Mar 13, 2006 7:43 pm
Re: How beautiful is your code?
Some of my code: http://www.talkchess.com/forum/viewtopic.php?t=46964
One in Pascal, one in C++. You tell me: Are they decent or are they crap?
One in Pascal, one in C++. You tell me: Are they decent or are they crap?
-
- Posts: 2949
- Joined: Mon May 05, 2008 12:16 pm
- Location: Bordeaux (France)
- Full name: Julien Marcel
Re: How beautiful is your code?
Thanks for sharing, Steven!sje wrote:Some of my code: http://www.talkchess.com/forum/viewtopic.php?t=46964
One in Pascal, one in C++. You tell me: Are they decent or are they crap?

I have been very impressed with this:
Code: Select all
The chess data interchange standards (EPD, FEN, PGN, and SAN) were developed by Steven Edwards
with the help of the Usenet community and were first published in 1994.

And despite I program in Pascal since 1992 (!) I just learned something new by just taking a look at your code:
Code: Select all
type
{ Integer ranges: unsigned }
ui8type = 0..255;
ui16type = 0..65535;
ui32type = 0..4294967295;
ui64type = 0..18446744073709551615;
{ Integer ranges: signed }
si8type = -128..127;
si16type = -32768..32767;
si32type = -2147483648..2147483647;
si64type = -9223372036854775808..9223372036854775807;
{ Digit ranges }
digittype = 0..9;
hexdigittype = 0..15;
{ Microseconds }
usectype = si64type; { Note: signed quanity }
I won't take a look at the big c/c++ archive, because it's not my cup of tea, but your Pascal code is very clean! (Although not so documented, but maybe enough, and I have a tendency to the opposite: too many comments in my sources.)
"The only good bug is a dead bug." (Don Dailey)
[Blog: http://tinyurl.com/predateur ] [Facebook: http://tinyurl.com/fbpredateur ] [MacEngines: http://tinyurl.com/macengines ]
[Blog: http://tinyurl.com/predateur ] [Facebook: http://tinyurl.com/fbpredateur ] [MacEngines: http://tinyurl.com/macengines ]
-
- Posts: 127
- Joined: Thu Sep 17, 2009 11:19 am
Re: How beautiful is your code?
Not sure about "beautiful" code, but there are a set of well defined quality attributes. The FURPS+ is a good example:JuLieN wrote:In our little community, sources of engines like Fruit or Stockfish are often praised, the first one for its clarity, the second one for its mastering of all C++ tricks (something that, as a pascal programmer, I have to trust you for). But what is a beautiful code ?
I just read a very interesting article on the subject:
http://kotaku.com/5975610/the-exception ... t=56177550
http://en.wikipedia.org/wiki/FURPS
Not all quality attributes are equally important and they may depend on the project. For a small hobby project for a chess engine, I'd say performance is very important, but for a large project with many developers testability, reliability and maintainability is much more important.
To write high quality code an understanding of architectures, patterns and anti-patterns is also needed. Some of the most important are probably the GRASP, SOLID and DRY principles (single responsibility, dependency injection etc..)
The development process itself is just as important though. Agile development is very hot these days. Basicly it means doing one thing at a time and finishing it before you begin something new. It sounds rather trivial but you'd be surprised how many start up 5 things at a time. Obviously 5 things at a time is 5 times as complex and as error prone and will leave the software in a non-working state for much longer.
A good development process also includes a revision control system, a solid test framework and a build server.
I just set up TeamCity, it's so very easy and quite fun to watch go through the unit tests!

At work we use a 2-layer model for testing, a so called physical layer at the bottom and a logical layer on top. Test definitions are made on the logical layer which sort of abstracts above the physical layer. It makes it possible to write tests in a more natural language closer to the use cases.
Re: How beautiful is your code?
As a professional software developer, No... just No. (maybe you were being sarcastic. If so, sorry)rreagan wrote:No one should try to write beautiful code. Everyone should try to write code that works, reliably, keeping it simple.
..... At the end of the day it's about how well you get the job done.
Edit: I should clarify; to me, beautiful code is maintainable code. Beautiful code is code that you can read and immediately understand what it does. This gets accomplished by using descriptive names for variables, classes and structures; by using descriptive names for parameters; by not creating ten different things that do kind-of-the-same thing, but creating functions that assist each other in completing a larger task (often referred to as "orthogonal code"); by structuring your project with good architecture, splitting your codebase into modules, keeping code inside the modules where it's actually used and not in some global utility classes (referred to as code locality); and lastly, no global objects!!
Readability and simplicity means maintainable code and maintainable code means code you can improve later. This should usually be your first consideration when writing any code. Code that you can't easily understand 6 months after you wrote it will never get fixed or improved, it gets replaced and rewritten (which takes longer than just writing good code to begin with) or it gets left in its bad state, forever being a hindrance to your work.
The only thing that might trump maintainability is speed. But DON'T start off writing code thinking "I'll just make it better later". That's the biggest mistake you could make as a programmer.
Where I work, and in fact most (good) software shops in the world, people who do this would get a serious reprimand for sloppy work. Writing ugly code, just because they couldn't be bothered to make it clear is unacceptable; it's bad work. People who continue to do this can go look for another job (or at least another team, because no way I'm keeping them on my project)
Of course, 99% of us write chess engines as a hobby so we don't have a boss... other than ourselves. So you can write any sort of code you want. Just remember, the only person you hurt by not writing good code, is you.
My advice is this:
Start off writing good, simple code. Then, if and only if you deem it worthy of optimization (by running it through profilers and analyzing your bottlenecks) you can go ahead and compromise maintainability for speed, but never sooner.
-
- Posts: 838
- Joined: Thu Jul 05, 2007 5:03 pm
- Location: British Columbia, Canada
Re: How beautiful is your code?
Simplicity is sometimes really hard to achieve in code. But it can be very valuable in the long term when you have to maintain that code (add features, fix a bug, refactor, add more features...) especially if you didn't write that code in the first place.
Complexity is the enemy.
Unnecessary complexity is the single biggest killer of software projects -- it saps productivity, makes changes difficult, slow, sometimes even impossible! It hides bugs, hides design flaws, hides inefficiencies. Code should be obviously correct; it is still possible for complex code to be correct, but its much harder to validate that correctness, or even to just to notice what all of the edge-cases are! How do you KNOW what a complex piece of code will really do in all situations? Complex code is difficult to understand, and difficult to reason about. Any fool can write code that compilers can understand; good programmers write code that humans can understand.
Pick good names for everything! Every function, method, parameter, class, field, local variable.
Picking good names for complex things is surprisingly hard. Sometimes when you can't think of a good name that really captures the essence of a construct, its a clue that it isn't simple enough: the class has too many responsibilities, or the method does too many things, etc. Split them apart until they each do one thing which is simple enough that you can name that one thing properly. Avoid overloading unless you have actual good reasons to use it. I hate when there's 4 functions called "SaveToFile" and one is a public API and the other three are internal helper functions that implement part of that public API and are called as part of the first function. But ugly horrible stuff like that can be found somewhere, in almost every large codebase.
Something I appreciate more and more as I get older, is being able to read a piece of code from "top to bottom" and understand completely what it does. That's a good start towards being "beautiful" -- the purpose and effect of each line of code should be simple and clear to the reader. You should not have to jump around all over the place to keep track of what the different code does; if it is decomposed well into smaller parts (functions, classes, modules, whatever) then you should be able to pick any one of those parts and read it from "top to bottom" and clearly understand what it does.
That's beautiful code, and its damn hard work to create, and a thankless task sometimes. But the maintenance programmer who comes after you (or it might be your future self, 3 years from now) will say a silent thank-you if you managed to leave behind a simple, maintainable codebase. "Beautiful" is an aesthetic description, but its a functional one too. Beautiful code is healthy, maintainable, debuggable, improvable code. Most code out there is the opposite: complex, ossified spaghetti code using obscure features and full of badly-named constructs and obscure bugs.
Complexity is the enemy.
Unnecessary complexity is the single biggest killer of software projects -- it saps productivity, makes changes difficult, slow, sometimes even impossible! It hides bugs, hides design flaws, hides inefficiencies. Code should be obviously correct; it is still possible for complex code to be correct, but its much harder to validate that correctness, or even to just to notice what all of the edge-cases are! How do you KNOW what a complex piece of code will really do in all situations? Complex code is difficult to understand, and difficult to reason about. Any fool can write code that compilers can understand; good programmers write code that humans can understand.
Pick good names for everything! Every function, method, parameter, class, field, local variable.
Picking good names for complex things is surprisingly hard. Sometimes when you can't think of a good name that really captures the essence of a construct, its a clue that it isn't simple enough: the class has too many responsibilities, or the method does too many things, etc. Split them apart until they each do one thing which is simple enough that you can name that one thing properly. Avoid overloading unless you have actual good reasons to use it. I hate when there's 4 functions called "SaveToFile" and one is a public API and the other three are internal helper functions that implement part of that public API and are called as part of the first function. But ugly horrible stuff like that can be found somewhere, in almost every large codebase.
Something I appreciate more and more as I get older, is being able to read a piece of code from "top to bottom" and understand completely what it does. That's a good start towards being "beautiful" -- the purpose and effect of each line of code should be simple and clear to the reader. You should not have to jump around all over the place to keep track of what the different code does; if it is decomposed well into smaller parts (functions, classes, modules, whatever) then you should be able to pick any one of those parts and read it from "top to bottom" and clearly understand what it does.
That's beautiful code, and its damn hard work to create, and a thankless task sometimes. But the maintenance programmer who comes after you (or it might be your future self, 3 years from now) will say a silent thank-you if you managed to leave behind a simple, maintainable codebase. "Beautiful" is an aesthetic description, but its a functional one too. Beautiful code is healthy, maintainable, debuggable, improvable code. Most code out there is the opposite: complex, ossified spaghetti code using obscure features and full of badly-named constructs and obscure bugs.
-
- Posts: 892
- Joined: Sun Nov 19, 2006 9:16 pm
- Location: Russia
Re: How beautiful is your code?
Satisfaction is a sign of ignorance. The more you learn programming, the less you like your old code.
-
- Posts: 440
- Joined: Thu Apr 26, 2012 1:51 am
- Location: Oak Park, IL, USA
- Full name: Erik Madsen
Re: How beautiful is your code?
I don't know about "beautiful", but my code is very clean. I've made an effort to refactor it as I enhance it, to ward off the entropy that inevitably creeps into a code base.JuLieN wrote:So how beautiful is your code?
I believe my code is very different from other chess engines. First of all, it's written in C#, which is not common. Secondly, it has an object-oriented design, whereas most chess engines are written in a procedural style.
I've used the code analysis feature built into Visual Studio 2012 to root out bad code. Also, I used JetBrains ReSharper for the same task. I highly recommend these two tools- especially ReSharper. In addition to detecting bad code, ReSharper identifies language usage opportunities, identifies scope narrowing possibilities (public / protected / private), enforces variable naming conventions, auto-formats code, refactors it (change method signatures, rename variables), etc. Great product.
Erik Madsen | My C# chess engine: https://www.madchess.net
-
- Posts: 1476
- Joined: Mon Jan 28, 2013 2:51 pm
Re: How beautiful is your code?
Let's begin...IMO the beautiful code has proper named variables and data structures.
Code: Select all
#include <bitset>
const int NUM_SQUARES=64;
typedef bitset<NUM_SQUARES> Bitboard;
typedef Bitboard Key; // For hash keys

-
- Posts: 3241
- Joined: Mon May 31, 2010 1:29 pm
- Full name: lucasart
Re: How beautiful is your code?
That's intersting. Is there really zero cost in using std::bitset<64> instead of using uint64_t ? I'm always very suspicious about these obfuscated template libraries, but perhaps I'm wrong.Gusev wrote:Code: Select all
#include <bitset> typedef std::bitset<NUM_SQUARES> Bitboard;
The operations that are critical on a bitboard are:
- get/set/test the i-th bit. I already see that bitset::set() is a variable parameter function, so I'm more than worried about the performance compared to a simple b |= (1ULL << i);
- all bitwise operations (logical ones, but also shifts, and multiplication for magics). How can a general purpose bitset template library do the >> and << efficiently ? (these operations don't make any sense from a set point of view)
- lsb(), msb(), popcnt(): those must use portable assembly (compiler intrinsics) to achieve any decent performance. I really doubt that a general purpose STL could do that.
Has anyone used bitset in a chess engine, and looked into performance ?
Theory and practice sometimes clash. And when that happens, theory loses. Every single time.