Re: binding free symbols in a lambda definition
Hi Lindsay, > # append > : (bench (let (N ()) (for X 1 (setq N (append N '(NIL (length N))) > 0.548 sec > -> 1 > > # cons > : (bench (let (N '()) (for X 1 (setq N (cons NIL N))) (length N))) > 0.000 sec > -> 1 'append' in such a loop is a lot slower than a straightforward 'cons', because 'cons' creates only a single new cell and puts it in front of the existing list, while 'append' makes a copy of the whole list (as it is non-destructive) and then 'conc's the new cell. > # conc > : (bench (let (N (list)) (for X (conc N (list))) (length N))) > 0.067 sec > -> 1 > ... > Interestingly, I was expecting conc to be faster then (setq..(cons..). At > least in this case, it was not. > 'conc' avoids the copying, but still traverses the (longer and longer) list each time. To build really long lists it is better to use (make ... (link ...)) ♪♫ Alex -- UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe
Re: binding free symbols in a lambda definition
Why not "(de myf FList (apply (car Flist) (cdr Flist))"? Am 08.02.2017 05:04 schrieb "pd" : > Hello, > > I wonder if there is any way to bind a free symbol in a lambda in order to > pass the lambda to a defined function (for example) > > What I want to do is something like this: > > (de myf (f l) (f l)) > > (let l 99 (myf '((x) (+ (car x) l)) (1 2))) > > I want it to return 100 but it fails with an error (1 2) number expected > > this is because free symbol l in lambda ((x) (+ (car x) l)) is not bind by > let as pretended because of quoting of lambda > > In other words, I think the problem is quoting avoids let binding as in: > > (setq f (let n 10 '((x) (+ x n -> ((x) (+ x n)) > > but I want it to return -> ((x) (+ x 10)) > > or using the typicall example: > > (de adder (n) '((x) (+ x n))) -> ((n) '((x) (+ x n))) > > so (adder 1) should return ((x) (+ x 1)) but it returns ((x) (+ x n)) > > Is there any way to manage this? Something similar to "expand" in newlisp > will do the job: > > newlisp: >(define (badadder n) (lambda (x) (+ x n))) >(badadder 3) -> (lambda (x) (+ x n)) >(define (adder n) (expand (lambda (x) (+ x n)) 'n)) >(adder 3) -> (lambda (x) (+ x 3)) > > The fist example in newlisp will be: > > (define (myf f l) (f l)) > > (let ((l 99)) (myf (lambda (x) (+ (first x) l)) '(1 2))) > > which fails for same reason picolisp fails but in newlisp the solution is: > > (define (myf f l) (f l)) > > (let ((l 99)) (myf (expand (lambda (x) (+ (first x) l)) 'l) '(1 2))) -> > 100 > > > thanks > > >
Re: binding free symbols in a lambda definition
Hi Alex, > However, a function call is about the most expensive thing in PicoLisp. It > interprets the parameter list (X), saves the old value of X, evaluates (not X) > and restores the value of X. (de null..) was really unnecessary here :) I just wrote it for completeness as part of the book exercise and after my earlier confusion regarding 'NIL, NIL, '()... Nice to know about 'def' when I need a bit of syntax sugar though ! I am starting to get the hang of the basics here I think. I've been spending a bit of time bench'ing some of the recursive functions and trying to eliminate the recursion or use a built-in function, as you have often shown. # my append : (de cuius (X Y) (cond ((not X) Y) (T (cons (car X) (cuius (cdr X) Y) : (bench (let (N ()) (for X 1 (setq N (cuius N '(NIL (length N))) 2.983 sec -> 1 # ...with nond : (de cuius (X Y) (nond (X Y) (NIL (cons (car X) (cuius (cdr X) Y) : (bench (let (N ()) (for X 1 (setq N (cuius N '(NIL (length N))) 2.644 sec -> 1 # ... neither of the above are even close in performance to ... # append : (bench (let (N ()) (for X 1 (setq N (append N '(NIL (length N))) 0.548 sec -> 1 # cons : (bench (let (N '()) (for X 1 (setq N (cons NIL N))) (length N))) 0.000 sec -> 1 # conc : (bench (let (N (list)) (for X (conc N (list))) (length N))) 0.067 sec -> 1 # -- or -- : (bench (let (N ()) (setq N (need 1)) (length N))) 0.000 sec -> 1. Interestingly, I was expecting conc to be faster then (setq..(cons..). At least in this case, it was not. /Lindsay
Re: binding free symbols in a lambda definition
If `and' and `or' is renamed, or just aliased, to `then' and `else', there is little need left for `if' and `cond' >:) . -- UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe
Re: binding free symbols in a lambda definition
Hi Lindsay, > I missed to include it... >(de null (X) (not X)) OK! :) However, a function call is about the most expensive thing in PicoLisp. It interprets the parameter list (X), saves the old value of X, evaluates (not X) and restores the value of X. Therefore I would recommend (def 'null not) This gives zero overhead :) > I'll have to work with nond a bit more to get how/when use that. Good. Just use the opposite conditions. Instead of (cond ((not A) (foo)) ((not B) (bar)) (T (mumble)) ) you write (nond (A (foo)) (B (bar)) (NIL (mumble)) ) ♪♫ Alex -- UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe
Re: binding free symbols in a lambda definition
Hi Alex, I missed to include it... (de null (X) (not X)) Thanks! for the suggestions. I tried the pairlis alternatives. Much better. 'extract' will be very useful. I'll have to work with nond a bit more to get how/when use that. /Lindsay On Thu, Feb 9, 2017 at 3:17 AM, Alexander Burger wrote: > Hi Lindsay, > > > # pairlis2: gives a list of pairs of corresponding elements > > # of the lists x and y, and appends this to the list a. > > # (pairlis '(A B C) '(1 2) () ) -> ((A . 1) (B . 2)) > > > > (de pairlis2 (X Y A) > >(cond > > ((null X) A) > > ((null Y) A) > > (T > > (cons > > (cons (car X) (car Y)) > > (pairlis2 (cdr X) (cdr Y) A) ) ) ) ) > > Sorry, I have not tested, but 'null' should be undefined. You could > replace it > with 'not'. But then 'nond' is better than 'cond', avoiding it completely > (see > discussion here in this list). > > > In general, using recursion here is quite an overkill. A simpler form > could be > >(de pairlis (X Y A) > (conc (mapcar cons X Y) A) ) > > or, if you want to handle the case where the first list is longer than the > second, > >(de pairlis (X Y A) > (conc > (extract > '((A B) (and A B (cons A B))) > X > Y ) > A ) ) > > ♪♫ Alex > -- > UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe >
Re: binding free symbols in a lambda definition
Hi Lindsay, > # pairlis2: gives a list of pairs of corresponding elements > # of the lists x and y, and appends this to the list a. > # (pairlis '(A B C) '(1 2) () ) -> ((A . 1) (B . 2)) > > (de pairlis2 (X Y A) >(cond > ((null X) A) > ((null Y) A) > (T > (cons > (cons (car X) (car Y)) > (pairlis2 (cdr X) (cdr Y) A) ) ) ) ) Sorry, I have not tested, but 'null' should be undefined. You could replace it with 'not'. But then 'nond' is better than 'cond', avoiding it completely (see discussion here in this list). In general, using recursion here is quite an overkill. A simpler form could be (de pairlis (X Y A) (conc (mapcar cons X Y) A) ) or, if you want to handle the case where the first list is longer than the second, (de pairlis (X Y A) (conc (extract '((A B) (and A B (cons A B))) X Y ) A ) ) ♪♫ Alex -- UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe
Re: binding free symbols in a lambda definition
Picolisp continues to astonish me with its 'Principle of Least Astonishment'... using @ variable arguments is much nicer. /Lindsay # using pairlis2 and sublis from prior email... (de curri2 @ (let (Fun (next) Args (rest) Par (pairlis2 (car Fun) Args) dropP '((X Y) (cond ((null Y) X) (T (dropP (cdr X) (cdr Y))) ) ) ) (list (dropP (car Fun) Args) (car (sublis Par (cdr Fun))) ) ) ) -> curri2 : (setq Fun (curri2 '((X Y) (+ X Y -> ((X Y) (+ X Y)) : (Fun 1 99) -> 100 : (setq Fun (curri2 '((X Y) (+ X Y)) 1) ) -> ((Y) (+ 1 Y)) : (Fun 99) -> 100 : (setq Fun (curri2 '((X Y) (+ X Y)) 1 99) ) -> (NIL (+ 1 99)) : (Fun) -> 100
Re: binding free symbols in a lambda definition
Hi Andrés, thanks for the "curri" examples! > Sorry for the large email and even while pretending to be a clarifying text > it is not :( I think it was :) > Also don't want to give an image of pretending to arrange picolisp's flaw > design, it is absolutely not, not only I don't have the needed > understanding of picolisp nor the knowledge to do so but I consider > picolisp a pretty good design with very smart decisions. What I trying to No worry, I didn't get that impression. I knew these use cases, but until now never had practical situations where they seemed useful. As we saw, they can be handled with the 'curry' function if necessary, but I believe that PicoLisp has better mechanisms - like fexprs and unlimited number of arguments to most functions - to *directly* express the programmer's intentions. For example, > (mapcar ((curri **) 2) (2 3 4)) > # equivalent to (mapcar '((X) (** 2 X)) (2 3 4)) would be written shorter in PicoLip (mapcar ** (2 3 4) (2 .)) -> (4 9 16) > (setq lstLen ((curri mapcar) length)) # equivalent to (de lstLen > (lst) (mapcar length lst)) > (lstLen '((1) (2 3 4) (2 3))) (mapcar length '((1) (2 3 4) (2 3))) -> (1 3 2) > yes, I have to study your classiCurry function to clearly understand how it > works and yes maybe I'm a bit confused about dynamic binding usefulness due > to my static binding background You are not alone :) I try to explain more, perhaps it is also useful for other readers here. > (let N 4 (print N)) > > binds symbol N to value 4 inside print expression and so it prints 4, this > is what we expect of let binding behaviour Yes, though instead of "binds .. inside print" I would say "binds N to 4 inside the body of 'let'. A lexically binding system would indeed magically replace N in the print expression, but in PicoLisp N is bound to 4 during the *time* this let body runs. > same for this code: > > (let N 4 (+ 1 N)) > > we expect to return 5 Yes. > In a coherent way we expect this code: > > (let N 4 ((X) (+ X N))) # erroneus code, I know it! > > to return a function which adds 4 to its parameter (and it would do it if > it doesn't throw a X undefined error) No. This code is not wrong per se, it just does not return a function. As you know, Lisp evaluates expressions by taking the CAR as a function, and the CDR as arguments to that function. So when the body of 'let' is executed, (X) is expected to evaluate to a function, and the result of evaluating (+ X N) is passed to that function. There might even be situations where the above expression makes sense. The problem is more that '+' expects a number, so let's modify it slightly: : (de X () # Define 'X' to return a function println ) -> X : (let N 4 ((X) (+ (size X) N))) 6 -> 6 What happens? (X) evaluates to the function 'println' (the function *pointer* to be exact, as 'println' is a primitive): : X -> (NIL println) : (X) -> 22966530359 # Function pointer to the code of 'println' Then (+ (size X) N) is evaluated : (size X) -> 2 and passed to be printed. It prints 6. > But here the problem is we cannot write an anonymous function (a lambda) > this way, we *must* quote it: > > (let N 4 '((X) (+ X N))) No, you *did* write an anonymous function. It ignored the value of N though. In PicoLisp, code and data are absolutely equivalent. Thus, the list ((X) (+ X N)) is, first of all, data. A list of two lists. The fact that it might be interpreted somewhere else as a function doesn't matter. The point is that in our head we want to return a function, but here we have a chunk of data to be returned. Thus it must be quoted, to inhibit the evaluation as seen above. > but now the quoting has the effect of not evaluating the lambda and thus > preserving it from let symbol binding, this is an undesiderable effect in > my opinion Yes, because there is no lexical (static) binding. All symbols are evaluated solely at runtime. If you need the values statically, you have to do it explicitly, e.g. with 'curry' or simply with list operations: (let N 4 (list '(X) (list '+ 'X N))) -> ((X) (+ X 4)) Voila, the expected function is returned. > So what to do? (from here I'm just reasoning loud) well, the key is to > separate function evaluation from function calling, what if there would be > a mark for type function? No, this would be a big drawback. You lose the equivalence of code and data. The term "function evaluation" is the same as "function calling". What you mean is "function building", i.e. the process of building a function from data, to be evaluated (or called) later. > 1- read the whole let expression > 2- read-macros get executed inmmediately (really I think this is part of > step 1) > 3- perform the bindings in "let prog" expression > 4- evaluate the "let prog" in te context set by let bindings (due to step 3) Exactly. And this is what happens. The point is just that the bindings are
Re: binding free symbols in a lambda definition
I've enjoyed the discussion. Curry is a common idiom in the javascript world (my current day job) so it was very interesting to explore it here. Being relatively new to picolisp I have a lot to learn about built-in functionality so exploring these ideas, with feedback from Alex and others more familiar, is very productive! Below is YAC (Yet another curry)... A simplication, that would allow more natural writing, would be to use @ instead of the current Args list of provided params to curri2. I am still getting the hang of that... /Lindsay I apologise if it is a lot of code to post here, but this was also great opportunity to apply a bit of what I have been learning from the "Lisp 1.5 Programmer's Manual" # note: pairlis2, sublis are functions are adapted from the manual to implement 'curri2' # pairlis2: gives a list of pairs of corresponding elements # of the lists x and y, and appends this to the list a. # (pairlis '(A B C) '(1 2) () ) -> ((A . 1) (B . 2)) (de pairlis2 (X Y A) (cond ((null X) A) ((null Y) A) (T (cons (cons (car X) (car Y)) (pairlis2 (cdr X) (cdr Y) A) ) ) ) ) # 'A is an assoc list ((u . v)..). # sublis: treats the u's as variables # when they occur in Y, and substitutes the # corresponding v's from the pair list (de sublis (A Y) (let (sub2 '((A Z) (cond ((null A) Z) ((= (caar A) Z) (cdar A)) (T (sub2 (cdr A) Z)) ) ) ) (cond ((atom Y) (sub2 A Y)) (T (cons (sublis A (car Y)) (sublis A (cdr Y)) ) ) ) ) ) # And now we can make curry too! (de curri2 (Fun Args) (let (Par (pairlis2 (car Fun) Args) dropP '((X Y) (cond ((null Y) X) (T (dropP (cdr X) (cdr Y))) ) ) ) (list (dropP (car Fun) Args) (car (sublis Par (cdr Fun))) ) ) ) -> curri2 : (curri2 '((X Y) (+ X Y))) -> ((X Y) (+ X Y)) : ('((X Y) (+ X Y)) 1 2) -> 3 : (curri2 '((X Y) (+ X Y)) (1)) -> ((Y) (+ 1 Y)) : ('((Y) (+ 1 Y)) 2) -> 3 : (curri2 '((X Y) (+ X Y)) (1 2)) -> (NIL (+ 1 2)) : ('(NIL (+ 1 2))) -> 3
Re: binding free symbols in a lambda definition
Sorry for the large email and even while pretending to be a clarifying text it is not :( Also don't want to give an image of pretending to arrange picolisp's flaw design, it is absolutely not, not only I don't have the needed understanding of picolisp nor the knowledge to do so but I consider picolisp a pretty good design with very smart decisions. What I trying to do is speaking out loud spreading out my thoughts to see if my understanding is right and also to see if my ideas may be useful somehow or must be considered as nonsenses On Thu, Feb 9, 2017 at 2:17 AM, pd wrote: > > > But let me try to better explain myself... > >
Re: binding free symbols in a lambda definition
Hi Alex > The classical curry in picolisp is what Alex has defined a few emails > > before ;-) > > I never saw a use for the classical curry, so I (ab)used this catchy name > :) > > Can you give an example where it is useful in PicoLisp? > I'm a newbie to picolisp I don't know enough picolisp to state what is useful or not. But curryfied functions are very useful in a lot of situations like processing lists like mapping (mapcar), folding... They are also very useful in function composition which in turn is useful again in list mapping and so on and also to define functions easier and clearly And also thery are useful in defining functons in terms of another functions in a clear, comprehensive and sucint way. Considering curry defined as Alex's ClassiCurry in terms of picolisp (let's call it curri here) (de curri (Fun) (let Par (list (caar Fun)) (list Par (cons 'curry Par (cdar Fun) (cdr Fun)) ) ) ) For example, consider a function like this: (de task (Action A B) (Action A B)) and you provide a bunch of functions as interface to the previous one: (de plus (A B) (task + A B)) (de minus (A B) (task - A B)) (de power (A B) (task ** A B)) .. with curry (really here curri) you can better define the interface functions as: (setq plus ((curri task) +)) (setq minus ((curri task) -)) (setq power ((curri task) **)) .. this way is shorter, clearer and less error-prone and easy to mantain because if signature of function task changes the interface functions are not affected at all (provided the first arg continues to be the action) Also curry functions and partial application are useful to process elements of a list with functions with many arguments, like (mapcar ((curri **) 2) (2 3 4))# equivalent to (mapcar '((X) (** 2 X)) (2 3 4)) (setq lstLen ((curri mapcar) length)) # equivalent to (de lstLen (lst) (mapcar length lst)) (lstLen '((1) (2 3 4) (2 3))) (((curri mapcar) length) '((1) (2 3 4) (2 3))) # equivalent to (mapcar '((L) (length L)) '((1) (2 3 4) (2 3))) > > > >((X) '((Y) (+ X Y))) > > ... > > The reason for this expression being completely useless in picolisp *I > > think* is the use of quote as an alias for lambda thus in practise > > protecting them from evaluation and binding > > This is not the reason. Quote and lambda are abselutely equivalent here. > > You could do > >(setq lambda quote) > > and then > > ((X) (lambda (Y) (+ X Y))) > > I know that, but I pretend to mean another thing, sadly without clarity and have the same result, i.e. a function returning ((Y) (+ X Y)), which is > a > correct, legal PicoLisp function accepting an single parameter Y and > returning a > sum. The quote (or lambda) is gone immediately when returning this > function. > > It may seem useless to you because PicoLisp uses dynamic binding (X is > evaluated > when this function *runs*), but you expected static binding (X is bound to > the > value from the environment when this function is *built*). > > The latter is done in the 'classiCurry' example in my last mail using the > PioLisp 'curry'. > yes, I have to study your classiCurry function to clearly understand how it works and yes maybe I'm a bit confused about dynamic binding usefulness due to my static binding background But let me try to better explain myself... Writing this code: (let N 4 (print N)) binds symbol N to value 4 inside print expression and so it prints 4, this is what we expect of let binding behaviour same for this code: (let N 4 (+ 1 N)) we expect to return 5 In a coherent way we expect this code: (let N 4 ((X) (+ X N))) # erroneus code, I know it! to return a function which adds 4 to its parameter (and it would do it if it doesn't throw a X undefined error) But here the problem is we cannot write an anonymous function (a lambda) this way, we *must* quote it: (let N 4 '((X) (+ X N))) but now the quoting has the effect of not evaluating the lambda and thus preserving it from let symbol binding, this is an undesiderable effect in my opinion So how to avoid this undesiderable side effect? well, first, we have to kow why it happens, i.e why we must quote the lambda? the answer to protect it from calling Calling is what happen to a function when its evaluated, so when let expression is evaluated, eval see its a function and calls it but it finds it needs one argument and there's none so fails with X undefined error, the solution to avoid calling the function is just avoid evaluating the function and thus the need of quotation with the bad side effect we've just seen So what to do? (from here I'm just reasoning loud) well, the key is to separate function evaluation from function calling, what if there would be a mark for type function? in a way the steps in let expression evaluation were similar to this: 1- read the whole let expression 2- read-macros get executed inmmediately (really I think this is part of step 1) 3- perform the bindings in "let
Re: binding free symbols in a lambda definition
On Wed, Feb 08, 2017 at 06:37:17PM +0100, pd wrote: > Picolisp curry function does not follow the pattern, its domain is > completely different and also its image. In other words, you call classical > curry passing it a function argument but you call picolisp curry passing it > several arguments to replace certain symbols inside expressions. It's a > different kind of animal ;-) Right. Actually, it does not necessarily *replace* certain symbols inside expressions. It does so only if you pass "pattern variables", see http://software-lab.de/doc/refP.html#pat? In the normal, general, case, an environment using 'job' is built. This is called a "closure" is in statically binding systems. I did not want to call the PicoLisp 'curry' function a closure, because it returns a *function* while a closure is not a function but the combination of a piece of code with an environmennt (i.e. a 'job' in PicoLisp). > The classical curry in picolisp is what Alex has defined a few emails > before ;-) I never saw a use for the classical curry, so I (ab)used this catchy name :) Can you give an example where it is useful in PicoLisp? > >((X) '((Y) (+ X Y))) > ... > The reason for this expression being completely useless in picolisp *I > think* is the use of quote as an alias for lambda thus in practise > protecting them from evaluation and binding This is not the reason. Quote and lambda are abselutely equivalent here. You could do (setq lambda quote) and then ((X) (lambda (Y) (+ X Y))) and have the same result, i.e. a function returning ((Y) (+ X Y)), which is a correct, legal PicoLisp function accepting an single parameter Y and returning a sum. The quote (or lambda) is gone immediately when returning this function. It may seem useless to you because PicoLisp uses dynamic binding (X is evaluated when this function *runs*), but you expected static binding (X is bound to the value from the environment when this function is *built*). The latter is done in the 'classiCurry' example in my last mail using the PioLisp 'curry'. ♪♫ Alex -- UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe
Re: binding free symbols in a lambda definition
Ahh, I see what you mean. I was not as familiar with the classical curry, as I was first introduced to the concept through PL. Thanks for clarifying with the great write-up! On Feb 8, 2017 11:45 AM, "pd" wrote: > Thanks for your replies, I think your "subst" is exactly the same to > newlisp "expand" > > But picolisp curry function doesn't do that, it simply returns a lambda >> with 1 parameter having the other one properly substituted with its value >> thus making impossible to partially apply the returned function >> >> >> I still think 'curry' is what you want. >> >> >> As far as partial application, wasn't 'adder' an example of that? >> >>: (adder 3) >>-> ((X) (+ X 3)) # partial application >>: ((adder 3) 7) # used as function call >>-> 10 >> >> > yes, adder is an example of partial & total application but now we're > talking about the result of using curry (here the adder function) which > allows partial application. > > But when talking about the curry function itself the problem is the domain > of function, in classical curry the domain are functions of n arguments > (usually n>1) and the image are also functions with exactly 1 argument. > > Picolisp curry function does not follow the pattern, its domain is > completely different and also its image. In other words, you call classical > curry passing it a function argument but you call picolisp curry passing it > several arguments to replace certain symbols inside expressions. It's a > different kind of animal ;-) > > So you cannot apply picolisp curry to any general function, as you do in > classical curry, you must create a picolisp curry call ad hoc to get a > expected function returned > > With a classical curry function you can use (call 'f) to get a curryfied > version of function f which takes only one argument and returns a function > who takes only one argument and returns a function who... (supposing f has > n arguments you have n levels on "indirection"), with picolisp curry you > cannot call it like (call 'f) being f a general function (defined with de) > > The classical curry in picolisp is what Alex has defined a few emails > before ;-) > > > >> I'm not sure that a structure such as >> >>((X) '((Y) (+ X Y))) >> >> would be very useful in PL, though it could certainly be built with our >> friends 'fill' or 'macro'. But I'm also not sure I understood your question >> entirely. >> >> What that helpful at all? >> >> >> > Absolutely unuseful in picolisp, what I tried to express is the concept of > functions returning functions characteristic of curryfied functions in > picolisp syntax. > > The reason for this expression being completely useless in picolisp *I > think* is the use of quote as an alias for lambda thus in practise > protecting them from evaluation and binding > > > > > > -- > Andrés > > *~ La mejor manera de librarse de la tentación es caer en ella**. ~ Oscar > Wilde* ~ >
Re: binding free symbols in a lambda definition
Thanks for your replies, I think your "subst" is exactly the same to newlisp "expand" But picolisp curry function doesn't do that, it simply returns a lambda > with 1 parameter having the other one properly substituted with its value > thus making impossible to partially apply the returned function > > > I still think 'curry' is what you want. > > > As far as partial application, wasn't 'adder' an example of that? > >: (adder 3) >-> ((X) (+ X 3)) # partial application >: ((adder 3) 7) # used as function call >-> 10 > > yes, adder is an example of partial & total application but now we're talking about the result of using curry (here the adder function) which allows partial application. But when talking about the curry function itself the problem is the domain of function, in classical curry the domain are functions of n arguments (usually n>1) and the image are also functions with exactly 1 argument. Picolisp curry function does not follow the pattern, its domain is completely different and also its image. In other words, you call classical curry passing it a function argument but you call picolisp curry passing it several arguments to replace certain symbols inside expressions. It's a different kind of animal ;-) So you cannot apply picolisp curry to any general function, as you do in classical curry, you must create a picolisp curry call ad hoc to get a expected function returned With a classical curry function you can use (call 'f) to get a curryfied version of function f which takes only one argument and returns a function who takes only one argument and returns a function who... (supposing f has n arguments you have n levels on "indirection"), with picolisp curry you cannot call it like (call 'f) being f a general function (defined with de) The classical curry in picolisp is what Alex has defined a few emails before ;-) > I'm not sure that a structure such as > >((X) '((Y) (+ X Y))) > > would be very useful in PL, though it could certainly be built with our > friends 'fill' or 'macro'. But I'm also not sure I understood your question > entirely. > > What that helpful at all? > > > Absolutely unuseful in picolisp, what I tried to express is the concept of functions returning functions characteristic of curryfied functions in picolisp syntax. The reason for this expression being completely useless in picolisp *I think* is the use of quote as an alias for lambda thus in practise protecting them from evaluation and binding -- Andrés *~ La mejor manera de librarse de la tentación es caer en ella**. ~ Oscar Wilde* ~
Re: binding free symbols in a lambda definition
On Wed, Feb 08, 2017 at 01:57:22PM +0100, pd wrote: > *I feel* curry to be a unfortunate name for that function because I expect > curry to be a function that once applied to another function with n > parameters it returns a chain of applying functions with exactly one > argument, that is having: > > : (de sum (x y) (+ x y)) > > I expect a function named curry to behave this way: > > (curry 'sum) -> ((x) '((y) (+ x y)))# it is really pseudocode not > actually picolisp code since returning a lambda quoted this way won't do > the job > > or in classical lisp notation: > > (curry 'sum) -> (lambda (x) (lambda (y) (+ x y))) > > in a way you now can apply the curryfied sum partially: ((curry 'sum) 2) > -> ((y) (+ 2 y)) or totally: ((curry 'sum) 3 4) -> 7 > > But picolisp curry function doesn't do that, it simply returns a lambda You can easily use PicoLisp's 'curry' to built the classical curry (de classiCurry (Fun) (let Par (list (caar Fun)) (list Par (cons 'curry Par (cdar Fun) (cdr Fun)) ) ) ) For your example (I use 'add' instead of 'sum' because the latter is built-in): : (de add (X Y) (+ X Y)) -> add : (classiCurry add) -> ((X) (curry (X) (Y) (+ X Y))) : ((classiCurry add) 2) -> ((Y) (job '((X . 2)) (+ X Y)) If you know that your function does not modify the values of its parameters, you can use pattern variables to get more efficient code with constants and no need for a 'job' closure: : (de add (@X Y) (+ @X Y)) -> add : (classiCurry add) -> ((@X) (curry (@X) (Y) (+ @X Y))) : ((classiCurry add) 2) -> ((Y) (+ 2 Y)) In both cases you get: : (((classiCurry add) 2) 3) -> 5 ♪♫ Alex -- UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe
Re: binding free symbols in a lambda definition
But picolisp curry function doesn't do that, it simply returns a lambda with 1 parameter having the other one properly substituted with its value thus making impossible to partially apply the returned function I still think 'curry' is what you want. Note that 'curry' works with an arbitrary number of parameters, e.g. (curry (@X @Y @Z) ... ) As far as partial application, wasn't 'adder' an example of that? : (adder 3) -> ((X) (+ X 3)) # partial application : ((adder 3) 7) # used as function call -> 10 I'm not sure that a structure such as ((X) '((Y) (+ X Y))) would be very useful in PL, though it could certainly be built with our friends 'fill' or 'macro'. But I'm also not sure I understood your question entirely. What that helpful at all?
Re: binding free symbols in a lambda definition
Hi, If I understand correctly what you said the reason for (let K 3 '(print `K)) returning (print NIL) rather than (print 3) [being K not previously defined] is that the sequence of steps is: Almost, there is a slight confusion in step 2. I would revise it like so: 1- read the whole let expression , here (let K 3 '(print `K)) 2- reader encounters `K, thus K is evaluated (returns NIL) immediately, and that result is substituted into the original expression before any runtime evaluation takes place. So now the expression is (let K 3 '(print NIL)). 3- evaluate the "let prog" in the context stated by let bindings, thus evaluates '(print NIL) in a context where K is bound to 3, but obviously K is not used in the "let prog" if so, would be hard to make the jump over step 2? that is making the quote protecting the whole expression and evaluating the read-macro ` only in step 3 when the expression is evaluated under symbol bindings stablished by let?maybe I'm saying nosense, sorry in advance! ;-) This issue here is readtime vs runtime. The read-macros will not be able to access symbol bindings created at runtime. You will need to use 'fill' or 'macro' for this. : (let K 3 (fill '(print K) 'K)) -> (print 3) # or : (let @K 3 (macro '(print @K))) -> (print 3) This article discusses the subtleties of the process in more detail: http://picolisp.com/wiki/?readvsruntime Happy hacking, Erik
Re: binding free symbols in a lambda definition
And then there's this... (From "Lisp 1.5 Programmer's Manual".. McCarthy... )... # This function gives the result of substituting the S-expression # x for all occurrences of the atomic symbol y in the S-expression z. (de subst (X Y Z) (cond ((= Y Z) X) ((atom Z) Z) (T (cons (subst X Y (car Z)) (subst X Y (cdr Z ) ) which lets you write things like : (de myf (N) (subst N 'N '((x) (+ x N -> myf : (myf 1) -> ((x) (+ x 1)) : ((myf 1) 99) -> 100 : (myf '(* 3 33)) -> ((x) (+ x (* 3 33))) : ((myf '(* 3 33)) 1) -> 100 You could build that out... picolisp ... (= code data) but at the end of the day you would probably end up with 'curry'. ( http://software-lab.de/doc/faq.html#closures).. with a job environment to manage scope, etc /Lindsay But I feel more comfortable with the other you provided > > : (de adder (N) (list '(x) (list '+ 'x (eval 'N > > because I feel more in control of generated lambda > > thanks! >
Re: binding free symbols in a lambda definition
Hi Alex > The key there is the back-quote (`) before the L to force evaluation > > See the doc section on 'Read-Macros' > > http://software-lab.de/doc/ref.html#macro-io > > Exactly. So the whole 'let' expression is read, *then* evaluated. 'L' is > what it > was globally at the time this expression was read, usually NIL. > > If I understand correctly what you said the reason for (let K 3 '(print `K)) returning (print NIL) rather than (print 3) [being K not previously defined] is that the sequence of steps is: 1- read the whole let expression , here (let K 3 '(print `K)) 2- evaluate the whole let expression resulting in (let K 3 '(print NIL)) since the evaluation of K returns NIL in this context because K is not defined 3- evaluate the "let prog" in the context stated by let bindings, thus evaluates '(print NIL) in a context where K is bound to 3, but obviously K is not used in the "let prog" is it that way? if so, would be hard to make the jump over step 2? that is making the quote protecting the whole expression and evaluating the read-macro ` only in step 3 when the expression is evaluated under symbol bindings stablished by let?maybe I'm saying nosense, sorry in advance! ;-)
Re: binding free symbols in a lambda definition
On Wed, Feb 8, 2017 at 5:37 AM, Erik Gustafson wrote: > I think 'curry' is what you're looking for. Your 'adder' example could be > written as: > >: (de adder (@N) (curry (@N) (X) (+ X @N))) >-> adder >: (adder 3) >-> ((X) (+ X 3)) >: (doc 'curry) # for more info :) > > Hope that helps, > Erik > > this does the job and is exactly what I was looking for (together with the fill solution pointed afterwards) but I feel uncomfortable with the use of curry here due to my functional programming background... *I feel* curry to be a unfortunate name for that function because I expect curry to be a function that once applied to another function with n parameters it returns a chain of applying functions with exactly one argument, that is having: : (de sum (x y) (+ x y)) I expect a function named curry to behave this way: (curry 'sum) -> ((x) '((y) (+ x y)))# it is really pseudocode not actually picolisp code since returning a lambda quoted this way won't do the job or in classical lisp notation: (curry 'sum) -> (lambda (x) (lambda (y) (+ x y))) in a way you now can apply the curryfied sum partially: ((curry 'sum) 2) -> ((y) (+ 2 y)) or totally: ((curry 'sum) 3 4) -> 7 But picolisp curry function doesn't do that, it simply returns a lambda with 1 parameter having the other one properly substituted with its value thus making impossible to partially apply the returned function Is there anyway in picolisp to reproduce the functional curry behaviour? that's a sequence of lambdas allowing partial application
Re: binding free symbols in a lambda definition
On Wed, Feb 8, 2017 at 7:15 AM, Lindsay John Lawrence < lawrence.lindsayj...@gmail.com> wrote: > 'fill' (http://software-lab.de/doc/refF.html#fill) does the job in some > cases as well and is a bit easier to read... > > : (de adder (N) (let @X N (fill '((x) (+ x @X) > -> adder > > this is a solution very similar to newlisp style, and probably fill is the most similar function to newlisp's expand (and curry being the second most similar ;) But I feel more comfortable with the other you provided : (de adder (N) (list '(x) (list '+ 'x (eval 'N because I feel more in control of generated lambda thanks!
Re: binding free symbols in a lambda definition
Alex, My mistake! In playing with that code, I had defined (setq L 99) shortly before that and forgotten I had done so. Without that, as you pointed out : (de myf (F L) (F L)) -> myf : (let (L 99) (myf '((x) (+ (car x) `L)) (1 2))) -> NIL A good lesson in taking care with scope and current execution environment. Thanks! /Lindsay On Tue, Feb 7, 2017 at 11:34 PM, Alexander Burger wrote: > Hi Lindsay, > > > :(de myf (F L) (F L)) > > -> myf > > : (let (L 99) (myf '((x) (+ (car x) `L)) (1 2))) > > -> 100 > > I do not think this works. > > > > The key there is the back-quote (`) before the L to force evaluation > > See the doc section on 'Read-Macros' > > http://software-lab.de/doc/ref.html#macro-io > > Exactly. So the whole 'let' expression is read, *then* evaluated. 'L' is > what it > was globally at the time this expression was read, usually NIL. > > > As Erik said, 'curry' is a way: > >: (let (L 99) (myf (curry (L) (X) (+ (car X) L)) (1 2))) >-> 100 > > ♪♫ Alex > -- > UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe >
Re: binding free symbols in a lambda definition
Hi Lindsay, > :(de myf (F L) (F L)) > -> myf > : (let (L 99) (myf '((x) (+ (car x) `L)) (1 2))) > -> 100 I do not think this works. > The key there is the back-quote (`) before the L to force evaluation > See the doc section on 'Read-Macros' > http://software-lab.de/doc/ref.html#macro-io Exactly. So the whole 'let' expression is read, *then* evaluated. 'L' is what it was globally at the time this expression was read, usually NIL. As Erik said, 'curry' is a way: : (let (L 99) (myf (curry (L) (X) (+ (car X) L)) (1 2))) -> 100 ♪♫ Alex -- UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe
Re: binding free symbols in a lambda definition
'fill' (http://software-lab.de/doc/refF.html#fill) does the job in some cases as well and is a bit easier to read... : (de adder (N) (let @X N (fill '((x) (+ x @X) -> adder : (adder 1) -> ((x) (+ x 1)) : (adder 2) -> ((x) (+ x 2)) : ((adder 1) 99) -> 100 /Lindsay
Re: binding free symbols in a lambda definition
You can also do this... : (de adder (N) (list '(x) (list '+ 'x (eval 'N -> adder : (adder 1) -> ((x) (+ x 1)) : (adder 2) -> ((x) (+ x 2)) : ((adder 99) 1) -> 100 Small examples like this one are great learning devices :) As Erik pointed out though, 'curry' is probably more general purpose and a lot more convenient to use for complex use cases. ( http://software-lab.de/doc/refC.html#curry) /Lindsay
Re: binding free symbols in a lambda definition
This works: :(de myf (F L) (F L)) -> myf : (let (L 99) (myf '((x) (+ (car x) `L)) (1 2))) -> 100 The key there is the back-quote (`) before the L to force evaluation See the doc section on 'Read-Macros' http://software-lab.de/doc/ref.html#macro-io /Lindsay On Tue, Feb 7, 2017 at 7:55 PM, pd wrote: > Hello, > > I wonder if there is any way to bind a free symbol in a lambda in order to > pass the lambda to a defined function (for example) > > What I want to do is something like this: > > (de myf (f l) (f l)) > > (let l 99 (myf '((x) (+ (car x) l)) (1 2))) > > I want it to return 100 but it fails with an error (1 2) number expected > > this is because free symbol l in lambda ((x) (+ (car x) l)) is not bind by > let as pretended because of quoting of lambda > > In other words, I think the problem is quoting avoids let binding as in: > > (setq f (let n 10 '((x) (+ x n -> ((x) (+ x n)) > > but I want it to return -> ((x) (+ x 10)) > > or using the typicall example: > > (de adder (n) '((x) (+ x n))) -> ((n) '((x) (+ x n))) > > so (adder 1) should return ((x) (+ x 1)) but it returns ((x) (+ x n)) > > Is there any way to manage this? Something similar to "expand" in newlisp > will do the job: > > newlisp: >(define (badadder n) (lambda (x) (+ x n))) >(badadder 3) -> (lambda (x) (+ x n)) >(define (adder n) (expand (lambda (x) (+ x n)) 'n)) >(adder 3) -> (lambda (x) (+ x 3)) > > The fist example in newlisp will be: > > (define (myf f l) (f l)) > > (let ((l 99)) (myf (lambda (x) (+ (first x) l)) '(1 2))) > > which fails for same reason picolisp fails but in newlisp the solution is: > > (define (myf f l) (f l)) > > (let ((l 99)) (myf (expand (lambda (x) (+ (first x) l)) 'l) '(1 2))) -> > 100 > > > thanks > > >
Re: binding free symbols in a lambda definition
I think 'curry' is what you're looking for. Your 'adder' example could be written as: : (de adder (@N) (curry (@N) (X) (+ X @N))) -> adder : (adder 3) -> ((X) (+ X 3)) : (doc 'curry) # for more info :) Hope that helps, Erik On Feb 7, 2017 10:04 PM, "pd" wrote: > Hello, > > I wonder if there is any way to bind a free symbol in a lambda in order to > pass the lambda to a defined function (for example) > > What I want to do is something like this: > > (de myf (f l) (f l)) > > (let l 99 (myf '((x) (+ (car x) l)) (1 2))) > > I want it to return 100 but it fails with an error (1 2) number expected > > this is because free symbol l in lambda ((x) (+ (car x) l)) is not bind by > let as pretended because of quoting of lambda > > In other words, I think the problem is quoting avoids let binding as in: > > (setq f (let n 10 '((x) (+ x n -> ((x) (+ x n)) > > but I want it to return -> ((x) (+ x 10)) > > or using the typicall example: > > (de adder (n) '((x) (+ x n))) -> ((n) '((x) (+ x n))) > > so (adder 1) should return ((x) (+ x 1)) but it returns ((x) (+ x n)) > > Is there any way to manage this? Something similar to "expand" in newlisp > will do the job: > > newlisp: >(define (badadder n) (lambda (x) (+ x n))) >(badadder 3) -> (lambda (x) (+ x n)) >(define (adder n) (expand (lambda (x) (+ x n)) 'n)) >(adder 3) -> (lambda (x) (+ x 3)) > > The fist example in newlisp will be: > > (define (myf f l) (f l)) > > (let ((l 99)) (myf (lambda (x) (+ (first x) l)) '(1 2))) > > which fails for same reason picolisp fails but in newlisp the solution is: > > (define (myf f l) (f l)) > > (let ((l 99)) (myf (expand (lambda (x) (+ (first x) l)) 'l) '(1 2))) -> > 100 > > > thanks > > >