[racket-dev] Proposed addition of #:where clause to the match library

From: Michael Bernstein (mbernstein57 at yahoo.com)
Date: Fri Oct 24 13:55:24 EDT 2014

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>

Posted on the dev mailing list.