Re: Silicon Valley D Meetup - March 18, 2021 - "Templates in the D Programming Language" by Ali Çehreli

2021-03-19 Thread Ali Çehreli via Digitalmars-d-announce

On 3/19/21 2:45 AM, data pulverizer wrote:

> I have to say that I got an enormous amount out of it!

Thank you for attending and steering the discussion to interesting 
places. It turned out to be much different from a "beginner-friendly" 
presentation. :)


It was interesting to understand some code by Andrei:


https://gist.github.com/andralex/0d85df38be2d9ffbe89cf1fb51c44213#file-reify-d-L164

It was interesting to realize that the selected line above can be an 
example of a use case for nested templates. Instead of the following 
line where the first template parameter is implicitly the "needle" and 
the rest are the "haystack"


  static assert(staticIndexOf!( byte, byte, short, int, long) ==  0);

we can use nested templates to have more readable code:

  static assert(staticIndexOf!byte.among!(byte, short, int, long) ==  0);

(Assuming 'among' is a nested template inside 'staticIndexOf'.)

> I feel energised for what I learned.

It is too nerdy to say but I could not go to sleep easily due to some 
adrenaline rush! Ha ha! :D


> There was one other person who made a useful comment that
> helped my understanding whose name I don't recall - thank you
> too.

That must be Jon Degenhardt. Jon mentioned how PR 7678 reduced the 
performance of std.regex.matchOnce. After analyzing the code we realized 
that the performance loss must be due to two delegate context allocations:



https://github.com/dlang/phobos/pull/7678/files#diff-269abc020de3a951eaaa5b8eca5a0700ba8b298767c7a64f459e74e1531a80aeR825

One delegate is 'matchOnceImp' and the other one is the anonymous 
delegate created on the return expression.


We understood that 'matchOnceImp' could not be a nested function because 
of an otherwise useful rule: the name of the nested function alone would 
*call* that function instead of being a symbol for it. That is not the 
case for a local delegate variable, so that's why 'matchOnceImp' exists 
as a delegate variable there.


Then there is the addition of the 'pure' attribute to it. Fine...

After tinkering with the code, we realized that the same effect can be 
achieved with a static member function of a static struct, which would 
not allocate any delegate context. I add @nogc to the following code to 
prove that point. The following code is even simpler than Jon and I came 
up with yesterday.


void foo(ref int i) pure @nogc @safe {
  // Another local variable that will be used by the static
  // function of the static struct
  double d = 0.0;

  /* Instead of a lambda variable like this:

 auto bar = () @trusted {
   // ...
 };

 We use a static member function of a static struct:
   */
  static struct S {
static auto bar(ref int j, double e) pure @trusted @nogc {
  // Doing something unsafe inside this trusted function
  *(cast(int*)cast(long*)&j) += 42 + e;

  // Totally unrelated: It is a shame that the 'double'
  // expression on the right-hand side is added to an 'int'
  // on the left-hand side but we know that. :/
}
  }

  // Pass needed variables instead of using them from a delegate
  // context
  return (&S.bar)(i, d);

  /* The following more convoluted method works as well but seems
   * unnecessary:

  alias T = typeof(&S.bar);
  enum attrs = functionAttributes!T | FunctionAttribute.pure_ ;

  return (() @trusted @nogc => (cast(SetFunctionAttributes!(T,
  functionLinkage!T, attrs)) &S.bar))()(i, d);
  */
}

void main() {
  int i = 0;
  foo(i);
  assert(i == 42);
}

There: we injected @trusted code inside a @nogc @safe function.

Question to others: Did we understand the reason for the convoluted code 
in that PR fully? Is the above method really a better solution?


Ali



Re: On the D Blog--Symphony of Destruction: Structs, Classes, and the GC

2021-03-19 Thread apz28 via Digitalmars-d-announce

On Thursday, 18 March 2021 at 12:55:17 UTC, Mike Parker wrote:
On Thursday, 18 March 2021 at 12:27:56 UTC, Petar Kirov 
[ZombineDev] wrote:




