Hello, today I'm here to suggest a guideline inspired by C++, for the stdlib conception.
I propose that anything that can work with a range instead of a container, should do so.
Let's reference a bit:
Krux02 already raised the issue 2 years ago, but it's a small paragraph, though it is of massive implication: https://forum.nim-lang.org/t/2111/1#13072 please read under the dot "loops and iterators, algorithms for collections".
Another reference mentioning the current efforts in standardization around it: https://www.fluentcpp.com/2017/01/12/ranges-stl-to-the-next-level/
So obviously today my problem with nim, is around sequtils, and set/tables, they don't cross operate. I can't apply a set difference between the keys of a hashtable and a set, without going through copies today, because the API of the algorithm is not decoupled: it takes containers instead of taking ranges !
Decoupling like this serves as a kind of duck typing which allows for combinatorial usages of procedures that would otherwise need tons of ad-hoc overloads to open to these usages, or simply have to be rewritten to work efficiently, as in this case: https://stackoverflow.com/a/49409410/893406
The advantages opened by this guideline are immense. The possibility of using sequtils-type's functional-style algorithms to any range. For example database queries. Or reversed content, or filtered content (all odds, or all not 0...). Or like boost::transform_iterator allows, adaptation of collections, like say, the values (or keys) in a hashtable.
And all that, with no copies, and no runtime overhead.
Of course sometimes an algorithm only makes sense for a particular kind of container. In this case, concepts can be used to restrict the genericity of the otherwise type-erased containers passed through ranges.
set is tailored for high performance hence it's only work with ordinal type.
Are you perhaps thinking like this package? https://nimble.directory/search?query=functional
Range in Nim usually is array and seq (cmiiw), and to support argument whether it's array or seq is using openArray[Type]
Table should work differently with range so I'm not sure what usage that work either on table or range.
About copies or sharing memory, it's been discussed in many threads, like using immutable variable which ensure of sharing, etc.
You missed my feature request "Make openarray a concept".
Any container that matches the concept (Iterable) would work with sequtils.
We could add other concept like Enumerable (iterable with an index/pairs) and go down the Monad rabbit hole but I do think it's useful.
Table doesn't work differently enough to break the iterable rules, what kind of ranges are you thinking about ? A range is a begin and an end iterator. Or otherwise said, one iterator with a "isFinished" method (since it is nim's choice). Soon they'll have next() if I understand correctly. Then, all procedures which work with OpenArray whould take an iterator instead.
The collection libraries of your link seems to get it right https://networkos.net/nim/collections.nim/doc/api/collections/iterate.html
the rest is 404 or 0.0.3, but zero-functional looked interesting, even though it's not necessary to go meta to get the same result.
Anyway this is all over the place. sequtils, sequtils2 ? misc ? collection libraries ? language extensions ? lots of attempts to to breathe in a language/ecosystem that doesn't grow fast enough it seems.
I thought table can get the element with key while range got the element with index, to iterate between table and range is using pairs and items and their mutable variants. to iterate table, keys or values, can use iterator keys and values .
You missed my feature request "Make openarray a concept".
Any container that matches the concept (Iterable) would work with sequtils.
Yes, this is good.
I belong to the camp that thinks Iterator is/can be bad concept because it is stateful and if underlying container change while you iterate it is almost certainly a crash. Iterators are sometimes required though, but they should be used only if nothing else works.
If algorithms start to consume stateful objects like iterators it can be a disaster. C++ is crappy when it comes to algorithms, imo it is bad example how to do things. The algorithm should take whole container or a stateless slice (openarray) as argument and provide result in one invocation.
We can have separate iterutils library that will be used when statefulness is required.
Update: there are other ways in Nim how you can achieve container/algorithm separation - templates accepting block of code, higher order function, function lifting.