News for hackers. Stuff that matters.
Re:Ink: React for Interactive CLI Apps by angra_mainyu on Friday November 01, 2024 @03:17PM (#42020534)
Not to mention:

      type Thing = string | boolean;

      const arr: string[] = [];

      function add(item: Thing, dst: Thing[]): void {
        dst.push(item);
      }

      add(false, arr);

Is valid typescript.
Re:Ink: React for Interactive CLI Apps by adamscybot on Friday November 01, 2024 @03:43PM (#42020770)
If you are used to structural typed systems though this actually "feels" expected. Don't get me wrong, I know where you are coming from. But the realisation comes from nominal systems, which are different beasts. As long as it actually evaluates to the expectations in the head of the developers using it, then that's okay.

However, regularly it's not the case -- especially with people moving from nominal systems.

TS can't really be practically nominal when it has to be constrained by its compile target. So I guess it ultimately boils down to an anomaly/criticism born from the legacy of how web standards came about.

Re:Ink: React for Interactive CLI Apps by consteval on Friday November 01, 2024 @04:31PM (#42021245)
Nominal type systems are pretty much better across the board IMO. Much safer and much less to keep in your head. Modern langs like Rust or F# have very complete and nice to use type systems.

But yeah unfortunately not sure if JS is an appropriate target for these type systems. Nim does it, but I'm not sure how safe it is.

Re:Ink: React for Interactive CLI Apps by adamscybot on Friday November 01, 2024 @05:13PM (#42021609)
One language that comes to mind is ReasonML. It doesn't have runtime checking. It's structural and compile time, but the guarantees are supposedly cast iron. https://reasonml-old.github.io/guide/language/type#design-de...

    type thing = 
      | String(string)
      | Bool(bool);

    let arr: list(thing) = [];

    let add = (item: thing, dst: list(thing)): list(thing) => {
      switch (item) {
      | String(s) => dst @ [String(s)] 
      | Bool(b) => dst @ [Bool(b)]    
      };
    };

    let newList = add(String("asd"), arr);

This doesn't work, since the dst array has to be one that can contain both string and bool in the first place.
Re:Ink: React for Interactive CLI Apps by Capricorn2481 on Saturday November 02, 2024 @11:15AM (#42026867)
To me this is expected? Thing is supposed to be one or the other. If I wanted a homogeneous array I would use a generic <T> for the add function, which makes more sense for a function that just pushes to an array anyway.
Re:Ink: React for Interactive CLI Apps by trenchgun on Saturday November 02, 2024 @04:14PM (#42028945)
arr was defined to be an array of strings. How are you pushing a boolean there?
Re:Ink: React for Interactive CLI Apps by Capricorn2481 on Sunday November 03, 2024 @04:11PM (#42036122)
Because you've given the function no information on whether those two "things" are related. You're saying when it gets passed into that function it can be treated as either with type widening.

I understand it may be unwanted at first glance, but this is a contrived example for demo purposes. You wouldn't really make an "add to array" function like this so specifically. You would use generics, which would solve the exact issue that is posed.

    function add<T>(item: T, dst: T[]): void {
        dst.push(item);
      }
Now you can work with any array, and it will only add items with the right type.

If you really need it to be just <Thing>, you can do this

    function add<T extends Thing>(item: T, dst: T[]): void {
        dst.push(item);
    }
Now it knows that Item and DST are related but need to be Thing.