[racket-dev] Five feature/limitation interactions conspire to drive mad

From: Ray Racine (ray.racine at gmail.com)
Date: Tue Jan 1 20:56:11 EST 2013

All good points on TR development flows.

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.

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.

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.

e.g quick sample from some proto code.
https://github.com/RayRacine/racketlib/blob/master/io/iteratee/iteratee.rkt
https://github.com/RayRacine/racketlib/blob/master/mapred/types.rkt
https://github.com/RayRacine/racketlib/blob/master/mapred/shuffle/merge-sort.rkt

BTW, I'm throwing down an inferencing gauntlet.  Here is a convenient
example of where TR's inferencing falls a bit short.
In merge-sort.rkt above.

(: merge-sort-inmem-blocks-to-disc (All (D) (Listof (Listof D))
(Sorter D) (Writer D) -> (Listof (Block D))))
(define (merge-sort-inmem-blocks-to-disc lst-data sorter writer)
  (let: ((enum : (Enumerator D (Listof (Block D)))
(enumerator/select-from-n-lists lst-data sorter))
         (iter : (Iteratee D (Listof (Block D)))   (iter-block
(generate-rdd-block-filename) writer)))
    (icomplete (enum iter))))

Here the let: bindings are necessary hints for TR inferencing to succeed.
I'd prefer.

(: merge-sort-inmem-blocks-to-disc (All (D) (Listof (Listof D)) (Sorter D) (
Writer D) -> (Listof (Block D))))
(define (merge-sort-inmem-blocks-to-disc lst-data sorter writer)
    (icomplete ((enumerator/select-from-n-lists lst-data sorter) (iter-bloc
(generate-rdd-block-filename) writer)))


Random musing follows.

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.

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.

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.

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.

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.

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.


On Tue, Jan 1, 2013 at 7:42 PM, Neil Toronto <neil.toronto at gmail.com> wrote:

> On 01/01/2013 03:35 PM, Matthias Felleisen wrote:
>
>>
>> Neil,
>>
>> thanks for the user story. We should hear more of those for all kinds of
>> corners in our world.
>>
>
> You're welcome!
>
>  Question: did you start the math library in an untyped form (and switch)
>> or did you go with types from the get-go?
>>
>
> 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.
>
> 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.
>
> I discovered reasons #3 and #4 while I was writing `math/array':
>
> 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.
>
> 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.
>
> 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.
>
> Neil ⊥
>
> _________________________
>  Racket Developers list:
>  http://lists.racket-lang.org/dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/dev/archive/attachments/20130101/6bc0bed2/attachment-0001.html>

Posted on the dev mailing list.