Re: [stack] An Overlooked Paradigm in Functional Programming

John Nowak <[email protected]> Sat, 30 Jan 2010 18:13:10 -0500
Newsgroups gmane.comp.lang.concatenative
Message-ID <[email protected]>
On Jan 30, 2010, at 4:18 PM, chris glur wrote:

> The following extract from joy-docos is informative and fun:======
> Consider   the  following  recursive  definition  and  use  of  the
>   factorial function in a (fantasy) functional language:
>    LET  factorial(n)  =  if n = 0 then 1 else n * factorial(n - 1)
> ----------------> So this 1-lines natural-code is obfiscated to  
> joy's ...
>   This is the program:
> 1           5
> 2           [  [pop  0  =]
> 3              [pop  pop  1]
> 4              [  [dup  1  -]  dip
> 5                 dip  i
> 6                 *  ]
> 7              ifte  ]
> 8           dup  i
>
> The absurdity of MANUALLY translating the 1-line pseudocode
> to joy, when a simple/immediate algol-like compilation is
> available tells much?

That's not even a remotely fair translation as it's not recursive like  
the example. The straight-forward recursive function is as such:

    fact = [zero?] [pop 1] [dup 1 - fact *] ifte

Or, alternatively, I'd rather write:

    fact = [zero?] [pop 1] [[] [1 -] bi fact *] ifte

There's only one "shuffle" word in the entire thing; 'pop'. 'bi' makes  
it explicit that you're deriving two values from one value given the  
identity function and the predecessor function. The rest are the same  
things you'd see in the mathematical definition.

What concatenative languages do you let you do well is write an  
efficient iterative version without meaningless names for accumulator  
variables:

    fact = dup [1 - dup 1 >] [[*] keep] while pop

But, more likely, you're just using the proper combinator anyway:

    fact = [1] [*] primrec

Or, in a more Haskell-like style:

    fact = 1 enum-to-from 1 [*] fold

Or:

    fact = 1 enum-to-from product

-jn