Community

Fredrik Olsson wrote:
> Perhaps a better example:
> Item[] itemsInRange(Item[] items, d_date start, d_date end) {
> Item[] ret;
> foreach (Item item; items) {
> if (isInRange(item.date, start, end)
> ret ~= item;
> }
> return ret;
> }
>
> Introducing itemsBefore() and itemsAfter() could be done, but less code
> for the same functionality would be to simply send "infinity" to
> itemsInTange's start or end. And now it would be nice with a set
> standard for "what is infinity".
You can use d_time.max and d_time.min. I also don't understand why use
isInRange rather than < and >.
> Best would be if the properties min and max could be made for typedefs,
> and maybe introduce your own, such as nad for "not a date".
There's already a d_time_nan for just that purpose.

Walter Bright wrote:
> Georg Wrede wrote:
>> Walter Bright wrote:
>>
>>> At the start that D wasn't going to accommodate 16 bit processors for
>>> very good reasons, there are 32 bit processors in wide use in the
>>> embedded market that do not have hardware floating point. There is no
>>> reason to gratuitously not run on those systems.
>>
>> Ok, that was exactly the answer I thought I'd get.
>>
>> Currently, this issue is not entirely foreign to me. I'm delivering a
>> HW + SW solution to a manufacturer of plastics processing machines,
>> where my solution will supervise the process and alert an operator
>> whenever the machine "wants hand-holding".
>>
>> For that purpose, the choice is between an 8-bit and a 16-bit
>> processor. Very probably a PIC. (So no D here. :-), I'll end up doing
>> it in C.)
>
> So, you're not even using a 32 bit processor, but a 16 bit design. I
> know for a fact that there are *new* embedded systems designs going on
> using 32 bit processors that don't have FPUs.
True. I understand they are targeted to big manufacturers, who know
exactly the use, and do large production runs. And where ASICs would be
too expensive, considering the width of the task. (Set top boxes,
automotive control subsystems, telecomms network equipment, etc.)
Making significant inroads to those areas, however, may be asking for
too much. The manufacturers are big corporations, they have an
established (and massive) infrastructure already in place, and that is
either directly or indirectly relying on C, whose track record is
unparallelled.
So for them to even glimpse at D, D would have to offer something
significantly better for that domain. (Which (I'm sorry) I don't
currently see.)
>> Now, considering Moore, and the fact that the 80387 math coprocessor
>> didn't have all too many transistors, the marginal price of math is
>> plummeting. Especially compared with the minimum number of transistors
>> needed for a (general purpose) 32-bit CPU.
>
> So why are you using a 16 bit design? I can guess - cost. And that's why
> embedded systems for 32 bit processors often don't have FPUs. Cost,
> where even a few cents matter. (Also power consumption.)
The task is simple enough for an 8-bit processor to handle just fine.
(In my case, the thing is mains-operated, and the CPU cost is negligible
compared with the rest of the delivery, so my reason is just easier
programming.)
>> Also, since the purveyors of 32-bit processors are keen on showing the
>> ease of use and versatility of their processors, it is likely that
>> even if math is not on the chip, they at least deliver suitable
>> libraries to emulate that in software.
>
> I have such a library (needed for the DOS-32 support). Although it works
> fine, it is 100 times slower than hardware floating point. Embedded CPUs
> are often strapped for speed, so why gratuitously require floating point?
It should be much slower. Otherwise FPUs would not be popular. :-)
Otoh, it doesn't slow down anything else, so in many cases the total
performance hit is minor. And a good compiler/linker would in any case
indluce only the actually used routines. You may even use this in
combination with lookup tables, if profiling results show the need.
(Why use FP hardware or libraries at all, is the same kind of question
as why use automatic memory management! Right? One can get by without,
but if it's there, why not use it.)
>> Now, in the former case, math is either on-chip, or included in the
>> libraries. In the latter, either we don't use math, or we make (or
>> acquire) the necessary functions from other sources.
>
> Or design out unnecessary uses of floating point.
For speed, of course. But for size, with D, it's not that simple. With
the current size of "Hello World" (if done without C's printf), a basic
FP library starts to feel small.
>> The second use case worries me. (Possibly unduely?) D not being
>> entirely decoupled from Phobos, at least creates an illusion of
>> potential problems for "from-scratch" SW development for embedded HW.
>
> Phobos doesn't require floating point support from the processor unless
> one actually uses floating point in the application code.
Turbo Pascal has had this since the '80s. You could turn a switch so
that it automatically uses the FP library if float was used and the
runtime computer didn't have an FPU.
> I also really don't understand why anyone using D would require not
> using Phobos. What's the problem?
I admit this is a "feelings based" thing with most people I've talked
with. It seems that on embedded platforms, many expect to write all the
needed code themselves. It's also felt (possibly unduely??) that Phobos
(or whatever general Win+*nix standard library) is mostly useless in
embedded applications.
Of course, this may also be due to lack of information on their side?
>> We do have to remember the reasons leading to choosing a 32-bit
>> processor in the first place: if the process to be cotrolled is too
>> complicated or otherwise needs more power than a 16-bit CPU can
>> deliver, only then should one choose a 32-bit CPU. Now, at that time,
>> it is likely that requirements for RAM, address space, speed, and
>> other things are big enough that the inclusion of math (in HW or
>> library) becomes minor.
>
> All I can say is I posed the same question to embedded systems people
> using 32 bit CPUs sans FPU, and they tell me the costs are not minor -
> either in money or power consumption.
The world is going towards an increasing number of small and midsize
companies entering the embedded arena. They typically would want to work
with a single architecture, for obvious reasons. A CPU that contains
math hardware which can be turned off when not needed (as well as other
systems that can be powered off), seems to answer that kind of needs. I
increasingly see CPU designers understanding this trend.
---
To give a parallell (to explain my view here): There are many Linux
distributions that are compiled with 386 as target. At the same time,
their specs for memory, clock speed, etc. _in_practice_ rule out any
machine not using recent Intel processors. I see this as a joke.
Call this inconsistent specs. I'm discussing here so D would avoid this
kind of inconsistencies.
Insisting on not needing hardware FP is ok. But to legitimize that, one
has to cater to scarce resources in other areas too. Conversely, not
genuinely making the language usable in smaller environments, makes
striving to independence of FPU not worth the effort and inconvenience.

Georg Wrede wrote:
> I admit this is a "feelings based" thing with most people I've talked
> with. It seems that on embedded platforms, many expect to write all the
> needed code themselves. It's also felt (possibly unduely??) that Phobos
> (or whatever general Win+*nix standard library) is mostly useless in
> embedded applications.
I'd like to get to the bottom of this feeling. For example, Kris was
unhappy that typeinfo imported std.strings. I can't figure out what the
problem with that is.
> To give a parallell (to explain my view here): There are many Linux
> distributions that are compiled with 386 as target. At the same time,
> their specs for memory, clock speed, etc. _in_practice_ rule out any
> machine not using recent Intel processors. I see this as a joke.
>
> Call this inconsistent specs. I'm discussing here so D would avoid this
> kind of inconsistencies.
For the embedded people I've talked with, D without floating point would
have been a good match.
> Insisting on not needing hardware FP is ok. But to legitimize that, one
> has to cater to scarce resources in other areas too. Conversely, not
> genuinely making the language usable in smaller environments, makes
> striving to independence of FPU not worth the effort and inconvenience.
It isn't necessary to strive to not use the FPU. Just don't use it
unless floating point is actually needed. There is no need nor benefit
to use floating point for calendar time. I've also seen people use
floating point for random number generators - this is also neither
necessary nor beneficial.

Walter Bright wrote:
> There is no need nor benefit to use floating point for calendar time.
> I've also seen people use floating point for random number generators
> - this is also neither necessary nor beneficial.
Heh, that's why I changed the subject. :-)
I'm not against the calendar thing. I'm only talking processors and
system requirements, etc. here. And consistency of specs.
I'll think some more before actually commenting on the rest of your post.

Walter Bright wrote:
> Georg Wrede wrote:
>
>> I admit this is a "feelings based" thing with most people I've talked
>> with. It seems that on embedded platforms, many expect to write all
>> the needed code themselves. It's also felt (possibly unduely??) that
>> Phobos (or whatever general Win+*nix standard library) is mostly
>> useless in embedded applications.
>
>
> I'd like to get to the bottom of this feeling. For example, Kris was
> unhappy that typeinfo imported std.strings. I can't figure out what the
> problem with that is.
I'll try to explain it from my perspective:
1) You show an adversion to tightly coupled library modules ~ made a
number of negative comments about the Java libraries in that respect ~
and have spelled out in the past a desire to duplicate code as necessary
to avoid said tight coupling. This is good design, and it's one of the
harder things to balance when building a library. Yet, there's flagrant
cases where D tosses this out of the window along with the bathwater.
Instead of adding a duplicate itoa() method (about 60 bytes of code), or
perhaps linking to the C library version, TypeInfo gratuitously imports
std.string and all its vast array of baggage. Heck, everyone makes
mistakes, but your comment above indicates you feel this kind of tight
coupling is perfectly fine?
Then, there's printf() being linked via Object ~ it's been 2 years since
the push to have that removed (which you agreed to), yet it's now clear
there's no intent to do so. So what's wrong with printf()? Well, it
brings along with it almost the entire C IO library, including most of
the wide-char processing and, of course, all the floating-point support,
setup, and management. All completely unecessary where one doesn't use
it. And it's linked at the base of the Object tree.
Without wishing to put too fine a point on it, you continue to do just
exactly what you preach against; and there's apparently no good reason
for it.
2) Not everyone likes Phobos. One might think you'd be happy to
encourage (support, even!) alternate libraries that might far exceed the
utility and/or design parameters of Phobos itself. Yet, by tightly
coupling the D language to Phobos, you make life difficult for those
alternate libraries. And for what reason? It makes no sense at all.
If you'd decouple the language from the library, you'd end up with
something very close to Ares. It's lean, efficient, and very flexible.
In fact, it lends itself very well to others building a working D
compiler & environment ~ the kind of thing that helps increase adoption
by decreasing concerns. By encouraging development of alternate
libraries, the D language stands a better chance of having a good one.
Via judicious decoupling, you can keep the resultant executable lean and
mean ~ making it more attractive to the embedded market, amongst others.
D might even avoid having to link the FPU management code by default :-P
You said "Kris was unhappy that typeinfo imported std.strings. I can't
figure out what the problem with that is" ~~ I hope this helps you get
there.

