Assemblyscript: Why not transpile to rust

Created on 6 Aug 2020  ·  5Comments  ·  Source: AssemblyScript/assemblyscript

Hi there,

I was wondering why you didn't go with the route of making a typesript to rust transpiler and then generate js code with the help of wasm-pack

From:

export greet(){
 let x: boolean = true;
 if(x){
  console.log("Greetings, x is true");
 }
}

(AST Traversing in between)

To:

#[wasm_bindgen]
pub fn greet() {
    let x: bool = true; 
    if x {
        println!("Greetings, x is true");
    }
}

Are there any reasons ?

question

All 5 comments

@solidsnail what about Automatic Memory Management (which AssemblyScript provides and Rust doesn't)? For the start. :wink:

@solidsnail immediately to the second question. AssemblyScript provides four options for a Runtime Support Library of different sizes and functionality (https://www.assemblyscript.org/runtime.html). What's your idea of reimplementing it with Rust (using no-std I presume)?

In the case of AssemblyScript, a language quite different to Rust, transpiling to Rust would effectively just replace the low-level layer of Binaryen IR with a different low-level layer of Rust that wasn't specifically designed for the task. Can be done to some extend, with the slight benefit of effectively being able to pipe through LLVM (I expect this benefit to diminish over time), but that'd also mean two layers of standard libraries with two layers of compilers, very likely yielding suboptimal and unnecessarily clumsy final WebAssembly code. The drawbacks quickly outweigh the benefits if there are any, i.e. making the whole thing larger to download, harder to set up, making compilation much slower, and ultimately being unable to bootstrap the compiler.

Also great reason described by Alon why we use Binaryen instead of LLVM or LLVM based languages

I see, thanks for the insights.

I'm actually more keen on seeing things from a DX perspective, thinking off something along the lines of this:

counter.tsx:

import { WASM, Component, i32 } from "./lib";

@Component
export class Counter {
  wasm_state = {
    count: 1,
  };

  @WASM({
    getter: true,
  })
  getCount() {
    return this.wasm_state.count;
  }

  @WASM({
    setter: true,
  })
  setCount(count: i32) {
    this.wasm_state.count = count;
  }

  render() {
    return (
      <div>
        <h1>Count: {this.getCount()}</h1>
      </div>
    );
  }
}

AST typescript traverse , transform and generate files:

counter.wasm:

extern crate cfg_if;
extern crate wasm_bindgen;

mod utils;

use cfg_if::cfg_if;
use wasm_bindgen::prelude::*;

cfg_if! {
    if #[cfg(feature = "wee_alloc")] {
        extern crate wee_alloc;
        #[global_allocator]
        static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
    }
}


#[wasm_bindgen]
pub struct State {
    count: i32,
}

#[wasm_bindgen]
impl State {
    #[wasm_bindgen(constructor)]
    pub fn new(count: i32) -> State {
        State { count }
    }

    #[wasm_bindgen(getter)]
    pub fn getCount(&self) -> i32 {
        self.count
    }

    #[wasm_bindgen(setter)]
    pub fn setCount(&mut self, count: i32) {
        self.count = count;
    }
}

counter.js:

import {html, render} from 'lit-html';
import { State  } from './counter.wasm';


export class Counter extends HTMLElement{
    constructor(){
        super();
        State.setCount(1)
        this.renderHtml()
    }

    renderHtml(){
      render(html`
        <div>
            <h1>Count: ${State.getCount()}</h1>
        </div>
        `, this);
    }
}
Was this page helpful?
0 / 5 - 0 ratings

Related issues

jarble picture jarble  ·  3Comments

DuncanUszkay1 picture DuncanUszkay1  ·  3Comments

pannous picture pannous  ·  4Comments

kungfooman picture kungfooman  ·  5Comments

kyegupov picture kyegupov  ·  3Comments