Comment by 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

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

  • 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.

    • 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?

      8 replies →

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.

  • 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)

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

* 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.

  • 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.

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

  • 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.

    • > 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?

"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

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.

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?

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?

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?

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.

  • `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.

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?

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?

  • > 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)

    • 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).

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