This is a read-only archive of lispforum.com. The forum was locked to new users and posts and is preserved here as static HTML from a database snapshot taken on 2019-09-07.

list and string

16 posts · 17914 views

Hello all,

I thought naively that the following code will allow me to print each element of a list and not display the nil element at the end.
Is it normal ?
(setq mylst '(chat chien oiseau lapin))

(loop for n from 0 to (- (length mylst) 1)
 do (print (nth n mylst)))
Do I have to add a condition to check that the nth n mylst is not nill like
(null (nth n mylst))
My main idea is to convert each element as a sub-string like "chat chien oiseau lapin".

Thanks by advance for your help.

Re: list and string

That nil is the value of the loop expression. And better way to print list this was is via format function.
(format t "~{~a~^ ~}" mylst)
cl-2dsyntax is my attempt to create a Python-like reader. My mirror of CLHS (and the dark themed version). Temporary mirrors of aferomentioned: CLHS and a dark version.

Re: list and string

Or
(dolist (el mylst)
  (print el))
Friends don't let friends do LOOP!

Re: list and string

Thanks for the answer but both solution displayed a NIL line.
I don't want the NIL line
Break 4 [6]> (setq mylst '(chat chien oiseau lapin))
(CHAT CHIEN OISEAU LAPIN)
Break 4 [6]> (dolist (el mylst)
(print el))

CHAT
CHIEN
OISEAU
LAPIN
NIL
Break 4 [6]> (format t "~{~a~^ ~}" mylst)
CHAT CHIEN OISEAU LAPIN
NIL
Break 4 [6]> (format t "~{~a~^ ~}" mylst)
CHAT CHIEN OISEAU LAPIN
NIL

Re: list and string

As I said the NIL is an evaluated value of the expression you've entered into REPL (the interactive mode you are woking with). That's how the REPL works:
  • prompts you with a prompt line.
  • you enter an expression.
  • prints whatever you write into the output stream (through print/write functions).
  • prints a value of your expression
  • and loops
If you write your program to a script file and run the interpreter in a script mode (e.g. for the SBCL implementation you have a --script switch at disposal) then you only see what you printed (without your NIL values).
If you are using interactive mode you have some options.
  • Use more modular approach and let the functions return produced values instead of printing them, but the strings will be quoted by #\" characters (as it's standard way of doing it).
  • The another possibility is use values like this:
    (progn (... your code ...) (values))
    The code does the thing that it doesn't return any value, but (I think) it's up to an implementation how it will be represented in REPL. Yeah in SBCL it really is no output, but it doesn't have to be everywhere. Moreover this piece of code is only bloating your code.
I recommend don't be bothered by the NILs at the end, because:
  • you, as a programmer using REPL, know what that NIL means.
  • you, as user, will be using program where the NILs won't be present.
Finally take a look this SLIME session:
http://i.imgur.com/AEgoOc3.png

Printed content and values of expressions are clearly distinguished by color, further, as you can see, no value in SLIME is indicated by the line
; no value
and not just nothing.
cl-2dsyntax is my attempt to create a Python-like reader. My mirror of CLHS (and the dark themed version). Temporary mirrors of aferomentioned: CLHS and a dark version.

Re: list and string

Hello,

In my code, I've a stack overflow problem. Thus, I'm wondering if it exists some debuggers for Windows or Linux?
I've a computer with cygwin under Windows or Ubuntu OS.

Thanks by advance for your help.

Re: list and string

All common-lisp implementations have a debugger built-in, which implementation are you using?

Re: list and string

clisp on cygwin

Re: list and string

Hmm, I see what you mean:
[3]> (defun tato () (tato))

TATO
[4]> (tato)

*** - Program stack overflow. RESET
Clisp does have a debugger, but for program stack overflow it doesn't use it, and just resets.

Infinite recursion is a sticky case, in general, for programs to recover from.

The stack...
  • contains all of the local variables for each function in the current thread of execution.
  • is allocated when a thread is created, with a particular size,
  • cannot be re-sized at run-time, because heap memory might have been allocated next to the stack,
  • cannot be re-located either, because you would need to re-write any pointers to stack locations (which is impossible to do correctly).
The result of this is that when you run out of stack you can't invoke any functions that need local variables (because that would push you even further into danger territory). Some systems keep a chunk of memory aside (in the heap) to store the temporary variables it might need in the event of such a problem, but clisp, apparently, doesn't do that.

Depending on your code you may be able to track the infinite recursion by using TRACE on your suspect function, alternatively you can use one of the clisp methods for starting with an increased stack size (if you don't have infinite recursion, just very deep function calls).

http://www.clisp.org/impnotes.html#faq-stack

Re: list and string

Hello,
I sent you a private message linked to this stack overflow problem.
(defun MyComp (MyInp MyList)
  (cond
    ((and (not MyInp) (not MyList)))
    ((not MyList) nil)
    ((eq (car MyList) '*) 
      (or 
        (MyComp MyInp (cdr MyList)) 
        (MyComp (cdr MyInp) MyList)
     )
    )
    
    ((not MyInp) nil)
    ((eq (char (string (car MyInp)) 0) '#\?)
      (and 
        (> (length (car MyInp)) 1) 
        (put 'Variables (MyFirst (car MyList)) (car (MyInp)))
      )
      (MyComp (cdr MyInp) (cdr MyList)) )

    ((eql (car MyInp) (car MyList)) (MyComp (cdr MyInp) (cdr MyList))) 
  )
)

;; Normally, its the first atom without the 1st caracter
(defun MyFirst (MySubList)
  (print MySubList)
)
with MyFirst is a function which returns the 1st element without the 1st caracter.

Re: list and string

I'm sorry for taking so long to reply, I've been super busy this week and when I got your private message I got surprisingly distracted by all the comments and names in French (though, in fairness, my last lesson in high school French was in 1996)

It looks sort of like you are implementing some kind of fuzzy matcher, but I think you got confused somewhere.

It also looks like you are using READ to produce symbols instead of using strings directly, which I consider an anti-pattern, are you following a book?

Re: list and string

Hello,
Thanks for your reply, I've to use pattern-matcher but it's not so easy as I though it at the beginning.
I think in my code the match function is not working correctly but it's quite not easy to debug as I haven't a IDE debbuger.

Re: list and string

Hello again,

I've put some traces in the code in order to identify which part is not working correctly. I've also modified the code in order to first have a eliza version working and after that add some regexp pattern-matching features.

The code is working, the only thing which is not working in this release is the "exit" part. When I type "au revoir"; the code should reply and exit but it's not working as-is.
Could you have a look on it for a different point of view ?
(setf *default-file-encoding* charset:utf-8)

;;(requires "Exo_36_Tools")

;;============================================================
;; Programme principal
;;============================================================
(defun Eliza (patterns)
  ;; Boucle infinie tant que le terme est connu
  (loop    
    ;;--------------------------------------------------------------------------
    ;; Entree clavier
    (setq MyInput (read-input))
    ;;(format t "***DEBUG***: MyInput: ~A~%" MyInput)
    
    ;; Cle associative
    (setq MyKeyw (assoc MyInput patterns :test #'match))
    ;;(format t "***DEBUG***: MyKeyw: ~A~%" MyKeyw)
    
    ;; Valeur de la cle associative 
    (setq MyAnsw (cdr MyKeyw))
    ;;(format t "***DEBUG***: MyAnsw: ~A~%~%" MyAnsw)
    
    ;; Imprime la reponse (MyAnsw est une liste)
    (answer MyAnsw)
    ;;--------------------------------------------------------------------------
  )
)

;;============================================================
;; Cette fonction lit une entree et renvoie une liste de mots
;; sous forme de chaine de caractere (String)
;;============================================================
(defun read-input ()
  ;; Lecture de l'entree terminal
  (read-from-string 
    ;; Concatene plusieurs mots en chaine de caractere "( <mots> )"
    (concatenate 'string 
      ;; Remplace les signes de ponctuation
      "(" (substitute-if #\SPACE #'no-punct (read-line)) 
      ")"
    )
  )
)

;;============================================================
;; Cette fonction cherche des signes de ponctuation
;;============================================================
(defun no-punct(char)
  ;; '\' est utilise pour les signes speciaux ex: \"
  (find char ",;!:'\"\(\)-")
)

;;============================================================
;; Cette fonction est en charge de tester le pattern matching
;;============================================================
(defun match (input-form pattern)
  ;;**************
  ;; *** DEBUG ***
  ;;**************
  (format t "***DEBUG***: Function match ~%")
  (format t "***DEBUG***:  |_input-form: ~A~%" input-form)
  (format t "***DEBUG***:  |_pattern: ~A~%" pattern)
  ;;==============
  
  (cond
    ;;((and (not input-form) (not pattern)) (format t "***DEBUG***: not - not~%"))
    
    ;; La forme d entree et le patron sont finis
    ((and (not input-form) (not pattern)))
    ;; Il reste encore un element dans la liste pattern
    ((not pattern) nil)
    ;; On compare element par element (input-form vs. pattern) recursivement
    ((eql (car input-form) (car pattern)) (match (cdr input-form) (cdr pattern)))
    
    ;;((eql (car input-form) (car pattern)) (format t "on recurse ~A ~%" (cdr input-form))
    
    ;; Le 1er element du patron contient un joker '*'
    ;;((eq (car pattern) '*) 
    ;;  (or 
    ;;    (match input-form (cdr pattern)) 
    ;;    (match (cdr input-form) pattern)
    ;; )
    ;;)
    ;; La forme d entree n est pas fini
    ;;((not input-form) nil)
    ;;((eq (char (string (car input-form)) 0) '#\?)
    ;;  (and 
    ;;    (> (length (car input-form)) 1) 
    ;;    (put 'Variables (butfirst (car pattern)) (car (input-form)))
    ;;)
    ;;((match (cdr input-form) (cdr pattern)) )
  )
)

;;============================================================
;; Cette fonction convertit une liste en chaine
;;============================================================
(defun ConvLstToStr (MyAnsList)
  ;; Transforme la liste en chaine de caractere
  (setq MyAnsStr (format nil "~A" MyAnsList))
  ;; Calcule la longueur de la chaine
  (setq MyLen (length MyAnsStr))
  ;; Supprime les parentheses ()
  (setq MyResStr (remove #\) (remove #\( MyAnsStr)))
)

;;============================================================
;; Cette fonction est en charge d imprimer la reponse
;;============================================================
(defun print-output (output-pattern)
  ;;**************
  ;; *** DEBUG ***
  ;;**************
  ;;(format t "***DEBUG***: Function print-output ~%")
  ;;(format t "***DEBUG***:  |_MyOutp: ~A~%" output-pattern)
  ;;==============
  
  (cond
    ;; Test si l'objet output-pattern est atomique
    ((atom output-pattern) (not output-pattern))
    ;; Sinon on imprime mot par mot de facon recursive
    (t (format t "~A~%" (ConvLstToStr (car output-pattern))) (print-output (cdr output-pattern)))
  )
  
  ;;**************
  ;; *** DEBUG ***
  ;;**************
  ;;(format t "***DEBUG***: End of function print-output ~%")
  ;;==============
)

;;============================================================
;; Cette fonction est en charge de la reponse
;;============================================================
(defun answer (output-pattern)
  ;;**************
  ;; *** DEBUG ***
  ;;**************
  ;;(format t "***DEBUG***: Function answer ~%")
  ;;(format t "***DEBUG***:  |_MyOutp: ~A~%" output-pattern)
  ;;==============
  
  (cond
    ;; Test si l'objet est atomique
    ((atom output-pattern) (print "Je n ai pas bien compris ; reformulez s il vous plait.") (terpri) t)
      ;; Non, on imprime la chaine
    (t (print-output output-pattern))
  )
  
  ;;**************
  ;; *** DEBUG ***
  ;;**************
  ;;(format t "***DEBUG***: End of function answer ~%")
  ;;==============
)

;;============================================================
;; Definition des patrons de reponse a utiliser
;;============================================================
;;[Laurence Ferrari] : Bonjour Francois Hollande
;;[Francois Hollande]: Bonjour Laurence Ferrari 
;;[Laurence Ferrari] : Francois Hollande, quel president comptez-vous etre?
;;[Francois Hollande]: Un president qui d abord respecte les francais, qui les
;;                     considerent.
;;[Laurence Ferrari] : Pouvez-vous developper?
;;[Francois Hollande]: Un president qui ne veut pas etre president de tout, 
;;                     chef de tout et en definitive responsable de rien.
;;[Laurence Ferrari] : Quelle serait votre vision de la separation des pouvoirs?
;;[Francois Hollande]: Moi president de la republique, je ne serais pas le chef
;;                     de la majorite, je ne recevrais pas les parlementaires de
;;                     la majorite a l Elysee.
;;[Laurence Ferrari] : Quels seront vos rapports avec votre premier ministre?
;;[Francois Hollande]: Moi president de la republique, je ne traiterais pas mon 
;;                     premier ministre de collaborateur.
;;[Laurence Ferrari] : Passons outre le terme collaborateur, continuez svp.
;;[Francois Hollande]: Moi president de la republique, je ne participerai pas a
;;                     des collectes de fond pour mon propre parti dans un 
;;                     hotel parisien.
;;[Laurence Ferrari] : Quel sera votre role dans la justice?
;;[Francois Hollande]: Moi president de la republique, je ferais fonctionner la 
;;                     justice de maniere independante. Je ne nommerais pas les
;;                     membres du parquet alors que l avis du conseil superieur 
;;                     de la magistrature n a pas ete dans ce sens.
;;[Laurence Ferrari] : Concernant les chaines de television publiques, quel sera
;;                     votre role?
;;[Francois Hollande]: Moi president de la republique, je n aurais pas la 
;;                     pretention de nommer les directeurs des chaines de 
;;                     television publiques,je laisserais ca a des instances 
;;                     independantes.
;;[Laurence Ferrari] : Quel comportement adopteriez-vous?
;;[Francois Hollande]: Moi president de la republique, je ferais en sorte que 
;;                     mon comportement soit a chaque instant exemplaire.
;;[Laurence Ferrari] : Envisagez-vous une reforme de statut penal du chef
;;                     de l etat?
;;[Francois Hollande]: Moi president de la republique, j aurais aussi a coeur de
;;                     ne pas avoir un statut penal du chef de l etat, je le 
;;                     ferais reforme de facon a ce que si des actes anterieurs
;;                     a ma prise de fonction viennent a etre conteste je puisse
;;                     dans certaines conditions me rendre a la convocation de 
;;                     tel ou tel magistrat ou m expliquer devant un certain 
;;                     nombre d instances.
;;[Laurence Ferrari] : Avez-vous reflechi a votre futur gouvernement?
;;[Francois Hollande]: Moi president de la republique, je constituerais un 
;;                     gouvernement qui sera paritaire autant de femme que 
;;                     d homme.
;;============================================================

(setq *Dialog_normal*
  ;;'(((bonjour * hollande *)
  '(((Bonjour Francois Hollande)
     (Bonjour Laurence Ferrari))
     
    ;;((francois hollande * president * comptez * etre *)
    ((Francois Hollande quel president comptez vous etre)
     (Un president qui d abord respecte les francais qui les considerent))
    
    ;;((pouvez * developper)
    ((Pouvez vous developper)
     (Un president qui ne veut pas etre president de tout chef de tout et en
      definitive responsable de rien))
    
    ;((* rapports * premier ministre *) 
    ((Quels seront vos rapports avec votre premier ministre) 
     (Moi president de la republique je ne traiterai pas mon premier ministre
      de collaborateur))
    
    ;;((* vision * separation * pouvoir)
    ((Quelle serait votre vision de la separation des pouvoirs)
     (Moi president de la republique je ne serais pas le chef de la majorite
      je ne recevrais pas les parlementaires de la majorite a L elysee))
    
    ;;((passons * terme * collaborateur *)
    ((Passons outre le terme de collaborateur continuez svp)
     (Moi president de la republique je ne participerai pas a des collectes de 
      fond pour mon propre parti dans un hotel parisien))

    ;;((* role * justice *)
    ((Quel sera votre role dans la justice)
     (Moi president de la republique je ferais fonctionner la justice de maniere
      independante Je ne nommerais pas les membres du parquet alors que L avis 
      du conseil superieur de la magistrature n a pas ete dans ce sens))

    ;;((* television publique * role *)
    ((Concernant les chaines de television publique quel sera votre role)
     (Moi president de la republique je n aurais pas la pretention de nommer les
      directeurs des chaines de television publique je laisserais ca a des
      instances independantes))

    ;;((* comportement * adopteriez * vous)
    ((Quel comportement adopteriez vous)
     (Moi president de la republique je ferais en sorte que mon comportement
      soit a chaque instant exemplaire))
    
    ;;((* reforme * statut penal * chef * etat)
    ((Envisagez vous une reforme de statut penal du chef de l etat)
     (Moi president de la republique j aurais aussi a coeur de ne pas avoir un
      statut penal du chef de L etat je le ferais reformer de facon a ce que si
      des actes anterieurs a ma prise de fonction viennent a etre conteste je 
      puisse dans certaines conditions me rendre a la convocation de tel ou tel 
      magistrat ou m expliquer devant un certain nombre d instances))

    ;;((* reflechi * futur gouvernement)
    ((Avez vous reflechi a votre futur gouvernement)
     (Moi president de la republique je constituerais un gouvernement qui sera 
      paritaire autant de femme que d homme))
    
    ;;((* merci * hollande * repondu * questions *)
    ((merci francois hollande d avoir repondu a mes questions)
     (Merci Laurence Ferrari de m avoir invite))
    
    ((au revoir) au revoir . fin)
    ((a bientot) au revoir . fin)
   )
)

Re: list and string

There doesn't appear to be anything in your program to end the loop, why do you think that "au revoir" would?

Edit: Grammar!

Re: list and string

Hello,
Sorry for the grammar.

Normally, when the code get the "." and "FIN" keywords, the infinite loop should stop.
Don't know how to detect this sequence "." and "FIN" to stop the loop. Do you have some clues or example for doing that ?

Re: list and string

You have an infinite loop, (the LOOP form in `eliza` has no keywords that would limit it (like stepping over a list, mapping a hash-table, iterating a vector, or counting up to a number) and it doesn't have a `(return)` either.

You could return a value that tells your outer loop to stop, or there are a number of non-local return approaches you could employ (THROW and CATCH, SIGNAL and HANDLER-BIND, amongst others),