<div dir="ltr"><div><div><div>All good points on TR development flows.<br><br>If I could elaborate from my perspective on Neils&#39; #3.  I think this is the #1 benefit of TR over R.  Yes, static type checking, real-time while you type is superb road kill on the highway of code development   And I do enjoy it so.  <br>
<br></div>BUT what TR really, really grants is the ability to just get META with HOF and not go insane, all evidence to the contrary, while doing so.<br><br>For me, cursed with wrong end of the bell curve working set intelligence, the following example of HOF without TR&#39;s training wheels would result in a multi-week rest visit to Arkham for me if undertaken in plain ol&#39; R.<br>
<br>e.g quick sample from some proto code.<br><a href="https://github.com/RayRacine/racketlib/blob/master/io/iteratee/iteratee.rkt">https://github.com/RayRacine/racketlib/blob/master/io/iteratee/iteratee.rkt</a><br><a href="https://github.com/RayRacine/racketlib/blob/master/mapred/types.rkt">https://github.com/RayRacine/racketlib/blob/master/mapred/types.rkt</a><br>
<a href="https://github.com/RayRacine/racketlib/blob/master/mapred/shuffle/merge-sort.rkt">https://github.com/RayRacine/racketlib/blob/master/mapred/shuffle/merge-sort.rkt</a><br><br></div>BTW, I&#39;m throwing down an inferencing gauntlet.  Here is a convenient example of where TR&#39;s inferencing falls a bit short.<br>
</div>In merge-sort.rkt above.<br><pre><div class="" id="LC41"><span class="">(</span><span class="">:</span> <span class="">merge-sort-inmem-blocks-to-disc</span> <span class="">(</span><span class="">All</span> <span class="">(</span><span class="">D</span><span class="">)</span> <span class="">(</span><span class="">Listof</span> <span class="">(</span><span class="">Listof</span> <span class="">D</span><span class="">))</span> <span class="">(</span><span class="">Sorter</span> <span class="">D</span><span class="">)</span> <span class="">(</span><span class="">Writer</span> <span class="">D</span><span class="">)</span> <span class="">-&gt;</span> <span class="">(</span><span class="">Listof</span> <span class="">(</span><span class="">Block</span> <span class="">D</span><span class="">))))</span></div>
<div class="" id="LC42"><span class="">(</span><span class="">define </span><span class="">(</span><span class="">merge-sort-inmem-blocks-to-disc</span> <span class="">lst-data</span> <span class="">sorter</span> <span class="">writer</span><span class="">)</span></div>
<div class="" id="LC43">  <span class="">(</span><span class="">let:</span> <span class="">((</span><span class="">enum</span> <span class="">:</span> <span class="">(</span><span class="">Enumerator</span> <span class="">D</span> <span class="">(</span><span class="">Listof</span> <span class="">(</span><span class="">Block</span> <span class="">D</span><span class="">)))</span> <span class="">(</span><span class="">enumerator/select-from-n-lists</span> <span class="">lst-data</span> <span class="">sorter</span><span class="">))</span></div>
<div class="" id="LC44">         <span class="">(</span><span class="">iter</span> <span class="">:</span> <span class="">(</span><span class="">Iteratee</span> <span class="">D</span> <span class="">(</span><span class="">Listof</span> <span class="">(</span><span class="">Block</span> <span class="">D</span><span class="">)))</span>   <span class="">(</span><span class="">iter-block</span> <span class="">(</span><span class="">generate-rdd-block-filename</span><span class="">)</span> <span class="">writer</span><span class="">)))</span></div>
<div class="" id="LC45">    <span class="">(</span><span class="">icomplete</span> <span class="">(</span><span class="">enum</span> <span class="">iter</span><span class="">))))<br></span><br></div></pre>Here the let: bindings are necessary hints for TR inferencing to succeed.  I&#39;d prefer.<br>
<div><br><div class="" id="LC41"><span class="">(</span><span class="">:</span> <span class="">merge-sort-inmem-blocks-to-disc</span> <span class="">(</span><span class="">All</span> <span class="">(</span><span class="">D</span><span class="">)</span> <span class="">(</span><span class="">Listof</span> <span class="">(</span><span class="">Listof</span> <span class="">D</span><span class="">))</span> <span class="">(</span><span class="">Sorter</span> <span class="">D</span><span class="">)</span> <span class="">(</span><span class="">Writer</span> <span class="">D</span><span class="">)</span> <span class="">-&gt;</span> <span class="">(</span><span class="">Listof</span> <span class="">(</span><span class="">Block</span> <span class="">D</span><span class="">))))</span></div>
<div class="" id="LC42"><span class="">(</span><span class="">define </span><span class="">(</span><span class="">merge-sort-inmem-blocks-to-disc</span> <span class="">lst-data</span> <span class="">sorter</span> <span class="">writer</span><span class="">)</span></div>
    <span class="">(</span><span class="">icomplete</span> <span class="">((</span><span class="">enumerator/select-from-n-lists lst-data sorter)</span><span class=""></span><span class=""></span> (iter-bloc (generate-rdd-block-filename) writer)))<br>
<br><br></div><div>Random musing follows.<br></div><div class="gmail_extra"><br></div><div class="gmail_extra">If I could lay on more subject anecdote.  Consider Scala, probably envisioned by Martin O. as a &quot;properly&quot; done core OO language with relatively seamless functional layering, i.e., lambda smoothly filled in around the edges.   An unintended consequence, I think, was how hell bent a serious subset of Scala users were to &quot;use&quot; Scala as a Functional Language at the core with OO smoothly filled in around the edges.  Scalaz, Scala Type Classes et al.  A substantial core of Scala user effort in and around essentially coding Haskell in Scala.<br>
<br></div><div class="gmail_extra">Abusing the analogy towards TR and R.  I think a potential unintended consequence is that TR will encourage continued user pressure on TR development for further ability to code &quot;Haskell&quot; in TR  e.g. Co/contra type variance (for collections), type bounds, generics (data types), , TRing of generics methods (gen:*) setting a basis for TR&#39;s version of Type Classes, etc.<br>
<br></div><div class="gmail_extra">Extrapolating to a hypothetical future, TR will ultimately result in a distinct separation in from R.  Technically, the development of a library in TR will always allow for some sort of mechanical means of isomorphic translation to R.   Practically, future libraries in TR will get more and more HOF (Haskell-idiomatic if you will) like and mapping down to R, which will technically work/run, however code/library interfaces will retain their HOF characteristics to such an extant that use in R coding will be a struggle.  Though leverage lifting R into TR, analogous how Scala supports leveraging the vast amount of Java code will be common.<br>
<br></div><div class="gmail_extra">In other words, three years from now, the same developer fluent in R and TR idioms, developing the same library, would fundamentally write two different libraries, technically isomorphic (translatable), but practically for-use distinct.<br>
<br></div><div class="gmail_extra">Bottom line wild hair prediction.  Beyond Racket core collections which by skill and effort by core maintainers to be bi-use (R and TR), future 3rd party libraries / collections will be TR xor R in nature.  <br>
<br></div><div class="gmail_extra">While I grant it is a huge overreach to offer analogy of religious wars into programming language musings, TR and R may very well turn out to be Catholic and Protestants (Emacs and Vi) all over again.  You are one or the other and rarely both.<br>
</div><div class="gmail_extra"><br><br><div class="gmail_quote">On Tue, Jan 1, 2013 at 7:42 PM, Neil Toronto <span dir="ltr">&lt;<a target="_blank">neil.toronto@gmail.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
On 01/01/2013 03:35 PM, Matthias Felleisen wrote:<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
Neil,<br>
<br>
thanks for the user story. We should hear more of those for all kinds of corners in our world.<br>
</blockquote>
<br>
You&#39;re welcome!<br>
<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
Question: did you start the math library in an untyped form (and switch) or did you go with types from the get-go?<br>
</blockquote>
<br>
It&#39;s all been in Typed Racket from the beginning. This was initially because I mostly had floating-point functions planned, and I wanted TR&#39;s help proving that I never used non-flonums by mistake. Also, I wanted the special functions to have performance competitive with C implementations.<br>

<br>
When I decided to do arrays, Typed Racket was again the natural choice. First, because it&#39;s not possible to use `require/typed&#39; to import polymorphic struct types. Second, because it allowed me to avoid a lot of runtime checks.<br>

<br>
I discovered reasons #3 and #4 while I was writing `math/array&#39;:<br>
<br>
3. Passing around higher-order functions can get confusing. I can&#39;t speak for anyone else, but when I get something like `array-axis-reduce&#39; - which is like a fold but with complicated types - to pass the type checker, my code is usually correct.<br>

<br>
4. TR&#39;s types for Racket&#39;s numeric tower, especially the additional `Index&#39; type, makes it easy to safely use unsafe indexing. Throughout `math/array&#39;, values of type `Index&#39; are always either a size (e.g. a vector length) or an index that has been proved to be less than a size. IOW, if I can get TR to prove j : Index, I&#39;m satisfied that (unsafe-vector-ref xs j) is actually safe. Also, if `j&#39; is a loop counter, TR can usually compare and increment using unsafe fixnum ops.<br>

<br>
There are a bunch of other little things that are like #4 (which is only a big thing because indexes are so prevalent in `math/array&#39;). Maybe I&#39;ll collect those into a separate user story.<br>
<br>
Neil ⊥<br>
<br>
_________________________<br>
 Racket Developers list:<br>
 <a target="_blank">http://lists.racket-lang.org/dev</a><br>
</blockquote></div><br></div></div>