Documentation and examples (and where is the documentation on reduce)?

2 views
Skip to first unread message

michele

unread,
Jun 29, 2010, 5:55:32 AM6/29/10
to Clojure
I really like Clojure, but as a complete n00b on Lisp languages, it is
frustrating that I many times have to hunt high and low for
documentation on basic stuff.

Recently I saw a code snippet that showed that reduce takes an
optional initial value, something I didn't know. When I see something
new, I usually go back to the documentation or the book I might be
reading to see if there is something more to learn about the current
function, and to familiarize myself with the documentation.

Well, to my surprise and frustration, I haven't found any place which
documents that reduce takes an optional initial value.

The first impression of the Clojure home page was a nice ordered set
of pages of documentation, but I soon realized that listing all the
functions with some textual explanation, just doesn't cut it. I
usually end up googling for more conrete information that shows me how
to actually use the functions.

Please, dear very good Clojure creators, if you don't want Clojure to
be another language for the specially initiated, good examples will
take Clojure to the next level.

People are just like Clojure, lazy.

David Nolen

unread,
Jun 29, 2010, 8:08:37 AM6/29/10
to clo...@googlegroups.com
True, while we wait for someone to actually build such a site I recommend that you ask your questions on:

1) The mailing list
2) #clojure channel at irc.freenode.net
3) StackOverflow

In all three places you'll get nice friendly answers pronto.

Two other useful things at the REPL are (doc function-name) and (source function-name).

David 

Meikel Brandmeyer

unread,
Jun 29, 2010, 8:17:40 AM6/29/10
to Clojure
Hi,

On Jun 29, 11:55 am, michele <michelemen...@gmail.com> wrote:

> Well, to my surprise and frustration, I haven't found any place which
> documents that reduce takes an optional initial value.

http://richhickey.github.com/clojure/branch-1.1.x/index.html

In particular:

http://richhickey.github.com/clojure/branch-1.1.x/clojure.core-api.html#clojure.core/reduce

(or alternatively: (doc reduce) at the repl)

What does this leave open on questions? (Granted: reduce is rather
well documented, there are worse examples.)

> Please, dear very good Clojure creators, if you don't want Clojure to
> be another language for the specially initiated, good examples will
> take Clojure to the next level.

Uh. Sky is falling again. But your are right. Nice examples would be a
nice addition. It's the first thing I'm looking for, when learning
something new. I'm not sure they should go to the reference docs,
though.

> People are just like Clojure, lazy.

Why do I support lazy people in my spare time? I'm an idiot.

Sincerely
Meikel

Jimmy

unread,
Jun 29, 2010, 8:28:32 AM6/29/10
to Clojure

> Uh. Sky is falling again. But your are right. Nice examples would be a
> nice addition. It's the first thing I'm looking for, when learning
> something new. I'm not sure they should go to the reference docs,
> though.

Ruby is an example of a language that does have some examples in the
reference docs and i think it helps a lot.
Regards,
Jimmy

michele

unread,
Jun 29, 2010, 1:11:28 PM6/29/10
to Clojure

Silly me. I forgot about (doc …).

Thanks for the answers. Well, it's good there is documentation, pity
it's all over the place.

Meikel, idiots are nice people too, so don't feel bad. But seriously,
why do you think we work this hard to make the computer do all this
things for us? Because we're lazy.




On Jun 29, 2:17 pm, Meikel Brandmeyer <m...@kotka.de> wrote:
> Hi,
>
> On Jun 29, 11:55 am, michele <michelemen...@gmail.com> wrote:
>
> > Well, to my surprise and frustration, I haven't found any place which
> > documents that reduce takes an optional initial value.
>
> http://richhickey.github.com/clojure/branch-1.1.x/index.html
>
> In particular:
>
> http://richhickey.github.com/clojure/branch-1.1.x/clojure.core-api.ht...

Meikel Brandmeyer

unread,
Jun 29, 2010, 3:46:03 PM6/29/10
to clo...@googlegroups.com
Hi,

Am 29.06.2010 um 19:11 schrieb michele:

