<div dir="ltr">No, that doesn&#39;t work.  If someone implements, say, an efficient subset? test, then set=? should use that rather than iterating using set-&gt;stream and set-member?.  You should use the highest-level methods you can, in order to get the most out of an implementation.  Which is why I made all the fallback implementations I did, to give implementers the best flexibility possible for getting a good implementation of all methods for the minimum possible effort on their part.<br>

<br>Similarly, I don&#39;t want to make set-&gt;stream primitive, because if someone does implement set-first and set-rest, it should be derivable.<br></div><div class="gmail_extra"><br clear="all"><div>Carl Eastlund</div>


<br><br><div class="gmail_quote">On Thu, Aug 1, 2013 at 7:26 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">

<div class="im">&gt; Would it be better to just remove the &quot;primitve&quot; / &quot;derived&quot; distinction,<br>
&gt; since it&#39;s somewhat artificial, and leave it up to the individual method<br>
&gt; descriptions?  Is there some better way I should be describing things?<br>
<br>
</div>Ok I can see now that there&#39;s no easy way to organize the methods.<br>
<br>
I think we should keep some distinction, since as a programmer it&#39;s<br>
good to know exactly what methods I have to implement. However, to me<br>
&quot;fallback&quot; implies that I should get it for free, so it seems most<br>
intuitive if derived methods only depend on primitive methods. Then<br>
for some subset of primitive methods that I implement, I should get<br>
the derived methods that depend on those primitives. I&#39;ll have to<br>
think more about what should be derived and primitive, but for now I<br>
think the easiest thing is to edit the docs to move set-&gt;stream (or<br>
some equivalent) into the primitive list?<br>
<div class="HOEnZb"><div class="h5"><br>
<br>
<br>
&gt;<br>
&gt; Carl Eastlund<br>
&gt;<br>
&gt;<br>
&gt; On Thu, Aug 1, 2013 at 6:51 PM, Stephen Chang &lt;<a href="mailto:stchang@ccs.neu.edu">stchang@ccs.neu.edu</a>&gt; wrote:<br>
&gt;&gt;<br>
&gt;&gt; &gt; For the other part, I either should have made it as you say -- implement<br>
&gt;&gt; &gt; the &gt; &quot;primitive&quot; ones and you get the others -- or else I should have<br>
&gt;&gt; &gt; clearly<br>
&gt;&gt; &gt; documented the relationship somewhere.<br>
&gt;&gt;<br>
&gt;&gt; You did document the dependencies, but some of them are circular, ie<br>
&gt;&gt; some derived rely on other derived. I&#39;d definitely be happy to patch<br>
&gt;&gt; things myself, but I guess I dont have a concrete complaint yet :),<br>
&gt;&gt; only that the distinctions feel somewhat arbitrary and did not match<br>
&gt;&gt; my initial intuition, which is why I&#39;m looking for additional insight.<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt; &gt; Do you have examples of which ones don&#39;t come &quot;for free&quot; with the<br>
&gt;&gt; &gt; primitive<br>
&gt;&gt; &gt; methods?<br>
&gt;&gt;<br>
&gt;&gt; Very few of the derived come free because most rely on set-&gt;stream,<br>
&gt;&gt; but set-&gt;stream is not &quot;primitive&quot; which is why I thought there might<br>
&gt;&gt; be a distinction between iterable sets and non-iterable.<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt; Carl Eastlund<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt; On Thu, Aug 1, 2013 at 6:27 PM, Stephen Chang &lt;<a href="mailto:stchang@ccs.neu.edu">stchang@ccs.neu.edu</a>&gt;<br>
&gt;&gt; &gt; wrote:<br>
&gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; Just played a bit with gen:set. It looks great and in particular the<br>
&gt;&gt; &gt;&gt; fallback implementations are very convenient.<br>
&gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; One comment: the distinction between &quot;primitive&quot; methods and &quot;derived&quot;<br>
&gt;&gt; &gt;&gt; methods confused me somewhat. Can you explain the reasoning for<br>
&gt;&gt; &gt;&gt; determining which is which?<br>
&gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; For example, when I first read the docs, I thought that if I<br>
&gt;&gt; &gt;&gt; implemented the primitives, I would get the derived, but that&#39;s not<br>
&gt;&gt; &gt;&gt; the case since some of the derived methods depend on each other.<br>
&gt;&gt; &gt;&gt; Reading the docs more thoroughly, it sort of seems like there&#39;s an<br>
&gt;&gt; &gt;&gt; implicit separation along the lines of iterability, ie, derived sets<br>
&gt;&gt; &gt;&gt; are &quot;iterable&quot; since many of the derived methods require set-&gt;stream,<br>
&gt;&gt; &gt;&gt; but that&#39;s not exactly right either.<br>
&gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; On Thu, Jul 25, 2013 at 1:58 PM, Carl Eastlund &lt;<a href="mailto:cce@ccs.neu.edu">cce@ccs.neu.edu</a>&gt; wrote:<br>
&gt;&gt; &gt;&gt; &gt; After some fixes, mostly to contracts and documentation, I&#39;ve pushed<br>
&gt;&gt; &gt;&gt; &gt; the<br>
&gt;&gt; &gt;&gt; &gt; new<br>
&gt;&gt; &gt;&gt; &gt; generics and set features to the master branch.<br>
&gt;&gt; &gt;&gt; &gt;<br>
&gt;&gt; &gt;&gt; &gt; Carl Eastlund<br>
&gt;&gt; &gt;&gt; &gt;<br>
&gt;&gt; &gt;&gt; &gt;<br>
&gt;&gt; &gt;&gt; &gt; On Tue, Jul 23, 2013 at 11:37 AM, Carl Eastlund &lt;<a href="mailto:cce@ccs.neu.edu">cce@ccs.neu.edu</a>&gt;<br>
&gt;&gt; &gt;&gt; &gt; wrote:<br>
&gt;&gt; &gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; &gt;&gt; My work on adding gen:set, and related changes to define-generics<br>
&gt;&gt; &gt;&gt; &gt;&gt; and<br>
&gt;&gt; &gt;&gt; &gt;&gt; gen:dict, is ready for review and (hopefully) to push to the master<br>
&gt;&gt; &gt;&gt; &gt;&gt; branch.<br>
&gt;&gt; &gt;&gt; &gt;&gt; The branch moved in the process of cleaning things up, it&#39;s now at:<br>
&gt;&gt; &gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; &gt;&gt;   <a href="https://github.com/carl-eastlund/racket/tree/generics-from-scratch" target="_blank">https://github.com/carl-eastlund/racket/tree/generics-from-scratch</a><br>
&gt;&gt; &gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; &gt;&gt; (The &quot;from scratch&quot; just refers to the process of rebuilding the git<br>
&gt;&gt; &gt;&gt; &gt;&gt; history, I didn&#39;t go out of my way to rewrite anything in the code<br>
&gt;&gt; &gt;&gt; &gt;&gt; base<br>
&gt;&gt; &gt;&gt; &gt;&gt; from<br>
&gt;&gt; &gt;&gt; &gt;&gt; scratch, although in some places a lot of code did move around.)<br>
&gt;&gt; &gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; &gt;&gt; What&#39;s new in the branch:<br>
&gt;&gt; &gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; &gt;&gt; - Generics now support a few new options<br>
&gt;&gt; &gt;&gt; &gt;&gt;   - #:fallbacks specifies fallback method implementations for<br>
&gt;&gt; &gt;&gt; &gt;&gt; instances<br>
&gt;&gt; &gt;&gt; &gt;&gt; with no implementation<br>
&gt;&gt; &gt;&gt; &gt;&gt;   - #:fast-defaults specifies instances on a &quot;fast path&quot;, useful for<br>
&gt;&gt; &gt;&gt; &gt;&gt; built-in types<br>
&gt;&gt; &gt;&gt; &gt;&gt;   - #:defined-predicate gives a more intuitive and efficient<br>
&gt;&gt; &gt;&gt; &gt;&gt; interface<br>
&gt;&gt; &gt;&gt; &gt;&gt; than #:defined-table<br>
&gt;&gt; &gt;&gt; &gt;&gt;   - #:derive-property allows generics to piggy-back on existing<br>
&gt;&gt; &gt;&gt; &gt;&gt; struct<br>
&gt;&gt; &gt;&gt; &gt;&gt; properties<br>
&gt;&gt; &gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; &gt;&gt; - Sets are now a generic datatype through gen:set<br>
&gt;&gt; &gt;&gt; &gt;&gt;   - lists are now sets<br>
&gt;&gt; &gt;&gt; &gt;&gt;   - the built-in set types are now documented as &quot;hash sets&quot;<br>
&gt;&gt; &gt;&gt; &gt;&gt;   - there are mutable and weak hash sets<br>
&gt;&gt; &gt;&gt; &gt;&gt;   - you can define new set types quickly with<br>
&gt;&gt; &gt;&gt; &gt;&gt; define-custom-set-types<br>
&gt;&gt; &gt;&gt; &gt;&gt;   - most set operations are now methods with fallbacks<br>
&gt;&gt; &gt;&gt; &gt;&gt;   - sets now support -copy and -clear operations, plus mutating [!]<br>
&gt;&gt; &gt;&gt; &gt;&gt; versions of operations<br>
&gt;&gt; &gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; &gt;&gt; - Dictionaries have a few changes<br>
&gt;&gt; &gt;&gt; &gt;&gt;   - new macro define-custom-hash-types [*]<br>
&gt;&gt; &gt;&gt; &gt;&gt;   - most dict operations are now methods with fallbacks<br>
&gt;&gt; &gt;&gt; &gt;&gt;   - dicts now support -copy, -clear, -clear!, and -empty? operations<br>
&gt;&gt; &gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; &gt;&gt; I&#39;ve run some benchmarks and performance of the various generic<br>
&gt;&gt; &gt;&gt; &gt;&gt; operations<br>
&gt;&gt; &gt;&gt; &gt;&gt; are comparable to the current HEAD, so there should be no major<br>
&gt;&gt; &gt;&gt; &gt;&gt; performance<br>
&gt;&gt; &gt;&gt; &gt;&gt; changes with this patch.<br>
&gt;&gt; &gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; &gt;&gt; [*] I&#39;ve added define-custom-hash-types and define-custom-set-types<br>
&gt;&gt; &gt;&gt; &gt;&gt; rather<br>
&gt;&gt; &gt;&gt; &gt;&gt; than just adding make-custom-set akin to make-custom-hash because<br>
&gt;&gt; &gt;&gt; &gt;&gt; make-custom-hash is hard to use.  The documented behavior -- that<br>
&gt;&gt; &gt;&gt; &gt;&gt; any<br>
&gt;&gt; &gt;&gt; &gt;&gt; custom<br>
&gt;&gt; &gt;&gt; &gt;&gt; hash is equal to any other created with the same bindings and<br>
&gt;&gt; &gt;&gt; &gt;&gt; predicates /<br>
&gt;&gt; &gt;&gt; &gt;&gt; hash functions -- was never true and can be expensive or at least<br>
&gt;&gt; &gt;&gt; &gt;&gt; tricky to<br>
&gt;&gt; &gt;&gt; &gt;&gt; implement.  It seemed more sensible to just remove the erroneous<br>
&gt;&gt; &gt;&gt; &gt;&gt; documentation on make-custom-hash, and add the definition form to<br>
&gt;&gt; &gt;&gt; &gt;&gt; create<br>
&gt;&gt; &gt;&gt; &gt;&gt; constructors for new, explicitly-compatible dict and set types.<br>
&gt;&gt; &gt;&gt; &gt;&gt; Both<br>
&gt;&gt; &gt;&gt; &gt;&gt; definition forms bind predicates and constructors for new (set or<br>
&gt;&gt; &gt;&gt; &gt;&gt; dict)<br>
&gt;&gt; &gt;&gt; &gt;&gt; types with immutable, mutable, and weak variants that inter-operate.<br>
&gt;&gt; &gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; &gt;&gt; If there are no serious issues brought up in the next day or two,<br>
&gt;&gt; &gt;&gt; &gt;&gt; I&#39;ll<br>
&gt;&gt; &gt;&gt; &gt;&gt; push it to the development branch, since our current release process<br>
&gt;&gt; &gt;&gt; &gt;&gt; isn&#39;t<br>
&gt;&gt; &gt;&gt; &gt;&gt; following HEAD.<br>
&gt;&gt; &gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; &gt;&gt; Carl Eastlund<br>
&gt;&gt; &gt;&gt; &gt;<br>
&gt;&gt; &gt;&gt; &gt;<br>
&gt;&gt; &gt;&gt; &gt;<br>
&gt;&gt; &gt;&gt; &gt; _________________________<br>
&gt;&gt; &gt;&gt; &gt;   Racket Developers list:<br>
&gt;&gt; &gt;&gt; &gt;   <a href="http://lists.racket-lang.org/dev" target="_blank">http://lists.racket-lang.org/dev</a><br>
&gt;&gt; &gt;&gt; &gt;<br>
&gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;<br>
&gt;&gt;<br>
&gt;<br>
<br>
</div></div></blockquote></div><br></div>