add documentation example for RBTree#4041
Conversation
4fce5ac to
59a165b
Compare
|
ping @CyberShadow Something weird happened here with doc tester. One file changed, 12k changes in docs? |
|
Difference is due to the different version ... |
std/container/rbtree.d
Outdated
| import std.container: RedBlackTree; | ||
| import std.algorithm: equal; | ||
|
|
||
| auto rbt = new RedBlackTree!(int)(3, 1, 4, 2, 5); |
There was a problem hiding this comment.
I think idiomatic D would be to use the factory method, which uses IFTI to infer the type.
auto rbt = redBlackTree(3, 1, 4, 2, 5);
I'm not sure why that happened, but it seems to have reconciled itself now. |
|
One other thing to demonstrate may be how inserting a duplicate on a normal tree doesn't change the rbtree, and returns 0 to indicate it couldn't be added. |
57126de to
32f1b06
Compare
Nice idea - done!
I added wrappers for the convenience function for |
| //takes less but not allowDuplicates works just fine). | ||
| return new RedBlackTree!(ElementType!Stuff, binaryFun!less, allowDuplicates)(range); | ||
| } | ||
|
|
There was a problem hiding this comment.
Nice additions! I'd like to see unit tests specifically for all of these though.
There was a problem hiding this comment.
When I initially fixed the constructor to support range construction I intentionally did not add these because the redBlackTree overload set is terribly designed. With this, there are 8 overloads of redBlackTree just to accomodate arbitrary argument order, one of which is a classical case of boolean blindness. Blergh.
There was a problem hiding this comment.
Do you have a better idea? Imho ranges are the most common type in D, so redBlackTree should support it.
Idea: You could have a redBlackTreeDups that always adds the parameter allowDuplicates, but I don't know whether it's worth it ;-)
It would be nice to have named parameters in D at some point though ...
|
I think the string check is probably fine. Strings are definitely special in D, so even though they are arrays and arrays should match the variadic version, nobody I think would expect |
done.
Excellent :) |
|
LGTM |
|
Just saw the string stuff, please no! This makes the function utterly useless in generic code. Every specialization of such caliber requires that the caller also specializes to achieve generic behaviour. It doesn't scale and is likely to surprise programmers.
|
Hmm that makes sense, so you suggest just to change the otherwise failing unittest? I was just worried that there might be code that would rely on this behavior ... |
|
Yes, An (admittedly still contrived) example for good measure. The user guesses and types Treating all ranges equally eliminates such clumsy issues. |
Done with fc67d6f. Converting an object to a string for tests has been criticized on other PRs of mine, but it was already there, so I kept the "style". |
|
@JakobOvrum, your arguments are well founded. I don't see anyone expecting I'm actually thinking, however, that |
If I would add those checks, it would result to the old behavior if you only have one argument as strings are arrays. So I think the constraints should be more on the other side, but as the compiler already prefers the specific range function over the variadic function, there is no need to add an extra constraint. |
|
I just tested, and I think it would result in void foo(T)(T[]...)
{
pragma(msg, T);
}
void main()
{
foo("hello"); // outputs immutable(char)
} |
https://github.com/D-Programming-Language/phobos/blob/master/std/container/rbtree.d#L1864 Compare with the new test with range input (how it should be) https://github.com/greenify/phobos/blob/docu-rbtree/std/container/rbtree.d#L1972
|
That test uses explicit template instantiation. |
|
I fully agree with @schveiguy that we need to have a better way - I recently started yet another discussion on this The main point here is that the user shouldn't need to specify an argument he doesn't care about. |
I don't know which functions you're referring to, but if it's something like
Not all types support the comparison operators. |
What I mean is, we have overloads for many different reasons, many of them have to do with separating implementation based on templates. In this case, it's overloading based on template parameter types and quantities -- what overloading is for. I can agree that the documentation is verbose, and could be simplified, but I like that the calls are simple and straightforward.
Most do. Even custom structs do, as long as you have members that do. I think it's the most useful default. What would you suggest otherwise? In dcollections, the comparison is done via TypeInfo.compare, but I think this is cleaner. |
I absolutely share your opinion @schveiguy Is it possible to hide all the different methods, so that the generated documentation is shorter? Here is my short summary/opinion:
Input of other DLang members would be kind, so that we can move forward with this PR :) |
|
Here's one way (not necessarily the best, but it's a way) of simplifying the docs when you have a large number of overloads for different template argument types that are mostly implementation-specific (i.e. the user shouldn't need to know about them): Basically, the user sees (both in code and in the generated docs) a single, unified API with a single set of constraints that apply to all possible template arguments; while the implementation may be split up into multiple cases with complex sig constraints based on which case(s) of template arguments they are specialized for. |
That's a really nice idea, but afaict it doesn't work well with the current overloads and optional template parameters, especially because sth. like this |
|
I think we should leave the overloads as is, especially in this PR. I'm not a fan of docs that simplify to that level. What I think might look good is to reorganize the docs so the range and variadic versions are documented together, call the third argument "stuff" in both cases. That will at least cut down the docs in half. |
+1
done.
How do you combine them? |
Document both above the first function, then use |
|
BTW, looking at it now, it's probably not good to call both arguments "stuff". Sorry for that suggestion. Keeping the types separately named will help with the docs. |
|
Meh, looking at the docs, they are already all Ditto'd. And very little documentation to explain what each parameter does. You can probably just add a bunch of Params documentation, and this will make the whole thing much more understandable. |
Done. Also added range examples to the "ddoced" unittest. I think it makes sense to add
No worries, but can let's try to move this PR forward - it was really planned as a trivial edit ;-) |
std/container/rbtree.d
Outdated
| Params: | ||
| allowDuplicates = Whether duplicates should be allowed (optional, default: false) | ||
| less = predicate to sort by (optional) | ||
| elems = elements to insert into the rbtree (can be a range or variadic arguments) |
There was a problem hiding this comment.
Great, just need one more for range.
There was a problem hiding this comment.
wouldn't that be confusing to the user? Imho it's better to state that it can be used for both (see brackets).
There was a problem hiding this comment.
Well, the parameter is called range though.
Maybe name the documented parameter elems/range? Or rename actual function parameter elems?
There was a problem hiding this comment.
I like elems/range the most - updated ;-)
|
Bleh, ddoc seems not to like |
|
Try the other way (2 separate parameter docs), so we can put this to bed. |
cd412c2 to
5266467
Compare
|
done & squashed all commits. |
|
Nice, I think it LGTM. @quickfur @JakobOvrum any issues with this? |
|
PR reviewer ping pong :) |
|
Auto-merge toggled on |
add documentation example for RBTree
In reference to #4039 and #4040 also an example for Red Black Trees.