Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Have J style adverbs, forks etc been emulated via libraries in mainstream functional languages?

Has an emulation of J style of super condensed tacit programming via verbs, adverbs, forks, etc., ever been attempted via libraries for mainstream functional languages?

If so, how successful was the result?

If not, is there a technical issue that makes this impossible, or is it just not worth doing?

I'm particularly interested in constructs like forks that don't appear to correspond directly to basic concepts in functional programming.

like image 232
RD1 Avatar asked Aug 03 '10 17:08

RD1


2 Answers

Doesn't tacit programming correspond pretty closely to combinator logic or pointless point-free style in Haskell? For instance, while I don't know J from what I gather a "fork" translates three functions f, g, and h and an argument x into an expression g (f x) (h x). The operation of "apply multiple functions to a single argument, then apply the results to each other in sequence" is a generalization of Curry's Schönfinkel's S combinator and in Haskell corresponds to the Applicative instance of the Reader monad.

A fork combinator in Haskell such that fork f g h x matches the result specified above would have the type (t -> a) -> (a -> b -> c) -> (t -> b) -> t -> c. Interpreting this as using the Reader functor ((->) t) and rewriting it for an arbitrary functor, the type becomes f a -> (a -> b -> c) -> f b -> f c. Swapping the first two arguments gives us (a -> b -> c) -> f a -> f b -> f c, which is the type of liftA2/liftM2.

So for the common example of computing the average, the fork +/ % # can be translated directly as flip liftA2 sum (/) (fromIntegral . length) or, if one prefers the infix Applicative combinators, as (/) <$> sum <*> fromIntegral . length.

If not, is there a technical issue that makes this impossible, or is it just not worth doing?

In Haskell at least, I think the main issue is that extremely point-free style is considered obfuscated and unreadable, particularly when using the Reader monad to split arguments.

like image 173
C. A. McCann Avatar answered Nov 15 '22 08:11

C. A. McCann


Camccann's discussion is pretty good. But note that this style now results in two traversals.

You can write a combinator library that merges the traversals. See here: http://squing.blogspot.com/2008/11/beautiful-folding.html

The post offers the following example for writing a mean:

meanF :: Fractional a => Fold a a
meanF = bothWith (/) sumF (after lengthF fromIntegral)

mean :: Fractional a => [a] -> a
mean = cfoldl' meanF

Also, Conal Eliott's followup posts generalize this much further: http://conal.net/blog/posts/enhancing-a-zip/

He pulled the code from his posts into a library available on hackage: http://hackage.haskell.org/package/ZipFold

like image 43
sclv Avatar answered Nov 15 '22 09:11

sclv