• Re: Another newbie question: if-elseif-elseif-elseif..etc.

    From B. Pym@21:1/5 to Peter Seibel on Mon Sep 2 10:38:55 2024
    Peter Seibel wrote:

    In the C version of my program I have:

    for (i=0; i<nchar; i=i+1) {
    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.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)