December 22, 2011
On Thursday, December 22, 2011 08:34:23 Jacob Carlborg wrote:
> On 2011-12-22 04:57, Walter Bright wrote:
> > My first thought is that std.datetime is already very large. Few will need a custom date formatter, so it should be in a separate module to:
> > 
> > 1. reduce cognitive load on the programmer
> > 
> > 2. reduce the overhead pulled in for every program that may want to use an std.datetime function, but not need custom formatting
> 
> As I've said several times, std.datetime is way too large and should be a package.

That's the way that it was originally proposed (albeit split in a poor manner), and a number of people (particularly Phobos devs) were against it, and have been any time that I've suggested splitting out part of it. The fact that Phobos has historically shunned sub-packages probably has a lot to do with that (though we're starting to have some).

To make it a package at this point would probably break a fair bit of code unless it were a new package which std.datetime publicly imported, so simply making std.datetime a package isn't necessarily a great idea, and there's a definite benefit IMHO in being able to just import it all with one import. But it's not necessarily unreasonable to create a new package which holds the various pieces and have std.datetime import them all.

- Jonathan M Davis
December 22, 2011
On 12/21/2011 10:56 PM, Jonathan M Davis wrote:
> On Wednesday, December 21, 2011 22:46:37 Walter Bright wrote:
>> On 12/21/2011 10:36 PM, Jonathan M Davis wrote:
>>> In general, I agree that that's a good policy. How expensive would you
>>> consider templated functions which aren't used to be with regards to
>>> that? They don't cost nothing, since they still have to be lexed and
>>> parsed, but they don't get fully compiled.
>>
>> The test is to import the module without referencing any functions in it.
>> Check if the resulting executable increases in size.
>
> Isn't that a compiler and/or linker issue? I mean, if _nothing_ is referenced
> in the module, then shouldn't it never pull anything in and therefore never
> increase the size of the executable?


We must deal with our imperfect tools as they are. For example, I am not going to rewrite the Linux ld linker, and the OSX linker, and the FreeBSD linker, etc.

December 22, 2011
On Thursday, December 22, 2011 00:05:58 Walter Bright wrote:
> We must deal with our imperfect tools as they are. For example, I am not going to rewrite the Linux ld linker, and the OSX linker, and the FreeBSD linker, etc.

If the compiler and/or linker don't strip unused symbols, then how on earth is importing the module _not_ going to pull in everything in it save for uninitialized templates?

- Jonathan M Davis
December 22, 2011
On Thursday, December 22, 2011 00:14:21 Jonathan M Davis wrote:
> On Thursday, December 22, 2011 00:05:58 Walter Bright wrote:
> > We must deal with our imperfect tools as they are. For example, I am not
> > going to rewrite the Linux ld linker, and the OSX linker, and the
> > FreeBSD
> > linker, etc.
> 
> If the compiler and/or linker don't strip unused symbols, then how on earth is importing the module _not_ going to pull in everything in it save for uninitialized templates?

Or rather, _uninstantiated_ templates.

- Jonathan M Davis
December 22, 2011
On 12/22/2011 12:14 AM, Jonathan M Davis wrote:
> On Thursday, December 22, 2011 00:05:58 Walter Bright wrote:
>> We must deal with our imperfect tools as they are. For example, I am not
>> going to rewrite the Linux ld linker, and the OSX linker, and the FreeBSD
>> linker, etc.
>
> If the compiler and/or linker don't strip unused symbols, then how on earth is
> importing the module _not_ going to pull in everything in it save for
> uninitialized templates?

There are data that needs to be there, but is never symbolically referenced, for example, the exception handler tables. The compiler does the best it can, like emitting one object file per function, but it always must behave conservatively.

The elf object file format isn't going to change, we aren't going to rewrite the gnu linker, nor will we rewrite the back ends of gcc and lcc.

There isn't any one simple rule to avoid unnecessary bloat, the only way is to get somewhat familiar with how things work. For example, using 'class' as a namespace generates a useless vtbl[] and a typeinfo instance, and in the future will generate useless reflection data. It's better to use a module as a namespace, as that is what it is designed for.

The most important thing is to design the boxes around the various units of functionality such that there are minimal lines between those boxes. For example, if I want to see if one file is newer than another (like for a make program), it should not pull in timezone processing or date formatting code.
December 22, 2011
On Thursday, December 22, 2011 00:54:49 Walter Bright wrote:
> The most important thing is to design the boxes around the various units of functionality such that there are minimal lines between those boxes. For example, if I want to see if one file is newer than another (like for a make program), it should not pull in timezone processing or date formatting code.

Both of those are part of SysTime, and the time zone in particular is an integral part of that. You can't do _anything_ with a SysTime without a time zone. That's part of the point of the design. It avoids time conversion issues. Sure, if stuff was rearranged, only TimeZone and LocalTime would have to be pulled in (since LocalTime is the default and TimeZone is its base class), but they have to be there regardless.

So, in principle, reducing how much has to be pulled in is very much desirable, but in this case, it doesn't make sense. The time zone stuff is required, and there's a usability issue if you split out the date formatting. It's already built into the type. It's just the custom formatting which isn't there yet, but that's going to be templated, so it shouldn't pull in any additional symbols unless it's used.

- Jonathan M Davis
December 22, 2011
On 12/22/2011 1:04 AM, Jonathan M Davis wrote:
> On Thursday, December 22, 2011 00:54:49 Walter Bright wrote:
>> The most important thing is to design the boxes around the various units of
>> functionality such that there are minimal lines between those boxes. For
>> example, if I want to see if one file is newer than another (like for a make
>> program), it should not pull in timezone processing or date formatting
>> code.
>
> Both of those are part of SysTime, and the time zone in particular is an
> integral part of that. You can't do _anything_ with a SysTime without a time
> zone. That's part of the point of the design. It avoids time conversion
> issues. Sure, if stuff was rearranged, only TimeZone and LocalTime would have
> to be pulled in (since LocalTime is the default and TimeZone is its base
> class), but they have to be there regardless.

Timezone information is not necessary to measure elapsed time or relative time, for example.


> So, in principle, reducing how much has to be pulled in is very much
> desirable, but in this case, it doesn't make sense. The time zone stuff is
> required, and there's a usability issue if you split out the date formatting.
> It's already built into the type.

Can it be added with PIMPL? PIMPL is good for more than just information hiding, it can also be a fine way to avoid pulling in things unless they are actually dynamically used (as opposed to pulling them in if they are statically referenced).


> It's just the custom formatting which isn't
> there yet, but that's going to be templated, so it shouldn't pull in any
> additional symbols unless it's used.


Please check and see if additional symbols are pulled in or not. I've seen a lot of template code where the author of that code never checked and was surprised at the instantiations that were happening that he overlooked.
December 22, 2011
On 21/12/2011 9:41 PM, Jonathan M Davis wrote:
> Okay. At the moment, the time point types in std.datetime have functions for
> converting to and from strings of standard formats but not custom formats, so
> functions for that need to be added. I've come up with a proposal for how
> they're going to work and would like some feedback on it.
>
> Originally, I was going to make them work like strftime and strptime, since it
> was my understanding that those functions were fairly standard among various
> programming languags. And it _does_ look like a variety of programming
> languages have something similar (Java, Ruby, Python, etc.), but the exact set
> of flags that they use is not standard, so there _isn't_ really a standard to
> follow, just similar functions across a variety of programming languages. And
> honestly, strftime and strptime aren't very good. They're fairly limited IMHO,
> and the choice of flags is fairly arbitrary, so it seems like a good idea to

Every language seems to force you memorize a bunch of format strings for different toString functions, which is quite annoying. I highly doubt I'm the only person who has to look up the format strings every single time I want to use a custom toString (besides an obvious one like YYYY).

It would be nice if D did better in this regard. Something taking advantage of enums, such as 'time.toCustomString!(Year, ", ", LongHour, ":", LongMinute, " ", AMPM)'. The problem with that particular example, is that it's... quite ugly. And bloated. Perhaps there would be a way to make it not quite so bloated however, while still retaining the simplicity of compile-time enums.

Perhaps this doesn't matter so much in D though, given that template arguments are passed in and thus can be evaluated at compile-time. I definitely like the current approach shown in docs, but it's still painful to try and figure out something like
assert(st.toCustomString!"%4yplus%04+Y-%emon-%02D%02H:%02m:%02s%f%tz"()
       == "2010-Jul-04 07:06:12").

December 22, 2011
On 2011-12-22 08:58, Jonathan M Davis wrote:
> On Thursday, December 22, 2011 08:34:23 Jacob Carlborg wrote:
>> On 2011-12-22 04:57, Walter Bright wrote:
>>> My first thought is that std.datetime is already very large. Few will
>>> need a custom date formatter, so it should be in a separate module to:
>>>
>>> 1. reduce cognitive load on the programmer
>>>
>>> 2. reduce the overhead pulled in for every program that may want to use
>>> an std.datetime function, but not need custom formatting
>>
>> As I've said several times, std.datetime is way too large and should be
>> a package.
>
> That's the way that it was originally proposed (albeit split in a poor
> manner), and a number of people (particularly Phobos devs) were against it,
> and have been any time that I've suggested splitting out part of it. The fact
> that Phobos has historically shunned sub-packages probably has a lot to do
> with that (though we're starting to have some).

Yeah, I don't get this. Most modules in Phobos are too large, in my opinion.

> To make it a package at this point would probably break a fair bit of code
> unless it were a new package which std.datetime publicly imported, so simply
> making std.datetime a package isn't necessarily a great idea, and there's a
> definite benefit IMHO in being able to just import it all with one import. But
> it's not necessarily unreasonable to create a new package which holds the
> various pieces and have std.datetime import them all.
>
> - Jonathan M Davis

It would break code, but it's better to break it sooner than later. Seems more and more like D should support importing all modules in a package, that Java does:

import foo.*;

And yes I know this can be done manually with public imports. I think it's a benefit to have smaller modules and that a given module is only responsible for one specific thing.

-- 
/Jacob Carlborg
December 22, 2011
On 2011-12-22 09:14, Jonathan M Davis wrote:
> On Thursday, December 22, 2011 00:05:58 Walter Bright wrote:
>> We must deal with our imperfect tools as they are. For example, I am not
>> going to rewrite the Linux ld linker, and the OSX linker, and the FreeBSD
>> linker, etc.
>
> If the compiler and/or linker don't strip unused symbols, then how on earth is
> importing the module _not_ going to pull in everything in it save for
> uninitialized templates?
>
> - Jonathan M Davis

Isn't that what we're trying to find out by testing it?

-- 
/Jacob Carlborg