I also recommend this same exercise to others through the book "The Ray Tracer Challenge" [1] by Jamis Buck, because it describes an entire implementation of a raytracer in pseudocode. Beginners mostly just need to plug-in their language of choice & still end up with a satisfying visual result. Experienced programmers can extend it by adding the ability to load non-trivial .obj models, which will necessarily motivate adding concurrency, bounding volumes, & other general performance improvements.
I'm planning on tackling it again in Elixir soon, which should be fun & interesting.
EDIT: Almost forgot to mention the free bonus chapters [2] that get you started on bounding volumes (AABB), soft area lights, and texture mapping.
[1] https://pragprog.com/titles/jbtracer/the-ray-tracer-challeng...
[1] http://www.raytracerchallenge.com/#bonus
[2] https://raytracing.github.io/
[1] https://youtube.com/playlist?list=PLy68GuC77sUTyOUvDhVboQoOl...
I second the advice of loading .obj, it's a good exercise.
Implementing Octrees is another good one that will speed up your code while exploring tree structures in that language.
To wit: https://littlegreenviper.com/series/swiftwater/
That series is almost abandoned, now, but it was instrumental, in my discovering how to write Swift.
This was one I wrote up, as I was exploring the SPM: https://littlegreenviper.com/series/spm/
Learning Bluetooth: https://littlegreenviper.com/series/bluetooth/
Writing a simple streaming server: https://littlegreenviper.com/series/streaming/
This was one that I wrote up, as I was learning CSS: https://littlegreenviper.com/series/stylist/
But before that I prefer to get a book and work my way through all the examples, otherwise I'm just making up what "idiomatic" means.
It can also be fun, if your sense of humor responds to funny names, and if you choose the right inputs.
It's a good introduction to handling input and output, string manipulation, error handling, abstractions for iteration (or lack thereof), and language performance characteristics. All while being a fairly easy task that can be implemented easily but performantly in 60 lines of Python: https://git.sr.ht/~wintershadows/polyglot-benchmarks/tree/ma...
It also lets you play around with different software architectures and abstraction models, introducing enough real-world complexity to prevent you from making too many assumptions, while the logic is simple enough to keep you from getting lost in deep algorithmic implementation.
I have started adding some of these implementations to a Git repo that I will eventually fill out with other "polyglot" comparisons. See here for (currently) Python, Nim, Perl, and (somewhat-overengineered) Common Lisp: https://git.sr.ht/~wintershadows/polyglot-benchmarks/tree/ma...
I have several more implementations that I haven't committed to Git yet, because I've been lazy.
I've learned a lot through this process, not just about individual programming languages, but also about "how things work" in the process of trying to figure out why Python is so much faster than every other language I've tried (on par with Nim, handily beating all others, haven't tried plain C yet).
By far the most trouble I ever have is getting soup-to-nuts deployment happening such that I can concentrate on fixing bugs without being scared shitless I won’t even be able get the damn thing running in production.
While I'm picking up Rust, I really like the "rustlings" project that lets you exercise various parts of the language locally, instead of in a browser, so I can use the tools that I like. https://github.com/rust-lang/rustlings
Currently working on a new version in C#/Monogame, and next version after that will probably be Unity so I can make a VR version, something that's on my bucket list. Also at some point I'm going to make a new web version again using Javascript/Phaser (already made another simple game in Phaser, so it shouldn't be too hard, just need to actually do it).
It's been going slow though since I have so much less spare time and energy nowadays, though.
There's a pretty causal relationship between starting my unfinished side projects and me trying a new language or library.
I use advent of code to really dig deep into a programming language I sort of know but want to learn to use more. I plan on learning modern C# this way this year, it's been almost a decade since I taught myself the language at this point.
It covers sockets, string handling, and byte handling.
I like it because it’s kind of small, but tests several aspects of working in the language.
* the program needs support for several numeric types: integers, floats and rationals. * several basic math algorithms are needed, which will either test the std lib, how to use the package manager, or other language constructs as I pipeline implement them * how easy is it to write/run tests
Here’s one version in Rust, which links to clojure, cl versions. Want to try it with Julia next due to the built-in support for rationals.
If you wanted smaller exercises, you could take some of the leetcode exercises and grind through them on your own (outside of the leetcode framework if your language isn't represented there; if it is represented there, the Leetcode easy and medium are pretty good and there's loads of them).
As for the practical aspect of picking up a new language (for a purpose), I'd shamelessly look into an already existing projects along with following whatever language textbook.
Learning syntax is likely a simplest step, picking up an idiom is more involved and is often specific to objectives.
This way I can see how to input data, display it and how I can operate with the database.
It's simple.
Sadly for Rust and MongoDB I tried that 5 times and never got to the point that it compiles. It just wasn't intuitive and the error messages didn't make sense. For Rust also I went through the tutorial, because I really wanted to like it and switch to it, but compared to Go it was just too complicated. I didn't understand the game, boxes ownership move unpack... it all didn't make sense . I digress but yeah, a guestbook is usually my 1st application.
Python has been stuff like Pi hats with sensors, or using Pandas to analyze VAERS or Kaggle data. I assume this is similar for other scripting or backend languages/projects.
UI could be something like using Angular to build a simple site, or Android to build a simple app.
Basically find something that's simple and functionally similar to what you think you want to achieve with the language. At least for me, I want to learn a language to use it on a project, not just learn it for the sake of learning it.
Gives me a chance to learn the new language with a project that's decent in size, without it being debilitating. Plus, it is fun writing an interpreter.
Functional -- writing an interpreter for a toy language,
Scripting -- Sudoku/Wordle solver with UI
Systems language with low-level hardware access -- OpenCV integration, driving I/O pins, web server.
For all of them, I also test access to native C/C++ libraries.
- Is in C++
- Focuses on spheres
[1]Raytracer Challenge:
- Is Written in pseudocode
- You will be able to render objects composed of polygons not just spheres
My "go to" for anything UI related is Connect 4.
Other than that I try to pick a game that fits the theme. Games are amazing because they have well defined business requirements with sufficient depth to really exercise your critical thinking skills.
I used to work on a fork of https://github.com/jackpal/Taipei-Torrent with custom features, I found its code to be easy enough to understand
Should note I often work on 2d tile based games.
Alternatively, if I bought a book about the language, I end up following the suggested exercises they usually provide at the end of each chapter.
I write an L3 order book implementation, because I usually do quant trading.
Others might want to start with a simple REST webservice, a todo list, a CRUD application, solutions for Project Euler exercises, etc.
To me the real worldness of that > clever technical scenarios
- Simple scope, easily expendable. - Stack as a simple data model. - State machine for number entry.
It tests quality of libraries, resource safety, concurrency, performance etc.
<s>IRC? That’s sounds familiar.</s> :P
Advent of code after that.
Then, implement a super basic Lisp.
cat, ping, netcat, grep, cut, etc.