Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Some highlights from this release are listed here[1].

The best part of Gleam in my opinion is the language's design. It's just so elegant to read and write. Take this example code snippet from the release notes:

    pub fn find_book() -> Result(Book, LibraryError) {
      case ask_for_isbn() {
        Error(error) -> Error(error)
        Ok(isbn) -> load_book(isbn)
      }
    }

It's a trivial code snippet, but I'm finding this kind of "first class" pattern matching produces very readable, elegant-looking, well organized code.

There was a discussion the other day about the pipe operator being added to PHP 8.x. Gleam was my first language which included a pipe operator. Now, having used it a bit, I feel every language should have something like it.

    pub fn hello_test() {
      telephone.ring()
      |> should.equal("Hello, Joe!")
    }
The pipe skips so much boilerplate and clearly communicates intent. Absolutely love it.

[1] https://gleam.run/news/no-more-dependency-management-headach...



>It's just so elegant to read and write.

Interesting. I was just about to write the opposite. I tried Gleam to solve last year's Advent of Code, and it felt like a weird mix between Rust and Elixir. You can't write code as elegantly as you'd do in Elixir, which was somewhat disappointing. I switched back to Elixir after a couple of days. I think the biggest advantage of Gleam is static type system.


If you've examples of code you have in Elixir that you could not express well in Gleam I would be very happy to help you out with that.

The two languages are almost the same at the value level, so code should translate across well.


Depending when this was, it was likely pre-1.x days? Things moved very quickly there for a while - it's worth checking back in again.

Gleam seems to have a lot of obvious influences from Rust, and the creator is a rust dev.

