How to make a visual programing language like snap

but i prefer using snap!

Well, luckily, Snap! is actually Scheme (one of our slogans is "Snap! is Scheme disguised as Scratch") so you could study SICP and do the exercises in Snap!. :~)

Good thing. In Snap! you all have all the graphics by default, while in many text programming languages you need to import some module or extension. Oh! and blocks can sense way more features (microphone, camera, mouse position and more) easily and support sound.

Or you may want to utilize the scratch-gui in node and study it and then learn react for ui

If you want to learn OS design, I suggest Operating Systems: Three Easy Pieces

by studying the best computer science book ever written! (Link removed). And do the exercises! In Chapter 4 you get to write an interpreter.

We shall see, but this may be the key that unlocks my stubborn brain. Watch this space.......

I thought I'd tried this before, but maybe not, I know I tried your logo books and simply scheme in snap and for whatever reason, I couldn't do it, and thus never jumped to SICP, though last I studied SICP I did it scheme. I wanted to get a hang of scheme before I jumped into snap completely...

but... I SAY that, but I'm only at 1.1.5 so far... Crosses her fingers

It's slow going. Don't try to rush through it. And ask questions if you need help.

I got stuck very quickly, I'm doing the second example with Factorials, the one with the iterations (1.2.1), and the problem I always have is snap has commands and reporters and text languages do not. (And I could use run, but the example does not, so I thus do not want to do that either, I'm trying not to skip ahead)

The thing is, fact-iter has a variable called product, and you can't put variables in c blocks.

It's stuff like this that frustrates me very quickly and stymies me. Like, if such a simple subsitution error stops me in my track, is there any point in me bothering? and that's usually where I rage quit and go do anything else, but while I'm logged in to the forums....

If you mean the example at the bottom of page SICP 43, this is how (I think) it translates to Snap!:
untitled script pic (24)

untitled script pic (25)

See also: Snap! Ref. Manual ch. VIII.

Snap! also supports truly imperative style:
(but that's not what SICP uses for examples)

untitled script pic (23)

Not quite, because what it's driving at is compounding two seperate actions into one, it's trying to establish the thesis that if you start small you can build big, eventually it does do something like that, I think the final part of that section if I skip ahead does do something like that (I'm recalling that from the last time I read the book a couple years ago)

So just doing it as one block straight up, to me, defeats the entire purpose.
The thing that I keep getting stuck on, is that Scheme doesn't Can't delineate between a command and a reporter because it doesn't need to, because the visual is a snap! thing. I'd be less perplexed if there was a c-shaped that would take reporters, but then I'm not learning I'm copying blindly.

Which, I'm kinda doing by copying the examples anyway, the thing is, I can SEE what the examples are doing, and I want to replicate those to confirm what I'm seeing.

OK, so if I have understood you correctly you are looking for how the code in the middle of page 43 translates to Snap! ?

untitled script pic (29)

untitled script pic (28)

And now, building from this code, you want to be able to use the "substitution model" and move to code of post 30 (which is the equivalent of the code at the bottom of SICP, page 43) ... is that correct?

Scheme is a predominantly functional language; I suppose all of SICP's examples may be coded as Snap! reporters (or predicates; a predicate is a special case of a reporter).
Scheme's lambda (SICP p. 83) is a Snap! ringed expression (reporter or predicate).
Scheme's let (p. 86) doesn't have an equivalent primitive in Snap! but you can either use:
untitled script pic (35), or

, or , depending on context and your preferences.
There may be some less obvious translations further down the SICP text, but you'll cross that bridge when you get there (or ask for help in this forum). Good luck for now!

Gah. You're right!

The annoying part is that I'd already figured that out the night before with one of the earlier examples, the "Square X" block but the way commands work is they command, not report, and I'd written an elaborate kludge and a comment alongside it "This works, but isn't RIGHT" and did a couple other examples until it clicked and I changed it.

The problem here is, as usual, I'm over thinking. All the examples I've made in the book are reporters, so assuming these two in particular would be different is on me. In particular, is because I was thinking in one specific pattern, ie; the code in the book is nested, and thus is a C-Block in Snap! and thus is a command, but Command is a specific thing to snap! (Well, No, but in this instance)

Since Scheme is a text interpreter, so if I were using it in scheme, I'd be typing it and pressing enter. I did it in MIT-Scheme when I first read the book.

Trying to use a GUI and a visual metaphor for something not written for either of them is always going to be an issue.

As for the other two you did... Spoilers lol.

I'll get there eventually lol.

Also, I need to specify, I'm extraordinarily familiar with computers, the only thing I can't do is code. So while you are being very helpful and did get help me get past my own mental block, keep in mind I'm not an absolute beginner.

Which, I should clarify, is one of the reasons I'm so annoyed with myself.

My first OS was dos. I install DOSBox on every computer I own lol... I should have known better.

This is not entirely your fault. We should have internal definitions, as Scheme does. We know that. There are various difficulties, especially with how to represent an internal definition in a visual language. Block Editor inside a Block Editor? The right thing in principle, but gets messy quickly. We could do it like Object Logo:

That's not horrible, although of course we'd have to drag the OUTER block into a ring in the INSIDE command. And it means you can't compile OUTER until you know that it has an internal definition INNER. Ideally each Block Editor would point to the other somehow. Then, would opening the outer block's Editor automatically open the inner block's one? Maybe not, in case there are 100 blocks defined in the outer one. (The question doesn't arise in the opposite direction because the inner block isn't in the palette unless you're editing the outer one -- which raises a new question: Does the inner block just go in the palette while editing the outer one? Probably not, because nothing would stop you dragging it into some script at toplevel or in another Editor.

So, yeah, that's why we haven't done this yet, I guess. And technically it's not absolutely necessary because you can just SET something TO a ringed block instead, and call it with CALL. But that's a pain in the butt.

Every time I try to do your Logo books in Snap! The Top/Bottom example always makes me rage quit. Every single time, but with this discussion, I'm tempted to see if I can.

Nope.

Mainly because Bottom doesn't have an Outer variable so Snap says "There's no outer in this context"

Let's be fair tho, your logo books and SICP are both multiple decades old at this point and Snap! is a relatively new language and it incorporates a lot of things that weren't even considered at that point, not to mention PC's in that era could barely do anything without a lot of clever side-steps, whereas modern PC's can just DO it. There are still limitations but they are much different than then.

What I've always been looking forward to in SICP is the Meta-circular evaluator and the interpreter and compiler, but I never get that far because the problem exists between keyboard and chair. LOL.

I ended up just reading SICP the first time because the Scheme interpreters I tried drove me up the wall and I was always planning on using Snap! anyway, so It wasn't really as useful as it could have been, but I am a huge fan of SICP and am determined to get to the end... wether or not I will... well.

Logo, unlike Snap!, is dynamically scoped. So examples in CSLS that depend on the variables of the calling procedure being available in the called procedure won't work.

But Scheme is lexically scoped, so SICP programs should work fine, or at least won't fail for that reason.

(I had this really elegant idea for "hybrid scope" for Snap!, so that both Scheme and Logo programs would work, but Jens convinced me that there's no efficient way to implement it.)

I guess a special block type would need to be added, something like a cap block but one that can be fitted into a script and that has a C-shape containing the body.

  • the special block would be edited with the same or a similar pop-up editor that's used for the cap block itself.
  • the body of the internal function would be edited like any other regular blocks that are part of the outer function.

Below is an impression of what it could look like:

untitled script pic (41)

collapsed:

untitled script pic (39)

That's a possibility, I guess. Except for the part about building REPORT into the grey C-shaped block. We don't want to suggest that reporting has to be at the lexical end of the script. I guess you want to document that FACT is a reporter, but I think the obvious way to do that is put a prototype (a picture of the block) in the top part of the grey block, same as we do in the hat of the toplevel procedure. Remember, you need those plus signs to let the user add inputs, etc., to the inner block.

The examples are to meant inspire. I'm aware they're far from perfect. :slight_smile:

So I'm stuck on the Count Change example, But, there's a couple questions.
Because Snap! doesn't have Cond but it does have an Expandable If, whenever the book asks for Cond I'm just using If, is that good/bad/ugly? (At least I'm assuming it doesn't, I couldn't find one in the primitives or the libraries)

On that, I "cheated" and looked at the scm file for ch1 and the code for that is different for the one in the book, and seems... SEEMS to be defining two commands at once?

(Define (count-change amount)
(cc amount 5)

But count change amount never appears in the body, but CC Amount does. The entire block seems to be naming each one twice and then using the nick name as it were and I'm lost.

I could maybe be focusing too much on the code, but as I read it, it's just meant to highlight tree recursion, right? Like you give it a set of rules and values (The value and count of each coin) and it goes through that rule set to figure out how many coins you need? Once it reaches the end of the tree it goes back to the top and starts again until it's done?

Right, the multi-branched IF is what we have instead of COND. (But bear in mind that, like all Scheme procedures, COND is a reporter.)

You give it the values of coins, and the total amount of money you want, not the "count of each coin"; that's what it has to figure out.

But don't think "goes back to the top." That's trying to turn the recursion into an iteration. I always used to tell my students, "if you hear yourself thinking 'go back,' stop right there and think some more."

The way to think about COUNT-CHANGE specifically is "we can split all the different sets of coins that add up to this value into the ones that include at least one half-dollar and the ones that don't." Then think about what inputs to give recursive calls to COUNT-CHANGE for each of those cases. (Even though the base cases come first in the finished code, it's best to think about the recursive case first.) Once you're sure you understand how to use two recursive calls for the non-base-case, then think about base cases. COUNT-CHANGE is tricky because it has three base cases: you've run out of types of coins, the amount of money you want is zero, or the amount of money you want is negative. (That happens if you try making 30 cents using at least one half-dollar.) Then the final step is to work out a correct order to test the base cases.