Re: Cutting a circular list.

2008-10-10 Thread Henrik Sarvell
There has been some prior discussion on the list:
http://www.mail-archive.com/search?q=circular+lists&l=picolisp%40software-lab.de

It might or might not be of help.

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


Cutting a circular list.

2008-10-10 Thread konrad Zielinski
Hi,

is there a way of cutting a circular list. for that matter how do we
manupulat cons structure. This is one of the places where things in
Pico do not work like I expect.

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

Now in Common Lisp I can do:
(setf (cdr A) nil)

and I will get:
A = (1)
B = (2 3 4)

But in Picolisp if I do
(set (cdr A) NIL)

I end up with

A = (1 NIL 3 4)
B = (NIL 3 4)

do I have a way to get the CommonLisp like behaviour in Pico Lisp?

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)

regs

Konrad.
-- 
UNSUBSCRIBE: mailto:[EMAIL PROTECTED]


Re: picoWiki

2008-10-10 Thread Tomas Hlavaty
Hi Henrik,

> I could help with implementing the code highlighting I have on
> prodevtips, it's all happening in the client through javascript, very
> easy actually, you simply need the ability to add html in the content,
> if the necessary javascript files are included then you can do:
>
> 
> 
>
> And all pico lisp code in the code block will be highlighted.

nice, I did not notice the syntax highliting feature though as I have
javascript turned off.

Syntax highlighting is nice but I think the links to picolisp
reference manual are the most important part of the  markup.
That's the main power of the web I think, not having to look things up
but simply click on them... "instant" information.

If you fancy doing this in picoLisp (that's the thing we are after
here anyway;-), there are a few things that could be improved in the
current  tag in picoWiki:

1) highlight class names and link them to a reference explanation.  As
there is no single reference place similar to built in functions,
maybe create a picoWiki reference for classes and link it there,
i.e. create a page classes, list there classes similar to the
reference for functions and refer markup there.  (I will have to
implement some picoWiki markup for html anchor for this.)

2) highlight strings and persistent symbols

3) cute parenthesis highliting as in lisp paste would be nice, see
http://paste.lisp.org/display/68251 for example

4) the content of the  element can start with prompt, e.g. 

  : (setq lambda quote)
  -> 67293272

the : and -> are currently linked to the picolisp reference which
should not be the case.

I attach the file which generates the picolisp xref/highliting.  To
use it:

