April 07, 2019
On 04/07/2019 08:41 AM, Robert M. Münch wrote:
> I have an AA int[ulong] and would like to traverse the AA from biggest
> to smallest by value. Is there an elegant way to do this?

Because associative array is a data structure to use when the order is not important, it comes down to getting the values and then sorting. Since there is already a .values that returns a copy of the values, I would just sort that one:

     auto arr = aa.values;
     sort(arr);
     use(arr);

I think that method might be faster than others because .values is provided by the AA implementation but I shouldn't say that without testing. :) So, with dmd v2.085.0, .values is 4 times faster than .byValues:

import std.algorithm;
import std.stdio;
import std.array;
import std.range;
import std.typecons;
import std.format;

enum aaElementCount = 100_000;
enum testCount = 100;

ulong expectedResult;

// So that the whole operation is not optimized out
void use(int[] aa) {
  const result = aa.sum;
  if (expectedResult == 0) {
    expectedResult = result;
  }
  // Make sure that all methods produce the same result
  assert(expectedResult != 0);
  assert(result == expectedResult, format!"%s != %s"(result, expectedResult));
}

void main() {
  auto aa = aaElementCount.iota.map!(i => tuple(i, i)).assocArray();

  import std.datetime.stopwatch;
  auto measurements = benchmark!(
    {
      auto arr = aa.byValue.array;
      // sort(arr);
      use(arr);
    },
    {
      auto arr = aa.values;
      // sort(arr);
      use(arr);
    },
    )(testCount);
  writefln("%(%s\n%)", measurements);
}

450 ms, 424 μs, and 8 hnsecs    <-- .byValue.array
108 ms, 124 μs, and 6 hnsecs    <-- .values

Of course the difference is much less when we comment-in the sort() lines.

Ali

April 08, 2019
On 2019-04-07 19:28:02 +0000, Dennis said:

> Did you import it? import std.algorithm;

:-/ of course not...

Why does DMD not give a hint, that an import from the standard lib might be missing? I find these explicit import statements very annyoing. DMD should build up a database of stuff it knows about (provided via a config file where to find what) and auto-import just the things I use/need. The current system is legacy based like it is in C since 40 years...

Anyway, might be worth a topic on its own...

-- 
Robert M. Münch
http://www.saphirion.com
smarter | better | faster

April 08, 2019
On Monday, 8 April 2019 at 07:53:23 UTC, Robert M. Münch wrote:
> On 2019-04-07 19:28:02 +0000, Dennis said:
>
>> Did you import it? import std.algorithm;
>
> :-/ of course not...
>
> Why does DMD not give a hint, that an import from the standard lib might be missing?

It does do this, so the question should be: why aren't its warnings
more extensive?

Example:

  void main() {
      writeln("Hello, world!");
  }

Fails to compile with this error:

  ./missing.d(4): Error: writeln is not defined, perhaps import std.stdio; is needed?

That seems to come from src/dmd/expressionsem.d , which uses importHint from
src/dmd/imphint.d , which just has this list:

  shared static this()
  {
      // in alphabetic order
      hints = [
          "calloc": "core.stdc.stdlib",
          "cos": "std.math",
          "fabs": "std.math",
          "free": "core.stdc.stdlib",
          "malloc": "core.stdc.stdlib",
          "printf": "core.stdc.stdio",
          "realloc": "core.stdc.stdlib",
          "sin": "std.math",
          "sqrt": "std.math",
          "writefln": "std.stdio",
          "writeln": "std.stdio",
          "__va_argsave_t": "core.stdc.stdarg",
          "__va_list_tag": "core.stdc.stdarg",
      ];
  }


April 08, 2019
On Monday, 8 April 2019 at 07:53:23 UTC, Robert M. Münch wrote:
> Why does DMD not give a hint, that an import from the standard lib might be missing? I find these explicit import statements very annyoing.

There currently are a few hard-coded import hints for common functions:
https://github.com/dlang/dmd/blob/master/src/dmd/imphint.d

But it definitely could be better.

As Sebastian said, you can do `import std.experimental.all;` or from version 2.086 `import std;` to import the entire standard library.

If dmd as a library pans out, a language server might automatically suggest imports for unresolved symbols like common Java and C# IDEs do.
April 08, 2019
Le 07/04/2019 à 19:16, Seb via Digitalmars-d-learn a écrit :
> Then you can do:
> 
> ---
> ["a": 1].byPair.array.sort!((a, b) => a.value < a.value).release.each!writeln;
> ---
> 
> You'll have a sorted array with key and value props.

