smj-edison 4 hours ago

Not relevant to the discussion on language choice, but I love this part:

> The single remarkable feature of my reader is that I don’t sort posts chronologically but by “reverse frequency”. If I follow a news site that publishes twice an hour and an essayist that publishes every two months, I want the essayist at the top of my feed if they published yesterday, even if there are 30 more recent news posts.

I love the idea of seeing the less frequent posters at the top!

lanthissa 8 hours ago

I really like gleam, the vibes are 'right' for me in that its got a strong type system and a functional style. Coming from scala land, that feels natural.

I think the author hit on a core challenge gleam will have to face, outside of dx. its main niche would be highly scalable type safe server apps, pretty similar to what scala is/was originally imagined as.

Its very hard to occupy that niche when by definition the projects you look to take on are large enough for languages to be heavily scrutinized. Your CTO wont really care if you choose rust, node, or go for some internal tooling. They will absolutely care about what is being used for core distributed services, and that just makes adoption hard.

  • epolanski 6 hours ago

    Most CTOs are great politicians, not great engineers.

  • cle 5 hours ago

    Maybe, but there are also a lot of companies being started right now (compared to the 2010s). Scala and Go were significantly boosted by being used at small companies that got huge (Spark and Docker respectively).

h14h 7 hours ago

I feel like Gleam's ability to compile to BEAM and JS is underutilized.

With how many people in the React/Typescript ecosystem are super excited about full stack type safety, this feature of Gleam feels like it's flying under the radar.

The pieces are there to have an unparraled DX for building everyday web apps, but the pieces haven't been assembled in a way that "clicks" for most people. At least, not that I've seen.

  • hinkley 2 hours ago

    I thought when I moved from Springboot + JavaScript to NodeJS I would enjoy the lack of context switching.

    What I didn’t know about myself is that I hate JavaScript a little bit more than I hate Java and for different reasons. So I was volunteering for stories in one when I was feeling frustrated with the other. Now it’s just more JavaScript unless I work on CLI, CI/CD pipelines, or telemetry bugs, which are still almost half JavaScript. I cannot get away from it enough and every time I do that takes someone else’s opportunity to do the same.

    I worry that all Gleam all the time would arrive at the same conclusion.

  • greener_grass 7 hours ago

    This already exists with F#, OCaml, Scala, Haskell... it doesn't seem to be a big draw.

    • h14h 7 hours ago

      Somehow didn't know this --I can't help but wonder why.

      The effort to make JS work on the server has been much more successful than any attempt to make server languages work on the client. Nothing jumps out to me as an obvious technical reason this is the case -- maybe it's moreso an imbalance in effort & attention?

      • ameliaquining 4 hours ago

        DOM APIs are only available in JavaScript, so doing things in the browser in a non-JavaScript language requires FFI—and it's a general truism of programming that FFI tends to be a pain point. Languages that target client-side web development try to compensate for this by offering language-native DOM abstractions of higher or lower quality, but usually you end up having to do something that these abstractions didn't anticipate, and/or incorporate a third-party library from npm, which forces you back into FFI. On the server it's much rarer for some critical piece of functionality to be available only in one language, because the server environment itself is language-agnostic.

        • grndn 3 hours ago

          As another comment said, you can write client side code in F# which gets transpiled to JS, just like Typescript or CoffeeScript. This approach allows you to use JSX components directly from your F# code. It's very cool. Other FP languages have something similar.

          https://www.compositional-it.com/news-blog/fsharp-react-seri...

        • greener_grass 4 hours ago

          F# allows you to use React pretty much directly, but it has still been only a modest success.

      • mamcx 2 hours ago

        > Somehow didn't know this --I can't help but wonder why.

        JS being the monolithic tyrant that other tyrants see with envy doesn't help.

        In the server and elsewhere you have several major langs with big enough sub-cultures and a stablished ethos of sharing, even if that mean the second biggest tyrant of C.

        JS developers overshadow any other tribe, so that mean that population could have much less exposure to polyglot alternatives.

        And then all that libraries, that are made to make sad any FFI you can trow at it.

        • klabb3 2 hours ago

          > JS being the monolithic tyrant

          There are probably tens of thousands of developers waiting in line to switch out JS. The reason they can’t is not even that it can’t run in the browser (many can) but that it interacts with the DOM natively, which makes it the only language that can be used in the browser without masochism. In turn, the DOM is the only UI that is truly cross platform, which makes it the by far best and cheapest option because everything else is either hobby or proprietary in 10 different flavors depending on which fiefdom you build your product in. Basically, JS isn’t popular because of ability, but its interoperability.

          The effort & money that has been poured into tech after JS was created would dwarf anything beforehand. Yet, we live today by the open standards that were developed before Bezos etc started purchasing private islands. So I’m a little hesitant to blaming JS for being backwards when the rest of the world couldn’t come up with an alternative despite having 1000x (not an exaggeration I think) more time and money to do so.

      • hombre_fatal 4 hours ago

        Server application development is just much different than UI/client development.

        It's easy to make JS work on the server like it's easy to make anything viable on the server: it's just one machine running your code, and the runtime only has to interoperate with a well known interface (the OS) that barely changes. And then consider that a web server's interface to the "user" is over a single, abstract port.

        In a browser application, you have to interface with JS to drive the UI building blocks (DOM and company). And the web API is async. And you have to build an interactive UI. And abstractions on top of all this are extremely leaky because they are hard to simply paper over and pretend they don't exist like you can on the server.

        Often when I see a JS replacement on the browser, it seems to offer very little over JS beyond "hey look, it's not JS" which just isn't enough to justify the penalty.

        Finally, the hard part of UI development is stuff like state management and deciding when things should rerender. Switching to a different language alone doesn't give you that. Figuring out a solution in JS, like MobX + React for example, probably does more for you than trying to make a whole new language work.

  • AzzieElbab 7 hours ago

    It is counterintuitive, but this feature did not do much for the Scala ecosystem. I wrote some toy projects but have not seen any in the real world.

    • lanthissa 7 hours ago

      some of the largest scala codebases under active development make heavy use of this feature.

      • hocuspocus 5 hours ago

        Sure but but the argument here is that Scala.js failed to grow the ecosystem. It doesn't convince people who aren't already.

AlphaWeaver 2 hours ago

> OTP in Gleam is what took me the most effort to figure out. The hexdocs cover the basics but that wasn’t enough for me to get the concepts right, especially where they differed from their Erlang counterparts.

This was the biggest thing I noticed as well- core OTP concepts like gen_servers and supervision trees aren't covered in the language tour, the docs, or even the "Gleam for Erlang Users" page... it makes sense that it's missing if it's pre-1.0, but I was very confused when I didn't find anything about it at all.

evnp 7 hours ago

Nice read, appreciate the balanced analysis. I love how `use` seems to have become the defacto keyword for "weird stuff happens here," we have Gleam's `use` now, `use` v `import` in Elixir... `useEffect` hijinx elsewhere...

  • krashidov 4 hours ago

    There's also using in typescript (maybe soon in javascript).

    https://www.totaltypescript.com/typescript-5-2-new-keyword-u...

    Not sure I'm a fan of it tbh

    • evnp 2 hours ago

      Interesting, thanks for highlighting. It does seem like a good set of patterns for the language to cater to. Agree the syntax feels a bit unintuitive at first glance (as opposed to something like `with` context managers in Python, though lack of async probably makes things simpler there).

cardanome 8 hours ago

Honestly with Elixir starting to implement gradual typing and having an mature ecosystem and amazing backend framework, it is probably the better horse to bet on for bigger projects on the OTP.

Not to say say that Gleam doesn't had has it's place, it is a very interesting language, just that Elixir is already a good and battle-proven language.

  • pmontra 4 hours ago

    Elixir has been in that place not too many years ago, on the verge of being mainstream. I'm not very sure that it's not still there now but I paid my bills with it for a while and I was generally happy with the language except for the handle this handle that verbosity. I liked the Ruby like syntax but I always said to the other devs in the team that an equivalent language with curly braces would be more successful because it would make many more developers feel at home. Gleam is a { } language and won't scare away anyone coming from C, C++, Java, JavaScript, TypeScript, Rust, Go, etc.

    • ljm 4 hours ago

      It makes me sad that some engineers would legitimately consider a lack of curly braces to be a criticism of a language or a reason not to use it, especially when you look at the absolute atrocities that can be committed with the syntax of many C-style languages.

      Looking at you C++.

lionkor 9 hours ago

