Sky – an Elm-inspired language that compiles to Go (github.com)

by whalesalad 89 comments 183 points
Read article View on HN

89 comments

[−] melodyogonna 39d ago
That's two new languages compiling to Go making HN frontpage in as many days. It seems people like everything about Go except the language itself. Me? I like everything about Go including the language, these transpiled languages are interesting though.

But I keep wondering if they could integrate at a lower-level than the source code. Like how JVM languages integrate at the bytecode level, or LLVM languages at the LLVM level

[−] MichaelNolan 39d ago

> But I keep wondering if they could integrate at a lower-level than the source code.

I’m sure they could, but targeting go source code has the benefit of giving early adopters an escape hatch. If it targeted LLVM directly, I would never consider using this at work since the risk of it being abandoned is too high. But since it targets go source, I would perhaps consider it for some low importance projects at work.

[−] seabrookmx 39d ago
The standard go toolchain doesn't use LLVM. Go has its own assembly format and machine code generation.
[−] sbrother 39d ago

> people like everything about Go except the language itself.

Thanks for putting so succinctly exactly how I feel about Go!

[−] lenkite 38d ago
I like Go as well, but I wish the Go team were slightly less conservative about language changes. Only asking for 10-15% less conservatism. It is OK to add one proper new language feature and one good standard library package per year. Or deprecating one language feature and one stdlib package every 2 years.
[−] nu11ptr 39d ago

> But I keep wondering if they could integrate at a lower-level than the source code.

Unfortunately nothing below source code level is stable, so they would constantly be chasing changes after any Go release. I personally wish they would focus on making it accessible, as Go actually has a nice runtime and would make a good language target.

[−] melodyogonna 38d ago
Aha! That would explain things. I was wondering if the Go assembly at least is stable and documented, couldn't really find anything
[−] onlyrealcuzzo 39d ago
What was the other one?

I'm working on a language that transpiles to Zig with a custom Go-like runtime (and no garbage collector, Rust-style Affine movement instead).

Sky seems quite cool, as it's additive to Go in interesting ways.

I originally considered keeping the GC and just transpiling to Go so I didn't need to write a Runtime.

Go rules! It really does. But I HATE writing/reading Go.

So I'm glad more people are doing this!

[−] styluss 39d ago
[−] onlyrealcuzzo 39d ago
Awesome, this is very close to what I originally considered.
[−] gottorf 39d ago

> Go rules! It really does. But I HATE writing/reading Go.

Same. I love the Go toolkits, the compile story, the speed at which it compiles, its backwards compatibility, the fact that stale Go code 10 years old still compile and run, etc., just don't care much for the language itself.

I wonder if the positive attributes of Go aren't compatible with clever types and other developer-friendly features?

