1 min read

18

This is a thread for people who want to learn programming, whether they are non-programmers, beginners, or advanced programmers who want to learn more. If you would like to discuss programming with other people from the LW community, this is the right place.

While programming is not a central topic of this website, it is related to many ideas discussed here. About a third of LW users described their profession as "Computers" in the recent survey. Some users have expressed desire to learn programming. Some users have recommended learning programming to others. There are many other websites (or books, etc.) for learning programming, but talking with the people you already know, following our traditions of rational discourse, could be an advantage.

So this is the experiment. Unlike Open Thread, it has a specific topic, and the beginners are encouraged to ask their programming questions, even if they are completely unrelated to the usual LW topics. Especially the open-ended questions like "how...?" and "why...?". (Maybe we are already strong enough to survive even the mindkilling questions like "which programming language is the best?".)

Here are some older LW articles about programming:

Here are some other resources:

...and there are also many links within the articles.

And here is the place for your questions:

New Comment
64 comments, sorted by Click to highlight new comments since:

A lot of these links are about how to get started coding. I am already a good programmer, maybe a damn good programmer. But I know there's a level above mine, and probably several. How do I get to the next level? What does the next level look like? Are there any resources that talk about how to become a great programmer?

My programming "achievements" were like this:

  • Learning the commands of my first programming language.
  • Learning the concepts of "if-when-else" and "while".
  • Using functions to manage programs with more than dozen lines.
  • Using multiple files to manage programs with more than dozen functions.
  • Realizing the importance of writing good documentation.
  • Cooperating with other people on the same project.
  • Using directories and projects to manage programs with more than dozen files.
  • Realizing the importance of reading the specification.
  • Learning design patterns.
  • Realizing the importance of using the right tools for the job.
  • Learning refactoring.
  • Testing my code.
  • Seeing my code as a web of functionality, instead of a list of text files.
  • Learning a few new programming languages, and using parts of their style in other languages.
  • Designing architecture of a large project.
  • Leading other people in a project. (not completed yet)
  • Keeping focus on Getting Stuff Done. (not completed yet)

Each one of them could be a topic for a separate discussion. Some of them have this zen-like aspect that you first learn about a concept (e.g. object-oriented programming) and you use it everywhere; then at some moment you start to understand where it provides value and where it does not, and then you use it less. Stuff that once felt like the essence of programming gradually becomes just another tool in the box, to be used or replaced when necessary: you don't have to use this specific library, this specific programming language, or this specific programming style.

The "social" skills (cooperating, leading), are not programming per se, but they will force you to use the other skills more carefully, because every mistake will hurt you tenfold.

Things that helped me:

  • Learning about formal languages at university. I would probably never learn it alone, because it seems so abstract. Most self-taught programmers don't learn this. But for a certain kind of problems (text processing: parsing data files, evaluating expressions, interpreting or compiling a language) it gives you the magical skill of looking at the problem and almost instantly seeing that "this problem belongs to this category of problems, and these are the standard tools to solve it; the tools for a different category would fail because so and so".

  • Learning different programming languages. The new languages introduce new concepts, but sometimes they show how the concepts which seemed essential in other languages can be avoided or done differently. -- I don't need line numbers outside of old versions of Basic. I don't have to make data type a part of the variable's name if I use static typing. The data types are not only for the compiler to determine the variable size in bits, but they can describe the meaning of the value. I don't have to use complicated variable names, if the scope of the variable is limited. In Java I use interfaces to describe what the class does, and extend classes to specify how. JavaScript and Lua allow object-oriented programming, and they don't even have classes. A function is just another type of value, and it can be stored in a variable. Functional languages do not even allow changing the value of a variable, and you still can do what you need. You can write a program to generate a program. You can make your own programming language. All Turing-complete languages are equivalent, so at the end what really matters is the convenience of use.

  • Reading the original documentation, as soon as you are able to understand it. For information about HTML, read W3C specifications, and avoid w3schools. For information about Java, read Java Language Specification and tutorials made by Sun. Most online tutorials are written by people who don't really understand the topic, they just learned it yesterday, and today they are trying to make some fame and adsense money from sharing their confused thoughts. (Especially everything related to PHP. Also PHP itself.) If most programmers are on the level zero, there will be many level-one gurus, and level-two system architects.

