www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Deprecate std.signals?

reply Berni44 <someone somemail.com> writes:
I've got the feeling, that std.signals is rarely used and not up 
to D's standards... Therefore I suggest to move it to undead and 
deprecate it.

But I might err on this. What do you think?
Mar 30 2021
next sibling parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Tue, Mar 30, 2021 at 11:23:21AM +0000, Berni44 via Digitalmars-d wrote:
 I've got the feeling, that std.signals is rarely used and not up to
 D's standards... Therefore I suggest to move it to undead and
 deprecate it.
 
 But I might err on this. What do you think?
Yes. T -- It said to install Windows 2000 or better, so I installed Linux instead.
Mar 30 2021
prev sibling next sibling parent Clint E. <clint gmail.com> writes:
On Tuesday, 30 March 2021 at 11:23:21 UTC, Berni44 wrote:
 I've got the feeling, that std.signals is rarely used and not 
 up to D's standards... Therefore I suggest to move it to undead 
 and deprecate it.

 But I might err on this. What do you think?
Go ahead make my day! Clint.
Mar 30 2021
prev sibling next sibling parent Bastiaan Veelo <Bastiaan Veelo.net> writes:
On Tuesday, 30 March 2021 at 11:23:21 UTC, Berni44 wrote:
 I've got the feeling, that std.signals is rarely used and not 
 up to D's standards... Therefore I suggest to move it to undead 
 and deprecate it.

 But I might err on this. What do you think?
I might be able to provide some background on this. Prior to becoming a D convert I used to program in C++, and Qt was the enabler that made that a pleasant experience. At the heart of Qt is their signal-and-slot concept that makes it possible to tie components together without them needing to know about each other or their lifetimes. It’s implementation relies heavily on the C preprocessor. Back in 2004 I decided to test D’s claim that a preprocessor is unnecessary to be equally powerful as C and C++. As a litmus test I made an attempt at implementing the signals and slots concept. I wasn’t quite successful [1]. Others tried as well, and I suppose that Walter got tired of the subject coming up on the mailing list time and again because one day he announced that he had implemented it himself and since then it has been in the standard library. I have always thought that this was a good idea, and I still do: if signals and slots are standardised, GUI libraries and other frameworks can be built on top of that and then they will all be compatible. Somehow that hasn’t happened yet. Neither has `std.signals` been the last word on the subject, because both `descore`[2] and `phobosx`[3] provide alternative implementations. And if I’m not mistaken, `dlangui`[4], ironically, uses its own variant. I understand that `std.signal` is not up to modern standards, and maybe deprecating it is a good idea. But I can’t help feeling that we thereby have failed to prove a point. — Bastiaan. [1] http://www.dsource.org/projects/dcouple/wiki [2] https://code.dlang.org/packages/descore [3] https://code.dlang.org/packages/phobosx [4] https://code.dlang.org/packages/dlangui
Apr 04 2021
prev sibling next sibling parent Berni44 <someone somemail.com> writes:
On Tuesday, 30 March 2021 at 11:23:21 UTC, Berni44 wrote:
 I've got the feeling, that std.signals is rarely used and not 
 up to D's standards... Therefore I suggest to move it to undead 
 and deprecate it.

 But I might err on this. What do you think?
