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, appends 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"