Settings

Theme

Building a hybrid native application with Gleam and Tauri

wezm.net

102 points by wezm 2 years ago · 19 comments

Reader

dcre 2 years ago

Recently learned about Gleam and am very interested in it as someone who always wanted to like Elixir but dislikes the Ruby syntax and lack of static typing. Love this approach to demonstrating the language in context.

As a mostly frontend dev I feel it’s worth mentioning that while it’s a nice way to try Gleam, the Gleam aspect of this is inessential, TypeScript is quite good, and using create-tauri-app with the react-ts, vue-ts, or svelte-ts preset is also a great way to try making cross-platform GUIs with Tauri. It uses Vite under the hood, and the generated app is extremely minimal — nothing like the awful create-react-app behemoths that probably left a bad taste in everyone’s mouth.

  • wezmOP 2 years ago

    > the Gleam aspect of this is inessential, TypeScript is quite good

    TypeScript can be quite productive but I find its type system lacking. Specifically the use of structural typing/lack of nominal typing and lack of sum types. I find these extremely useful when writing reliable software, which is why Gleam appeals to me.

    • Tade0 2 years ago

      That's by all design.

      Does this prevent you from writing reliable software?

    • dcre 2 years ago

      It has sum types! Type unions with a discriminator.

      • wezmOP 2 years ago

        It kinda does if https://www.typescriptlang.org/play#example/discriminate-typ... is what you're referring to but it appears to be missing one of the major benefits: an error/warning if you haven't handled all variants.

        Edit: lots of replies showing how TypeScript can be made to do exhaustiveness checking. It's neat and all but it's a lot of gymnastics compared to languages that just have this built in, which again is part of the appeal of Gleam for me.

        • laurencerowe 2 years ago

          You can workaround the lack of exhaustive matching with the following pattern:

              type Variant = { kind: "value", value: string  } | { kind: "error", error: string } | { kind: "unexpected" };
          
              class Unreachable extends Error {
                  constructor(unexpected: never) {
                      super(`${unexpected}`);
                  }
              }
          
              function useVariant(variant: Variant) {
                  switch (variant.kind) {
                      case "value":
                          return variant.value;
                      case "error":
                          return variant.error;
                      default:
                          throw new Unreachable(variant);
                  }
              }
          
          The `new Unreachable(variant)` will fail the type check only when you have not exhaustively matched all variants.
        • klavinski 2 years ago

          For the most straightforward nominative pattern matching, I would write a small match function:

              type A = { kind: "kindA", a: "dataA" }
              type B = { kind: "kindB", b: "dataB" }
              type Sum = A | B
          
              const match = <
                  const V extends { kind: string },
                  const C extends { [ kind in V[ "kind" ] ]: ( value: V & { kind: kind } ) => unknown }
              >( value: V, cases: C ) => cases[ value.kind as V[ "kind" ] ]( value ) as ReturnType<C[ V[ "kind" ] ]>
          
              // You check the type of result, change the type of value to A or B, make the cases non-exhaustive...
              const howToUse = ( value: Sum ) => {
                  const result = match( value, {
                      kindA: _ => _.a,
                      kindB: _ => _.b
                  } )
              }
          
          You can test it here: https://www.typescriptlang.org/play?#code/C4TwDgpgBAglC8UDeU...
        • smj-edison 2 years ago

          I ran into this exact issue when I was working on a piece of typescript that interoperates with a rust server, here's how I was able to do exhaustiveness checking (the errors aren't the prettiest, but it works): https://github.com/wwtos/mjuo/blob/main/vpo-frontend/src/lib...

          EDIT: and an example of usage: https://github.com/wwtos/mjuo/blob/ca8c514185c1b5bb22aec752a...

        • dcre 2 years ago

          Yeah, that can be annoying. Until pattern matching makes it into JS, the main way people deal with this is to use a library. For example, ts-pattern lets you stick `.exhaustive()` at the end of a match call and I believe you get the error at typechecking time, not runtime.

          https://github.com/gvergnaud/ts-pattern

        • superice 2 years ago

          Oh that’s easy to fake with type narrowing:

          function expectType<A, B extends A>() {}

          expectType<never, typeof yourUnion>();

          The function call will fail at compile time if yourUnion is anything more than never, which you can use in your else case of if statements that narrow the discriminated union.

  • weatherlight 2 years ago

    Gleam's type system is just a Hindley-Milner type system. Which is tried, true and simpler, and extensively battle tested.

    Typescript's type system isn't sound. Gleam's is.

manusachi 2 years ago

For those who is interested, as mentioned in the article, Gleam is already near v1 (v1.0.0-rc2)! And in a recent talk[1] Louis shared the idea, that there won't be major changes to the language anymore, and the main focus now is switching to the tooling!

https://www.youtube.com/watch?v=clsTrQUt-4M

endigma 2 years ago

You should disable overflow scroll for your code blocks its bad UX on mobile to get scroll trapped in a code block (iOS/Safari)

anentropic 2 years ago

FYI Celcius -> Celsius

https://en.wikipedia.org/wiki/Celsius

  • wezmOP 2 years ago

    Ahh whoops. Will fix in the morning, thanks.

    Edit: fixed now (might take a few mins for the cache to expire).

brigadier132 2 years ago

Oh wow, I did not know they developed a js backend for it.

jasonjmcghee 2 years ago

Heads up, the link to the code repository at the top of the post 404d for me.

  • wezmOP 2 years ago

    Oops, thanks for heads up, I had it set to private. Should be fixed now.

    • mariusor 2 years ago

      Also Celsius is the name of a guy, and you're misspelling it throughout the code base. :)

Keyboard Shortcuts

j
Next item
k
Previous item
o / Enter
Open selected item
?
Show this help
Esc
Close modal / clear selection