# Verbose or shorter stdlib crystal docs preferred

**URL:** <https://forum.crystal-lang.org/t/verbose-or-shorter-stdlib-crystal-docs-preferred/1931>\
**Category:** Crystal Contrib\
**Created:** [April 10, 2020, 7:28pm UTC](https://forum.crystal-lang.org/t/verbose-or-shorter-stdlib-crystal-docs-preferred/1931 "2020-04-10T19:28:26Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![rogerdpack](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/rogerdpack/32/117_2.png) [@rogerdpack](https://forum.crystal-lang.org/u/rogerdpack)\
**Post date:** [April 10, 2020, 7:28pm UTC](https://forum.crystal-lang.org/t/verbose-or-shorter-stdlib-crystal-docs-preferred/1931/1 "2020-04-10T19:28:26Z")

</div>

I’ve been working on polishing up some stdlib crystal docs for a new functionality.

Are “fully fleshed, rich, with examples” stdlib docs preferred or “shorter, less verbose” explanation style docs?

Thanks!

---

<div class="post-metadata">

**Author:** ![bcardiff](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/bcardiff/32/3_2.png) [@bcardiff](https://forum.crystal-lang.org/u/bcardiff)\
**Post date:** [April 10, 2020, 8:07pm UTC](https://forum.crystal-lang.org/t/verbose-or-shorter-stdlib-crystal-docs-preferred/1931/2 "2020-04-10T20:07:09Z")

</div>

I would say that examples are ok. But I would not expect the API docs to do a whole description of the module. I think that is more relevant to the crystal-book in some sections.

Do you want to share a sneak peek here of what you mean by “fully fleshed, rich, with examples”?

---

<div class="post-metadata">

**Author:** ![da1nerd](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/da1nerd/32/960_2.png) [@da1nerd](https://forum.crystal-lang.org/u/da1nerd)\
**Post date:** [April 12, 2020, 1:33pm UTC](https://forum.crystal-lang.org/t/verbose-or-shorter-stdlib-crystal-docs-preferred/1931/3 "2020-04-12T13:33:49Z")

</div>

I agree with @bcardiff. When I’m first learning a language I like to have something like the crystal-book that holds your hand through the language and explains the big picture of some of the modules. After that I want lean API docs with well documented inputs and outputs, but keep examples to a minimal. I think it makes it easier to find things. However, I do occasionally wish there were examples, but I think they should be limited to one.

On a side note I do wish more time was given to macros in the crystal-book.

---

<div class="post-metadata">

**Author:** ![rogerdpack](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/rogerdpack/32/117_2.png) [@rogerdpack](https://forum.crystal-lang.org/u/rogerdpack)\
**Post date:** [April 15, 2020, 3:28am UTC](https://forum.crystal-lang.org/t/verbose-or-shorter-stdlib-crystal-docs-preferred/1931/4 "2020-04-15T03:28:44Z")

</div>

Example of “rich, full, with examples”

```auto
  # Returns a new array with all elements sorted based on the return value of
  # their comparison method `#<=>`
  #
  # If *stable* is `true`, performs a stable sort, i.e. equal elements' relative order is preserved
  # (slower, uses more memory).
  # If *stable* is `false`, performs an unstable sort, i.e. equal elements' relative order may change
  # (faster, uses less memory).
  # For elements where being equal means interchangeable (`Primitive` and `String`), unstable sort is the default
  # (identity isn't distinguishable, so relative order doesn't matter, so it defaults to faster method).
  # For everything else, stable sort is the default.
  # 
  # a = [3, 1, 2]
  # a.sort # => [1, 2, 3]
  # a # => [3, 1, 2]
  #
  # class MyClass
  # property val : Int32
  #
  # def initialize(@val)
  # end
  #
  # def <=>(other)
  # self.val <=> other.val
  # end
  # end
  #
  # b = MyClass.new(1)
  # c = MyClass.new(1)
  # d = MyClass.new(0)
  # e = MyClass.new(2)
  # [b, c, d, e].sort # => [d, b, c, e] relative order is preserved by default
  # [b, c, d, e].sort(stable = false) # => [d, b, c, e] or [d, c, b, e] absolute order is respected, but relative order for equals may change
  # 
  def sort(stable = elements_have_identity?) : Array(T)
    ....

```

Terse might be something like

````auto
  # Returns a new array with all elements sorted based on the return value of
  # their comparison method `#<=>`
  #
  # If *stable* is `true`, performs a stable sort, see https://en.wikipedia.org/wiki/Sorting_algorithm#Stability
  # default is true for objects, false for Primitive and String.
  # ```
  # a = [3, 1, 2]
  # a.sort # => [1, 2, 3]
  # a # => [3, 1, 2]
  # b = [my_instance1, my_instance2, my_instance3].sort(stable = false)
  # b # => if any instance's compare the same their relative order may be rearranged.
  def sort(stable = elements_have_identity?) : Array(T)
    ....

````

Thanks!

---

<div class="post-metadata">

**Author:** ![Blacksmoke16](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/blacksmoke16/32/1241_2.png) [@Blacksmoke16](https://forum.crystal-lang.org/u/Blacksmoke16)\
**Post date:** [April 15, 2020, 3:36am UTC](https://forum.crystal-lang.org/t/verbose-or-shorter-stdlib-crystal-docs-preferred/1931/5 "2020-04-15T03:36:00Z")

</div>

In this context, `terse` would be better IMO. The other example in the verbose example would be better suited to `Comparable`.

Best documentation consists of explanation of what it does, what the arguments do/are, and a short example of using it. For anything more link out to related types.

---

<div class="post-metadata">

**Author:** ![straight-shoota](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/straight-shoota/32/36_2.png) [@straight-shoota](https://forum.crystal-lang.org/u/straight-shoota)\
**Post date:** [April 15, 2020, 9:15am UTC](https://forum.crystal-lang.org/t/verbose-or-shorter-stdlib-crystal-docs-preferred/1931/6 "2020-04-15T09:15:05Z")

</div>

The rich example seems too complicated. It should focus on the bare minimum. I’m not sure what’s the best way to demonstrate stable sort. Maybe sort arrays to avoid introducing an extra type?  
But the accompanying rich text is at the level of detail that we should be aiming for.

---

<div class="post-metadata">

**Author:** ![asterite](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/asterite/32/60_2.png) [@asterite](https://forum.crystal-lang.org/u/asterite)\
**Post date:** [April 15, 2020, 12:10pm UTC](https://forum.crystal-lang.org/t/verbose-or-shorter-stdlib-crystal-docs-preferred/1931/7 "2020-04-15T12:10:34Z")

</div>

> [@rogerdpack](#):
>
> for a new functionality

For what functionality?

I think discussing terse vs. rich is okay, but if we don’t know what is it for then it’s not clear why we are discussion it.

Just as a note, the current doc generator will take the first line of a doc comment as a summary, and show the full doc when you click on the definition. There’s already a terse vs. full in the current way.

---

<div class="post-metadata">

**Author:** ![rogerdpack](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/rogerdpack/32/117_2.png) [@rogerdpack](https://forum.crystal-lang.org/u/rogerdpack)\
**Post date:** [April 15, 2020, 1:34pm UTC](https://forum.crystal-lang.org/t/verbose-or-shorter-stdlib-crystal-docs-preferred/1931/8 "2020-04-15T13:34:34Z")

</div>

> [@asterite](#):
>
> For what functionality?

The “new” stable parameter, in the example case.

---

<div class="post-metadata">

**Author:** ![rogerdpack](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/rogerdpack/32/117_2.png) [@rogerdpack](https://forum.crystal-lang.org/u/rogerdpack)\
**Post date:** [April 15, 2020, 1:36pm UTC](https://forum.crystal-lang.org/t/verbose-or-shorter-stdlib-crystal-docs-preferred/1931/9 "2020-04-15T13:36:55Z")

</div>

> [@straight-shoota](#):
>
> Maybe sort arrays to avoid introducing an extra type?

I assume you mean in the example?  
Yeah it’s tricky in this case since to actually do an example where “stable = false” matters it has to be an object, not a primitive…hmm…

---

<div class="post-metadata">

**Author:** ![asterite](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/asterite/32/60_2.png) [@asterite](https://forum.crystal-lang.org/u/asterite)\
**Post date:** [April 15, 2020, 1:47pm UTC](https://forum.crystal-lang.org/t/verbose-or-shorter-stdlib-crystal-docs-preferred/1931/10 "2020-04-15T13:47:16Z")

</div>

Just a comment: I think stable short should be a separate function. It’s not like you want to configure sorting by passing an argument. When you sort stuff, you either want them stable or you don’t care. If you want it stable, you would call `stable_sort`.

That way there’s no need to clutter existing docs.

---

<div class="post-metadata">

**Author:** ![rogerdpack](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/rogerdpack/32/117_2.png) [@rogerdpack](https://forum.crystal-lang.org/u/rogerdpack)\
**Post date:** [April 16, 2020, 4:24am UTC](https://forum.crystal-lang.org/t/verbose-or-shorter-stdlib-crystal-docs-preferred/1931/11 "2020-04-16T04:24:35Z")

</div>

Hmm

Yeah there has been a small amount of earlier discussion:

> <https://github.com/crystal-lang/crystal/issues/6057#issuecomment-605584525>
>
> It may be useful to have the option to stable sort arrays.
> I'm thinking about adding it as a flag in Array#sort,...

Here’s the situation:

Imagine I get an array of…instances coming out of a database query in a certain initial order given by the query. I want to have the initial order be my secondary ordering, so I `sort_by` to introduce a new primary ordering, while retaining the secondary ordering that the array started with.  
If `sort_by` isn’t stable, any chained `sort_by` jumbles all previous ordering.  
So for `sort_by` at least, it feels like it should be default stable or it can lead to…unanticipated behavior. This is how Rust does it (though Go doesn’t).  
It seems to me that people that “don’t care, give me something sorted” might prefer a stable sort (fewer surprises, easier for beginners), unless they are really going for speed, in which case they might prefer an unstable sort.

For the other `sort` methods, it might not be intuitive that unstable by default means that comparisons that report “equal” are possible to result in a scrambled order, as well. [https://github.com/crystal-lang/crystal/issues/6057#issuecomment-605584525](https://github.com/crystal-lang/crystal/issues/6057#issuecomment-605584525)

See also [Poll: should default sort behavior be "fast" or "stable"?](https://forum.crystal-lang.org/t/poll-should-default-sort-behavior-be-fast-or-stable/1360)

So overall it seems to me like `unstable_sort` should be kind of an opt-in “you know what you’re getting in to” type of thing?

So maybe I can propose the addition of `unstable_sort` methods, for the reasons above, thoughts?

Thanks,

-Roger-

---

<div class="post-metadata">

**Author:** ![rogerdpack](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/rogerdpack/32/117_2.png) [@rogerdpack](https://forum.crystal-lang.org/u/rogerdpack)\
**Post date:** [April 16, 2020, 4:26am UTC](https://forum.crystal-lang.org/t/verbose-or-shorter-stdlib-crystal-docs-preferred/1931/12 "2020-04-16T04:26:51Z")

</div>

In terms of “big vs. small docs” I noticed that go’s docs have “big examples” but they’re just collapsed at the top of the documentation (so basically, at the Class or Module level), ex:

[https://golang.org/pkg/sort](https://golang.org/pkg/sort)  
But maybe that’s because they don’t have a book?

If so it might be good to link from the stdlib docs to the book?  
Just an idea.

---

<div class="post-metadata">

**Author:** ![rogerdpack](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/rogerdpack/32/117_2.png) [@rogerdpack](https://forum.crystal-lang.org/u/rogerdpack)\
**Post date:** [April 16, 2020, 5:27am UTC](https://forum.crystal-lang.org/t/verbose-or-shorter-stdlib-crystal-docs-preferred/1931/13 "2020-04-16T05:27:33Z")

</div>

I remembered one thing in favor of parameter with default. The default can be set based on the element type of the Array.

You can have an “sensible default,” for instance with an Array of Primitives, since there is no “identity” among equal elements, relative order doesn’t matter, so unstable sort works “as well as stable” so it can default to unstable without any penalty. It can set up an “intelligent default”.  
The benefit being if somebody new’s up an array of Int32’s and runs `sort` on it they get the “fast sort” by default, without having to fully understand why. It might be worth having, so that people can call `sort` and it “just does the right thing” so nobody has to worry about it.

That’s how Java does it. If it’s a Collection of Primitives, then it uses “fast unstable sort” if it’s objects, it uses “stable sort”.

Or maybe that’s too confusing and better to just go with explicit (method names or parameter with a universal default)? See points above. Hmm…

---

<div class="post-metadata">

**Author:** ![straight-shoota](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/straight-shoota/32/36_2.png) [@straight-shoota](https://forum.crystal-lang.org/u/straight-shoota)\
**Post date:** [April 16, 2020, 10:48am UTC](https://forum.crystal-lang.org/t/verbose-or-shorter-stdlib-crystal-docs-preferred/1931/14 "2020-04-16T10:48:16Z")

</div>

Yeah, I don’t think such extensive examples should be in the API docs. Linking to advanced guides would be a good solution.
