base.scm 9.6 KB

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