<div dir="ltr"><div><div>Yes, this is an issue.  I kind of vaguely hint at it in the documentation, and didn&#39;t get around to making it an explicit point -- I use the phrase &quot;implements&quot; for things that have to be directly implemented, and &quot;supports&quot; for sort of &quot;transitive&quot; implements.  I use in-set and things like it in some of the fallbacks because the dependencies for set-&gt;stream are somewhat complex, and I didn&#39;t want to repeat the logic in each and every case; I wanted to just call set-&gt;stream.  At some point I tried to make an indirect helper that did dependency checking and reported errors in terms of the primary method being called, but it got a bit cumbersome.  I probably should have seen through the better code and docs, but I sort of hit a point of &quot;I need to just push this and see how it goes&quot;.<br>

<br></div>So, for documenting this, off the top of my head I&#39;d define tech terms &quot;implemented method&quot; and &quot;supported method&quot; in the documentation for define-generics, and refer to them as necessary in methods for gen:set and so on.  That way, saying that, for instance, set-count is a supported method whenever set-&gt;stream is a supported method, allows the documentation to imply all the direct dependencies of set-&gt;stream on things that need to be implemented methods, without having to restate them all.<br>

<br></div>For the implementation, what we have would fit the docs, and it might also be possible to slightly improve the error messages with some refactoring.<br></div><div class="gmail_extra"><br clear="all"><div>Carl Eastlund</div>


<br><br><div class="gmail_quote">On Fri, Aug 2, 2013 at 3:43 PM, Stephen Chang <span dir="ltr">&lt;<a href="mailto:stchang@ccs.neu.edu" target="_blank">stchang@ccs.neu.edu</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

Actually, I am realizing that every derived method depends on<br>
set-&gt;stream, even the ones that don&#39;t document it (ie set-union,<br>
set-union!, set-intersect, set-intersect!, etc), since they use<br>
in-set.<br>
<br>
I was in the process of creating a patch for the docs to add the<br>
missing dependencies but I ran into an issue that I think warrants<br>
discussion.<br>
<br>
When the docs specifies dependencies for derived methods, there are<br>
actually two kinds that are being conflated.<br>
<br>
*** The first kind of dependency is stricter and requires the<br>
programmer to explicitly implement the required methods, and fallbacks<br>
do not count. In the code, this dependency is enforced with a call to<br>
the #:defined-predicated supplied to define-generics.<br>
<br>
Example:<br>
<br>
set-copy says it depends on set-clear and set-add!.<br>
<br>
Below is a set implementation that implements all the primitive<br>
methods plus set-&gt;stream. There exist set-clear and set-add! functions<br>
but set-clear is a fallback so set-copy wont work. Only if I<br>
explicitly implement set-clear will I get set-copy.<br>
<br>
(struct lstset (lst)<br>
  #:transparent<br>
  #:methods gen:set<br>
  [(define (set-member? s x) (match s [(lstset lst) (member x lst)]))<br>
   (define (set-add s x)<br>
     (match s<br>
       [(lstset lst)<br>
        (lstset (cons x (filter (λ (y) (not (equal? y x))) lst)))]))<br>
   (define (set-remove s x) (match s [(lstset lst) (lstset (remove x lst))]))<br>
   (define (set-add! s x) (void))<br>
   (define (set-remove! s x) (void))<br>
   (define (set-&gt;stream s) (lstset-lst s))])<br>
<br>
&gt; (set-add (lstset &#39;(1 2)) 4)<br>
(lstset &#39;(4 1 2))<br>
&gt; (set-clear (lstset &#39;(1 2)))<br>
(lstset &#39;())<br>
&gt; (set-copy (lstset &#39;(1 2 3)))<br>
. . set-copy: not implemented for (lstset &#39;(1 2 3))<br>
<br>
<br>
<br>
*** The second kind of dependency is looser and allows fallbacks. For<br>
example set-count requires set-&gt;stream, but if I implement in-set,<br>
that is good enough.<br>
<br>
<br>
I guess my question is, is this a docs issue, or should the code have<br>
more calls to set-implements?<br>
<div class="HOEnZb"><div class="h5"><br>
<br>
<br>
On Fri, Aug 2, 2013 at 1:47 PM, Stephen Chang &lt;<a href="mailto:stchang@ccs.neu.edu">stchang@ccs.neu.edu</a>&gt; wrote:<br>
&gt;&gt; With that in mind, I think it would make sense to move `set-first&#39; and<br>
&gt;&gt; `set-empty?&#39; to the primitive set (making it clear that they are<br>
&gt;&gt; optional, and can be derived from `set-&gt;stream&#39; if need be). With those<br>
&gt;&gt; two in the primitive set, anything that implements all the primitives<br>
&gt;&gt; should get all the derived for free, right?<br>
&gt;<br>
&gt; Oh yeah, I like that better than moving set-&gt;stream to primitives<br>
&gt; since they are more &quot;standard&quot; set operations.<br>
&gt;<br>
&gt; Carl, I dont see how guaranteeing some fallback implementations<br>
&gt; affects allowing more efficient versions. I think most programmers<br>
&gt; understand that the default implementation is probably not very<br>
&gt; efficient.<br>
&gt;<br>
&gt;<br>
&gt;<br>
&gt;<br>
&gt;<br>
&gt;<br>
&gt;&gt;<br>
&gt;&gt; Vincent<br>
<br>
</div></div></blockquote></div><br></div>