From 246ee2e48fa40b7534e294f219f99688a3c823eb Mon Sep 17 00:00:00 2001 From: Case Duckworth Date: Sun, 13 Aug 2023 22:59:29 -0500 Subject: Update extras --- chicanery.extras.scm | 58 ++++++++++++++++++++++++++++++++++++++++++++-------- chicanery.scm | 6 +++--- 2 files changed, 53 insertions(+), 11 deletions(-) diff --git a/chicanery.extras.scm b/chicanery.extras.scm index 27968df..bcb4929 100644 --- a/chicanery.extras.scm +++ b/chicanery.extras.scm @@ -1,8 +1,7 @@ ;;; chicanery extras --- extra stuff from ur old pal acdw -(export list-map - list-for-each - list-append) +(export list-map list-for-each list-append + map for-each append) ;;; Generalized map, for-each, ... ;; List versions are renamed `list-'. Un-prefixed versions work @@ -81,13 +80,9 @@ ;;; Functions that should be in scheme ;; This sections should be as small as possible -(export atom? - read-port +(export read-port read-port-chunk-size) -(define (atom? x) - (not (pair? x))) - (define read-port-chunk-size (make-parameter 512)) @@ -113,3 +108,50 @@ (case-lambda (() (%read-port (current-input-port))) ((p) (%read-port p)))) + +(export atom? defined?) + +(define (atom? x) + (not (or (null? x) + (pair? x)))) + +(define (defined? sym) + (call-with-current-continuation + (lambda (k) + (with-exception-handler + (lambda (e) (k #f)) + (lambda () + (eval sym (interaction-environment)) + #t))))) + +(export with-output-to-string + with-input-from-string) + +(define (with-output-to-string thunk) + (call-with-port (open-output-string) + (lambda (port) + (parameterize ((current-output-port port)) + (thunk)) + (get-output-string port)))) + +(define (with-input-from-string s thunk) + (call-with-port (open-input-string s) + (lambda (port) + (parameterize ((current-input-port port)) + (thunk))))) + +(export displayed ->string written print) + +(define (displayed x) + (with-output-to-string + (lambda () (display x)))) + +(define (written x) + (with-output-to-string + (lambda () (write x)))) + +(define (print . xs) + (for-each display xs) + (newline)) + +(define ->string displayed) diff --git a/chicanery.scm b/chicanery.scm index 12f5ab3..0fc71e4 100644 --- a/chicanery.scm +++ b/chicanery.scm @@ -20,7 +20,7 @@ (import (scheme time)) (import (scheme write)) (import utf8) - (export * + - / <= < >= = > abs and append apply assoc assq assv begin + (export * + - / <= < >= = > abs and #;append apply assoc assq assv begin binary-port? boolean? boolean=? bytevector bytevector-append bytevector-copy bytevector-copy! bytevector-length bytevector-u8-ref bytevector-u8-set! bytevector? car cdr caar cadr cdar cddr @@ -34,13 +34,13 @@ error-object-message error-object? even? odd? exact inexact exact-integer-sqrt exact-integer? exact? inexact? exp expt features file-error? floor floor/ floor-quotient floor-remainder - flush-output-port for-each gcd lcm get-output-bytevector + flush-output-port #;for-each gcd lcm get-output-bytevector get-output-string guard if import import-for-syntax include include-ci input-port-open? output-port-open? input-port? output-port? integer? lambda length let let* letrec letrec* let-values let*-values let-syntax letrec-syntax list list-copy list-ref list-set! list-tail list? list->vector make-bytevector make-list make-parameter make-string - make-vector map max min member memq memv modulo remainder negative? + make-vector #;map max min member memq memv modulo remainder negative? positive? newline not null? number->string string->number number? open-input-bytevector open-output-bytevector open-input-string open-output-string or pair? parameterize peek-char peek-u8 port? -- cgit 1.4.1-21-gabe81 From 0cf8abf7f168786bcdae91973c41b06e08cd7b7c Mon Sep 17 00:00:00 2001 From: Case Duckworth Date: Sun, 13 Aug 2023 23:01:20 -0500 Subject: Update README --- README.md | 45 ++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 40 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 1d5e86b..85a5994 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,48 @@ -# Chicanery: subtle, opinionated improvements to R7RS in CHICKEN +# Chicanery: subtle, opinionated improvements to R7RS Scheme (in CHICKEN) -`chicanery` is my attempt at a prelude module for CHICKEN scheme. It imports and re-exports all `r7rs` modules, using `utf8` where possible, and it corrects a few (in my mind) rough spots in the language, to whit: +While I was reading the [R7RS +specification](https://standards.scheme.org/official/r7rs.pdf), I was a little +annoyed by how broken up the standard library seemed to be. While the most +egregious example is maybe `(scheme case-lambda)`, which exports ... only +`case-lambda`, the other libraries like `(scheme write)` for `display`, `(scheme +cxr)` for functions like `caddr` but not `cddr`, and the rest didn't really seem +logical to me. Plus, in CHICKEN scheme, the one I usually use, `utf8` is an egg +you need to install separately... -- `map`, `for-each`, and `append` are now generalized over lists, vectors, strings, and bytevectors (where appropriate). The list versions of these procedures have been named `list-map`, `list-for-each`, and `list-append` respectively. -- `ref` and `copy` have been defined as generalized functions over the above data types. +To ameliorate these minor warts in what I otherwise consider to be an excellent +language, `chicanery` was born. It's kind of like a prelude, I suppose? It +imports all `r7rs` modules and re-exports their identifiers, and makes sure the +implementation is Unicode-aware. It also includes a few extras ;) + +## Chicanery extras + +I also thought it was strange that `map`, `for-each`, and `append` apply to +lists only, while `vector-map` and `string-for-each`, exist, for example. +`chicanery` prefixes the default `map`, `for-each`, and `append` functions with +`list-`, and redefines those identifiers to functions that are generic over +Scheme's base collection types (lists, strings, vectors, bytevectors where +applicable). I didn't make the functions fully-generic to keep them efficient +and because I don't know how to do that, but you can still use `vector-append` +or `list-map` if you know what type you need and want speed. + +In a similar vein, I've also added generic functions `ref` and `copy` that +dispatch to `string-ref`, `list-copy`, and the like. + +Other extras include + +- `(atom? x)` determines whether `x` is an atom (i.e., not a pair or null) +- `(read-port)`, `(read-port port)` reads a port until hitting end-of-file (IDK + why this isn't in R7RS!), in chunks of `read-port-chunk-size` +- `(defined? x)` returns whether the symbol `x` is bound to a variable +- `(with-input-from-string str thunk)` calls `thunk` with `str` bound as the current-input-port. +- `(with-output-to-string thunk)` calls `thunk` and returns a string of the output. +- `(displayed x)`, `(->string x)` returns `x` as a string (via `display`) +- `(written x)` returns `x` as a string (via `write`) +- `(print x ...)` displays `x ...` followed by a newline ## Todo -- Make sure `set!` works in, like, `(set! (ref 5 '(1 2 3 4 5)) 10)` +- Support multiple scheme implementations. I tried doing this (see the [multiple-impls](https://git.acdw.net/chicanery/?h=multiple-impls) branch), but it kept not working in weird ways, plus it was like whack-a-mole with all the different schemes and just exhausting. ## License -- cgit 1.4.1-21-gabe81