While the Gleam ecosystem is vastly less mature than Elixir's or Rust's (because it's literally younger), the language itself, I've found, is vastly more pleasant to read/write. YMMV of course.


> Gleam seems to have a lot of obvious influences from Rust, and the creator is a rust dev.

Hi! That's me!

Gleam the language doesn't have any Rust influence really. It's a happy accident that some of the syntax ended up looking the same, but that's likely due to both being inspired by similar languages such as OCaml and the C family. Most the syntax and the semantics predate Gleam's compiler being rewritten in Rust.

The build tool is a rip-off of Cargo for sure though.


> The build tool is a rip-off of Cargo for sure though.

Hey, great artists steal, as the saying goes...

It's all shaped up really nice. I'm a big fan of Gleam and your work in general.


Thank you, very kind.


more like both gleam and rust have a strong ML influence (gleam might actually consider itself an ML? not sure about that, but it's definitely a descendant)


I prefer Elixir's syntax over Gleam's, but my main issue with Gleam is architectural. Specifically, Gleam had to bastardize BEAM and OTP to implement static typing. To me, static typing vs. dynamic typing is like having a shelf with a doily vs. one without a doily (the shelf works fine either way), so messing up a solid Actor Model implementation, for instance, for the sake of static typing seems like the wrong thing to do.


How does it bastardize the beam? Like are there things you can do in elixir/erlang that you couldn’t with gleam?


It has been a while since I looked at Gleam. Some things may have changed. However, the last time I used Gleam, I was forced to switch back to Elixir because Gleam:

• Lacks support for named processes.

• Has limited actor abstractions.

• Doesn't support OTP system messages.

• Has implemented supervisors in a way that can lead to improper shutdowns, data loss, and deviations from the expected BEAM behavior.

• Doesn't support pattern matching directly in function definitions. Instead, it requires you to use case statements.

• Doesn't support global mutable variables because it has no way to track variable types and state changes when BEAM modifies these variables, which is one of the hallmark features of BEAM.

• Doesn't support hot code reloading.

All of these features, which are readily available in Erlang and Elixir, are far more important to me than static typing. I've used statically typed languages like C, C++, C#, and Java, and dynamically typed languages like Python, Ruby, and Elixir throughout my 30+ years career. I've never once lamented not having static types, nor have I ever jumped for joy when I do. For me, static vs. dynamic typing is largely irrelevant and doesn't affect my work one way or the other.


I'm curious to know what the parent meant, as well. My understanding, which is incomplete admittedly, is that Gleam's type system lives in Gleam and isn't carried over into the produced Erlang/BEAM code, since BEAM has no concept of types, etc.

Gleam also has an OTP implementation[1] available, which includes Actors and the like. My understanding is that every BEAM language must implement OTP themselves, so there's nothing unusual here.

[1] https://hexdocs.pm/gleam_otp/


Gleam's type system is the root cause of the problem. Please see my reply to the parent of your post.


Omg yes, pattern matching is such an amazing feature I miss it dearly in languages that don't have it!


I'm so envious of this. In TypeScript I use ts-pattern and Effect Schema, and while they make this logic way nicer, it's insanely verbose and doesn't offer any of the niceties of being first class.


I have not used it at all, but Gleam does have a javascript target in it's compiler/build-tool. So in theory, you can write Gleam (strongly typed, etc) and produce js.

I've exclusively used the BEAM/Erlang target so far - but the js community within Gleam seems quite interesting.


I've been considering trying this, but my team already struggles to properly adopt TypeScript so I'm fairly sure introducing Gleam would cause a few people to throw me out a window.


Gleam is so much smaller and easier than typescript and the type system works harder for what it is. TS gets you because it is similar to javascript in some ways that make it easier to start the transition. But a complete js -> ts transition is about as big a deal as it would be from js to any other language, except you can use the same external libraries.


No just no


Sorry but yes. Pure structural typing is a dead end hindley milner is the future.


;)


Error(error) -> Error(error) has strong if err != nil { return err; } vibes, and I don't consider that a good thing.


No, it doesn't have strong if err != nil { return err; } vibes.

Pattern matching on Ok/Error is one of the best known error handling, while go error handling is one of the worst. They are about as far from each other as possible.


Interesting, I find myself thinking the exact opposite.


That's what Gleam's use expressions[1] are for (the last example is exactly this case). Most languages with the same heritage as Gleam have grown a similar syntactical feature, such as OCaml's binding operators or F#'s computation expressions. Although I appreciate how simple Gleam's is while having similar power.

[1]: https://gleam.run/news/v0.25-introducing-use-expressions/


This is a trivial snippet. Often you will transform/map your error into another type (or deal with it in some way), so it's not so much `if err != nil { return err; }` vibes like you're thinking here.

The beauty here is being compelled to handle both the happy and sad paths. You cannot just pretend the sad path doesn't exist.


Good Go code also wraps errors...


It's not just about wrapping. use-expressions, result.try and result.map eliminate the boilerplate of checking for errors entirely: https://erikarow.land/notes/using-use-gleam


One man's boilerplate is another man's explicitness.


snake case convention is the only thing that always feels odd to me.

Perhaps its because I deal in TypeScript all day, every day, but it never stuck with me.

That said, small price to pay for a very nice runtime!


I come from js/ts as well and I find snake case much more readable than camel after using it in other languages for a bit. There are even js/ts projects that use snake case despite the camel case convention, for readability

https://github.com/sveltejs/svelte/issues/3479#issuecomment-...


Yeah, CamelCase for modules, snake_case for functions and variables.

Your brain can instantly tell what entity you’re dealing with.


I come from a background where everything is camelCase. Naturally I wrote my JSON this way as well, among other things.

Switching to snake_case was challenging at first - I kept writing things in camelCase. Now, I've become pretty fond of snake_case and have a tough time going back into environments that require camelCase - funny thing, that is.

Thankfully Gleam's build tool/language server has a fairly strongly opinionated formatter built in, so it will let you know pretty quickly and help you fix it.


One thing I disliked is black, the Python formatter, with its utterly naive rules, that treat all code the same. It required me to workaround in many places, like always using a trailing comma for any list or tuple, to keep the items on separate lines, instead of black fumbling around and putting them on the same line. It was utterly annoying. This made me very vary of "opinionated" (read: inflexible unconfigurable pieces of software) formatters. Hopefully Gleam's formatter isn't as stupid as black is.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: