Planning for AssemblyScript support and integration for the next 6 months, starting Jan'21

Every 6-12 months, NEAR revisits the degree of its support and integration of AssemblyScript. Since last time we revisited it in Feb 2020, it is time to revisit it again.

Current support and integration

Currently, NEAR supports AssemblyScript project in the following ways:

  • It is the top financial contributor to the core AssemblyScript team, with monthly donations of 2k USD;

  • @willemneal runs monthly AssemblyScript Community Group meeting;

  • @willemneal is also an active contributor to as-pect and the core AssemblyScript code;

  • @willemneal occasionally posts bounties for AssemblyScript community see: near-sdk-as

Overall, @willemneal spends only a fraction of his work time on AssemblyScript.

AssemblyScript is currently integrated with NEAR tech stack in the following way:

Updates since Feb 2020

  • AssemblyScript compiler evolved from version 0.9 to 0.17;

  • near-sdk-as functionality has improved to be close to near-sdk-rs functionality and have similar DevX;

  • We have started AssemblyScript Community Group which meets monthly;

  • We have contract testing infrastructure in Rust that can test Wasm contracts independently on which language they are written in;

  • NEAR Studio was removed and replaced with http://examples.near.org/

  • Fastly announced more openly their support of AssemblyScript as an edge computing language;

  • Shopify announced more openly its support of AssemblyScript;

  • We stumbled upon a pretty critical bug in AssemblyScript STD which also showed that our near-sdk-as was probably not that much used, otherwise people would’ve noticed it sooner;

  • @corwinharrell and @amgando did a user study on AssemblyScript. Given the choice of Rust vs AssemblyScript. 3 out of 7 people said they would use Rust, 3 said they would use AssemblyScript, 1 person said they don’t care as long as it works;

  • @nearmax did a user study on JS, TypeScript, AssemblyScript, Rust. 249 people voted, the survey was not shared with any language-specific community).

Decision framework

We will choose one of the options below and commit to it for the next 6 months. Anyone in the thread can propose alternative options or express their preferences towards one or another option. Since in the past discussions of AssemblyScript lasted longer than several months we will time box this discussion and set a deadline for the decision to be January 15th, 2021. We will follow DACI decision making framework. Since the topic of AssemblyScript involves not one but many teams in NEAR Organization, @nearmax is going to be the Driver and the Approver. The following people are going to be contributors of the technical knowledge: @olonho , @willemneal , @nearmax, @evgenykuzyakov , @mikedotexe , @chadoh . And the following people are going to be contributors of the product knowledge: @olonho, @willemneal , @amgando , @thisisjoshford, @corwinharrell , @vgrichina , @mattlockyer , @mikedotexe, @nearmax. Anyone else joining this conversation can be either Contributor or Informed depending on the depth of their knowledge of the subject.

Option 1 (same support, more ownership, less integration)

Support:

  • Continue the same financial support of the core AssemblyScript team;
  • Continue running AssemblyScript CG;
  • Get a dedicated person to own near-sdk-as, contribute to as-pect, and create AS bounties;

Integration:

Explanation. We believe in the future of AssemblyScript and are willing to support it, but are cautious about vouching for its stability, given that compiler is not 1.0 and there are some bugs (@mikedotexe @thisisjoshford can provide more informations on issues that we encountered with AssemblyScript and near-sdk-as). Given that users are completely comfortable using Rust for the contracts, according to the surveys, we are switching docs and create-near-app to Rust.

Pros:

  • We are not losing moment with AssemblyScript;
  • We are getting more clear ownership of our own AssemblyScript components;
  • We do not risk users starting using AssemblyScript for their contracts just to later rewrite them to Rust, because something does not work (happened to RainbowBridge and several hackathon projects);

Cons:

  • We expand the scope of the horizontal teams: Berrypickers, DevRelations, and maybe Product. They now have to worry about Rust and AssemblyScript dev-tools.

Option 2 (same support, freeze integration)

Support:

  • Continue the same financial support of the core AssemblyScript team;
  • Continue running AssemblyScript CG;
  • Freeze development of near-sdk-as and contributions to as-pect;

Integration:

Explanation. We believe in the future of AssemblyScript and are willing to support it, but want to completely focus on a single “happy path” in our developer journey, which is Rust.

Pros:

  • All pros from Option 1;
  • Allows us to focus all effort on one language;

Cons:

  • Having AssemblyScript support as a first-class language in NEAR is postponed by at least 6 more months.

Option 3 (external ownership without attribution without NEAR Inc/NEAR Foundation taking responsibility for it)

Support:

  • Continue the same financial support of the core AssemblyScript team;
  • Continue running AssemblyScript CG;
  • Get a third-party to develop near-sdk-as, as-pect, and help with release of AssemblyScript 1.0, e.g. through a grant;

Integration:

  • Remove AssemblyScript from our docs and tools entirely, allow third-party to develop their set of docs and tools;
  • Do not vouch for the quality of the AssemblyScript dev tools as NEAR Foundation or NEAR Inc.

Explanation. We allow someone else to develop it faster, however we don’t have control over their quality and so we cannot vouch for it.

Pros:

  • We are moving even faster with AssemblyScript support;
  • There is no scope increase for horizontal teams like Berrypickers, DevRelations, and Product, since AssemblyScript dev-tools are now done by someone else;
  • For NEAR Inc and NEAR Foundation there is less code surface that it needs to vouch for.

Cons:

  • AssemblyScript devtools become disjoint from other dev-tools and documentation.

Option 4 (replace AssemblyScript with another popular language)

Support:

Integration:

  • Remove AssemblyScript from all our tools and docs.

