behavior of CASE with strings PART 2

classic Classic list List threaded Threaded
12 messages Options
Reply | Threaded
Open this post in threaded view
|

behavior of CASE with strings PART 2

Damien Mattei
testing with eqv? predicate (that seems to be used in kawa CASE if it follow R5RS) and according to https://www.gnu.org/software/kawa/Conditionals.html i have this:

|kawa:1|# (case "dog" (("cat" "dog" "mouse") "animal") (else "mineral or vegetable"))
animal
#|kawa:2|# (invoke "dog":class 'getName)
java.lang.String
#|kawa:3|# (eqv? "dog" "dog")
#t
#|kawa:4|# (define a "dog")
#|kawa:5|# (eqv? a "dog")
#t

and now in my code:

i modified the code to display things:

(begin

                 (display-msg-var-nl  "ResultatGeneralAFKawa : work : type1 = " type1)
                 (display-msg-var-nl  "ResultatGeneralAFKawa : work : type2 = " type2)

                 (display-msg-var-nl  "ResultatGeneralAFKawa : work : Nom = " Nom)

                 (if (equal? "B5" type1)
                     (display-nl "ResultatGeneralAFKawa : work : equal? test TRUE")
                     (display-nl "ResultatGeneralAFKawa : work : equal? test FALSE"))

                 (if (eqv? "B5" type1)
                     (display-nl "ResultatGeneralAFKawa : work : eqv? test TRUE")
                     (display-nl "ResultatGeneralAFKawa : work : eqv? test FALSE"))

                 ;;(display (string-append "|" (type1:getClass:getName) "|"))
                 (display "ResultatGeneralAFKawa : work : type1 is of type : ")
                 (display   (invoke type1:class 'getName) )
                 (newline)

                 (display "ResultatGeneralAFKawa : work : B5 is of type : ")
                 (display   (invoke "B5":class 'getName) )
                 (newline)

       
                 (if (eq? "B5" type1)
                     (display-nl "ResultatGeneralAFKawa : work : eq? test TRUE")
                     (display-nl "ResultatGeneralAFKawa : work : eq? test FALSE"))


                 (set! nutype1
                       (case type1
                         (("O") 1) ;; java.lang.String
                         (("O0") 2)
                         (("O1") 3)
                         (("O2") 4)
                         (("O3") 5)
                         (("O4") 6)
                         (("O5") 7)
                         (("O6") 8)
                         (("O7") 9)
                         (("O8") 10)
                         (("O9") 11)
                         (("B") 12)
                         (("B0") 13)
                         (("B1") 14)
                         (("B2") 15)
                         (("B3") 16)
                         (("B4") 17)
                         (("B5") 18)
                         (("B6") 19)
                         (("B7") 20)
                         (("B8") 21)
                         (("B9") 22)
                         (("A") 23)
                         (("A0") 24)
                         (("A1") 25)
                         (("A2") 26)
                         (("A3") 27)
                         (("A4") 28)
                         (("A5") 29)
                         (("A6") 30)
                         (("A7") 31)
                         (("A8") 32)
                         (("A9") 33)
                         (("F") 34)
                         (("F0") 35)
                         (("F1") 36)
                         (("F2") 37)
                         (("F3") 38)
                         (("F4") 39)
                         (("F5") 40)
                         (("F6") 41)
                         (("F7") 42)
                         (("F8") 43)
                         (("F9") 44)
                         (("G") 45)
                         (("G0") 46)
                         (("G1") 47)
                         (("G2") 48)
                         (("G3") 49)
                         (("G4") 50)
                         (("G5") 51)
                         (("G6") 52)
                         (("G7") 53)
                         (("G8") 54)
                         (("G9") 55)
                         (("K") 56)
                         (("K0") 57)
                         (("K1") 58)
                         (("K2") 59)
                         (("K3") 60)
                         (("K4") 61)
                         (("K5") 62)
                         (("K6") 63)
                         (("K7") 64)
                         (("K8") 65)
                         (("K9") 66)
                         (("M") 67)
                         (("M0") 68)
                         (("M1") 69)
                         (("M2") 70)
                         (("M3") 71)
                         (("M4") 72)
                         (("M5") 73)
                         (("M6") 74)
                         (("M7") 75)
                         (("M8") 76)
                         (("M9") 77)
                         (else => (begin
                                    (display-nl "display values:")
                                    (dv type1)
                                    (dv nutype1)
                                    (display "WARNING : ResultatGeneralAFKawa : work : CASE type1 in ELSE")
                                    (newline)
                                    '()))))
                                   
                 (dv nutype1)

display* and dv are macro to display variables.

here is the output in logs:

ResultatGeneralAFKawa : work : type1 = B5
ResultatGeneralAFKawa : work : type2 = F5
ResultatGeneralAFKawa : work : Nom = FIN
ResultatGeneralAFKawa : work : equal? test TRUE
ResultatGeneralAFKawa : work : eqv? test FALSE
ResultatGeneralAFKawa : work : type1 is of type : java.lang.String
ResultatGeneralAFKawa : work : B5 is of type : java.lang.String
ResultatGeneralAFKawa : work : eq? test FALSE
display values:
type1 = B5
nutype1 = ()
WARNING : ResultatGeneralAFKawa : work : CASE type1 in ELSE

my concern is with type1 which is of type java.lang.String ,also "B5" in case is of type java.lang.String ,and they should be equal in the sense of eqv? and the CASE should be satisfied in (("B5") 18) but in,stead it goes in ELSE clause
because "B5" and type1 are not equal (eqv?) as "dog" and "dog" (depends of the scheme implementation )
i do not want to rewrite the CASE in other things, is there a way to have String that equal in the sense of eqv?  ?

regards,

damien


--
[hidden email], [hidden email], UNS / OCA / CNRS
Reply | Threaded
Open this post in threaded view
|

Re: behavior of CASE with strings PART 2

Per Bothner


On 01/17/2017 02:07 AM, Damien MATTEI wrote:
> testing with eqv? predicate (that seems to be used in kawa CASE if it follow R5RS) and according to https://www.gnu.org/software/kawa/Conditionals.html i have this:
>
> |kawa:1|# (case "dog" (("cat" "dog" "mouse") "animal") (else "mineral or vegetable"))
animal

CASE *cannot* meaningfully be used with strings.

#|kawa:2|# (case (string-copy "dog") (("cat" "dog" "mouse") "animal") (else "mineral or vegetable"))
mineral or vegetable

The reason is that case tests use eqv?, and "The eqv? procedure returns #f if" ...
"obj 1 and obj 2 are pairs, vectors, bytevectors, records,
or strings that denote distinct locations. (quoting directly from R7RS).
R5RS is the same in this respect.

Thus (eqv? (string-copy "dog") "dog") is #f, as is (eqv? (string #\d #\o #\g) "dog").
Even (eqv? "dog" "dog") is *unspecified* according to R7RS, because it does not
require that the two "dog" literals are the same location.

It might be reasonable to add a warning, like Kawa does with lists:

#|kawa:8|# (case "dog" ((("cat") "dog" "mouse") "animal") (else "mineral or vegetable"))
/dev/stdin:8:15: warning - List and vectors will never be matched in a case clause
/dev/stdin:8:15: warning - datum type incompatible with the key

--
        --Per Bothner
[hidden email]   http://per.bothner.com/
Reply | Threaded
Open this post in threaded view
|

Re: behavior of CASE with strings PART 2

Jamison Hope
On Jan 17, 2017, at 8:23 AM, Per Bothner <[hidden email]> wrote:

> CASE *cannot* meaningfully be used with strings.

Indeed.  Meanwhile, this sort of categorization of strings can be
useful, as evidenced by the addition of String switches to Java 7.

The portable Scheme way to do this would be to use symbols instead of
strings, since ordinarily symbols are interned and thereby eqv?, but I
could see a place for Kawa-specific syntax that compiles to the
equivalent of a Java String switch block (which uses hash codes and a
lookupswitch to avoid doing every string comparison in a big if-else
chain).

I'm not sure what we would call the macro, though -- string-case makes
me think of uppercase vs lowercase.

--
Jamison Hope
The PTR Group
www.theptrgroup.com



Reply | Threaded
Open this post in threaded view
|

Re: behavior of CASE with strings PART 2

Per Bothner


On 01/17/2017 07:57 AM, Jamison Hope wrote:
> On Jan 17, 2017, at 8:23 AM, Per Bothner <[hidden email]> wrote:
>
>> CASE *cannot* meaningfully be used with strings.
>
> Indeed.  Meanwhile, this sort of categorization of strings can be
> useful, as evidenced by the addition of String switches to Java 7.

I guess we could add it as a Kawa "extension", but it would explicitly
violate r5rs/r7rs.

> The portable Scheme way to do this would be to use symbols instead of
> strings, since ordinarily symbols are interned and thereby eqv?, but I
> could see a place for Kawa-specific syntax that compiles to the
> equivalent of a Java String switch block (which uses hash codes and a
> lookupswitch to avoid doing every string comparison in a big if-else
> chain).

I think this is something to think of for the Kawa 3.0 release,
using the new PATTERN construct in each clause.
--
        --Per Bothner
[hidden email]   http://per.bothner.com/
Reply | Threaded
Open this post in threaded view
|

Re: behavior of CASE with strings PART 2

Per Bothner


On 01/17/2017 10:36 PM, Per Bothner wrote:
> I think this is something to think of for the Kawa 3.0 release,
> using the new PATTERN construct in each clause.

The invoke branch has a 'match' form, which has the syntax:

(match TARGET-EXPR (PATTERN BODY...) ...)

This matches TARGET-EXPR against each PATTERN, until one matches,
at which point the BODY... forms are evaluated.

This is the 'match' form from Racket:
   https://docs.racket-lang.org/guide/match.html
   https://docs.racket-lang.org/reference/match.html

Unfortunately, the implemented forms of PATTERN are very
limited, but the intention to allow literals and quoted forms.
These will be compared using equal?, so you will be able to write:

    (match "yes"
     ("no" #f)
     ("yes" #t))

THIS IS NOT YET IMPLEMENTED.  (It's not conceptually hard; I just need to
decide the best way to present such match forms.)

I think this is the generalization of 'case' that we're looking for.
--
        --Per Bothner
[hidden email]   http://per.bothner.com/
Reply | Threaded
Open this post in threaded view
|

Re: behavior of CASE with strings PART 2

Damien Mattei
Le Thursday 19 January 2017 05:53:05 Per Bothner, vous avez écrit :

>
> On 01/17/2017 10:36 PM, Per Bothner wrote:
> > I think this is something to think of for the Kawa 3.0 release,
> > using the new PATTERN construct in each clause.
>
> The invoke branch has a 'match' form, which has the syntax:
>
> (match TARGET-EXPR (PATTERN BODY...) ...)
>
> This matches TARGET-EXPR against each PATTERN, until one matches,
> at which point the BODY... forms are evaluated.
>
> This is the 'match' form from Racket:
>    https://docs.racket-lang.org/guide/match.html
>    https://docs.racket-lang.org/reference/match.html
>
> Unfortunately, the implemented forms of PATTERN are very
> limited, but the intention to allow literals and quoted forms.
> These will be compared using equal?, so you will be able to write:
>
>     (match "yes"
>      ("no" #f)
>      ("yes" #t))
>
> THIS IS NOT YET IMPLEMENTED.  (It's not conceptually hard; I just need to
> decide the best way to present such match forms.)
>
> I think this is the generalization of 'case' that we're looking for.

Hi Per,

thanks for your answer...
i read the many answers to the mailing list about CASE and STRINGS and delayed my answer because i
wanted to answer after having a solution (still not done)

i understand the various implementation of Scheme follow or not the R5RS and R7RS
 but this could be changed in a future revision because it is limitating to be able to use CASE with STRINGS
in language such as ASP, Java and not Scheme, with Racket it seems that equal? predicate is used,
so probably my code will work with Racket.

i think of many solutions and finalyy begin to write a  recursive macro implementing a case-string
 but i'm facing proble with multiple "ellipsis" in a recursive macro and wanted to debug it this morning
when  i read your last message, so here it is:

;; CASE adapted for string comparison

(define-syntax case-string
 
  (syntax-rules ()
   
    ((_ var
        (lst res)
        (... ...)
        (else => res-else))
     
     (if (member var lst)
         res
         (case var
           (... ...)
           (else => res-else))))
   
    ((_ var
        (else => res-else))

     res-else)))

ellispsis have to be fixed and the behavior seems to be not defined in R5RS i tried many scheme and it behave diffrently, even in Racket with #lang R5RS
it does not work now

Damien

--
[hidden email], [hidden email], UNS / OCA / CNRS
Reply | Threaded
Open this post in threaded view
|

Re: behavior of CASE with strings PART 2

Per Bothner
On 01/19/2017 02:04 AM, Damien MATTEI wrote:
> i understand the various implementation of Scheme follow or not the R5RS and R7RS
>  but this could be changed in a future revision because it is limitating to be able to use CASE with STRINGS
> in language such as ASP, Java and not Scheme, with Racket it seems that equal? predicate is used,
> so probably my code will work with Racket.

I guess it may be worth considering extending case to use equal? rather than eqv?.
Though in theory an incompatible change, I don't see how it would break working programs.
What do people think?  Though note this is not just a one-line change.  I'd have to study to case
implementation and optimizations and see what would need to change.  So it could be a
"wishlist" item, but not necessarily right away.

> i think of many solutions and finalyy begin to write a  recursive macro implementing a case-string
>  but i'm facing proble with multiple "ellipsis" in a recursive macro and wanted to debug it this morning
> when  i read your last message, so here it is:

There is a syntax-rules implementation of case in R7RS (7.3 Derived expression types).
You could use thtat as a starting-point.  Of course it wouldn't have the optimizations
of Kawa's builtin case.
--
        --Per Bothner
[hidden email]   http://per.bothner.com/
Reply | Threaded
Open this post in threaded view
|

Re: behavior of CASE with strings PART 2

Damien Mattei-2
In reply to this post by Damien Mattei
Hi Per,

i could use string->symbol instead of strings with the normal CASE but
i finally wrote a macro for CASE with strings,
it was harder than expected , i learned macro at university with the
define-macro style ,i was familiar with this style, now define-syntax
is used, here is my macro:

(define-syntax case-string

  (syntax-rules ( => )


    ;; (define dog "dog")
    ;; (case-string dog (("dog") "animal")   (else => "mineral or vegetable"))
    ((case-string var
          lst
          (else => res-else  ...))

     (if (member var (car (quote lst)))
       (cadr (quote lst))
       (begin
         res-else
         ...)))

    ;; (define cat "cat")
    ;; (case-string cat (("dog") "animal") (("cat") "my daughter say
cats are not animals!")  (else => "mineral or vegetable"))
    ((case-string var
              lst
              lst2
              ...
              (else => res-else ...))

     (if (member var (car (quote lst)))
     (cadr (quote lst))
     (case-string var
              lst2
              ...
              (else => res-else ...))))



    ;;(case-string dog  (else => "silly case"))
    ((case-string var
          (else => res-else ...))

     (begin
       res-else
       ...))))

i'm not sure if this macro is r5rs compliant but i have test it
working. I will test it monday in our Kawa apps in Tomcat but i'm
almost sure it will solve all the errors.

Regards,

 Damien
Reply | Threaded
Open this post in threaded view
|

Re: behavior of CASE with strings PART 2

Damien Mattei-2
In reply to this post by Per Bothner
Hi Per,

in my opinion , rather than following Racket guide lines that are
complex , i prefer to write macro some times,
 and do things that are R*RS compliant because it's the best way to
keep progams compatible as i use many scheme
implementations,Kawa,Bigloo,Racket  .

the last macro i wrote case-string is working with Kawa and Racket
(even with #lang r5rs activated! should not work) but not with Bigloo
because the macro is not r5rs compliant ,it has some variable after
the ellipsis, and it is forbidden in r5rs and r7rs. (
http://www.schemers.org/Documents/Standards/R5RS/HTML/ )

i will try to understand how this one :

(define-syntax case
  (syntax-rules (else)
    ((case (key ...)
       clauses ...)
     (let ((atom-key (key ...)))
       (case atom-key clauses ...)))
    ((case key
       (else result1 result2 ...))
     (begin result1 result2 ...))
    ((case key
       ((atoms ...) result1 result2 ...))
     (if (memv key '(atoms ...))
         (begin result1 result2 ...)))
    ((case key
       ((atoms ...) result1 result2 ...)
       clause clauses ...)
     (if (memv key '(atoms ...))
         (begin result1 result2 ...)
         (case key clause clauses ...)))))

works next week....
and modify it for strings

regards,

damien




On Thu, Jan 19, 2017 at 5:53 AM, Per Bothner <[hidden email]> wrote:

>
>
> On 01/17/2017 10:36 PM, Per Bothner wrote:
>>
>> I think this is something to think of for the Kawa 3.0 release,
>> using the new PATTERN construct in each clause.
>
>
> The invoke branch has a 'match' form, which has the syntax:
>
> (match TARGET-EXPR (PATTERN BODY...) ...)
>
> This matches TARGET-EXPR against each PATTERN, until one matches,
> at which point the BODY... forms are evaluated.
>
> This is the 'match' form from Racket:
>   https://docs.racket-lang.org/guide/match.html
>   https://docs.racket-lang.org/reference/match.html
>
> Unfortunately, the implemented forms of PATTERN are very
> limited, but the intention to allow literals and quoted forms.
> These will be compared using equal?, so you will be able to write:
>
>    (match "yes"
>     ("no" #f)
>     ("yes" #t))
>
> THIS IS NOT YET IMPLEMENTED.  (It's not conceptually hard; I just need to
> decide the best way to present such match forms.)
>
> I think this is the generalization of 'case' that we're looking for.
>
> --
>         --Per Bothner
> [hidden email]   http://per.bothner.com/
Reply | Threaded
Open this post in threaded view
|

match form as a generalization of case

Per Bothner
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
[hidden email]   http://per.bothner.com/
Reply | Threaded
Open this post in threaded view
|

Re: match form as a generalization of case

Damien Mattei-2
thank you Per,
i will try this as soon as possible, if it is always build for jdk8 it
could be running because i must keep compatibility (and other people
are administering the sidonie2.oca.eu server and they want to keep the
server secure with only well tested package and they do not want to
have anything to recompile-sic)on the tomcat server with jdk8 (not 7
or 9), openjdk8 for debian,  and with bigloo that is compiled for
jdk8.
Also the pakckaging of kawa seems to have changed from .jar to .zip i
suppose i can extract it to create a jar file the way i already do it
with bigloo that provide.zip for the runtime lib, i must do that
because netbeans (and perheaps tomcat) only accept .jar files and zip
files are not recognized.I do not understand why switching from jar to
zip, seems to become general as it is more en more uncountered.
Damien

On Sun, Jan 22, 2017 at 5:35 AM, Per Bothner <[hidden email]> wrote:

> 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
> [hidden email]   http://per.bothner.com/
Reply | Threaded
Open this post in threaded view
|

Re: match form as a generalization of case

Per Bothner
On 01/23/2017 02:12 PM, Damien Mattei wrote:
> thank you Per,
> i will try this as soon as possible, if it is always build for jdk8 it
> could be running because i must keep compatibility (and other people
> are administering the sidonie2.oca.eu server and they want to keep the
> server secure with only well tested package and they do not want to
> have anything to recompile-sic)on the tomcat server with jdk8 (not 7
> or 9), openjdk8 for debian,  and with bigloo that is compiled for
> jdk8.

The binary distribution should work fine on Java 7 (except for the
JLine line editing support). If it doesn't, I made a mistake.

The source distribution is supposed to be buildable on Java 6, as well as
Android.  (It might build on Java 5, but I haven't tested that in a while.)

> Also the pakckaging of kawa seems to have changed from .jar to .zip i
> suppose i can extract it to create a jar file the way i already do it
> with bigloo that provide.zip for the runtime lib, i must do that
> because netbeans (and perheaps tomcat) only accept .jar files and zip
> files are not recognized.I do not understand why switching from jar to
> zip, seems to become general as it is more en more uncountered.

Zip is more commonly used that jar - by definition, since a jar file
is a zip file. Kawa uses a zip file to bundle the kawa.jar file *plus* a bunch of
other stuff: Helper libraries, shell/batch scripts, and documentation.
Just use unzip (or jar xf) to extract the files and use kawa-VERSION/lib/kawa.jar.
--
        --Per Bothner
[hidden email]   http://per.bothner.com/