[−] osigurdson 39d ago
I understand the motivation as I don't really like writing Go code. Interestingly, I don't mind reading it though (as long as the if err != nil isn't too exhausting).

A transpilation step though? I'll accept that in Typescript (barely) but not for any other language really.

[−] melodyogonna 38d ago
[−] ksec 39d ago
If we think of Go as different kind of C, then having Go as a compiled target seems to make sense as C is a compiled target.
[−] anaumann 38d ago

> But I keep wondering if they could integrate at a lower-level than the source code.

For my version (aptly named "Goto" [1]), I forked the go compiler with the intent of keeping it up to date. All changes I made only apply to .goto files, .go files compile exactly as is and are interoperable both ways with goto.

I paused the project due to hitting type-checking bugs when trying to add non-nillable pointers. Everything before was just desugared directly when converting to AST, but for those I needed to touch the typechecker which was too time-consuming for a hobby project back then (pre-coding agents). I might give it another go sometime as I did like the full interoperability aspect.

[1] https://github.com/goto-lang/goto

[−] throwaway894345 39d ago
LLVM and JVM have stable interfaces. Go has an intermediate representation but it isn’t stable. Anyone who wanted to depend on it would be on the hook when the implementation changes.
[−] gethly 38d ago
Go is simple. People like complexity. So the write abstractions to feel better about themselves.
[−] 1-more 39d ago
I will add this to my list of Elm-inspired tools that call to mind Brian Eno's quip about the first Velvet Underground album: "I think everyone who bought one of those 30,000 copies started a band!" With Elm it feels like it's 1% of Elm users creating a language.

https://quoteinvestigator.com/2016/03/01/velvet/

[−] taolson 39d ago
Nice to see another language with Haskell / Miranda type syntax, but the vibe-coded implementation sure shows: e.g. src/Compiler/Infer.sky isUpperStart:

    isUpperStart : String -> Bool
    isUpperStart name =
        case String.slice 0 1 name of
            
            "A" ->
                True
            
            "B" ->
                True
            
            "C" ->
                True
        ... for 23 more cases.
And the corresponding go code in the bootstrap compiler is even worse.
[−] zem 39d ago
at first glance this looks amazing! basically provides everything I have ever wanted in a full stack language. looking forward to experimenting with it.

edit: looking through the docs/examples some more, it looks like javascript interop is fairly clunky, both because it relies on string concatenation to embed fragments of javascript, and because the string concatenation syntax is not great (and the formatter makes it even worse - see the example at https://github.com/anzellai/sky/blob/main/examples/13-skysho...)

I would encourage you to at the least add multiline strings with interpolation support, and ideally add a small compiler for html literals.

[−] skybrian 39d ago
Functional languages have some good and some bad features and there's no reason to copy them all. For example, you don't need to have a Hindley-Milner type system (bidirectional is better) or currying just because it's a functional language.
[−] rkangel 38d ago
Keeps saying "no websocket required" like it's a good thing. The JS client (https://github.com/anzellai/sky/blob/main/docs/design/sky-li...) seems to rely on long polling.

Phoenix LiveView (the inspiration) defaults to using WebSockets because it's much more efficent, but falls back to Long polling if not available.

[−] mmstghjx 38d ago
This is awesome! I love Haskell's syntax, but its adoption isn't where I'd like it to be.

One thing that I don't see is a way to mitigate the "andThen" pyramid of doom.

This happens when you have a language without early returns and you have chain multiple Result returning operations. You can use nested case expressions:

  case operation1 x of
      Ok value -> case operation2 value of
        Ok value2 -> value2
        Err msg -> "error from operation2: " ++ msg
      Err msg -> "error from operation1: " ++ msg

Or nested andThen calls

  operation1 x
     >> mapError (\msg -> "error from operation1: " ++ msg) 
     >> `andThen (\value -> operation2 value)
     >> mapError (\msg -> "error from operation2: ++ msg)
This is nicer to read, but still a lot of noise.

Haskell has do notation to alleviate this but that brings with it the type-class that shall not be named.

Some languages, like Rust, introduce different per-type syntactical solutions such as async/await for Promises and ? for Result.

I particularly like Gleam's use` notation, which is syntactical sugar around functions that take a callback as their final argument.

Do you have a solution for this in Sky?

[−] submain 39d ago
Great work :). Go doesn't have TCO. That means functional languages (no for loops) could blow up the stack. How did you solve that?
[−] danpalmer 39d ago
Wow, this is amazing. I always wanted to love Haskell but never really managed, Elm nailed the balance of usability and correctness, plus the architecture was beautiful.

I've never liked Go, but its strengths are absolutely compiling to single binaries, fast compile times, and concurrency primitives (not necessarily using them) etc. Compiling to Go is a great idea.

[−] librasteve 39d ago
Very cool.

I am comparing this https://github.com/anzellai/sky#tea-architecture with this https://harcstack.org (my thing) ... guess I have some work to do ;-)

[−] flossly 38d ago
I think you have an interesting spot in the design space here...

Have you seen Lamdera? They have a way to use Elm on the server-side that is supposedly acceptable to the Elm-BDFL Evan Czaplicki.

https://lamdera.com/

This talk explains it well: https://www.youtube.com/watch?v=4T6nZffnfzg

Sky does all on the server (more popular lately with HTMX and LiveView), where Elm+Lamdera is basically 2 project and Lamdera ties you into a propietary-ish ecosystem.

[−] desireco42 39d ago
Elm is a language I enjoyed the most. I love Ruby, I loved some other languages, even Haskell I enjoyed, but Elm is special. So let's make this work.

Now that you got foundation created, let's see how to move it forward.

[−] onlyrealcuzzo 39d ago
First - awesome job. Congrats. Self hosting is an accomplishment!

But I'm curious to get your thoughts on the process in hindsight.

I understand why it's valuable: to cast a wide net in catching bugs and give a good signal that your language is generally "ready".

I'm working on a similar language, but worried about going down the self-hosting path, as I think it'd slow me down rather than speed me up.

How did it work for you?

[−] harikb 39d ago
Somewhat unrelated to the language itself:

> The compiler bootstraps through 3+ generations of self-compilation.

I guess it applies to any language compiler, but f you are self-hosting, you will naturally release binary packages. Please make sure you have enough support behind the project to setup secure build pipeline. As a user, we will never be able to see something even one nesting-level up.

[−] __natty__ 39d ago
I would love to see Java inspired language compiled to Go. I really like Go portability and standard library and Java... verbosity. I prefer explicit names, types and all the syntax around that. Graalvm is not an answer for me because as far as I'm aware it doesn't support cross-compile.
[−] riclib 39d ago
Can’t wait to play with it. Great design!
[−] tasuki 39d ago
A bit too bleeding edge for me, but it does look super nice (ie exactly like Elm).
[−] ch4s3 39d ago
If you allow FFI are you really inspired by Elm? ;)
[−] mrichman 39d ago
Compiles to Go or transpiles to Go?
[−] MegagramEnjoyer 39d ago
wow this is pretty cool!
[−] redoh 39d ago
[flagged]
[−] anzellai 37d ago
[dead]
[−] linzhangrun 39d ago
[flagged]