> Rust comes with all the systems programming overhead, which in my opinion is not a good bargain if you are not, you know, programming systems. Alas, I’m too old to pick up my own garbage.

Granted, I'm a systems programmer, but I find the difference between Rust's memory model and a managed memory model (like C#'s) not very big. The only difference is that it's trivial to leak resources in C#, and it's very hard to leak resources in Rust.

Happy to get recommendations of a language that has both a GC or similar managed memory model, and also can manage all other resources the same way.

What Rust does right is what C++ tried to do; RAII. Memory is a resource, file- and socket-streams are resources, mutexes are resources, and they are all handled via the same principle that we all know and intuitively understand: Scopes. By extension, reference counting enables doing an AND of all the scopes.

I have never found that to be more mental overhead than, say, python, C#, or Golang, where forgetting to close a file, or forgetting to call Dispose(), or doing it twice by accident, or using mutexes, is a common source of nasty bugs. Extend this to the concurrency model Rust has, where both threads and async can be used, and all the resource management and borrowing just cleanly extends to that to avoid concurrency bugs, and you have unparalleled resource management.

  • virexene 8 hours ago

    I'll have to disagree here.

    Leaking resources in Rust is pretty trivial: create an Rc cycle with internal mutability. By contrast, in languages with a GC, cycles will be properly collected.

    And there is nothing preventing GC languages from tying their non-memory resources to the lifetime of a value like Rust. See Python files, which are closed when the file handle is collected (ie. when all variables holding it go out of scope), and if that's not explicit enough, there's the "with" keyword to explicitly introduce a scope at the end of which the file is closed.

    • pessimizer 6 hours ago

      > Leaking resources in Rust is pretty trivial: create an Rc cycle with internal mutability.

      It's trivial to do on purpose, but difficult to do accidentally.

  • neonsunset 8 hours ago

    In Go, you have to explicitly do a defer. In C#, you just write `using var file = File.Open(...);`. Some methods handle disposal for you - you never interact with it if all you need is

      foreach (var line in File.ReadLines("example.txt")) { ... }
    
    Here, file handle will be opened once you start enumeration and will be closed through enumerator disposal which is one of the calls foreach is desugared into (to be accurate, this specific implementation will also close the handle when reading the last line, but I'd expect user-authored type to do handle closure through dispose implementation only)

    I agree that Rust implicitly inserting drop() by proving the exact place the value gets dropped at is superior, but C# experience is not exactly terrible either.

    • CharlieDigital 8 hours ago

      To be clear, `Dispose()` (aka `using`) is not the same as GC. It just cleans up unmanaged resources (connections, file handles, etc.) and marks the managed entity available for GC.

      • pjmlp 8 hours ago

        Depends, C# and .NET in general have support for manual memory management, it is a matter how it was allocated in first place.

        People keep forgetting CLR was designed to accommodate C++ as well, and during the years some of those capabilities have been exposed to other languages in more easier ways than reaching out to C++/CLI.

    • pjmlp 8 hours ago

      Additionally, there are Roslyn analysers that will complain when we forget about using.

innocentoldguy 7 hours ago

I'm sure Gleam fits a niche—maybe something similar to Elm?—but I can't justify using it over Elixir because I'm not willing to trade things like

1. Full access to the BEAM.

2. Full access to OTP behaviours and other features.

3. Lisp-style macros.

4. Late-bound function calls.

5. Dynamic message passing.

6. Native supervision trees.

7. Internationalization.

for static types. Doing so feels like trading my car's engine for a suction cup phone holder.

(EDIT: Fixed formatting.)

  • juped 2 hours ago

    Elixir is all in on being an OTP language, and is a friend, not competitor, to Erlang (go ahead, call one from the other freely, the only friction is that module name atoms look a little weird in the other language).

    Gleam is not entirely foreign but it sets itself further apart; it's all in on cloning Rust.

    (Elixir's set-theoretic type system is _not_ a constructor-soup ML deal, by the way. The people who talk about "static type systems" now are people who caught the ML bug and think "is like ML" equals "types", and they will not find it satisfying, just like they don't find existing Dialyzer types satisfying. So that's the niche for Gleam.)

  • cardanome 5 hours ago

    Yeah, especially as Elixir is gradually gaining gradual typing support so you will get some level of static type safety anyway.

johnisgood 8 hours ago

> don’t make it a reasonable choice for applications that require computation efficiency

Solely or alone (only) computation efficiency, otherwise use NIFs and/or Ports.

kristopolous 8 hours ago

I've suspected gleam is really good candidate for generative coding for a while. Reading it and writing it seems to require a pretty small window of attention.

  • lanthissa 8 hours ago

    agreed, intuitively, referential transparency + strong types 'feels' like it should be the best ai programming language.

    and exhaustive pattern matching + result types should help as well pushing issues out of runtime.

brap 9 hours ago

It’s a nice language, and I like Lustre, but `use` is truly ugly.

I don’t understand why they didn’t make promises a first class citizen and added something like `await`. We’ve learned this lesson in JS already.

  • crackrook 2 hours ago

    I've written a fair amount of Gleam for personal projects at this point and I actually really like `use` when the alternative is excessive indentation / callback hell. That said, I do feel like its existence is a bit contradictory to the language's stated goal of simplicity; `use` is not an orthogonal feature, and I could see it being the subject of much bike-shedding in a team setting.

    Languages that have explicit goals of simplicity, like Go, have become increasingly attractive to me after working professionally with Scala for the past 3 years. Though I love Scala's expressiveness, the fact that there are a million ways to accomplish each objective makes decision paralysis and bike-shedding in code review inevitable.

  • mightyham 8 hours ago

    Your complaint doesn't make sense to me because `use` is essentially the same thing as `await` in JS. It hoists the rest of the function body into a callback so that the logic can be flat. In fact, `use` is an improvement on `await` because it is more generic and avoids the issue of function coloring. Promises also don't make as much sense in BEAM languages where callback based asynchronous code is not all that common or encouraged.

    • tmountain 5 hours ago

      I'm still learning Gleam, but I do not believe that "use" has anything to do with async. It seems to be a direct riff on Haskell's "do notation" syntax sugar (<-), which is used for unwrapping monads, but Gleam seems keen on insulating users from these details at the surface level.

      The author of the article has an intuition that "use" is helpful for error handling, and it definitely is because one of the core benefits of monads is chaining certain categories with a guarantee that nothing will blow up in the process; however, use cases are broader, as you can chain all sorts of things.

      Looking at it now, it's actually akin to clojure's threading operator, which basically just simplifies syntax when making successive function calls (argument threading). Whatever the case, it's not just for errors/async, but more so for chaining without causing a bunch of unnecessary indents to occur.

      • lpil 2 hours ago

        Hello! I'm the creator of Gleam.

        > It seems to be a direct riff on Haskell's "do notation" syntax sugar

        It's not this at all! It may seem this way at first as Gleam's `use` is used in many of the same places as Haskell's `do`, but `use` is a much more general syntax which is used for a much wider array of things. They also work very differently, `do` being constrained by types and laws, while `use` being purely a syntactic feature with no type restrictions or laws.

        • tmountain 42 minutes ago

          Wow, thanks for the reply, and correction! I look forward to learning more about Gleam, as I've just started with it, and I'm really enjoying it so far.

  • lpil 2 hours ago

    Erlang doesn't have promises. The main draw of the BEAM ecosystem is that it has a different concurrency system which is capable of many things that the JavaScript one is not.

  • rdtsc 3 hours ago

    Why use await when you have processes? Await would feel very much out of place in the erlang world.

  • sureglymop 5 hours ago

    I actually find kotlins syntax for this a bit more verbose and less confusing. But there are tradeoffs for both.

  • greener_grass 7 hours ago

    The JS approach is worse than a do-notation approach because it is not extensible. Now we are stuck without cancellation token propagation (forever?)

VWWHFSfQ 5 hours ago

> The thing is: Rust comes with all the systems programming overhead, which in my opinion is not a good bargain if you are not, you know, programming systems. Alas, I’m too old to pick up my own garbage.

I struggled with this as well when I first started programming Rust. Until I got some great advice on the rust-users forum one day: just clone.

You don't have to struggle with the borrow checker, lifetimes, or anything else if you don't want to. Just clone everything. It's usually all your Pythons, Gos, and anything else with a GC is doing anyway. Clippy will tell you the easy places you can fix it. And when you get better and more confident, then you'll spot it yourself too.

So just clone, who cares. The RAII is going to clean up after you no matter what.