Re: Questions about EmuLisp

2016-01-03 Thread Alexander Burger
Hi Christophe,

> These are primarily questions for Alex, but I'm interested
> in the answers of other people too.

I'm afraid that I don't have useful answers, but I try ...


> 1) What do you think of EmuLisp?

I like the fact that it is written in JS, but I don't know its
limitations.

> 2) Would you promote it?
> 3) Would you use it on the futur website for the demo REPL?

Personally I prefer server-side application code, as it gives more power
to the application, and also makes development a lot easier. So it is
not an option for me at the moment. On the client I prefer hand-crafted
JS, which doesn't need to be touched during application development.

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


Re: Questions about EmuLisp

2016-01-02 Thread Henrik Sarvell
Hi Christophe.

AFAIK ClojureScript is pretty much feature complete as opposed to Emu,
there's a risk for confusion and perhaps bad PR if an online REPL
based on Emu becomes the de facto way of playing around with PL for
novices, ie "Why can't I do X which the manual seems to imply?!!" or
"This crap sucks, it can't even do Y." when it in fact can do Y.

Some prominent disclaimer should be there, perhaps with information on
what features are not available.

The fact that PL is now apt-get installable makes it trivial to test
out the real thing too.




On Sat, Jan 2, 2016 at 9:40 PM, Christophe Gragnic
 wrote:
> Hi all,
>
> These are primarily questions for Alex, but I'm interested
> in the answers of other people too.
>
> I'm a big fan of PicoLisp even if I only scratched the surface yet,
> since I don't use the server or the DB.
> I know most of the heavy PicoLisp users here rely extensively
> on the server and the DB and wouldn't use Ersatz for real things.
> So bear with me for questions about EmuLisp,
> which is even "weaker" that Ersatz!
>
> 1) What do you think of EmuLisp?
> 2) Would you promote it?
> 3) Would you use it on the futur website for the demo REPL?
> 4) I'm beginning a journey to the understandings of
> Clojure/ClojureScript and would love to see something
> like this for PicoLisp. Does this ring a bell for someone?
>
> For your information, there is now a NodeJS module:
> https://www.npmjs.com/package/emulisp
>
>
> chri
>
> --
>
> http://profgra.org/lycee/ (site pro)
> http://delicious.com/profgraorg (liens, favoris)
> https://twitter.com/profgraorg
> http://microalg.info (langage de programmation pédagogique)
> http://expressions.club/ (structure des expressions mathématiques)
> --
> UNSUBSCRIBE: mailto:picolisp@software-lab.de?subjectUnsubscribe
--
UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe


RE: questions about the gui

2015-11-21 Thread Denis Fourt
Hi,

Joh-Tob, thanks, of course you are right, it is the job of the OS to prevent 
such conflicts, how could I have forgotten that!!! And thanks for pointing the 
c source file.

Alex, thanks for the explanations, as I had not understood that picolisp 
behaved like a web server without the calling app. (app) is an elegant solution 
to the stateless browser problem.

Denis


> From: a...@software-lab.de
> To: picolisp@software-lab.de
> Subject: Re: questions about the gui
> Date: Sat, 21 Nov 2015 12:55:23 +0100
>
> Hi Denis,
>
> in addition to what Joh-Tob said, let me correct some issues about
> 'app'.
>
>> b) I understand that calling the (app) function allows multiple users to 
>> access
>> an application at the same time, which makes web apps and collaborative 
>> software
>> possible
>
> What (app) really does is establishing a "session".
>
> When a client (browser) connects to the server, the server forks a child
> process which sends a response to the request. This is typically a GET
> request, and the child sends a HTML page to the client. At the same
> time, the server parent process continues to listen for further
> requests.
>
> Now, when (app) is NOT called in the child while it generates its
> response (i.e. it sends a static page), then the child process
> terminates.
>
> If, however, (app) is called, the child does not terminate. It allocates
> a new port to listen for further requests from that client, allows
> login, keeps the session's state, and so on.
>
> So multi-user access to the application is also possible without (app),
> but each request will be answered in a fire-and-forget style.
>
>
>> a process listening on different port is created for each user isn't it?
>
> right, this is what is happening.
>
>
>> So how do you avoid conflict when running independent applications?
>
> To have more than one application running on a single machine, you start
> several server parent processes. Each of them will be independently
> listening on its own port. We use 'httpGate' as a port proxy, so that
> from the browser's view the port is always 80 (HTTP) or 443 (HTTPS), but
> is relayed on the server to the right port (and thus server process).
>
>
>> In case of single user desktop apps, not calling (app) and reserving a port
>> seems sufficient. But in case of several users?
>
> So, as you see, (app) has nothing to do with single- or multi-user.
> Also, a single application will need (app) to allow sessions, and this
> in turn has nothing to do with how many users access this application.
>
> ♪♫ Alex
> --
> UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe
  PԔ � &j)mX�����zV�u�.n7�

Re: questions about the gui

2015-11-21 Thread Alexander Burger
Hi Denis,

in addition to what Joh-Tob said, let me correct some issues about
'app'.

> b) I understand that calling the (app) function allows multiple users to 
> access
> an application at the same time, which makes web apps and collaborative 
> software
> possible

What (app) really does is establishing a "session".

When a client (browser) connects to the server, the server forks a child
process which sends a response to the request. This is typically a GET
request, and the child sends a HTML page to the client. At the same
time, the server parent process continues to listen for further
requests.

Now, when (app) is NOT called in the child while it generates its
response (i.e. it sends a static page), then the child process
terminates.

If, however, (app) is called, the child does not terminate. It allocates
a new port to listen for further requests from that client, allows
login, keeps the session's state, and so on.

So multi-user access to the application is also possible without (app),
but each request will be answered in a fire-and-forget style.


> a process listening on different port is created for each user isn't it?

right, this is what is happening.


> So how do you avoid conflict when running independent applications?

To have more than one application running on a single machine, you start
several server parent processes. Each of them will be independently
listening on its own port. We use 'httpGate' as a port proxy, so that
from the browser's view the port is always 80 (HTTP) or 443 (HTTPS), but
is relayed on the server to the right port (and thus server process).


