λ-wiki
::
evaluation
+
| 1 |
help
|
pages
|
skin
|
login
|
code
www!k! v.20120610
! CE SITE NECESSITE JAVASCRIPT !
λ-wiki :: éditeur
_h1 evaluation _p Defining functions (and vars) is made in respect with this general syntax : {pre °° {define name args = body } where : - args is an optional sequence of variable names prefixed with a colon ':' - body is a valid math form {first rest} with ALL curly brackets replaced by round brackets - first is a static or dynamic math function °°} _p Variables are defined with "args" as an empty string. Actually a variable is a function without arguuments, and a function is a variable with arguments, both are stored in the same array : dyna_func[]. _h3 1) defining functions _h6 1.1) defining some primitives _p Usually, we can define a function hypo = √(x{sup 2}+y{sup 2}) with the static functions {y °°{mult ...}°°}, {y °°{add ...}°°} and {y °°{sqrt ...}°°} this way : {y °°{sqrt {add {mult x x} {mult y y}}}°°}. In order to study a more interesting case, we will use dynamically defined primitives {y °°{_add ...}°°}, {y °°{_mult ...}°°} and {y °°{_sqrt ...}°°} on which a _hypo function will be built. _ul °°{define _PI = 3.1416}°° - > {define _PI = 3.1416} _ul °°{define _rac2 = (sqrt 2)}°° - > {define _rac2 = (sqrt 2)} _ul °°{define _add :a :b = (add :a :b)}°° - > {define _add :a :b = (add :a :b)} _ul °°{define _mult :a :b = (mult :a :b)}°° - > {define _mult :a :b = (mult :a :b)} _ul °°{define _rac :a = (sqrt :a)}°° - > {define _rac :a = (sqrt :a)} _h6 1.2) defining 'hypo' _ul °°{define _hypo :x :y = (_rac (_add (_mult :x :x) (_mult :y :y))) }°° - > {define _hypo :x :y = (_rac (_add (_mult :x :x) (_mult :y :y))) } _h3 2) calling functions _h6 2.1) testing primitives _ul °°{_PI}°° - > {_PI} _ul °°{_rac2}°° - > {_rac2} _ul °°{_add 9 16}°° - > {_add 9 16} _ul °°{_mult 3 3}°° - > {_mult 3 3} _ul °°{_rac 25}°° - > {_rac 25} _h6 2.2) calling 'hypo' _ul °°{_hypo 3 4}°° - > {_hypo 3 4} _h3 3) tracing 'hypo' _h6 3.1) define _ul °°{define hypo :x :y = (_rac (_add (_mult :x :x) (_mult :y :y))) }°° _ul loop in core_func and find core_func['define'] - > _ul rest = hypo :x :y = (_rac (_add (_mult :x :x) (_mult :y :y))) _ul split on "=" - > _ul30 nameArgs = hypo :x :y - > split on " " - > _ul50 name = hypo _ul50 args = :x :y - > [:x,:y] _ul30 body = (_rac (_add (_mult :x :x) (_mult :y :y))) _ul create element : func[name] = °°{args:args, body:body}°°; _h6 3.2) apply _ul °°{hypo 3 4}°° - > _ul30 name = hypo _ul30 values = "3 4" _ul loop in dyna_func and find dyna_func['hypo'] - > _ul30 name = hypo - > loop - > func['hypo'] - > _ul50 args = func['hypo'].args = [:x,:y] _ul50 body = func['hypo'].body = (_rac (_add (_mult :x :x) (_mult :y :y))) _ul50 values = 3 4 - > [3,4] _ul replace [3,4] in [:x,:y] - > (_rac (_add (_mult 3 3) (_mult 4 4))) _ul activate : replace "(,)" by °°{,}°° - > °°{_rac {_add {_mult 3 3} {_mult 4 4}}}°° _ul return to the loop °°{_rac {_add {_mult 3 3} {_mult 4 4}}}°° _ul then, the loop first matches °°{_mult 3 3} and {_mult 4 4}°° _ul30 and treats them like hypo - > ... - > return 9 and 16 in the loop _ul then matches °°{_rac {_add 9 16}}°° _ul30 and treats it like hypo - > ... - > return °°{_rac 25}°° _ul then matches °°{_rac 25}°° _ul30 and treats it like hypo - > ... - > return 5 _ul the result is 5. _h3 4) special functions _p So it is possible to build nested functions which will be correctly matched in the good order by the parser's loop which matches first the innermost expressions {y °°{first rest}°°} and last the outermost ones. _p It must be noticed that the {y define} function doesn't follow this rule ; in {y °°{define name args = body }°°}, name, args, "=", and body are arguments undefined when the expression is evaluated, the job of the {y define} function is to build the function {y name(args) = body}. The {y define} function is actually a special function. _p The {y if} function is another important one, whose syntax is {y °°{if boolean then then_term else else_term }°°}. Examples : _ul °°{if true then YES else NO}°° - > {if true then YES else NO} _ul °°{define B = 2}°° - > {define B = 2} = 2 _ul30 °°{if {equal {B} 1} then {mult 2 2} else {sqrt 2}}°° - > {if {equal {B} 1} then {mult 2 2} else {sqrt 2}} _ul30 °°{if {equal {B} 2} then {mult 2 2} else {sqrt 2}}°° - > {if {equal {B} 2} then {mult 2 2} else {sqrt 2}} _p In the previous calls, the "then_term" and the "else_term" are both evaluated and that is useless. The next expressions prevent the evaluation of the useless term : _ul30 °°{if {equal {B} 1} then (mult 2 2) else (sqrt 2)}°° - > {if {equal {B} 1} then (mult 2 2) else (sqrt 2)} _ul30 °°{if {equal {B} 2} then (mult 2 2) else (sqrt 2)}°° - > {if {equal {B} 2} then (mult 2 2) else (sqrt 2)} _p The {y if} expressions can be embedded in a function definition : {ul °°{define foo :n = (if (equal :n 0) then (mult 2 2) else (sqrt 2)) }°° - > {define foo :n = (if (equal :n 0) then (mult 2 2) else (sqrt 2)) } } _ul °°{foo 0}°° - > {foo 0} _ul °°{foo 1}°° - > {foo 1} _h6 Could it be used to evaluate a factorial ? {ul °°{define factorial :n = (if (equal :n 0) then 1 else (mult :n (factorial (add :n -1))))°° - > {define factorial :n = (if (equal :n 0) then 1 else (mult :n (factorial (add :n -1)))) } } _ul °°{factorial 6}°° - > {pre °° {if false then 1 else {mult 6 {if false then 1 else {mult 5 {if false then 1 else {mult 4 {if false then 1 else {mult 3 {if false then 1 else {mult 2 {if false then 1 else {mult 1 {if true then 1 else {mult 0 {factorial -1}} }} }} }} }} }} }} } °°} _p {b The problem is that this function throws an infinite loop !} The parser prevents infinite loops, grace to a loop's counter limited to an arbitrary finite value (about 15) and the previous sequence of words is returned, in which it can be seen an invalid expression : "{b °°{mult 0 {factorial -1}}°°}". Manually replacing in this expression the curly brackets by round brackets {b °°(mult 0 (factorial -1))°°} has the effect to desactivate it, to stop the loop and on exit ... to get the expected result. So, the following expression : {pre °° {if false then 1 else {mult 6 {if false then 1 else {mult 5 {if false then 1 else {mult 4 {if false then 1 else {mult 3 {if false then 1 else {mult 2 {if false then 1 else {mult 1 {if true then 1 else (mult 0 {factorial -1}} }} }} }} }} }} }} } °°} {p gives the good answer for °°{factorial 6}°° : {if false then 1 else {mult 6 {if false then 1 else {mult 5 {if false then 1 else {mult 4 {if false then 1 else {mult 3 {if false then 1 else {mult 2 {if false then 1 else {mult 1 {if true then 1 else (mult 0 (factorial -1)) }}}}}}}}}}}}} ! How can this specific desactivation be done automatically ? No known solution to this issue until now, if the answer exists !} _h6 conclusion _p An other question rises now : even if a solution could be found to this issue, such a deeply nested expressions should quickly become monstruously heavy for big values of N, and should inefficiently consume too much memory space and processor time. It seems to be time to look for iterative alternative to recursive factorial and to forget recursive processe in this syntax for a while ! {pre _h6 functions list in this page : {lib dyn} }