3 ms·
In {lambda talk} it's not possible to write {lambda {y} {lambda {x} {x y}}} because in {lambda {x} {x y}} y is a free variable and lambdas don't define closures
by martyalain 8y ago
In {lambda talk} it's not possible to write {lambda {y} {lambda {x} {x y}}} because in {lambda {x} {x y}} y is a free variable and lambdas don't define closures, don't accept free variables. I develop a little bit in http://lambdaway.free.fr/lambdaspeech/?view=closure http://lambdaway.free.fr/lambdaspeech/?view=closure. I just found that there is a life out of closures ...
About precedence, let's compare the prefixed parenthesed syntax to the standard math notation:
{+ 1 {* 2 3} 4} -> 11 // equivalent to 1+(2*3)+4
{+ {* 3 3} {* 4 4}} -> 25 // equivalent to (3*3)+(4*4)
{/ {+ 2 5} 2} -> 3.5 // equivalent to (2+5)/2
Note that in the standard math notation, you can forget parenthesis in the two first formulas provided you remember to multiply before adding. In the last formula you must always use parenthesis. My opinion is that the systematic use of parenthesis helps to understand the process. And, last but not least, the evaluator is much more easier to write.
- kazinator 8y ago> y is a free variable No it isn't; it's bound by the outer lambda. You have some funny situation going on there, I'm afraid. If the inner lambda effectively blocks the y reference from connecting with the outer lambda, then y cannot be called a "free variable" in any ordinary sense. Obviously the inner lambda binds it with the purpose of intercepting it and calling it invalid. We might call that an "intercepted, invalid variable" (new term I'm coining right here). A true free variable has no interaction with the enclosing lambda w.r.t. which it is free.
- martyalain 8y ago" No it isn't; it's bound by the outer lambda. " Not in {lambda talk) where a lambda knows nothing but defined arguments. A lambda has no access to any outer environment ... because there is no environment except the global dictionary where are stored primitives and user defined constants and functions. Take a minute to read this page http://lambdaway.free.fr/lambdaspeech/?view=closure http://lambdaway.free.fr/lambdaspeech/?view=closure. Closure is a matter of implementation, not of semantic. And there is a life out of closure. For instance in Scheme we could define the pair structure like this (define cons (lambda (x y) (lambda (z) (z x y)))) (define car (lambda (z) (z (lambda (x y) x)))) (deffine cdr (lambda (z) (z (lambda (x y) y)))) where x and y in the inner lambda's body {z x y} get their values from the outer lambda. In {lambda talk} we define the pair structure like this {def cons {lambda {x y z} {z x y}}} {def car {lambda {z} {z {lambda {x y} x}}}} {def cdr {lambda {z} {z {lambda {x y} y}}}} where cons is a function waiting for three values. When called with two values, {cons hello world}, the lambda stores them in its body and returns a new lambda waiting for the missing value, {lambda {z} {z Hello World}}. And {car {cons Hello World}} will return Hello. The remaining issue without closure is that sometimes you have to build it "by yourself", see for instance this page http://lambdaway.free.fr/lambdaspeech/?view=let http://lambdaway.free.fr/lambdaspeech/?view=let In {lambda talk} lambdas are nothing but local text substitutions. As explained in http://lambdaway.free.fr/lambdaspeech/?view=factory_201902_paper http://lambdaway.free.fr/lambdaspeech/?view=factory_201902_p... . It's as simple as that!
- kazinator 8y ago> A lambda has no access to any outer environment The issue is that the processing of your outer lambda is not traversing its interior to connect with the y reference; it is blocked by the inner lambda. > lambdas are nothing but local text substitutions An outer lambda can substitute inside the inner lambda, even if it's all textual. "{{lambda {y} {lambda {x} {x y}}} arg}" --> substitute y = "arg" everywhere y is not shadowed. "{lambda {x} {x arg}}" There you go: lexical closure: the "arg" text is captured inside the character string "{lambda {x} {x arg}}". This simple thing not working is just a bug in your implementation (that you simply documented away as a requirement instead of fixing it).
- martyalain 8y agoThank you for your kind remarks but I'm still unable to understand the proposed code. Testing the first expression in the current {lambda talk} evaluator doesn't return anything: A) abstraction: 1: {{lambda {y} {lambda {x} {x y}}} arg} 2: {{lambda {y} _LAMB_0} arg} // where _lAMB_0 is {lambda {x} {x y}} 3: {_LAMB_1 arg} // where _LAMB_1 is {lambda {y} _LAMB_0} B) application: 1: {_LAMB_1 arg} 2: {{lambda {y} _LAMB_0} arg} 3: _LAMB_0 4: stop Well I don't understand your idea. I'm just an amateur. In this paper http://lambdaway.free.fr/lambdaspeech/?view=fabric_new http://lambdaway.free.fr/lambdaspeech/?view=fabric_new I give the eval_lambda() JS code (section 2.3. special forms evaluation) where inner lambdas are recursively evaluated without carrying arguments which are ipso facto unknown by inner lambdas. Until now I am unable to write a code which could carry them. In this page http://lambdaway.free.fr/workshop/?view=lambdacode http://lambdaway.free.fr/workshop/?view=lambdacode, following Peter Norvig (http://norvig.com/lispy.html http://norvig.com/lispy.html) I wrote a more "standard" evaluator tokenizing the code, building a nested tree and recursively evaluating it. The evaluator's main function ( var evaluate = function (x, env) {...} ) works in nested environments and lambdas naturally define closures. It's a very clever approach compared to "my" regexp based evaluation. And everything works fine ... but doesn't completely fit my needs in a wiki context: - First, as in most of languages, words must be quoted to be protected from any unwanted evaluation, - the {pre some code} container can't be used (spaces, tabs, line returns are destroyed during the tokenization), - I just can't imagine the cost of the AST approach for such a page http://lambdaway.free.fr/lambdaspeech/?view=jules_verne http://lambdaway.free.fr/lambdaspeech/?view=jules_verne containing 1228778 chars, simply copy/pasted from a text file, as it is. It's just text as in a text editor (plus some enrichments, a TOC, ...). The {lambda talk}'s evaluator flies quickly over the 1228778 chars, say 250000 words, words are just words, and has to evaluate a reduced number of function calls, about 180, until all curly braces have disappeared. PS.: I find the TXR language http://nongnu.org/txr/rosetta-solutions.html http://nongnu.org/txr/rosetta-solutions.html very, very impressive. Félicitations.