What do you want to see in Learn C The Hard Way?
I bought the domain to force myself to do something with the free time I'll soon have an abundance of.
I want to see more young programmers doing systems programming and making cool things with the language that forms the basis of almost everything we use.
What do you want to see covered in a 'book' that purports to teach C the hard way? :)
I will be following Zed's example, although I'll be influenced by my learning under K&R. I really do want to be demonstrating proper, modern C.
126 comments
[ 2.4 ms ] story [ 205 ms ] threadHowever, if you wish to try anyway, I recommend looking at "Assembly Language Step-by-Step: Programming with Linux" by Jeff Duntemann. It aims to teach people assembly language as their first language, so you may find it useful.
I'm a professional python dev :)
But it's a bit misleading to call it "Learn C The Hard Way" after LPTHW, if your intended audience is experienced programmers. The whole point of LPTHW was that it was for beginners.
Top of their website: "The book is a very beginner book for people who want to learn to code. If you can already code then the book will probably drive you insane. It's intended for people who have no coding chops to build up their skills before starting a more detailed book."
K&R has sated that need.
It's easier to understand what I'm aiming for when you've already gone through the rigamarole of learning C from the existing texts.
Show the relation between pointers and arrays. Offer some best practices on using pointers. Explain the most common caveats like buffer overflows, problems with null terminated strings or off by one errors.
But, that laptop was ripped off and the particular file appears not to have made it into backups.
Does this description happen to ring a bell? Any references?
or possibly this (pdf warning): http://home.earthlink.net/~momotuk/pointers.pdf
Note that it's also available in an HTML version, at:
http://pweb.netcom.com/~tjensen/ptr/pointers.htm
C doesn't syntactically distinguish rvalues and lvalues, so this level of indirection often goes unnoticed. I strongly suspect this is why learning pointers is often hard: trying to grasp an additional level of indirection before having comprehended the first one is nearly hopeless.
[1] Variables are containers for values. This is isomorphic to a constant pointer to a mutable cell.
Examples provided here: http://news.ycombinator.com/item?id=1705332
I saw Zed mention the same title on his blog once. His idea was to provide something for programmers with experience in other languages and some basic knowledge of C. As I fit in that category, I'd like to see something beyond K&R. Especially some stuff on organizing modern projects written in C, makefiles etc.
I'll consider some "break it and fix it" exercises for diagnosing these kinds of problems though.
I grew up as a programmer reading it too so I appreciate what you're saying.
if there are any buffer overflows, integer overflows, off-by-one's, signedness issues, failure to check return values of everything, use of typically insecure things like sprintf instead of snprintf, all of these problems will just carry over into your readers' code. please do us all a favor and stress the importance of writing secure code from the ground up and not as an afterthought or something only done just before releasing it.
I can reinforce each lesson/problem you're describing one by one through the exercises, but a new person simply wouldn't know good code if it slapped them in the face.
Confer with Learn Python the Hard Way to get a feel for the aesthetic and technique I'm working towards.
I don't want to write bulletproof code, I want to teach them how and why to write bulletproof code.
I'm not qualified to meet that kind of lofty standard anyway.
I can reinforce each lesson/problem you're describing one by one through the exercises, but a new person simply wouldn't know good code if it slapped them in the face.
that is my point: your readers might not understand everything you're doing, so they're just going to copy and paste parts of it into their new projects. if you give them sloppy code to learn from, they're going to copy that sloppiness into their code that makes its way into the real world.
there are a lot of things in c that new programmers have to be especially careful about that aren't relevant to python.
Retracted.
This confuses me. How can you teach someone to do something if you won't do it yourself? Reading your statement literally, you are effectively going to say, "This is how and why to write bulletproof code, but I'm not going to." The whole point of LxTHW is to learn by doing. If you're doing it wrong, they're learning it wrong.
> I'm not qualified to meet that kind of lofty standard anyway.
Then you shouldn't write the book. Honestly. I know you intend to do some good and to be productive, but serving as a teacher and a reference point in an area that you're not qualified in is actually counterproductive.
I'm not saying don't write the book. Get qualified first.
Further, the aim is to teach people how and why to write bulletproof code, not to demonstrate bulletproof CString tutorials.
No such thing as a perfect program, startup, relationship, or book.
Not being perfect is not the same as going in the wrong direction.
It would be nice to provide links to articles and books on why one should use snprintf instead of sprintf or what is integer overflow and how do you deal with it and other topics for writing secure code.
However, as a beginner, it will simply not register since I'm more worried about having used a period instead of an arrow to access a struct member.
Perhaps, instead of writing a beginner C book, an advanced C book is needed more.
Might as well put Lance Armstrong on a bicycle in front of a 5 year old and expect them to learn how to ride a bicycle by watching Lance go in a circle.
I've always felt that teaching 'don't do that, cause it's bad' sticks rather poorly - unless something that obviously dangerous is involved, making your own mistakes is much more educational than memorizing a set of best practices and never even peeking into those blind alleys or pitfalls. You can do that and have good habits, but you'll have a dogmatic rather than a fundamental grasp of the knowledge, and this will constrict further development.
My approach is going to be relatively unflavored by the Macro Hell of other projects. I'd rather not instill those habits. They can learn that on their own time.
I want the learner prepared to write clean sysprog code. That's it, the rest they can learn having been taught proper C and make their own stylistic decisions.
If you're going to cover macros, please make sure to explain how they work and the multitude of pitfalls as well as how to deal with them; which is to wrap each macro in parenthesis.
Best not to go there beyond explaining how and why not to, and leave it at that.
Order of operations is an example of something that bites people with macros. (ref/deref + macro has nailed a lot of professionals I know)
In the context of writing a driver, you will have to cover concurrency, multi-threading, semaphores/mutexes, function pointers (callbacks), memory management, etc.
One personal side note, would be nice if you integrate TTD into the projects. The number of C developers that I deal with who do not understand the concept of a unit test is amazing.
Also, please cover C99 and talk a little about compilers, linkers and assemblers. You can concentrate only on one binary format (doesn't matter which one) as long as you explain a little bit about how your C code gets converted into machine format and what does that mean.
I would ask myself: "What makes my book on C different from all the other ones?"
Why should I spend my time on reading your book instead of any number of other tutorials or K&R?
EDIT:
Forgot to add, please provide a public repository for your code examples and start using something like Git right away. That's one thing I really enjoy from all the Rails books, they push you into using an RCS immediately.
There might be a project. I'm modeling it after Zed's approach to some degree regardless.
>(I am assuming kernel and driver development)
Not particularly.
>turn it into a simple project or write a character driver
Nah.
>People will learn how to write code for the Linux Kernel
That is in fact, the opposite of what I'm trying to do.
I want to teach C, not Linux.
>would be nice if you integrate TTD into the projects
I'll demonstrate how/why, it won't be an integral part of it. TTD is use-case specific, not a universal benefit.
>The number of C developers that I deal with who do not understand the concept of a unit test is amazing.
That's a cultural problem, not a pedagogical one.
>Also, please cover C99 and talk a little about compilers, linkers and assemblers.
I'm going to aim for implementation agnostic insofar as it's possible while keeping them aware of the caveats.
What you're advocating is a significant departure from Zed's example. Not my goal.
>explain a little bit about how your C code gets converted into machine format
Implementation specific, outside scope.
>"What makes my book on C different from all the other ones?"
Out of scope of what I'm worrying about, it's a book, not a startup.
>Why should I spend my time on reading your book instead of any number of other tutorials or K&R?
Pretty sure you're not the crowd I'm aiming for, but I'll be happy if you can glean value from it.
Most C books are provincial or overly prosaic. I'm not interested in explaining, I'm interested in whipping people into coders. They can get their compiler and language implementation from a Comp Sci program.
It'd also dilute the focus of the book.
I'll encourage reusing existing code/libraries.
Other than that, pretty much the same style as I did LPTHW.
Also, read:
http://sheddingbikes.com/posts/1288945508.html
There's more advice there.
Teach how to implement a couple of non-trivial algorithms (e.g., quicksort, topological sort).
Planned on it.
Learn Haskell the Hard Way
Learn Erlang the Hard Way
Learn Common Lisp the Hard Way
Learn R the Hard Way
Besides a "Learn X the Hard Way", I would actually like to see more people try to recreate the style of "The Little Scheme", which uses the socratic method to teach the learner. I think the socratic method requires the user to rack their brain a bit more, but results in much greater enjoyment and retention.
I would much prefer to see these two:
"The Little Haskeller"
"The Little Erlanger"
For example, it would be brilliant if someone can explain monads and list comprehension with the same eloquence as The Little Schemer explains currying and YCombinator.
I'd like to see the little Erlanger too actually.
http://prof.beuth-hochschule.de/fileadmin/user/scheffler/Leh...
However, none of the Little ___er books are, of themselves, good ways to learn to use the language they are in; they're more like finger exercises when learning piano -- they reinforce your mental muscles to make thinking in the right way for those languages feel more natural.
However, where "The Little _____er" books excel and overcome all other teaching formats I've seen is in introducing complex paradigm-shifting concepts in a way that is digestable in tiny chunks.
Concepts such as monads, zippers and list comprehension are exactly the the type of concepts that are very difficult to teach/explain using common teaching approaches that "tell, but do not show"
The socratic method used in "The Little Schemer" makes sure to dismantle these extremely abstract concepts into atoms '(pun intended). You really need to understand each atomic piece before you move on.
In most explanations of monads the teacher rattles off a long run-on sentence that touches on several facets of a concept such as monads, making it all that much harder to digest. In fact, most sentences/paragraphs attempting to explaining monads just cause the learner to choke on the terseness and density of information being communicated in one utterance.
The way I see it, both types of books are very valuable. The Little Schemer teaches recursion as a concept better than any other text I've seen. I've never seen anything else that come close. In fact, most texts that touch on recursion quickly move into comparing it to iteration both in form and performance. SICP is an example of a teaching resource that does this. If I remember correctly, the first time you really see recursion in SICP is when the book discusses Ackermann's function and the pros and cons of recursion versus iteration.
I just had a look on simtel but I couldn't find them. Maybe you should put some effort into scanning old software archives and seeing if you can unearth them. C is pretty old - you wouldn't be the first one that had this idea.
I just wish to learn the current state of the art - what are best practices that have evolved since K&R?
* Mostly, arena-based allocators.
Paul Wilson's "Uniprocessor Garbage Collection Techniques" (http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.47.2...) is an excellent overview, as is Jones and Lins's _Garbage Collection: Algorithms for Automatic Dynamic Memory Management_.
Could be intel debugger, could be undefined behavior, could be implementation defined behavior. I tested them on a group of about 15 C devs, mixture of embedded, linux, DSP, and other volken.
Got the same guesses I made and a lot of question marks.
It's easy to run your mouth but not actually contribute, you might consider your role in this process before commenting again.
You need to go get libraries for a lot of the stuff you'd normally use the standard library for in a more modern language. These libraries exist, and many of them are excellent, but because they're not built-in, people are less likely to use them. This is especially dangerous in C, because it requires so much work to do anything even vaguely complex.
edit: That came off as saying "Teach some libraries". What I really mean is "Teach people to go find libraries."