> Meikel, idiots are nice people too, so don't feel bad. But seriously,
> why do you think we work this hard to make the computer do all this
> things for us? Because we're lazy.

Ah. IMHO, computer help us solving problems which we wouldn't have without them.

But then: laziness is the source of intelligence. Or was it the other way around?

;)

Sincerely
Meikel

michele

unread,
Jun 30, 2010, 2:08:33 AM6/30/10
to Clojure

Mother's invention is a lazy necessity, I think.

Walter van der Laan

unread,
Jul 2, 2010, 6:18:01 AM7/2/10
to Clojure
You can find a lot of examples using http://github.com/defn/walton

For example you can point your browser at http://getclojure.org:8080/examples/reduce
for reduce examples.

Meikel Brandmeyer

unread,
Jul 2, 2010, 10:50:45 AM7/2/10
to Clojure
Hi,

On Jul 2, 12:18 pm, Walter van der Laan <waltervanderl...@gmail.com>
wrote:

> For example you can point your browser athttp://getclojure.org:8080/examples/reduce
> for reduce examples.

Is it necessary to have >250 examples for a function which has
effectively five variations?

(reduce + [])
(reduce + [1])
(reduce + [1 2 3])
(reduce + 0 [])
(reduce + 0 [1 2 3])

Then there are examples like this one:
(reduce '* '(1 2 3))

Someone who is new to Clojure and tries to understand reduce... Does
he understand why the result is 3? A result which relies on a not very
well-known fact, that you can actually call symbols like keywords for
map lookup with up to two arguments. (I bet there quite a few of
"seasoned" clojurians who didn't know that) I - if I was a newbie to
the language - would mainly think: wtf? Additionally the particular
example above doesn't even make sense.

I'm all for examples, but please: clear examples focusing on the thing
being demonstrated. Symbol calling or showing that [1 2 3] and (list 1
2 3) can be interchanged in the example above are nice to know, but
don't help to understand reduce itself. They should go to their own
sections in a tutorial.

The 0.02€ of a guy who has not put effort in creating examples for the
core API.

Sincerely
Meikel

PS: I also think the examples should demonstrate idiomatic clojure. [1
2 3] is idiomatic while '(1 2 3) is not. Whatever we put in examples
will show up in code. So be it [] vs. '() or (.java interop) vs. (.
interop (java)) - we should pay attention!

Mike Meyer

unread,
Jul 2, 2010, 2:58:09 PM7/2/10
to clo...@googlegroups.com, m...@kotka.de
On Fri, 2 Jul 2010 07:50:45 -0700 (PDT)
Meikel Brandmeyer <m...@kotka.de> wrote:
> On Jul 2, 12:18 pm, Walter van der Laan <waltervanderl...@gmail.com>
> wrote:
> > For example you can point your browser athttp://getclojure.org:8080/examples/reduce
> > for reduce examples.
> Is it necessary to have >250 examples for a function which has
> effectively five variations?
> (reduce + [])
> (reduce + [1])
> (reduce + [1 2 3])
> (reduce + 0 [])
> (reduce + 0 [1 2 3])

Seconded.

> I'm all for examples, but please: clear examples focusing on the thing
> being demonstrated. Symbol calling or showing that [1 2 3] and (list 1
> 2 3) can be interchanged in the example above are nice to know, but
> don't help to understand reduce itself. They should go to their own
> sections in a tutorial.

Yes. Symbol calling and the equivalence of [1 2 3] and '(1 2 3) aren't
really relevant to what reduce can do. Nor is showing someone how to
extract the arglist from a functions metadata.

While I think the effort is marvelous, some thought should go into the
purpose. That page looks like the purpose is to show off the
cleverness of the person who wrote it. As such, this page is probably
more confusing than helpful.

> PS: I also think the examples should demonstrate idiomatic clojure. [1
> 2 3] is idiomatic while '(1 2 3) is not. Whatever we put in examples
> will show up in code. So be it [] vs. '() or (.java interop) vs. (.
> interop (java)) - we should pay attention!

