HN user

zedshaw

8,999 karma

http://zedshaw.com/

Posts0
Comments1,024
View on HN
No posts found.

Someone linked me here asking me how I can write good quality code so fast so I thought I would come and drop a comment just in case other people read this and fall prey to the "HN must be true" virus.

I have no idea if I write code better or faster than other people. Maybe I do, but I always think that I don't write very good code most of the time so I have to be extra careful. I spent a lot of time writing code very slowly and being extra careful so that I could make sure it's good quality. I guess after focusing on quality for so long I just got faster at it compared to others. But, I'm going to guess that I actually am not much faster than other people.

LOL. An account with these as the only comments and no submissions? Man this place is so weird. It's like you're at a party, and then some guy can scream at you from across the room while wearing a Richard Nixon mask and everyone goes "Oh yeah that is true." Never questioning why the guy is wearing a mask at a party.

Anyway, I think you need to look up the words "tirade" and "incomprehensible"

How to See Color and Paint It -- It taught me how to see color and paint it. Also how to use a palette knife which makes my paintings very different and fun.

Remembrance of Things Past -- I'm still reading this, as it's a massive stream of consciousness book, but I wish I'd started it when I was younger so that I'd be done with it by now. It's just so weird to read it and experience the writing that I enjoy it for simply being different. As you read it just remember that every ; is really a . and every . is really \n\n.

Van Gogh: The Life -- I absolutely hate the authors. They're great at research, but I feel they had a vendetta against Van Gogh of some kind. Throughout the book, at times when Van Gogh should be praised for an invention, they make him seem like a clueless dork. Ironically, their attempt to portray him as a dork who deserves his treatment ends up demonstrating more concretely how terrible his life was because he was different. I think if this book were around when I was younger I might have become an artist instead of a programmer.

A Confederacy of Dunces -- Absolutely brilliant book, and probably one of the greatest examples of comedic writing there is. It's also nearly impossible to explain to people except to say it's the greatest example of "and then hilarity ensues".

Mickey Baker's Complete Course in Jazz Guitar -- After a terrible guitar teacher damaged my left thumb I thought I'd never play guitar again. I found this book and was able to use it to learn to retrain how my left hand works and finally get back to playing. Mickey Baker's album also brought me to the Bass VI, which got me thinking I could build one, and then I did and now I've built 6 guitars. I play really weird because of this book and I love it. This book also inspired how I wrote my own books teaching programming and without it I'd still be a cube drone writing Python code for assholes. If I'd found this book when I was younger it most likely would have changed my life then too.

Reflections on A Pond -- It's just a book of this guy painting the same scene 365 times, one for each "day of the year" even though it took him many years to do it. All tiny little 6x8 impressions of the same scene. I learned so much about how little paint you need to do so much, and it's also impressive he was able to do it. I can't really think about anything I've done repetitively for every day of a year. I've attempted the same idea with self-portraits but the best I could do was about 3 month's worth before I went insane and started hating my own face.

Alla Prima: Everything I Know About Painting -- Instructionally this book isn't as good as How To See Color, but as a reference guide it is about the most thorough book on painting there is. It's so huge it's almost impossible to absorb all of it in one reading, so I've read it maybe 5 times over the years.

The man who moved my book into the "avoided" category admitted to me in an email that he did it just because of my K&R critique, not because of the book's quality, is not a C programmer, hasn't coded C professionally ever, and works doing PHP with almost no C experience.

For reverse engineering? You should use every single thing you can get your hands on that helps you learn. The K and R are the two people who wrote C. Of course you should read their if you want to learn C. Then read, and WRITE the code in, everything else you can get your hands on to learn a programming language. It may only take one book, it may take 10, but that's how you do it.

Then after that go learn Assembler, or even better, implement a compiler. You'd probably learn a ton of the things you need to know for reverse engineering code from just making one simple compiler.

That's a rather slanderous thing to say, and I honestly wish programmers would quit this fear mongering of others in the profession. I do it too, but lately I've been saying that we need to stop it.

You've never met me in person, so read some of the comments from people who have. By saying that I should never work with people you are effectively attempting to prevent me from having a job. That's an incredibly abusive thing to do to someone else, and it's just an odd thing to do in a professional setting.

Based on this, I wonder how you are to work with? Are you the kind of person who goes around getting people fired? Are you to be trusted in your opinion of others if it's so easily swayed by public opinion? Are you potentially racist or at least blindly biased?

