Re: [GSOC] New unicode module beta, with Grapheme support!

2012-08-23 Thread Dmitry Olshansky

On 23-Aug-12 10:34, Jacob Carlborg wrote:

On 2012-08-22 23:31, Dmitry Olshansky wrote:

Well, officially the final bell has rung, marking the end of GSOC.


Cool.


P.P.S. Volunteers who'd like to test x64 are welcome to run
  rdmd gen_uni.d
and report back (maybe it's my local setup problem).


On Mac OS X, using DMD 2.060 64bit, the assert at line 568 is triggered.
The last part of the output is:


Great... at least the error is the same :) So the only Q remains is why 
Phobos tests fail for me but doh.

Guess I'll have to go the old painful way of debugging.


2FA1D ---> 2A600
2fa1d -~->  2a600
core.exception.AssertError@gen_uni(568): Assertion failure

5   gen_uni 0x0001000a06ea _d_assertm + 38
6   gen_uni 0x000113f7 void
gen_uni.__assert(int) + 23
7   gen_uni 0x0001377c void
gen_uni.writeTries().int __foreachbody8149(ref dchar, ref ushort) + 124
8   gen_uni 0x00010009f406 _aaApply2 + 106
9   gen_uni 0x00013497 void
gen_uni.writeTries() + 687
10  gen_uni 0x000113b7 _Dmain + 1131
11  gen_uni 0x0001000a108a extern (C)
int rt.dmain2.main(int, char**).void runMain() + 34
12  gen_uni 0x0001000a0a41 extern (C)
int rt.dmain2.main(int, char**).void tryExec(scope void delegate()) + 45
13  gen_uni 0x0001000a10d4 extern (C)
int rt.dmain2.main(int, char**).void runAll() + 56
14  gen_uni 0x0001000a0a41 extern (C)
int rt.dmain2.main(int, char**).void tryExec(scope void delegate()) + 45
15  gen_uni 0x0001000a09cb main + 235
16  gen_uni 0x00010f44 start + 52
17  ??? 0x0001 0x0 + 1


I also piped it to a file which resulted in this:

http://pastebin.com/xjg68CdG




--
Olshansky Dmitry


Re: Fragile ABI

2012-08-23 Thread Kagamin

On Tuesday, 21 August 2012 at 15:15:02 UTC, David Piepgrass wrote:
Finally, it's Windows-only (although it has been reimplemented 
on Linux, e.g. for WINE) and modules must be registered in the 
Windows Registry.


Conceptually COM is just a set of ideas for interoperable 
component design, which happens to actually work across languages 
and frameworks: .net, C, C++, Delphi, D. Registry works only as a 
centralized repository of components which is needed if you want 
to plug arbitrary components into your system, it has nothing to 
do with the problem of fragile ABI.


Re: Ascii matters

2012-08-23 Thread bearophile

Sean Kelly:

Gotcha.  Despite it being something I'd use regularly, I 
wouldn't want this in Phobos because it seems like it could 
cause maintenance problems.  I'd rather explicitly cast to 
ubyte as a way to flag that I was doing something potentially 
unsafe.


What's unsafe in what I have presented? The constructor verifies 
every char to be in 7 bits, and then you use the new type safely. 
No casts, and no need to flag something as unsafe.


This usage of types to denote capabilities is quite common in 
functional languages, see articles I've recently linked here as:

http://tomasp.net/blog/type-first-development.aspx

Bye,
bearophile


Formatted read consumes input

2012-08-23 Thread monarch_dodra

As title implies:


import std.stdio;
import std.format;

void main()
{
  string s = "42";
  int v;
  formattedRead(s, "%d", &v);
  writefln("[%s] [%s]", s, v);
}

[] [42]


Is this the "expected" behavior?

Furthermore, it is not possible to try to "save" s:

import std.stdio;
import std.format;
import std.range;

void main()
{
  string s = "42";
  int v;
  formattedRead(s.save, "%d", &v);
  writefln("[%s] [%s]", s, v);
}