> In case of single user desktop apps, not calling (app) and reserving a port
> seems sufficient. But in case of several users?

So, as you see, (app) has nothing to do with single- or multi-user.
Also, a single application will need (app) to allow sessions, and this
in turn has nothing to do with how many users access this application.

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


Re: questions about the gui

2015-11-21 Thread Joh-Tob Schäg
I assume you fear that a port gets binded to a socket twice.
That can not happen, since unix/linux does not allow two processes to bind
the same process.
(app) calls the pil function (port).
The port function itself is able to find a unused port an binds it. For
more details read (doc 'port)
If you are good with C you might want to look inside net.c and understand
doport.
Picolisp takes care of the ports for you.

2015-11-21 9:36 GMT+01:00 Denis Fourt :

> Yes, this helps, I did not understand that psh was a debugging tool. About
> (app), I still would like to know, if there was a way to run more than one
> application on the same computer and be sure that they would not by
> accident decide to use the same port. I understand that within one app
> there is no problem (as long as there are not too many users), but with two
> or more? Or do my network programming memories need a refresh?
>
> Denis
> 
> > From: johtob...@gmail.com
> > To: picolisp@software-lab.de
> > Subject: Re: questions about the gui
> > Date: Sat, 21 Nov 2015 08:51:43 +0100
> >
> >
> > Hello,
> >
> > It is a local shell that connects to a local webserver.
> > It can be used for webdevelopment, you can expect variables and so on.
> > (app) open a new process with a new port. So each process and each
> > single user linked to it can has a own state. The user can connects to
> > his new port
> > Does it help?
> >
> > Am 21.11.2015 08:28 schrieb "Denis Fourt"
> > mailto:denis.p...@hotmail.com>>:
> > Hello,
> > After reading the gui documentation, I would like some help on the
> > following topics, please :
> > a) I am not sure to understand the purpose and the uses of the psh
> function
>   --
> UNSUBSCRIBE: mailto:picolisp@software-lab.de?subjectUnsubscribe
>


RE: questions about the gui

2015-11-21 Thread Denis Fourt
Yes, this helps, I did not understand that psh was a debugging tool. About 
(app), I still would like to know, if there was a way to run more than one 
application on the same computer and be sure that they would not by accident 
decide to use the same port. I understand that within one app there is no 
problem (as long as there are not too many users), but with two or more? Or do 
my network programming memories need a refresh? 

Denis

> From: johtob...@gmail.com 
> To: picolisp@software-lab.de 
> Subject: Re: questions about the gui 
> Date: Sat, 21 Nov 2015 08:51:43 +0100 
> 
> 
> Hello, 
> 
> It is a local shell that connects to a local webserver. 
> It can be used for webdevelopment, you can expect variables and so on. 
> (app) open a new process with a new port. So each process and each 
> single user linked to it can has a own state. The user can connects to 
> his new port 
> Does it help? 
> 
> Am 21.11.2015 08:28 schrieb "Denis Fourt" 
> mailto:denis.p...@hotmail.com>>: 
> Hello, 
> After reading the gui documentation, I would like some help on the 
> following topics, please : 
> a) I am not sure to understand the purpose and the uses of the psh function 
  --
UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe


Re: questions about the gui

2015-11-20 Thread Joh-Tob Schäg
Hello,

It is a local shell that connects to a local webserver.
It can be used for webdevelopment, you can expect variables and so on.
(app) open a new process with a new port. So each process and each single
user linked to it can has a own state. The user can connects to his new
port.
Does it help?
Am 21.11.2015 08:28 schrieb "Denis Fourt" :

> Hello,
> After reading the gui documentation, I would like some help on the
> following topics, please :
> a) I am not sure to understand the purpose and the uses of the psh function


Re: Questions

2009-05-14 Thread Alexander Burger
Hi Kriangkrai,

> > Only when an object is accessed (value, property list etc.), it is
> > automatically loaded into the Lisp heap as an "external" symbol.
> 
> And once loaded, they can be garbage collected when needed, right?

Yes. The garbage collector knows about external symbols, and handles
them specially. For example, it won't throw away a symbol that is dirty
(not yet committed).


