list* not returning a list

Showing 1-11 of 11 messages
list* not returning a list Marek Srank 12/26/12 12:35 PM
function list* doesn't return a list, because it uses 'cons' under the hood:

(list? (list* 1 2 3 '()))
;=> false

(class (list* 1 2 3 '()))
;=> clojure.lang.Cons

...however, its docstring says: "Creates a new list containing the items prepended to the rest, the last of which will be treated as a sequence."

I think that this can be pretty confusing... Shouldn't it be fixed (at least the docstring)?


Cheers,
Marek.

Re: list* not returning a list Stephen Compall 12/26/12 2:07 PM
On Wed, 2012-12-26 at 12:35 -0800, Marek Šrank wrote:
> ...however, its docstring says: "Creates a new list containing the items
> prepended to the rest, the last of which will be treated as a sequence."

List is almost always colloquial, not literally IPersistentList.

I would be in favor of eliminating list?, really, in favor of
seq?/sequential?/seqable?.

> I think that this can be pretty confusing... Shouldn't it be fixed (at
> least the docstring)?

http://dev.clojure.org/jira/

--
Stephen Compall
^aCollection allSatisfy: [:each|aCondition]: less is better

Re: list* not returning a list Ben 12/26/12 2:13 PM
On Wed, Dec 26, 2012 at 2:07 PM, Stephen Compall
<stephen...@gmail.com> wrote:
> On Wed, 2012-12-26 at 12:35 -0800, Marek Šrank wrote:
>> ...however, its docstring says: "Creates a new list containing the items
>> prepended to the rest, the last of which will be treated as a sequence."
>
> List is almost always colloquial, not literally IPersistentList.
>
> I would be in favor of eliminating list?, really, in favor of
> seq?/sequential?/seqable?.

Given that lists and (e.g.) vectors behave differently in some
circumstances (as the first argument to conj, for instance), it seems
desirable to be able to tell what one's got on one's hands.

--
Ben Wolfson
"Human kind has used its intelligence to vary the flavour of drinks,
which may be sweet, aromatic, fermented or spirit-based. ... Family
and social life also offer numerous other occasions to consume drinks
for pleasure." [Larousse, "Drink" entry]
Re: list* not returning a list Tom Jack 12/26/12 6:28 PM
A small bug in ClojureScript was related to this: https://github.com/clojure/clojurescript/commit/88b36c177ebd1bb49dbd874a9d13652fd1de4027

It looks like the only thing missing to make Cons implement IPersistentList is IPersistentStack. Why not implement it?
Re: list* not returning a list Ben 12/27/12 8:06 AM
On Wed, Dec 26, 2012 at 6:28 PM, Tom Jack <t...@tomoj.la> wrote:
> A small bug in ClojureScript was related to this:
> https://github.com/clojure/clojurescript/commit/88b36c177ebd1bb49dbd874a9d13652fd1de4027
>
> It looks like the only thing missing to make Cons implement IPersistentList
> is IPersistentStack. Why not implement it?

This seems very weird to me:

> (list? (cons 1 '()))
false

Especially since:

> (list? (empty (cons 1 '())))
true

making list? true of cons cells would presumably also eliminate the
need for those awkward (apply list ...)s in, e.g., clojure.walk/walk.
Re: list* not returning a list Michał Marczyk 12/27/12 9:08 AM
On 27 December 2012 03:28, Tom Jack <t...@tomoj.la> wrote:
> It looks like the only thing missing to make Cons implement IPersistentList
> is IPersistentStack. Why not implement it?

IPersistentStack extends IPersistentCollection, which includes
count(), so that's no go for Cons (the rest part might be a lazy seq).

Cheers,
M.


>
>
> On Wednesday, December 26, 2012 4:13:38 PM UTC-6, Ben wrote:
>>
>> On Wed, Dec 26, 2012 at 2:07 PM, Stephen Compall
>> <stephen...@gmail.com> wrote:
>> > On Wed, 2012-12-26 at 12:35 -0800, Marek Šrank wrote:
>> >> ...however, its docstring says: "Creates a new list containing the
>> >> items
>> >> prepended to the rest, the last of which will be treated as a
>> >> sequence."
>> >
>> > List is almost always colloquial, not literally IPersistentList.
>> >
>> > I would be in favor of eliminating list?, really, in favor of
>> > seq?/sequential?/seqable?.
>>
>> Given that lists and (e.g.) vectors behave differently in some
>> circumstances (as the first argument to conj, for instance), it seems
>> desirable to be able to tell what one's got on one's hands.
>>
>> --
>> Ben Wolfson
>> "Human kind has used its intelligence to vary the flavour of drinks,
>> which may be sweet, aromatic, fermented or spirit-based. ... Family
>> and social life also offer numerous other occasions to consume drinks
>> for pleasure." [Larousse, "Drink" entry]
>
> --
> 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
Re: list* not returning a list Ben 12/27/12 9:52 AM
On Thu, Dec 27, 2012 at 9:08 AM, Michał Marczyk
<michal....@gmail.com> wrote:
> On 27 December 2012 03:28, Tom Jack <t...@tomoj.la> wrote:
>> It looks like the only thing missing to make Cons implement IPersistentList
>> is IPersistentStack. Why not implement it?
>
> IPersistentStack extends IPersistentCollection, which includes
> count(), so that's no go for Cons (the rest part might be a lazy seq).

Doesn't stop existing lazy seqs:


user=> (def x (repeat 2))
#'user/x
user=> (coll? x)
true
user=> (instance? clojure.lang.IPersistentCollection x)
true
user=> (count x)
; predictable lack of results
Re: list* not returning a list Marek Srank 12/27/12 11:37 AM
Making Cons implement IPersistentList will solve all cases except when list* gets only one argument. This is problematic. The source looks like this:

(defn list*
  "Creates a new list containing the items prepended to the rest, the
  last of which will be treated as a sequence."
  {:added "1.0"
   :static true}
  ([args] (seq args))
  ([a args] (cons a args))
  ([a b args] (cons a (cons b args)))
  ([a b c args] (cons a (cons b (cons c args))))
  ([a b c d & more]
     (cons a (cons b (cons c (cons d (spread more)))))))

Calling 'seq' in the first case means that with calls like: (list* {:a 1}) we get clojure.lang.PersistentArrayMap$Seq and not a List. In theory, we could do just (apply list args) here, but apply itself also uses list* in its implementation. Luckily, it doesn't use the one-argument version of list*, so we could probably declare 'apply' above the 'list*' in the 'core.clj' source and then use it there... Does it seem reasonably?

Marek
Re: list* not returning a list Michał Marczyk 12/27/12 1:00 PM
On 27 December 2012 18:52, Ben Wolfson <wol...@gmail.com> wrote:
> On Thu, Dec 27, 2012 at 9:08 AM, Michał Marczyk
> <michal....@gmail.com> wrote:
>> On 27 December 2012 03:28, Tom Jack <t...@tomoj.la> wrote:
>>> It looks like the only thing missing to make Cons implement IPersistentList
>>> is IPersistentStack. Why not implement it?
>>
>> IPersistentStack extends IPersistentCollection, which includes
>> count(), so that's no go for Cons (the rest part might be a lazy seq).
>
> Doesn't stop existing lazy seqs:

Oh, indeed. Thanks!


>
>
> user=> (def x (repeat 2))
> #'user/x
> user=> (coll? x)
> true
> user=> (instance? clojure.lang.IPersistentCollection x)
> true
> user=> (count x)
> ; predictable lack of results
>
> --
> Ben Wolfson
> "Human kind has used its intelligence to vary the flavour of drinks,
> which may be sweet, aromatic, fermented or spirit-based. ... Family
> and social life also offer numerous other occasions to consume drinks
> for pleasure." [Larousse, "Drink" entry]
>
Re: list* not returning a list Marek Srank 1/4/13 12:06 PM
I found CLJ-1060 [1] and added there a patch with Cons implementing IPersistentList and (apply list args) in one-argument case of list*. 

Re: list* not returning a list Michał Marczyk 1/4/13 2:16 PM
Hey,

I replied in the ticket with some comments. The main issue I see is
that I'm used to the notion that IPersistentLists are things which are
not lazy and which have next/rest parts which are themselves IPLs and
this approach seems to cause that no longer to be the case. If it were
not to be the case, then the question arises why maintain the list/seq
distinction at all. Will be interesting to read further opinions on
this!

Cheers,
Michał