svn: r16704
This commit is contained in:
Eli Barzilay 2009-11-12 00:18:08 +00:00
parent e65ab46bfd
commit e34e001167
10 changed files with 110 additions and 2 deletions

View File

@ -9,11 +9,23 @@
(define (bytes-ci=? b0 b1) (define (bytes-ci=? b0 b1)
(string-ci=? (bytes->string/utf-8 b0) (string-ci=? (bytes->string/utf-8 b0)
(bytes->string/utf-8 b1))) (bytes->string/utf-8 b1)))
;; Eli: If this ever gets in, it should say that the memory requirements
;; are 4 times the input size, especially since bytes are often used to save
;; space. Also, fails on (bytes-ci=? #"\277" #"\277"), and a trivial fix
;; would still fail on (bytes-ci=? #"\276\277" #"\277\276")
(define (read/bytes bs) (define (read/bytes bs)
(read (open-input-bytes bs))) (read (open-input-bytes bs)))
;; Eli: This is a really bad name for something that is often called
;; `read-from-string', or `read-from-bytes' in this case. I first read it as
;; "read with bytes". Regardless, I see little point in composing two
;; functions where the two names are clear enough -- you might consider
;; looking at the version in CL.
(define (write/bytes v) (define (write/bytes v)
(define by (open-output-bytes)) (define by (open-output-bytes))
(write v by) (write v by)
(get-output-bytes by)) (get-output-bytes by))
;; Eli: Same bad name as above. Also, is there any point in this given
;; (format "~s" v), and the fact that using the resulting string for printout
;; will get the same result.

View File

@ -2,12 +2,16 @@
(define path-element? (define path-element?
(or/c path-string? (symbols 'up 'same))) (or/c path-string? (symbols 'up 'same)))
;; Eli: We already have a notion of "path element" which is different
;; from this (see `string->path-element') .
(define port-number? (between/c 1 65535)) (define port-number? (between/c 1 65535))
(define non-empty-string/c (define non-empty-string/c
(and/c string? (and/c string?
(lambda (s) (not (zero? (string-length s)))))) (lambda (s) (not (zero? (string-length s))))))
;; Eli: If this gets in, there should also be versions for bytes, lists, and
;; vectors.
(provide/contract (provide/contract
[non-empty-string/c contract?] [non-empty-string/c contract?]

View File

@ -14,6 +14,7 @@
((error-display-handler) (exn-message exn) exn) ((error-display-handler) (exn-message exn) exn)
(get-output-string (current-error-port))) (get-output-string (current-error-port)))
(format "~s\n" exn))) (format "~s\n" exn)))
;; Eli: (or/c exn any)??
(provide/contract (provide/contract
[network-error ((symbol? string?) (listof any/c) . ->* . (void))] [network-error ((symbol? string?) (listof any/c) . ->* . (void))]

View File

@ -14,6 +14,17 @@
(if (equal? l0 r0) (if (equal? l0 r0)
(list-prefix? ls rs) (list-prefix? ls rs)
#f)])])) #f)])]))
;; Eli: Is this some `match' obsession syndrom? The simple definition:
;; (define (list-prefix? ls rs)
;; (or (null? ls) (and (pair? rs) (equal? (car ls) (car rs))
;; (list-prefix? (cdr ls) (cdr rs)))))
;; is shorter, and faster. As for making this a library function: how
;; about a version that removes the equal prefix from two lists and
;; returns the tails -- this way you can tell if they're equal, or one
;; is a prefix of the other, or if there was any equal prefix at all.
;; (Which can be useful for things like making a path relative to
;; another path.) A nice generalization is to make it get two or more
;; lists, and return a matching number of values.
(provide/contract (provide/contract
[list-prefix? (list? list? . -> . boolean?)]) [list-prefix? (list? list? . -> . boolean?)])

View File

@ -42,5 +42,14 @@
;; is-var-mutated? : identifier -> boolean ;; is-var-mutated? : identifier -> boolean
(define (is-var-mutated? id) (module-identifier-mapping-get table id (lambda _ #f))) (define (is-var-mutated? id) (module-identifier-mapping-get table id (lambda _ #f)))
(provide find-mutated-vars is-var-mutated?) ;; Eli:
;; - The `for-template' doesn't look like it's needed.
;; - This is the *worst* looking interface I've seen in a while. Seems very
;; specific to some unclear optimization needs. (Either that, or translated
;; from C.)
;; - Besides weird, identifiers maps are (IIRC) not weak, which makes this even
;; less general.
;; - What's with the typed-scheme literals? If they were needed, then
;; typed-scheme is probably broken now.
(provide find-mutated-vars is-var-mutated?)

View File

@ -22,6 +22,15 @@
new-path new-path
empty empty
(url-fragment in-url)))) (url-fragment in-url))))
;; Eli: if it also removes the query, this it's a bad name, and it's
;; questionable whether it is general enough. Why not make it into a
;; keyworded function that can change any part, which sounds like a much more
;; useful utility? Some `foo' that would allow:
;; (define (url-replace-path proc in-url)
;; (foo in-url #:path (proc (url-path in-url)) #:query '()))
;; or even accept a changing function for all keywords:
;; (define (url-replace-path proc in-url)
;; (foo in-url #:path proc #:query '()))
;; ripped this off from url-unit.ss ;; ripped this off from url-unit.ss
(define (url-path->string strs) (define (url-path->string strs)
@ -42,3 +51,7 @@
[(up) ".."] [(up) ".."]
[else (error 'maybe-join-params [else (error 'maybe-join-params
"bad value from path/param-path: ~e" s)]))))) "bad value from path/param-path: ~e" s)])))))
;; Eli: I don't know what this is supposed to be doing -- I don't see any
;; "maybe"ness), it throws away the `path/param-param's, and it accepts
;; strings too (which makes me wonder how is this related to the url
;; library).

View File

@ -11,6 +11,8 @@
[else [else
(let-values ([(base name dir?) (split-path p)]) (let-values ([(base name dir?) (split-path p)])
(loop base (list* name r)))]))) (loop base (list* name r)))])))
;; Eli: We already have `explode-path', this looks like it's doing the
;; same thing, except a little less useful.
; strip-prefix-ups : (listof path-element?) -> (listof path-element?) ; strip-prefix-ups : (listof path-element?) -> (listof path-element?)
(define (strip-prefix-ups l) (define (strip-prefix-ups l)
@ -23,6 +25,18 @@
(set-box! prefix? #f))) (set-box! prefix? #f)))
#t)) #t))
l)) l))
;; Eli: This is bad. If I understand it correctly, this is what this
;; *should* have been:
;; (define (strip-prefix-ups l)
;; (if (and (pair? l) (eq? 'up (car l))) (strip-prefix-ups (cdr l)) l))
;; or even:
;; (define (strip-prefix-ups l)
;; (match l [(cons 'up l) (strip-prefix-ups l)] [_ l]))
;; except that the above version manages to combine ugly and
;; obfuscated code, redundant mutation, redundant code (why is it a
;; box? why is there a (begin #t ...)?), and being extra slow. Oh,
;; and if this wasn't enough, there's exactly one place in the web
;; server that uses it.
; path-without-base : path? path? -> (listof path-element?) ; path-without-base : path? path? -> (listof path-element?)
(define (path-without-base base path) (define (path-without-base base path)
@ -31,12 +45,19 @@
(if (list-prefix? b p) (if (list-prefix? b p)
(list-tail p (length b)) (list-tail p (length b))
(error 'path-without-base "~a is not a prefix of ~a" base path))) (error 'path-without-base "~a is not a prefix of ~a" base path)))
;; Eli: see my comment on `list-prefix?' -- it would make this trivial.
;; Also, if you want to look for a useful utility to add, search the code for
;; `relativize', which is a popular thing that gets written multiple times
;; and would be nice to have as a library. (But there are some differences
;; between them, I think.)
;; build-path-unless-absolute : path-string? path-string? -> path? ;; build-path-unless-absolute : path-string? path-string? -> path?
(define (build-path-unless-absolute base path) (define (build-path-unless-absolute base path)
(if (absolute-path? path) (if (absolute-path? path)
(build-path path) (build-path path)
(build-path base path))) (build-path base path)))
;; Eli: This looks completely unnecessary. I find the code much easier to
;; understand than the long name.
(define (directory-part path) (define (directory-part path)
(let-values ([(base name must-be-dir) (split-path path)]) (let-values ([(base name must-be-dir) (split-path path)])
@ -44,6 +65,10 @@
[(eq? 'relative base) (current-directory)] [(eq? 'relative base) (current-directory)]
[(not base) (error 'directory-part "~a is a top-level directory" path)] [(not base) (error 'directory-part "~a is a top-level directory" path)]
[(path? base) base]))) [(path? base) base])))
;; Eli: There is now a `file-name-from-path', which suggests that the name for
;; this should be `directory-name-from-path', but perhaps a new name is
;; better for both. Also, I find it questionable to return the current
;; directory in the first case.
(provide/contract (provide/contract
[explode-path* (path-string? . -> . (listof path-element?))] [explode-path* (path-string? . -> . (listof path-element?))]

View File

@ -3,10 +3,14 @@
(define (read/string str) (define (read/string str)
(read (open-input-string str))) (read (open-input-string str)))
;; Eli: Same comments as `read/bytes'.
(define (write/string v) (define (write/string v)
(define str (open-output-string)) (define str (open-output-string))
(write v str) (write v str)
(get-output-string str)) (get-output-string str))
;; Eli: Same comments as `write/string', and worse -- this is the same as
;; (format "~s" v)
; lowercase-symbol! : (or/c string bytes) -> symbol ; lowercase-symbol! : (or/c string bytes) -> symbol
(define (lowercase-symbol! s) (define (lowercase-symbol! s)
@ -15,6 +19,11 @@
(if (bytes? s) (if (bytes? s)
(bytes->string/utf-8 s) (bytes->string/utf-8 s)
s)))) s))))
;; Eli: This doesn't make any sense at all. Why is the `!' in the name? Why
;; does it accept bytes? Why does a function in a "string" library accept
;; bytes? How can I guess that this creates a new symbol from that name?
;; (Which makes me think that this is (compose string->symbol string-downcase
;; symbol->string))
(provide/contract (provide/contract
[lowercase-symbol! ((or/c string? bytes?) . -> . symbol?)] [lowercase-symbol! ((or/c string? bytes?) . -> . symbol?)]

View File

@ -40,6 +40,11 @@
(syntax-property #'(constructor expr ...) (syntax-property #'(constructor expr ...)
'disappeared-use 'disappeared-use
#'S)))])) #'S)))]))
;; Eli: You give a good point for this, but I'd prefer if the optimizer would
;; detect these, so you'd get the same warnings for constructors too when you
;; use `-W warning'. (And then, if you really want these things to be
;; errors, then perhaps something at the mzscheme level should make it throw
;; errors instead of warnings.)
(define dummy-value (box 'dummy)) (define dummy-value (box 'dummy))
@ -53,3 +58,8 @@
#f] #f]
[else #t])) [else #t]))
(cdr (vector->list vec))))) (cdr (vector->list vec)))))
;; Eli: Why is there that `false-on-opaque?' business instead of having
;; an interface similar to `struct->vector'? I'd prefer an optional
;; on-opaque value, and have it throw an error if it's opaque and no
;; value is given. Also, `gensym' seems much better to me than a box
;; for a unique value.

View File

@ -41,6 +41,9 @@
(apply make-prefab-struct key (apply make-prefab-struct key
(loop (struct->list x))))] (loop (struct->list x))))]
[else x]))) [else x])))
;; Eli: Is there any difference between this (with the default) and
;; `syntax->datum'? If not, then maybe add the optional (or keyword) to
;; there instead?
;; Defining pattern variables ;; Defining pattern variables
@ -82,6 +85,7 @@
(define-syntax-rule (with-temporaries (temp-name ...) . body) (define-syntax-rule (with-temporaries (temp-name ...) . body)
(with-syntax ([(temp-name ...) (generate-temporaries (quote-syntax (temp-name ...)))]) (with-syntax ([(temp-name ...) (generate-temporaries (quote-syntax (temp-name ...)))])
. body)) . body))
;; Eli: +1 to this, not sure about the next two
;; generate-temporary : any -> identifier ;; generate-temporary : any -> identifier
(define (generate-temporary [stx 'g]) (define (generate-temporary [stx 'g])
@ -106,7 +110,16 @@
(let* ([str (apply format fmt args)] (let* ([str (apply format fmt args)]
[sym (string->symbol str)]) [sym (string->symbol str)])
(datum->syntax lctx sym src props cert))) (datum->syntax lctx sym src props cert)))
;; Eli: This looks very *useful*, but I'd like to see it more convenient to
;; "preserve everything". Maybe add a keyword argument that when #t makes
;; all the others use values lctx, and when syntax makes the others use that
;; syntax? Also, I'd prefer it if each of these keywords would also accept a
;; syntax instead of a value, to copy the value from.
;; Finally, if you get to add this, then another useful utility in the same
;; spirit is one that concatenates symbols and/or strings and/or identifiers
;; into a new identifier. I considered something like that, which expects a
;; single syntax among its inputs, and will use it for the context etc, or
;; throw an error if there's more or less than 1.
;; Error reporting ;; Error reporting
@ -122,3 +135,4 @@
ctx ctx
stx stx
extras))) extras)))
;; Eli: The `report-error-as' thing seems arbitrary to me.