“I was really excited to write this article, because it gave me an excuse to really think about what beautiful code is. I still don’t think I know, and maybe it’s entirely subjective. I do think the two biggest things, for me at least, are stylistic indenting and maximum const-ness. A lot of the stylistic choices are definitely my personal preferences, and I’m sure other programmers will have different opinions. I think the choice of what style to use is up to whoever has to read and write the code, but I certainly think it’s something worth thinking about. I would suggest everyone look at the Doom 3 source code because I think it exemplifies beautiful code, as a complete package: from system design down to how to tab space the characters.” John Carmack himself replies in the comments.
This is going to be a post about personal preferences …
Being the novice programmer that I am, some of it was over my head, but other parts of it I could comprehend.
One thing that struck me is the part about where to put the braces. Personally, braces just look messy to me, so I’d rather use a language without them. IMHO, having a terminating statement like ‘END IF’ is a lot more elegant than having braces all over the f**king place.
And don’t even get me started on semi-colons
You’ll learn to love them; like the most of us
You can start flamewars just because of mentioning where the curly braces should be!!
I actually prefer writing:
int main()
{
}
to
int main() {
}
but, apart of feeling it more natural and making easier to see where a block starts and ends, I do not have any excuse to prefer it over the other one.
Not just a matter of aesthetics; it also depends on the tools you use.
With XEmacs, when the cursor is at a closing brace, the line with the matching opening brace is shown in the status bar.
With this setup, it is advantageous to place the opening brace and function definition on the same line for quick reference.
I also think it depends on the language you are writing in where you should put it.
e.g.
If it is JavaScript Douglas Crockford recommends the opening brace should be on the first line, because of JavaScript semi-colon insertion mechanism.
Java is the same due to convention. Microsoft recommend you use opening brace on the following line as you do when writing C# and is the visual studio intellisense default.
Personally I somewhat agree with the OP and I have had a gutful of C style syntax.
Same, Allman style is the best!
Especially when programmers tend to have atleast 1200 pixels of height on their screens (well atleast I hope programmers are smarter than average consumer and don’t give in into 16:9 fad just because it’s cheaper for Samsung to make 23″ 16:9 than 23″ 16:10…).
Edited 2013-01-16 11:04 UTC
Please, be my guest :
http://www.codeproject.com/script/Articles/MemberArticles.aspx?amid…
Especially check my CSkinProgress and WaterMarker source code : space instead of tab, 2 space indent, hungarian notation, one instruction per line, etc…
Kochise
I think curly braces stand out more from the rest of the code than yet another word.
I’ll agree with you on the semicolons and I do like Python’s indent-based block syntax, but using words rather than curly braces is one of the reasons I’ve never tried to learn Ruby and refer to it as the bastard child of Java, Perl, and BASIC.
(Though by no means the only reason. The standard library and core language syntax are full of caveats, the Unicode support is inferior to Python’s, it’s not used much outside of Rails and apps based on it, etc.)
Agreed. The only thing that stands out more is probably the indenting itself.
Seeing all that wasted vertical space just drives me nuts. (Partly because it means more scrolling, more time spent repositioning my Vim cursor when scrolling drags it along for the ride, and more time reacquiring my train of thought when scrolling sometimes disrupts it)
…not to mention it doesn’t fit as nicely with my Python-originated mental model that an indent level (syntactic block) is generally associated with the first line prior.
In fact, I’m sure that, in some places, I’ve been guilty of writing slightly less than ideal code using things like the ternary operator (PHP, mostly) and list comprehensions (Python) in order to vertically-compact my code.
Edited 2013-01-15 23:59 UTC
I personally think list comprehensions are a cool feature and should be used more, not just in Python. It may be harder to figure out what it does, but at a glance, at least you can tell what kind of things are in the list.
I normally agree wholeheartedly (one of many reasons why I love using CoffeeScript in place of writing Javascript directly), but even they can be abused.
See, for example, this inefficient one-liner I’ve used as a disposable snippet for doing 90% of the parsing of simple, un-sectioned, unquoted rcfile-like key=value files in reference-counted implementations of Python:
dict([line.strip().split(‘=’) for line in open(whatever) if line.strip() and not line.lstrip().startswith(‘#’)])
(90% because it still needs an extra step to trim whitespace from the key and value names but I don’t remember off-hand how to cram that into the same line.)
Yeah… The beauty of indent-controlled blocking in languages like Python and Coffeescript is that it kills multiple birds with one stone:
1. It eliminates a lot of noise.
2. It makes something that everyone does anyway for readability actually mean something.
3. It effectively kills most styling arguments (not all, but most).
Anyway, I’m quite fond of it.
And then the nicely formatted code gets thrown away when another team member gets to touch the code.
That is why I just follow what is the project guidelines, regardless how I feel about them.
Well, at least it’s your “humble opinion”…
Having programmed in both, I they both have pros and cons.
The real problems are:
1: badly formatted code,
2: lack of naming conventions,
3: and bad program design
1
—
Badly formatted code will make even the most readable of languages a struggle to follow.
2
—
It doesn’t matter how well you format your code, if your function / variable names are badly chosen (eg abbreviated names that mean nothing to anyone but the developer) and there’s no clear naming convention, then it can be a tough job understanding what the routine does.
I will also add, overly verbose names are bad too (I have one colleague who uses entire sentences in their function names. While it’s helps explain what the function does, it makes code readability more challenging).
3
—
Bad program design is a more subjective topic. Most (if not all) developers roughly agree on indentation; and naming conventions only have to be readable, concise and consistent. Not everyone agrees on the specifics of naming conventions, but as long as those 3 criteria are met, then anyone new to the code can quickly understand the standards applied to that particular project.
However bad program design is about the code design of the code – when to you objects, functions, iteration and so on. Sometimes application performance is paramount, which often means writing clever routines in a manner that isn’t ideal for a human reading back. Other times you’ll be writing a program which isn’t going to tax the processor much, so you can afford to opt for readability over performance (Sometimes you’re lucky and the optimised code is also the most readable code).
Then you have people using obscure language features or unpopular features (goto is a great example of that. But thankfully there’s very few occasions when a goto is the better method of writing a routine).
And after all that, you have the topic of code separation (eg using MVC’s in web development to keep server side code separate from HTML).
———-
At the end of the day, it doesn’t really matter whether your language uses English words or braces – a good developer can make their code readable.
But also, a lot of it comes down to practice. If you’ve never spent any time developing in C-derived languages, then the C syntax will naturally look a mess. But most developers get used to it and even come to love braces (that certainly happened to me).
I had a computer programming teacher that used to prefer:
a = a + 1;
to
a++;
in the name of readibility!!!
So, “readable code” is a very subjective term and in this case, if my teacher could not read the “++” thing… we have a problem!
I actually prefer the first way myself, even though I can read the second. In general, I don’t mind code that’s a little more verbose, if it’s easier to read.
Obviously though, there is a tradeoff between readability and verbosity; if you’re using 30 lines of code to do something that could be done in 3, you could probably do better. On the other hand, if those 3 lines of code look like modem line noise on a terminal (as many perl scripts seem to end up looking like), I’d rather have the 30 lines
But again, this is all down to experience. A good Perl developer should be able to read that code easily enough.
Where I draw the line is over-engineered regex:
* they can be completely unreadable – even to many seasoned developers
* and they usually run slower then multiple, more precise, expressions.
A basic example is a ‘trim’ command. The following will remove spaces from the start and the end of the string:
s/(^\s|\s$)//
However it’s actually computationally less efficient then having two separate replaces:
s/^\s//
s/\s$//
So the real issue isn’t Perl’s syntax, it’s that you’re either reading bad Perl code, or that you’re not familiar enough with Perl to understand it’s syntax.
And this is my problem with people who bang on about how bad Perl / C++ / etc is for readability vs Python / VB / etc. Those people are generally inexperienced developers and thus not really qualified to comment. It’s a bit like saying simplified Chinese is less readable than English, because I’m an English speaker who’s only exposure to Chinese is from friends of that heritage.
Hi,
The other problem is adequate error handling.
For me, adequate error handling means telling the user what was wrong with descriptive error messages; like “missing space between foo and bar”, “bad character after foo”, “bar needs to be at least 4 characters”, etc.
With a single over-engineered regex the only error message you can do is “Something was wrong but this code is too stupid to tell you what”…
– Brendan
On the other hand, why not have a goddamn Trim function? It’s infinitely more readable than any of this ‘s/’ crap. You’re trying to make excuses for a write-only language who’s code looks like line noise by saying, ‘Well, a good programmer should be able to read line noise’
Edited 2013-01-16 16:35 UTC
If it is purely a readability argument, I see no reason to not use the increment operator, as long as it is alone or just being used in a loop construct. Throwing it into an array index or dropping it into a computation is confusing and dangerous.
Your teacher may have just been trying to avoid having to deal with explaining prefix vs postfix increment, how they evaluate, and all the confusion that usually leads to with a newish programmer. Sometimes teachers do things that seem silly and pointless when your still green around the ears but 20 years later you go “yeah, I get it now”…
Edited 2013-01-16 02:56 UTC
A compiler would just use an inc command in both cases… Though a++ makes sense only with integer variables.
a = a + 1 = a.operator+( T other )
a++ = a.operator++( int )
++a = a.operator++()
Three completely different function calls
OzzyLondon,
“a = a + 1 = a.operator+( T other )
a++ = a.operator++( int )
++a = a.operator++()
Three completely different function calls”
You are absolutely correct. And the post-increment operator highlights a C++ syntactic hack in and of itself. Personally I’m a bit disappointed that the language designers reverted to such an ugly hack (passing in unused int parameter to distinguish between functions).
Probably because he came from a Pascal background, in many case “readability” means “what I am used to read”..
I have a special thing for “a += 1;” myself: quite short and doesn’t have the pre/post issue of “++”.
There is a very big difference between “not being able to do something” and “preferring something else.”
a = a + 1 has little ambiguity to it, whereas a++ may have a rather ambiguous behavior: i.e. When does the value for a get updated? Is it implementation specific? etc, etc.
Well, if you find that ambiguous, then perhaps you should find another profession. The behavior of the prefix increment is very well defined,and is a very, very basic topic that most books cover within the first 3-5 chapters.
No, no it’s not. You try to maintain someone else’s VB.Net app… “End If”‘s (and “End …” blocks in general) are complete crud. Braces are only complicated if you don’t line them up correctly.. but most modern IDE’s don’t even make that hard. I far prefer ‘}’ to working out which flavour of ‘End …’ is missing in a VB method that some idiot made span 3 or 4 screens. Dometimes life is too short to not refactor, and moving VB code to C# is not all that hard. In fact, the last time I did that I fixed about 3 or 4 obscure bugs that VB introduced due to it’s utter shit syntax (and this is with Option Explicit and Option Strict on.)
Having come from a Pascal background (but having done a lot of C++ in my BeOS days, ADA at university and BASIC before that), the “begin .. end” block teaches you much better practices than C’s braces. There are plenty of places I will use a block where other programmers will not, mainly because it saves time in the long run.
The semi-colon is a fairly unambiguous end of statement marker. If that is hard to understand, you are pretty much doomed.
I use both punctuation (C) and verbose (ADA) languages and tolerate both well.
The solution is a syntax colouring editor with very different colours for keywords and plain identifiers (not black and dark blue…)
The begin/end stuff becomes colorful patches surrounding black code.
With ADA (83) we always had a “BEGIN” and an “END xxxx;” for all constructs, save possibly the “REPEAT… UNTIL …”, though it’s been a good 20 years since I did any ADA and I don’t remember it well. Same with Pascal (Object Pascal; Delphi.) With VB you don’t. You get this:
Compare that to the C#
Or Pascal
The beauty Pascal is that the entire If is one statement with compounds, the beauty of the C# is that it is not (really.) Both have advantages.
EDIT: remembering to add the actual point: The blocks make it easy to see what belongs where, where as with VB and other non block delimited languages, it’s all about context.
Yeah, that’s kind of okay. But again, when the code spans 3 or 4 screens (bad coding practice, horrible to maintain) it’s more about refactoring to a sane state initially. Syntax highlighting has come a long way. The first editor I used on a daily basis was Delphi 1 and the syntax highlighting was very simple and the code insight did not exist. You had to actually know what to type – a skill lost by many recent CS graduates.
Edited 2013-01-16 12:35 UTC
More over
It’s not hard before the lack of blocks starts to make the language unreadable and easy to misinterpret.
That’s badly formatted C#
I prefer the following:
if (X == Null) {
Something();
Somethingelse();
} else if (Blah == “Give up”) {
Somemore();
} else {
ShootYourself(DateTime.Now);
}
In my opinion that is significantly more readable than any of the other examples you’ve listed.
Sometimes I concatenate the lines further:
if (X == Null) {
Something();
Somethingelse();
}
else if (Blah == “Give up”) { Somemore(); }
else { ShootYourself(DateTime.Now); }
(this isn’t the best of examples (and not helped by the formatting on OSNews), even I wouldn’t concatenate specifically here, but sometimes it does aid readability.
edit:
You can use blocks in C-derived languages as well:
{
if (X == Null) {
Something();
Somethingelse();
} else if (Blah == “Give up”) {
Somemore();
} else {
ShootYourself(DateTime .Now);
}
}
Edited 2013-01-16 14:10 UTC
Actually apart from the lack of indentation it was correct. The Visual Studio default and the Microsoft Recommended Coding conventions all use that style.
http://blogs.msdn.com/b/brada/archive/2005/01/26/361363.aspx
Yeah I’m aware of that and I don’t agree with it. I think it’s less readable and the opposite of what developers in most other C-derived languages prefer.
Plus I object to Microsoft dictating how I -or any other 3rd party developer- chooses to format the braces in our own source code. That’s my prerogative, not theirs.
Edited 2013-01-16 14:21 UTC
Well it is a matter of taste, so I tend to adopt what the language creators recommend, in this case Microsoft.
Well they firstly aren’t, they are a set of suggested guidelines.
While I agree it is personal taste, pretty much all C# books, examples and third party libraries use that bracing style. Also Visual Studio and StyleCop default to type of bracing. It is what other C# programmers expect to see. I don’t see any benefit in bucking the trend in the community, but as I said it is personal choice.
As I say, when I am doing Java or JavaScript I use the bracing style that you suggest. Java because it is what Sun recommended and JavaScript because of the issues with Semi-colon insertion.
Edited 2013-01-16 14:43 UTC
I guess that’s fair enough then. I guess my extremely limited exposure to C# is shining through here hehe. (not that I haven’t coded in other languages that share the same heritage)
I am not sure why the bracing is different and I would normally agree with you, except everyone does it that way when you are doing C#.
On of the main things I like about C#/VB.NET is how it cleans up the getters and setters with Properties.
There is one thing I don’t like about .NET which I do like about Java is that you have to specify whether you are going to deal with a Exception or let is percolate upwards.
haha yeah, I remember when I first stumbled across that. It completely threw me for ages.
I do agree it’s a pretty awsome feature (once I had wrapped my head around what was happening hehe)
I didn’t understand why it was a good thing, until after I finished my degree.
I’ve been reading:
http://www.amazon.es/Clean-Code-Handbook-Software-Craftsmanship/dp/…
Most of the examples are Java, but the ideas apply for any number of languages. A lot of what was actually covered in the story article was mentioned in here.
A lot of the ideas are really simple but effective and I have been applying them over the past few months at work. My code IMHO has become better as a consequence.
I usually put braces on a new line unless the block is one line long.
if (someArg == null)
throw new ArgumentNullException(“someArg”);
The only exception I usually have to this is if its part of a larger if-the-else statement and the other blocks are multiline and have curly braces. Then I think:
if (this == that)
doX();
else if (x == y)
{
// ..
}
else
{
// ..
}
I think the obsession with vertical space is kind of silly in this day and age. I am much more sensitive to code that sprawls horizontally forever.
Besides, I often find new line braces more readable while less compact, whereas the opposite is true for a lack of braces, same line braces, or first brace same line.
At the end of the day though, it is extremely annoying when some full-of-himself programmer ignores the established project coding guidelines. I don’t care if a monkey wrote it, if I’m going to be a part of a team, I’m going to follow their rules.
I hear you on that.
In the past I’ve written code that I’ve personally hated but it was correct in the context of the wider project.
That said, I have been known to completely rewrite smaller projects before, but those have been extreme circumstances (and there’s usually been more wrong than just the use of blocks and braces hehe)
I usually like putting the braces.
Here here, we are having a meeting about coding standards just because there isn’t any in our team.
I would like to make sure we use the Microsoft ones for C#, just because they are easily referenced and are well known. Also because we have a lot of juniors, when they look at code samples they are normally using the Microsoft syntax for the most part.
Your opinion, and bear in mind, OSNews lost my indentation. To me, your code looks suboptimal for readability. I work in a large team, other people picking up classes and libraries I’ve written is essential. Standard style guides and conformity saves a lot of time and prevents prima donnas. Plus, having come from Pascal, those arguments just waste too much time. Suffice to say:
And that is just scratching the surface and not even dealing with tabs, etc. It’s a holy war, not worth winging about.
For C#, the basic layout I use (and enforce here) is based on the standard Microsoft use in all of their sample code. Sorry if you don’t like that, complain to someone who has write access to Microsoft’s source repository 😉 Visual Studio also usefully formats this way – why fight the IDE?
I never use tabs, they are evil. I use 2 spaces for “Tabstop” because otherwise your code shoots off to the right at great speed. I would go for simple over terse single line every time. I tend to (recently) add in extra space in if/else if/method params. This is just a concession to a speed reading on a high res monitor. Text scans better.
Not exactly the same thing. In Pascal this is one statement:
if (x = y) then dosomthing else dosomthingelse(y);
and so is this:
if (x = y) then begin dosomthing; end else dosomthingelse(y);
and so is this:
if (x = y) then begin dosomthing; doanotherthing(x); end else begin dosomthingelse(y); end;
dosomething and dosomethingelse(..) are compound, as are the other examples. Like I said, the C syntax is sort of similar, but not exactly. Pascal thinks of the compounds as being part of a single statement, with compound elements. Where as C doesn’t (IIRC.) The braces in C are just a way to create a block and the if/else links those blocks together. Semantics, I know. But look again at the basic Pascal version:
if (x = y) then dosomthing else dosomthingelse(y);
That is a pure statement, with no semicolon after the first clause. Geddit? 🙂 C would require 2 statements linking the blocks:
if (x==y) dosomething(); else dosomthingelse(y);
I don’t. How is that any different from
(x == y) ? dosomething() : dosomethingelse(y);
?
Maybe it looks a bit more cryptic than its begin/end counterpart if you embed these kind of statements into each other, but not by much. Stacking ternary statements is always ugly and unreadable, regardless of the language used.
Because ? is an operator, not a key word and it doesn’t really work in the same way – at least in c#. Plus in Pascal one can have as many segments in the statement as one likes:
if (x = y) then begin do1(); do3(); end else if (x = a) then do2() else begin do4(); end; //3 blocks
if (x = y) then begin do1(); do3(); end else if (x = a) then do2() else begin do4(); if (y = x) then begin do5(); do6(); end else do7(); end; //a 2 block embedded in a 3 block
Obviously, no one would format the code that way – it’s just an example.
You can’t really implement that using ? without a lot of unreadable complexity.
Normally most formatting problems can be sorted with the IDE.
TBH a lot of the problems you describe are more to do with the way the applications have been written and not the language itself. I am sure I can point you to some of the atrocities I have seen in C# (my favourite being the INullObject interface I recently found).
Personally I like VB.NET, while the syntax is odd you can write code pretty quickly. My main issue with the language is that it is difficult to see the difference at a glace between an array and a procedure/function.
A lot of newer developers especially those coming from Python or Ruby find the use of a semi-colon slightly arduous. There was recently a flame war between Douglas Crockford and one of Twitter Bootstrap developer over whether you should make of the JavaScript semi-colon insertion mechanism.
Edited 2013-01-16 13:16 UTC
Ugh, that NullObject b.s is the kind of ridiculous over abstraction that you see from Java Programmers who move on to C#.
It is incredible the amount of gunk that Java programs have. Seriously. I’m convinced Java is just a collection of terrible design patterns looking for a problem.
Oh jesus.. no it’s not! Here is an example:
Define a class and on that class create a public event
Public Class Whatever
  …
  Public Event MyEvent(ByVal SomeValue As String)
  …
  Public Sub RunHack(ByVal whatever as String)
    MyEvent(whatever);
  End Sub
End Class
Then in another class try this:
Public Class TwatFace
  …
  WithEvents myHack as Whatever
  …
  …
  Public Sub ABadIdea(ByVal whatever as String) handles myHack.MyEvent
    MsgBox(whatever)
  End Sub
  …
  Public Sub LetsBreakEventHandling()
    Dim fcukit As New Whatever
    myHack = fcukit
    myHack.RunHack(“Shoot yourself now…”)
  End Sub
  …
End Class
What happens if we call LetsBreakEventHandling? Well, it should never compile… it does. It should probably freak out and crash, but you’ll see a message box happily telling you “Shoot yourself now…”. And I know all of this because the fcukwit programmers, on contract from India, that we used before I took over didn’t know about “AddHandler Xxxxx, AddressOf Yyyyy”.
Even with option explicit and strict on, you can do this:
Dim X as Integer
X = 99
Dim Y as Boolean ”uninitialised, so compiler decides
Select Case X
  Case 1, 2
    Something()
  Case 3, 4
    Somethingelse()
  Case Y
    WhatThef–kDoesThisEvaluateTo()
End Select
VB is dangerous, plain and simple and there’s nothing you can do in VB that can’t be done in a safer .Net language at a similar speed.
Edited 2013-01-16 16:43 UTC
Look I am sorry you have a crap codebase, but the fact remains the same … you can write bad code in any language.
Edited 2013-01-16 16:45 UTC
Look I’m sorry you like VB, but the fact remains you can do better in just about any other language that targets .Net/CLR. VB is shit and it always was. VB lets you do completely unsafe things and even when you tighten it up to require as much safety as possible, it still lets you do ridiculously stupid things. A bad programmer can write reasonable code in C#, because there is a lot of padding to protect them, not least proper type safety. A bad programmer will hack together a horrible solution in VB.
This has nothing to do with the code base. I’ve dealt with very competent programmers using VB, and the C# translation is still far less unsafe due to the greater type safety and lack of silent casting and type munging that VB does in the background.
Edited 2013-01-16 17:08 UTC
Utter rubbish. In fact in some circumstances VB actually has some advantages over C# (XML parsing for example).
Absolute crap, I have seen C# programmers just wrap stuff in Try … Catch statements when encountering a null pointer exception. This is pretty much the modern equivalent of VB6’s “On Error Resume Next”, rather than deal with the condition sanely.
Or my personal favourite, catch the exception and throw e.Message … so you lose the original exception.
I am sure I could find quite a few other languages that are far worse. VB.NET is fine if you take some care about what you are doing.
Just look at the dailywtf.com, there is bad code is eveyr language and the two factors that always rear their heads
* Mis-management
* Moronic Team members.
Edited 2013-01-16 17:03 UTC
In your opinion. I’ve had zero issues parsing Xml in C#. The VB syntax makes my eyes bleed. The best integration I’ve seen is Actionscript.
If you say so. I think most sensible people that have encountered VB programmers would beg to differ. Even recently, a contractor was “let go of” because his code was pretty much the epitome of VB legacy over sense.
Haven’t we all? And I’ve seen exactly the same in VB – plus all the other cruft that language brings with it. Between rewriting a few methods with bad decisions regarding exception handling and dealing with crusty VB code, well – I know what I’d prefer.
Seriousy? Here is how I deal with that: 10 minute talk including best coding practices handout, misconduct warnings (1 verbal, 2 written), bad yearly review if there’s no improvement, removal from project work – probable contract termination. Do you know how often my organisation has had to go past first formal written warning? Probably 2 times in the last 15 years. This is why you interview carefully – with a formal practical element, pay for training when required and don’t hire incompetent people. That’s not to say mistakes are never made, but that’s also why you give new hires a 3 month probation and make sure contractors are on weekly contracts until they have proven themselves.
And you can go on making excuses. Or you can just not use it. I know which one is better for my business and saves me the most money.
Every single problem you have brought up and every solution has to be due to bad development practices in the vast number of cases.
I have no idea what you mean by “crufty” VB code, everything I can do in VB has direct C# equivalent apart from some minor things. But I come from a Java background.
Yes there are a few shitty things, but much like JavaScript and PHP if you are mindful of them you can successfully mitigate the problems … again this comes down to whoever is writing the software.
I’d argue that whilst that may be true, all of the examples I’ve given demonstrate why VB is not a safe language to use. The fact that one can get away with writing such bad code in the first place is key. Come on – you have a Java background and VB is a good language over C#? Really? I respect that you have your own opinion and that you are writing the code you use, but my experience with working with varied VB shops tells me that I will never employ anyone to write code in VB going forward. All our VB is legacy and we are actively (though slowly) migrating it away from that language.
I don’t think what he said is untrue, just less true for some than others. People with a strong VB background have picked up VB.NET rather quickly (to my dismay, Id rather see it die a cold death, but ah well)
I think your counter-point underlines his point quite well though, in that WithEvents is a construct included in VB.NET for pure legacy reasons.
C# has the advantage of being able to learn from the mistakes of other languages, whereas when VB.NET was being developed, they likely valued VB familiarity over purity.
That’s why you can do stupid things in VB.NET, but you can also do stupid things in C++, in Java, and in C# (Look at boxing before Generics for example).
C# not having as many ways to shoot your foot off is a testament to C# as a language, sure.
VB.NET is completely type safe.
Also, the switch statement with a boolean is probably going to evaluate to zero, because that’s what a bool of false (default value for the bool value type) evaluates to when converted to an int.
With regards to “WithEvents” – yes probably. But that’s not what the MSDN says. As far as I can see, it’s required when the “handles” clause is being used. That’s not really legacy then.
No it’s not… not in the “you can’t use the wrong type because it won’t compile” sense of the notion. VB will happily munge and cast between integral types and Decimal/Double. VB will silently cast a Boolean to an integer. This should not compile, but it does:
Dim X as Boolean
Function WFT as Boolean
Return X
End Function
….
Switch Case Y
Case WTF ”This could be anything
….
Yeah, probably. But when you have to run code to verify that fact, it’s screaming “walk away” to me.
And the compiler silently casts the Bool to an Integer. That might be how VB6 worked, but VB.Net uses the CLR and so an explicit cast is required. How helpful VB.
Oh, and rewinding to “type safe”.. try turning off Option Strict and Option Explicit and see how much worse you can make stuff… you don’t even need to declare the return types of Functions… VB just guesses for you and silently casts the result to the type you assign the result to. Even with it on, you can still do everything else I mention. The first thing I do with VB code these days is look at the project properties and if it isn’t already set, build it with Option Explicit and Option Strict turned on and fix all the errors. It is far, far too common to still find shops using VB.Net as if it was VB6.
I agree with you that VB is terrible, but it doesn’t make it type-unsafe because of it.
I think casting is more of a gray area and VB.NET definitely has more ambiguity. Its harder to know at a glance if something is correct.
C# does some implicit casting too, if you define an implicit operator overload. I’m sure VB.NET does something similar to manage to stay within the CLR sandbox.
What VB.NET does imho, is wrap bad ideas around syntax. Examples being like you said implicit conversions (which imo have always been a bad idea no matter the language) and implicit late binding.
VB.NET takes late binding, implicit typing, and implicit casts and muddies the waters into this incomprehensible soup of syntax.
However, it is still easy for VB developers to pick up VB.NET . That’s always been the reason imo for VB.NET’s existence. I’d never write any meaningful amount of code using it.
I think any time someone uses dynamic in C#, late binding in VB.NET or find yourself using some of these more weird features, they need to step back and think about what the hell they’re doing.
I agree that VB syntax isn’t the best.
I have mostly written C#, Java, PHP and JavaScript. I have never coded in classic VB, So I tend to write VB like C#.
We have a lot of points in our code base (that is mostly inherited), where Try … Catch is mis-used, and that is one of the better things I have to deal with.
* Functions doing more than one thing and multiple return values of the same type (usually string) which mean different things depending on how it is used.
* Very misleading variable names.
* Try … Catch misused.
* Lack of understanding for some key OOP principles, a classic being two different types having say the first 5 properties and methods being exactly the same and having 2 or 3 properties that are different … it is screaming to use inheritance, but it was just muddled together.
I could go on, but my main point was that any one of these problems aren’t down to the language but down to lack of understanding of principles. I don’t think any language magically fixes those.
I’ve been working with a contractor (politically, I had nothing to do with him being hired for the project – I would have vetted him better, but he’s actually being subcontracted to a third party who seem happy not to care.) He doesn’t believe in inheritance. It drives me absolutely insane. He will do exactly as you say. He’s very pattern orientated, but prefers using interfaces and single level hierarchies. I came from a Delphi background and I’m used to using interfaces to create a contract that is implemented in a class, but also creating hierarchies that build up reusable blocks of code. The flat namespace approach really doesn’t make sense to me at all. Example: I have a requirement to implement a set of classes to process allocation of a table based set of prices, which differ by application. I personally would create a base class with the commonality in it, then build classes on top of that to implement the specifics. I would more than likely create an interface with the specific details for accessing any of the children generically, I’d utilise abstract and virtual methods/properties to ensure the interface could be applied at a level where it made sense. He on the other hand would create one interface and implement a new class for each different use. His argument is that inheritance causes complexity that can be avoided, but I’ve worked on some stupidly complex class hierarchies that were poorly designed and still simpler and easier to maintain that a class per implementation of the functionality with lots of boiler plate code included.
Edited 2013-01-18 14:04 UTC
henderson101,
It might be a matter of preference. I often find that I don’t like the way inheritance is used and strongly prefer interfaces myself. This is one reason I like .net over C++. The “IS A” relationship and “HAS A” relationships often tread very thin lines and with the exception of polymorphism the differences become syntactic rather than expressive.
Yeah, inheritance doen’t soleve every problem. But it has its applications. In the case where the same boiler plate code is almost cut and pasted in to multiple classes with no variation, it makes a lot more sense to create a base class and inherit tose characteristics. Don’t get me wrong, I don’t advocate inheritance over sense (“inheritance madness” as a Turkish co-worked used to call in back in the ’90’s), but I also think it is important to use all the tools you have effectively, not overly complicate or convolute your code and leave the least margin or error for future maintainability. Cut and paste flat hierarchies are prone to feature disparity when one developer changes an aspect in some but not all classes and then introduces unexpected behaviours. I’d rather see a helper class with the base implementation and then the use of the adapter or mediator pattern with full encapsulation be used than absolute cut and paste.
And don’t get me started on “Modules”… Global static classes that are automagically pulled in to the scope of all classes in the same namespace… without the need to specify the module name. Ack!
Thank you for posting this Thom. Its going to be very useful to me over the next month or two.
And having written several game engines for games shipped to most plaforms.. this article is great.
I can definitely say that there is a point to be made here about C++. For this kind of things, C++ is still the best choice up to this day because the optimal ratio of OOP/Low Level/Performance/Code Size. Other languages bloat too much in one or more of these elements but C++ hits the balance.
The problem with C++ is that I think it’s a language that takes around a decade of using it to fully come to terms with. Reading the source code of other people that is more experienced greatly helps but truth is that even if you read the full specification, you will still not understand what most features are really used for until you need them, and then it clicks.
I think people focus too much on naming conventions, curly braces, semi colons, and camel casing. There’s not enough focus on the act of engineering something that’s sustainable a few months down the road.
Too little attention is paid to the design of your object model (if you’re oo inclined), the decisions made around multi-threading, and the relative costs of what you use in the language.
I’ve seen countless examples of people obsessing over for example how comments would be formatting, only to end up producing this over engineered bullshit code that is unmaintainable. But I guess itll keep them from scrolling vertically (on their text terminal I presume, because we magically traveled two decades back in time where that kind of shit matters)
And whats worse is that these questions are even more important in C++ where the compiler and run time make less security, resource, and correctness guarantees.
Its more important to know who owns what reference to what object, or what threads will call this method, what synchronization primitives we’re going to use, how will we handle dependencies, or component failures, etc. This is the real bread and butter of programming.
Except for the formatting part our current code base uses much the same, with generally Qt type function names and naming conventions. Minimal use of inheritance, generally things are structs with functions, heavy heavy use of const everywhere.
It’s a pretty effective style of coding, easy to maintain and debug. One technicality was the improper ordering of the const stuff and not constifying enough when pointers passed in
example parameter
type ** value
would be better expressed as:
type * const * const value
so the function won’t hose itself if the function writer improperly reassigns one of the levels of “value” instead of just the contents.
I’m sorry but it does. There is a REASON why nearly every game out there runs on Unreal while ID tech 4 like the Cryengine is only used by the parent company, and that is because they suck.
You look at how much resources an average scene in Doom 3 used when there wasn’t crap going on and you’d have to have a hectic battle going on for Unreal to use the same amount, they blew their resources on pretty lighting without remembering that pretty lighting isn’t worth squat if there isn’t things to put IN the pretty lighting. There is a reason why you could have the screen filled with demons in Doom 1 & 2 while 3 was nearly all one on one, and that was because ID Tech 4 simply chugs if you pile on the bad guys.
So while I’m glad the coders can be impressed by the code as a gamer I certainly wasn’t impressed with the finished product. Doom 3 like Fear 3 is one of those games where I play the previous games all the time, the third one? Never, its just not fun and I find it quite boring.
ON what planet does the CryEngine suck? Planet Delusional? I’m not saying it’s better than Unreal but it surely doesn’t suck. Ran everything with great looks and speed even on a modest system. It’s not based on idtech4, btw.
The Doom3 engine though…not so great in my experience. On a system that ran HL2 and Far Cry smoothly with good detail (using an Intel chipset) Doom 3 would struggle at the lowest supported resolution (640×480 or 800×600, can’t recall) especially when a couple of enemies appeared. Then the frame rate dropped to something that felt like single-digits.
Read what I wrote friend it sucks for the amount of resources VS what you get for those resources. Look up the end battle of Crysis 1, its pretty infamous on how to this day that will cause many top end cards to choke because its so badly coded. There is even a fan made patch that will kick down the setting when you reach that ONE spot just because its so badly coded.
Again look at the facts, you have a good 90% of the games being made on Unreal, while CryEngine and ID Tech 4 are ONLY used by the parent companies…think that is a coincidence? Don’t misunderstand, I’m not saying both engines can’t put out a static scene capable of making you drool, THAT is not the problem. The problem is when you actually start to DO something in those scenes the engines blow through resources like a fat guy at an all you can eat buffet and end up using MUCH more than they should.
When I could take an HD4850 which at release was a top tier card at nearly $300 USD, which would epic “cool guys don’t look at explosions” scenes with full AA and AF in any of the latest Unreal based games but it would have a scene that looked like a coder threw up on it in Crysis one when it got to the final battle? Something was very VERY wrong with that engine. Remember we are talking GAME engines here, making good static scenes don’t count for much if the user has to spend half a grand just to get more than 15 FPS when you have enemies on the scene.