<html><head></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div><br></div><div>This whole discussion reminds me of the idea of specialization interface specification. The notion is due to Lamping, I think. Stevie and I read the paper and his class contracts provide some of the power of SIs but not all. In particular, they fail to provide the power that seems to be necessary here:&nbsp;</div><div><br></div><div>&nbsp;specifying the cycles among methods that is required to be overridden wholesale&nbsp;</div><div>&nbsp;&amp;&amp;</div><div>&nbsp;specifying the 'what I get for free' methods&nbsp;</div><div><br></div><div>As far as I know, there is no PL that actually supports such specs and everyone relies on plain old English docs to get this across. Then everyone gets it wrong the first time and plays until it works.&nbsp;</div><div><br></div><div>It's quite likely to be a DLS-level research paper, possibly OOPSLA if we integrate it with a type system eventually. -- Matthias</div><div><br></div><div><br></div><div><br></div><div><br></div><br><div><div>On Aug 1, 2013, at 7:30 PM, Carl Eastlund wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><div dir="ltr">No, that doesn't work.&nbsp; If someone implements, say, an efficient subset? test, then set=? should use that rather than iterating using set-&gt;stream and set-member?.&nbsp; You should use the highest-level methods you can, in order to get the most out of an implementation.&nbsp; 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'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 "primitve" / "derived" distinction,<br>
&gt; since it's somewhat artificial, and leave it up to the individual method<br>
&gt; descriptions? &nbsp;Is there some better way I should be describing things?<br>
<br>
</div>Ok I can see now that there's no easy way to organize the methods.<br>
<br>
I think we should keep some distinction, since as a programmer it's<br>
good to know exactly what methods I have to implement. However, to me<br>
"fallback" 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'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; "primitive" 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'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'm looking for additional insight.<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt; &gt; Do you have examples of which ones don't come "for free" 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 "primitive" 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 "primitive" methods and "derived"<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'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's an<br>
&gt;&gt; &gt;&gt; implicit separation along the lines of iterability, ie, derived sets<br>
&gt;&gt; &gt;&gt; are "iterable" since many of the derived methods require set-&gt;stream,<br>
&gt;&gt; &gt;&gt; but that'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'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's now at:<br>
&gt;&gt; &gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; &gt;&gt; &nbsp; <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 "from scratch" just refers to the process of rebuilding the git<br>
&gt;&gt; &gt;&gt; &gt;&gt; history, I didn'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'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; &nbsp; - #: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; &nbsp; - #:fast-defaults specifies instances on a "fast path", useful for<br>
&gt;&gt; &gt;&gt; &gt;&gt; built-in types<br>
&gt;&gt; &gt;&gt; &gt;&gt; &nbsp; - #: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; &nbsp; - #: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; &nbsp; - lists are now sets<br>
&gt;&gt; &gt;&gt; &gt;&gt; &nbsp; - the built-in set types are now documented as "hash sets"<br>
&gt;&gt; &gt;&gt; &gt;&gt; &nbsp; - there are mutable and weak hash sets<br>
&gt;&gt; &gt;&gt; &gt;&gt; &nbsp; - 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; &nbsp; - most set operations are now methods with fallbacks<br>
&gt;&gt; &gt;&gt; &gt;&gt; &nbsp; - 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; &nbsp; - new macro define-custom-hash-types [*]<br>
&gt;&gt; &gt;&gt; &gt;&gt; &nbsp; - most dict operations are now methods with fallbacks<br>
&gt;&gt; &gt;&gt; &gt;&gt; &nbsp; - dicts now support -copy, -clear, -clear!, and -empty? operations<br>
&gt;&gt; &gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; &gt;&gt; I'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'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. &nbsp;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. &nbsp;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'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'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; &nbsp; Racket Developers list:<br>
&gt;&gt; &gt;&gt; &gt; &nbsp; <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>
_________________________<br> &nbsp;Racket Developers list:<br> &nbsp;<a href="http://lists.racket-lang.org/dev">http://lists.racket-lang.org/dev</a><br></blockquote></div><br></body></html>