Slices in Scheme

; Slices are an important data type in Scheme, giving
; a more powerful interface to sequences than arrays.

; Unlike arrays, lists in Scheme are not typed by their elements.
; An empty list is represented by '() and has length 0.
(define s '())
(display "uninit: ")
(display s)
(display " ")
(display (null? s))
(display " ")
(display (= (length s) 0))
(newline)

; To create a list with non-zero length, we can use `make-list`.
; Here we make a list of 3 elements (initially #f).
(define s (make-list 3))
(display "emp: ")
(display s)
(display " len: ")
(display (length s))
(newline)

; We can set and get just like with arrays.
(set! s (list "a" "b" "c"))
(display "set: ")
(display s)
(newline)
(display "get: ")
(display (list-ref s 2))
(newline)

; `length` returns the length of the list as expected.
(display "len: ")
(display (length s))
(newline)

; In addition to these basic operations, lists support
; several more that make them richer than arrays.
; One is `append`, which returns a list containing
; one or more new values.
(set! s (append s '("d")))
(set! s (append s '("e" "f")))
(display "apd: ")
(display s)
(newline)

; Lists can also be copied. Here we create a new list `c`
; with the same elements as `s`.
(define c (list-copy s))
(display "cpy: ")
(display c)
(newline)

; Lists support a "slice" operator with the `list-tail` and `take` procedures.
; For example, this gets a slice of the elements s[2], s[3], and s[4].
(define l (take (list-tail s 2) 3))
(display "sl1: ")
(display l)
(newline)

; This slices up to (but excluding) the 5th element.
(set! l (take s 5))
(display "sl2: ")
(display l)
(newline)

; And this slices up from (and including) the 3rd element.
(set! l (list-tail s 2))
(display "sl3: ")
(display l)
(newline)

; We can declare and initialize a variable for list
; in a single line as well.
(define t '("g" "h" "i"))
(display "dcl: ")
(display t)
(newline)

; Scheme doesn't have a built-in `slices` package, but we can
; define our own equality function for lists.
(define (lists-equal? l1 l2)
  (and (= (length l1) (length l2))
       (every (lambda (x y) (equal? x y)) l1 l2)))

(define t2 '("g" "h" "i"))
(when (lists-equal? t t2)
  (display "t == t2")
  (newline))

; Lists can be composed into multi-dimensional data
; structures. The length of the inner lists can
; vary, unlike with multi-dimensional arrays.
(define twoD
  (list
    (list 0)
    (list 1 2)
    (list 2 3 4)))
(display "2d: ")
(display twoD)
(newline)

This Scheme code demonstrates the equivalent concepts of slices in Go using Scheme’s built-in list data structure. Scheme’s lists are similar to Go’s slices in many ways, offering dynamic sizing and various operations for manipulation.

Note that Scheme doesn’t have a direct equivalent to Go’s slices, as Scheme uses lists as its primary sequence type. Lists in Scheme are typically implemented as linked lists, which behave differently from Go’s slices in terms of performance characteristics, especially for operations like random access.

The concepts of length, appending, copying, and slicing are all present, though implemented differently. For example, Scheme uses append for adding elements, list-tail and take for slicing, and list-copy for copying.

Multi-dimensional structures in Scheme are simply lists of lists, which can have varying lengths, similar to how slice of slices work in Go.

Remember that while this code demonstrates similar concepts, the underlying implementation and performance characteristics of Scheme lists are quite different from Go slices.