I meanwhile filed a [PR](https://github.com/dlang/phobos/pull/7952). If you've got still any opinions on that, you might like to share them there.
Apr 12 2021
prev sibling parent reply Ahmet Sait <nightmarex1337 hotmail.com> writes:
On Tuesday, 30 March 2021 at 11:23:21 UTC, Berni44 wrote:
 I've got the feeling, that std.signals is rarely used and not 
 up to D's standards... Therefore I suggest to move it to undead 
 and deprecate it.

 But I might err on this. What do you think?
So I did some research on this looking at phobos and a bunch of other signal/event implementations and concluded that std.signals isn't even that bad (in fact it's better than some of the stuff found in the wild). It has issues but they are fixable. It's nonsensical to me how people want to remove code before talking about why is it bad and how can it be done better. So let's do that first. Issues with std.signals as far as I see: - Signal is a mixin template This one wasn't supposed to be a problem but semantics of mixin templates result in this issue: [Issue 5028 - Problem with named mixins in base class and derived class](https://issues.dlang.org/show_bug.cgi?id=5028) I would be in favor of fixing the semantics for the better instead of blaming this particular design. Mixin templates even allow for some neat tricks like making `emit()` function protected and therefore making it only callable in the class the - Signal uses weak reference semantics This is not actually an issue but a questionable choice nonetheless. Currently, Signal puts delegates into a malloc-ed array which is not scanned by the GC and it subscribes to the object's dispose event using `rt_attachDisposeEvent()`, so when some object is collected (or manually destroyed), the Signal gets notified and it removes those delegates which reference that destroyed object. I don't know what behavior is the better default but events are strong references where I'm coming from - Signal does not work with lambda delegates This one is basically a consequence of the previous point and looks like the biggest reason people handroll their own; `rt_attachDisposeEvent()` requires an Object and therefore Signal depends on the delegate context pointer referring to a class instance. If there was a proper way to know what kind of context pointer a delegate has, this wouldn't be an issue. See [Issue 19842 - std.signals Segfault when connecting with a lambda](https://issues.dlang.org/show_bug.cgi?id=19842). - Making closures capture the variables into an object instance would solve this for most cases except struct member functions still won't work. See [Issue 9601 - Make regular D objects on closures](https://issues.dlang.org/show_bug.cgi?id=9601). - Introducing different delegate types to the language would potentially solve this. The idea is to have different delegates that are compiled down to the same runtime code but allow for overloading via type system similar to how char & byte types work. I suspect it is unlikely for this idea to see the light of day considering the immense bureaucratic nonsense in the DIP process. Happy to be proven wrong of course. - Making delegates even fatter by introducing a simple `ptrType` field so that we can just check it. Not a fan of this idea. - Making `rt_attachDisposeEvent()` work with things other than Object. I have no idea if this is feasible but theoretically the GC can provide such an API (callback for when a memory region is collected). - Alternatively, screw that runtime dispose event feature and just stop. Make delegates strongly referenced and tell users to be careful and not destroy/free stuff if it's referenced by delegates somewhere. - Have a better idea? Let's see what you got. - Signal is not thread safe I don't think this is even relevant. Maybe fix shared first? :P - Signal.emit() is not reentrant It currently does not allow recursive calls to the same signal. Looks like a limitation imposed in order to fix other bugs. Now let's look at bugzilla: - [Issue 4150 - std.signals causes memory corruption and heisenbugs](https://issues.dlang.org/show_bug.cgi?id=4150) This bug is no longer valid, not reproducable, and should be closed. - [Issue 9606 - `std.signal` implementation is fundamentally incorrect](https://issues.dlang.org/show_bug.cgi?id=9606) Looks like a valid bug. Signal assumes `rt_attachDisposeEvent()` callback is not called inside emit(). Related to weakref business above. - [Issue 16203 - std.signals connect() error](https://issues.dlang.org/show_bug.cgi?id=16203) Duplicate of [Issue 19842 - std.signals Segfault when connecting with a lambda](https://issues.dlang.org/show_bug.cgi?id=19842). - [Issue 17011 - cleanup std.signals documentation](https://issues.dlang.org/show_bug.cgi?id=17011) Documentation enchanment. - [Issue 18903 - std.signals uses _dtor](https://issues.dlang.org/show_bug.cgi?id=18903) Not actually a bug. - [Issue 19842 - std.signals Segfault when connecting with a lambda](https://issues.dlang.org/show_bug.cgi?id=19842) The biggest actual problem with std.signals as has been mentioned above. There is literally nothing interesting about what other implementations do either. Everyone just does the same thing creating yet another struct with delegate[] array over and over again thinking what they do is magically better. Idk maybe that's what std.signals should do after all ¯\\\_(ツ)_/¯ Let's see what people think.
May 08 2021
next sibling parent Berni44 <someone somemail.com> writes:
On Saturday, 8 May 2021 at 09:37:07 UTC, Ahmet Sait wrote:
 So I did some research on this looking at phobos and a bunch of 
 other signal/event implementations and concluded that 
 std.signals isn't even that bad (in fact it's better than some 
 of the stuff found in the wild). It has issues but they are 
 fixable.
