Confused about sequential definition

2011-07-07 Thread octopusgrabbus
What does this mean exactly?

sequential?
function

Usage: (sequential? coll)

Returns true if coll implements Sequential

from 
http://clojure.github.com/clojure/clojure.core-api.html#clojure.core/sequential

-- 
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: Confused about sequential definition

2011-07-07 Thread Ken Wesson
On Thu, Jul 7, 2011 at 4:48 PM, octopusgrabbus octopusgrab...@gmail.com wrote:
 What does this mean exactly?

 sequential?
 function

 Usage: (sequential? coll)

 Returns true if coll implements Sequential

 from 
 http://clojure.github.com/clojure/clojure.core-api.html#clojure.core/sequential

Seems to test for ordered Clojure collections. I get true for seqs,
lists, and vectors, but not strings, arrays, java.util.LinkedLists,
maps, or sets. So unordered collections and ordered Java collections
seem to be excluded.

There's also seq? which excludes vectors and coll? which includes maps
and sets. All exclude non-Clojure seqables such as LinkedLists,
strings, and arrays.

None return true for nil.

Unfortunately there isn't a built-in predicate function corresponding
to will seq work on this?. This inherently works:

(defn seqable? [x]
  (try
(seq x)
(catch Exception _ false)))

producing (seq x) if doesn't throw an exception, false if it does.
It's a bit icky but does the job, and has a few useful properties:

(if-let [a (seqable? x)] ...)

runs the body with a bound to (seq x) if x is seqable and not empty.

(if (false? (seqable? x)) ...)

catches non-seqables.

But it doesn't quite work as a straight predicate if you want nil and
empty inputs treated as seqable. You can change that by just adding
true on a line by itself after (seq x), but then you have to call
seq a second time if you want the seq result, which you usually do.
Changing the (seq x) to (if-let [a (seq x)] a ()) will return a truthy
value for all objects interpretable as a seq but will turn all empties
into a non-nil empty list instead of nil.

Another form avoids the icky exception hack and doesn't call seq on
its argument:

