base.scm 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379
  1. ; -*- Mode: Scheme; Syntax: Scheme; Package: Scheme; -*-
  2. ; Copyright (c) 1993-2008 by Richard Kelsey and Jonathan Rees. See file COPYING.
  3. ; This is file base.scm.
  4. ;;;; Fundamental definitions
  5. ; Order of appearance is approximately that of the Revised^4 Report.
  6. ; Booleans
  7. (define (not x) (if x #f #t))
  8. (define (boolean? x) (or (eq? x #t) (eq? x #f)))
  9. ; Equality
  10. (define (eqv? x y)
  11. (or (eq? x y)
  12. (and (number? x)
  13. (number? y)
  14. (eq? (exact? x) (exact? y))
  15. (= x y))))
  16. (define (equal? obj1 obj2)
  17. (cond ((eqv? obj1 obj2) #t)
  18. ((pair? obj1)
  19. (and (pair? obj2)
  20. (equal? (car obj1) (car obj2))
  21. (equal? (cdr obj1) (cdr obj2))))
  22. ((string? obj1)
  23. (and (string? obj2)
  24. (string=? obj1 obj2)))
  25. ((vector? obj1)
  26. (and (vector? obj2)
  27. (let ((z (vector-length obj1)))
  28. (and (= z (vector-length obj2))
  29. (let loop ((i 0))
  30. (cond ((= i z) #t)
  31. ((equal? (vector-ref obj1 i) (vector-ref obj2 i))
  32. (loop (+ i 1)))
  33. (else #f)))))))
  34. (else #f)))
  35. ; Messy because of inexact contagion.
  36. (define (max first . rest)
  37. (max-or-min first rest #t))
  38. (define (min first . rest)
  39. (max-or-min first rest #f))
  40. (define (max-or-min first rest max?)
  41. (let loop ((result first) (rest rest) (lose? (inexact? first)))
  42. (if (null? rest)
  43. (if (and lose? (exact? result))
  44. (exact->inexact result)
  45. result)
  46. (let ((next (car rest)))
  47. (loop (if (if max?
  48. (< result next)
  49. (> result next))
  50. next
  51. result)
  52. (cdr rest)
  53. (or lose? (inexact? next)))))))
  54. (define (abs n) (if (< n 0) (- 0 n) n))
  55. (define (zero? x) (= x 0))
  56. (define (positive? x) (< 0 x))
  57. (define (negative? x) (< x 0))
  58. (define (even? n) (= 0 (remainder n 2)))
  59. (define (odd? n) (not (even? n)))
  60. ; Lists
  61. (define (caar x) (car (car x)))
  62. (define (cadr x) (car (cdr x)))
  63. (define (cdar x) (cdr (car x)))
  64. (define (cddr x) (cdr (cdr x)))
  65. (define (caaar x) (caar (car x)))
  66. (define (caadr x) (caar (cdr x)))
  67. (define (cadar x) (cadr (car x)))
  68. (define (caddr x) (cadr (cdr x)))
  69. (define (cdaar x) (cdar (car x)))
  70. (define (cdadr x) (cdar (cdr x)))
  71. (define (cddar x) (cddr (car x)))
  72. (define (cdddr x) (cddr (cdr x)))
  73. (define (caaaar x) (caaar (car x)))
  74. (define (caaadr x) (caaar (cdr x)))
  75. (define (caadar x) (caadr (car x)))
  76. (define (caaddr x) (caadr (cdr x)))
  77. (define (cadaar x) (cadar (car x)))
  78. (define (cadadr x) (cadar (cdr x)))
  79. (define (caddar x) (caddr (car x)))
  80. (define (cadddr x) (caddr (cdr x)))
  81. (define (cdaaar x) (cdaar (car x)))
  82. (define (cdaadr x) (cdaar (cdr x)))
  83. (define (cdadar x) (cdadr (car x)))
  84. (define (cdaddr x) (cdadr (cdr x)))
  85. (define (cddaar x) (cddar (car x)))
  86. (define (cddadr x) (cddar (cdr x)))
  87. (define (cdddar x) (cdddr (car x)))
  88. (define (cddddr x) (cdddr (cdr x)))
  89. (define (null? x) (eq? x '()))
  90. (define (list . l) l)
  91. ;(define (length l)
  92. ; (reduce (lambda (ignore n) (+ n 1)) 0 l))
  93. ; Bummed version. Pretend that you didn't see this.
  94. (define (length l)
  95. (real-length l 0))
  96. (define (real-length l r)
  97. (if (null? l)
  98. r
  99. (real-length (cdr l) (+ r 1))))
  100. (define (append . lists)
  101. (if (null? lists)
  102. '()
  103. (let recur ((lists lists))
  104. (if (null? (cdr lists))
  105. (car lists)
  106. (reduce cons (recur (cdr lists)) (car lists))))))
  107. (define (reverse list)
  108. (append-reverse list '()))
  109. (define (append-reverse list seed)
  110. (if (null? list)
  111. seed
  112. (append-reverse (cdr list) (cons (car list) seed))))
  113. (define (list-tail l i)
  114. (cond ((= i 0) l)
  115. (else (list-tail (cdr l) (- i 1)))))
  116. (define (list-ref l k)
  117. (car (list-tail l k)))
  118. (define (mem pred)
  119. (lambda (obj l)
  120. (let loop ((l l))
  121. (cond ((null? l) #f)
  122. ((pred obj (car l)) l)
  123. (else (loop (cdr l)))))))
  124. (define memq (mem eq?))
  125. (define memv (mem eqv?))
  126. (define member (mem equal?))
  127. (define (ass pred)
  128. (lambda (obj l)
  129. (let loop ((l l))
  130. (cond ((null? l) #f)
  131. ((pred obj (caar l)) (car l))
  132. (else (loop (cdr l)))))))
  133. ;(define assq (ass eq?)) ; done by VM for speed
  134. (define assv (ass eqv?))
  135. (define assoc (ass equal?))
  136. (define (list? l) ;New in R4RS
  137. (let recur ((l l) (lag l)) ;Cycle detection
  138. (or (null? l)
  139. (and (pair? l)
  140. (or (null? (cdr l))
  141. (and (pair? (cdr l))
  142. (not (eq? (cdr l) lag))
  143. (recur (cddr l) (cdr lag))))))))
  144. ; Characters
  145. (define (char>? x y) (char<? y x))
  146. (define (char>=? x y) (not (char<? x y)))
  147. (define (char<=? x y) (not (char>? x y)))
  148. ; Strings
  149. (define (string . rest)
  150. (list->string rest))
  151. (define (substring s start end)
  152. (let ((new-string (make-string (- end start) #\space)))
  153. (do ((i start (+ i 1))
  154. (j 0 (+ j 1)))
  155. ((= i end) new-string)
  156. (string-set! new-string j (string-ref s i)))))
  157. (define (string-append . strings)
  158. (let ((len (reduce (lambda (s n) (+ (string-length s) n)) 0 strings)))
  159. (let ((new-string (make-string len #\space)))
  160. (let loop ((s strings)
  161. (i 0))
  162. (if (null? s)
  163. new-string
  164. (let* ((string (car s))
  165. (l (string-length string)))
  166. (do ((j 0 (+ j 1))
  167. (i i (+ i 1)))
  168. ((= j l) (loop (cdr s) i))
  169. (string-set! new-string i (string-ref string j)))))))))
  170. (define (string->list v)
  171. (let ((z (string-length v)))
  172. (do ((i (- z 1) (- i 1))
  173. (l '() (cons (string-ref v i) l)))
  174. ((< i 0) l))))
  175. (define (list->string l)
  176. (let ((v (make-string (length l) #\space)))
  177. (do ((i 0 (+ i 1))
  178. (l l (cdr l)))
  179. ((null? l) v)
  180. (string-set! v i (car l)))))
  181. ; comes from low-level package ...
  182. ;(define (string-copy s)
  183. ; (let ((z (string-length s)))
  184. ; (let ((copy (make-string z #\space)))
  185. ; (let loop ((i 0))
  186. ; (cond ((= i z) copy)
  187. ; (else
  188. ; (string-set! copy i (string-ref s i))
  189. ; (loop (+ i 1))))))))
  190. (define (string-fill! v x)
  191. (let ((z (string-length v)))
  192. (do ((i 0 (+ i 1)))
  193. ((= i z) (unspecific))
  194. (string-set! v i x))))
  195. (define (make-string=? char=?)
  196. (lambda (s1 s2)
  197. (let ((z (string-length s1)))
  198. (and (= z (string-length s2))
  199. (let loop ((i 0))
  200. (cond ((= i z) #t)
  201. ((char=? (string-ref s1 i) (string-ref s2 i))
  202. (loop (+ i 1)))
  203. (else #f)))))))
  204. ;(define string=? (make-string=? char=?)) -- VM implements this
  205. (define string-ci=?-proc (make-string=? char-ci=?))
  206. (define (string-ci=? s1 s2)
  207. (string-ci=?-proc s1 s2))
  208. (define (make-string<? char<? char=?)
  209. (lambda (s1 s2)
  210. (let ((z1 (string-length s1))
  211. (z2 (string-length s2)))
  212. (let ((z (min z1 z2)))
  213. (let loop ((i 0))
  214. (if (= i z)
  215. (< z1 z2)
  216. (let ((c1 (string-ref s1 i))
  217. (c2 (string-ref s2 i)))
  218. (or (char<? c1 c2)
  219. (and (char=? c1 c2)
  220. (loop (+ i 1)))))))))))
  221. (define string<? (make-string<? char<? char=?))
  222. (define string-ci<?-proc (make-string<? char-ci<? char-ci=?))
  223. (define (string-ci<? s1 s2)
  224. (string-ci<?-proc s1 s2))
  225. (define (string>? s1 s2) (string<? s2 s1))
  226. (define (string<=? s1 s2) (not (string>? s1 s2)))
  227. (define (string>=? s1 s2) (not (string<? s1 s2)))
  228. (define (string-ci>? s1 s2) (string-ci<? s2 s1))
  229. (define (string-ci<=? s1 s2) (not (string-ci>? s1 s2)))
  230. (define (string-ci>=? s1 s2) (not (string-ci<? s1 s2)))
  231. (define (set-string-ci-procedures! ci=? ci<?)
  232. (set! string-ci=?-proc ci=?)
  233. (set! string-ci<?-proc ci<?))
  234. ; Vectors
  235. ;(define (vector . l) ; now an opcode for efficiency
  236. ; (list->vector l))
  237. (define (vector->list v)
  238. (do ((i (- (vector-length v) 1) (- i 1))
  239. (l '() (cons (vector-ref v i) l)))
  240. ((< i 0) l)))
  241. (define (list->vector l)
  242. (let ((v (make-vector (length l) #f)))
  243. (do ((i 0 (+ i 1))
  244. (l l (cdr l)))
  245. ((null? l) v)
  246. (vector-set! v i (car l)))))
  247. (define (vector-fill! v x)
  248. (let ((z (vector-length v)))
  249. (do ((i 0 (+ i 1)))
  250. ((= i z) (unspecific))
  251. (vector-set! v i x))))
  252. ; Control features
  253. (define (map proc first . rest)
  254. (if (null? rest)
  255. (map1 proc first)
  256. (map2+ proc first rest)))
  257. (define (map1 proc l)
  258. ;; (reduce (lambda (x l) (cons (proc x) l)) '() l)
  259. (if (null? l)
  260. '()
  261. (cons (proc (car l)) (map1 proc (cdr l)))))
  262. (define (map2+ proc first rest)
  263. (if (or (null? first)
  264. (any null? rest))
  265. '()
  266. (cons (apply proc (cons (car first) (map1 car rest)))
  267. (map2+ proc (cdr first) (map1 cdr rest)))))
  268. (define (for-each proc first . rest)
  269. (if (null? rest)
  270. (for-each1 proc first)
  271. (for-each2+ proc first rest)))
  272. (define (for-each1 proc first)
  273. (let loop ((first first))
  274. (if (null? first)
  275. (unspecific)
  276. (begin (proc (car first))
  277. (loop (cdr first))))))
  278. (define (for-each2+ proc first rest)
  279. (let loop ((first first) (rest rest))
  280. (if (or (null? first)
  281. (any null? rest))
  282. (unspecific)
  283. (begin (apply proc (cons (car first) (map car rest)))
  284. (loop (cdr first) (map cdr rest))))))
  285. ; Promises, promises.
  286. (define-syntax delay
  287. (syntax-rules ()
  288. ((delay ?exp) (make-promise (lambda () ?exp)))))
  289. ; A slightly modified copy of the code from R4RS; the modification ensures
  290. ; that the thunk is GC'ed after the promise is evaluted.
  291. ; JAR writes: "It is not for us to judge the wisdom of the new definition."
  292. (define (make-promise thunk-then-result)
  293. (let ((already-run? #f))
  294. (lambda ()
  295. (if already-run? ; can't be interrupted from now
  296. thunk-then-result
  297. (let ((result (thunk-then-result))) ; until after this call
  298. (cond ((not already-run?)
  299. (set! already-run? #t)
  300. (set! thunk-then-result result)))
  301. thunk-then-result)))))
  302. (define (force promise)
  303. (promise))