From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 64305 invoked by alias); 22 Jan 2017 04:36:03 -0000 Mailing-List: contact kawa-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: kawa-owner@sourceware.org Received: (qmail 64163 invoked by uid 89); 22 Jan 2017 04:35:59 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=1.1 required=5.0 tests=AWL,BAYES_00,BODY_8BITS,GARBLED_BODY,RCVD_IN_DNSWL_LOW,SPF_PASS autolearn=no version=3.3.2 spammy=highlights, if, evaluating, 831 X-HELO: aibo.runbox.com Received: from aibo.runbox.com (HELO aibo.runbox.com) (91.220.196.211) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Sun, 22 Jan 2017 04:35:49 +0000 Received: from [10.9.9.212] (helo=mailfront12.runbox.com) by bars.runbox.com with esmtp (Exim 4.71) (envelope-from ) id 1cV9sY-0002d0-Rh for kawa@sourceware.org; Sun, 22 Jan 2017 05:35:46 +0100 Received: from 70-36-239-8.dsl.dynamic.fusionbroadband.com ([70.36.239.8] helo=localhost.localdomain) by mailfront12.runbox.com with esmtpsa (uid:757155 ) (TLS1.2:DHE_RSA_AES_128_CBC_SHA1:128) (Exim 4.82) id 1cV9sU-0000On-3u for kawa@sourceware.org; Sun, 22 Jan 2017 05:35:42 +0100 Subject: match form as a generalization of case To: kawa@sourceware.org References: <201701171107.25991.Damien.Mattei@unice.fr> <7b059bf7-e537-1338-de60-6a6a93baaae8@bothner.com> From: Per Bothner Message-ID: <4509f53c-2941-4b1b-4935-e7b7bc5090a9@bothner.com> Date: Sun, 22 Jan 2017 04:36:00 -0000 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.6.0 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit X-IsSubscribed: yes X-SW-Source: 2017-q1/txt/msg00034.txt.bz2 I checked into the invoke branch a new 'match' form. (Actually, it was there before, but was broken.) I also checked some pattern extension to make match more useful, and documentation. If you want to try it out without re-building form git, you can try this: http://ftp.gnu.org/gnu/kawa/kawa-2.91_invoke-20170121.zip That zip file includes the documentation, which you can browse with the command: kawa-2.91_invoke/bin/kawa --browse-manual Here are the highlights. Note also that lambda and let forms both take PATTERNs now. -- Syntax: match MATCH-KEY EXPRESSION MATCH-CLAUSE^{+} The ‘match’ form is a generalization of ‘case’ using PATTERNs, MATCH-KEY ::= EXPRESSION MATCH-CLAUSE ::= ‘(’ PATTERN [GUARD] BODY ‘)’ The MATCH-KEY is evaluated, Then the MATCH-CLAUSEs are tried in order. The first MATCH-CLAUSE whose PATTERN matches (and the GUARD, if any, is true), is selected, and the corresponding BODY evaluated. It is an error if no MATCH-CLAUSE matches. (match value (0 (found-zero)) (x #if (> x 0) (found-positive x)) (x #if (< x 0) (found-negative x)) (x::symbol (found-symbol x)) (_ (found-other))) One ‘case’ feature is not (yet) directly supported by ‘match’: Matching against a list of values. However, this is easy to simulate using a guard using ‘memq’, ‘memv’, or ‘member’: ;; compare similar example under case (match (car '(c d)) (x #!if (memv x '(a e i o u)) ’vowel) (x #!if (memv x '(w y)) ’semivowel) (x x)) 8.3.1 Patterns -------------- The usual way to bind variables is to match an incoming value against a “pattern”. The pattern contains variables that are bound to some value derived from the value. (! [x::double y::double] (some-expression)) In the above example, the pattern ‘[x::double y::double]’ is matched against the incoming value that results from evaluating ‘(some-expression)’. That value is required to be a two-element sequence. Then the sub-pattern ‘x::double’ is matched against element 0 of the sequence, which means it is coerced to a ‘double’ and then the coerced value is matched against the sub-pattern ‘x’ (which trivially succeeds). Similarly, ‘y::double’ is matched against element 1. The syntax of patterns is a work-in-progress. (The focus until now has been in designing and implementing how patterns work in general, rather than the details of the pattern syntax.) PATTERN ::= IDENTIFIER | ‘_’ | PATTERN-LITERAL | ‘’’DATUM | PATTERN ‘::’ TYPE | ‘[’ LPATTERN^{*} ‘]’ LPATTERN ::= PATTERN | ‘@’ PATTERN | PATTERN ‘...’ | GUARD PATTERN-LITERAL ::= BOOLEAN | number | CHARACTER | STRING GUARD ::= ‘#!if’ EXPRESSION This is how the specific patterns work: IDENTIFIER This is the simplest and most common form of pattern. The IDENTIFIER is bound to a new variable that is initialized to the incoming value. ‘_’ This pattern just discards the incoming value. It is equivalent to a unique otherwise-unused IDENTIFIER. PATTERN-LITERAL Matches if the value is ‘equal?’ to the PATTERN-LITERAL. ‘’’DATUM Matches if the value is ‘equal?’ to the quoted DATUM. PATTERN ‘::’ TYPE The incoming value is coerced to a value of the specified TYPE, and then the coerced value is matched against the sub-PATTERN. Most commonly the sub-PATTERN is a plain IDENTIFIER, so the latter match is trivial. ‘[’ LPATTERN^{*} ‘]’ The incoming value must be a sequence (a list, vector or similar). In the case where each sub-pattern is a plain PATTERN, then the number of sub-patterns must match the size of the sequence, and each sub-pattern is matched against the corresponding element of the sequence. More generally, each sub-pattern may match zero or more consequtive elements of the incoming sequence. ‘#!if’ EXPRESSION No incoming value is used. Instead the EXPRESSION is evaluated. If the result is true, matching succeeds (so far); otherwise the match fails. This form is called a “guard” (https://en.wikipedia.org/wiki/Guard_(computer_science)). -- --Per Bothner per@bothner.com http://per.bothner.com/