Reusable type branding in TypeScript
The closest way to get nominal typing in TypeScript is with type branding. I haven’t actually used this small library, but it illustrates the idea: https://github.com/kourge/ts-brand
A curated list of awesome Nim frameworks, libraries, software and resources.
One can, of course, go much further than simply distinct number types: https://github.com/ringabout/awesome-nim#science
(Unchained seems maybe the most featureful of those units packages.)
Clean code begins in your IDE with SonarLint. Up your coding game and discover issues early. SonarLint is a free plugin that helps you find & fix bugs and security issues from the moment you start writing code. Install from your favorite IDE marketplace today.
I'm not optimistic on unit types myself. I've found that unit-named variables often with transparent type aliases as documentation (type Sample = usize, type Amplitude = i16/f32) have many of the advantages of distinct units, without their downsides compared to bare numbers. In several projects where I've used naming and transparent aliases comprehensively, I don't recall ever letting a unit mistake escape from my local tree into master, since I reread my own code when committing and merging. In one case (https://gitlab.com/exotracker/exotracker-cpp/-/blob/dev/src/... used to have two EXPLICIT_TYPEDEF) I did add distinct units because I found I was mixing together two types too often during development. Though I find that unit types come with significant disadvantages (ergonomic and semantic flaws) preventing them from being a catch-all solution:
- You need an implicit conversion to eg. size_t, otherwise you can't pass (smp: Sample) into array indexing like (amplitudes[smp]) or data slicing, without an extra conversion or accessing the underlying value like (smp.v). But you can't allow (smp += midi_pitch) to convert both arguments to int, then cast the result to Sample when assigning.
- You need some conversion to allow (smp + 1) with type either integer (convertible to Sample) or Sample, unless you want to annotate all arithmetic with boilerplate like (smp + (Sample)1), or (smp.v + 1). I've experienced this problem in my own code, and had to write (smp.v) when my compiler saw (smp + 1) and told me it didn't know whether to wrap 1 or unwrap smp.
- Expressions of type Amplitude * 2 should have type Amplitude. Go's time library gets this wrong, where multiplying Duration * Duration = Duration, which makes sense if Duration is an integer like i32 or i64, but not if Duration is a unit system dimension.
- (not a regression but a limitation) Units won't stop you from adding two temperatures in Celsius. To fix this you need separate coordinate and displacement types, which is a new pile of complexity.
- You may want distinct types for "samples/sec" and "cycles/sec". Modeling this in type systems has multiple current approaches, all of which rely on language support (F#) or complex type machinery I've had issues with.
- You can't easily convert between slices of f32 (like an audio buffer provided by the OS), and slices of Amplitude. Or worse yet vectors of f32 and Amplitude. (This problem affects bulk data in collections, more than scalar types generally passed and returned in the stack.)
An Intuition for Lisp Syntax
2 projects | news.ycombinator.com | 28 Aug 2022
Want to start learning how to code so I can start getting into the gaming industry but don’t no where to start any advice ?
1 project | reddit.com/r/gamedev | 8 Feb 2023
How to contribute to open source projects?
1 project | reddit.com/r/csMajors | 8 Feb 2023
What is the best "first-time" selfhosted project I can do to learn the ropes?
1 project | reddit.com/r/selfhosted | 8 Feb 2023
Alright lads it seems like all the cool projects/companies I want to work in want Java, I'll bite, I come from C#/Typescript, any Java project recommendations I should start on the side?
1 project | reddit.com/r/java | 7 Feb 2023