Checking a list for patterns in clisp

75 Views Asked by At

I am new to clisp and i had a question about lists

Suppose i have a list of 6 symbols (not strings) in clisp and I want to write a function that checks it for particular properties such as:

  1. the first 3 symbols are single letters
  2. the last 3 symbols are digits

I have been told I am supposed to avoid variable creation and looping functions:

Don't use setf, looping functions like do, while, repeat, or any other side effects


Now there are certain issues i have with this

  1. Slicing the list but i am not sure how i can store the 2 list to actually perform the check on them

  2. How would I actually check if the first 3 symbol is a letter and the last 3 symbol are digits? symbolp comes to mind but if I cannot loop through the list my only option is to recurse through it.

For example:

(mylist '(A A A 0 0 0))
T
1

There are 1 best solutions below

0
coredump On

Note: your requirements are about avoiding side-effects, but "variable creation" is probably not part of that: you mention setf, which affects an existing variable, but you can still use let I think.

Building blocks

I would suggest writing first individual predicate functions that check if symbols satify simple properties. You need to access the symbols' names:

(symbol-name 'a)
=> "A"

Notice how it is in uppercase, in practice the way symbols are read all in uppercase, lowercase (or even other ways) can be modified, but by default symbol names are converted to uppercase.

Once you have a string, you can check the LENGTH:

(length (symbol-name 'abc))
=> 3

Accessing characters in strings is done with CHAR:

(char "Word" 0)
=> #\W

There are also standard functions like ALPHA-CHAR-P that can be useful in your case, but if this is a homework maybe you need to write something on your own. Feel free to ask if this is a problem.

Note also that your lists are assumed to be heterogenous, you just need to check if they satisfy your properties. You can use (typep value 'integer) to check for example if a value is an integer (see TYPEP and INTEGER type).

You may want to use also TYPECASE to perform dispatching based on the type of a value.

Testing your property

Instead of looping, you mentioned you can use recursion, but note that you can also use higher-order functions like EVERY or REDUCE.

But in your case your property can be written recursively; lets write A any symbol that is just a letter, and 0 any digit. Then you want to recognize sequences as follows:

S(n) = AAAA...   ...0000
       ^^^^^^^   ^^^^^^^
       n times   n times

where N = 3 in your case.

Note that you can write S(n) in terms of S(n-1), and you should be able to write a recursive function that matches the kind of lists you want. Here is an example trace with size 2 where my intermediate recursive function P returns a list of two values.

  0: (P (A A 0 0) 2)
    1: (P (A 0 0) 1)
      2: (P (0 0) 0)
      2: P returned (T (0 0))
    1: P returned (T (0))
  0: P returned (T NIL)