Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expanding the Rust wasm Book #41

Closed
1 of 9 tasks
mgattozzi opened this issue Feb 1, 2018 · 24 comments
Closed
1 of 9 tasks

Expanding the Rust wasm Book #41

mgattozzi opened this issue Feb 1, 2018 · 24 comments
Labels
book help wanted Extra attention is needed

Comments

@mgattozzi
Copy link
Contributor

mgattozzi commented Feb 1, 2018

In #12 we added the book to act as a central part of documenting and working with wasm and Rust.
We should continue to expand it as we hash things out and continue to work on wasm. I've compiled a list of tasks below to help grow and maintain the book. This can be a starting point for those wishing to help out but aren't really sure what to do.

Tasks

  • Document workflows: This is part of Document workflows #7. We need to document different ways to work with and utilize Rust. For instance how to use various bits of tooling to shrink binaries or clean them up beyond what the wasm32 target does, or passing data into and out of JS for instance. The book tells people how to setup the environment and run hello world. Now we need to go beyond that.
  • Document tools available to users: We have this in Writing wasm tooling in Rust #10 but for someone just picking up the book and who doesn't want to wade through the issue tracker having a list would be good.
    Update: In Add Tools page (#41) #42 we added the page but this can be expanded as it is a living document! Finding more tools to add and removing old or unused ones overtime will be important.
  • Expanding How to write Wasm friendly code #28 into it's own section: This will allow users who want to make a crate know how to make it easier to work with wasm.
  • Current state of wasm32 development with rustc: Not everyone has the time to read all the PRs, tracking issues, and things going on with it and having a sort of changelog of sorts would help us keep track of changes specific to wasm but also give consumers of the wasm32 backend a way to see what's changing.
  • Collection of articles: People have talked about their experiences online with Rust and wasm. We should bring them into a place that's easy to access and learn from. This also allows us to supplement the book as it's expanded
  • Collection of demos: Lots of people are making things with wasm and Rust. Let's collect them all into a central place so people can see it in action!
  • Tutorials and guides: What is wasm? What is wat? How can someone learn it and utilize it with Rust? The WebAssembly website has some great resources but they focus more on C++ being used and not everyone wants to look at standards. A lot of the docs are what web assembly is and less how to use it. Let's make some high quality Rust examples and guides!
    • Tutorial for Writing a Library for JS: Scenarios where we are writing a Rust crate that will be compiled into a WebAssembly module that is used as a library by JavaScript. For example, perhaps the hot portion of some JS is being re-written in Rust/wasm. Similar to scenarios like Oxidizing Source Maps with Rust and WebAssembly
    • Tutorial for Writing Pure-Rust Web Apps: Scenarios where there isn't any hand-written JS being loaded, only machine generated glue to access DOM APIs, and all the magic is in pure Rust.

There's likely more we can do to increase our documentation efforts but this seems like a good few steps we can take to really get our documentation efforts underway.

@mgattozzi mgattozzi added help wanted Extra attention is needed book labels Feb 1, 2018
joaolucasl added a commit to joaolucasl/rust-wasm that referenced this issue Feb 1, 2018
@3442853561
Copy link

There is a handbook to teach how to programming with wasm. Real World WebAssembly

@mgattozzi
Copy link
Contributor Author

@3442853561 I can make a section for resources like this and split it by language :)

@3442853561
Copy link

3442853561 commented Feb 2, 2018

@mgattozzi May I help you to finish this book? What should I do?

@mgattozzi
Copy link
Contributor Author

@3442853561 Yeah! You'll need to do a few things:

  1. There's a file that acts as a table of contents. The file is src/SUMMARY.md. You'll need to add a line at the end that looks like this - [External Resources](./external-resources.md)
  2. You'll need to then create the file external-resources.md under the src directory.
  3. In that file at the top put # External Resources
  4. Write a small summary about what the document is for, in this case listing WebAssembly tutorials and blog posts for use by the reader that aren't in the book.
  5. List the resource. We'll want to split up listing by language in this case a section for Chinese tutorials/resources. I would reccomend using the actual characters for the language rather than using English here.

If english isn't your first language don't worry. I'll help you make edits :)

At some point I'd like to just make multiple different versions of this natively translated.

@Pauan
Copy link

Pauan commented Feb 12, 2018

@mgattozzi You had posted a comment here but I'm replying to it in this thread, so as to keep the threads on-topic.

I would love to contribute some examples, however my harddrive had recently gotten corrupted, so I lost all of my Rust code. When I finish another Rust project I can contribute it.

I can also give some explanations right now about what I did, how I did it, what problems I encountered, how I fixed those problems, etc.

@sendilkumarn
Copy link
Member

@Pauan would be awesome to hear those 👍

@mgattozzi & @Pauan If there is anything, that I can help with the documentation and experimenting would be more than happy to do so.

@mgattozzi
Copy link
Contributor Author

