Logic programming library development log

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))

  • What does call stand for? (is it a predicate?)
  • I was also puzzled by 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)))

  • Is apply equivalent to reportcall in Snap! ?
  • what is eval equivalent to in Snap! ?
  • what is the user-initial-environment?
  • where does (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 EVALs 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


so it's a variant of 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


where expression is Any(unevaluated) and environment is an environment, derived from
untitled script pic (3)
or one of its variants, most likely CALLER. I think what I wrote might even work, but I wouldn't swear to it. Anyway, it takes an expression and evaluates it, using the given environment to find values of variables. (Note: A Lisp environment, which is what we're talking about here, is different from a query language environment. The relevant environment here is user-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
untitled script pic (4)

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.

  • The SICP example appears to be very well thought-out in many respects. It’s definitely superior to my initial version regarding unification, Booleans, and streams.
  • SICP is very rigorous regarding abstraction, going a long way towards readable code (though this is hindered, for me at least, by the Scheme syntax, which is so much less readable than e.g. Snap!); I may deviate from some of this for better efficiency (instead of using functions to abstract from the underlying data structure, I may use appropriately named variables as item numbers).
  • The table-directed procedure selection - BTW as an exercise I redeveloped the table reporter in Snap!, may share it when it will be good enough for general use - is really educational, and probably handy for a large project, but perhaps a bit exaggerated for this one.

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:
untitled script pic (2)
:~)

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
untitled script pic (3)

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 :slight_smile:

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 PAIRs.

Here you go.

I don't agree. Abstraction is actually an indispensable tool for coping with complexity, and enabling cooperation. How can anyone make a decision about anything (like what's going to be for dinner tonight) if they insist on first understanding all involved factors down to the level of elementary particles (and everything - everything! - in between).

If anything "has to go" it would be secrecy: one needs to be able to inspect / test any-thing reportedly underlying a phenomenon / service / claim. However even that is not always feasible, e.g. I wouldn't want criminals to spy on me, take the money, and run - "the enemy" to disrupt society / abolish the rule of law / trample dissidents, for that matter - would you?

It's a very real dilemma: sometimes we just need to trust others / authorities / "the process" beyond a certain point, and may be disappointed eventually; but if we don't, things could get far worse. So we need trust-enhancing mechanisms - a free press, a privacy authority, corporate reputations, open source platforms - and even those may turn out wolves in sheep's clothing. An ideal world isn't in sight.

I may have (unconsciously) hinted at you :wink:

BTW I recently wrote a Scheme pair constructor too, but rather differently:

Logic programming SICP script pic

Now isn't that interesting (@callietastrophic): two very different implementations that may be abstracted from by using the same hat block? The thing is, anyone can build a universe of Scheme-blocks code on top of either @bluebaritone21 's implementation, or mine, or anyone else's, without necessarily knowing what's under the hood - and it could be ported to any other implementation without a rewrite.

C'mon. Obviously @callietastrophic doesn't want to program by hooking oscilloscope probes onto the wires inside a chip. (Although Brian Silverman's famous laptop has a circuit-level simulation of a 6502 running on it, and he programs it.) But she does mean something by this. (That's the right pronoun, right? Or do I mean "they"?) For her the particular abstraction barrier between blocks and text is super important, for reasons I admit I only slightly understand.

I'm having trouble understanding this, because to me these two paragraphs are contradictory. The first seems to say that you want to live above the block-programming abstraction; the second seems to say that you want to live below it.

Certainly something has to be done about that, but as you point out later, two of you have done that. I can imagine a version of PRINTABLE that recognizes some abstraction for a dotted pair and includes the dot in the printform. And a reader that reads dot notation, for the other direction.

Rather than adding dotted pairs to Snap! 's linked list implementation, if we're going to change Snap! itself for the sake of this project I'd rather generalize to a much more useful feature, namely, allowing users to provide read and print hooks for abstract data types, so (make-rational 2 3) would display as ⅔ rather than as a list. (Just imagine if the lowest level of the 3D array that represents the bitmap of a costume were displayed as little color squares!) And (more challenging) so that the reader would recognize [-]?[0-9]+/[-]?[1-9][0-9]* as a call to make-rational.

Oh for sure!

Hahaha. You're good at this.

Not speaking in name of @callietastrophic of course, I think consistently using “they” is fine (I wouldn’t have agreed perhaps two years ago!). Even though it may seem absurd in cases where you actually (think you) know the "identity" of the person behind the @vatar - because, who knows, anyone might one day feel different (or even experience multiple personalities).

Huh? Too challenging for me, I'm afraid.

I'm a woman, so She/Her are my pronouns, but on a neutral place like a forum, I generally don't assume or ask, but I do try to refer to them as they, because, they are a person no matter what (well, we'll see in a couple years when skynet ChatGPT... nah I was right the first time takes over)

As for this topic. It frustrates me because I know what I'm driving at but iunno. Until a miracle happens and I suddenly get past my brain block, I can't prove it.

But I also don't see it happening any time soon and I have no idea where I would start to even attempt it.

Also I feel that every time I post in a thread I hijack it, so yeah, I'm still here, mostly just reading

I hope you'll find what you're looking for one day!

... or at least: be able to define it (even if it doesn't exist yet, perhaps you a/o others may create it)

Well yeah, I kind a want to create it, if only because I neeeeeeeeeeeed the money, but even if someone else creates it and I can use it properly and start making software I don't hate lol.

but until that day, (Apocalypse +1), I'll keep sitting around getting annoyed at everything.

That's a regex meaning possibly a minus, followed by 1 or more digits, followed by a /, followed by possibly a minus, followed by the digits 1 through 9, followed by 1 or more digits, eh?

The only questions I have is why is the last digit check not optional, and why a wild card?