what also sucks is the effect on 3rd world countries - which due to lack of industrialization are low polluters.
but the biggest thing that makes me -- mad are the climate change deniers.
what also sucks is the effect on 3rd world countries - which due to lack of industrialization are low polluters.
but the biggest thing that makes me -- mad are the climate change deniers.
Another interesting point of reference are "refinement types", which allow you to specify things like ranges to "refine" a type; the various constraints are then run through a kind of automated reasoning system called an SMT solver to ensure they're all compatible with each other.
It makes a lot of things impossible. For example, if you defined two different types of ranges, OneToFifty and OneToHundred similarly to your PercentType above, the following code would be problematic:
let x: OneToFifty = <...>;
let y: OneToHundred = <...>;
y = x;
Any human programmer would say the third line makes sense because every OneToFifty number is also OneToHundred. But for a compiler, that's impossible to determine because JavaScript code is Turing-complete, and so it can't generally say that one is certainly a subset of the other.In other words, any two custom-defined types like that would be unassignable from and to each other, making the language much less usable. Now add generics, co-/contravariance, type deduction, etc., and suddenly it becomes clear how much work adding a new type to the type system is; much more than just a boolean function.
That said, TypeScript has a lot of primitives, for example, template string types for five-digit zip codes:
type Digit = '0' | '1' | '2' | '3' | <...> | '9';
type FiveDigitZipCode = `${Digit}${Digit}${Digit}${Digit}${Digit}`;
(Actually, some of these are Turing-complete too, which means type-checking will sometimes fail, but those cases are rare enough for the TS team to deem the tradeoff worth.) type Enumerate<N extends number, Acc extends number[] = []> = Acc['length'] extends N
? Acc[number]
: Enumerate<N, [...Acc, Acc['length']]>
type NumberRange<F extends number, T extends number> = Exclude<Enumerate<T>, Enumerate<F>>
type ZeroToOneHundred = NumberRange<0, 100>
One limitation is that this has to be bounded on both ends so constructing a type for something like GreaterThanZero is not possible.Similarly for zip codes you could create a union of all possible zip codes like this:
type USZipCodes = '90210' | ...
Often with the idea you have in mind the solution is to implement an object where the constructor does a run time check of the requirements and if the checks pass instantiate the instance and otherwise throw a run time error.In functional programming this is often handled with the Option which can be thought of as an array with exactly 0 or 1 elements always. 0 elements when a constraint is not met and 1 element when all constraints are met.
This [0] is a library I wrote for JS/TS that provides an implementation of Options. Many others exist and other languages like Rust and Scala support the Option data structure natively.
I understand the desire here. Runtime type checking is often necessary for data validation, and we can see lots of libraries developed to help fill the gap here. But I think the fact that there are so many libraries with different design decisions is pretty indicative that this is not a solved problem with an obvious solution. We knew this going into the early design of TypeScript, and it's a principle that's held up very well.
What have been happy to find is that we've grown TypeScript to be powerful enough to communicate precisely what runtime type-checking libraries are actually doing, so that we can derive the types directly. The dual of this is that people have the tools they need to build up runtime type validation logic out of types by using our APIs. That feels like a reasonable level of flexibility.
I'm imagining a language where I could define a custom data type with a regular function. For instance, I could have a method that the compiler would use to verify the validity of what I input, as shown below:
function PercentType(value: number) { if (value > 100 || value < 0) throw new Error();
return true;
}Is the lack of such a feature in TypeScript (or any language) a deliberate design decision to avoid unnecessary complexity, or due to technical constraints such as performance considerations?
My WPM decreased by around 25% and I actually found Colemak to be rather uncomfortable; with QWERTY (and DVORAK) you tend to alternate stroke between hands. Even if there is more finger travel, it just feels right to me.
Also, having a different layout than the peers around you is an absolute pain.
My conclusion is that having an alternative layout is not worth the marginal improvements if any it may offer. If I was forced to try another layout though, I would try DVORAK.
“ChatGPT, please update the website to the latest meme framework”
And with that they were all obsolete
Did the author express that his intent was to capture browser marketshare? If not, he may not be delusional :)
(solopreneur and someone that works in a 4 people startup)