Lists and Objects

From MemCP
Revision as of 15:32, 17 May 2024 by Carli (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

Lists are a powerful feature in Scheme. Lists can express both: Data and Programs.

List handling

The following list functions can be used:

> '(1 2 3) "list literal"
= (1 2 3)

> (cons 0 '(1 2 3)) "prepend item to list"
= (0 1 2 3)

> (append '(1 2 3) 4 5) "append items to list"
= (1 2 3 4 5)

> (has? '(1 2 3) 2) "check if item is in list"
= true

> (filter '(1 2 3) (lambda (x) (< x 2))) "filter items that are smaller than 2"
= (1)

> (map '(1 2 3) (lambda (x) (* x 2))) "double all numbers"
= (2 4 6)

> (reduce '(1 2 3) + 0) "build sum by starting with 0 and reducing them over (+ 0 value)"
= 6

Associative Lists (Objects)

The following functions can be used:

> (set obj '("a" 1 "b" 2 "c" 3)) /* construct object from a list with alternating key-value */
= ("a" 1 "b" 2 "c" 3)

> (obj "a") /* extract a value */
= 1

> (set_assoc obj "a" "5") /* construct a new object with another value */
= ("a" "5" "b" 2 "c" 3)

> (set obj (set_assoc obj "a" "5")) /* modify obj */
= ("a" "5" "b" 2 "c" 3)


> (filter_assoc obj (lambda (key value) (not (equal? key "c")))) /* filter an object by a condition */
= ("a" 1 "b" 2)

> (map_assoc obj (lambda (key value) (* value 2))) /* double all values */
= ("a" 2 "b" 4 "c" 6)

> (reduce_assoc obj (lambda (accumulator key value) (+ accumulator value)) 0) /* sum up all values */
= 6

As you see in set_assoc, we have a pure functional approach here. Objects are not modified in-place like in languages like Java, JavaScript, Python, C++ or such, but rather we have to construct a modified copy of that value and overwrite it to the original value. The Scheme optimizer will detect if an in-place operation would be safe, too and can optimize this corner case but the language itself prioritizes safety.

Code JITing with List Literals

One can construct lists that themselves represent code. You need basically three primitives:

  • List Literals
  • Symbol Literals
  • (cons list [LIST]) to insert a list literal into the code

All other primitive values like strings, numbers etc. will just be passed through without interpretation.

> (set my_program '('print "Hello World"))
= (print "Hello World")

> (eval my_program)
Hello World