lisp - Why do these both print the same thing? -


i'm curious why using "remove" isn't removing list, if declared in variable, have variable work , becomes messy, code;

    ;;;;pig latin (defun pig-latin ()     (let ((word (read-line)))         (setf ind-characters (loop char across word             collect char))             (setf first-char (car ind-characters))         (setf reversed-word (reverse ind-characters));flips          (remove (last reversed-word) reversed-word)         (print reversed-word))) 

the output is:

(#\d #\r #\o #\w) (#\d #\r #\o #\w) 

i have expected #\w removed second part of output doesn't unless declare in variable. how work single piece of data , remove/add need without declaring lot of variables?

(i thought have been asked before, , there relevant things on stack overflow, didn't find suitable duplicate.)

the issue remove returns new list; doesn't modify existing list. relevant portion hyperspec entry remove (emphasis added):

remove, remove-if, remove-if-not return sequence of same type sequence has same elements except in subsequence bounded start , end , satisfying test have been removed. this non-destructive operation. if elements need removed, result copy. result of remove may share sequence; result may identical input sequence if no elements need removed.

this means need use value returned remove. e.g., return it, bind variable, or assign variable:

(defun remove-1 (list)   (remove 1 list))  ; return result  (let ((list-without-ones (remove 1 list)))  ; bind result   ...)  (setf list (remove 1 list)) ; update variable 

note language includes delete function, can destructive. note, though, doesn't eliminate need save result. means list structure may modified. still need save result, though, because cons cell first in old list might not cons cell that's first in new list. more this, see, instance:


it's worth noting many common lisp functions operate on sequences, not lists. sequences include vectors, of strings subtype. e.g., (reverse "word") return "drow". similarly, can use position-if on sequences. means simple pig latin function can done this:

(defun vowelp (char)   (position char "aeiou" :test 'char-equal))  (defun pig-latin (word)   (let ((i (position-if 'vowelp word))) ; position of first vowel     (if (null i) word                   ; if no vowels, return word       (concatenate 'string              ; else, concatenate parts:                    (subseq word i)      ; * "ord"                    (subseq word 0 i)    ; * "w"                    "ay"))))             ; * "ay" 

Comments