LISP Can anyone explain me this cond example? - lisp

(defun Left (state)
(setq new_place (- (second state) 1))
(cond
((endp state) NIL)
((= (first state) 1) NIL)
(T (> (second state) 1) (list skoupa (- (second state) 1) (last state)))))
I cannot understand this line ((endp state) NIL) that NIL drives me crazy whats the purpose of it ? i understand endp state will result True or NIL. for example if it results True then i will have ((T) NIL) is this a correct statement? what is the result of this?

I tried to convert this to pseudocode.
Added an if as stated in my comments assuming it was supposed to be
(T (if (> (second state) 1)
(list skoupa (- (second state) 1))
(last state)))))
HTH.
function Left (state)
set new_place = (second state)-1
if state is empty
return NIL
else
if (first state) == 1
return NIL
else
if (second state) > 1
return (list skoupa (second state)-1
else
return (last state)

Related

Second child of an Emacs Lisp

With these emac lisp definitions given to me I need to get the correct results for (defun operand (n ast)). Currently, the first child works like it's supposed to but for the second child (operand (- n 1) (cadr ast)) gives the second child as (INT_LITERAL pos) and not the rest of the child ((INT_LITERAL pos) (77)). Not sure where to go from here. As you can see I've done some guess and testing to fix my solution but nothing has worked yet. From my understanding when my results are nil that means that frame has no parent frame but I'm not sure why it does not print out the whole operand.
(defun store (offset value alist)
"Insert the value for this offset, replacing the previous value (if any)."
(cond
((null alist) (list (cons offset value))) ; ((offset . value))
((eq offset (caar alist)) (cons (cons offset value) (cdr alist)))
(t (cons (car alist)
(store offset value (cdr alist))))
)
)
(defun lookup (offset alist)
"Return the value associated with this offset, or raise an error."
(cond
((null alist) (user-error "UNINITIALISED %s" offset) (exit))
((eq (caar alist) offset) (cdar alist))
(t (lookup offset (cdr alist)))
)
)
;;(setq a (store 1 19 (store 0 17 ())))
;; a
;; (setq a (store 2 20 a))
;; (setq a (store 1 29 a))
;; (lookup 3 ())
;; (lookup 3 a)
;;(lookup 1 a)
;;; Accessors for the various fields in an AST node
(defun position (ast)
"The position stored in an AST node"
(cadar ast)
)
(defun kind (ast)
(caar ast)
)
(defun operand (n ast)
;; Your code goes here.
(if (eq n 0)
(caadr ast) ;;first child
(operand (- n 1)(cadr ast)) ;;second child
)
)
;;(operand (- n 1)(cadr (cadr ast))) gives 77 (#o115, #x4d, ?M)
;;(operand (- n 1)(cadr ast)) gives (INT_LITERAL pos)
;;(operand (- n 1) (cadr (cddr ast))) gives nil
;;(operand (- n 1) (cdr (cadr ast))) gives nil
;; (operand (- n 1)(caddr ast)) gives nil
;;(operand (- n 1)(car ast)) gives wrong type argument listp, pos
;;(operand (- n 1)(cdr ast)) gives nil
;;cadadr, cadr, cadddr, cdadr, caddr, car, cdr
;; (setq ast '((PLUS pos) (( (VARIABLE pos) (b 1) ) ((INT_LITERAL pos) (77) ) ) ))
;; (kind ast) = PLUS
;; (position ast) = pos
;; (operand 0 at) = ((VARIABLE pos)(b 1))
;; (kind (operand 0 ast))= VARIABLE
;; (operand 1 ast)= supposed to equal ((INT_LITERAL pos) (77))
;; (kind (operand 1 ast)) = supposed to equal INT_LITERAL
Your question is not easy to follow -- I'm confident that you could pare all that code down to something far more minimal for these purposes.
At present you're calling operand recursively, but the ast data does not have the nested structure required by that recursion, and so things quickly break down.
I think you just want this?
(defun operand (n ast)
(nth n (cadr ast)))

What's the element in position n of a list

I have this function which gives me the element at given position in a list and need to rewrite it with cond instead of if. Also I want to change it a bit so If I give a negative value it returns nil for example
(getn 2 '(a b c)) => (c)
(getn -1 '(a b c)) => nil
The function :
(defun getn (n lst)
(if
(zerop n)
(car lst)
(getn (1- n) (cdr lst)) ) )
I did that but doesn't work :
(defun getn (nb liste)
(cond
((= 0 nb) liste)
(getn (1- n) (cdr liste)) )
Your first version is almost right. Note that when you call getn recursively you are shortening the list, so there will be a point where you are passing nil as the lst argument. You have to check for this condition before anything else and return nil if lst is nil.
cond is like a list of sequential if's. In your case you can write:
(cond ((null lst) nil)
((< n 0) nil)
((= n 0) (car lst))
...
)
(defun getn (n lst)
(cond ((or (null lst) (< n 0)) nil)
((= n 0) (car lst))
(t (getn (- n 1) (cdr lst)))))
For the case, that the nth element of the list is itself nil,
in lisp often one sends additional information. A second value, which is t,
if an element was found, and nil if no element was found.
So nil; t means the nth element was nil, while nil; nil means no element
was found.
(defun getn (n lst)
(cond ((or (null lst) (< n 0)) (values nil nil))
((= n 0) (values (car lst) t))
(t (getn (- n 1) (cdr lst)))))
[8]> (getn 1 '(1 nil 3))
NIL ;
T
;; an element was found -> T as second value, and the element was `nil`
[9]> (getn 1 '(1))
NIL ;
NIL
;; no element was found -> nil as second value, and therefore first value is also `nil`.
A very good book to learn recursive thinking and programming in lisp is The little schemer or the older version the little lisper. I learned through it thinking recursively.

More than one argument for predicate in delete-if

Suppose I want to delete one step (element) from the states list.
(defparameter *states* '((:top nil nil) (:subjects nil nil)))
;predicate
(defun equal-state? (step state)
(equal (car step) state))
If I use (delete-if #'equal-state? *states*) then how the second argument ( state) can be passed to predicate?
edited: I have finally found a similar question but I am inclined to retain it because of clarity in the question.
CL-USER 67 > (let ((state :top))
(delete-if (lambda (step)
(equal-state? step state))
*states*))
((:SUBJECTS NIL NIL))
or
CL-USER 68 > (defun make-predicate (state)
(lambda (step)
(equal-state? step state)))
MAKE-PREDICATE
CL-USER 69 > (delete-if (make-predicate :subjects)
*states*)
((:TOP NIL NIL))
As user coredump mentions, delete-if is a potentially destructive operation. The non-destructive alternative to delete-if is remove-if.
One can also use remove/ delete:
CL-USER 77 > (remove :subjects
'((:top nil nil)
(:subjects nil nil))
:key #'first
:test #'equal)
((:TOP NIL NIL))

How to not return anything in a COND

So I'm making this function in lisp, and in the cond part basically if a condition is met, I return a list with 2 values, and if the condition is not met, I would like to not return anything at all! Here it is:
(defun lista-dos-aprovados (turma)
(mapcar (lambda (aluno)
(cond ((> (media-notas (notas aluno)) 9.5)
(list (first aluno) (second aluno)))
(t nil)))
turma))
the names are in portuguese but I think it doesn't really matter here. What I'd like to do is when the code reaches the (t nil) part, I don't want it to write NIL inside my list. I tried not having the T condition or leaving it empty after the T, still it always writes NIL.
You can remove the nil in the result of mapcar, like in:
(defun lista-dos-aprovados (turma)
(remove nil
(mapcar (lambda (aluno)
(cond ((> (media-notas (notas aluno)) 9.5)
(list (first aluno) (second aluno)))
(t nil)))
turma)))
and note that you can simplify the function as:
(defun lista-dos-aprovados (turma)
(remove nil
(mapcar (lambda (aluno)
(when (> (media-notas (notas aluno)) 9.5)
(list (first aluno) (second aluno))))
turma)))
or you can use a loop:
(defun lista-dos-aprovados (turma)
(loop for aluno in turma
when (> (media-notas (notas aluno)) 9.5)
collect (list (first aluno) (second aluno))))

How do I format a list of strings

I have a list of strings that I need to format using emacs lisp. This was the only way I could think of going about it:
(setq slist '("is there" "any" "way" "directed iteration"))
(format "%s _%s_ %s to do %S in elisp?"
(elt slist 0)
(elt slist 1)
(elt slist 2)
(elt slist 3)
(elt slist 4))
Giving me what I want.
is there _any_ way to do "directed iteration" in elisp?
There must be a more elegant way, but after much thought, I'm not seeing it. I'm very new to emacs lisp and I might be missing something obvious.
Use apply:
(apply 'format "%s _%s_ %s to do %S in elisp?" slist)
The apply function takes a function (or symbol) as its first argument, then a number of individual arguments, finishing with a list of arguments.
I've decided to make it into a standalone project by adding some more features, fixing some bugs and adding more bugs! yey :)
You can find the project here: http://code.google.com/p/formatting-el/source/browse/trunk/formatting.el
Not sure how much buggy this is, but at the first sight it seems to work:
(defun directive-end (c)
(member c "csdoxXeg%"))
(defun pp-if-nil (spec)
(position ?\% spec))
(defun pp-list (spec args)
(let ((pos 0) (last 0) (fstring "% ") current seen-^)
(catch 't
(while t
(setq pos (1+ (or (position ?% spec :start pos) -1))
current (aref spec pos))
(unless (and seen-^ (char-equal current ?\}) (null args))
(princ (substring spec last (1- pos))))
(setq last pos pos (1+ pos))
(cond
((char-equal current ?^)
(incf last)
(setq seen-^ t))
((char-equal current ?\{)
(setq pos (+ pos (pp-list (substring spec pos) (car args)))
args (cdr args)
last pos
seen-^ nil ))
((char-equal current ?\})
(if args (setq pos 0 last 0)
(throw 't nil)))
((char-equal current ?%)
(setq seen-^ nil last (1+ last))
(write-char ?%))
(t (unless args (error "Not enough argumens for list iteration"))
(setf (aref fstring 1) current)
(princ (format fstring (car args)))
(setq args (cdr args)
seen-^ nil
last
(or (position-if #'directive-end spec :start pos)
pos)))))) pos))
(defun cl-format (spec &rest args)
(with-output-to-string
(let ((pos 0) (last 0) (fstring "% ") current)
(catch 't
(while t
(setq pos (1+ (or (position ?\% spec :start pos) -1))
current (aref spec pos))
(when (= pos 0) (throw 't nil))
(princ (substring spec last (1- pos)))
(setq last pos pos (1+ pos))
(cond
((char-equal current ?^)
(unless args
(setq last (pp-if-nil spec)
pos last)))
((char-equal current ?\{)
(setq pos (+ pos (pp-list (substring spec pos) (car args)))
args (cdr args)
last pos))
((char-equal current ?\})
(error "Unmatched list iteration termination directive"))
((char-equal current ?%)
(write-char ?%)
(incf last))
(t (unless args (error "Not enough argumens"))
(setf (aref fstring 1) current)
(princ (format fstring (car args)))
(setq args (cdr args)
last
(or (position-if #'directive-end spec :start pos)
pos))))
(incf pos))))))
(cl-format "begin: %{%s = %d%^,%}; %% %c %% %{%{%s -> %d%^.%},%}"
'(a 1 b 2 c 3) ?\X '((a 2 b 4 c 6) (a 1 b 3 c 5)))
"begin: a = 1,b = 2,c = 3; % X % a -> 2.b -> 4.c -> 6,a -> 1.b -> 3.c -> 5,"
This tries to replicate some (very simplistic) Common Lisp-like printing behaviour of the ~{ ... ~} directives.