Re: replacement for (let L2 (drop L1 2)....

2017-02-06 Thread Lindsay John Lawrence
All of those problems are fun to explore... try writing different versions
of the selected solutions, iterative vs recursive, using just basic list
building block functions vs the wonderfully convenient functions that
picolisp provides, etc

This particular one piqued my interest enough to try writing another
version of 'drop' that is recursive and just uses *car, cdr, cons*...

# -
(de dropNN (Lst N I)
   # (println Lst N I (% I N))
   (cond
  ((= '() Lst) '() )
  ((gt0 (% I N)) (cons (car Lst) (dropNN (cdr Lst) N (inc I
  (T (dropNN (cdr Lst) N (inc I))) ) )

(de *dropN *(Lst N)
   (dropNN Lst N 1) )


: (dropN '(a b c d e f g h i j k) 2)
-> (a c e g i k)

# -

Having written that, it is relatively easy to tinker out something similar
that 'picks' every Nth element...

# -
(de pickNN (Lst N I)
   # (println Lst N I (% I N))
   (cond
  ((= '() Lst) '() )
  ((=0 (% I N)) (cons (car Lst) (pickNN (cdr Lst) N (inc I))) )
  (T (pickNN (cdr Lst) N (inc I))) ) )

(de *pickN *(Lst N)
   (getNN Lst N 1) )

: (pickN '(a b c d e f g h i j k) 2)
-> (b d f h j)

# -

Lisp is, at least for me, one of the most fun languages to explore in this
way.

It may seem slow, but I believe the time I have spent playing with basic
lisp building blocks, and simple list manipulation problems like this one,
is time well spent. The insight gained carries over into so many other
problems and their solutions.

/Lindsay



On Mon, Feb 6, 2017 at 2:51 PM, dean <deangwillia...@gmail.com> wrote:

> Oh gosh...I missed that completely...Thanks Lindsay..That explains
> everything!
> I'm really pleased you told me that because drop looks like a really
> useful function.
> Best Regards
> Dean
>
> On 6 February 2017 at 22:27, Lindsay John Lawrence <
> lawrence.lindsayj...@gmail.com> wrote:
>
>> P16 (**) Drop every N’th element from a list.
>>
>> (de drop (Lst N)
>>   (make
>> (for (I . X) Lst
>>   (unless (=0 (% I N))
>>   (link X) ) ) ) )
>>
>> : (drop ’(a b c d e f g h i k) 3)
>> -> (a b d e g h k)
>>
>> 'drop' is the function given as a solution to the problem.
>>
>> /Lindsay
>>
>>
>> On Mon, Feb 6, 2017 at 1:24 PM, dean <deangwillia...@gmail.com> wrote:
>>
>>> Hi Alex
>>>: (filter prog2 (1 a 2 b 3 c) '(T NIL .))
>>>-> (1 2 3)
>>>: (filter prog2 (1 a 2 b 3 c) '(NIL T .))
>>>-> (a b c)
>>>
>>> Yes the above is exactly what I'm after.
>>>
>>> I copied this drop example straight from ninety nine.
>>> ? P16 (**) Drop every N'th element from a list.
>>> : (drop '(a b c d e f g h i k) 3)
>>> !? (drop '(a b c d e f g h i k) 3)
>>> drop -- Undefined
>>>
>>> I'm not sure why I'm getting "undefined".
>>> I'm using the pil in my picolisp directory which looks like this...

Re: replacement for (let L2 (drop L1 2)....

2017-02-06 Thread Lindsay John Lawrence
Once I started to get the hang of the basic building blocks, I started
seeing patterns and ways to build on what I had written before
e.g. To me, the next logical development of dropN, pickN is to allow
providing a predicate function... effectively making it a general purpose
list filter

# -
(de selectNN (Lst P I)
  # (println Lst I)
  (cond
((= '() Lst) '() )
((P (car Lst) I) (cons (car Lst) (selectNN (cdr Lst) P (inc I
(T (selectNN (cdr Lst) P (inc I))) ) )

(de selectN (Lst P)
  (selectNN Lst P 1) )

# -
Compare selectN to dropN and pickN.
Now you can write code like this
: (selectN '(a 0 b 1 c 2 d 3 e 4 f 5 g 6 h 7 i 8 j 9 k 10) '((V I) (sym?
V)))
-> (a b c d e f g h i j k)
: (selectN '(a 0 b 1 c 2 d 3 e 4 f 5 g 6 h 7 i 8 j 9 k 10) '((V I) (num?
V)))
-> (0 1 2 3 4 5 6 7 8 9 10)
: (selectN '(a 0 b 1 c 2 d 3 e 4 f 5 g 6 h 7 i 8 j 9 k 10) '((V I) (=0 (%
(inc I) 2
-> (a b c d e f g h i j k)
: (selectN '(a 0 b 1 c 2 d 3 e 4 f 5 g 6 h 7 i 8 j 9 k 10) '((V I) (gt0 (%
(inc I) 2
-> (0 1 2 3 4 5 6 7 8 9 10)


Lego my Lisp :)

/Lindsay




On Mon, Feb 6, 2017 at 4:18 PM, Lindsay John Lawrence <
lawrence.lindsayj...@gmail.com> wrote:

> All of those problems are fun to explore... try writing different versions
> of the selected solutions, iterative vs recursive, using just basic list
> building block functions vs the wonderfully convenient functions that
> picolisp provides, etc
>
> This particular one piqued my interest enough to try writing another
> version of 'drop' that is recursive and just uses *car, cdr, cons*...
>
> # -
> (de dropNN (Lst N I)
># (println Lst N I (% I N))
>(cond
>   ((= '() Lst) '() )
>   ((gt0 (% I N)) (cons (car Lst) (dropNN (cdr Lst) N (inc I
>   (T (dropNN (cdr Lst) N (inc I))) ) )
>
> (de *dropN *(Lst N)
>(dropNN Lst N 1) )
>
>
> : (dropN '(a b c d e f g h i j k) 2)
> -> (a c e g i k)
>
> # -
>
> Having written that, it is relatively easy to tinker out something similar
> that 'picks' every Nth element...
>
> # -
> (de pickNN (Lst N I)
># (println Lst N I (% I N))
>(cond
>   ((= '() Lst) '() )
>   ((=0 (% I N)) (cons (car Lst) (pickNN (cdr Lst) N (inc I))) )
>   (T (pickNN (cdr Lst) N (inc I))) ) )
>
> (de *pickN *(Lst N)
>(getNN Lst N 1) )
>
> : (pickN '(a b c d e f g h i j k) 2)
> -> (b d f h j)
>
> # -
>
> Lisp is, at least for me, one of the most fun languages to explore in this
> way.
>
> It may seem slow, but I believe the time I have spent playing with basic
> lisp building blocks, and simple list manipulation problems like this one,
> is time well spent. The insight gained carries over into so many other
> problems and their solutions.
>
> /Lindsay
>
>
>
> On Mon, Feb 6, 2017 at 2:51 PM, dean <deangwillia...@gmail.com> wrote:
>
>> Oh gosh...I missed that completely...Thanks Lindsay..That explains
>> everything!
>> I'm really pleased you told me that because drop looks like a really
>> useful function.
>> Best Regards
>> Dean
>>
>> On 6 February 2017 at 22:27, Lindsay John Lawrence <
>> lawrence.lindsayj...@gmail.com> wrote:
>>
>>> P16 (**) Drop every N’th element from a list.
>>>
>>> (de drop (Lst N)
>>>   (make
>>> (for (I . X) Lst
>>>   (unless (=0 (% I N))
>>>   (link X) ) ) ) )
>>>
>>> : (drop ’(a b c d e f g h i k) 3)
>>> -> (a b d e g h k)
>>>
>>> 'drop' is the function given as a solution to the problem.
>>>
>>> /Lindsay
>>>
>>>
>>> On Mon, Feb 6, 2017 at 1:24 PM, dean <deangwillia...@gmail.com> wrote:
>>>
>>>> Hi Alex
>>>>: (filter prog2 (1 a 2 b 3 c) '(T NIL .))
>>>>-> (1 2 3)
>>>>: (filter prog2 (1 a 2 b 3 c) '(NIL T .))
>>>>-> (a b c)
>>>>
>>>> Yes the above is exactly what I'm after.
>>>>
>>>> I copied this drop example straight from ninety nine.
>>>> ? P16 (**) Drop every N'th element from a list.
>>>> : (drop '(a b c d e f g h i k) 3)
>>>> !? (drop '(a b c d e f g h i k) 3)
>>>> drop -- Undefined
>>>>
>>>> I'm not sure why I'm getting "unde

Re: replacement for (let L2 (drop L1 2)....

2017-02-06 Thread Lindsay John Lawrence
I couldn't resist tinkering with this a bit more.

# --
(de selectN (Lst P)
   (let selectNN
  '((Lst P I)
 (cond
((= 'NIL Lst) 'NIL)
((P (car Lst) I)
   (cons
  (car Lst)
  (selectNN (cdr Lst) P (inc I)) ) )
(T (selectNN (cdr Lst) P (inc I))) ) )
  (selectNN Lst P 1) ) )
# --

Same code, I just realized Picolisp (= code data) allows me to move the
recursing function inside the initializing one.
The results are the same, but now the recursing function is effectively
private.

: (selectN '(a 0 b 1 c 2 d 3 e 4 f 5 g 6 h 7 i 8 j 9 k 10) '((V I) (=0 (%
(inc I) 2
-> (a b c d e f g h i j k)
: (selectN '(a 0 b 1 c 2 d 3 e 4 f 5 g 6 h 7 i 8 j 9 k 10) '((V I) (gt0 (%
(inc I) 2
-> (0 1 2 3 4 5 6 7 8 9 10)
: (selectN '(a 0 b 1 c 2 d 3 e 4 f 5 g 6 h 7 i 8 j 9 k 10) '((V I) (sym?
V)))
-> (a b c d e f g h i j k)
: (selectN '(a 0 b 1 c 2 d 3 e 4 f 5 g 6 h 7 i 8 j 9 k 10) '((V I) (num?
V)))
-> (0 1 2 3 4 5 6 7 8 9 10)

/Lindsay



On Mon, Feb 6, 2017 at 5:04 PM, Lindsay John Lawrence <
lawrence.lindsayj...@gmail.com> wrote:

>
> Once I started to get the hang of the basic building blocks, I started
> seeing patterns and ways to build on what I had written before
> e.g. To me, the next logical development of dropN, pickN is to allow
> providing a predicate function... effectively making it a general purpose
> list filter
>
> # -
> (de selectNN (Lst P I)
>   # (println Lst I)
>   (cond
> ((= '() Lst) '() )
> ((P (car Lst) I) (cons (car Lst) (selectNN (cdr Lst) P (inc I
> (T (selectNN (cdr Lst) P (inc I))) ) )
>
> (de selectN (Lst P)
>   (selectNN Lst P 1) )
>
> # -
> Compare selectN to dropN and pickN.
> Now you can write code like this
> : (selectN '(a 0 b 1 c 2 d 3 e 4 f 5 g 6 h 7 i 8 j 9 k 10) '((V I) (sym?
> V)))
> -> (a b c d e f g h i j k)
> : (selectN '(a 0 b 1 c 2 d 3 e 4 f 5 g 6 h 7 i 8 j 9 k 10) '((V I) (num?
> V)))
> -> (0 1 2 3 4 5 6 7 8 9 10)
> : (selectN '(a 0 b 1 c 2 d 3 e 4 f 5 g 6 h 7 i 8 j 9 k 10) '((V I) (=0 (%
> (inc I) 2
> -> (a b c d e f g h i j k)
> : (selectN '(a 0 b 1 c 2 d 3 e 4 f 5 g 6 h 7 i 8 j 9 k 10) '((V I) (gt0 (%
> (inc I) 2))))
> -> (0 1 2 3 4 5 6 7 8 9 10)
>
>
> Lego my Lisp :)
>
> /Lindsay
>
>
>
>
> On Mon, Feb 6, 2017 at 4:18 PM, Lindsay John Lawrence <
> lawrence.lindsayj...@gmail.com> wrote:
>
>> All of those problems are fun to explore... try writing different
>> versions of the selected solutions, iterative vs recursive, using just
>> basic list building block functions vs the wonderfully convenient functions
>> that picolisp provides, etc
>>
>> This particular one piqued my interest enough to try writing another
>> version of 'drop' that is recursive and just uses *car, cdr, cons*...
>>
>> # -
>> (de dropNN (Lst N I)
>># (println Lst N I (% I N))
>>(cond
>>   ((= '() Lst) '() )
>>   ((gt0 (% I N)) (cons (car Lst) (dropNN (cdr Lst) N (inc I
>>   (T (dropNN (cdr Lst) N (inc I))) ) )
>>
>> (de *dropN *(Lst N)
>>(dropNN Lst N 1) )
>>
>>
>> : (dropN '(a b c d e f g h i j k) 2)
>> -> (a c e g i k)
>>
>> # -
>>
>> Having written that, it is relatively easy to tinker out something
>> similar that 'picks' every Nth element...
>>
>> # -
>> (de pickNN (Lst N I)
>># (println Lst N I (% I N))
>>(cond
>>   ((= '() Lst) '() )
>>   ((=0 (% I N)) (cons (car Lst) (pickNN (cdr Lst) N (inc I))) )
>>   (T (pickNN (cdr Lst) N (inc I))) ) )
>>
>> (de *pickN *(Lst N)
>>(getNN Lst N 1) )
>>
>> : (pickN '(a b c d e f g h i j k) 2)
>> -> (b d f h j)
>>
>> # -
>>
>> Lisp is, at least for me, one of the most fun languages to explore in
>> this way.
>>
>> It may seem slow, but I believe the time I have spent playing with basic
>> lisp building blocks, and simple list manipulation problems like this one,
>> is time well spent. The insight gained carries over into so many other
>> problems and their solutions.
>>
>> /Lindsay
>>
>>
>>
>> On Mon, Feb 6, 2

Re: (= code data)

2017-02-06 Thread Lindsay John Lawrence
Very interesting! It will take me a while to digest all of that though =)
/Lindsay

Side note: I had to look up the square bracket use. I did not realize you
could do that in picolisp. The semantics are different but it reminded me
of the code in the "Lisp 1.5 Programmer's Manual" (
http://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf).
I've only worked through the first 3 sections of that in detail, but it
really helped me to get a handle on some key lisp concepts. At least to me,
the functions the author defines there for manipulating sets are
brilliantly succinct.

On Mon, Feb 6, 2017 at 10:03 AM, Danilo Kordic 
wrote:

> Hi Lindsay.
>
> What do You think about:
>   : [load "frac.l"]  #
> https://gist.github.com/DKordic/6016d743c4c124a1c04fc12accf7ef17 Not
> usable yet :) .
>   : (/ 10 -15)
>   -> (/ -2 3)
>
> Maybe `recur' should also be mentioned in ``Jump anywhere'' task.
>
>
> Hi Rowan.
>
> [de help: [Sym Txt]
>   [def Sym 'help: Txt] ]
>
> [help: "`prop'erty is clearly better than a txt in `prg' if it should
> be extracted by a procedure.  "
>   [de help [Sym]
> "I prefer even this over Reader Comments (``#'').  "
> [get Sym 'help:] ] ]
> --
> UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe
>


Re: replacement for (let L2 (drop L1 2)....

2017-02-07 Thread Lindsay John Lawrence
Thanks Alex!

recur/recurse... I hadn't noticed those functions in the picolisp function
library until now. Very useful.

/Lindsay


On Mon, Feb 6, 2017 at 10:41 PM, Alexander Burger 
wrote:

> Hi Lindsay,
>
> > I couldn't resist tinkering with this a bit more.
>
> Many thanks for this and all the previous examples!
>
> > # --
> > (de selectN (Lst P)
> >(let selectNN
> >   '((Lst P I)
> >  (cond
> > ((= 'NIL Lst) 'NIL)
> > ((P (car Lst) I)
> >(cons
> >   (car Lst)
> >   (selectNN (cdr Lst) P (inc I)) ) )
> > (T (selectNN (cdr Lst) P (inc I))) ) )
> >   (selectNN Lst P 1) ) )
> > # --
> >
> > Same code, I just realized Picolisp (= code data) allows me to move the
> > recursing function inside the initializing one.
> > The results are the same, but now the recursing function is effectively
> > private.
>
>
> As a further simplification, you could use recur/recurse:
>
>(de selectN (Lst P)
>   (let I 1
>  (recur (Lst P I)
> (cond
>((= 'NIL Lst) 'NIL)
>((P (car Lst) I)
>   (cons
>  (car Lst)
>  (recurse (cdr Lst) P (inc I)) ) )
>(T (recurse (cdr Lst) P (inc I))) ) ) ) )
>
> ♪♫ Alex
> --
> UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe
>


Re: replacement for (let L2 (drop L1 2)....

2017-02-07 Thread Lindsay John Lawrence
I just noticed... my original source for the selectN function is this...

(de selectN (Lst P)
..
   ((= '() Lst) '() )
..

However when I (pp 'selectN) it wrote the line where I am trying to test
for an empty list as

(de selectN (Lst P)
..
   ((= 'NIL Lst) 'NIL)
..

Is that  correct? Shouldn't the pp output at least look something like
this? (no ' on NIL)

..
((= NIL Lst) NIL)
..

It  is a bit of nuance regarding '() ,  NIL and  'NIL I will have to keep
in mind.

/Lindsay


On Mon, Feb 6, 2017 at 11:13 PM, Alexander Burger 
wrote:

> On Tue, Feb 07, 2017 at 07:41:45AM +0100, Alexander Burger wrote:
> > (cond
> >((= 'NIL Lst) 'NIL)
>
> One important note: (= 'NIL Lst) is not a good idea.
> Better to use (not Lst).
>
> (= NIL Lst) would compare *names* if 'Lst' happened to be
> a symbol, so (= NIL "NIL") returns T.
>
> Better is (== NIL Lst), which checks for identity.
>
> Anyway, good that we have have 'not' ;)
>
> ♪♫ Alex
> --
> UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe
>


Re: replacement for (let L2 (drop L1 2)....

2017-02-07 Thread Lindsay John Lawrence
Thanks!
I still trip over those nuances if I don't pay attention testing for
NIL or '(), or not, in lists and symbols.
/Lindsay

On Mon, Feb 6, 2017 at 11:13 PM, Alexander Burger 
wrote:

> On Tue, Feb 07, 2017 at 07:41:45AM +0100, Alexander Burger wrote:
> > (cond
> >((= 'NIL Lst) 'NIL)
>
> One important note: (= 'NIL Lst) is not a good idea.
> Better to use (not Lst).
>
> (= NIL Lst) would compare *names* if 'Lst' happened to be
> a symbol, so (= NIL "NIL") returns T.
>
> Better is (== NIL Lst), which checks for identity.
>
> Anyway, good that we have have 'not' ;)
>
> ♪♫ Alex
> --
> UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe
>


Re: replacement for (let L2 (drop L1 2)....

2017-02-06 Thread Lindsay John Lawrence
P16 (**) Drop every N’th element from a list.

(de drop (Lst N)
  (make
(for (I . X) Lst
  (unless (=0 (% I N))
  (link X) ) ) ) )

: (drop ’(a b c d e f g h i k) 3)
-> (a b d e g h k)

'drop' is the function given as a solution to the problem.

/Lindsay


On Mon, Feb 6, 2017 at 1:24 PM, dean  wrote:

> Hi Alex
>: (filter prog2 (1 a 2 b 3 c) '(T NIL .))
>-> (1 2 3)
>: (filter prog2 (1 a 2 b 3 c) '(NIL T .))
>-> (a b c)
>
> Yes the above is exactly what I'm after.
>
> I copied this drop example straight from ninety nine...
> ? P16 (**) Drop every N'th element from a list.
> : (drop '(a b c d e f g h i k) 3)
> !? (drop '(a b c d e f g h i k) 3)
> drop -- Undefined
>
> I'm not sure why I'm getting "undefined".
> I'm using the pil in my picolisp directory which looks like this
> exec ${0%/*}/bin/picolisp ${0%/*}/lib.l @ext.l "$@"
> i.e. not the one in /bin which contains /usr which I think ISN'T local
> and I think I compiled a local version.
>
> Irrespectivethank you very much for your solution.
>
> Best Regards Dean
>
>
> On 6 February 2017 at 15:24, Alexander Burger  wrote:
>
>> On Mon, Feb 06, 2017 at 12:25:14PM +0100, Alexander Burger wrote:
>> > > I'd like to split a list '(txt1 2 txt2 6
>> > > into 2 lists
>> > > '(txt1 txt2...
>> > > and
>> > > '(2 6
>> >
>> > You could for example filter them:
>> >
>> >(let
>> >   (Lst '(txt1 2 txt2 6)
>> >  A (filter sym? Lst)
>> >  B (filter num? Lst) )
>> >   ... use A and B ...)
>>
>> It is not clear what you need.
>>
>>
>> If, for example, you want every *second* element, there is a nice trick:
>>
>>: (filter prog2 (1 a 2 b 3 c) '(T NIL .))
>>-> (1 2 3)
>>
>>: (filter prog2 (1 a 2 b 3 c) '(NIL T .))
>>-> (a b c)
>>
>> Similarly, you can extract other sequences if you pass the right pattern
>> of
>> NIL's and T's.
>>
>> ♪♫ 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-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-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: Future of PicoLisp?

2017-02-04 Thread Lindsay John Lawrence
I also run PicoLisp out of a TinyCore Linux 'VirtualBox' image...
This turned out to be the best route for me to get the performance and
features of picolisp I wanted on microsoft windows hosts.

TinyCore64 + vboxsf (to access host drives) + picolisp is a great combo in
< 50Mb
Exporting that as an 'appliance'  < 15Mb.
== full linux kernel with all the goodness that provides + picolisp
awesomeness to easily utilize all that goodness.

A slightly larger image with docs+w3m+vim (or the picollsp 'vi' Alexander
published) may make a nicely focused little 'lisp machine'  to learn and
tinker on.

/Lindsay


On Sat, Feb 4, 2017 at 8:40 AM, Erik Gustafson 
wrote:

> Hi list,
>
> Sounds like it's time to update the 'apt-get yourself some PicoLisp'
> section on the wiki, as this is no longer the best route for those new to
> the language.
>
> To confirm, the best options seem to be:
>
> - pil64 for Android
> - Ersatz for Windows
> - Docker Image (Packaged PL + Tiny Core)
> - Build from source
>
> Please add if I'm missing anything.
>
> Now as far as trying PicoLisp goes, could we make a little app like
> http://www.tryclj.com? A sandboxed subset of PL where one could try out
> the language and maybe work through a short accompanying tutorial to give a
> taste of the language, before diving into the install process. I think this
> has been discussed before...?
>
> Also isn't there the Emulisp (PL in JS) REPL app? Could that be leveraged?
> Maybe this is a solution without a problem; I agree with others that most
> people discovering PL will likely be comfortable building from source,
> spinning up a VM, etc.
>
> Finally, a side note: I recently came across https://antergos.com. It's
> basically a graphical installer for Arch Linux. I gave it a try and found
> it to be as easy as installing Ubuntu... Click through the install wizard
> and ten minutes later you've got a full-blown Arch desktop environment (or
> base-install if desired) with built-in access to the AUR. The AUR has
> always been up to date (many thanks!) with the latest PicoLisp. Might be
> worth a mention?
>
> Erik
>


Re: Future of PicoLisp?

2017-02-03 Thread Lindsay John Lawrence
I hope it is not dark.
I am just starting on my adventure using PicoLisp and having a wonderful
time of it.

Having said that, I have never used any of the distribution packages.
Picolisp is simple to compile with minimal dependencies. Thank you for that
as well Alex.

On my laptop machine I have just been compiling the latest download
whenever it is available.
It also runs extremely well in a minimal TinyCore Linux  image.
Tinycore+Picolisp+core system utils makes for a great sandbox in a few tens
of megabytes as either a virtualbox or as a bootable stick

I think I also compiled it on Android a few months ago (in Termux) without
issue. I'll have to try it again there.

Keep the light on :)

/Lindsay






On Thu, Feb 2, 2017 at 11:47 PM, Alexander Burger 
wrote:

> Hi all,
>
> the future of PicoLisp is dark. I'm not sure if it can survive in packaged
> distribution.
>
> Ubuntu doesn't support it any more, probably due to the PIE (position
> independent executable) on x86-64.
>
> And at least on Android they seem to demand switching to Clang. The 32-bit
> versions of PicoLisp (pil32 and mini) which are written in C cannot be
> compiled
> on Clang, because Clang doesn't support dynamically allocated arrays, which
> pil32 depends on. As far as I notices, pil64 also has trouble on
> Clang/Android.
>
> :( Alex
> --
> UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe
>


Re: Matching and Hashes

2017-01-25 Thread Lindsay John Lawrence
> I could do this in perl, but I wouldn't be building character ;-)

.. 20+yrs ago, I used to say that when using perl instead of some other
language :)

/Lindsay

On Wed, Jan 25, 2017 at 8:47 AM, Alexander Burger 
wrote:

> Hi Joe,
>
> > The T appears to act as a function in your first option. Does that act
> like
> > "If true return the cdr then break out of the for loop"?
>
> Yes, exactly. The 'T' is indeed not a function, but the marker of special
> clauses in the 'for' syntax (but also 'loop' or 'do'). 'NIL' is also
> supported.
>
> The reference of 'for' says, terse as usually:
>
>If a clause has NIL or T as its CAR, the clause's second element is
> evaluated
>as a condition and - if the result is NIL or non-NIL, respectively -
> the prg
>is executed and the result returned.
>
>
> > I could do this in perl, but I wouldn't be building character ;-)
>
> Yess :)
> ♪♫ Alex
> --
> UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe
>


Re: Future of PicoLisp?

2017-02-20 Thread Lindsay John Lawrence
Picolisp has a release archive readily downloadable here...
http://software-lab.de/down.html.
In my limited experience with picolisp, it actually reminds me of sqlite  (
http://sqlite.org) in its approach...

"Small, Fast, Reliable. Chose any three"

Sqlite seems to have a particularly effective source management model and
an astonishingly active mailing list.
The only way to get the latest (or even moderately recent) version of
sqlite is to download a pre-compiled snapshot from the website or build it
yourself. Both very trivial tasks for the motivated.

The source repo for sqlite is Fossil (
http://www.fossil-scm.org/index.html/doc/trunk/www/index.wiki).
Fossil, written for sqlite, holds all the code, history and docs in a
sqlite database. How 'lisp' is that? ;)

Alex,

Picolisp has the wiki, vip, built in database all written in picolisp... is
an scm such a big leap? Just a thought :)

/Lindsay


On Mon, Feb 20, 2017 at 10:19 AM, Jakob Eriksson 
wrote:

>
>
> I would love for the public repo to be on github!
>
> I think for many, an open source project does not really exist,
> unless it is on Github. We should also try to resurrect somehow,
> the [picolisp] tag on Stack Overflow.
>
> Given that it is encouraged to put in official documentation in the
> form of Q/A on Stack Overflow, I think we could have a coordinated
> effort from here to do it.
>
>
>
>
> On 2017-02-20 18:15, Petr Gladkikh wrote:
> > I admit that I am a passerby here but my impression is that things
> > around PicoLisp feel closed and this is not about the code itself.
> > In particular, there seems to be no public source code repository so
> > source history can only be inferred somehow from releases. I see that
> > some people already try to mirror it (see,
> > e.g. https://github.com/taij33n/picolisp
> > ) but since it is not "official"
> > there's no development or associated discussions. Since revision control
> > is essential for any non-trivial project, the lack of it is surprising.
> > Also there's no public bug tracker. Instead I have to subscribe to this
> > list so it is hard to track what happened to issues.
> >
> > That said removing some friction for outsiders would help to keep things
> > running.
> >
> >
> > 2017-02-03 8:47 GMT+01:00 Alexander Burger  > >:
> >
> > Hi all,
> >
> > the future of PicoLisp is dark. I'm not sure if it can survive in
> > packaged
> > distribution.
> >
> > Ubuntu doesn't support it any more, probably due to the PIE (position
> > independent executable) on x86-64.
> >
> > And at least on Android they seem to demand switching to Clang. The
> > 32-bit
> > versions of PicoLisp (pil32 and mini) which are written in C cannot
> > be compiled
> > on Clang, because Clang doesn't support dynamically allocated
> > arrays, which
> > pil32 depends on. As far as I notices, pil64 also has trouble on
> > Clang/Android.
> >
> > :( Alex
> > --
> > UNSUBSCRIBE: mailto:picolisp@software-lab.de
> > ?subject=Unsubscribe
> >
> >
> >
> >
> > --
> > Petr Gladkikh
> --
> UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe
>


Re: clip and chop down consecutive "internal" white spaces to one

2017-02-18 Thread Lindsay John Lawrence
Thanks Alex,

In the context of

: (glue " " (filter prog (split (chop "  s  pac e s") " ")))
-> "s pac e s"

where

: (split (chop "  s  pac e s") " ")
-> (NIL NIL ("s") NIL ("p" "a" "c") ("e") ("s"))

it is not immediately obvious to me that the arguments passed to the
(filter prog ..) are treated as they are.

I'll have to think about it some more... and write more picolisp! but I am
confident I will figure it out in time =)

/Lindsay


Lots of pun

2017-02-19 Thread Lindsay John Lawrence
My first non-trivial bits of picolisp...

https://github.com/thinknlive/picolisp-maze

/Lindsay


Re: clip and chop down consecutive "internal" white spaces to one space??

2017-02-17 Thread Lindsay John Lawrence
(de trimmr (S C)
   (default C " ")
   (glue C (filter '((E) E) (split (chop S) C

: (setq Str "   spaaaces, spaaaces   everywhere  spaaaces spaaaces r so
squuare   ")
-> "   spaaaces, spaaaces   everywhere  spaaaces spaaaces r so squuare   "
: (trimmr (trimmr Str) "a")

-> "spaces, spaces everywhere spaces spaces r so squuare"

/Lindsay


Re: clip and chop down consecutive "internal" white spaces to one

2017-02-18 Thread Lindsay John Lawrence
Thanks Alex.

I was sure there was something like 'bool' to replace '((E) E)... I just
could not find it at the time. =)

I am surprised that 'prog works. Why, in this context, does it treat it's
argument as 'data'?

Given (NIL NIL NIL ("s" "p" "a" "a" "a" "c" "e" "s" ",") 

: (prog NIL)
-> NIL

: (prog ("s" "p" "a" "a" "a" "c" "e" "s" ","))
!? ("s" "p" "a" "a" "a" "c" "e" "s" ",")
"s" -- Undefined

? (prog '("s" "p" "a" "a" "a" "c" "e" "s" ","))
-> ("s" "p" "a" "a" "a" "c" "e" "s" ",")

/Lindsay


Re: Future of PicoLisp?

2017-02-24 Thread Lindsay John Lawrence
Hi Alex,

I've been using LetsEncrypt.

This page https://gethttpsforfree.com clearly documents the steps to get a
certificate manually.
I ended up writing an automated javascript (nodejs) version of the steps on
that page that works for my purposes but is essentially just 'get it done'
 code.

It should be straightforward to write a picolisp version of it...

/Lindsay



On Thu, Feb 23, 2017 at 11:45 PM, Alexander Burger 
wrote:

> Hi Erik,
>
> thanks for the long post!
>
> Just in short:
>
> > 'Learn PicoLisp the Hard Way'
>
> I totally agree. This would be a great project, I'm ready to join.
> Same for Stack Overflow support.
>
>
> > And let's make sure said landing page is served over HTTPS. It's 2017.
>
> Yes, yes, I know ;) In fact, it is on my todo list since half a year.
>
> I want to use Let's Encrypt, as I already do on another server. However,
> the
> picolisp.com server is currently a mix of Wheezy, Jessie and Stretch, and
> whatever I tried to get the certbot running resulted in a storm of Python
> package mismatch error messages. No way .. I gave up, and decided to wait
> until
> Debian Stretch is stable and thus available from my provider.
>
> ♪♫ Alex
> --
> UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe
>


Re: P35 Prime Factors

2017-02-25 Thread Lindsay John Lawrence
Hi Alex,  Joh-Tob,

Thank you. With the Knuth reference the code makes a lot more sense!

I had implemented a more basic version.

For large ranges, the performance difference of the Alex's iterative
version that utilizes the sequence is much better! It is a very nice use of
circular lists.

: (bench (for X 300 (prime-factors X)))
16.547 sec
-> (2 2 2 2 2 2 3 5 5 5 5 5 5)
: (bench (for X 300 (primeFactorz X)))
24.632 sec
-> (5 5 5 5 5 5 3 2 2 2 2 2 2)


: (bench (prime-factors 1000))
0.000 sec
-> (2 2 2 2 2 2 2 2 2 2 2 5 5 5 5 5 5 5 5 5 5 5)
: (bench (primeFactorz 1000))
0.000 sec
-> (5 5 5 5 5 5 5 5 5 5 5 2 2 2 2 2 2 2 2 2 2 2)
:

(de primeFactorz (N)
   (use Result
  (recur (N)
 (let (Root (inc (sqrt N))  X 2)
(when (gt0 (% N X))
   (setq X 3)
   (while
  (and
 (gt0 (% N X))
 (< (inc 'X 2) Root) ) ) )
(setq
   X (if (<= X Root) X N)
   Result (cons X Result) )
(unless (= X N) (recurse (/ N X))) ) )
  Result ) )


/Lindsay


On Sat, Feb 25, 2017 at 1:25 AM, Joh-Tob Schäg <johtob...@gmail.com> wrote:

> I verified that it works for all numbers lower than 1000.
>
>
> My code:
> (let N 2
>(while (> 1000 N )
>   (ifn (= N (apply '* (prime-factors N)))
>  (print N))
>   (inc 'N)))
>
> 2017-02-25 9:58 GMT+01:00 Alexander Burger <a...@software-lab.de>:
>
>> Hi Lindsay, Joh-Tob,
>>
>> On Sat, Feb 25, 2017 at 09:36:04AM +0100, Joh-Tob Schäg wrote:
>> > The purpose of the list is to increase the speed of the algorithm by
>> > skipping some numbers. This is possible because of the math of
>> Differences
>>
>> Correct.
>>
>> > between consecutive primes but i am currently verifying the algorithm
>> if it
>> > works, since the list might be wrong.
>>
>> I took it from Donald E. Knuth's "Art of Computer Programming", Volume 2
>> (Seminumerical Algorithms). In "Factoring into Primes" on page 365 he
>> writes:
>>
>>The sequence ... of trial divisors .. can be taken to be simply 2, 3,
>> 5, 7,
>>11, 13, 17, 19, 23, 25, 29, 31, 35, .. where we alternately add 2 and
>> 4 after
>>the first three terms.
>>...
>>A further savings of 20 percent ... removing the numbers 30m +/- 5 ..
>>
>> I believe the term (let (D 2 L (1 2 2 . (4 2 4 2 4 6 2 6 .)) generates
>> that
>> sequence.
>>
>> ♪♫ Alex
>>
>>
>> >
>> > 2017-02-25 7:44 GMT+01:00 Lindsay John Lawrence <
>> > lawrence.lindsayj...@gmail.com>:
>> >
>> > > Does anyone know the algorithm that is being expressed here?
>> > >
>> > > I am trying to understand the code... http://picolisp.com/wiki/?99p35
>> > >
>> > > de prime-factors (N)
>> > >(make
>> > >   (let (D 2  L (1 2 2 . (4 2 4 2 4 6 2 6 .))  M (sqrt N))
>> > >  (while (>= M D)
>> > > (if (=0 (% N D))
>> > >(setq M (sqrt (setq N (/ N (link D)
>> > >(inc 'D (pop 'L)) ) )
>> > >  (link N) ) ) )
>> > >
>> > > and  having difficulties understanding the purpose of the circular
>> list.
>> > >
>> > > /Lindsay
>> > >
>> > >
>> > >
>> --
>> UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe
>>
>
>


Re: BBWT

2017-02-25 Thread Lindsay John Lawrence
Thanks Alex,  The feedback is appreciated.

This is a good clarification of how namespaces work in the 64bit version.

 Also, somehow, it had not 'clicked' with me that transient symbols could
be used in this regard. Re-read that section of the documentation again...
=)
"With that mechanism, it is possible to create symbols with a local
access scope, not accessible from other parts of the program"

/Lindsay


On Sat, Feb 25, 2017 at 12:40 AM, Alexander Burger 
wrote:

> Hi Lindsay,
>
> > Bijective Burrows Wheeler Transform
> > https://github.com/thinknlive/picolisp-bbwt
>
> Cool! This code looks very good! :)
>
>
> > As I was working on this I realized I need to start thinking about how to
> > organize my code...
> >
> > The two main functions, encodeBBWT and decodeBBWT feel larger than they
> > should be because I have defined smaller functions within them that use
> > variables in the same scope.
> >
> > My question:  Is there an 'idiomatic' or recommended way to organize
> module
> > or project code in picolisp?
>
> Binding the functions 'Put' and 'Bwt' locally is perfectly legal, but not
> really
> necessary here, as they never change. So they just create (minimal) runtime
> overhead. I would define them the normal way, perhaps as transient symbols
> if I
> want to hide them from the outside world:
>
>(de "put" (B C)
>   (let (V ...
>
>(de "bwt" (W)
>   (let (C ...
>
>
> Using a namespace is also possible, but too much overhead in my feeling
> for such
> a small file. It would go like this:
>
>(symbols 'bbwt 'pico)
>(local put bwt)
>
>(de put (B C)  # Shadows the built-in 'put', use with care
>   (let (V ...
>
>(de bwt (W)
>   (let (C ...
>
>(de pico~encodeBBWT (L)
>   ...
>
>(de pico~decodeBBWT (L)
>   ...
>
> This creates the symbol 'encodeBBWT' in the 'pico' namespace. Another (I
> think
> better) way is:
>
>(de encode (L)
>   ...
>
>(de decode (L)
>   ...
>
> and later, when used from another namespace, call it as
>
>(bbwt~encode ...)
>(bbwt~decode ...)
>
>
> Concerning 'Debug', I would omit it here, and call (trace 'encodeBBWT) or
> (trace
> 'bbwt~encode) or (mapc trace '(bbwt~encode bbwt~decode bbwt~put bbwt~bwt)
> to
> debug it.
>
> Other minor improvements:
>
>   V2 (car (cdr V)) )
> ->
>   V2 (cadr V) )
>
>
>(while (car W)
>   (if (not (cdr W))
>  (Put C (car W))
>  (Put (car (cdr W)) (car W)) )
> ->
>(while (car W)
>   (Put
>  (ifn (cdr W) C (cadr W))
>  (car W) )
>
> and some similar cases :)
>
> ♪♫ Alex
> --
> UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe
>


P35 Prime Factors

2017-02-24 Thread Lindsay John Lawrence
Does anyone know the algorithm that is being expressed here?

I am trying to understand the code... http://picolisp.com/wiki/?99p35

de prime-factors (N)
   (make
  (let (D 2  L (1 2 2 . (4 2 4 2 4 6 2 6 .))  M (sqrt N))
 (while (>= M D)
(if (=0 (% N D))
   (setq M (sqrt (setq N (/ N (link D)
   (inc 'D (pop 'L)) ) )
 (link N) ) ) )

and  having difficulties understanding the purpose of the circular list.

/Lindsay


BBWT

2017-02-24 Thread Lindsay John Lawrence
Bijective Burrows Wheeler Transform

https://github.com/thinknlive/picolisp-bbwt

As I was working on this I realized I need to start thinking about how to
organize my code...

The two main functions, encodeBBWT and decodeBBWT feel larger than they
should be because I have defined smaller functions within them that use
variables in the same scope.

My question:  Is there an 'idiomatic' or recommended way to organize module
or project code in picolisp?

/Lindsay

P.S. I haven't paid much attention to namespaces or module management in
picolisp until now so I'll spend some time reading the docs with that in
mind.


Re: later and output

2017-02-25 Thread Lindsay John Lawrence
My earlier function 'primeFactorz' had a bug! returning the wrong results
for actual prime numbers :(

: (primeFactorz 17)
-> (3 5)   # WRONG!

I have to be more careful with integer arithmetic. The corrected function
is:

(de primeFactorz (N)
   (use Result
  (recur (N)
 (let (Root (inc (sqrt N))  X 2)
(when (gt0 (% N X))
   (setq X 3)
   (while
  (and
 (gt0 (% N X))
 (<= (inc 'X 2) Root) ) ) )
(setq X (if (<= X Root) X N)
  Result (cons X Result))
(unless (= X N) (recurse (/ N X))) ) )
  Result ) )

: (primeFactorz 17)
-> (17)

/Lindsay

Addum: I have to say I am  impressed with how straightforward it is to
parallelize code in picolisp!

I found my bug while playing with Joh-Tob's Check function and the
discussion on this thread really helped me to understand how to use 'later'.

: (bench (CheckPrimeFactors 1 CheckP1))
1.287 sec
-> NIL
: (bench (CheckPrimeFactors 1 CheckP2))
1.310 sec
-> NIL
: (bench (CheckPrimeFactors 1 CheckP1=P2))
1.340 sec
-> NIL
: (bench (CheckPrimeFactors 32 CheckOdd))
(2 3 T 5 T 7 8 T)
(T 11 12 13 T T T 17)
(18 19 20 T T 23 T T)
(T 27 28 29 30 31 32 T)
0.006 sec
-> (T 27 28 29 30 31 32 T)
: (bench (CheckPrimeFactors 32 CheckEven))
(T T 4 T 6 T T 9)
(10 T T T 14 15 16 T)
(T T T 21 22 T 24 25)
(26 T T T T T T 33)
0.006 sec
-> (26 T T T T T T 33)


Definitions: Assuming 'prime-factors' 'primeFactorz':

: CheckP1
-> ((N) (ifn (= N (apply '* (prime-factors N))) N T))
: CheckP2
-> ((N) (ifn (= N (apply '* (primeFactorz N))) N T))
: CheckP1=P2
-> ((N) (ifn (= (sort (prime-factors N)) (sort (primeFactorz N))) N T))
: CheckOdd
-> ((N) (if (bit? 1 (length (prime-factors N))) N T))
: CheckEven
-> ((N) (ifn (bit? 1 (length (prime-factors N))) N T))


(de CheckPrimeFactors (Limit Checkit)
   (let Lst (need 8)
  (for (N 2 (>= Limit N))
 (map
'((L)
   (set L NIL)
   (later L (Checkit N))
   (inc 'N) )
Lst )
 (wait NIL (full Lst))
 (ifn (fully flg? Lst) (println Lst)) ) ) )


Re: trouble reading non blocking space etc

2017-02-14 Thread Lindsay John Lawrence
Not sure about file charset encoding (a0?)... But perhaps something like
this...?

$ xxd test.txt
000: 6869 a074 6865 6972 3aa0 686f 7720 6172  hi.their:.how ar
010: 6520 796f 750a   e you.

: (pack
  (make
 (in "test.txt" (while (rd 1) (link (char @ ) )
-> "hi their: how are you^J"

# .. or without pack
: (make (in "test.txt" (while (rd 1) (link (char @ )
-> ("h" "i" " " "t" "h" "e" "i" "r" ":" " " "h" "o" "w" " " "a" "r" "e" " "
"y" "o" "u" "^J")

/Lindsay


On Tue, Feb 14, 2017 at 8:33 AM, dean  wrote:

> Ok...It seems that (rd 1) doesn't work well with (until (eof) so I tried
>
> (in "/home/me/test_fl.txt"
>(while (setq B (rd 1))
>   (prinl (char B))
>   (if (= (key) "x") (quit
>
> and "while" testing the output of "rd 1" worked fine
>
> On 14 February 2017 at 16:21, dean  wrote:
>
>> Ok Done it now including the decimal codes and I'd previously seen both
>> hex and hax so...this should keep me busy for a while :).
>>
>> (in "/home/me/test_fl.txt"
>>(until (eof)
>>   (setq B (rd 1))
>>   (prinl B  )
>>   (if (= (key) "x") (quit
>>
>> On 14 February 2017 at 15:50, dean  wrote:
>>
>>> This is the closest I've got i.e. the first byte seems to go into B now
>>> but then I'm in an endless loop with B's value stuck with that first byte.
>>>
>>> (in "/home/me/test_fl.txt"
>>>(until (eof)
>>>   (setq B (pipe (echo 1) (read)))
>>>   (prinl B)
>>>   (if (= (key) "x") (quit
>>>
>>> On 14 February 2017 at 13:03, dean  wrote:
>>>
 My mistakeI haven't done it at all and what is moreI'm not sure
 how you get the hex value (or decimal value) of the byte to decide what to
 do with it.

 On 14 February 2017 at 12:38, dean  wrote:

> Done it :)
>
> (in "/home/me/test_fl.txt"
>(until (eof)
>   (echo 1)
>   (setq B (in NIL))
>   (prinl B)
>   (key)))
>
>
> On 14 February 2017 at 12:26, dean  wrote:
>
>> Looking a possible ways around this I saw this in the tutorial :)
>>
>> (in "/home/me/test_fl.txt"
>>(until (eof)
>>   (echo 1)
>>   (key)))
>>
>> and it works great. My problem is I don't know how to
>> capture (echo 1)  into a symbol's val.
>>
>>
>> On 13 February 2017 at 23:03, dean  wrote:
>>
>>> Thank you very much for this!
>>> I tried (cd src; make tools) both from the command line...because of
>>> "$"
>>> and from within Picolisps RPL because of the parens.
>>> I looked in src and there is just the utf2.c file.
>>> When I do $ (cd src; make tools) from the command line I get...
>>> $ (cd src; make tools)
>>> *** Parse error in /home/me/picoLisp/src: Missing dependency
>>> operator (Makefile:20)
>>> *** Parse error: Need an operator in 'else' (Makefile:28)
>>> *** Parse error: Missing dependency operator (Makefile:29)
>>> *** Parse error: Need an operator in 'else' (Makefile:37)
>>> etc.
>>>
>>> which looks like
>>> the block beginning
>>> ifeg ($(shell uname), Linux)
>>> .
>>> .
>>> else
>>> ifeg ($(shell uname, OpenBSD)
>>> .
>>> .
>>> I'm the second i.e. OpenBSD option and know very nothing about
>>> makefiles.
>>> I'm on a 64 bit OS but am looking at two -m32 options in there.
>>> That might well be ok but I thought I'd mention it.
>>>
>>> Best Regards
>>> Dean
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>> On 13 February 2017 at 21:52, Alexander Burger 
>>> wrote:
>>>
 Hi Dean,

 > 6869 a074 6865 6972 3aa0 686f 7720 6172 6520 796f 750a
 > hi.their:.how are you.
 >
 > The following program...
 >
 > (in "/home/me/test_fl.txt"
 >(until (eof)
 >   (setq Ln (line T))
 >   (prinl Ln)))
 >
 > results in this
 >
 > hiനeir:ਯw are you

 OK, as you noticed in your other mail, PicoLisp can handle *only*
 UTF-8 input.


 > (load "@lib/import.l")

 This is probably not necessary here.


 > (in '("bin/utf8" "/home/me/test_fl.txt")

 Good, that's the right way!


 > bin/utf8: Can't exec

 Try this:

$ (cd src; make tools)

 ♪♫ Alex
 --
 UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe

>>>
>>>
>>
>

>>>
>>
>


Re: Recursion-Loop Macro?

2017-02-13 Thread Lindsay John Lawrence
There is lots of discussion on the mail archive on this topic over the
years.
http://www.mail-archive.com/picolisp@software-lab.de/msg03860.html
There are others. Try searching tail recursion, macros, fexpr.

The mail archive has been an excellent source of information on picolisp.

I haven't found significant advantage to having tail recursion. Either in
picolisp, or other languages I generally work with.
Not recursing saves 'stack' but by the time that is an issue I am looking
for a different algorithm.

I am discovering picolisp has some great general purpose functions for just
that.

Here's an example I worked out recursively last week (set intersection),
then tried to do the same thing without recursion, then with (idx).
(randl, concurret, concurreti, concurretix are defined at the end of this
message)

# Make two lists of random numbers with random range large enough for small
collision set
: (nil (setq M (randl 1 999) N (randl 1 999)))
-> NIL

# Recurse
: (bench (sort (uniq (concurret M N
4.103 sec
-> (1144218 1809896 2048032 2258715 2819894 5571078 9413422 9726100 9936515)

# loop
: (bench (sort (uniq (concurreti M N
2.566 sec
-> (1144218 1809896 2048032 2258715 2819894 5571078 9413422 9726100 9936515)

# idx
: (bench (sort (uniq (concurretix M N
0.018 sec
-> (1144218 1809896 2048032 2258715 2819894 5571078 9413422 9726100 9936515)

Idx 'wins'.


/Lindsay


# ==
# Set intersection: recursive solution.
(de membro (X Y)
   (cond
  ((not Y) NIL)
  ((= X (car Y)) T)
  (T (membro X (cdr Y))) ) )

(de concurret (X Y)
   (cond
  ((not X) NIL)
  ((membro (car X) Y)
 (cons (car X) (concurret (cdr X) Y)) )
  (T (concurret (cdr X) Y)) ) )

# Set intersection: no recursion
(de membri (X Y)
   (until (or (not Y) (= X (car Y)))
  (setq Y (cdr Y)) )
   (= X (car Y)) )

(de concurreti (X Y)
   (let (V NIL)
  (until (not X)
 (when (membri (car X) Y)
(setq V (cons (car X) V)) )
 (setq X (cdr X)) )
  V ) )
# Set intersection: Filter X into (idx); filter Y on that.
(de concurretix (X Y)
   (let (R NIL)
  (filter
 '((V)
(not (idx 'R (cons (hash V) V) T)) )
 X )
  (uniq
 (filter
'((V) (idx 'R (cons (hash V) V)))
Y ) ) ) )

# Generate list of random numbers in given range
(de randl (L R) (make (do L (link (rand 0 R)


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 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: conc: unexpected results

2017-02-09 Thread Lindsay John Lawrence
I tried conc to an empty list on both 32 and 64 bit versions of picolisp
I even installed SBCL just to try the similar 'nconc' on that platform.

The results are consistent for all of them.
I  just don't understand why Is it simply 'standard', historical
reasons? because of the way evaluation works?

As it is, I would not be able to build a list 'destructively' without
conditional logic for the initial empty list.
conc works as expected when M is not empty. i.e M is rewritten.


# 
# Could also use NIL to represent the empty list (
http://software-lab.de/doc/ref.html#nilSym)
: (setq M '() N '(A B C))
-> (A B C)
: (conc M N)
-> (A B C)
: M
-> NIL
: N
-> (A B C)

# This is even weirder to me...
# Again, I expected M, not N, to be rewritten
: (setq M NIL N '(A B C) L '(1 2 3))
-> (1 2 3)
: (conc M N L)
-> (A B C 1 2 3)
: M
-> NIL
: N
-> (A B C 1 2 3)
: L
-> (1 2 3)
# -

/Lindsay


Re: Segfault with huge list...?

2017-02-10 Thread Lindsay John Lawrence
If it even matters, the overhead of recurse is slowest here.
So impressive that picolisp can iterate/recurse over a 10M element list in
these times.
(VirtualBox VM, 4GB, 1Core, with 64bit Debian).

.. and 'make' is a lot more useful that I first realized.

/Lindsay

# Iterative
(de sumi (L)
   (let (Sum (car L))
  (while (setq L (cdr L))
 (setq Sum (+ Sum (car L))) ) ) )

# Recurse
(de sumr (N)
   (cond
  ((not N) 0)
  (T (+ (car N) (sumr (cdr N ) )

# This may take a moment...
: (setq bigly (range 1 1000) D NIL) -> NIL
: (bench (apply '+ bigly))  0.097 sec  -> 500500
: (bench (sum '+ bigly))0.139 sec  -> 500500
: (bench (sumi bigly))  0.275 sec  -> 500500
: (bench (sumr bigly))  0.639 sec  -> 500500

: (setq bigly (need 1000 1) D NIL) -> NIL
: (bench (apply '+ bigly))  0.099 sec  -> 1000
: (bench (sum '+ bigly))0.139 sec  -> 1000
: (bench (sumi bigly))  0.272 sec  -> 1000
: (bench (sumr bigly))  0.643 sec  -> 1000

: (bench (setq bigly (make (for X 1000 (link (+ (- 1000 X) 1)
(length bigly))0.437 sec -> 1000
: (bench (sumr bigly))  0.630 sec  -> 500500
: (bench (sumi bigly))  0.279 sec  -> 500500


Am 10.02.2017 15:28 schrieb "Mike Pechkin" :
>>
>>> hi,
>>>
>>> On Fri, Feb 10, 2017 at 3:07 PM, Christopher Howard <
>>> christopher.how...@qlfiles.net> wrote:
>>>
>>> > Hi list. When I try to do
>>> >
>>> > (apply '+ (range 1 100)
>>> >
>>>
>>>
>>> ​List of ​millions of items is not a problem.
>>> Problem how you use it.
>>> (apply) is not for free, ​It *creates*​ a function call with a million of
>>> arguments.
>>> Stack size make sense.
>>>
>>>
>>> > I get segfault. I thought maybe this was some kind of internal
>>> > limitation of the apply function, so I defined a foldl:
>>> >
>>> > (de foldl (Fn Acc Lst)
>>> > (if (== () Lst) Acc
>>> > (let Acc2 (Fn Acc (car Lst))
>>> >  (foldl Fn Acc2 (cdr Lst)) ) ) )
>>> >
>>> > : (foldl '+ 0 (range 1 1000))
>>> > (foldl '+ 0 (range 1 1000))
>>> > -> 500500
>>> > : (foldl '+ 0 (range 1 100))
>>> > (foldl '+ 0 (range 1 100))
>>> >
>>> >
>>> ​
>>> Stack size makes sense too.
>>> I like recursions this way:
>>>
>>> (de rec1 (F A L)
>>>(if L
>>>   (rec1 F (inc 'A (++ L)) L)
>>>   A ) )
>>>
>>> recursion with hidden accumulator from outer call and car-cdr:
>>> (de rec2 (F L A)
>>>(default A 0)
>>>(if L
>>>   (rec2 F (cdr L) (inc 'A (car L)))
>>>   A ) )
>>> The call will be:  (rec2 '+ (range 1 100)))
>>>
>>>
>>> As recursion just loop you can implement it without big stack too:
>>> (de sum1 (L)
>>>(let N 0
>>>   (for I L
>>>  (inc 'N I) ) ) )
>>>
>>> even without list creation:
>>> (de sum2 (X)
>>>(let N 0
>>>   (for I X
>>>  (inc 'N I) ) ) )
>>>
>>>
>>> And finally, that's why (sum) was implemented:
>>> (sum prog (range 1 100)))
>>>
>>>
>>> Bonus: for practice write recursion function to sum numbers without
>>> (range)
>>
>>
>


Re: Segfault with huge list...?

2017-02-10 Thread Lindsay John Lawrence
I think I'll start keeping a list =) of picolisp's pleasant surprises.
/Lindsay

On Fri, Feb 10, 2017 at 11:06 AM, Joh-Tob Schäg  wrote:

> Linsday when you want to prevent values from neing printed take a look at
> the 'nil function.
>
>


Re: conc: unexpected results

2017-02-09 Thread Lindsay John Lawrence
Apologies for bothering everyone with this. It took some research (there is
surprising little discussion of the function online or even in most books),
but I at least understand how it works now.

It seems that it is not often used in everyday programming: "It is a good
idea to leave the use of NCONC, RPLACA, RPLACD, and DELETE to risk-loving
programmers. Unless desperate for time or space saving, using them just
leads to unnecessary bugs. "--Lisp (Winston, Horn) P. 117

/Lindsay


On Thu, Feb 9, 2017 at 5:21 PM, Lindsay John Lawrence <
lawrence.lindsayj...@gmail.com> wrote:

> I tried conc to an empty list on both 32 and 64 bit versions of picolisp
> I even installed SBCL just to try the similar 'nconc' on that platform.
>
> The results are consistent for all of them.
> I  just don't understand why Is it simply 'standard', historical
> reasons? because of the way evaluation works?
>
> As it is, I would not be able to build a list 'destructively' without
> conditional logic for the initial empty list.
> conc works as expected when M is not empty. i.e M is rewritten.
>
>
> # 
> # Could also use NIL to represent the empty list (
> http://software-lab.de/doc/ref.html#nilSym)
> : (setq M '() N '(A B C))
> -> (A B C)
> : (conc M N)
> -> (A B C)
> : M
> -> NIL
> : N
> -> (A B C)
>
> # This is even weirder to me...
> # Again, I expected M, not N, to be rewritten
> : (setq M NIL N '(A B C) L '(1 2 3))
> -> (1 2 3)
> : (conc M N L)
> -> (A B C 1 2 3)
> : M
> -> NIL
> : N
> -> (A B C 1 2 3)
> : L
> -> (1 2 3)
> # -
>
> /Lindsay
>
>
>


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
>


conc: unexpected results

2017-02-09 Thread Lindsay John Lawrence
conc does not rewrite N if N is an empty list.

# 1.
: (let (N '()) (conc N '(A)))
-> (A)
# 2
: (let (N '()) (conc N '(A)) N)
-> NIL
# 3.
: (let (N '(NIL)) (conc N '(A)) N)
-> (NIL A)
# 4.
: (let (N '()) (setq N (conc N '(A))) N)
-> (A)

In #2 above, I was expecting N to be (A)
If N is not empty, as in #3 it works as expected, or I can force the
assignment, as in #4... which shouldn't be necessary.

Originally I wanted to do:
:  (let (N '()) (for X 10 (conc N '(A))) N)
-> NIL  # expected '(A A A A A A A A A A)

..and this goes into never land. [kill -9]
 (let (N '()) (for X 10 (setq N (conc N '(A N)


/Lindsay


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


I/O buffering.

2017-01-17 Thread Lindsay John Lawrence
Is is possible to turn off I/O buffering in a PicoLisp program?
e.g In Perl one can do something like this...

#!/usr/bin/perl
$| = 1; # Turn off I/O buffering
while () {
s/-/_/g; # Replace dashes with underscores
print $_;
}

I'd like to do something similar with a PicoLisp program.

Best Regards,
/Lindsay


Re: I/O buffering.

2017-01-18 Thread Lindsay John Lawrence
Hi Alex,

Thank you. That is a nice example.

The ability to explicitly flush buffered data on the output channel was
what I was looking for.
Of course, there is a existing function to do just that... that I should of
thought to look for... (flush)

I am still trying to get a handle on using  io channels in picolisp.. and
the nuances of '@'  :)

One way to do that has been to see where I can use channels to wire useful
functionality into existing projects.
For context, the Perl example I referenced is from here
https://httpd.apache.org/docs/2.2/rewrite/rewritemap.html#prg

Best regards,
/Lindsay.


On Tue, Jan 17, 2017 at 10:46 PM, Alexander Burger 
wrote:

> Hi Lindsay,
>
> > Is is possible to turn off I/O buffering in a PicoLisp program?
>
> I/O buffering can't be turned off, it happens on a lower (stdin) level.
>
>
> I think what you mean is a low-level (e.g. character-wise) read as opposed
> to
> the higher-level 'read' function.
>
> > e.g In Perl one can do something like this...
> >
> > #!/usr/bin/perl
> > $| = 1; # Turn off I/O buffering
> > while () {
> > s/-/_/g; # Replace dashes with underscores
> > print $_;
> > }
>
> This could be:
>
>(while (char)
>   (prin
>  (case @
> ("-" "_")
> (T @) ) ) )
>
> ♪♫ Alex
> --
> UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe
>


Re: Scaled division and sqrt

2017-02-27 Thread Lindsay John Lawrence
Thanks Eric,

I am going to have to play with those two particular built-in functions a
bit more. Their use, especially '*/ was not intuitive to me. At first, or
second, reading.

Having just tried it... I am surprised that the 'sqrt*  I implemented is
quite a bit faster! than the built-in 'sqrt. I'll try the long division
later.

: (scl 10) (bench (nil (sqrt 2.0)))   # Built-in
30.917 sec
-> NIL
: (scl 10) (bench (nil (sqrt* 2.0)))   #
2.906 sec
-> NIL
: (scl 1) (bench (nil (sqrt 2.0))) # Built-in
0.253 sec
-> NIL
: (scl 1) (bench (nil (sqrt* 2.0)))
0.044 sec
-> NIL


1 Million digits of sqrt(2):

The 'sqrt* function implemented does need more than 13 iterations to
converge accurately when the number of digits are > 300K or so. The
corrected version is below.  It now checks for convergence. 1M digits of
the sqrt(2) takes 20 iterations to converge. The results, dumped to a file,
are the same as the first 1M digits here...
https://apod.nasa.gov/htmltest/gifcity/sqrt2.1mil

I'll say it again.. I am really impressed by picolisp. I have not had this
much fun expressing ideas in code in some time.

/Lindsay


: (scl 100) (bench (nil (sqrt* 2.0)))
323.805 sec
: (scl 100) (bench (out "sqrt2-1M.txt" (nil (prin (sqrt* 2.0)
932.620 sec


# Scaled fixed point sqrt()
# ... check for convergence added.
(de sqrt* (N S)
   (let (P (/ N 2)  M 63  C (0 0 .))
  (default S *Scl)
  (set C P  (cdr C) 0)
  (setq N (* N (** 10 S)))
  (while
 (and
(ge0 (dec 'M))
(<> (car C) (cadr C) P) )
 (setq P (/ (+ P (/ N P)) 2))
 (pop 'C)
 (set C P))
 (set C 0  (cdr C) 0)
  P ) )


Re: Scaled division and sqrt

2017-02-27 Thread Lindsay John Lawrence
Hi Danilo,

Sorry, I do not follow this. Can you explain a bit more?

Thanks!
/Lindsay


On Mon, Feb 27, 2017 at 3:32 AM, Danilo Kordic 
wrote:

> It seems You reimplemented `*/'.
>
> How about something like:
>   # [name 'sqrt "isqrt"]  # Somthing like that.
>   [scl [if native 17 8]]
>   [de sqrt [N]
> [list [isqrt (** 100 *Scl) N] 'E [- *Scl]] ]
>
>
>


Re: Scaled division and sqrt

2017-02-27 Thread Lindsay John Lawrence
Hi Alex,

I am missing something basic here that article is how I ended up
writing the functions.

With the functions I implemented I can write something like...

: (scl 64) (format (sqrt* 2.0) *Scl)
-> "1.4142135623730950488016887242096980785696718753769480731766797379"

: (scl 64) (format (/* 1.0 9967.0) *Scl)
-> "0.0001003310926055984749673923949031804956355974716564663389184308"

How do I get similar results with the built-in functions?


/Lindsay


Copy/Clone a 'job

2017-02-26 Thread Lindsay John Lawrence
Hi,

How would I copy|clone, reinitialize or dispose of a 'job' function?

For example, given

(de hexSpigot NIL
   (job '((N))
  (ifn N (setq N '(0)))
  (prog1
 (hex (% (car N) 16))
 (setq N (cons (+ 1 (car N)) N)) ) ) )

I can then do..

: (do 32 (prin (hexSpigot)))

0123456789ABCDEF0123456789ABCDEF-> "F"

Now, hexSpigot something like this...

: (pp 'hexSpigot)
(de hexSpigot NIL
   (job
  '((N 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12
11 10 9 8 7 6 5 4 3 2 1 0 ) )
  (ifn N (setq N '(0)))
  (prog1
 (hex (% (car N) 16))
 (setq N (cons (+ 1 (car N)) N)) ) ) )



The job vars are being modified and the list N is growing.. using ever
greater amounts of memory. If I want to reset the spigot, or even clone it
to have more than one, how would I do that?


/Lindsay


Re: Copy/Clone a 'job

2017-02-26 Thread Lindsay John Lawrence
Thanks Alex,

I'll have to play with your solution a bit. I don't quite follow how the
global is working there in conjunction with 'job and 'off.

However, after banging around on this for a couple of hours, trying 'copy',
various auxillary functions to return the quoted 'job, etc I was at my wits
end...when just a few minutes ago, I remembered where the mail list had
discussed 'job most recently... over 'curry!

This seems to do what I want as well...

: (pp 'getHexSpigot)
(de getHexSpigot NIL
   (curry
  ((N))
  NIL
  (default N '(0))
  (prog1
 (hex (% (car N) 16))
 (setq N (cons (+ 1 (car N)) N)) ) ) )
-> getHexSpigot

Now I can do this...

: (def 'hexSpigot1 (getHexSpigot))
-> hexSpigot1
: (def 'hexSpigot2 (getHexSpigot))
-> hexSpigot2

: (do 8 (prin (hexSpigot1)))
01234567-> "7"
: (do 16 (prin (hexSpigot2)))
0123456789ABCDEF-> "F"

: hexSpigot1
-> (NIL (job '((N 8 7 6 5 4 3 2 1 0)) (default N '(0)) (prog1 (hex (% (car
N) 16)) (setq N (cons (+ 1 (car N)) N)
: hexSpigot2
-> (NIL (job '((N 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0)) (default N
'(0)) (prog1 (hex (% (car N) 16)) (setq N (cons (+ 1 (car N)) N)

: (off hexSpigot1)
: (off hexSpigot2)


/Lindsay




On Sun, Feb 26, 2017 at 1:19 AM, Alexander Burger 
wrote:

> Hi Lindsay,
>
> > (de hexSpigot NIL
> >(job '((N))
> > ...
> > : (do 32 (prin (hexSpigot)))
> > ...
> > 0123456789ABCDEF0123456789ABCDEF-> "F"
> > ...
> > : (pp 'hexSpigot)
> > (de hexSpigot NIL
> >(job
> >   '((N 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12
> > 11 10 9 8 7 6 5 4 3 2 1 0 ) )
> > ...
> > The job vars are being modified and the list N is growing.. using ever
> > greater amounts of memory. If I want to reset the spigot, or even clone
> it
> > to have more than one, how would I do that?
>
> The simplest is to use a global:
>
>(setq *HexSpigot '((N)))
>
>(de hexSpigot NIL
>   (job *HexSpigot
>  ...
>
> and later just do the 'setq' again.
>
>
> BTW, for an expression like
>
>(ifn N (setq N (0)))
>
> there is 'default'
>
>(default N (0))
>
> So the above could be made a bit easier:
>
>(off *HexSpigot)
>
>(de hexSpigot NIL
>   (job (default *HexSpigot '((N . (0
>  (prog1
> (hex (% (car N) 16))
> (setq N (cons (+ 1 (car N)) N)) ) ) )
>
>(do 32 (prin (hexSpigot)))
>(off *HexSpigot)
>(do 32 (prin (hexSpigot)))
>
> i.e. just call 'off' to reset it :)
>
> ♪♫ Alex
> --
> UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe
>


Re: exercism.io

2017-02-25 Thread Lindsay John Lawrence
There is some very nice code in here.
For me, the 'allbase' function is a particularly nice gem.

/Lindsay


On Fri, Feb 24, 2017 at 8:44 PM, Mike Pechkin 
wrote:

> hi all,
>
> I've implemented tasks from A to F:
> https://bitbucket.org/mihailp/tankfeeder/src/
> 9de46f9e807786fdbf4a86604aca20dd25f0c19e/exercism-io/?at=default
>
> o) dumbest and duplicates from rosettacode ignored
> o) worth to check are Alphametrics and Change
>
> If you want:
> o) pick up one task
> o) set reservation
> o) implement and send your code
> o) repeat
>
> Mike
>
>


Re: Scaled division and sqrt

2017-02-28 Thread Lindsay John Lawrence
allbase   -->  tankfeeder / exercism-io / a-f.l

/Lindsay


On Tue, Feb 28, 2017 at 3:41 AM, Danilo Kordic  wrote:
>> If you are going to use a list, could also just put the 'scale' in a property
>> of the list?
>
>   I wouldn't call it a propert to avoid confusion with PicoLisp `prop'erties.
>
>   I couldn't find `allbase'.
>
>   I had [[https://en.wikipedia.org/wiki/Algebraic_data_type][Algebraic
> DataTypes]]
> in mind, just like fractions.
>
> (= (Float B S E)
>(* S (** B E)) )
>
>
>   ``(314 E -2)'' looks like
> [[https://en.wikipedia.org/wiki/Scientific_notation][Scientific
> notation]].
> And wouldn't cause an error in PicoLisp.
>
>   Current implementation of PicoLisp numbers is also a linked list:
> [path "@doc64/structures"].  Too bad they can not be manipulated like any 
> other
> list.  Base is (** 2 64).
>
>   [[https://en.wikipedia.org/wiki/Quote_notation][Quote notation]]: If we 
> allow
> circular reference in the `Num' structure it will result in a subset of
> rational numbers.  Arithmetic Shift, `AS', will give the rest.
> ``I mean, how hard could it be?  ''
> --
> UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe
-- 
UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe


Self-similar fractal curves on canvas

2017-03-02 Thread Lindsay John Lawrence
I developed this a bit more.

https://github.com/thinknlive/picolisp-gosper

I think now it may be a nice little tool to explore these kinds of functions.

You can step draw the results, or draw all at once.  You can also
modify the lisp function code and then reload the module to try the
changes immediately without restarting the service.

I'll add more over time as I think of it. Perhaps zoom and navigation
buttons, buttons to change the step size and refresh rate from the ui,
etc.

The picolisp ui framework makes this so easy.

/Lindsay


On Wed, Mar 1, 2017 at 4:42 AM, Erik Gustafson
 wrote:
> Hi Lindsay,
>
> I practiced a bit more with the built-in functions...
>
> https://github.com/thinknlive/picolisp-gosper.git
>
>
> Very cool! Looks like you've got '*/' all figured out now :)
>
> Thanks for sharing
>
> - Erik
-- 
UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe


Re: Scaled division and sqrt

2017-03-01 Thread Lindsay John Lawrence
Thanks Eric.

This was also an opportunity to start dabbling a bit with the app ui
framework. Very interesting.

At least initially, it reminds me a bit of the way you could write
PHP... but this feels more elegant.
Even lisp looks less like line noise than php ;)

The javascript canvas pipeline I utilized there is quite powerful.
There is a lot more I can do with it.
For the denser images, the server side code is generating 1M+ points
which are then  piped back to the client (~3Mb) for rendering.

Once I am more familiar with it I'd like to exploit the session state
a bit more to dribble data streams in smaller chunks.

/Lindsay
-- 
UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe


Re: Copy/Clone a 'job

2017-02-26 Thread Lindsay John Lawrence
Thanks for the suggestion Joe.

Other than copy-paste examples, I haven't played much with either #oop and
#dbase in picolisp. It is definitely on my list ;)

I've been trying to get a good understanding of variable scope, state and
lifetime. Especially with functions that have the side-effect of
manipulating globals, or lists, 'destructively'.  Once I have that, I think
the symbol management in picolisp's oop and db facets should be easy enough
to grasp.

My hex digit example was a bit contrived... I was actually working through
this https://rosettacode.org/wiki/Pi#PicoLisp, and after reading the
referenced source at
http://www.cs.ox.ac.uk/jeremy.gibbons/publications/spigot.pdf,  tweaked it
to return the digits in hexadecimal (see code below).

To get off-topic a bit, philosophically

I am a proponent of minimalism in coding and algorithms/tools that make it
easy to generate, manipulate or filter 'streams.

Hence.. picolisp!

https://en.wikipedia.org/wiki/Unix_philosophy: "Write programs that do one
thing and do it well. Write programs to work together. Write programs to
handle text streams, because that is a universal interface."  --- Doug
Mcllroy

I think what Mcllroy could have said there, instead of text streams, was
'symbol lists' ;)

/Lindsay


# From https://rosettacode.org/wiki/Pi#PicoLisp
# But, return the digits in hexadecimal and provide a way to 'reset' the
spigot.

(de makeHexaPi ()
(curry ((Q . 1) (R . 0) (S . 1) (K . 1) (N . 3) (L . 3)) ()
  (while (>= (- (+ R (* 4 Q)) S) (* N S))
 (mapc set '(Q R S K N L)
(list
   (* Q K)
   (* L (+ R (* 2 Q)))
   (* S L)
   (inc K)
   (/ (+ (* Q (+ 2 (* 7 K))) (* R L)) (* S L))
   (+ 2 L) ) ) )
  (prog1 N
 (let M (- (/ (* 16 (+ R (* 3 Q))) S) (* 16 N))
(setq Q (* 16 Q)  R (* 16 (- R (* N S)))  N M) ) ) ) )



: (def 'pi16Digit (makeHexaPi))
-> pi16Digit
: (pack (make (do 8 (link  (hex (pi16Digit))
-> "3243F6A8"
: (pack (make (do 8 (link  (hex (pi16Digit))
-> "885A308D"

: (off pi16Digit)
-> NIL
: (def 'pi16Digit (makeHexaPi))
-> pi16Digit
: (pack (make (do 16 (link  (hex (pi16Digit))
-> "3243F6A8885A308D"



On Sun, Feb 26, 2017 at 4:30 AM, Joe Bogner  wrote:

> Hi Lindsay,
>
> It looks like you are using job primarily to retain the value of N
> between invocations. Is that true? Just curious, why not move the loop
> inside of hexSpigot instead of looping outside of it? Another option
> to consider if you want the behavior of being able to increment the
> hexSpigot at any point - use a pil class
> (http://software-lab.de/doc/ref.html#oop)
>
>
>
> Thanks,
> Joe
>


Re: Scaled division and sqrt

2017-02-27 Thread Lindsay John Lawrence
Hi Danilo,

Ah. I get it. Interesting idea. If you are going to use a list, could also
just put the 'scale' in a property of the list?

When I came across the 'allbase function in Mike Penchkin's code... I
thought of the following...
It would be a bit wasteful of storage, but could represent arbitrarily
sized fixed or floating point numbers in any base as a list, each list atom
being a digit in that base. If you keep the digits ordered (least...most)
significant,  the performance may be quite reasonable as well.

The arithmetic functions to manipulate those 'lists' would be an
interesting exercise in basic concepts... and with picolisp numbers, you
could work with not just bignums, but big number bases. For example..
simple positive addition, base10, might look something like this (code at
end)...

: (num2L 1234)
-> (4 3 2 1)
: (L2Num (num2L 1234))
-> "1234"
: (format (L2Num (num2L 1234)))
-> 1234
: (L+ (num2L 1234) (num2L 654321))
-> (5 5 5 5 5 6)
: (num2L (L+ (num2L 1234) (num2L 654321)))
-> (6 5 5 5 5 5)
: (format (L2Num (L+ (num2L 1234) (num2L 654321
-> 65


/Lindsay

# TODO: Generalize Num2L, L2Num, or add similar functions to accept any
number base and scale.
(de num2L (N)
   (mapcar format (reverse (chop (format N
)

(de L2Num (L)
   (pack (reverse L))
)

# Positive number addition (the easiest one)
(de L+ (L1 L2)
   (let (R NIL  S 0  D 0  C 0)
  (default L1 '(0) L2 '(0))
  (if (> (length L2) (length L1)) (swap 'L1 (swap 'L2 L1)))
  (mapcar
 '((D1 D2)
(setq S
   (+ (or D1 0) (or D2 0) C) )
(until (< S 10)
   (setq S (- S 10))
   (inc 'C) )
(setq R (cons S R)) )
 L1
 L2 )
  (if (> 0 C) (setq R (cons C R)))
  (reverse R)) )


On Mon, Feb 27, 2017 at 8:25 AM, Danilo Kordic 
wrote:

> By constructing base 10 floating point numbers with
> ``[list Significand 'E Exponent]''.
> As if `E' is a binary operator.  Of course that makes no sense in Lisp.
> ``(Decimal Significand Exponent)'' would make sense.
>
> For example:
>   : (sqrt 2)
>   -> (141421356237309505 E -17)
> --
> UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe
>


Re: Scaled division and sqrt

2017-02-27 Thread Lindsay John Lawrence
Hi Alex, Erik,

I definitely took the 'long way around' on this one... and got some good
exercise along the way! =)

Thank you for the detailed explanation. I get it now... although I need a
bit more practice and care in using the functions comfortably.

My initial impetus was to be able to easily, and repeatably, generate long
sequences of digits. Some with repeating patterns. Others not.
Rational and irrational numbers  are one simple way to do that and the
support for arbitrary size numbers in picolisp make it easy to do so.
Hence the examples with sqrt(2) and 1/[prime], etc.

Kind Regards,
/Lindsay


Scaled division and sqrt

2017-02-27 Thread Lindsay John Lawrence
Hi,

Are there scaled (fixed point) versions of division and sqrt in picolisp? I
may have missed them...

In any event I wrote a couple of functions to provide that functionality
that may be useful to others as well. Performance is reasonable.

It is quite nice to be able to be able to do arbitrary precision arithmetic
in this way =)

/Lindsay

Code:

# Scaled fixed point long division. (if necessary, round last digit)
# TODO: Brute force implementation...
#   There is probably a better way to do it.
: (pp '/*)
(de /* (N D S)
   (let (Q NIL  R NIL  Acc NIL  Cnt 0)
  (default S *Scl)
  (setq S (+ 2 S))
  (do S
 (T (>= Cnt S))
 (setq
Q (/ N D)
R (% N D)
Acc (cons Q Acc)
Cnt (inc Cnt)
N R )
 (when (and (gt0 N) (<= N D))
(while (and (gt0 N) (<= N D))
   (setq
  N (* N 10)
  Acc (cons 0 Acc)
  Cnt (inc Cnt) ) )
(pop 'Acc)
(dec 'Cnt) ) )
  (setq R (pop 'Acc))
  (if (<= 5 R)
 (setq Acc (cons (+ 1 (pop 'Acc)) Acc)) )
  (setq Acc (flip Acc))
  (format
 (pack (cons (car Acc) "." (cdr Acc)))
 (- S 2) ) ) )
-> /*

# Scaled fixed point sqrt(); no rounding
# TODO: Converges in 4-7 iterations in tests, 13 is probably overkill
: (pp 'sqrt*)
(de sqrt* (N S)
   (let (P (/ N 2)  M 13)
  (default S *Scl)
  (setq N (* N (** 10 S)))
  (while (ge0 (dec 'M))
 (setq P (/ (+ P (/ N P)) 2)) )
  P ) )
-> sqrt*



Some Tests:

# Arbitrary Fixed Precision Square Root
# Compare: bc.
# also: https://apod.nasa.gov/htmltest/gifcity/sqrt2.1mil
: (scl 64) (format (sqrt* 2.0) *Scl)
-> "1.4142135623730950488016887242096980785696718753769480731766797379"
: (scl 64) (format (sqrt* 0.5) *Scl)
-> "0.7071067811865475244008443621048490392848359376884740365883398689"
: (scl 64) (format (sqrt* 9967.0) *Scl)
-> "99.8348636499294268455686673311236280296661789737252407300182230035"
: (scl 10) (bench (nil (sqrt* 2.0)))
2.027 sec

# Arbitrary Fixed Precision Long Division
# Compare: bc e.g. "scale=64 1/9967"
: (scl 64) (/* 1.0 9967.0)
-> 1003310926055984749673923949031804956355974716564663389184308
: (scl 64) (format (/* 1.0 9967.0) *Scl)
-> "0.0001003310926055984749673923949031804956355974716564663389184308"
: (scl 64) (format (format (/* 1.0 9967.0) *Scl) *Scl)
-> 1003310926055984749673923949031804956355974716564663389184308
: (scl 32) (/* 22.0 7.0)
-> 314285714285714285714285714285714
: (scl 0) (/* 22.0 7.0)
-> 3
: (scl 1) (/* 22.0 7.0)
-> 31
: (scl 8) (/* 22.0 7.0)
-> 314285714
: (scl 32) (/* 1.0 3.0)
-> 
: (scl 32) (/* 10.0 3.0)
-> 3
: (scl 32) (format (/* 1.0 3.0) *Scl)
-> "0."
: (scl 32) (format (/* 10.0 3.0) *Scl)
-> "3."
: (scl 32) (format (/* 0.22 0.7) *Scl)
-> "0.31428571428571428571428571428571"
: (scl 32) (format (/* 9968.0 32.0) *Scl)
-> "311.5000"
: (scl 1) (bench (nil (format (/* 1.0 9967.0) *Scl)))
7.685 sec


Subscribe

2016-08-27 Thread Lindsay John Lawrence



(= code data)

2016-12-27 Thread Lindsay John Lawrence
I've been working my way through the Rosetta code examples as a way to
build fluency in picolisp. This little gem was an epiphany in my
understanding of the equivalence of code and data in lisp.

https://rosettacode.org/wiki/Jump_anywhere#PicoLisp

(de foo (N)
   (prinl "This is 'foo'")
   (printsp N)
   (or (=0 (dec 'N)) (run (cddr foo))) )


/Lindsay
p.s. studying the rosetta code examples has been time well spent.


Fixed-point scaling and lookup tables

2017-04-01 Thread Lindsay John Lawrence
My next little picolisp project...

Picolisp's built-in functions for scaled arithmetic are brilliant once you
understand how they work. Still, it would be great to get more scientific
functions without have to link an external math lib, and get 'real-time'
performance when needed as well.

http://wilsonminesco.com/16bitMathTables/ is a nice write-up (link found on
hacker news) of what you can do with fixed point, scaling and lookup
tables... Also has links to code to generate the tables.

I think the concepts and technique will transfer quite nicely to picolisp.
We'll see...

/Lindsay


Arrays

2017-04-13 Thread Lindsay John Lawrence
The 'lack' of arrays has been a non-issue in picolisp for me so far. I've
been generating and manipulating some pretty substantial bitmaps using
notation like this.

2-D Array:
(setq *Img (make (do Size (link (need Size 0)

Write:
(let (Bit (rand 0 1))
   (for Pt *Plot
  (set (nth *Img (cadr Pt) (car Pt)) Bit)))

Read:
(make
   (for Pt *Plot
  (link (car (nth *Img (cadr Pt) (car Pt))


Being just lists, it is trivial to slice n dice, nest them, embed
additional structures/lists at given data points, serialize, etc..

/Lindsay


Re: L-system rules with PicoLisp

2017-03-03 Thread Lindsay John Lawrence
Hi Alex, Joh-Tob,

A 'co may be exactly what I am looking for in this case.  Thanks!

Generating all the states at once was nice in one sense as I could
immediately scale the view when rendering the results.
Picolisp easily supported lists of ~2M elements on the  4GB, single-core
virtual box I am currently using.

The code below is the recursive Gosper implementation I came up with that
uses very little stack. This version just emits states.
It should be easy to adapt to other L-systems, but doesn't yet have the
state management needed to 'grow' fractal plants.

If you want to "space-fill" (
https://en.wikipedia.org/wiki/Space-filling_curve) your hard drive with a
Gosper, or similar, curve...
This will do it for you ;)

: (out "test.dat" (nil (GosperR 10)))
: (call 'ls "-l")
-rw-r--r-- 1 llawrence llawrence 659108913 Mar  3 14:58 test.dat

Just counting the state changes emitted...

: (bench (nil (GosperR 10)) (msg (text "EmitCount: @1" EmitCount)))
"EmitCount: 659108913"
50.547 sec

: (bench (nil (GosperR 11)) (msg (text "EmitCount: @1" EmitCount)))
"EmitCount: 4613762399"
348.925 sec

Picolisp continues to impress me with its expressiveness and power.

/Lindsay

# ##
# Recursive L-system emitter

(de Plot (L)
   (map '((X) (prin (car X))) L) )

(de Fn (L)
   (let R
  (fish
 atom
 (mapcar
'((X)
   (cond
  ((= X "A") A)
  ((= X "B") B)
  (T X) ) )
L ) )
  R ) )

(de L-Run (L D)
   (cond
  ((>= D MaxDepth) (Plot L))
  (T
 (map
'((X)
   (L-Run (Fn (list (car X))) (inc D)) )
L ) ) ) )

(de GosperR (MaxDepth)
   (let (A (chop "A-B--B+A++AA+B-")
 B (chop "+A-BB--B-A++A+B"))
  (default MaxDepth 2)
  (L-Run A 1) ) )


On Fri, Mar 3, 2017 at 11:04 AM, Alexander Burger 
wrote:

> On Fri, Mar 03, 2017 at 01:39:25PM +0100, Joh-Tob Schäg wrote:
> > I haven't figured out how to do it yet, but I think, in this case, a
> > 'recursive' solution that renders as points are created would use a lot
> > less resources, assuming that processed replacement rules are garbage
> > collected as the stack unwinds and elements are traversed over.
> >
> > ​This sound like a case for 'co ​
>
> Makes sense probably.
>
> ♪♫ Alex
> --
> UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe
>


Re: L-system rules with PicoLisp

2017-03-03 Thread Lindsay John Lawrence
Thanks Alex,
Your explanation was the motivation I needed to attempt the recursive
version...
/Lindsay


> Yes and no. It is correct that the garbage collector does not run at each
> release. Instead, it runs when a new cell is needed and the current heap is
> found to be full.
>
> So garbage collection is indeed "immediate", in that as long as there is
> free
> memory no collection is needed, and if not, the collector runs (typically
> just a
> few milliseconds).
>
> If after a collection still no cells are available, the heap is increased.
> Therefore, if a program slowly allocates more and more memory, it helps
> intially
> to allocate a bigger heap, e.g. (gc 800) or whatever size is needed in the
> long
> run.
>


Re: L-system rules with PicoLisp

2017-03-04 Thread Lindsay John Lawrence
Thanks Alex,
I appreciate the suggestions. As ever, I learn something from them ;)
/Lindsay


On Fri, Mar 3, 2017 at 10:10 PM, Alexander Burger 
wrote:

> Hi Lindsay,
>
> > The code below is the recursive Gosper implementation I came up with that
> > uses very little stack. This version just emits states.
> > ...
> > Picolisp continues to impress me with its expressiveness and power.
>
> As ever, I can't resist to suggest some optimizations :)
>
>
> > (de Plot (L)
> >(map '((X) (prin (car X))) L) )
>
> (mapc prin L) would be enough.
>
>
> > (de Fn (L)
> >(let R
> >   (fish
> >  atom
> >  (mapcar
> > '((X)
> >(cond
> >   ((= X "A") A)
> >   ((= X "B") B)
> >   (T X) ) )
> > L ) )
> >   R ) )
>
> The 'let' is not necessary, as R is never used. And 'fish' is for nested
> structures, a flat list can be handled directly e.g. with 'filter' or
> 'extract'
>
>(extract '((X) (cond ((pair X)) ((=X "A") A) ..)) L)
>
> As 'A' and 'B' are free variables here, 'Fn' should be named differently,
> starting with an underscrore (see doc/ref.html#conv)). You coud try 'lint'
> or
> 'lintAll' to see what it complains.
>
> The PicoLisp naming conventions also recommend upper case first letters for
> locally bound variables. Functions defined globally like 'Plot' or 'Fn'
> should
> better start in lower case.
>
>
> > (de L-Run (L D)
> >(cond
> >   ((>= D MaxDepth) (Plot L))
> >   (T
>
> Here an 'if' is shorter than a 'cond'.
>
> ♪♫ Alex
> --
> UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe
>


Re: Arithmetic Coding

2017-03-09 Thread Lindsay John Lawrence
Hi Alex,

Thank you. The (profile) tool is exactly what was needed here

In the scaling loops, it made more of a difference than I thought  to copy
object properties into local variables.

However, the idx tree change you pointed out is what helped most.

: (prog (setq Msg (make (do (** 2 16) (link (rand (char "A") (char
"Z")) (length Msg))
-> 65536
: (bench (/ (length (ACDC_Compress Msg)) 8))
2.761 sec
-> 38785
: (bench (= Msg (ACDC_Decompress (ACDC_Compress Msg
5.478 sec
-> T

Initially those numbers were larger by a factor of 5

I am sure there is lot more I will find to optimize as a I explore a bit
more.

/Lindsay



# 1Mb list
: (prog (setq Msg (make (do (** 2 20) (link (rand (char "A") (char
"Z")) (length Msg))
-> 1048576
: (bench (= Msg (ACDC_Decompress (ACDC_Compress Msg

73.807 sec
-> T
: (mapc prof ...-> NIL
: (bench (/ (length (ACDC_Compress Msg)) 8))
36.574 sec
-> 616497

: (profile)
(2492 217 computeLower> . +ACDC_BasicModel)
(602 48 emit> . +ACDC_BasicModel)
(137 10 ACDC_Compress)
(129 8 update> . +ACDC_BasicModel)
(0 0 emitEof> . +ACDC_BasicModel)
-> (0 0 emitEof> . +ACDC_BasicModel)


Unexpected behavior

2017-03-11 Thread Lindsay John Lawrence
Hi

I am having difficulty understanding the following..

This works as expected...

: (setq Sum '(1 1 0))
-> (1 1 0)
: (set Sum (+ (cadr Sum) (caddr Sum)))
-> 1
: (rot Sum)
-> (0 1 1)
: (set Sum (+ (cadr Sum) (caddr Sum)))
-> 2
: (rot Sum)
-> (1 2 1)
: (set Sum (+ (cadr Sum) (caddr Sum)))
-> 3
: (rot Sum)
-> (1 3 2)
: (set Sum (+ (cadr Sum) (caddr Sum)))
-> 5
: (rot Sum)
-> (2 5 3)
: (set Sum (+ (cadr Sum) (caddr Sum)))
-> 8
: Sum
-> (8 5 3)

However, when I put it in a function...

(de Fibonacci (N)
   (let (Fib '(1 1 0))
  (do N
 (rot Fib)
 (set Fib (+ (cadr Fib) (caddr Fib))) )
   (car Fib) ) )

The results are something like a 'co routine or 'job... in that Fib as a
memory between calls and it is not re-initialized with the 'let as I
expected.

-> Fibonacci
: (Fibonacci 1)
-> 2
: (Fibonacci 1)
-> 3
: (Fibonacci 1)
-> 5
: (Fibonacci 1)
-> 8
..

The behavior I expected was

: (Fibonacci 3)
-> 5
.

Why?

/Lindsay


Re: Unexpected behavior

2017-03-11 Thread Lindsay John Lawrence
Or strictly speaking...

(de Fibonacci (N)
   (let (Fib '(2 1 1))
  (set Fib 2 (cdr Fib) 1 (cddr Fib) 1)
  (cond
 ((= N 0) 0)
 ((= N 1) (caddr Fib))
 ((= N 2) (cadr Fib))
 (T
(do (- N 3)
   (rot Fib)
   (set Fib (+ (cadr Fib) (caddr Fib)))
)
(car Fib))
 ) ) )

/Lindsay



On Sat, Mar 11, 2017 at 11:20 AM, Lindsay John Lawrence <
lawrence.lindsayj...@gmail.com> wrote:

> Nm... After tinkering in the debugger.. using 'pp etc..
> I get it. I am still getting the  (= code data) in picolisp.
>
> This gives the results I wanted.
>
> (de Fibonacci (N)
>(let (Fib '(1 1 0) R 0)
>   (do N
>  (rot Fib)
>  (set Fib (+ (cadr Fib) (caddr Fib)))
>   )
>   (setq R (car Fib))
>   (set Fib 1 (cdr Fib) 1 (cddr Fib) 0)
>   R
> ) )
>
> Now I can write...
>
> : (Fibonacci 1)
> -> 2
> : (Fibonacci 10)
> -> 144
> : (bench (nil (Fibonacci 10)))
> 3.388 sec
> : (length (chop (Fibonacci 10)))
> -> 20899 digits!
>
> Picolisp bignums are awesome!
>
> /Lindsay
>
>
>


Re: Unexpected behavior

2017-03-11 Thread Lindsay John Lawrence
Nm... After tinkering in the debugger.. using 'pp etc..
I get it. I am still getting the  (= code data) in picolisp.

This gives the results I wanted.

(de Fibonacci (N)
   (let (Fib '(1 1 0) R 0)
  (do N
 (rot Fib)
 (set Fib (+ (cadr Fib) (caddr Fib)))
  )
  (setq R (car Fib))
  (set Fib 1 (cdr Fib) 1 (cddr Fib) 0)
  R
) )

Now I can write...

: (Fibonacci 1)
-> 2
: (Fibonacci 10)
-> 144
: (bench (nil (Fibonacci 10)))
3.388 sec
: (length (chop (Fibonacci 10)))
-> 20899 digits!

Picolisp bignums are awesome!

/Lindsay



On Sat, Mar 11, 2017 at 10:49 AM, Lindsay John Lawrence <
lawrence.lindsayj...@gmail.com> wrote:

> Hi
>
> I am having difficulty understanding the following..
>
> This works as expected...
>
> : (setq Sum '(1 1 0))
> -> (1 1 0)
> : (set Sum (+ (cadr Sum) (caddr Sum)))
> -> 1
> : (rot Sum)
> -> (0 1 1)
> : (set Sum (+ (cadr Sum) (caddr Sum)))
> -> 2
> : (rot Sum)
> -> (1 2 1)
> : (set Sum (+ (cadr Sum) (caddr Sum)))
> -> 3
> : (rot Sum)
> -> (1 3 2)
> : (set Sum (+ (cadr Sum) (caddr Sum)))
> -> 5
> : (rot Sum)
> -> (2 5 3)
> : (set Sum (+ (cadr Sum) (caddr Sum)))
> -> 8
> : Sum
> -> (8 5 3)
>
> However, when I put it in a function...
>
> (de Fibonacci (N)
>(let (Fib '(1 1 0))
>   (do N
>  (rot Fib)
>  (set Fib (+ (cadr Fib) (caddr Fib))) )
>(car Fib) ) )
>
> The results are something like a 'co routine or 'job... in that Fib as a
> memory between calls and it is not re-initialized with the 'let as I
> expected.
>
> -> Fibonacci
> : (Fibonacci 1)
> -> 2
> : (Fibonacci 1)
> -> 3
> : (Fibonacci 1)
> -> 5
> : (Fibonacci 1)
> -> 8
> ...
>
> The behavior I expected was
>
> : (Fibonacci 3)
> -> 5
> ..
>
> Why?
>
> /Lindsay
>
>
>
>
>


Re: Unexpected behavior

2017-03-11 Thread Lindsay John Lawrence
Thanks Alex!

This makes sense to me now...

(de Fibonacci (N)
   (let (F (list 2 1 1))
  (cond
 ((= N 0) 0)
 ((= N 1) (caddr F))
 ((= N 2) (cadr F))
 (T
(do (- N 3)
   (rot F)
   (set F (+ (cadr F) (caddr F))) )
(car F) ) ) ) )

/Lindsay


On Sat, Mar 11, 2017 at 11:35 AM, Alexander Burger <a...@software-lab.de>
wrote:

> On Sat, Mar 11, 2017 at 11:20:21AM -0800, Lindsay John Lawrence wrote:
> > Nm... After tinkering in the debugger.. using 'pp etc..
> > I get it. I am still getting the  (= code data) in picolisp.
>
> Cool! Our mails overlapped! :)
>
> ♪♫ Alex
> --
> UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe
>


Naming conventions...

2017-03-11 Thread Lindsay John Lawrence
'F'->'f' =) Trying to get in the habit to be disciplined with this. It
certainly helps as I write larger and more complex bits of code.


/Lindsay


(de fibonacci (N)
   (let (F (list 2 1 1))
  (cond
 ((= N 0) 0)
 ((= N 1) (caddr F))
 ((= N 2) (cadr F))
 (T
(do (- N 3)
   (rot F)
   (set F (+ (cadr F) (caddr F))) )
(car F) ) ) ) )


>


Re: TC -> Loop Transformation?

2017-03-10 Thread Lindsay John Lawrence
Hi Christopher,

Congratulations on the new baby. You'll have lots of late nights to code
now...or maybe not.

This may give some added insight into what you are trying to accomplish...
https://rosettacode.org/wiki/Jump_anywhere#PicoLisp

The code example there was worth some time to study for me, especially in
consideration of scoping. It may even have been my lisp enlightenment
moment (= code data).

/Lindsay



>


Arithmetic Coding

2017-03-08 Thread Lindsay John Lawrence
As part of getting a handle on OO in picolisp I implemented a basic
arithmetic coder.
This is just the Coder and a simple adaptive model.

https://github.com/thinknlive/picolisp-acdc

It is slower than I expected it to be, but I was focused more on getting
the implementation correct in this pass.

Any optimization suggestions welcome. Maybe not use OO at all and leverage
namespaces.

/Lindsay


Gosper-curve from 'co routine

2017-03-05 Thread Lindsay John Lawrence
Using Picolisp 'co routine to...

Generate Gosper-curve states from L-System rules

: (GosperGen T)  # Reset
-> T
: (do 64 (prin (GosperGen)))
A-B--B+A++AA+B--+A-BB--B-A++A+B--+A-BB--B-A++A+B+A-B--B+A++AA+B--> "-"
: (GosperGen)
-> "+"
: (GosperGen)
-> "+"
: (GosperGen)
-> "A"
..

A depth of 12 generates about 32GB worth of information...

This uses very little stack and is easily generalized for other L-Systems
to generate rules for 'growing'  complex images that can be rendered using
the picolisp canvas drawing lib.

/Lindsay


# A and B mean to move forward
# + means to turn left 60 degrees
# - means to turn right 60 degrees

(de GosperGen (D)
   (if (=T D)
  (co 'gospergen)
  (co 'gospergen
 (let
(A (chop "A-B--B+A++AA+B-")
   B (chop "+A-BB--B-A++A+B")
   _MaxDepth D
   _Plot '((L) (mapc yield L))
   _Fn
   '((X)
  (cond
 ((= X "A") A)
 ((= X "B") B)
 (T (list X)) ) )
   _L-Run
   '((L D)
  (if (>= D _MaxDepth)
 (_Plot L)
 (mapc
'((X) (_L-Run (_Fn X) (inc D)))
L ) ) ) )
(default _MaxDepth 13)
(_L-Run A 1) ) ) ) )


Re: Self-similar fractal curves on canvas

2017-03-02 Thread Lindsay John Lawrence
Thanks for the reminder. I'll add it in.
MIT Lic. No restriction. As-is, no warranty, no liability.

Enjoy.

/Lindsay
Gratitude makes any experience more enjoyable. It doesn't make the journey
any less new, the effort any less real.


On Thu, Mar 2, 2017 at 9:13 AM, Christopher Howard <
christopher.how...@qlfiles.net> wrote:
> Hi, this looks cool and I want to play around with it, but licensing
> information is not clear. Could you please add clear licensing/copying
> terms to the repository (ideally on each source file)?
>


Re: Scaled division and sqrt

2017-02-28 Thread Lindsay John Lawrence
Hi,

I practiced a bit more with the built-in functions...

https://github.com/thinknlive/picolisp-gosper.git

/Lindsay
-- 
UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe


Re: PicoLisp as first language

2017-07-31 Thread Lindsay John Lawrence
Thanks for writing this. I think it is a great start and will help a lot of
other newcomers as well

/Lindsay


On Mon, Jul 31, 2017 at 7:07 AM, Nehal  wrote:

> Dear PicoLisp programmers,
>
> Hi! I am Nehal, a new PicoLisp learner and programmer from India.
>
> I am currently working on making simple, easy to begin with PicoLisp
> Documentation for school students. Usually children are taught Java, C++
> but my objective is to have them started with PicoLisp so that they learn
> programming as well as other core subjects such as Math, Physics with the
> aid of PicoLisp.  Through this experience they not only will have knack on
> several subjects with practical learning but will also hone skills in
> PicoLisp, a virtual machine and language they can befriend for life.
>
> In this light, I recently published an article on picolisp.com. Kindly
> see: https
> 
> ://
> 
> picolisp.com
> 
> /wiki/?
> 
> picolispforpythonandchickenschemeprogrammers
> 
> .
>
> This document is currently having less examples. I would like to have
> something more appended to it.
>
> I will be grateful if you can visit the link and give me feedback.
> Suggestions, extensions are requested and welcome.
>
> Thank you so much.
>
> Regards,
> Nehal
>
> सा विद्या या विमुक्तये
>


Re: (rank)

2017-05-23 Thread Lindsay John Lawrence
Thanks Alex,

My sample code ("ABRA..) is wrong. Sorry about that.
I simplified too much from some other code  I have written that has a lot
of unrelated stuff in it.

However, what about these examples? Similar to those of the documentation:

: (rank 'c '((a . a) (b . b) (d . d)) T)   # ???
-> NIL
: (rank 'd '((a . a) (b . b) (d . d)) T)   # ???
-> NIL

: (rank 'd '((a . a) (b . b) (d . d)))
-> (d . d)
: (rank 'c '((a . a) (b . b) (d . d)))
-> (b . b)

The latter two work as I would expect.
I expected the first two to return '(d . d)

/Lindsay



On Tue, May 23, 2017 at 12:32 PM, Alexander Burger 
wrote:

> Hi Lindsay,
>
> > : (nil (setq *BitsSA (sort (make (map link (chop "ABRAABRACADABRA"))
>
> *BitsSA is a list of lists of characters:
>
>: (more *BitsSA)
>("A")
>("A" "A" "B" "R" "A" "C" "A" "D" "A" "B" "R" "A")
>("A" "B" "R" "A")
>("A" "B" "R" "A" "A" "B" "R" "A" "C" "A" "D" "A" "B" "R" "A")
>...
>
> > : (rank (chop "BR") *BitsSA)
> > -> ("R" "A" "C" "A" "D" "A" "B" "R" "A")
>
> This does not make sense. You search the ranking list with a *list*
> argument
> (chop "BR"), i.e. ("B" "R")
>
> Same here:
>
> > : (rank (chop "BRA") *BitsSA T)# ???
> > -> NIL
>
> So you compare the CARs of *BitsSA - which are characters (i.e. symbols) -
> with
> lists. A list, however, is always greater than a symbol.
>
> >From https://software-lab.de/doc/ref.html#cmp:
>
>For differing types, the following rule applies: Numbers are less than
>symbols, and symbols are less than lists.
>
> ♪♫ Alex
>
> --
> UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe
>


Re: Fixed-point scaling and lookup tables

2017-05-26 Thread Lindsay John Lawrence
>
> For a much faster solution than the idx mechanism, look at this:
> http://www.mail-archive.com/picolisp@software-lab.de/msg05199.html
>
> This is a very interesting idea. Thanks for pointing it out. Is there a
formal name for the algorithm?
For some more general purpose data structures I am working with, it may be
a great solution.

I'll compare it to what I was in the process of doing, which was to have an
'idx something to the effect of (N, nth L N).

However, for the numerical table lookups, if I am going to a shared lib, I
might as well do the ~O(1) lookup in a static array.

/Lindsay


Re: (rank)

2017-05-24 Thread Lindsay John Lawrence
Hi Alex,

Ah. That's what I missed the sort direction of the second argument..

Thank you
Lindsay



On Tue, May 23, 2017 at 10:47 PM, Alexander Burger 
wrote:

> Hi Lindsay,
>
> > My sample code ("ABRA..) is wrong. Sorry about that.
>
> Ah, I see. No problem.
>
>
> > : (rank 'c '((a . a) (b . b) (d . d)) T)   # ???
> > -> NIL
> > : (rank 'd '((a . a) (b . b) (d . d)) T)   # ???
> > -> NIL
> >
> > : (rank 'd '((a . a) (b . b) (d . d)))
> > -> (d . d)
> > : (rank 'c '((a . a) (b . b) (d . d)))
> > -> (b . b)
> >
> > The latter two work as I would expect.
> > I expected the first two to return '(d . d)
>
> The reason here is that 'rank' expects a *sorted* list. It traverses the
> list,
> and stops as soon as it can confirm or refute the desired condition.
>
> With a second argument non-NIL, it tries to "Returns the element from lst
> ...
> with a minimal CAR greater or equal to any". However, already the first
> element
> (a . a) is *less* than 'c' or 'd', hence it returns NIL.
>
> If you reverse the list, it works:
>
>: (rank 'c '((d . d) (b . b) (a . a)) T)
>-> (d . d)
>
>: (rank 'b '((d . d) (b . b) (a . a)) T)
>-> (b . b)
>
> It is the purpose of the second argument to tell 'rank' in which direction
> it
> should expect the list to be sorted.
>
> ♪♫ Alex
>
> --
> UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe
>


Re: Fixed-point scaling and lookup tables

2017-05-25 Thread Lindsay John Lawrence
Hi,

I finally made a start on these tables... (there has been so much other
stuff to explore with picolisp =)

But I think I may have hit a dead-end right away for a 'pure' picolisp
implementation; from the performance benefit point of view. At least for
the two tables I cared most about.. multiplication and division. An idx,
while impressively fast, comes nowhere near native multiplication.

I'll try a table lookup implementation via a shared lib and see what
overhead the function call would add. The time delta may also disappear for
scientific tables (sin, cos, log, etc).

In the meantime I thought I would share the code below for any thoughts or
observations... demonstrates multiplication by table lookup and addition.

This is the only instance I've run into where I have wanted some kind
explicit array in picolisp...  but I wouldn't trade a bit of the current
functionality and performance of the platform for it.

/Lindsay

#2  2
# ab = ( ((a + b)  - (a - b)  ) ) / 4
#
#

(let (A (rand 1 255) B (rand 1 255)) (= (* A B) (>> 2 (- (** (abs (+ A B))
2) (** (abs (- A  B)) 2))) ) )

#
# For a restricted integer number range, using a table of 'squares' / 4
# reduces the multiplication to 3 additions (with two table lookups)
#

(let (A (rand 1 255) B (rand 1 255))(= (* A B) (- (cdr (lup *MULTBL (abs (+
A B (cdr (lup *MULTBL (abs (- A B)) )

# Table of squares/4
(nil (setq *MULT (make (for N (** 2 9) (link (cons N (>> 2 (* N N )) ))
(balance '*MULTBL *MULT)

# Test functions
(de MLup (A B)
  (-
 (cdr (lup *MULTBL (abs (+ A B
 (cdr (lup *MULTBL (abs (- A B ) )

# Multiplication by lookup
(de mult-test2 ()
  (bench
  (do (** 2 20)
(let (
A (rand 1 255)
B (rand 1 255)
A+B (cdr (lup *MULTBL (abs (+ A B
A-B (cdr (lup *MULTBL (abs (- A B ) (- A+B A-B) ) ) ) )

# Built-in multiplication
(de mult-test1 ()
  (bench
  (do (** 2 20)
(let (
A (rand 1 255)
B (rand 1 255) )
(* A B) ) ) ) )

: (mult-test1)
0.392 sec
-> 14151
: (mult-test2)
1.507 sec
-> 2249
: (= (* 13 41) (MLup 13 41))
-> T


2017-04-01 22:45 GMT+02:00 Lindsay John Lawrence <
>> lawrence.lindsayj...@gmail.com>:
>>
>>> My next little picolisp project..
>>>
>>> Picolisp's built-in functions for scaled arithmetic are brilliant once
>>> you understand how they work. Still, it would be great to get more
>>> scientific functions without have to link an external math lib, and get
>>> 'real-time' performance when needed as well.
>>>
>>> http://wilsonminesco.com/16bitMathTables/ is a nice write-up (link
>>> found on hacker news) of what you can do with fixed point, scaling and
>>> lookup tables... Also has links to code to generate the tables.
>>>
>>> I think the concepts and technique will transfer quite nicely to
>>> picolisp.  We'll see...
>>>
>>> /Lindsay
>>>
>>>
>>
>