This analysis looks like a useful public service! Thank you, considerate netizen!
hallettj
Just a basic programmer living in California
- 14 Posts
- 230 Comments
hallettj@leminal.spaceOPto
Programming@programming.dev•The 6 Big Ideas of TypescriptEnglish
3·7 days 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·7 days 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.
hallettj@leminal.spaceOPto
Programming@programming.dev•The 6 Big Ideas of TypescriptEnglish
31·8 days agoIt’s intended to acquaint one with the language, and there is a lot do that. I don’t know what is the right way to write this kind of stuff; but my thinking was if I were learning I’d rather start with this kind of piece before getting into a book.
hallettj@leminal.spaceto
Programming@programming.dev•GitHub Actions Is Slowly Killing Your Engineering Team - Ian DuncanEnglish
1·16 days agoI use sops for NixOS, but those secrets aren’t accessed in CI. For actual CI I’ve used a combination of 2-4 above.
hallettj@leminal.spaceto
Programming@programming.dev•GitHub Actions Is Slowly Killing Your Engineering Team - Ian DuncanEnglish
3·17 days agoThere are a few options:
-
Sops-nix or Agenix store secrets encrypted in the repo. Each local machine needs to be set up with a PGP or an SSH key to decrypt and encrypt as necessary. This is what I do with my NixOS configuration.
-
Manage secrets externally to repo code. I like to use direnv; sometimes I configure the checked-in
.envrcfile to source another file with secrets, that is not checked in. -
Don’t use secrets locally. If secrets are things like deploy keys, and I want all deploys going through CI, then I don’t want secrets configured locally. Instead running a deploy script locally should be a dry run, which doesn’t need secrets.
-
Generate secrets at runtime. This is for cases where the project runs a cluster of services which need to authenticate with each other. For tests with locally running test services, authentication is confined to this isolated system. So secrets can be generated at test time, and written to env or config files that are not checked in.
-
hallettj@leminal.spaceto
Programming@programming.dev•GitHub Actions Is Slowly Killing Your Engineering Team - Ian DuncanEnglish
20·18 days agoWell, I’m in that Nix shop category. For example, I run tests for my OSS project using lots of Python versions. There’s no need to use a Github Actions matrix for that - Nix does it more efficiently. Doesn’t even require containers or VMs. And the whole setup runs exactly the same locally, on Github Actions, or on Garnix. (But Garnix has better Nix caching than other CI runners, so that’s what I use.)
hallettj@leminal.spaceto
Programming@programming.dev•January 1st is not always on the first week of the yearEnglish
5·21 days agoHow is that? Do you mean that week 1 can occur twice? Or is there another issue?
IIUC you can have days at the start and the end of the year that are all in week 1, and those are two different weeks. But one of those would be, let’s say, week 1 year 2025, and the other would be week 1 year 2026. According to the blog post if you have a week 1 at the end of a year the ISO year number for that week is the next year.
hallettj@leminal.spaceto
Neovim@programming.dev•A Guide to vim.pack (Neovim built-in plugin manager)English
1·30 days agoThis is a helpful guide!
hallettj@leminal.spaceto
Star Trek Social Club@startrek.website•Karim Diané on playing Star Trek’s first gay KlingonEnglish
12·1 month agoAll we know is that Jellico swooped in and saved the day!
I guess there is sort of an implication in Chain of Command that Troi chose to wear a “non-standard uniform” until Jellico ordered her to change. He says, “I prefer a certain… formality on the bridge. I’d appreciate if you wear a standard uniform.” I’ve just done a TNG rewatch, and I’m pretty sure there is no other in-universe explanation given.
hallettj@leminal.spaceto
Nix / NixOS@programming.dev•Locate Nix Packages Like A Pro | Search All Packages for All Files with nix-index - VimjoyerEnglish
6·1 month agoThe comma command is magic! Of course I use it often to run something that I don’t feel like I need listed in my main config - especially a command that I just want to run once. But there are also plenty of cases where I do want to add a package to a config, and I know the command that I want, but I don’t know which package it comes from. The comma is a real easy way to find out.
I haven’t watched the video - maybe these tips are already in there. If you run a command like
, digyou’ll often be prompted to choose which package to get the command from, if the same command is provided by multiple packages. So that’s one way to get a package name. If you don’t get that prompt you can use comma as a lookup tool like this:$ , --print-packages dig Packages that contain /bin/dig: - dig.dnsutils - bind.dnsutilsOr you can ask comma to show you the path of the executable it would run, and infer the package name from the path:
$ , --print-path dig /nix/store/qm1hvm2hfryx7xz9k3njsb6gksvs29is-bind-9.20.18-dnsutils/bin/digThe Nix store path format is
/nix/store/<hash>-<pname>-<version>-<output>so that is thednsutilsoutput ofbind, which isbind.dnsutils.So that gives me package names I can put in my NixOS config, or devshell, or whatever. In this case I could install any of
dig,bind,dig.dnsutils, orbind.dnsutils. (They all end up pointing to that binary inbind.dnsutils.)
hallettj@leminal.spaceto
Nix / NixOS@programming.dev•Locate Nix Packages Like A Pro | Search All Packages for All Files with nix-index - VimjoyerEnglish
1·1 month agodeleted by creator
hallettj@leminal.spaceto
Risa@startrek.website•Forgive me, Doctor, for I have sinned: I haven't watched anything Trek in almost 2 monthsEnglish
7·2 months agoWhat’s the problem with either of these?
hallettj@leminal.spaceto
ADHD memes@lemmy.dbzer0.com•Water, Hazelnut Coffee and Strawberry Fanta <3English
5·2 months agoI think coffee can fill all of these functions
Plenty of tools are using the system keychain. There are good libraries that provide a generic interface to gnome-keyring or kwallet depending on what is running. When I was working with Node I used the keytar library for that purpose.
Edit: Oh, apparently there is a standard DBus API for keyrings. So you can use libsecret to interact with whatever keyring.
hallettj@leminal.spaceto
Star Trek Social Club@startrek.website•[Star Trek Voyager] To me, "Retrospect" episode is not as bad as "Blood Fever"English
6·2 months agoI think two things can be bad at the same time. I do think Retrospect is more problematic than Blood Fever because the implication in Retrospect is, “don’t take women at their word”. Vorik’s assault on B’Elanna in Blood Fever is obviously wrong, even if it is not adequately addressed in the episode. OTOH the story in Retrospect makes it seem like almost a reasonable position to assume that a sexual assault allegation is false until proven otherwise. That’s a problem.
It is very difficult for a woman to come forward with an assault accusation; and when they do those accusations are dismissed far too often. That leaves women with all of the consequences of coming forward, but without any justice, making it even less likely that future assaults will be reported. To put an end to sexual assaults, it’s necessary to believe women.
hallettj@leminal.spaceto
Star Trek Social Club@startrek.website•I want to know more of the breen.English
111·2 months agoMy impression from DS9 is not that they are bounty hunters, but that they are isolationists, and are probably zenophobic. The Breen government allies with the Dominion because they see some benefit for themselves. I don’t think it’s a guns-for-hire situation. It seems like the Dominion is quite good at using enticements and threats to cajole self-serving governments that otherwise wouldn’t get involved in quadrant power struggles.
The masks do bear a resemblance to Star Wars bounty hunters. They remind me most of Leia’s bounty hunter disguise. There’s a suggestion that the reason they wear masks and full-body suits is to confuse outsiders. Weyoun says that despite rumors of being extremely cold, Breen actually has a pleasant climate, and so no one knows why they wear refrigeration suits. But since that comes via Weyoun, who knows what’s true.
hallettj@leminal.spaceto
Star Trek Social Club@startrek.website•The Undiscovered Country: Why is the galley set so worn out?English
11·2 months agoTIL the Enterprise A only served 7 years. But yeah, that’s plenty of time for cosmetic wear to build up in a well-used galley
Edit: The Enterprise A was commissioned in Voyage Home. According to Memory Alpha Undiscovered Country takes place 7 years later.
hallettj@leminal.spaceto
Star Trek Social Club@startrek.website•Episode Discussion | Star Trek: Starfleet Academy | 1x06 "Come, Let's Away"English
11·2 months agoLearning Nus is short for
NusiferNustopher made me chuckleEdit: Thanks for the correction @Routhinator@startrek.website !



Yes, that’s right. Everything except for Javascript’s usual dynamically checked types are erased.