main.d(9): Error: template std.format.formattedRead does not 
match any function template declaration
C:\D\dmd.2.060\dmd2\windows\bin\..\..\src\phobos\std\format.d(526): 
Error: template std.format.formattedRead(R,Char,S...) cannot 
deduce template function from argument types 
!()(string,string,int*)



The workaround is to have a named backup:
  auto ss = s.save;
  formattedRead(ss, "%d", &v);


I've traced the root issue to formattedRead's signature, which is:
uint formattedRead(R, Char, S...)(ref R r, const(Char)[] fmt, S 
args);


Is there a particular reason for this pass by ref? It is 
inconsistent with the rest of phobos, or even C's scanf?


Is this a file-able bug_report/enhancement_request?


Re: Ascii matters

2012-08-23 Thread Don Clugston

On 23/08/12 05:05, bearophile wrote:

Sean Kelly:


I'm clearly missing something.  ASCII and UTF-8 are compatible.
 What's stopping you from just processing these as if they were UTF-8
strings?


std.algorithm is not closed
(http://en.wikipedia.org/wiki/Closure_%28mathematics%29 ) on UTF-8, its
operations lead to UTF-32.


Which operations in std.algorithm over map 0-0x7F into higher characters?


Non-virtual private struct inheritance

2012-08-23 Thread monarch_dodra
In C++, it is a very common practice, when writing a struct 
template, to have said template derive from a base non-template 
struct. This makes sure there is no executable bloat, and, more 
often than not, the inheritance is private, so invisible to users 
(no "interface leak").


For instance, std::list is a classic example of this: First, you 
have the template create a node, and then you defer to the base 
class for all insertions/deletions, that don't really care about 
what a T is.


My first question is: Is such an approach even encouraged in D? 
Or is the module compilation system able to see through what 
does/doesn't depend on these parameters?


Can be swapping inheritance for member variables, or free 
standing external methods. Both works most of the time, but 
neither are quite as polyvalent.


...

D being a heavily templated system language, executable size is 
something that should be controlable, correct? Is there any 
chance we could see this kind of limited inheritance for structs? 
As in just basic non-polymorphous inheritance? I seem to remember 
a few threads about other users wishing for inheritance with 
structs...


Re: Ascii matters

2012-08-23 Thread bearophile

Don Clugston:

Which operations in std.algorithm over map 0-0x7F into higher 
characters?


The first example I've shown:

string s = "test string";
dchar[] s2 = map!(x => x)(s).array(); // Uses the Id function

Bye,
bearophile


Re: Non-virtual private struct inheritance

2012-08-23 Thread bearophile

monarch_dodra:

In C++, it is a very common practice, when writing a struct 
template, to have said template derive from a base non-template 
struct. This makes sure there is no executable bloat,


"alias this" seems to help both for composition and against 
template bloat:



struct Foo {
int x;
int bar() { return x * 2; }
}
struct Bar(T) {
Foo f;
T y;
alias f this;
}
void main() {
Bar!int b1;
b1.x = 10;
assert(b1.bar() == 20);
Bar!double b2;
b2.x = 100;
assert(b2.bar() == 200);
}


In the asm listing there is only one bar:

_D3foo3Foo3barMFZi:
enter 4, 0
mov EAX, [EAX]
add EAX, EAX
leave
ret


Another way to fight template bloat is the @templated() I have 
suggested elsewhere, that applied to something inside a template 
allows you to choose what that something is templated to (even 
nothing).


Bye,
bearophile


Re: Non-virtual private struct inheritance

2012-08-23 Thread monarch_dodra

On Thursday, 23 August 2012 at 13:17:23 UTC, bearophile wrote:

monarch_dodra:

In C++, it is a very common practice, when writing a struct 
template, to have said template derive from a base 
non-template struct. This makes sure there is no executable 
bloat,


"alias this" seems to help both for composition and against 
template bloat:



struct Foo {
int x;
int bar() { return x * 2; }
}
struct Bar(T) {
Foo f;
T y;
alias f this;
}
void main() {
Bar!int b1;
b1.x = 10;
assert(b1.bar() == 20);
Bar!double b2;
b2.x = 100;
assert(b2.bar() == 200);
}


In the asm listing there is only one bar:

_D3foo3Foo3barMFZi:
enter 4, 0
mov EAX, [EAX]
add EAX, EAX
leave
ret


Another way to fight template bloat is the @templated() I have 
suggested elsewhere, that applied to something inside a 
template allows you to choose what that something is templated 
to (even nothing).


Bye,
bearophile


Thanks for the answer. Very nice. "alias this" is still the first 
thing I think about, but in this case, it works perfectly well 
actually.




Re: Ascii matters

2012-08-23 Thread Sean Kelly
On Aug 23, 2012, at 4:25 AM, bearophile  wrote:

> Sean Kelly:
> 
>> Gotcha.  Despite it being something I'd use regularly, I wouldn't want this 
>> in Phobos because it seems like it could cause maintenance problems.  I'd 
>> rather explicitly cast to ubyte as a way to flag that I was doing something 
>> potentially unsafe.
> 
> What's unsafe in what I have presented? The constructor verifies every char 
> to be in 7 bits, and then you use the new type safely. No casts, and no need 
> to flag something as unsafe.
> 
> This usage of types to denote capabilities is quite common in functional 
> languages, see articles I've recently linked here as:
> http://tomasp.net/blog/type-first-development.aspx

So it throws an exception if there are non-ASCII characters in the range?  Is 
this really better than just casting the input array to ubyte?

Re: Ascii matters

2012-08-23 Thread bearophile

Sean Kelly:

So it throws an exception if there are non-ASCII characters in 
the range?  Is this really better than just casting the input 
array to ubyte?


The cast to ubute[] doesn't perform a run-time test of the
validity of the input, so yeah, the exception is better. Your
code is also able to catch and manage the exception (like asking
the user for another valid input file).

If you carry around some type as "Astring", later you don't have
to cast it back to char[] to print the data as a string (this
discussion is about data that is naturally text, this discussion
is not about generic numerical octets).

An appropriate type statically encodes in your program that you
are using an ascii string. This makes your code more readable.
But when in the code you see a variable of generic type ubyte[]
it doesn't tell you a lot about its contents.

Bye,
bearophile


Re: Vote for the new std.hash (oops, std.digest)

2012-08-23 Thread Jens Mueller
Dmitry Olshansky wrote:
> The discussion around new unified API for digest hash functions has
> subdued, just in time as the review period has ended.
> 
> The voting for std.digest package starts today and ends on 29
> August.
> 
> Rules are simple: reply in this thread with definite "YES" or "NO"
> on whether this package should go into Phobos. Including descriptive
> short notes is appreciated (esp. the NO ones).
> 
> 
> Latest locations of docs and source:
> 
> Code: (location changed!)
> https://github.com/jpf91/phobos/tree/newHash/std/digest
> https://github.com/jpf91/phobos/compare/master...newHash
> 
> Docs: (location changed!)
> http://dl.dropbox.com/u/24218791/d/phobos/std_digest_digest.html
> http://dl.dropbox.com/u/24218791/d/phobos/std_digest_md.html
> http://dl.dropbox.com/u/24218791/d/phobos/std_digest_sha.html
> http://dl.dropbox.com/u/24218791/d/phobos/std_digest_crc.html
> 

YES.
I like it. The API is solid and future-proof for more digesting.
Many thanks Johannes.

Jens


Re: Vote for the new std.hash (oops, std.digest)

2012-08-23 Thread d_follower
On Wednesday, 22 August 2012 at 12:36:08 UTC, Dmitry Olshansky 
wrote:
The discussion around new unified API for digest hash functions 
has subdued, just in time as the review period has ended.


The voting for std.digest package starts today and ends on 29 
August.


Rules are simple: reply in this thread with definite "YES" or 
"NO" on whether this package should go into Phobos. Including 
descriptive short notes is appreciated (esp. the NO ones).



Latest locations of docs and source:

Code: (location changed!)
https://github.com/jpf91/phobos/tree/newHash/std/digest
https://github.com/jpf91/phobos/compare/master...newHash

Docs: (location changed!)
http://dl.dropbox.com/u/24218791/d/phobos/std_digest_digest.html
http://dl.dropbox.com/u/24218791/d/phobos/std_digest_md.html
http://dl.dropbox.com/u/24218791/d/phobos/std_digest_sha.html
http://dl.dropbox.com/u/24218791/d/phobos/std_digest_crc.html


Can all the algorithms work at compile time (given immutable 
constant data, e.g. a string) ? YES : NO.


Hope that's descriptive.


Re: Null references

2012-08-23 Thread Nick Treleaven

On 21/08/2012 21:17, Nick Treleaven wrote:

I have an Option struct on my home computer that only allows access to
the held value if the error case is simultaneously handled:

Option!int a = foo();

int n = a.match!(
 (int x) => x,
 (None n) => 0 // or throw, or what have you.
 );


I've now implemented match, similar to the above:
https://github.com/ntrel/d-maybe/blob/master/maybe.d#L222

My match() always returns Maybe!T, because for pointers the lambdas 
could return null.


Taken from the unittest:

assert(match!(to!string, ()=>"")(maybe(2)) == "2");
assert(match!(to!string, ()=>"")(Maybe!int()) == "");
assert(match!((x, y)=>text(x, y), {})(maybe(2), maybe(34)) == "234");
assert(match!((x, y)=>text(x, y), {})(Maybe!int(), maybe(34)) == null);
assert(match!((x, y)=>text(x, y), ()=>"none")(Maybe!int(), maybe(34)) == 
"none");


I'd be interested to see your Option code.

Nick


Re: standard ranges

2012-08-23 Thread Steven Schveighoffer
Sorry to resurrect this thread, I've been very absent from D, and am just  
now going through all these old posts.


On Wed, 27 Jun 2012 17:41:14 -0400, Timon Gehr  wrote:


On 06/27/2012 11:11 PM, Steven Schveighoffer wrote:



No, druntime, and include minimal utf support. We do the same thing with
AssociativeArray.



In this case it is misleading to call it a library type.


What I mean is, the compiler does not define the structure of it.  It  
simply knows it exists, and expects a certain API for it.


The type itself is purely defined in the library, and could possibly be  
used directly as a library type.



If you want immutable(char)[], use "abc".codeunits or equivalent.



I really don't want to type .codeunits, but I want to use
immutable(char)[] everywhere. This 'library type' is just an interface
change that makes writing nice and efficient code a kludge.


When most string functions take strings, why would you want to use
immutable(char)[] everywhere?



Because the proposed 'string' interface is inconvenient to use and  
useless. It is a struct with one data member and no additionally

maintained invariant, and it strictly narrows the essential parts of
the interface to the data that is reachable without a large typing
overhead. immutable(char)[] supports exactly the operations I usually
need. Maybe I'm not representative.


Most usages of strings are to concatenate them, print them, use them as  
keys, read them from a stream, etc.  None of this requires direct access  
to the data.  They can be treated as a nebulous type.


So maybe you are in the minority.  I don't really know.


The current situation is not simple to understand.


It is simple, even if not immediately obvious. It does not have to be
immediately obvious without explanation. It needs to be convenient.


I will respond to this in a different way.  This is the confusing part:

string x;
assert(!hasLength!string);
assert(!isRandomAccessRange!string);
auto len = x.length;
auto c = x[0]; // wtf?

It is *always* going to cause people to question isRandomAccessRange and  
hasLength because clearly a string has the purported properties needed to  
satisfy both.



Generic code that accepts arrays has to special-case narrow-width
strings if you plan to
use phobos with them in some cases. That is a horrible situation.



Generic code accepts ranges, not arrays. All necessary (or maybe
unnecessary, I don't know) special casing is already done for you in
Phobos. The _only_ thing that is problematic is the inconsistent
'foreach' behaviour.


Plenty of generic code specializes on arrays.



Ok, point taken. But plenty of generic code then specializes on
strings as well. Would the net gain be so huge? There is also always
the option of just not passing strings to some helper template function
you defined.


The net gain is not in the reduction of specializations -- of course we  
will need specializations for strings because to do any less would make D  
extremely inefficient compared to other languages.


The gain is in the reduction of confusion.  We are asking our users "I  
know, I know, it's an array, but *please* pretend it's not! Don't listen  
to the compiler!"


And this is for a *BASIC* type of the language!

range.save() is the same thing.  It prevents nothing, and you have to take  
special care to avoid using basic operations (i.e. assign) and pretend  
they don't exist, even though they compile.  To me, that is worthless.  If  
a string does not support random access, then str[0] should not compile.  
period.



You are right about the random-access part, but the definition of an
array does not depend on the 'range' concept.


The range concept is notably more confusing with strings that are random  
access types but not random access ranges, even though they support all  
the properties needed for a random access range.


-Steve


Re: Vote for the new std.hash (oops, std.digest)

2012-08-23 Thread Jesse Phillips
On Wednesday, 22 August 2012 at 12:36:08 UTC, Dmitry Olshansky 
wrote:
The discussion around new unified API for digest hash functions 
has subdued, just in time as the review period has ended.


Yes.


Re: Null references

2012-08-23 Thread Namespace
Is there any special reason why these functions doesn't get 
"Maybe" as (const) ref?


void show(T)(Maybe!T m)
bool opEquals(Maybe!T m)
void opAssign(Maybe!T m)


Re: Direct access to struct construction, copying and destruction

2012-08-23 Thread Steven Schveighoffer
On Wed, 11 Jul 2012 04:21:29 -0400, Benjamin Thaut  
 wrote:




I already now what type info does, it does nothing.
The compiler fills in the xpostblit and xdtor fields of the  
TypeInfo_Struct with the correct function pointers to postblit or  
destruct functions. These fields always contain the correct function to  
call. But the __postblit and __dtor funtions that are directly callable  
on the struct itself, are only correct if there is a explicit destructor  
/ postblit constructor defined. So it shouldn't be much of a problem to  
also expose the __fielddtor and __fieldpostblit functions that get  
filled into the TypeInfo_Struct object anyway.


Also see this: http://d.puremagic.com/issues/show_bug.cgi?id=5667

-Steve


Re: More on vectorized comparisons

2012-08-23 Thread Sean Cavanaugh

On 8/22/2012 7:19 PM, bearophile wrote:

Some time ago I have suggested to add support to vector comparisons in
D, because this is sometimes useful and in the modern SIMD units there
is hardware support for such operations:


I think that code is semantically equivalent to:

void main() {
 double[] a = [1.0, 1.0, -1.0, 1.0, 0.0, -1.0];
 double[] b = [10,   20,   30,  40,  50,   60];
 double[] c = [1, 2,3,   4,   5,6];
 foreach (i; 0 .. a.length)
 if (a[i] > 0)
 b[i] += c[i];
}


After that code b is:
[11, 22, 30, 44, 50, 60]


This means the contents of the 'then' branch of the vectorized
comparison is done only on items of b and c where the comparison has
given true.

This looks useful. Is it possible to implement this in D, and do you
like it?


Well, right now the binary operators == != >= <= > and < are required to 
return bool instead of allowing a user defined type, which prevents a 
lot of the sugar you would want to make the code nice to write.  Without 
the sugar the code would ends up this:


foreach(i; 0 .. a.length)
{
float4 mask = greaterThan(a[i], float4(0,0,0,0));
b[i] = select(mask, b[i] + c[i], b[i]);
}

in GPU shader land this expression is at least simpler to write:

foreach(i; 0 .. a.length)
{
b[i] = (b[i] > 0) ? (b[i] + c[i]) : b[i];
}


All of these implementations are equivalent and remove the branch from 
the code flow, which is pretty nice for the CPU pipeline.   In SIMD the 
comparisons generate masks into a register which you can immediately 
use.  On modern (SSE4) CPUs the select is a single instruction, on older 
ones it takes three: (mask & A) | (~mask & B), but its all better than a 
real branch.


If you have a large amount of code needing a branch, you can take the 
mask generated by the compare, and extract it into a CPU register, and 
compare it for 0, nonzero, specific or any bits set.  a float4 
comparison ends up generating 4 bits, so the code with a real branch is 
like:


if (any(a[i] > 0))
{
// do stuff if any of a[i] are greater than zero
}   
if (all(a[i] > 0))
{
// do stuff if all of a[i] are greater than zero
}
if ((getMask(a[i] > 0) & 0x7) == 0x7)
{
// do stuff if the first three elements are greater than zero
}




Re: profiler issues: time overflows, conversion to seconds, gui/html output

2012-08-23 Thread Rainer Schuetze



On 23.08.2012 05:52, timotheecour wrote:

I'm not sure how to interpret trace.log from running dmd with -profile
(on osx at least).
I inserted a stopwatch inside main, which gave 35.8 seconds.

1) How to convert times in trace.log to seconds? Eg, how to get 35.8
seconds using the numbers below?

here's the first last line for times:
 Timer Is 3579545 Ticks/Sec, Times are in Microsecs 

   Num  TreeFuncPer
   CallsTimeTimeCall

here's the last line:
  1 16317420002   -43499161   -43499161 _Dmain



The trace code is in druntime/rt/trace.d. There you can see that the 
ticks/sec is just set to the shown constant value for anything but 
Windows, but RDTSC is used to read the processor cycles. So the values 
are probably off by a factor of 300 to 1000.




2) Why are there negative numbers? (seems like an overflow problem, but
the total time is quite small so it seems the scale is wrong).


