Gleam Is Pragmatic

(blog.drewolson.org)

250 points | by crowdhailer a year ago ago

60 comments

  • jazzypants a year ago ago

    > I won’t fall into the trap of trying to define Monads in this post. Instead, let’s talk about monadic-style APIs – that is, APIs that allow you to do a bunch of things one after another, with the ability to use the result of a previous computation in the next computation, and also allows some logic to happen between steps.

    Am I crazy, or did he just give a really good definition of monads in programming? I think that it benefits by not letting itself get bogged down in Category Theory nomenclature which doesn't actually matter when programming.

    • marcosdumay a year ago ago

      He described a problem people use monads to solve, not monads themselves.

      Haskell people do talk about monadic vs. applicative combinators that are different by whether you can use the results of a previous step on the next ones. But that doesn't have a direct relation with the actual definition of those.

      But yes, if you are teaching a programming language that uses monads to someone, you will probably want to explain the problem they solve, not the actual structures. As most things in math, the structures become obvious once you understand the problem.

    • dkarl a year ago ago

      It's a good description of one application of monads, which is often helpful to beginners if they have been thrown into real code without yet understanding the "why" of monads. If you look up "railway-oriented programming," you'll find more presentations of it.

      I think it is a very practical place to start, especially for programmers who have been thrown into a codebase while still new with monads, because it helps them avoid a common mistake that plagues beginners: accidentally dropping error values on the non-success track. Often you simply want to drop values on the non-success track, and there are convenient idioms for doing so, but just as often, you need to examine those values so you can report failures, by returning metrics on validation failures, by providing the right status code in an HTTP response, etc. Railway-oriented programming is a vivid metaphor that reminds programmers that they need to make a decision about how to handle values on the other track.

    • bos a year ago ago

      No, this isn’t a good description of monads. It merely describes a case that shows up sometimes.

    • cdelsolar a year ago ago

      A monad is just a monoid in the category of endofunctors, what's the problem?

    • memco a year ago ago

      Yin the OOP world I’ve seen this pattern called chaining : usually either method or object chaining.

    • orthoxerox a year ago ago

      Not really. The big important part of monads is flattening/unnesting the output.

      Basically, if you can convert a `Foo<T>` into a `Foo<U>` by applying a function `T -> U`, it's a monoid. Think `map` or `fold`.

      But if you can convert a `Foo<T>` into a `Foo<U>` by applying a function `T -> Foo<U>`, it's a monad. Flattening is "some logic", but not any logic, it's inherent to `Foo<>` itself.

    • agumonkey a year ago ago

      It's a good spit, some people used to describe them as "programmable semi colon" but while it's simple, it may be too short for most people to grasp.

    • RexM a year ago ago

      I think you just fell into the trap.

  • atemerev a year ago ago

    The greatest power of BEAM-based languages is the fully preemptive actor model. Nobody else supports it. This is a superpower, the solution of most problems with concurrent programming.

    In Erland and Elixir, actors and actor-based concurrency hold the central place in the corresponding ecosystems, well supported by extensive documentation.

    In Gleam, actors and OTP are an afterthought. They are there somewhere, but underdocumented and abandoned.

    • steve_adams_86 a year ago ago

      This is exactly what I want from Gleam. It does seem to be under documented and abandoned. Is there any understanding of why? Like you say, this seems like a super power. I see so much potential. A language that’s ergonomic, pragmatic as the author says, great performance, low-ish barrier to entry, etc. It seems like it could be an awesome tool for building highly reliable software that’s not so difficult to maintain.

    • sodapopcan a year ago ago

      Are there any articles that do a deeper dive into this? I ask because straight up I've been curious about Gleam, but not enough to do a really deep dive because Elixir is too good and, like Erlang, is a very special kind of dynamic language that doesn't leave me feel too lacking.

      As I understand it, there have been a few "high profile" attempts to bring static typing to Erlang, all of which gave up when it came to typing messages. Your comment essentially confirms my bias, but is Gleam making real strides in solving this, or is it poised to merely cater to those who demand static-typing with curly braces--everything-else-be-dammed?

    • jatins a year ago ago

      this is Gleam OTP package https://github.com/gleam-lang/otp

      I agree it's underdocumented but doesn't seem abandoned (has commits in last week)

    • lpil a year ago ago

      Hello! I’m the maintainer of the Gleam OTP library. It is not abandoned or an afterthought.

    • dullcrisp a year ago ago

      I understand things best by comparing across different languages so don’t take this the wrong way but I wonder if you can help me understand: If say I start a goroutine in Go and give it a channel to use as a mailbox, concurrency in Go is cooperative but it’ll automatically use OS threads and yield whenever it reads from the channel. Does Erlang/OTP do something different? If so what does it do and what are the advantages? Or is it more that the library and ecosystem are built around this model?

    • vereis a year ago ago

      Gleam runs on the BEAM

  • skybrian a year ago ago

    Gleam's 1.0 release was in May and it's still adding major features.

    JavaScript support looks interesting. Browsing the package repo, I don't see how to tell which packages are supported on Erlang's VM, when compiling to JavaScript, or both. JavaScript-specific documentation seems pretty thin so far?

    • oDot a year ago ago

      You're right about the lack of FFI-specific docs, but Gleam is such a simple language that it's very workable.

      I wrote Vleam[0], which allows writing Gleam inside Vue SFCs, and the experience was pretty good even without the docs.

      You do have to sometime read the source of other Gleam packages to understand how things work, but again -- Gleam is so simple it's not too bad of an experience.

      [0]: https://github.com/vleam/vleam

    • lpil a year ago ago

      Most of the work for this has been done, the main missing piece is surfacing it in the UI, which someone will hopefully pick up soon.

  • patte a year ago ago

    This is a very concise overview! I have made a small example chat app [1] to explore two interesting aspects of gleam: BEAM OTP and compilation to javascript (typescript actually). If anyone is interested...

    [1]: https://github.com/patte/gleam-playground

  • rossng a year ago ago

    The `use` syntax is interesting - don't recall seeing anything similar before. But I'm struggling to understand how exactly it is executed and a glance at the Gleam docs didn't help.

    Is the `use` statement blocking (in which case it doesn't seem that useful)? Or does it return immediately and then await at the point of use of the value it binds?

  • fire_lake a year ago ago

    Gleam looks nice but if an F# comparisons was added, I think that would come out ahead based on the authors priorities.

    • devmunchies a year ago ago

      One thing I dislike with erlang based languages (both gleam and elixir) is that they use “<>” for string concatenation.

      In F#, “<>” is the equivalent of “!=“. Postgres also uses <> for inequality so my queries and f# code have that consistency.

    • cipehr a year ago ago

      The author links to a blog post talking about railway oriented programming in f#.. it might be fair to assume they are aware of f#

    • munchler a year ago ago

      I converted the example on the Gleam home page [0] to F#:

          let spawn_task i =
              async {
                  let n = string i
                  printfn $"Hello from {n}"
              }
      
          // Run loads of threads, no problem
          seq { 0..200_000 }
              |> Seq.map spawn_task
              |> Async.Parallel
              |> Async.RunSynchronously
              |> ignore
      
      The two are pretty similar, but I would give F# the nod on this one example because it doesn't actually have to create a list of 200,000 elements, doesn't require an explicit "main" function, and requires fewer brackets/parens.

      [0]: https://gleam.run/

    • stonethrowaway a year ago ago

      [flagged]

  • steve_adams_86 a year ago ago

    Wow, this is a great overview. I’ve been playing with Gleam a bit and this was really helpful. I’ll definitely refer to this later.

    I’d like to dig into the OTP library (I’m curious if anyone has worked with it much?) and create a state chart library with it, but I’m still firmly in the “I don’t totally get it” camp with a few parts of Gleam. I don’t deny that it’s pragmatic. Maybe it’s more so that I’m not up to speed on functional patterns in general. I was for years, but took a hiatus to write code for a game engine and supporting infrastructure. It was so Wild West, but I kind of liked it in the end. Lots of impure, imperative code, haha.

    • okkdev a year ago ago

      Most people use the OTP lib! There's this super useful intro repo: https://github.com/bcpeinhardt/learn_otp_with_gleam

    • conradludgate a year ago ago

      I've tried to get my head around functional programming and also OTP but I also just never got my head around it.

      Functional programming seems too limiting and OTP seems more complicated than I would have hoped for a supposedly distributed concurrency system.

      I'm sure it's just a skill issue on my part. Right now I'm way too rust-brained. I've heard lots of things about gleam being good for productivity but I don't feel unproductive writing web apps in Rust but I felt every unproductive trying to write a non-trivial web app in gleam

  • beanjuiceII a year ago ago

    tried gleam but the fact i have to manually serialize/deserialize things, pretty annoying, that doesn't seem very pragmatic

    • steve_adams_86 a year ago ago

      Isn’t manual ser/de pretty common? I like it personally. Being explicit at program boundaries usually means far fewer bugs inside the program. In JS I can pile whatever JSON I want into an object, but eventually I need to throw Zod or something at it to tame the crazy.

      Maybe a generic “pile this data into this value and pretend it’s safe” tool might be nice for prototyping.

    • __jonas a year ago ago

      I agree that the stdlib decoder functions aren't the most ergonomic, but I think people are aware it's a pain point and there is development in that are, these two packages for example:

      https://hexdocs.pm/decode

      https://hexdocs.pm/toy/

    • lawn a year ago ago

      This is the biggest reason I cooled a bit on Gleam and whenever I want to do some backend stuff I'd much rather use Rust (using serde to convert to structs) or Elixir (put it in dynamic maps).

      I wish Gleam would implement some kind of macro system, making a serde-like package possible.

    • wonger_ a year ago ago

      This is one of the complaints people have with Elm too. Json.Encode/Decode is a pain

  • Degorath a year ago ago

    I understand why the `use` syntax is preferable for its generalizability to many different "callback style" things, but the whole construct of `use foo <- result.try(bar())` is so much worse than defining let* in ocaml and being able to write `let* foo = bar() in`...

    • lpil a year ago ago

      What would you say makes it much worse?

  • amelius a year ago ago

    > Running on the battle-tested Erlang virtual machine that powers planet-scale systems such as WhatsApp and Ericsson, Gleam is ready for workloads of any size.

    Does a Gleam programmer in practice need to deal with Erlang? Do Erlang error messages leak through?

    • giacomocava a year ago ago

      Pure Gleam will get you really far without having to touch any Erlang, I've done Gleam for almost a year now and there were very little cases where I needed to write Erlang code myself, usually there's already a library that deals with it for most common needs :)

  • d--b a year ago ago

    Doesn’t it compare mostly to F#, rather than Haskell or OCaml? The examples in the post really look like F# to me

  • ogogmad a year ago ago

    Is there a way to implement matrix arithmetic with nice syntax (for instance, "A + B" to add two matrices A and B) in Gleam? The lack of ad-hoc polymorphism might paradoxically be a blessing.

  • vivzkestrel a year ago ago

    newbie here, how does gleam compare to golang, rust and python?

    • widdershins a year ago ago

      It has some syntax similarities to Rust, but it has GC so there's no borrow checker (or any of the associated syntax). It is also fully immutable, unlike Rust. It leans heavily on sum types, just like Rust. Also expression-based syntax and some other things resemble Rust. However, it lacks Traits. Overall it looks Rust-ish but it's much simpler and has a functional focus.

      With Go it shares a lazer focus on simplicity and preemptive channel-based concurrency. But of course for all the above reasons listed above it looks very different from Go in most other ways.

      In many way its language choices are the opposite of Python (static types, immutability, massive concurrency is the norm).

  • oldpersonintx a year ago ago

    [dead]

  • stonethrowaway a year ago ago

    [flagged]

    • zelphirkalt a year ago ago

      Does the C# runtime or language or so have any of the abilities that a BeamVM language can make use of? Afaik Gleam can do the same things you can do with Erlang, easily making a cluster of machines and easily running code on any of the machines in the cluster, load balanced, pattern matching on binary ...

      Otherwise I don't understand what C# has to do with Gleam.

    • flooow a year ago ago

      What has C# got to do with... anything in this article?

  • behnamoh a year ago ago

    It's not pragmatic if you have to import these basic libs:

    ```

    import gleam/dict.{type Dict}

    import gleam/int

    import gleam/io

    import gleam/result

    import gleam/string

    ```

    • eterm a year ago ago

      Why not?

      What's wrong with a standard library the bits of which you want you choose to import?

    • UncleOxidant a year ago ago

      I guess I don't entirely agree, but I do wonder why each import has to include 'gleam' in the path. Why can't it assume that the default path is 'gleam' and import libraries relative to that path. Like `import string` instead of having to do `import gleam/string`?

  • zombot a year ago ago

    The syntax doesn't look like it supports partial application? Big no-no. Also, no compilation to native code. Another big no-no.