[racket-dev] Proposed addition of #:where clause to the match library
I think it would desirable to add a 'where clause' to thematch module (it could be implemented as a keyword argument:#:where (test).
Below are versions and an insertion sort algorithm from<http://rosettacode.org/wiki/Sorting_algorithms/Insertion_sort>First a Qi version, then an Erlang version, followed by a proposedRacket version with a 'where clause', a failed attempt at writinga Racket version with a predicate clause, and finally a practical(at the present time) Racket version of the algorithm.
I'm not an experienced programmer but I am intrigued by patternmatching and have glanced at pattern matching capabilities ina variety of functional languages.
I'd appreciate comments on whether this feature is considereddesirable/feasible in Racket.
Qi version of insertion sort using 'where clause':
(define insert X [] -> [X] X [Y | Ys] -> [X Y | Ys] where (<= X Y) X [Y | Ys] -> [Y | (insert X Ys)]) (define insertion-sort [] -> [] [X | Xs] -> (insert X (insertion-sort Xs))) (insertion-sort [6 8 5 9 3 2 1 4 7])
Erlang version on same web page using 'when clause':
-module(sort).-export([insertion/1]). insertion(L) -> lists:foldl(fun insert/2, [], L).
insert(X, []) -> [X];insert(X, L = [H | _]) when X =< H -> [X | L];insert(X, [H | T]) -> [H | insert(X, T)].
> sort:insertion([5,3,9,4,1,6,8,2,7]).
Proposed Racket version (based on the Erlang example)uses #:where keyword:
(define/match (insert X lst) [{ X '() } (list X)] [{ X (cons H T) } #:where (<= X H) (list* X H T)] [{ X (cons H T) } (cons H (insert X T))])
(define (insertion-sort lst) (foldl insert '() lst))
I don't think that a corresponding Racket predicate matchcan be written (I may not have coded it correctly!)It's also messy:
(define/match (insert-b X lst) [{ X '() } (list X)] [{ X (and (cons H T) (? (λ (H X) (<= X H)))) } (list* X H T)] [{ X (cons H T) } (cons H (insert-b X T))])
(define (insertion-sort-b lst) (foldl insert-b '() lst))
(insertion-sort-b '(6 8 5 9 3 2 1 4 7))
Current working Racket version(modified slightly from the posted Racket version)It's necessarily missing the third match pattern:
(define/match (insert-c X lst) [{ X '() } (list X)] [{ X (cons H T) } (cond [(<= X H) (list* X H T)] [else (cons H (insert-c X T))])])
(define (insertion-sort-c lst) (foldl insert-c '() lst))
(insertion-sort-c '(6 8 5 9 3 2 1 4 7))
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/dev/archive/attachments/20141024/6059b80a/attachment.html>