The time in ms is calculated as (time * 100) / freq, so with a 
processor speed of 2GHz, this will overflow after about 2000s. This 
doesn't seem to explain negative values in your run, so some random hints:


- if you rerun the program, results will accumulate in trace.log
- if you are calling recursive functions from inside main, there might 
be some issues with the timings of these functions (from my own 
experience from writing a profiler, it can get quite tricky to measure 
the execution time of recursive functions), and these are used to 
calculate the FuncTime of main.





3) are there any tools to visualize trace.log (eg gui, html or otherwise)?
The only ones I found were outdated (ptrace.d for tango and profiled.d
for D1)



Visual D lets you explore trace.log in a browse window inside Visual 
Studio, but I guess this won't help you on OSX.


Re: Null references

2012-08-23 Thread Simen Kjaeraas
On Thu, 23 Aug 2012 18:27:41 +0200, Nick Treleaven   
wrote:



I'd be interested to see your Option code.


Here you go. After looking at your code, and with Modern C++ Design
fresh in mind, I see that match and hasValue might have worked better
as free functions.

I took the liberty of implementing the optional function calls
discussed earlier. If your eyes glaze over or you feel an urge to
kill, you are likely looking at that part of the code.

--
Simen

Option.d
Description: Binary data


Re: Vote for the new std.hash (oops, std.digest)