kris wrote:
> Walter Bright wrote:
>> I'd like to get to the bottom of this feeling. For example, Kris was
>> unhappy that typeinfo imported std.strings. I can't figure out what
>> the problem with that is.
>
>
> I'll try to explain it from my perspective:
>
> 1) You show an adversion to tightly coupled library modules ~ made a
> number of negative comments about the Java libraries in that respect ~
> and have spelled out in the past a desire to duplicate code as necessary
> to avoid said tight coupling. This is good design, and it's one of the
> harder things to balance when building a library. Yet, there's flagrant
> cases where D tosses this out of the window along with the bathwater.
The trouble with Java was that even the most trivial program pulled in
*everything*, including the graphics library. The typeinfo for a
particular type is only linked in if that type is actually used in a
user program.
> Instead of adding a duplicate itoa() method (about 60 bytes of code), or
> perhaps linking to the C library version, TypeInfo gratuitously imports
> std.string and all its vast array of baggage. Heck, everyone makes
> mistakes, but your comment above indicates you feel this kind of tight
> coupling is perfectly fine?
Although there is a lot of code in std.string, unreferenced free
functions in it should be discarded by the linker. A check of the
generated .map file should verify this - it is certainly supposed to
work that way. One problem Java has is that there are no free functions,
so referencing one function wound up pulling in every part of the class
the function resided in.
> Then, there's printf() being linked via Object ~ it's been 2 years since
> the push to have that removed (which you agreed to), yet it's now clear
> there's no intent to do so. So what's wrong with printf()? Well, it
> brings along with it almost the entire C IO library, including most of
> the wide-char processing and, of course, all the floating-point support,
> setup, and management. All completely unecessary where one doesn't use
> it. And it's linked at the base of the Object tree.
printf doesn't pull in the floating point library (I went to a lot of
effort to make that so!). It does pull in the C IO library, which is
very hard to not pull in (there always seems to be something referencing
it). It shouldn't pull in the C wide character stuff. D's IO (writefln)
will pull in C's IO anyway, so the only thing extra is the integer
version of the specific printf code (about 4K).
> 2) Not everyone likes Phobos. One might think you'd be happy to
> encourage (support, even!) alternate libraries that might far exceed the
> utility and/or design parameters of Phobos itself. Yet, by tightly
> coupling the D language to Phobos, you make life difficult for those
> alternate libraries. And for what reason? It makes no sense at all.
The only parts of phobos directly referenced by the compiler are
typeinfo, object, and the code in internal.
> If you'd decouple the language from the library, you'd end up with
> something very close to Ares. It's lean, efficient, and very flexible.
> In fact, it lends itself very well to others building a working D
> compiler & environment ~ the kind of thing that helps increase adoption
> by decreasing concerns. By encouraging development of alternate
> libraries, the D language stands a better chance of having a good one.
> Via judicious decoupling, you can keep the resultant executable lean and
> mean ~ making it more attractive to the embedded market, amongst others.
> D might even avoid having to link the FPU management code by default :-P
>
>
> You said "Kris was unhappy that typeinfo imported std.strings. I can't
> figure out what the problem with that is" ~~ I hope this helps you get
> there.
And I hope I responded adequately.

