lambdaway
::
unclosure
6
|
list
|
login
|
load
|
|
{uncover http://lambdaway.free.fr/workshop/data/mies_pav.jpg 100 400 Less is more.} _h1 [[closure]] | unclosure | [[workaround|?view=meta9]] _p Is there a life out of closure? _h2 1) Lisp/Scheme _p In [[Lisp/Scheme|?view=lambdacode]] lambdas are {i closures}, they have acces to their local context. For instance: {pre (def closure (lambda (a) (lambda (b) (* a b)))) -> closure (closure 3) -> the pointer to a function where a is bound to 3 ((closure 3) 4) -> 12 } _p In this example the inner lambda has acces to the variable {b a} carried by the outer lambda. _h2 2) lambdatalk _p In [[lambdatalk|?view=coding]] lambdas are not {i closures}, just a kind of combinators with access to the global dictionary. If we were following a similar code in lambdatalk {pre '{def closure {lambda {:a} {lambda {:b} {* :a :b}}}} -> {def closure {lambda {:a} {lambda {:b} {* :a :b}}}} '{closure 3} -> {closure 3} '{{closure 3} 4} -> {{closure 3} 4} } _p things don't work anymore. In lambdatalk lambdas have no access to their local context, here the inner lambda can't access {b :a} and the {b '{* :a :b}} expression leads to an error, {b NaN}. _p In fact things are easier in lambdatalk. We simply write the function waiting for two values {pre '{def unclosure {lambda {:a :b} {* :a :b}}} -> {def unclosure {lambda {:a :b} {* :a :b}}} } _p Let's trace the call on two values {pre '{unclosure 3 4} -> '{{lambda {:a :b} {* :a :b}} 3 4} -> '{{lambda {:b} {* 3 :b}} 4} -> '{{lambda {} {* 3 4}} } -> '{* 3 4} -> {* 3 4} } _p And so we can write similarly to Lisp/Scheme: {pre '{unclosure 3} -> the pointer to a function where :a is replaced by 3 '{{unclosure 3} 4} -> {{unclosure 3} 4} } _p So, even if in lambdatalk lambdas don't close over their local context, they are implemented so that {b they accept {i de facto} to be partially called}. _p It's a useful behaviour in a loop waiting for a uniadic function, for instance {pre '{S.map {unclosure 3} {S.serie 1 10}} -> {S.map {unclosure 3} {S.serie 1 10}} } _p It works because {b '{unclosure 3}} is a uniadic function, {b '{lambda {:b} {* 3 :b}}}. _h2 3) an alternative _p In case we need the main function to be uniadic we can also use an IIFE and write {pre '{def unclosure2 {lambda {:a} {{lambda {:a :b} {* :a :b}} :a} // which is {lambda {:b} {* 3 :b}} }} -> {def unclosure2 {lambda {:a} {{lambda {:a :b} {* :a :b}} :a}}} '{unclosure2 3} -> {unclosure2 3} '{{unclosure2 3} 4} -> {{unclosure2 3} 4} '{S.map {unclosure2 3} {S.serie 1 10}} -> {S.map {unclosure2 3} {S.serie 1 10}} } _h2 conclusion _p Thanks to partial application there is a life out of closure. _p Alain Marty 2021/06/23 _h2 refs _ul [[https://medium.com/edge-coders/coding-tip-try-to-code-without-loops-18694cf06428|https://medium.com/edge-coders/coding-tip-try-to-code-without-loops-18694cf06428]] _ul [[https://stackoverflow.com/questions/220658/what-is-the-difference-between-a-closure-and-a-lambda|https://stackoverflow.com/questions/220658/what-is-the-difference-between-a-closure-and-a-lambda]]
lambdaway v.20211111