Ask HN: Confused semi-newbie programmer needs some advice.
Last spring I completed my first year of study in Computer Science, at a relatively large American university. I took two courses in CS: Intro To Programming, and Data Structures. Both of these classes taught exclusively C++.
Besides a little Python (that I've completely forgotten), that is my background in programming.
Initially, I was satisfied with the courses I took. I'm taking a year off to travel (currently, I'm living in Japan), and I've been doing a bit of thinking. I've begun to realize, that while my professors preached that they were trying to teach me the underlying algorithms and not the language, I really only was taught how to do stuff in C/C++. I recently have been playing with SBCL, and I realized that I had no idea what I'm doing. I feel like most of the concepts they taught me depend completely on the way C++ works.
I've decided to correct this. I won't be back at the university for another 10 months, and during that time I want to learn a new language.
I've seen discussions about Scheme, Clojure, CL, C, C++, Java, Haskell, Erlang and so many more.
In your opinions, what should I learn, and how should I learn it? I don't really care about usefulness in the workplace, I just want to see what I know, and I want to learn more.
Anyway, I'm just feeling a little discouraged. I hate feeling like I'm wasting my time at a university to a tune of $20,000 a year. I'm sure I've learned valuable stuff, but it all feels very one-sided.
I really appreciate any advice. I've been really impressed with the entire community here, and I dislike feeling as though I have nothing to offer back.
56 comments
[ 3.1 ms ] story [ 118 ms ] threadGood refresher: http://www.diveintopython.org/
Now, in C, working with lists requires knowing a bit about how pointers work. If you worked in a different language and used the language's libraries, you might literally never think about how the list is internally represented ever again, and concentrate solely on the API for it.
The biggest suggestion I have for supplementing (not replacing) your expensive CS education is building stuff concurrently with learning stuff, and I don't mean the little toy 100 line projects they assign you for school. Unfortunately, with where you are in the world right now, building stuff is hard. However, if you teach yourself HTML and get ONE dynamic language half-way under your belt, you'll be able to do web programming, which greatly simplifies displaying output to the user. Then all you have to do is do string processing, and blam, you have something FUN to show to the user.
You'd be amazed how far you can get on just combining those simple building blocks. As you grow in expertise, you can go a LOT farther, but for now, learning how to take input from the user, do some crunching, and show them a web page gives you many, many options for doing fun things.
Should I go with simple Javascript, or something more? I only did HTML/CSS, nothing at all with dynamic webpages.
You will probably get involved with many languages in the future.
Every language has its purpose.
Here's a bit of my personal experience. almost two years ago I took my first formal programming courses. It started out with Algorithms (DFD, etc.) and Operating Systems. Then we moved on to C++. At first, I felt just like you: aside from the basic programming principles and logic I learned in Algorithms, all I knew was how to do stuff in C++. I took up Ruby (mainly due to Rails, but it helped me discover a wonderful language).
The curriculum progressed: Java, Delphi, SQL, Visual Basic, .NET, PHP, HTML&CSS, (which I already knew), etc.
You'd be surprised at how much these concepts come back and help out. Basically, what you learn in the first couple of classes is not "how to do stuff in language x", rather how to think and develop an effective algorithm, which can be applied to any programming language. Right now, you know how to do stuff in C++. When you learn another language, you'll just have to learn the syntax and some other quirks, and you'll pick it up quickly.
For example, in my class we took up a good level of Pascal and Delphi in 2-3 months of class, which is not too shabby.
This is a great place to start: http://gigamonkeys.com/book/
Thanks for the input. I wouldn't mind continuing with CL. Many people I've talked to said they find it incredibly useful for small projects that they need to throw together in a short time.
http://common-lisp.net/project/slime/
If you want an absolute mind blowing trip, grab a copy of scheme or a lisp variant such as Clojure [hip at the moment].. and work through SICP - 'Structure and Interpretation of Computer Programs' the classic course by abelson and sussman of MIT.
You can download the lecture videos and the full course is online. Seeing how they introduced lisp programs to calculate derivatives and do symbolic algebra was awe inspiring.
Language does matter : Python Ruby Haskell.. all respectable, but Id go to the source for some subtleties you'd enjoy - lisp is probably the foundation of all computer languages in some mathematical sense.
Text: http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-4.html#...
Videos: http://groups.csail.mit.edu/mac/classes/6.001/abelson-sussma...
I'd recommend at least the first video lecture and see if you like it.
If you have 10 months before you got back to university, I suggest, you work with one language and build something substantial in that time. It doesn't matter which language you select (and this is where my advice differs from those of people who recommend lisp/Haskell and so on, you could choose C or C++ or Java, it doesn't matter).
The key is to make something substantial, but which also has a lot of intermediate stopping points (a ray tracer/renderer is a good example, it gives you visual feedback of your progress) and work on it every day. Writing a large program is substantially different experience from working through toy examples and you will learn a lot, irrespective of the language you use.
Of course you could still use lisp or haskell or smalltalk (EDIT: if you are already somewhat familiar with them, learning a new language and building something large is tricky) if you so choose, but it doesn't matter really.
Just build something ambitious.
My 2 cents. Good Luck.
I'm a very impatient person, all the side-projects I've made have had very tight feedback loops, where you quickly get results and can change them and see your project grow. My first language on the side was PERL, which is a very unstructured get-stuff-done-fast kind of language which suited me perfectly at that time and was fun to learn, for me.
Horses for courses, etc.
I never really implied "language you don't know". My advice was "use a language you know and build something ambitious" (vs trying to find the ultimate "cool" language). I'll edit.
"Building something and learning from your mistakes is indeed the best way to learn,"
This is what I was trying to say, (with "something" != tiny programs). I know many people who "know" many languages(and try to know more) but haven't built anything substantial with any of them.
So good advice in principle, but probably too early IMHO. I have recently completed SICP (after having 15y of experience and knowing multiple PLs) and it is still one of the best introductory textbooks I can think of, if only for the breadth they cover using their examples. In addition to learning functional programming concepts, how an interpreter works and last but not least building a compiler is more than anybody can expect to learn in 10 months time, too.
PS: One does not need to be a beginner to appreciate SICP. Actually, having a lot of programming experience enables you to work through SICP in a breeze...
EDIT: After reading through the comments, probably it would be a good idea to skim through "Simply Scheme" by Brian Harvey and Matthew Wright. Many people think its the "predecessor" of SICP and probably would be a good complement for you:
http://www.eecs.berkeley.edu/~bh/ss-toc2.html
If you are choosing SICP, be sure to check the video lectures from MIT!
So when we later got to C, the new things were the syntax and the imperative model, but most students had learned enough about algorithms to know what they wanted to do, which made it a lot easier to learn.
After that we also tried out Prolog, which belongs to yet another paradigm, so over the first year we tried a variety of languages that got you thinking very differently about programming than if you'd only do an imperative language.
Later on in the program we had some courses that went down closer to hardware, we did assembly language, and we even wired our own processor, did the microcode for it, and wrote a small assembly program for the "computer" we made.
Over the course of the entire program we never dug deep into one specific language or paradigm, but we went across the entire field of computer science, and that turned out to be an excellent foundation. In my experience, the people I know that are really good programmers have all done this, either through university, or by self-study. It requires a lot of passion for programming to do it by yourself though, but it's an alternative to finding a diverse CS program that focuses on breadth instead of depth.
First off, absolutely get a copy of _Structure and Interpretation of Computer Programs_ (SICP: http://mitpress.mit.edu/sicp/) - this is one of the best books on programming I've ever seen, and while it uses a subset of Scheme, it's really more about major concepts in CS. It's excellent. Do the exercises. It will take a while, but do the exercises.
For C, get _The ANSI C Programming Language_ by Kernighan and Ritchie ("K&R"). Harbison's _C: A Reference Manual_ is a good reference.
If you do real work in C, you might find Lua helpful - it's a C library that provides a drop-in scripting language for C projects. It's a also nice language in its own right, simple but very expressive, and stylistically somewhere between Python and Javascript. (_Programming in Lua_ by Ierusalimschy is the only book you need, though having a printed copy of the reference manual wouldn't hurt.)
Prolog is a fun language. You'll probably need to stick with it a while before it switches from being weird and novel to actually useful, though, and be prepared to be a little disappointed upfront - some of the early AI hype oversold it. It's actually pretty lousy as a theorem prover, but it has a unique programming model that is very powerful for some problems. (It will also help if you want to learn Erlang later.)
For Prolog, I like _The Art of Prolog_ by Sterling and Shapiro. It's on logic & declarative programming as a paradigm, and how well Prolog lives up to it. It's deep, and uses Prolog to teach about programming in general, much like SICP does with Scheme. Highly recommended, whether or not you use Prolog in the long run. (The newest edition is kind of expensive, but you could get by with the first edition. They fleshed out the latter 'project' chapters a lot in the second, though.)
As a reference, _Programming in Prolog_ by Clocksin & Mellish is good. I also liked _Clause & Effect_ by Clocksin; it's sort of like _The Little Schemer_, but for Prolog. _The Craft of Prolog_ by O'Keefe is great, once you're comfortable with the ideas in _The Art of Prolog_.
The thing that made data structures really make sense to me was learning OCaml. (_Developing Applications with Objective Caml_ is free online: http://caml.inria.fr/pub/docs/oreilly-book/) Having a garbage collector helps, and the ML family has powerful tools built-in for working with types and data structures. Doing the exercises for the first three or four chapters of that book is enough, if you're only going to use it to study data structures. (It's a great language, too, though.)
Edit: Added Lua subsection to C.
I don't necessarily believe you should keep chugging away at C/C++ until the language kind of disappears and you're left staring at the concept, but if you jump from language to language hoping one will open up things for you, I think you're walking the wrong path. My suggestion is that unless you fully intend to truly learn another language, you should stick with C/C++ and just progress with it. Once you are really comfortable with it, move on to something else. Trust me, once you do have that first language under your belt, the others come a lot more easily.
If you really do want to switch to a different language, I would suggest Python. I learned Python the summer between my Freshman and Sophomore years, and I felt that the language gets out of your way a lot more than Java (the only language I really knew before then). I think Lisp or Haskell might be a bit too much of a stretch from your C/C++ background. I've heard programmers that have been programming for years stumble over Lisp. It's a different way of thinking, and if you're just trying to broaden your horizons, you should be able to do that without learning a different way to think.
I'd also fallow the advice of some of the other people on here and actually build something. I've had a lot of fun doing web development with Ruby on Rails. Ruby's a great language as well, but I found it a little harder to parse coming from a C++-like language than Python. I've heard great things about Django, so maybe you could try building a web app in it?
About your other point, with sticking to C/C++ until the language disappears, I think I'm just afraid I'll get stuck in that paradigm, and if I don't broaden my horizons now, I'll have a hard time later on. You may have a point though. I'll think about it.
Thanks for the advice.
Python: this will teach you to program at a higher level, and the libraries will make it easier for you to get into web programming or GUI programming or simple game programming or any other thing that excites you. That's what it's all about, when you're learning: do something that excites you, and you'll learn faster. Python has a very low barrier to entry, so try this first.
Lisp: once you know Python, you're not going to be bowled over by things like garbage collection. But you can still learn a lot from Lisp; if nothing else, it can give valuable practice with recursion and metaprogramming and the idea of a read-eval-print loop. It's a cool and fun language.
Haskell: this one is kind of difficult to learn, which is why I recommend learning it after you've got Lisp under your belt. A lot of advanced computer science stuff tends to debut in the Haskell community, and the average intelligence of Haskellers is pretty shocking. It's also a neat language that you can do cool projects with.
If you can learn these languages, I guarantee that you will be able to shift paradigms a lot easier than people who coasted along with the standard trio of C, C++, and Java.
I definitely think it's a good idea to learn other languages, but what, exactly, is your goal? Are you trying to understand CS concepts better, or are do you just want to learn another language?
Before entering the course i was skeptical , and until the thirty year i fell like i was wasting time. The point is, when you are at the academic world, it´s not about how get real things done, it´s more about to learn general concepts to build a solid base (in terms of knowledge). With this base, you will be able to learn how to get REAL thinks done much more fast, in a very professional way(read, trustable for the "market").
Therefore, you are not going to CS (or Math, another good option) to get things done, you are going to build a very good "BASE" to get (a lot of) things done.
In a simple way, goes like this: Learning lisp, python, c++ and java, you are investing on "content" for your professional life. Going to CS you are investing in "context". A guy who learns lisp in a garage is very different from a guy who made CS and learn lisp by himself. The second one have much more "base" and a better context to solve problems, although both have the same "content" (the lisp knowledge).
Don´t give up on CS and try to be close from as much people as you can, specially the good guys ... in this way you will be building a very good "context".
Oh, about the programming language ... i think you are starting from the wrong point. First, you should pick up an idea or project to implement (something that you really want to do) and then you go for the language. And yes, the best way to get "content" is working on real projects. Ruby is good for scripting, as python and php are, so if you are going to build something for the web, you should not think about C, C++ and Lisp, just pick a language more close to the web related stuff. But if your idea, or project is about mathematics, desktop and hard calculations, forget about ruby and php and go for C or Lisp. Therefore you start choosing a project (or idea) and then the programming language to learn, not the language and then the idea.
Well, i´m a very noob just like you, and my words are probably full of lies, but that´s my experience in the last five years. Hope you can get something useful from this big (sorry by that) post.
And sorry by my poor english.
Thanks for the advice, and your English is just fine. Obviously not perfect, but more than good enough.
Today, web-enabling almost always is a requirement. People usually want access to their applications with their iphone and in the worst case (the battery just exploded, notebook lost, etc.) from a cybercafé.
Sure, you can web-enable most (business) applications with pure HTML/CSS. But if you take advantage of the power of AJAX (XMLHttpRequest), you can build GUIs with such high performance that it feels (almost) like a regular desktop application and therefore people often don’t even care about installing the available client-application on their office computers. People love it if they don’t have to install anything at all.
I would start with something like that: Imagine you’re abroad and your notebook just fell down the stairs - it’s broken. What would you like to have access to in that situation from a cybercafé. Maybe an address book? Now imagine, that the cybercafé you are into has an awfully slow connection and they charge you a fortune for every single byte that travels their connection. So, your address book should be fast as lightning, means: nothing similar should go over the wire more than once (search box, headers of your address list, pagination elements, etc.). There's nothing that can beat JavaScript in solving this problem.
High level programming languages are froth; once you understand the basic concepts, it's best to work with C and system calls til you're absolutely sure what you are doing. Learn how to use a debugger, disassembler, packet sniffer and every utility you can find for creating mischief.
A few books on actual hacking, you know, the "blackhat" kind, might come handy. Hacking tutorials from the underground scene are masterpieces of juvenile bravado but they're written by people with heart. No one in academia or industry has the same passion for computing, or for that matter skill, as those "vandals".
Get a screw driver and take your machines apart (yes, get more than one machine.) Network them. Break them. Boot obscure OSes on them. Get as many computers with different architectures and instruction sets as you can get.
You don't deserve to be coding in a fancy functional distributed language with rad tools. You need to pay your dues first and get your hands dirty.
Your university probably sucks; your professor, your TA and the A-student in your classes are probably all lousy programmers. Your library there is under-stocked. Any industry representative who comes to give a speech about computing is probably a fraud. And once you graduate, or drop out, and make computing a profession; if you ever have to assemble a team of top-notch programmers to work with, the first names to standout will be strangers who you know by their nicknames from underground computing subculture. The guys you see doing interviews and recording lectures in polo shirts and khakis are laughably incompetent, big enterprise or "startup".
Join the demo scene, the amiga scene, the root-kit scene, the virus scene, the calculator hackers, etc. to see what good programmers look like. Real, honest to goodness hacking without blogging, self-promotion or careerist pan-handling. They do it for the love it, them honest thieves.
I went with OpenBSD and C++ and that has taught me more about bits and bytes than the college degrees ever did.
Ditch these self-pleasuring technology forums too. They are full of people masturbating their own egos, nothing more.
The problem is that I think it's completely the wrong thing to do. One of the major effects of programming in a language extensively is that you start to "think" in that language whenever you have a new problem. This is both good and bad, of course, because while it helps you become proficient in the language, it also prevents you from seeing possibly simpler solutions (i.e., that aren't easier in your language).
Also, languages don't arise in a vacuum -- they're designed in a certain time period, with various assumptions about environment and hardware baked right in. This can be extremely dangerous because as a user of the language, you will start to think in terms of those limitations as well, even if they no longer apply! So for example, C is one of these languages I'd strongly NOT recommend, unless you're working in a domain where it's necessary/preferred (low-level networking, some embedded devices, etc). C assumes you live in a time when computers are quite slow and have little memory (both of which must be very carefully monitored), there's only 1 processing core (so you can just do sequential programming), and programmer time is less valuable than execution time (so you can spend days optimizing the hell out of small routines). But the times have changed -- computers are fast, they all have multiple processors, there's a lot of RAM, etc. Most people want to be building more complex things, and for 95% of applications, I'd wager that C is exactly the wrong language to be "thinking" in.
Starting with a more "modern" language (which includes the LISPs, despite them being older) lets you avoid these preconceptions.
Also, there seems to be a lot of penance involved in the parent's advice -- "you need to pay your dues first and get your hands dirty." Fuck that shit.
Sure, if your end goal to is to really learn this low-level stuff, then go for it. But if your interests lie elsewhere, do that instead by jumping right into that domain. Maybe you want to build large distributed systems, or come up with new visualization tools, or build a logic system. C seems like a remarkably bad choice for these and so many other projects. In fact, it seems like a bad choice to even learn C first, precisely because your notions of what's possible, of the "right" way of approaching problems will become infected with the C mindset.
Most importantly, motivation is a key resource you must not squander. For many people, fixing broken computers, struggling with a difficult operating system, or looking at assembly and network packets is grueling work with no payoff. I'd be willing to bet that for such people (many of whom could be great hackers in other domains), the parent's advice is sure to sap your morale and turn you off from programming.
Finally, time is not an infinite resource either. Why waste your life on things that don't interest you and won't help you much in the long-term? Work on things that excite you, and you'll not only be so much happier, but you'll also learn much more in the long run.
P.S. I know several "real hackers"/"good programmers" and while some of them might fit the parent's description of such, many of them also fit the parent's description of the poseurs -- the A-student in my class back in college, the guy recording lectures in polo shirts and khakis, the family man with a wife and kids and a mortgage. Stereotyping is still stereotyping when applied in the opposite direction.
I don't even think learning stuff just for the sake of learning it even works. You always need some reason to learn stuff to really need it. For example, you can't learn photoshop by reading a book about photoshop. You have to try to accomplish something.
So set yourself a real goal, "I want to become a good programmer" doesn't count, something you want to build. Perhaps try to write a MMORPG - everybody will tell you that you will fail, but who knows.
I think it is very stupid to assume that after one year of learning C you can not yet program good enough to do anything. Set yourself a goal, then try to figure out how to achieve it. In fact, in my opinion, the job of a software developer is not to be good at some kind of programming language and then routinely solve problems with that skill. The job is to constantly learn new skills and to adapt to new requirements. Therefore the attitude "I am not good enough" is the exact opposite attitude of the attitude a programmer should have.
Disclaimer: I never got into C Systems programming myself. Probably I suck as a programmer - so what. We all do.
Edit2: Flicking through "Programming Clojure" only requires an afternoon, "Progamming Erlang" could be read in a weekend. Why don't you (the original poster) consider what you want to do, then evaluate a few possible paths (different languages, frameworks), pick one and get coding? Choosing a language just because of popular vote seems rather risky.
Edit3: Your MMOPRG's code will probably shit. User's will never know and won't care, though. Your second MMORPG's code will be shit in a very different way. And so on...
The parent post nails it: Find something you want to build and then build it.
I'd add that once you build it you'll probably learn enough to want to rebuild it without all the mistakes... and once you do you'll probably want to rebuild it a third time.
It's supposed to be fun. Work on something you love so much that you work on it until your hands need a break from the keyboard.
The rounded programmer understands both computation and computers. C or an assembly language is a great way to learn how the computer works, but working at such a low level makes it harder to see the structure of the procedures you write and the processes they generate. Personally, I think it's more fun and rewarding to learn about computation first, then take a look under the hood. Others may disagree. Either way, you should learn both eventually.
For learning about computation, there are few better resources than The Structure and Interpretation of Computer Programs, MIT's introductory computer science text for over 20 years. It, and supporting course materials are available online free of charge, and there's a print version for traditionalists.
You are not in a CS curriculum to learn C++,Java,Scheme,etc.
Thanks.
Good luck.
Oh, and the stuff Mahmud said about your professors and industry types being phonies is largely true. Not always, of course, but often enough. That you're even on this site suggests that you're prepared to think deeper than them.
How did they get created or conceptualized in the first place? Why do we need them?
Do it the right way: Start with C, and start from the smallest and most fundamental constructs that C has: The structures and functions. Know that there was only assembler in the first place. Then look into how function calls are made. Disassemble the simplest function you have and understand its logic. Now you know why there is a function. Then go into the structure. Disassemble one. Put different types in it, see how they get laid out in memory.
Start as above, and learn how things work down to the last byte. Then eventually you will cover all constructs created and you will know where they come from. Do the above for 3-5 years, each time you encounter a new language idiom or concept.
Finally you will see that in all strongly typed languages most constructs are worthless and they get in your way. You will get back to using C ;-)
You might also go for the much higher level languages or different areas of computing, but since you showed interest in understanding programming deeper, this is the way to go.
The perks: functional and object oriented compact syntax lift is an excellent web framework appears to guide design towards application or library perspectives Dave Pollack feels that his perception of programs and functions has changed to state modifications and data transformations. I don't quite see it but I'm a noob.
But it is still a good idea to learn a new language just to get a new perspective. I would recommend that you learn a highlevel functional programming one, like Lisp, Scheme or Haskel. This will really give you a different perspective from C/C++ and teach you to think about programming in a completely different way.
I strongly recommend you check out this Haskel tutorial (which I found on HN myself):
http://learnyouahaskell.com/