As I said, that viewpoint is from my perspective ~ the intent was
certainly not to elicit a defensive response. Instead, I'd hoped you'd
be open to some suggestions;
More inline:
Walter Bright wrote:
> kris wrote:
>
>> Walter Bright wrote:
>>
>>> I'd like to get to the bottom of this feeling. For example, Kris was
>>> unhappy that typeinfo imported std.strings. I can't figure out what
>>> the problem with that is.
>>
>>
>>
>> I'll try to explain it from my perspective:
>>
>> 1) You show an adversion to tightly coupled library modules ~ made a
>> number of negative comments about the Java libraries in that respect ~
>> and have spelled out in the past a desire to duplicate code as
>> necessary to avoid said tight coupling. This is good design, and it's
>> one of the harder things to balance when building a library. Yet,
>> there's flagrant cases where D tosses this out of the window along
>> with the bathwater.
>
>
> The trouble with Java was that even the most trivial program pulled in
> *everything*, including the graphics library. The typeinfo for a
> particular type is only linked in if that type is actually used in a
> user program.
Yes, that's correct. But typeinfo is a rather rudimetary part of the
language support. Wouldn't you agree? If I, for example, declare an
array of 10 bytes (static byte[10]) then I'm bound over to import
std.string ~ simply because TypeInfo_StaticArray wants to use
std.string.toString(int), rather than the C library version of itoa() or
a "low-level support" version instead.
That's tight-coupling within very low-level language support. Uncool.
Wouldn't you at least agree that specific instance is hardly an absolute
necessity?
>> Instead of adding a duplicate itoa() method (about 60 bytes of code),
>> or perhaps linking to the C library version, TypeInfo gratuitously
>> imports std.string and all its vast array of baggage. Heck, everyone
>> makes mistakes, but your comment above indicates you feel this kind of
>> tight coupling is perfectly fine?
>
>
> Although there is a lot of code in std.string, unreferenced free
> functions in it should be discarded by the linker. A check of the
> generated .map file should verify this - it is certainly supposed to
> work that way. One problem Java has is that there are no free functions,
> so referencing one function wound up pulling in every part of the class
> the function resided in.
This is exactly the case with printf <g>. It winds up linking the world
because it's a general purpose utility function that does all kinds of
conversion and all kinds of IO. Printf() is an all or nothing design ~
you can't selectively link pieces of it.
That's usually not a problem. However, you've chosen to bind it to
low-level language support (in the root Object). That choice causes
tight coupling between the language low-level support and a high-level
library function ~ one which ought to be optional.
Wouldn't you at least agree this specific case is not necessary for the
D language to function correctly? That there are other perfectly
workable alternatives?
>> Then, there's printf() being linked via Object ~ it's been 2 years
>> since the push to have that removed (which you agreed to), yet it's
>> now clear there's no intent to do so. So what's wrong with printf()?
>> Well, it brings along with it almost the entire C IO library,
>> including most of the wide-char processing and, of course, all the
>> floating-point support, setup, and management. All completely
>> unecessary where one doesn't use it. And it's linked at the base of
>> the Object tree.
>
>
> printf doesn't pull in the floating point library (I went to a lot of
> effort to make that so!). It does pull in the C IO library, which is
> very hard to not pull in (there always seems to be something referencing
> it). It shouldn't pull in the C wide character stuff. D's IO (writefln)
> will pull in C's IO anyway, so the only thing extra is the integer
> version of the specific printf code (about 4K).
How can it convert %f, %g and so on if it doesn't use FP support at all?
Either way, it's not currently possible to build a D program without a
swathe of FP support code, printf, the entire C IO package, wide-char
support, and a whole lot more besides. I'd assumed the linked FP support
was for printf, but perhaps it's for std.string instead? I've posted the
linker maps (in the past) to illustrate exactly this.
There's no absolute need for most of this stuff. It shouldn't be bound
at the low level.
>> 2) Not everyone likes Phobos. One might think you'd be happy to
>> encourage (support, even!) alternate libraries that might far exceed
>> the utility and/or design parameters of Phobos itself. Yet, by tightly
>> coupling the D language to Phobos, you make life difficult for those
>> alternate libraries. And for what reason? It makes no sense at all.
>
>
> The only parts of phobos directly referenced by the compiler are
> typeinfo, object, and the code in internal.
No argument there. Yet those modules are slowly importing chunks of
Phobos, making them dependencies also. My point is, and has always been,
there's no need for those secondary dependencies. Especially at the
level of language-support (like typeinfo and object).
>
>
>> If you'd decouple the language from the library, you'd end up with
>> something very close to Ares. It's lean, efficient, and very flexible.
>> In fact, it lends itself very well to others building a working D
>> compiler & environment ~ the kind of thing that helps increase
>> adoption by decreasing concerns. By encouraging development of
>> alternate libraries, the D language stands a better chance of having a
>> good one. Via judicious decoupling, you can keep the resultant
>> executable lean and mean ~ making it more attractive to the embedded
>> market, amongst others. D might even avoid having to link the FPU
>> management code by default :-P
>>
>>
>> You said "Kris was unhappy that typeinfo imported std.strings. I can't
>> figure out what the problem with that is" ~~ I hope this helps you get
>> there.
>
>
> And I hope I responded adequately.
Are you not at all interested in improving this aspect of the language
usage?