Just implementation deficiency. I think it is fixable with 
some refactoring of the GC pipeline. One approach would be, 
(similar to other language implementations - see below), that 
GC-allocated objects with destructors should be placed on a 
queue and their destructors be called when the GC has finished 
the collection. Afterwards, the GC can release their memory 
during the next collection.


This need to improve which allow to call free memory in destructor
For realloc..., when size = 0, it needs to call free

https://github.com/dlang/druntime/blob/3a32cc0305d4dd066f719d4c2df97337c86ea7ff/src/core/internal/gc/impl/conservative/gc.d#L444

vs

https://github.com/dlang/druntime/blob/3a32cc0305d4dd066f719d4c2df97337c86ea7ff/src/core/internal/gc/impl/conservative/gc.d#L678




Re: On the D Blog--Symphony of Destruction: Structs, Classes, and the GC

2021-03-19 Thread Paulo Pinto via Digitalmars-d-announce
On Thursday, 18 March 2021 at 12:27:56 UTC, Petar Kirov 
[ZombineDev] wrote:

On Thursday, 18 March 2021 at 09:21:27 UTC, Per Nordlöw wrote:

[...]


Just implementation deficiency. I think it is fixable with some 
refactoring of the GC pipeline. One approach would be, (similar 
to other language implementations - see below), that 
GC-allocated objects with destructors should be placed on a 
queue and their destructors be called when the GC has finished 
the collection. Afterwards, the GC can release their memory 
during the next collection.


[...]


Small correction, since .NET 5 / C# 9, implementing IDisposable 
isn't required if the Dispose() method is available.


This is done as performance improvement for using structs with 
determistic destruction and avoid implicit convertions to 
references when interfaces are used.


Re: On the D Blog--Symphony of Destruction: Structs, Classes, and the GC

2021-03-19 Thread Per Nordlöw via Digitalmars-d-announce

On Thursday, 18 March 2021 at 12:21:46 UTC, Mike Parker wrote:
I actually don't agree with that. I'll be discussion the 
solution in the next article:


if(!GC.inFinalizer) {
...
}

It's perfectly fine to perform GC operations in destructors 
when they aren't invoked by the GC.


Could we at least add some guard in the GC that notifies the user 
of the reason for getting an exception, preferrably including a 
source position, when trying to allocate in a destructor run 
during finalization? Not getting an explanation has stolen hours 
of my development time on several occasion. And likely happen in 
the future for other users aswell potentially making them abandon 
D for other languages.


Re: Silicon Valley D Meetup - March 18, 2021 - "Templates in the D Programming Language" by Ali Çehreli

2021-03-19 Thread data pulverizer via Digitalmars-d-announce

On Wednesday, 17 March 2021 at 21:54:27 UTC, Ali Çehreli wrote:

I will explain templates in a beginner-friendly way.

Although this is announced on Meetup[1] as well, you can 
connect directly at


  
https://us04web.zoom.us/j/2248614462?pwd=VTl4OXNjVHNhUTJibms2NlVFS3lWZz09


March 18, 2021
Thursday
19:00 Pacific Time

Ali

[1] 
https://www.meetup.com/D-Lang-Silicon-Valley/events/kmqcvqyccfbxb/


I turned up to this online meetup and I have to say that I got an 
enormous amount out of it! Conversations like this once a month 
or so a few years ago would have made me a much better programmer 
(and maybe even a different person) now. Ali spent a lot of time 
dissecting code in such an informative, cogent, and enlightening 
way, I'm kicking myself for not getting involved in these kinds 
of meetings before. Even though the scheduled time for me was 
2:00am in the morning, I feel energised for what I learned. It's 
a bit like I was groping around in the semi-darkness and someone 
switched on a light bulb.


Many thanks to Ali for setting this one up!  There was one other 
person who made a useful comment that helped my understanding 
whose name I don't recall - thank you too.