Re: Question on Sequences
Thanks Leif, thanks folks, these are good tips. On Mon, Nov 18, 2013 at 4:12 AM, Leif wrote: > > Hi, Alexandru. > > If you just need more performance on vectors only, there are the core > functions mapv, filterv, and subvec (O(1), which can be used to implement > takev and dropv). Also, looking at the source of mapv and filterv is > instructive, because they use transients internally; you might do that in > your solution to get a bit more speed. > > If you really need a generic solution where most clj.core functions are > performant on your custom data structures, I don't have suggestions, but > you can refer to what the experts do: > > https://github.com/clojure/data.priority-map > https://github.com/ztellman?tab=repositories (potemkin, clj-tuple, > immutable-bitset, et al) > > Hope that helps, > Leif > > > On Saturday, November 16, 2013 7:01:14 PM UTC-5, Alexandru Nedelcu wrote: >> >> Hi, >> >> I'm trying to understand the design of Clojure's collections and one >> thing that I find odd is the return of functions operating on sequences. >> Like for instance a call such as this will return a lazy-seq and not a >> vector: >> >> (drop 2 [1 2 3 4]) >> >> The reason why I find it odd is that data-structures have different >> characteristics and one may want to use a vector because it supports >> efficient indexing and appending to the end. >> >> Of course, dropping 2 elements like above from a vector is probably >> going to have O(n) complexity and thus returning something lazy is more >> appropriate. And while there are some operations, like "conj", "pop" and >> "peek" that preserve the type, functions such as map and filter also >> return lazy-seq. And I worry that the property of the collection you >> start with is lost, given that this returns a "cons": >> >> (conj (filter even? [1 2 3 4 5]) 6) >> >> So lets say that I want to write a generic function that preserves the >> type of that collection. Is something like this idiomatic? >> >> (defn only-evens [coll] >>(into (empty coll) (filter even? coll))) >> >> Thanks, >> >> -- >> Alexandru Nedelcu >> www.bionicspirit.com >> >> PGP Public Key: >> https://bionicspirit.com/key.aexpk >> >> -- > -- > 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. > -- Alexandru Nedelcu www.bionicspirit.com PGP Public Key: https://bionicspirit.com/key.aexpk -- -- 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: Question on Sequences
On Sat, Nov 16, 2013 at 9:00 PM, Cedric Greevey wrote: > This efficiency is why built-in functions to map, filter, etc. vectors to > vectors aren't provided > Well, there is mapv and filterv. -- -- 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: Question on Sequences
Hi, Alexandru. If you just need more performance on vectors only, there are the core functions mapv, filterv, and subvec (O(1), which can be used to implement takev and dropv). Also, looking at the source of mapv and filterv is instructive, because they use transients internally; you might do that in your solution to get a bit more speed. If you really need a generic solution where most clj.core functions are performant on your custom data structures, I don't have suggestions, but you can refer to what the experts do: https://github.com/clojure/data.priority-map https://github.com/ztellman?tab=repositories (potemkin, clj-tuple, immutable-bitset, et al) Hope that helps, Leif On Saturday, November 16, 2013 7:01:14 PM UTC-5, Alexandru Nedelcu wrote: > > Hi, > > I'm trying to understand the design of Clojure's collections and one > thing that I find odd is the return of functions operating on sequences. > Like for instance a call such as this will return a lazy-seq and not a > vector: > > (drop 2 [1 2 3 4]) > > The reason why I find it odd is that data-structures have different > characteristics and one may want to use a vector because it supports > efficient indexing and appending to the end. > > Of course, dropping 2 elements like above from a vector is probably > going to have O(n) complexity and thus returning something lazy is more > appropriate. And while there are some operations, like "conj", "pop" and > "peek" that preserve the type, functions such as map and filter also > return lazy-seq. And I worry that the property of the collection you > start with is lost, given that this returns a "cons": > > (conj (filter even? [1 2 3 4 5]) 6) > > So lets say that I want to write a generic function that preserves the > type of that collection. Is something like this idiomatic? > > (defn only-evens [coll] >(into (empty coll) (filter even? coll))) > > Thanks, > > -- > Alexandru Nedelcu > www.bionicspirit.com > > PGP Public Key: > https://bionicspirit.com/key.aexpk > > -- -- 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: Question on Sequences
This efficiency is why built-in functions to map, filter, etc. vectors to vectors aren't provided; better to use (into []) on a chain of seq-outputting transformations of a vector than to chain these hypothetical vector-native functions. OTOH, it occurs to me that efficient chaining can still be achieved in library form, by using monads of some sort to transform it into (into [] (op1 (op2 (op3 ... v under the hood. We have something like (into [] (filter x v)), (into [] (map y v)), etc. that we'd like composed into (into [] (filter x (map y (filter z ... v, rather than stacking repeated (into [])s, and that pattern *looks* an awful lot like it should be expressible as a monadic transformation of some kind. I don't have enough monad-fu to write out an actual implementation, though. :) That also leads to the weird thought that there might be some way to use monads to create reducers-like functionality for nearly any underlying data structure, with only the need to parametrize a few things for different underlying storage. On Sat, Nov 16, 2013 at 7:11 PM, Andy Fingerhut wrote: > I don't know if it is idiomatic, but it certainly looks like a good way to > achieve the desired effect. > > If you chained together calls to several functions like your example > only-evens, it would not be lazy, and it would build up a separate instance > of collections of the original type at each step of the way. Likely it > would be more efficient to delay the conversion back to the original > collection type until after the last sequence operation you wanted to > perform. > > Andy > > > On Sat, Nov 16, 2013 at 4:01 PM, Alexandru Nedelcu > wrote: > >> Hi, >> >> I'm trying to understand the design of Clojure's collections and one >> thing that I find odd is the return of functions operating on sequences. >> Like for instance a call such as this will return a lazy-seq and not a >> vector: >> >> (drop 2 [1 2 3 4]) >> >> The reason why I find it odd is that data-structures have different >> characteristics and one may want to use a vector because it supports >> efficient indexing and appending to the end. >> >> Of course, dropping 2 elements like above from a vector is probably >> going to have O(n) complexity and thus returning something lazy is more >> appropriate. And while there are some operations, like "conj", "pop" and >> "peek" that preserve the type, functions such as map and filter also >> return lazy-seq. And I worry that the property of the collection you >> start with is lost, given that this returns a "cons": >> >> (conj (filter even? [1 2 3 4 5]) 6) >> >> So lets say that I want to write a generic function that preserves the >> type of that collection. Is something like this idiomatic? >> >> (defn only-evens [coll] >>(into (empty coll) (filter even? coll))) >> >> Thanks, >> >> -- >> Alexandru Nedelcu >> www.bionicspirit.com >> >> PGP Public Key: >> https://bionicspirit.com/key.aexpk >> >> > -- > -- > 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: Question on Sequences
I don't know if it is idiomatic, but it certainly looks like a good way to achieve the desired effect. If you chained together calls to several functions like your example only-evens, it would not be lazy, and it would build up a separate instance of collections of the original type at each step of the way. Likely it would be more efficient to delay the conversion back to the original collection type until after the last sequence operation you wanted to perform. Andy On Sat, Nov 16, 2013 at 4:01 PM, Alexandru Nedelcu wrote: > Hi, > > I'm trying to understand the design of Clojure's collections and one > thing that I find odd is the return of functions operating on sequences. > Like for instance a call such as this will return a lazy-seq and not a > vector: > > (drop 2 [1 2 3 4]) > > The reason why I find it odd is that data-structures have different > characteristics and one may want to use a vector because it supports > efficient indexing and appending to the end. > > Of course, dropping 2 elements like above from a vector is probably > going to have O(n) complexity and thus returning something lazy is more > appropriate. And while there are some operations, like "conj", "pop" and > "peek" that preserve the type, functions such as map and filter also > return lazy-seq. And I worry that the property of the collection you > start with is lost, given that this returns a "cons": > > (conj (filter even? [1 2 3 4 5]) 6) > > So lets say that I want to write a generic function that preserves the > type of that collection. Is something like this idiomatic? > > (defn only-evens [coll] >(into (empty coll) (filter even? coll))) > > Thanks, > > -- > Alexandru Nedelcu > www.bionicspirit.com > > PGP Public Key: > https://bionicspirit.com/key.aexpk > > -- -- 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.
Question on Sequences
Hi, I'm trying to understand the design of Clojure's collections and one thing that I find odd is the return of functions operating on sequences. Like for instance a call such as this will return a lazy-seq and not a vector: (drop 2 [1 2 3 4]) The reason why I find it odd is that data-structures have different characteristics and one may want to use a vector because it supports efficient indexing and appending to the end. Of course, dropping 2 elements like above from a vector is probably going to have O(n) complexity and thus returning something lazy is more appropriate. And while there are some operations, like "conj", "pop" and "peek" that preserve the type, functions such as map and filter also return lazy-seq. And I worry that the property of the collection you start with is lost, given that this returns a "cons": (conj (filter even? [1 2 3 4 5]) 6) So lets say that I want to write a generic function that preserves the type of that collection. Is something like this idiomatic? (defn only-evens [coll] (into (empty coll) (filter even? coll))) Thanks, -- Alexandru Nedelcu www.bionicspirit.com PGP Public Key: https://bionicspirit.com/key.aexpk signature.asc Description: OpenPGP digital signature