<div dir="ltr"><div><div><div>All good points on TR development flows.<br><br>If I could elaborate from my perspective on Neils' #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's training wheels would result in a multi-week rest visit to Arkham for me if undertaken in plain ol' 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'm throwing down an inferencing gauntlet. Here is a convenient example of where TR'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="">-></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'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="">-></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 "properly" 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 "use" 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 "Haskell" 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'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"><<a target="_blank">neil.toronto@gmail.com</a>></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'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's all been in Typed Racket from the beginning. This was initially because I mostly had floating-point functions planned, and I wanted TR'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's not possible to use `require/typed' 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':<br>
<br>
3. Passing around higher-order functions can get confusing. I can't speak for anyone else, but when I get something like `array-axis-reduce' - which is like a fold but with complicated types - to pass the type checker, my code is usually correct.<br>
<br>
4. TR's types for Racket's numeric tower, especially the additional `Index' type, makes it easy to safely use unsafe indexing. Throughout `math/array', values of type `Index' 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'm satisfied that (unsafe-vector-ref xs j) is actually safe. Also, if `j' 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'). Maybe I'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>