I love a good philosophy meme! Reminds me of this philosophy help desk comic: https://existentialcomics.com/comic/51. That one doesn’t have Wittgenstein’s perspective
hallettj
Just a basic programmer living in California
- 3 Posts
- 182 Comments
At least you remembered your pants
hallettj@leminal.spaceto
Programming@programming.dev•Why do so many programming languages have their own package manager?English
6·8 days agoI agree that this doesn’t seem necessary. Personally I think Nix would be a good candidate for dependency management that works consistently between languages. I think that may be partway set up for Haskell, and I’ve noticed that nixpkgs has a good collection of Python dependencies. But for most cases the Nix flow currently usually involves using the language’s bespoke dependency manifest to generate a Nix expression that downloads dependencies from the language’s bespoke package repo.
One advantage of Nix is that you don’t need all packages in one repo. Nixpkgs is mostly geared for the NixOS Linux distro. Each language ecosystem could have its own repo if that makes the most sense, with Nix being the common connective language.
I’m using Rust on the server, Typescript on the client. Some very interesting options have appeared in Typescript over time for better ADT handling!
ts-pattern provides a match function that verifies matches are exhaustive. Yes, it’s a static check. It’s got a powerful matching language that does stuff like extract nested properties from complex inputs, like Rust’s match. I recommend reading the documentation - for me it led to some “I didn’t know that was possible!” moments.
I’ve also been using fp-ts to get
OptionandEithertypes. (Eitherinstead ofResultbecause fp-ts is inspired by Haskell.) It has features for processing fallible values as monads which gets close to the conciseness of Rust’s?operator and try Trait, but is more generalized. It also has mtl-ish types likeTaskEitherwhich roughly serve the purpose of a Promise but with an explicit error type.Now that you mention it, must-use detection for
Eithervalues would be helpful. Eslint has a built-in check that does exactly that for Javascript’s native Promise type. I haven’t tried it, but it looks like eslint-plugin-fp-ts has a rule that might do the same for other types.
hallettj@leminal.spaceto
Programming@programming.dev•The git history command deserves more attentionEnglish
1·27 days agoOh, nice! Does this do something like Git Butler where you can have multiple branches “checked out” simultaneously, and keep track of which changes belong to which of those branches as you work? But maybe without the commitment that Git Butler requires to using its tooling?
hallettj@leminal.spaceto
Programming@programming.dev•What do you check first when a CI pipeline passes locally but fails in CI?English
1·1 month agoI try to capture every detail of the build and test environments in Nix devshells. And where I can I try to encapsulate as much as possible in Nix checks and packages which run in build sandboxes - both locally and on the server. Build sandboxes don’t work for everything, but the devshells alone are great for reproducibility.
- Wrong interpreter version? A devshell with a
flake.lockfile ensures every environment is using the exact same interpreter. - Accidentally picking up stuff from the local
.env? Sandboxed checks and builds don’t get any files that aren’t version controlled, so that’s not an issue. But it’s still an issue with devshells. - Accidentally picking up programs or env vars in your environment? Sandboxed builds always get a clean starting environment. If you run
nix develop --ignore-envyou get a devshell that also gets a clean starting state.
Nix doesn’t fix everything.
- File system case sensitivity - depending on where this issue presents (program-generated files vs source files), I use property testing to catch this problem. In fact I was working on exactly that the other day.
- Timing issues - that’s a good old fashioned hard problem. Try to make logical dependencies explicit. It’s really easy to get implicit order dependencies in concurrent code if you aren’t on guard. In languages that support it promises or futures are good for spelling out what needs to happen in what order.
- Edit: Difficulty keeping secrets in sync - one option is to use Sops or Age to put encrypted secrets in version control. Then your CI only needs to be configured with one secret to decrypt the other secrets it needs.
- Wrong interpreter version? A devshell with a
Every time my wife comes back from a work trip she complains that the rental ICE car felt like driving with the parking brake on compared to our little budget EV
It reminds me of Luke Dangler’s flight of the floof painting series
hallettj@leminal.spaceto
Android@lemmy.world•I released v0.3.0 of my LCARS Star Trek theme/generator for Niagara LauncherEnglish
2·2 months agoNiagara is an excellent launcher. I’ll check out the theme!
Thanks for the plug! Bloom County is definitely my favorite print comic
I haven’t done this, but I think this idea is going to stick with me going forward
hallettj@leminal.spaceto
Programming@programming.dev•There’s Never Been a Better Time to Study Computer ScienceEnglish
7·3 months agoOh I was pissed when the bubble burst right before I graduated from high school
hallettj@leminal.spaceto
Comic Strips@lemmy.world•You're the only carpenter in town.English
2·3 months agoIIRC in the movie The Last Temptation of Christ making crosses is kinda his thing
I’m sorry. I’ve often thought the term “temperate climate” is misleading. That’s clearly bipolar
Oh! Is this how bootlegging works?
hallettj@leminal.spaceto
Programming@programming.dev•What do you want out of a coding monospace font?English
4·4 months agoI like to use this style of italics for keywords. (That’s also what the Maple examples do.) My thinking is you see keywords so often that you recognize them by shape, not by reading the individual letters. And my theory is that the italic variant being a little harder to read helps my eyes skim over keywords, to focus more on words that I do need to read precisely, like variable names.
It does mean that I spend some time customizing my syntax highlighting theme to make it work the way I prefer. I’ve got examples set up on my blog. Although that’s not Maple - it’s a different font with cursive italics called Cartograph CF.
hallettj@leminal.spaceOPto
Programming@programming.dev•The 6 Big Ideas of TypescriptEnglish
2·4 months agoYes, that’s right. Everything except for Javascript’s usual dynamically checked types are erased.
hallettj@leminal.spaceOPto
Programming@programming.dev•The 6 Big Ideas of TypescriptEnglish
3·4 months agoI’ve already conceded on point 6 that types are not technically functions, and that I’m making an analogy. I think analogies are in the territory of opinions.
If you really want to argue technical correctness on point 5 then let me try to illustrate more clearly what a type parameter list is. First I’ll cite some sources to clarify terminology.
From the Wikipedia article on Generic programming (emphasis mine):
Generic programming is a style of computer programming in which algorithms are written in terms of data types to-be-specified-later that are then instantiated when needed for specific types provided as parameters.
That sentence cites the book “Programming Languages: An Active Learning Approach” by Kent D. Lee, which uses both the terms “type parameter” and “type argument”.
The Typescript Handbook page on Generics uses the terms “type parameter” and “type argument” many times. Here are some excerpts:
The type of generic functions is just like those of non-generic functions, with the type parameters listed first
Generic classes have a generic type parameter list in angle brackets
(I know we’ve been talking about functions, not classes. But both have type parameter lists, and it’s the same concept in both cases, so I think this line is relevant.)
When we use GenericIdentityFn, we now will also need to specify the corresponding type argument
I think we can clearly establish this terminology as it relates to one of the examples from my article:
function useState<S>(initialState: S): [S, (value: S) => void] { /* ... */ } // ╰┬╯ // This is called a "type parameter" // This is called a "type argument" // ╭────────┴──────╮ useState<"open" | "closed">("open")And you can see here how type arguments bind to type parameters in a way that is directly analogous to value arguments binding to value parameters:
function useState<S>(initialState: S): [S, (value: S) => void] { /* ... */ } // ╰┬╯ ╰────────┬─╯ // │ └────────────────────────┐ // └───────────────────────┐ │ // ─────────┴──── │ // type argument binds to type parameter │ // ────────┬──── │ // │ ───────┴─────── // │ value argument binds to value parameter // │ ──────┬─────── // ╭────────┴──────╮ ╭─┴──╮ useState<"open" | "closed">("open")Your counterargument that “Generic functions can have the type specified” is just a different way of saying that a type argument binds to a type parameter.
Just in case the issue is with the use of the word “list”, a generic function can have multiple type parameters. Thus, a list. Here is another example from my article that demonstrates a list of type parameters:
// Two type parameters make a list // ╭────────────┴─────────────╮ function getOrDefault<Obj, Key extends keyof Obj>( obj: Obj, key: Key, def: NonNullable<Obj[Key]> ): NonNullable<Obj[Key]> { const value = obj[key] return value != null ? value : def }Note that
getOrDefaulthas a type parameter list, and also has a value parameter list (or simply “paremeter list” if you prefer). Therefore it has two parameter lists.Is the problem that when I use the words “parameter list”, to you that means specifically what I’ve been calling value parameters? And that’s not the same thing as type parameters? I think I’ve been very clear that I’m talking about two lists with different kinds of parameters. If that’s the issue then please make some allowance for the way I’m using terminology, and for the context in which I’m using it.
Maybe the issue is that functions can be called with only value arguments? Or that non-generic functions don’t have a type parameter list? I think I addressed this in my article. Type arguments are implicit, so they can be omitted from call sites. But the type parameter list exists in the generic function definition either way. A non-generic function doesn’t have a type parameter list - but I think an equally valid interpretation is that it has an empty type parameter list, which is expressed in the language by omitting the angle brackets.
Anyway, there’s no way you can say it isn’t true that some functions have two parameter lists when type parameter lists are a thing, and value parameter lists are a thing, and generic functions have both.
You can say that I’m overgeneralizing by saying that all functions have two parameter lists when actually only generic functions have two parameter lists. But I think you’d have to be pretty pedantic to say that makes my point wrong. I think it would be glossing over a nuance. If this is the point you disagree on then let me know.
Or you can say, as I do, that all functions do have two parameter lists, but for non-generic functions the type parameter list is empty, so we don’t write it. That’s my interpretation - or in other words, my opinion, which is not a matter of fact.
hallettj@leminal.spaceOPto
Programming@programming.dev•The 6 Big Ideas of TypescriptEnglish
21·4 months agoatrocious code block font
That’s author’s perogative I’m afraid. But if you have more specific feedback I’ll listen. For example, I’m thinking maybe you object to the handwritten italic font? I like to use that italic for keywords, because I recognize those by shape instead of by reading anyway. I think the use of italic helps me to skim over the keywords, and focuses my eyes on the non-keyword words that I need to pay more attention to. But then there’s always the question of where to draw the line. Like, should built-in types like
numberandstringbe italicized?some of non-code annotations are misaligned (on phone) e. g. nullable string
Thanks for pointing this out! It turns out my monospace font doesn’t have glyphs for box drawing characters, and different web browsers were using different fallback fonts with very different glyph sizes. I configured another font for box drawing, and made sure that it uses glyphs with the same size as the other monospace glyphs. (No, I’m still not going to change the font. It’s my favorite, even if it makes me work a little harder.)
5 is about Generics with emphasis on React. functions don’t “take two parameter lists”. Generic functions can have the type specified.
Yes, functions do take two parameter lists! There is a type parameter list, and a value parameter list, clear as day! The type parameter list is how you specify the type. Just like the value parameter list is how you specify the arguments.
That section is intended to help readers to understand generics by explaining it in a way that they probably haven’t seen before. I wanted to relate the unfamiliar concept to a familiar one.
6 is wrong. types cannot “be functions”. You can do some type algebra on types.
Again, I disagree; and I provided multiple examples. I know that generic types are technically not functions. But I think they sort of do the same thing, which is to transform inputs into some output. In most languages in generics it’s not especially helpful to think this way. But in Typescript there is a lot of sophisticated stuff you can do with “utility” types, and I think it’s helpful to think of those as functions, but at the type level. Once again, this is about relating an unfamiliar concept to a familiar one.
But I did add a note to make it extra clear that types are technically not functions, even if they function like functions.


My dad is involved with a volunteer group for similar emergency radio coordination in the Fort Ross area (in northwest Sonoma County). I don’t think they’ve gotten into the mesh protocols yet.