Explanation. As the survey has shown users prefer the idea of a more generally known language for contracts than AssemblyScript, which is what we actually care about — we want to provide an alternative that is less niche than Rust.

Pros:

  • We have a more popular language for smart contracts. Some general purpose languages, like C# have stable Wasm compiler supported by large organizations like Microsoft;

Cons:

  • It is unclear whether AssemblyScript->Wasm is more efficient and stable than C#(or other general purpose language)->Wasm. @olonho needs to weigh-in on it;
  • There is a sunk cost of stopping AssemblyScript support.

Update 1: Removed “Rust>>JS>>TypeScript>>AssemblyScript” to not confuse people. As @vgrichina pointed out.

3 Likes

I think we forgot:

Option 5 (focus on making it easy to support any language of choice, which is main selling point of WebAssembly).

Our runtime API is generally pretty small and easy integrate into any language which supports C-style APIs.
This means we can demonstrate this to community by showing how e.g. you can build minimal smart contract on C, no_std Rust, Swift, TinyGo, etc.

This also means we actually need to provide WASM-specific (but language agnostic) tools which allow shipping secure code:

  • integration testing support (drive minimal node like ganache vs bake in support for Rust). Current way of testing Rust code is actually pretty scary: we compile for x86 using basically far more mature compiler backend than WebAssemby and run in completely fake environment. I believe some of the teams already noticed discrepancies, but hard to find now in chats.
  • fuzzing at both binary args level and individual arguments / storage state / etc. @willemneal had pretty good insight that we can use existing gas instrumentation code to drive fuzzer basically. Which makes even more sense given that it’s pretty important to discover pathological gas usage for given inputs.
  • stress testing tools. We had pretty bad bugs in nearcore (like with access keys recently) caused by lack of stress testing. We should make it easy to stress test.

Pros:

  • we are seen as more neutral
  • opportunities for community contributions (many developers love making frameworks from scratch more than apps. I think Rick Tobacco already mentioned wanting to do C++ SDK on TG)
  • access to larger talent pool (WebAssembly fans are particularly excited to use their language of choice with a new tech stack, at least SF WASM Weekly crowd)
  • robust tools which help to have better security for every language without trusting any specific language implementation

Cons:

  • we can get blamed for problems even with languages we don’t support (questionable as will happen anyways. Example: wallet getting shit for Marlin staking UX issues)
  • more work then when we aren’t doing fuzzing / integration testing tools
1 Like

I also suggest we seriously revisit out Rust support as well:

  • zero to hero time is unacceptable for quick onboarding. Just compiling code from scratch takes multiple minutes.
  • smart contract sizes are too damn high: https://gov.near.org/t/raising-storage-prices-and-smart-contract-sizes/330/2. This is becoming a practical problem for wallet already.
  • test on x86, deploy on WebAssembly isn’t taking security seriously
  • persistent collections are really confusing (this is a problem on AS side as well). I think we better should use ActiveRecord pattern familiar to many web and backend developers. Or anything else which is more like “define table, make queries” vs manage indices myself by hand.
1 Like
  • @nearmax did a user study on JS, TypeScript, AssemblyScript, Rust. 249 people voted the following preference on the languages: Rust>>JS>>TypeScript>>AssemblyScript (the survey was not shared with any language-specific community).

this is very obvious gerrymandering.

if you actually interpret it as choice between 2 options (Rust and JS-like), then Rust loses this survey

when choosing from hypotheticals I myself want to use JS (and voted JS).

however AS is closest alternative we can actually have running on WebAssembly

Great summary @nearmax! One small adjustment I wanted to make: The link you have provided for the user study conducted by @amgando and myself is actually just a one-off survey that I shared on twitter that didn’t see much engagement. While still relevant, these survey responses are not reflective of the 1:1 sessions that @amgando and I also facilitated. To view the outcome of that work, those interested should reference this report that was generated to summarize the first batch of sessions. The TLDR outcome of this research, as outlined in the report, is as follows:

The general sentiment of the community as it exists today is that AssemblyScript is a valuable option in the toolkit of developers interested in and currently building on NEAR. Developers like what is familiar, as it helps them to start and make progress faster/easier. As a result, there’s a general preference for familiar languages like TypeScript (and AS by proxy) over Rust without necessarily grokking the implications or benefits of the latter.

It may be beneficial for those diving into this to surface this in the summary as well.

1 Like

I am very grateful for NEAR’s invaluable support to AssemblyScript, it really makes a difference as we wouldn’t be where we are today without you, but I am a bit surprised by two points.

First, that Rust isn’t already the default, as a stable foundation while WebAssembly is still an MVP, also given how slow the specification is progressing. WebAssembly hasn’t made any progress to help managed languages yet, and expecting AssemblyScript to compete toe to toe with a systems language at this point in time is unrealistic, just as it is unrealistic to expect AssemblyScript and its very small team to compete with Rust/LLVM in general. I mean, we are doing our best, often beyond a healthy limit, but there is a difference in multiple magnitudes of financial support, human resources and influence on the specification process between the Rust and AS ecosystems still. In fact, comparing the two for stability or applicability in the current state of affairs is starting to do more harm than it helps, because AssemblyScript and its people can only lose.

Secondly, that upping your support isn’t an option given how much you rely on it. It would already help a ton for example to assemble a temporary but dedicated team testing the hell out of the compiler and its standard library and PRing the tests upstream so you can be certain that it meets critical demands in production, no matter how boring that work is. Not maintaining a fork, no uncommon code style, and no outdated compiler versions, as it happened in the past. I do agree of course that the string compare bug was particularly embarrassing, yet it not being found earlier is a statement with multiple dimensions. With broader adoption it would have been found earlier, as it would have been found earlier with focused adoption.