: (load '@lib/http.l)
-> http404
: (load '@lib/xhtml.l)
-> 
: (load "/tmp/markupLisp.l")
-> markupLisp
: (markupLisp "(setq lambda quote)")
(http://www.software-lab.de/refS.html#setq";>setq lambda http://www.software-lab.de/refQ.html#quote";>quote)-> T
: 

The markupLisp function gets a string and outputs html.

I hope to post the whole picoWiki code at some point when it's more
complete and the mess cleaned up bit:-)

Cheers,

Tomas

(setq *Xref
   (mapcar pack '(new  sym  str  char  name  sp?  pat?  fun?  all  intern  
extern    loc  box?  str?  ext?  touch  zap  length  size  format  chop  
pack  glue  pad  align  center  text  wrap  pre?  sub?  low?  upp?  lowc  uppc  
fold  val  getd  set  setq  def  de  dm  recur  undef  redef  daemon  patch  
xchg  on  off  onOff  zero  one  default  expr  subr  let  let?  use  accu  
push  push1  pop  cut  del  queue  fifo  idx  lup  cache  locale  dirname 
put get prop ; =: : :: putl getl wipe meta 
atom pair lst? num? sym? flg? sp? pat? fun? box? str? ext? bool not == n== 
= <> =0 =T n0 nT < <= > >= match 
+ - * / % */ ** inc dec >> lt0 ge0 gt0 abs bit? & | x| sqrt seed rand max 
min length size accu format pad oct hex fmt64 money 
car cdr caar cadr cdar cddr caaar caadr cadar caddr cdaar cdadr cddar cdddr 
cadddr cr nth con cons conc circ rot list need full make made chain link 
yoke copy mix append delete delq replace insert remove place strip split 
reverse flip trim clip head tail stem fin last member memq mmeq sect diff index 
offset assoc asoq rank sort uniq group length size val set xchg push push1 pop 
cut queue fifo idx balance get fill apply 
load args next arg rest pass quote as pid lit eval run macro curry def de 
dm recur recurse undef box new type isa method meth send try super extra with 
bind job let let? use and or nand nor xor bool not nil t prog prog1 prog2 if 
if2 ifn when unless cond nond case state while until loop do at for catch throw 
finally ! e $ sys call tick ipid opid kill quit task fork pipe later timeout 
bye 
apply pass maps map mapc maplist mapcar mapcon mapcan filter seek find pick 
cnt sum maxi mini fish by 
path in ipid out opid pipe ctl any sym str load hear tell key poll peek 
char skip eol eof from till line format scl read print println printsp prin 
prinl msg space beep tab flush rewind rd pr wr rpc wait sync echo info file dir 
lines open close port listen accept host connect nagle udp rc pretty pp show 
view here prEval mail 
*Class class dm rel var var: new type isa method meth send try object 
extend super extra with This 
pool journal id seq lieu lock begin commit rollback mark free dbck rel dbs 
dbs+ db: fmt64 tree root fetch store count leaf minKey maxKey genKey useKey 
init step scan iter prune zapTree chkTree db aux collect 
be goal prove -> unify ? 
pretty pp show loc debug vi ld trace lint lintAll fmt64 
argv opt gc raw alarm protect heap env up stk date time usec stamp dat$ 
$dat datSym datStr strDat expDat day week ultimo tim$ $tim telStr expTel locale 
allowed allow pwd cd chdir ctty info dir dirname call tick kill quit task fork 
pipe timeout mail test bye 
NIL *OS *DB T *Solo *PPid *Pid @ @@ @@@ This *Dbg *Zap *Scl *Class *Dbs 
*Run *Hup *Sig1 *Sig2 ^ *Err *Rst *Msg *Uni *Led *Adr *Allow *Fork *Bye

Re: Asyncronous IO

2008-10-10 Thread Tomas Hlavaty
Hi Alex and John,

>> The comment is a bit misleading as it does not prevent blocking
>> really.  The data might be available but the 'read' function might
>> still block.
>
> Yes, all those comments regarding non-blocking (also in the way
> Konrad used it) mean that during normal operations (i.e. not hanging
> in an error condition) everything will go smoothly. It does not mean
> "non-blocking" in the technical sense. But for those "normal"
> operations, it goes surprisingly well when messages observe the
> PIPE_BUF limit. So the *application* is non-blocking, not the
> underlying protocol. Without *Run and (poll) the input would always
> block even on a single input channel.

I understand your interpretation.  However, there is a huge difference
in consequences:

1) If you have a server with separate processes for each request or
session, it is not such a big deal if one client hangs (and eventually
timeouts...).

2) If you have a server with single process though (no threads),
anything that causes blocking makes the server completely useless.  In
this case, the only operation that is allowed and intended to block is
the select() syscall (task or *Run thingy in picolisp).

So, your interpretation is fine for the first case but I don't think
it is acceptable for the second case.

>> So the poll will still be useful in an nbio world.
>
> Yep.

No, poll is useful if your i/o operations block.  The you can use the

  : (and (poll *Fd) (in @ (read)))  # Prevent blocking

"trick" if you are aware of the consequences and are happy with them
for your particular application (the first case).

If you have "real" non-blocking i/o operations, then poll is kind of
"built in".  If you have a look at the example I sent, there is no
poll simply because the same functionality is provided directly by the
rdx and wrx functions.

>> If the socket is set not to block, then the socket will read as
>> much data as is available and the underlying read call will return
>> the number of bytes read, right?
>
> Yes, but in blocking mode it will also read only as many bytes as
> are available.
>
> So there is not really a fundamental difference between the
> capabilities of blocking and nonblocking sockets, when select() is
> used.
>
> But nonblocking mode has a few advantages in pathological
> situations.

I think the difference is much bigger than you admit.  It is actually
two different worlds, Venus and Mars;-) It is not a matter of setting
a block/no-block flag on a file descriptor, it is a matter of
switching to completely different kind of thinking and implementing
things.  That's why Alex's experiment did not turn out well.  See his
post: completely different flow required...or something like that.

It is not so much the low level read function but the control flow and
other higher level i/o functions.  For example the picolisp (read)
function which reads an arbitrary Lisp expression would have to be
completely rewriten to work in a single process/thread server.  The
same goes for (most of) the rest of picolisp.  It just was not
designed for that.

One of the reasons we have processes provided for us in operating
systems is that we can write nice, "simple" sequential programs.  The
ugly details or "event-driven/unnatural thinking" are abstracted away.
If you do not want to use processes, you have to switch to different
kind of thinking and write completely different code.

Also again, select() is not about blocking but about events.

Cheers,

Tomas
-- 
UNSUBSCRIBE: mailto:[EMAIL PROTECTED]


Re: Asyncronous IO

2008-10-10 Thread Alexander Burger
On Fri, Oct 10, 2008 at 01:17:30PM -0400, John Duncan wrote:
> If the socket is set not to block, then the socket will read as much  
> data as is available and the underlying read call will return the  

Yes, but in blocking mode it will also read only as many bytes as are
available.

> number of bytes read, right? So the poll will still be useful in an  
> nbio world.

Yep. So there is not really a fundamental difference between the
capabilities of blocking and nonblocking sockets, when select() is used.

But nonblocking mode has a few advantages in pathological situations.

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


Unsubscribe

2008-10-10 Thread Howard Gordon
Good bye Howard Gordon <[EMAIL PROTECTED]> :-(
You are now unsubscribed



-- 
UNSUBSCRIBE: mailto:[EMAIL PROTECTED]


Re: Asyncronous IO

2008-10-10 Thread John Duncan
If the socket is set not to block, then the socket will read as much  
data as is available and the underlying read call will return the  
number of bytes read, right? So the poll will still be useful in an  
nbio world.

John

On 10 Oct 2008, at 12:36 PM, Alexander Burger wrote:

> Hi Tomas,
>
>> The comment is a bit misleading as it does not prevent blocking
>> really.  The data might be available but the 'read' function might
>> still block.
>
> Yes, all those comments regarding non-blocking (also in the way Konrad
> used it) mean that during normal operations (i.e. not hanging in an
> error condition) everything will go smoothly. It does not mean
> "non-blocking" in the technical sense. But for those "normal"
> operations, it goes surprisingly well when messages observe the  
> PIPE_BUF
> limit. So the *application* is non-blocking, not the underlying
> protocol. Without *Run and (poll) the input would always block even  
> on a
> single input channel.
>
> Cheers,
> - Alex
> -- 
> UNSUBSCRIBE: mailto:[EMAIL PROTECTED]

-- 
UNSUBSCRIBE: mailto:[EMAIL PROTECTED]


Re: Asyncronous IO

2008-10-10 Thread Alexander Burger
Hi Tomas,

> The comment is a bit misleading as it does not prevent blocking
> really.  The data might be available but the 'read' function might
> still block.

Yes, all those comments regarding non-blocking (also in the way Konrad
used it) mean that during normal operations (i.e. not hanging in an
error condition) everything will go smoothly. It does not mean
"non-blocking" in the technical sense. But for those "normal"
operations, it goes surprisingly well when messages observe the PIPE_BUF
limit. So the *application* is non-blocking, not the underlying
protocol. Without *Run and (poll) the input would always block even on a
single input channel.

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


Re: picoWiki

2008-10-10 Thread Henrik Sarvell
I could help with implementing the code highlighting I have on
prodevtips, it's all happening in the client through javascript, very
easy actually, you simply need the ability to add html in the content,
if the necessary javascript files are included then you can do:





And all pico lisp code in the code block will be highlighted.

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


Re: Asyncronous IO

2008-10-10 Thread Tomas Hlavaty
Hi Alex,

http://www.software-lab.de/refP.html#poll says:

   (poll 'cnt) -> cnt | NIL

   Checks for the availability of data for reading on the file
   descriptor cnt. See also open, in and close.

   : (and (poll *Fd) (in @ (read)))  # Prevent blocking

The comment is a bit misleading as it does not prevent blocking
really.  The data might be available but the 'read' function might
still block.

Cheers,

Tomas
-- 
UNSUBSCRIBE: mailto:[EMAIL PROTECTED]


Re: Asyncronous IO

2008-10-10 Thread Tomas Hlavaty
Hi Konrad,

> 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.

I would say that select (in C) and task and *Run (in picolisp) do not
have anything to do with blocking i/o.  It has to do something with
the concept of asynchronous.  In other words, when the process does
not have anything to do, it goes to sleep by calling select and when
there is some event on the registered file descriptors (e.g. read or
write is possible), the process is woken up.

Whether i/o is blocking or not is a property of the file/socket and
i/o functions.  So what gives you non-blocking reads and writes is
setting the file to non-blocking mode and then handling "partial" i/o
data in a specific way.

Cheers,

Tomas
-- 
UNSUBSCRIBE: mailto:[EMAIL PROTECTED]


Re: picoWiki

2008-10-10 Thread Tomas Hlavaty
Hi Konrad,

> 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.

I have mixed emotions about this one.  A link to the original
documents might be enough (maybe with some elaboration in the
picoWiki) but I admit it is a pain when I need to search for something
and have to search through a few docs separately.  Maybe the search
function could search the picoWiki pages and a few external documents?

Any ideas how to implement the search functionality/algorithm?  I
wanted to get inspired by CLiki but I did not manage to download it as
the server was down.

> 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.

Yes.  And the author does not mind when we pick his brain:-)

> 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.

Same here;-)

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

That would be great.  Feel free to do that, it will take some time for
the content to get into a good shape.

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

Well, "occasional" syntax highlighting is just a side effect.  If I
find a symbol from the ref.hmtl inside the  tag, I simply create
a link to it.  It might be possible to do more syntax highliting, like
for example paste.lisp.org does which is quite neet.

Now the code is:

===

(setq *Xref
   (mapcar pack '(new  sym  ...)))

(de xtok (L)
   (when (member (car L) '("(" " " "^I" "^J" "^M"))
  (let L (cdr L)
 (make
(until (or (not L) (member (car L) '(")" " " "^I" "^J" "^M")))
   (link (car L))
   (setq L (cdr L)))

(de xref (L)
   (let? Tok (xtok L)
  (let Tok2 (pack Tok)
 (when (member Tok2 *Xref)
(cons
   Tok2
   (pack "http://www.software-lab.de/ref";
  (cond
 ((= "*" (car Tok))
  (uppc (cadr Tok)))
 ((member (lowc (car Tok))
 (chop "abcdefghijklmnopqrstuvwxyz"))
  (uppc (car Tok)))
 (T "_"))
  ".html#" Tok))
   
(de markupLisp (B)
   (let X (chop B)
  (while X
 (ifn (xref X)
(ht:Prin (pop 'X))
(prin (pop 'X))
( (car @) (cdr @))
(do (length (car @)) (pop 'X))

===

Cheers,

Tomas
-- 
UNSUBSCRIBE: mailto:[EMAIL PROTECTED]


Re: Asyncronous IO

2008-10-10 Thread Tomas Hlavaty
One bug fix:

any eagain(any ex __attribute__((unused))) {
   return boxCnt(EAGAIN);
}

should be

any eagain(any ex __attribute__((unused))) {
   return boxCnt(-EAGAIN);
}

as (eagain) should be a negative value.  Negative values returned by
rdx and wrx mean errno. And, EAGAIN value returned by rdx or wrx
should not end the the callback task.

(unless (or (gt0 N) (= N 'EAGAIN))
   (setq End (cons rd N)

It "worked" for me yesterday because I did not test the "negative"
example which would verify that it really is not blocking.

>abu:~/pico ./p dbg.l
>: (connect "localhost" )
>-> 3
>: (out 3 (wr 1 2 3 254 255))
>-> 255

I used (out 3 (prinl "hi")) yesterday (or similar), and then I could
read the data back (in S (line T)).  I was quite surpriced how much
data I could write in the socket without reading out of it and still
didn't get any error.  I still probably didn't send enough data to
fill the buffers.

> The difficult thing might be the negative test. Perhaps send a *lot*
> of data, and do some "ifconfig xxx down" in between?

Probably.  I could not find much on Google, maybe
http://lkml.org/lkml/2002/7/22/77 but haven't looked into it yet.  It
might be enough to put a print statement for eagain case, try some
heavy load testing, maybe try to disrupt it somehow as you suggest (or
introduce back the above bug) and see what happens.  So, unless
somebody finds it blocks I would consider it non-blocking for now;-)

> There is already a closure for 'Sock'

I see.

> should also work. But you could put your buffer there:
>
>(task @
>   Buffer (need 5)
>   (callback @ Buffer) )
>

Yes.

For Konrad's chat application, the buffer should be shared by all
callbacks as it is now.  It might be handy to have it local for other
applications.  Also, now the buffer is fixed sized which is one way of
implementing it and has its pros and cons.

There could be versions of rdx wrx which would use 'fifo' instead and
this would provide "unbounded" buffer.  The buffer management would be
simpler in this case but I am not sure whether it is a good idea
having no constraints on i/o buffers.

>> also be useful if it would be possible optionally switch on -g without
>> having to modify the gcc.l file.
>
> I would use 'patch' in such a case:
>
>(patch gcc
>   '(apply @A "-o" @Z)
>   (append '(apply) @A '("-g" "-o") @Z) )

Nice trick:-)

Thanks,

Tomas
-- 
UNSUBSCRIBE: mailto:[EMAIL PROTECTED]


Re: Asyncronous IO

2008-10-10 Thread Alexander Burger
Hi Konrad,

> 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.

Yep, this is also needed.


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

Right. The syntax of *Run (positive file descriptors, negative timeouts)
does not allow such a specification. Internally, file descriptors for
writing are used, but currently only for interprocess pipes.

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


Re: Asyncronous IO

2008-10-10 Thread Alexander Burger
Hi Tomas,

> I attach a simple non-blocking echo server.  There are some functions

Nice!

> Conceptually it should not block, I am not sure how to test it though.
> Any ideas?

Positive testing works well:

   abu:~/pico ./p dbg.l nb-ex.l
   : (more *Run)
   (5 (when (accept @) (task @ Sock @ (callback Sock
   -> NIL

second process

   abu:~/pico ./p dbg.l
   : (connect "localhost" )
   -> 3
   : (out 3 (wr 1 2 3 254 255))
   -> 255

first process

   callback 3 J=0 I=0 N=5
 read 5
 written 5
 rotate J=5 I=5 N=5
   end 3 J=0 I=0 N=5

   : *B 
   -> (1 2 3 254 255)

   : (more *Run)
   (3 (job '((Sock . 3)) (callback Sock)))
   (5 (when (accept @) (task @ Sock @ (callback Sock
   -> NIL

:-)

The difficult thing might be the negative test. Perhaps send a *lot* of
data, and do some "ifconfig xxx down" in between?



> - buffer could be local for the sockets, so 'callback' should be a
>   closure...  I guess I would have to use 'job' but that's next lesson
>   I have to look at:-)

There is already a closure for 'Sock'

   (task (port ) # Listen on port 
  (when (accept @)   # A connect arrived
 (task @ # Install another task on this socket
Sock @   # Keep the socket in the task's env
(callback Sock) ) ) )

resulted in (see above)

   (3 (job '((Sock . 3)) (callback Sock)))

Strictly speaking, the 'Sock' variable would not be necessary here,
because '@' is already bound to the file descritor when the task's body
is called. So a simple

   (task @ (callback @))

should also work. But you could put your buffer there:

   (task @
  Buffer (need 5)
  (callback @ Buffer) )

or similar.


> There should really be -m32 switch in the 'gcc' function.  It would

Thanks for the tip! I'll include it.


> also be useful if it would be possible optionally switch on -g without
> having to modify the gcc.l file.

I would use 'patch' in such a case:

   (patch gcc
  '(apply @A "-o" @Z)
  (append '(apply) @A '("-g" "-o") @Z) )

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