Strings

So far we've learnt about the following types of Lisp object:

  • Numbers, like 2, 4, and 17.
  • Procedure names, like + and list
  • Lists, like (1 2 3 4) and (+ 3 6).

We also learnt that Lisp uses lists for both data and programs. The first list (1 2 3 4) is data, because 1 isn't the name of a procedure. The second list, (+ 3 6), is a procedure call to add 3 and 6 (or it could be data that just happens to look like that procedure call).

Strings

The new type is a string: a sequence of any characters enclosed in double-quotes. So here are three examples:

"ATmega328"
" msec"
""

The last one is the empty string, which contains no characters, but its still a valid and useful string. You can include a double-quote in a string by prefixing it with a backslash:

"He shouted \"Help!\" and ran away."

Now some procedures that work with strings (note that most of these also work with lists):

Finding the length of a string: length

We've already met length with lists. It can also be used to find the length of a string; for example:

> (length "Lisp")
4

Joining strings together: concatenate

The procedure concatenate allows you to join any number of strings together. The second argument is a symbol specifying what type of result you want to return; uLisp only supports string. For example:

> (concatenate 'string "ATmega" "2560")
"ATmega2560"

Testing strings: string=

The procedure string= tests whether two strings are equal. For example:

> (string= "ATmega328" (concatenate 'string "ATmega" "328")
t

Getting a subsequence from a string: subseq

This procedure extracts part of a string. It takes three parameters:

  • the string
  • the number of the first character you want
  • the number of the character one after the last character you want

The characters are counted starting at 0. For example:

> (subseq "ATmega2560" 2 6)
"mega"

If you leave out the third parameter you get the rest of the string to the end.

Printing strings

Here's a useful function pri for printing several strings and variables:

(defun pri (&rest lst)
  (terpri)
  (mapc 'princ lst))

For example, we can use it to print integer data from a sensor stored in variables tmp and hum:

(pri "Temperature: " tmp ", Humidity: " hum)

might print:

Temperature: 23, Humidity: 2

Writing a procedure using strings

Now we're ready to write a procedure using strings. Let's write a simple piglatin program. It takes the first letter of the word, concatenates it to the word with the first letter removed, and adds "ay" on the end:

(defun pig (word)
(concatenate 'string (subseq word 1) (subseq word 0 1) "ay"))

Try it out:

> (pig "pig")
"igpay"

Note that it doesn't work for words beginning with a vowel. This could be fixed with an if construct.

Exercises

1. Rotate a string n places to the left

Write a procedure rot that rotates a string n characters to the left. So, for example:

(rot "mousetrap" 5)

should give:

"trapmouse"