I'm having a problem with the racket language. I want to find a goal state in a list. But in the moment that reaches the limit I gave as parameter I get -> function call: expected a function after the open parenthesis, but received empty. The problem is in expand2.
How do I write this in Racket?
(define (main start limit)
(let ([result (expand start limit)])
(write result)))
(define (expand state limit)
(cond ((goal state) (list state))
((< limit 0) '())
(else
(let ([children (next-states state)]) ;;next states return a list of the kind ((4 3) (2 3))
(let ((result (expand2 children (- limit 1))))
(and result (cons state result)))) ;;(append result (cons state result)))))
(define (expand2 states limit)
(if (null? states)
(list states)
((expand (car states) limit)
(expand2(cdr states) limit))))
(define (next-states state)
(remove-null
(list
(fill-first state) ;;if state is '(2 3) -> '(4 3)
(fill-second state) ;; and so on
(pour-first-second state)
(pour-second-first state)
(empty-first state)
(empty-second state))))
Thanks
EDIT: I´m trying to write the water jugs problem, where you need to have the first jug with 2 gallons and you have unmeasured jugs of 4 and 3 gallons of capacity. To start the program u use (main '(4 3) 7) for example. 7 is the limit depth of the tree
The expression in the alternate branch within expand2
((expand (car states) limit)
(expand2 (cdr states) limit))
means that you're trying to call the result of the recursive call to expand as a function, but as far as I can see expand never returns a function.
What is it that you actually want to do in this branch?
EDIT:
While I still don't fully understand how your current code is supposed to work, I think some instructions how to implement backtracking with recursion should help you:
The recursive call should be able to go onto all possible branches that follow from the current state. Each time a recursive call returns, check whether it has returned a valid final result - in which case you simply return again to the next higher level -, or if it's a special result that represents failure - in which case you make the next recursive call if there are still branches from the current state remaining, or also return the special result if you've exhausted the possible branches.
EDIT 2:
Here is some example code that should hopefully clarify the basic ideas I explained above about how to do backtracking with recursion. Interesting to note is that the Racket standard library function ormap can do a significant portion of our work for us:
(define (backtrace state)
(if (goal state)
(list state)
(let [[result (ormap backtrace (next-states state))]]
(and result (cons state result)))))
Searching
Searching nested structures [graph] with backtracking typically requires a queue or a stack or a similar structure to hold temporary state. In Lisps, stacks are easy because it is easy to push elements onto the front of a list with cons and to access the first element of a list with first or car and to take the "popped" list with rest or cdr. Using a list as a stack provides a depth first search.
Handling State
The standard way to handle state in a functional style is passing the state as an additional argument. A typical method is to define an inner function which takes the additional argument and then to call it with a trampoline.
Example Code
This is based on my understanding of the general goal of the question. The specific inputs and outputs can be adjusted depending on your needs:
#lang racket
(define (main start limit)
(define (success? item limit)
(equal? item limit))
(define (inner start limit stack)
;; list? any? list? -> any? or null?
;; Returns limit on match, null on no match
(cond
;; There's nothing left
[(and (empty? start)
(empty? stack))
null]
;; A list has been exhausted
;; So backtrack using the stack
;; As start state
[(empty? start)
(inner stack limit null)]
;; Otherwise look at the first item
[else
(let ((item (car start)))
;; Does the item match the limit?
;; **Remember the limit could be a list**
(cond
;; If it matches return the matching value
[(success? item limit) item]
;; Otherwise if the item is a list
;; Push the elements of item onto the stack
[(list? item)
(inner (rest start)
limit
(append item stack))]
;; The item isn't a list and it doesn't match.
[else (inner (rest start)
limit
stack)]))]))
;; Trampoline the inner function
(inner start limit null))
Sample Output
> (main '(1 2 3 (4 5) 6) '(4 5))
'(4 5)
> (main '(1 2 3 (4 5) 6) 6)
6
> (main '(1 2 3 (4 5) 6) 4)
4
> (main '(1 2 3 (4 5) 6) 8)
'()
If (expand (car states) limit) return empty, then
( (expand (car states) limit)
(expand2(cdr states) limit))
is the same as (empty ...) and you will get the error function call: expected a function after the open parenthesis, but received empty
Racket has this very nice IDE called DrRacket. It will ident the code you're writing according to the code structure. Pressing CTRL+i will "fix" identation for you when you edit code so press it often. Inidented code in LISPy languages are unreadable!
From your original formatting it was not clear to see that the definition of expand2 was inside expand at a illegal place (local definitions goes on the top), but with proper indentation you see it's there.
There are lots of strange things in you code. One is the missing parentheses that makes this program invalid from the start.
Another is the fact you have two applications that themselves are surrounded by parenthesis:
((expand (car states) limit) (expand2 (cdr states) limit))
If you compare that to eg.
(- 10)
You see that (expand (car states) limit) needs to become a procedure, just like the variable - becomes a procedure. Here you either have forgot an operand. eg. (cons expr-1 expr-b) or if there are side effects perhaps you wanted a (begin expr-1 expr-2).
DrRacket has a pretty decent debugger once your application is without syntax errors. You can step through your code and find your other bugs as well. Give it a try!
Related
I'm learning LISP and I am trying to write a function that adds 1 to each element inside my list. I first test for if the first element is a number or not then add 1 to the first element in the list. I then recursively call the function on the rest of the list but I get an error. Any help? Here's the function:
(defun add-1-all (L)
(cond (not (numberp (first L)) nil)
(t (+1 (first L)) (add-1-all (rest L)))))
Here are more approaches:
When dealing with lists (see Joshua's comment), use ENDP, FIRST and REST, which are preferred over NULL, CAR and CDR. They convey the intent more clearly and in the case of ENDP, check that the argument is a proper-list. Imagine you pass a dotted-list built with (cons 'a 'b), what should happen? ENDP detects that the list is not proper and signals an error.
(defun add-1-all (list)
(unless (endp list)
(cons (1+ (first list))
(add-1-all (rest list)))))
I used UNLESS for its NIL value, which some people might not like. You may want to explicitely return NIL when reaching the end of your list. In that case, stick with COND or just use IF.
Loop.
(defun add-1-all (list)
(loop for e in list collect (1+ e)))
Make it work on arrays too, not just lists.
(defun add-1-all (sequence)
(map (type-of sequence) #'1+ sequence))
The easiest way to accomplish your goal would be to use map. Map applies a function to each element of a sequence. That way one does not have to take care of details like iterating through the sequence. In the code below I use mapcar which works only on lists.
(defun add-1 (list)
(mapcar #'1+ list))
To find out about other mapping functions that CL provides run (apropos "map") and use (describe ) to find out more. Or better yet use the clhs search engine or the extended CL documentation search engine
The solution you provided is attempting to solve the problem through recursion. The general idea is to traverse the list using first/rest while building a new one with the elements incremented by one. When the list reaches the end (You can use the functions null or endp to test that the end of the list has been reached) the new list should be returned. One of the problems with your solution is that it lacks an accumulator. Also your base-case (the condition that signals to stop the recursion) is wrong.
A couple of other pointers. Use an editor that formats your code as it is difficult to read. Also CL is not a Lisp-1 so you can use list as a variable name and it won't collide with the function list. They have separate namespaces. It is also helpful to post the error message and the explain what/how your solution is trying to do. You may also find this textbook useful for learning Lisp
You could write (+ 1 (first L)) or (1+ (first L)) but you didn't write that.
Also, you should use cons to tack the result on the first element to the result of the rest of them.
Also, did you really want to drop off all the elements after the first non-number? Or did you want to assume all elements were numbers, in which case you should learn about map or mapcar, which allows you to solve the problem in 15 characters.
First of all your code is wrong if you compile it you get several errors and warnings, is important a good lisp syntax and also knowing what you are writing. If you are learning lisp I reccomend you to get a confortable environment for that like slime and quicklisp
; SLIME 2015-06-01; compiling (DEFUN ADD-1-ALL ...)
; file: /tmp/file451NPJ
; in: DEFUN ADD-1-ALL
; (1 (FIRST L))
;
; caught ERROR:
; illegal function call
; (REST L)
; --> CDR
; ==>
; L
;
; note: deleting unreachable code
; (COND (NOT (NUMBERP (FIRST L)) NIL) (T (1 (FIRST L)) (ADD-1-ALL (REST L))))
; ==>
; (IF NOT
; (PROGN (NUMBERP (FIRST L)) NIL)
; (COND (T (1 (FIRST L)) (ADD-1-ALL (REST L)))))
;
; caught WARNING:
; undefined variable: NOT
;
; compilation unit finished
; Undefined variable:
; NOT
; caught 1 ERROR condition
; caught 1 WARNING condition
; printed 1 note
Then it is a good idea to use recursion for doing this task, for recursions is important to know when to stop and the base case of your algorithm
In you case you can also use if for this two path the function will be this:
(defun add-1-all (list)
(cond
((null list) nil)
(t (cons (1+ (car list))(add-1-all (cdr list))))))
I recommend you to try doing this using a tail recursive function for better perfomance and a great learning.
Also with lisp you can use more functional style, when time comes you will learn this, like using higher order functions in this case your function is as follows:
;; functional programming higher order functions
(defun add-1-all-ho (list)
(mapcar #'1+ list))
I want to know if these two definitions of nth are equal:
I. is defined as macro:
(defmacro -nth (n lst)
(defun f (n1 lst1)
(cond ((eql n1 0) lst1)
(t `(cdr ,(f (- n1 1) lst1)))))
`(car ,(f n lst)))
II. is defined as a bunch of functions:
(defun f (n lst)
(cond ((eql n 0) lst)
(t `(cdr ,(f (- n 1) lst)))))
(defun f1 (n lst)
`(car ,(f n `',lst)))
(defun --nth (n lst)
(eval (f1 n lst)))
Am i get the right idea? Is macro definition is evaluating of expression, constructed in its body?
OK, let start from the beginning.
Macro is used to create new forms that usually depend on macro's input. Before code is complied or evaluated, macro has to be expanded. Expansion of a macro is a process that takes place before evaluation of form where it is used. Result of such expansion is usually a lisp form.
So inside a macro here are a several levels of code.
Not quoted code will be evaluated during macroexpansion (not at run-time!), in your example you define function f when macro is expanded (for what?);
Next here is quoted (with usual quote or backquote or even nested backquotes) code that will become part of macroexpansion result (in its literal form); you can control what part of code will be evaluated during macroexpansion and what will stay intact (quoted, partially or completely). This allows one to construct anything before it will be executed.
Another feature of macro is that it does not evaluate its parameters before expansion, while function does. To give you picture of what is a macro, see this (just first thing that came to mind):
(defmacro aif (test then &optional else)
`(let ((it ,test))
(if it ,then ,else)))
You can use it like this:
CL-USER> (defparameter *x* '((a . 1) (b . 2) (c . 3) (d . 4)))
*X*
CL-USER> (aif (find 'c *x* :key #'car) (1+ (cdr it)) 0)
4
This macro creates useful lexical binding, capturing variable it. After checking of a condition, you don't have to recalculate result, it's accessible in forms 'then' and 'else'. It's impossible to do with just a function, it has introduced new control construction in language. But macro is not just about creating lexical environments.
Macro is a powerful tool. It's impossible to fully describe what you can do with it, because you can do everything. But nth is not something you need a macro for. To construct a clone of nth you can try to write a recursive function.
It's important to note that LISP macro is most powerful thing in the programming world and LISP is the only language that has this power ;-)
To inspire you, I would recommend this article: http://www.paulgraham.com/avg.html
To master macro, begin with something like this:
http://www.gigamonkeys.com/book/macros-defining-your-own.html
Then may be Paul Graham's "On Lisp", then "Let Over Lambda".
There is no need for either a macro nor eval to make abstractions to get the nth element of a list. Your macro -nth doesn't even work unless the index is literal number. try this:
(defparameter test-list '(9 8 7 6 5 4 3 2 1 0))
(defparameter index 3)
(nth index test-list) ; ==> 6 (this is the LISP provided nth)
(-nth index test-list) ; ==> ERROR: index is not a number
A typical recursive solution of nth:
(defun nth2 (index list)
(if (<= index 0)
(car list)
(nth2 (1- index) (cdr list))))
(nth2 index test-list) ; ==> 6
A typical loop version
(defun nth3 (index list)
(loop :for e :in list
:for i :from index :downto 0
:when (= i 0) :return e))
(nth3 index test-list) ; ==> 6
Usually a macro is something you use when you see your are repeating yourself too much and there is no way to abstract your code further with functions. You may make a macro that saves you the time to write boilerplate code. Of course there is a trade off of not being standard code so you usually write the macro after a couple of times have written the boilerplate.
eval should never be used unless you really have to. Usually you can get by with funcall and apply. eval works only in the global scope so you loose closure variables.
For the life of me, I can't understand continuations. I think the problem stems from the fact that I don't understand is what they are for. All the examples that I've found in books or online are very trivial. They make me wonder, why anyone would even want continuations?
Here's a typical impractical example, from TSPL, which I believe is quite recognized book on the subject. In english, they describe the continuation as "what to do" with the result of a computation. OK, that's sort of understandable.
Then, the second example given:
(call/cc
(lambda (k)
(* 5 (k 4)))) => 4
How does this make any sense?? k isn't even defined! How can this code be evaluated, when (k 4) can't even be computed? Not to mention, how does call/cc know to rip out the argument 4 to the inner most expression and return it? What happens to (* 5 .. ?? If this outermost expression is discarded, why even write it?
Then, a "less" trivial example stated is how to use call/cc to provide a nonlocal exit from a recursion. That sounds like flow control directive, ie like break/return in an imperative language, and not a computation.
And what is the purpose of going through these motions? If somebody needs the result of computation, why not just store it and recall later, as needed.
Forget about call/cc for a moment. Every expression/statement, in any programming language, has a continuation - which is, what you do with the result. In C, for example,
x = (1 + (2 * 3));
printf ("Done");
has the continuation of the math assignment being printf(...); the continuation of (2 * 3) is 'add 1; assign to x; printf(...)'. Conceptually the continuation is there whether or not you have access to it. Think for a moment what information you need for the continuation - the information is 1) the heap memory state (in general), 2) the stack, 3) any registers and 4) the program counter.
So continuations exist but usually they are only implicit and can't be accessed.
In Scheme, and a few other languages, you have access to the continuation. Essentially, behind your back, the compiler+runtime bundles up all the information needed for a continuation, stores it (generally in the heap) and gives you a handle to it. The handle you get is the function 'k' - if you call that function you will continue exactly after the call/cc point. Importantly, you can call that function multiple times and you will always continue after the call/cc point.
Let's look at some examples:
> (+ 2 (call/cc (lambda (cont) 3)))
5
In the above, the result of call/cc is the result of the lambda which is 3. The continuation wasn't invoked.
Now let's invoke the continuation:
> (+ 2 (call/cc (lambda (cont) (cont 10) 3)))
12
By invoking the continuation we skip anything after the invocation and continue right at the call/cc point. With (cont 10) the continuation returns 10 which is added to 2 for 12.
Now let's save the continuation.
> (define add-2 #f)
> (+ 2 (call/cc (lambda (cont) (set! add-2 cont) 3)))
5
> (add-2 10)
12
> (add-2 100)
102
By saving the continuation we can use it as we please to 'jump back to' whatever computation followed the call/cc point.
Often continuations are used for a non-local exit. Think of a function that is going to return a list unless there is some problem at which point '() will be returned.
(define (hairy-list-function list)
(call/cc
(lambda (cont)
;; process the list ...
(when (a-problem-arises? ...)
(cont '()))
;; continue processing the list ...
value-to-return)))
Here is text from my class notes: http://tmp.barzilay.org/cont.txt. It is based on a number of sources, and is much extended. It has motivations, basic explanations, more advanced explanations for how it's done, and a good number of examples that go from simple to advanced, and even some quick discussion of delimited continuations.
(I tried to play with putting the whole text here, but as I expected, 120k of text is not something that makes SO happy.
TL;DR: continuations are just captured GOTOs, with values, more or less.
The exampe you ask about,
(call/cc
(lambda (k)
;;;;;;;;;;;;;;;;
(* 5 (k 4)) ;; body of code
;;;;;;;;;;;;;;;;
)) => 4
can be approximately translated into e.g. Common Lisp, as
(prog (k retval)
(setq k (lambda (x) ;; capture the current continuation:
(setq retval x) ;; set! the return value
(go EXIT))) ;; and jump to exit point
(setq retval ;; get the value of the last expression,
(progn ;; as usual, in the
;;;;;;;;;;;;;;;;
(* 5 (funcall k 4)) ;; body of code
;;;;;;;;;;;;;;;;
))
EXIT ;; the goto label
(return retval))
This is just an illustration; in Common Lisp we can't jump back into the PROG tagbody after we've exited it the first time. But in Scheme, with real continuations, we can. If we set some global variable inside the body of function called by call/cc, say (setq qq k), in Scheme we can call it at any later time, from anywhere, re-entering into the same context (e.g. (qq 42)).
The point is, the body of call/cc form may contain an if or a condexpression. It can call the continuation only in some cases, and in others return normally, evaluating all expressions in the body of code and returning the last one's value, as usual. There can be deep recursion going on there. By calling the captured continuation an immediate exit is achieved.
So we see here that k is defined. It is defined by the call/cc call. When (call/cc g) is called, it calls its argument with the current continuation: (g the-current-continuation). the current-continuation is an "escape procedure" pointing at the return point of the call/cc form. To call it means to supply a value as if it were returned by the call/cc form itself.
So the above results in
((lambda(k) (* 5 (k 4))) the-current-continuation) ==>
(* 5 (the-current-continuation 4)) ==>
; to call the-current-continuation means to return the value from
; the call/cc form, so, jump to the return point, and return the value:
4
I won't try to explain all the places where continuations can be useful, but I hope that I can give brief examples of main place where I have found continuations useful in my own experience. Rather than speaking about Scheme's call/cc, I'd focus attention on continuation passing style. In some programming languages, variables can be dynamically scoped, and in languages without dynamically scoped, boilerplate with global variables (assuming that there are no issues of multi-threaded code, etc.) can be used. For instance, suppose there is a list of currently active logging streams, *logging-streams*, and that we want to call function in a dynamic environment where *logging-streams* is augmented with logging-stream-x. In Common Lisp we can do
(let ((*logging-streams* (cons logging-stream-x *logging-streams*)))
(function))
If we don't have dynamically scoped variables, as in Scheme, we can still do
(let ((old-streams *logging-streams*))
(set! *logging-streams* (cons logging-stream-x *logging-streams*)
(let ((result (function)))
(set! *logging-streams* old-streams)
result))
Now lets assume that we're actually given a cons-tree whose non-nil leaves are logging-streams, all of which should be in *logging-streams* when function is called. We've got two options:
We can flatten the tree, collect all the logging streams, extend *logging-streams*, and then call function.
We can, using continuation passing style, traverse the tree, gradually extending *logging-streams*, finally calling function when there is no more tree to traverse.
Option 2 looks something like
(defparameter *logging-streams* '())
(defun extend-streams (stream-tree continuation)
(cond
;; a null leaf
((null stream-tree)
(funcall continuation))
;; a non-null leaf
((atom stream-tree)
(let ((*logging-streams* (cons stream-tree *logging-streams*)))
(funcall continuation)))
;; a cons cell
(t
(extend-streams (car stream-tree)
#'(lambda ()
(extend-streams (cdr stream-tree)
continuation))))))
With this definition, we have
CL-USER> (extend-streams
'((a b) (c (d e)))
#'(lambda ()
(print *logging-streams*)))
=> (E D C B A)
Now, was there anything useful about this? In this case, probably not. Some minor benefits might be that extend-streams is tail-recursive, so we don't have a lot of stack usage, though the intermediate closures make up for it in heap space. We do have the fact that the eventual continuation is executed in the dynamic scope of any intermediate stuff that extend-streams set up. In this case, that's not all that important, but in other cases it can be.
Being able to abstract away some of the control flow, and to have non-local exits, or to be able to pick up a computation somewhere from a while back, can be very handy. This can be useful in backtracking search, for instance. Here's a continuation passing style propositional calculus solver for formulas where a formula is a symbol (a propositional literal), or a list of the form (not formula), (and left right), or (or left right).
(defun fail ()
'(() () fail))
(defun satisfy (formula
&optional
(positives '())
(negatives '())
(succeed #'(lambda (ps ns retry) `(,ps ,ns ,retry)))
(retry 'fail))
;; succeed is a function of three arguments: a list of positive literals,
;; a list of negative literals. retry is a function of zero
;; arguments, and is used to `try again` from the last place that a
;; choice was made.
(if (symbolp formula)
(if (member formula negatives)
(funcall retry)
(funcall succeed (adjoin formula positives) negatives retry))
(destructuring-bind (op left &optional right) formula
(case op
((not)
(satisfy left negatives positives
#'(lambda (negatives positives retry)
(funcall succeed positives negatives retry))
retry))
((and)
(satisfy left positives negatives
#'(lambda (positives negatives retry)
(satisfy right positives negatives succeed retry))
retry))
((or)
(satisfy left positives negatives
succeed
#'(lambda ()
(satisfy right positives negatives
succeed retry))))))))
If a satisfying assignment is found, then succeed is called with three arguments: the list of positive literals, the list of negative literals, and function that can retry the search (i.e., attempt to find another solution). For instance:
CL-USER> (satisfy '(and p (not p)))
(NIL NIL FAIL)
CL-USER> (satisfy '(or p q))
((P) NIL #<CLOSURE (LAMBDA #) {1002B99469}>)
CL-USER> (satisfy '(and (or p q) (and (not p) r)))
((R Q) (P) FAIL)
The second case is interesting, in that the third result is not FAIL, but some callable function that will try to find another solution. In this case, we can see that (or p q) is satisfiable by making either p or q true:
CL-USER> (destructuring-bind (ps ns retry) (satisfy '(or p q))
(declare (ignore ps ns))
(funcall retry))
((Q) NIL FAIL)
That would have been very difficult to do if we weren't using a continuation passing style where we can save the alternative flow and come back to it later. Using this, we can do some clever things, like collect all the satisfying assignments:
(defun satisfy-all (formula &aux (assignments '()) retry)
(setf retry #'(lambda ()
(satisfy formula '() '()
#'(lambda (ps ns new-retry)
(push (list ps ns) assignments)
(setf retry new-retry))
'fail)))
(loop while (not (eq retry 'fail))
do (funcall retry)
finally (return assignments)))
CL-USER> (satisfy-all '(or p (or (and q (not r)) (or r s))))
(((S) NIL) ; make S true
((R) NIL) ; make R true
((Q) (R)) ; make Q true and R false
((P) NIL)) ; make P true
We could change the loop a bit and get just n assignments, up to some n, or variations on that theme. Often times continuation passing style is not needed, or can make code hard to maintain and understand, but in the cases where it is useful, it can make some otherwise very difficult things fairly easy.
Let us say I have a list ((3 4 5) (d e f) (h i j) (5 5 5 5))
How can I get the last element of each list in such a way that the output would look like this (5 f j 5)?
Assuming this is about Common Lisp, there is a function last which returns a list containing the last item of a list. If you use this function with mapcan, which applies a given function to each element of a list and returns the concatenated results, you'll get what you want.
Note though that accessing the last element of a list is an O(N) operation, so if this isn't just homework after all, you might want to consider if you can't solve the real problem more efficiently than taking the last item of each list (maybe use another datastructure instead).
This, like most early LISPy homework problems is an exercise in thinking recursively and/or thinking in terms of induction. The way to start is to ask yourself simple questions that you can answer easily.
For example, if you had been asked to write something that gave you the first element in each list, I would thing about it this way:
Given a list of lists:
What is first-element of every list in the list '()? (easy - null)
What is first-element of every list in the list '(a)? (easy - a, or maybe an error)
What is first-element of every list in the list '((a))? (easy - (a))
What is first-element of any list in the form '(anything), where anything is a list? (easy - (first anything))
What is the first element of every list in the form '(anything morestuff)? (easy - (cons (first anything) (first-element morestuff)) )
What is first of an atom? either the atom or an error (depends on your point of view)
What is first of null? nil.
What is first of a list? (car list)
From here we can start writing code:
;; here's first, meeting questions 6-8
(define first (lambda (l)
(cond
((null? l) nil) ; Q7
((atom? l) l) ; Q6
(t (car l))))) ; Q8
;; with first we can write first-element, meeting questions 1-5
(define first-element (lambda (l)
(cond
((null? l) nil) ; Q1
((atom? l) (first l)) ; Q2
(t (cons (first (car l) (first-element (cdr l)))))))) ; Q4-5
Now this isn't your homework (intentionally). You should play with this and understand how it works. Your next goal should be to find out how this differs from your assignment and how to get there.
With respect to MAPCAR? Don't worry about it. You need to learn how to solve recursive problems first. Then you can worry about MAPCAR. What is the point of this assignment? To help you learn to think in this mode. Dang near everything in LISP/Scheme is solved by thinking this way.
The reason I went with all the questions to break it down into the parts that I'm worried about. If I'm given the task "how do I do foo on every item in a list?" I should answer the questions: How do I do handle null? How do handle an atom? How do I do handle on the first element on the list? How do I handle everything else? Once I've answered that, then I figure out how to actually do foo. How do I do foo on null? How do I do foo on an atom? How do I do foo on a list?
(defun get-last-lists (s)
(setq rt 'nil)
(loop for i from 0 to (- (length s) 1)
do (setq rt (append rt (last (nth i s)))))
(print rt))
as a beginner of lisp, i post my solution.
Write a procedure that returns the last element of a list, then learn a little about the built-in MAP (a.k.a. MAPCAR) procedure and see if any lightbulbs go off.
probably it is already solved, but I figured this out
; SELECT-FROM-INNER-LIST :: [list] -> [list]
(DEFUN SFIL (lst)
(COND ((NULL lst) NIL)
((LISTP (FIRST lst)) (APPEND (LAST (FIRST lst)) (SFIL (REST lst))))
))
Now, this works for legit list...so if you call function SFIL with correct list.... if not, it will return NIL
hopefully this will be helpful, for anyone who finds it
Right now I have
(define (push x a-list)
(set! a-list (cons a-list x)))
(define (pop a-list)
(let ((result (first a-list)))
(set! a-list (rest a-list))
result))
But I get this result:
Welcome to DrScheme, version 4.2 [3m].
Language: Module; memory limit: 256 megabytes.
> (define my-list (list 1 2 3))
> (push 4 my-list)
> my-list
(1 2 3)
> (pop my-list)
1
> my-list
(1 2 3)
What am I doing wrong? Is there a better way to write push so that the element is added at the end and pop so that the element gets deleted from the first?
This is a point about using mutation in your code: there is no need to jump to macros for that. I'll assume the stack operations for now: to get a simple value that you can pass around and mutate, all you need is a wrapper around the list and the rest of your code stays the same (well, with the minor change that makes it do stack operations properly). In PLT Scheme this is exactly what boxes are for:
(define (push x a-list)
(set-box! a-list (cons x (unbox a-list))))
(define (pop a-list)
(let ((result (first (unbox a-list))))
(set-box! a-list (rest (unbox a-list)))
result))
Note also that you can use begin0 instead of the let:
(define (pop a-list)
(begin0 (first (unbox a-list))
(set-box! a-list (rest (unbox a-list)))))
As for turning it into a queue, you can use one of the above methods, but except for the last version that Jonas wrote, the solutions are very inefficient. For example, if you do what Sev suggests:
(set-box! queue (append (unbox queue) (list x)))
then this copies the whole queue -- which means that a loop that adds items to your queue will copy it all on each addition, generating a lot of garbage for the GC (think about appending a character to the end of a string in a loop). The "unknown (google)" solution modifies the list and adds a pointer at its end, so it avoids generating garbage to collect, but it's still inefficient.
The solution that Jonas wrote is the common way to do this -- keeping a pointer to the end of the list. However, if you want to do it in PLT Scheme, you will need to use mutable pairs: mcons, mcar, mcdr, set-mcar!, set-mcdr!. The usual pairs in PLT are immutable since version 4.0 came out.
You are just setting what is bound to the lexical variable a-list. This variable doesn't exist anymore after the function exits.
cons makes a new cons cell. A cons cell consists of two parts, which are called car and cdr. A list is a series of cons cells where each car holds some value, and each cdr points to the respective next cell, the last cdr pointing to nil. When you write (cons a-list x), this creates a new cons cell with a reference to a-list in the car, and x in the cdr, which is most likely not what you want.
push and pop are normally understood as symmetric operations. When you push something onto a list (functioning as a stack), then you expect to get it back when you pop this list directly afterwards. Since a list is always referenced to at its beginning, you want to push there, by doing (cons x a-list).
IANAS (I am not a Schemer), but I think that the easiest way to get what you want is to make push a macro (using define-syntax) that expands to (set! <lst> (cons <obj> <lst>)). Otherwise, you need to pass a reference to your list to the push function. Similar holds for pop. Passing a reference can be done by wrapping into another list.
Svante is correct, using macros is the idiomatic method.
Here is a method with no macros, but on the down side you can not use normal lists as queues.
Works with R5RS at least, should work in R6RS after importing correct libraries.
(define (push x queue)
(let loop ((l (car queue)))
(if (null? (cdr l))
(set-cdr! l (list x))
(loop (cdr l)))))
(define (pop queue)
(let ((tmp (car (car queue))))
(set-car! queue (cdr (car queue)))
tmp))
(define make-queue (lambda args (list args)))
(define q (make-queue 1 2 3))
(push 4 q)
q
; ((1 2 3 4))
(pop a)
; ((2 3 4))
q
I suppose you are trying to implement a queue. This can be done in several ways, but if you want both the insert and the remove operation to be performed in constant time, O(1), you must keep a reference to the front and the back of the queue.
You can keep these references in a cons cell or as in my example, wrapped in a closure.
The terminology push and pop are usually used when dealing with stacks, so I have changed these to enqueue and dequeue in the code below.
(define (make-queue)
(let ((front '())
(back '()))
(lambda (msg . obj)
(cond ((eq? msg 'empty?) (null? front))
((eq? msg 'enqueue!)
(if (null? front)
(begin
(set! front obj)
(set! back obj))
(begin
(set-cdr! back obj)
(set! back obj))))
((eq? msg 'dequeue!)
(begin
(let ((val (car front)))
(set! front (cdr front))
val)))
((eq? msg 'queue->list) front)))))
make-queue returns a procedure which wraps the state of the queue in the variables front and back. This procedure accepts different messages which will perform the procedures of the queue data structure.
This procedure can be used like this:
> (define q (make-queue))
> (q 'empty?)
#t
> (q 'enqueue! 4)
> (q 'empty?)
#f
> (q 'enqueue! 9)
> (q 'queue->list)
(4 9)
> (q 'dequeue!)
4
> (q 'queue->list)
(9)
This is almost object oriented programming in Scheme! You can think of front and back as private members of a queue class and the messages as methods.
The calling conventions is a bit backward but it is easy to wrap the queue in a nicer API:
(define (enqueue! queue x)
(queue 'enqueue! x))
(define (dequeue! queue)
(queue 'dequeue!))
(define (empty-queue? queue)
(queue 'empty?))
(define (queue->list queue)
(queue 'queue->list))
Edit:
As Eli points out, pairs are immutable by default in PLT Scheme, which means that there is no set-car! and set-cdr!. For the code to work in PLT Scheme you must use mutable pairs instead. In standard scheme (R4RS, R5RS or R6RS) the code should work unmodified.
What you're doing there is modifying the "queue" locally only, and so the result is not available outside of the definition's scope. This is resulted because, in scheme, everything is passed by value, not by reference. And Scheme structures are immutable.
(define queue '()) ;; globally set
(define (push item)
(set! queue (append queue (list item))))
(define (pop)
(if (null? queue)
'()
(let ((pop (car queue)))
(set! queue (cdr queue))
pop)))
;; some testing
(push 1)
queue
(push 2)
queue
(push 3)
queue
(pop)
queue
(pop)
queue
(pop)
The problem relies on the matter that, in Scheme, data and manipulation of it follows the no side-effect rule
So for a true queue, we would want the mutability, which we don't have. So we must try and circumvent it.
Since everything is passed by value in scheme, as opposed to by reference, things remain local and remain unchanged, no side-effects. Therefore, I chose to create a global queue, which is a way to circumvent this, by applying our changes to the structure globally, rather than pass anything in.
In any case, if you just need 1 queue, this method will work fine, although it's memory intensive, as you're creating a new object each time you modify the structure.
For better results, we can use a macro to automate the creation of the queue's.
The push and pop macros, which operate on lists, are found in many Lispy languages: Emacs Lisp, Gauche Scheme, Common Lisp, Chicken Scheme (in the miscmacros egg), Arc, etc.
Welcome to Racket v6.1.1.
> (define-syntax pop!
(syntax-rules ()
[(pop! xs)
(begin0 (car xs) (set! xs (cdr xs)))]))
> (define-syntax push!
(syntax-rules ()
[(push! item xs)
(set! xs (cons item xs))]))
> (define xs '(3 4 5 6))
> (define ys xs)
> (pop! xs)
3
> (pop! xs)
4
> (push! 9000 xs)
> xs
'(9000 5 6)
> ys ;; Note that this is unchanged.
'(3 4 5 6)
Note that this works even though lists are immutable in Racket. An item is "popped" from the list simply by adjusting a pointer.