See how that works? It's possible to take anyone's words and, with a bit of grammar jujitsu, use it to destroy someone else. I've recently tried to stop saying people shouldn't work with someone or that I won't work with others, and I have been meaning to write about it. Hopefully my comment will make you feel the same way.

This book is for people who don't know any programming. So let's catalog your claims in that light:

1. "no use of context managers when working with files" - I teach files early on, before they even know how to make a block. After my book they can easily learn this.

2. "no use of format when working with text formatting and output" - Which format? At the time I was writing this there were what seemed like 10 changes to it and how it worked. The % format syntax works all the time, and it's something found everywhere. Learning it is useful, and doesn't prevent them from using format later.

3. "Avoid any project that mentions "Python 3"" - They should, Python 3 is not ready and is simply frustrating. Python 2 is on all of their computers already for many people, so that's the better one for a beginner. Also after learning 2, they can learn 3 if they need, but if they learn 3, they have to learn 2.

3. "Every if-statement must have an else" - This is for training their ability to think of the entire set of possible boolean results in an if-statement. It's also the cause of many logic bugs and you should consider it as a good way to check your own logic constructs.

4. "no list|dict|generator|set comprehensions." - The book is for beginners who can't even figure out how to run a python script on their own. You think they'll get comprehensions? That's insane. Later they can easily learn this, and I think a theme in your comments is that you think once someone reads one book they are done learning, which is a bizarre idea.

5. "no idiomatic hints" - Which idiom would that be? The early Python that's like JavaWithCamelCase or the new Python that's like c_with_underscores? The problem with Python idioms is they warp fairly regularly depending on what's in vogue at the time, so I just teach the simplest thing that seems to be common among all of them. And again, they will whatever "idiom" you think is important later when someone like you who thinks they're important yells at them about it. Brains are not made of stone.

6. "no gotchas." -- The book has loads of gotchas, AND I have videos that go with it where I show people the gotchas, AND there's additional problems for them to solve at the end of every exercise, AND I encourage them to break their scripts to see how Python gives them errors.

You would do well to ditch the idea that people cannot relearn things. Maybe this is holding you back as well, and it's simply false. Heroin and smoking are "bad habits". Playing a guitar scale wrong is a "bad habit". Whether you use CamelCase or loads_of_underscores is just easily updated information.

I have to serve the student's needs before any in the community, and there's a very practical reason for going with Python2:

The vast majority of code out there is in Py2, so if someone learns Py2 first, they can start coding and doing stuff right now. If they stumble onto a need for Py3 later, then they would have the skill to learn Py3 from the tutorial and other books.

If they learn Py3 first, then immediately they have to learn Py2 because there's simply too much code out there that uses it. This will frustrate beginners as the next thing they need to do after my book is start using Python to make things.

When the situation changes, and not just because the Python leaders say it does, then I'll update the book. Honestly though, I think Go, Rust, Nim, and Clojure have a better chance at widespread adoption than Python3 at this point.

Incidentally, the mistake that the Python3 project made was to not use a virtual machine that could run both 2 and 3 byte code. If I can run tons of languages on my CPU, the JVM, and the .NET CLR, then Python3 could have run both 2 and 3. I predict that to get people on the new version of Python they will have to make Python4 and have it run 2,3 and 4 seamlessly so that it won't matter how much code is out there in any version of the language.

Just my .02 on that topic.

Me too, man that book has been an epic slog. I've ended up rewriting it like 10 times but finally have a draft off to the publisher for editing. I'm still not totally happy with it, but it's the best I could possibly do.

The latest rewrite emphasizes secure coding and defensive programming practices, algorithms, testing, and how to learn a new programming language, and simply uses C in as safe a way as possible to do that. Hopefully it's effective but I still need to sit with students in IRL classes to test that out better.

Yep, this is exactly right, although I'd say it almost totally teaches programming. The book definitely teaches computational thinking and gets people over that hump and into finally learning programming, but I need to work on a follow-up book that has a lot of projects for people to tackle on their own. That's really where they finally learn to code as an independent programmer.

That's a good assessment of the books, and one I put into the introduction. It's weird because what is great for a beginner with zero knowledge is incredibly painful for someone who's experienced. I think that's the key with my book's success and also why a lot of professional programmers seem to completely dislike it. It's also why I'm very honest and upfront about this right in the beginning.

You're welcome. I honestly write the books for people like you, and thankfully the world of programmers and the world of regular people really doesn't intersect much.