> > The current database files are in a binary format (called "PLIO" for
> > PicoLisp I/O). This is the same format as written and read by the 'pr'
> > and 'rd' functions.
> 
> And try following and have no success (the database file is still in binary).
> 
>(let (rd read pr print)
>   (pool "/tmp/t.db")
>   (set *DB "Hello world") (put *DB 'a 11)
>   (commit) )

True. This will not work, as the low level DB-I/O routines do not really
call 'rd' and 'pr', but some internally hard-coded equivalents. It is
just the format that is the same.

Cheers,
- Alex
-- 
UNSUBSCRIBE: mailto:picol...@software-lab.de?subject=unsubscribe


Re: Questions

2009-05-14 Thread Kriangkrai Soatthiyanont
Hi Alex,

> Only when an object is accessed (value, property list etc.), it is
> automatically loaded into the Lisp heap as an "external" symbol.

And once loaded, they can be garbage collected when needed, right?

> The current database files are in a binary format (called "PLIO" for
> PicoLisp I/O). This is the same format as written and read by the 'pr'
> and 'rd' functions.

And try following and have no success (the database file is still in binary).

   (let (rd read pr print)
  (pool "/tmp/t.db")
  (set *DB "Hello world") (put *DB 'a 11)
  (commit) )

Best regards,
KS
-- 
UNSUBSCRIBE: mailto:picol...@software-lab.de?subject=unsubscribe


Re: Questions

2009-05-13 Thread Alexander Burger
Hi Henrik,

> When you have a database of several hundred GB, have you used the
> ability to split it up? If so why and how, what considerations went
> into the splitting decision?

Yes, split up in several types of application that communicate with each
other, where each application has its own DB (split into several files,
of course). These applications run on a number of blades, each with
multiple CPUs. The two biggest DBs we have at one customer, one with 250
million and one with ore than 300 million primary items. As each item is
represented by about 7 database objects, plus some auxiliary objects and
a lot of indexes, the total number of external symbols at that customer
is around four billion.


> I recall faintly that you had to implement remote database
> functionality at one point (I even think that discussion is in the
> mailing list somewhere). Was that done for this very project which is
> using the big DB?

Yes, this is what triggered that feature. There is a central application
that queries the other DBs.

Cheers,
- Alex
-- 
UNSUBSCRIBE: mailto:picol...@software-lab.de?subject=unsubscribe


Re: Questions

2009-05-13 Thread Henrik Sarvell
When you have a database of several hundred GB, have you used the
ability to split it up? If so why and how, what considerations went
into the splitting decision?

I recall faintly that you had to implement remote database
functionality at one point (I even think that discussion is in the
mailing list somewhere). Was that done for this very project which is
using the big DB?

/Henrik


On Wed, May 13, 2009 at 4:08 PM, Alexander Burger  wro=
te:
> Hi Kriangkrai,
>
>> 1. In FFI, it seems that 'boxCnt()' (not 'box()') must be used to
>> return a correct value, why?
>
> You are free to use both. 'box()' is the lowest level, it puts a pattern
> of 32 bits into a new cell.
>
> =A0 =A0 =A0 =A0 |
> =A0 =A0 =A0 =A0 V
> =A0 =A0 =A0+-+-+
> =A0 =A0 =A0| 32 =A0| =A0/ =A0|
> =A0 =A0 =A0+-+-+
>
> As I wrote in the last mail, the lowest bit in a number is the sign
> bit. 'boxCnt()' takes care of that, shifting the number left and
> inserting that bit.
>
> =A0 static inline any boxCnt(long n) {return box(n>=3D0? =A0n*2 : -n*2+1)=
;}
>
>> =A0 =A0any f1(any ex) {return box(123);} =A0 //=3D> -61 in Lisp
>
> =A061 * 2 -> 122
> =A0plus sign bit -> 123
>
>
>> 2. Is whole database in database files is loaded into memory?
>
> No, this is usually not possible. In the project I'm currently working
> in, the databases have a size of several hundred gigabytes.
>
> Only when an object is accessed (value, property list etc.), it is
> automatically loaded into the Lisp heap as an "external" symbol.
>
>
>> 3. Is it possible to have the database file a text file (not binary),
>> may be a PicoLisp file (like Emacs config file is an Emacs Lisp file)?
>> So that the data can be manually edited by a text editor.
>
> The current database files are in a binary format (called "PLIO" for
> PicoLisp I/O). This is the same format as written and read by the 'pr'
> and 'rd' functions.
>
> A normal text file would be less efficient due to the necessary parsing,
> and theoretically possible, but is currently not implemented.
>
>
>> 4. Could you please explain "hook" in the database library (+Hook and
>> the "hook" arguments)?
>
> A hook is an object which contains object-local indexes.
>
> Normally, all objects in the database are searchable by one ore several
> criteria (name, number, address, other objects etc.). This is done via
> indexes, implemented with B-Trees, which originate in the database root
> object.
>
> But sometimes it is necessary to have indexes relative to some other
> object. Take, for example, a database of suppliers of products. Each
> supplier is an object in the database, having various attributes like
> name, address, telephone etc. Besides that, there are articles (items or
> products) associated with that supplier. Each article has a unique item
> number, but unique perhaps only in the context of that supplier, not
> globally. Thus, the index of article numbers will be local to that
> supplier. Each article has a (+Hook +Link) to the supplier and the item
> number will be hooked to that supplier.
>
> =A0 (rel sup (+Hook +Link) (+Supplier)) =A0# The link to the supplier in =
article
> =A0 (rel nr =A0(+Key +Number) sup) =A0 =A0 =A0 =A0 # The article number, =
hooked to 'sup'
>
> Cheers,
> - Alex
> --
> UNSUBSCRIBE: mailto:picol...@software-lab.de?subject=3dunsubscribe
>
-- 
UNSUBSCRIBE: mailto:picol...@software-lab.de?subject=unsubscribe


Re: Questions

2009-05-13 Thread Alexander Burger
Hi Kriangkrai,

> 1. In FFI, it seems that 'boxCnt()' (not 'box()') must be used to
> return a correct value, why?

You are free to use both. 'box()' is the lowest level, it puts a pattern
of 32 bits into a new cell.

 |
 V
  +-+-+
  | 32  |  /  |
  +-+-+

As I wrote in the last mail, the lowest bit in a number is the sign
bit. 'boxCnt()' takes care of that, shifting the number left and
inserting that bit.

   static inline any boxCnt(long n) {return box(n>=0?  n*2 : -n*2+1);}

>any f1(any ex) {return box(123);}   //=> -61 in Lisp

 61 * 2 -> 122
 plus sign bit -> 123


> 2. Is whole database in database files is loaded into memory?

No, this is usually not possible. In the project I'm currently working
in, the databases have a size of several hundred gigabytes.

Only when an object is accessed (value, property list etc.), it is
automatically loaded into the Lisp heap as an "external" symbol.


> 3. Is it possible to have the database file a text file (not binary),
> may be a PicoLisp file (like Emacs config file is an Emacs Lisp file)?
> So that the data can be manually edited by a text editor.

The current database files are in a binary format (called "PLIO" for
PicoLisp I/O). This is the same format as written and read by the 'pr'
and 'rd' functions.

A normal text file would be less efficient due to the necessary parsing,
and theoretically possible, but is currently not implemented.


> 4. Could you please explain "hook" in the database library (+Hook and
> the "hook" arguments)?

A hook is an object which contains object-local indexes.

Normally, all objects in the database are searchable by one ore several
criteria (name, number, address, other objects etc.). This is done via
indexes, implemented with B-Trees, which originate in the database root
object.

But sometimes it is necessary to have indexes relative to some other
object. Take, for example, a database of suppliers of products. Each
supplier is an object in the database, having various attributes like
name, address, telephone etc. Besides that, there are articles (items or
products) associated with that supplier. Each article has a unique item
number, but unique perhaps only in the context of that supplier, not
globally. Thus, the index of article numbers will be local to that
supplier. Each article has a (+Hook +Link) to the supplier and the item
number will be hooked to that supplier.

   (rel sup (+Hook +Link) (+Supplier))  # The link to the supplier in article
   (rel nr  (+Key +Number) sup) # The article number, hooked to 'sup'

Cheers,
- Alex
-- 
UNSUBSCRIBE: mailto:picol...@software-lab.de?subject=unsubscribe


Re: Questions

2009-05-13 Thread Henrik Sarvell
Hi Kriangkrai,

I can't remember the wording in the documentation for (pool), if it
loads all in to memory, I think so though. You can split databases
into numbered files if they're big, how that is done should be covered
too in the documentation, (tutorial or refrence).

When it comes to general database manipulation, I've written some
stuff here: http://www.prodevtips.com/2008/04/23/simple-oodb-in-pico-lisp/

It has not been reviewed by Alex so there might be better or more
efficient ways to do these things, the code works though.

/Henrik


On Wed, May 13, 2009 at 2:42 PM, Tomas Hlavaty  wrote:
> Hi Kriangkrai,
>
>> 1. What is the purpose of the ".ffi.fn" files?
>
> the FFI generator works with miniPicoLisp which runs as 64 bit app so
> I did not need to install any 32 bit libraries... =A0.ffi.fn files
> contain symbol table which is included in the tab.c file. =A0It should
> work with normal picolisp after some modifications regarding how it is
> compiled and linked. =A0I have somewhere a bit improved version for
> normal picolisp but haven't got around to polishing it well enough to
> publish it.
>
>> 2. After running ".ffi" to generate files, how should I build it so
>> that the functions can be called in PicoLisp? Do you have a sample
>> Make file?
>
> It is all in the mplisp.tar.gz file. =A0It is miniPicoLisp though.
>
>> 3. For the type 'double', I see that you use box()/unBox() instead
>> of doubleToNum()/numToDouble(), why, any differences? That make me
>> has another question, what more functions that
>> doubleToNum()/numToDouble() do, as PicoLisp fixed-point is just a
>> (big) integer?
>
> miniPicoLisp is missing some macros that are in picolisp2 but it
> should work anyway as there are only integers in both versions.
>
>> By the way, http://logand.com/sw/mplisp.tar.gz do not exist (404).
>
> Oops, fixed, thank you!
>
> Cheers,
>
> Tomas
> --
> UNSUBSCRIBE: mailto:picol...@software-lab.de?subject=3dunsubscribe
>
-- 
UNSUBSCRIBE: mailto:picol...@software-lab.de?subject=unsubscribe


Re: Questions

2009-05-13 Thread Tomas Hlavaty
Hi Kriangkrai,

> 1. What is the purpose of the ".ffi.fn" files?

the FFI generator works with miniPicoLisp which runs as 64 bit app so
I did not need to install any 32 bit libraries...  .ffi.fn files
contain symbol table which is included in the tab.c file.  It should
work with normal picolisp after some modifications regarding how it is
compiled and linked.  I have somewhere a bit improved version for
normal picolisp but haven't got around to polishing it well enough to
publish it.

> 2. After running ".ffi" to generate files, how should I build it so
> that the functions can be called in PicoLisp? Do you have a sample
> Make file?

It is all in the mplisp.tar.gz file.  It is miniPicoLisp though.

> 3. For the type 'double', I see that you use box()/unBox() instead
> of doubleToNum()/numToDouble(), why, any differences? That make me
> has another question, what more functions that
> doubleToNum()/numToDouble() do, as PicoLisp fixed-point is just a
> (big) integer?

miniPicoLisp is missing some macros that are in picolisp2 but it
should work anyway as there are only integers in both versions.

> By the way, http://logand.com/sw/mplisp.tar.gz do not exist (404).

Oops, fixed, thank you!

Cheers,

Tomas
-- 
UNSUBSCRIBE: mailto:picol...@software-lab.de?subject=unsubscribe


Re: Questions

2009-05-13 Thread Kriangkrai Soatthiyanont
Hi Tomas,

> you can find a prototype ffi generator at
> http://logand.com/mplisp/src/mod/ It should be fairly straitforward to
> understand how different types get converted between picolisp and C,
> e.g. =A0http://logand.com/mplisp/src/mod/ffi.l is the ffi generator and
> http://logand.com/mplisp/src/mod/gl.ffi is sample ffi binding for
> OpenGL.

Thanks a lot for this. I have questions:

1. What is the purpose of the ".ffi.fn" files?

2. After running ".ffi" to generate files, how should I build it so
that the functions can be called in PicoLisp? Do you have a sample
Make file?

3. For the type 'double', I see that you use box()/unBox() instead of
doubleToNum()/numToDouble(), why, any differences? That make me has
another question, what more functions that doubleToNum()/numToDouble()
do, as PicoLisp fixed-point is just a (big) integer?

By the way, http://logand.com/sw/mplisp.tar.gz do not exist (404).

Best regards,
KS
-- 
UNSUBSCRIBE: mailto:picol...@software-lab.de?subject=unsubscribe


Re: Questions

2009-05-13 Thread Kriangkrai Soatthiyanont
Hi Alex,

More questions ;-)

1. In FFI, it seems that 'boxCnt()' (not 'box()') must be used to
return a correct value, why? When 'box()' should be used instead to
return a value? (I see many places in C source that use box() when
returning a value.) Which one should be used to return a
pointer/address?

   any f1(any ex) {return box(123);}   //=> -61 in Lisp
   any f2(any ex) {return boxCnt(123);}   //=> 123 in Lisp

2. Is whole database in database files is loaded into memory?

3. Is it possible to have the database file a text file (not binary),
may be a PicoLisp file (like Emacs config file is an Emacs Lisp file)?
So that the data can be manually edited by a text editor.

4. Could you please explain "hook" in the database library (+Hook and
the "hook" arguments)?

Best regards,
KS
-- 
UNSUBSCRIBE: mailto:picol...@software-lab.de?subject=unsubscribe


Re: Questions

2009-05-12 Thread Tomas Hlavaty
Hi Kriangkrai,

> Because with (@ attr1 val1 ...), you can retrive the attributes by
> just using (assoc '@ sxml).
> Is there any advantage of using your syntax @attr1 val1 ...?

advantage is that you don't have to put the attributes in a list
manually, your 'with-xml' function can do that for you;-)

>> Also, if you don't manage to hook your error handler to define the
>> tag functions "on-the-fly", you can always traverse the tree
>> argument of 'with-xml' and replace (or define) the tag symbols with
>> your generic tag function and then eval the whole tree.
>
> Good idea. Thanks :-)

