prelude.scm 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449
  1. "Prelude --- Standard Library for interpretive-scheme"
  2. "Copyright © 2018 Alex Vong <alexvong1995@gmail.com>"
  3. "This file is part of interpretive-scheme."
  4. "interpretive-scheme is free software; you can redistribute it and/or modify it"
  5. "under the terms of the GNU General Public License as published by"
  6. "the Free Software Foundation; either version 3 of the License, or (at"
  7. "your option) any later version."
  8. "interpretive-scheme is distributed in the hope that it will be useful, but"
  9. "WITHOUT ANY WARRANTY; without even the implied warranty of"
  10. "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the"
  11. "GNU General Public License for more details."
  12. "You should have received a copy of the GNU General Public License"
  13. "along with interpretive-scheme. If not, see <http://www.gnu.org/licenses/>."
  14. (define list
  15. (lambda args
  16. args))
  17. (define (procedure? x)
  18. (or (primitive-procedure? x)
  19. (compound-procedure? x)))
  20. (define (fold op init ls)
  21. (if (null? ls)
  22. init
  23. (fold op
  24. (op (car ls) init)
  25. (cdr ls))))
  26. (define %+ +)
  27. (define +
  28. (lambda nums
  29. (fold %+ 0 nums)))
  30. (define %- -)
  31. (define -
  32. (lambda nums
  33. (let ((first (car nums))
  34. (rest (cdr nums)))
  35. (if (null? rest)
  36. (%- 0 first)
  37. (%- first (apply + rest))))))
  38. (define %* *)
  39. (define *
  40. (lambda nums
  41. (fold %* 1 nums)))
  42. (define (reverse ls)
  43. (fold cons '() ls))
  44. (define (length ls)
  45. (fold (lambda (_ n)
  46. (+ n 1))
  47. 0
  48. ls))
  49. (define (any pred ls)
  50. (fold (lambda (x accum)
  51. (or accum (pred x)))
  52. #f
  53. ls))
  54. (define (every pred ls)
  55. (fold (lambda (x accum)
  56. (and accum (pred x)))
  57. #t
  58. ls))
  59. (define (fold-right op init ls)
  60. (fold op init (reverse ls)))
  61. (define (not x)
  62. (if x #f #t))
  63. (define (identity x)
  64. x)
  65. (define (const x)
  66. (lambda _ x))
  67. (define (negate proc)
  68. (lambda args
  69. (not (apply proc args))))
  70. (define %apply apply)
  71. (define (%compose g f)
  72. (lambda args
  73. (g (%apply f args))))
  74. (define compose
  75. (lambda procs
  76. (fold-right %compose identity procs)))
  77. (define caar (compose car car))
  78. (define cadr (compose car cdr))
  79. (define cdar (compose cdr car))
  80. (define cddr (compose cdr cdr))
  81. (define caaar (compose car car car))
  82. (define caadr (compose car car cdr))
  83. (define cadar (compose car cdr car))
  84. (define caddr (compose car cdr cdr))
  85. (define cdaar (compose cdr car car))
  86. (define cdadr (compose cdr car cdr))
  87. (define cddar (compose cdr cdr car))
  88. (define cdddr (compose cdr cdr cdr))
  89. (define caaaar (compose car car car car))
  90. (define caaadr (compose car car car cdr))
  91. (define caadar (compose car car cdr car))
  92. (define caaddr (compose car car cdr cdr))
  93. (define cadaar (compose car cdr car car))
  94. (define cadadr (compose car cdr car cdr))
  95. (define caddar (compose car cdr cdr car))
  96. (define cadddr (compose car cdr cdr cdr))
  97. (define cdaaar (compose cdr car car car))
  98. (define cdaadr (compose cdr car car cdr))
  99. (define cdadar (compose cdr car cdr car))
  100. (define cdaddr (compose cdr car cdr cdr))
  101. (define cddaar (compose cdr cdr car car))
  102. (define cddadr (compose cdr cdr car cdr))
  103. (define cdddar (compose cdr cdr cdr car))
  104. (define cddddr (compose cdr cdr cdr cdr))
  105. (define first car)
  106. (define second cadr)
  107. (define third caddr)
  108. (define fourth cadddr)
  109. (define fifth (compose car cddddr))
  110. (define sixth (compose cadr cddddr))
  111. (define eighth (compose cadddr cddddr))
  112. (define ninth (compose car cddddr cddddr))
  113. (define tenth (compose cadr cddddr cddddr))
  114. (define last (compose car reverse))
  115. (define cons*
  116. (lambda args
  117. (fold cons
  118. (last args)
  119. (cdr (reverse args)))))
  120. (define apply
  121. (lambda args
  122. (let ((proc (car args))
  123. (args* (cdr args)))
  124. (%apply proc
  125. (%apply cons* args*)))))
  126. (define (filter pred ls)
  127. (fold-right (lambda (x accum)
  128. (if (pred x)
  129. (cons x accum)
  130. accum))
  131. '()
  132. ls))
  133. (define (%map proc ls)
  134. (fold-right (lambda (x accum)
  135. (cons (proc x) accum))
  136. '()
  137. ls))
  138. (define unfold-right
  139. (lambda args
  140. (let ((pred (first args))
  141. (proc (second args))
  142. (next (third args))
  143. (init (fourth args))
  144. (accum (if (>= (length args) 5) (fifth args) '())))
  145. (if (> (length args) 5)
  146. (error "Too many arguments supplied: UNFOLD-RIGHT" args)
  147. (if (pred init)
  148. accum
  149. (unfold-right pred
  150. proc
  151. next
  152. (next init)
  153. (cons (proc init) accum)))))))
  154. (define zip
  155. (lambda ls-of-ls
  156. (reverse (unfold-right (lambda (ls-of-ls) (any null? ls-of-ls))
  157. (lambda (ls-of-ls) (%map car ls-of-ls))
  158. (lambda (ls-of-ls) (%map cdr ls-of-ls))
  159. ls-of-ls))))
  160. (define map
  161. (lambda args
  162. (let ((proc (car args))
  163. (ls-of-ls (cdr args)))
  164. (%map (lambda (ls)
  165. (apply proc ls))
  166. (apply zip ls-of-ls)))))
  167. (define for-each
  168. (lambda args
  169. (let ((proc (car args))
  170. (ls-of-ls (cdr args)))
  171. (fold (lambda (ls _)
  172. (apply proc ls)
  173. '())
  174. '()
  175. (apply zip ls-of-ls)))))
  176. (define (%append ls ls*)
  177. (fold-right cons ls* ls))
  178. (define append
  179. (lambda ls-of-ls
  180. (fold-right %append '() ls-of-ls)))
  181. (define (concatenate ls-of-ls)
  182. (apply append ls-of-ls))
  183. (define (list? x)
  184. (cond ((null? x) #t)
  185. ((pair? x) (list? (cdr x)))
  186. (else #f)))
  187. (define (%<-> a b)
  188. (or (and a b)
  189. (not (or a b))))
  190. (define (%equal? a b)
  191. (cond ((boolean? a)
  192. (cond ((boolean? b)
  193. (%<-> a b))
  194. ((or (integer? b)
  195. (string? b)
  196. (symbol? b)
  197. (null? b)
  198. (pair? b)
  199. (eof-object? b))
  200. #f)
  201. (else
  202. (error "Unknown value type: EQUAL?" b))))
  203. ((integer? a)
  204. (cond ((integer? b)
  205. (= a b))
  206. ((or (boolean? b)
  207. (string? b)
  208. (symbol? b)
  209. (null? b)
  210. (pair? b)
  211. (eof-object? b))
  212. #f)
  213. (else
  214. (error "Unknown value type: EQUAL?" b))))
  215. ((string? a)
  216. (cond ((string? b)
  217. (string=? a b))
  218. ((or (boolean? b)
  219. (integer? b)
  220. (symbol? b)
  221. (null? b)
  222. (pair? b)
  223. (eof-object? b))
  224. #f)
  225. (else
  226. (error "Unknown value type: EQUAL?" b))))
  227. ((symbol? a)
  228. (cond ((symbol? b)
  229. (string=? (symbol->string a)
  230. (symbol->string b)))
  231. ((or (boolean? b)
  232. (integer? b)
  233. (string? b)
  234. (null? b)
  235. (pair? b)
  236. (eof-object? b))
  237. #f)
  238. (else
  239. (error "Unknown value type: EQUAL?" b))))
  240. ((null? a)
  241. (cond ((null? b)
  242. #t)
  243. ((or (boolean? b)
  244. (integer? b)
  245. (string? b)
  246. (symbol? b)
  247. (pair? b)
  248. (eof-object? b))
  249. #f)
  250. (else
  251. (error "Unknown value type: EQUAL?" b))))
  252. ((pair? a)
  253. (cond ((pair? b)
  254. (and (%equal? (car a) (car b))
  255. (%equal? (cdr a) (cdr b))))
  256. ((or (boolean? b)
  257. (integer? b)
  258. (string? b)
  259. (symbol? b)
  260. (null? b)
  261. (eof-object? b))
  262. #f)
  263. (else
  264. (error "Unknown value type: EQUAL?" b))))
  265. ((eof-object? a)
  266. (cond ((eof-object? b)
  267. #t)
  268. ((or (boolean? b)
  269. (integer? b)
  270. (string? b)
  271. (symbol? b)
  272. (null? b)
  273. (pair? b))
  274. #f)
  275. (else
  276. (error "Unknown value type: EQUAL?" b))))
  277. (else
  278. (error "Unknown value type: EQUAL?" a))))
  279. (define equal?
  280. (lambda args
  281. (if (null? args)
  282. #t
  283. (let ((first (car args))
  284. (rest (cdr args)))
  285. (every (lambda (x)
  286. (%equal? x first))
  287. rest)))))
  288. (define (expt a b)
  289. (if (>= b 0)
  290. (apply * (make-list b a))
  291. (error "Negative power: EXPT" b)))
  292. (define (%max a b)
  293. (if (> a b) a b))
  294. (define max
  295. (lambda nums
  296. (fold %max
  297. (car nums)
  298. (cdr nums))))
  299. (define (%min a b)
  300. (if (< a b) a b))
  301. (define min
  302. (lambda nums
  303. (fold %min
  304. (car nums)
  305. (cdr nums))))
  306. (define (zero? x)
  307. (= x 0))
  308. (define (positive? x)
  309. (> x 0))
  310. (define (negative? x)
  311. (< x 0))
  312. (define (%/ a b)
  313. (if (zero? (remainder a b))
  314. (quotient a b)
  315. (error "Not divisible: /" a b)))
  316. (define /
  317. (lambda nums
  318. (let ((first (car nums))
  319. (rest (cdr nums)))
  320. (if (null? rest)
  321. (%/ 1 first)
  322. (%/ first (apply * rest))))))
  323. (define (abs x)
  324. (if (negative? x)
  325. (- x)
  326. x))
  327. (define (modulo a b)
  328. (let ((r (remainder a b)))
  329. (if (or (< (abs r) (abs b))
  330. (and (>= a 0) (>= b 0))
  331. (and (negative? a) (negative? b)))
  332. r
  333. (+ r b))))
  334. (define (even? n)
  335. (zero? (modulo n 2)))
  336. (define odd? (negate even?))
  337. (define make-list
  338. (lambda args
  339. (let ((n (first args))
  340. (init (if (>= (length args) 2) (second args) '())))
  341. (if (> (length args) 2)
  342. (error "Too many arguments supplied: MAKE-LIST" args)
  343. (unfold-right zero?
  344. (const init)
  345. (lambda (n) (- n 1))
  346. n)))))
  347. (define (list-ref ls k)
  348. (let ((kth-cdr (apply compose
  349. (make-list k cdr))))
  350. (car (kth-cdr ls))))
  351. (define iota
  352. (lambda args
  353. (let ((count (first args))
  354. (start (if (>= (length args) 2) (second args) 0))
  355. (step (if (>= (length args) 3) (third args) 1)))
  356. (if (> (length args) 3)
  357. (error "Too many arguments supplied: IOTA" args)
  358. (unfold-right (lambda (n) (< n start))
  359. identity
  360. (lambda (n) (- n step))
  361. (+ start
  362. (* (- count 1)
  363. step)))))))
  364. '
  365. (define fold*
  366. (lambda args
  367. (let ((op (car args))
  368. (init (cadr args))
  369. (ls-of-ls (cddr args)))
  370. (if (null? ls)
  371. init
  372. (fold op
  373. (apply op (car ls) init)
  374. (cdr ls))))))