How are ideas implemented into Snap!?

Hello! I'm very fascinated by the development process of Snap!, specifically how new ideas are formulated and implemented. I know there are few developers (and that Jens programs), but what goes behind the design of new features? Do ideas abruptly emerge? Is there a list of design goals or criteria? Do you try to minimize redundancy or syntactic sugar?

Thank you very much!

Some years back, Jens made a list of all the major features he had in mind up until around now, and for the most part he's been checking them off steadily. But some major things not on that list have also been done.

For example, I've been bugging Jens about APL-style array processing since I joined the team for BYOB 3. But when Jens learned from Mark Guzdial about media programming, he suddenly became excited about it for efficiency reasons.

The recent JS-dictionary based OOP work was also a sudden idea, because German CS teachers were asking for it.

Metaprogramming, on the other hand, was on the list all along. I think it was the last item (I don't have a copy handy), so who knows what's next... well, except I'm excited that meeting the needs of people who want to specialize one menu input based on the setting of another one has gotten Jens 90% of the way to a general internal definition feature. The main obstacle was making a block's script variables available to any code in its Block Editor window, not just to the main block itself, and now we have that. Internal definitions are another thing I've wanted since the beginning.

The ability to use dynamic scoping, another thing I've wanted all along, is now doable using the THIS CALLER block.

I know Jens still wants to improve our handling of sounds, so you should expect something to happen about that eventually.

A huge elephant in the room is accessibility for people with visual or motor impairment. The keyboard editor is a first step, but there's lots more we need, including in particular an interface to screen reader software.

We also know the costume editors (bitmap and vector) need a rewrite. I'm guessing that now is a good time to take a break from big new features to deal with that, and with incremental backup saving (maybe log-based), and a bazillion little things that have been in the github issues collection forever.

In parallel with that, we're working on improving the community site to have better support for classroom teachers and to allow comments on projects as everyone wants.

Most of our big ideas have come from the languages we grew up in, namely Smalltalk for Jens and Lisp for me. Those are two of the small number of programming languages that embody important big ideas in computer science; APL is another. And Prolog, which can be implemented as a library written in Snap! itself. (That's almost at the hold-your-breath stage, thanks to @qw23.) In my view those are the big four. We've learned from Henry Lieberman's design for prototype-based object inheritance done right (as distinct from how JS does it). Continuations, of course, come from Scheme, our preferred dialect of Lisp.

(By contrast, the whole mainstream C-based languages, including JS, Java, and Python, are based not on big organizing ideas but rather on exposing to the programmer the weaknesses of computer hardware. That's entirely appropriate for C's original purpose, namely to implement the Unix operating system, or operating systems in general, or the memory management part of a programming language processor. But it's harmful when used as a general-purpose language, and especially when used as a teaching language. Imho.)

Our design goals have been changing, in what I view as a sorta chaotic way. When we started out, our goal was to have a minimal language in which other features could be implemented by the users; we were very proud about getting first class procedures and lists while adding only eight blocks to Scratch. We are super proud that FOR, MAP, etc. can be written in Snap! itself.

But when you write such basic tools in Snap!, your programs run slowly. Over time we've implemented more and more, especially list processing tools, as primitives. I'm pleased that they're primitives, so we are putting our best (functional) foot forward about list programming, but also sad that students don't get the benefit of writing them themselves. The recent addition of editable primitives is another thing I've asked for since forever! This should let us have our cake and eat it too. But we have to settle whether the code you see when you choose Edit on a primitive block should be the simplest possible version that gets the point across


or should instead implement all the bells and whistles of the primitive version. But once that's all cleaned up, and I (or you...) get around to Scheme-style hygienic macros with define-syntax, and qw23 finishes the logic programming library, I'll feel like our programming language work is done, and from there on it's all about the GUI. (For example, the ability to lasso a bunch of scripts and drag them all into the palette to delete them all at once.) But that's me, and I'm not speaking for Jens about this.

Syntactic sugar is becoming more of a thing thanks to metaprogramming. (That is, users can add their own.) I'm perfectly happy about that, although as you know Jens is less so.

Thanks for your interest!

I've been wondering, internally, how do the prototypes for the blocks that have actual definitions handle them? Do they use a 1:1 Snap! to Javascript translation? Are they ran like custom blocks (meaning, are the definitions written in Snap!, parsed into js as normal, and ran as thus)? Or are they just written completely differently and the definition is just a functional front?

Further more, how are modified main primitives handled?

I guess these are questions more suitable for Jens

Christmas sathvikrias

wait, can you please give an example? Is that different from when slot [ V] signals [ V], set slot [ V] to [], and expand [ V] to () slots ?

what would there be to add? sounds have pretty much the same handling as costumes, which seem fine.

:laughing:
random considering the rest of your post, but yeah, I guess.

I think.

not sure, I didn't find anything much out after looking for a really long time (for my xml script builder project).

I think he's talking more on how sounds are stored internally rather than the snap abstraction.

oh! that makes more sense.

As demonstrated by the definition of (combine @list using (() @addInput)) , the snap definitions don't always match up with their javascript definition. There was a whole discussion about this recently: Combine definition - sequence of evaluation.

When you run a primitive block, it checks for the first block in the definition, <> primitive [ V] . If the first input is true, then the javascript definition matching the selector in the second input is ran. If the first input is false, then the snap definition is ran.

Thank you for this explanation. It is probably one of the most valuable posts in the forum, imo. Also thanks to the op for bringing up the question.

Exposing design and implementation details of a CS tool like SNAP is very valuable and helpful in understanding the bigger picture. With an environment like SNAP, while the primary focus is user friendliness and adoption in educational settings, and thus the need to hide the complexity; there's still value in sharing the decisions and process behind for those interested in the beauty of the creation itself.

If the Boolean input to PRIMITIVE is True (the usual case), then the primitive is written in Javascript coded by Jens. That was obviously true before we had the Snap!-encoded primitive feature; there was no candidate Snap! code to translate to JS. Now it's not obvious, but that's still the case; the code for a primitive is written directly in JS. The Snap! code, if any, is run if you change the flag to False, but there's no guarantee that it does exactly what the JS code does. As I said above, my view is that we shouldn't even try to get close to how the actual primitive code works; we should leave out all the optimization, leave out the hyperblock behavior, and just give the simplest possible code that conveys the idea of what the primitive is about.

You mean, if you overwrite a primitive with a custom block? Then it's a custom block, just like any other Snap! code you write.

The first of those is a special case of internal definitions. I want to be able to put an arbitrary custom block inside a block editor, and have that block exist only in the context of the main block of that block editor, with access to the main block's local variables. Like this:

A sound editor, maybe? And some representation for frequency-domain arrays to make it clearer what the numbers mean.

Thanks!

Thank you so much for your reply! I appreciate that you took the time to answer!

Do you think that Jens would implement his own screen reader, or would he use open-source software?

This will make CPS much more convenient! Currently, my "helper" procedures are ringed scripts.

Back in 2020 (when I first joined), I would've been very excited about this, but I've grown accustomed to the forums. I hope that when comments on projects are added, we can still use Share your Projects as we do now.

Oop- I've been working on the same thing way before posting my "Custom Reporter Speech Balloon Formatting (and Custom Types)" topic. That topic exists only because I wanted to represent facts and rules better. Well, I've moved on to higher-order types and hygienic macros, so I guess it was for the best! : )

I've read that document more times than you could count! Lol.

That would be very useful, though there are already a lot of quality-of-life features! Yesterday, I learned that holding shift while dragging a block extracts it!

Although I love Snap!, I feel that one of the disadvantages of having a block palette is that you're discouraged not to reduce boilerplate code within other custom blocks. When functions aren't all visible in the same place, creating a function doesn't feel so...impactful. (I feel the same way about variables, and this was one of my frustrations with Scratch.) Yes, I know you can hide blocks from the palette, but it just becomes harder to call them. I'm hoping that internal definitions come out in 11.0.0!

Thank you once again!

He would be adding support for regular screen readers, like JAWS or NVDA (I am very well-versed in the topic of screen readers).

Why would we not be able to? The forum can be used to give a bit more insight to some projects.

I misspoke. I did not mean that we would not be able to, but since project comments would be the more direct form of communication, they may be used more than the forums. However, the comments system may not have the features of the forums, so elaborate discussions about projects may be lost in favor of "Nice project!" and "Cool."

Even today (especially today), seeing Scratch look so much like Snap! is cursed to me

(I guess, rather, it's actually the other way around)

I absolutely love it. There's something so experimentally wonderful about it!

It's like seeing two related characters in a movie from different time periods at a reunion

Yes, the creative, well-known, and friendly guy...and their younger brother who wanted to study liberal arts but is now a software engineer.

True!!

Two months ago I thought of the same idea.

Is it feasible now?

Sadly, no. We got custom hats first. :triumph: