How do Snap! blocks convert to JavaScript?

You're off by an order of magnitude. Ten thousand. More than ten thousand lines of code :slight_smile:
The comment at the beginning of that file is over a thousand lines of explanation, though. Did you read it? I've written it in English.

What's the "yikes" about, though? If you don't want to read go watch some movies, and if you don't want to think go play with some chat bot. But don't tag me here with questions about JavaScript or about how things works if you're too lazy to think. This about hard fun. I'm sorry if you're not ready for "hard".

Jens. Be nice.

@blockpointstudios: Even 10K lines isn't very much to implement a programming language. If you seriously want to write such a thing, you first have to learn how to read a large program, namely, not straight through from beginning to end, but in layers of abstraction, from big chunks (evaluate this script) down to details (look up the block in a table).

I just have one more question. How are the blocks the program?

EDIT: I think I understand now. As a block runs, it gets interpreted for computers to understand. Instead of compiling the whole project into another language, only one line is interpreted.

On another topic, I do understand that my comment about morphic.js was quite rash, and I'm currently reading the documentation. I have heard from other sources that Blockly is the best way to create a similar visual programming language, but I'd like to attempt this without it. I'll probably use morphic.js, as it was created for easier use of JavaScript.

I was like you, but before you made your question, I did it myself without asking to the forums, and yes, Snap! is not a compiler, is an interpreter, because, the Javascript is only for the block processes, not for the execution of the entire script, lambda and rings are just like containers of the copy of the blocks to execute the copies and get results of them. The ring object is the Context, that object have Context.prototype.toBlock to get a RingMorph based of the Context, and the Context to contain the blocks and continuations are in the expression of the Context. The RingMorph heirs from ReporterBlockMorph, that's why the reporter and ring blocks are too similar. The Context is on threads.js, and the block morphs are on blocks.js. Take care, this is just a clue for you. See ya! :wink:

Thanks!

Did you make your own visual programming language? If so, would you say that morphic.js is vital for creating one...?

Well, I'm creating one, public will be soon, but is just another fork of Snap!, but yes, morphic.js is the base to create morphs, animations with them, any use to them is possible, but only at your manner to demonstrate it. My programming language extends and revitalizes Snap! to a better one, with goods and bads, but yes, the name of it, is Super-Snap!. Search only in the forums, and you will be impressed!!! :wink:

Besides the documentation, are there any tutorials?

To the self Snap! and my fork, no, but discover it by yourself. :slightly_smiling_face: :lambda:

Hmm...

Does the placement of blocks in the editor affect how the project runs? Also, do you need to create a separate id for each instance of the same block?

Yes, the blocks in different placements can change the interpreting of them, but no, the ID is not necessary for the execution the blocks, also the blocks run in different processes, any block is similar to another one but not equal to them, only by itself.

And if do you wanna to view a post with a Super-Snap! beta, just go to this one... True Fullscreen request? (and more other features)

Then, how do blocks get interpreted if code isn't assigned to an id?

The code are in three objects at the moment, there are SpriteMorph, StageMorph and Process.
If the name of the object ends in Morph, is just a heir of the Morph, the Process is just the object is not a morph but executes the code of the blocks by their selectors, any heir of BlockMorph have its own selector, that means that the code of them are executed in any of the three objects that I mentioned above, just search any coincidence with the block's selector and one of them is the code.
The code are on (SpriteMorph.prototype. + selector), StageMorph.prototype. + selector) or Process.prototype. + selector) The "+" means that just fuse the .prototype. and the selector. :wink:

Sorry. What do you mean by selector?

The selector is the block's own name to identify to its own code.
For example, the selector of "move %n steps" is doForward.
Another example is that the selector of "wait until %b" is doWaitUntil.
The final example is that the block spec of doForever is "forever %loop".
Not all the blocks have the selector similar to the block spec. :exclamation:
And the hat blocks have no code in their selectors, the code are executed
with the triggers that are linked with its block specs. The only hat block that
have a code in its selector is the "when %b" block with selector doWhen, and
it's code is in ThreadManager.prototype.doWhen in threads.js. The selectors are in
objects.js. And the code of them are in threads.js and objects.js too. :lambda:

Thank you so much! How does the script turn %n and other codes into actual inputs, and how is the input sensed by the script?

Morphic is vital if you want to make a lively language, i.e., one in which you can drag a block into (or otherwise edit) a script while it's running, and the change takes effect immediately. Morphic gives very detailed control over things like which object sees the drop when you drag a block onto a pile of overlapping objects and let go. Early on, in the development of Snap!, in certain situations it was hard to drop an input onto the input slot you meant, and Jens fixed it by giving priority to empty slots over slots that already had something in them. You have to have your own widget manager, Morphic or equivalent, to be able to control the user interface at that level of detail.

But that's not how most people do it, because the browser has its own window manager, called the DOM, and if you want to put things in a window it's much easier to use the DOM than to roll your own. Besides the obvious point that if you use the DOM you don't have to invent your own window management, the browser makes a lot of things easy that people don't even think about as issues. For example, the DOM provides text copy-paste, specifically taking charge of which object you're pasting into when a bunch of them overlap. For the longest time, you couldn't paste into BYOB text fields, and specifically, you couldn't copy your password from your password manager program and paste it into the BYOB login window. (By the time Snap! came along, that problem was solved.) With Morphic, as far as the DOM knows, the entire Snap! window is one big bitmap canvas, so it can't help you organize text fields.

When Jens rewrote BYOB as Snap!, we had a one year deadline. Jens spent the first eight months of that year implementing and debugging the Javascript-based version of Morphic. I was terrified! But once Morphic worked, he wrote the whole rest of Snap! in four months.

There are other costs, too. Browsers come with huge libraries of user-contributed extensions. I have 14 of them installed in my Chrome and even more in my Firefox. Here are a few of them:

Dark Reader, which provides dark background viewing on a per-site basis (because some sites break if you do it the simple way).

Duck Duck Go Privacy Essentials, which removes advertising and tracking from the pages you view.

LastPass, a password manager that remembers all your passwords for you (because that makes it easy to use a different password on each site, which is the right way to protect yourself).

NoScript, which removes things from web pages, like the Duck Duck Go one, but with much more detailed control over different types of threats. (The cost is that you spend your first few weeks with NoScript tuning it up for your particular level of paranoia and your particular exceptions, whereas DDG Privacy just runs out of the box.)

Volume Master, which has per-site volume controls (so you can crank Snap! projects way down, for example).

... and so on. Anyway, the point is, those extensions modify the processing of particular kinds of DOM elements, so they automatically work on web pages implemented in the DOM, but they don't automatically work on Snap!. Having to implement our own copy-paste is an example; that would have just worked if we'd used the DOM.

Thank you!

The inputs of the blocks are evaluated with the name of the object you selected and .prototype.evaluate or to the really expand the evaluation, just search Process.prototype.evaluateInput and put () after the function, and in the inner of the () put a variable of with an input inside that, just like proc.evaluateInput(input) meaning that proc is any process and input is the input that you put in a function parameter just like
function anonymous (input) {}, inside of them you put the algorithm in different ways,
one of them is function anonymous (input, proc) {return proc.evaluateInput(input);}, just test it with a "call %cmdRing %inputs" block, put only an imaginary variable which contains an block input inside, and no second open input is necessary, that's because that the javascript block's proc input is fulfilled with the process of the "call %cmdRing %inputs" block because calling the javascript is just applying the same function but the inputs add the process itself if the last of the javascript inputs is not in the "call %cmdRing %inputs" block, just there is the explanation at all. :wink:

Oh, the code sense the input with the function parameters of them. :wink: