- jashkenas 2009
I'm doing a (free) operating system (just a hobby, won't be big and professional like gnu) for 386(486) AT clones. This has been brewing since april, and is starting to get ready. I'd like any feedback on things people like/dislike in minix, as my OS resembles it somewhat (same physical layout of the file-system (due to practical reasons) among other things)."
My thinking is, not only can I do amazing front-end stuff on the web, but I can do front-end GUI applications that aren't reliant on Electron thanks to OCaml magic.
[0]: https://github.com/onivim/oni2#introduction
JS has had switch statements for a long time. Do you mean switch "expressions" that can be used inline? It's not pretty but JS has long supported that too using either eval() "hacks" or IIFEs: https://stackoverflow.com/questions/32451049/is-eval-the-onl...
Do you mean pattern matching? There are two Stage 1 TC39 proposals with different approaches to it:
More hands-on/direct: https://github.com/tc39/proposal-pattern-matching
More indirect: https://github.com/tc39/proposal-do-expressions
> list comprehensions
There are several libraries with strong Iterator support today that while not syntactically gorgeous do great jobs at allowing you to write simple list operations. Off the top of my head are IxJS and iter-tools, but also classic mainstays like up to date versions of lodash and Ramda.
There's a Stage 2 proposal to bring more of them into "the standard library": https://github.com/tc39/proposal-iterator-helpers
There's also a Stage 2 proposal for an operator to make the syntax generally nicer no matter the library: https://github.com/tc39/proposal-pipeline-operator
> array slicing
Array.prototype.slice() was added back in ES2015: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...
Array.prototype.at() was "just added" in ES2022 for unary (single argument) "slice" (ability to use negative indexes): https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...
If you prefer syntax to function calls, there's a Stage 1 proposal still live for that: https://github.com/tc39/proposal-slice-notation
> better equality operators
That ship has probably sailed. Most projects at this point just have linter rules to standardize everything to the more reliable "triple equals" (===, and !==).
There are proposals for more structural equality functions in the standard library, though, for instance: https://github.com/tc39/proposal-array-equality
Edit: this is explained a bit here [1]. It uses Template Literal Types[2].
1 https://blog.joshuakgoldberg.com/type-system-game-engines/
2 https://www.typescriptlang.org/docs/handbook/2/template-lite...
I have to say, the fact that you can do something so... obscene, but in a way that's actually surprisingly readable, speaks highly of Typescript's type system and design.
Maybe "dependent-but-stringly typed" is possible?
I do really wish TS had actual inbuilt reflective type checking along the lines of this: https://github.com/Hookyns/tst-reflect ...I can hazily see some kind of monstrosity that could come from linking these things together hah
I.e. if I write
type foo = {
bar: "Vodka"
}
I'm guaranteeing that the value of 'bar' on any object of that type must be "Vodka" - the type of bar is not string, it's literally "Vodka" because string values can be types.This seems a little obscure and pointless, but you can put these string types in a union, and enforce that a value must be one of many values.
function doTheThing(color: "RED" | "GREEN") {
//do stuff
}
doTheThing("RED"); //ok
doTheThing("GREEN"); //ok
doTheThing("ORANGE"); //doesn't compile, because the type of the param *isn't* string, it's "RED" | "GREEN"
You can also define a type like type Mountain = { name: "EVEREST", height: 8848 } | { name: "K2", height: 8611 };
and then at compile time know that if mountain.name === "EVEREST" then height === 8848 because the types of name and height aren't string and number, they're "EVEREST" | "K2" and 8848 | 8611, and the compiler is smart enough to work out one based on the other.==============================================
For extra context - a lot of this is for interoptability with Javascript code - you want to call some Javascript function with a stringly typed enum, and enforce only passing in valid values, but the Javascript code still just deals with strings.
A lot of Typescripts kind of insane flexibility is so you can introduce type safety to all sorts of dynamic Javascript code, without having to make sacrifices on the dynamic-ness of it.
Turns out this flexibility is actually kinda awesome to have in general even when you're not trying to refactor an existing JS codebase.
```
type Color = "red" | "blue"; type Quantity = "one" | "two";
type SeussFish = `${Quantity | Color} fish`; // same as // type SeussFish = "one fish" | "two fish" // | "red fish" | "blue fish";
```
doTheThing(readFromUser())
What does the compiler do in cases where you have strings coming in like this?The bigger reason why it is this way is to ensure you can write type annotations for stringly-typed Javascript. While Typescript is it's own thing really at this point, it still is very focused on making it possible to type-annotate JS code.
type Event = 'onClick' | 'onHover'
// some stringly typed javascript can now be nicely typed
something.triggerEvent('onClick', someData)
It lets you do some really nice things, and is quite strongly typed despite how it looks at first glace, while still letting me write some strongly-typed definitions for existing Javascript code that was very much __not__ written with types in mind.In general, however, I still think APIs written in TypeScript first are a lot cleaner type-wise than typings retrofitted onto a JS API. And having TypeScript as an afterthought these days doesn't seem like a good path to go anymore.
Sort of like using Python to generate Typescript, as random example - my Python code doesn't have to typecheck, but its output does, so I can do absurd shit in Python and still feel good about the output.
One example is something like this: https://www.typescriptlang.org/docs/handbook/2/template-lite...
These are types that are built from string templates. Since strings are loose and can be manipulated in crazy ways like appending, we can now manipulate types in the same way. We can write types that are themselves parsers.
So idk if that's good or not, the downside in C++ is that TMP errors are fucking insane, but the upside is that I can have a function that says "pass me something and I'll call "iter" on it and I don't care what that thing is".
It also feelsy kinda more "typey". Types are just values. Types are just strings or numbers or whatever. They're things, with the constraint being that they must exist concretely (or be inferrable) when the type checker runs. No distinction between types and values seems like it's the ideal.
https://github.com/codemix/ts-sql
This project was my go-to "nifty but pointless" example for TS string literal types before this article :)
interface TypeScript {
typeScript: TypeScript;
}This also makes me interested in the formalization attempts I have heard are ongoing for TS’s type system. Anyone with good paper/videos on that development feel free to drop a link.
The link in the post goes to a GitHub repo.