In Clojure there are a few constructs and functions to handle them that make
use of this to keep multithreaded apps sane:

However, in the course of developing web apps I've only used them when I
want different request to share a piece of storage that needs to be updated
very often and not written to disk all the time.

In that scenario Clojure makes everything very easy through deref and

In PicoLisp if you create *Foo and set it to say 1 child processes spawned
by http requests can read that variable just fine, if they want to update it
they can use boss, this has been discussed before:

In Clojure it could work like this:
1.) Foo is 1.
2.) Thread 1 wants to change the value of Foo and this operation ends up
taking 2s and Foo will end up being 10 afterwards.
3.) While thread 1 is manipulating Foo thread 2 is spawned, now thread 2 has
to wait for 1 to finish and gets 10 as input value, thread 2 only wants to
multiply Foo with 2.
4.) Thread 2 is finished and Foo ends up being 20.

The end result is something that is expected by all users of the application
should they compare notes because user 2 who spawned thread 2 might expect
the result to be 1 * 2 = 2, however after talking with user 1 who spawned
thread 1 they realize that user 1 was in fact there first and the result is
the expected result.

The fact that Clojure enforces this way of working is seen as one of it's
greatest virtues and strengths. If PicoLisp's boss works in the same way you
have the same situation where you don't have to worry about inconsistent

When I try a similar scenario in PicoLisp like this:

(load "lib/boss.l")

(setq *Foo 1)

(de addToFoo (Num)
   (wait 1000)
   (setq *Foo (+ Num *Foo)) )

(de multiplyFooWith (Num)
   (setq *Foo (* Num *Foo)))

(pipe (boss 'addToFoo 2))

(pipe (boss 'multiplyFooWith 3))

(wait 1100)

(println *Foo)


I get 5 as the output, the multiplication happens before the addition. There
is thus no inherent enforcement in boss when it comes to in-memory

However when you are manipulating database objects you can enforce by

(de addToFoo (Num)
   (wait 1000)
   (put> *Foo 'var (+ Num (; *Foo var)))
   (commit 'upd) )

(de multiplyFooWith (Num)
   (put!> *Foo 'var (* Num (; *Foo var))))

I haven't tested the above but I'm pretty sure the end result would be 6.

On Fri, Sep 9, 2011 at 11:32 PM, Jakob Eriksson <> wrote:

> On Fri, Sep 09, 2011 at 03:57:49PM +0200, Alexander Burger wrote:
> > On Fri, Sep 09, 2011 at 03:04:21PM +0200, Jakob Eriksson wrote:
> > > > ATM I cannot see how this could be useful. PicoLisp has no threads,
> and
> > >
> > > If you defined "threads" less strict, such that processes could be
> "threads",
> > > could it make sense then?
> >
> > Only if some shared/mapped memory is used, as far as I understand.
> > What advantages would you see, and for which purpose?
> Don't know, these things are over my head, I was hoping someone here
> would know more than me and say, "yes, this is good because"... :-)
> >
> > Cheers,
> > - Alex
> > --
> --

Reply via email to