Re: binding free symbols in a lambda definition

2017-02-10 Thread Alexander Burger
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

2017-02-10 Thread Joh-Tob Schäg
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

2017-02-09 Thread Lindsay John Lawrence
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

2017-02-09 Thread Danilo Kordic
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

2017-02-09 Thread Alexander Burger
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

2017-02-09 Thread Lindsay John Lawrence
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

2017-02-09 Thread Alexander Burger
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

2017-02-09 Thread Lindsay John Lawrence
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

2017-02-09 Thread Alexander Burger
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

2017-02-09 Thread Lindsay John Lawrence
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

2017-02-09 Thread pd
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

2017-02-08 Thread pd
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

2017-02-08 Thread Alexander Burger
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

2017-02-08 Thread Erik Gustafson
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

2017-02-08 Thread pd
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

2017-02-08 Thread Alexander Burger
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

2017-02-08 Thread Erik Gustafson
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

2017-02-08 Thread Erik Gustafson
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

2017-02-08 Thread Lindsay John Lawrence
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

2017-02-08 Thread pd
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

2017-02-08 Thread pd
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

2017-02-08 Thread pd
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

2017-02-08 Thread Lindsay John Lawrence
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

2017-02-07 Thread Alexander Burger
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

2017-02-07 Thread Lindsay John Lawrence
'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

2017-02-07 Thread Lindsay John Lawrence
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

2017-02-07 Thread Lindsay John Lawrence
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

2017-02-07 Thread Erik Gustafson
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
>
>
>