Many thanks for doing this! :-)
May 08 2021
prev sibling next sibling parent Imperatorn <johan_forsberg_86 hotmail.com> writes:
On Saturday, 8 May 2021 at 09:37:07 UTC, Ahmet Sait wrote:
 On Tuesday, 30 March 2021 at 11:23:21 UTC, Berni44 wrote:
 [...]
So I did some research on this looking at phobos and a bunch of other signal/event implementations and concluded that std.signals isn't even that bad (in fact it's better than some of the stuff found in the wild). It has issues but they are fixable. [...]
Agreed. Don't just turn away, fix the bugs. Those needs to be addressed anyway. Signals still have a place imo. If ppl are in a "cleaning mood" there are many places to do that anyway ☀️
May 08 2021
prev sibling parent reply Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Saturday, 8 May 2021 at 09:37:07 UTC, Ahmet Sait wrote:
 On Tuesday, 30 March 2021 at 11:23:21 UTC, Berni44 wrote:
 I've got the feeling, that std.signals is rarely used and not 
 up to D's standards... Therefore I suggest to move it to 
 undead and deprecate it.

 But I might err on this. What do you think?
So I did some research on this looking at phobos and a bunch of other signal/event implementations and concluded that std.signals isn't even that bad (in fact it's better than some of the stuff found in the wild). It has issues but they are fixable.
I have no opinion on this, but just want to point out that many programmers now expect React-like observer-patterns. I'm not making a judgment of whether that is good or bad, but something comparable is more likely to be adopted.
May 08 2021
parent reply Bastiaan Veelo <Bastiaan Veelo.net> writes:
On Saturday, 8 May 2021 at 11:16:06 UTC, Ola Fosheim Grøstad 
wrote:
 On Saturday, 8 May 2021 at 09:37:07 UTC, Ahmet Sait wrote:
 So I did some research on this looking at phobos and a bunch 
 of other signal/event implementations and concluded that 
 std.signals isn't even that bad (in fact it's better than some 
 of the stuff found in the wild). It has issues but they are 
 fixable.
I have no opinion on this, but just want to point out that many programmers now expect React-like observer-patterns. I'm not making a judgment of whether that is good or bad, but something comparable is more likely to be adopted.
For someone alien to React, how would you describe the main differences? Thanks, —Bastiaan.
May 09 2021
parent reply Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Sunday, 9 May 2021 at 11:11:35 UTC, Bastiaan Veelo wrote:
 For someone alien to React, how would you describe the main 
 differences?
It is more like a protocol than an implementation, so that you can implement it in many different ways depending on the datastructure you want to observe. Fits well with RAII. IIRC, the key point is that you obtain a subscriber-delegate that produces an unsubscribe delegate when you subscribe. You then call it from the destructor of the observer-owner. I assume you can use it for wrapping existing C/C++ libraries. What is convenient is that you can change the implementation without changing the entire codebase.
May 09 2021
parent Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Sunday, 9 May 2021 at 11:20:53 UTC, Ola Fosheim Grøstad wrote:
 On Sunday, 9 May 2021 at 11:11:35 UTC, Bastiaan Veelo wrote:
 For someone alien to React, how would you describe the main 
 differences?
It is more like a protocol than an implementation, so that you
I guess I should mention that the advantage of this would be that you can write code for the protocol. Working kinda like ranges with filter(), map() etc, so that the observer gets conveniently filtered and converted data using ranges-like library functions.
May 09 2021