scimonster wrote:
I got all that; the wiki explained it pretty well...
Stuff like the MAP block is where I get lost
I'm so confused! You said it was recursion you didn't get...
But, okay, the MAP block. Again, tell me where you get lost.
1. Given a list, you'd often like to compute some function of each item of the list.
2. Those examples are all nearly the same script; aside from the block's name, the only difference is in the
ADD [some-function-of [ITEM (index) OF (list)]] TO (result)
Whenever you see a pattern like that, you should want to generalize it, so you just write the pattern once and then you can use it repeatedly. That's what MAP is: a generalization of the examples above.
3. You'd like to be able to specify the function to use like this:
but you can't, because the value of [( ) + (3)] is 3, not the add-three-to function. (BYOB, like Scratch, uses zero as the value of any unspecified numeric input.) So, to use MAP, you need a way to say "the-whatever-function":
4. That's all there is to it! Except that the actual MAP block in the tools package is more complicated, because it takes multi-input functions to map over multiple lists, and that's a little tricky. And also it provides the index as an upvar so you can number the items of the list.
5. Oh, and, I forgot, Jens and I got tired of dragging THE BLOCK blocks around everywhere, so each of us invented a shortcut. I invented grey borders, so if you drag a block such as [( ) + (3)] onto a grey input slot (i.e., an input slot of type procedure) and drag extra close, you get a grey border around your block that means the same as THE BLOCK. Jens invented shift-clicking on a block in the scripting area, which gives you a menu with only one entry, "quote," and if you choose it, you get an actual THE BLOCK block around the block you shift-clicked on.
Offline
Hi Brian and Jens,
Since the release of Scratch 2.0 seems to be getting put further and further off, I am starting to pin all of my hopes on Snap instead. JavaScript and HTML 5 are definitely the future and should allow programmers to design a plethora of real word applications with Snap. I believe that Snap along with Google App Inventor might just bring us into a new era of computer programming in which block-based languages become used for serious applications. This would be totally awesome!!!
In the hopes of doing what I can to speed up the release of Snap, I have two questions/ideas:
1. Have you thought about open-sourcing the development of Snap on something like Github so that more interested and well-meaning folks can help accelerate Snap's development? Right now the Khan Academy programmers are using Github brilliantly to teach volunteer programmers how to use their API to develop the front end of Khan Academy, which is also all in Javascript and HTML5. You may want to take a look to get some ideas: https://github.com/Khan/khan-exercises
2. I read your response to 14GOD's question about donations, but have you thought about using Kickstarter? If you haven't checked out Kickstarter, it is extremely simple and fun ways to generate funds for cool projects. There are already several Scratch-based projects that have been rather successful, like Minibloq:
http://www.kickstarter.com/projects/791396812/minibloq-graphical-programming-environment-for-ard?ref=category.
Well, I hope these thoughts might help in someway.
Best wishes,
Webstermath
Offline
webstermath wrote:
1. Have you thought about open-sourcing the development of Snap on something like Github so that more interested and well-meaning folks can help accelerate Snap's development?
This is really Jens's department; he's in charge of the code. But I think that kind of arrangement is great once you have the foundation in place and there are a million little detail things you need done. Doing a complete rewrite from scratch will be hard enough with the 7 programmers now on board. But maybe the 4.0 -> 4.1 transition could be done that way.
webstermath wrote:
2. have you thought about using Kickstarter?
Hmm. Maybe Jens could do that; he's a free agent. But I'm an academic, and as soon as someone other than the university pays me to do something, I have to fill out a million forms, and it's not worth the hassle. This NSF grant, if we get it, will pay me a bit for my time in the summer, and will let us hire Jens as a consultant (also a paperwork hassle, but luckily, we have staff people whose job it is to do that kind of sponsored-project paperwork). I suppose the university could use Kickstarter, but no doubt that requires agreeing to some Terms of Service contract that I'm not authorized to sign on the university's behalf.
Maybe when we get to the point of handing out Snap t-shirts at conferences.
Offline
bharvey wrote:
scimonster wrote:
I got all that; the wiki explained it pretty well...
Stuff like the MAP block is where I get lostI'm so confused! You said it was recursion you didn't get...
But, okay, the MAP block. Again, tell me where you get lost.
1. Given a list, you'd often like to compute some function of each item of the list.
http://cs.berkeley.edu/~bh/add3.gif
http://cs.berkeley.edu/~bh/double.gif
http://cs.berkeley.edu/~bh/sqrts.gif
2. Those examples are all nearly the same script; aside from the block's name, the only difference is in the
ADD [some-function-of [ITEM (index) OF (list)]] TO (result)
Whenever you see a pattern like that, you should want to generalize it, so you just write the pattern once and then you can use it repeatedly. That's what MAP is: a generalization of the examples above.
http://cs.berkeley.edu/~bh/simple-map.gif
3. You'd like to be able to specify the function to use like this:
http://cs.berkeley.edu/~bh/bad-map.png
but you can't, because the value of [( ) + (3)] is 3, not the add-three-to function. (BYOB, like Scratch, uses zero as the value of any unspecified numeric input.) So, to use MAP, you need a way to say "the-whatever-function":
http://cs.berkeley.edu/~bh/good-map.png
4. That's all there is to it! Except that the actual MAP block in the tools package is more complicated, because it takes multi-input functions to map over multiple lists, and that's a little tricky. And also it provides the index as an upvar so you can number the items of the list.
5. Oh, and, I forgot, Jens and I got tired of dragging THE BLOCK blocks around everywhere, so each of us invented a shortcut. I invented grey borders, so if you drag a block such as [( ) + (3)] onto a grey input slot (i.e., an input slot of type procedure) and drag extra close, you get a grey border around your block that means the same as THE BLOCK. Jens invented shift-clicking on a block in the scripting area, which gives you a menu with only one entry, "quote," and if you choose it, you get an actual THE BLOCK block around the block you shift-clicked on.
1) That's simple.
2) I understand CALL a little better now...
3) ...
4) ??????????????????????
5) I didn't know about Jens's trick.
Offline
scimonster wrote:
3) ...
I couldn't quite tell whether this ellipsis is meant to be a continuation of the one in #2 (i.e., you understand #3 a little better too) or something else!
4) ??????????????????????
That's an example of calling map with a two-input function and two lists. It calls the function with the two first items, then with the two second items, then with the two third items.
So if you read the actual MAP block in the tools package, it has a very long script that handles these multi-list calls as well as the more common one-list case. The list input to MAP is declared to be a multiple input, which is why you see the left and right arrowheads in the MAP block. Therefore, the actual input as seen inside the MAP script is a list of lists. In order to get all the first items of the sublists, all the second items, etc., the script says
MAP [THE [ITEM <index> OF [ ]] BLOCK] OVER <lists>
but this would be a recursive call with no base case, so MAP handles the one-list case separately as a base case for that recursive call.
This is the sort of thing that's messy but not a big intellectual leap, so there's really no reason you have to delve into the MAP script. Better you get a solid understanding of #2 and #3, about which you should ask questions if still uncertain.
Offline
bharvey wrote:
5. Oh, and, I forgot, Jens and I got tired of dragging THE BLOCK blocks around everywhere, so each of us invented a shortcut. I invented grey borders, so if you drag a block such as [( ) + (3)] onto a grey input slot (i.e., an input slot of type procedure) and drag extra close, you get a grey border around your block that means the same as THE BLOCK. Jens invented shift-clicking on a block in the scripting area, which gives you a menu with only one entry, "quote," and if you choose it, you get an actual THE BLOCK block around the block you shift-clicked on.
That's a neat trick! But why not add it to the non-secret context menu and give it a better, less string-y name, like "wrap"?
Offline
fullmoon wrote:
That's a neat trick! But why not add it to the non-secret context menu and give it a better, less string-y name, like "wrap"?
Or "lambdafy"?
He had a reason, which I'm sure he'll explain when he gets back from vacation, but I think it had to do with the fact that it only works in the scripting area, not in the palette. But I agree about the name.
Offline
bharvey wrote:
scimonster wrote:
3) ...
I couldn't quite tell whether this ellipsis is meant to be a continuation of the one in #2 (i.e., you understand #3 a little better too) or something else!
It means "I got lost."
bharvey wrote:
4) ??????????????????????
http://cs.berkeley.edu/~bh/multimap.png
That's an example of calling map with a two-input function and two lists. It calls the function with the two first items, then with the two second items, then with the two third items.
So if you read the actual MAP block in the tools package, it has a very long script that handles these multi-list calls as well as the more common one-list case. The list input to MAP is declared to be a multiple input, which is why you see the left and right arrowheads in the MAP block. Therefore, the actual input as seen inside the MAP script is a list of lists. In order to get all the first items of the sublists, all the second items, etc., the script says
MAP [THE [ITEM <index> OF [ ]] BLOCK] OVER <lists>
but this would be a recursive call with no base case, so MAP handles the one-list case separately as a base case for that recursive call.
This is the sort of thing that's messy but not a big intellectual leap, so there's really no reason you have to delve into the MAP script. Better you get a solid understanding of #2 and #3, about which you should ask questions if still uncertain.
So one list I understand; it's multiples that's over my head.
Offline
scimonster wrote:
It means "I got lost."
Ah. Okay. Let me go through that more slowly, and again tell me where, if anywhere, you get lost. Sections in parentheses are optional.
3a. What happens in Scratch when you nest operators, e.g., [<3> * [<4> + <5>]]? The multiplication block only knows how to multiply numbers; it doesn't know anything about Scratch blocks. So Scratch has to first evaluate the [<4> + <5>] part, getting 9, and then it can call the * block with the inputs 3 and 9.
So, in general, the rule is, evaluate from the inside out. (This rule has a fancy name, "applicative order," but you're not required to know that. )
(3b. There are exceptions to this rule, called "special forms." All the Scratch C-shaped blocks are special forms, because applicative order would say to evaluate the stuff in the C slot before starting the outer block. But that's not really important to the argument right now; I'm just including it so nobody complains about 3a.)
3c. If a numeric slot is empty, it's treated as if it had a zero. Exercise: What's the value of [<3> * [< > + <5>]]?
3d. When we write a custom block such as MAP in BYOB, it follows the same inside-out rule as the built-in blocks. So if we say
what is the value of the first input to MAP?
(: .3 :rewsnA)
Is that value a function? Can we ask what value we get from f(7), f(8), and f(1)?
Those are rhetorical questions -- the answers are no and no.
3e. So, we need a different way to say "the function f(x)=x+3" or rather, since we don't want to give this function a particular name like F, "the function x ↦ x+3."
(The symbol ↦, pronounced "mapsto," is math-speak for a function without a name.)
For this we use THE BLOCK. The value reported by
[THE [< > + <3>] BLOCK]
isn't 3; it's the function we need!
(3f. An empty input slot in a block inside THE BLOCK doesn't mean zero; it means "this is where the input to the function goes"! It's like the x in f(x)=x+3.)
3g. A grey input slot, e.g. the first slot in the MAP block, means that that input has been declared to be a procedure type (command, reporter, or predicate depending on the shape of the slot). This is just like the rounded input slot for numbers, the hexagonal slot for Booleans, etc.
(3h. The idea is, that dark grey color means procedures in every context. So, for example, if you see a block or script outlined in grey in a variable, list, or speech balloon, that means it's the block or script itself, not the result of running it, that you're looking at. This is why the grey-border abbreviation for THE BLOCK should make sense to you.)
3i. The value you provide for that first input to MAP has to be a function. But that doesn't have to mean that there's a THE BLOCK block right there inside the MAP call. For example, you could say
SET <foo> TO [THE <...> BLOCK]
and then later say
MAP <foo> OVER [LIST .....]
But somewhere you have to use THE BLOCK (or the grey border abbreviation) to create a value that's a function.
So one list I understand; it's multiples that's over my head.
4a. Okay, so, the function f(x)=x+3 in the example above has one input, x. But functions can have any number of inputs. In particular, lots of Scratch blocks are two-input functions: the four arithmetic operators, JOIN, MOD, AND, OR, etc. I can't offhand think of any three-input functions in Scratch, but there are a few three-input commands, e.g., GLIDE.
4b. As I've explained before on this thread, I think, the use of an empty input slot to represent the input to a function, as in [< > + <3>] above, is based on education research from 40 years ago that showed that young kids who have trouble with
x + 3 = 7
can nevertheless figure out the same problem in the form
□ + 3 = 7
(That first character is a hollow square in case your browser doesn't render it correctly.) So, in the hope of allowing pre-algebra-aged kids to use first class functions, we use a hollow (empty) slot to mean "the missing value goes here."
Although I think that's a good notation -- it's one of the pieces of BYOB I'm really proud of -- it's not so good for talking about function inputs, as I want to do now. So I'm going to use variables like x and y in the discussion.
4c. If you call MAP with one list input, then MAP expects a one-input function [f(x)=...], and every empty slot in the function represents the same input value. So
THE [< > * < >] BLOCK
represents f(x)=x * x, or x squared.
But if you call MAP with two list inputs, then MAP expects its first input to be a two-input function, and so the same
THE [< > * < >] BLOCK
represents f(x,y)=x * y in that context. (I know this sounds like a kludge when described formally, but I claim that in a specific situation it's almost always intuitive how to express the function you mean.)
4d. So in the example
(the first block is there just to show what it looks like before you fill in the inputs), MAP calls the function f(x,y)=x+y three times, first f(1,40), then f(2,50), then f(3,60). It reports a list of the results: 1+40=41, 2+50=52, and 3+60=63.
4e. MAP isn't limited to two list inputs; you can give it any number of lists you want, as long as the function you give it expects that many inputs. So, if you give it four lists, then it has to be a function with four inputs f(x,y,z,w)=....
4f. Once you have that many inputs, the empty-slot notation can be confusing. So there's an alternative; you can click the right arrowhead at the end of THE BLOCK and provide names for the inputs (like the "x", "y", etc. above). Then you drag those names into the block to specify which input goes where, just like any other Scratch variables.
Okay?
Offline
Yes, thanks a-lot! I do algebra BTW.
Offline
i have byob 3.1
Offline
is there any way to connect Snap/BYOB to an online scoring system of some sort??? would be very useful for games!
Offline
Taneb wrote:
I think if you use messages it may be possible with a bit of creativity, but at the moment there isn't anything other than mesh (found in the Share menu) to do that.
If you have an external program that does whatever you're trying to do, you can have that other program listen on some private port number and then tell BYOB to join a mesh at localhost:1234 or whatever the number is.
Eventually we'll have first class web pages, but not for a while -- not in 4.0, probably not in 4.1.
Offline
@Taneb and rubiks_cube_guy238: I think the question about Church numerals is the only one outstanding from this recent flurry. Did what I posted help? I tried to explain the setup without doing the actual exercises, but if you'd like to see the addition procedure for Church numerals I'll post it.
P.S. I just remembered that on my undone task list is to update the PDF to reflect the fact that the IF/THEN/ELSE reporter block in the tools package is now a special form, so you should ignore what it says about using grey borders for the THEN and the ELSE parts. Sorry!
Last edited by bharvey (2011-06-14 23:13:29)
Offline
14God wrote:
I don't think I believe in global warming, its too rainy and dreary up here in Washington Hows the weather in California?
You scared me -- for a moment I thought you actually meant it, until I saw the smiley.
It's gotten really Califormia-like in California the past two
weeks, but we'd had rather brisk (high 50s) weather and some drizzles earlier in the spring and summer. But at least it's not like the tornado I was in (the edge of) while I was in Boston!
@Taneb: Good job!
Offline
I want to create 100 clones of a sprite using code on the fly, and want to change postion of each clone at different place. I looked at BYOB & Scratch both, looks like I have to create 100 different sprites one by one at the time of writing the program. Any other better option?
Offline
themsb wrote:
I want to create 100 clones of a sprite using code on the fly, and want to change postion of each clone at different place. I looked at BYOB & Scratch both, looks like I have to create 100 different sprites one by one at the time of writing the program. Any other better option?
Same as former msg : have a look at this link :
http://www.xleroy.net/ByobTuto/thumbnails.html
Download to get the scripts.
Offline
themsb wrote:
I want to create 100 clones of a sprite using code on the fly, and want to change postion of each clone at different place. I looked at BYOB & Scratch both, looks like I have to create 100 different sprites one by one at the time of writing the program. Any other better option?
As of BYOB 3.1 you can use the CLONE block (under Operators) to make a clone. So you could say
REPEAT 100 TIMES
RUN ( (THE SCRIPT
GO TO X: (PICK RANDOM ...) Y: (PICK RANDOM ...) )
OF (CLONE))
Last edited by bharvey (2011-06-16 18:05:06)
Offline
bharvey wrote:
scimonster wrote:
I don't understand 1/4 of BYOB. I somewhat agree with the ST about this.
So, now that the first sentence is no longer true, do you still believe the second sentence? (Honest answer, please!)
I haven't downloaded 3.1 yet, so I'm not sure.
I'll do that soon, then get back to you.
Offline