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