Disable the #:before-first' and
#:after-last' functionality in `add-between'.
Leave it working in splicing mode. I prefer doing that over always
splicing them, since that would make a less uniform interface, so I
rather keep all options open. There is no longer a `#:nothing' keyword,
which is the main point of this downgrade.
(See mailing list discussion on "no-argument" for the reason.)
(cherry picked from commit 6565538b09
)
This commit is contained in:
parent
601c90541d
commit
6e878f99fd
|
@ -177,58 +177,58 @@
|
||||||
|
|
||||||
;; General note: many non-tail recursive, which are just as fast in racket
|
;; General note: many non-tail recursive, which are just as fast in racket
|
||||||
|
|
||||||
(define default-nothing (gensym 'nothing))
|
|
||||||
(define (add-between l x
|
(define (add-between l x
|
||||||
#:splice? [splice? #f]
|
#:splice? [splice? #f]
|
||||||
#:nothing [nothing default-nothing]
|
#:before-first [before-first '()]
|
||||||
#:before-first [before-first nothing]
|
|
||||||
#:before-last [before-last x]
|
#:before-last [before-last x]
|
||||||
#:after-last [after-last nothing])
|
#:after-last [after-last '()])
|
||||||
(unless (list? l)
|
(unless (list? l)
|
||||||
(raise-argument-error 'add-between "list?" 0 l x))
|
(raise-argument-error 'add-between "list?" 0 l x))
|
||||||
(when splice?
|
(cond
|
||||||
|
[splice?
|
||||||
(define (check-list x which)
|
(define (check-list x which)
|
||||||
(unless (list? x)
|
(unless (list? x)
|
||||||
(raise-arguments-error 'add-between
|
(raise-arguments-error
|
||||||
|
'add-between
|
||||||
(string-append "list needed in splicing mode" which)
|
(string-append "list needed in splicing mode" which)
|
||||||
"given" x
|
"given" x
|
||||||
"given list..." l)))
|
"given list..." l)))
|
||||||
(check-list x "")
|
(check-list x "")
|
||||||
(unless (eq? nothing before-first) (check-list before-first " for #:before-first"))
|
(check-list before-first " for #:before-first")
|
||||||
(check-list before-last " for #:before-last")
|
(check-list before-last " for #:before-last")
|
||||||
(unless (eq? nothing after-last) (check-list after-last " for #:after-last")))
|
(check-list after-last " for #:after-last")]
|
||||||
(if (or (null? l) (null? (cdr l)))
|
[else
|
||||||
(let* ([r (cond [(eq? after-last nothing) '()] [splice? after-last] [else (list after-last)])]
|
(define (check-not-given x which)
|
||||||
[r (cond [(null? l) r] [(null? r) l] [(cons (car l) r)])]
|
(unless (eq? '() x)
|
||||||
[r (cond [(eq? before-first nothing) r]
|
(raise-arguments-error
|
||||||
[splice? (append before-first r)]
|
'add-between
|
||||||
[else (cons before-first r)])])
|
(string-append which " can only be used in splicing mode")
|
||||||
r)
|
"given" x
|
||||||
(let* ([r ; main loop (two loops for efficiency, maybe not needed)
|
"given list..." l)))
|
||||||
(if splice?
|
(check-not-given before-first "#:before-first")
|
||||||
(let ([x (reverse x)]
|
(check-not-given after-last "#:after-last")])
|
||||||
[bl (and (not (eq? before-last x))
|
(cond
|
||||||
(reverse before-last))])
|
[(or (null? l) (null? (cdr l)))
|
||||||
(let loop ([i (cadr l)] [l (cddr l)] [r '()])
|
(if splice? (append before-first l after-last) l)]
|
||||||
(cond [(pair? l) (loop (car l) (cdr l) (cons i (append x r)))]
|
;; two cases for efficiency, maybe not needed
|
||||||
[bl (cons i (append bl r))]
|
[splice?
|
||||||
[else (cons i (append x r))])))
|
(let* ([x (reverse x)]
|
||||||
(let loop ([i (cadr l)] [l (cddr l)] [r '()])
|
;; main loop
|
||||||
(cond [(pair? l) (loop (car l) (cdr l) (cons i (cons x r)))]
|
[r (let loop ([i (cadr l)] [l (cddr l)] [r '()])
|
||||||
[else (cons i (cons before-last r))])))]
|
(if (pair? l)
|
||||||
;; add `after-last'
|
(loop (car l) (cdr l) (cons i (append x r)))
|
||||||
[r (cond [(eq? after-last nothing) r]
|
(cons i (append (reverse before-last) r))))]
|
||||||
[splice? (append (reverse after-last) r)]
|
;; add `after-last' & reverse
|
||||||
[else (cons after-last r)])]
|
[r (reverse (append (reverse after-last) r))]
|
||||||
;; reverse
|
;; add first item and `before-first'
|
||||||
[r (reverse r)]
|
[r `(,@before-first ,(car l) ,@r)])
|
||||||
;; add first item
|
r)]
|
||||||
[r (cons (car l) r)]
|
[else
|
||||||
;; add `before-first'
|
(cons (car l)
|
||||||
[r (cond [(eq? before-first nothing) r]
|
(reverse (let loop ([i (cadr l)] [l (cddr l)] [r '()]) ; main loop
|
||||||
[splice? (append before-first r)]
|
(if (pair? l)
|
||||||
[else (cons before-first r)])])
|
(loop (car l) (cdr l) (cons i (cons x r)))
|
||||||
r)))
|
(cons i (cons before-last r))))))]))
|
||||||
|
|
||||||
(define (remove-duplicates l [=? equal?] #:key [key #f])
|
(define (remove-duplicates l [=? equal?] #:key [key #f])
|
||||||
;; `no-key' is used to optimize the case for long lists, it could be done for
|
;; `no-key' is used to optimize the case for long lists, it could be done for
|
||||||
|
|
|
@ -862,41 +862,30 @@ except that it can be faster.
|
||||||
|
|
||||||
|
|
||||||
@defproc[(add-between [lst list?] [v any/c]
|
@defproc[(add-between [lst list?] [v any/c]
|
||||||
[#:nothing nothing any/c (gensym)]
|
[#:before-first before-first list? '()]
|
||||||
[#:before-first before-first any/c nothing]
|
|
||||||
[#:before-last before-last any/c v]
|
[#:before-last before-last any/c v]
|
||||||
[#:after-last after-last any/c nothing]
|
[#:after-last after-last list? '()]
|
||||||
[#:splice? splice? any/c #f])
|
[#:splice? splice? any/c #f])
|
||||||
list?]{
|
list?]{
|
||||||
|
|
||||||
Returns a list with the same elements as @racket[lst], but with
|
Returns a list with the same elements as @racket[lst], but with
|
||||||
@racket[v] between each pair of elements in @racket[lst]; the last
|
@racket[v] between each pair of elements in @racket[lst]; the last
|
||||||
pair of elements will have @racket[before-last] between them, instead
|
pair of elements will have @racket[before-last] between them, instead
|
||||||
of @racket[v] (but @racket[before-last] defaults to @racket[v]). In
|
of @racket[v] (but @racket[before-last] defaults to @racket[v]).
|
||||||
addition, if @racket[before-first] is supplied as a value other than
|
|
||||||
@racket[nothing], then @racket[before-first] is inserted before the first
|
|
||||||
element; if @racket[after-last] is supplied as a value other than
|
|
||||||
@racket[nothing], then @racket[after-last] is inserted after the last
|
|
||||||
element.
|
|
||||||
|
|
||||||
If @racket[splice?] is true, then @racket[v], @racket[before-first],
|
If @racket[splice?] is true, then @racket[v] and @racket[before-last]
|
||||||
@racket[before-last], and @racket[after-last] should be lists, and
|
should be lists, and the list elements are spliced into the result. In
|
||||||
the list elements are spliced into the result.
|
addition, when @racket[splice?] is true, @racket[before-first] and
|
||||||
|
@racket[after-last] are inserted before the first element and after the
|
||||||
|
last element respectively.
|
||||||
|
|
||||||
@mz-examples[#:eval list-eval
|
@mz-examples[#:eval list-eval
|
||||||
(add-between '(x y z) 'and)
|
(add-between '(x y z) 'and)
|
||||||
(add-between '(x) 'and)
|
(add-between '(x) 'and)
|
||||||
(add-between '("a" "b" "c" "d") "," #:before-last "and")
|
(add-between '("a" "b" "c" "d") "," #:before-last "and")
|
||||||
(add-between #:before-first "Todo:"
|
|
||||||
'("a" "b" "c") "," #:before-last "and"
|
|
||||||
#:after-last ".")
|
|
||||||
(add-between '(x y z) '(-) #:before-last '(- -)
|
(add-between '(x y z) '(-) #:before-last '(- -)
|
||||||
#:before-first '(begin) #:after-last '(end LF)
|
#:before-first '(begin) #:after-last '(end LF)
|
||||||
#:splice? #t)
|
#:splice? #t)
|
||||||
(add-between '("a" "b" "c" "d") ","
|
|
||||||
#:nothing #f #:before-first #f #:after-last "!")
|
|
||||||
(add-between '("a" "b" "c" "d") ","
|
|
||||||
#:before-first #f #:after-last "!")
|
|
||||||
]}
|
]}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -245,19 +245,20 @@
|
||||||
[r3 (in-list '(() (x) (x (5) y) (x (5) y (5) z)
|
[r3 (in-list '(() (x) (x (5) y) (x (5) y (5) z)
|
||||||
(x (5) y (5) z (5) w)))])
|
(x (5) y (5) z (5) w)))])
|
||||||
(test r1 add-between l 5)
|
(test r1 add-between l 5)
|
||||||
(test `(0 ,@r1) add-between l 5 #:before-first 0)
|
;; (test `(0 ,@r1) add-between l 5 #:before-first 0)
|
||||||
(test `(,@r1 9) add-between l 5 #:after-last 9)
|
;; (test `(,@r1 9) add-between l 5 #:after-last 9)
|
||||||
(test `(0 ,@r1 9) add-between l 5 #:before-first 0 #:after-last 9)
|
;; (test `(0 ,@r1 9) add-between l 5 #:before-first 0 #:after-last 9)
|
||||||
(test r2 add-between l 5 #:before-last 7)
|
(test r2 add-between l 5 #:before-last 7)
|
||||||
(test `(0 ,@r2) add-between l 5 #:before-first 0 #:before-last 7)
|
;; (test `(0 ,@r2) add-between l 5 #:before-first 0 #:before-last 7)
|
||||||
(test `(,@r2 9) add-between l 5 #:after-last 9 #:before-last 7)
|
;; (test `(,@r2 9) add-between l 5 #:after-last 9 #:before-last 7)
|
||||||
(test `(0 ,@r2 9) add-between l 5 #:before-first 0 #:after-last 9 #:before-last 7)
|
;; (test `(0 ,@r2 9) add-between l 5 #:before-first 0 #:after-last 9 #:before-last 7)
|
||||||
(test r3 add-between l '(5))
|
(test r3 add-between l '(5))
|
||||||
(test `(0 ,@r3) add-between l '(5) #:before-first 0)
|
;; (test `(0 ,@r3) add-between l '(5) #:before-first 0)
|
||||||
(test `(,@r3 9) add-between l '(5) #:after-last 9)
|
;; (test `(,@r3 9) add-between l '(5) #:after-last 9)
|
||||||
(test `(0 ,@r3 9) add-between l '(5) #:before-first 0 #:after-last 9)
|
;; (test `(0 ,@r3 9) add-between l '(5) #:before-first 0 #:after-last 9)
|
||||||
(test r1 add-between l 5 #:nothing #f #:before-first #f)
|
;; (test r1 add-between l 5 #:nothing #f #:before-first #f)
|
||||||
(test r1 add-between l 5 #:nothing #f #:after-last #f))
|
;; (test r1 add-between l 5 #:nothing #f #:after-last #f)
|
||||||
|
)
|
||||||
;; spliced cases
|
;; spliced cases
|
||||||
(for* ([x (in-list '(() (4) (4 5)))]
|
(for* ([x (in-list '(() (4) (4 5)))]
|
||||||
[y (in-list '(() (6) (6 7)))])
|
[y (in-list '(() (6) (6 7)))])
|
||||||
|
|
Loading…
Reference in New Issue
Block a user