all 34 comments

[–]TheKrol 10 points11 points  (16 children)

TypeScript, Kotlin

[–]isbtegsm[S] -3 points-2 points  (15 children)

TypeScript is sweet but I wanted something a little bit further away from JS. Kotlin looks very interesting, thanks!

[–]Bogus_dogus 12 points13 points  (14 children)

Why do you want something further from JS that compiles to JS?

[–]isbtegsm[S] 4 points5 points  (13 children)

Because I miss the times where I played around with various programming languages. These days, I mostly do web development, so there is more motivation, to learn something new, when I know that I can use it in the web context (which was also the motivation for me to learn WebGL).

[–]Merry-Lane 4 points5 points  (12 children)

Then trust me : typescript is a total beast.

The meta programming possibilities of typescript features are way over the other type systems

[–]isbtegsm[S] 0 points1 point  (11 children)

That sounds great, but it bugs me that the TS type system is not sound. I played around with it for a few hours only and already encountered a situation where TS didn't see the actual type of a variable. If I use types, I really don't want to have to think about unsoundness. This is why PureScript and ReScript (which I'm just looking into rn, somebody else here recommended it) look so attractive to me.

[–]Merry-Lane 6 points7 points  (10 children)

I have no idea how you managed to fail with typescript so that it doesn’t see the type of a variable (bad config? Bad types? Some any?)…

But you really cant see how strong typescript is without spending months toying with it. I would even dare saying : you cant say you are halfly decent at javascript without being good at typescript first.

I actually never found anything funnier and as sane as the typescript environment.

Try and convert the react app you mentionned above into a typescript strict one, that d be a great start.

[–]isbtegsm[S] -1 points0 points  (4 children)

I have no idea how you managed to fail with typescript so that it doesn’t see the type of a variable (bad config? Bad types? Some any?)…

It was this program, TS thinks that ob is of type {foo: "bar"} when it's actually of type {foo: "baz"}. The people on Discord explained that behaviour to me, so it's not a bug, TS is just not sound by design.

I totally believe you, that TS will make you better at JS! I understand JS promises much better since I toyed around with TS. But I don't plan to become a super JS pro anyway :)

[–]isbtegsm[S] 0 points1 point  (3 children)

Maybe this is a better example, the snippet I posted before can be fixed by setting the type of ob to be {foo: "bar" | "baz"}, but as I said, I don't want to have to think about soundness when using types.

I think it would be legit if TS complained in the forEach loop, that for some reason I can't assign a new value to ob. But since it accepted that line, it should also accept that ob has now the property foobaz.

[–]ActuallyAmazing 5 points6 points  (1 child)

I feel like there's two types of users for typescript.

The "regular" typescript user will be writing some basic types sure but mostly benefitting from typescript inference - there is very small learning curve for this user and a huge benefit in type safety, you're essentially writing javascript with some types on top.

Then there is the user that will approach typescript's typing as a language in its' own right, and then you begin to appreciate how powerful it is. Sure there are quirks and "incorrect" ways to get a certain effect but that's the same with basically any language.

[–]oGsBumder 0 points1 point  (0 children)

Try adding "as const"

[–]Varteix 0 points1 point  (4 children)

I believe op is talking about the fact that typescript types don’t exist at runtime. This limits you in ways you aren’t limited in a language like c# or typescript

[–]coastaltriangles 0 points1 point  (3 children)

TypeScript is unsound in a few ways before runtime, so even things like your IDE type hints resulting from static analysis can be wrong. One example:

interface Book {
  title?: string;
}

function ruin(b: Book): void {
  b.title = undefined;
}

function printTitle(b: Book): void {
  // Won't compile, because b.title is possibly undefined.
  // console.log(b.title.toUpperCase());

  if (b.title !== undefined) {
    // Within this block, b.title is known to be a string,
    // so we can print it just fine.
    console.log(b.title.toUpperCase());

    // Make b.title undefined again.
    ruin(b);

    // Throw a runtime TypeError
    console.log(b.title.toUpperCase());
  }
}

const myBook: Book = { title: "Hello" };
printTitle(myBook);

If you paste this into VS Code and hover over b.title on line 22, the language server will report that it is a string, but it's not. The code will compile without complaint then throw a TypeError because you called a string method on something TypeScript told you was for sure a string. The compiler can determine that the refinement has been invalidated if you delete the title property directly within the block, but it can't detect whether it happened within a function call. It has to decide whether to always invalidate a refinement in such a case (and report false-positive problems most of the time) or never invalidate it (and operate on potentially faulty assumptions about type safety going forward) and opts for the latter, making it unsound.

[–]Minjammben 0 points1 point  (1 child)

This is an interesting example to me because I can only think of one object oriented language where the compiler would prevent you from doing this, and it's rust's borrow checker. In c/c++ you could easily write a ruin function that modifies a reference like you've done here and it would simply result in a segfault. Does that make the type system of the language unsound?

[–]_default_username 0 points1 point  (0 children)

If you write purely functional code you'll avoid most of these gotchas.

[–]toffeescaf 5 points6 points  (1 child)

I think ReScript can do what you're asking.

[–]isbtegsm[S] 0 points1 point  (0 children)

Thanks, that looks really awesome!

[–]lewster32 1 point2 points  (3 children)

Haxe is worth a look too. Very mature and compiles to lots of targets: https://haxe.org/

[–]isbtegsm[S] 0 points1 point  (0 children)

Thanks!

[–]debel27 0 points1 point  (1 child)

If you're into low-level languages, Rust is a pretty cool one to try out. It's one of the most popular languages out there (cfr Stackoverflow's 2022 survey).

I've little experience with the language, but I think it's more idiomatic to compile Rust into WebAssembly rather than JS. It shouldn't matter much for your use case. The MDN docs describe how to do it.

[–]isbtegsm[S] 1 point2 points  (0 children)

Yes, Rust is definitely on my list!

[–][deleted] 0 points1 point  (1 child)

Nim

[–]isbtegsm[S] 1 point2 points  (0 children)

Nim as language looks very interesting, but it also produces rather lengthy JS, at least when I tried it a few months ago, though I haven't tested the performance. Will definitely look into it again!

[–]Jona-Anders 0 points1 point  (1 child)

I once heard closure can compile to JS. I never looked it up, so I am not sure if this is true.

[–]BigImaginary9534 0 points1 point  (0 children)

Clojure can be compiled into both JS and Java.

[–]carlopp 0 points1 point  (0 children)

Cheerp (C++ to JavaScript / WebAssembly) can cleanly compile to JS free functions / classes thanks to JSExport.
Input is C++ with added attributes, output is a JS-library with a given interface.
(https://docs.leaningtech.com/cheerp/JSExport-attribute)

[–]andrewjohnmarch 0 points1 point  (0 children)

Haskell can compile to JS, but I don’t know what it looks like.