2012-08-23 Thread Jens Mueller
d_follower wrote:
> On Wednesday, 22 August 2012 at 12:36:08 UTC, Dmitry Olshansky
> wrote:
> >The discussion around new unified API for digest hash functions
> >has subdued, just in time as the review period has ended.
> >
> >The voting for std.digest package starts today and ends on 29
> >August.
> >
> >Rules are simple: reply in this thread with definite "YES" or "NO"
> >on whether this package should go into Phobos. Including
> >descriptive short notes is appreciated (esp. the NO ones).
> >
> >
> >Latest locations of docs and source:
> >
> >Code: (location changed!)
> >https://github.com/jpf91/phobos/tree/newHash/std/digest
> >https://github.com/jpf91/phobos/compare/master...newHash
> >
> >Docs: (location changed!)
> >http://dl.dropbox.com/u/24218791/d/phobos/std_digest_digest.html
> >http://dl.dropbox.com/u/24218791/d/phobos/std_digest_md.html
> >http://dl.dropbox.com/u/24218791/d/phobos/std_digest_sha.html
> >http://dl.dropbox.com/u/24218791/d/phobos/std_digest_crc.html
> 
> Can all the algorithms work at compile time (given immutable
> constant data, e.g. a string) ? YES : NO.

It says "Digests do not work in CTFE".
Just checked it for MD5.
I do not know but I think this is just a current limitation of the CTFE
implementation.

