Why does peek on a seq of vector fail?

2013-06-20 Thread Jason Gilman
Why does (peek (seq [1])) result in: 
ClassCastException clojure.lang.PersistentVector$ChunkedSeq cannot be cast 
to clojure.lang.IPersistentStack  clojure.lang.RT.peek (RT.java:634)

Peek documentation For a list or queue, same as first, for a vector, same 
as, but much more efficient than, last. If the collection is empty, returns 
nil. implies that there shouldn't be a problem working with vectors.

This works without issue:
(peek [1]) 

This is on Clojure 1.5.1

-- 
-- 
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
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.




Re: Why does peek on a seq of vector fail?

2013-06-20 Thread Jason Gilman
Also, I really appreciate anyone who takes the time to answer. My company 
is currently evaluating Clojure. I'm trying to determine if this is 
non-idiomatic use of the language or some other issue. Doing something like 
this can cause the bug to occur without directly calling seq on a vector:

(defn bar [my-list n]
  (if (= n 0)
  (peek my-list)
  (bar (rest my-list) (dec n
(bar [1 2 3] 1)

Both rest and peek work on a vector without a problem but the combination 
of the two causes problems.

On Thursday, June 20, 2013 3:54:43 PM UTC-4, Jason Gilman wrote:

 Why does (peek (seq [1])) result in: 
 ClassCastException clojure.lang.PersistentVector$ChunkedSeq cannot be cast 
 to clojure.lang.IPersistentStack  clojure.lang.RT.peek (RT.java:634)

 Peek documentation For a list or queue, same as first, for a vector, same 
 as, but much more efficient than, last. If the collection is empty, returns 
 nil. implies that there shouldn't be a problem working with vectors.

 This works without issue:
 (peek [1]) 

 This is on Clojure 1.5.1


-- 
-- 
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
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.




Re: Why does peek on a seq of vector fail?

2013-06-20 Thread David Nolen
Calling seq on vector returns a sequence which is no longer a vector. The
docstring is pretty specific about which types it's supposed to work on.

clojure.core/peek
([coll])
  For a list or queue, same as first, for a vector, same as, but much
  more efficient than, last. If the collection is empty, returns nil.

David


On Thu, Jun 20, 2013 at 4:11 PM, Jason Gilman jason.gil...@gmail.comwrote:

 Also, I really appreciate anyone who takes the time to answer. My company
 is currently evaluating Clojure. I'm trying to determine if this is
 non-idiomatic use of the language or some other issue. Doing something like
 this can cause the bug to occur without directly calling seq on a vector:

 (defn bar [my-list n]
   (if (= n 0)
   (peek my-list)
   (bar (rest my-list) (dec n
 (bar [1 2 3] 1)

 Both rest and peek work on a vector without a problem but the combination
 of the two causes problems.

 On Thursday, June 20, 2013 3:54:43 PM UTC-4, Jason Gilman wrote:

 Why does (peek (seq [1])) result in:
 ClassCastException clojure.lang.PersistentVector$**ChunkedSeq cannot be
 cast to clojure.lang.IPersistentStack  clojure.lang.RT.peek (RT.java:634)

 Peek documentation For a list or queue, same as first, for a vector,
 same as, but much more efficient than, last. If the collection is empty,
 returns nil. implies that there shouldn't be a problem working with
 vectors.

 This works without issue:
 (peek [1])

 This is on Clojure 1.5.1

  --
 --
 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
 ---
 You received this message because you are subscribed to the Google Groups
 Clojure group.
 To unsubscribe from this group and stop receiving emails from it, send an
 email to clojure+unsubscr...@googlegroups.com.
 For more options, visit https://groups.google.com/groups/opt_out.




-- 
-- 
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
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.




Re: Why does peek on a seq of vector fail?

2013-06-20 Thread László Török
Hi,

I think it's by design.

It only works with concrete data structure (list, vector, queue) types that
implement

clojure.lang.IPersistentStack

Las




2013/6/20 Jason Gilman jason.gil...@gmail.com

 Also, I really appreciate anyone who takes the time to answer. My company
 is currently evaluating Clojure. I'm trying to determine if this is
 non-idiomatic use of the language or some other issue. Doing something like
 this can cause the bug to occur without directly calling seq on a vector:

 (defn bar [my-list n]
   (if (= n 0)
   (peek my-list)
   (bar (rest my-list) (dec n
 (bar [1 2 3] 1)

 Both rest and peek work on a vector without a problem but the combination
 of the two causes problems.

 On Thursday, June 20, 2013 3:54:43 PM UTC-4, Jason Gilman wrote:

 Why does (peek (seq [1])) result in:
 ClassCastException clojure.lang.PersistentVector$**ChunkedSeq cannot be
 cast to clojure.lang.IPersistentStack  clojure.lang.RT.peek (RT.java:634)

 Peek documentation For a list or queue, same as first, for a vector,
 same as, but much more efficient than, last. If the collection is empty,
 returns nil. implies that there shouldn't be a problem working with
 vectors.

 This works without issue:
 (peek [1])

 This is on Clojure 1.5.1

  --
 --
 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
 ---
 You received this message because you are subscribed to the Google Groups
 Clojure group.
 To unsubscribe from this group and stop receiving emails from it, send an
 email to clojure+unsubscr...@googlegroups.com.
 For more options, visit https://groups.google.com/groups/opt_out.






-- 
László Török

-- 
-- 
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
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.




Re: Why does peek on a seq of vector fail?

2013-06-20 Thread John D. Hume
On Jun 20, 2013 3:11 PM, Jason Gilman jason.gil...@gmail.com wrote:

 (defn bar [my-list n]
   (if (= n 0)
   (peek my-list)
   (bar (rest my-list) (dec n
 (bar [1 2 3] 1)


It seems likely you want either first and rest* (to work from the front of
any seqable) or peek and pop (to work from the back of a vector or the
front of a list or queue). Combining peek and rest on a vector as the bar
function does makes no sense, since they work at opposite ends.

*or next in place of rest.

-- 
-- 
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
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.




Re: Why does peek on a seq of vector fail?

2013-06-20 Thread Jason Gilman
I think I get the difference now between a sequence, list, and a vector. Thanks 
for the quick answers. 

On Jun 20, 2013, at 5:14 PM, John D. Hume duelin.mark...@gmail.com wrote:

 On Jun 20, 2013 3:11 PM, Jason Gilman jason.gil...@gmail.com wrote:
 
  (defn bar [my-list n]
(if (= n 0)
(peek my-list)
(bar (rest my-list) (dec n
  (bar [1 2 3] 1)
 
 
 It seems likely you want either first and rest* (to work from the front of 
 any seqable) or peek and pop (to work from the back of a vector or the front 
 of a list or queue). Combining peek and rest on a vector as the bar function 
 does makes no sense, since they work at opposite ends.
 
 *or next in place of rest.
 
 -- 
 -- 
 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
 --- 
 You received this message because you are subscribed to a topic in the Google 
 Groups Clojure group.
 To unsubscribe from this topic, visit 
 https://groups.google.com/d/topic/clojure/7DzLLsmnm-E/unsubscribe.
 To unsubscribe from this group and all its topics, send an email to 
 clojure+unsubscr...@googlegroups.com.
 For more options, visit https://groups.google.com/groups/opt_out.
  
  

-- 
-- 
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
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.




Re: seq and vector

2008-11-24 Thread Rich Hickey



On Nov 24, 2:41 am, [EMAIL PROTECTED] [EMAIL PROTECTED]
wrote:
 On Nov 24, 12:41 am, Kevin Downey [EMAIL PROTECTED] wrote:

  I don't think you understand. clojure data structures are IMMUTABLE.
  every call to conj, or anyother function returns a new object. To
  optimize there is sharing of structure.

 In the particular case at hand, i.e. calling vec on a seq, there is no
 structural sharing involved. On the contrary a new Object array of the
 same length as the seq is created. See RT.seqToArray for details.

This is going around in circles.

If you are going to replace every element in a vector, there can be no
sharing with any prior vector, under any method. If you will only
replace a few elements, use reduce. If you are going to replace most
elements, creating a new vector will be more efficient than sharing.
All of these would be true whether or not you had vmap or vfilter.

The seq functions don't change any types etc. They are functions of
collections/seqs to seqs.

Were filter/map etc to return vectors for vectors, then chained
operations would have to return fully-realized intermediate results.
That's wasteful in comparison to the behavior of the seq-based
functions.

Try this:

(def v (vec (range 100)))

(defn vmap [f v]
  (into [] (map f v)))

(time (count (vmap inc (vmap inc v
user= Elapsed time: 1171.923 msecs

(time (count (into [] (map inc (map inc v)
user= Elapsed time: 613.164 msecs

Speculating about inefficiency without a concrete counter-proposal is
not productive. While there could no doubt be some higher-performance
vector constructor/reducers, producing vector-returning versions of
the sequence ops is not generally a good idea.

Rich

--~--~-~--~~~---~--~~
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
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: seq and vector

2008-11-24 Thread [EMAIL PROTECTED]

On Nov 24, 3:03 pm, Rich Hickey [EMAIL PROTECTED] wrote:
 Speculating about inefficiency without a concrete counter-proposal is
 not productive. While there could no doubt be some higher-performance
 vector constructor/reducers, producing vector-returning versions of
 the sequence ops is not generally a good idea.

You are right. I give in.
--~--~-~--~~~---~--~~
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
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: seq and vector

2008-11-23 Thread Stuart Sierra

On Nov 23, 1:23 am, Rich Hickey [EMAIL PROTECTED] wrote:
 I still don't understand your expectation here. If the filter does any
 filtering, it won't return everything in the vector, so the new result
 will have fewer items. Do you want a vector with fewer items? Then
 you'll have a new vector.

On Nov 23, 7:38 am, [EMAIL PROTECTED] [EMAIL PROTECTED]
wrote:
 Sure. But I get a seq and not a vector.  Now don't get me wrong - I
 like the whole sequence library. It's just the performance cost to get
 a vector back. That's why I mean relative to seqs the data structures
 sometimes feel like second class.

I think this discussion is circling around the fact that a Seq is not
a data structure at all; it's a transient view of a collection.  It's
more like an Iterator than a List.  The map function creates a new Seq
that iterates over its argument, and returns a Seq that iterates over
the results of the mapping function.  If you need a vector, you have
to create a new vector.  With immutability, there's no way to avoid
copying, but since the copy will share structure with the original,
the performance penalty should be minimal.  You're still making copies
when you use lists; it's just slightly more convenient to work with
lists because they implement the Seq interface directly.

-Stuart Sierra
--~--~-~--~~~---~--~~
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
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: seq and vector

2008-11-23 Thread Matthias Hölzl
On Sun, Nov 23, 2008 at 2:34 PM, André Thieme
[EMAIL PROTECTED]wrote:


 On 23 Nov., 13:38, [EMAIL PROTECTED] [EMAIL PROTECTED]
 wrote:

  I have agents whose state is a vector (used as a buffer) of messages.
  There are a couple of transformation functions, e.g. tagging messages,
  removing messages from the vector etc. which are implemented with map
  and filter. In addition when messages are appended to the vector, conj
  is used and messages end up at the end of the vector. Later I noticed
  that the order was screwed because some intermediate tagging (using
  map) returned a secuence as the new agent's state and later additions
  with conj prepended messages at the front. This motivated me to ask
  for the simplest and most efficient way to get a vector back because
  that's what I wanted. Now I use a list instead of a vector and use
  reverse when necessary.

 A typical design pattern in functional programming languages is,
 to write ones own map function. Was it easier to solve your problem
 by doing it with lists compared to something like:

 user (defn vmap [function vector]
(loop [[f  r :as v] vector  result []]
  (if (nil? v)
  result
  (recur r (conj result (function f))
 #'user/vmap
 user (vmap inc [10 20 30])
 [11 21 31]
 ?

 Although I would agree that something like vmap should be in the
 core language itself. Maybe if there would be a datatype
 clojure.lang.LazyConj vs. the now existing clojure.lang.LazyCons.
 And then a (lazy-conj ...) function would also be needed.
 This could then build lazy lists and also vectors, and on top of that
 one could build vmap, or replace map with it.


Wouldn't it be be less brittle to define an operation that always adds an
element to the end of a sequence instead of relying on conj and some
(undocumented?) knowledge how it works for (seqs over) particular
datatypes?

For example, if you define something like

(defmulti enqueue (fn [coll elt] (class coll)))
(defmethod enqueue LazilyPersistentVector [coll elt]
  (conj coll elt))
(defmethod enqueue :default [coll elt]
  (concat coll [elt]))

you get stacks using cons/first/rest and queues using enqueue/first/rest in
a nice, symmetrical way.

user (def queue (enqueue (enqueue (enqueue [] 1) 2) 3))
#'user/queue
user (first queue)
1
user (rest queue)
(2 3)
user (def stack (cons 3 (cons 2 (cons 1 []
#'user/stack
user (first stack)
3
user (rest stack)
(2 1)

If you are dealing with long queues, performance might certainly be a
concern with this approach.  But unless you have a server with a really
heavy workload I don't think it should be a problem for message queues (and
you can still use vmap for performance reasons, but the program stays
correct even if you accidentially use map somewhere).

  Matthias

--~--~-~--~~~---~--~~
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
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: seq and vector

2008-11-23 Thread Kevin Downey

I don't think you understand. clojure data structures are IMMUTABLE.
every call to conj, or anyother function returns a new object. To
optimize there is sharing of structure.

On Sun, Nov 23, 2008 at 4:38 AM, [EMAIL PROTECTED]
[EMAIL PROTECTED] wrote:

 On Nov 23, 1:23 am, Rich Hickey [EMAIL PROTECTED] wrote:
 I still don't understand your expectation here. If the filter does any
 filtering, it won't return everything in the vector, so the new result
 will have fewer items. Do you want a vector with fewer items? Then
 you'll have a new vector.

 Sure. But I get a seq and not a vector. Now don't get me wrong - I
 like the whole sequence library. It's just the performance cost to get
 a vector back. That's why I mean relative to seqs the data structures
 sometimes feel like second class. In my example I no longer use a
 vector to hold items even though that would be the most appropriate
 data structure. To be more specififc:

 I have agents whose state is a vector (used as a buffer) of messages.
 There are a couple of transformation functions, e.g. tagging messages,
 removing messages from the vector etc. which are implemented with map
 and filter. In addition when messages are appended to the vector, conj
 is used and messages end up at the end of the vector. Later I noticed
 that the order was screwed because some intermediate tagging (using
 map) returned a secuence as the new agent's state and later additions
 with conj prepended messages at the front. This motivated me to ask
 for the simplest and most efficient way to get a vector back because
 that's what I wanted. Now I use a list instead of a vector and use
 reverse when necessary.

 In general, it can be efficient to perform a series of transformations
 in the seq space and then realize a vector at the end if you want. The
 lazy seqs just act as a cursor over the data, and a stream of results,
 and building a new vector from scratch by appending, as vec or (into
 [] ...) would do, is more efficient than element 'replacement'.

 If you don't expect a copy when mapping across an entire vector, and
 you want to use the immutable data structures, what alternative do you
 imagine?

 I certainly don't want to move away from immutability. It's more an
 issue with the return types. In the example setting outlined above
 suppose I have a message buffer (vector) of length n. Now some
 messages need to be tagged, which means mapping over the vector and
 possibly changing some messages. Now by changing I mean of course that
 the message m which is a map is transformed into m' where m' has
 some :tag key for instance. This mapping over the vector gives me a
 seq, i.e. the type has changed from vector to a sequence and this type
 change will cause later appending to the buffer to bahve differently.
 Now, to get a vector back I was told to use vec which AFAICS is very
 costly. Your proposal to use reduce in order to build up the new
 vector was a very good suggestion. For mapping at least. But the
 general issue for me was the type change. What would I propose? Not
 sure. I guess this behavior is by design and if I would want to get
 vectors there ios no way around copying. Which lead me to my
 conclusion that I better use a list instead of a vector. However it
 didn't give me that warm and fuzzy feeling that I normally get when
 programming in Clojure. Sorry that I can't be more specific than this.


 




-- 
The Mafia way is that we pursue larger goals under the guise of
personal relationships.
Fisheye

--~--~-~--~~~---~--~~
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
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: seq and vector

2008-11-22 Thread Christian Vest Hansen

With (vec) I think: http://clojure.org/api#toc508

On Sat, Nov 22, 2008 at 7:07 PM,  [EMAIL PROTECTED] wrote:

 In one of my data structures I have a vector as a buffer where things
 are appended to. In addition the things in that buffer sometimes get
 modified using map or filter. Now as map and filter return sequences I
 wonder how to get a vector back efficiently. I need a vector in order
 for conj to append and not to prepend as it happens with sequences,
 otherwise the order would be screwed. What is the most efficient (and
 still idiomatic) way to achieve this?

 Thanks!

 




-- 
Venlig hilsen / Kind regards,
Christian Vest Hansen.

--~--~-~--~~~---~--~~
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
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: seq and vector

2008-11-22 Thread [EMAIL PROTECTED]

On Nov 22, 7:31 pm, Christian Vest Hansen [EMAIL PROTECTED]
wrote:
 With (vec) I think:http://clojure.org/api#toc508

That's not really efficient as it copies the whole seq. It seems that
relative to sequences the other data structures are second class
insofar as when you use the sequence library (i.e. most of Clojure's
functions), there is no way back other than making copies. (conj (vec
(map identity [1 2 3])) 4) looks rather silly to me and while it's
inefficiency might be tolerable on small vectors it becomes an issue
with bigger ones.




--~--~-~--~~~---~--~~
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
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: seq and vector

2008-11-22 Thread Rich Hickey



On Nov 22, 1:07 pm, [EMAIL PROTECTED] wrote:
 In one of my data structures I have a vector as a buffer where things
 are appended to. In addition the things in that buffer sometimes get
 modified using map or filter. Now as map and filter return sequences I
 wonder how to get a vector back efficiently. I need a vector in order
 for conj to append and not to prepend as it happens with sequences,
 otherwise the order would be screwed. What is the most efficient (and
 still idiomatic) way to achieve this?

map and filter don't modify anything. What does it mean to filter a
vector?

In any case, the vector itself is immutable, so calling vec on the
return value of filter is fine.

As far as map, if you have a function that will only affect a few of
the items in the vector, you might want to reduce, making 'changes' as
you go.

Rich

--~--~-~--~~~---~--~~
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
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: seq and vector

2008-11-22 Thread [EMAIL PROTECTED]

On Nov 22, 9:48 pm, Rich Hickey [EMAIL PROTECTED] wrote:
 map and filter don't modify anything. What does it mean to filter a
 vector?

Yes yes, I know that. Still in English its sometimes easier to be
sloppy and pretend that I modify something even though I get another
vector.

 In any case, the vector itself is immutable, so calling vec on the
 return value of filter is fine.

Well yes its fine but what happens is that filter returns a (lazy) seq
and calling vec on that seq will allocate a new array of the same
length and copy every item over.

 As far as map, if you have a function that will only affect a few of
 the items in the vector, you might want to reduce, making 'changes' as
 you go.

Thanks. That sounds like it would work out nicely. Still in general my
issue seems to be that data strucutres turn into seqs and this can
cause subtle issues as for instance the different behaviour of conj
and a simple rule such as calling vec on the seq seems to be to
costly.

--~--~-~--~~~---~--~~
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
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: seq and vector

2008-11-22 Thread Rich Hickey



On Nov 22, 4:59 pm, [EMAIL PROTECTED] [EMAIL PROTECTED]
wrote:
 On Nov 22, 9:48 pm, Rich Hickey [EMAIL PROTECTED] wrote:

  map and filter don't modify anything. What does it mean to filter a
  vector?

 Yes yes, I know that. Still in English its sometimes easier to be
 sloppy and pretend that I modify something even though I get another
 vector.

  In any case, the vector itself is immutable, so calling vec on the
  return value of filter is fine.

 Well yes its fine but what happens is that filter returns a (lazy) seq
 and calling vec on that seq will allocate a new array of the same
 length and copy every item over.


I still don't understand your expectation here. If the filter does any
filtering, it won't return everything in the vector, so the new result
will have fewer items. Do you want a vector with fewer items? Then
you'll have a new vector.

  As far as map, if you have a function that will only affect a few of
  the items in the vector, you might want to reduce, making 'changes' as
  you go.

 Thanks. That sounds like it would work out nicely. Still in general my
 issue seems to be that data strucutres turn into seqs and this can
 cause subtle issues as for instance the different behaviour of conj
 and a simple rule such as calling vec on the seq seems to be to
 costly.

Nothing turns anything into seqs - a seq is a view on a collection.

If you are 'modifying' every element, then you'll have to have an
entirely new vector. Calling a mapping function and pouring the result
into a new vector will be more efficient than pretending to modify
each element in place with assoc.


In general, it can be efficient to perform a series of transformations
in the seq space and then realize a vector at the end if you want. The
lazy seqs just act as a cursor over the data, and a stream of results,
and building a new vector from scratch by appending, as vec or (into
[] ...) would do, is more efficient than element 'replacement'.

If you don't expect a copy when mapping across an entire vector, and
you want to use the immutable data structures, what alternative do you
imagine?

Rich

--~--~-~--~~~---~--~~
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
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: seq and vector

2008-11-22 Thread André Thieme

On 23 Nov., 01:23, Rich Hickey [EMAIL PROTECTED] wrote:
 On Nov 22, 4:59 pm, [EMAIL PROTECTED] [EMAIL PROTECTED]
 wrote:

 I still don't understand your expectation here. If the filter does any
 filtering, it won't return everything in the vector, so the new result
 will have fewer items. Do you want a vector with fewer items? Then
 you'll have a new vector.

As I understand he wants this:
(conj (map inc [10 20 30]) 7) ==  [11 21 31 7]

and not:
(conj (map inc [10 20 30]) 7) == (7 11 21 31)
--~--~-~--~~~---~--~~
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
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---