
Scrap is the way
Updated on
The Story of Scrap
My coding journey began with Scratch, an intuitive platform that introduced me to the world of programming. Yet, as I ventured into JavaScript, I faced a formidable challenge. While Scratch had provided a solid foundation, the transition to JavaScript felt like a daunting leap. This challenge ignited the idea for Scrap, a tool designed to simplify the transition from block-based programming to JavaScript.
Download ScrapFeatures
- Block-based coding – While Scrap encourages the transition to text-based programming, it supports both block and text editors.
- Strongly typed – In the text editor, Scrap supports TypeScript type annotations, which provide type safety. In the block editor, Scrap won’t allow you to connect blocks with incompatible types.
- Blocks ⇆ Code – Scrap allows you to convert blocks to code and vice versa. This feature is especially useful for learning JavaScript syntax.
- No VM, no interpreter – Scrap compiles your code to JavaScript, which means that you can run it anywhere, without Scrap.
- HTML output – Scrap allows you to export your code as HTML, which means that you can share your projects with anyone, anywhere.
- Open-source – Scrap is open-source, which means that you can contribute to it and make it better.
Code × Text
ScrapScript
is a code name for the problem of the incompatibility. It aims to design an ECMAScript subset, which
can be converted to blocks and back as easy as possible.
It’s been obvious since the very beginning that ScrapScript needs to be typed, as not all blocks are compatible by shape. Previously, this was handled via JSDoc but when the Monaco Editor was introduced in Scrap 4, TypeScript was way more helpful.
However, not all JavaScript features will be supported. Classes, symbols, regular expressions, modules, sets & maps, undefined, template literals, and many more…
And some equivalent features lose their different syntax when converted. An example might be:
object.toString();
// After conversion to blocks and back
String(object);
Thanks to #158, I realised that Date.prototype.getTime()
can be
implemented.
// These are equivalent:
object.valueOf();
Number(object); // default Scrap syntax
+object;
object.getTime(); // for dates, #158
The inspiration
The name Scrap is a combination of the words Scratch and Snap, two block-based programming languages that inspired me to create Scrap. Snap gave me an idea to make the IDE advanced and powerful, while Scratch inspired me to make it intuitive and easy to use.
Under the hood
The technology
Scrap is coded with Rust, TypeScript, and Sass.
Scrap consists of HTML frontend and Rust backend. The Rust backend handles the underlying logic, and also the compilation of user code to JavaScript, with the help of SWC. The frontend is built with TypeScript and Sass and uses Blockly as a block editor. The code editor is powered by Monaco Editor.
Scrap uses technology based on BlockLike.js as an engine (not VM).
Scrap engine and SWC
Scrap Engine is based on BlockLike.js; these days, the code bases are totally different, and the features differ as well.
As Scrap doesn’t have a VM, somehow it needs to delay block execution (like Scratch does), and control code execution. The compiler handles most of that, but still, some things must be done at runtime – setters, getters, and throwing uncatchable errors do the job.
Scrap comes up with a SWC plugin, which provides users better coding experience, as their code can be less ugly
.
That means, if one includes Scrap Engine and uses just the code written in
IDE, it won’t work.
Let’s see how the engine and SWC cooperate:
- Async / await
- Scrap Engine’s methods are asynchronous
- In IDE, users don’t even notice, as SWC adds the necessary keywords
- Setters / getters
- Scrap Engine needs to have methods instead of getters and setters (
self.getX()
andself.setX(10)
- In IDE, users use the more familiar syntax:
self.x = 10
- Scrap Engine needs to have methods instead of getters and setters (
- Control flow
- When the Scrap engine needs to, or is told to stop the project, it throws
Scrap.StopError
- SWC makes sure users cannot catch the error, as this would lose the effect
- When the Scrap engine needs to, or is told to stop the project, it throws
- On-screen variables
- Scrap engine allows to have Scratch-like on-screen variables
- SWC allows users to declare them inside the
Variables
interface and rewrites the setters and getters
- SWC also handles the conversion between blocks and text
Monaco Editor
Monaco Editor is extended, so it provides:
- TypeScript IntelliSense tied to the Scrap environment
- warning about the block-incompatible syntax
- color pickers when using Scrap’s color functions
- syntax highlighting mirrors the block colors
Conclusion
Scrap is a tool that simplifies the transition from block-based programming to JavaScript. It is designed to be intuitive and easy to use, while also providing advanced features for more experienced users. Scrap is open-source, which means that you can contribute to it and make it better. If you are interested in contributing to Scrap, please get in touch with me.