Jens


Re: More on vectorized comparisons

2012-08-23 Thread bearophile

Sean Cavanaugh:

Well, right now the binary operators == != >= <= > and < are 
required to return bool instead of allowing a user defined 
type, which prevents a lot of the sugar you would want to make 
the code nice to write.


The hypothetical D sugar I was looking for is this, where 'a', 
'b' and 'c' are normal dynamic arrays of doubles (not of float[4] 
of double[2]) (currently this code is a syntax error):


if (a[] > 0)
b[] += c[];


The front-end is able to implement those two lines of code as it 
likes, like seeing those normal arrays as arrays of double[2] (or 
double[4] on more modern CPUs) and put there all the needed 
intrinsics or assembly needed to implement that semantics.


So what's the problem the > operator causes in this code?

Bye,
bearophile


Re: Dynamic loading, D all the way (dmd 64bit 2.060/Ubuntu 64bit 12.04/x86_64)

2012-08-23 Thread Philip Daniels

On Wednesday, 22 August 2012 at 16:57:26 UTC, Paulo Pinto wrote:
On Wednesday, 22 August 2012 at 15:51:05 UTC, Philip Daniels 
wrote:

snip<


If we had dynamic loading, would we be able to do dependency
injection in D?


Dependency injection does not require dynamic loading per se.