These kinds of recommendations are good, but not exactly what I was looking for, probably because they are a bit too high-level. Let me give you an example of the types of things I think have made me an incrementally better programmer recently:

  • Using a scripting language (Jython or Matlab) in combination with a compiled language (Java) to get the best of both approaches. One-off, adhoc analyses or jobs can be quickly developed in the scripting language, and then either thrown away or migrated to the compiled language if they prove to be useful. The ability of a tool like Jython or Matlab to script Java objects means that you can reuse your highly polished object logic in the scripting language.
  • Enforcing a "no-cycles" rule in my list of object and package dependencies. A full build of my code compiles package-by-package, so that if package A is ordered before package B in the list, package A cannot refer to package B. This is a good straitjacket to put yourself in, but I actually take it a step further and require that there cannot be circular object dependencies within a package.
  • A "smart" fast compilation script that checks if a source file has been modified and then recompiles just that file. This is actually kind of fast and loose in the sense that it can introduce bugs if you're not careful.
  • Extensive use of assertions. Assertions actually serve two purposes - the obvious purpose of producing a "fail-fast" effect so that the code breaks immediately and for a clearly specified reason when the assertion fails. But they also serve for self-documentation. For example, say you are using a method that takes two arrays, one of size NxM and the other of size NxP. This introduces the potential for bugs if the array sizes don't line up and also confusion if the caller can't figure out whether s/he needs to pass an array or its transpose. Putting in the appropriate assertion both prevents confusing error messages but also indicates to the reader what the correct array sizes are.
  • Figuring out how to rely on the compiler more to catch potential errors at compile time. By writing code in a certain way, you can be more confident that IF there is an error, the compiler will catch it. One principle here is to use methods with mixed signatures - it's better to have mymeth(String, int, boolean) than mymeth(String, String, String) because in the latter case the compiler won't be able to catch it when you pass the arguments in the wrong order. Using enums is also a good idea.
  • Use of AutoHotKey to remap common commands to keyboard shortcuts that are easier on the fingers. For example, I remap cut and paste operations to the function keys, because I don't like stretching my left pinky finger all the way out there to hit the control key.

Some things I need to get better at:

  • I need to know more about Unix. I have been procrastinating on taking the plunge and switching over to Linux for personal use.
  • Overall I need to have a more efficient computing environment - not just the programming language but the full ecosystem of tools: editor, shell, scripting language, keyboard, etc. (Aha, I just realized that I want my shell to produce sounds or music to supplement the text output so I can actually hear it if a program is behaving improperly).
  • I need to get better at building modular parameterized components and reusing them to build more complex applications. The Unix pipe-output-to-input is the model here, but it doesn't do all the things I need it do. I can imagine a visual "wiring diagram" tool here (maybe similar to SpaceChem) that allows the user to hook up programs to each other, using basically the same piping idea, but in a more flexible way.
  • I should be able to make better estimates both for how long various process will take and how long they should take if my code were perfectly efficient (i.e. how close am I getting to the actual physical limitations of the hardware).
  • I should get better at using code analysis tools to detect errors. One thing that constantly annoys me is variable shadowing, and that should be possible to detect automatically ( I know some IDEs do this. I have mixed feelings about IDEs).

I am a big fan of IDEs, because they can remove a lot of trivial (or not so trivial) inconveniences.

  • I point a mouse cursor at any variable / function / class, and a documentation is displayed; if I press Ctrl and click, the definition is opened. What is the alternative: Remembering everything?

  • I often rename my variables / functions / classes, because I believe that the name should reflect the meaning as closely as possible, but sometimes when I finish writing something, I realize the meaning is slightly different than I originally thought. IDE replaces all instances of the given thing, but does not touch other things with the same name (e.g. a local variable in a different function, or a method of a different class). What is the alternative: Always thinking hard about the name? Leaving the old name even when it feels wrong? Check carefully whether only the correct words are being replaced?