I know that this may not be what you folks want to hear from me, and that it may fuel the fire of burning AS down at NEAR in those wanting to, but perhaps my honest opinion will help you make a forward-facing decision that will ultimately result in your success. I definitely owe you that.

With this line of reasoning we could also derive that huge parts of Rust SDK and nearcore aren’t being used as well IMO.

BTW I don’t think TreeMap was really used in any of our examples or that they had any good reason to do string comparisons otherwise. Most contracts would retrieve few keys, update some numbers, write keys back. If sorted list is needed, etc I think most use cases end up using indexer vs maintaining sorted list on chain.

Same goes with AssemblyScript usage in general outside of NEAR. It’s usually some heavy number crunching (gameboy emulator, chess engine, etc), not really focused on strings. Which is likely main reason this wasn’t found before.

In any case this really looks like such cycle:

  • deprioritize AssemblyScript
  • AssemblyScript support doesn’t get a lot of cycles
  • some critical bug is found later than if it was if there was more work in this direction
  • use this as excuse to deprioritize further
  • rinse and repeat

i.e. this is basically self-fulfilling prophecy

1 Like

@vlad

Regarding Option 5. We still need at least one go-to language that we support as NEAR organization that we can vouch for that we can recommend to our partners, also for http://examples.near.org/ and http://docs.near.org/ . We are too early to release responsibility and control over our SDKs. Once we have enough traction and ecosystem we can delegate maintenance of the SDKs to different groups in the ecosystem.

Regarding language-agnostic Wasm-specific tools. This is a nice theoretical concept, however even ganache requires you to write tests in a specific language. We have ganache-like integration testing suite that can be used by any Wasm contracts but it requires tests in Rust. Gas-guided fuzzing is a nice theoretical concept, however, as @olonho explained general-purpose fuzz testing tools are more about having a feeling of safety, rather than safety. We can add fuzz testing and stress testing for contracts once we resolve more urgent problems, like DevX smoothness of the SDKs.

Regarding Rust support.

zero to hero time is unacceptable for quick onboarding. Just compiling code from scratch takes multiple minutes.

Do we have any data-driven evidence that compilation of the smart contracts is actually an issue to our partners? We could ask Ashley Crawford to do a survey. If you would like to have this argument then the burden of doing such research is on you. Given that Solidity contracts take approximately the same time to compile it is unlikely that anyone would see it as an issue.

smart contract sizes are too damn high: https://gov.near.org/t/raising-storage-prices-and-smart-contract-sizes/330/2 . This is becoming a practical problem for wallet already.

In the issue that you have linked it was answered that this is not an issue of Rust, but rather the fact that we haven’t added no-std support for near-sdk-rs yet. Given that AssemblyScript STD is quite minimal it is more correct comparing Rust no-std contracts to AssemblyScript contracts in terms of their size.

test on x86, deploy on WebAssembly isn’t taking security seriously

Do we have any specific evidence that this is an issue? We have compiler specialists in our organization that haven’t expressed concern about it. Besides, the integration testing suite developed by @willemneal runs contracts as Wasm not x86.

persistent collections are really confusing (this is a problem on AS side as well).

As you have said yourself, this is not a Rust issue.

To summarize, out of 4 issues of Rust that you have brought up: 2 are not supported by data, 1 is not a Rust issue, and another one is addressed in the linked URL. Also, this discussion is about AssemblyScript support.

this is very obvious gerrymandering. if you actually interpret it as choice between 2 options (Rust and JS-like), then Rust loses this survey

This is a comparison of 4 different programming languages. The intention was to show that if users had a choice between JS, TS, and AS they would’ve chosen JS. Rust was added for the baseline. If we were interested in comparing Rust to AssemblyScript then we would’ve created a Rust vs AS survey. It’s purpose is also to show that some users might not grok low-level implications of choosing one language over another, e.g. JS might not be the best contract language in terms of safety and minimalism once compiled, however many users chose it. This is to show that the choice of which language to support should not be done only based on what users prefer, but should also include knowledge of compiler experts.

With this line of reasoning we could also derive that huge parts of Rust SDK and nearcore aren’t being used as well IMO.

Finding a bug in a compiler or STD is a much more serious issue than finding a bug in a user code.

In any case this really looks like such cycle:

  • deprioritize AssemblyScript
  • AssemblyScript support doesn’t get a lot of cycles
  • some critical bug is found later than if it was if there was more work in this direction
  • use this as excuse to deprioritize further
  • rinse and repeat

i.e. this is basically self-fulfilling prophecy

This is not a self-fulfilling prophecy. We did not find any bugs in Rust STD or compiler not because we are supporting near-sdk-rs, but because the language is mature. Similarly, if we put more energy into near-sdk-as it won’t guarantee that AssemblyScript compiler or STD will become bug free.

@corwinharrell

To view the outcome of that work, those interested should reference this report that was generated to summarize the first batch of sessions.