On the other hand, 'with-xml' will then waste lot's of time traversing
all those trees (unless you get somehow clever, memoize the "replaced"
tree) so I would recommend to use @lib/xhtml.l if you use 'built-in'
html components or @lib/xml.l if your xml tags can be anything.  With
your original approach, there is still danger Henrik emphasized, that
you can "overshadow" existing functions.  The libraries above do not
have this problem.

Cheers,

Tomas
-- 
UNSUBSCRIBE: mailto:picol...@software-lab.de?subject=unsubscribe


Re: Questions

2009-05-12 Thread Tomas Hlavaty
Hi Kriangkrai,

> A tutorial on PicoLisp FFI would be great; with that, PicoLisp would
> have no shortage of libraries! ;-)

not exactly a tutorial, but I have looked into this a while ago and
you can find a prototype ffi generator at
http://logand.com/mplisp/src/mod/ It should be fairly straitforward to
understand how different types get converted between picolisp and C,
e.g.  http://logand.com/mplisp/src/mod/ffi.l is the ffi generator and
http://logand.com/mplisp/src/mod/gl.ffi is sample ffi binding for
OpenGL.

Cheers,

Tomas
-- 
UNSUBSCRIBE: mailto:picol...@software-lab.de?subject=unsubscribe


Re: Questions