Generally, when I work with a good IDE, I am not just editing a set of text files, but I feel like I am working with the generated classes and functions directly. Because it is so responsive, it feels more real. When I work without the IDE (or with a bad IDE), it feels very clumsy. For example, I can type "my_obj.my_func()" on the keyboard, but I don't get an immediate response whether an object "my_obj" exists, whether it has a function "my_func", whether the function has zero parameters. The IDE gives me this feedback all the time, it feels so natural, and I become tense without it. Sure, I can get the feedback later, from the compiler. But that's like a difference between walking with open eyes, and walking with closed eyes and shortly looking around once in a minute. I can still successfully navigate to my goal, it just takes a heavy tax on my attention.

My favourite IDE is Eclipse, for Java. In settings it has a long list of things some people consider bad programming style, and you can select which of them will be underlined in the source code as warnings. Just reading the whole list is interesting. Once I tried to turn on all of them and then improve my program to fully pass the test. (Then I turned off one setting. It required localizing all the strings in code; that would be an overkill.) I learned some interesting things from that. But this could be achieved also by using an external tool, such as FindBugs or PMD.

require that there cannot be circular object dependencies within a package.

How do you avoid circular dependencies between e.g. "a node is a branch or a leaf" and "a branch contains two nodes"?

I agree with the other things (with the sidenote that some IDEs give you smart compilation and keyboard shortcuts automatically). The idea of an acoustic feedback sounds interesting!

If you want to develop your *nix skills, switching to Linux for personal use will not be as much help as you think. The most sure-fire way of picking up Linux chops is having to work with a core installation you can only access through the command line.

This is all good, but also just stuff that gets you from a neophyte to a competent programmer. What about the part where you want to get from the competent programmer level to the John Carmack, Peter Norvig and Oleg Kiselyov level?

You could ask them. But someone got to that level first, how did they do that?

Let's suppose my goal is to become so cool that I could code StarCraft 3 during a weekend... without all the textures and levels and music and movies; just with some sample data, so my minions can later provide the rest. This would make me rather happy. :D

I could just spend one weekend doing my best, which obviously would not be enough. Then I could reflect on what was wrong. What was really slowing me down. I could try to research a solution for that (there is always a high prior probability that someone else already did it), or try to solve the problem myself. If I found I was missing some specific skill, I would focus on improving that skill.

The next test weekend, I could start again from the very beginning -- more precisely, I would not reuse the specific code that I wrote the previous weekend; however, if in meantime I have prepared some useful library for myself, I would use that. The idea is that I am not unnecessarily handicapping myself; I am just assuming that what I did previously was wrong, so I am not going to build on my mistakes, but to do it right. Also, by always starting again I could get some feedback on whether this weekend I was really more effective than the previous one.

All Turing-complete languages are equivalent, so at the end what really matters is the convenience of use.

Well, any Turing complete language can implement a sort, but not every language can implement a sort in O(n log n) time, or a sort that uses O(log n) additional memory. Sorry, just being nitpicky.

True, though any turing-complete language can definitely, provably implement a sort that uses O(n log n) + k time or uses O(log n) + k additional memory (or straight-up all of them can do O(log n) memory if they have hard drive write access and OS auth to run other programs). "k" here is the amount of time it takes for this program to write and compile a compiler for some other, more efficient language, and then write the algorithm in that language, compile, and then run that.

At the extreme, the program could be an AI specialized in figuring out how to code the most efficient sorting algorithm given certain hardware specs, then figure out the most efficient language to write that in, then write it, then save it, then run it and delete itself.

Obviously, this is far, far from being convenient or efficient.

My comment viewed a Turing complete language as a sort of self-contained mathematical thing, which doesn't necessarily have access to the operation "ask the OS to run this sequence of x86 instructions". When people talk about Turing equivalence, that's typically the meaning they use.

Interpreting one language in another is okay, but interpretation doesn't necessarily preserve time and space complexity (try interpreting an impure language in a pure one).

Yeah, alright, thanks for that clarification. I didn't realize I was thinking about it in terms of "Java/Python/C/etc. running on some traditional computer".

Agreed that interpretation is quite prone to overhead and delays.

[-]maia00

