- TypeScript: the type system is incredibly powerful and expressive. You can guarantee wild things at compile time without a single runtime test.
- Clojure: very simple and elegant way to learn/introduce FP.
- Rust: I’m learning it now, and while I definitely understand why it’s considered difficult to learn… it’s certainly much less intimidating (in my experience) than other systems programming languages, in particular because of the borrow checker.
I feel like there's essentially no useful type inference, writing custom types is a nightmare because everything has its own special keyword rather than a simple core set of composable types, error messages feel intentionally vague, and having to write constructors and custom "isType" checks for every type you define is a massive chore.
In Haskell I could write:
data Tree a = Leaf | Branch (Tree a) a (Tree a)
tree = Branch (Branch Leaf 1 Leaf) 3 (Branch Leaf 2 Leaf)
whereas in typescript it would be something like: type Leaf = {
type: 'leaf'
}
type Branch<a> = {
type: 'branch'
v: a
l: Tree<a>
r: Tree<a>
}
type Tree<a> = Leaf | Branch<a>
const isLeaf = (l: any): l is Leaf => l?.type === 'leaf'
const isBranch = <a,>(b: any): b is Branch<a> => b?.type === 'branch'
const isTree = <a,>(t: any): t is Tree<a> => isLeaf(t) || isBranch<a>(t)
const Leaf = (): Leaf => ({ type: 'leaf' })
const Branch = <a,>(v: a, l: Tree<a> = Leaf(), r: Tree<a> = Leaf()): Branch<a> => ({ type: 'branch', v, l, r })
const tree = Branch(2, Branch(1), Branch(3))
How does this not feel like a major pain in the ass? Is there a simpler way to get typescript to do all the boilerplate for you?For real engineering I think it’s a wonderful compromise between formality and practicality.
I make pretty heavy use of mocks and like how easy it is to mock external API calls in Go by either wrapping an external call in a mockable interface or spinning up a local server with `httptest`. I also love how quick it is to write a couple of benchmark tests to get a rough idea of perf tradeoffs between approaches.
I usually try to keep tests small, but I do like testing more end to end and inter-package flows as well. At some point large tests do get brittle and reliability on CI is key so I try to stay away from convoluted test paths, but it's been pleasantly doable to write reliable tests even for larger flows with Go. When I worked on an auth service we had tests going through full oauth failure and success flows and those got pretty big (eg imagine an end to end PKCE auth code grant test that also has to communicate with an additional external provider). For these we had separate tests at the storage level, and mocked storage (or used a test memstore where relevant) at the auth handler level.
I like `testify` for assertions, `gomock` for mocking, `spannertest` for spanner, and `miniredis` for redis testing.
* a mainstream language with an upscale type system
* can look as lightweight as Python if you prefer that style
* .. while still retaining the power of the JVM with little Java-esque ceremony
* as multi-paradigm as C++
* Akka, Spark/Flink/Kafka, plentiful jobs in Data Engineering/Big Data Analytics/ML
Just * don't touch SBT (especially just starting with the language)
* ignore anything that rhymes with scalaz/cats for work purposes
* consider Kotlin if Scala is out of the question in your company/team
Is Kotlin still that relevant after the latest releases of Java?
Python - Experimenting with numbers - eg a fancy calculator, plotter, DSP prototyper etc. Robust set of mathematical, scientific, and statistical libraries. Frictionless syntax. Nice REPL (ipython) Doesn't have the licensing issue of Matlab. Julia has better mathematical syntax, but has too much overhead to compete. (ie it's slow for this use, despite being advertised as a fast language)
HTML, CSS, and Typescript - Web; keep it simple, universal, and fast.
- C++ : Mostly what I work in, for raw speed and control.
- Ada : Most of the C++ feature set (RAII, custom alloc) with straightforward syntax. It's very underrated (aspects and built-in concurrency are amazing) easy to call C from, and has its own package manager.
- Python : cross-platform automation
Typescript: The type system is very expressive, and easy to read unlike more powerful ones like Haskell.
Shell (bash): Yes, no other language comes close to compose programs together and manipulate/redirect text to/from files/other programs. I wish for another language to give me the opportunity to write something like:
export BAR="foo-$(wget https://some-api.example.com | jq -r .some-field)"
cat <<EOF | kubectl apply -f -
---
apiVersion: v1
kind: ConfigMap
metadata:
name: example
data:
foo: $BAR
EOF
Makefile: The simplest/most portable way of abstracting/automating complex commands. I'd choose make above any other tooling that has been reinventing the wheel (looking at you gulp, grunt, etc...).
Whenever I'm working with teammates/coworkers, telling them "just run 'make' to setup your dev env" is just priceless.One could argue that my last 2 entries are not programming languages, yet they are powerful tool that IMHO every dev should know.
The language I reach for the most is C#. LINQ is great and the base libraries are solid. Plus, the industry I'm in (building controls) is largely Windows based, so that obviously influences that choice.
I really enjoy the concepts and syntax of OCaml, but I've repeatedly lost of the battle of making it work on Windows.
The JVM has become much more popular in the building controls industry in the last decade. So I've been thinking of picking up a JVM language this year. Trying to decide between Clojure and Kotlin.
With sealed types, pattern matching, var, records, it is fun to write compilers. Java is on track, as it has been for a long time, to become ‘ML the good parts.’
My current job is more focused on business processes and advising on cybersec, this means that coding for me is only for fun and side projects.
I love the syntax and the sufficient standard library. I would pick python every time, but Nim's performance and compilation to a single binary file makes everything so much simpler so I can focus on the features instead of having to optimize and manage dependencies.
I have completed Advent of Code in Nim this year and it has been a joy.
But at the scope I code, it presents itself as a way for me to solve the problem by myself.
Julia has an intuitive and expressive syntax, while having good flexibility and the ability to work in multiple paradigms. Also, being a scientific programming language, it lends itself well to much of my work.
Haskell is rigid enough to force good design; this "higher barrier" generally results in better mental models by front-loading the understanding of a problem.
Honorable mention to a non-language, the Makefile. Especially with things like help targets[1], it's a very good accelerator for picking projects back up after they have sat on the shelf a while.
[1] https://marmelab.com/blog/2016/02/29/auto-documented-makefil...
Edit: There's a why in the question! Basically, I like the explicitness of the language core, the fact that is very high level (and easy to teach), and it's easy (and fast to get feeback) while testing things in the REPL..
ls -l | awk … | bash
even though it is notoriously unsafe. I guess a lot of younger folks know xargs but not awk.IMHO the best parts of awk are regex literals, natural pipeline participation, and familiar/simple syntax. Sitting down to write a complete program in awk start to finish though ... no thanks.
https://ilya-sher.org/2017/10/10/why-i-have-no-favorite-prog...
Then all I need to do is focus on how to pace my thinking and taking regular breaks
My treadmill desk is helping with that and hyperfiddle/rcf is great for TDD practice to ensure I'm moving forwards with small stable increments
Although, I've started toying with Elixir and I'm considering moving to an Elixir shop when I get back from a big trip next year. If anyone is interested in hiring a senior software dev that actively wants to learn Elixir, hit me up!
Ruby is pretty great too.
Simple in a good way, fast, excellent toolchain, great libraries, great Documentation and easy to learn, read and explain. A pragmatic language that I can simply get sh* done with.
I can do everything in it. It's fast and small.