This is a request to all devs for a new type of article that outlines the non-obvious features and quirks of the languages you use the most.
All My Dev Tools Are Written In [Language]
Here's my issue:
- Nearly all my developer tools are open-source projects written in Rust (Nushell, Helix, WezTerm, and more).
- I don't need Rust for anything, and I have my hands full with other languages I use for work.
- I would like to learn enough Rust to modify my tools and contribute to the projects.
- I don't have a lot of time to devote to learning.
If you're a dev, I know you can likely relate:
- You want to port a project to the web but you haven't touched JavaScript since 2005 and have no idea where to start with modern tooling.
- You want to customize your Neovim config but you don't know Lua.
- You want to build custom tooling or workflows in Logseq but you don't know Clojure (or Datalog, whatever that is).
- You have a use case where a Bash script is the quickest solution but you forgot Bash doesn't support floats so 3 hours later you're uh... bashing your head in frustration.
So my personal problem is in Rust, but I would love for there to be an ecosystem of this kind of article available for ALL languages: an 80/20 introduction to a language, for programmers of other languages.
The 80/20 Rule
You've likely come across this truism, but in case you haven't, it goes like this:
- 80% of a company's profits come from just 20% of its clients.
- 80% of all community problems are started by 20% of the users.
- 80% of your memories with someone come from just 20% of the time you spend together.
- You spend roughly 80% of your time playing just 20% of the video games you own, a.k.a. you spent $70 on Final Fantasy VII Rebirth but have barely played it as you clock your 300th hour in Balatro.
The 80/20 rule is a heuristic that helps you focus on what's important:
- You should probably prioritize the needs of that 20% of your clients before anything else.
- You should probably kidnap that 20% of your users and drop them in the middle of the Mojave Desert.
- You should probably spend less time with the people you love, those unmemorable nobodies.
- Only ever play mobile roguelites.
We can extrapolate what this means for programming languages:
When learning a programming language, 80% of the headaches come from just 20% of the stuff you don't yet know.
Your Mission
So can you do me a favor, please? Whatever you primary programming language is, identify the 20% of:
- usage rules
- coding styles & idioms
- language quirks
- standard library utilities
- dev tools
- macros
- other unintuitive stuff to newcomers to the language
that you use 80% of the time, or that you see in GitHub projects of that language 80% of the time. Whatever will make reading code in that language easier to a newcomer.
Basically, when you were learning your language, what did you struggle to understand or use correctly? And from that list, what's roughly that 20% you use 80% of the time, or that you see in roughly 80% of the open-source projects you browse?
Can you then write an article where you tell me about these things? Name it something like "Rust 80/20" or "TypeScript 80/20". And in whatever social media platform you choose to share your article give it a hashtag like #rust8020
or #ts8020
?
To give you an example of the stuff I'm struggling trying to read Rust code:
- How do I know when to use a
::prelude
thingy VS using the actual thing? What even IS a prelude? - When is it acceptable to reach for a macro VS a regular function? I've seen APIs written both ways, as in
clap
derive vs builder APIs. - When am I more likely to encounter lifetimes? I get scared whenever I see the little tick marks, because I never know when to expect them.
- The whole business with
unwrap
and!
and?
. I find it very unintuitive.
What I Am NOT Asking For
I am not asking for beginner's guides, though. There are already a great series of articles titled "learn X in 15 minutes" like this excellent beginner's guide to Lua that take you through the main syntax of a language. Thing is, once you know one programming language (or a few), picking up the features of another is mostly just learning a few syntax differences and implementation details. Generally, there are already good beginner guides for every language, even those you've never heard of, such as this excellent guide to a language named Janet.
I'm also not asking for pedantic style guides. Those are for language fanboys, not casual users. Don't tell me how to write idiomatic Python. I know ThePrimeagen used to do that in Stack Overflow back in 2010 or whatever, but unless you have aspirations to be a mustachioed Twitch streamer dev, don't tell me about your idiomatic Python. Only tell me idiomatic rules if there's a particularly dumb construct you see in actual code all the time and I should know about it, like ugly list comprehensions and ternary operators.
A JavaScript Example
If you get what I'm looking for and have enough sauce to get cooking, you can stop reading. (Just link me your article in the comments after plz.) But if you'd like a more thorough explanation of what I mean, I want to give a brief overview of an article I would've found useful when I got started with JS. This won't be an actual 80/20 introduction to JavaScript, but I bet most of us are at least somewhat familiar in order for this to make sense, and get a better idea of the type of article I'd love to see.
1. In JavaScript, we pass around functions like they're your ex-boyfriend.
Whether or not it's a good idea, in JavaScript we like to encapsulate functionality in functions, and then pass them around like memory overhead isn't a thing. Because functions are first-class constructs in JavaScript, we can, and do, pass them around like variables all the time. This is a common pattern in functional programming, which is much more popular now, and most languages now support lambdas and closures. This wasn't always true though, and I used to find the function shenanigans of JavaScript very confusing:
- passing in functions as parameters to functions
- passing in function calls as parameters to other functions
- returning function arguments as functions within objects
- calling a function's mom within another function and having her mom do some work from within yet another function
- having said grandma function promise to return a modified clone of herself in the future unless there's some sort of unhandled network error
As such, here's a short guide to get you up-to-speed with some of the most common ways you'll see functions being passed around in JS. (Note to the reader: if this was an actual article, I would spend a LOT more time explaining closures, but this is just an example.)
// An imported function
import { importedFunction } from "some-npm-dependency";
// A regular JS function
function goodLittleFunction() {
// Do stuff here
}
// A gross un-labled arrow function that
// is super popular to use right now because
// it means JS devs don't have to bother
// learning scoping rules or prototype
// binding, even though it prevents error
// messages from being nicely labeled
// because they are anonymous. Have you
// ever had a moment in debugging where
// you go "and then some random function
// gets called, but I don't care which
// function it is, event though this is
// where the error is coming from"?
// No?
// Well we are JS devs, and that's how
// we decided we're going to do things.
const lilArrowFunction = () => {
// Do stuff here
};
// Sometimes arrow functions get a single parameter
// as input, in which case you can skip the parens
// altogether. You can tell it's still an arrow
// function because it still has an arrow, but my
// brain is wonky and I used to have trouble parsing
// arrow functions without parentheses in my head.
// Also, notice this function is returning another
// function, which will be modified by whatever
// argument you passed in to the function. This is
// a very common pattern in JS, and functional
// programming in general.
const yourExBoyfriend = param => {
return () => {
// Do stuff with `param`.
// The effect of this returned function
// will be permanently different depending
// on what the value of `param` is.
};
};
// Now let's demonstrate how you'll see functions being used.
// Here we pass a function to another function. If you check
// the documentation to `importedFunction`, it likely uses
// this passed-in function as a callback, meaning it will do
// the work that `importedFunction` is supposed to do, and
// then it will do whatever you specify in `goodLittleFunction`.
// This is a way for you to specify your own functionality
// that gets run as a custom step in other people's code.
importedFunction(goodLittleFunction);
// Here we are creating a new arrow function at the same time
// we pass it into `importedFunction` as a parameter. This is
// how we can quickly encapsulate a function *call* as the work
// that needs to be done.
importedFunction(() => lilArrowFunction());
// You'll often see this when dealing with DOM event handlers
// on the browser. In the following, when the user clicks the
// button, the browser will call our `lilArrowFunction`.
document.getElementById("my-button").addEventListener(
"click",
() => lilArrowFunction(),
);
// Often, you'll see badly-named parameters being used in the body
// of these types of functions. Read the documentation, and you'll
// likely see that the function you're using exposes some kind of
// object you're supposed to use to derive your functionality.
importedFunction(obj => yourExBoyfriend(obj));
// In the example below, the browser gives you an object containing
// a bunch of information about the event that triggered the event
// listener. Here, the user has badly named the event parameter `e`
// for convenience, which is only acceptable because this is a VERY
// common use case, and it prevents the developer from typing out
// 'event' in its entirety repeatedly. I'd say it even helps
// readability. You'll likely also see `fn`, `err`, `msg`
// and a few other obvious ones, but there are also some other
// common ones that are a bit less obvious:
// - `cb` for a callback function, a.k.a. a wrapped function call
// - `req` and `res` for the request and response objects of some
// network functionality, such as `fetch`, or in web server code.
// - `el` for an HTML element reference in browser code
// - `ctx` for 'context' used in browser graphics APIs and in code
// that encapsulates some sort of state that is passed around.
document.getElementById("midas-input").addEventListener("input", e => {
e.target.style.backgroundColor = "gold";
});
2. JS dev tooling is complex; use Bun instead
(Note to the reader: notice that this is not relevant to reading code, but writing it. Having an opinion here is OK, because you're not tricking the reader into thinking this is how things are commonly done, but rather a tip on how THEY can get started more easily. However, if I wanted to show some typical server code, I would not be appropriate to use Bun or Deno; I would just show some common Node and Express code.)
You want to throw some JS on the browser. You could install a thousand dev dependencies, install React for no reason, run a local development server, have the dev server compile your React into HTML, and a bunch more cartoonishly exaggerated steps in the style of a 90s infomercial... or you could just install Bun!
Step 1: install Bun
curl -fsSL https://bun.sh/install | bash
Step 2: start a new Bun project
mkdir my-experiment && cd my-experiment && bun init
Step 3: write your HTML boilerplate
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>My JS Experiment</title>
</head>
<body>
<script src="my-experiment.js"></script>
</body>
</html>
Step 4: install an NPM dependency
bun i cowsay
Step 5: use that dependency in your JS
my-experiment.js
import * as cowsay from "cowsay";
const cowDialog = cowsay.say({ text: "I don't like to say 'moo'" });
console.log(cowDialog);
Step 6: Directly execute your HTML using Bun!
bun ./index.html
Bun v1.2.4 ready in 47.77 ms
➜ http://localhost:3000/
Press h + Enter to show shortcuts
Bundled page in 22ms: index.html
Bam! Now you can open http://localhost:3000/
on your browser, and should see the following in your dev console:
___________________________
< I don't like to say 'moo' >
---------------------------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
Now Go Write Me Some Articles! Pretty Please.
That's my basic idea for these 80/20 articles. If you like it, I'd love to see one for whatever language you want to throw at me: React, Julia, Svelte, Nushell, C++, Zig, Odin, Nim, Crystal, whatever! And remember to link me in a comment so I can see them. And write the Rust one ASAP because I'm over here waiting. Get to it. Up and atom. Remember I'm paying you nothing!
Top comments (0)