Any suggestions for finding a larger project to work on to advance the later skills, if one is mostly doing self-study? (I'm an EE student dabbling in various languages, and don't feel super-comfortable working with large projects yet, though I've had some experience with C++-specific stuff.)

Some projects become large because besides the central problem or a set of central problems there is also a lot of infrastructure: user interface, data serialization, export and import, etc.

Here is an example of a school project:

"Find the cheapest path between points A and B in a weighed graph."

Here is how the same problem would look in a real life:

"Create a web application for transporting cargo. Many companies provide transport between specified cities. The customer needs to move their cargo from place A to place B. The application finds and displays the cheapest path on Google Maps.

User can select starting and ending position by clicking the icons of stations on Google Maps, or by selecting from the pull-down input. (The first input displays a list of countries with at least one station, on the selection the second input is shown with a list of stations in given country.) User provides the total weight of the cargo, and selects checkboxes if the cargo has some special properties (e.g. fragile, radioactive, biohazard). Then user clicks on the Search button.

The shortest path is computed and displayed visually on the Google Maps. On the side of the screen the list of path segments is displayed: the length of each segment, the price of transport through this segment, and the company which provides the transport. Then the total length and total price. By clicking a button the user can export the list to a PDF file.

Administrator can log in the system using their username and password. Administrator can edit the list of stations: name and GPS coordinates in the station. The GPS coordinates can be provided as numbers, or by clicking or dragging the station icon on the Google Maps. The data are stored in a database. The list of stations can be exported to an Excel file, or imported from the Excel file.

There is more than one administrator, each one has their own username and password. Each administrator editing action must be saved to a log file, so if one of them intentionally destroys some data, it can be found who did it and when. One or more administrators can be meta-administrators with ability to create or remove administrators, or edit their data (username, real name, phone contact,...) or change their password. These data (except for the password) can be also exported to Excel.

Administrator can also edit the list of track segments consisting of: starting station, ending station, company, maximum weight, price per unit weight, and whether cargo with special properties (fragile, biohazard...) can be transported there. There can be more than segment between two stations for the same company (e.g. a cheaper option for normal cargo, and a more expensive or more weight-limited option for fragile cargo), however if there are two options for the same company where one is strictly better than the other (not more expensive and not more limited), this is clearly a mistake and should be displayed. The list of segments can also be exported to Excel and imported back. The export has an option of exporting everything to a single Excel file, or to a separate Excel file for each company.

By the way, the lists of stations and segments the administrators edit are displayed in a table, which has 20 rows per page, can be sorted by any columns, and filtered by various criteria."

What open source software do you like? I think the best would be to pick a small software with 1-5 core developers.

Go to the mailinglist of the project and say that you want to help. Describe your present ability and ask for suggestion about how you could best contribute code to the software.

A lot of open source projects are happy to welcome new developers. Senior programmers at the project will review your code and tell you if it's bad.

In case some open source project isn't happy to welcome you, move to the next project.

A book that greatly improved my code was Clean Code by Robert C. Martin. It helped me understand things such as when code comments are appropriate and how to split code into well-factored functions. The book’s main flaw is that it’s sometimes hard to tell which of its advice is Java-specific and which is widely applicable. But I definitely still recommend it.

The author wrote another book, The Clean Coder, which is also about improving as a programmer. It’s not about coding well – it’s “a code of conduct for professional programmers”, and talks about things like when to say “no” to your boss, how to make a commitment, and how to estimate time for tasks. It was not as good as Clean Code, but it was helpful.

You can easily download ebooks of these from Google searches: Clean Code, The Clean Coder.

It seems to me that many of the people we see as great programmers are those who made their mark on a particular field of programming. So my answer would be, if you're already an okay programmer (can get hired at Google or a hedge fund), you could pick a subfield that intensely interests you, and just dive as deep as you can.

The reason most people don't do that is most jobs have a mismatch between what's interesting to you and what's useful to the employer. It's worth trying to minimize that mismatch and get encouragement from your employer somehow, though I have no idea how, it seems to mostly depend on luck.

There's http://norvig.com/21-days.html with provides a bunch of suggestions.

Otherwise getting better at programming is like getting better at anything. You need to spot patterns of suboptimal behavior.

Do code reviews with other people. Talk about whether the code is optimal and how it can be improved.

[-]ema00

Paul Graham's writings on programming and learning Haskell leveled me up. Although i suspect you are already at that level.

I've been fiddling about with Project Euler (I'm about a dozen questions in) using Python and I'm painfully aware that I've been taking the easiest route through all of the problems each time - bruteforce searches with minimal optimization. When reading through the discussion threads after I solve the problem, I'll often come across a wonderfully elegant solution and at once understand it and then kick myself for not coming up with it. The problem is that I feel like I'm looking at a bunch of clever tricks without the insight needed to understand why I should have embarked on that line of reasoning. I guess what I'm asking is, what are some good books or resources I can consume in order to better my understanding of how to solve these kinds of problems?

