Ah, okay.
My life has been too hectic lately for me to have a solid chunk of time to look at the library, but I'll get there...
Ah, okay.
My life has been too hectic lately for me to have a solid chunk of time to look at the library, but I'll get there...
No problem as far as I’m concerned. One’s personal life, and health, should always be one’s top priorities.
Getting back to logic programming and SICP section 4.4 ... since, as I have understood, Snap! 's list
and Scheme's pair
are somewhat different, how would:
(cons variable value)
(par. 4.4.4.8)
... translate to Snap! ?
i think I have found the solution myself: it’s up to me to decide - as long as I’m consistently adhering to the same structure.
Yeah, you can do it however you want. But you're a little constrained by the fact that IN FRONT OF will only accept a list as its second input, whereas cons lets you put anything in the cdr. So for example a point on the plane which would naturally be (cons xposition yposition) in Lisp would have to be (LIST ...) in Snap!. If the list is stored as a Lisp-style linked list, that'd be two pairs rather than just one.
No, because that's not invertible. It has to be that
(car (cons a b)) = a
(cdr (cons a b)) = b
and that doesn't work for cdr, because if you see (list a (list b)) you don't know whether its cdr is supposed to be b or (list b).
I've actually been wondering if there's a way to create imperfect lists, I.E. '(1 . 2).
No. That was a decision made in Scratch long ago, which we haven't, so far anyway, seen fit to change. I think that if we were ever to introduce pair mutation (SET ALL BUT FIRST OF _ TO _) (note the imperfect tense!), we might consider non-list pairs at the same time. Neither is very likely.
OK. Then I guess the only feasible general translation of a LISP / Scheme pair
is a Snap! list of two items, while LISP / Scheme's list
would translate to building nested 2-item lists in Snap!, much like the structure of streams. Is that right?
Yes, exactly.
I have a few questions about procedures on SICP section 4.4.4.2., paragraph "filters":
(define (lisp-value call frame-stream)
_ (stream-flatmap
_ _ (lambda (frame)
_ _ _ (if (execute
_ _ _ _ _ (instantiate
_ _ _ _ _ call
_ _ _ _ _ frame
_ _ _ _ _ (lambda (v f)
_ _ _ _ _ _ (error "Unknown pat var: LISP-VALUE" v))))
_ _ _ _ (singleton-stream frame)
_ _ _ _ the-empty-stream))
_ _ frame-stream))
call
stand for? (is it a predicate?)lambda (v f)
, but I think I know what it stands for now: the lambda function is an unbound variable handler
that will ignore its second input - please correct me if I'm wrong.(define (execute exp)
_ (apply (eval (predicate exp) user-initial-environment)
_ _ _ _ _ (args exp)))
apply
equivalent to call
in Snap! ?eval
equivalent to in Snap! ?(args exp)
come in?Another question, about sect. 4.4.4.7: what would symbol?
translate to in Snap! ?
Sort of. The example just before Exercise 4.56 is
(and (salary ?person ?amount)
(lisp-value > ?amount 30000))
so call
is the list (< ?amount 30000)
.
Execute
EVAL
s the <
in user-initial-environment
but doesn't eval
anything else; it just does
(apply (eval ...) (args exp))
where the call to eval
turns the symbol <
into the less-than primitive predicate.
We're not quite done talking about execute
, but these questions come first.
Apply
is
call
that takes an input list instead of a variadic input. (Actually for real Lispians, it's apply
that's fundamental and call
(more typically called invoke
) that's the variant. Eval
and apply
are objects of religious fervor to Lispians, because they do pretty much all the work of a Lisp interpreter. When we say things like "Inside every bad language interpreter there's a Lisp interpreter trying to get out" we mean that those other interpreters always have a version of eval
(not necessarily called that, of course) and a version of apply
(ditto), buried in syntax.)
We don't exactly have eval
in Snap!, because code wasn't first class until just recently. It's sort of
expression
is Any(unevaluated) and environment
is an environment, derived fromuser-initial-environment
, which for our purposes means the global environment, but some Lisp interpreters, including the Chapter 4 one apparently, have an environment frame just for globals defined by the user, whose parent is an environment frame with the globals that come predefined when you fire up the interpreter (which, in the case of Scheme, includes all the primitive procedures, whose names are bound to them as ordinary variables).)
As for symbol?
, Snap! doesn't distinguish text strings from symbols; any text string that isn't a number can be a symbol, which basically means "the name of a variable." So the closest we come is
So when we see (lisp-value < ?salary 30000)
in a query we end up calling (in Lisp) (< 12000 30000)
(or whatever the person's salary is). By the time we're in the Lisp world, there are no query system variables left in the expression, thanks to instantiate
, so the only thing we had to look up in the Lisp environment is <
.
I hope that helps!
By the way, I hope I said this before, but you don't have to write an exact copy of the SICP query system. The real Prolog does better at catching infinite loops, for example, I think. Just, whatever you end up with has to be callable from Snap! code.
Thx a lot! And yes, I know you didn’t ask me to write a copy of the SICP version. However the best way, for me, to study an intricate example, is to rebuild at least crucial parts of it; and then develop my own (if possible: improved) version.
SICP is the bible of computer science. Everything they do is brilliant. "Very well thought out" indeed! :~)
Although, actually, to my taste, the tiny abstract data types where the two selectors are obviously just car and cdr make the code harder to read. I believe in data abstraction, but I think they overdo it a little. I know this is heretical.
The thing about Lisp syntax is that you're supposed to edit in Emacs or some other Lisp-aware editor, so things are automatically indented correctly. It's funny that you compare it to Snap!, since of course our syntax basically is Lisp syntax, but with expressions colorized. You just have to remember that the rounded ends of the reporter blocks are really parentheses:
:~)
I think the data-directed dispatch is really lightweight and elegant! It makes the actual dispatch code tiny. And you don't have to edit the existing code of the evaluator to add a new special form. That makes it harder to introduce new bugs into the old code by mis-editing.
I agree, a table library is a great idea, although having dictionaries eliminates some of the need for them. Here, for example, you could have a dictionary with entries like
P.S. I see that I wrote
somehow turning ">
" into "<
." Sigh. I guess I have an affinity for workers rather than bosses.
I’m not impressed, being an atheist (though non-practicing).
3 Hail Mary’s!
It’s quite easy to write hard-to-read code in Snap!, too.
You may be right. Just using the Snap! dictionary function.
You just have to remember that the rounded ends of the reporter blocks are really parentheses
Yeah. I mean I've been saying that for a while lol.
We don't exactly have
eval
in Snap*!* , because code wasn't first class until just recently
I mean you DO. It's called Snap!
The thing about Lisp syntax is that you're supposed to edit in Emacs or some other Lisp-aware editor, so things are automatically indented correctly.
That's what blocks are. A use for whitespace that demonstrates human readability and how it can be used in computation research. It's such a monumental paradigm shift because it changes everything.
I gave up on SICP a while ago. Not because it's a bad book, but because it's not written for snap, snap makes too many subtle changes that scheme can't account for because the scheme it was written for is nearly 30 years old and snap! is new.
QW23's been doing some great work teaching themselves examples and figuring out the foibles that I can't.
Because basically what I want to do is write software, but coding has always been arcane smug rubbish that takes great pride in excluding others. Snap! gave me a gateway that I can't use because every other programming brand in existence is arcane ritualistic text.
Now as I've said previously, I understand why snap! made the decisions it did and as it's primary a teaching language, I even agree with them.
But I still want to write my own software and I want to do it in a block based ide, because there's no such thing as a block based ide. It's turtles text all the way down and always has been.
[scratchblocks] (Pick Random (1) to (10)) [/scratchblocks] is (Pick Random (1) to (10))
The only difference is that one has a markup signifier that the browser knows "When I receive [scratchblocks]" message and it's the same markup that knows to replace ":-)" with
Which is why I try and try and try to figure out how to put a text parser in snap! and/or an ability to drop .c or .scm or .whatever files into snap, but the problem is, most existing software is writing in programming brands names that don't want you to solve the problem they want you to use their products without thinking too deeply about it.
That annoys the living duck out of me.
Ah, you should join my religion. We worship Alonzo Church, who invented computer science, at the same time Turing did. (In fact, Church was Turing's PhD thesis advisor, although that's a little misleading because Turing was already doing things before becoming an official grad student.) People just credit Turing with it because (1) he won World War II, and (2) nobody understood the importance of Church's lambda calculus until John McCarthy invented Lisp.
Oh, sure. But you can't blame that on the syntax we provide. You can write obfuscated code in any language!
The idea of SICP is that it isn't a book on how to program in Scheme; it's a book on how to program in any language. (That's especially true since finally, after 63 years, all those other languages have lambda!) Scheme just gets in the way less than most.
I get that you find it hard to learn the ideas without concrete programs to examine and to write. That's why John Denero at Berkeley rewrote it using Python (although he also changed a lot to emphasize OOP more), and why those other guys rewrote it using JavaScript, and why I want to rewrite it using Snap!. So, yeah.
Sorry, I deleted that because it was a leeetle antagonistic, I typed it quickly and went back to doing what I was doing lol.
get that you find it hard to learn the ideas without concrete programs to examine and to write. That's why John Denero at Berkeley rewrote it using Python (although he also changed a lot to emphasize OOP more), and why those other guys rewrote it using JavaScript, and why I want to rewrite it using Snap*!* . So, yeah.
Well no, I have the entire internet of concrete source to experiment with. The issue is I don't have a block based IDE to use any of it, because amongst other things, the unrelenting conspiracy abstraction is necessary.
Again. I need to state that I'm not opposed to snap and I understand why the safety features are there, but there NEEDS to be a third tier block language without those limitations. NEEDS., It's absolutely essential that something like that exists.
You can't "Leave it to the engineers" or "trust the computer knows what it's doing" anymore for as long as Scratch and Snap exist, because you're now teaching what used to be advanced university level knowledge to high-schoolers and acting surprised when they want to know more!
You're unlocking the key to the kingdom and then saying "No" (And the worst part is, it's not even intentionally)
You basically solved the problem. It's a writing idea but there's a thing for aspiring writers that you "Show not Tell" Which is you describe and explain the scene and the actions that happens instead of saying "Bob did this, Steve Did that and they all lived happily ever after"
Scratch And Snap! SHOW. Text Programming Brands are designed to tell, and only tell and not let you deviate from the path they choose, and the logical development of visual languages in advanced spaces is mind blowing... but no, we've still got to put up with Text Programming Brands refusing to vanish into the dusty archives of history
TL;DR;
Text is [scratchblocks] (Block (Is)) [/scratchblocks] TEXT.
Abstraction has to go.
I guess rewriting SICP is like eating an elephant: better do it one byte at a time. Like, Ch. 1 this year (though I think a Snap! manual update is more urgent for now - where the same adage may apply).
A major decision, I think, will be how to replace the SICP code with Snap! - is it going to be a literal translation? Or a rewrite from scratch - no pun intended - using the underlying ideas? IMO a serious dilemma with a literal translation would be whether to copy Scheme's pair
type.
Would it help if someone wrote an automatic Scheme-to-Snap! translator? Or perhaps a set of Scheme blocks in Snap! ?
Sorry, I'm not much of a Church-goer: non-practicing, remember?
Huh. I just wrote a set of Scheme blocks in Snap!, including PAIR
s.