I notice that almost all scheme functions can only return one list as output.
In the following, I would like to return multiple values of all the adjacent nodes of neighbors.
(define (neighbors l w)
(if (and (= 1 l) (= 1 w))
(list (and (l (+ 1 w))) (and (+ 1 l) w)))) ; how to output 2 or more values?
In this case I'm first testing if the node is at corner, if so, return 2 values of the coordinates where (l and w+1), (l+1 and w) basically if I'm at (1,1) return me (1,2) and (2,1)
Same applies when the node has only 1 neighbor near the edge, in this case I will have 3 values.
When no edge is nearby I will have 4 return values.
I tried to use cons, append, list, display, write none of them seems working with additional values. I need this as a sub-function of this question. How should I implement it so I could pass on the return value and use it recursively to return me all the adjacent nodes?
Edit: I found the answer: use the keyword "values" to return multiple values. Example:
(define (store l w)
(values (write l)
(write w)
(newline)
(list (+ 1 w) l)
(list w (+ 1 l))))
values, continuation passing style, and list are at least three ways of returning multiple values:
(import (rnrs))
; let-values + values
(define (foo1)
(values 1 2 3))
(let-values (((a b c) (foo1)))
(display (list a b c))
(newline))
; cps
(define (foo2 k)
(k 1 2 3))
(foo2 (lambda (a b c)
(display (list a b c))
(newline)))
; list
(define (foo3)
(list 1 2 3))
(let ((result (foo3)))
(display result)
(newline))
The Guile implementation of Scheme has a receive syntax, which it says is "much more convenient" than values. I haven't used it yet, however, but this may be useful:
http://www.gnu.org/software/guile/manual/html_node/Multiple-Values.html
You can return a pair of values in a cons cell:
(define (foo)
(cons 'a 5))
(let* ((r (foo))
(x (car r))
(y (cdr r)))
(display x) (display y) (newline))
You can generalise this to return multiple values in a list, too.
Related
I want to generate in Lisp the list of all permutations of a set. This is what I tried:
(defun ins(e n l)
(cond
((equal n 1) (cons e l))
(T (cons (car l) (ins e (1- n) (cdr l))))
)
)
;; (print (ins '1 1 '(2 3)))
;; (print (ins '1 2 '(2 3)))
;; (print (ins '1 3 '(2 3)))
(defun insert(e n l)
(cond
((equal n 0) nil)
(T (cons (ins e n l) (insert e (1- n) l) ))
)
)
;; (print (insert '1 3 '(2 3)))
(defun inserare(e l)
(insert e (1+ (length l)) l)
)
;(print (inserare '1 '(2 3))) -> ((2 3 1) (2 1 3) (1 2 3))
And from here I just can't make the final permutations function. I tried something like this:
(defun perm(L)
(cond
((null L) nil)
(T (append (perm (cdr L)) (inserare (car L) L)))
)
)
But this is not the good approach
Here is one way.
First of all, if you have a list like (x . y) and you have the permutations of y you will need to create from them the permutations of (x . y). Well consider one of these permutations p, and let this be (p1 p2 ...). From this you will need to make a bunch of permutations including x: (x p1 p2 ...), (p1 x p2 ...), (p1 p2 x ...) ... (p1 p2 ... x).
So let's write a function to do this: a function which given some object and a list will 'thread' the object through the list creating a bunch of new lists with the object inserted at every point. For reasons that will become clear this function is going to take an extra argument which is the list of things to attach the new permutations to the front of. It's also going to use a little local function to do the real work.
Here it is:
(defun thread-element-through-list (e l onto)
(labels ((tetl-loop (erofeb after into)
(if (null after)
(cons (nreverse (cons e erofeb)) into)
(tetl-loop (cons (first after) erofeb)
(rest after)
(cons (revappend (cons e erofeb) after) into)))))
(tetl-loop '() l onto)))
I'm not going to explain the details of this function, but there are a couple of things worth knowing:
tetl-loop is thread-element-through-list-loop;
erofeb is before backwards, because the elements are in reverse order on it;
the nreverse is just a gratuitous hack because at that point erofeb is otherwise dead – there is effectively no mutation in this function.
And we can test it:
> (thread-element-through-list 1 '(2 3) '())
((2 3 1) (2 1 3) (1 2 3))
Now, OK, what we actually have is not just one permutation of y, we have a list of them. And we need to thread x through each of them, using `thread-element-through-list. So we need a function to do that.
(defun thread-element-through-lists (e ls onto)
(if (null ls)
onto
(thread-element-through-lists
e (rest ls)
(thread-element-through-list e (first ls) onto))))
This also has an argument which defines what it's adding its results to, and you can see how this onto list now gets passed around to build the list.
And we can test this
> (thread-element-through-lists '1 '((2 3) (3 2)) '())
((3 2 1) (3 1 2) (1 3 2) (2 3 1) (2 1 3) (1 2 3))
Look at that carefully. I gave thread-element-through-lists, 1, and a list which was the permutations of (2 3), and it has turned out for me the permutations of (1 2 3). So what you now need to do (which I am not going to do for you) is to write a function which:
knows the permutations of () (which is () and of a single-element list (which is a list containing that list)`;
uses thread-elements-through-lists together with a recursive call to itself to compute the permutations of any longer list.
I am trying to return from
'('(animal '(name a b c) '(age 1 2 3) '(family x y z)) only '(name age family). How do I do that? I was trying this:
(car(apply append(cons (cadr (car list)) '())))
but I get an error.
I am not sure the list you want to handle is:
'('(animal '(name a b c) '(age 1 2 3) '(family x y z)) or
'(animal (name a b c) (age 1 2 3) (family x y z))
The latter one makes more sense to me. Your (sub) problem is to return a list containing all first elements of sublists. You may need to use recursion. Something like:
(define get_list_of_first
(lambda (lol)
(if (null? lol) '()
(cons (car (car lol)) (get_list_of_first (cdr lol)))
)
)
)
This is a very basic example to learn Scheme. You need to use the above function to continue your assignment (I guess). Have fun.
I am trying to replace the elements in a scheme list with its position.
For example, calling:
(position '((a b) c))
should return:
'((0 1) 2)
So far, my code keeps the list format, but the index is not updating.
(define (position term1)
(define index 0)
(cond [(null? term1) '()]
[(list? term1) (cons (position (car term1)) (position(cdr term1)))]
[else (+ 1 index) index]))
When (position '((a b) c)) is called, it returns
'((0 0) 0)
Can anybody explain why the index isn't updating?
There are a couple things wrong: first notice that every time you recursively call position, index is bound to zero.
Second, look at your else branch. (+ 1 index) evaluates to 1 (it does not change any variables) and index evaluates to 0. This branch can only evaluate to one thing, so what happens is the last one is returned and the rest are discarded. This is where your zeroes come from.
It seems like within your function you are trying to keep a global state (the current index) and modify it each time you label a leaf. The "modifying state" part is not good functional style, but if you are okay with that then take a look at set!.
Here is one solution using CPS:
#lang racket
(define (index xs [i 0] [continue (λ (xs i) xs)])
(match xs
[(cons x xs) (index x i
(λ (js j)
(index xs j
(λ (ks k)
(continue (cons js ks) k)))))]
['() (continue '() i)]
[x (continue i (+ i 1))]))
; Example
;(index '((a b) (c d) x (e (f g) h)))
; '((0 1) (2 3) 4 (5 (6 7) 8))
Here (index xs i continue) replaces the elements in xs with their indices, the count starts from i. Let's say the result of indexing xs is js, then continue is called with the indexing result and the next index to be used: (continue js j).
Daenerys Naharis already pointed out what's wrong, so let me point out some features of Scheme and Racket you may be unaware of that you could use in a solution that maintains functional style.
This is called a named let:
(let loop ((index 0)
(result '()))
(if (= index 10)
(reverse result)
(loop (+ 1 index) (cons index result)))
Within the let form, loop is bound as a function that takes all the local variables as arguments. Calling it recursively calls the let form itself. This way you can make index an argument without making it an argument of position. You can also put the result in an argument, which allows you to make the call to loop a tail call.
The other feature is less widespread among existing Scheme implementations: Optional arguments. In Racket, they're defined like this:
(define (position term1 (index 0)) ...)
Then position can be called with or without the index argument.
An example using mutation that maintains it's own state so that each item of each list has a unique id.
Example Usage:
> (position '((a b) c))
'((0 1) 2)
> (position '((a b) c (d (e))))
'((3 4) 5 (6 (7)))
Example Implementation:
#lang racket
(provide position)
(define base -1)
(define (indexer)
(set! base (add1 base))
base)
(define (position list-of-x)
(cond [(null? list-of-x) null]
[else
(define head (first list-of-x))
(cond [(list? head)
(cons (position head)
(position (rest list-of-x)))]
[else (cons (indexer)
(position (rest list-of-x)))])]))
I wrote a function which finds all the subsets of a list already and it works. I'm trying to write a second function where I get all the subsets of N length, but it's not working very well.
This is my code:
(define (subset_length_n n lst)
(cond
[(empty? lst) empty]
[else (foldr (lambda (x y) (if (equal? (length y) n) (cons y x) x)) empty (powerset lst))]
))
where (powerset lst) gives a list of all the subsets.
Am I misunderstanding the purpose of foldr?
I was thinking that the program would go through each element of the list of subsets, compare the length to n, cons it onto the empty list if there the same, ignore it if it's not.
But (subset_length_n 2 (list 1 2 3)) gives me (list (list 1 2) 1 2 3) when I want (list (list 1 2) (list 1 3) (list 2 3))
Thanks in advance
When using foldr you don't have to test if the input list is empty, foldr takes care of that for you. And this seems like a job better suited for filter:
(define (subset_length_n n lst)
(filter (lambda (e) (= (length e) n))
(powerset lst)))
If you must, you can use foldr for this, but it's a rather contrived solution. You were very close to getting it right! in your code, just change the lambda's parameters, instead of (x y) write (y x). See how a nice indentation and appropriate parameter names go a long way toward writing correct solutions:
(define (subset_length_n n lst)
(foldr (lambda (e acc)
(if (= (length e) n)
(cons e acc)
acc))
empty
(powerset lst)))
Anyway, it works as expected:
(subset_length_n 4 '(1 2 3 4 5))
=> '((1 2 3 4) (1 2 3 5) (1 2 4 5) (1 3 4 5) (2 3 4 5))
I want to do
(filter-list-into-two-parts #'evenp '(1 2 3 4 5))
; => ((2 4) (1 3 5))
where a list is split into two sub-lists depending on whether a predicate evaluates to true. It is easy to define such a function:
(defun filter-list-into-two-parts (predicate list)
(list (remove-if-not predicate list) (remove-if predicate list)))
but I would like to know if there is a built-in function in Lisp that can do this, or perhaps a better way of writing this function?
I don't think there is a built-in and your version is sub-optimal because it traverses the list twice and calls the predicate on each list element twice.
(defun filter-list-into-two-parts (predicate list)
(loop for x in list
if (funcall predicate x) collect x into yes
else collect x into no
finally (return (values yes no))))
I return two values instead of the list thereof; this is more idiomatic (you will be using multiple-value-bind to extract yes and no from the multiple values returned, instead of using destructuring-bind to parse the list, it conses less and is faster, see also values function in Common Lisp).
A more general version would be
(defun split-list (key list &key (test 'eql))
(let ((ht (make-hash-table :test test)))
(dolist (x list ht)
(push x (gethash (funcall key x) ht '())))))
(split-list (lambda (x) (mod x 3)) (loop for i from 0 to 9 collect i))
==> #S(HASH-TABLE :TEST FASTHASH-EQL (2 . (8 5 2)) (1 . (7 4 1)) (0 . (9 6 3 0)))
Using REDUCE:
(reduce (lambda (a b)
(if (evenp a)
(push a (first b))
(push a (second b)))
b)
'(1 2 3 4 5)
:initial-value (list nil nil)
:from-end t)
In dash.el there is a function -separate that does exactly what you ask:
(-separate 'evenp '(1 2 3 4)) ; => '((2 4) (1 3))
You can ignore the rest of the post if you use -separate. I had to implement Haskell's partition function in Elisp. Elisp is similar1 in many respects to Common Lisp, so this answer will be useful for coders of both languages. My code was inspired by similar implementations for Python
(defun partition-push (p xs)
(let (trues falses) ; initialized to nil, nil = '()
(mapc (lambda (x) ; like mapcar but for side-effects only
(if (funcall p x)
(push x trues)
(push x falses)))
xs)
(list (reverse trues) (reverse falses))))
(defun partition-append (p xs)
(reduce (lambda (r x)
(if (funcall p x)
(list (append (car r) (list x))
(cadr r))
(list (car r)
(append (cadr r) (list x)))))
xs
:initial-value '(() ()) ; (list nil nil)
))
(defun partition-reduce-reverse (p xs)
(mapcar #'reverse ; reverse both lists
(reduce (lambda (r x)
(if (funcall p x)
(list (cons x (car r))
(cadr r))
(list (car r)
(cons x (cadr r)))))
xs
:initial-value '(() ())
)))
push is a destructive function that prepends an element to list. I didn't use Elisp's add-to-list, because it only adds the same element once. mapc is a map function2 that doesn't accumulate results. As Elisp, like Common Lisp, has separate namespaces for functions and variables3, you have to use funcall to call a function received as a parameter. reduce is a higher-order function4 that accepts :initial-value keyword, which allows for versatile usage. append concatenates variable amount of lists.
In the code partition-push is imperative Common Lisp that uses a widespread "push and reverse" idiom, you first generate lists by prepending to the list in O(1) and reversing in O(n). Appending once to a list would be O(n) due to lists implemented as cons cells, so appending n items would be O(n²). partition-append illustrates adding to the end. As I'm a functional programming fan, I wrote the no side-effects version with reduce in partition-reduce-reverse.
Emacs has a profiling tool. I run it against these 3 functions. The first element in a list returned is the total amount of seconds. As you can see, appending to list works extremely slow, while the functional variant is the quickest.
ELISP> (benchmark-run 100 (-separate #'evenp (number-sequence 0 1000)))
(0.043594004 0 0.0)
ELISP> (benchmark-run 100 (partition-push #'evenp (number-sequence 0 1000)))
(0.468053176 7 0.2956386049999793)
ELISP> (benchmark-run 100 (partition-append #'evenp (number-sequence 0 1000)))
(7.412973128 162 6.853687342999947)
ELISP> (benchmark-run 100 (partition-reduce-reverse #'evenp (number-sequence 0 1000)))
(0.217411618 3 0.12750035599998455)
References
Differences between Common Lisp and Emacs Lisp
Map higher-order function
Technical Issues of Separation in Function Cells and Value Cells
Fold higher-order function
I don't think that there is a partition function in the common lisp standard, but there are libraries that provide such an utility (with documentation and source).
CL-USER> (ql:quickload :arnesi)
CL-USER> (arnesi:partition '(1 2 3 4 5) 'evenp 'oddp)
((2 4) (1 3 5))
CL-USER> (arnesi:partition '(1 2 b "c") 'numberp 'symbolp 'stringp)
((1 2) (B) ("c"))