1. 69

Inspired by a conversation on #lobsters, I was wondering what sorts of tiny projects fellow Lobsters might have for getting comfortable in a language or learning a particular technique.

Ideally, something that should take maybe a free evening or two to get finished.

Thoughts?

    1. 34

      I like implementing some of the smaller RFCs (FTP, POP3, TFTP, SSH). Since they are widely used, you will be able to find a client or server to test against.

      1. 7

        I’d strongly advise against FTP. While the protocol in general seems to be ok, every client seems to be a lot of hacks on top of other hacks to play nice with different servers.

        So yeah, if you ever want to test against one implementation, it might work…

        I found finger to be quite nice for this, also my default for learning languages is an IRC bot.

      2. 5

        For a slightly longer project, you could probably do Minecraft classic or maybe even Mumble…

        1. 5

          I feel like there are a few orders of magnitude of complexity between FTP and Minecraft, even in the most basic premise and feature set of a Minecraft clone.

    2. 19

      I’ve never done it personally but I’ve been told that writing a basic IRC client is a lot of fun and not overly difficult.

      1. 2

        From my experience, the greater problem with writing an IRC client is getting to understand how RFCs are written and to be read. I wrote a kind of IRC library for AWK a few weeks back, and most of the time was spent trying to understand ABNF and other peculiarities, unrelated to the immediate implementation.

        So if someone does this, it’s probably not bad to also have a few implementations in other languages one understands a bit better to help you along.

    3. 15

      text analysis (counting most common N-grams) and markov chain model building + text generation.

      Fun algorithm that fits in my head, touches I/O, munging strings, nested data-structures, and demonstrates both abstraction capabilities and performance characteristics of a language.

      plus it’s always new because there’s a probabilistic component to it and you can run it against new sources of data.

    4. 14

      My goto exercise is writing an irc bot. It allows you to start simple (sockets and strings) but you can iterate further and add other things on top like try async io or natural language parsing.

      Writing irc bots helped me learn asynchronous IO using python twisted and rust’s tokio.

    5. 13

      I’ve taken to reimplementing cat(1), to the end that I wrote a linter script to double check the new implementations against the old ones.

      They’re all implemented to varying amounts. I think gocat, excat, rscat and rbcat are the most feature complete.

    6. 11

      Some examples of tiny projects I’ve done:

      • OBJ file format loader for texture triangle meshes, going from string of an OBJ file to a packed buffer of tris with normals and UV coords.
      • Web page for adding up recurring monthly expenses and income to show net profits/losses.
      • Web page for showing the weights to put on a standard bar to get to a target value.
    7. 9

      To learn some Rust, I ported most of picol. Can recommend it. It was more like three or four evenings though.

      1. 1

        Oh that is neat!

    8. 8

      I tend to go for making websites and/or APIs or cmd line tools.

    9. 8

      My goto learning project these days is a parser combinator library. It’s big enough to exercise most parts of the language but small enough to be manageable in a weekend or two. The most recent one I worked on and finished was in typescript. Most of the time I’ll start and not finish but that’s fine because the goal is to just get over the initial learning hump.

    10. 8

      Not precisely what you asked but exercism is amazing for this.

    11. 12

      Advent of Code is great for this.

      1. 3

        I have to say that I totally hated every single task of the 2018 edition.

        So, it might not be a suggestion for everyone.

        1. 1

          Interesting! What did you hate about them, and if you liked 2017 and previous years what made them different?

          1. 1

            That was my first time, I had never heard of AoC before then :D

            1. 1

              That’s cool. So, the question still stands - what didn’t you like about the puzzles?

              1. 2

                For me, it was day 15, which was basically a huge pile of busy-work.

                This year is the first where the project creator didn’t also create all the puzzles, and I think it shows.

                1. 1

                  Yeah I can see that. I rather wish the past year’s puzzles were viewable for comparison

              2. 2

                Even though they were shrouded in little bits of story, which was okay, I found them to be the usual and tedious puzzles they give you on every other website.

                Initially I saw them as somewhat realistic problems solvable via programming but they were more like algorithmic problems with some story slapped on top.

                And there were very few moments of cleverness, like cutting out absolutely all the boring stuff and find a good enough approximation. All results had to be perfect, nothing just “good enough”, as it would be in real life.

                Maybe it’s just me going in with the wrong expectations :D

      2. 3

        +1 - the puzzles are fun and ramp up in difficulty :)

      3. 2

        Thanks for the link, but I mean little projects that you personally have done. Posting a link to a collection of puzzles is neat and all but not really what I’m looking for.

        1. 6

          I mean, I’ve personally learned two languages with AoC, so I’m not talking in the abstract. :)

          Before I came across AoC, I had a couple web projects I would rewrite every few years. One is a scoreboard for a Nethack tournament and the other is a scoreboard for a dice-rolling tournament (of sorts). I’ve found AoC to be a better way to see more of a language in a shorter time period.

        2. 4

          To some extent it is driven by the language niche. But for generic answers…

          For the basics, I find Conways Game of Life is a good hygiene exercise.

          Implementing a scheme is always fun. You can size it accordingly (a no-macro interpreter is a smaller time commitment, adding richer features (compile to llvm, compile to asm, proper quasiquoting macros) adds more depth.

          A simple (made up) register machine is fun. If you base it on an existing instruction set (z80, risc-v) then you have an emulator.

          Another puzzle site (which you don’t want, but which is awesome) is cryptopals.com.

      4. 1

        +1 to AoC as a learning tool - I started working through the advent of code problems the other day with the goal of becoming productive in rust. They are nicely bite-sized, with the extra benefit that you can compare your code against more experienced rustaceans, e.g. https://github.com/BurntSushi/advent-of-code

        I discovered a bunch of nice patterns like FromStr this way, and was impressed at how concise solutions could be!

    12. 7

      Graphics projects like a ray tracer/fractal viewer/rasteriser can be tiny and fun.

      Or an LZ4 decoder without no error checking or optimisations is like a page of code.

    13. 5

      If the language has easily used GUI bindings, then I’ll mess with a 4-function calculator. If I’m testing out a video game library, then it’ll be a twin stick shooter, as they are rather easy to make. (I’ve done calculators in TCL, VB.NET, and Factor, and shooters in Pygame, Love2D and Godot). Otherwise it varies. With Go, I’ve done mostly websites, with Lua, I almost exclusively do video games, except when using it as a scripting interface to Go.

      If you want to exercise a very foreign language, writing a CSV parser can be educational. (I wrote on early on when I was working on PISC). And if you want something slightly more involved, a stack calculator can be handy.

    14. 5

      I usually try some kind of command line tool that interacts with a http API so I can get a feel of the package management if any, the libs available, how to read the stdlib and libs documentation… or a basic http/gopher/irc server.

    15. 5

      Project Euler.

      There’s plenty of raw math, but also plenty of opportunities to implement algorithms and really get a feel for how any particular language handles most basic things that many languages are expected to handle (IO, loops/recursion, threading, inheritance, OOP, memory allocation, etc). Your thing produces an answer to a problem that you can instantly check for correctness.

      1. 2

        I like Project Euler but I thought it ended up being too Mathy (maybe that’s the purpose). The solutions often involve understanding particular aspects of number theory, which are fun to read up, but I found them hard to understand. Sometimes you can brute force the thing, but often you have to know these results - at least for the later problems.

    16. 5

      Word finder game. (The one where you have a 4x4 grid of letters and find words in adjacent letters.)

    17. 4
      • Shell (bash, sh): a lot of stuff to learn, from signals, background jobs, termcaps, …
      • tar/gzip: not that complex to implement and neat to understand.
      • VM+interpreted Lang: implement a lisp running in your VM, so much possible stuff, only your time investment is the limit!
      • HTTP/1.0 server: not that hard too, just a bigger RFC with nice stuff to learn if you work in the web.
      • debuggers or programming tools: gdb, ldd, file, etc
      • games and bots: for example a chess game is easy to build, and writing a bit is very interesting. You could even learn graphical libs to do it or just in the terminal.

      All those are stuff that help you to learn new languages but at the same time new concepts and technologies.

    18. 4

      Writing a small IRC client, if going for smaller then a reddit client or a bot for discord/telegram/whatever you like. Fun and simple but doesn’t cover much for a language.

      If you’re going bigger - I think writing a text editor is nice and challenging enough, to the level you want to extend it…

    19. 3
    20. 3

      For UI/JavaScript-related stuff, I have done two recent projects.

      1: Dist-O-Matic finds the closest professional teams to you/your location. Source

      2: Typing Keyboard is a JS synthesizer that you can use with your keyboard. Source

    21. 3

      This blog post outlines a technique for learning new programming languages. TL;DR you build a quick tool to connect to the RhymeBrain API and return some (very bad) puns based on a keyword. It’s simple enough to fully wrap your head around but complex enough to touch many parts of any language. It’s even got implementation steps you can use as goal posts!

    22. 3

      I always end up writing tiny raytracers. I never get too far, but I like the task because it provides opportunity to:

      1. File IO (writing images using a library, or constructing PGM, for instance), reading scene descriptions
      2. Data Abstraction (shapes, materials, etc) – and interfaces! You almost always want multiple object that have an intersects type “method”
      3. Math / vector type things.
      4. Arrays – typically 2d arrays.
      5. And, if you’re really motivated, you can play with concurrency as well.

      I’ve done this for Haskell in the past, and most recently with Rust a few years ago at this point. I never did get shading or any of the more interesting aspects completed for Rust, but the default scene does draw 3 spheres. :)

    23. 3

      TinyWM is a pretty cool way to learn to write a window manager for X :)

    24. 3

      It really depends on the language. If this is something that lives in the browser, I like something visual that plays with the canvas or generative art. If it’s something on the terminal, I like replicating classic Unix commands. For more specialized languages I try to do a task that leans into their strengths, so with R maybe I try to do a time series model on a tiny dataset.

    25. 3

      We use AWS a lot at work, and I frequently need to write small programs to do things in it. I’ll often implement them in a language I haven’t used much, and sometime re-implement one of my old ones in a new language. It’s something actually useful, and gives you an idea of how the basics work, though part of it is how well the AWS libs for that language happen to work.

    26. 3

      Chip-8 emulator or a web api :)

    27. 4

      Many people suggest using a repeatable toy project as a basis for learning. I would argue this is no good because simply transferring the domain knowledge to a new language or technique also transfers your bias on how to solve the problem using your previous language/technique.

      What I recommend is simply doing a project you would have done anyway, that you are passionate about and use that as an excuse to learn the new language. You learn not only how to solve a new problem but solve it using new ideas. It’s doubly motivating!

      So a better question for you is, not what is a toy project, but what is a project you would love to do for yourself that isn’t a toy, that satisfies a real need or solves a problem.

      1. 4

        Porting is different than implementing. Porting is much different than implementing, and with the burden of learning the domain lifted, one can concentrate on the implementation but still have it be concrete enough to move forward while not getting stuck learning two things.

        In the Tiny-C program I linked, even just porting it to a new language allows one to learn a significant portion of the problem domain, so porting too has benefit.

        Toy has a bad connotation, how about Model?

        1. 1

          You can only learn through a process of getting new information. Fortunately we have information theory to tell us what that is. We must go through a process that creates surprise, because otherwise you aren’t, by definition, getting new information. Getting stuck is part of learning and should be an exciting event because that means you are maximizing your learning.

          Solving a new problem is exciting, learning a new language is exciting, putting them together is just so so fun.

      2. 1

        Tiny projects aren’t toy projects…

        1. 1

          Totally agree! Many tiny projects satisfy a need, solve a problem, or are just plain fun. If I said tiny anywhere I meant toy.

    28. 3

      Implementing a roguelike game is a neat excercise.

    29. 2

      I’ve enjoyed reimplementing the smallpt path tracer in various languages, particularly if they are high performance (although I did write a version in Python… It took something like a few seconds to render a 2x2 pixel image…).

    30. 2

      Step 1: Try to write something against project Euler questions I have previously solved, to get an idea of datatypes, and data-, compute- and control-structures.

      Step 2: Re-implement a version of the xxd command, to get familiar with IO and it’s specifics.

      (Optional) Step 3: Write a few classes to implement timeout timers which can be used to answer questions like “how long until some given resource expires” etc.

      Step 4: Something that connects to IRC, says “Hello World!” in a temporary channel and then disconnects. When that works, make it stick around and reply to a given message.

    31. 2

      Web crawlers. You can test graph traversal algorithms, I/O, and parsing.

    32. 2

      Maybe write a mini-Ansible tool for running tasks on remote hosts in parallel. Here’s my take on it: https://github.com/mihaitodor/wormhole Through this exercise, I explored the following topics:

      • Yaml parsing with custom deserialisation
      • Establishing SSH connections and copying files via SCP
      • A bit of concurrent programming
      • Design a non-trivial architecture
      • Write some tests
    33. 2

      Whenever I sit down to learn a new computer language I like to make it a fun task.

      Therefore to begin with, I take a few small programs from the book Computer Spacegames. Being that the book was published in 1982 the games within are both simple and written in BASIC, the first language I learnt.

      In porting to a new computer language it forces me to learn how the fundamentals work in that language and because these are small games it becomes a fun task. So far I have ported the Space Mines to C, C++, C#, Python, PHP, JavaScript, Node, Go and Rust. My documentation of the Go port can be read on my blog here

      I can then build upon that fundamental knowledge with more advanced programs, building up over a few weeks to larger applications. Currently I am learning the faiface/pixel library in Go by porting examples from Dan Shiffman’s Coding Train YouTube channel from Processing (Java) and p5.js (JavaScript) sources.

    34. 1

      On my end, I don’t have an answer off top of head but do have ingredients. As in, it should be one or more projects that touch on various parts of the language: use of scalar and compound datatypes; different structuring a la programming in the large; different types of control flow; error handling; I/O (esp files and networking); concurrency and parallelism; wrapping existing code; anything that highlights language-specific advantages (eg macros for building DSL’s). Probably best to have a few, small apps plus maybe one, mid-sized one.

    35. 1

      This probably won’t help much, but since almost all of the projects I make for fun are pretty small, maybe a few thousand lines, when I want to learn a new language I’ll either recreate a recent project in the new language, or if I haven’t got very far I’ll just stop work on the original and restart in the new language.

      It does depend on the language and why I’m learning it, though. It’s nice if the project will show off features of the language.

    36. [Comment removed by author]