2009-05-12 Thread Alexander Burger
Hi Kriangkrai,

> Ah, Thanks. Could you please explain how a "double" value is encoded
> in "cell"? I could not "decipher" doubleToNum() and numToDouble() in
> big.c!

As PicoLisp only handles scaled fixed point numbers, the "double" is
encoded as a number, with the additional scale passed to the functions.
In general, a number is encoded in cells as

 Number
 |
 V
  +-+-+ +-+-+ +-+-+
  |'DIG'|  ---+---> |'DIG'|  ---+---> |'DIG'|  /  |
  +-+-+ +-+-+ +-+-+

where each digig 'DIG' holds 32 bits of information (in the 64 bit
version, there are also 60 bit short numbers, and the bignum cells
naturally hold 64 bits). The sign is in the lowest bit of the first
digit.

So what numToDouble() does is: Take that number, scale and add up all
the digits, and finally set the sign. doubleToNum() does the opposite,
by fitting a (sufficiently large) double number into the above cell
structure.


>: *Scl
>-> 0
>: (let *Scl 2 1.23)
>-> 1
> Is this because 1.23 is "parsed" when *Scl is still 0, right?

Correct. '*Scl' only applies to input (the "reader"). It is usually set
globally, at the beginning of an application, e.g. with (setq *Scl 2).
In general, it is not so very useful and important, as the I/O format
will always depend on the local context.


> Is there a better way than using:
>: (let *Scl 2 (format "1.23" *Scl))

Probably not. Typically, such cases will not use the global '*Scl', but
some value from the database or some other context.

For example, the numeric input fields in "lib/form.l" each have their
own local scale. The other parameters to 'format' (the decimal and
thousands delimiter) are usually taken from the current locale.


> 1. What does 'mis>' stand for?

In the sense of negation (as in "misfit" or "misfortune"). This message
is sent to relation objects to check if a given value will fit. If not,
the GUI issues an error message. Most of these methods are defined in
"lib/db.l".


> 2. Why a "reverse" association list (instead of a normal association
> list) is used for the "property list"?
>: (putl 'X '((10 . a) (20 . b))) (show 'X)

This has advantages if you access these cells directly, with 'prop'
or '::'. While

   : (get 'X 'a)
   -> 10

will give the value,

   : (prop 'X 'a)
   -> (10 . a)

returns the whole cell. This can be used with all functions that accept
a 'var' argument (a 'var' is either a symbol or a cell):

   : (inc (prop 'X 'a))
   -> 11
   : (get 'X 'a)
   -> 11


> Thanks for your time answering my questions.

No problem :-)

Cheers,
- Alex
-- 
UNSUBSCRIBE: mailto:picol...@software-lab.de?subject=unsubscribe


Re: Questions

2009-05-11 Thread Kriangkrai Soatthiyanont
Hi Alex,

> Please take a look in "src/ext.c". There is, for example, 'ext:Sin',
> that interfaces to scaled integers:
>
> =A0 : (ext:Sin 314159 10)
> =A0 -> 0
> =A0 : (ext:Cos 314159 10)
> =A0 -> -10

Ah, Thanks. Could you please explain how a "double" value is encoded
in "cell"? I could not "decipher" doubleToNum() and numToDouble() in
big.c!

A tutorial on PicoLisp FFI would be great; with that, PicoLisp would
have no shortage of libraries! ;-)


> If you set '*Scl', you can make it a little more readable:
>
> =A0 : (setq *Scl 5)
> =A0 -> 5
>
> =A0 : (ext:Cos 3.14159 1.0)
> =A0 -> -10
> =A0 : (ext:Sin 0.5 1.0)
> =A0 -> 47943
>
> =A0 : (format (ext:Cos 3.14159 1.0) *Scl)
> =A0 -> "-1.0"
> =A0 : (format (ext:Sin 0.5 1.0) *Scl)
> =A0 -> "0.47943"

By the way, is the result of following code expected?
   : *Scl
   -> 0
   : (let *Scl 2 1.23)
   -> 1
Is this because 1.23 is "parsed" when *Scl is still 0, right? Is there
a better way than using:
   : (let *Scl 2 (format "1.23" *Scl))
   -> 123


More questions ;-)

1. What does 'mis>' stand for?