Ditto.

Examples are read in order, and should be presented from simple to
more complex. In particular, the first example shouldn't require
knowing anything but clojure syntax. Each further example should
introduce at most one new concept, reinforce the previous example
(though that should be kept to a minimum), or show the function
working on different data types - if they're not doing one of those
things, why are they there? All the inputs to an example should be
either literals, or the result of a simple function invocation. If the
user has to work to figure out what the input is, they're that much
more likely to skip the example, or - even worse - come up with the
wrong input and hence wrong result. Finally, maybe provide one example
(short) that might be considered a "real world" use.

They really need to include an explanation. Having the expected
results there would be nice as well.

> The 0.02€ of a guy who has not put effort in creating examples for the
> core API.

Not wanting to be that guy (no offense intended to Meikel, he made a
good point), here's what I think is a nice set of reduce examples:

; sum of 0 through 10: 45
(reduce + (range 10))

; Divide 1 by 2 and then 3: 1/6
(reduce / 1 [2 3])

; Build a set from a collection: #{:a :c :b}
(reduce conj #{} [:a :b :c])

; Build a sorted set from multiple collections: #{1 2 3 4 5 6}
(reduce into (sorted-set) [[3 1 2] [5 4 6]])

; Reverse a list: (3 2 1)
(reduce #(cons %2 %1) [] [1 2 3])

; Build a hash-map from n to n squared:
; {0 0, 1 1, 2 4, 3 9, 4 16, 5 25, 6 36, 7 49, 8 64, 9 81}
(reduce #(assoc %1 %2 (* %2 %2)) {} (range 10))

; Edge case with one argument: returns argument -> 2
(reduce conj [2])

; Edge case with one argument: returns argument -> 1
(reduce conj 1 [])

; Note that in the previous two examples, conj is not invoked, as it
; always returns a sequence.

; Edge case with no arguments: (*) -> 1
(reduce * [])

; Broken edge case: Wrong number of arguments passed to function:
(reduce conj [])


--
Mike Meyer <m...@mired.org> http://www.mired.org/consulting.html
Independent Network/Unix/Perforce consultant, email for more information.

O< ascii ribbon campaign - stop html mail - www.asciiribbon.org

Ryan Waters

unread,
Jul 2, 2010, 11:30:09 AM7/2/10
to clo...@googlegroups.com
n00b question: Why is [1 2 3] idiomatic and not '(1 2 3) ? Is it a
vectors vs. lists thing, notation thing, or something else?

I don't have a lisp background so there's a truckload of lisp reading
I still want to do which may answer questions like these for me. If
there's a particular text on what would help a person discern
idiomatic vs. not, in clojure, I'd be happy to put that on my "list"
'(ha ha). :P

Ryan

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

Paul Moore

unread,
Jul 2, 2010, 12:41:38 PM7/2/10
to clo...@googlegroups.com
On 2 July 2010 15:50, Meikel Brandmeyer <m...@kotka.de> wrote:
> Then there are examples like this one:
> (reduce '* '(1 2 3))
>
> Someone who is new to Clojure and tries to understand reduce... Does
> he understand why the result is 3? A result which relies on a not very
> well-known fact, that you can actually call symbols like keywords for
> map lookup with up to two arguments. (I bet there quite a few of
> "seasoned" clojurians who didn't know that) I - if I was a newbie to
> the language - would mainly think: wtf?

Even with your explanation, I'm baffled... I can get to

user=> ('* ('* 1 2) 3)
3

Ah. This means look '* up in ('* 1 2) and use 3 as the default if you
don't find it. And you don't (for all sorts of odd reasons - why
doesn't this raise a "what are you doing, it's not even a map you're
looking up in" exception? :-)), so the result is the default, 3.

Uh, yeah.

That example is actually harmful - as it confused me about what does
and doesn't need quoting - something I would probably have got right
instinctively until I read this :-(

Paul.

Justin Kramer

unread,
Jul 2, 2010, 5:50:18 PM7/2/10
to Clojure
Nice, Mike. I stole your work and put it into the Wiki I created to
see how it fit:

http://clojure-examples.appspot.com/clojure.core/reduce

(Note: reduce seems to be missing a doc string in 1.2 master; for
other functions doc strings show up.)

As cool as walton is, it's kind of a firehose. A curated collection of
examples (perhaps pilfering from walton and others) would be more
valuable, I think.

Justin

On Jul 2, 2:58 pm, Mike Meyer <mwm-keyword-googlegroups.

Mike Meyer

unread,
Jul 2, 2010, 6:37:38 PM7/2/10
to clo...@googlegroups.com, jkkr...@gmail.com
On Fri, 2 Jul 2010 14:50:18 -0700 (PDT)
Justin Kramer <jkkr...@gmail.com> wrote:

> Nice, Mike. I stole your work and put it into the Wiki I created to
> see how it fit:
>
> http://clojure-examples.appspot.com/clojure.core/reduce

Well, I like it, but I might be a bit biased.

I think the important part is the rules that went into picking the
examples. I just picked examples from Walton that followed them,
tweaked those to build up properly, and then added the edge
cases. http://clojure-examples.appspot.com/guidelines actually covers
it, but my version was more explicit, and gave a why.

Cleaning mine version up and combining them gives:

* Keep it simple and self contained
- the first example shouldn't require knowing anything but clojure syntax
- the inputs to an example should either be literals or simple expressions
- the user shouldn't have to figure out anything but the new concept or type
* Build up examples cumulatively
- each example should introduce at most one new concept
- or reinforce the previous example (though that should be kept to a minimum)
- or show the function working on a new data type

I'd go ahead and edit the page, but figure you might want to such a
change beforehand.

<mike

Meikel Brandmeyer

unread,
Jul 3, 2010, 2:14:18 AM7/3/10
to clo...@googlegroups.com
Hi,

Am 03.07.2010 um 00:37 schrieb Mike Meyer:

> Cleaning mine version up and combining them gives:
>
> * Keep it simple and self contained
> - the first example shouldn't require knowing anything but clojure syntax
> - the inputs to an example should either be literals or simple expressions
> - the user shouldn't have to figure out anything but the new concept or type
> * Build up examples cumulatively
> - each example should introduce at most one new concept
> - or reinforce the previous example (though that should be kept to a minimum)
> - or show the function working on a new data type

I would also add:

- exercise edge cases

I'm not sure, but maybe some formal transformation to show the general idea, if possible.

(reduce + 0 [1 2 3]) => (+ (+ (+ 0 1) 2) 3).
(map - [1 2 3]) => (-1 -2 -3)
(filter even? [1 2 3]) => (#_1 2 #_3)
(remove even? [1 2 3]) => (1 #_2 3)
(take 2 [1 2 3]) => (1 2 #_3)

With the removed items greyed out, or so. There only one example would be sufficient. Just to explain the idea. I'm not sure how useful this would be for more complicated functions, though...

Sincerely
Meikel

Justin Kramer

unread,
Jul 5, 2010, 6:22:12 PM7/5/10
to Clojure
I've integrated your suggestions into the wiki's guidelines:

http://clojure-examples.appspot.com/guidelines

Feel free to add anything else that needs mentioning. There's also a
talk page for discussion.

Justin

On Jul 2, 6:37 pm, Mike Meyer <mwm-keyword-googlegroups.
620...@mired.org> wrote:
> On Fri, 2 Jul 2010 14:50:18 -0700 (PDT)
>
> Justin Kramer <jkkra...@gmail.com> wrote:
> > Nice, Mike. I stole your work and put it into the Wiki I created to
> > see how it fit:
>
> >http://clojure-examples.appspot.com/clojure.core/reduce
>
> Well, I like it, but I might be a bit biased.
>
> I think the important part is the rules that went into picking the
> examples. I just picked examples from Walton that followed them,
> tweaked those to build up properly, and then added the edge
> cases.http://clojure-examples.appspot.com/guidelinesactually covers
Reply all
Reply to author
Forward
0 new messages