August 24, 2021
On 8/24/21 1:14 PM, Paul Backus wrote:

>> On Tuesday, 24 August 2021 at 16:58:26 UTC, Adam D Ruppe wrote:
>>> On Tuesday, 24 August 2021 at 16:52:30 UTC, Ali Çehreli wrote:

>>>>     auto s = format!"hello %s world %s"(a, b);
>>>
>>> yikes that's like the worst thing in the whole D world. brutally slow
>>> by all metrics.

[...]

> Internally, `format` uses `formattedWrite`
> with an `Appender` as the output range [1]

That's what I thought. Additionally, some of my structs define toString() functions that work with a "sink" so they would be written into the buffer of an appender without extra string creation:

  https://dlang.org/library/std/format/write.html

To do even better, we could write the following function that reuses a static Appender object:

auto appendingFormatter(string fmt, string file = __FILE__, size_t line = __LINE__, Args...)(Args args) {
  import std.array : Appender;
  import std.format : formattedWrite;

  static Appender!(char[]) buffer;
  buffer.clear();
  buffer.formattedWrite!fmt(args);
  return buffer.data;
}

import std.stdio;

void main() {
  size_t total;

  enum N = 100;

  foreach (i; 0 .. N) {
    foreach (d; 0 .. N) {
      total += appendingFormatter!"hello %s world %s"(i, d).length;
      total += appendingFormatter!"goodbye %s moon %s"(i * 10, d / 7).length;
    }
  }

  writeln(appendingFormatter!"An arbitrary value: %s"(total));

  const a = appendingFormatter!"%s"(42); const b = appendingFormatter!"%s"(43);
  // BUG: Fails.
  assert((a == "42") && (b == "43"));
}

Performance is awesome because there is almost no memory allocation.

Unfortunately, there is that bug on the last line of main because there is no __COLUMN__ or __ID__ or __COUNTER__ or etc. that would differ per __LINE__. Or, is there? Please? :)

Do you know a trick that would pass that assertion?

Ali


August 25, 2021
On 8/24/21 3:33 PM, Ali Çehreli wrote:

> there is no __COLUMN__ or __ID__ or __COUNTER__ or etc. that would differ per __LINE__.

I found the following two closed PRs that tried to implement C's __COUNTER__ macro:

  https://github.com/dlang/dmd/pull/10093

  https://github.com/dlang/dmd/pull/10131

As mentioned in the second PR, the semantics can be confusing especially with separate compilation. (I wonder how C works out the semantics.) (And 'static foreach' may be sufficient to handle C's __COUNTER__ for us in a way that leaves the semantics to the user. (I am not sure about that...))

Actually, for this particular use case, I would be happy with a __COLUMN__ counter that would resolve to the location on the line e.g. exactly where the first '_' character of __COLUMN__ appeared. Combined with __FILE_FULL_PATH__ and __LINE__, this would allow us produce unique positions.

Does that make sense?

Ali


August 26, 2021
On Thursday, 26 August 2021 at 05:41:17 UTC, Ali Çehreli wrote:
> On 8/24/21 3:33 PM, Ali Çehreli wrote:
>
> > there is no __COLUMN__ or __ID__ or __COUNTER__ or etc. that
> would differ per __LINE__.
>
> I found the following two closed PRs that tried to implement C's __COUNTER__ macro:
>
>   https://github.com/dlang/dmd/pull/10093
>
>   https://github.com/dlang/dmd/pull/10131
>
> As mentioned in the second PR, the semantics can be confusing especially with separate compilation. (I wonder how C works out the semantics.) (And 'static foreach' may be sufficient to handle C's __COUNTER__ for us in a way that leaves the semantics to the user. (I am not sure about that...))
>
> Actually, for this particular use case, I would be happy with a __COLUMN__ counter that would resolve to the location on the line e.g. exactly where the first '_' character of __COLUMN__ appeared. Combined with __FILE_FULL_PATH__ and __LINE__, this would allow us produce unique positions.
>
> Does that make sense?
>
> Ali

The linked `__COUNTER__` (10131)  is actually fine.

I think it does to work inside a static  foreach as well.
whereas `__COLUMN__`   would not give you unique identifiers in a static foreach.


August 26, 2021
On Thursday, 26 August 2021 at 05:41:17 UTC, Ali Çehreli wrote:
> On 8/24/21 3:33 PM, Ali Çehreli wrote:
>
> > there is no __COLUMN__ or __ID__ or __COUNTER__ or etc. that
> would differ per __LINE__.
>
> I found the following two closed PRs that tried to implement C's __COUNTER__ macro:
>
>   https://github.com/dlang/dmd/pull/10093
>
>   https://github.com/dlang/dmd/pull/10131
>
> As mentioned in the second PR, the semantics can be confusing especially with separate compilation. (I wonder how C works out the semantics.) (And 'static foreach' may be sufficient to handle C's __COUNTER__ for us in a way that leaves the semantics to the user. (I am not sure about that...))
>
> Actually, for this particular use case, I would be happy with a __COLUMN__ counter that would resolve to the location on the line e.g. exactly where the first '_' character of __COLUMN__ appeared. Combined with __FILE_FULL_PATH__ and __LINE__, this would allow us produce unique positions.
>
> Does that make sense?

Yes, dmd uses something similar to generate unittests names.

__COUNTER__ would have been fine to name symbols because the mangles start with the module name so separate compilation would not have caused multiple definitions errors.
1 2
Next ›   Last »