2016 Update
This commit is contained in:
parent
948b86eafa
commit
dcf5d15da3
7965 changed files with 139854 additions and 31002 deletions
|
|
@ -1,15 +1,18 @@
|
|||
While implementing a recursive function, it often happens that we must resort to a separate "helper function" to handle the actual recursion.
|
||||
While implementing a recursive function, it often happens that we must resort to a separate ''helper function'' to handle the actual recursion.
|
||||
|
||||
This is usually the case when directly calling the current function would waste too many resources (stack space, execution time), cause unwanted side-effects, and/or the function doesn't have the right arguments and/or return values.
|
||||
This is usually the case when directly calling the current function would waste too many resources (stack space, execution time), causing unwanted side-effects, and/or the function doesn't have the right arguments and/or return values.
|
||||
|
||||
So we end up inventing some silly name like "foo2" or "foo_helper". I have always found it painful to come up with a proper name, and see a quite some disadvantages:
|
||||
So we end up inventing some silly name like '''foo2''' or '''foo_helper'''. I have always found it painful to come up with a proper name, and see some disadvantages:
|
||||
|
||||
* You have to think up a name, which then pollutes the namespace
|
||||
* A function is created which is called from nowhere else
|
||||
* The program flow in the source code is interrupted
|
||||
::* You have to think up a name, which then pollutes the namespace
|
||||
::* Function is created which is called from nowhere else
|
||||
::* The program flow in the source code is interrupted
|
||||
|
||||
Some languages allow you to embed recursion directly in-place. This might work via a label, a local ''gosub'' instruction, or some special keyword.
|
||||
Some languages allow you to embed recursion directly in-place. This might work via a label, a local ''gosub'' instruction, or some special keyword.
|
||||
|
||||
Anonymous recursion can also be accomplished using the [[Y combinator]].
|
||||
Anonymous recursion can also be accomplished using the [[Y combinator]].
|
||||
|
||||
If possible, demonstrate this by writing the recursive version of the fibonacci function (see [[Fibonacci sequence]]) which checks for a negative argument before doing the actual recursion.
|
||||
|
||||
;Task:
|
||||
If possible, demonstrate this by writing the recursive version of the fibonacci function (see [[Fibonacci sequence]]) which checks for a negative argument before doing the actual recursion.
|
||||
<br><br>
|
||||
|
|
|
|||
15
Task/Anonymous-recursion/ALGOL-68/anonymous-recursion.alg
Normal file
15
Task/Anonymous-recursion/ALGOL-68/anonymous-recursion.alg
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
PROC fibonacci = ( INT x )INT:
|
||||
IF x < 0
|
||||
THEN
|
||||
print( ( "negative parameter to fibonacci", newline ) );
|
||||
stop
|
||||
ELSE
|
||||
PROC actual fibonacci = ( INT n )INT:
|
||||
IF n < 2
|
||||
THEN
|
||||
n
|
||||
ELSE
|
||||
actual fibonacci( n - 1 ) + actual fibonacci( n - 2 )
|
||||
FI;
|
||||
actual fibonacci( x )
|
||||
FI;
|
||||
|
|
@ -1,13 +1,20 @@
|
|||
#define system.
|
||||
#define extensions.
|
||||
#import system.
|
||||
#import extensions.
|
||||
|
||||
#symbol fibo = (:n)
|
||||
[
|
||||
(n < 0)
|
||||
? [ #throw InvalidArgumentException new &message:"Must be non negative". ].
|
||||
#class(extension)mathOp
|
||||
{
|
||||
#method fib
|
||||
[
|
||||
(self < 0)
|
||||
? [ #throw InvalidArgumentException new &message:"Must be non negative". ].
|
||||
|
||||
^ { eval:n [ ^ (n > 1) ? [ ($self:(n - 2)) + ($self:(n - 1)) ] ! [ n ]. ] }:n.
|
||||
].
|
||||
^ control eval:self &for:
|
||||
(:n)
|
||||
[
|
||||
(n > 1) ? [ this eval:(n - 2) + this eval:(n - 1) ] ! [ n ]
|
||||
].
|
||||
]
|
||||
}
|
||||
|
||||
#symbol program =
|
||||
[
|
||||
|
|
@ -15,7 +22,7 @@
|
|||
[
|
||||
console writeLiteral:"fib(":i:")=".
|
||||
|
||||
console writeLine:(fibo:i) | if &InvalidArgumentError: e
|
||||
console writeLine:(i fib) | if &InvalidArgumentError: e
|
||||
[
|
||||
console writeLine:"invalid".
|
||||
].
|
||||
|
|
|
|||
7
Task/Anonymous-recursion/Io/anonymous-recursion.io
Normal file
7
Task/Anonymous-recursion/Io/anonymous-recursion.io
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
fib := method(x,
|
||||
if(x < 0, Exception raise("Negative argument not allowed!"))
|
||||
fib2 := method(n,
|
||||
if(n < 2, n, fib2(n-1) + fib2(n-2))
|
||||
)
|
||||
fib2(x floor)
|
||||
)
|
||||
13
Task/Anonymous-recursion/REXX/anonymous-recursion-1.rexx
Normal file
13
Task/Anonymous-recursion/REXX/anonymous-recursion-1.rexx
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
/*REXX program to show anonymous recursion (of a function or subroutine). */
|
||||
numeric digits 1e6 /*in case the user goes ka-razy. */
|
||||
parse arg x . /*obtain the optional argument from CL.*/
|
||||
if x=='' | x=="," then x=12 /*Not specified? Then use the default.*/
|
||||
w=length(x) /*W: used for formatting the output. */
|
||||
do j=0 to x; jj=right(j, w) /*use the argument as an upper limit.*/
|
||||
say 'fibonacci('jj") =" fib(j) /*show the Fibonacci sequence: 0 ──► x */
|
||||
end /*j*/
|
||||
exit /*stick a fork in it, we're all done. */
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
fib: procedure; parse arg z; if z>=0 then return .(z)
|
||||
say "***error*** argument can't be negative."; exit
|
||||
.: procedure; parse arg #; if #<2 then return #; return .(#-1) + .(#-2)
|
||||
14
Task/Anonymous-recursion/REXX/anonymous-recursion-2.rexx
Normal file
14
Task/Anonymous-recursion/REXX/anonymous-recursion-2.rexx
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
/*REXX program to show anonymous recursion of a function or subroutine with memoization.*/
|
||||
numeric digits 1e6 /*in case the user goes ka-razy. */
|
||||
parse arg x . /*obtain the optional argument from CL.*/
|
||||
if x=='' | x=="," then x=12 /*Not specified? Then use the default.*/
|
||||
@.=.; @.0=0; @.1=1 /*used to implement memoization for FIB*/
|
||||
w=length(x) /*W: used for formatting the output. */
|
||||
do j=0 to x; jj=right(j, w) /*use the argument as an upper limit.*/
|
||||
say 'fibonacci('jj") =" fib(j) /*show the Fibonacci sequence: 0 ──► x */
|
||||
end /*j*/
|
||||
exit /*stick a fork in it, we're all done. */
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
fib: procedure expose @.; arg z; if z>=0 then return .(z)
|
||||
say "***error*** argument can't be negative."; exit
|
||||
.: procedure expose @.; arg #; if @.#\==. then return @.#; @.#=.(#-1)+.(#-2); return @.#
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
/*REXX program to show anonymous recursion (of a function/subroutine). */
|
||||
numeric digits 1e6 /*in case the user goes kaa-razy.*/
|
||||
|
||||
do j=0 to word(arg(1) 12, 1) /*use argument or the default: 12*/
|
||||
say 'fibonacci('j") =" fib(j) /*show Fibonacci sequence: 0──►x */
|
||||
end /*j*/
|
||||
exit /*stick a fork in it, we're done.*/
|
||||
/*──────────────────────────────────subroutines─────────────────────────*/
|
||||
fib: procedure; if arg(1)>=0 then return .(arg(1))
|
||||
say "***error!*** argument can't be negative."; exit
|
||||
.:procedure; arg _; if _<2 then return _; return .(_-1)+.(_-2)
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
10 INPUT "Enter a number: ";n
|
||||
20 LET t=0
|
||||
30 GO SUB 60
|
||||
40 PRINT t
|
||||
50 STOP
|
||||
60 LET nold1=1: LET nold2=0
|
||||
70 IF n<0 THEN PRINT "Positive argument required!": RETURN
|
||||
80 IF n=0 THEN LET t=nold2: RETURN
|
||||
90 IF n=1 THEN LET t=nold1: RETURN
|
||||
100 LET t=nold2+nold1
|
||||
110 IF n>2 THEN LET n=n-1: LET nold2=nold1: LET nold1=t: GO SUB 100
|
||||
120 RETURN
|
||||
Loading…
Add table
Add a link
Reference in a new issue