LISP meaning of # symbol - lisp

In my Lisp code I have the function (nfa-regex-compile), which creates a list of cons with the initial state, the transitions and the final state (representing the nodes of an automaton) starting from a regular expression given as argument.
In this case, I took as expression a sequence, but I don't understand why, if I give more than two symbols, the function produces (# #) instead of going on generating the new states.
CL-USER 39 : 3 > (nfa-regex-compile '(seq a))
((INITIAL 0) ((DELTA 0 A 1) (FINAL 1)))
CL-USER 40 : 3 > (nfa-regex-compile '(seq a b))
((INITIAL 0) ((DELTA 0 A 1) ((DELTA 1 B 2) (FINAL 2))))
CL-USER 41 : 3 > (nfa-regex-compile '(seq a b c))
((INITIAL 0) ((DELTA 0 A 1) ((DELTA 1 B 2) (# #))))
CL-USER 42 : 3 > (nfa-regex-compile '(seq a b c d e f))
((INITIAL 0) ((DELTA 0 A 1) ((DELTA 1 B 2) (# #))))
for example if i have a sequence abc, the automaton should be:
(INITIAL 0) (DELTA 0 A 1) (DELTA 1 B 2) (DELTA 2 C 3) (FINAL C)
Automaton for the regular expression abc

When printing, the standard variable *print-level* controls how deep into the nesting structure the printer descends. If the structure depth exceeds that level, the printer stops and prints a bare # instead of any more structure.
For example:
* (defvar *structure*
'(:level-1 :level-1
(:level-2 :level-2 :level-2)
(:level-2 :level-2 (:level-3 :level-3
(:level-4) :level-3))))
* (dotimes (i 5)
(let ((*print-level* i))
(print *structure*)))
#
(:LEVEL-1 :LEVEL-1 # #)
(:LEVEL-1 :LEVEL-1 (:LEVEL-2 :LEVEL-2 :LEVEL-2) (:LEVEL-2 :LEVEL-2 #))
(:LEVEL-1 :LEVEL-1 (:LEVEL-2 :LEVEL-2 :LEVEL-2)
(:LEVEL-2 :LEVEL-2 (:LEVEL-3 :LEVEL-3 # :LEVEL-3)))
(:LEVEL-1 :LEVEL-1 (:LEVEL-2 :LEVEL-2 :LEVEL-2)
(:LEVEL-2 :LEVEL-2 (:LEVEL-3 :LEVEL-3 (:LEVEL-4) :LEVEL-3)))
The actual structure never changes, only its printed representation.
This variable is sometimes rebound in the debugger to avoid printing heavily nested structure. See the documentation for your implementation for details.

Related

How to modify list inside a function

(defun list-parser (list count)
...);;this function reads items by count from list and do some process to them.
;;i.e.convert items read from code to char, or to other things and then return it.
;;Also, the items in list should be consumed, globally.
(defmethod foo ((obj objtype-2) data-list)
(setf (slot-1 obj) (read-list data-list 1))
obj)
(defmethod foo ((obj objtype-1) data-list)
(setf (slot-1 obj) (read-list data-list 1)
(print data-list)
(slot-2 obj) (read-list data-list 2)
(print data-list)
(slot-3 obj) (foo (make-instance 'objtype-2) data-list)
(print data-list)
(slot-4 obj) (read-list data-list 3))
obj)
How to let it work like this:(read-list just works like read-byte in some way:
1.return a value read(and parsed here)
2.change the stream position(here the list)).
(let ((obj)
(data))
(setf data '(1 2 3 4 5 6 7 8)
obj (foo (make-instance 'objtype-1) data))
(print data))
>>(2 3 4 5 6 7 8)
>>(4 5 6 7 8)
>>(5 6 7 8)
>>(8)
Or rather, how do you deal with this kind of task? Do you convert list to other type?
I am not quite sure what you are after, but here is a function which creates a 'list reader' object (just a function). A list reader will let you read chunks of a list, treating it a bit like a stream.
(defun make-list-reader (l)
;; Make a list reader which, when called, returns three values: a
;; chunk of list, the length of tha chunk (which may be less than
;; how much was asked for) and the remaining length. The chunk is
;; allowed to share with L
(let ((lt l)
(len (length l)))
(lambda (&optional (n 1))
(cond
((zerop len)
(values nil 0 0))
((< len n)
(values lt len 0))
(t
(let ((it (subseq lt 0 n)))
(setf lt (nthcdr n lt)
len (- len n))
(values it n len)))))))
(defun read-from-list-reader (r &optional (n 1))
;; Read from a list reader (see above for values)
(funcall r n))
And now:
(defvar *l* (make-list-reader '(1 2 3)))
*l*
> (read-from-list-reader *l* 1)
(1)
1
2
> (read-from-list-reader *l* 2)
(2 3)
2
0
> (read-from-list-reader *l* 10)
nil
0
0
What you can't really do is write a function (not actually a function of course since it modifies its argument) which works like this while modifying its argument list. So you can write a function which will do this:
> (let ((l (list 1 2)))
(values (read-from-list l)
l))
(1)
(2)
which works by modifying the car and cdr of the first cons of l as you'd expect. But this can't work when there is no more to read: l is a cons and nil isn't a cons, so you can't ever make l nil with a function.
But in any case such a function is just a mass of traps for the unwary and generally horrid: for instance your example would involve modifying a literal, which isn't legal.

Scheme macro - Expand a list into a set of function calls

This procedure to identify that a tic-tac-toe row is marked does not work (X _ _ row is identified as fully marked when it is not)
(define (won? b m)
(define (row-marked? r)
(every?-ec (:vector c (index i) b) (if (memv i r)) [char=? c m]))
"Returns #t if the mark m won"
(let ([rr '((0 1 2) (3 4 5) (6 7 8) (0 3 6) (1 4 7) (2 5 8) (0 4 8) (2 4 6))])
`(or ,#(map (lambda (r) `(row-marked? (list ,#r))) rr))))
while the procedure below works
(define (won? b m)
(define (row-marked? r)
(every?-ec (:vector c (index i) b) (if (memv i r)) [char=? c m]))
"Returns #t if the mark m won"
(or (row-marked? '(0 1 2)) (row-marked? '(3 4 5)) (row-marked? '(6 7 8))
(row-marked? '(0 3 6)) (row-marked? '(1 4 7)) (row-marked? '(2 5 8))
(row-marked? '(0 4 8)) (row-marked? '(2 4 6))))
I've tried with no luck
(let ([rr '((0 1 2) (3 4 5) (6 7 8) (0 3 6) (1 4 7) (2 5 8) (0 4 8) (2 4 6))])
`(or ,#(map (lambda (r) `(row-marked? ,r)) rr)))
and
(let ([rr '((0 1 2) (3 4 5) (6 7 8) (0 3 6) (1 4 7) (2 5 8) (0 4 8) (2 4 6))])
`(or ,#(map (lambda (r) `(row-marked? ',r)) rr)))
as well. What I'm doing wrong?
My goal is to avoid code repetition and automatically generate the executable (or ...) expression while keeping the short-circuiting of both or and every-ec
Thank you!
What you need isn't a macro (and as you've specified it it can not be done by a macro), it's SRFI 1's any function:
(define (won? b m)
(define (row-marked? r)
(every?-ec (:vector c (index i) b) (if (memv i r)) [char=? c m]))
"Returns #t if the mark m won"
(any row-marked?
'((0 1 2) (3 4 5) (6 7 8) (0 3 6) (1 4 7) (2 5 8) (0 4 8) (2 4 6))))
A single-list version of any, which is all you need, is very easy to write:
(define (any/1 p l)
(if (null? l)
#f
(or (p (first l))
(any/1 p (rest l)))))
A fully-fledged any is a bit harder to get right, especially if you want it to be efficient in the simple cases.
It's worth while perhaps seeing why what you want to achieve can't be done with a macro. If you consider the fragment
(let ([rr ...])
(m row-marked? rr))
Then can m be a macro whose expansion is (or (row-marked ...) ...)? No, it can't be, because macros transform source code and the list which is bound to rr is not available until run time: the macro does not have the source code it needs to transform.
Really, the thing you want to avoid here, is that the forms in the body of row-marked? should be evaluated only as many times until they return true, and the mechanism for doing that is just wrapping them up in a function and calling it only as many times as needed.
However that mechanism is sometimes a bit syntactically clumsy: if I have something like
(any (λ (e1 e2)
(and (integer? e1) (integer? e2)
(even? e1) (even? e2))
(not (= e1 e2)))
l1 l2)
I might rather write this as
(finding-first ((e1 l1) (e2 l2))
(and (integer? e1) (integer? e2)
(even? e1) (even? e2)
(not (= e1 e2))))
And, of course, you can:
(define-syntax finding-first
(syntax-rules ()
[(_ ((v l) ...) form ...)
(any (λ (v ...) form ...) l ...)]))

Function not assigning values in Racket

Why following function (match-redefine) is not working?
(define vlist (list 10 20 30))
(match-define (list aa bb cc) (list 1 2 3))
(define alist (list aa bb cc))
alist
vlist
(define (match-redefine dst_list src_list)
(for ((d dst_list)(s src_list)) (set! d s)) )
(rnmatch-redefine alist vlist)
alist
vlist
The output is:
'(1 2 3)
'(10 20 30)
'(1 2 3)
'(10 20 30)
The destination list (alist) remains unchanged. Can this function be made to work?
Edit: I tried vector as suggested by #OscarLopez in the answers, but it does not work:
(match-define (list a b c) (list 0 0 0 ) )
(define variable_vect (vector a b c))
a
b
c
(define valuelist (list 1 2 3) )
(for ((i variable_vect)(j valuelist)) ; does not work
(set! i j))
variable_vect
a
b
c
(set! variable_vect valuelist)
(println "------- after ----------")
variable_vect
a
b
c
Output is:
0
0
0
'#(0 0 0)
0
0
0
"------- after ----------"
'(1 2 3)
0
0
0
Edit: It seems I will have to use special class to apply this:
(define myob%
(class object%
(super-new)
(init-field val)
(define/public (getval) val)
(define/public (setval v) (set! val v)) ))
(define (copyvalues objlist valuelist)
(for ((a alist)(v valuelist)) (send a setval v)) )
(define (show_objlist alist)
(for ((a alist)) (println (send a getval))) )
; USED AS FOLLOWS:
(define ob1 (make-object myob% 5))
(define ob2 (make-object myob% 5))
(define ob3 (make-object myob% 5))
(define alist (list ob1 ob2 ob3))
(println "---------- first assignment -----------")
(define vlist (list 1 2 3))
(copyvalues alist vlist)
(show_objlist alist)
(println "---------- second assignment -----------")
(define ylist (list 10 20 30))
(copyvalues alist ylist)
(show_objlist alist)
(println "---------- individual access -----------")
(send ob1 getval)
(send ob3 getval)
Output is:
"---------- first assignment -----------"
1
2
3
"---------- second assignment -----------"
10
20
30
"---------- individual access -----------"
10
30
You ask why the function is not working.
The reason is that (set! d s) is doing something
you do not expect.
Observe:
#lang racket
(define vlist (list 10 20 30))
(match-define (list aa bb cc) (list 1 2 3))
(define alist (list aa bb cc))
alist
vlist
(define (match-redefine dst_list src_list)
(for ((d dst_list)(s src_list))
(set! d s)
(displayln (~a "d is now: " s))))
(match-redefine alist vlist)
The output is:
'(1 2 3)
'(10 20 30)
d is now: 10
d is now: 20
d is now: 30
This means that you change the value of d (not the value of the variable which corresponds to the symbols that d runs through.
See your previous question on the same topic.
Again, this is not the way we do things in Scheme. Besides, your code is simply reassigning a local variable that was pointing to an element in the list, the destination list remains unmodified.
You could use vectors instead of lists - those can be modified, exactly as you would modify an array in the most common programming languages, something like this:
(define value_list (list 1 2 3))
(define value_vect (vector 0 0 0))
value_vect
=> '#(0 0 0)
(for [(i (in-range (vector-length value_vect)))
(value value_list)]
(vector-set! value_vect i value))
value_vect
=> '#(1 2 3)
Anyway you should not modify a list of variables, just return a list with the new values. And don't think about mutating the list - although it is possible to do so using mutable pairs, that's not the correct way to deal with this situation, please stop thinking about mutating everything you encounter!

How would I get the min/max of a list using a key

I currently have a list of objects, each containing a certain attribute. I would like to get the element of the list with the min attribute value. Is there a concise way of doing this?
The python equivalent would be something like: min(d, key=d.get)
Is there a way of getting the min/max N elements?
CL-USER 8 > (reduce #'min '((1) (-1) (3)) :key #'first)
-1
or
CL-USER 9 > (loop for e in '((1) (-1) (3)) minimize (first e))
-1
I fear getting the container element is more difficult:
CL-USER 9 > (defun minimum (list predicate key)
(when list
(let* ((m0 (first list))
(m1 (funcall key m0)))
(mapc (lambda (e0 &aux (e1 (funcall key e0)))
(when (funcall predicate e1 m1)
(psetf m0 e0 m1 e1)))
list)
m0)))
MINIMUM
CL-USER 10 > (minimum '((a 1) (b -1) (c -2)) #'< #'second)
(C -2)
CL-USER 11 > (minimum '((a 1) (b -1)) #'< #'second)
(B -1)
CL-USER 12 > (minimum '((a 1)) #'< #'second)
(A 1)
CL-USER 13 > (minimum '() #'< #'second)
NIL
Use the function provided by the Alexandria library: extremum.
(extremum '((a 3) (b 1) (c 2)) #'< :key #'second)
=> (B 1)

Is there a common lisp macro for popping the nth element from a list?

I'm pretty fresh to the Common Lisp scene and I can't seem to find an quick way to get the nth element from a list and remove it from said list at the same time. I've done it, but it ain't pretty, what I'd really like is something like "pop" but took a second parameter:
(setf x '(a b c d))
(setf y (popnth 2 x))
; x is '(a b d)
; y is 'c
I'm pretty sure that "popnth" would have to be a macro, in case the parameter was 0 and it had to behave like "pop".
EDIT: Here's my crap first version:
(defmacro popnth (n lst)
(let ((tempvar (gensym)))
`(if (eql ,n 0)
(pop ,lst)
(let ((,tempvar (nth ,n ,lst)))
(setf (cdr (nthcdr ,(- n 1) ,lst)) (nthcdr ,(+ n 1) ,lst))
,tempvar))))
Something like this:
Removing the nth element of a list:
(defun remove-nth (list n)
(remove-if (constantly t) list :start n :end (1+ n)))
constantly returns a function, that always returns its argument.
As a macro that accepts a place, using define-modify-macro:
(define-modify-macro remove-nth-f (n) remove-nth "Remove the nth element")
POP-NTH
(defmacro pop-nth (list n)
(let ((n-var (gensym)))
`(let ((,n-var ,n))
(prog1 (nth ,n-var ,list)
(remove-nth-f ,list ,n-var)))))
Example:
CL-USER 26 > (defparameter *list* (list 1 2 3 4))
*LIST*
CL-USER 27 > (pop-nth *list* 0)
1
CL-USER 28 > *list*
(2 3 4)
CL-USER 29 > (pop-nth *list* 2)
4
CL-USER 30 > *list*
(2 3)
Yes, Lisp has a macro for popping the N-th element of a list: it is called pop.
$ clisp -q
[1]> (defvar list (list 0 1 2 3 4 5))
LIST
[2]> (pop (cdddr list))
3
[3]> list
(0 1 2 4 5)
[4]>
pop works with any form that denotes a place.
The problem is that, unlike cddr, nthcdr isn't an accessor; a form like (nthcdr 3 list) does not denote a place; it works only as a function call.
Writing a specialized form of pop is not the best answer; rather, we can achieve a more general fix by writing a clone of nthcdr which behaves like a place accessor. Then the pop macro will work, and so will every other macro that works with places like setf and rotatef.
;; our clone of nthcdr called cdnth
(defun cdnth (idx list)
(nthcdr idx list))
;; support for (cdnth <idx> <list>) as an assignable place
(define-setf-expander cdnth (idx list &environment env)
(multiple-value-bind (dummies vals newval setter getter)
(get-setf-expansion list env)
(let ((store (gensym))
(idx-temp (gensym)))
(values dummies
vals
`(,store)
`(let ((,idx-temp ,idx))
(progn
(if (zerop ,idx-temp)
(progn (setf ,getter ,store))
(progn (rplacd (nthcdr (1- ,idx-temp) ,getter) ,store)))
,store))
`(nthcdr ,idx ,getter)))))
Test:
$ clisp -q -i cdnth.lisp
;; Loading file cdnth.lisp ...
;; Loaded file cdnth.lisp
[1]> (defvar list (list 0 1 2 3 4 5))
LIST
[2]> (pop (cdnth 2 list))
2
[3]> list
(0 1 3 4 5)
[4]> (pop (cdnth 0 list))
0
[5]> list
(1 3 4 5)
[6]> (pop (cdnth 3 list))
5
[7]> list
(1 3 4)
[8]> (pop (cdnth 1 list))
3
[9]> list
(1 4)
[10]> (pop (cdnth 1 list))
4
[11]> list
(1)
[12]> (pop (cdnth 0 list))
1
[13]> list
NIL
[14]>
A possible improvement to the implementation is to analyze the idx form and optimize away the generated code that implements the run-time check on the value of idx. That is to say, if idx is a constant expression, there is no need to emit the code which tests whether idx is zero. The appropriate code variant can just be emitted. Not only that, but for small values of idx, the code can emit special variants based on the "cadavers": cddr, cdddr, rather than the general nthcdr. However, some of these optimizations might be done by the Lisp compiler and thus redundant.
I came up with a solution that is a little more efficient than my first attempt:
(defmacro popnth (n lst)
(let ((t1 (gensym))(t2 (gensym)))
`(if (eql ,n 0)
(pop ,lst)
(let* ((,t1 (nthcdr (- ,n 1) ,lst))
(,t2 (car (cdr ,t1))))
(setf (cdr ,t1) (cddr ,t1))
,t2))))
Here is it in action:
[2]> (defparameter *list* '(a b c d e f g))
*LIST*
[3]> (popnth 3 *list*)
D
[4]> *list*
(A B C E F G)
[5]> (popnth 0 *list*)
A
[6]> *list*
(B C E F G)
I have same suspicion as #6502...If I remember right...Neither push nor pop can be defined as modify-macros, the former because the place is not its first argument, and the latter because its return value is not the modified object.
Definition of define-modify-macro
An expression of the form (define-modify-macro m (p1 ... pn) f) defines a new macro m, such that a call of the form (m place a1 ... an) will cause place to be set to (f val a1 ... an), where val represents the value of place. The parameters may also include rest and optional parameters. The string, if present, becomes the documentation of the new macro.
I have this popnth works just fine:
(defun nthpop (index lst)
(pop (nthcdr (1- index) lst)))
> *list*
(1 2 3 4 5)
> (nthpop 2 *list*)
2
> *list*
(1 3 4 5)