The simple difference is that characters are very cheap to compare. Can eq? use eq? to compare two characters as identical. This is because during compilation, the compiler will essentially list all characters with a number, so you are simply comparing integers, a very cheap job with the machine.
This means that two characters are identical if and only if they consist of the same characters. It is impossible to distinguish two characters that have the same characters in the code, they are constants, they are the same objects, like 3 and 3 .
However, two lines can be different objects located in different places of memory, and to compare them, you need to compare each character separately to match.
Therefore, symbols should be used and are often used for this, for example, given:
(assq 'symb '((foo 1 2 3) (bar symb) (symb "match")))
This returns a list (symb "match") , it's as cheap as a comparison:
(assq 4 '((0 1 2 3) (1 symb) (4 "match")))
Which returns a list (4 "match") . However, when using strings in the form of keys, assq no longer enough, which uses the eq? procedure eq? for comparison, use assoc instead, which uses the equal? , which is much more expensive because it recursively compares the composition. The aforementioned implementation is actually cheap enough to be often used as a way to model associative arrays and environments in interpreters, although this, of course, is not random access.
Edit: as you requested, in threads:
The Scheme standard supports a good pair, one of them is the force function, the other is a special form called delay . Effective that
(delay (+ 1 2 3))
Or any other code instead of (+ 1 2 3) returns this so-called "promise", it delays the calculation of the answer in this promise, but promises that the result will be identical when evaluating this 6 we get there. This may seem completely useless, but let's say that the result depends on some variable that can be changed:
(define x 4) ; x is bound to 4. (let ((promise (delay (+ 2 x)))) ; evaluating the expression now would result into 6, but we delay it. (set! x 5) ; we change the value of x. (display (force promise)) ; displays 7 (set! x 6) ; change it again (force promise) ; ALSO displays 7, not 8 )
It becomes obvious that a promise is truly evaluated only once, and in a forced repetition it gives the same meaning as in the evaluation for the first time.
This is what is commonly used in streams or conceptual "endless lists". The cdr of the list in this case is a promise for the rest of the list, which is forcibly restored, because otherwise it will turn into an inexhaustible calculation, for example, we usually define:
(define (stream-cdr x) (force (cdr x))) ; it forces that promise to evaluate it. ; and optionally (define stream-car car) ; same
Since this argument cannot evaluate its argument, it must be a special form:
(define-syntax stream-cons (syntax-rules () ((stream-cons xy) (cons x (delay y))))
The compiler or interpreter of your circuit now translates each event (stream-cons xy) to (cons x (delay y)) for any arbitrary x and y.
So, as a simple example, now that our estimate is delayed until we need it, we can create an endless list of zeros:
(define zero-stream (stream-cons 0 zero-streams))
The list borrowed on its own, which will undoubtedly never end if we did not use a thread that is useless, but it shows this idea. We can just use stream-cdr again and again on this, without even reaching the empty list, we again get the same "endless list 0".
A more practical example is a list of all Fibonacci numbers, which is more complex:
(define fibs (stream-cons 0 (stream-cons 1 (stream-map + fibs (stream-cdr fibs))))
Stream-map is an analogue of normal display, this definition is quite complicated, but I'm sure you can find it, it generates a stream. So, `(stream-map (lambda (xy) (+ 1 xy)) zeroes zeroes) will create a stream completely filled with one. The flow of fibs is recursively determined by itself. The first two elements are given, and the rest are calculated from two threads, which are simply fibs and the cdr stream of the fibs themselves.