kris wrote:
> Yes, that's correct. But typeinfo is a rather rudimetary part of the
> language support. Wouldn't you agree? If I, for example, declare an
> array of 10 bytes (static byte[10]) then I'm bound over to import
> std.string ~ simply because TypeInfo_StaticArray wants to use
> std.string.toString(int), rather than the C library version of itoa() or
> a "low-level support" version instead.
It has nothing to do with having a static byte[10] declaration. For the
program:
void main()
{
static byte[10] b;
}
The only things referenced by the object file are _main, __acrtused_con,
and __Dmain. You can verify this by running obj2asm on the output, which
gives:
-------------------------------------
_TEXT segment dword use32 public 'CODE' ;size is 0
_TEXT ends
_DATA segment para use32 public 'DATA' ;size is 0
_DATA ends
CONST segment para use32 public 'CONST' ;size is 0
CONST ends
_BSS segment para use32 public 'BSS' ;size is 10
_BSS ends
FLAT group
includelib phobos.lib
extrn _main
extrn __acrtused_con
extrn __Dmain
__Dmain COMDAT flags=x0 attr=x0 align=x0
_TEXT segment
assume CS:_TEXT
_TEXT ends
_DATA segment
_DATA ends
CONST segment
CONST ends
_BSS segment
_BSS ends
__Dmain comdat
assume CS:__Dmain
xor EAX,EAX
ret
__Dmain ends
end
----------------------------------
Examining the .map file produced shows that only these functions are
pulled in from std.string:
0002:00002364 _D3std6string7iswhiteFwZi 00404364
0002:000023A4 _D3std6string3cmpFAaAaZi 004043A4
0002:000023E8 _D3std6string4findFAawZi 004043E8
0002:00002450 _D3std6string8toStringFkZAa 00404450
0002:000024CC _D3std6string9inPatternFwAaZi 004044CC
0002:00002520 _D3std6string6columnFAaiZk 00404520
I do not know offhand why a couple of those are pulled in, but I suggest
that obj2asm and the generated .map files are invaluable at determining
what pulls in what. Sometimes the results are surprising.
> That's tight-coupling within very low-level language support. Uncool.
> Wouldn't you at least agree that specific instance is hardly an absolute
> necessity?
std.string.toString is 124 bytes long, and doesn't pull anything else in
(except see below). Writing another version of it in typeinfo isn't
going to reduce the size of the program *at all*, in fact, it will
likely increase it because now there'll be two versions of it.
>> Although there is a lot of code in std.string, unreferenced free
>> functions in it should be discarded by the linker. A check of the
>> generated .map file should verify this - it is certainly supposed to
>> work that way. One problem Java has is that there are no free
>> functions, so referencing one function wound up pulling in every part
>> of the class the function resided in.
> This is exactly the case with printf <g>. It winds up linking the world
No, it does not link in the world, floating point, or graphics
libraries. It links in C's standard I/O (which usually gets linked in
anyway), and about 4000 bytes of code. That's somewhat less than a
megabyte <g>.
> because it's a general purpose utility function that does all kinds of
> conversion and all kinds of IO. Printf() is an all or nothing design ~
> you can't selectively link pieces of it.
>
> That's usually not a problem. However, you've chosen to bind it to
> low-level language support (in the root Object). That choice causes
> tight coupling between the language low-level support and a high-level
> library function ~ one which ought to be optional.
>
> Wouldn't you at least agree this specific case is not necessary for the
> D language to function correctly? That there are other perfectly
> workable alternatives?
It's just not a big deal. Try the following:
extern (C) int printf(char* f, ...) { return 0; }
void main()
{
static byte[10] b;
}
and compare the difference in exe file sizes, with and without the
printf stub.
>> printf doesn't pull in the floating point library (I went to a lot of
>> effort to make that so!). It does pull in the C IO library, which is
>> very hard to not pull in (there always seems to be something
>> referencing it). It shouldn't pull in the C wide character stuff. D's
>> IO (writefln) will pull in C's IO anyway, so the only thing extra is
>> the integer version of the specific printf code (about 4K).
> How can it convert %f, %g and so on if it doesn't use FP support at all?
It's magic! Naw, it's just that if you actually use floating point in a
program, the compiler emits a special extern reference (to __fltused)
which pulls in the floating point IO formatting code. Otherwise, it
defaults to just a stub. Try it.
> Either way, it's not currently possible to build a D program without a
> swathe of FP support code,
> printf,
> the entire C IO package,
> wide-char support,
> and a whole lot more besides. I'd assumed the linked FP support
> was for printf, but perhaps it's for std.string instead? I've posted the
> linker maps (in the past) to illustrate exactly this.
My point is that assuming what is pulled in by what is about as reliable
as guessing where the bottlenecks in one's code is. You can't tell
bottlenecks without a profiler, and you've got both hands tied behind
your back trying to figure out who pulls in what if you're not using
.map files, grep, and obj2asm.
> Are you not at all interested in improving this aspect of the language
> usage?
Sure, but based on accurate information. Pulling printf won't do
anything. Try it if you don't agree.
For example, which modules pull in the floating point formatting code?
It isn't printf. We can find out by doing a grep for __fltused:
boxer.obj: __fltused
complex.obj: __fltused
conv.obj: __fltused
date.obj: __fltused
demangle.obj: __fltused
format.obj: __fltused
gamma.obj: __fltused
math.obj: __fltused
math2.obj: __fltused
outbuffer.obj: __fltused
stream.obj: __fltused
string.obj: __fltused
ti_Acdouble.obj: __fltused
ti_Acfloat.obj: __fltused
ti_Acreal.obj: __fltused
ti_Adouble.obj: __fltused
ti_Afloat.obj: __fltused
ti_Areal.obj: __fltused
ti_cdouble.obj: __fltused
ti_cfloat.obj: __fltused
ti_creal.obj: __fltused
ti_double.obj: __fltused
ti_float.obj: __fltused
ti_real.obj: __fltused
Some examination of the .map file shows that the only one of these
pulled in by default is std.string. So I think a reasonable approach
would be to look at removing the floating point from std.string - printf
isn't the problem, nor is referencing a function in std.string.