Re: [stack] disallowing recursive definitions
Stevan Apter <[email protected]>
| Newsgroups | gmane.comp.lang.concatenative |
|---|---|
| Message-ID | <[email protected]> |
> i'm still puzzled why authors of concatenative languages like cat and factor
> have resisted the incorporation of array primitives into their languages. in
> the admittedly trivial examples below, why not write
>
> 1+til / applied to n generates 0..n-1, then add 1
>
> or
>
> 1 drop til 1+ / add 1 to n, generate 0..n, then drop the first
>
> instead of either looping or recursion?
>
or in postfix notation:
til 1 +
1 + til 1 drop
----- Original Message -----
From: "Stevan Apter" <[email protected]>
To: <[email protected]>
Sent: Saturday, March 01, 2008 8:51 AM
Subject: Re: [stack] disallowing recursive definitions
> my interest in joy was triggered by examples contained in manfred's original
> papers. those examples suggested that a way of simplifying the expression of
> algorithms which had been overlooked by the mainstream programming languages.
> as a long-time APLer, i was already convinced that one source of complexity
> was explicit looping, but it wasn't until i found myself drowning in a welter
> of explicit recursions on one particular project that i began to suspect that
> it might be possible to do for recursion what APL had done for looping. joy's
> small set of recursive combinators suggested how this might be done.
>
> i'm still puzzled why authors of concatenative languages like cat and factor
> have resisted the incorporation of array primitives into their languages. in
> the admittedly trivial examples below, why not write
>
> 1+til / applied to n generates 0..n-1, then add 1
>
> or
>
> 1 drop til 1+ / add 1 to n, generate 0..n, then drop the first
>
> instead of either looping or recursion?
>
> my sense is that programmers (and language designers) *still* do not appreciate
> the power of array programming. here's an example i posted the other day on
> comp.lang.functional, a general sudoku solver written in q by arthur whitney.
> for readability, i've replaced the case statement of q ($[x;y;z]) with if-then-
> else pseudocode.
>
> f:{if all x then enlist x else raze f each amend[x;i]each where 27=x[raze p i:x find 0]find til 10]}
>
> note the explicit tail-recursion on 'f' in the else clause. also note that this is
> the standard algorithm used in sudoku solvers written in java, python, ruby, ocaml,
> &c. compression is achieved through the use of a handlful of array primitives
> (til, find, raze, where, all), one iterator (each), a primitive for updating
> positions of an array (amend), and a single primitive extended from scalars to
> arrays (=).
>
>
> ----- Original Message -----
> From: "John Nowak" <[email protected]>
> To: <[email protected]>
> Sent: Thursday, February 28, 2008 9:43 PM
> Subject: Re: [stack] disallowing recursive definitions
>
>
>>
>> On Feb 28, 2008, at 6:47 PM, Joe Bowbeer wrote:
>>
>>> As a former Schemer and fan of continuations, I'm conditioned to
>>> view (tail)
>>> recursion as the simpler, more powerful concept. Not looping.
>>
>> I have a Scheme background as well.
>>
>>> Functional programming languages rely on recursion and still boast of
>>> referential transparency: the ability to substitute function
>>> applications by
>>> their definitions. But they don't take the substitution as far as
>>> you'd
>>> like to...
>>
>> Indeed.
>>
>>> Functional languages favor recursion over looping because looping
>>> traditionally requires a loop variable whose value changes: a side
>>> effect.
>>
>> What's surprising is how easily the stack lets you write code in an
>> imperative style while remaining purely functional. Here's a small
>> example where, given a natural number, we construct a list from 1 to
>> that number:
>>
>> ; Scheme, via recursion
>>
>> (define (foo n)
>> (let f ((n n) (xs '()))
>> (if (zero? n)
>> xs
>> (f (- n 1) (cons n xs)))))
>>
>> ; Joy-like, via recursive combinator
>>
>> foo = null swap ((cons) keep pred) (zero?) until pop
>>
>> ; Another Joy-like version
>> ; (prec :: A int int (A int -> A) -> A)
>>
>> foo = null swap 1 (cons) prec
>>
>> - John
>>
>