Thank you for performing this research. I see issues with the how the study was done:

  • We have discussed multiple times in the past that we should not be conflating TypeScript and AssemblyScript, and even more so JavaScript. TS and AS are different languages – one cannot be called from another, they have disjoint documentation and ecosystems. We had many situations where people would start writing contracts in TypeScript only later to realize that they cannot link any of the TypeScript libraries or use TypeScript documentation or community support. In many cases once they found it they switched to Rust. For example, this happened to Anton Bukov who initially wrote a large chunk of RainbowBridge in TypeScript only to realize he cannot compile it to Wasm and cannot convert it to AssemblyScript because of TypeScript dependencies. He had to rewrite it to Rust. If we have extremely experienced contract developers like Anton confused by AssemblyScript/TypeScript then we cannot expect web2 developers to not do the same mistake over and over. @amgando was there when we have decided to not conflate TS and AS, so I am surprised to see it conflated in this research. Also, one can argue that Kotlin and Java or C and C++ have more in common than AssemblyScript and TypeScript, given that Kotlin/Java or C/C++ can be linked with each other and share the same ecosystem. The general pattern about AssemblyScript is that people are very excited developing on it, until they spent a couple of days doing it;
  • The research conclusions do not mention any data, e.g. what is the number of partners answering this or that way? what is the percentage of the community answering this or that way? It is hard to conclude how statistically important this research is, what is the split between Rust vs JS audience and why it is such. The conclusion “The general sentiment of the community as it exists today is that AssemblyScript is a valuable option in the toolkit of developers interested in and currently building on NEAR.” is very high-level and does not answer the question: “how valuable?”.
  • It is also not clear to me whether this research is trying to compare Rust to AssemblyScript or it is trying to figure out the value of AssemblyScript on its own;
  • The research seems to be asymmetric in questions that it is asking about Rust and AssemblyScript, which might be biasing the users. E.g. questions like: “Regardless of your existing knowledge of Rust, how familiar are you with its purported benefits for authoring smart contracts?” I bet there are even fewer people that are familiar with the benefits of AssemblyScript, e.g. that it is a self-hosted compiler, etc. however this question was not asked.

@dcode

I agree that it is completely unfair to expect AssemblyScript to be toe in toe with Rust. I really don’t like how our conversation about AssemblyScript support always side tracks into Rust vs AssemblyScript debate. The original post that I wrote is focused on how we support AssemblyScript independently on its comparison to Rust.

Upping AssemblyScript support is also an option, it might be viewed as an extension of Option 3. Would AssemblyScript core team be interesting in supporting it by switching focus from things like working on self-hosted compiler to co-authoring tests and STD libraries?

We really appreciate your honesty, and I would like to set expectation that this discussion is going to be happening every 6-12 months anyway. And extreme options are always going to be on the table.

Could you please help us with the following question as a subject matter expert: how difficult would it be to add TypeScript->Wasm or JS->Wasm support, compared to helping AssemblyScript getting to its full maturity?

Could you please help us with the following question as a subject matter expert: how difficult would it be to add TypeScript->Wasm or JS->Wasm support, compared to helping AssemblyScript getting to its full maturity?

You could build a TypeScript->Wasm or JS->Wasm compiler, or fall back to run unmodified JavaScript directly by either embedding V8, or compiling an interpreter like quickjs to Wasm to run unmodified JS through either of these. The latter options aren’t necessarily difficult, but have other drawbacks like that V8 is huge and that interpreters are slow.

Would AssemblyScript core team be interesting in supporting it by switching focus from things like working on self-hosted compiler to co-authoring tests and STD libraries?

I’d be very interested in merging more tests upstream and fixing issues discovered in the process, but ideally in a way that I can still focus on milestones like bootstrapping as it achieves invaluable confidence into the compiler or general progress on fronts not many people can help me with. I am sure that others on the team would also welcome PRs for more standard library tests and issues discovered in the process to fix. If that helps?

@nearmax thanks for this feedback. It’s good to know where your head is at and I think your observations about what I’ve shared are completely valid. It’s clear that I could’ve provided some more context about the summary that I authored.

Regarding how the research was conducted:

I first want to give full disclosure that my role in these sessions was primarily one of coordinator and handling of logistics as well as record keeping. I am not a smart contract developer, and my experience and exposure to Rust and AS is limited, so I’ve relied heavily on @amgando to offer his expertise in evaluating the development capabilities and perspectives of the candidates that we were able to sit with for this research. I’m sure he can weigh in here or elsewhere to provide some more nuanced insights and to help fill in the gaps as far as communicating learnings from these sessions where I am unable.

The research conclusions do not mention any data, e.g. what is the number of partners answering this or that way?

You’re correct in that this particular summary report was entirely qualitative and does not contain sufficient quantitative metrics to be useful as a tool for evaluating specific criteria. My initial intent for the report was just to provide the larger org with a summary of the work that had been done, and to relay the general sentiment from participants that we had observed.

In my role as coordinator, I didn’t want to misrepresent specific smart-contract related learnings from the tests/tasks that @amgando had designed, since my ability to interpret participant behavior in this context is fairly limited. As a result, the summary definitely falls short when considered as a definitive source of quantitative data. I will be going back over the session data with @amgando to provide more quantitative insights in a form that is more useful as a reference for decision making.

We have discussed multiple times in the past that we should not be conflating TypeScript and AssemblyScript, and even more so JavaScript…

If this is the case, this was definitely lost on me personally. My impression from how some of these questions about developers’ language preferences have been framed is that the audience that is most likely to favor AssemblyScript are those with a JS background who view the path from JS > TS > AS as the path of least resistance. This seemed to be the sentiment shared by most of the individuals we talked to over the course of the research. If there have been discussions about the fact that these things should not be conflated, then I was not privy to this and this definitely had an impact on how I perceived the sentiment of participants.

@amgando lets definitely circle back to see what quantitative insights we can extract from our sessions to hopefully provide @nearmax and team with the specific references they need to better inform this decision making.

Just to be clear my arguments “against” Rust are purely to use it as a baseline to establish which trade offs we are making between languages, not to attack Rust development.

I personally think we should enable multiple languages – this is whole point of WebAssembly. Also generally trade offs between languages often are highly subjective and every OS typically has different languages for different use cases. I don’t think 100m Defi projects and Berry Club’s of the world should be using the same language.

Regarding language-agnostic Wasm-specific tools. This is a nice theoretical concept, however even ganache requires you to write tests in a specific language.