You're conflating internet interactions with real interactions.

I don't drink at all. Never done drugs and have never been drunk or anything. When I go to bars with friends I find that as the night goes on people become complete drunken idiots and are impossible to deal with. There's no polite way to tell a guy to stop talking to you about his chia pet collection or to keep someone from puking on your shoes or trying to start a fight. Best solution is to just not go to bars, which is what I do. If I need to fit in for some reason, I usually just pretend I'm kind of drunk like everyone else, which I haven't done since I was in my early 20s.

Twitter, these HN comments, IRC, the whole internet is like a massive bar full of drunk idiots. Especially toward the end of the day. Something about the internet makes people turn off their rational mind and just spew hate, stupidity, propaganda, and lies. In this case, it's the same interactions and I get tired of it. You can't tell a belligerent drunk to politely stop smashing your car any more than you can tell a belligerent twitter user to stop talking to you.

So, your comment amounts to judging my interactions with people professionally based on my interactions a bunch of drunk idiots at a bar. Nobody is a saint, and expecting me or anyone else to take abuse and poor behavior like Jesus before you'll think they're a good person is wrong.

And, the fact that you are actually spending your morning (day/night) telling people how I'm a fucked up asshole because of how I deal with fucked up assholes kind of says more about you than me.

I am contrarian and rude, but you most likely worship quite a few people in tech who are also contrarian and rude but you say nothing. I bet there's a CEO you admire who is even worse than me and you tout his words like they're a gospel.

I personally would love nothing more than to have the industry flush everyone who behaves like that totally out of it, but as long as people like you hold those with no power to different standards than those with power, it'll never change.

No, the relevant fact in RiaG is that DHH had been lying to people for years claiming that "rails scales" when he had to handle 400 restarts a day of his process.

And then I was trying to be funny and shit.

It's interesting that you'd use an anonymous account to sling some slander, but I'll answer you:

Yep, that comment thread is great and people should read it for an explanation as to how completely insecure C is. It made me realize that nobody can teach C safely. Not me, not K&R, nobody. The language is completely unsafe by design. If you think K&R could, you should realize that they fixed the code in the book numerous times to make it more secure during it's 40+ printings.

Based on that, I killed my darlings. I should have never started this book as a "C book". I rewrote about 50% of it to instead focus on the things a mere mortal like me can teach:

  0. How to learn any programming language quickly with some tricks I know.
  1. Secure programming and defensive coding skills, which a broken language like C is perfect for teaching.
  2. Testing and reliability.
  3. Most of the C I've found safe and useful, and how to avoid UB when possible.
  4. Algorithms and how to apply them.
  5. And finally building projects as small challenges to get better at C.
So everyone was right, and I adapted the book to denote that. I also started a project, which hopefully I'll find time to do, that is going to catalog all of the UB in C, write a unit test for each one, and then attempt to assess the security failures of it:

https://github.com/zedshaw/cubfail

I'm currently finishing up a book, but this project interests me because what I've seen is most "professional" C programmers end up pulling out UB whenever they are called out on a secure coding practice they fail at. I think a good catalog of how to cause security failure with C UB would be instructive to everyone.

And then we can all just stop using C. It's terrible.

Now that you have this new information, hopefully you'll update your slander.

It's unsafe in exactly the same way that the unsafe copy() function is

No, that's the logic error every programmer makes. The copy() function is always wrong, because it can't confirm that the string has the right length without looking at the string which causes the error.

With my function I can go to as great a length as I want to confirm that the string is actually as long as I say it is. I can't mitigate every possible error of misuse, but the errors safercopy() can have are much smaller than copy().

Your argument is effectively stating that because you can exploit one with a general "UB" error, that it's the same size and classification of errors as with the other. That's invalid, and proven in my writing.

That'd be up to my publisher (A/W) but I do believe they roll out French versions of my book depending on market demand. How that demand happens I have no idea.

Alright, I did finally get this working. Pretty fucking awesome, I had not thought of that. Here's a version everyone can try:

https://gist.github.com/zedshaw/64b3fb6b7ed653852619

