lisp passing value to function? - lisp

i am new to lisp and in my code i want to convert 3 first bit to integer and check if number of ones in next bits is equal to that or not this is my code:
(defun new (vi n res)
(cond ((= vi nil) (cond ((= 0 res) t) ))
((= 2 n) (new (cdr vi) 1 (* (car vi) 4)))
((= 1 n) (new (cdr vi) 0 (+ (res) (* (car vi) 2))))
((= 0 n) (new (cdr vi) -1 (+ (res) (car vi ))))
((= vi nil) (nil))
((= -1 n) (new (cdr vi) -1 (- res (car vi))))))
i wanted to test it but when i write it:
(new ( 0 1 0 0 0 0 1 0 0 1 0) 2 0 )
it errors 0 is not a function
i tried this one :
(new (list `0 `1 `0 `0 `0 `0 `1 `0 `0 `1 `0) 2 0 )
but it errors
=: (0 1 0 0 0 0 1 0 0 1 0) is not a number

SBCL shows these warnings compiling your function:
; in: DEFUN NEW
; (= VI NIL)
;
; caught WARNING:
; Constant NIL conflicts with its asserted type NUMBER.
; See also:
; The SBCL Manual, Node "Handling of Types"
; in: DEFUN NEW
; (NIL)
;
; caught WARNING:
; The function NIL is undefined, and its name is reserved by ANSI CL so that even
; if it were defined later, the code doing so would not be portable.
; (RES)
;
; caught STYLE-WARNING:
; undefined function: COMMON-LISP-USER::RES
;
; compilation unit finished
; Undefined functions:
; NIL RES
; caught 2 WARNING conditions
; caught 1 STYLE-WARNING condition

Related

End of file (character) in Common Lisp

Basically im trying to read lines from a file recursively (because i can't use any loop cycle), but i don't know where the file ends.
This is my function:
;; (get-problemas 0)
(defun get-problemas (indice &optional file (problemas '()))
(cond
((null file) (with-open-file (open "C:/Users/nunor/Desktop/problemas.dat" :direction :input :if-does-not-exist nil)
(get-problemas (1+ indice) open (cons (read open) nil))
)
)
(t (cond
((= indice 6) problemas)
(t (get-problemas (1+ indice) file (append problemas (cons (read file) nil))))
)
)
)
)
I'm using a counter 'indice' to stop de recursion because i dont kow how to stop when i reached the end of the file.
And i'm putting the lists that the file contains in to a list called 'problemas'.
The file looks like this:
(a (((0 0 0) (0 0 1) (0 1 1) (0 0 1)) ((0 0 0) (0 1 0) (0 0 1) (0 1 1))) 3)
(b (((0 0 0) (0 0 1) (0 1 1) (0 0 1)) ((0 0 0) (0 1 0) (0 0 1) (0 1 1))) 3)
(c (((0 0 0) (0 0 1) (0 1 1) (0 0 1)) ((0 0 0) (0 1 0) (0 0 1) (0 1 1))) 3)
(d (((0 0 0) (0 0 1) (0 1 1) (0 0 1)) ((0 0 0) (0 1 0) (0 0 1) (0 1 1))) 3)
(e (((0 0 0) (0 0 1) (0 1 1) (0 0 1)) ((0 0 0) (0 1 0) (0 0 1) (0 1 1))) 3)
(f (((0 0 0) (0 0 1) (0 1 1) (0 0 1)) ((0 0 0) (0 1 0) (0 0 1) (0 1 1))) 3)
I hope you can help me.
Look at some solutions that use loop and rewrite them into recursion. Take for example this one:
(defun get-file (filename)
(with-open-file (stream filename)
(loop for line = (read-line stream nil)
while line
collect line)))
Note the usage of (read-line stream nil), which returns nil at the end of the file. You can just repeatedly call it and save the result of each call until you will get nil:
(defun read-until-null (f)
(let ((result (read-line f nil)))
(unless (null result)
(cons result (read-until-null f)))))
(defun file-to-lines (path)
(with-open-file (f path :direction :input :if-does-not-exist nil)
(read-until-null f)))
This works for me:
(defun get-problemas (&optional file (problemas nil))
(if file
(let ((prob (read file nil)))
(if prob
(get-problemas file (cons prob problemas))
(nreverse problemas)))
(with-open-file (stream (open "problemas.dat" :direction :input))
(get-problemas stream))))
Notes:
We pass arguments to read so that it doesn't throw an error, but returns nil. We detect this nil to terminate the recursion.
Your tail recursion with explicit accumulator is good; I improved it by avoiding append and accumulating the output in reverse. When we terminate the recursion, we nreverse the reversed list of "problemas".
I got rid of the :if-does-not-exist nil. If the file doesn't exist, we want to bail, and not recurse.
Rather than all the hair about the file argument it's natural to split this into two functions. One deals with opening the file:
(defun get-problemas (&optional (file "C:/Users/nunor/Desktop/problemas.dat"))
(with-open-file (in file :direction :input)
(with-standard-io-syntax
(let ((*read-eval* nil))
(get-problemas/accumulate in '())))))
Note this uses with-standard-io-syntax and binds *read-eval* to nil which are both elementary safety precautions which far too few Lisp programmers use.
The second, recursive, function builds the list of problems. It uses a trick which also seems to be unknown to too many Lisp programmers: to detect the end of file you return the stream itself since this is an object which can't (without great heroics) be in data read from the file:
(defun get-problemas/accumulate (in accumulation)
(let ((got (read in nil in)))
(if (eql got in)
(reverse accumulation)
(get-problemas/accumulate in (cons got accumulation)))))
I managed to solve my problem.
To know if i reached the end of the file i used "(read file nil 'eof)", if it reached the end of the file 'line' is going to be 'eof, and in cond i verify if 'line' is equal to 'eof so the recursion can stop.
This is how my function looks like now:
(defun get-problemas (&optional file (problemas '()))
(cond
((null file) (with-open-file (open "C:/Users/nunor/Desktop/problemas.dat" :direction :input :if-does-not-exist nil)
(get-problemas open (cons (read open) nil))
)
)
(t (let
(
(line (read file nil 'eof))
)
(cond
((eq line 'eof) problemas)
(t (get-problemas file (append problemas (cons line nil))))
)
)
)
)
)
Thank you for your help.

Never called Lisp function

(defun func (in s f l)
(cond
((null in) (append l (list (list 'end (+ 1 f)))))
((eq (car in) 'foo) (foo-asd (cdr in) s f l))
((atom (car in))(atom-asd in (+ 1 s) (+ 1 f) l))
))
.
(defun atom-asd (in s f l)
(cond ((eql in nil) ())
(append l (list (list 'frob s (car in) (+ 1 f))))))
.
(defun foo-asd (in s f l)
(cond
((eql in nil) (append l (list (list 'frob s 'myst f))))
((func in s f (append l (list (list 'frob s 'myst (+ 1 f))))))
((foo-asd (cdr in) s f l))
))
.
Regarding this code if call (func '(foo x y) 0 0 ()) the function foo-asd will be called, then func is called again and it will enter the function atom-asd, when atom-asd ends it execution, all the program ends, without calling the recursive call foo-asd. I need foo-asd to be called, but i do not understand why it isn't called after atom-asd ends.
[4]> (trace func)
;; Tracing function func.
(func)
[5]> (trace atom-asd)
;; Tracing function atom-asd.
(atom-asd)
[6]> (trace foo-asd)
;; Tracing function foo-asd.
(foo-asd)
[7]> (func '(foo x y) 0 0 ())
1. Trace: (func '(foo x y) '0 '0 'nil)
2. Trace: (foo-asd '(x y) '0 '0 'nil)
3. Trace: (func '(x y) '0 '0 '((frob 0 myst 1)))
4. Trace: (atom-asd '(x y) '1 '1 '((frob 0 myst 1)))
*** - cond: variable append has no value
The following restarts are available:
USE-VALUE :R1 Input a value to be used instead of append.
STORE-VALUE :R2 Input a new value for append.
ABORT :R3 Abort main loop
Break 1 [8]>
So in atom-asd:
(defun atom-asd (in s f l)
(cond
((eql in nil)
())
(append
l (list (list 'frob s (car in) (+ 1 f))))))
You have two predicates. one tests (eql in nil) which obviously is nil, then it checks if the variable append has a non nil value. Problem is append is not a bound variable. It is a binding in the function namespace, but here every term is inclused in one set of parentheses so append is by itself th eexpression that gets tested. You might have meant that it should do (append ...) when the first term didn't kick in and you should have written it like this:
(defun atom-asd (in s f l)
(cond
((eql in nil)
())
(t
(append l (list (list 'frob s (car in) (+ 1 f)))))))
With this version we get a result:
[8]> (func '(foo x y) 0 0 ())
5. Trace: (func '(foo x y) '0 '0 'nil)
6. Trace: (foo-asd '(x y) '0 '0 'nil)
7. Trace: (func '(x y) '0 '0 '((frob 0 myst 1)))
8. Trace: (atom-asd '(x y) '1 '1 '((frob 0 myst 1)))
8. Trace: atom-asd ==> ((frob 0 myst 1) (frob 1 x 2))
7. Trace: func ==> ((frob 0 myst 1) (frob 1 x 2))
6. Trace: foo-asd ==> ((frob 0 myst 1) (frob 1 x 2))
5. Trace: func ==> ((frob 0 myst 1) (frob 1 x 2))
((frob 0 myst 1) (frob 1 x 2))

Usage of DEFSETF

It is just really hard to understand from a standard description, so:
For instance, I'm trying to set a k-th position of some list (ls) to a specific value. Even have a function of my own, that gives acces to k-th elt.
(defun kth-elt (lst k)
(cond ((> 0 k) nil)
((equal 0 k) (car lst))
((< 0 k) (kth-elt (cdr lst) (- k 1))))).
Also made a function, that updates that value.
(defun kth-upd (lst k new)
(cond ((> 0 k) nil)
((equal 0 k) (setf (car lst) new))
((< 0 k) (kth-upd (cdr lst) (- k 1) new))))
Now i can actually use that, but i wanna understand the difference between it and DEFSETF. Also I still do not understand. how to "teach" defsetf to use these. Thx for help.
Based on your definitions, it is simply:
(defsetf kth-elt kth-upd)
Instead of using kth-upd, you can now use kth-elt and (setf kth-elt).
For example:
(let ((list (copy-list '(a b c d e f))))
(setf (kth-elt list 3) nil)
list)
=> (A B C NIL E F)
But the real benefits of using SETF consistently is that you can combine this setter with other ones. Just consider incrementing a value:
(let ((list (make-list 10 :initial-element 0)))
(incf (kth-elt list 3))
(incf (kth-elt list 5) 20)
list)
=> (0 0 0 1 0 20 0 0 0 0)
See also this answer from Rainer Joswig for more background on places and SETF.
Setf expander
Note that you are doing the list traversal twice: you first get the current value, then computes the new one; only then, you store the new value, starting from the beginning of the list:
0: (KTH-ELT (0 0 0 0 0 0 0 0 0 0) 3)
1: (KTH-ELT (0 0 0 0 0 0 0 0 0) 2)
2: (KTH-ELT (0 0 0 0 0 0 0 0) 1)
3: (KTH-ELT (0 0 0 0 0 0 0) 0)
3: KTH-ELT returned 0
2: KTH-ELT returned 0
1: KTH-ELT returned 0
0: KTH-ELT returned 0
0: (KTH-UPD (0 0 0 0 0 0 0 0 0 0) 3 1)
1: (KTH-UPD (0 0 0 0 0 0 0 0 0) 2 1)
2: (KTH-UPD (0 0 0 0 0 0 0 0) 1 1)
3: (KTH-UPD (0 0 0 0 0 0 0) 0 1)
3: KTH-UPD returned 1
2: KTH-UPD returned 1
1: KTH-UPD returned 1
0: KTH-UPD returned 1
This can also be seen by macroexpansion:
(incf (kth-elt list 3))
... is macroexpanded as:
(LET* ((#:LIST796 LIST) (#:NEW1 (+ 1 (KTH-ELT #:LIST796 3))))
(KTH-UPD #:LIST796 3 #:NEW1))
Another possible approach might be to use DEFINE-SETF-EXPANDER:
(define-setf-expander kth (list index)
(alexandria:with-gensyms (store cell)
(values `(,cell)
`((nthcdr ,index ,list))
`(,store)
`(setf (car ,cell) ,store)
`(car ,cell))))
The function returns 5 different code parts that can be assembled to access and modify a place. cell and store are local variables introduced using GENSYM.
The variable cell (i.e. the variable named after the fresh symbol bound to cell) will be bound to (nthcdr index list). store contains the value to set in the place. Here, it will be put at the appropriate place by using (setf (car cell) store). Also, the existing value in the place is (car cell). As you can see, we need to manipulate, under the hood, the cons cell we mutate (of course, an error is raised with empty lists).
The macroexpansion for (incf (kth list 3)) is:
(LET* ((#:CELL798 (NTHCDR 3 LIST)) (#:STORE797 (+ 1 (CAR #:CELL798))))
(SETF (CAR #:CELL798) #:STORE797))
The setter function knows how to access the place that holds the value we want to change, and can change it directly, which is more efficent than just a pair of reader/writer functions.
Remark about mutability
SETF is designed around mutable data. If you write an accessor for a key/value store on the network, so that (remote host key) will connect and retrieve a value, and (setf (remote host key) value) sends the new value back, then it is not guaranteed that the remote value is always updated when (remote host key) is used as an intermediate place.
For example, if the value is a list, (push val (remote host key)) will push on the local list created on your host, there is no obligation for setf to actually ensure the result is sent back to the network when it is part of a larger expression. That allows SETF to be efficient by mutating places, at the small cost of requiring you to be more explicit. In the preceding example, you have to write (setf (remote host key) new-list) directly (not as a nested place) to effectively send the new data back.
As an addendum to coredump's answer, it's worth noting that the following works, and is, in my opinion, much better than using defsetf:
(defun kth-elt (lst k)
(cond ((> 0 k) nil)
((= 0 k) (car lst))
((< 0 k) (kth-elt (cdr lst) (- k 1)))))
(defun (setf kth-elt) (new lst k)
(cond ((> 0 k) nil)
((= 0 k) (setf (car lst) new))
((< 0 k) (setf (kth-elt (cdr lst) (- k 1)) new))))
There are cases when you need defsetf but they are not that common.
(kth-elt itself is just a special-case of elt of course: in real life you don't need to write any of this.)

Evaluating Racket expression

Given these definitions:
(define s 8)
(define p (/ s 2))
(define (f s p)
(cond [(or (> s 0) p) 'yes] [(< s 0) 'no]))
I want to evaluate this expression:
(f 0 (and (< s p) (> s 2)))
So far I have:
⇒ (f 0 (and (< 8 p) (> s 2)))
⇒ (f 0 (and (< 8 4) (> s 2)))
⇒ (f 0 (and false (> s 2)))
⇒ (f 0 false)
How do I finish this?
You need to replace this with the body of f (the cond expression) with the parameters replaced by their matching arguments.
Racket sees that f is a procedure and evaluates it's arguments:
(f 0 (and (< s p) (> s 2))) ; ==>
(f 0 (and (< 8 4) (> 8 2))) ; ==>
(f 0 (and #f #t)) ; ==>
(f 0 #f) ; s=0, p=#f
Then the arguments is substituted for the variables in the body of f:
; ==>
(cond [(or (> 0 0) #f) 'yes]
[(< 0 0) 'no])
since both (or (> 0 0) #f) and (< 0 0) are #f the result is the undefined value chosen by the implementation. In racket it's #<void>
; ==>
#<void>
This could have been avoided by always have a else term:
(define (f s p)
(cond [(or (> s 0) p) 'yes]
[(< s 0) 'no]
[else 'banana]))
(f 0 (and (< s p) (> s 2))) ; ==> banana

Why does CLISP stops responding during this nested loop?

I am trying to create subsequences of some word with the following code. When I added by k, the code stopped responding, though if I replace k with a particular number, it works. What is happening?
(let ((c nil)) (loop for k from 0 to (length "abc")
finally (return c) do (loop for j from 0 to (length "abc") by k
do (loop for i from j to (length "abc") do (push (subseq "abc" j i) c)))))
Debugging
if I replace k with a particular number, it works
What happens if you replace k with 0?
It would be much more helpful if you formatted this code with typical conventions, and probably if you isolated the particular part of the code that's problematic. That is, (remove-duplicates …) isn't the problem here, you could have removed it. With some more conventional formatting, and some comments, your code is:
(remove-duplicates
(let ((c nil))
(loop for k from 0 to (length "abc") ; k starts at 0
finally (return c)
do (loop for j from 0 to (length "abc") by k ; looping for j from 0 to something by k
do (loop for i from j to (length "abc")
do (push (subseq "abc" j i) c)))))
:test 'equal)
What's going to happen if you try to loop for j from 0 to anything by k? You're pretty much saying, "start with j at 0, then increment it by 0 for the next iteration…" so j never gets anywhere. This really could have been caught with a print or format. I know that's not the same as using a debugger, but sometimes the simplest ways are the quickest:
[8]> (remove-duplicates
(let ((c nil))
(loop for k from 0 to (length "abc")
finally (return c)
do (loop for j from 0 to (length "abc") by k
do
(format t "~&k: ~a, j: ~a" k j )
(loop for i from j to (length "abc")
do (push (subseq "abc" j i) c)))))
:test 'equal)
k: 0, j: 0
k: 0, j: 0
k: 0, j: 0
…
Collecting subsequences
If you're trying to collect the subsequences of a given sequence, you might do it like this. This works on both strings (vectors) and lists (although it's less efficient for lists).
(defun subsequences (sequence)
(loop
with length = (length sequence)
for i from 0 to length
nconcing (loop
for j from (1+ i) to length
collecting (subseq sequence i j))))
(subsequences "abc")
;=> ("a" "ab" "abc" "b" "c")
(subsequences '(1 2 3))
;=> ((1) (1 2) (1 2 3) (2) (2 3) (3))
Appendex: A hard-to-understand error from SBCL
Interestingly, you'll get a runtime error with SBCL, although the error message doesn't make it particularly clear why. Perhaps it's related to the infinite looping.
* (remove-duplicates
(let ((c nil))
(loop for k from 0 to (length "abc")
finally (return c)
do (loop for j from 0 to (length "abc") by k
do
(loop for i from j to (length "abc")
do (push (subseq "abc" j i) c)))))
:test 'equal)
debugger invoked on a TYPE-ERROR in thread #<THREAD "initial thread" RUNNING
{1002978E71}>:
The value 0
is not of type
(OR (SINGLE-FLOAT (0.0)) (DOUBLE-FLOAT (0.0d0)) (RATIONAL (0))).
Type HELP for debugger help, or (SB-EXT:QUIT) to exit from SBCL.
restarts (invokable by number or by possibly-abbreviated name):
0: [ABORT] Exit debugger, returning to top level.
What do you think BY 0 should do in a loop?
(loop for i from 0 upto 10 by 0 do (princ '*))
If you are not advancing the variable, you'll get an endless loop.