2016 Update

This commit is contained in:
Tina Müller 2016-12-05 22:15:40 +01:00
parent 948b86eafa
commit dcf5d15da3
7965 changed files with 139854 additions and 31002 deletions

View file

@ -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>

View 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;

View file

@ -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".
].

View 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)
)

View 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)

View 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 @.#

View file

@ -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)

View file

@ -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