Path: ...!feeds.phibee-telecom.net!2.eu.feeder.erje.net!feeder.erje.net!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail From: "B. Pym" Newsgroups: comp.lang.lisp Subject: Re: Another newbie question: if-elseif-elseif-elseif..etc. Date: Mon, 2 Sep 2024 10:38:55 -0000 (UTC) Organization: A noiseless patient Spider Lines: 106 Message-ID: MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Injection-Date: Mon, 02 Sep 2024 12:38:56 +0200 (CEST) Injection-Info: dont-email.me; posting-host="be16f105eb25ffb81fdb5ad4c116404b"; logging-data="2964722"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX185pO/sNtlEBQ+RGw8uPA4J" User-Agent: XanaNews/1.18.1.6 Cancel-Lock: sha1:Z8LA6yPf2vwHHQfVciOUHSXV3Nk= Bytes: 4416 Peter Seibel wrote: > > In the C version of my program I have: > > > > for (i=0; i > if (tmp[i]>=0 && tmp[i]<=31) { > > dat[i]=tmp[i]+128;} > > else if (tmp[i]>=32 && tmp[i]<=63) { > > dat[i]=tmp[i];} > > else if (tmp[i]>=64 && tmp[i]<=95) { > > dat[i]=tmp[i]-64;} > > else if (tmp[i]>=128 && tmp[i]<=159) { > > dat[i]=tmp[i]+64;} > > else if (tmp[i]>=160 && tmp[i]<=191) { > > dat[i]=tmp[i]-64;} > > else if (tmp[i]>=192 && tmp[i]<=223) { > > dat[i]=tmp[i]-128; > > } > > } > > > > I'd like to achieve the same thing in Common Lisp (Clisp). But I'm > > confused by the fact that there doesn't seem to be an elseif > > construct. I see there is an if-then-else though. > > > > Part of my problem is likely due to the fact that I'm slavishly > > translating the C form into Lisp, when I should really be thinking > > in different terms. That is, I probably need to do this in an > > entirely new way - one, unfortunately, I cannot see at the moment. > > > > Can anyone give me an idea of how this type of thing should be done in > > Lisp? > > Try COND. > > (loop for i from 0 below nchar > for e across tmp do > (cond > ((>= 0 e 31) (setf (aref dat i) (+ e 128))) > ((>= 32 e 63) (setf (aref dat i) e)) > ((>= 64 e 95) (setf (aref dat i) (- e 64))) > ((>= 128 e 159) (setf (aref dat i) (+ e 64))) > ((>= 160 e 191) (setf (aref dat i) (- e 64))) > ((>= 192 e 223) (setf (aref dat i) (- e 128))))) > > Or even: > > (loop for i from 0 below nchar > for e across tmp do > (setf (aref dat i) > (+ e (cond > ((>= 0 e 31) 128) > ((>= 32 e 63) 0) > ((>= 64 e 95) -64) > ((>= 128 e 159) 64) > ((>= 160 e 191) -64) > ((>= 192 e 223) -128) Kenny Tilton wrote: > > (loop for i from 0 below nchar > > for e across tmp do > > (setf (aref dat i) > > (+ e (cond > > ((>= 0 e 31) 128) > > ((>= 32 e 63) 0) > > ((>= 64 e 95) -64) > > ((>= 128 e 159) 64) > > ((>= 160 e 191) -64) > > ((>= 192 e 223) -128) > > Nice. But the cond is not exhaustive and would return nil for e from 96 > to 127 or above 223, so perhaps a final clause is desirable: Two CL gurus thought that that nonsense made sense. But does it? I can't think of a number e that satisfies (>= 0 e 31). [In other words, 0 >= e and e >= 31.] Let's see if we can find one. (do ((e -1 (+ 1 e))) ((> e 32)) (format #t "~d: ~a " e (cond ((>= 0 e 31) 'Yes) (#t '_)))) -1: _ 0: _ 1: _ 2: _ 3: _ 4: _ 5: _ 6: _ 7: _ 8: _ 9: _ 10: _ 11: _ 12: _ 13: _ 14: _ 15: _ 16: _ 17: _ 18: _ 19: _ 20: _ 21: _ 22: _ 23: _ 24: _ 25: _ 26: _ 27: _ 28: _ 29: _ 30: _ 31: _ 32: _ No, it seems that there is no such number. Perhaps it should be (<= 0 e 31). (do ((e -1 (+ 1 e))) ((> e 32)) (format #t "~d: ~a " e (cond ((<= 0 e 31) 'Yes) (#t '_)))) -1: _ 0: Yes 1: Yes 2: Yes 3: Yes 4: Yes 5: Yes 6: Yes 7: Yes 8: Yes 9: Yes 10: Yes 11: Yes 12: Yes 13: Yes 14: Yes 15: Yes 16: Yes 17: Yes 18: Yes 19: Yes 20: Yes 21: Yes 22: Yes 23: Yes 24: Yes 25: Yes 26: Yes 27: Yes 28: Yes 29: Yes 30: Yes 31: Yes 32: _ If two "CL gurus" agree on something, it's probably wrong.