Bill
While David has given you an answer to your immediate query, I would
ask you to step back and consider whether you're sure you really need
references. You haven't supplied enough context for us to make that
call.
-Per
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clo...@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+u...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
>
> To unsubscribe from this group, send email to clojure+unsubscribegooglegroups.com or reply to this email with the words "REMOVE ME" as the subject.
>
(def savedColors [black, white])
.....
(defn saveColor [color panel]
(swap! savedColors (conj savedColors color)) <-- this does not
work
..... also show the colors in the editor
))
I get the following error:
Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException:
clojure.lang.PersistentVector cannot be cast to clojure.lang.Atom
I assume I'm using swap! correctly, but may not be.
Bill
On Mar 23, 9:57 am, Per Vognsen <per.vogn...@gmail.com> wrote:
> By definition, persistent data structures are never mutable. But there
> are various kinds of mutable references (vars, refs, atoms, agents)
> that can _refer_ to persistent (hence unchanging) data structures.
>
> While David has given you an answer to your immediate query, I would
> ask you to step back and consider whether you're sure you really need
> references. You haven't supplied enough context for us to make that
> call.
>
> -Per
>
> On Tue, Mar 23, 2010 at 8:35 PM, WoodHacker <ramsa...@comcast.net> wrote:
> > I understand howconjworks. But how do you add a value to a
> > persistent vector? You have to add the new item to the vector with
> > (conjvector item), but how do you assign the return value to the
> > persistent vector. So far I have it working with a def -- (def
> > vector (conjvector item)) -- but I'm not sure this is 'pure'
Actually, swap! doesn't seem to work in my case. I should state
what I'm
trying to do. I'm writing a graphics editing program where I want
the user
to be able to choose and save color values. I start out with a
vector
containing blank and white. When the user selects a new color and
wants
to save it I add the new color to the vector.
(def savedColors [black, white])
.....
(defn saveColor [color panel]
(swap! savedColors (conj savedColors color)) <-- this does not
--
On Wed, Mar 24, 2010 at 02:43:49PM -0700, WoodHacker wrote:
> (def savedColors [black, white])
(def savedColors (atom [black white]))
> Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException:
> clojure.lang.PersistentVector cannot be cast to clojure.lang.Atom
This message should be pretty obvious, no?
Sincerely
Meikel
The issue is adding a value to a defined vector - (def savedColors
[black, white])
One solution was given as: (swap! savedColors conj newcolor)
This produces still the following runtime error:
Exception in thread "AWT-EventQueue-0"
java.lang.ClassCastException: clojure.lang.PersistentVector cannot
be cast to clojure.lang.Atom
Another solution was to make savedColors an atom - (def savedColors
(atom [black, white]))
This produces a new compile error:
Exception in thread "AWT-EventQueue-0"
java.lang.IllegalArgumentException: Don't know how to create ISeq
from: clojure.lang.Atom
Changing savedColors to a list instead of a vector gets the same
error. The atom example on the web is for a map.
I'm sure this can be done. So far I just don't know how.
Bill
The def cannot produce that error. You probably mean that it
originates with some reference to savedColors that is expecting a
sequence. You must explicitly dereference savedColors by prefixing it
with @ to get at the contained value:
user> (def saved-colors (atom [1, 2]))
#'user/saved-colors
user> (doseq [x @saved-colors] (println "Saved color:" x))
Saved color: 1
Saved color: 2
nil
-Per
When you conj something onto a vector, it doesn't change that vector;
it returns a new vector. The new vector reuses the old one's memory
for efficiency, but if you look at the old one it doesn't have the new
member. It's unchanged.
What can change are references. So you can make a reference to the
vector, and then build a new vector with the new items, and then
change the reference to point to the new vector. That's what (swap!)
does.
But you have to have a reference to start with. Which (atom) gives
you. But a reference is not the same as a vector; you can't use it
directly when you need a vector, but must dereference it with @.
Example:
Clojure 1.1.0
user=> (def start-colors [:black :white])
#'user/start-colors
user=> (def saved-colors (atom start-colors))
#'user/saved-colors
user=> start-colors
[:black :white]
user=> @saved-colors
[:black :white]
user=> (swap! saved-colors conj :red)
[:black :white :red]
user=> start-colors
[:black :white]
user=> saved-colors
#<Atom@1d256fa: [:black :white :red]>
user=> @saved-colors
[:black :white :red]
user=>
--
Mark J. Reed <mark...@gmail.com>