bharvey wrote:
Lucario621 wrote:
I'm confused - what's with the ones, twos, and sevens in the picture?
Well, first of all, the ones and twos are making twelves. The picture is showing ways to represent $1.37; the last two lines show
4 quarters, 2 dimes, 1 nickel, 12 pennies
and
4 quarters, 2 dimes, 17 pennies
It uses numbers if there are seven or more of a particular kind of coin.
Ohhhh that makes sense now ^_^
Offline
Hey, in honor of Lucario I made an improved version that has better spacing for numbers (and a wider serif at the bottom of the 1 so it's more nearly the same width as the other digits).
Offline
BYOB 3.0.8 available.
Jens wrote:
This minor release contains the following bugfixes and enhancements:
(1) Pause / Resume
processes forked by LAUNCH blocks can now be paused and resumed along with all other threads. Thanks, majormax, for finding and reporting this bug.
(2) Internal Errors
fixed two "internal error" bugs that sometimes occurred in the Block Editor (isTransparentAt:) and when attempting to delete custom block definitions. Thanks, Luke and Stefano for detecting these.
(3) new cool SICP example project by Brian - CountChange!
Offline
bharvey wrote:
Hmm, I must be missing something... I downloaded the project, and I see how one sprite controls the other, but I don't get the competition part -- I guess there's some goal to achieve that isn't obvious in the code.
You have not the whole story.
In Chapter 1 of the story the sprite was commanded from an other sprite.
In Chapter 2 the story continues by a function (=block) which opens a one-line text editor where you can type text command to move the turtle, like gt 100 100 for GOTO 100 100.This mimics the time when Lisp and Logo had only a simple one-line editor.
In Chapter 3 you can create directly from this one-line editor a new function, square in the example, but without input variables. For the moment this function is saved into a Byob list.
In Chapter 4 I shall try to improve with variables passing.
In Chapter 5, if any, I'll try to save the function entirely in text. For this I need to write a text interpreter to extract all the Long, Insane, Stupid, Parenthesis and brackets from the text !!!!
I agree with you , what I am doing is like delivering mailpost with a Ferrari. It was only for fun. But Fun, in all meanings of the term, is very an important incentive for progress of humanity (think to Bach, Einstein, Shakespeare .....), probably as much as greed and money.
After all , Byob is an excellent means to learn difficult algorithmic science with FUN , compared to these "good old times" when you had to type everything on a small PC with its microscopic 64 K memory !!
Offline
xly wrote:
In Chapter 1 of the story the sprite was commanded from an other sprite. [...]
I think this tutorial needs some organizing text, not just comments in the code but something on the web page that you can read to get the overall structure of the series.
Offline
Fiat500 wrote:
how to convert .ypr to .sb?
Sorry, you can't. The whole point of BYOB is that we can express things in ways that Scratch can't, so our project files have extra information. If you don't make custom blocks or use any of our non-Scratch features, you should use Scratch!
Offline
I has an ideaz!
Instead of having a 'Boolean (unevaluated)' option in the advanced argument selector dialog, have an option near the bottom labeled 'Unevaluated', so that any input can be unevaluated.
Offline
rubiks_cube_guy238 wrote:
I has an ideaz!
Instead of having a 'Boolean (unevaluated)' option in the advanced argument selector dialog, have an option near the bottom labeled 'Unevaluated', so that any input can be unevaluated.
But things like c-shaped inputs are ALREADY unevaluated, so what would they be if they were unevaluated AGAIN?
Offline
rubiks_cube_guy238 wrote:
I has an ideaz!
Instead of having a 'Boolean (unevaluated)' option in the advanced argument selector dialog, have an option near the bottom labeled 'Unevaluated', so that any input can be unevaluated.
That's an excellent idea, rubiks_cube_guy238, and it did strike Brian an me just the same way as it struck you, when we were reflecting unevaluated Booleans. Then we in fact did come up with your suggested "ANY UNEVALUATED" slot type, and Brian redesigned the long form input dialog to how it appears now, with a row of UNEVALUATED slots at the bottom. (The ANY UNEVALUATED slot now is at the center of the bottom row).
Isn't it cool how some (if not most) design decisions just sort of come naturally all by themselves when you think about an expressive system?
Last edited by Jens (2010-10-19 02:27:03)
Offline
nXIII wrote:
But things like c-shaped inputs are ALREADY unevaluated, so what would they be if they were unevaluated AGAIN?
There wouldn't be a "C-shaped" type option in his plan; instead, if you chose "command" and checked the "unevaluated" box, you'd get a C-shaped slot.
Jens wrote:
Then we in fact did come up with your suggested "ANY UNEVALUATED" slot type
No, Jens, I think you've misread what he wants: not "any (unevaluated)" but "unevaluated (orthogonal to type)" as a checkbox.
rubiks_cube_guy238 wrote:
have an option near the bottom labeled 'Unevaluated', so that any input can be unevaluated.
In principle I think your instinct is good -- factor out the orthogonal attributes from the underlying types. But there are two reasons I think we can't do exactly what you suggest.
First of all, it's a three-way choice, not just evaluated vs. unevaluated. The "middle" choice is "procedure returning type X"; as Jens suggests, this is subtly reflected in the way the options are arranged in the long dialog, in a 3x3 matrix:
(no value) (any type) (Boolean) plain <impossible> Any Boolean procedure Command Reporter Predicate unevaluated C-shape Any (unev) Boolean (unev)
It took us a while to understand the "no value" column of this chart, partly because of the impossible slot (what does it mean to have an input slot with no value?) and partly because C-shaped slots existed before BYOB did, and it took me a while (Jens understood this all along but let me talk him out of it for a while) to understand C-shaped slots as unevaluated slots rather than as procedure-type slots. So if we were to follow through on your idea, we'd have a separate set of radio buttons with "plain," "procedure," and "unevaluated" as the choices.
But, second, although that would be an elegant factoring of type from evaluation model, I think it would be harder for beginners to understand. By contrast, seeing pictures of the different kinds of slots arranged 3x3 helps people get it, I hope.
More specifically, I think we have the evaluation models arranged from easy to hard. First people get the idea of simple types, then they get the idea of procedures returning those types (or returning nothing, in the first column), and finally we introduce the idea of an input slot that looks like the simple type but behaves like the procedure type.
I hope this is comprehensible -- it's after midnight and I've been on the run since 8:30am.
P.S. eight hours later: In factoring out procedureness we are also constrained by the Scratch design, with only three block shapes. Why isn't there a block shape meaning "this procedure reports a number"? There are such blocks -- most of the Operations ones for example -- but the Scratch Team chose not to single them out as a distinct block type. We are following their lead in providing procedure-reporting-X types only for the Boolean and everything-else cases. And that constrains which types we provide as unevaluated, since those are really procedure slots.
Last edited by bharvey (2010-10-19 11:47:29)
Offline
Has anyone else found that shift-clicking a Reporter gives a menu with one item, "quote," and clicking it creates a the block block around the Reporter?
This will cause an error if you do it to an input variable in a block primitive.
Last edited by EvilGenius (2010-10-19 15:33:56)
Offline
Yes
I wrote that shortcut so I don't have to go through the whole process of switching to the Operators category page, dragging out an instance of THE BLOCK, dropping it in the scripting area and inserting my reporter into it. I find it convenient (because I usually prefer the explicit THE BLOCK notation instead of the grey-bordered auto-lambdafication mechanism), but should make yourself familiar with what it does.
Last edited by Jens (2010-10-19 18:37:39)
Offline
bharvey wrote:
Jens wrote:
Yes
Hmm, how come it doesn't work for me?
It didn't work for me until I downloaded 3.0.8, but it's a very, very handy feature.
Somewhat tangentially, I'd like to weigh in on the discussion about unevaluated inputs. It is my humble opinion that there should be some way to distinguish evaluated from unevaluated input slots at a glance. If users are trying a block that they didn't create, it might not be immediately obvious to them in some cases what kind of slot they are dealing with.
Offline
fullmoon wrote:
It didn't work for me until I downloaded 3.0.8
I have 3.0.8! Is this one of these Windows-only things, Jens?
[EDIT: Never mind, I was trying it in the palette, and it only works on a block in the scripting area. (But why?)]
It is my humble opinion that there should be some way to distinguish evaluated from unevaluated input slots at a glance.
I sympathize -- I was happy with plain old procedure types. But we had some very persistent lobbying from actual teachers who wanted a reporter IF/ELSE that would look just like the primitive command one, and would therefore be understandable and usable intuitively by someone who hasn't learned about first class procedures yet.
What they asked for was to make reporter IF/ELSE a built in magic special case. After literally hours of impassioned (on both sides) argument over Skype, Jens and I caved in on this, but then by morning we independently invented the idea of unevaluated input types as a way to satisfy their need without adding an ugly special case.
But, see, the whole point of unevaluated input slots is that they look exactly like ordinary evaluated ones. Semantically, they're exactly the same as procedure input types; the only difference is that they're in disguise. I don't see how we could have it both ways about this, unless we did something like "if you hold down left shift and right control while hovering over a block, the unevaluated input slots temporarily turn into procedure type slots."
P.S. I love your rotating campaign slogan sigs! (Do adults get to vote?)
Last edited by bharvey (2010-10-20 12:08:54)
Offline
bharvey wrote:
P.S. I love your rotating campaign slogan sigs! (Do adults get to vote?)
Of course (but I think you already knew that)! You're a member of the Scratch community too.
@Fullmoon: Your signature is AWESOME.
Offline
I Am Dumb!!!
Offline
bharvey wrote:
But, see, the whole point of unevaluated input slots is that they look exactly like ordinary evaluated ones. Semantically, they're exactly the same as procedure input types; the only difference is that they're in disguise. I don't see how we could have it both ways about this, unless we did something like "if you hold down left shift and right control while hovering over a block, the unevaluated input slots temporarily turn into procedure type slots."
I have no problem with the way unevaluated arguments work at the moment -- I just want to be able to look at a slot on a custom block, and know instantly whether it is unevaluated or not. Surely a slight tint or something would do the trick? Personally, I miss the days when you could pass an unevaluated argument explicitly by dropping it in with a grey border. Ah, well.
Perhaps I'm making too much of a deal about this, but I am a statically-typed, callback-lovin', Java/AS user born and bred, so this sort of intuitiveness and ease-of-use is a little mind-boggling .
By the way, I happen to be writing my own little language in Actionscript. I know, efficiency-wise it's a little like taking out the trash on a ride-on lawnmower, but it's more of a personal challenge than anything I intend to be useful to anyone else. This week I'm starting to write blocks/anonymous functions (for my own sanity, actually, all functions are anonymous until they are assigned to a variable) and I am considering a way to pass unevaluated arguments into these. I'm not quite sure how the syntax should work.
Consider these hypothetical snippets and let me know which one is your favorite. I'm trying to work out how to best iterate over all the elements in an array.
( self poemFragments = ["east","west","over the cuckoo's nest"] io out("One flew "+poemFragments :(0)) io out("One flew "+poemFragments :(1)) io out("One flew "+poemFragments :(2)) )
I'm not sure what this should become. Maybe:
( ... poemFragments each(*i, { io out("One flew "+i) }) )
In this case the "each" is actually a method of the poemFragments array, which would take an unevaluated reference to a variable (a sort of pointer, I suppose) and set it to each item in the array in turn, and evaluate the second argument, an anonymous, parameter-less block. On the other hand, I could implement the "yield" keyword as well:
( ... poemFragments each():(fragment) { io out("One flew "+fragment) } )
In this case the method continually yields an item in the array and then calls the block attached to the end of the method call with the colon. This is how Ruby does it, but it's basically syntactic sugar for the next possibility:
My personal favorite would be to pass a single argumented block to the each method:
( ... poemFragments each((fragment){ io out("One flew "+fragment) }) )
There's always the boring ol' for loop:
( ... for(i=0;i<poemFragments.length();i++) { io out("One flew "+poemFragments :(i)) you getTheIdea() } )
The only thing that's stopping me from implementing the third one right away is I'm worried about how one might break out of a loop built this way. I plan to implement "for" anyway but I'd like something more OO as well.
Wait...it occurs to me that a traditional "for" loop actually takes four procedures as input, it's just elegantly hidden from the user. Which brings us right back to the beginning!
Suggestions, please!
Offline
fullmoon wrote:
Personally, I miss the days when you could pass an unevaluated argument explicitly by dropping it in with a grey border.
Umm, I think one of us is confused. The thing with the grey border isn't an "unevaluated argument"; it's a procedure-type argument! And you can still do that! The unevaluated type is different -- and the difference is precisely that it looks just like an evaluated input.
I'm still reading the rest of your message; stay tuned.
Offline
bharvey wrote:
fullmoon wrote:
Personally, I miss the days when you could pass an unevaluated argument explicitly by dropping it in with a grey border.
Umm, I think one of us is confused. The thing with the grey border isn't an "unevaluated argument"; it's a procedure-type argument! And you can still do that! The unevaluated type is different -- and the difference is precisely that it looks just like an evaluated input.
I'm still reading the rest of your message; stay tuned.
Yes, I am quite confused. I see how the two are different in that sense but they appear to function exactly the same to me. If you pass the (x position) reporter into an unevaluated slot, the block can CALL that reporter just the same as if the reporter was surrounded by "the block", which itself is the same as surrounding a reporter with a grey border (right?). So from my understanding, unevaluated arguments are basically a shortcut for wrapping certain inputs in "the block". Maybe there's something really fundamental I'm just not getting. I've never taken any CS courses, and you teach them for a living, so if there's a misunderstanding it's probably on my part!
Oh, and I tried the grey border thing and it does still work...I don't know what I was thinking.
Last edited by fullmoon (2010-10-21 00:21:23)
Offline
fullmoon wrote:
for my own sanity, actually, all functions are anonymous until they are assigned to a variable
Yay!! Good for you! That's how a language should be.
Wait...it occurs to me that a traditional "for" loop actually takes four procedures as input, it's just elegantly hidden from the user. Which brings us right back to the beginning!
Yeah, the BYOB3 reference manual has that very example (the C for loop, which, by the way, is "traditional" only by the standards of you whippersnappers; the tools.ypr FOR is much more traditional) to illustrate why one might use an inline command input slot rather than a C-slot.
By the way, as to the "back to the beginning" remark, I'd like to point out that you're not exactly in the target audience for BYOB! You're well past being a novice programmer. So you want to see under the hood, but a beginner might just be scared away by that, in a context (such as reporter IF) in which s/he wasn't expecting to think in terms of higher order procedures.
Suggestions, please!
Well, for one, the word that you've spelled "psssss" in your sig is traditionally spelled "psssst"!
More seriously, I'm not an object oriented programmer by instinct, so for something looking like your examples I'd just as soon say
for x in poemFragments {... + x}
But since you have anonymous functions, why not
poemFragments forEach: (lambda (x) (...))
That seems most natural to me.
Offline
Well, for one, the word that you've spelled "psssss" in your sig is traditionally spelled "psssst"!
Thank you! I thought that looked weird...now I feel compelled to change it!
Code:
poemFragments forEach: (lambda (x) (...))That seems most natural to me.
This is more or less my third example, I just left out the "lambda" keyword because I don't think my parser needs it! For clarity, though, I think I'll end up marking blocks/functions with a "@" symbol, because it doesn't seem to be getting much use anywhere else. I've also left out the colon-delimited arguments and I'm opting to go C-style, although we'll see what Jens can do to get me to change my mind
I think I'll probably also implement the for/in loop...might as well. Thanks for the suggestions!
Offline