October 06, 2015
On Friday, 2 October 2015 at 02:25:21 UTC, Yaser wrote:
> Are there any critical frameworks or libraries that are holding you back in fully investing in D? Obviously I think D is an awesome language, but some frameworks/libraries hold me back, wish I could do everything in D.

Nothing major for me, just a plentitude of small problems.

For example: you can't rely on Clock.currTime.toString() (or ISO string overloads) to provide a reliable fixed-length representation for logging purposes and the class mysteriously lacks any kind of .format() function that's available pretty much everywhere else.

When I decide to write a small tool in D, I pretty ensure that, next to D's awesome features, I'll be exposed to some ugly warts of the language or its ecosystem. My experience with DUB packages (btw, there should be a word for it, like Ruby's gems) is that, at least on Windows, they are often out of date and require undocumented build steps to even build -- and that's before you try to use them and hit the wall of RTFS solutions to documentation.

TL;DR: instead of focusing on solving my problem, I have to focus on solving problems unknown in other languages. Saving time by using fantastic language features and then wasting twice as much reinventing the wheel is not what I want to do.
October 06, 2015
On Monday, 5 October 2015 at 16:40:06 UTC, Jan Johansson wrote:
> Yes, I know WCF more than well, doing my own bindings, federated security bindings, you name it. I also know that WCF works with attribute values during runtime, through reflections and extract aspect oriented instructions on how to treat types. It would be slick to do the same in D.

Yes, but that's only because C# doesn't support DbI, it also doesn't mean WCF accepts arbitrary types in contracts: http://stackoverflow.com/questions/7444851/why-knowntypeattribute-need-in-wcf
October 06, 2015
On Tuesday, 6 October 2015 at 13:31:25 UTC, krzaq wrote:
> For example: you can't rely on Clock.currTime.toString() (or ISO string overloads) to provide a reliable fixed-length representation for logging purposes and the class mysteriously lacks any kind of .format() function that's available pretty much everywhere else.

The ISO standard doesn't really say what to do with the number of decimal places, and it's usually cleanest to not have a bunch of trailing zeroes, which is why the to*String functions are the way they are. I was thinking about adding a way to tell it the number of digits though, since std.experimental.logger had to deal with that. It's not something that's generally come up though. I really should have gotten the custom formatting done before now, but it is on the todo list. For most stuff though, it's best to just use toISOExtString, since it's a standard format and quite legible (unlike straight ISO - I don't know why they even have the ISO format in addition to the extended ISO format; it's pretty much impossible to read).

- Jonathan M Davis
October 06, 2015
On Tuesday, 6 October 2015 at 14:28:42 UTC, Kagamin wrote:
> On Monday, 5 October 2015 at 16:40:06 UTC, Jan Johansson wrote:
>> Yes, I know WCF more than well, doing my own bindings, federated security bindings, you name it. I also know that WCF works with attribute values during runtime, through reflections and extract aspect oriented instructions on how to treat types. It would be slick to do the same in D.
>
> Yes, but that's only because C# doesn't support DbI, it also doesn't mean WCF accepts arbitrary types in contracts: http://stackoverflow.com/questions/7444851/why-knowntypeattribute-need-in-wcf

I know about that too, the KnownType is applied to types that the DataContractSerializer (not the XmlSerializer) must be aware of before it can serialize the type (you enlist the type to the serializer). Thanks.
October 07, 2015
On Monday, 5 October 2015 at 09:08:56 UTC, Jonas Drewsen wrote:
> On Monday, 5 October 2015 at 06:18:45 UTC, Manu wrote:
>> [...]
> [...]
>
> The first method is bad because you need to mixin code manually for each module you have.
>
> The second method is bad because you need to keep the "registration" file in sync with any modules added/renamed/removed.
>
> [...]
>
> /Jonas

Method 1: Adding a static c'tor to every module does not work very long in practice (as experienced first handed) cause you are in "cyclic c'tor hell" very quick...

--Stephan
October 07, 2015
On Tuesday, 6 October 2015 at 16:38:06 UTC, Jan Johansson wrote:
> I know about that too, the KnownType is applied to types that the DataContractSerializer (not the XmlSerializer) must be aware of before it can serialize the type (you enlist the type to the serializer). Thanks.

For a general purpose serialization it can make sense to support arbitrary types, but WCF is a communication technology that warrants contracts including and especially web-services that usually require full contract to be expressed in WSDL in order to be cross-platform.
October 07, 2015
On Wednesday, 7 October 2015 at 07:08:39 UTC, extrawurst wrote:
> Method 1: Adding a static c'tor to every module does not work very long in practice (as experienced first handed) cause you are in "cyclic c'tor hell" very quick...

The cyclic dependency checking in druntime makes static constructors almost unusable. It's a case of being protected so much while trying to do something that you can't do what you're trying to do. There really should be some way IMHO to have something similar to @trusted where you tell the compiler/runtime that the order does not matter for a particular static constructor and that it should just trust the programmer on that, but Walter rejected the idea when it was brought up.

- Jonathan M Davis
October 07, 2015
Am Wed, 07 Oct 2015 08:41:30 +0000
schrieb Jonathan M Davis <jmdavisProg@gmx.com>:

> On Wednesday, 7 October 2015 at 07:08:39 UTC, extrawurst wrote:
> > Method 1: Adding a static c'tor to every module does not work very long in practice (as experienced first handed) cause you are in "cyclic c'tor hell" very quick...
> 
> The cyclic dependency checking in druntime makes static constructors almost unusable. It's a case of being protected so much while trying to do something that you can't do what you're trying to do. There really should be some way IMHO to have something similar to @trusted where you tell the compiler/runtime that the order does not matter for a particular static constructor and that it should just trust the programmer on that, but Walter rejected the idea when it was brought up.
> 
> - Jonathan M Davis

With LDC you can abuse the C constructor mechanism to do that. GDC does not yet expose C constructors to D code but it's on my list and it's easy to implement.
October 07, 2015
On Wednesday, 7 October 2015 at 10:03:11 UTC, Johannes Pfau wrote:
> Am Wed, 07 Oct 2015 08:41:30 +0000
> schrieb Jonathan M Davis <jmdavisProg@gmx.com>:
>
>> On Wednesday, 7 October 2015 at 07:08:39 UTC, extrawurst wrote:
>> > Method 1: Adding a static c'tor to every module does not work very long in practice (as experienced first handed) cause you are in "cyclic c'tor hell" very quick...
>> 
>> The cyclic dependency checking in druntime makes static constructors almost unusable. It's a case of being protected so much while trying to do something that you can't do what you're trying to do. There really should be some way IMHO to have something similar to @trusted where you tell the compiler/runtime that the order does not matter for a particular static constructor and that it should just trust the programmer on that, but Walter rejected the idea when it was brought up.
>> 
>> - Jonathan M Davis
>
> With LDC you can abuse the C constructor mechanism to do that. GDC does not yet expose C constructors to D code but it's on my list and it's easy to implement.

I'm not quite sure what you mean by C constructors, so I don't know how that works, but unless it's in all of the compilers, I don't think that it's really worth much ultimately. And we _do_ have workarounds already. std.stdio is an example of one such module where what is essentially its static constructor is called by another module in order to break the cycle. But then you lose out on the special benefits of static constructors with regards to initializing stuff like immutable objects, which can be a problem - particularly when stuff like pure gets involved.

Honestly, I think that if we don't want it to be considered borderline bad practice to use static constructors, I think that we need a solution for this that allows them to function normally without being concerned about circular dependencies (at least when the programmer marks them as such). And if the C constructor mechanism that you're talking about somehow does that, then great, but it needs to be standard D, or it's a pretty limited solution.

- Jonathan M Davis
October 07, 2015
Am Wed, 07 Oct 2015 10:50:38 +0000
schrieb Jonathan M Davis <jmdavisProg@gmx.com>:

> On Wednesday, 7 October 2015 at 10:03:11 UTC, Johannes Pfau wrote:
> > Am Wed, 07 Oct 2015 08:41:30 +0000
> > schrieb Jonathan M Davis <jmdavisProg@gmx.com>:
> >
> >> On Wednesday, 7 October 2015 at 07:08:39 UTC, extrawurst wrote:
> >> > Method 1: Adding a static c'tor to every module does not work very long in practice (as experienced first handed) cause you are in "cyclic c'tor hell" very quick...
> >> 
> >> The cyclic dependency checking in druntime makes static constructors almost unusable. It's a case of being protected so much while trying to do something that you can't do what you're trying to do. There really should be some way IMHO to have something similar to @trusted where you tell the compiler/runtime that the order does not matter for a particular static constructor and that it should just trust the programmer on that, but Walter rejected the idea when it was brought up.
> >> 
> >> - Jonathan M Davis
> >
> > With LDC you can abuse the C constructor mechanism to do that. GDC does not yet expose C constructors to D code but it's on my list and it's easy to implement.
> 
> I'm not quite sure what you mean by C constructors, so I don't know how that works, but unless it's in all of the compilers, I don't think that it's really worth much ultimately.

Most C compilers support some __attribute(constructor)__ feature. In LDC this translates to something like this:

import ldc.attribute;

@attribute("constructor") extern(C) void myConstructor()
{
}

and GDC will use basically the same syntax. It's not really meant for
end users though. We can use this to implement some parts of
the druntime shared DSO handling. And it's useful for betterC programs
or embedded systems, as the implementation in the (C) runtime is very
simple. But you're right, this is probably not a good / general purpose
solution. It just wanted to point out that there's another possible
workaround ;-)

> And we _do_ have workarounds already. std.stdio is an example of one such module where what is essentially its static constructor is called by another module in order to break the cycle. But then you lose out on the special benefits of static constructors with regards to initializing stuff like immutable objects, which can be a problem - particularly when stuff like pure gets involved.
> 
> Honestly, I think that if we don't want it to be considered borderline bad practice to use static constructors, I think that we need a solution for this that allows them to function normally without being concerned about circular dependencies (at least when the programmer marks them as such).

I think it wouldn't be hard to implement a solution. I guess it's mainly a political discussion :-(

An UDA which can be placed on functions with certain signatures would be nice. And this allows having multiple static ctors per module (Could be useful for constructors in mixins):

@constructor void myConstructor() //compiler enforces function signature
{
}

> And if the C constructor mechanism that you're talking about somehow does that, then great, but it needs to be standard D, or it's a pretty limited solution.

If we can have a standard solution in DMD there are better ways than
relying on C constructors. The druntime has absolutely no control over
'C constructors' (they're called by the C runtime) which can lead to
problems in some corner cases. C constructors are mainly useful for low
level or embedded code. And they're useful as long as we don't have a
standard solution, as GDC/LDC can implement them without DMDs
approval ;-)