Just more Euler problems will help, though they may not be optimal. Around problem 50, brute force stops being a viable option, and you have to start referencing wikipedia and, sometimes, the resources wikipedia lists. By the time you reach 100, the problems start getting genuinely hard (for me, they may not get hard until significantly after that for you). See if you can solve each problem with paper and pencil before you even create a program, or, if you must create a program, use it to test a hypothesis instead of to find the answer.

For bonus points, try to get your algorithms down to one second of running time once you get a working algorithm.

Disclaimer: I myself have only been programming for about a year, and while I have been told I write very good code by my manager, I'm still an amateur

Thanks for that - and they'll probably start getting hard for me quite a bit before 100. I've nowhere near the programming experience of you; I've been partially using Project Euler to teach myself Python.

I did the same, though I went into them knowing a small amount of Java and a similar amount of JavaScript. I doubt the Euler problems are the optimal way to learn a language, but they're certainly a really, really good one.

This seems like it'd be better as a wiki page than a Discussion post.

About a third of LW users described their profession as "Computers" in the recent survey.

They also have quite high salaries.

This seems like it'd be better as a wiki page than a Discussion post.

Wikis aren't great for discussion or Q&A. The list of resources could go there though.

Consideration: Many more people regularly check the discussion feed than look at the wiki page.

A workaround could be having the actual discussion post in the wiki, but announcing it here.

[-]gwern130

