sicp | Exercises and notes from Structure and Interpretation
kandi X-RAY | sicp Summary
kandi X-RAY | sicp Summary
Exercises and notes from Structure and Interpretation of Computer Programs, first edition. In JavaScript.
Support
Quality
Security
License
Reuse
Top functions reviewed by kandi - BETA
Currently covering the most popular Java, JavaScript and Python libraries. See a Sample of sicp
sicp Key Features
sicp Examples and Code Snippets
Community Discussions
Trending Discussions on sicp
QUESTION
Let's take the following filter
function:
ANSWER
Answered 2021-Jun-15 at 06:05Yes, your double lambda approach does work. But there are nicer ways to do this too.
It turns out define
can do this directly. The following two pieces of code are identical:
QUESTION
In doing some tests I've noticed that append
always gives me the same output as input when using map
:
ANSWER
Answered 2021-Jun-15 at 01:20The append
procedure takes zero or more list arguments, and a final argument that can be any object. When the final argument is a list, the result of appending is a proper list. When the final argument is not a list, but other list arguments have been provided, the result is an improper list. When only one argument is provided, it is just returned. This behavior with one argument is exactly the behavior of an identity procedure.
QUESTION
I have the following function to scale a (2-col) matrix:
...ANSWER
Answered 2021-Jun-14 at 22:28Your last attempt is correct: you'll have to extract the lambda
used for scale
outside the map
call. You can't modify the innermost lambda, map
expects a lambda
with one argument, you can't pass a nested lambda
there. So if you want to curry the scale
there's no option but:
QUESTION
I'm arduously struggling my way through the N-queens problem in SICP (the book; I spent a few days on it -- last question here: Solving Eight-queens in scheme). Here is what I have for the helper functions:
...ANSWER
Answered 2021-Jun-12 at 09:35When you are doing the SICP problems, it would be most beneficial if you strive to adhere to the spirit of the question. You can determine the spirit from the context: the topics covered till the point you are in the book, any helper code given, the terminology used etc. Specifically, avoid using parts of the scheme language that have not yet been introduced; the focus is not on whether you can solve the problem, it is on how you solve it. If you have been provided helper code, try to use it to the extent you can.
SICP has a way of building complexity; it does not introduce a concept unless it has presented enough motivation and justification for it. The underlying theme of the book is simplification through abstraction, and in this particular section you are introduced to various higher order procedures -- abstractions like accumulate, map, filter, flatmap which operate on sequences/lists, to make your code more structured, compact and ultimately easier to reason about.
As illustrated in the opening of this section, you could very well avoid the use of such higher programming constructs and still have programs that run fine, but their (liberal) use results in more structured, readable, top-down style code. It draws parallels from the design of signal processing systems, and shows how we can take inspiration from it to add structure to our code: using procedures like map, filter etc. compartmentalize our code's logic, not only making it look more hygienic but also more comprehensible.
If you prematurely use techniques which don't come until later in the book, you will be missing out on many key learnings which the authors intend for you from the present section. You need to shed the urge to think in an imperative way. Using set! is not a good way to do things in scheme, until it is. SICP forces you down a 'difficult' path by making you think in a functional manner for a reason -- it is for making your thinking (and code) elegant and 'clean'.
Just imagine how much more difficult it would be to reason about code which generates a tree recursive process, wherein each (child) function call is mutating the parameters of the function. Also, as I mentioned in the comments, assignment places additional burden upon the programmers (and on those who read their code) by making the order of the expressions have a bearing on the results of the computation, so it is harder to verify that the code does what is intended.
Edit: I just wanted to add a couple of points which I feel would add a bit more insight:
- Your code using set! is not wrong (or even very inelegant), it is just that in doing so, you are being very explicit in telling what you are doing. Iteration also reduces the elegance a bit in addition to being bottom up -- it is generally harder to think bottom up.
- I feel that teaching to do things recursively where possible is one of the aims of the book. You will find that recursion is a crucial technique, the use of which is inevitable throughout the book. For instance, in chapter 4, you will be writing evaluators (interpreters) where the authors evaluate the expressions recursively. Even much earlier, in section 2.3, there is the symbolic differentiation problem which is also an exercise in recursive evaluation of expressions. So even though you solved the problem imperatively (using set!, begin) and bottom-up iteration the first time, it is not the right way, as far as the problem statement is concerned.
Having said all this, here is my code for this problem (for all the structure and readability imparted by FP, comments are still indispensable):
QUESTION
ANSWER
Answered 2021-Jun-05 at 14:21QUESTION
ANSWER
Answered 2021-May-31 at 23:11In SICP type streams the car
of a stream is not delayed, but the cdr
is.
The whole expression,
QUESTION
I'm going through an exercise to grab the 'leaves' of a nested list in scheme (from SICP). Here is the exercise input-output:
...ANSWER
Answered 2021-May-31 at 13:17The reason there are three cases is that you are importing some scalar / vector distinction from some other language: Scheme doesn't have it and it is not helpful. Instead a list is a recursively-defined object: a list is either the empty list, or it is a pair of something and a list. That means there are two distinctions to make, not one: is an object a pair, and is an object the empty list:
QUESTION
I'm doing the SICP exercise of filtering a list based on the odd/even-ness of the first argument. For example:
...ANSWER
Answered 2021-May-24 at 21:34You can use apply
to make the recursive calls without using a helper function. Its last argument is a list, which will be spread into arguments in the function call. This allows you to pass first
again as well as (cdr lst)
.
You can also just use cons
to build a new list from an element and a subsequent list, rather than creating a temporary list to use append-list
.
QUESTION
I'm working my way through SICP, and it gives the following definition for zero
for Church Numerals:
ANSWER
Answered 2021-May-20 at 09:41There is no x
in (lambda (x) x)
. None.
The x
in (lambda (x) x)
is bound. It could be named by any name whatever. We can not talk about x
in (lambda (x) x)
any more than we could talk about y
in (lambda (y) y)
.
There is no y
in (lambda (y) y)
to speak of. It is just a placeholder, an arbitrary name whose sole purpose in the body is to be the same as in the binder. Same, without regard for which specific name is used there as long as it is used twice -- first time in the binder, and the other time in the body.
And in fact there is this whole 'nother notation for lambda terms, called De Bruijn notation, where the same whole thing is written (lambda 1)
. With 1
meaning, "I refer to the argument which the binder 1 step above me receives".
So x
is unimportant. What's important is (lambda (x) x)
which denotes a function which returns its argument as is. The so called "identity" function.
But even this is not important here. The Church encoding of a number is really a binary function, a function expecting two arguments -- the f
and the z
. The "successor step" unary function f
and the "zero" "value" z
, whatever that might be, as long as the two go together. Make sense together. Work together.
So how come we see two unary functions there when it is really one binary function in play?
That is the important bit. It is known as currying.
In lambda calculus all functions are unary. And to represent a binary function an unary function is used, such that when given its (first) argument it returns another unary function, which, when given its (now, second) argument, performs whatever thing our intended binary function ought to perform, using those two arguments, the first and the second.
This is all very very simple if we just write it in combinatory (equational) notation instead of the lambda notation:
QUESTION
In SICP it defines the church numerals for positive numbers as follows:
...ANSWER
Answered 2021-May-14 at 00:49Your version presupposes the existence of primitives like cond, 0, 1, =, and -. The point of all this is to show that you can implement such primitives starting from nothing but lambda.
Community Discussions, Code Snippets contain sources that include Stack Exchange Network
Vulnerabilities
No vulnerabilities reported
Install sicp
Support
Reuse Trending Solutions
Find, review, and download reusable Libraries, Code Snippets, Cloud APIs from over 650 million Knowledge Items
Find more librariesStay Updated
Subscribe to our newsletter for trending solutions and developer bootcamps
Share this Page