@Pauan no rush. If you can great!
@sendilkumarn yeah totally that would be awesome! Does anything in the task list above interest you? If not have you done some experimenting with things that might be helpful to other users like "Making small wasm binaries?" or "How to do more complicated JS Interop?"

In general we're trying to centralize resources for people, even blog posts. Let me know if there's something you want to take a crack at or if you have another idea I might have missed in the list above! More than happy to then review your PR or help you with getting the docs in! :D

@fitzgen
Copy link
Member

fitzgen commented Feb 14, 2018

Heads up to issue subscribers: I just edited the original comment to add this under the tutorials item:

  • Tutorial for Writing a Library for JS: Scenarios where we are writing a Rust crate that will be compiled into a WebAssembly module that is used as a library by JavaScript. For example, perhaps the hot portion of some JS is being re-written in Rust/wasm. Similar to scenarios like Oxidizing Source Maps with Rust and WebAssembly
  • Tutorial for Writing Pure-Rust Web Apps: Scenarios where there isn't any hand-written JS being loaded, only machine generated glue to access DOM APIs, and all the magic is in pure Rust.

@sendilkumarn
Copy link
Member

sendilkumarn commented Feb 15, 2018

Tooling

Can we also tell users about the plugins that are available for rust ?

Current state of wasm32 development with rustc

This seems to be interesting, can you let me know about the places where we have these details.

interesting use case to have yet another arewereadysite 👍

@mgattozzi
Copy link
Contributor Author

@sendilkumarn so the issue tracker here is the current state. Unfortunately that means having to read and understand it all. Since we're the source we need to curate it for others who don't want to wade through the issue tracker (most people won't and shouldn't need too). We keep track of things going on in rustc here as well like llvm6 being merged as well as lld support for wasm.

I don't see why we can't include plugins with their own section in the tooling area as well. Just need to add the caveat that it's an unstable feature, but then again they're using nightly for wasm so it's really not as big a deal.

@Pauan
Copy link

Pauan commented Feb 15, 2018

So, to explain about my experience using Rust + WebAssembly.

There is a website called SaltyBet, where you can bet fake money on virtual fighting matches. My goal was to create a robot that would automatically bet, hopefully making more money than it loses.

Rather than trying to create the robot directly, I decided to write a genetic evolutionary algorithm, and the evolutionary algorithm would then create the robot for me. Then I can run that robot on SaltyBet.

There are two parts to the Rust program:

  1. The genetic algorithm I wrote myself, completely from scratch, in normal Rust. Which means it can work on any target that Rust supports.

    In simulations the generated robot did exceptionally well, but I never got a chance to try it out on SaltyBet.

  2. A Chrome Extension, which would handle the automated betting (clicking on buttons, retrieving the information about who won, etc.)

    This is also written by me in Rust, except it's using stdweb (since it's a Chrome Extension, and Chrome Extensions must be written in JavaScript).

    I have to compile it with the asmjs-unknown-emscripten target, because Chrome Extensions don't load .wasm files correctly, because of the way that Chrome Extensions handle URLs. Using .wasm works fine for regular web pages, it's only Chrome Extensions that are broken. This will get fixed once stdweb gets better Webpack / Parcel support.

For the most part stdweb follows the usual web APIs: you can do document().query_selector("#foo"), you can add event listeners, all the usual JavaScripty stuff. It automatically handles conversion between JavaScript and Rust, and it's usually quite easy to use.

But there's a catch. When you use a callback, that callback is marked with 'static. For example:

element.add_event_listener(|event: ClickEvent| {
    // ...
});

In this case we're passing in a |event: ClickEvent| { ... } callback to JavaScript. And that callback has a 'static lifetime. Which means that it cannot capture any non-'static references from the outer scope.

Or to put it another way, if you want to use something which is outside of the callback, then you either have to move it (transfer ownership) into the callback, or you have to use Rc<A>.

If a variable is only used inside the callback, then I recommend using move, because it's much easier (and faster!):

let mut foo: u32 = 5;

element.add_event_listener(move |event: ClickEvent| {
    // use foo
});

But if you want to use some variable both inside and outside the callback, then you must use Rc<A> (and you must .clone() it as appropriate):

let foo: Rc<u32> = Rc::new(5);

{
    let foo = foo.clone();

    element.add_event_listener(move |event: ClickEvent| {
        // use foo
    });
}

// use foo

If you want to mutate a variable from inside and outside the callback, then you must use Rc<RefCell<A>> (or Rc<Cell<A>>) instead:

let foo: Rc<RefCell<u32>> = Rc::new(RefCell::new(5));

{
    let foo = foo.clone();

    element.add_event_listener(move |event: ClickEvent| {
        let foo = foo.borrow_mut();
        // use foo
    });
}

// use foo

When using callbacks, be prepared to use Rc<A> (and Rc<RefCell<A>>) a lot.

