How to learn how to program well
FWIW, my language of choice right now is Python, which is what our startup is written in. What little I know and understand about functional programming and recursion, I enjoy, but I feel like I still don't have a very strong grasp on algorithms, performance, and what makes for truly beautiful code.
I own PG's ANSI Common Lisp and have considered studying it as part of the answer to this question.
To complicate this, a little background: I've been offered two jobs: Job A means I can code in any language I want on a really cool skunkworks project--but I would have to be entirely self-taught; Job B means I would have to code in C#.NET, but I would be surrounded by some serious nerds (OS and graphics types) that would in theory be willing to mentor me.
What would you choose, assuming compensation was the same?
I graduated with a CS major, and many of my classmates who graduated with the same did not have a very strong grasp on "algorithms, performance, or what makes beautiful code". Don't let the lack of a formal CS education distress you. The students who know the most are the ones who are off doing their own projects and working with each other to create things, those who charge through the curriculum learn a lot, but don't internalize the knowledge, and thus retain little of it.
Job B if you want to encourage your technique.
To improve my programming I generally do things that I can't figure out how to do in my head.
Personally, I find myself in similar dilemma. I studied CS, and the whole time my goal in life was to be a programmer and work with computers. Then you get into the industry and you realise you have achieved your goal, and find you need new goals. You realise the IT world is so huge and there so much to do out there. There is much more to IT than programming.
Theres probably no right answer. I would reassess my goals. Where do you want to be in 10 years. 15 years? Imagine the path to this goal, and I'm sure the right choice will present itself. It may be neither of those options. In fact, I wouldn't limit myself to only 2.
Do you want to be a programmer all your life? (sounds pretty boring to me). This is an important question to ask yourself. What is going to be the best step to where you want to be later on?
I think the ideal situation would be having something like Job B for a while until you feel like you're a solidly professional duder, and then move on to something more risky and adventurous. I wasted vast amounts of time trying to teach myself to program as a teenager because I didn't know where to go to. Having some structure and guidance could help you.
The internet makes self learning easier, but then again, mostly all you'd learn from job A you could learn from hobby projects anyway. Face to face interaction with other programmers is harder to substitute.
Just in case you haven't read this already:
http://www.norvig.com/21-days.html
[Sorry, meant to post this as a top level reply.]
That article included a link to the video lectures of the Structure and Interpretation of Computer Programs by A&S themselves, given to HP employees back in the 80's:
http://www.archive.org/details/mit_ocw_sicp
http://mitpress.mit.edu/sicp/full-text/book/book.html