Re: ClassField and Chart

2012-03-10 Thread Konrad Zielinski
Thanks Alex,

its working. Its been quite a learning experience.

regs

Konrad



On Sat, Mar 10, 2012 at 7:20 PM, Alexander Burger a...@software-lab.de wrote:
 Hi Konrad,

 The code is still crashing and it has something to do with how I'm
 using the class field.

 OK, I found two more errors:


 1. The chart's put function should not set the class field to 'This'

   (list This (: nm) (diestr (: level)) (: notes))

 but to the object's type (i.e. th list of classes)

   (list (type This) (: nm) (diestr (: level)) (: notes))


 2. Then, the return value of the get function is wrong. It returns
   the 'Data' list (the visual representation):

         (put! Itm 'notes (cadddr Data))
         Data )
      ((car Data)

   It must be the object 'Itm' in the current row

         (put! Itm 'notes (cadddr Data))
         Itm )
      ((car Data)


 With that, we have:

   (gui '(+Set +E/R +Chart) '((L) (filter bool L)) '(gear : home obj) 5
      '((Itm)
         (with Itm
            (list (type This) (: nm) (diestr (: level)) (: notes)) ) )
      '((Data Itm)
         (cond
            (Itm
               (put! Itm 'nm (cadr Data))
               (put! Itm 'level (caddr Data))
               (put! Itm 'notes (cadddr Data))
               Itm )
            ((car Data)
               (new! (car Data)
                  'nm (cadr Data)
                  'level (diestr (caddr Data))
                  'notes (cadddr Data) ) ) ) ) )
   (table NIL NIL
      '((NIL Type) (NIL Name) (NIL Level) (NIL Notes))
      (do 3
         (row NIL
            (gui 1 '(+ClassField) '(curr)
               '((Armour +Armour +Item) (Weapon +Weapon +Item) (Item 
 +Item)) )
            (gui 2 '(+TextField) 10)
            (gui 3 '(+TextField) 4)
            (gui 4 '(+TextField) 30)
            (gui 5 '(+DelRowButton)) ) ) )
   (scroll 3 T)

 Cheers,
 - Alex
 --
 UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe



-- 
read my mind at: http://the-willows.blogspot.com/
--
UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe


Re: ClassField and Chart

2012-03-08 Thread Konrad Zielinski
Hi Alex,

I don't actually understand the  choMaster function or why I would
actually need one?

the model I have is:

(class +Monster ...)
(rel gear (+List +Joint) whos (+Item))


(class +Monster ...)
 (rel whos (+Joint) gear (+Monster))

And I'm trying to add the list of Gear objects onto the Monster page.
So the master is always going to be the object in (: home obj). Do I
just wrap that up as an anonymous function?

regs

Konrad.


On Thu, Mar 8, 2012 at 6:39 PM, Alexander Burger a...@software-lab.de wrote:
 On Thu, Mar 08, 2012 at 08:24:02AM +0100, Alexander Burger wrote:

    (gui '(+E/R +Chart) '(children : home obj) 5
       '((This) (list NIL This (: nm)))
       car )
    (table NIL NIL
       '(NIL (NIL Class) (NIL Name))
       (do 6
          (row NIL
             (gui 1 '(+ChoButton) '(choMaster (field 1)))
             (gui 2 '(+ClassField) '(curr)
                '((Armour +Armour +Item) (Weapon +Weapon +Item )) )
             (gui 3 '(+TextField))
             (gui 4 '(+DelRowButton))
             (gui 5 '(+BubbleButton)) ) )
       (scroll 6 T)

 Obvoiusly, '(: nm)' in the chart's get function should be '(: name)'.


 Then, if you want the name to be editable in the chart, you can change
 the above to

   ...
   (gui '(+E/R +Chart) '(children : home obj) 5
      '((This) (list NIL This This))
      car )
   ...
               '((Armour +Armour +Item) (Weapon +Weapon +Item )) )
            (gui 3 '(+Obj +TextField) '(name +Master) 30)
            (gui 4 '(+DelRowButton))
   ...

 That is, you pass the object 'This' instead of just the name '(: name)'
 to the chart field, and make the field an '+Obj' field (holding an
 object instead of just plain text).

 Cheers,
 - Alex
 --
 UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe



-- 
read my mind at: http://the-willows.blogspot.com/
--
UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe


Re: Structuring a GUI project to avoid stop - starts

2012-03-05 Thread Konrad Zielinski
Thanks Jose,

If I'm understanding this correctly the simple way to do this is to
put the logic for each page in its own file. so instead of (de report
..) I would have a report.l file that just contains the guts of what
I'm coding.

Reloading model.l is not really an issue for me. Besides at the moment
if it does change ir porably means that the underlying database also
needs to be nerfed and recreated becasue I've made large changes to
the the entity structures. THough this is not likely at this stage
where I'm mostly working on getting my reporting function to spit out
the HTML that I want.

regs

Konrad.

2012/3/6 José Romero jose.cyb...@gmail.com:
 Hi Konrad,

 On Tue, 6 Mar 2012 12:46:44 +1100
 Konrad Zielinski kzielin...@gmail.com wrote:

 Hi,

 At the moment I have my project in two files

 model.l which contains my domain classes, database init code and other
 related functions.
 server.l which contains my URL handling functions.

 I find that I'm constantly having to kill and restart the server
 process and then navigate to the code I'm working on. This is quite
 cumbersome.

 Is there a way to get the running picolisp process to detect and
 action changed source files without constant restarts.

 regs Konrad


 You could just use the technique Alex uses, most of the code that
 may need some quick tweak for each object is contained in a file that
 is quickly 'loaded every time a request for that object arrives.

 If you are careful designing the application you could make server.l
 'load model.l again once in a while (maybe by visiting some secret
 URL). if you have stuff in server.l that may change very often, move it
 out to another module.

 If you want to automatically detect a changed file and reload it, you
 could code something like this, on Linux, using inotifywait(1) (I use
 this code for synchronizing files between my shared host and my laptop
 over ssh+rsync)

 # Recursively watch the current directory
 (setq *InotifyFD
   (pipe
      (call 'inotifywait -mrq
         -e modify,create,move,delete
         . ) ) )

 (de reload ()
   # load modules, initialize variables, etc etc.
         )

 (task *InotifyFD
   (in *InotifyFD
      # The process died somehow, clean up.
      (when (eof) (task *InotifyFD))
      (line) # Eat notification.
      # Wait 5 secs for the notifications to settle before reloading

Re: How do Relations and gui objects hook together.

2012-02-22 Thread Konrad Zielinski
Hi Alex

Thanks for the explanation. Though this really should be mentioned in
the documentation. Its a rather obscure call in Family.l which just
looks like its creating a Heading.  but it turns out to be vital for
the application to work.

I notice that there are a few other methods defined in form.l that are
not actually documented anywhere. The button helpers I can sort of
work.  But the choDlg and panel with their long and rather complicated
argument lists are somewhat harder to puzzle out.

regs

Konrad


On Thu, Feb 16, 2012 at 8:02 PM, Alexander Burger a...@software-lab.de wrote:
 Hi Konrad,

 I've being trying to work out how the Family.l application hooks
 together its database and gui objects together and simply haiing no
 luck.

 as far as I unsetad the current Person object is being stored in the
 global variable *ID by the (default *ID (val *DB)) call.

 *ID is used only temporarily, to communicate the object across HTTP
 calls as URL parameter.

 The real place of the object is normally in the 'obj' property of the
 form. The crucial call here is

   (id ...)

 'id' takes care of storing the object in *ID into the 'obj' property
 of the current form, enable or disable the form according to certain
 rules, and lock the object if necessary.


 but then none of the gui calls seem to reference this object at all.
 So how is one hooked up to the other.

 There the crucial item is the +E/R prefix class (as you noticed). It
 takes care of connecting the displayed value in the GUI component to
 the internal DB object's attribute.


 Also what are the initilisation arguments to the +E/R prefix class

 They take the form of a cons pair, with the attribute (relation) in the
 CAR, and an executable expression giving the object in the CDR.

 Whenever +E/R needs to read a value from the object into the GUI, or
 write changes from the GUI to the object, it evaluates the 'exe' in the
 CDR to obtain the DB object.

 supposed to mean '(nm : home obj) . The first one appears to be
 relation name but what does the rest of the lsit do.  I've tried

 So 'nm' is the relation (e.g. the person's name), and '(: home obj)' the
 object expression. As the object is stored in the 'obj' property of the
 current form, and each GUI component knows the form it resides in from
 its 'home' property, '(: home obj)' means: Get my (the GUI component's)
 home form, and from that the object.

 readin the code and the libraries it imports and re reading the
 Applicaton development document several times but it just seems to
 skip over this point. We have information on DB programming and

 The documentation is not (yet) complete here. It's really a lot of
 stuff, and explaining it all would probably be longer than the
 implementation itself. I hope this will improve in the future.

 Cheers,
 - Alex
 --
 UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe



-- 
read my mind at: http://the-willows.blogspot.com/
--
UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe


Re: android success with full picolisp

2012-02-21 Thread Konrad Zielinski
Do you know if this approach would work for on a Kindle Keyboard as well?

It would be an interesting way to add functionaltiy to my kindle.

regs

Konrad



On Tue, Feb 21, 2012 at 2:04 PM, Joe Bogner joebog...@gmail.com wrote:
 Doug - Neat! I took a different approach and got picolisp working on my
 android phone and kindle fire by using terminal-ide
 (http://code.google.com/p/terminal-ide/ ) as the shell and cross compiling
 picoLisp with gcc-arm-linux-gnueabi on my linux box. I can post the binary
 if anyone is interested.

 I didn't do anything with it because terminal-ide (and it's busybox compile)
 couldn't resolve DNS (didn't include a /etc/resolv.conf) and I lost root at
 the time with my kindle fire.
 http://forum.xda-developers.com/showthread.php?p=22103721 . I was originally
 going to play around with scripting out something that involved the network.

 I kicked around shelling out to a java app to resolve DNS but then moved
 onto another project. Other than that it worked great. It was nice to have
 VIM around as well. I may go back to it at some point but didn't really have
 a practical use for it on android especially since I could just ssh into my
 linux if I wanted to tinker with picoLisp.

 Thanks for sharing

 On Mon, Feb 20, 2012 at 9:46 PM, Doug Snead semaphore_2...@yahoo.com
 wrote:

 More android + picolisp fun, this time with the full picolisp.  Using the
 android SDK and NDK, I hacked a picolisp/src/makefile to work for android's
 arm processor like this:

 --- makefile ---
 [snip]

 CFLAGS := -c -O2  -pipe \
         -falign-functions=64 -fomit-frame-pointer -fno-strict-aliasing \
         -W -Wimplicit -Wreturn-type -Wunused -Wformat \
         -Wuninitialized -Wstrict-prototypes \
         -D_GNU_SOURCE  -D_FILE_OFFSET_BITS=64
 # ?? had: -m32

 NDK_ROOT = ~/android/android-ndk-r7
 NDK_BIN =
 $(NDK_ROOT)/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin
 SYS_ROOT = $(NDK_ROOT)/platforms/android-8/arch-arm/
 CC = $(NDK_BIN)/arm-linux-androideabi-gcc --sysroot=$(SYS_ROOT)
 LD = $(NDK_BIN)/arm-linux-androideabi-ld
 AR = $(NDK_BIN)/arm-linux-androideabi-ar
 RANLIB = $(NDK_BIN)/arm-linux-androideabi-ranlib
 STRIP = $(NDK_BIN)/arm-linux-androideabi-strip

         OS = Arm
         PICOLISP-FLAGS = -m32 -rdynamic
         LIB-FLAGS = -lc -lm -ldl
         DYNAMIC-LIB-FLAGS = -m32 -shared -export-dynamic

 [snip]
 -

 Then (to my surprise) picolisp and dynamic libraries were made,

 # file ../bin/picolisp  ../lib/ext  ../lib/ht ../lib/z3d
 ./bin/picolisp: ELF 32-bit LSB executable, ARM, version 1 (SYSV),
 dynamically linked (uses shared libs), stripped
 ./lib/ext:      ELF 32-bit LSB shared object, ARM, version 1 (SYSV),
 stripped
 ./lib/ht:       ELF 32-bit LSB shared object, ARM, version 1 (SYSV),
 stripped

 ./lib/z3d:      ELF 32-bit LSB shared object, ARM, version 1 (SYSV),
 stripped

 So far so good...

 Using this android approach generally,


 http://gimite.net/en/index.php?Run%20native%20executable%20in%20Android%20App

 I placed the picolisp executable in the assets dir and at run-time, copy
 it from assets to /data/data/ in the right place for that app.

 Since I'm using the emulator and I know where the executable was placed, I
 can run it using adb, for some command-line tests:

 # adb shell /data/data/com.mytest/picolisp '-de foo (X) (println X)'
 '-foo 123' -bye
 123

 # adb shell /data/data/com.mytest/picolisp '-de foo (X) (println (* X
 2))'  '-foo 123' -bye
 246

 # adb shell /data/data/com.mytest/picolisp '-de foo (X) (println (* X
 2))'  '-foo 12345' -bye
 24690

 A bit cumbersome having to unpack the executable and other files from the
 app's .apk (zip archive) to run it ... but it can be done.  And no fiddling
 with bits ... no changes to the (full picolisp) source at all.

 Next step is to try to similarly unpack all the libraries and see if a
 picolisp database server application can be run. Then more testing.  And use
 that with android's browser, all within an android app.

 But I'm very confident that the full picolisp will run on the android from
 what I see so far!

 There are ways to call java from C also, so that opens up possibilities of
 using android java libraries from android picolisp too.

 Cheers,

 Doug

 --
 UNSUBSCRIBE: mailto:picolisp@software-lab.de?subjectUnsubscribe





-- 
read my mind at: http://the-willows.blogspot.com/
--
UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe


Re: Canonical way to do master detail relationship.

2012-02-12 Thread Konrad Zielinski
Thanks Alex,

I Believe this is what I was looking for:

(class +Master +Entity)
(rel children (+List +Bag)
  ((+Key +String))   # description
  ((+Number)) )  # rank

I'll see how I go with it. As to number of details I'm expecting it to
sit at less then 5 almost all the time, with no detail records being
the most common case.

regards

Konrad


-- 
read my mind at: http://the-willows.blogspot.com/
-- 
UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe


UNSUBSCRIBE

2010-07-25 Thread konrad Zielinski
Good bye konrad Zielinski kzielin...@gmail.com :-(
You are now unsubscribed


-- 
read my mind at: http://the-willows.blogspot.com/
-- 
UNSUBSCRIBE: mailto:picol...@software-lab.de?subject=unsubscribe


Re: Status of 64 picoLisp

2008-10-16 Thread konrad Zielinski
Hi All,

It would appear that setting up a chroot is remarkably easy, well
under debian anyway, I can't speak for other distros as I haven't
tried. AndJus it seems to work quite nicely too, even if their are
other ways to do it.

Anyway now that I have a chroot I can install a version of Firefox
with flash as well : )




Disclaimer: I have not examined the low level virtual machine to any
level of detail. the following is a general observation about VM's.
For all I know the people behind LLVM have done things better.

Some languages are simply sufficiently different that they do not work
well on some virtual machines. Attempting to implement Erlang on the
JVM comes to mind. The underlying primities are different.

Often what generic virtual machine means is good for any language
sufficently close to C, IE staticly typed etc. Lisp is not decented
from C and makes somwhat different assumptions about a lot of things,
so it may not be a good fit.



And now back to questions about 64 bit picolisp:

Is switching to an assembler going to mean the demise of gcc.l ?
Are we going to see inline picoLisp Assembler instead?O

How is a new assembler based version of Picolisp going to affect 32
bit platforms. I imagine they are going to be arround for quite a
number of decades yet?

Regs

Konrad

On 16/10/2008, Tomas Hlavaty [EMAIL PROTECTED] wrote:
 Hi Alex,

 thanks for explanation.

 I was curious to try picolisp bignums and must say that for somebody
 doing anything serious, it is probably rather inefficient.  As a
 benchmark, I tried the example from
 http://paste.lisp.org/display/15116

 (setq X 0)
 (setq Y 1)
 (for (N 2 (= N 100) (inc N))
(let Z (+ X Y)
   (setq X Y)
   (setq Y Z)))
 (prinl Y)

 Very rough results using picolisp native bignums:

 (= N 1)

 $ time ~/picolisp/p gmp-test2.l -bye  gmp-test2.log

 real  0m0.131s
 user  0m0.124s
 sys   0m0.008s

 (= N 10)

 $ time ~/picolisp/p gmp-test2.l -bye  gmp-test2.log

 real  0m10.190s
 user  0m10.157s
 sys   0m0.008s

 (= N 100)

 $ time ~/picolisp/p gmp-test2.l -bye  gmp-test2.log
   C-c C-cKilled

 real  17m58.856s
 user  17m51.687s
 sys   0m5.572s

 (killed after 18 mins!)

 The original C program:

 $ time ./gmp  gmp.log

 real  0m50.060s
 user  0m50.059s
 sys   0m0.004s

 I wrote simple ffi wrapper for gmp library and the results:

 $ time ../../p gmp-test.l -bye  gmp-test.log

 real  0m50.507s
 user  0m50.239s
 sys   0m0.248s

 using the following code:

 (setq X (mpz_new))
 (setq Y (mpz_new))
 (mpz_init X)
 (mpz_init Y)
 (mpz_set_ui X 0)
 (mpz_set_ui Y 1)
 (setq Z (mpz_new))
 (for (N 2 (= N 100) (inc N))
(mpz_init Z)
(mpz_add Z X Y)
(mpz_set X Y)
(mpz_set Y Z)
(mpz_clear Z))
 (mpz_print Y)
 (prinl)

 Would not it be better to use gmp library for bignums if they are
 going to be supported?

 What is the reason picolisp has bignums in the first place?  Do
 you/somebody else use it for anything?  Would not it be simpler and
 good enough on 64 bit systems not having them at all?

 What impact on interfacing foreign libraries the asm rewrite have?

 Cheers,

 Tomas
 --
 UNSUBSCRIBE: mailto:[EMAIL PROTECTED]

-- 
UNSUBSCRIBE: mailto:[EMAIL PROTECTED]


Re: Status of 64 picoLisp

2008-10-15 Thread konrad Zielinski
I suspect this would be in contradiction to some of the stated goals
of PicoLisp,
For one you would no longer be close to the machine. Just close to the
virtual machine.


On 16/10/2008, Jakob [EMAIL PROTECTED] wrote:
 On 15 Oct 2008, at 9:11 AM, Alexander Burger wrote:

 It is a complete rewrite. Even the implementation language changed.
 Instead of C it is written in a generic assembler (which in turn is
 written in PicoLisp :) that generates GNU assembler code (currently
 there is only a x86-64 generator, but other CPUs are possible).


 Oh. Please consider http://en.wikipedia.org/wiki/Low_Level_Virtual_Machine

 Because it is awesome, and if you port to that, you do not have to port
 to any other architecture. I was only recently made aware of LLVM, and
 it is really cool.

 Apple reportedly has started using it, probably wise from their past
 experience with switching CPU architecture. With LLVM, switch as much as
 you like. And no, LLVM is NOT another Java in disguise. LLVM is like a
 real CPU.

 regards,
 Jakob


 --
 UNSUBSCRIBE: mailto:[EMAIL PROTECTED]

-- 
UNSUBSCRIBE: mailto:[EMAIL PROTECTED]


Re: Cutting a circular list.

2008-10-13 Thread konrad Zielinski
2008/10/13 Tomas Hlavaty [EMAIL PROTECTED]:
 Hi Konrad,

 Well thats two improvements to the documentation.

 Perhaps a perfect candidate for the Wiki?

 Hmm.

 var - Variable: Either a symbol or a cell

 (set 'var 'any ..) - any
 Stores new values any in the var arguments. See also setq, val and def.

 Even taken in concert these two snippets don't actually explain what
 will happen if var is a cell. It may be obvious (if you already know)
 that if var is a cell than action will be taken on the car part.
 However it does not actually say so. I note that the definition of con
 does say so even though its signature has the more specific data type
 of Lst.

 The best a very careful first time reader could pick up is that the
 behavior is not explicitly spelled out. They could then, guess,
 experiment or ask.

 I would say that there are some functions where additional verbosity
 is warranted. the function for assigning values is one such place.
 Especially when the acutal behaviour may not be what people with Lisp
 experience expect.

 While succinctness is good in documentation, it is possible to have
 too much of a good thing.

 nothing is perfect but rather than arguing with Alex about quality of
 his documentation, would not it be easier and more useful to take
 action and put it in the picoWiki?  I think everybody would appreciate
 your knowledge and it would be preserved for newcomers too.

Yes I intend to. I'd like to give something a little more substantial
on structure manipulation. There is a few things I have in mind.

 It would
 at least make it easier for Alex not to spend his lifetime maintaining
 his documentation to everybody's tastes and focus on his clients,
 writing code and having fun instead;-)

Documentation is part of the reason why picolisp is a great project.
There are too many Open source projects where the code is the
documentation.

As such improvements to the documentation are just as important as
improvements to the code. As  I said earlier this seems a point which
is sufficently important to be in the core documentation.

The one nice thing about having core documetnation, which is local to
my system is that I can access it when I'm offline, which is most of
the time.

I get the impression that some people stay online constantly. Here in
Australia however internet connections are comparable expensive (we
don't have true unlimited usage plans, it is all metered by download
amount). So my laptop stays offline unless I really, really, need
somthing that isn't on my system.

regs

Konrad.



 There are many different Lisp dialects so people's expectations could
 vary depending on their background.  A wiki page for people comming
 from Common Lisp background, for example, would be great!

 Cheers,

 Tomas
 --
 UNSUBSCRIBE: mailto:[EMAIL PROTECTED]

-- 
UNSUBSCRIBE: mailto:[EMAIL PROTECTED]


Re: picoWiki

2008-10-13 Thread konrad Zielinski
Hi,

After some consideration I agree that supplementing the core docs is
better then replacing them.

If I could make a feature suggestion. It would be handy if there was a
shortcut syntax for linking to the definition of terms in the core
documentation (much as the lisp tag currently does). so that we
didn't have to type the entire address every time. possibly {ref set}
to refer to the refS.html#set in the core documentation.

regards

Konrad.

2008/10/14 Tomas Hlavaty [EMAIL PROTECTED]:
 Hi Randall,

 In my experience, a Wiki is only truly successful if there are very
 clear rules, styles, and usually someone with a heavy hand to
 enforce that.

 Would you have any suggestions what those rules and styles should be?

 A simple solution would be, just duplicate the documentation in the

 I am not sure whether it is a good idea completely replacing the
 documentation Alex created and maintains.  Alex will probably not give
 that up anyway?  However, the existing documentation is a good start,
 e.g. http://logand.com/picoWiki/classes then can be filled with
 comments, examples, observations, ideas etc. like I started with
 http://logand.com/picoWiki/+Blob

 It would be good to address things that are not covered by his
 documentation, are out of scope for the core picolisp package, link to
 other people's blogs or software or elaborate where we feel more
 information is necessary for people not enough familiar with picolisp
 (like me;-).  Alex's documentation can be incorporated in the forms of
 links like for example in the lisp markup and maybe integrated with
 the search function.

 Wiki, make it better and better and make sure it is well supported.

 This would be an ideal to aim for:-)

 Cheers,

 Tomas
 --
 UNSUBSCRIBE: mailto:[EMAIL PROTECTED]

-- 
UNSUBSCRIBE: mailto:[EMAIL PROTECTED]


Re: Cutting a circular list.

2008-10-11 Thread konrad Zielinski
Hi Alex,

Well thats two improvements to the documentation. The description of set says:

Stores new values any in the var arguments. I suspect it should say
what you said above. and have a see also link to con.

regs

Konrad.

On 11/10/2008, Alexander Burger [EMAIL PROTECTED] wrote:
 Hi Konrad,

 (set 'A (1 2 3 4))
 (set 'B (cdr A))
 ...
 (set (cdr A) NIL)

 The 'set' function puts a value into the CAR part of a cell (no matter
 whether this is a list cell or a symbol).

   A B

   | |
   V V
   +-+-+ +-+-+ +-+-+ +-+-+
   |  1  |  ---+--- |  2  |  ---+--- |  3  |  /  |--- |  4  |  /  |
   +-+-+ +-+-+ +-+-+ +-+-+
 ^
 |
  (cdr A)

 So 'set' receives the cell which is pointed to by 'B', and stores 'NIL'
 into its value cell.


 What you want to achieve is

   A B

   | |
   V V
   +-+-+ +-+-+ +-+-+ +-+-+
   |  1  |  /  | |  2  |  ---+--- |  3  |  /  |--- |  4  |  /  |
   +-+-+ +-+-+ +-+-+ +-+-+

 i.e. storing NIL into the CDR part of the first cell of 'A'.

 'set' cannot do this, but 'con' stores a value in the CDR part of a cell:

 : (con A NIL)
 - NIL
 : A
 - (1)
 : B
 - (2 3 4)


 the goal is to take a list build by fifo and turn it into a normal
 list starting at the 2nd element.

 so instead of (4 1 2 3 .)
 I get (1 2 3 4)

 You were on the right way:

: A
- (4 1 2 3 .)

: (setq L (cdr A))
- (1 2 3 4 .)

: (con A NIL)
- NIL

: L
- (1 2 3 4)
: A
- (4)

 Cheers,
 - Alex
 --
 UNSUBSCRIBE: mailto:[EMAIL PROTECTED]

-- 
UNSUBSCRIBE: mailto:[EMAIL PROTECTED]


Re: picoWiki

2008-10-09 Thread konrad Zielinski
Yes, Wiki's can be quite useful.

Getting a copy of the standard reference documentation on there would
be useful. Then we could all work on expanind it a little as the
current desciptions are quite terse in places.

Granted the fact that we have readable documentation at all is a great
boon, and a credit to the author, way too many projects out there
don't have docs worth spitting at, let alone reading.

A Cookbook of how to solve various task would probably be the next
step. At the moment my mode of operation seems to be:

 1) try to do X
 2) get stuck
 3) Ask Alex
 4) Get a response with code which is remarkably consise and uses
functions I ether didn't know existed or had completly forgotten
about.

There seems to be a lot of cool and consise ways of doing things once
you join the dots of which sets of functions to use together : )

I certainly would consult a wiki, and do my best to contribute where
the occation arose.

P.S. how did you do the syntax highligting for lisp code? It's a
rather nice feature.

regards

Konrad.

On 09/10/2008, Alexander Burger [EMAIL PROTECTED] wrote:
 Hi Tomas,

 class=i href=?ChangesChanges/a, w3m will interpret it as
 http://logand.com/?Changes. It works in Firefox though, i.e. it opens
 http://logand.com/picoWiki?Changes page as intended.

 Just tried with both w3m and firefox, and both seem to work well :-)

 Cheers,
 - Alex
 --
 UNSUBSCRIBE: mailto:[EMAIL PROTECTED]

-- 
UNSUBSCRIBE: mailto:[EMAIL PROTECTED]


Re: Asyncronous IO

2008-10-09 Thread konrad Zielinski
Hi Alex,

that sends me back to the drawing board a little. Yet again I recall
seeing the fifo function but didn't realise I might need it : )

A few other things occured to me as I was working on this on the
train. The task and *Run mechanism (if used with enough care) give us
non blocking reads.

But the underlying select function also provides non blocking writes.
so that you can dely trying to write to a socket until it is ready for
more data.

It would appear that task and *Run have no way of using this part of
the select function.

There is also out of band data as a thrid set of descriptors however
all the documentation suggests that this is rarely used unless you are
doing particularly low level magic.

regards

Konrad.

2008/10/10 Alexander Burger [EMAIL PROTECTED]:
 Hi all,

 Sorry for the confusion,

 Let me try to explain the situation:

 In the present system, it does not help at all to put the socket into
 non-blocking mode. The reason is that select() is conceptionally
 separated from read().

 After select() signals (correctly or incorrectly) that data are
 available, the corresponding task's body is executed. It will try to
 read from that socket, and from that moment there is no way back. When
 no data at all arrive, or only a few bytes but not the complete message,
 it has to wait until the full message is assembled, be it blocking or
 non-blocking.

 Even if select() would be accurate, and never send an event to the tasks
 unless there are really data available, it would not help because there
 might be less data available than are needed for the full message, and
 the missing data might never arrive.


 So if you need to do such things asynchronously, the whole process of
 assembling the message - probably byte by byte - has to be put into a
 separate task. And you need a timeout for that task, too, because it may
 well be that the message will never be completed. The timeout should
 abort that task and close the connection.

 In this case, a non-blocking mode might be helpful, as in cases where
 select() wrongly said that data are available will not block the system,
 but most probably in those cases the data will arrive a few milliseconds
 later anyway (when the TCP stack resends the packet), or the connection
 will close down (sending EOF to the task), and processing will resume.
 Only in the - very few - remaining cases, the timeout will fire and have
 to cleanup the task and its connection.

 The drawback of implementing such a fully non-blocking system will be
 that the present separation of event generation (select) and data
 processing (read) cannot be held up any longer, and a completely
 different application flow is required.


 Therefore, I would go with the current solution, collect the messages in
 the task's body character by character (or even byte by byte), and
 implement a decent timeout for the pathological cases where this message
 assembly gets stuck for whatever reason. The collection of those pieces
 in the background might be done nicely with the 'fifo' function, keeping
 a first-in, first-out list for each task, and some supervisor logic in a
 higher layer checks those queues for messages, and retrieves and
 executes them.

 Just my two yen.

 Cheers,
 - Alex
 --
 UNSUBSCRIBE: mailto:[EMAIL PROTECTED]

-- 
UNSUBSCRIBE: mailto:[EMAIL PROTECTED]


Re: Asyncronous IO

2008-10-08 Thread konrad Zielinski
Ahh,

I belive the issue is that I have actually installed picoLisp under
usr/local but don't use it exclusivly from that directory. As such I
get the following:

script src=http://localhost:8080//usr/local/picoLisp/lib/form.js;
type=text/javascript/script

which includes an absolure path to forms.js

regards

Konrad


On 08/10/2008, Alexander Burger [EMAIL PROTECTED] wrote:
 Hi Konrad,

 sufficently abstract the URL space from the physical disk. Most other
 mature frameworks allow your to creat a completly virtual url space
 which has no relation to physical files on disk. The way the forms.l
 maps a full path to its javascript file and puts it in the output

 Hmm, which path do you think of? There is only one .js file referenced
 in form.l, and it appears as

src=http://localhost/8080/lib/form.js;

 makes me particularly uncomfortable as it is exposing data on where I
 have installed picolisp.

 so the only path that is exposed is lib/. Where do you see the
 installation path? In general, the GUI only uses relative paths anyway.
 (note: the /8080/ is not part of the path, but the port encoded for
 httpGate).

 Cheers,
 - Alex
 --
 UNSUBSCRIBE: mailto:[EMAIL PROTECTED]

-- 
UNSUBSCRIBE: mailto:[EMAIL PROTECTED]


Re: Asyncronous IO

2008-10-08 Thread konrad Zielinski
Henrik,

all of the references I'm aware of are based on Python.

the standard Python library includes modules called asyncore and asynchat
(sections 17.5 and 17.6 of the Python documentation.

The original Asyncronous webserver (as far as I'm aware) is medusa
http://www.nightmare.com/medusa/
http://www.amk.ca/python/code/medusa

Twisted is a more mature (read complex) implementation of the same
thing. At this stage i belive they have reimplemented everything and
don't even use the standard asyncore module anymore.

I use teisted at work and from the application developers point of
view the system allows complex applications to be built in very neat
small peices.  The approach has the advantage of not having the same
kind of concurrency issues as threaded code has.

By definition asyncronous code is only doing one thing at a time, so
there is no danger of two functions accessing the same data objects at
the same time, without the need for stemapors or locks. I believe that
the Erlang language uses a similer approach to implement its light
weight processes, and it allows them to scale to thousands of
processes.

regards

Konrad

On 08/10/2008, Henrik Sarvell [EMAIL PROTECTED] wrote:
 Sounds clever, but very complicated maybe to maintain the scheduling?
 You mentioned multiplayer online games as a possibility, are the big
 ones with thousands of simultaneous users already operating under
 these principles? It would be great if you could point me to a
 resource on the basics behind this way of doing things.

 /Henrik
 --
 UNSUBSCRIBE: mailto:[EMAIL PROTECTED]

-- 
UNSUBSCRIBE: mailto:[EMAIL PROTECTED]


Re: Asyncronous IO

2008-10-08 Thread konrad Zielinski
Hi All,

In the matter of how to begin. Twisted is I think the wrong place. It
is a very large and complicated beast which has grown in its own
unquie direction. So much so that it is incompatable with a lot of
standard python tools and libraries, uses its own logging system etc.

In copying python the place to start are Asyncore and Asynchat. The
Medusa pages had some basic examples of building an asyncronous client
and then an asyncronous proxy.

I intend to try to build these things and satisfy myself that I'm
really getting asyncronous behaviour.

After that I'm thinking that a good proof of concept application would
be a basic instant messanger which allows multiple users to connect
and send messages to each other. this is a nice application which has
shared state without needing a particularly fancy interface.

As this is a personal project, I'm happy to share code, questions and
comments through this list if there is interest.

A similer Tic Tac Toe server which allows multiple simultainous games
and routes moves to the correct clients would also be nice.

Then its on to the main event. where more care is needed in working
out what functions are needed and how additional functionality should
be hooked into the system. Here I would be aiming to build a generic
UDP and TCP server that is as adaptable as Medusa and Twisted.

At this point, if there is enough interest. putting code on
Sourceforge or Google code might be worth while. Heck it might even
give pico Lisp some extra publicity. (I note this list has been
getting a little more lively lately, which is a good sign).

And can be used as a base for any protocol anyone chooses to throw at it.

One reason why the Async approach is well suited to python is due to
limitations in the Python interpreter. Python has something called a
Global interpreter lock, which restricts it to using a single CPU,
even if threading primitives are used. Ergo threading primities become
an overhead which increases code complexity without giving increased
scalability.

I believe that picoLisp has similer single CPU limitation, I'm pretty
sure that there are no threading primitives. So the only possible
choices are Asyncronous or Forking. The latter makes shared state
somewhat difficult to manage, and exists allready (so there is nothing
new to build).

2008/10/9 Alexander Burger [EMAIL PROTECTED]:
 Hi all,

 oops, sorry! Forget what I wrote:

 A .html file will
 be directly sent to the client, without any forking. And also .l files
 do not automatically cause the fork, but only if (app) is called during
 their execution.

 This was wrong. The 'server' function in lib/http.l will always fork
 when a connection request arrives. It is just that the child process
 immediately terminates after serving the connection (unless (app) was
 called).


 BTW, as a matter of an example, the 'server' function in lib/http.l
 *does* implement a non-forking server, but only in the child process
 once the initial connect from a client has created a session:

   ...
   (loop # Main loop in the parent process
  (setq *Sock (listen P))# Wait for a request
  (NIL (fork) (close P)) # The child closes 'P' and exits the loop
  (close *Sock) )# The parent closes the new connection and 
 continues
   (task *Sock (http @)) # The child installs a task on that socket
   (http *Sock)  # and serves the first page
   (or *SesId (bye)) # If (app) was not called, terminate
   (task *Sock   # Else install a task for the new session 
 socket
  (when (accept *Sock)  # Accept requests on that socket
 (task @ (http @))  # without forking
 (http @) ) ) )


 Note: This uses in two places a construct of the form

   (task socket (http socket))
   (http socket)

 The reason for that is that for HTTP/1.1 more than one transaction may
 be done before the connection is closed.

 Hope this helps.

 Cheers,
 - Alex
 --
 UNSUBSCRIBE: mailto:[EMAIL PROTECTED]

-- 
UNSUBSCRIBE: mailto:[EMAIL PROTECTED]


Re: Asyncronous IO

2008-10-08 Thread konrad Zielinski
Hi Alex,

 your response to Tomas's questions dosn't seem to have made it to the list.

Most of the documentation I have seen seems to suggest that Sockets
need to be put into non blocking mode explicitly, ie using select() is
not sufficent. At a low level attempting to read from a nonblocking
socket will return a Would Block error condition.

Is the picoLisp socket and task code allready setting sockets into non
blocking mode?

regards

Konrad.

2008/10/9 Tomas Hlavaty [EMAIL PROTECTED]:
 Hi Alex,

 thanks for the explanation!

 Tomas
 --
 UNSUBSCRIBE: mailto:[EMAIL PROTECTED]

-- 
UNSUBSCRIBE: mailto:[EMAIL PROTECTED]


Re: Asyncronous IO

2008-10-07 Thread konrad Zielinski
Hi Henrik

the whole idea of an asycronous server is that you only use one
process. to handle all requests. this way session data can be stored
without using an external symbols.

Even further several clients may share state in some way, though the
only example I can think of off the top of my head is a multiplayer
online game.

The performance asumption is that your server is I/O bound and not cpu
bound. Generally anytime you do something that may block you need to
differ that processing probably by adding the waiting resource as its
own task. And in the meantime move on to other processing such as
other waiting requests.

The only time I would spawn a new process is if a request needed
somthing very intensive done. We would then need to have a task
waiting on the other process to complete its work.

the idea is that your process is not allowed to block, so each time IO
is needed the currently executing code needs to be suspened, so that
the system can do something else without blocking. Twisted dose this
by breaking up larger lgoical units into small functions that
essentially sechdule a handler function to be handled when an external
resoult is ready as the last thing before returning.

I am operating at the limits of my understanding here and to be honest
I'm not certain how the whole differed processing model will translate
into picolisp. Though on the face of it, I think it should transfer
rather well.

The Task mechanism along with some other functions I reacal reading
about seem up to the job.

regards

Konrad.

2008/10/8 Henrik Sarvell [EMAIL PROTECTED]:
 Konrad, I'm also a fan of friendly urls and the way you describe it is
 currently how I have set things up to work with Apache through custom
 logic in PHP and mod_rewrite. Let me know if you want any help and
 I'll try my best :-)

 I don't know exactly what you're aiming at and I couldn't get a lot of
 details from the Twisted homepage. What I would like though is a
 restful setup similar to Apache + PHP. All state/session information
 would then be stored in the Pico DB and accessed through a unique
 session id, just like in PHP. Each time a request happens a new pico
 process is spawned and whatever is designated to happen happens and
 finally the pico process terminates. In effect each script would be
 its own little mini-application.

 This model is arguably the main reason why PHP dominates web
 development at the moment, that and the fact that it's a templating
 language automatically. Automatic templating is something I can live
 without though :-)

 /Henrik
 --
 UNSUBSCRIBE: mailto:[EMAIL PROTECTED]

-- 
UNSUBSCRIBE: mailto:[EMAIL PROTECTED]


Re: using the http server to return xml

2008-10-04 Thread konrad Zielinski
I think my problem with setting mime types originally was due to
basing my code on the initial hello world example, where the html
function is called bare inside project.l. In this model the call to
server is on the command line.

I'm guessing this means that Mime remains whatever it was when server
started and my setting of mime was taking place in a forked process
for the request, and hence was not actually affecting anything. I am
guessing here as I havn't read the http code in detail yet. Now that
I'm doing somthing similer to the sample application and having a
app.l which does all the loading and calls server from inside picoLisp
code I suspect things will work correctly.

I still don't quite follow what curl is supposed to be showing is
wrong with my use of http header. I'm installing it now and will dig
further. I'm determined to get this thing working right.

On 04/10/2008, Alexander Burger [EMAIL PROTECTED] wrote:
 Hi Konrad,

 I've got it returning an actual .xml file ok. (had to modify the
 definition of *Mimes directly as calling (mime xml text/xml 1)
 didn't seem to have any effect.

 Though this is not central to your question, it is strange because it
 should work.

 Where in your code did you call 'mime'? Should be ok anytime after
 lib/http.l is loaded.

 Cheers,
 - Alex
 --
 UNSUBSCRIBE: mailto:[EMAIL PROTECTED]

-- 
UNSUBSCRIBE: mailto:[EMAIL PROTECTED]


Re: using the http server to return xml

2008-10-04 Thread konrad Zielinski
Thanks Alex,

the following fixed the problem. As the bulk of my app will be sending
xml files arround like this I guess I can make these settings globally
for the application. I'm not entierly sure what the implications are.
but I suspect their not too important providing my documents don't
grow to some ridiculous size.

regards

Konrad.

On 04/10/2008, Alexander Burger [EMAIL PROTECTED] wrote:
 On Fri, Oct 03, 2008 at 09:32:43PM +1000, konrad Zielinski wrote:
 (de mydata2 ()
  (httpHead text/xml; charset=utf-8 1)
  (xml? T)
  (xml '(root NIL Document 2))
  )

 mydata works perfectly. mydata2 fails to roduce any output. Now the

 Not sure what the problem is, but two things come to mind:

 1. In which context is 'mydata2' called? If the connection is not closed
for some reason, you could try to call (flush) after sending the
data.

 2. If the initial request from the browser was HTTP/1.1, then the global
'*Http1' is set to '1', causing the picoLisp server to initiate a
chunked transfer. You could try

   (let (*Http1 0  *Chunked NIL)
  (httpHead text/xml; charset=utf-8 1) )

 Cheers,
 - Alex
 --
 UNSUBSCRIBE: mailto:[EMAIL PROTECTED]

-- 
UNSUBSCRIBE: mailto:[EMAIL PROTECTED]


Re: Contriving a static variable.

2008-06-13 Thread konrad Zielinski
Thanks Alex,

now that I know the solution the entry for job in the reference manual
makes perfect sense. {reviously I couldn't quite work out how it
differed from bind.  Pico Lisp does seem to be a rather challenging
language to learn, getting to a point of know what builtin to use
when.

Especially if you have been away from any lisp programming for a while
(as I have). However I'm determined to master it so bear with my and
the questions should get a little more insightfull.

regards

Konrad

2008/6/13 Alexander Burger [EMAIL PROTECTED]:
 On Fri, Jun 13, 2008 at 01:14:04PM +1000, konrad Zielinski wrote:
 I've been trying to get my head around how closures work in Pico lisp.

 As PicoLisp uses dynamic binding, there are no _direct_ static lexical
 clausures. As in other cases too, the programmer has to (or better: can)
 control things directly.

 There are several functions to control dynamic environments, like 'bind'
 or 'job'.

 specifically how would I set up a variable a function which returns
 successive integers each time it is called.

 I would use 'job' here

   (de counter ()
  (job '((Cnt . 0))
 (inc 'Cnt) ) )

 You supply a list of variables (here 'Cnt') and initial values (here
 '0') to 'job', and a runtime body.

   : (counter)
   - 1
   : (counter)
   - 2

 If you inspect this function

   : (pp 'counter)
   (de counter NIL
  (job '((Cnt . 2)) (inc 'Cnt)) )

 You see that the explicit environment is maintained by 'job'. During the
 execution of the runtime body (inc 'Cnt), the variables are dynamically
 bound to their values, and saved thereafter.


 My first Idea was to return this form anther function but it didn't work

 You can this, too. The 'curry' function employs 'job' in certain cases

   (de make-counter (InitialValue @Increment)
  (curry (@Increment InitialValue) ()
 (inc 'InitialValue @Increment) ) )

 Calling 'make-counter' returns a new function

   : (make-counter 0 1)
   - (NIL (job '((InitialValue . 0)) (inc 'InitialValue 1)))

 which is basically the same as our counter above.

   : (def 'counter (make-counter 0 1))
   - counter
   : (counter)
   - 1
   : (counter)
   - 2

 Cheers,
 - Alex
 --
 UNSUBSCRIBE: mailto:[EMAIL PROTECTED]

-- 
UNSUBSCRIBE: mailto:[EMAIL PROTECTED]