Re: [Chicken-hackers] PATCH: wrong type for alist-delete!

2016-02-12 Thread Peter Bex
On Fri, Feb 12, 2016 at 12:40:45PM +, Andy Bennett wrote:
> Hi Peter,
> 
> What happens when the alist argument to assoc isn't static? Does the
> data analysis know the types?

Hi Andy!

In that case it depends on where the list comes from.
In the general case (most cases, I'd say) that's impossible.  Then
it will simply fall back to (list-of (pair * *)) aka (list-of pair),
which would be the same as it would treat all cases after my patch.

I say the general case is "most cases", because a list coming from
elsewhere and which may be mutated at any time has to be assumed to
have contents of unknown types.  If someone does a set-car! somewhere,
they can completely invalidate the types we know about the list.

> Which type is better for safe code
> generation in the non-static data case (which I imagine to be the
> general case).

The more specific type is always better, and it is equivalent to the
less specific type when the types aren't known.

> Is there a difference between building the alist up dynamically with
> alist-cons compared to using quasiquote or cons or something?

I don't think there's a difference there, because (after the fix in
my patch), the types of lists created by alist-cons are known just
like for regular old cons.

Cheers,
Peter


signature.asc
Description: Digital signature
___
Chicken-hackers mailing list
Chicken-hackers@nongnu.org
https://lists.nongnu.org/mailman/listinfo/chicken-hackers


Re: [Chicken-hackers] PATCH: wrong type for alist-delete!

2016-02-12 Thread Andy Bennett
Hi Peter,

> It occurred to me that maybe the scrutinizer is smart enough to merge
> lists of pairs of (known) mixed types, and it actually is!
> 
> (use srfi-1)
> (print (assoc 'x '((1 . 2) (#f . 4)) (lambda (x y) (> x y
> 
> When compiled, this will tell you:
> Warning: at toplevel:
>   (test.scm:2) in procedure call to `assoc', expected argument #3 of type 
> `(procedure ((or false fixnum) symbol) *)', but was given an argument of type 
> `(procedure (number number) boolean)'
> 
> So I guess my patch needlessly weakens the type declarations.

What happens when the alist argument to assoc isn't static? Does the
data analysis know the types? Which type is better for safe code
generation in the non-static data case (which I imagine to be the
general case).

Is there a difference between building the alist up dynamically with
alist-cons compared to using quasiquote or cons or something?



Regards,
@ndy

-- 
andy...@ashurst.eu.org
http://www.ashurst.eu.org/
0290 DA75 E982 7D99 A51F  E46A 387A 7695 7EBA 75FF




signature.asc
Description: OpenPGP digital signature
___
Chicken-hackers mailing list
Chicken-hackers@nongnu.org
https://lists.nongnu.org/mailman/listinfo/chicken-hackers


Re: [Chicken-hackers] PATCH: wrong type for alist-delete!

2016-02-12 Thread Peter Bex
On Fri, Feb 12, 2016 at 08:50:21AM +0100, Peter Bex wrote:
> It occurred to me that maybe the scrutinizer is smart enough to merge
> lists of pairs of (known) mixed types, and it actually is!
> 
> (use srfi-1)
> (print (assoc 'x '((1 . 2) (#f . 4)) (lambda (x y) (> x y
> 
> When compiled, this will tell you:
> Warning: at toplevel:
>   (test.scm:2) in procedure call to `assoc', expected argument #3 of type 
> `(procedure ((or false fixnum) symbol) *)', but was given an argument of type 
> `(procedure (number number) boolean)'
> 
> So I guess my patch needlessly weakens the type declarations.  I'll send
> a new patch before next week that applies the same kind of aggressively
> specific type to the alist procedures.

With the attached patch, you get the same message, but with the arguments
reversed which is, as discussed, more consistent:

Warning: at toplevel:
  (test.scm:3) in procedure call to `assoc', expected argument #3 of type 
`(procedure (symbol (or false fixnum)) *)' but was given an argument of type 
`(procedure (number number) boolean)'

And if you change srfi-1 to data-structures, and assoc to rassoc,
the current master doesn't give a compile time warning, but with this
patch you'll get the same warning with both CHICKEN versions:

Warning: at toplevel:
  (test.scm:2) in procedure call to `rassoc', expected argument #3 of type 
`(procedure (symbol (or false fixnum)) *)' but was given an argument of type 
`(procedure (number number) boolean)'

Now, whether the signature of "rassoc" should differ from that of "assoc"
in core is another matter.  But at least we get better error checking
now, and potentially better performance too.

I've also simplified the (forall (a b) ...) for memq, memv and the
CHICKEN 5 version of member to (forall (a) ...), because the "a" type
didn't add anything.  For those procedures accepting a comparison
procedure, it does matter, so there I've kept it.  I've augmented the
type information for rassoc, alist-cons, alist-copy, and alist-delete[!]
so the types are very precise.  I also noticed that alist-update
included an extra argument in its type after the comparison procedure,
which the code does not accept, so I've removed that as well.

Cheers,
Peter
From c54596f61348e5fb39441b0f42bb9ade2fbe8c21 Mon Sep 17 00:00:00 2001
From: Peter Bex 
Date: Fri, 12 Feb 2016 20:17:03 +0100
Subject: [PATCH] Fix type signatures of a few alist procedures.

Thanks to Joerg Wittenberger for pointing out that the types weren't
exactly right.

This also makes the types and higher order procedures consistent in how
they call their argument predicates: always the supplied key first, and
the "thing in the list" second.

Conflicts:
	types.db
---
 data-structures.scm |  6 +++---
 types.db| 45 -
 2 files changed, 31 insertions(+), 20 deletions(-)

diff --git a/data-structures.scm b/data-structures.scm
index 65fdad7..f6726ee 100644
--- a/data-structures.scm
+++ b/data-structures.scm
@@ -223,7 +223,7 @@
 		  (let loop ([lst lst])
 			(and (pair? lst)
 			 (let ([a (##sys#slot lst 0)])
-			   (if (and (pair? a) (cmp (##sys#slot a 0) x))
+			   (if (and (pair? a) (cmp x (##sys#slot a 0)))
    a
    (loop (##sys#slot lst 1)) ) ) ) ) ) ] ) ] 
 	 [item (aq x lst)] )
@@ -243,7 +243,7 @@
(let ((a (##sys#slot lst 0)))
  (cond ((not (pair? a))
 (error 'alist-update "bad argument type" a))
-   ((cmp (##sys#slot a 0) k)
+   ((cmp k (##sys#slot a 0))
 (cons (cons k v) (##sys#slot lst 1)))
(else
 (cons (cons (##sys#slot a 0) (##sys#slot a 1))
@@ -261,7 +261,7 @@
 			 ((pair? lst)
 			  (let ((a (##sys#slot lst 0)))
 			(##sys#check-pair a 'alist-ref)
-			(if (cmp (##sys#slot a 0) x)
+			(if (cmp x (##sys#slot a 0))
 a
 (loop (##sys#slot lst 1)) ) ))
 			 (else (error 'alist-ref "bad argument type" lst)) )  ) ) ) ) )
diff --git a/types.db b/types.db
index c902bac..b5a5333 100644
--- a/types.db
+++ b/types.db
@@ -179,22 +179,19 @@
 (reverse (forall (a) (#(procedure #:clean #:enforce) reverse ((list-of a)) (list-of a)))
  ((null) (null) (let ((#(tmp) #(1))) '(
 
-(memq (forall (a b) (#(procedure #:clean #:foldable) memq
-(a (list-of b))
-(or false (list-of b
+(memq (forall (a) (#(procedure #:clean #:foldable) memq (* (list-of a))
+		   (or false (list-of a
   ((* null) (let ((#(tmp) #(1))) '#f))
   ((* list) (##core#inline "C_u_i_memq" #(1) #(2
 
-(memv (forall (a b) (#(procedure #:clean #:foldable) memv
-(a (list-of b))
-(or false (list-of b
+(memv (forall (a) (#(procedure #:clean #:foldable) memv (* (list-of a))
+		   (or false (list-of a
   ((* null) (let ((#(tmp) #(1))) '#f))
   (((or symbol procedure immediate) list)

Re: [Chicken-hackers] PATCH: wrong type for alist-delete!

2016-02-12 Thread Peter Bex
On Fri, Feb 12, 2016 at 08:34:15PM +0100, Peter Bex wrote:
> And if you change srfi-1 to data-structures, and assoc to rassoc,
> the current master doesn't give a compile time warning, but with this
> patch you'll get the same warning with both CHICKEN versions:
> 
> Warning: at toplevel:
>   (test.scm:2) in procedure call to `rassoc', expected argument #3 of type 
> `(procedure (symbol (or false fixnum)) *)' but was given an argument of type 
> `(procedure (number number) boolean)'

Interestingly enough, CHICKEN 5 gives this warning only at lower
optimization levels.  With -O3 and higher, the warning goes away(!)
I'm not sure what causes this it doesn't seem to be caused by
#:foldable because if I remove it, the warning is still gone, and
because the same happens with the "sort" procedure from data-structures,
which doesn't have #:foldable:

(use data-structures)
(print (sort '(x y z) (lambda (a b) (> a b

With -O2 or lower:

Warning: at toplevel:
  (/tmp/test.scm:5) in procedure call to `chicken.data-structures#sort', 
expected argument #2 of type `(procedure (symbol symbol) *)' but was given an 
argument of type `(procedure (number number) boolean)'

With -O3 or higher, no output!  CHICKEN 4 doesn't have this problem.

Anyway, it is a separate issue to the types.db patch but I just wanted
to mention it so you don't wonder why the warning doesn't show up.
I've created ticket #1258 so we won't forget to fix this before we
make a release.

Cheers,
Peter


signature.asc
Description: Digital signature
___
Chicken-hackers mailing list
Chicken-hackers@nongnu.org
https://lists.nongnu.org/mailman/listinfo/chicken-hackers


Re: [Chicken-hackers] PATCH: wrong type for alist-delete!

2016-02-11 Thread Peter Bex
On Thu, Feb 11, 2016 at 10:06:13PM +0100, Peter Bex wrote:
> On Thu, Jan 14, 2016 at 03:14:50PM +0100, Jörg F. Wittenberger wrote:
> > Hi all,
> > 
> > the srfi document wants a different type for alist-delete! than types.db
> > declares.
> 
> After all the discussion at the start, this thread kind of petered out.
> So let's try again.  Attached is a patch that got a bit larger as I was
> working on it and spotted more and more inconsistencies and problems:
> 
> 1) The types declared for memq, memv, member, assq, assv and [r]assoc
> were also too specific, asserting that they accepted a list of pairs of
> the same object types in each car and the same object types in
> each cdr of the pairs in the list.  Especially the type for assoc
> was ambitious but completely wrong :)

It occurred to me that maybe the scrutinizer is smart enough to merge
lists of pairs of (known) mixed types, and it actually is!

(use srfi-1)
(print (assoc 'x '((1 . 2) (#f . 4)) (lambda (x y) (> x y

When compiled, this will tell you:
Warning: at toplevel:
  (test.scm:2) in procedure call to `assoc', expected argument #3 of type 
`(procedure ((or false fixnum) symbol) *)', but was given an argument of type 
`(procedure (number number) boolean)'

So I guess my patch needlessly weakens the type declarations.  I'll send
a new patch before next week that applies the same kind of aggressively
specific type to the alist procedures.

Cheers,
Peter


signature.asc
Description: Digital signature
___
Chicken-hackers mailing list
Chicken-hackers@nongnu.org
https://lists.nongnu.org/mailman/listinfo/chicken-hackers


Re: [Chicken-hackers] PATCH: wrong type for alist-delete!

2016-02-11 Thread Peter Bex
On Thu, Jan 14, 2016 at 03:14:50PM +0100, Jörg F. Wittenberger wrote:
> Hi all,
> 
> the srfi document wants a different type for alist-delete! than types.db
> declares.

After all the discussion at the start, this thread kind of petered out.
So let's try again.  Attached is a patch that got a bit larger as I was
working on it and spotted more and more inconsistencies and problems:

1) The types declared for memq, memv, member, assq, assv and [r]assoc
were also too specific, asserting that they accepted a list of pairs of
the same object types in each car and the same object types in
each cdr of the pairs in the list.  Especially the type for assoc
was ambitious but completely wrong :)

2) I noticed a lot of these alist- procedures were marked "#:enforce",
but they won't enforce that the list is a proper list, nor that it
contains only pairs: If it can stop early it will, without verifying
anything after the found pair.  The "assoc" definition didn't have this
annotation, which I think is correct, so I've also removed it from the
others.

3) I've made the types of all higher order alist and list traversing
procedures such that the predicate receives the argument that was 
passed by the user first, and the thing in the list that it's comparing
against second.  This meant I had to change two procedure bodies in
data-structures.scm.  We had a short discussion about this on IRC, and
we concluded that SRFI-1 is explicit about argument order while our
data-structures documentation isn't explicit:

 "The comparison procedure is used to compare the element keys ki of
   alist's entries to the key parameter in this way: (= key ki).
   Thus, one can reliably remove all entries of alist whose key is
   greater than five with (alist-delete 5 alist <)"

If this is too large a change, I'd be okay with changing the types so
they're (procedure (* a) *) instead of (procedure (a *) *), but since
we don't specify anything about this, I'd argue any program which
relies on argument order is wrong anyway.  At least this way we get
a modicum of type sanity checking, which is worthwhile IMO.

4) I noticed that the type of alist-cons was completely wrong:
(alist-cons a b lst) isn't equivalent to (cons a (cons b lst)),
but to (cons (cons a b) lst)!  Also, I took the opportunity to
mark it #:pure, because it's just two conses, and cons is pure too.
   Come to think of it, would it be worthwhile to just rewrite it to
cons calls using a "specialization" for (* * *)?

The attached patches are for master and chicken-5.  SRFI-1 got moved
out to an egg for chicken-5, so if this commit is applied, the srfi-1
changes should (probably manually?) be extracted and applied to the
srfi-1 egg as well.

Cheers,
Peter
From 1279b315c5e5df2f41b5554d0cf07f1531090b17 Mon Sep 17 00:00:00 2001
From: Peter Bex 
Date: Thu, 11 Feb 2016 21:48:56 +0100
Subject: [PATCH] Fix type signatures of a few alist procedures.

Thanks to Joerg Wittenberger for pointing out that the types weren't
exactly right.

This also makes the types and higher order procedures consistent in how
they call their argument predicates: always the supplied key first, and
the "thing in the list" second.

Conflicts:
	types.db
---
 data-structures.scm |  6 +++---
 types.db| 45 +++--
 2 files changed, 26 insertions(+), 25 deletions(-)

diff --git a/data-structures.scm b/data-structures.scm
index 65fdad7..f6726ee 100644
--- a/data-structures.scm
+++ b/data-structures.scm
@@ -223,7 +223,7 @@
 		  (let loop ([lst lst])
 			(and (pair? lst)
 			 (let ([a (##sys#slot lst 0)])
-			   (if (and (pair? a) (cmp (##sys#slot a 0) x))
+			   (if (and (pair? a) (cmp x (##sys#slot a 0)))
    a
    (loop (##sys#slot lst 1)) ) ) ) ) ) ] ) ] 
 	 [item (aq x lst)] )
@@ -243,7 +243,7 @@
(let ((a (##sys#slot lst 0)))
  (cond ((not (pair? a))
 (error 'alist-update "bad argument type" a))
-   ((cmp (##sys#slot a 0) k)
+   ((cmp k (##sys#slot a 0))
 (cons (cons k v) (##sys#slot lst 1)))
(else
 (cons (cons (##sys#slot a 0) (##sys#slot a 1))
@@ -261,7 +261,7 @@
 			 ((pair? lst)
 			  (let ((a (##sys#slot lst 0)))
 			(##sys#check-pair a 'alist-ref)
-			(if (cmp (##sys#slot a 0) x)
+			(if (cmp x (##sys#slot a 0))
 a
 (loop (##sys#slot lst 1)) ) ))
 			 (else (error 'alist-ref "bad argument type" lst)) )  ) ) ) ) )
diff --git a/types.db b/types.db
index c902bac..9d94746 100644
--- a/types.db
+++ b/types.db
@@ -179,46 +179,39 @@
 (reverse (forall (a) (#(procedure #:clean #:enforce) reverse ((list-of a)) (list-of a)))
  ((null) (null) (let ((#(tmp) #(1))) '(
 
-(memq (forall (a b) (#(procedure #:clean #:foldable) memq
-(a (list-of b))
-(or false (list-of b
+(memq (forall (a) (#(procedure #:clean 

[Chicken-hackers] PATCH: wrong type for alist-delete!

2016-01-14 Thread Jörg F . Wittenberger
Hi all,

the srfi document wants a different type for alist-delete! than types.db
declares.

Patch attached.
>From 5834292305ac4882484169104535c72981e0167b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=C3=B6rg=20F=2E=20Wittenberger?=
 
Date: Thu, 14 Jan 2016 15:12:26 +0100
Subject: [PATCH] Fix type of alist-delete! according to srfi-1 spec.

---
 types.db | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/types.db b/types.db
index f259673..2491131 100644
--- a/types.db
+++ b/types.db
@@ -1854,7 +1854,7 @@
 (alist-cons (forall (a b c) (#(procedure #:clean) alist-cons (a b (list-of c)) (pair a (pair b (list-of c))
 (alist-copy (forall (a) (#(procedure #:clean #:enforce) alist-copy ((list-of a)) (list-of a
 (alist-delete (forall (a b) (#(procedure #:enforce) alist-delete (a (list-of b) #!optional (procedure (a b) *)) list)))
-(alist-delete! (forall (a b) (#(procedure #:enforce) alist-delete! (a (list-of b) #!optional (procedure (a b) *)) undefined)))
+(alist-delete! (forall (a b) (#(procedure #:enforce) alist-delete! (a (list-of b) #!optional (procedure (a b) *)) list)))
 (any (forall (a) (#(procedure #:enforce) any ((procedure (a #!rest) *) (list-of a) #!rest list) *)))
 (append! (#(procedure #:enforce) append! (#!rest list) list))
 
-- 
2.6.2

___
Chicken-hackers mailing list
Chicken-hackers@nongnu.org
https://lists.nongnu.org/mailman/listinfo/chicken-hackers


Re: [Chicken-hackers] PATCH: wrong type for alist-delete!

2016-01-14 Thread Evan Hanson
On 2016-01-14 15:14, Jörg F. Wittenberger wrote:
> the srfi document wants a different type for alist-delete! than types.db
> declares.
> 
> Patch attached.

Looks good to me. Debatably it ought to have an undefined return value,
as with typical destructive update procedures, but hey.

Signoff attached.

Evan
>From 061cfad9022d823a04dac69d1d766e8bd492118a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=C3=B6rg=20F=2E=20Wittenberger?=
 
Date: Thu, 14 Jan 2016 15:12:26 +0100
Subject: [PATCH] Fix type of alist-delete! according to srfi-1 spec.

Signed-off-by: Evan Hanson 
---
 types.db | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/types.db b/types.db
index f259673..2491131 100644
--- a/types.db
+++ b/types.db
@@ -1854,7 +1854,7 @@
 (alist-cons (forall (a b c) (#(procedure #:clean) alist-cons (a b (list-of c)) (pair a (pair b (list-of c))
 (alist-copy (forall (a) (#(procedure #:clean #:enforce) alist-copy ((list-of a)) (list-of a
 (alist-delete (forall (a b) (#(procedure #:enforce) alist-delete (a (list-of b) #!optional (procedure (a b) *)) list)))
-(alist-delete! (forall (a b) (#(procedure #:enforce) alist-delete! (a (list-of b) #!optional (procedure (a b) *)) undefined)))
+(alist-delete! (forall (a b) (#(procedure #:enforce) alist-delete! (a (list-of b) #!optional (procedure (a b) *)) list)))
 (any (forall (a) (#(procedure #:enforce) any ((procedure (a #!rest) *) (list-of a) #!rest list) *)))
 (append! (#(procedure #:enforce) append! (#!rest list) list))
 
-- 
2.6.4

___
Chicken-hackers mailing list
Chicken-hackers@nongnu.org
https://lists.nongnu.org/mailman/listinfo/chicken-hackers


Re: [Chicken-hackers] PATCH: wrong type for alist-delete!

2016-01-14 Thread Peter Bex
On Fri, Jan 15, 2016 at 09:00:54AM +1300, Evan Hanson wrote:
> On 2016-01-14 15:14, Jörg F. Wittenberger wrote:
> > the srfi document wants a different type for alist-delete! than types.db
> > declares.
> > 
> > Patch attached.
> 
> Looks good to me. Debatably it ought to have an undefined return value,
> as with typical destructive update procedures, but hey.

Not for SRFI-1, where the return value should be the same as the
non-destructive variant:

"alist-delete! is the linear-update variant of alist-delete. It is
 allowed, but not required, to alter cons cells from the alist parameter
 to construct the result."

But more to the point, isn't this type wrong?  (which would then
technically be wrong for _all_ the alist procedures)

> (alist-delete! (forall (a b) (#(procedure #:enforce) alist-delete! (a 
> (list-of b) #!optional (procedure (a b) *)) list)))

If I have an alist '((1 . x) (2.0 . y) (foo . 3)), then the type is
"(list-of pair)", and you can't get any more precise than that I think.
The types of the keys are mixed, which is somewhat weird but it's allowed
in an alist.

Anyway, in the above type signature, if the list is of type (list-of pair),
then "b" is "pair".  However, the procedure receives (a b) as arguments.
That's incorrect: it wouldn't receive the PAIRS in the list, but the
KEYS (so alternating, a fixnum, flonum and symbol).

Usually you'd pass a comparison procedure that accepts only keys of the
same type, but as you can see above that's not necessarily the case (this
example works fine if we use EQUAL? as the procedure).

I'm not 100% sure what the type should be though.  Perhaps something like
this?

(alist-delete! (forall (a b) (#(procedure #:enforce) alist-delete! (a (list-of 
pair) #!optional (procedure (a b) *)) (list-of pair

I kept the b in there to indicate that the comparison procedure doesn't
necessarily receive two arguments of the same type.

Thoughts?

Cheers,
Peter


signature.asc
Description: Digital signature
___
Chicken-hackers mailing list
Chicken-hackers@nongnu.org
https://lists.nongnu.org/mailman/listinfo/chicken-hackers


Re: [Chicken-hackers] PATCH: wrong type for alist-delete!

2016-01-14 Thread Evan Hanson
On 2016-01-14 21:32, Peter Bex wrote:
> Not for SRFI-1, where the return value should be the same as the
> non-destructive variant:

Right -- I meant srfi-1's API itself might be different.

The "list" return isn't incorrect, but it's also not as specific as it
could be. "(list-of pair)" would indeed be better.

Evan


signature.asc
Description: PGP signature
___
Chicken-hackers mailing list
Chicken-hackers@nongnu.org
https://lists.nongnu.org/mailman/listinfo/chicken-hackers


Re: [Chicken-hackers] PATCH: wrong type for alist-delete!

2016-01-14 Thread John Cowan
Evan Hanson scripsit:

> Looks good to me. Debatably it ought to have an undefined return value,
> as with typical destructive update procedures, but hey.

Not how linear-update works:  the !-less version is pure, the ! version is
not pure (or at least may not be pure).  In any case, the data structure
being changed is what is returned.  A number of SRFIs work like this.

-- 
John Cowan  http://www.ccil.org/~cowanco...@ccil.org
What is the sound of Perl?  Is it not the sound of a [Ww]all that people
have stopped banging their head against?  --Larry

___
Chicken-hackers mailing list
Chicken-hackers@nongnu.org
https://lists.nongnu.org/mailman/listinfo/chicken-hackers


Re: [Chicken-hackers] PATCH: wrong type for alist-delete!

2016-01-14 Thread John Cowan
Peter Bex scripsit:

> (alist-delete! (forall (a b) (#(procedure #:enforce) alist-delete! (a 
> (list-of pair) #!optional (procedure (a b) *)) (list-of pair

That seems right, but isn't b here equivalent to star?

-- 
John Cowan  http://www.ccil.org/~cowanco...@ccil.org
Verbogeny is one of the pleasurettes of a creatific thinkerizer.
--Peter da Silva

___
Chicken-hackers mailing list
Chicken-hackers@nongnu.org
https://lists.nongnu.org/mailman/listinfo/chicken-hackers


Re: [Chicken-hackers] PATCH: wrong type for alist-delete!

2016-01-14 Thread Evan Hanson
On 2016-01-14 16:10, John Cowan wrote:
> Evan Hanson scripsit:
> > Looks good to me. Debatably it ought to have an undefined return value,
> > as with typical destructive update procedures, but hey.
> 
> Not how linear-update works:  the !-less version is pure, the ! version is
> not pure (or at least may not be pure).  In any case, the data structure
> being changed is what is returned.  A number of SRFIs work like this.

Indeed, though that's not what the "!" convention means to me at first
glance. When I see a bang, I think guaranteed destructive update, not
linear-update. Of course, with lists you can't always do that, hence the
bangs and specified optionality.

IIRC there's some discussion of exactly this in the srfi-1 archives. I
just wish linear-update used a different naming convention.

Evan

___
Chicken-hackers mailing list
Chicken-hackers@nongnu.org
https://lists.nongnu.org/mailman/listinfo/chicken-hackers