Individual programming questions might be asked in the regular open threads, but list of resources and commentaries are the sort of curated thing which should be in an open wiki page. (Posts are really bad for that since they are so 'owned'; when was the last time XiXi updated the previous CS/programming textbook post http://lesswrong.com/lw/cpz/computer_science_and_programming_links_and/ ?)

Would it be possible to made standard posts free for editing? (Ironically I don't have the programming knowledge to know)

I suspect not. Such a thing is basically a wiki, then...

This seems like it'd be better as a wiki page than a Discussion post.

I put the links from the article here: http://wiki.lesswrong.com/wiki/Programming_resources

Next step: copy in XiXi's stuff.

I think it would be best as a sticky, in some sort of "more permanent/ongoing" threads category. Do we have something like that on the wiki?

Well, every wiki page is a permanent/ongoing sort of thing?

There is a special threads page.

If we juxtapose Yossi Kreinin's rant about nomads vs settlers in programming, Steve Yegge's rant about liberals vs conservatives in programming, and Robin Hanson's idea that liberals are foragers while conservatives are farmers, do we get anything insightful?

I associate Yosefk's nomad programmers with maximizing the amount of program you can hold in your head, since you don't find working very closely with other people very productive. This gets you weird super-expressive languages like Lisp and Haskell in favor of things like Java or C++, which have the forced common idiom and interface conventions to help collaboration between multiple developers. This gets you different types of culture, with the nomad programmers making small works that can get arbitrarily tricky and impressive, while the settler programmers do less idiosyncratic work in order to keep being able to talk to each other, and build the stuff that's eating the world by the sheer volume of output they can collectively manage.

This interfaces a bit oddly with Yegge's language taxonomy. By this idea, the solo programmers prefer languages that let them do clever stuff in a small number of lines. This works both in very statically typed languages like Haskell and very dynamically typed ones like Perl. While there are similarly languages like Java (designed for peons) and PHP (designed badly) that programmers often avoid if given the choice.

The interesting bit in Hanson's post is the idea that while everyone cares about fairness, liberty and care, only farmers also strongly care about loyalty, respecting authority and respecting sanctity. The group hierarchy virtues only make sense in projects that require cooperation from multiple people, and possibly hierarchies of teams operating under a managing authority. These kind of groups can also use sanctity norms like syntax formatting conventions to keep it easier for different people to work on all parts of the project.

I have been on both extremes of this division. As a nomad against a group of settlers: "So just because you guys never heard about these most frequent design patterns (and most likely even about the whole idea of design patterns), it means that I shouldn't ever use them... and instead use your preferred way of hundred-lines blocks of procedural code with dozens of ad-hoc modifications because the whole thing is already too heavy to be refactored (and you probably haven't heard about refactoring either)?" And as a settler after a nomad raid: "So Mr. Smart created this weird framework here, completely idiosyncratic and undocumented, and now he moved on to a fresh project, and it is my job to understand what he tried to do here and solve all the resulting problems, so Mr. Smart can get the credit for being smart, and I get the lowly work of cleaning up his mess. I wish he had to clean up his own mess, just as I have to clean mine." And the funny thing is that now as I write it, I understand how the other side probably felt.

It is about long-term responsibilities. Programming is not just "create this magical stuff", but also "maintain this stuff when it starts falling apart". Some people are shining good at the former task, and completely suck at the latter, and then someone else must pay for their ticket to fame.

(Not surprisingly, I feel similarly about politics. Designing an utopia is not a hard problem if in a case of disaster you are allowed to say "meh, whatever" and go away, leaving the starving millions behind.)

Perhaps this is a good place to recommend a book "Algorithmic Adventures" by Juraj Hromkovič.

Author is a university professor who also makes public lectures for elementary school children. I believe the book is completely accessible to beginners; it explains the concepts as simply as possible (but not simpler) and covers various parts of computer science, including even quantum computing and bio-computing. It gives reader a good idea about what computer science means for people who study it at university.

So I think it is a good idea for people who study programming outside university to read this book, to get a large picture of what else is there besides learning specific programming languages.

So,

When people say programming changes the way you look at problems, do you need to specificly learn a (certain?) language to gain this understanding, or can you study the concepts separately?

If the former, how is the best way to get the most out of programming (if you have no other particular agenda, like necessity for a job), and if the latter, how best to do that?

Learning and using an actual language is important in that it will give you much a tighter feedback loop than just learning about the concepts abstractly or through pen-and-paper.

Python is the most commonly recommended programming language for those who want to learn the basics. Learn Python the Hard Way is often recommended as a beginner's learning source. I haven't tried it myself (I already know how to program) but it looked reasonable when I gave it a skim.

Thanks. I have a list of books people recommend (and a favourite that I've decided to use), but I haven't heard much about how other people learnt, before these all came out. How did you?

I was a physics major and kind of got thrown into the deep end in a "Scientific Programming" class where we had to write physics simulations in C with very little instruction. Back then I (somehow) didn't realize that doing my own online research and self-learning was a good idea so I had to rely on the TA a lot when I didn't know how to do something. Fortunately programming came somewhat naturally to me and I was able to do ok by learning from the example code we were given and proceeding by analogy. Interestingly there were people in the class who were better than me at physics and math but found programming a lot harder than I did. I don't know what the difference was.

After my degree I decided I didn't like physics enough to continue and went back to school for a master's in IT, since I'd enjoyed the programming class and it seemed like a good field job-wise. There I learned programming in a more normal way (starting with Java) and got better about self learning, including teaching myself Ruby using the first half of Why's (Poignant) Guide to Ruby.

Since then I've continued learning through working as a programmer, through online resources (including Coursera which has some great courses), and through books. It was also helpful to have a smart programmer at my first company who was able to informally mentor me when I was new.

(Sorry for the long-winded answer, but I agree with you that's it's interesting to see how people really did something, not just how they'd recommend doing it).

I mostly agree with ShardPhoenix. Actually learning a language is essential to learning the mindset which programming teaches you.

I find it's easiest to learn programming when I have a specific problem I need to solve, and I'm just looking up the concepts I need for that. However, that approach only really works when you've learned a bit of coding already, so you know what specific problems are reasonable to solve.

Examples of things I did when I was learning to program: I wrote programs to do lots of basic math things, such as testing primality and approximating integrals. I wrote a program to insert "literally" into sentences everywhere where it made grammatical sense. I used regular expressions to search through a massive text file for the names of people who were doing the same course as me. Having the goal made it easier to learn the syntax and concepts.

However, that approach only really works when you've learned a bit of coding already, so you know what specific problems are reasonable to solve.

This struck me as slightly odd.

In my experience, people who do not have at least a decent grasp of the concepts involved in programming will not even be able to imagine the kinds of problems that are not reasonable to solve. They will, on occasion, think up things that they believe is "simple", but would in practice require the equivalent of a whole Google department working on it for years before it can get done. If that's what you meant by knowing what problems are reasonable to solve, then that's fine.

However, even such large, Google-scaled projects could still present a good way to motivate yourself and start looking up and learning stuff about coding.

I'm pretty sure we exactly agree on this. Just out of curiosity, what did you think I meant?

I believe I went with the wrong interpretation of "solve". I read it as something much more open, in the sense of "figuring out the problem's key elements", which would mean "needing to solve" google-scale projects and then them being "reasonable to solve" is equivalent to doing the research and experimentation required to figure out all the important structural elements of the problem, and what kind of team exactly would be working on which problems in order to implement the full solution.

If I interpret "solve" as in "fully functional" (coded, runs, performs the desired operation without bugging for the standard test cases), then what you said and what I said reduce to approximately the same thing.

Programming is about processing data automatically. You could do a "programming without a computer" if you have something else to process the data. For example, humans.

Giving commands to humans could be an analogy to programming. The analogy would work best if we ignore the human-specific stuff (e.g. how to motivate them) and focus on the large task.

For example, in an alternative universe without computers, you could be a director of a new library. You have received one million new books; they are in unsorted heaps in the next building. Your goal is to make a system where it is easy to find a book by title, and if possible, also by author's name. It should be possible to later add or remove books. The work of your employees costs money, and the total costs of running the library should not be unnecessarily large.

This is almost like making a program. You have to design data structures (where do you put the books? will you also use some notes on paper? what notes? how will the papers be organized?) and program (instructions for your employees: the initial book import, finding a book, adding a book, removing a book). You have to make estimates about complexity of the program (how many man-days will you need for one million books? if you have twice as much employees, can you make it happen twice faster? for two million books, would your costs double?).

Databases predate computers. I don't have good examples for other programming concepts.

I have also designed a lesson for children to teach the skills of "being specific", "following instructions literally" and "designing instructions to be followed literally". They had a chess-board and a small toy which could be put on some square and face a certain direction. They had paper cards with commands "go forward", "turn left" and "turn right". The task was to create a list of commands which would make the toy get from a starting position (e.g. B3, facing north) to an end position (e.g. D5, facing north). They arranged the list of paper commands next to the chess-board. Then they switched places with a classmate and tested their commands. But I did not measure if this lesson really increased their skills.

So the idea is to be able to intuitively see the individual parts of a problem and feel how complicated they each are? Cool. Sounds all reductionist. I'll have to learn python now then.

[-][anonymous]10

Up voted for sharing useful links as well as previous LW discussion! I think a wiki article based on this would be a good idea.

[-][anonymous]10

Does anyone have experience with Erlang? It seems interesting, but I don't know whether to spend time learning it, Haskell, or one of the more employable languages (C/C++/Java/MATLAB).

It depends on how much programming knowledge you currently have. If you want to just learn how to program, I recommend starting with Python, or Haskell if you really like math, or the particular language which lets you do something you want to be able to do (eg Java for making simple games, JavaScript for web stuff). Erlang is a cool language, but it's an odd choice for a first language.

In my opinion as a CS student, Python and Haskell are glorious, C is interesting to learn but irritating to use too much, and Java is godawful but sometimes necessary. The other advantage of Python is that it has a massive user base, so finding help for it is easier than for Erlang.

If I were you, I'd read Learn Python the Hard Way or Learn You a Haskell For Great Good- the second of those is how I started learning Haskell.

For Haskell, I'd strongly suggest Hutton's Programming in Haskell as an introductory text for folks with no functional-programming experience. First, it is slightly cheaper; and second, it has the word λ inscribed in large friendly letters (well, letter) on the cover. But seriously — it presents basic Haskell in a gentle but mathy way, without a lot of the gushing of some of the more recent texts. It's written as a textbook, with topics presented sequentially; with academic exercises rather than pseudo-industrial ones. Rather impressively, it presents Parser and IO monads before introducing the Monad abstraction by name, so one actually has worked some examples of monads before trying to puzzle out what a monad is.

If you're studying a language to learn from it, then the choice of language depends on what you want it to teach you.

Erlang and Haskell are similar languages, and mostly teach the same things: purely applicative (“functional”) programming and high-order (also called “functional”) programming. Erlang also teaches message-passing concurrency and live patching; Haskell also teaches laziness and modern static typing. I've found Haskell more educational than Erlang, possibly because more of the things it teaches were new to me, possibly because I've done more with it, and possibly because it has more to teach. (But it is more complex.) Haskell is also more popular and has more libraries. IIRC you're a mathematician or at least math-inclined, so you'd be comfortable with Haskell's very mathematical culture.

Of the “employable languages”:

  • C teaches low-level data representations and efficiency concerns, and how to deal with unsafe tools. These are all things a programmer needs to know, and C itself is very widely used, so it's almost essential for a professional programmer to learn, but not for someone who only writes programs as an aid to other things. (Your blog suggests you already know some C.)
  • C++ is very complex, and most of what it teaches is C++-specific and not very enlightening, so I don't recommend studying it unless you need to use it.
  • Java is simple (except for its libraries) and not very enlightening. If you know C and Haskell, you know 3/4 of the important parts.
  • I don't know MATLAB. This is the second time I've heard it described as practically useful, so I suppose I should look into it.

Java is simple (except for its libraries) and not very enlightening.

Maybe not, but I still prefer its approach to inheritance and polymorphism than the approach some other languages take. For example, why Python is a great language overall, I dislike its entire OOP mechanism. IMO, Java is worth trying just because of that.

Yes, Java makes the distinction between:

  • these classes do the same thing (but internally they can be completely different); and
  • this class is a copy of that class, with some added data and functionality.
[-][anonymous]00

Let me try again: has anyone had any experience e.g., building something with Erlang?

I don't need a compare/contrast of feature sets or textbook recommendations; I want to know what it was like doing something with it.

Is MATLAB particularly employable? I wouldn't have guessed that.

[-][anonymous]00

matlab is the new fortran

engineering.

If I'm looking to learn programming for the purposes of setting up a website, am I better starting with general programming practice or website specific stuff?

[-]sdr60

In ascending order of resolution:

  • There are a lot of quicker ways to set up a website -a lot of hosting solutions come with one sort of web designer, or another; you can be up&running with a general blogger account in 2 minutes. If you have a specific end-goal (eg. moving inventory) in mind, this'll give you disproportionally quicker bang for your time.

  • Depending on what your goals are, the primary challenges of websites might not be the technical details, but rather clear communication & value presentation. If you have a goal, articulate it in writing first.

With that said...

  • Knowing HTML allows you to create static websites; CSS gives you fine-grained control over presentation; Javascript (and specifically, JQuery) allows you to create client-side (in-browser) interactions. You can get through these without the understanding of CS basics (for JS specifically, there are a lot of online collections for scripts, etc)

  • Web-specific domain languages (php, python, ruby) gives you server-side capabilities (storing & querying data, generating dynamic pages, business logic). More assembly required, and this needs some CS fundamentals.

In short: it depends on whether you see this website&programming as an instrumental goal towards something larger, or as a terminal goal towards "being a better website creator". Hope this makes sense.

Learning programming takes years.

A simple website could be done in an afternoon by someone who already knows the right tools if the website only needs the most standard functionality (what exactly that is depends on the tool), and a free design is acceptable.

Even for someone who wants a website and wants to learn programming, the optimal way is to pay someone else to do the website, then ignore the whole website-making stuff, and focus on programming in general for a few months or years.

Learning programming takes years.*

* On average, for the average population.

On the other hand, the better you are, the more things you learn just because they are easy enough to learn to be worth your time.

[-][anonymous]30

Depends what kind of website.

Read Learn Python the Hard way. It teaches python, plus has a big extended example for buildign a website.

For programming AI, Michael Wilson's Mini-FAQ from a couple years back.

Is there anything else that tackles actual present-day AI research and development you need a programmer for for people who are already competent programmers and have read the obvious introductory GOFAI and machine learning textbooks?