Settings

Theme

Moonbit: Fast, compact and user friendly language for WebAssembly

moonbitlang.com

313 points by dlib 2 years ago · 161 comments

Reader

hongbo_zhang 2 years ago

Hi, I am the lead of this project, you can try it now with our online IDE, https://try.moonbitlang.com (F5 to run)

The docs are available https://github.com/moonbitlang/moonbit-docs, the compiler would be publicly available when we reach the beta status (expected to be the end of Q2 in 2024).

Feel free to ask me any question

  • sizediterable 2 years ago

    These are the usual questions I seek answers to first when seeing a new programming language:

      - What does writing asynchronous code look like
      - Will it have any novel or less mainstream features, e.g.
        - Algebraic effects [1]
        - Contexts/Capabilities [2]
        - Linear types [3]
      - Is the type system sound and does it support/need type casts
      - Does the language support interfaces/traits/protocols
      - How rich are generics, e.g.
        - Explicit variance annotations on type parameters
        - Lower or upper bound constraints on type parameters
        - Higher-kinded types
      - Is structural vs nominal subtyping more prevalent
      - Does it have algebraic data types? Generalized algebraic data types?
    
    [1] https://v2.ocaml.org/manual/effects.html

    [2] https://docs.hhvm.com/hack/contexts-and-capabilities/introdu...

    [3] https://austral-lang.org/linear-types

    • hongbo_zhang 2 years ago

      Thanks for your interest.

      Note Moonbit is a language/platform for industrial usage(not an academic language), I contributed to OCaml so that I am familiar with the good/bad parts of a type system. Its aim is to build fast and run fast, and generate the tiny Wasm output.

      Type system is sound, you can take it as Rust(- some features hinder fast compilation) with GC and an emphasis on data oriented programming, so we have ADT, generics, interface and ad-hoc polymorphism. We also plan to make the pattern match more expressive with first class pattern support.

      The async story is constrained by the WASM runtime, we will evolve with the Wasm proposal.

      • wffurr 2 years ago

        I thought the raison d’être for Rust was not having a GC. If this is a garbage collected language, and requires a runtime for such, isn’t this more like Go or any JVM language?

        • yawpitch 2 years ago

          Arguably the raison d’être for Rust is memory safe systems programming, and opt-in GC you implement as / if needed is just a consequence of that… if you’re not targeting the very small subset of systems that _cannot_ benefit from automated GC then that’s a great choice, but for everyone else it’s just complex boilerplate. This is aimed at an evolving runtime spec that already incorporates opt-in GC.

          In other words if it’s Rust’s broader features but explicitly meant to write programs for a runtime that already includes opt-in GC, then it’s not doing what JVM languages or Go are doing, so there’s space for it.

        • spion 2 years ago

          For situations where you can afford a GC, Rust but with GC would be an excellent language, due to the ways macros are done, traits work, how errors are handled, tools like cargo, docs.rs, testing and doctests, self-contained binaries with additional ability to compile extra assets into them, high quality language server (rust-analyzer), and the quality of the ecosystem.

          As it is now, though, regrettably Rust imposes on you the penalty of dealing with borrowing and ownership even when there is no reason to pay for that. Its not too bad in most cases but one can't help but imagine a Rust-but-with-GC world :)

          • afavour 2 years ago

            > one can't help but imagine a Rust-but-with-GC world

            Rust with reference counting gets you a long way there. I’ve leaned in Rc<> a ton in some projects and had a pretty great experience.

            • mmastrac 2 years ago

              I built https://github.com/mmastrac/keepcalm/ to specifically give "permission" to use ref-counting to make your life easier. For a webserver, references don't make any sense and really don't add anything measurable from a performance perspective.

              • afavour 2 years ago

                That’s awesome. I do think someone smarter than me needs to write a “Pragmatic Rust” book, or something. The complexities around references and lifetimes put a lot of people off but really aren’t necessary a lot of the time.

          • wffurr 2 years ago

            For that world there is also Rhai (https://github.com/rhaiscript/rhai), TypeScript, Scheme, etc.

            Though Moonbit does look nice too.

          • necrophcodr 2 years ago

            If you want some of the ergonomics and DX of Rust, but in a GC'd language, OCaml (the language also used to implement early Rust compilers) might be more the path to be taken. Great tooling, handlings errors in sensible ways, and pattern matching, allows you to move business logic faster and focus on shaping data rather than transforming the bytes of them.

        • blovescoffee 2 years ago

          They're just talking about the type system. Yes the type system in Rust serves it's GC-free goals but you could copy paste the type system and build other languages with different goals.

  • tgv 2 years ago

    I think people would like to know about licenses, pricing, and control over the project. Perhaps your commercial strategy doesn't benefit from divulging that information now, but secrecy and uncertainty can kill interest.

    • hongbo_zhang 2 years ago

      It is in an very early stage, but I expect it will be free to use as normal users. To be honest, we are also thinking about how to make the project more sustainable in the long term, the project is maintained by a team of professionals who also need be paid. We will figure this out when we reach the beta (in the end of Q2/2024)

    • Etherlord87 2 years ago

      What a great question, immediately made me realize I don't need it (killed my interest).

  • MarcScott 2 years ago

    Your docs at https://moonbitlang.com/docs/syntax/ are unreadable due to the text and background colour

    • rapnie 2 years ago

      I may also point to the image on the announce page is 4.7 MB.

      • jwl4fun 2 years ago

        The image size should be smaller now, it's about 200k, thanks for your feedback :)

        • andrewcobby 2 years ago

          Each line of code on the homepage hero appears to be truncating the last character for me (W11/FF/ultrawide screen). Somewhat comically yielding `moon new hell` XD

    • hongbo_zhang 2 years ago

      Sorry, we are fixing that, should be better later

  • curist 2 years ago

    Is having a dedicated fn keyword necessary? I mean, what’s the fundamental difference between a func and a fn ?

    • hongbo_zhang 2 years ago

      Not strictly necessary, we are not decided on it.

      For func the annotation is required, while fn does not need any type annotation

      • darkest_ruby 2 years ago

        I would strongly recommend to only go with one syntax, and not differentiate between regular functions and lambda statement

        • ledauphin 2 years ago

          I disagree - allowing for type inference on the closures will make for a much more pleasant language, whereas requiring type annotations on top level functions makes sense for lots of reasons.

          • troupo 2 years ago

            > allowing for type inference on the closures

            You can still have your type inference without forcing the unnecessary requirement that local functions be `fn` while top functions be `func`.

            • andrewcobby 2 years ago

              I agree with this, I'm designing a similar language and have gone with this approach. Same syntax for all functions, but top-level functions require explicit type annotations (purely for documentation/sanity more so than a technical requirement).

            • ledauphin 2 years ago

              agreed, but there's still differentiation in syntax, and I was responding to someone asking for no differentiation.

  • kardianos 2 years ago

    * Is there a need to differentiate func and fn? * Part of the function signature is "->" to indicates what it returns. Is this arrow needed? * For new types, you use syntax "struct User". I think Go got it right in this case where types are created with "type User struct", which can also create function types for fn variables like "type AssignUser func(name: String, id: Int) -> Int". * Does it help the lexer/parser to have the ":"? In function signature, do you need the ":" in func(name: String)? Could it be "func(name String)"? Same with type declaration but not assignment "mut elems: List[Int]", could that not be "mut elems List[int]"?

    I'm picking nits. Overall I like it.

    • politician 2 years ago

      I agree, it seems like there are a lot of decisions for the syntax to make writing the parser easier. It almost seems like the assumption is that there will be a robust autocomplete service available for inserting the extra notation.

      The func/fn thing though with type inference of return values is especially annoying though because you won’t be able to hoist it to a package level function without changes to the signature. Subsequent readers have to perform their own mental return type analysis as well, and that’s just extra cognitive load. When reading code, I like when functions are extremely clear about their inputs and outputs.

      I like that this exists though, and hope the project is successful.

  • thangngoc89 2 years ago

    Oh hey. Wasn't you the lead developer of Bucklescript/Rescript compiler? This gonna be epic.

    • hongbo_zhang 2 years ago

      Yes. Moonbit is heavily influenced by BuckleScript/ReScript. We learned a lot from our previous experience, that's why we are shipping our IDE even in the pre-alpha release. We also learned to how to make type checking fast and parallelisable.

      • andsoitis 2 years ago

        > We learned a lot from our previous experience

        Does this mean you are no longer working on ReScript and you are fully focused on MoonBit?

  • brundolf 2 years ago

    "Moonbit makes programming easier with its automatic memory management, setting it apart from Rust."

    I'm curious how it handles allocations/deallocations (seemingly) without a GC or a borrow checker?

    Edit: I see you mention a GC in another comment (https://news.ycombinator.com/item?id=37186990), but the binary is really small despite that. Does Moonbit just plan to lean on Wasm's proposed built-in GC, once that's ready? And if so, I'm curious how some of the examples in the docs work right now since (I believe) that proposal hasn't been shipped anywhere yet

  • abusaidm 2 years ago

    Nice demo, I tried some of the examples and tweaked to see what happens. I noticed no mention of UTF-8 and I tried to add some arabic letters and other RTL letters and it printed garbage chars.

    Are langs other than english supported?

  • azdavis 2 years ago

    Glad to see new languages designed around having good support for IDEs. matklad (rust analyzer) and I wrote a bit about this:

    - https://matklad.github.io/2023/08/01/on-modularity-of-lexica...

    - https://azdavis.net/posts/pl-idea-tooling/

    I think pure functions, sum/product types, and pattern matching are generally accepted as an excellent way to model and manipulate pure data. I wonder what the team’s thoughts are about handling less pure things like asynchrony and I/O, as well as more interesting control flow like exceptions/panicking, coroutines, generators, iterators, etc.

  • jackcviers3 2 years ago

    In the lexical closure doc example, why choose to show variable name shadowing? What is the purpose of `let x = 3` in the below?

    let x = 3 func foo(x: Int) { fn inc() { x + 1 } // OK, will return x + 1 fn fail() { y + 1 } // fail: The value identifier y is unbound. }

    `foo` also captures the global `x`, but shadows it with the parameter `x`.

    Can `Generics` be generic - are there higher kinds? Are they all invariant, or do they have variance and if so what is the notation?

    Maybe I missed it - can methods be destructured from structs? Can enums have methods?

    Is there partial application for methods and functions?

  • 10000truths 2 years ago

    The docs don't seem to cover how you're supposed to interact with the host environment from within Moonbit. How do you define imported and exported functions?

  • andsoitis 2 years ago

    I loaded the IDE but don't see examples of doing graphics or UI. The docs are also silent on this topic, as far as I can tell.

    Is graphics or UI programming possible in MoonBit?

    • troupo 2 years ago

      It clearly states: it targets web assembly. So, this should answer your question I think

      • andsoitis 2 years ago

        > It clearly states: it targets web assembly. So, this should answer your question I think

        Not sure what you're implying.

        Here's an example of doing graphics using Rust and WASM - http://cliffle.com/blog/bare-metal-wasm/#making-some-pixels

        And another: https://blog.logrocket.com/implement-webassembly-webgl-viewe...

        Given that MoonBit is developing their own IDE and it is hosted on the web, I would think one could provide an elegant pipeline to do graphics programming, no?

        If this were open source, I would contribute in this realm becase I'm a graphics and UI person and also enjoy working with new programming languages.

        • 10000truths 2 years ago

          A WebAssembly runtime is a pure compute+memory sandbox. It can only interact with the host environment in three ways:

          1. The host calls an exported WASM function

          2. The WASM runtime runs code that calls an imported function

          3. The host reads/writes the WASM runtime's memory/globals

          In your example, the WASM build process spits out two artifacts - a WASM module and a JS module. The JS module defines the actual JavaScript host functions that manipulate the canvas, and then exposes those functions to the WASM instance.

        • rapnie 2 years ago

          > I would contribute in this realm becase I'm a graphics and UI person and also enjoy working with new programming languages.

          Maybe the case of Makepad will interest you then: https://news.ycombinator.com/item?id=36567681

          https://github.com/makepad/makepad

      • eole666 2 years ago

        Well, you can do graphics programming in c++ or using a game engine and compile it to Webassembly.. So this language could definitely have a graphics library.

        • WhiteNoiz3 2 years ago

          That's only because the host javascript which loads the WASM is exposing functions to do webgl stuff. When you use emscripten to compile C++ is to WASM, part of that equation is the JS runtimes that allow you to call translate openGL calls to Webgl, play sounds etc. It's possible to do with moonbit, but it would require some work on your part.

  • Lerc 2 years ago

    I couldn't see any reference to default parameters. Are they a thing?

    I would quite like the ability to have something like

    func makeBox(width: Int = 100, height: Int = width) -> BoxThing

    everything else I've seen, I like the look of. One of my litmus tests for languages is to have the ability to make decent Vector types, tuples and operator overloading should perform that function nicely.

    • hongbo_zhang 2 years ago

      `default parameters` and some local features will be elaborated later on. We make the big(non local) features first and add various nice sugars step by step.

  • ledgerdev 2 years ago

    Very cool, I really love to see these new wasm native languages, very exciting.

    Do you have any plans for a standard library? Build one specific for the language, or will perhaps try use or create/collaborate on a cross language standard library based on wasm component model? Is this even possible or good idea?

    May I ask the toolchain you're using to build Moonbit?

  • DonHopkins 2 years ago

    Is there anything for binding Moonbit code to JavaScript, like Emscripten's Embind?

    https://emscripten.org/docs/porting/connecting_cpp_and_javas...

    What do you think of that approach?

    Will things change as WebAssembly evolves?

    • hongbo_zhang 2 years ago

      > Will things change as WebAssembly evolves?

      Yes, but we also plan to support old Wasm versions, like 1.0 etc.

      Note Moonbit is designed in a modular way that it should be easy to target different backends (JS, Native). Currently we are focused on make the Wasm experience optimal(including the debugger)

      • DonHopkins 2 years ago

        Thank you!

        What I meant wasn't Moonbit targeting JavaScript, but integrating Moonbit compiled into WebAssembly with JavaScript, making it so they can call back and forth to each other more easily, like Embind wraps C++ classes, methods, and functions with glue so they are exposed and callable as JavaScript classes, methods, and functions.

        Kind of like what SWIG or Boost.Python (which inspired Embind) does, too.

        The plumbing for integrating JavaScript and WebAssembly is evolving (especially with respect to passing objects and garbage collection).

  • ice-bergg 2 years ago

    Why not go for global type inference? Should be possible with the relatively simple type system

  • Corsome 2 years ago

    Will the compiler be open sourced?

afavour 2 years ago

The site compares it to Rust and Go but to me the comparison is AssemblyScript. It’s also WASM-native and new with relatively little ecosystem around it. But compared to Moonbit it’s a familiar language to anyone that’s used TypeScript. So why use Moonbit over AssemblyScript?

  • noelwelsh 2 years ago

    Because Moonbit is a modern language, while AssemblyScript is carrying forward the mistakes of the past. For example, Moonbit supports pattern matching and most language constructs are expressions. AS doesn't have pattern matching and consists primarily of statements. Moonbit has algebraic data types; it's not clear to me that AS does.

    There might be other differences at runtime, but it's difficult to tell from just the website.

    • andsoitis 2 years ago

      > Because Moonbit is a modern language, while AssemblyScript is carrying forward the mistakes of the past.

      No language has "no mistakes".

      For instance, let's take a language like Scala, which appeared 20 years ago. Has it avoided mistakes of the past? Or lets take Rust, which appeared 8 years ago. Is it "perfect"? Same with Moonbit; it will make tradeoffs and mistakes and whatnot.

      Mistakes are not always technical in nature either. They can be mistakes in positioning, strategy, community, governance, poor documentation, etc.

      • chefandy 2 years ago

        Modern doesn't imply perfect— just that it uses recent advancements.

        • coder543 2 years ago

          In most conversations, TypeScript generally seems to be considered a fairly "modern" language. TypeScript offers a variety of rather advanced type system features, and AssemblyScript is based on it, so by extension, AssemblyScript should be fairly "modern" too.

          Based on the limited docs that are available[0], Moonbit appears to be using C++-style "generics" that are just simple template substitutions (no constraints), which is far less "modern" than what TypeScript offers.

          Honestly, I don't think imprecise words like "modern" are particularly useful, helpful, or good for discussions like this. "Pattern matching" has been a feature of certain programming languages for decades, so is that truly a "modern" feature?

          [0]: https://moonbitlang.com/docs/syntax/#generics

          • chefandy 2 years ago

            I'm not saying it's any more modern than any other language— I pointed out that being imperfect doesn't preclude modernity. Nobody even claimed it was perfect to begin with.

    • IshKebab 2 years ago

      Go is also an old-school statement based language though.

  • NoThisIsMe 2 years ago

    Looks much closer to Grain [1] than AssemblyScript

    1. https://grain-lang.org/

  • csjh 2 years ago

    I think the Rust and Go comparisons are because they’re popular languages with first class WASM support but I agree

    • jedisct1 2 years ago

      Why didn't they include Zig and AsssemblyScript, then?

      • giovannibonetti 2 years ago

        Not OP, but although Zig is pretty good, it is arguably a relatively low-level language for application development. Thinking about pointers, for example, is tiring and unnecessary for most apps.

      • csjh 2 years ago

        No clue, maybe they performed too well :p

garganzol 2 years ago

Having `func` keyword for a top function definition, but `fn` keyword for a nested function definition is evil. It should be either `func` or `fn` independently of a particular context.

  • brundolf 2 years ago

    It might be because nested functions are closures, which are optionally-named, optionally-typed, and can capture values, unlike top-level declarations. It's not unusual for languages to have a special closure/lambda syntax (whether that's really necessary or good is another question, but there's a lot of precedent)

    • garganzol 2 years ago

      Any function is a closure. Top-level function declarations can capture static variables and type members. Nested functions can capture static variables, type members, and local variables of a declaring function. Difference is negligible.

      • brundolf 2 years ago

        Conceptually, as a high-level user of a typical language. But there can be nuanced differences in the implementation and/or the semantics, depending on the language. I don't know if that's true here, but it's certainly plausible.

  • tritipsocial 2 years ago

    I think it's an elegant design decision, because it allows the use of a more compact and readable function definition for nested functions. The 'fn' allows you to omit names and types, and so the shorter keyword (fn vs func) indicates the function definition may also be shorter.

  • Touche 2 years ago

    Really, "evil"?

    • politician 2 years ago

      Excess energy wasted = Unnecessary cognitive load * number of affected (readers + writers) * lifetime of Moonbit code * Calories per thought

      Tongue in cheek, yes, but I’m sure that if we can make this about contributing to climate change via energy consumption then there will be a sufficient group of folks ready to label it evil.

      • troupo 2 years ago

        It also makes refactoring a pain in the ass. Wanna convert your local function to top level? Do unnecessary monkey job of using a different keyword.

noelwelsh 2 years ago

I'm excited to see a modern GCed language that is targetting WASM. Closest comparison is probably Grain (https://grain-lang.org/).

  • frou_dh 2 years ago

    Apparently the Grain compiler is written in ReasonML rather than plain OCaml. Isn't it a bit comedic how readily these niche things are stacked up?

    • noelwelsh 2 years ago

      OCaml syntax is quite annoying ... everything is backwards and it even uses double semicolons! :-)

    • giraffe_lady 2 years ago

      Why? A language's implementation language doesn't affect me much. And isn't reason just a syntax layer on ocaml? The tooling can convert back and forth and the runtime semantics are the same. I can read reason code fine if I need to, but I don't.

  • tempodox 2 years ago

    Grain does look interesting, thanks for the link!

homarp 2 years ago

"The development of an entire language toolchain, previously spanning years or even a decade, has been streamlined through our accrued experience and the establishment of a dedicated talented team from Moonbit's inception. We expect Moonbit to reach beta status by the end of Q2 of 2024, indicating a phase of relative stability, minimal bugs, and a robust Foreign Function Interface (FFI) for interactions with the Wasm host. We will make the source code publicly available once we reach beta quality. Our strategic plans involve Wasm GC integration for Wasm 2.0 and our homebrewed GC for Wasm 1.0, in line with Wasm proposals."

so https://github.com/moonbitlang/ is empty for now

fovc 2 years ago

I see from comments here that Moonbit has a GC. However, the resulting binary for Fibonacci is 253 bytes, which presumably does not include a GC. Is that using the proposed WASM-native GC, or is the build system smart enough to omit the GC since it’s not needed here?

  • andsoitis 2 years ago

    When you right-click on the file and choose Compile to Wat (second last menu item), you can see the WASM text directly.

    This is the output of the Fibonacci example:

    (module (import "spectest" "print_i32" (func $printi (param $i i32))) (memory $rael.memory (export "memory") 1) (table $rael.global funcref (elem)) (func $fib.fn/2 (param $n/1 i32) (result i32) (local $x/12 i32) (local.get $n/1) (local.set $x/12) (block $join:11 (local.get $x/12) (i32.const 0) (i32.eq) (if (result i32) (then (i32.const 0)) (else (local.get $x/12) (i32.const 1) (i32.eq) (if (result i32) (then (i32.const 1)) (else (br $join:11))))) (return)) (local.get $n/1) (i32.const 1) (i32.sub) (call $fib.fn/2) (local.get $n/1) (i32.const 2) (i32.sub) (call $fib.fn/2) (i32.add)) (func $fib2.fn/1 (param $num/2 i32) (result i32) (local $n/4 i32) (local $acc1/5 i32) (local $acc2/6 i32) (local $x/16 i32) (block $join:3 (local.get $num/2) (i32.const 0) (i32.const 1) (local.set $acc2/6) (local.set $acc1/5) (local.set $n/4) (br $join:3)) (loop $join:3 (result i32) (local.get $n/4) (local.set $x/16) (block $join:15 (block $join:14 (block $join:13 (local.get $x/16) (i32.const 0) (i32.eq) (if (result i32) (then (br $join:13)) (else (local.get $x/16) (i32.const 1) (i32.eq) (if (result i32) (then (br $join:14)) (else (br $join:15))))) (return)) (local.get $acc1/5) (return)) (local.get $acc2/6) (return)) (local.get $n/4) (i32.const 1) (i32.sub) (local.get $acc2/6) (local.get $acc1/5) (local.get $acc2/6) (i32.add) (local.set $acc2/6) (local.set $acc1/5) (local.set $n/4) (br $join:3))) (func $init/3 (i32.const 3) (call $fib.fn/2) (call $printi) (i32.const 46) (call $fib2.fn/1) (call $printi)) (export "_start" (func $init/3)))

  • csjh 2 years ago

    Probably smart enough, since code size is part of their mission statement

conaclos 2 years ago

This makes me think about Grain [0] - another Wasm-first programming language. This could be nice to add Grain to the comparison.

[0] https://grain-lang.org/

pmontra 2 years ago

About Team links to a edu.cn page in Chinese. It seems a university project but I can't confirm. The Join Us page is another Chinese one. The examples on the home page seem to require JavaScript from baidu.com.

  • Erlangen 2 years ago

    Demos still work with umatrix plugin on. It requires script from unpkg and msecnd(microsoft domain), but not baidu.

taklimakan 2 years ago

That’s not how you’d implement fibonacci in Go

  • spion 2 years ago

    I'm not a fan of Go, but I have to admit that benchmark doesn't make any sense. If you use tail calls in a language that doesn't support TCO, then of course you'll get bad results.

    I guess its easier to just throw in some numbers than compare idiomatic implementations and then discuss tradeoffs with some nuance.

    Even if its just a language teaser, I'd still add a note on TCO to avoid misleading people though.

  • makapuf 2 years ago

    Yes, using WASM and Go in an contrived example and not mentioning tinyGo is not very honest.

    • ghusbands 2 years ago

      Do you have reason to believe that tinyGo would do better on that particular benchmark?

      • csjh 2 years ago

        Based on the name, I’d imagine part of TinyGo’s raison d`être would be a smaller binary size. Plus, seems optimized for speed rather than speed-of-compiler

  • tgv 2 years ago

    That's not how you'd implement it in rust either. It's a pretty bad benchmark. From my experience, I'd guess it's lack of tail recursion and the switch statement. That one can be slow in Go.

    It is however a good teaser for Moonbit.

MikeTheRocker 2 years ago

Is this project associated with Meta? The creator Hongbo Zhang worked at Meta on some of their open source programming language projects (ReasonML and Flow). According to LinkedIn, he's still employed there.

depr 2 years ago

Who funds the development? Will there be paid features?

iFire 2 years ago

No license.

https://github.com/moonbitlang/moonbit-docs/

pxeger1 2 years ago

Interesting how this is written like a corporate press release.

jacquesm 2 years ago

What is your long term plan?

Do you intend to support this language indefinitely?

  • hongbo_zhang 2 years ago

    Yes, it will be my last project before retirement, we have a very ambitious goal and long term vision.

    • jacquesm 2 years ago

      Thank you, that really helps. Too many abandonware languages already. If you are close to retirement it might be a good idea to get a governance structure in place that survives your retirement. That way the language isn't tied to you personally.

lemper 2 years ago

in an era where there are too many choices for writing things, if you don't show how your language is different and/or better compared to other languages which almost definitely more popular, then you'll lost before you start. I mean, show some example and I'll decide if it's worth to try. for this language? sorry, I'm not sold in the slightest.

  • loeg 2 years ago

    Halfway down the page is some (tiny) comparisons to Go and Rust, highlighting some differences and then elaborating (in prose) as to why that's better. We're both reading the same article, right? "A taste of MoonBit."

phosphorco 2 years ago

Well. I am very excited by this. We've built our front end in F# with Fable and our backend/engine is in Rust which compiles to WASM.

The WASM story came second, and it'd be really cool to eventually lean into something like this, particularly given the much faster compilation time.

Have followed your work on Rescript, and excited to see that this is where you've taken things.

thefounder 2 years ago

I like it a lot tbh b/c it looks a lot like Go.

Unfortunately Go is unusuable as wasm target for browsers due its huge binary. The browser needs a lot of time to download and parse it. Not to mention it starts to crash if your app is large enough(i.e a complete SPA in Go only).

  • aatd86 2 years ago

    Yeah, Go has to embed the whole runtime and that amkes for huge payloads.

    I'm interested in your experience as I've been working on wasm SPA with Go.

    How does it crash? Seems to me that there are examples of stable webapps (for instance using go-app).

    Were you using a framework or raw syscall/js call?

    Have you tried compiling with tinyGo?

    • thefounder 2 years ago

      I've been using my own wrapper/library around syscall/js. It crashes mostly due memory issues/allocation. My own app worked fine until a point and then it started crashing.

      I applied several temporary fixes by limiting the amount of memory it allocates at start-up. Then optimised various libs to use less memory such:

      - instead of generating the html in pure Go using x/html package and applying it to the DOM later I created my own /x/html like package using the DOM (via syscall/js) directly. This was a big optimisation.

      - "cleaned" up/forked some public libraries such these provided by Google. For example many of Google's libraries (and not only) use an OpenTelemetry component that's cpu/memory intensive(at least for wasm/browsers).

      - replaced some libraries with my own implementation(i.e aws library) reduced to only the API calls I need.

      Now it stopped crashing in firefox/chrome (at least on my computer) but it crashes on Safari(at least on mobile). At this point I stopped working on it because I feel the platform is just not ready and I no longer have the drive to fix it(been working for more than 2 years on it).

      As you can see it forces you to think about resource management and browser compatibility and you are working in the dark b/c these limitations are not published/official.

      Keep in mind that I didn't run intensive tasks. Just SPA stuff(web services requests, data rendering etc).

      I didn't try to compile it with tinyGo because I built my tooling/libraries based on Go and unfortunately I do not have the resources required to support yet another platform/compiler(tinyGo). I made extensive use of reflection and last time I checked tinygo had some issues/restrictions with that. Recently I've implemented generics as well(where it made sense).

      I may revisit Go with WASM if/when there is a WASM-GC integration.

      The good part is that perf issues aside it made UI apps development a pleasure(for me at least).

      • aatd86 2 years ago

        I see. In my experience, the wasm target is very allocation-sensitive.

        I've had to implement a few free-lists myself and went for allocation hunt.

        Perhaps it's a memory leak somewhere.

        If you have some code example, maybe I can have a look.

bbkane 2 years ago

Looks quite nice, but you should add a banner to the load screen for https://try.moonbitlang.com that it will take quite a while to load and the page is not broken.

  • lolinder 2 years ago

    I'd assume that's not normal and is just due to being on the front page of HN.

neoneye2 2 years ago

Suggestion. Rename from `func` to `fn` so it's more aligned with Rust.

  • tritipsocial 2 years ago

    The `fn` keyword is already used for local functions, which allow a more compact function definition than `func`.

csjh 2 years ago

I’ve been considering trying my hand at a C-like WASM language, with most features mapping directly to WASM instructions. Surprised no one’s done something like that yet. Very cool tech

  • moron4hire 2 years ago

    What about AssemblyScript? https://www.assemblyscript.org/

  • WhiteNoiz3 2 years ago

    There are a few.. Zig compiles to webassembly and looks fairly C-like. You can also use Cheerp or Emscripten to compile C to WebAssembly (though they both assume you are targeting the browser).

    Also +1 for Assemblyscript which is fairly C-ish. It's based on Javascript / Typescript but really works more like C if you are doing anything low level (also it doesn't support Closures etc).

keithalewis 2 years ago

Looking forward to a "container-free Cloud IDE with offline capabilities, accessible from any location with a browser".

mmastrac 2 years ago

The module-level init seems like a great idea. I have been pondering how to get something like this right.

simon_void 2 years ago

how do you intend to handle nulls? allow nulls, nullable types or Option/Maybe type?

DoesntMatter22 2 years ago

There are now more programming languages coming out than JD frameworks! Hard to keep up

  • andsoitis 2 years ago

    Unless you're deeply interesting the programming language space for its own sake, the good news is you don't really have to keep up because they're unlikely to make any dent anytime soon.

    Even if you are interested in the programming language space, most are not groundbreaking.

revskill 2 years ago

Can i SSR a WASM module ?

mijoharas 2 years ago

I tried clicking through to find some syntax and got to this page[0] which seems to show things but the text is illegible on a dark background (something to do with picking up a dark mode setting on my device maybe?)

[0] https://moonbitlang.com/docs/syntax/

  • jwl4fun 2 years ago

    Thanks for your feedback, the back background should works now.

    • layer8 2 years ago

      The colored syntax highlighting is still hard to read in dark mode, too little contrast. You really need different colors for light vs. dark mode.

      • mijoharas 2 years ago

        Fwiw I did also think this a little, but they were good enough to be legible so I didn't mention it.

        The code examples actually looked fine to me on the page before the change due to the white background to them.

    • mijoharas 2 years ago

      Thanks! It is indeed fixed.

pjmlp 2 years ago

So why bother with this, when compared against AssemblyScript and Grain, both more mature and existing communities?

  • hongbo_zhang 2 years ago

    It depends on how you are measuring maturity.

    Moonbit is indeed only developed for less than a year(very fast moving), but it already has a full working IDE, optimizing compiler, fast build system and experimental package manager. We have a dedicated team working on this with professional experience for over a decade, we expect we will reach the maturity on par with Rust in terms of Wasm experience in a couple of years.

  • noelwelsh 2 years ago

    I would say Grain is very close to Moonbit. They are both MLs for WASM. AssemblyScript is not. No pattern matching, not expression oriented, no ADTs AFAICT, etc.

  • IshKebab 2 years ago

    Grain miserably fails rule 0 of programming language websites - show me the language! They expect you to go through installation, IDE setup, hello world before they tell you anything about it.

    The front page doesn't even tell you anything about its unique features. This Moonbit page is a million times better. I might actually try it. I'm not going to try Grain. Why would I?

    • pjmlp 2 years ago

      They assume anyone is clever enough to find the guide on their site.

      https://grain-lang.org/docs/guide/hello_world

      • IshKebab 2 years ago

        That's a guide for how to learn the language once you've already decided that you want to learn it. There's nothing to convince me that I should bother.

        Hello world and variable declaration syntax isn't going to make me go "ooo interesting! Tell me more!".

        I skimmed the guide and found none of the promised "Grain is a new language that puts academic language features to work".

        It seems to be a reasonably nice ML/Rust-alike presumably with GC and depending on the unstable WASM GC proposals, though that's mostly a guess - obviously they don't say that anywhere in the main page.

  • TuringTest 2 years ago

    Rust-like features and performance with Go-like usability are big selling points.

    Also we don't known how it will be licensed, but if it's proprietary that could also be a selling point with companies that won't touch Grain's LGPL license.

    • mkesper 2 years ago

      That's absolutely nuts. Would you risk building upon a stack that might be sold tomorrow to a competitor and killed instantly? Without software freedom and a community this is just a toy.

      • TuringTest 2 years ago

        Companies do it all the time with other software platforms, it really depends on the level of service contracted.

        Prudent companies also require the source code to be kept in a holding that transfers ownership to them if the supplier goes bankrupt.

IshKebab 2 years ago

Do you really avoid pointers by making everything a pointer?

  • TuringTest 2 years ago

    Yes, if the reference is immutable. The main problem with pointers is ad-hoc memory management anyway.

    • IshKebab 2 years ago

      The references are not immutable in this case.

      • TuringTest 2 years ago

        A reference, unlike a pointer, always points to the same memory address(*); so the reference is immutable even if the cell contents it points to are not. That's the difference between a reference and a pointer, by definition; not just the different syntax.

        Back in the day, that was one of the major selling points of the new language Java over the more common C and C++. Developers don't learn about it nowadays because changing pointers is practically never done outside the most esoteric parts of system programming.

        (*) Semantically, at least. The compiler is free to relocate the value to a different memory position in a way transparent to the programmer.

xmonkee 2 years ago

Absolutely nothing about memory management?

  • ledauphin 2 years ago

    "Moonbit makes programming easier with its automatic memory management" isn't absolutely nothing.

    they apparently have their own GC and intend to use the one that comes with WASM 2.0.

Keyboard Shortcuts

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