This is necessary because JavaScript might call the callback at any time, and Rust cannot guarantee that the references will still be alive when JavaScript calls the callback. Using Rc is safe because it will keep the underlying memory alive as long as the callback is alive.

This isn't really stdweb's fault, it's just a fundamental problem with JavaScript interop, so you'll have this problem even if you're not using stdweb.

Also, if you want to use a JavaScript API which isn't already provided by stdweb, then things get a lot trickier. You have to use the js! macro, which lets you insert JavaScript code directly inside your Rust code:

fn foo(input: u32) {
    js! {
        var array = [1, null, "foo", @{input}];
        console.log("Look, it's JavaScript code!", array[2]);
    }
}

But there's a lot of subtleties involved, especially with callbacks. And when converting a JavaScript API into Rust, it's sometimes hard to figure out how to do it (in large part because JavaScript is dynamically typed).

But overall I've been very happy with stdweb, it's done an excellent job of not only making it possible to use JavaScript APIs, but also fairly pain-free too.

@mgattozzi
Copy link
Contributor Author

mgattozzi commented Feb 23, 2018

@koute Your work on stdweb is kind of becoming a defacto standard when working with wasm. I was wondering if you'd like to have a tutorial or introduction of some sort featured in the book if you wanted I was thinking having it be apart of the tutorials and guides section. Especially since you just released 0.4 :)

@fitzgen
Copy link
Member

fitzgen commented Feb 24, 2018

#70 reminds me that we should also have a section for how to debug and profile when targeting WebAssembly.

@koute
Copy link

koute commented Feb 24, 2018

@mgattozzi Of course I would! Having more documentation is always a good thing.

What kind of a tutorial do you have in mind? I'm totally willing to help write something up.

@mgattozzi
Copy link
Contributor Author

@koute I was thinking a getting started, exporting stuff for JS to work with wasm, as well as maybe integrating with parcel now that you added it. Even if you didn't have time if you list some things you want or think would be useful to document I could get a separate issue open and organize it so we can track working on it. I was thinking we could have sections for the bigger tools in the eco-system and document them and stdweb would be one of the first for that :)

@fitzgen
Copy link
Member

fitzgen commented Feb 27, 2018

Does anyone have a good idea for the thing that the tutorial builds?

  • It should be a realistic example
  • It should be somewhat compute heavy, since that is where Rust+Wasm shines
  • It should not involve too much marshaling of data between wasm and JS
  • It should be something that a Web person who is interested in using Rust for their inner loop might be passingly familiar with

Ideas?

@sendilkumarn
Copy link
Member

I would suggest this
an infinite scrolling table with a lot of rows. This will show the capability of dom manipulations and sorting & filtering will show the power of rust + wasm.

This might look simple, but when we can do this seamlessly then we can package them as a separate package and give that as a web component and I bet people will love to use that.

probably add an async loading and showcase the capabilities of fullstack with rust.

@Pauan
Copy link

Pauan commented Feb 28, 2018

@fitzgen How about something involving WebGL: very compute-heavy, very interesting for web developers, and very cool in general. I always love seeing fancy 3D renderings.

@mgattozzi
Copy link
Contributor Author

I'm not sure exactly what might be the best, but having a site they can also open to see a non wasm version to see the difference would be good as well. Visibly seeing the speed difference rather than saying there is one provides better impact and makes it more memorable.

Basically we need a "Wow. Holy crap this is really cool" kind of moment.

@Pauan
Copy link

Pauan commented Feb 28, 2018

@mgattozzi That's a great idea! We need something similar to this, in other words a site that shows you the speed difference.

@fitzgen
Copy link
Member

fitzgen commented Feb 28, 2018

My concern with webgl is that it involves a lot of boundary crossing to invoke each api call, and that a lot of the interesting bits are just the shader code rather than rust compiled to wasm.

@sendilkumarn
Copy link
Member

following up on the comment here

It would be really awesome to either use the title or labels to segregate the issues. We can write a crawler to munch on these data to showcase a SPA that showcases the high level details that we need people to know about the current WASM process. (It might require few rewriting but I am sure that it helps on the longer run)

@sendilkumarn
Copy link
Member

sendilkumarn commented Mar 1, 2018

My concern with webgl is that it involves a lot of boundary crossing

exactly that was my concern too

OTOH I need to have a simpler looking example that solves what developers struggle daily in their applications. This should be a custom-element such that everybody, irrespective of the framework they use, capable of using it.

My worry is that, people always think that WASM is something that you need to use for extraordinary gaming applications | some cool graphics stuff with webgl. On one side it stands true, it does gives us awesome capabilities to make things faster, OTOH, withrust it provides us easier readable | maintainable code and taking care of high performance.

From what I really believe, developers who are doing normal web apps should see back this capability and then try to use it in their applications and that is where the aim should be (IMO)

@jrichocean
Copy link

This issue has been moved here

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
book help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

7 participants