Re: Is Transactional Memory Relevant to PicoLisp?

2011-09-10 Thread Henrik Sarvell
In Clojure there are a few constructs and functions to handle them that make
use of this to keep multithreaded apps sane: http://clojure.org/refs

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

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:
http://www.mail-archive.com/picolisp@software-lab.de/msg01743.html

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

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)

(bye)

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

However when you are manipulating database objects you can enforce by
yourself:

(de addToFoo (Num)
   (dbSync)
   (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 ja...@vmlinux.org 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
  --
  UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe
 --
 UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe



Re: Is Transactional Memory Relevant to PicoLisp?

2011-09-10 Thread Henrik Sarvell
End result of 9 of course.


On Sat, Sep 10, 2011 at 9:55 PM, Henrik Sarvell hsarv...@gmail.com wrote:

 In Clojure there are a few constructs and functions to handle them that
 make use of this to keep multithreaded apps sane: http://clojure.org/refs

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

 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:
 http://www.mail-archive.com/picolisp@software-lab.de/msg01743.html

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

 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)

 (bye)

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

 However when you are manipulating database objects you can enforce by
 yourself:

 (de addToFoo (Num)
(dbSync)
(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 ja...@vmlinux.org 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
  --
  UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe
 --
 UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe