Thanks for your comments on the draft manual.
OldCodger wrote:
First I think constant reference to Scratch is confusing. You can't assume new users will have prior knowledge of Scratch.
Hmm. Not counting the contents, index, and acknowledgements, there are 12 pages that make reference to Scratch. Five of them are trivial, isolated comments along the lines of "As in Scratch..." or "Unlike Scratch..." with the rest of the sentence perfectly understandable if you've never seen Scratch. The seven substantive ones are on three topics: (1) first class data; (2) the long input dialog box and extended types; and (3) special forms.
First class data: There's an explicit definition that doesn't make reference to Scratch, and an explanation for how Snap! lists are first class. I think it's pedagogically very helpful, though, to have an example of a type that isn't first class -- and in Snap!, they all are, or will be! So any example has to come from another language, and Scratch is a more likely prior language than anything else.
Input types: This is the place where I think your comment has most merit. The Snap! type system is definitely organized around an understanding of the Scratch types. and the explanation repeatedly refers to Scratch over four pages. I suppose it could equally well say "the types every programming language has," except that those B&D languages don't have an Any type, and traditional languages distinguish between Character (a scalar type) and String (an aggregate type). I think that the pedagogic value of this discussion for Scratchers outweighs the lack of pedagogic value for non-Scratchers (although there's plenty of non-Scratch-specific explanation, too).
Special forms: Here I'm caught in a trap of my own making -- reporter IF is included in the tools library that I want everyone to get by default, so I can't really make a big fuss about it being missing in Snap! itself, hence the reference to Scratch. I suppose I could just jump into "how could we write reporter IF as a custom block?" but I think the discussion about its (irremediable) lack in Scratch helps motivate that exercise. And at the very end there's a subsection explicitly pointing out that Scratch has special forms to try to help people not think of them as esoteric.
I did try to make the manual not assume that the user knows Scratch; that's why I added chapter 0, which starts from the beginning. It's not a very long chapter because, you know, kids just get the business of snapping blocks together. So I emphasized the parts that, in my teaching experience, kids don't get by themselves, namely BROADCAST and variables.
Second I think you need to make it explicit whether different kinds of data can be held in a list or not.
Lists of lists are on page 19; lists of procedures on page 32, separated because lists are introduced before procedures as data. When we get first class objects, they'll be in lists also! But, basically, anything can be put in a list. I suppose there could be a sentence "anything that can be the value of a variable can also be an item in a list"; do you think that would help?
Finally I think that the style of programming; imperative or functional needs much more expansion to really explain the benefits of each.
Absolutely. That's just one of many topics I'd want to expand in a proper tutorial manual -- on my project list for next year. The present manual is a funny sort of hybrid, basically a reference manual but with micro-tutorials on topics likely to be obscure to the lay (non-Scheme-speaking) reader. A bunch of people have commented that this is either too much or not enough, but I don't see how to avoid that given our way-over-deadline release pressure.
We also have the help screens, which are a sort of virtual appendix to the manual.
Offline
In my second point I was thinking of the difference between a language like Haskell where lists can only hold elements of the same type.
Snap! By contrast can mix types in the same list but this is not really clear and you only really notice it with the mention of association lists and you have to be on your toes to pick the implication of the key/value pair which might be of different types. I prefer lists to only hold a single data type and like Haskell's use of tuples in this case.
Re-reading the part about types; page 23 I notice a subtle shift from the statement "Scratch block inputs come in two types:" and then "The Snap! type system is an expanded version including Procedure, List, and Object types".
This seems confusing and is further compounded by talking about "type shapes." It is important to distinguish between a type system and the more colloquial usage of the word type.
Procedures or functions. When thinking imperative code perhaps procedure comes most readily to mind but functional programming uses functions and these are fundamentally different ways of thinking. Section 4 has the title "Procedures as Data" but I think "Functions as Data" might be closer to the mark. You keep switching between the two terms; see pages 31 and 32. Leave procedures to OOP.
Offline
OldCodger wrote:
In my second point I was thinking of the difference between a language like Haskell where lists can only hold elements of the same type.
Oh, sorry! Yes, I'll make that clearer.
This seems confusing and is further compounded by talking about "type shapes." It is important to distinguish between a type system and the more colloquial usage of the word type.
This made me smile. You think that the reader of the manual is unfamiliar with Scratch, but is a graduate student in programming language semantics?
Especially for our nonspecialist audience, I think it's appropriate that we use "type" in the way nonspecialists use it. And anyway, type systems are all a bad idea. God created the Lambda; all else is the work of man.
Procedures or functions. When thinking imperative code perhaps procedure comes most readily to mind but functional programming uses functions and these are fundamentally different ways of thinking. Section 4 has the title "Procedures as Data" but I think "Functions as Data" might be closer to the mark. You keep switching between the two terms; see pages 31 and 32. Leave procedures to OOP.
Ah. I suppose for experienced Pascal or Java programmers that might be confusing. I grew up in an older tradition, in which f(x)=2(x+3) and g(x)=2x+6 are the same function, but different procedures. But one way or another I'll make sure the use of language is consistent.
Thanks.
Offline
bharvey wrote:
And anyway, type systems are all a bad idea.
God created the Lambda; all else is the work of man.
I learned Forth as my first language, followed by Prolog. I came across Functional Programming and tried OCaml but prefer Haskell. The enthusiasm of Simon Peyton Jones is infectious! Unlike you I mostly like the strict typing of Haskell. One thing I don't like is the way languages like Python and to some extent Snap! just throw in a few functional programming structures but then leave them stranded so to speak as hostages in a sea of imperative procedures.
Offline
OldCodger wrote:
languages like Python and to some extent Snap!
I don't know of another example like Python, whose functional-programming-hating designer was dragged (a little bit) into it kicking and screaming, by users.
Snap! is, in this respect, just like its parent (one of its parents, the other being Smalltalk) Scheme: designed by lovers of functional programming but not doctrinaire about it. When we develop tutorial materials, I promise, there will be a lot of functional programming on display.
Offline
When we develop tutorial materials, I promise, there will be a lot of functional programming on display
I look forward to it.
Xly said
Snap! is not designed to be an all-purpose programming language.
So what is Snap! designed for?
Offline
OldCodger said :
" Xly said
Snap! is not designed to be an all-purpose programming language.
So what is Snap! designed for?"
The previous post ov bharvey gives you the answer.
Snap! is the son of Smalltalk + Scheme.
As far as Iknow, these two languages have not been designed to serve the needs of large international companies !
Offline
bharvey wrote:
OldCodger wrote:
languages like Python and to some extent Snap!
I don't know of another example like Python, whose functional-programming-hating designer was dragged (a little bit) into it kicking and screaming, by users.
Is that really what happened? How interesting. I like the functional bits in Python. What else am I missing, other than macros?
Offline
blob8108 wrote:
Is that really what happened?
http://python-history.blogspot.com/2009 … tures.html
What else am I missing, other than macros?
I'm not sure if this means "what other features aren't in Python" or "what else don't I understand" or something entirely different. But, assuming you're asking about Python, it doesn't have first class continuations.
And since (from a sufficiently abstract perspective) there are only three programming language features (lambda, continuations, and macros), Python scores .5 out of 3.
(Snap! scores 2/3, but we'll get around to macros eventually.)
Offline
OldCodger wrote:
So what is Snap! designed for?
To a large extent, our design decisions have come from a rather narrow target: teaching a SICP-inspired intro computer science course to non-CS majors and attracting a non-geek audience. The "non-geek audience" part is what attracted Berkeley to Scratch, and the "SICP-inspired" part is what led first to recursion and then to lambda. (Continuations in Snap! are just showing off, not really to teach to English majors.)
I think the paradigmatic story is about special forms. Two of our teaching colleagues, Dan Garcia and Josh Paley, wanted reporter IF as a primitive, because our solution back then was to lambdafy the second and third inputs and Dan and Josh thought that was unteachable. This was back when we were trying really hard to minimize the number of blocks we added to Scratch, so Jens and I were resisting, and finally we had a very long Skype conference call (in the middle of the night for poor Jens) at which they wore us down (only partly because Jens was so tired) and we agreed to do it, and then the next day Jens and I independently came up with the idea of unevaluated inputs so we wouldn't have to make IF a special case after all. But it was that specific teaching need that inspired us.
Of course we're delighted that other people have found the language useful for other things, and to the extent possible we've tried to take those things into account also. But, for example, we feel that strict typing is one of the things that drive non-geeks away from CS (because you need half a page of declarations before you can add 2 and 2). Ditto compiled (vs. interpreted) languages.
Offline
I meant "what other features aren't in Python"; but seeing as I didn't even know about continuations, and reading the Wikipedia page makes my brain hurt slightly, "what else don't I understand" seems appropriate, too...
And I still can't find a good example of a macro that shows why they're useful. Clearly I'll just have to get further with SICP...
bharvey wrote:
since there are only three programming language features (lambda, continuations, and macros), Python scores .5 out of 3.
![]()
Is the ".5" because we don't have multi-line/"proper" lambdas?
Thanks for your help with the CS interview thing recently, by the way! I never did get around to trying all those algorithms, but just thinking about them and reading most of the first chapter of SICP was pretty helpful, as it turned out.
Offline
blob8108 wrote:
reading the Wikipedia page makes my brain hurt slightly
Yeah, that's a problem with Wikipedia. Try reading the section on continuations in the Snap! Reference Manual and see if that helps.
And I still can't find a good example of a macro that shows why they're useful. Clearly I'll just have to get further with SICP...
Well, yes, but not for that reason. SICP doesn't talk about macros.
Here's the canonical example. I want a LOCALSET block that combines the actions of SCRIPT VARIABLES (with one variable) and SET. But if I put a SCRIPT VARIABLES block inside my LOCALSET block, the variable I make will be local to LOCALSET itself rather than, as desired, the caller of LOCALSET.
So what we need is for LOCALSET to be a macro, i.e., a block that reports a script, which is then evaluated in the caller in place of the macro invocation.
Is the ".5" because we don't have multi-line/"proper" lambdas?
![]()
Yeah.
Thanks for your help
You're welcome!
Last edited by bharvey (2013-01-13 17:02:45)
Offline
xly wrote:
OldCodger said :
" Xly said
Snap! is not designed to be an all-purpose programming language.
So what is Snap! designed for?"
As far as I know, these two languages have not been designed to serve the needs of large international companies !
I don't think a language has to be designed to serve the needs of business to qualify as a general purpose language. I would say that Snap! and Scheme are very suited to being a general purpose languages for individuals who do not need to do a lot of data processing.
Offline
OldCodger wrote:
I don't think a language has to be designed to serve the needs of business to qualify as a general purpose language. I would say that Snap! and Scheme are very suited to being a general purpose languages for individuals who do not need to do a lot of data processing.
I think that xly thinks that you think that Snap! should be more about information hiding -- that's what he means by "serve the needs of business," because it's (I think) mostly industrial-size teams of programmers who shoot each other in the foot.
From the perspective of general-purposeness, a huge difference between Snap! and Scheme is that the latter can read and write files! That's something I expect we'll get around to eventually, but if we wanted to take over the real world (as opposed to the school world, which we do want to take over) file I/O would have been way higher on our priority list.
Offline
bharvey wrote:
came up with the idea of unevaluated inputs
As far as I know, this isn't a feature in other languages, right?
If I were making my own programming language (something I actually consider every time I code Java for our robotics team ), you should be able to very easily rewrite the while function as something like this:
def while condition (unevaluated) action (unevaluated): if not condition(): pass else: while condition action while (1=1) (print "Hi") def a 0 while (a<10) ( a+=1 (print a) )
But in JS I'd do something like this:
function while(condition,func) { if (condition()) { while(condition,func); } } while(function(){return true;}, function(){console.log("Hi");});
Which is functional, but really ugly.
Last edited by Hardmath123 (2013-01-14 01:13:24)
Offline
Hardmath123 wrote:
As far as I know, this isn't a feature in other languages, right?
Oh, yes, Lisp has had special forms since forever. In Lisp, though, it's all or nothing (for a given procedure); you don't declare individual inputs as unevaluated. But that's not a problem because you can eval the ones you want to.
First time through LOTR?
Offline
Hardmath123 wrote:
bharvey wrote:
came up with the idea of unevaluated inputs
As far as I know, this isn't a feature in other languages, right?
If I were making my own programming language (something I actually consider every time I code Java for our robotics team), you should be able to very easily rewrite the while function as something like this:
Code:
def while condition (unevaluated) action (unevaluated): if not condition(): pass else: while condition action while (1=1) (print "Hi") def a 0 while (a<10) ( a+=1 (print a) )But in JS I'd do something like this:
Code:
function while(condition,func) { if (condition()) { while(condition,func); } } while(function(){return true;}, function(){console.log("Hi");});Which is functional, but really ugly.
Neither of those work because you never actually invoke action (or func in the JS one).
Offline
bharvey wrote:
Hardmath123 wrote:
As far as I know, this isn't a feature in other languages, right?
Oh, yes, Lisp has had special forms since forever. In Lisp, though, it's all or nothing (for a given procedure); you don't declare individual inputs as unevaluated. But that's not a problem because you can eval the ones you want to.
Well, Lisp's starting to feel like an exception now. Do any boring old vanilla languages have them?
First time through LOTR?
Yeah. I'm barely getting any time to read—I try on the bus, but it's so noisy, I average at maybe 10 pages in a half-hour ride.
Offline
Hardmath123 wrote:
Well, Lisp's starting to feel like an exception now.
God's programming language.
Do any boring old vanilla languages have them?
Umm. Text-based macros such as C's #define are equivalent for certain purposes although much more painful to use. But nothing else is really quite like Lisp special forms, afaik.
Yeah. I'm barely getting any time to read—I try on the bus, but it's so noisy, I average at maybe 10 pages in a half-hour ride.
![]()
Not the easiest book to read in 10-page chunks!
I just skipped over the descriptions of vegetation and the poetry, but I shouldn't be a bad influence.
EDIT: Wow, over 10% done already! You rock.
Last edited by bharvey (2013-01-15 06:46:29)
Offline
Thinking more about Snap! and Lisp, I do not think Lisp can be considered a functional language because:
Lisp procedures can return non-static values, that is you can call them multiple times with the same arguments and receive different return values each time.
This fact disqualifies Lisp from being a functional language.
Special forms seem important to Lisp but after a little reading feel Haskell achieves the same more succinctly and with safety.
Offline
OldCodger wrote:
Lisp procedures can return non-static values
I thought that a language only had to support programming in a functional style to be considered "functional" (as opposed to C, say, which doesn't afaik).
I haven't tried Haskell — but in "Hackers and Painters", which I finished last week, Paul Graham says that languages shouldn't try and stop you doing things, like assigning different types to the same variable or accessing private variables of an object. I think Python 's philosophy in that regard is described as "we're all consenting adults here". Any kind of restriction is just annoying (I hate Java in that respect ).
Also, Brian: I've been reading Hackers: Heroes of the Computer Revolution, which tells the story of the PDP-6 hackers at MIT, and I think there might have been a mention of some guy called Brian Harvey...
Last edited by blob8108 (2013-01-15 12:03:34)
Offline
OldCodger wrote:
This fact disqualifies Lisp from being a functional language.
It certainly disqualifies Lisp from being a purely functional language, yes.
But, you know, Haskell was invented in 1990, 40 years after the functional programming style was invented in Lisp. I really don't want to have to defend Lisp.
Offline
blob8108 wrote:
Also, Brian: I've been reading Hackers: Heroes of the Computer Revolution, which tells the story of the PDP-6 hackers at MIT, and I think there might have been a mention of some guy called Brian Harvey...
![]()
Yeah. Still a kid at heart, but I've been around for a while.
Offline
Sorry for being off-topic, but are there any good resources for reading up on computer science concepts? I'm still a bit confused about lambda and OOP in general. Thanks.
Offline
in order to support macros we'll probably need a quasiquote block (and unquote, and unquote-splicing, of course).
For examples of macros, perhaps consider that custom c-blocks that contain a REPORT block report into the c-block and not to it's caller, whereas primitive c-blocks return from the caller. If you wrote a macro that expanded into code involving a primitive c-block, or tail-recursive function, that would solve this problem.
Also, I would like a way to redefine primitive blocks in terms of the original version.
Offline