Re: Mutually-referencing structures

2010-04-06 Thread Christophe Grand
On Mon, Apr 5, 2010 at 4:54 PM, Douglas Philips d...@mac.com wrote:

 Immutability is orthogonal to reference-ness.
 There is nothing wrong with having immutable cyclic graphs of values.


There is something wrong with immutable cyclic data structures: an undefined
(or unexpected) behaviour on update because of identity and state being
conflated again.

Let say one can write:
(def john-doe {:name John Doe :email j...@doe.com :account {:owner
#cyclic reference to the root map :balance 1000}})

Then you want to add 10$ to John's account:
(update-in john-doe [:account :balance] + 10)

The resulting data structure is:
{:name John Doe :email j...@doe.com :account {:owner #cyclic reference
to the root map :balance 1010}}

but what would #cyclic reference to the root map point to? to the previous
value of john-doe! So if we expands the reference:
{:name John Doe :email j...@doe.com :account {:owner {:name John Doe
:email j...@doe.com :account {:owner #cyclic reference to the root map
:balance 1000}} :balance 1010}}

This is not exactly the expected result. The result is confusing because the
cyclic reference must be to the identity of the user account not to its
actual value.

The same problem arises even when you update a non-nested field:
(assoc john-doe :email john@corp.com)

The resulting value would be:
{:name John Doe :email john@corp.com :account {:owner {:name John
Doe :email j...@doe.com :account {:owner #cyclic reference to the root
map :balance 1000}} :balance 1000}}

You really need an indirection level to properly handle cyclic data
structures.

hth,

Christophe

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

To unsubscribe, reply using remove me as the subject.


Re: Mutually-referencing structures

2010-04-06 Thread Sophie
On Apr 6, 8:09 am, Christophe Grand christo...@cgrand.net wrote:

 Let say one can write:
 (def john-doe {:name John Doe :email j...@doe.com :account {:owner
 #cyclic reference to the root map :balance 1000}})

At this point the cyclic structure is a consistent value. As long as
updates create new values that match the domain invariants, why should
any subsequent value cause a  problem?

 Then you want to add 10$ to John's account:
 (update-in john-doe [:account :balance] + 10)

If that is what you update, then of course you will get ...

 The resulting data structure is:
 {:name John Doe :email j...@doe.com :account {:owner #cyclic reference
 to the OLD root map :balance 1010}}

But how is this unique to cyclic structures? I can always mistakenly
create values and update them to end up with a structure that
incorrectly combines old and new values.

(def john-doe {zip-code: 12345 state: {name: CA}})

(update-in john-doe [:zip-code] + 5000)
;; new zip code, invalid old state

Maintaining domain invariants is the programmers responsibility,
whether or not there are cyclic references. Why wouldn't the same
facility that lets you create consistent mutual references in the
original John Doe value, also allow you to create consistent mutual
references in a consistent new (updated) John Doe value?

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

To unsubscribe, reply using remove me as the subject.


Re: Mutually-referencing structures

2010-04-06 Thread Douglas Philips

On 2010 Apr 6, at 9:09 AM, Christophe Grand wrote:

On Mon, Apr 5, 2010 at 4:54 PM, Douglas Philips d...@mac.com wrote:
Immutability is orthogonal to reference-ness.
There is nothing wrong with having immutable cyclic graphs of  
values.


There is something wrong with immutable cyclic data structures: an  
undefined (or unexpected) behaviour on update because of identity  
and state being conflated again.

... details elided ...
This is not exactly the expected result. The result is confusing  
because the cyclic reference must be to the identity of the user  
account not to its actual value.



(def john-doe {:name John Doe :email j...@doe.com})

(def account {:identity john-doe :balance 100} )

(assoc john-doe :email john.doe at gee mail.com)

Now the account contains old/obsolete data and no cycles are needed to  
cause that.


Doesn't seem that cycles are the problem...

-Doug

--
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

To unsubscribe, reply using remove me as the subject.


Re: Mutually-referencing structures

2010-04-06 Thread Laurent PETIT
The question of the OP was also a practical one : is either Clojure
or functional not a good match?

Honestly, I don't know the answer for sure, because:

  * there is still no (widely known ?) utilities to manipulate things
easily. There were attemps like the one by Jeffrey Streizhem in
clojure contrib, (dataset / datalog), but who's using it for real ?
  * The STM is indeed easy to work with, by using the metaphore of the
database (and i think it is the right way of doing things. functions,
and macros to generate some of those functions can help managing the
necessary level of indirection).
* BUT : isn't the real problem that one will not content
[him/her]/self with playing with in-memory data ? One will want to
make the data persistent (outside-of-process, aka
storage-persistance). And with this kind of problem, one will have a
graph of identities containing references to other identities (the
needed level(s) of indirection). How does one painlessly store/unstore
those graphs to databases ?

Not to say: how does one totally reliably move data from the STM
to/from an RDBMS ? Currently, the trick is to send things to an
agent, but this does not provide all the required guarantees ...


So from the practical point of view, I'm not sure (alas) if clojure
has -yet- the expected YES! answer ...


2010/4/6 Douglas Philips d...@mac.com:
 On 2010 Apr 6, at 9:09 AM, Christophe Grand wrote:

 On Mon, Apr 5, 2010 at 4:54 PM, Douglas Philips d...@mac.com wrote:
 Immutability is orthogonal to reference-ness.
 There is nothing wrong with having immutable cyclic graphs of values.

 There is something wrong with immutable cyclic data structures: an
 undefined (or unexpected) behaviour on update because of identity and state
 being conflated again.

 ... details elided ...

 This is not exactly the expected result. The result is confusing because
 the cyclic reference must be to the identity of the user account not to its
 actual value.


 (def john-doe {:name John Doe :email j...@doe.com})

 (def account {:identity john-doe :balance 100} )

 (assoc john-doe :email john.doe at gee mail.com)

 Now the account contains old/obsolete data and no cycles are needed to cause
 that.

 Doesn't seem that cycles are the problem...

        -Doug

 --
 You received this message because you are subscribed to the Google
 Groups Clojure group.
 To post to this group, send email to clojure@googlegroups.com
 Note that posts from new members are moderated - please be patient with your
 first post.
 To unsubscribe from this group, send email to
 clojure+unsubscr...@googlegroups.com
 For more options, visit this group at
 http://groups.google.com/group/clojure?hl=en

 To unsubscribe, reply using remove me as the subject.


-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: Mutually-referencing structures

2010-04-06 Thread Christophe Grand
On Tue, Apr 6, 2010 at 3:41 PM, Sophie itsme...@hotmail.com wrote:

 On Apr 6, 8:09 am, Christophe Grand christo...@cgrand.net wrote:
 
  Let say one can write:
  (def john-doe {:name John Doe :email j...@doe.com :account {:owner
  #cyclic reference to the root map :balance 1000}})

 At this point the cyclic structure is a consistent value.


True.





  Then you want to add 10$ to John's account:
  (update-in john-doe [:account :balance] + 10)

 If that is what you update, then of course you will get ...

  The resulting data structure is:
  {:name John Doe :email j...@doe.com :account {:owner #cyclic
 reference
  to the OLD root map :balance 1010}}

 But how is this unique to cyclic structures?


If your structures aren't cyclic the newly updated value can't accidentally
contain references to its previous self.



 I can always mistakenly
 create values and update them to end up with a structure that
 incorrectly combines old and new values.


Sure.


Maintaining domain invariants is the programmers responsibility,
 whether or not there are cyclic references. Why wouldn't the same
 facility that lets you create consistent mutual references in the
 original John Doe value, also allow you to create consistent mutual
 references in a consistent new (updated) John Doe value?


What if you also want an history or a log in your data structure, pointing
to previous value? Then you wouldn't want these references to be updated by
the mechanism which create consistent mutual references. So you would put a
marker on it to say it is static.
At the end you have a complex system which walks the data-structure and
tracks all mutual references to update them all at once (except those which
are marked as static). This is nearly the description of the Clojure STM
except that with the STM you mark the references which need to be updated
all at once not those which don't.

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

To unsubscribe, reply using remove me as the subject.


Re: Mutually-referencing structures

2010-04-06 Thread Christophe Grand
On Tue, Apr 6, 2010 at 3:43 PM, Douglas Philips d...@mac.com wrote:

  (def john-doe {:name John Doe :email j...@doe.com})

 (def account {:identity john-doe :balance 100} )

 (assoc john-doe :email john.doe at gee mail.com)

 Now the account contains old/obsolete data and no cycles are needed to
 cause that.

 Doesn't seem that cycles are the problem...


The cycles are gone but the identity john-doe aand its curren-state are
still conflated so you get the same problem:
(def account {:identity john-doe :balance 100} )
(assoc john-doe :email john.doe at gee mail.com)

On the first line you define a reference between the current value of
account and the current value of john-doe, so it is to be expected that
(assoc john-doe :email john.doe at gee mail.com) won't give the expected
result since you didn't provided the system with enough knowledge.

(def account {:identity #'john-doe :balance 100} )
(def john-doe (assoc john-doe :email john.doe at gee mail.com))
; or (alter-var-root #'john-doe assoc :email john.doe at gee mail.com)

there account points to the updated john-doe

Of course, one should not abuse vars, and the above code should at least be
rewritten with refs:

(def account (ref {:identity john-doe :balance 100}) )
(def john-doe (ref {:name John Doe :email j...@doe.com}))
(dosync (alter john-doe assoc :email john.doe at gee mail.com))

Really, to me the problem isn't creating cyclic data-structures but updating
them: the system must know which mutual references are to the identity (and
should be updated) and which are not. You have to give this information to
the system one way or the other, the system can't guess.

Btw, to some extent, one can create cyclic data-structures in Clojure (only
lazyseqs though -- unless you implement your own map or use lazy-map etc.) :
user= (defn cyclic-seq [coll] (let [s (promise)] @(deliver s (lazy-cat coll
@s
user= (let [s (cyclic-seq [1 2 3])] (identical? (seq s) (seq (drop 3 s
true

Christophe

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

To unsubscribe, reply using remove me as the subject.


Re: Mutually-referencing structures

2010-04-06 Thread Per Vognsen
On Tue, Apr 6, 2010 at 9:59 PM, Christophe Grand christo...@cgrand.net wrote:
 Btw, to some extent, one can create cyclic data-structures in Clojure (only
 lazyseqs though -- unless you implement your own map or use lazy-map etc.) :
 user= (defn cyclic-seq [coll] (let [s (promise)] @(deliver s (lazy-cat coll
 @s
 user= (let [s (cyclic-seq [1 2 3])] (identical? (seq s) (seq (drop 3 s
 true

I've already mentioned it a few times in passing, but my letrec macro
uses promises and some simple-minded code walking to abstract away
this kind of thing. The included example code is a pair of mutually
cyclic lazy-seqs.

http://gist.github.com/336461

-Per

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

To unsubscribe, reply using remove me as the subject.


Re: Mutually-referencing structures

2010-04-06 Thread Douglas Philips

On 2010 Apr 6, at 10:59 AM, Christophe Grand wrote:
The cycles are gone but the identity john-doe aand its curren-state  
are still conflated so you get the same problem:


Thus, since simple trees have the exact same issues, circularity is  
not the problem.



Really, to me the problem isn't creating cyclic data-structures but  
updating them: the system must know which mutual references are to  
the identity (and should be updated) and which are not. You have to  
give this information to the system one way or the other, the system  
can't guess.


To rephrase what you've said:
the system must know which references are to the identity and  
which are not.
Clojure already has that covered, but it won't do it for you behind  
your back. :)
And this is not unique to circularity and it is not caused by  
circularity.


There is an issue that you cannot create immutable mutual references,  
but that is a -separate- issue.



Btw, to some extent, one can create cyclic data-structures in  
Clojure...


I think Per was showing something similar.

Please don't blame circularity for identity/value problems. ;)

-Doug

--
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

To unsubscribe, reply using remove me as the subject.


Re: Mutually-referencing structures

2010-04-06 Thread Per Vognsen
On Tue, Apr 6, 2010 at 10:43 PM, Douglas Philips d...@mac.com wrote:
 On 2010 Apr 6, at 10:59 AM, Christophe Grand wrote:

 The cycles are gone but the identity john-doe aand its curren-state are
 still conflated so you get the same problem:

 Thus, since simple trees have the exact same issues, circularity is not the
 problem.

I agree. The deeper problem there is identity-value conflation rather
than circularity.

As for the general problem of manipulating immutable cyclic data
structures, it admittedly requires techniques not usually taught even
in advanced courses on functional programming. A good paper to read is
Cycle Therapy:

http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.64.2027


-Per

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

To unsubscribe, reply using remove me as the subject.


Re: Mutually-referencing structures

2010-04-06 Thread Michael Gardner
On Apr 6, 2010, at 9:01 AM, Laurent PETIT wrote:

* BUT : isn't the real problem that one will not content
 [him/her]/self with playing with in-memory data ? One will want to
 make the data persistent (outside-of-process, aka
 storage-persistance). And with this kind of problem, one will have a
 graph of identities containing references to other identities (the
 needed level(s) of indirection). How does one painlessly store/unstore
 those graphs to databases ?

XML with ID/IDREFs seems the obvious choice.

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

To unsubscribe, reply using remove me as the subject.


Re: Mutually-referencing structures

2010-04-06 Thread Sophie
I would really love to see (clearly by someone much smarter than I :)
an insightful summary of these kinds of concept-heavy discussions,
stickied or FAQd or even book'd somewhere.

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

To unsubscribe, reply using remove me as the subject.


Mutually-referencing structures

2010-04-05 Thread Sophie
(deftype Account [owner balance])
(deftype Person [accounts])

joe has 1 account.

How to I create / initialize joe  the account with mutual references?
I'd rather not use refs.

Thanks!

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

To unsubscribe, reply using remove me as the subject.


Re: Mutually-referencing structures

2010-04-05 Thread Michael Gardner
On Apr 5, 2010, at 2:09 AM, Sophie wrote:

 (deftype Account [owner balance])
 (deftype Person [accounts])
 
 joe has 1 account.
 
 How to I create / initialize joe  the account with mutual references?
 I'd rather not use refs.

You can't do it directly without one of the two being mutable. But you could 
simulate it by assigning each object a unique ID and having them refer to each 
other by that ID.

-Michael

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: Mutually-referencing structures

2010-04-05 Thread Per Vognsen
You need a level of indirection. One way is to make the backward
reference from accounts to owners be based on a non-pointer primary
key (maybe a keyword) that can be resolved through some table. This is
how it works in relational database systems

If you want to use references of some sort, mutability (possibly
implicit) is required. Here's an example of implicit mutation via
delay/force:

(deftype Account [owner balance])
(deftype Person [name accounts])

(declare per)

(def per-account1 (Account (delay per) 42))
(def per-account2 (Account (delay per) 9000))

(def per (Person Per [per-account1, per-account2]))

(:name @(:owner per-account1)) ;; Per

Note that you will need to dereference backward references explicitly.

In this example, I also relied on forward declaration of vars for
tying the circular knots. If you want to this within functions, you'll
need something like letrec. Here's a proof of concept I did a while
ago:

http://gist.github.com/336461

With that, you could write the above as follows:

(letrec [per-account1 (Account (delay per) 42)
   per-account2 (Account (delay per) 9000)
   per (Person Per [(delay per-account1), (delay per-account2)])]
  (:name @(:owner per-account1)))

Unfortunately, because of the way my letrec implementation works,  you
will need to delay both forward and backward references.

By the way, as you will quickly see if you play around with this kind
of code in the REPL, you must be careful with circular references:
it's very easy to send the printer into an infinite loop. You can do a
(set! *print-level* some small number) to prevent this from
happening.

-Per

On Mon, Apr 5, 2010 at 2:09 PM, Sophie itsme...@hotmail.com wrote:
 (deftype Account [owner balance])
 (deftype Person [accounts])

 joe has 1 account.

 How to I create / initialize joe  the account with mutual references?
 I'd rather not use refs.

 Thanks!

 --
 You received this message because you are subscribed to the Google
 Groups Clojure group.
 To post to this group, send email to clojure@googlegroups.com
 Note that posts from new members are moderated - please be patient with your 
 first post.
 To unsubscribe from this group, send email to
 clojure+unsubscr...@googlegroups.com
 For more options, visit this group at
 http://groups.google.com/group/clojure?hl=en

 To unsubscribe, reply using remove me as the subject.


-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: Mutually-referencing structures

2010-04-05 Thread Sophie
Is this a Clojure restriction, or is it intrinsic to functional
programming?

If my app is essentially about a user creating and editing a graph
structure (sometimes via crud-level interactions, other times by
somewhat larger refactorings), is either Clojure or functional not a
good match?

Thanks for any advice!

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

To unsubscribe, reply using remove me as the subject.


Re: Mutually-referencing structures

2010-04-05 Thread Michael Gardner
On Apr 5, 2010, at 7:49 AM, Sophie wrote:

 Is this a Clojure restriction, or is it intrinsic to functional
 programming?

It's a consequence of immutable data structures, which are an aspect of 
functional programming. An immutable object can never be changed, and you can't 
create multiple objects simultaneously, so you can't ever get a cycle of direct 
references between immutable objects.

 If my app is essentially about a user creating and editing a graph
 structure (sometimes via crud-level interactions, other times by
 somewhat larger refactorings), is either Clojure or functional not a
 good match?

You can still do things functionally, with a level of indirection. I don't see 
any problem with that approach, but whether it's a good match for your project 
is up to you.

Otherwise, you can use mutable structures. Clojure certainly supports 
mutability, but as a primarily-functional language it might not be the right 
tool for the job if you're going to use mutability extensively.

-Michael

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

To unsubscribe, reply using remove me as the subject.


Re: Mutually-referencing structures

2010-04-05 Thread Sophie
 It's a consequence of immutable data structures, which are an aspect of 
 functional programming. An immutable object can never be changed

But single-assignment is a quite valid (and more flexible?)  form of
immutability. I'm not convinced cycles are intrinsically tied to it in
any way.

(In fact, I initially thought Clojure had an unambiguous sentinel
value for not initialized)

I was hoping to develop (or find :) macros to automate the code for
maintaining various kinds of 2-way pointers, rather than use separate
ID fields or (essentially global) collections of pairs for relations.

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

To unsubscribe, reply using remove me as the subject.


Re: Mutually-referencing structures

2010-04-05 Thread Michael Gardner
On Apr 5, 2010, at 4:34 PM, Sophie wrote:

 But single-assignment is a quite valid (and more flexible?)  form of
 immutability. I'm not convinced cycles are intrinsically tied to it in
 any way.

If you can assign to it, it's mutable. What you're talking about is creating a 
mutable object, then making it immutable at some point (say, after it's first 
assigned to). Immutable object cycles are indeed possible if one permits this; 
Clojure doesn't, at least not for simple objects.

-Michael

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

To unsubscribe, reply using remove me as the subject.


Re: Mutually-referencing structures

2010-04-05 Thread Per Vognsen
It's no more mutable than a pure lambda calculus with lazy evaluation.
There is no _observable_ mutability. Anything else is an
implementation detail.

Single assignment comes from the tradition of logic programming and
concurrent process calculus rather than lambda calculus. A single
assignment variable is a lot like a pure promise. By pure I mean that
one cannot peek at the promise without blocking on it. This is
all-important in preventing race conditions in a concurrent setting.

If Sophie is interested, I used promises as single assignment
variables in the letrec implementation I posted.

It's fair to say that while Clojure supports single assignment
variables in the form of promises, they are not fundamental
language-level constructs the way they are in languages like Prolog or
Oz. You have to explicitly dereference them like any other IDeref.

-Per

On Tue, Apr 6, 2010 at 6:53 AM, Michael Gardner gardne...@gmail.com wrote:
 On Apr 5, 2010, at 4:34 PM, Sophie wrote:

 But single-assignment is a quite valid (and more flexible?)  form of
 immutability. I'm not convinced cycles are intrinsically tied to it in
 any way.

 If you can assign to it, it's mutable. What you're talking about is creating 
 a mutable object, then making it immutable at some point (say, after it's 
 first assigned to). Immutable object cycles are indeed possible if one 
 permits this; Clojure doesn't, at least not for simple objects.

 -Michael

 --
 You received this message because you are subscribed to the Google
 Groups Clojure group.
 To post to this group, send email to clojure@googlegroups.com
 Note that posts from new members are moderated - please be patient with your 
 first post.
 To unsubscribe from this group, send email to
 clojure+unsubscr...@googlegroups.com
 For more options, visit this group at
 http://groups.google.com/group/clojure?hl=en

 To unsubscribe, reply using remove me as the subject.


-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en