Going through Hacker School for the first time this summer made me more familiar with the landscape of programming. I began to see patterns, and with that, paths. I know what kind of things interest me and what I want to get good at. This is my list of things I am either learning right now or want to learn during my second time around. The first half consists of things to do, and the last half of general themes.
Domain-specific languages
DSLs are programming languages optimized for reasoning within a certain domain. This is done by focusing only on the relevant components and ways of composing these within that domain.
For example, with HTML you have elements for things like paragraphs and headings that denote how things should be rendered in a web browser, and these elements can be nested in a natural manner.
I believe writing domain-specific languages is a powerful way to solve problems in general, as well as a good exercise in problem decomposition and programming-language-of-choice mastery.
There are plenty of examples of powerful DSLs - for markup (HTML), symbolic math (Mathematica), string matching (regex), relational data querying (SQL), parsers (YACC), and hardware design (Verilog).
In Clojure, writing DSLs is fairly natural, largely thanks to its code as data property. Code as data means the source code itself is represented by native data structures (symbols, lists, vectors, maps etc). This makes it easy to extend the language with your own syntactic constructs, essentially bending the language to your will, with the help of macros.
The evaluator, which determines the meaning of expressions in a programming language, is just another program. -- SICP
Specific projects: Toy DSL for expressing and reasoning about logical circuits. DSL in Clojurescript for dealing with state and/or DOM manipulation in client-side single-page apps.
Concurrency and communication
Concurrency deals with several processes running at the same time. How do you run and coordinate them?
There are many ways computer programs can communicate. More specifically what I want to explore is how to create and use RESTful APIs in a sane manner. This also touches on interface design, which is another topic that I want to learn more about.
Go is a simple, modern language which was designed with concurrency and server software in mind, so that's the context I will explore these things in.
Specific projects: Write a server that exposes a RESTful API, deals with lots of connections and does computations in another process
Data structures and algorithms
The reason for learning about algorithms and data structures is not so much for knowing the specific algorithms per se as it is for knowing what it looks like under the hood, and being able to go from a problem to feeling what type of data structure and algorithms ought to be used.
Specific projects: Implement and know when to use basic data structures using Data Structures and Algorithms by Aho et al.
Feedback and tangibility
In programming, and in any other pursuit, for that matter, we do things on a small level - typing individual characters on a keyboard - and on a large level - starting huge software projects. Regardless of what level, feedback is important to know where we are and what we are supposed to be doing.
Examples of actions with feedback: evaluating expressions in a REPL, writing tests for functions or expected behaviors, pushing code; interaction with end users, extra eyes and social cues while pair coding with someone, chaos monkey testing a complex system.
These are just patterns and things to be mindful of. There are no hard and fast rules.
In general, the goal is to make things yours as much as possible. Bring it closer. Knock down walls. Install doors.
Specific ideas: Start writing tests and create a workflow that eases friction. If you are stuck, ask yourself what feedback would make what you are doing trivial, then make it so.
Low coupling, high cohesion
This is part of general system design and project structure. It is a general goal to be conscious of and to strive for.
It is very much related to the notion by Rich Hickey, and surely shared by others, thatdesign is about taking things apart.
Specific ideas: Make a non-trivial library with low coupling and high cohesion. Be conscious of and study good systems, regardless of domain. Make a web service with moving parts and break it.
Write-ups and documentation
Rumor has it that programming is as much about communicating as it is about actually coding.
Specific ideas: Do technical write-ups of things you have made. Write documentation and usage examples for your programs.
Most important of all
Do things.