Elm ports with Nim

Nim compiles to JavaScript and I’m using it with Elm. I might publish this on nimble

    Module* {.importjs.} = ref object of JsRoot
    Program* {.importjs.} = ref object of JsRoot
    SubPort*[T: JsRoot] {.importjs.} = ref object of JsRoot

# Initialize a Program (doesn't work with flags or Browser.element)
proc runModule*(
    name: cstring,
): Program {.importjs: "Elm[#].init()".}

# Subscribe to a Cmd port (from Elm)
proc subscribe*[T: JsRoot, Output](
    program: Program,
    name: cstring,
    onTrigger: proc(payload: T): Output,
) {.importjs: "#.ports[#].subscribe(#)".}

# Get a reference to a Sub port (to Elm)
proc getSubPort*[T: JsRoot](
    program: Program,
    name: cstring,
): CmdPort[T] {.importjs: "#.ports[#]".}

# Send a value through a Sub port
proc send*[T: JsRoot](
    subPort: SubPort[T],
    payload: T,
) {.importjs: "#.send(#)".}

May I ask why you are doing this? What are you using Nim for?

1 Like

My project (dullbananas/editsc) has a lot of code outside of elm (elm is not good enough with performance), so writing javascript directly would be a pain in the stdout.

Typescript has a slow compiler and is not very flexible. Rust (with webassembly) is good but there’s some limitations with javascript ffi.

Nim is a good programming language with sexy expressive ffi, optimizations like compile-time evaluation, macros, uniform function call syntax, etc.

It’d be great if you could provide a little full stack demo.

Nim got on my radar recently. From what I gathered there’s a difference between procs and funcs where one of the two disallows mutations which I thought was a very interesting language feature.

One could then imagine enforcing mutation being isolated to one area of the code base rather than spreading it.

Via a simple pre git commit hook and shell script.

I’d be interested to hear your thoughts :wink:

1 Like

I’ve been using Nim a bit more and I’m actually hating it.

  • The cryptic compiler error messages are the opposite of Elm’s
  • Unsafe. For example, var statement without a value causes it to be 0-initialized which is not explicit and often done accidentally
  • No result/maybe types. In Nim I have to use exceptions (like python) :face_vomiting:
  • Library documentation isn’t often good

I’m gonna just use Rust and make a better alternative to wasm-bindgen

If you work on better Rust-elm interop I’m also interested in what you’ll do. For the time being I’ve just been piling up ports and hand wiring the different parts between rust and elm.

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.