This is not true. You can interact with ganache via RPC from any language. You probably aree confusing with Truffle which provides JS testing framework (and there is very huge difference between providing JS and Rust as options, JS is vastly more popular and familiar).

Gas-guided fuzzing is a nice theoretical concept, however, as @olonho explained general-purpose fuzz testing tools are more about having a feeling of safety, rather than safety.

So let’s decide whether arguments should be backed by data or deferred to authority, as you seem to be doing either

What I know for sure is that if we don’t fuzz for trivial issues – attackers will do it.

I agree 100% it’s not going to be guarantee of security however, same as literally anything else.

Do we have any specific evidence that this is an issue? We have compiler specialists in our organization that haven’t expressed concern about it.

I’ve seen somebody on our chat groups complaining about discrepancy when running on-chain. It is hard to find it now unfortunately. However WebAssembly has some design choices that often affect other language implementations seriously (e.g. 0 being valid pointer).

Besides, the integration testing suite developed by @willemneal runs contracts as Wasm not x86.

This is good news.

Do we have any data-driven evidence that compilation of the smart contracts is actually an issue to our partners? We could ask Ashley Crawford to do a survey. If you would like to have this argument then the burden of doing such research is on you. Given that Solidity contracts take approximately the same time to compile it is unlikely that anyone would see it as an issue.

We don’t have data but given you are deferring to experts I will do to – @corwinharrell what do you think. Will around 10x bigger project startup time is likely to be affecting conversion rates?

Closest things I have is data on how many repos are using respective libraries on GH:
https://github.com/search?l=TOML&q=near-sdk-rs&type=Code
https://github.com/search?l=JSON&q=near-runtime-ts&type=Code
https://github.com/search?l=JSON&q=near-sdk-as&type=Code

This obviously has a lot of confounding variablew but if anything shows that AssemblyScript SDK is pretty popular choice for public repos using NEAR and seems to get more popular over time (compare near-runtime-ts to near-sdk-as).

In the issue that you have linked it was answered that this is not an issue of Rust, but rather the fact that we haven’t added no-std support for near-sdk-rs yet. Given that AssemblyScript STD is quite minimal it is more correct comparing Rust no-std contracts to AssemblyScript contracts in terms of their size.

I’m excited for no_std, but we are de-facto right now on mainnet having 10x higher cost on contracts which are deployed using Rust vs AssemblyScript, so it doesn’t matter what Rust can do in theory.
For many projects it’s crucial to have contracts deployable by users. AS currently provides practical advantage here for now.

We did not find any bugs in Rust STD or compiler not because we are supporting near-sdk-rs, but because the language is mature.

How do you think it did become mature? People were using it more and more and finding and fixing bugs.

Similarly, if we put more energy into near-sdk-as it won’t guarantee that AssemblyScript compiler or STD will become bug free.

I didn’t ever try to imply it’ll become bug free. No software is bug free. Take for example Rust:

https://github.com/rust-lang/rust/issues?q=is%3Aissue+is%3Aopen+label%3AC-bug (2k+ unresolved compiler bugs)
Issues · rust-lang/rust · GitHub (WASM specific compiler bugs)

We just would identify more bugs and get them fixed, exactly like happened for existing problems. AS folks are pretty responsive for actual bugs.

Finding a bug in a compiler or STD is a much more serious issue than finding a bug in a user code.

nearcore isn’t your normal user code. It’s OS code on which we execute user code (smart contracts). near-sdk-rs is STD from NEAR devs point of view.
nearcore bugs are arguably far more impactful than anything in smart contracts.

The intention was to show that if users had a choice between JS, TS, and AS they would’ve chosen JS.

Among 3 similar languages users have chosen most familiar and flexible and generally voted according to relative popularity of languages. No surprise here, except I didn’t expect Rust to have less votes than other languages in total. I’d prefer to use JS myself everything else being equal.

It’s purpose is also to show that some users might not grok low-level implications of choosing one language over another, e.g. JS might not be the best contract language in terms of safety and minimalism once compiled, however many users chose it.

It’s not clear from survey you need to take these implications into accounts. Like in theory you can make JS system optimized for blockchain usage (i.e. pre-compile into intermediate code during deploy, make VM startup faster, etc).

As for safety I highly disagree this is top priority for every use case. It definitely is top priority on ETH as with $10-$200 transaction cost the only viable use cases are capital heavy and so super risky. Still ETH somehow managed to pull it off with extremely immature purpose built VM and language. NEAR brings transaction cost down and makes use cases with less capital involved (e.g. Berry Club, Paras) far more viable. Which means speed to market can often be far more important than safety.

