On Monday, 10 April 2017 at 04:32:20 UTC, Adam D. Ruppe wrote:
On Sunday, 9 April 2017 at 14:47:39 UTC, Jonathan Marler wrote:
Does anyone know why Socket and Address in phobos were created as classes instead of structs?

It is probably just the historical evolution, but I find it pretty handy: I did a subclass of Socket to do SSL, then as is nice with classes, I can pass that to other code using the Socket interface and have it work.

So I'd be sad if they changed it now too much, the class is legitimately useful here and actually not very expensive`.

An interesting benefit. However, I don't think this is the ideal way to support such a use case. I think it would have been better if there was a shared stream/socket-like interface that you could override to use raw sockets or SSL. I'll explain why.

My first thought is that since the interface you are using (the Socket class) wasn't really designed to be overridden, you probably had to do some interesting hacks to make it work. For example, when you accept a new socket, you probably had to delete the Socket object you got and create a new SSLSocket object passing the handle from one to the other, and make sure that the original Socket object didn't close it. I'm guessing that to prevent this close you probably set the socket handle on the accepted Socket object to null/invalid? Or maybe you just called the raw accept function and created a new object. But if the library is the one calling accept, then you would obviously have to override the accept function and do something that I would call "hacky".

My other thought is that by separating both the virtual interface and the raw socket functions, you have provided both a low-level and high-level API that each application can choose to use. The tradeoff being "control" vs "extensibility". The high-level being more extensible (can be overriden to support things like SSL), and the low-level being less abstracted and therefore provides more control or access to the underlying implementation. This low-level access is more useful for code that needs to use socket-specific features.

I will say that one disadvantage with this approach is that by separating both the virtual interface and the direct socket interface, you open up the door for library writers to make the mistake of using the wrong level of the API. If a library used the lower-level API and you wanted to override it with say, an SSL implementation, then you are out of luck unless you update the library to use the higher level interface. Of course this is more of a "practical real world" disadvantage that "in theory" can be prevented with good libraries.

-----------------------
DISCLAIMER
-----------------------
I would like to say something to anyone who wants to contribute to this thread. These comments are meant to discuss the pros/cons of the std.socket design and DO NOT serve as justification for changing phobos. Such a change would require much more discussion. The problem I've seen is that people will immediately halt a conversation by jumping to the end and arguing that such ideas will never be implemented because the benefit to risk ratio is too low. Benefit to risk ratio is very good and necessary discussion to have, however it's not good to stop a conversation early by jumping to this stage before people have even had a chance to discuss the merits of design and ideas on their own. Any discussion on the ideas/design with your thoughts/feedback/experience are welcome. If you want to discuss whether ideas/changes should be carried out, I would hold off those comments since it derails good discussion. Thanks.

Reply via email to