That's what I would do: just operating on an array of {k,v} pairs.

-- 
diniz {la vita e estranj}
April 08, 2019
On Monday, 8 April 2019 at 08:31:33 UTC, Dennis wrote:
> On Monday, 8 April 2019 at 07:53:23 UTC, Robert M. Münch wrote:
>> Why does DMD not give a hint, that an import from the standard lib might be missing? I find these explicit import statements very annyoing.
>
> There currently are a few hard-coded import hints for common functions:
> https://github.com/dlang/dmd/blob/master/src/dmd/imphint.d
>
> But it definitely could be better.

Yeah, it's not too hard to improve this.
A quick start:

https://github.com/dlang/dmd/pull/9576
April 08, 2019
On Sunday, 7 April 2019 at 17:16:12 UTC, Seb wrote:
> ---
> ["a": 1].byPair.array.sort!((a, b) => a.value < a.value).release.each!writeln;
> ---

What's the purpose of .release? The documentation in https://dlang.org/phobos/std_range.html#.SortedRange.release is rather monosyllabic.
April 08, 2019
On Monday, 8 April 2019 at 17:13:32 UTC, Seb wrote:
> On Monday, 8 April 2019 at 08:31:33 UTC, Dennis wrote:
>> On Monday, 8 April 2019 at 07:53:23 UTC, Robert M. Münch wrote:
>>> Why does DMD not give a hint, that an import from the standard lib might be missing? I find these explicit import statements very annyoing.
>>
>> There currently are a few hard-coded import hints for common functions:
>> https://github.com/dlang/dmd/blob/master/src/dmd/imphint.d
>>
>> But it definitely could be better.
>
> Yeah, it's not too hard to improve this.
> A quick start:
>
> https://github.com/dlang/dmd/pull/9576

I can't make an issue yet, but since they're asking for a BugZilla issue,
a relevant one would be "published D examples fail without import hints".
In the very first chapter of the D Programming Language, library changes
result in errors for enforce (which you add) and std.algorithm.splitter

The book has an errata but the compiler's the very first thing that can
communicate "D has helpful error messages" instead of "maybe I should
wait for this language to mature a bit more".

For more comprehensive hints, isn't the documentation generated? Maybe,
patch docgen to generate this table as well.
April 08, 2019
On Monday, 8 April 2019 at 18:04:28 UTC, kdevel wrote:
> What's the purpose of .release? The documentation in https://dlang.org/phobos/std_range.html#.SortedRange.release is rather monosyllabic.

The sort function returns a SortedRange, which is usually an array wrapper with the extra type information that its content is sorted, enabling certain algorithms like lowerBound and upperBound with help of binary search.

"Ranges whose elements are sorted afford better efficiency with certain operations. For this, the assumeSorted function can be used to construct a SortedRange from a pre-sorted range. The std.algorithm.sorting.sort function also conveniently returns a SortedRange. SortedRange objects provide some additional range operations that take advantage of the fact that the range is sorted."
(https://dlang.org/phobos/std_range.html)

When you release it, you get it back as a normal slice without the type information that it is sorted, so you can assign it to regular old array variables. As mentioned in the quote, you can get it back as sortedRange with assumeSorted.
April 08, 2019
On Monday, 8 April 2019 at 18:04:28 UTC, kdevel wrote:
> On Sunday, 7 April 2019 at 17:16:12 UTC, Seb wrote:
>> ---
>> ["a": 1].byPair.array.sort!((a, b) => a.value < a.value).release.each!writeln;
>> ---
>
> What's the purpose of .release? The documentation in https://dlang.org/phobos/std_range.html#.SortedRange.release is rather monosyllabic.

As others have already explained, you'll get the original range back (instead of the SortedRange).
Sometimes, this is useful.
The obvious example is assigning back to the original range:

---
import std.experimental.all;
void main()
{
    auto arr = ["a": 1].byPair.array;
    arr = arr.sort!((a, b) => a.value < a.value);
}
---

https://run.dlang.io/is/8sFxVb

OTOH this works:

---
import std.experimental.all;
void main()
{
    auto arr = ["a": 1].byPair.array;
    arr = arr.sort!((a, b) => a.value < a.value).release;
}
---
https://run.dlang.io/is/TgXUZj

In the example where I used it, you won't need it.
Sorry for the confusion, but as it's often every now and then pretty useful, I thought it is a nice idea to give it more spotlight as it's one of the lesser known parts of Phobos.