I was solving exercise-3.23 of section 3.3.2 of SICP,
which is an implementation of deque.
As Racket doesn't support set-car! and set-cdr!,so I use #lang planet neil/sicp from SICP Support for DrRacket,and wrote the code:
#lang planet neil/sicp
(define (make-deque) (cons '() '()))
(define (empty-deque? dq) (null? (front-ptr dq)))
;;; just here, I use when form
(define (front-delete-deque! dq)
(cond ((empty-deque? dq)
(error "FRONT-DELETE-DEQUE! called with empty deque" dq))
(else
(set-car! dq (caddr (front-ptr dq)))
(when (null? (front-ptr dq))
(set-cdr! dq '())))))
(define (front-ptr dq) (car dq))
(define (rear-ptr dq) (cdr dq))
I got an error: when: unbound identifier in module, which is very strange.
I think it has something to do with the neil/sicp, since Racket has when form.
And can someone explain what exactly #lang planet neil/sicp means and matters?
PS: forget how I implement the deque.
It's quite possible that the implementors of the neil/sicp package chose not to support when - after all, it's not part of the standard language and (as far as I can remember) it was never mentioned in SICP. But fear not, when is not essential and you can write something equivalent, just substitute this part:
(when (null? (front-ptr dq))
(set-cdr! dq '()))
With this:
(if (null? (front-ptr dq))
(set-cdr! dq '())
#f)
And if you're feeling bold you can even write your own when macro, one of the nice things of Scheme is that you can extend its syntax. Left as an exercise for the reader.
SICP is beautiful stuff; beautifully designed to work with Scheme, plain and simple. Rather than dealing with the idiosyncrasies of Racket, such as not having set-car! apparently, why not just choose a proper Scheme?
There are different Scheme standards. The most recent, R7RS, defines when and provides a definition as:
(define-syntax when
(syntax-rules ()
((when test result1 result2 ...)
(if test
(begin result1 result2 ...)))))
If you use a Scheme based on R5RS or R6RS they will either already define when or allow you to define it as above.
Related
I am having a hard time debugging this code and was hoping somebody might be able to help with pseudocode or examples of similar problems. Thank you ahead of time!
Define a non-recursive Scheme procedure (remove-them2 lst n) which returns a list of all elements of lst that do not appear in the list n.
Here is what I have so far:
(define (remove-them2 lst n)
(if (null? lst)
n
(let ((tail (remove-them2 cons((cdr lst) (cdr n)))))
(if (member (car lst) (car n) tail)
tail
(cons (car lst) (car n) tail)))))
I'm afraid there are several syntax errors in your solution, please take some time to study how to write procedures in Scheme and how to invoke procedures. To name a few:
We don't call a procedure like this: cons(...), the correct way is (cons ...)
cons expects two arguments, but you're passing three
remove-them2 expects two arguments, but you're passing one
member expects two arguments, but you're passing three
The way you're building the output list is incorrect
We don't need to ask for (car n), we're interested in checking if an element is a member of the whole n list
There's no need to have a tail variable here, it's easier if we just call the recursion directly; and anyway you're using tail incorrectly.
It's not clear what algorithm you tried to implement, but the actual solution is simple - although we'll have to rewrite the code from scratch to make it work:
(define (remove-them2 lst n)
(if (null? lst)
'()
(if (member (car lst) n)
(remove-them2 (cdr lst) n)
(cons (car lst) (remove-them2 (cdr lst) n)))))
EDIT: It's also possible to write a solution without using recursion:
(define (remove-them2 lst n)
(filter (lambda (e) (not (member e n)))
lst))
Either way, it works as expected:
(remove-them2 '(1 2 3 4 5 6 7) '(1 3 5))
=> '(2 4 6 7)
Without knowing which subset of the language you are allowed to use it's hard to answer this reasonably.
I'll assume that you want something which is not syntactically recursive (so you can't use a function with an accumulator: I'm not sure what the right word is for this), you are allowed to use map and append, but you're not allowed to use filter as that seems like such an immediate answer.
With those constraints here is how you can do this:
(define (remove-them2 l baddies)
(apply append (map (lambda (e)
(if (memv e baddies)
'()
(list e)))
l)))
I think this is pretty artificial and horrible, but it works (in languages like CL it would not portably work however, which is why I think it's horrible).
In the book The Seasoned Schemer - the author writes the following code:
(define intersectall
(lambda (lset)
(letcc hop
(letrec
((A (lambda (lset)
(cond
((null? (car lset)) (hop (quote ())))
((null? (cdr lset)) (car lset))
(else
(intersect (car lset)
(A (cdr lset))))))))
(cond
((null? lset) (quote ()))
(else (A lset)))))))
Here is potentially how it could look in Clojure:
(defmacro letcc
[name & body]
`(letfn [(~name [arg#]
(throw (ex-info (str '~name) {:name '~name :value arg#})))]
(try ~#body
(catch clojure.lang.ExceptionInfo e#
(if (= '~name (:name (ex-data e#)))
(:value (ex-data e#))
(throw e#))))))
(defn intersectall
[lset]
(letcc hop
(letfn [(A [lset]
(cond (empty? (first lset))
(hop ())
(empty? (rest lset))
(first lset)
:else
(intersect (first lset) (A (rest lset)))))]
(cond (empty? lset)
()
:else
(A lset)))))
My question is: How do you do letcc in Clojure?
Background
The core Clojure language does not support first-class continuations. That, and the fact that the JVM does not provide a way to capture the current continuation, means there is no way of implementing letcc that is satisfactory for all situations.
However, it is possible to implement continuations in some situations. Specifically, if you own all the code (that is, the code in which you must capture continuations) then you can employ continuation-passing-style (CPS). Basically, you add an extra parameter to each function. This parameter is a function that represents the continuation of that call. You "return" a value by calling the continuation function. Of course, this style is a pain to write by itself -- but fortunately this is a transform we can easily apply to specific code via macros.
By itself, CPS is unsuitable for platforms that do not do tail-call optimization (TCO). Because the last step of any function in CPS is to invoke another function, without TCO the stack quickly overflows except for the most trivial of computations. This problem can be solved by employing thunking and trampolining.
Solutions
As I alluded above, you can write your own CPS transform using macros. However, I would invite you to checkout my pulley.cps library, which already does this for you. There are alternatives, but as far as I'm aware pulley.cps is the only Clojure library that provides all of the following:
call-cc/let-cc
Seamless calls between "native" (non-transformed) and transformed code
Exception (try/catch/finally) support
binding forms (they're properly tail-recursive too!)
Allows you to provide a CPS version of an existing native function (this is necessary if you want to capture a continuation within that function)
Alternatives include:
delimc provides a library for delimited continuations. This doesn't appear to be very complete (e.g., binding fails because it doesn't understand the try/finally block) and hasn't been touched in 4 years.
algo.monads is a monad library for Clojure. There is a strong and interesting relationship between monads and continuations, and algo.monads provides a continuation monad. Although monadic style isn't quite as covenient, it does have the advantage of making the effect more explicit, which can aid in encapsulating the code that uses control effects from the code that doesn't. Plus, do notation (e.g., the domonad macro) greatly blurs the lines between direct and monadic style.
The continuation caught by (letcc hop ...) in your example is used as an "upwards continuation". One could have used the name return instead: (letcc return ... (return () ...). When the continuation named return is called, the entire letcc-expression evaluates to the value given to return -- which is then returned as the result of intersectall.
This means that 1. the continuation goes up (we return) and 2. the continuation is used once only. When these conditions are met, one can implement letcc in terms of try and catch as you have done.
So as I see it, by writing your letcc macro, you have answered your own question.
Now as Nathan Davis mentions there are other use cases of continuations, but Clojure does not support them directly.
Note: There is a related question here: The Seasoned Schemer, letcc and guile
I'm trying to write a Scheme function that counts all the items in a list, but unlike the length function that is available would count inner lists also so countAll '(a (a b)) would return 3 and not 2.
the first check is for an empty list, the second is supposed to check if the head of the list is currently a list itself, it should then add the length of THAT list to the total and call the next recursive call, if it isn't, it should simply skip to the third part which will add one to the total and call the function recursively.
I'm getting syntactical errors and I'm unsure about my approach. Am I going about this the right way? Are there better/Easier ways to do this?
(define countAll
(lambda (list)
(if (null? list)
0
((if (list? (car list)
(+ length (car list)
(countAll (cdr list))))))
(+ 1
(countAll (cdr list))))))
(+ 1
(countAll(cdr list)
)))))
You've made a mess of your parentheses. I would strongly advise rewriting this using cond, as in
(cond
((null? lst) 0)
((list? (car lst)) (???))
(else (???)))
This will make it easier to see what you are doing and much less likely that you mess up your parentheses. Nested ifs really are something to avoid except in the simplest of circumstances.
Your approach is nearly right, but you've missed something. You have made a big assumption about what happens when (list? (car lst)) evaluates to true. Can you think what it is? If you think about it hard enough, you'll realise that you cannot use the length function here.
The solution to this kind of problem follows a well-known structure, a recipe if you wish, for traversing a list of lists. This looks like homework, so I'll help you with the general idea and you go ahead filling-in the blanks:
(define (countAll lst)
(cond ((null? lst) ; if the list is empty.
<???>) ; then it doesn't have any elements
((not (list? (car lst))) ; if the first element in the list is not a list
(<???> (countAll <???>))) ; add one and advance the recursion over the `cdr`
(else ; otherwise
(+ (countAll <???>) ; add the result of the recursion over the `car`
(countAll <???>))))) ; with the result of the recursion over the `cdr`
If you need more help understanding how to structure a solution to this kind of problems dealing with lists of lists, I'd recommend you take a look at either The Little Schemer or How to Design Programs, both books will teach you how to grok recursive processes in general.
if you want to count elements of nested list you can use the deep recursion function as some people answer here. or what I do is use racket function (flatten) to make the nested list flat then use recursion on level 1 list as in the following code
(define (howMany ls)
(if (null? ls)
0
(+ 1 (howMany (cdr ( flatten ls )))))) ; flat the nested list and deal with it as a level 1 list.
I have defined a list (in Racket/Scheme):
(define myList (cons 'data1 (cons 'data2 (cons 'data3 (cons 'data4 empty)))))
or
(list 'data1 'data2 'data3 'data4)
And I want to write a function that cycles through the list and outputs all values of the list.
(define (outputListData list)
(cond
[(null? list) list]
[else (getListData)]))
With what function can I cycle through the content of the list? I know one can use first & rest to get list data, but I guess that's not the right way here.
BTW: Is there a good, compact racket reference like php.net? I find the official Racket docs very confusing ...
You can use a for loop. Example:
(for ([x (list 1 2 3)])
(printf "~s -> ~s\n" x (* x x)))
There are more functional ways to do this, of course, but this way works too. You'll probably want to look at a textbook like How To Design Programs to do the recursive approach. See: http://www.ccs.neu.edu/home/matthias/HtDP2e/
dyoo's solution is nice and succinct in a Scheme like Racket that has useful iteration routines built in. Just FYI, though, your 'outputListData' is not far from being the standard recursive way to do this. You just need to change a couple of lines:
(define (outputListData list)
(cond
[(null? list) #f] ; actually doesn't really matter what we return
[else (printf "~s\n" (first list)) ; display the first item ...
(outputListData (rest list))])) ; and start over with the rest
Since this is an "imperative" kind of procedure that isn't designed to return a value, it doesn't really matter what we do with an empty list so long as we stop recurring (to avoid an infinite loop). If the list isn't empty, we output the first element and start over recursively with the rest of the list.
BTW, here's another way you could write something almost identical if you just needed a "for" loop in the middle of some other function:
(let loop ((l (list 'foo 'bar 'baz 'quux))) ; or put whatever input you need
(cond ((null? l) #f)
(else
(printf "~s\n" (first l))
(loop (rest l)))))
One way to think about this "named let" is that it defines a temporary function called loop, which works just like outputListData above. Scheme has the nice property that it won't grow the stack for "tail calls" like these, so you can always write what would be an "iterative" for or while loop in this recursive style.
I highly recommend The Little Schemer by Friedman and Felleisen for a quick intro to this style of function writing! I found it through Douglas Crockford's page here.
Edit as per comments: Use for-each
(for-each display myList)
Try this:
(void (map display myList))
Breaking it down:
(void x) causes x to be ignored instead of returned to the REPL/parent expression as a value.
(map function lst): For a list '(a1 a2 ... an) returns the list '((function a1) (function a2) ... (function an)).
So we use map to display all the items, but since we only care about the side-effect and not the return value, we call void on the returned list.
Official docs:
void
map
I think the solution that is the easiest to understand it to come up with a so called "list-eater" function. This is the way my university introduced recursion and lists in Racket. Also most books on Racket (i.e. "How To Design Programs" or "Realm Of Racket") explain it this way. This is the code:
(define my-list (list 'data1 'data2 'data3 'data4))
(define (print-list a-list-of-data)
(when (not (empty? a-list-of-data))
(print (first a-list-of-data))
(print-list (rest a-list-of-data))))
If you call the function with the example list my-list, you will get the following output:
(print-list my-list)
'data1'data2'data3'data4
The function does the following: As long as the given list is not empty, it grabs the first element of that list and passes it to the function print. Then, it tells itself to do the exact same thing with the rest of the list. (It calls itself on the rest of the list.) This second part is what they call recursion.
However, you can shorten that by using a function called map:
(define (print-list a-list-of-data)
(map print a-list-of-data))
This basically says that you want the function print to be called on each element of the given list. The output is exactly the same.
Hope it helped!
I'm currently playing a bit around with scheme, and I've been stuck for quite a while trying to figure out how to implement a test, that checks if any element in 'xs' is also stored in 'l'.
That is the mathematical function '\in', just for each element in the list xs.
Do you want to write it yourself for practice, or do you just need the functionality?
If you just want the functionality then use the answer by larsmans (I have never used that, but it looks good to me).
To implement try the following (disclaimer: I have not tested this)
(define has-intersect?
(lambda (xs l)
(cond
[(null? xs) #f]
[(member? (car xs) l) #t]
[else (has-intersect? (cdr xs) l)])))
In mathematical terms, you're checking whether the intersection of two lists/sets is non-empty. If you have an SRFI-1 library, this is trivial:
(not (null? (lset-intersection l xs)))
An implementation of SRFI-1 can be found in SLIB.
(Disclaimer: I'm a former SLIB contributor.)