Thread overview
d unpopular why is
6 days ago
monkyyy
6 days ago
Vijay Nayar
5 days ago
monkyyy
6 days ago

tldr: std.containers is bad.

D at its best is a cleaned up d with extensive meta programming. Of the meta-programming paradigms most important for genetic code is probably templates and iterators.

Why are templates with an iterator concept important, well citing Alexander Stepanov era arguments and stl, you can separate out algorithms from data structures and have n^2 implementations for n*2 blocks of code, because every data structure with every algorithm should just fit together nicely. BUT that's only true IFF data structures and algorithms are roughly balanced.

Between std.algrothm, std.range, std.array, etc. I estimate there's probably 100 useful algorithms, std.containers defines 5.(And I have a low opinion of them); 100 * 5 isn't balanced in the slightest, like maybe if there were 20 there be 10 useful ones.

As it stands using the std effectively probably means that:

  1. your willing to learn templates
  2. your willing to write data structures
  3. you learn to complexity of the std take on d's ranges
  4. it isn't easier to just use slices and aa everywhere(making the template hell that std made, probably less effective than writing 2 versions of every algorithm with much less templates)

That's a high upfront cost, and an ongoing cost of writing the data structures.

6 days ago

On Monday, 20 June 2022 at 14:04:25 UTC, monkyyy wrote:

>

tldr: std.containers is bad.

If I understand your point correct, it is that std.container classes appear to be almost empty, and yet there's a ton of algorithms in std.range and std.algorithm, and you find this to be imbalanced because all these algorithms are not useful without a data structure to act upon.

The way D is written with templates and ranges is certainly different than what you might expect from C++'s STL or Java's libraries, which has pros and cons.

The cons:

  • If you approach things by starting with the data structure (the noun), and then look for things you can do with it (verbs), then the code/docs can seem disorganized and scattered.
  • Taking time to understand templates/ranges takes time.
  • Each class which returns or takes in a range introduces a layer of templates which your code may have to account for.

The pros:

  • If you approach things by starting with the functions (verbs), then they can be applied to any data structure (noun) that you want, even new ones that you create.
  • A bit of time invested up front in understanding templates/ranges applies to all data structures, not just one at a time.
  • The use of std.range.interfaces can make writing your own code less complex when dealing with ranges.

Thankfully the number of methods that define what a range is is fairly small, thus creating your own struct to represent one for your own classes starts to become natural after a bit of practice.

There will be many cases where the logic you are trying to do, such as returning the minimum or maximum of a range requires that the entire range be consumed (e.g. by calling std.array : array). That's OK, just because you use ranges, it doesn't mean they're the cure-all for all problems. From an efficiency standpoint, this is one of the reasons that ForwardRanges are there, you can "save()" your position and have one function compute the max of the remaining elements, and then still iterate forward with other algorithms.

Even so, there are a few cases where I struggle to use ranges, especially cases where an algorithm "seeks" a particular value, and then starts iterating forwards and backwards to find particular data. Those cases often require a total rewrite of the algorithm.

5 days ago

On Tuesday, 21 June 2022 at 06:59:34 UTC, Vijay Nayar wrote:

>

On Monday, 20 June 2022 at 14:04:25 UTC, monkyyy wrote:

>

tldr: std.containers is bad.
Thankfully the number of methods that define what a range is is fairly small, thus creating your own struct to represent one for your own classes starts to become natural after a bit of practice.

I'm no stranger to writing data structures; if anything I do it too much.

To put it another way, lets say the devs will implement one block of code I suggest. If I suggest an algorithm in an ideal world that will produce 5 new useful instantiations of lazy std-only code. If they implement a new data structure that will make 100 new instantiations.

Fundamentally why shouldn't the next 5 data structures that are arguably general that someone thinks up off the top of their head not be included?

(and the answer I got a while back was they are waiting on std.experimental.allocator to be released; for .... reasons)