Re: [Chicken-users] matchable egg usage question

2011-01-30 Thread Felix

Hi, Alex!

Are the new matchable extensions documented in the wiki? if not,
could you update it?


cheers,
felix

___
Chicken-users mailing list
Chicken-users@nongnu.org
http://lists.nongnu.org/mailman/listinfo/chicken-users


Re: [Chicken-users] matchable egg usage question

2011-01-29 Thread Alex Shinn
On Sun, Jan 30, 2011 at 1:40 PM, Alex Shinn  wrote:
>
> Because it searches for patterns where the head of the tree
> at each step along the path matches _, and the leaf matches
> '(bar 1).  The head is not searched as a potential leaf.

Sorry, whether the head is checked as a leaf or not
is irrelevant in this case - the node must either be a
list with a matching head pattern, or the leaf pattern.
In this case it doesn't match the leaf, so the entire
head (a (b (bar 1))) is matched as _, and then the
tail of () recursively searched (and fails).  It won't
match one pattern and then recursively search
within the matched value for other patterns.

-- 
Alex

___
Chicken-users mailing list
Chicken-users@nongnu.org
http://lists.nongnu.org/mailman/listinfo/chicken-users


Re: [Chicken-users] matchable egg usage question

2011-01-29 Thread Alex Shinn
On Sun, Jan 30, 2011 at 1:33 PM, Alan Post  wrote:
>
> Wonderful!  This is working for the test cases I sent, but it
> doesn't seem to work when I have a list where the first element
> is also a list:
>
>  (pretty-print (map
>    (match-lambda
>      (('foo (_ *** '(bar 1))) #t)
>      (_ #f))
>    '((foo (bar 1))
>      (foo (a (bar 1)))
>      (foo (a (b (bar 1
>      ; these three fail
>      (foo ((a (b (bar 1)
>      (foo (a ((b (bar 1)
>      (foo (a (b ((bar 1
>
> I don't understand why the last three examples fail to match the
> pattern here.  I would expect them all to match, or if that weren't
> true I'd expect all but the last one to match.

Because it searches for patterns where the head of the tree
at each step along the path matches _, and the leaf matches
'(bar 1).  The head is not searched as a potential leaf.

That's a somewhat arbitrary decision, but works well with the
intended use case which is matching SXML (where the head
is always a symbol).

-- 
Alex

___
Chicken-users mailing list
Chicken-users@nongnu.org
http://lists.nongnu.org/mailman/listinfo/chicken-users


Re: [Chicken-users] matchable egg usage question

2011-01-29 Thread Alan Post
On Sun, Jan 30, 2011 at 12:28:00PM +0900, Alex Shinn wrote:
> On Sun, Jan 30, 2011 at 12:09 PM, Alan Post  
> wrote:
> >
> > Alex, will you explain what I'd doing wrong here using
> > tree searching patterns?
> >
> > (pretty-print (map
> >  (match-lambda
> >    (('foo *** '(bar 1)) #t)
> >    (_ #f))
> >  '((foo (bar 1))
> >    (foo (a (bar 1)))
> >    (foo (a (b (bar 1
> >    (foo (a (b (c (bar 1
> >
> > Only the first form |(foo (bar 1))| is returning #t here.
> > The remaining forms return #f.  I would expect all of them
> > to return true, based on my naive understanding of the ***
> > operator.
> 
> 'foo has to match every step of the path.  It sounds
> like you want
> 
>   ('foo (_ *** '(bar 1)))
> 

Wonderful!  This is working for the test cases I sent, but it
doesn't seem to work when I have a list where the first element
is also a list:

  (pretty-print (map
(match-lambda
  (('foo (_ *** '(bar 1))) #t)
  (_ #f))
'((foo (bar 1))
  (foo (a (bar 1)))
  (foo (a (b (bar 1
  ; these three fail
  (foo ((a (b (bar 1)
  (foo (a ((b (bar 1)
  (foo (a (b ((bar 1

I don't understand why the last three examples fail to match the
pattern here.  I would expect them all to match, or if that weren't
true I'd expect all but the last one to match.

-Alan
-- 
.i ko djuno fi le do sevzi

___
Chicken-users mailing list
Chicken-users@nongnu.org
http://lists.nongnu.org/mailman/listinfo/chicken-users


Re: [Chicken-users] matchable egg usage question

2011-01-29 Thread Alex Shinn
On Sun, Jan 30, 2011 at 12:09 PM, Alan Post  wrote:
>
> Alex, will you explain what I'd doing wrong here using
> tree searching patterns?
>
> (pretty-print (map
>  (match-lambda
>    (('foo *** '(bar 1)) #t)
>    (_ #f))
>  '((foo (bar 1))
>    (foo (a (bar 1)))
>    (foo (a (b (bar 1
>    (foo (a (b (c (bar 1
>
> Only the first form |(foo (bar 1))| is returning #t here.
> The remaining forms return #f.  I would expect all of them
> to return true, based on my naive understanding of the ***
> operator.

'foo has to match every step of the path.  It sounds
like you want

  ('foo (_ *** '(bar 1)))

-- 
Alex

___
Chicken-users mailing list
Chicken-users@nongnu.org
http://lists.nongnu.org/mailman/listinfo/chicken-users


Re: [Chicken-users] matchable egg usage question

2011-01-29 Thread Alan Post
On Sat, Jan 29, 2011 at 11:23:54AM +0900, Alex Shinn wrote:
> So by deliberately limiting match we force people
> to write faster code.  At the same time, it's more
> verbose code - if you really want a match as powerful
> as prolog you could implement it and deal with the
> fact that it can be very slow in some cases.  And in
> that case you will eventually need to add a way to
> explicitly commit matches (i.e. "cut" in prolog) for
> decent performance.
> 
> [I'm not completely consistent in this, though,
> because the tree patterns I added do in fact
> require more complex searching and backtracking.
> But tree searches require this in general.]
> 

Alex, will you explain what I'd doing wrong here using
tree searching patterns?

(pretty-print (map
  (match-lambda
(('foo *** '(bar 1)) #t)
(_ #f))
  '((foo (bar 1))
(foo (a (bar 1)))
(foo (a (b (bar 1
(foo (a (b (c (bar 1

Only the first form |(foo (bar 1))| is returning #t here.
The remaining forms return #f.  I would expect all of them
to return true, based on my naive understanding of the ***
operator.

-Alan
-- 
.i ko djuno fi le do sevzi

___
Chicken-users mailing list
Chicken-users@nongnu.org
http://lists.nongnu.org/mailman/listinfo/chicken-users


Re: [Chicken-users] matchable egg usage question

2011-01-28 Thread Alex Shinn
On Fri, Jan 28, 2011 at 2:21 PM, Alan Post  wrote:
> I'm trying to use the matchable egg to detect #!key parameters in
> functions I've constructed.  I have functions that accept multiple
> #!key parameters, and I'm not sure how to make the matchable egg
> match |(func ... mykey: myvalue ...)|.  That is, how to get the
> matchable egg to match two parameters anywhere in an input list.

Why not use Chicken's builtin #!key handling?

  (apply (lambda (#!key key1 key2)
;; code using key1 and key2
...)
 (list key1: val1 key2: val2))

> This is what I've got so far.  I am interested in whether the
> #!key paramater 'a' is set to #t:

OK, the original point of this style of pattern matching
was it was simple and fast - it does a simple linear
match against each possible pattern so is as fast as
using low-level destructuring and checking (faster if
the match library can eliminate common sub-patterns).

As soon as you introduce any ambiguity in how a
pattern can match the whole process becomes a
search algorithm, with backtracking in the general
case.  So whereas the pattern

  (a b c)

is constant time (O(m) in the pattern size),

  (a b c ...)

is linear (O(n) in the input size), which is fine, but

  (a b c ... d ...)

is O(n^2) in the input size depending on where
you choose to split between c and d.  And

  (a b c ... d ... e ...)

is O(n^3), etc.

Most of the time when you want to use this sort
of pattern, you don't want backtracking - you want
c to match as many elements as it can and then
"commit," and take the rest of the list as d.  So if
the match doesn't let you express the expensive
patterns, you have to iterate over one c at a time:

  (let lp ((ls ls) (c-ls '())
(match ls
  ((c . rest) (lp (cdr ls) (cons c c-ls)))
  (else
   ;; match d's in remaining ls
   ...)))

This is O(n), and is the same sort of idiom many
complex syntax-rules libraries use.

So by deliberately limiting match we force people
to write faster code.  At the same time, it's more
verbose code - if you really want a match as powerful
as prolog you could implement it and deal with the
fact that it can be very slow in some cases.  And in
that case you will eventually need to add a way to
explicitly commit matches (i.e. "cut" in prolog) for
decent performance.

[I'm not completely consistent in this, though,
because the tree patterns I added do in fact
require more complex searching and backtracking.
But tree searches require this in general.]

-- 
Alex

___
Chicken-users mailing list
Chicken-users@nongnu.org
http://lists.nongnu.org/mailman/listinfo/chicken-users


[Chicken-users] matchable egg usage question

2011-01-27 Thread Alan Post
I'm trying to use the matchable egg to detect #!key parameters in
functions I've constructed.  I have functions that accept multiple
#!key parameters, and I'm not sure how to make the matchable egg
match |(func ... mykey: myvalue ...)|.  That is, how to get the
matchable egg to match two parameters anywhere in an input list.

This is what I've got so far.  I am interested in whether the
#!key paramater 'a' is set to #t:

  (use matchable)

  (pretty-print (map
(match-lambda
  ((_ 'a: #t . _) '(0 #t))
  ((_ ... 'a: #t) '(1 #t))
  (_  #f))
'((foo)
  (foo bar)
  (foo a: #f)
  (foo a: #f b: #t)
  (foo a: #f b: #t c: #t)
  (foo a: #f c: #t b: #t)
  (foo b: #t a: #f c: #t)
  (foo b: #t c: #t a: #f)
  (foo a: #t)
  (foo a: #t b: #t)
  (foo a: #t b: #t c: #t)
  (foo a: #t c: #t b: #t)
  (foo b: #t a: #t c: #t)
  (foo b: #t c: #t a: #t
  (exit)

This works for every case except when the #!key I want to match
appears in the middle of a list of arguments, as happens in the
second-to-last case I'm trying to match.

Is there a way to make match work in this case?  What pattern
should I add to match values anywhere in the list, not just the
front and end?

-Alan
-- 
.i ko djuno fi le do sevzi

___
Chicken-users mailing list
Chicken-users@nongnu.org
http://lists.nongnu.org/mailman/listinfo/chicken-users