In an interview, I would much rather hear a person say something about a statically declared variable with no initialization being poor code to leave behind for the next person than some arcana about the standard.
In an interview, I would much rather hear a person say something about a statically declared variable with no initialization being poor code to leave behind for the next person than some arcana about the standard.
Why are you forcing those two choices? One could be well-versed with the arcana AS WELL AS point out that bit about statically declared variable ..
The problem IMO is most programmers cargo-cult/copy-paste/stackoverflow their way into programming jobs. No, that does not mean you never ask for help. No, that does not mean you never copy-paste. (Phew!)
Its sort of like when you're learning math. Great mathematicians can understand the theory and just apply it to whatever problem they come across. Its because they have a very solid foundation underneath them. They wield their knowledge like tools and can just build anything with those tools because they understand those tools very well. Most students however just learn the patterns of the problems. And once they know enough patterns they can solve problems which fit into one of those pre-understood patterns.
The people who are deeply knowledgeable about the language are good at knowing the boundaries of the language, knowing when you're using constructs that are not valid-syntax (which still compile), etc. The social aspect of 'good comments' , 'readable code' or 'maintainable code' is also important. You can have programmers that do both. Ofcource those programmers will never work for 'you' (not you, personally..) because most programming jobs are shitty and do not require programmers of that skill. You'll find them toiling away in anonymity, working in research labs, working on compiler optimizers or operating systems or some other domain with challenging technical problems.
Sadly you are required to move for such jobs, which is not always an option.
Compare this with C. There is a degree of serious technical focus that languages like these demand for big projects. Embedded systems, Operating systems, Databases, compilers etc. A big part of software world uses these languages on a daily basis. But there is no where the kind of hipster crowd, these languages have the web frameworks or languages have.
Even if you spend some time searching for resources on the net, there are few that teach deep C skills. There might be one or two books out there which haven't been updated in 2 decades.
By and large, these are unfashionable fields to work in. The barrier to entry is really high, Success comes only with seriousness and application of well focused effort, mistakes are expensive and they warrant serious RTFM'ing the hard way- to write to some real serious code.
Sure some languages take less time to learn than others. But every single language makes tradeoffs. For e.g performance vs productivity/usability OR static typing vs dynamic typing is a common theme when discussing C vs {Java, Python, blah}.
Also, your comments falsely compare the difficulty of the TASK with the difficulty of the IMPLEMENTATION/LANGUAGE. They are not the same! Take any advanced applied math algorithm and implement it in Python. Its not 'easy' by any means.
The domains you mentioned have a higher barrier to entry because the tasks themselves are difficult. The languages and technology used are simply variables in a much larger optmization problem that also includes monetary/human/computing/time resources as variables.
Personally I don't care about C, due to its unsafe by default design and my background in safer languages for systems programming.
I got my first computer, a Timex 2068, at the age of 10. Spent two years mainly playing games and eventually started looking into programming.
When I learned C, at the age of 16, I already knew BASIC (Spectrum, GW, Quick, Turbo), Assembly (Z80, x86, 68000), Turbo Pascal.
So C was for me a bit "meh" language, given that Turbo Pascal gave me much more, granted except for portability. So I quickly jumped to C++, which allowed me some strong typing comfort and higher abstractions in a forced C land.
Regardless of the language, when I was 18, I had already coded compilers, graphics applications, GUI prototypes, MS-DOS drivers.
Nowadays kids seem just to do JavaScript/Python/Ruby frameworks for generating web pages.
That's progress, IMHO.
Instead of distributing application binaries carefully targeted to each type of user machine, we only have to run the application on one server machine (or a cluster of them) in a central location and can serve the application over the network. We now have code-generating frameworks that help automate away much of the tedious, repetitive parts of implementing an application.
It's not a good thing that software development is hard. It does mean that you're a very smart and hard-working person if you're able to do it effectively. But it's not a good thing for society that you need to be so smart and hard-working in order to do it.
It is, however, a good thing that it's not as hard as it used to be. The fact that a software developer has to do and know less today than they did 20-30 years ago, just to build an application and distribute it to a large number of users, is a sign of progress.
it has pointers, pointer arithmetic, manual memory allocation, function pointers, casts, unions, you name it.
I bet you could write could write 30 odd rules for cpp and then compile your "pascal" with cc, e.g.:
#define begin {
#define end }
#define := =
#define ^ *
#define @ &
and so on
- It has real strings
- Arrays don't decay to pointers
- It has reference arguments, which avoid pointer usage for records and out arguments
- Requires explicit casts for type conversions, instead of implicit type casts
- Provides region allocators, which allow to release a full block of memory in one go
- Has real enumerations that don't decay into ints
- Allows writing generic code over arrays without requiring the developer to manage a separate length variable
- Has proper memory allocation constructs instead of requiring the developer to know the size of memory to allocate
Finally, there are other languages in the Pascal family, that provide safety, while allowing for C dirty tricks done explicitly via a system/unsafe package which provides much fine control over the use of said features.
pascal style strings can be done with the preprocessor, as can generic iterators, allocation for idiots, and "out" function arguments.
memory pools are a library feature.
and the arrays are the same too, a pointer in pascal can be treated as an infinitely sized array, but the reverse isn't true, just like in C.
and, believe it or not, there are other languages in the C family, that provide safety in the same way there are for pascal.
tl;dr: pascal and C are more alike than different.
That still does not make them safe, implicit conversion to int will still happen.
> pascal style strings can be done with the preprocessor, as can generic iterators, allocation for idiots, and "out" function arguments.
No type safety.
> memory pools are a library feature.
That aren't part of any C compiler. So you can't count them being available.
> and the arrays are the same too, a pointer in pascal can be treated as an infinitely sized array, but the reverse isn't true, just like in C.
You lost me there.
> and, believe it or not, there are other languages in the C family, that provide safety in the same way there are for pascal.
Yes, that is why I use Modern C++, C#, Java, D and will only use C at gunpoint.
> tl;dr: pascal and C are more alike than different.
True, except in Pascal when bad things happen is because the developer explicitly wanted them to happen.
In C everything goes and to have Pascal's safety back, all modern C compilers provide static analyzers. Thus proving a point about the languages design's.
True. Talent going to waste is sadly nothing new. Has happened, will continue to happen. :(
As someone who's both a mathematician and a programmer, I think that analogy glosses over an important difference, which is also relevant to why many people refuse to memorize certain things.
Good mathematical theories are internally consistent in a very strong sense. When you're learning them, you feel like you're learning something eternal that could not possibly turn out any other way. If you forget half of calculus, you can reconstruct it from the other half, and the reconstruction will be unique.
The details of programming languages, like C and especially C++, are not like that. For many mathematicians who would otherwise make excellent programmers, the details of C will feel like something not worth memorizing, because they don't make sense - they are not an inevitable, provably unique solution to any problem.
To a mathematically inclined mind, programming concepts form a hierarchy depending on how "inevitable" and worth memorizing they are. Concepts like computability, lambda calculus or big-O complexity are near the top, syntaxes of specific languages are lower down, and API details are at the bottom. That also reflects the rates of change: math doesn't change, languages change every decade, and APIs change every year.
If I want to hire a programmer for the long term, as opposed to getting quick help on my current project, I will be mostly asking them about concepts from the top of the hierarchy, not what static means in C. Of course some people will disagree with me and demand detailed knowledge about static or templates or whatnot, while dismissing mathematical questions as "puzzles". Maybe that's also a valid style of programming, I'm not sure...
No wonder everyone is always talking about the rapid pace of learning in high technology.
Have you implemented a compiler or a interpreter for a popular language? I could be wrong but I strongly suspect you haven't. If you have ever implemented a compiler you understand the language at a fundamental level and when stumped with a bug or a highly technical puzzle or what have you - you get that "aha" moment where its like "Ofcource ! How else could it be. This language feature must be using this construct because of X or Y reason and the compiler has to work this way because this part here doesnt allow for it to work any other way, etc ,etc and the optimizer has xyz amount of scratch registers so abc condition could never happen, and on and on."
Lawrence Kesteloot said it well at http://www.teamten.com/lawrence/writings/what_interests_me.h...:
On a planet far away they have universities. In those universities they have many of the same subjects we teach here, such as math, biology, philosophy, history, computer science, psychology, and literature. But although the subjects of the classes are the same, the contents are different. They teach a history class, but their history is different from ours. So are their biology and literature. I’m not interested in subjects where their content is different from ours.
In some classes, though, the content is the same. They’re teaching the same physics class (assuming they’re at the same level of understanding we’re at) and the same math classes (with a different base). In computer science most of what they teach is different, but their theory of computation is surely the same. Their biology is different, but their teaching of evolution is the same. Their philosophy is vastly different (think how different Eastern and Western philosophies are on earth), but their philosophy of science is probably very similar.
Even if this point of view doesn't make sense to some people, I subscribe to it because it's very inspiring to me. YMMV.
You're mis-applying things here. The language is not something to be theorized by itself. Like any (edit:spell) other body of knowledge, it has its own set of initial axioms and the 'C standard' which defines the language is simply a collection of rules other meta-knowledge which are based on those. In that sense it is internally consistent. Thats what I meant.
You misunderstand the usage of consistency regarding mathematics. It is not the same. These rules which compose C are design decisions, and whether they are entirely artificial. Mathematical consistency arises from imposing axioms, following which there are no decisions to be made.
Well, no. You can deduce A language but it might not be C.
I sense we're going down a fruitless path here. In my first post I was only giving an analogy of someone understanding math at a fundamental level to someone understanding a programming language at a fundamental level and how they could inform similar abilities/prowess in people when it comes to dealing with complex problems/etc.
Compare with a formal theory like PA, which fits on a page and describes the natural numbers. Proving a theorem about PA has implications everywhere, because natural numbers are everywhere. Or if we want to talk about computation, there are many formal theories with short descriptions that have much more to say about computation in general.
> You could make many different tiny changes to the rules of C and still end up with a workable programming language. (Many people have done that, there are tons of languages derived from C.)
Coincidentally, same is Math. I give you Euclid's Fifth postulate as an example.
>You could say that the rules of C are "random" - after learning the first n rules, you cannot use logic to predict the n+1st.
This depends on how do you enumerate these rules. If you learn that auto variables are allocated on the stack it's easy to predict that you cannot return their addresses and there are not going to be default initializes for them.
Another way to put it is, learning the postulates for langx doesn't provide enough value for many to be worth doing.
And I agree, this is one of the assertions my opponent has made. I did not go to refute it because, if not outright false, it's disingenuous.
>Another way to put it is, learning the postulates for langx doesn't provide enough value for many to be worth doing.
This is also true, same goes for everything else. I make money using C - I learn C's postulates. If somebody paid me to use topology - I'd learned topology postulates. What would be stupid if I were paid to use topology but said: "it's hard to learn and it makes no sense for me because I don't like mathematics and don't know any other math discipline so why would I all of sudden learn topology's postulate when I can copy formulas from the net and ask questions on manifoldoverflow.com?"
I'm not sure what you mean about the operator overloading thing.
Template types are also not really first-class members of the type system. The compiler can't really reason about them, it only type-checks them after expansion, when all the genericity disappears. This is completely different than the fail-fast approach in Haskell or even Java, where the code is type-checked at the generic level.
Don't get me wrong - templates is an awesome, extremely powerful feature of C++, but it doesn't play well with the rest of the language, and really feels tacked-on.
Function templates are not generic functions. Same as template classes are not types. They play really well with the rest of C++ but I agree, not so well with the rest of Java or Haskell :)
This is the major problem people nowadays have with C++ - they learn some "practical" high-level language in school (usually riddled with random stuff, judging by how much people here are pissed with my mentioning of PHP) and try to think about C++ in concepts of such a language. Then blame C++ for not being their favorite language.
Don't get me wrong. I am quite happy with this making my skills very rare and expensive, giving me both job security and decent compensation. I also want to thank all the people spreading the "C++ is complex hodgepodge of completely random things so it's impossible to learn" idea :)
Even though the library is covered by the same standard as the language it's not a part of the language and, in practice, is not even available all the time.
A better nitpick would be dynamic_cast throwing under some conditions. But then, how does it make iostreams the part of the language? There is just a typedef in the std namespace that aliases the type for some optional, compiler specific, data.
"Don't get me wrong. I am quite happy with this making my skills very rare and expensive, giving me both job security and decent compensation."
Eh? C++ skills are not any more expensive than decent Java/C#/Python/(put whatever mainstream language here) skills. Who told you that? This is supply-demand. There is lower supply of C++ coders, so some may think the prices should be higher, but in fact it is compensated by lower demand. C++ is also still being taught at schools, so those skills are not that rare as, say, Haskell, Erlang or Go.
As for the price of my skills - my paycheck told me that. And sure, it could be low demand (there are vacancies in my field, that had been open for years, but I don't really know what kind of demand there is for Python, could be decades for all I care). I am just happy for my compensation and if others have more expensive skills - I am happy for them too :)
IMHO the approach is a great example of premature optimisation: generate 2^N versions then try to fold some similar ones to save space. Much better approach is: generate 1 version and specialize small parts when really needed. Technically, assuming sufficiently smart compiler, both would end up with exactly the same code, performing exactly the same, but the latter solution is preferable for other non-performance wise reasons (like better type checking, ability to distribute binary libraries, faster compile times, etc.).
BTW: I still often find Scala containers to be often much faster than C++ STL. But this is probably for much different reasons than template/generics implementation.
In the first case - I fail to see how it follows. In the second case - our levels of expertise is too far apart to discuss anything. I am not saying you are not qualified, I might be just too out of the loop and missing some dramatic advances in Java, Scala etc.
Point being that there is no system that is complete. There are large bodies of mathematics these days that have specialized their notations and axioms to their domains. It is incredibly difficult to maintain a masterful knowledge of all of their idiosyncrasies and notations.
I don't think you know how great mathematicians think. http://en.wikipedia.org/wiki/57_(number)#In_mathematics "Although 57 is not prime, it is jokingly known as the "Grothendieck prime" after a story in which Grothendieck supposedly gave it as an example of a particular prime number."
I'm confused. What is your basis for that statement? If you you know how they think why don't you just express it? :-S I am sorry, I have no clue what your point is, or even if you have one.
That makes him a counterexample of the claim that all great mathematicians can apply heir knowledge.
If he were a computer scientist, he would have written several brilliant papers about the pros and cons of various properties of programming languages, but he would not be able to write a compiler for any language or even to write a program.
But puzzle questions like that are silly anyways, so whatever.
You're the one forcing the choices.
He's just saying that one should consider another metric to gauge developers, that is knowledge of good software practices over deep language arcana wisdom. And he's saying that whatever the knowledge depth (or lack of) of a candidate on the C or C++ language, he'll choose the one with better software practices. (Of course, the two metrics are slightly correlated, but being an expert on C trivia doesn't necessarily makes you a good developer)
Life is too short to become an expert on C's dark corners, and I'm not even talking about C++'s.
"I would much rather [a person do X] than [a person do Y]"
I parse this kind of statement as a person doing X is more important than a person doing Y. I stated that I thought both were achievable. How have you parsed it?
Also trivia implies some memorized factoids. The entire point of the article is having an understanding of the underlying implementation of the compiler, maybe the implementation of the standard library, or the OS or the hardware ADDS to your knowledge about C making you a much more complete/well-rounded developer. Calling it C trivia is baffling to me.
>Life is too short to become an expert on C's dark corners, and I'm not even talking about C++'s.
Agreed !
That's some of the point of the article, but some of it is also about memorized factoids. There is a lot of focus on what different versions of the C standard say about different things, which is just factoids. There is a lot of focus on how different declaration syntax behaves (statics, linker visible, etc.), which is just factoids.
Also the difference in syntax and translation unit/linker behavior is not a random fact. Its the culmination of the thought process that goes into designing the language and also knowing a bit of the theory behind classical compilers/linkers.
"So, that's what you think your code will do... what does the standard say?"
or, "Why did you use int there when the API spec defines the parameter as taking size_t?"
or, "You think that code in your inner loop will compile to one machine instruction. Have you actually looked at the compiler's output?"
and the looks/responses that I got. There seem to be very few programmers who understand the language & their compilers deeply enough, or even care to learn. These programmers are far more productive because they're not constantly guessing or assuming how their code might work.If I see
static int i;
in code, I'm going to change it to static int i = 0;
even if I know that static integers are initialized to 0 in the standard, because I know that eventually someone will have to maintain the code who doesn't know that. I don't particularly care what the standard says there: the code shouldn't assume detailed understanding of the standard, which isn't realistically a valid assumption.Don't get cute and always prefer to explicitly state in code what you get for free implicitly. The maintenance guy that follows behind you will be the one to espouse how clever you actually are. That's how I mentor junior engineers as a general rule.
A person who just knows it's "bad code"--but not why--is almost certainly going to leave other bad code from lack of understanding. To pull an example from the slides, the virtual destructor: making that class virtual when it shouldn't is a waste of CPU cycles _and_ bad documentation for future developers.
C and C++ can make someone loose days to track down issues, in this day and age, where teams are distributed with lots of offshoring and various skill levels across development sites.
My last C++ project was in 2006, since then I have only used C++ outside work. At work our focus has been in JVM and .NET languages.
I don't miss playing the C++ fireman expert role that has to fix a stability problem created by someone in the other side of the planet.
Nonobligatory image to support statement: http://codinghorror.typepad.com/.a/6a0120a85dcdae970b0128776...
Sometimes I think that having deep and expert understanding of a language may cause you to create code that other team members cannot understand... not on purpose, but due to your assumption that these are common knowledge (whether they should be or not isn't the issue.)