(defn array? [x] (and x (contains? (set (.getName (.getClass x))) \[)))

(defn seqable? [x]
  (or
(coll? x)
(nil? x)
(instance? java.util.Collection x)
(instance? java.util.Map x)
(instance? java.util.Set x)
(string? x)
(array? x)))

It does do a bit of a hack to test for arrays and it breaks if seq is
extended in the future to work with anything it currently won't
accept.

-- 
Protege: What is this seething mass of parentheses?!
Master: Your father's Lisp REPL. This is the language of a true
hacker. Not as clumsy or random as C++; a language for a more
civilized age.

-- 
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: Confused about sequential definition

2011-07-07 Thread Mark Rathwell
What it means exactly is that there is an interface called Sequential
(defined in
https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Sequential.java)
that some other interfaces and abstract classes implement or extend, and
some clojure data structures that you use implement or extend those, thereby
implementing the Sequential interface, and so instances of those data
structures will return true for this function.

What it means practically, is that the data structure is seqential, like a
list or vector, and not like a map.  Depending on what you are wanting to
use it for, there may be a better function to consider.

If you want to explore the relationships in the language, some people seem
to like Clojure Atlas: http://www.clojureatlas.com/

http://www.clojureatlas.com/

On Thu, Jul 7, 2011 at 4:48 PM, octopusgrabbus octopusgrab...@gmail.comwrote:

 What does this mean exactly?

 sequential?
 function

 Usage: (sequential? coll)

 Returns true if coll implements Sequential

 from
 http://clojure.github.com/clojure/clojure.core-api.html#clojure.core/sequential

 --
 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 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: Confused about sequential definition

2011-07-07 Thread octopusgrabbus

Thank you for the explanations. I saw sequential in an example out on
the web. At first, I thought it had something to do with the ordering
of a sequence's elements.

cmn

On Jul 7, 5:22 pm, Mark Rathwell mark.rathw...@gmail.com wrote:
 What it means exactly is that there is an interface called Sequential
 (defined 
 inhttps://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/S...)
 that some other interfaces and abstract classes implement or extend, and
 some clojure data structures that you use implement or extend those, thereby
 implementing the Sequential interface, and so instances of those data
 structures will return true for this function.

 What it means practically, is that the data structure is seqential, like a
 list or vector, and not like a map.  Depending on what you are wanting to
 use it for, there may be a better function to consider.

 If you want to explore the relationships in the language, some people seem
 to like Clojure Atlas:http://www.clojureatlas.com/

 http://www.clojureatlas.com/

 On Thu, Jul 7, 2011 at 4:48 PM, octopusgrabbus 
 octopusgrab...@gmail.comwrote:







  What does this mean exactly?

  sequential?
  function

  Usage: (sequential? coll)

  Returns true if coll implements Sequential

  from
 http://clojure.github.com/clojure/clojure.core-api.html#clojure.core/...

  --
  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 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: Confused about sequential definition

2011-07-07 Thread David Nolen
On Thu, Jul 7, 2011 at 5:14 PM, Ken Wesson kwess...@gmail.com wrote:

 (defn array? [x] (and x (contains? (set (.getName (.getClass x))) \[)))

 (defn seqable? [x]
  (or
(coll? x)
(nil? x)
(instance? java.util.Collection x)
(instance? java.util.Map x)
(instance? java.util.Set x)
(string? x)
(array? x)))

 It does do a bit of a hack to test for arrays and it breaks if seq is
 extended in the future to work with anything it currently won't
 accept.


A better extensible way to do this: http://dosync.posterous.com/51626638

David

-- 
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: Confused about sequential definition

2011-07-07 Thread Ken Wesson
On Thu, Jul 7, 2011 at 6:00 PM, David Nolen dnolen.li...@gmail.com wrote:
 On Thu, Jul 7, 2011 at 5:14 PM, Ken Wesson kwess...@gmail.com wrote:

 (defn array? [x] (and x (contains? (set (.getName (.getClass x))) \[)))

 (defn seqable? [x]
  (or
    (coll? x)
    (nil? x)
    (instance? java.util.Collection x)
    (instance? java.util.Map x)
    (instance? java.util.Set x)
    (string? x)
    (array? x)))

 It does do a bit of a hack to test for arrays and it breaks if seq is
 extended in the future to work with anything it currently won't
 accept.

 A better extensible way to do this: http://dosync.posterous.com/51626638
 David

Interesting, but there is still going to be a performance issue for
the perhaps-common case of testing a non-seqable for seqability: in
that case, it will do the reflective check for isArray and it won't
use the protocol to cache the result. Making it do so, however, would
cause problems if one had (seqable? some-foo) and later attempted to
extend the protocol to mark Foos as seqable within the same runtime
session.

I'm surprised that (.isArray (.getClass foo)) is that slow, though. It
may be reflection, but it's not the sort I was given to understand
was slow, namely reflective method invocation. An obvious JVM
implementation would make the first word of every object a pointer to
its concrete Class instance and then the above should be no worse than
(.length (.getSomeString some-bean)): a method call and a field lookup
in an object whose pointer was the result of another method call and
another field lookup in another object. Indeed, both method calls are
nonpolymorphic in the former case, since the getClass method is final
and the entire Class class is final so isArray is also final.

-- 
Protege: What is this seething mass of parentheses?!
Master: Your father's Lisp REPL. This is the language of a true
hacker. Not as clumsy or random as C++; a language for a more
civilized age.

-- 
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: Confused about sequential definition

2011-07-07 Thread David Nolen
On Thu, Jul 7, 2011 at 11:21 PM, Ken Wesson kwess...@gmail.com wrote:

 Interesting, but there is still going to be a performance issue for
 the perhaps-common case of testing a non-seqable for seqability: in
 that case, it will do the reflective check for isArray and it won't
 use the protocol to cache the result. Making it do so, however, would
 cause problems if one had (seqable? some-foo) and later attempted to
 extend the protocol to mark Foos as seqable within the same runtime
 session.

 I'm surprised that (.isArray (.getClass foo)) is that slow, though. It
 may be reflection, but it's not the sort I was given to understand
 was slow, namely reflective method invocation. An obvious JVM
 implementation would make the first word of every object a pointer to
 its concrete Class instance and then the above should be no worse than
 (.length (.getSomeString some-bean)): a method call and a field lookup
 in an object whose pointer was the result of another method call and
 another field lookup in another object. Indeed, both method calls are
 nonpolymorphic in the former case, since the getClass method is final
 and the entire Class class is final so isArray is also final.


(extend-type Object
  ISeqable
  (seqable? [x]
(let [c (.getClass x)]
 (if (.isArray c)
   (do
 (extend-type (.getClass x)
   ISeqable
   (seqable? [x] true))
 true)
   (do
 (extend-type (.getClass x)
   ISeqable
   (seqable? [x] false))
 false)

-- 
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: Confused about sequential definition

2011-07-07 Thread Ken Wesson
On Fri, Jul 8, 2011 at 12:58 AM, David Nolen dnolen.li...@gmail.com wrote:

 (extend-type Object
   ISeqable
   (seqable? [x]
             (let [c (.getClass x)]
              (if (.isArray c)
                (do
                  (extend-type (.getClass x)
                    ISeqable
                    (seqable? [x] true))
                  true)
                (do
                  (extend-type (.getClass x)
                    ISeqable
                    (seqable? [x] false))
                  false)

 On Thu, Jul 7, 2011 at 11:21 PM, Ken Wesson kwess...@gmail.com wrote:
 ... it won't use the protocol to cache the result. Making it do so, however,
 would cause problems if one had (seqable? some-foo) and later attempted
 to extend the protocol to mark Foos as seqable within the same runtime
 session.


-- 
Protege: What is this seething mass of parentheses?!
Master: Your father's Lisp REPL. This is the language of a true
hacker. Not as clumsy or random as C++; a language for a more
civilized age.

-- 
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: Confused about sequential definition

2011-07-07 Thread David Nolen
On Fri, Jul 8, 2011 at 1:00 AM, Ken Wesson kwess...@gmail.com wrote:

  On Thu, Jul 7, 2011 at 11:21 PM, Ken Wesson kwess...@gmail.com wrote:
  ... it won't use the protocol to cache the result. Making it do so,
 however,
  would cause problems if one had (seqable? some-foo) and later attempted
  to extend the protocol to mark Foos as seqable within the same runtime
  session.


Problem for who? Problem how? Extending seqable? to types you do not control
or which are not seqable? as defined by Clojure itself is asking for trouble
anyhow.

David

-- 
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: Confused about sequential definition

2011-07-07 Thread Ken Wesson
On Fri, Jul 8, 2011 at 1:06 AM, David Nolen dnolen.li...@gmail.com wrote:
 On Fri, Jul 8, 2011 at 1:00 AM, Ken Wesson kwess...@gmail.com wrote:

  On Thu, Jul 7, 2011 at 11:21 PM, Ken Wesson kwess...@gmail.com wrote:
  ... it won't use the protocol to cache the result. Making it do so,
  however,
  would cause problems if one had (seqable? some-foo) and later attempted
  to extend the protocol to mark Foos as seqable within the same runtime
  session.

 Problem for who? Problem how? Extending seqable? to types you do not control
 or which are not seqable? as defined by Clojure itself is asking for trouble
 anyhow.

If you extend it further at all, it could happen that it gets called
on a non-array object of a type before being extended to that type,
though this is much more likely at a REPL than in deployment at least.
On the other hand if you won't ever extend it further at all there's
no real advantage over a non-protocol solution, like the monolithic
(or ...)-bodied function punting to a memoized is-array-class?
function to check for the array case.

-- 
Protege: What is this seething mass of parentheses?!
Master: Your father's Lisp REPL. This is the language of a true
hacker. Not as clumsy or random as C++; a language for a more
civilized age.

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