What is the equivalent of the rest procedure in SICP in MIT Scheme 9.2? - scheme

I am on exercise 2.32 which presents the following code:
(define (subsets s)
(if (null? s)
(list nil)
(let ((rest (subsets (cdr s))))
(append rest (map <??> rest)))))
When I try to call the rest procedure in MIT Scheme 9.2 it doesn't recognize the procedure (there is a similar issue with nil in the book, which is replaced by () in modern Scheme). What is the equivalent rest procedure in modern Scheme? I don't believe it is cdr because cdr is used throughout the book.

You're misunderstanding the exercise - rest is not a procedure, is a local variable that corresponds the the rest of the subsets (perhaps you should take a look at the documentation regarding let). This is what the book is asking:
(define (subsets set)
(if (null? set)
(list '())
(let ((rest (subsets (cdr set))))
(append rest
(map (lambda (sets) (cons (car set) sets))
rest)))))

As #tfb points out, rest in this code is not a procedure, it is a locally-bound symbol.
Maybe you are misinterpreting an error message about rest; without seeing it, it is hard to say.

Related

The Little Schemer: `lat?` without `cond`?

One of the first questions in the second chapter of The Little Schemer (4th edition) asks the reader to write the function lat?, where (lat? l) returns true if l is a list of atoms.
It goes on to say:
You were not expected to be able to do this yet, because you are still missing some ingredients.
But I'm familiar with recursion, and the definition of atom? earlier in the book already introduced and (further implying the existence of or), so I gave it a shot anyway: (repl)
(define lat?
(lambda (l)
(or
(null? l)
(and
(atom? (car l))
(lat? (cdr l))))))
On the next page, the book introduces the cond operator to enable this definition of lat?:
(define lat?
(lambda (l)
(cond
((null? l) #t)
((atom? (car l)) (lat? (cdr l)))
(else #f))))
Is there any significant difference between these two implementations?
cond is a special form, that takes (roughly) the form
(cond
((test-expression) (then-expression))
((test-expression2) (then-expression2))
(else
(then-expression3)))
Its semantics is that it will evaluate the test-expressions in order, and for the first one that it finds to evaluate to #t (the true value), then it will evaluate its associated then-expression and return its value. If all the test-expressions evaluate to #f (the false value), and an else clause is present, then it will evaluate its associated then-expression3 in this case, and return its value.
So as far as semantics are concerned, the two implementations are equivalent. Their only difference might be that afaik the cond version is considered more idiomatic in the Scheme community.

I have got this code to remove the last element of a list. How can i change this to remove a set word regardless of its location?

#lang racket
(define (remove-last lst)
(if (null? (cdr lst))
'()
(cons (car lst) (remove-last (cdr lst)))))
(remove-last '(Help Me Please))
This then prints out:
(Help Me)
How can I change this? For example if I wanted to remove me.
Like this, for example:
(define (remove-words lst words)
(cond
((null? lst)
'())
((member (car lst) words)
(remove-words (cdr lst) words))
(else
(cons (car lst) (remove-words (cdr lst) words)))))
then
> (remove-words '(Help Me Please) '(Me Help Not))
'(Please)
You can also use the procedures for sets:
(define (remove-words lst words)
(set-subtract lst words))
Please note that you are working with symbols here, not strings.
You can also solve the problem using filter-not and member together:
(define (remove-words lst words)
(filter-not (lambda (x) (member x words) lst))
If you want to cut down on the wordiness of that anonymous function, the tools most suited to that are curry and cut (with the latter needing a (require srfi/26) to use).
Currying a function turns it into a new function that accepts one argument, then returns another function that accepts one more argument, then again, then again, and so on until it has all the arguments it needs to call the original function. A curried version of remove-words would be called as ((remove-words lst) words) instead, and you could make it from our current implementation with (curry remove-words). This requires that the arguments be supplied in left to right order, which doesn't work for member. There's another form curryr that goes right-to-left, but because member takes an optional third argument it won't work.
You could use cut (from srfi 26) then, which lets you pick which arguments of a function you want to "lock-in" and which you want the new function to accept. (cut member <> words)creates a new function (lambda (arg) (member arg words)) and (cut * <> <> 8) creates (lambda (arg1 arg2) (* arg1 arg2 8)). So with this, remove-words looks like:
(require srfi/26)
(define (remove-words lst words)
(filter-not (cut member <> words) lst))
Although going with set-subtract is still probably the best solution since you should avoid reinventing the wheel as much as possible (unless you're trying to learn more about wheels). Nonetheless, it's very useful to have a firm grip on the general functions provided by Racket that make your life easier.

How to implement call-with-values to match the values example in R5RS

R5RS says...
Values might be defined as follows:
(define (values . things)
(call-with-current-continuation
(lambda (cont) (apply cont things))))
It doesn’t, however, say how call-with-values might be implemented if values were implemented this way. So, if values is implemented this way, how would call-with-values be implemented?
(This came up because I was trying to get some code that used call-with-values to work with TinyScheme, which doesn’t support it. I managed by faking values and call-with-values with lists, but—when I saw this in R5RS—I wanted to know if this might be a better workaround.)
Kent Dybvig defines call/cc, values and call-with-values thusly:
(define call/cc call/cc)
(define values #f)
(define call-with-values #f)
(let ((magic (cons 'multiple 'values)))
(define magic?
(lambda (x)
(and (pair? x) (eq? (car x) magic))))
(set! call/cc
(let ((primitive-call/cc call/cc))
(lambda (p)
(primitive-call/cc
(lambda (k)
(p (lambda args
(k (apply values args)))))))))
(set! values
(lambda args
(if (and (not (null? args)) (null? (cdr args)))
(car args)
(cons magic args))))
(set! call-with-values
(lambda (producer consumer)
(let ((x (producer)))
(if (magic? x)
(apply consumer (cdr x))
(consumer x))))))
The short answer is: You can't
The nifty implementation of values does not change the fact that there is no way to implement the other procedures if you don't have any of them to poke at the values. If you had one way to peek then you could implement the others with that.
(+ (values 4 5))
(apply + (values 4 5))
Doesn't work and that's why you need those other primitives.
When that said. There is no difference between returning more values and returning lists with values since the difference is optimization. You could make a macro that treats both of them as a binding and then the way you use them would be the same. The difference in performance is some pointer jumping and some consing which is reasonable fast for any lisp implementation. Heres a minimalistic implementation that will work given your code is correct:
(define values list)
(define (call-with-values producer consumer)
(apply consumer (producer)))

How do I get the functions put and get in SICP, Scheme, Exercise 2.78 and on

I am trying to do exercise 2.78 in SICP, but the functions put and get are unknown. I have tried multiple languages, like pretty big, racket, r5rs, mit-scheme, mzscheme, etc. I even downloaded the SICP support (http://www.neilvandyke.org/sicp-plt/), to no avail. How can I get these functions to work?
Yes, I found SICP a little annoying sometimes because of stuff like this. Functions that are assumed to exist but don't actually exist make it harder to try to the examples. I wrote my own (get) and (put) like so (this was in GNU guile):
(define global-array '())
(define (make-entry k v) (list k v))
(define (key entry) (car entry))
(define (value entry) (cadr entry))
(define (put op type item)
(define (put-helper k array)
(cond ((null? array) (list(make-entry k item)))
((equal? (key (car array)) k) array)
(else (cons (car array) (put-helper k (cdr array))))))
(set! global-array (put-helper (list op type) global-array)))
(define (get op type)
(define (get-helper k array)
(cond ((null? array) #f)
((equal? (key (car array)) k) (value (car array)))
(else (get-helper k (cdr array)))))
(get-helper (list op type) global-array))
Probably a naive implementation from the perspective of later in the book, but fairly simple and worked fine.
There is an implementation of put and get by Eli Bendersky.
These functions could be implemented using builtin Basic Hash Table Operations. Here is my modified version of Eli's code to work properly with MIT-Scheme Release 9.1.1.
(define *op-table* (make-hash-table))
(define (put op type proc)
(hash-table/put! *op-table* (list op type) proc))
(define (get op type)
(hash-table/get *op-table* (list op type) '()))
UPDATED:
I've found bug with above mentioned code after time. Empty lists are interpreted as true in conditional clauses by Scheme, so correct get implementation should be following:
(define (get op type)
(hash-table/get *op-table* (list op type) #f))
If you use Racket programming language please use these:
(define *op-table* (make-hash))
(define (put op type proc)
(hash-set! *op-table* (list op type) proc))
(define (get op type)
(hash-ref *op-table* (list op type) '()))
In subsection Creating local tables of 3.3.3 Representing Tables, there is an implementation.
mit-scheme has a built-in global table that you can use.
http://www.gnu.org/software/mit-scheme/documentation/mit-scheme-ref/The-Association-Table.html
simply define get and put to:
(define get 2d-get)
(define put 2d-put!)

Idiomatic usage of local vs lambda?

In Exercise 30.1.1 of HtDP, I started off using local and then modified it to use lambda in order to answer the question.
(define (add-to-each2 accu a-list)
(cond
[(empty? a-list) empty]
[else (local ((define s (+ accu (first a-list))))
(cons s (add-to-each2 s (rest a-list))))]))
and
(define (add-to-each5 accu a-list)
(cond
[(empty? a-list) empty]
[else (cons ((lambda (x y)
(first (map + (list (first y))
(list x)))) accu a-list)
(add-to-each5 (+ accu (first a-list))(rest a-list)))]))
In this particular instance, to me, the local version is easier to read. Are there situations where the lambda version would be preferred? Thank you.
First off, I think you might be getting relative-2-absolute confused with add-to-each, since add-to-each just adds the same number to each element of the list, rather than incrementing an accumulator. The rest of this post assumes that's the case, and just takes out that incrementing.
I think let would be my first choice for the local binding. Your lambda example uses a common pattern that simulates let using lambda and application:
(let ([x e]) body)
Is equivalent to:
((lambda (x) body) e)
If you use this transformation from lambda to let in your example, you get:
(define (add-to-each5 n a-list)
(cond
[(empty? a-list) empty]
[else (cons (let ([x n] [y a-list])
(first (map + (list (first y))
(list x))))
(add-to-each5 n (rest a-list)))]))
A good compiler will likely generate the same code for this as for your two examples, so it mostly comes down to style. The "left-left lambda" pattern can be more difficult to read, as you note, so I prefer let.
However, Exercise 30.1.1 is trying to make you use map as a replacement for the explicit recursion that occurs in each of your examples. You are using map in your example but only for a single addition at a time, which makes map kind of painful: why bother wrapping up (list (first y)) and (list x) when you just want (+ (first y) x)?
Let's look at a simple definition of map to see how it might be helpful, rather than painful, for this problem:
(define (map f ls)
(cond
[(empty? ls) empty]
[else (cons (f (first ls)) (map f (rest ls)))]))
Right away, you should notice some similarities to add-to-each: the first line of the cond checks for empty, and the second line conses something to do with the first element onto a recursive call to map on the rest. The key, then, is to pass map an f that does what you want to do to each element.
In the case of add-to-each, you want to add a particular number to each element. Here's an example of adding 2:
> (map (lambda (n) (+ 2 n)) (list 1 2 3 4 5))
(3 4 5 6 7)
Notice that map and lambda are both here as 30.1.1 requests, and they act on an entire list without the explicit recursion of the original add-to-each: the recursion is all abstracted away in map.
This should be enough to get you to a solution; I don't want to give away the final answer, though :)

Resources