It is all about using interfaces instead of classes, and 
initializing the corresponding instance members.


You just need some piece of code that takes the responsibility 
of locating such interfaces, by registering the classes 
somehow, or by compile time reflection, which gets called on 
program initialization.


You can do this in D today.

--
Paulo


But wouldn't that require you to link everything together at, 
err, compile time?


What I'm getting at is, would it be possible to port a DI/IoC 
tool such as StructureMap 
(http://docs.structuremap.net/index.html) or Spring to D? This 
can handle tasks such as creating dynamic plug-in architectures. 
For example, given SomeBigApp.exe (not written by me) which looks 
in standard folders for components implementing a particular 
interface, I can just drop my code in that folder and have it 
loaded at runtime. I could even drop it in there after the 
program starts running. I know how to achieve this in the .Net 
world, just wondered if it was possible in D.




Re: Vote for the new std.hash (oops, std.digest)

2012-08-23 Thread Bernard Helyer

Yes.

The API seems fairly solid to me, and the
need for these things is fairly wide reaching.


Phobos unittest failure on single-core machines

2012-08-23 Thread Ed McCardell
When trying to run the phobos unittests on my 32- and 64-bit linux 
single-processor machines, I get this output:


  Testing generated/linux/debug/64/unittest/std/parallelism
  totalCPUs = 1
  core.exception.AssertError@std.parallelism(4082): unittest failure

Has anyone else seen this, or is possible that I have an error in my dmd 
setup? (I'm using dmd/druntime/phobos from git HEAD, building in what I 
thought was the normal manner).


--Ed McCardell


Consistency, Templates, Constructors, and D3

2012-08-23 Thread F i L
DISCLAIMER: This isn't a feature request or anything like that. 
It's ONLY intended to stir _constructive_ conversation and 
criticism of D's existing features, and how to improve them _in 
the future_ (note the 'D3' in the title).


I've had a couple of ideas recently about the importance of 
consistency in a language design, and how a few languages I 
highly respect (D, C#, and Nimrod) approach these issues. This 
post is mostly me wanting to reach out to a community that enjoys 
discussing such issues, in an effort to correct any 
mis-conceptions I might hold, and to spread potentially good 
ideas to the community in hopes that my favorite language will 
benefit from our discussion.



---


First, let me assert that "Consistency" in a language is 
critically important for a few reasons:


1. One way of doing things means one way to _remember_ things. It 
keeps us sane, focused, and productive. The more we have to fight 
the language, the harder it is to master.


2. Less things to remember means it's easier to learn. First 
impressions are key for popularity.


3. Less discrepancies means fewer human errors, and thus, fewer 
"stupid" bugs.





# CAST/TRAITS ##

To start, let's look at: cast(T) vs to!T(t)

In D, we have one way to use template function, and then we have 
special keyword syntax which doesn't follow the same syntactical 
rules. Here, cast looks like the 'scope()' or 'debug' statement, 
which should be followed by a body of code, but it works like a 
function which takes in the following argument and returns the 
result. Setting aside the "func!()()" syntax for a moment, what 
cast should look like in D is:


int i = cast!int(myLong);

It's a similar story with __traits(). What appears to be a 
function taking in a run-time parameter is actually compile-time 
parameter which works by "magic". It should look like:


bool b = traits!HasMember(Foo);




# FUNCTIONS PARAMETERS ##

All that brings me to my next argument, and that's that the 
"func!()()" is inconsistent, or at the very least, hard to 
understand (when it doesn't have to be). We have one way of 
defining "optional" runtime parameters, and a different set of 
rules entirely for compile-time parameters. Granted, these things 
are very different to the compiler, to the programmer however, 
they "appear" to just be things we're passing to a function.


I think Nimrod has a better (but not perfect) approach to this, 
in that there are different "kinds" of functions. One that takes 
in runtime params, and one that takes in compile-time ones; but 
at the call site, you use them the same:


# Nimrod code

template foo(x:int) # compile time
  when x == 0:
doSomething()
  else:
doSomethingElse()

proc bar(x:int) # run time
  if x == 0:
doSomething()
  else:
doSomethingElse()

block main:
  foo(0) # both have identical..
  bar(0) # ..call signatures.

In D, that looks like:

void foo(int x)() {
  static if (x == 0) { doSomething(); }
  else { doSomethingElse(); }
}

void bar(int x) {
  if (x == 0) { doSomething(); }
  else { doSomethingElse(); }
}

void main() {
  foo!0();
  bar(0); // completely difference signatures
}

Ultimately foo is just more optimized in the case where an 'int' 
can be passed at compile time, but the way you use it in Nimrod 
is much more consistent than in D. In fact, Nimrod code is very 
clean because there's no special syntax oddities, and that makes 
it easy to follow (at least on that level), especially for people 
learning the language.


But I think there's a much better way. One of the things people 
like about Dynamicly Typed languages is that you can hack things 
together quickly. Given:


function load(filename) { ... }

the name of the parameter is all that's required when throwing 
something together. You know what 'filename' is and how to use 
it. The biggest problem (beyond efficiency), is later when you're 
tightening things up you have to make sure that 'filename' is a 
valid type, so we end up having to do the work manually where in 
a Strong Typed language we can just define a type:


function load(filename)
{
  if (filename != String) {
error("Must be string");
return;
  }
  ...
}

vs:

void load(string filename) { ... }

but, of course, sometimes we want to take in a generic parameter, 
as D programmers are fully aware. In D, we have that option:


void load(T)(T file)
{
  static if (is(T : string))
...
  else if (is(T : File))
...
}

but it's wonky. Two parameter sets? Type deduction? These 
concepts aren't the easiest to pick up, and I remember having 
some amount of difficulty first learn what the "func!(...)(...)" 
did in D.


So why not have one set of parameters and allow "typeless" ones 
which are simply compile-time duck-typ

Re: Consistency, Templates, Constructors, and D3

2012-08-23 Thread F i L

Typo: '_head' and '_next' in this example should be 'static'


bleh.. I mean only '_head' should be static. Not '_next'




Re: Consistency, Templates, Constructors, and D3

2012-08-23 Thread F i L

F i L wrote:
This would also keep consistent syntax when using 
FreeLists/MemeoryPools, because everything is done through 
factories in this case, and the implementation can be arbitrary:


class Foo {
  private Foo _head, _next;

  [ ... ]


Typo: '_head' and '_next' in this example should be 'static'