2. Why a "reverse" association list (instead of a normal association
list) is used for the "property list"?
   : (putl 'X '((10 . a) (20 . b))) (show 'X)
   X NIL
  b 20
  a 10
   -> X

Thanks for your time answering my questions.

Best regards,
KS
-- 
UNSUBSCRIBE: mailto:picol...@software-lab.de?subject=unsubscribe


Re: Questions

2009-05-11 Thread Kriangkrai Soatthiyanont
Hi Tomas,

>> =A0 =A0(with-xml
>> =A0 =A0 =A0 (> =A0 =A0 =A0 =A0 =A0"text"
>> =A0 =A0 =A0 =A0 =A0(> =A0 =A0 =A0 =A0 =A0"text" ))
>
> If you go this route, why not something like:
>
> (with-xml
> =A0 ( =A0 =A0 =A0"text"
> =A0 =A0 =A0( =A0 =A0 =A0"text" ) )

Because with (@ attr1 val1 ...), you can retrive the attributes by
just using (assoc '@ sxml).
Is there any advantage of using your syntax @attr1 val1 ...?

> Also, if you don't manage to hook your error handler to define the tag
> functions "on-the-fly", you can always traverse the tree argument of
> 'with-xml' and replace (or define) the tag symbols with your generic
> tag function and then eval the whole tree.

Good idea. Thanks :-)

Best regards,
KS
-- 
UNSUBSCRIBE: mailto:picol...@software-lab.de?subject=unsubscribe


Re: Questions

2009-05-11 Thread Tomas Hlavaty
Hi Kriangkrai,

>(with-xml
>   (  "text"
>  (  "text" ))

If you go this route, why not something like:

(with-xml
   (mailto:picol...@software-lab.de?subject=unsubscribe


Re: Questions

2009-05-11 Thread Alexander Burger
Hi Kriangkrai,

> > Also, floating point calculations are better done separately (there are C 
> > functions for that)
> 
> Do you mean using FFI, i.e. calling C functions from Lisp? If so, how?
> Could you give me an example for calling C's "double sin(double x)" in
> .

Please take a look in "src/ext.c". There is, for example, 'ext:Sin',
that interfaces to scaled integers:

   : (ext:Sin 314159 10)
   -> 0
   : (ext:Cos 314159 10)
   -> -10


If you set '*Scl', you can make it a little more readable:

   : (setq *Scl 5)
   -> 5

   : (ext:Cos 3.14159 1.0)
   -> -10
   : (ext:Sin 0.5 1.0)
   -> 47943

   : (format (ext:Cos 3.14159 1.0) *Scl)
   -> "-1.0"
   : (format (ext:Sin 0.5 1.0) *Scl)
   -> "0.47943"

Cheers,
- Alex
-- 
UNSUBSCRIBE: mailto:picol...@software-lab.de?subject=unsubscribe


Re: Questions

2009-05-11 Thread Kriangkrai Soatthiyanont
Hi Alex,

> As I said, not without modification of the low-level error handler.
> Execution is not continued after the error is caught, as the 'catch' is
> in 'mydefs' and not on the lowest level.
>
> Why would you need that?

It will enable code like this:

   (with-xml
  ( Also, floating point calculations are better done separately (there are C 
> functions for that)

Do you mean using FFI, i.e. calling C functions from Lisp? If so, how?
Could you give me an example for calling C's "double sin(double x)" in
.


Best regards,
KS
-- 
UNSUBSCRIBE: mailto:picol...@software-lab.de?subject=unsubscribe


Re: Questions

2009-05-11 Thread Alexander Burger
Hi Kriangkrai,

> Is there a way, to make the code below works, the first time 'foo' is defined?
> : foo
> -> NIL
> : (mydefs (+ 1 (foo 3 4)))   # should returns 20

As I said, not without modification of the low-level error handler.
Execution is not continued after the error is caught, as the 'catch' is
in 'mydefs' and not on the lowest level.

Why would you need that? If you want a mechanism just to load a certain
set of functions on the fly (like those with a colon for the built-in
dlopen/dlsym mechanism), you could do something like:

In a file "foo.l":

   (de foo (X Y)
  (+ X (* Y Y)) )

and then define those functions like

   (de on-the-fly (@Fun @File)
  (def @Fun
 (curry (@Fun @File) @
(undef '@Fun)
(load @File)
(pass @Fun) ) ) )

   (on-the-fly 'foo "foo.l")
   (on-the-fly 'bar "bar.l")

then, 'foo' looks initially like

   : foo
   -> (@ (undef 'foo) (load "foo.l") (pass foo))

Now if you execute it

   : (foo 3 4)
   -> 19

it will be redefined

   : foo  
   -> ((X Y) (+ X (* Y Y)))



> Is PicoLisp64 just a 64-bit version of PicoLisp? Or it will have
> more/different features? (I would request floating-point support ;-)

It will be (I hope) totally compatible. Floating point support is not an
option (perhaps you might want to look in the archive of this list, we
had a discussion about that). The additional tag bit received by the
extension to 64 bits is better used for a short integer, and doing
otherwise would break some fundamental assumptions. Also, floating point
calculations are better done separately (there are C functions for that)
or - recommended - in scaled fixpoint arithmetics (a good example for
that is the flight simulator).

Cheers,
- Alex
-- 
UNSUBSCRIBE: mailto:picol...@software-lab.de?subject=unsubscribe


Re: Questions

2009-05-10 Thread Kriangkrai Soatthiyanont
Hi Alex,

>> OK. Can the "Undefined error handling" be defined/extended/overridden
>> at Lisp (not C) level? Something like Ruby's const_missing() and
>> method_missing()?
>
> You can achieve something similar by catching the error, and then
> defining the function on the fly. For example
>
>(put 'foo 'mydef '((X Y) (+ X (* Y Y
>
>(de mydefs Prg
>   (let Res (catch '("Undefined") (run Prg 1))
>  (nond
> ((== Res "Undefined") Res)
> ((get (car ^) 'mydef)
>(quit Res (car ^)) )
> (NIL
>(def (car ^) @)
>(eval ^ 1) ) ) ) )
>
> If you call it as
>
>: foo # 'foo' is undefined
>-> NIL
>: (mydefs (foo 3 4))  # Call it
>-> 19
>: foo # Now 'foo' is defined
>-> ((X Y) (+ X (* Y Y)))
>: (mydefs (+ 1 2 3))  # Call something else
>-> 6
>: (mydefs (bar 3 4))  # 'bar' has not 'mydef'
>bar -- Undefined
>?
>
> But, as I said, this is not so general, as the execution of a program
> will not be directly continued.

Is there a way, to make the code below works, the first time 'foo' is defined?
: foo
-> NIL
: (mydefs (+ 1 (foo 3 4)))   # should returns 20


> If you change the example in "project.l" so that you pass an expression
> to 'noButton'. Pressing "No" then will close both the alert and the
> parent dialog:
>
> 21c21
> <  (noButton) ) )
> ---
>>  (noButton '(act> (: home top 1 gui 3))) ) )
>
> (the 3 is there because the 'cancelButton' is the third GUI component in
> the dialog)

That works, thanks.


>> OK. By the way, is there a "reference-style" documentation for GUI
>> (e.g. +gui, +Chart) and Database (e.g. +Entity, +Relation), something
>
> Oh, I'm sorry. That's on my todo list (and also the debugging and Pilog
> functions) since a long time. I try currently to invest all my spare
> time in PicoLisp64, and even for that I don't find enough time :-(
>

It's good that it is on your todo list, so we (PicoLisp users) can use
PicoLisp at its full power!
Is PicoLisp64 just a 64-bit version of PicoLisp? Or it will have
more/different features? (I would request floating-point support ;-)


Best regards,
KS
-- 
UNSUBSCRIBE: mailto:picol...@software-lab.de?subject=unsubscribe


Re: Questions

2009-05-10 Thread Alexander Burger
Hi Kriangkrai,

> OK. Can the "Undefined error handling" be defined/extended/overridden
> at Lisp (not C) level? Something like Ruby's const_missing() and
> method_missing()?

I don't know Ruby, but probably not, because there is no hook at the
lowest level in the interpreter.

You can achieve something similar by catching the error, and then
defining the function on the fly. For example

   (put 'foo 'mydef '((X Y) (+ X (* Y Y

   (de mydefs Prg
  (let Res (catch '("Undefined") (run Prg 1))
 (nond
((== Res "Undefined") Res)
((get (car ^) 'mydef)
   (quit Res (car ^)) )
(NIL
   (def (car ^) @)
   (eval ^ 1) ) ) ) )

(you need the current testing version of PicoLisp if you want to try it.
I found that the variable '^' (see doc/ref_.html#^) was not correctly set
in the error catching routine)

If you call it as

   : foo # 'foo' is undefined
   -> NIL
   : (mydefs (foo 3 4))  # Call it
   -> 19
   : foo # Now 'foo' is defined
   -> ((X Y) (+ X (* Y Y)))
   : (mydefs (+ 1 2 3))  # Call something else
   -> 6
   : (mydefs (bar 3 4))  # 'bar' has not 'mydef'
   bar -- Undefined
   ?  

But, as I said, this is not so general, as the execution of a program
will not be directly continued.


> OK. But it will close only the "alert" (the enclosing "form" of the
> button), not the "dialog" (parent "form" of the alert). To close the
> dialog, the user must press the cancel button, after the alert was
> closed.

Yes, that's correct.

> Isn't (dispose (: home top 1)) trying to close the "dialog"?
> Is it possible to do so?

Yes, but because 'dispose' does not exist any more, you cannot do it
directly. What works, for example, is to send an action message 'act>'
to the close button (or any other button) of the parent dialog:

If you change the example in "project.l" so that you pass an expression
to 'noButton'. Pressing "No" then will close both the alert and the
parent dialog:

21c21
<  (noButton) ) )
---
>  (noButton '(act> (: home top 1 gui 3))) ) )

(the 3 is there because the 'cancelButton' is the third GUI component in
the dialog)

BTW, it is always the case that when a lower-level dialog or alert is
closed, all dialogs/alerts above it (i.e. children of that dialog) are
closed.


> OK. By the way, is there a "reference-style" documentation for GUI
> (e.g. +gui, +Chart) and Database (e.g. +Entity, +Relation), something

Oh, I'm sorry. That's on my todo list (and also the debugging and Pilog
functions) since a long time. I try currently to invest all my spare
time in PicoLisp64, and even for that I don't find enough time :-(

Cheers,
- Alex
-- 
UNSUBSCRIBE: mailto:picol...@software-lab.de?subject=unsubscribe


Re: Questions

2009-05-09 Thread Kriangkrai Soatthiyanont
Hi Alex,

>> 1. What is the purpose of calling (wait) after (server 8080 "...")? It
>> will "wait" for what? What is the differences if (wait) is not called?
>
> In this case (when called without any arguments), 'wait' will wait for
> an infinite time (see also "doc/refW.html#wait"). The purpose is to
> inhibit PicoLisp from dropping into a read-eval loop when 'server'
> received a connect. This is opposed to debugging mode where you don't
> call that 'wait', and instead want to debug the GUI session.

OK. Thanks.

>> 2. Could you explain how does "ht:" magic work?
>>: ht:Prin
>>-> NIL
>>: (ht:Prin "xxx")
>>xxx-> T
>
> 'ht:Prin' is a normal symbol and thus has a value of NIL initially. If
> such a symbol is called as a function, it would usually cause an error:
>
>: abc
>-> NIL
>: (abc "xxx")
>!? (abc "xxx")
>abc -- Undefined
>
> However, when the "Undefined" error handling routine of PicoLisp detects
> that the name of that undefined symbol contains a colon, it tries to
> locate a shared object library (DLL) with the name before the colon
> (here 'ht'), and searches for a symbol with the name after the colon
> (here 'Prin'). If it finds such a symbol, it "defines" the Lisp symbol
> 'ht:Prin' so that from now on it is just like any other function written
> in C:
>
>: ht:Prin
>-> NIL   # Not defined
>: (ht:Prin "xxx")# Calling it
>xxx-> T
>: ht:Prin
>-> 1540706488# Now it is defined
>
>
>>: (ht:abc)
>>ht:abc -- /usr/local/picoLisp/lib/ht: undefined symbol: abc
>
> So this failed, as the 'ht' library does not contain 'abc'.

OK. Can the "Undefined error handling" be defined/extended/overridden
at Lisp (not C) level? Something like Ruby's const_missing() and
method_missing()?

>> 3. In the "Alerts and Dialogs" example in doc/app.html, there is a
>> call (dispose (: home top 1))
>
> Oops, you found an error in the documentation! The function 'dispose'
> does not exist any more. It is now implicit in the 'yesButton'. So the
> example should look like:
>
>'(alert NIL "Are you sure? "
>   (yesButton
>  '(set> (: home top 2 gui 1)
> (val> (: home top 1 gui 1)) ) )
>   (noButton) ) )
>
> I fixed it, and uploaded a corrected version to the testing release.
>
>
>> which is meant to remove enclosing form
>> (right?), but the problem is that 'dispose' does not exist!
>
> To be precise, it is meant to remove the dialog from above the form. On
> a page, there may be any numbers of forms, and above these forms may be
> any number of "pop up" dialogs. These dialogs usually have some buttons
> like "close", "yes", "no" etc. which may or may not close them.
>
> Instead of the 'dispose' function, dialogs are now closes by the
> '+Close' prefix class to those buttons. For example, the 'yesButton'
> looks like:
>
>(de yesButton (Exe)
>   (gui '(+Close +Button) ',"Yes" Exe) )
>
> i.e. it creates a button which inherits the close behavior from
> '+Close', and which is labelled "Yes". When that button is pressed, the
> expression 'Exe' is executed (the (set> ...)) above, and the dialog (or
> alert) is closed.

OK. But it will close only the "alert" (the enclosing "form" of the
button), not the "dialog" (parent "form" of the alert). To close the
dialog, the user must press the cancel button, after the alert was
closed. Isn't (dispose (: home top 1)) trying to close the "dialog"?
Is it possible to do so?

>> 4. What is 'Dn' in (dm set> (Val Dn) ...)? For what?
>
> This is an internal parameter to the 'set>' method of GUI components. It
> is not used on the application level. IIRC, it means "down", and is used
> in "charts" (two-dimensional tables of GUI components) to avoid infinite
> recursion when setting the values of those components. This is because
> setting the value of such a components will trigger the setting of the
> value of the whole chart, and setting the value of a chart will trigger
> the setting of the values of its individual components.

OK. By the way, is there a "reference-style" documentation for GUI
(e.g. +gui, +Chart) and Database (e.g. +Entity, +Relation), something
like the useful "Pico Lisp Reference" (ref.html)? The source code has
"sparse" comments, if any! ;-)

Best regards,
KS
-- 
UNSUBSCRIBE: mailto:picol...@software-lab.de?subject=unsubscribe


Re: Questions

2009-05-09 Thread Alexander Burger
Hi Kriangkrai,

> 1. What is the purpose of calling (wait) after (server 8080 "...")? It
> will "wait" for what? What is the differences if (wait) is not called?

In this case (when called without any arguments), 'wait' will wait for
an infinite time (see also "doc/refW.html#wait"). The purpose is to
inhibit PicoLisp from dropping into a read-eval loop when 'server'
received a connect. This is opposed to debugging mode where you don't
call that 'wait', and instead want to debug the GUI session.


> 2. Could you explain how does "ht:" magic work?
>: ht:Prin
>-> NIL
>: (ht:Prin "xxx")
>xxx-> T

'ht:Prin' is a normal symbol and thus has a value of NIL initially. If
such a symbol is called as a function, it would usually cause an error:

   : abc
   -> NIL
   : (abc "xxx")
   !? (abc "xxx")
   abc -- Undefined

However, when the "Undefined" error handling routine of PicoLisp detects
that the name of that undefined symbol contains a colon, it tries to
locate a shared object library (DLL) with the name before the colon
(here 'ht'), and searches for a symbol with the name after the colon
(here 'Prin'). If it finds such a symbol, it "defines" the Lisp symbol
'ht:Prin' so that from now on it is just like any other function written
in C:

   : ht:Prin
   -> NIL   # Not defined
   : (ht:Prin "xxx")# Calling it
   xxx-> T
   : ht:Prin
   -> 1540706488# Now it is defined


>: (ht:abc)
>ht:abc -- /usr/local/picoLisp/lib/ht: undefined symbol: abc

So this failed, as the 'ht' library does not contain 'abc'.


> 3. In the "Alerts and Dialogs" example in doc/app.html, there is a
> call (dispose (: home top 1))

Oops, you found an error in the documentation! The function 'dispose'
does not exist any more. It is now implicit in the 'yesButton'. So the
example should look like:

   '(alert NIL "Are you sure? "
  (yesButton
 '(set> (: home top 2 gui 1)
(val> (: home top 1 gui 1)) ) )
  (noButton) ) )

I fixed it, and uploaded a corrected version to the testing release.


> which is meant to remove enclosing form
> (right?), but the problem is that 'dispose' does not exist!

To be precise, it is meant to remove the dialog from above the form. On
a page, there may be any numbers of forms, and above these forms may be
any number of "pop up" dialogs. These dialogs usually have some buttons
like "close", "yes", "no" etc. which may or may not close them.

Instead of the 'dispose' function, dialogs are now closes by the
'+Close' prefix class to those buttons. For example, the 'yesButton'
looks like:

   (de yesButton (Exe)
  (gui '(+Close +Button) ',"Yes" Exe) )

i.e. it creates a button which inherits the close behavior from
'+Close', and which is labelled "Yes". When that button is pressed, the
expression 'Exe' is executed (the (set> ...)) above, and the dialog (or
alert) is closed.


> 4. What is 'Dn' in (dm set> (Val Dn) ...)? For what?

This is an internal parameter to the 'set>' method of GUI components. It
is not used on the application level. IIRC, it means "down", and is used
in "charts" (two-dimensional tables of GUI components) to avoid infinite
recursion when setting the values of those components. This is because
setting the value of such a components will trigger the setting of the
value of the whole chart, and setting the value of a chart will trigger
the setting of the values of its individual components.

Cheers,
- Alex
-- 
UNSUBSCRIBE: mailto:picol...@software-lab.de?subject=unsubscribe