Also check out pretty interesting research (http://earlbarr.com/publications/typestudy.pdf). Having static type checking empirically is preventing around 15% of bugs compared to plain JS projects. However this still means 85% of bugs are happening regardless. So it is an improvement, but not even close to order of magnitude improvement.

2 Likes

@dcode We need to run a non-optimizing compiler so that the compilation cost can be approximated from the program size.

I’d be very interested in merging more tests upstream and fixing issues discovered in the process, but ideally in a way that I can still focus on milestones like bootstrapping as it achieves invaluable confidence into the compiler or general progress on fronts not many people can help me with. I am sure that others on the team would also welcome PRs for more standard library tests and issues discovered in the process to fix. If that helps?

This helps, thank you. If we decide to contribute to the stability of the AssemblyScript compiler and STD we would be grateful if we could have a joined planning and get a commitment from AssemblyScript core team.

@corwinharrell Thank you for coordinating the research. I am sure it took a good chunk of your time. Regarding not conflating JS, TS, AS, we unfortunately have stories that I shared above when we sold AS as TS to users and they had to redo their entire project because they were operating under wrong assumptions. Please get back to us with the quantitative data ASAP, since we would like to make this decision by EOW.

@vgrichina

I personally think we should enable multiple languages – this is whole point of WebAssembly. Also generally trade offs between languages often are highly subjective and every OS typically has different languages for different use cases. I don’t think 100m Defi projects and Berry Club’s of the world should be using the same language.

There are two issues with focusing on making our devtools language-agnostic:

  • We are operating under limited resources and time. It is much easier and faster to achieve a polished end-to-end development experience when we are focusing on single primary language than if we are trying to generalize it to all languages. It makes life of Contract Runtime, Berrypickers, DevRel and DevCommunity teams much easier. Once we have polished it for one language we can think of how we will be generalizing it to other languages;
  • Language-agnostic devtools is only a vision. It is unclear how it would translate to specific technical designs, and whether some of it is even going to be feasible.

This is not true. You can interact with ganache via RPC from any language. You probably aree confusing with Truffle which provides JS testing framework (and there is very huge difference between providing JS and Rust as options, JS is vastly more popular and familiar).

Correct, I mean Truffle. Thanks for correcting.

So let’s decide whether arguments should be backed by data or deferred to authority, as you seem to be doing either
What I know for sure is that if we don’t fuzz for trivial issues – attackers will do it.
I agree 100% it’s not going to be guarantee of security however, same as literally anything else.

The decision making is done used by both data and expert opinion (not to be confused with authority). I would expect opinions on what market prefers to be backed by data and opinions of feasibility and safety to be backed by expert opinion, since general audience is not familiar with implications of choosing this or that compiler.

To understand whether we want to spend any time on fuzzers and how we prioritize it against other work items, we need to understand the potential impact fuzzers might create, how much our users will value them, and whether there are better alternatives, e.g. making our integration testing framework more polished. Please feel free to follow up with Berrypickers on collecting data from our community on how useful it might be compared to other options.

We don’t have data but given you are deferring to experts I will do to – @corwinharrell what do you think. Will around 10x bigger project startup time is likely to be affecting conversion rates?

As explained above, I would defer to experts only when it comes for opinions on deep tech, e.g. is there any JS->Wasm compiler that is safe to use? Is AssemblyScript compiler stable enough to not accidentally cause UB? Market preferences should be backed up by data.

Closest things I have is data on how many repos are using respective libraries on GH:
https://github.com/search?l=TOML&q=near-sdk-rs&type=Code
https://github.com/search?l=JSON&q=near-runtime-ts&type=Code
https://github.com/search?l=JSON&q=near-sdk-as&type=Code

This is interesting data, thank you! (don’t forget that near-bindgen was an old name for near-sdk-rs) I wonder how much the fact that http://docs.near.org/ uses AssemblyScript examples has biased people trying NEAR Protocol to create more repositories with AssemblyScript examples compared to Rust examples.

I’m excited for no_std, but we are de-facto right now on mainnet having 10x higher cost on contracts which are deployed using Rust vs AssemblyScript, so it doesn’t matter what Rust can do in theory.
For many projects it’s crucial to have contracts deployable by users. AS currently provides practical advantage here for now.

I don’t think 10x is a fair comparison. The size of the contract does not grow linearly with its complexity, especially when people start importing external dependencies. Given that AssemblyScript ecosystem has almost no libraries it biases people who want to write complex projects to choose Rust over AssemblyScript since they don’t want to reimplement all the dependencies themselves. So 10x difference could be a signal that people do not use AssemblyScript for anything medium to high complexity.

How do you think it did become mature? People were using it more and more and finding and fixing bugs.

Rust became mature by being supported by Mozilla with dozens if not hundreds people paid to continuously improve it.

We just would identify more bugs and get them fixed, exactly like happened for existing problems. AS folks are pretty responsive for actual bugs.

Identifying and fixing bugs in a compiler and STD is a huge undertaking, unlike other software projects. It took Rust 9 years and the backing of Mozilla to become a stable compiler. It took Go lang 5 years and the backing of Google to become a stable compiler. AssemblyScript has ~2 core developers and has started development around 2019. Support from NEAR creates a big impact for AssemblyScript, however, we need to be honest about the degree of complexity we are talking about here. Even if throw our entire organization at it, if history is an indicator, it would take many years and dozens or hundreds more people working on compiler + STD (not to be confused with people just using AssemblyScript) to get it to a stable state.

nearcore isn’t your normal user code. It’s OS code on which we execute user code (smart contracts). near-sdk-rs is STD from NEAR devs point of view.
nearcore bugs are arguably far more impactful than anything in smart contracts.

I disagree, nearcore+near-sdk-rs is not as low-level as compiler+STD.

Among 3 similar languages users have chosen most familiar and flexible and generally voted according to relative popularity of languages. No surprise here, except I didn’t expect Rust to have less votes than other languages in total. I’d prefer to use JS myself everything else being equal.

The survey is actually an indicator that we cannot rely on the preferences of the community alone when deciding whether to support certain language as a contract language. JS might be the most favorite language, but regular developers do not know that JS contracts might be incredibly large in size once compiled to Wasm, or that JS->Wasm compiler is not production ready. Similarly, we cannot rely only on the opinion of the community whether to support AS->Wasm compiler and we should be using opinion of compiler experts in our organization.

It’s not clear from survey you need to take these implications into accounts. Like in theory you can make JS system optimized for blockchain usage (i.e. pre-compile into intermediate code during deploy, make VM startup faster, etc).

We might be able to do that, but it might be much more difficult than doing it for other languages, even TypeScript.

As for safety I highly disagree this is top priority for every use case. It definitely is top priority on ETH as with $10-$200 transaction cost the only viable use cases are capital heavy and so super risky.

Our requirements is a super set of Etheruem requirements. What you are saying is that we can be focusing on being faster at a cost of being safe, because ETH ecosystem biases use cases to be capital heavy. However, we also have capital heavy use cases. In fact, our fist step in org strategy (that will be presented by @illia) is addressing existing capital heavy market. So we need to be both safe and move fast.

Still ETH somehow managed to pull it off with extremely immature purpose built VM and language. NEAR brings transaction cost down and makes use cases with less capital involved (e.g. Berry Club, Paras) far more viable. Which means speed to market can often be far more important than safety.

I expect people to compare our quality to the present days Ethereum not early days Ethereum.

Also check out pretty interesting research (http://earlbarr.com/publications/typestudy.pdf). Having static type checking empirically is preventing around 15% of bugs compared to plain JS projects. However this still means 85% of bugs are happening regardless. So it is an improvement, but not even close to order of magnitude improvement.

That’s correct. Thank you for sharing this link even though it does not fully support your point. We might want to focus on polishing our integration testing suite instead of focusing on static analysis or fuzz testing.

Think Option 5, while highly attractive is hard to do practically. So my personal inclination here around Option 3 or Option 4, with C++ as the language. It may sound strange, but C++ after 14 (see C++14 - Wikipedia) become rather attractive language due to type inference, lambdas and such. Another possible option is Lua (GitHub - vvanders/wasm_lua: Lua VM running in a WASM environment).

Another option is to provide tooling which automatically generates Rust contracts out of simple wizard/graphical language, so that initial bootstrap is handled by tooling, and then developer can have functional contract immediately. For example Scratch educational visual programming language (Scratch (programming language) - Wikipedia) is OSS and could be tuned to produce smart contracts.

As an educator here’s what I’ve noticed that’s relevant to this discussion:

Developers may like the idea of writing contracts in a language they believe they already know.

Capturing mindshare is a difficult game. The phrase “AssemblyScript is like TypeScript” makes NEAR an attractive option in a sea of (some very) esoteric alternatives. The perceived “low opportunity cost of exploring NEAR” is likely a major factor in attracting developers to our platform in the first place. It would be imprudent to ignore the potential impact of extinguishing this lighthouse of engagement.

And although it is true that this has lead to significant confusion in the past (as presented by @nearmax above), our documentation and examples made a hard switch in how we frame AssemblyScript around Q1 2020 to address this confusion. I believe this switch in our messaging was effective but have not done the due diligence to support this claim beyond the anecdotal evidence that several non-trivial Hack the Rainbow submissions were written in AssemblyScript.

“NEARly thinking” is a process that does not require extreme levels of rigor at the outset

NEAR boasts a unique account model that is at once both trivial for web developers to understand and yet consistently disorienting for Ethereum developers. NEAR’s composable actions, asynchronous cross-contract calls, permissioned access keys and other features are also part of NEARly thinking.

It takes time for people to wrap their head around these ideas – let alone “why blockchain?”.

For the average developer – I’m speaking here of people like me who have never dreamed of applying to compete an ICPC event – this early learning time is better spent adapting to the many new and innovative mental models of NEAR rather than fighting with the Rust compiler.

For this reason, AssemblyScript (or any other low-overhead, prototype-friendly) development is a valuable rung in the mass-adoption ladder.

Insisting on Rust may inadvertently stifle innovation among our community members

Reducing or eliminating support for AssemblyScript has the very likely impact of

  • reducing the number of incoming developers (see above two points)
  • increasing the barrier to entry for new developers (Rust learning curve) and
  • threatening our appeal to underrepresented groups in tech (this is a topic for another time)

Rust programming is not “smooth” (as experts admit). The ROI on this masochism is the unprecedented safety needed for money and identity.

The increase in difficulty of fluid self-expression through code is likely to make people less playful, less creative and therefore less innovative with their contributions as they hesitate to take on the lonely, little death of one failed build after another.

In this regard, AssemblyScript (or any other language designed for, or associated with, play) is a valuable asset to our community.

Having said this, I can not defend with numbers the anecdotal evidence collected in my work with @corwinharrell (as @nearmax invites us to do above). The design intent of that research was to gather user stories through expert observation.

We spent several hours pairing with developers as they struggled towards NEARly thinking.

I was left with the distinct impression that the syntactic familiarity provided by AssemblyScript during the learning process reduced cognitive load to the point that developers were able to reason about the system and draw meaningful conclusions free of distraction from the compiler.



Based on this discussion I would weigh in with something between Options 3 and 5

Specifically:

  1. Recognize AssemblyScript as an effective onboarding tool to the NEAR platform for JavaScript / TypeScript developers and as a medium for creative early contract design work along your NEAR journey. Now is the time to attract and retain new developers, not 6-12 months from now. I tried to make this argument above.

  2. Transition to focus all our internal, tightly integrated efforts on a unified technical runway paved in one language: Rust, to de-risk our ability to deliver on our ambitious goals (Option 3). @nearmax makes a sound case for this above.

  3. Fund one (or better, many small) external partner(s) to take on the challenge of owning and improving our AssemblyScript tooling as well as other languages and programming environments. This fund should be significant and reflect the far reaching ambitions of this project with focus on the most popular languages by adoption volume first. (Options 3+5) @frol, @vlad and @olonho make good arguments for this above.

  4. Hire a competent, capable internal representative as liaison to external partners. This role would be dedicated to maintaining something close to parity between internal design changes and external development efforts so we don’t outpace our partners and threaten the integrity of their work. Although this point is only briefly mentioned above, divergence across organizational boundaries will become a big risk after separation of responsibilities. This may require more than one FTE. (Option 5)

5 Likes

@amgando

Capturing mindshare is a difficult game. The phrase “AssemblyScript is like TypeScript” makes NEAR an attractive option in a sea of (some very) esoteric alternatives. The perceived “low opportunity cost of exploring NEAR” is likely a major factor in attracting developers to our platform in the first place. It would be imprudent to ignore the potential impact of extinguishing this lighthouse of engagement.

To paraphrase, the choice of calling AssemblyScript a TypeScript is a marketing choice. There are however pros and cons to doing this bait and switch. We have examples of projects suffering from finding out AssemblyScript is not TypeScript. Their disillusionment hurts our image, and we have actually measured through surveys how much the image of NEAR drops in eyes after users actually try writing contracts in what is sold to them as TypeScript to later find out that this is not a TypeScript. It is unclear whether pros outweigh the cons.

The other issue, is that we have explicitly agreed as an organization to not call AssemblyScript TypeScript. It is unclear why this was reverted for that research.

For this reason, AssemblyScript (or any other low-overhead, prototype-friendly) development is a valuable rung in the mass-adoption ladder.

I agree that AssemblyScript is valuable. The question is how valuable? Supporting AssemblyScript comes at a cost, do the pros outweigh the costs?

To summarize. If we want to argue in favor of supporting AssemblyScript we need to answer the question: “How exactly is AssemblyScript valuable for NEAR?”. Instead the question that was mostly answered in the replies in this thread is “Is AssemblyScript valuable for NEAR?”. The default choice for committing to any technology in our organization is no – that is there needs to be a reason to commit to something, not the other way around. There is however an exception when we cannot evaluate value of something without committing to it, and so we run an experiment with the goal of collecting the data. We’ve been supporting AssemblyScript for several years now, however it is unfortunate that we haven’t used this opportunity to collect the data to answer the question: “How exactly is AssemblyScript valuable for NEAR?”. The experiment, however, cannot run indefinitely, because the nature of experiment is that it is temporary.

what kind of data do you need to show that AssemblyScript is valuable.

right now there is

  • deep UX research from @corwinharrell and @amgando showing users prefer AssemblyScript and don’t have good understanding why would they use Rust instead (having 200m locked in smart contract would be good example, maybe we need to make it more clear)
  • your own survey showing that 58.1% of people prefer to use JS-like language over Rust
  • 239 total GH matches for AS SDK vs 73 for Rust.
  • top-grossing third-party dapp on NEAR is built using AS SDK (Paras) and generally is a solid case study of web team being able to iterate quickly on concept (i.e. what we wanna out of AS support).
  • about 5x-10x smaller .wasm sizes on practice currently in prod. Which impacts both storage cost and execution cost because of .wasm compilation.

Note that both our docs:
near-sdk · NEAR Documentation and examples have solid stuff on Rust:
https://examples.near.org

So I don’t think we are biased towards AS. In fact we had to cancel NEAR Studio to accommodate Rust as main focus. Which according to @illia has negatively impacted engagement with web IDE.

But we had to do it because there is expectation that Rust going to be safer for use cases with a lot of money. It’s probably true though never was supported by strong data (e.g. nearcore had serious security issues despite using Rust) but by trust into maturity of language.

Rick Tobacco (user in our Telegram) wants to work on C++ SDK actually. We should definitely give grants for support as e.g. it might attract some EOS devs. Or generally people who want to start doing something new with C++ (SF WASM meetup had plenty of such folks).

Unfortunately C++ generally has similar issues as Rust:

  • slow compilation speed
  • large executable sizes
  • not something most webdevs would want to use

Lua is super cool idea as a bounty as well if it’s fast enough – strong synergy with gamedev community. Won’t hurt for NFT adoption.

My 2 cents and a question for @dcode:

Is it possible to make AssemblyScript and Typescript more compatible?
I mean, is it possible to make AssemblyScript compile most of valid Typescript code to WASM?

If developers can use the same mechanism they’re using with Rust (i.e. test and debug on x86, leveraging rust tooling, but finally compile to WASM), it will make AssemblyScript way more valuable and powerful. I mean if I can use all the incredible powerful and ubiquitous Typescript & Javascript IDEs & debugging tools to debug a NEAR SC in written in “TS/AssemblyScript”, it makes AssemblyScript a much more valuable tool for NEAR and for any other WASM-based env.

I understand that there are pain-points for compatibility e.g. big integer management, u64, u128, u256, u8 arrays, but those are language design decisions that can be changed, for example devs in Solidity use a safe-integer library with methods like sub() add() mul() a-la LISP. This is ok and acceptable. We can manage big integers like that and make AS and TS compatible.

I understand that this means AS not being a “different language”, and becoming a “compile to WASM” option for TS, but I think that’s a good thing!

If changing the direction of AS is not possible, Can we make at least some “AS version/subset” that’s oriented to be: compilable, debuggable and executable in a TS/js environment, with all the highly powerful TS/js tools?

All these requests come from my experience with AS, mainly trying to write in AS the staking-pool rust core-contract. It was a frustrating experience. The same happened to me, I started writing TS only to find minor differences that prevent me from using all the TS/js powerful tools.

1 Like

To clarify one point in my position: I’m against removing AssemblyScript from our docs and tooling. I tried to make the case for keeping AssemblyScript as a prominent feature of our developer onboarding experience. But I do support de-risking our roadmap by offloading ongoing AssemblyScript maintenance (and even expanding to other languages) to partners and community.

@nearmax – Regarding what you say here about “reverting for that research” …

I think you may have gotten the wrong impression about this. We were not referring to AssemblyScript as TypeScript during the research nor have we made that mistake since we agreed as a team almost a year ago to be explicit about AssemblyScript. For sure this is the case in anything I’ve been directly involved with. We can discuss offline if you prefer since this is out of scope here but I wanted to make this clear.

1 Like