I officially concede that because you can work two pointers on a computer to overwrite another location of memory to alter a for-loop (incidentally, there's not UB listed in ANSI for 'alter the variable of a for-loop') that everyone should go back to writing their C code just as K&R intended.

Please, you all should rely on only the '\0' byte terminator of all strings, don't do any bounds checking, don't check the return code of functions, and you will be totally safe.

Because, UB means "I ain't gotta fix it."

Enjoy, now I'm going painting.

Well this if fun folks, but frankly, you all have proven just how conservative programmers are. My chapter advocating something as "revolutionary" as including the lengths of strings when you process them has received more hate mail than anything I've written. And I'm the guy who gets death threats because I don't like Ruby.

If you are reading this and saying, "This guy's wrong about including the lengths of strings!" Then I ask: Why are you using any modern language? Nearly every language in use today include the lengths of strings and backing buffers in their string implementation, and you all use it and appreciate it, but when I advocate it suddenly it is heresy and deserving of vitriol.

I personally don't care what you all think, which I know insults your pride at being the smartest people in the room, but until you are willing to admit that your hatred of that chapter is based entirely on nostalgia and not on the merits of my fairly simple claim that K&R (or any) C code is error prone, then you are not going to advance the state of the art any further than the 1970s.

This is what makes me sad about computing today. You are all desperately clinging to the notion that you are radical free thinking futurists while you desperately cling to reverence for the past and are incredibly resistant to any change. If something as simple as a thought experiment to look objectively at how things are done and try something better makes you angry, then you are not free thinking futurists.

Anyway, enjoy your day folks. I'm going to go do some painting.

Are we looking at the same code? I use an assert to quickly check for NULL, and this is a simple example of how to work with the function. Other parts of the book use more extensive error checking and I use my debug.h macros quite a lot, but if you find bugs feel free to email me them. I'd really appreciate it.

You actually were an asshole first my friend. You came in with a comment that was rude, not insightful, and seriously uninformed and then announce how you're going to flag it as awful. Everything about what you wrote makes you an asshole, and you started it. There were about a trillion different ways you could have written your comment in a polite yet still direct way to further the discourse along but you chose to be obnoxious.

Don't be butthurt that I'm just better at being an asshole than you are.

Alright my friend, here's the gist:

https://gist.github.com/zedshaw/c20a69f17578909523c4

The rules:

1. You said you can make that for-loop run forever that can call it and it'll enter an infinite loop. 2. To prove that, you can only alter the main function, then hand me back the code and I'll compile it and run it on my machines. 3. It has to run without stopping for 24 hours. If you can do that then I'll consider that an "infinite loop". 4. You can't call any more functions than what's in there already. So no fancy hacks to keep the OS from allowing segfaults by putting in signal handlers, linking against other libraries, or anything.

Very curious how you do this. This is fun!

Edit: And, I may not be checking comments so email me to gloat if you figure it out. help@learncodethehardway.org any time. You can also post it here. Just link me the reply so I can go look.

Ahhh the "undefined behavior" trope, whereby a C "expert" who's memorized a standard trots out the abstract machine to justify his point. An abstract machine that doesn't actually exist and that no computer actually functions as.

I'll take you up on that challenge. I'm curious to see how you'd write a program to make a for-loop never exit. Give me a few minutes...

Curious, did you find a bug I'm not seeing? How do you think an alternative copy function that uses lengths would have buffer overflows?

People are downvoting you, but as the author of this I can say you're right. Not necessarily lisp, but using any language that doesn't have the fatal flaw of totally broken strings is better.

C is still a large historical influence on many languages, and knowing it makes people more capable as programmers. That's why I teach it, and I use it because I'm just old like that. Once someone knows C they can fix all kinds of problems, and then can learn a huge number of languages fairly easily.

But these days, without a solid reason for using it, I'd avoid C and use a better alternative.

I know, that's why I have these:

http://c.learncodethehardway.org/book/ex20.html

But, when talking about this I didn't want to muddy the waters with my own assert alternatives. Programmers have a hard enough time focusing on the issue of a for-loop vs. a while loop.

Edit: malloc returning NULL means you're out of heap. That's usually catastrophic in almost all cases, but the important part is that people don't detect that, then use the NULL pointer. That's the bug.

I don't think you know what it means when someone asks whether a loop will terminate. It's an analysis of the logic of the loop to determine if it will exit. This kind of analysis has been the actual foundation of computer science since there was computer science. I believe this guy Turing was doing some stuff with it.

However, you have a logical flaw in your statement. You say the function will not terminate if it is passed an invalid pointer, but processes terminate when they access invalid pointers. If that's true, then it will terminate. However, if processes do not terminate when passed invalid pointers, then this function will still terminate because it will hit the end of its length variable and terminate.

So you're wrong on many counts.