Re: std.socket undefined UnixAddress?

2013-01-24 Thread Rob T
I solved the problem by creating my own version of UnixAddress. 
The existing implementation needs some work. I'll filed a bug 
report.


http://d.puremagic.com/issues/show_bug.cgi?id=9384

--rt


Re: Coping files and folders

2013-01-24 Thread monarch_dodra
On Thursday, 24 January 2013 at 07:41:23 UTC, Jacob Carlborg 
wrote:

On 2013-01-24 07:28, Joel wrote:
How does one copy folders (with files in them) including sub 
folders,

and creating any needed folders?

Like:
land\house\cat.d
land\house\rat.exe
land\house\bedroom\ants.txt

to
root\island\house\cat.d
root\island\house\rat.exe
root\island\house\bedroom\ants.txt

One work around is to use 'system' (under std.process).


I don't think Phobos currently has any functions for this. 
Someone posted code in these newsgroups of a parallel 
implementation of copy and remove.


Mustn't be very hard to manually write copyDir.

The problem with copyDir is its transactional behavior: What 
should it do in case of a failure mid copy? Bail? Cleanup? 
Continue?


Anyways, I just threw this together. The first version bails on 
first error.
The second version keeps going as much as it can, and returns 
true on success.


The caller is then free to (or not to) call rmdirRecurse in case 
of failure.


//Throws exception on first error.
void copyDir(string inDir, string outDir)
{
if (!exists(outDir))
mkdir(outDir);
else
if (!isDir(outDir))
throw new FileException(format(Destination path %s 
is not a folder., outDir));


foreach (entry; dirEntries(inDir.idup, SpanMode.shallow))
{
auto fileName = baseName(entry.name);
auto destName = buildPath(outDir, fileName);
if (entry.isDir())
copyDir(entry.name, destName);
else
copy(entry.name, destName);
}
}

//Silently keeps going as much as it can, then returns true on 
success,

//or false if an error occured.
bool copyDirSilent(string inDir, string outDir)
{
if (!exists(outDir))
{
auto e = collectException(mkdir(outDir));
if (e !is null)
return false;
}
else
if (!isDir(outDir))
return false;

foreach (entry; dirEntries(inDir, SpanMode.shallow))
{
auto fileName = baseName(entry.name);
auto destName = buildPath(outDir, fileName);
if (entry.isDir())
{
bool b = copyDirSilent(entry.name, destName);
if (b == false)
return false;
}
else
{
auto e = collectException(mkdir(outDir));
if (e !is null)
return false;
}
}
return true;
}


Re: Passing opaque struct between functions/modules

2013-01-24 Thread Mike Parker

On Wednesday, 23 January 2013 at 16:33:08 UTC, Sarath Kumar wrote:

DMD v2.61; openSUSE 12.1

Source:
---
libA.d:

module libA;

extern (C)
{
struct Opaque;

Opaque* getObject();

void doSomething(Opaque *);
}
--
libB.d:

module libB;

extern (C)
{
struct Opaque;

void doAction(Opaque *);
}
---
bug.d

import libA, libB;

int main(string[] args)
{
auto opaque = libA.getObject();
libA.doSomething(opaque); // this is okay
libB.doAction(opaque);  // but this is not, compiler 
error here

return 0;
}

When I compile the above files, I get the below error.
$ rdmd bug.d
bug.d(7): Error: function libB.doAction (Opaque*) is not 
callable using argument types (Opaque*)
bug.d(7): Error: cannot implicitly convert expression (opaque) 
of type Opaque* to Opaque*


If I do an explicit cast, libB.Opaque*, for opaque in line 7, 
bug.d, I get completely different set of errors.


$ rdmd bug.d
libB.d(5): Error: struct libB.Opaque unknown size
libB.d(5): Error: struct libB.Opaque no size yet for forward 
reference

libB.d(5): Error: struct libB.Opaque unknown size
libB.d(5): Error: struct libB.Opaque no size yet for forward 
reference

libA.d(5): Error: struct libA.Opaque unknown size
libA.d(5): Error: struct libA.Opaque no size yet for forward 
reference


Can someone please tell me the right way to pass an opaque 
object between module's functions.


The error message here is deceiving. Declare the struct in one 
module only and then import it in every module that uses it. So, 
for example, keep the declaration in libA, remove it from libB 
and in libB add import libA;.


Re: Passing opaque struct between functions/modules

2013-01-24 Thread Sarath Kumar

On Wednesday, 23 January 2013 at 17:14:31 UTC, Ali Çehreli wrote:

On 01/23/2013 08:33 AM, Sarath Kumar wrote:

 Can someone please tell me the right way to pass an opaque
object
 between module's functions.

I am assuming that you are interfacing with a C library. That 
library must have a D binding file. I am assuming that it is 
your libA.d:



There is also a library that implements the struct and the 
functions. Although you would have it in the C library, here is 
a D module to imitate it:


// libA_impl.d
// These are presumably defined in a C library. Simply 
imitating it with this

// D module
extern (C)
{
struct Opaque
{
int i;
double d;
}

Opaque* getObject()
{
return new Opaque(42, 1.5);
}

void doSomething(Opaque *)
{}
}



I don't know the contents of the struct as libA and libB are 3rd 
party C libraries.




Segfault in _d_dynamic_cast ()

2013-01-24 Thread Minas Mina
I am trying to create a BVH tree structure to speed up 
raytracing. So far it has been fine. I have created the BVH tree. 
It works for 202 triangles/spheres.


However, when the scene has more spheres/triangles, I get a 
segmentation fault when the rays are traces, not when the tree is 
being built.


To let you understand, there is a Surface class, from which 
BVHNode, Sphere and Triangle inherit.


I have written a small function that prints the BVH tree 
recursively. Here it is:


void printBVH(Surface root, int i = 0, string str = )
{
if( root is null )
return;

writeln(--PRINT()--);
writeln(icy);//writeln(root.boundingBox());
writeln(name = , root.name,  depth = , i,  [, str, ]);
writeln(--~~~--\n);

if( (cast(BVHNode)root) !is null ) // OOPS! SEG FAULT HERE
{
printBVH((cast(BVHNode)(root)).left, i+1, left);
printBVH((cast(BVHNode)(root)).right, i+1, right);
}
}

And I pass to printBVH() the root node that the function that 
builds the tree has returned.


// replaces every two Surfaces with one that is their parent. 
Proceeds until there is only one surface, which is the root.
BVHNode createBVHTree2(Surface[] objects, ubyte axis = 0, int 
depth = 0)

{
import std.algorithm, std.stdio;

BVHNode root;

// sort left out for now until the seg fault is fixed
	//sort!((a.boundingBox().min.x + a.boundingBox().max.x) * 0.5f 
 (b.boundingBox().min.x + b.boundingBox().max.x) * 0.5f, 
SwapStrategy.unstable)(objects);


while( objects.length  1 )
{
writeln(--- Level ---);
foreach(o; objects)
write([, o.name, ] );
writeln();

auto temp = new Surface[objects.length/2 + 1];
auto sz = 0UL;

for(auto i = 0UL; i  objects.length; i += 2)
{
writeln(i = , i,  sz = , sz+1);

BVHNode parent = new BVHNode();
parent.name = p;

parent.left = objects[i];
if( i + 1  objects.length )
{   
parent.right = objects[i+1];

auto box1 = objects[i].boundingBox(), box2 = 
objects[i+1].boundingBox();

parent.box = combine(box1, box2);
}
else
{
parent.right = null;
parent.box = objects[i].boundingBox();
}

temp[sz++] = parent;
}

temp.length = sz;
objects = temp;
}

root = cast(BVHNode)objects[0];

return root;
}

Ok, so when I print the scene using printBVH(), I get a segfault 
in the line:

if( (cast(BVHNode)root) !is null )

GDB says: Program received signal SIGSEGV, Segmentation fault.
0x004b55fc in _d_dynamic_cast ()

Note that I have written the createBVHTree() and printBVH() 
functions in Java to see if it would be different. The code works 
in Java. I guess something is wrong with the compiler here and 
the way it handles recursion(?) -- By the way the code seg faults 
at the 11 depth level. Are there any know bugs for this?


Thanks.


Re: Passing opaque struct between functions/modules

2013-01-24 Thread Mike Parker

On Thursday, 24 January 2013 at 09:39:39 UTC, Sarath Kumar wrote:

On Thursday, 24 January 2013 at 09:04:09 UTC, Mike Parker wrote:


The error message here is deceiving. Declare the struct in one 
module only and then import it in every module that uses it. 
So, for example, keep the declaration in libA, remove it from 
libB and in libB add import libA;.


I can't import libA into libB. So, I had moved the forward 
declaration into a separate D file and did a public import into 
libA and libB. This works. But this is a workaround. I will 
file a bug.




The only potential bug I see here is in the error message. What 
you're seeing is a conflict that arises from D's name mangling. 
The doSomething in libA is expecting a parameter of type 
libA.Opaque* and getObject is returning the same, whereas the 
functions in libB are expecting a parameter of type libB.Opaque*. 
You can see this if you do the following:


writeln(doSomething.mangleof);
writeln(doAction.mangleof);

This is why your code is failing when you call getAction, because 
you're passing it a libA.Opaque* returned from libA.getObject. 
The solution is to declare opaque struct in a single place and 
import it everywhere you need it. That's why your public imports 
work. I would suggest that you not use the public import in this 
case, but work out some other scenario. In Derelict (a collection 
of C bindings) for example, I tend to follow this pattern for any 
lib a bind to:


types.d - all type  constant declarations go here
functions.d - all function declarations go here, imports the 
types module


Then I have a module named according to the C library's primary 
header that publicly imports both. For SDL2, for example:


module derelict.sdl2.sdl;

public {
import derelict.sdl2.types;
import derelict.sdl2.functions;
}

This way, all types are declared in a single location so there's 
no danger of mixing up different mangles of the same type.


Re: Pull 1019

2013-01-24 Thread mist
yebblies: Can an auto-ref function pointer/deltegate implicitly 
convert to ref?
9rnsr: To @yebblies : I yet not implement it because this is a 
basic proposal.


IMHO, what he says is that behavior proposed by yebblies is some 
more complicated special cases he is not going to do within this 
pull request to keep things simple.


All pulls are proposals, by the way, it is up to one of core devs 
(other than pull author) to make a decision about merging.


On Wednesday, 23 January 2013 at 23:46:19 UTC, Namespace wrote:

I have now seen something I've probably overlooked before.
Here:
https://github.com/D-Programming-Language/dmd/pull/1019#issuecomment-11836011 
Kenji says, that the pull is a basic _proposal_.


What does this mean? It isn't merged until we made a final 
discussion and decision about that? :/


I thought that this is the solution for all C++ rvalue ref 
problems. Am i wrong?
I'm asking so much because I've been using it already - and I 
love it. Without such thing it is very annoying to work with 
structs.


Why is null lowercase?

2013-01-24 Thread Matthew Caron

This is probably a question for Walter, but maybe others know.

Of all of the differences between C and D, the one which I have the most 
difficulty adapting to is null being lowercase. Does anyone know why 
this decision was made?

--
Matthew Caron, Software Build Engineer
Sixnet, a Red Lion business | www.sixnet.com
+1 (518) 877-5173 x138 office


Re: Segfault in _d_dynamic_cast ()

2013-01-24 Thread Maxim Fomin

On Thursday, 24 January 2013 at 10:14:29 UTC, Minas Mina wrote:
I am trying to create a BVH tree structure to speed up 
raytracing. So far it has been fine. I have created the BVH 
tree. It works for 202 triangles/spheres.


skipped

Thanks.


Requests for debugging help without source code are likely to be 
buried in archives silently. Perhaps you can look at 
_d_dynamic_cast source code 
(https://github.com/D-Programming-Language/druntime/blob/master/src/rt/cast_.d#L69) 
and figure out the exact statement which produces segfault.


Re: Why is null lowercase?

2013-01-24 Thread bearophile

Matthew Caron:

Of all of the differences between C and D, the one which I have 
the most difficulty adapting to is null being lowercase. Does 
anyone know why this decision was made?


Probably because writing all in uppercase ugly. null is a keyword 
like the others, and they are in lowercase. DO YOU PREFER A 
LANGUAGE ALL IN UPPERCASE?


Bye,
bearophile


Re: Why is null lowercase?

2013-01-24 Thread Mike Parker

On Thursday, 24 January 2013 at 12:56:03 UTC, Matthew Caron wrote:

This is probably a question for Walter, but maybe others know.

Of all of the differences between C and D, the one which I have 
the most difficulty adapting to is null being lowercase. Does 
anyone know why this decision was made?


In the world of C and C++, 'NULL' is a macro. Macros, by 
convention, are all uppercase. Contrast that with C++11 which 
provides for 'nullptr', a type rather than a macro. Consider 
Java, which also has a lowercase null. In D, null follows the 
same convention as other built-ins, so it is lowercase. To me, it 
makes perfect sense. There are no macros in D, so I wouldn't have 
expected to see NULL to begin with. *That* would have been highly 
inconsistent.


Re: Why is null lowercase?

2013-01-24 Thread monarch_dodra

On Thursday, 24 January 2013 at 12:56:03 UTC, Matthew Caron wrote:

This is probably a question for Walter, but maybe others know.

Of all of the differences between C and D, the one which I have 
the most difficulty adapting to is null being lowercase. Does 
anyone know why this decision was made?


Keep in mind that strictly speeking, NULL != null:

NULL is a C macro that expands to 0.
null is a D keyword that cannot be implicitly cast to an integer.

This is a source of bugs:

//
void foo(int);
void foo(int*);
//

in C++:
foo(NULL); //Calls void foo(int)

in D:
foo(null); //Calls void foo(int*)

Having code that is valid in both C++ and D, but having a 
different behavior would be VERY bad.



BTW, you can be thankful that it is *just* null, because what 
it really is C++11's null_ptr. Which is worst.


Re: Why is null lowercase?

2013-01-24 Thread Leandro Motta Barros
Hi,

In C, NULL is a #define, and #defines are typically all-caps. In D,
null is real keyword recognized by the compiler, and those are
typically lowercase. I am just guessing here, but I'd say the choice
for 'null' instead of 'NULL' is just to be coherent with this.

Personally, I kinda like 'null'. :-)

LMB




On Thu, Jan 24, 2013 at 10:56 AM, Matthew Caron matt.ca...@redlion.net wrote:
 This is probably a question for Walter, but maybe others know.

 Of all of the differences between C and D, the one which I have the most
 difficulty adapting to is null being lowercase. Does anyone know why this
 decision was made?
 --
 Matthew Caron, Software Build Engineer
 Sixnet, a Red Lion business | www.sixnet.com
 +1 (518) 877-5173 x138 office


Re: Pull 1019

2013-01-24 Thread Namespace

Thanks for your answer. That explains my question.
I would love to see an official statement about this pull and 
this feature. But neither in the related threads or here in 
learn I get such statement. That is very sad because this 
feature is very important and long discussed.


Re: Pull 1019

2013-01-24 Thread Namespace

On Thursday, 24 January 2013 at 13:42:36 UTC, Namespace wrote:

Thanks for your answer. That explains my question.
I would love to see an official statement about this pull and 
this feature. But neither in the related threads or here in 
learn I get such statement. That is very sad because this 
feature is very important and long discussed.


And I must add: I read so often that Walter does not like to 
break existing code.
But with dmd 2.061 structs aren't lvalues anymore (that was a 
correct decision) but auto ref (which would solve the problem 
and prevent breaking existing code) wasn't merged and it seems 
that this feature isn't that relevant if I look on the merge 
history.

That a bit weird to me.


Re: Passing opaque struct between functions/modules

2013-01-24 Thread Maxim Fomin

On Wednesday, 23 January 2013 at 16:33:08 UTC, Sarath Kumar wrote:

DMD v2.61; openSUSE 12.1

Source:
---
libA.d:

module libA;

extern (C)
{
struct Opaque;

Opaque* getObject();

void doSomething(Opaque *);
}
--
libB.d:

module libB;

extern (C)
{
struct Opaque;

void doAction(Opaque *);
}
---
bug.d

import libA, libB;

int main(string[] args)
{
auto opaque = libA.getObject();
libA.doSomething(opaque); // this is okay
libB.doAction(opaque);  // but this is not, compiler 
error here

return 0;
}

When I compile the above files, I get the below error.
$ rdmd bug.d
bug.d(7): Error: function libB.doAction (Opaque*) is not 
callable using argument types (Opaque*)
bug.d(7): Error: cannot implicitly convert expression (opaque) 
of type Opaque* to Opaque*


If I do an explicit cast, libB.Opaque*, for opaque in line 7, 
bug.d, I get completely different set of errors.


$ rdmd bug.d
libB.d(5): Error: struct libB.Opaque unknown size
libB.d(5): Error: struct libB.Opaque no size yet for forward 
reference

libB.d(5): Error: struct libB.Opaque unknown size
libB.d(5): Error: struct libB.Opaque no size yet for forward 
reference

libA.d(5): Error: struct libA.Opaque unknown size
libA.d(5): Error: struct libA.Opaque no size yet for forward 
reference


Can someone please tell me the right way to pass an opaque 
object between module's functions.


--
Thanks,
Sarath


You have hit one of the D problems regarding extern(). The first 
problem is that extern(C)-declared objects inside functions are 
still mangled, the other problem is that extern(C) Type var; 
still creates var object, unlike C does (except when Type is a 
function pointer).


The following D program is compiled and linked:

extern(C) int i;

void main()
{
i = 0;
}

However, a C equivalent would result in linking error due to 
unresolved i reference.


So, what you are really doing is unusable. By the way, doing this 
way you are actually defining two different structs, libA.Opaque 
and libB.Opaque. Compiler is right in this case, because these 
types are incompatible, but it should print full names to show 
the difference explicitly.


If you are working with C library, you can use following scheme:
--main.d
extern extern(C) struct Opaque;

extern extern(C) Opaque* getObject();


void main()
{
Opaque* ptr = getObject();
}
-struct.c---
struct Opaque
{
int i;
double d;
};

struct Opaque op;

struct Opaque* getObject()
{
return op;
}


and if you are using D code, you should use .di files.


Re: Pull 1019

2013-01-24 Thread monarch_dodra

On Thursday, 24 January 2013 at 13:51:27 UTC, Namespace wrote:

On Thursday, 24 January 2013 at 13:42:36 UTC, Namespace wrote:

Thanks for your answer. That explains my question.
I would love to see an official statement about this pull and 
this feature. But neither in the related threads or here in 
learn I get such statement. That is very sad because this 
feature is very important and long discussed.


And I must add: I read so often that Walter does not like to 
break existing code.


break *cough* valid *cough* existing code.

This wasn't really a new/changed feature that broke your code. It 
was just something that worked that never should have worked.


I know it sucks being on your end, but that's how it is.


Singleton Pattern with struct

2013-01-24 Thread ParticlePeter

Hi,

I am trying to figure out the singleton pattern with a struct 
instead of a class:

[code]
struct Singleton  {

private :
this( int a = 0 ) {} ;
static Singleton * s ;

public :
@disable this() ;
static ref Singleton instance()  {
if ( s is null )
s = new Singleton( 0 ) ;
return * s ;
}

int val = 0 ;
}
[/code]

This compiles, but when I use it:
[code]
auto s = Singleton.instance ;
writeln( s.val ) ;

Singleton.instance.val = 2 ;
writeln( s.val ) ;
[/code]

I get:
0
0

Where is my mistake ?

Cheers, PP !


Re: Passing opaque struct between functions/modules

2013-01-24 Thread Sarath Kumar

On Thursday, 24 January 2013 at 11:52:57 UTC, Mike Parker wrote:


The only potential bug I see here is in the error message. What 
you're seeing is a conflict that arises from D's name mangling. 
The doSomething in libA is expecting a parameter of type 
libA.Opaque* and getObject is returning the same, whereas the 
functions in libB are expecting a parameter of type 
libB.Opaque*.


  It is a bug because even after casting, the compiler gives an 
error. The compiler wants to know the size of the opaque object, 
even though I'm dealing with a pointer only. As Maxim Fomin 
mentioned, the compiler is trying to create an instance of the 
object even when it is declared as extern (C) and it is a pointer.


--
Thanks,
Sarath


Re: Singleton Pattern with struct

2013-01-24 Thread Maxim Fomin

On Thursday, 24 January 2013 at 14:11:10 UTC, ParticlePeter wrote:

Hi,

I am trying to figure out the singleton pattern with a struct 
instead of a class:

[code]
struct Singleton  {

private :
this( int a = 0 ) {} ;
static Singleton * s ;

public :
@disable this() ;
static ref Singleton instance()  {
if ( s is null )
s = new Singleton( 0 ) ;
return * s ;
}

int val = 0 ;
}
[/code]

This compiles, but when I use it:
[code]
auto s = Singleton.instance ;
writeln( s.val ) ;

Singleton.instance.val = 2 ;
writeln( s.val ) ;
[/code]

I get:
0
0

Where is my mistake ?

Cheers, PP !


Even if Singleton.instance returns by ref, s object is still 
stack-allocated struct, which is not affected by further 
modification of private pointer.


import core.stdc.stdio : printf;

struct Singleton  {

private :
this( int a = 0 ) {} ;
static Singleton * s ;

public :
@disable this() ;
static ref Singleton instance()  {
if ( s is null )
s = new Singleton(0) ;
return * s ;
}

int val = 0 ;
}

void main()
{
auto s = Singleton.instance ;
printf( %d\n, s.val ) ; //0

Singleton.instance.val = 2 ;
printf( %d\n,  s.val ) ; // also 0
printf( %d\n, Singleton.instance.val); // is 2 as expected
}


Re: Singleton Pattern with struct

2013-01-24 Thread Jacob Carlborg

On 2013-01-24 15:43, Maxim Fomin wrote:


Even if Singleton.instance returns by ref, s object is still
stack-allocated struct, which is not affected by further modification of
private pointer.


The struct is allocated using new.

--
/Jacob Carlborg


Re: Singleton Pattern with struct

2013-01-24 Thread ParticlePeter
Even if Singleton.instance returns by ref, s object is still 
stack-allocated struct, which is not affected by further 
modification of private pointer.


But where and when is ( a second  ? ) Singleton created or 
duplicated ? The only ctor is in the static instance ( it is 
called only once according to my debugger ) and allocates a 
Singleton instance on the Heap ( as far as I understand new 
Struct ). The return statement does return a reference ( to a 
pointer, even that shouldn't be necessary ) so I would expect ... 
well a reference and not a copy. So where does the second object 
come from ?


Re: Singleton Pattern with struct

2013-01-24 Thread Maxim Fomin
On Thursday, 24 January 2013 at 15:05:15 UTC, Jacob Carlborg 
wrote:

On 2013-01-24 15:43, Maxim Fomin wrote:


Even if Singleton.instance returns by ref, s object is still
stack-allocated struct, which is not affected by further 
modification of

private pointer.


The struct is allocated using new.


This is about auto s =  in main, not about new in method. 
Type of s is Singleton, not Singleton* or ref Singleton.


Singleton s = Singleton.instance; // is compiled when
Singleton* s = Singleton.instance; // is not - Error: cannot 
implicitly convert // expression (instance()) of type Singleton 
to Singleton*


Re: Pull 1019

2013-01-24 Thread Namespace

break *cough* valid *cough* existing code.

This wasn't really a new/changed feature that broke your code. 
It was just something that worked that never should have worked.


Ok, ok, it wasn't a valid solution but it was the only solution 
for handy programming with structs. We have still nothing which 
is compareable with the rvalue ref of C++ and now where this 
handy programming with structs is gone you have to write your 
code twice: for ref and for not ref. That is annoying.



I know it sucks being on your end, but that's how it is.


Yes it sucks and I hope it will change in the near future, but 
I'm not sure.
Maybe I should get to like the idea that I have to write my code 
twice. Who knows how long it takes to merge this pull or to find 
another solution...


Re: Singleton Pattern with struct

2013-01-24 Thread ParticlePeter

Got it, thanks, I changed the instance method to:
[code]
static Singleton * instance()  {
if ( s is null )
s = new Singleton( 0 ) ;
return s ;
}
[\code]

and everything works as expected.

Cheers, PP !



Re: Singleton Pattern with struct

2013-01-24 Thread Maxim Fomin

On Thursday, 24 January 2013 at 15:50:34 UTC, ParticlePeter wrote:

Got it, thanks, I changed the instance method to:
[code]
static Singleton * instance()  {
if ( s is null )
s = new Singleton( 0 ) ;
return s ;
}
[\code]

and everything works as expected.

Cheers, PP !


Yes, but this can be broken by:

import core.stdc.stdio : printf;

struct Singleton  {

private :
this( int a = 0 ) {} ;
static Singleton * s ;

public :
@disable this() ;
static Singleton* instance()  {
if ( s is null )
s = new Singleton(0) ;
return s ;
}

int val = 0 ;
}

void main()
{
Singleton s = * Singleton.instance;
printf( %d\n, s.val ) ; //
Singleton.instance.val = 2 ;
printf( %d\n, s.val ) ; //0
}

Here s is explicitly defined to be a struct object, not pointer 
(reference), so main.s is independent of further modification of 
Singleton.instance.


Re: S-Expressions

2013-01-24 Thread qznc

On Wednesday, 23 January 2013 at 17:49:23 UTC, bearophile wrote:

We are getting to the Mathematica again:
http://rosettacode.org/wiki/Rosetta_Code/Rank_languages_by_popularity

Bye,
bearophile


We're even now ;)

http://rosettacode.org/wiki/Rosetta_Code/Rank_languages_by_popularity#D


Re: Singleton Pattern with struct

2013-01-24 Thread Era Scarecrow

On Thursday, 24 January 2013 at 16:07:36 UTC, Maxim Fomin wrote:

Yes, but this can be broken by:



void main()
{
Singleton s = * Singleton.instance;
printf( %d\n, s.val ) ; //
Singleton.instance.val = 2 ;
printf( %d\n, s.val ) ; //0
}

Here s is explicitly defined to be a struct object, not pointer 
(reference), so main.s is independent of further modification 
of Singleton.instance.


 I'm not sure but this seems like one of the few appropriate 
places i would just make a normal struct and just use a global 
variable. True there could 'be' multiple instances of these 
singletons, but only ever making one ensures it would work right 
so long as you cannot copy it. Wasn't disabling this(this) and 
opAssign the way to ensure that didn't happen?


 Course if you didn't and you relied on the instance one, and you 
cannot copy then you could only pass by reference or be required 
to use .instance every time you needed it. Seems a bit excessive.



 Hmmm. You could separate the data and remove the pointer... then 
use alias this.


[code]
  struct Singleton {
static SingletonData single;
alias single this;
@disable this(this);
//disable copy/assignment? Not that it would matter...
//copying nothing does nothing, as there's nothing here.

private static struct SingletonData {
  //methods and data here.
}
  }
[/code]


Re: Singleton Pattern with struct

2013-01-24 Thread Maxim Fomin

On Thursday, 24 January 2013 at 16:17:34 UTC, Era Scarecrow wrote:

On Thursday, 24 January 2013 at 16:07:36 UTC, Maxim Fomin wrote:

Yes, but this can be broken by:



void main()
{
   Singleton s = * Singleton.instance;
   printf( %d\n, s.val ) ; //
   Singleton.instance.val = 2 ;
   printf( %d\n, s.val ) ; //0
}

Here s is explicitly defined to be a struct object, not 
pointer (reference), so main.s is independent of further 
modification of Singleton.instance.


 I'm not sure but this seems like one of the few appropriate 
places i would just make a normal struct and just use a global 
variable. True there could 'be' multiple instances of these 
singletons, but only ever making one ensures it would work 
right so long as you cannot copy it. Wasn't disabling 
this(this) and opAssign the way to ensure that didn't happen?


 Course if you didn't and you relied on the instance one, and 
you cannot copy then you could only pass by reference or be 
required to use .instance every time you needed it. Seems a bit 
excessive.



 Hmmm. You could separate the data and remove the pointer... 
then use alias this.


[code]
  struct Singleton {
static SingletonData single;
alias single this;
@disable this(this);
//disable copy/assignment? Not that it would matter...
//copying nothing does nothing, as there's nothing here.

private static struct SingletonData {
  //methods and data here.
}
 [/code]


I agree, but disabling ctors makes creating module-level object 
tricky. Static struct initialization might help.


Re: Singleton Pattern with struct

2013-01-24 Thread ParticlePeter

Yes, but this can be broken by:

import core.stdc.stdio : printf;

struct Singleton  {

private :
this( int a = 0 ) {} ;
static Singleton * s ;

public :
@disable this() ;
static Singleton* instance()  {
if ( s is null )
s = new Singleton(0) ;
return s ;
}

int val = 0 ;
}

void main()
{
Singleton s = * Singleton.instance;
printf( %d\n, s.val ) ; //
Singleton.instance.val = 2 ;
printf( %d\n, s.val ) ; //0
}

Here s is explicitly defined to be a struct object, not pointer 
(reference), so main.s is independent of further modification 
of Singleton.instance.


O.k. good to know, I'll try to avoid this. But one thing is still 
not clear,
This method here ( my first approach ) does return a reference to 
an object on the heap, right ?


static ref Singleton instance()  {
if ( s is null )
s = new Singleton( 0 ) ;
return * s ;
}

so when I use it with:
auto another_s = Singleton.instance ;

Why is the s inside the struct and another_s not identical ?
Afaik that is the purpose of the ref keyword ?







Re: Singleton Pattern with struct

2013-01-24 Thread Ali Çehreli

On 01/24/2013 08:52 AM, ParticlePeter wrote:

 This method here ( my first approach ) does return a reference to an
 object on the heap, right ?

Yes, but the caller does not get a reference.

 static ref Singleton instance() {
 if ( s is null )
 s = new Singleton( 0 ) ;
 return * s ;
 }

 so when I use it with:
 auto another_s = Singleton.instance ;

 Why is the s inside the struct and another_s not identical ?
 Afaik that is the purpose of the ref keyword ?

When you print the type of another_s you will see that it is not a ref, 
because unlike C++, D does not have local ref variables; it has pointers 
for that purpose.


import std.stdio;

ref int foo()
{
return *new int;
}

void main()
{
auto i = foo();
writeln(typeid(i));
}

Prints 'int', not 'ref int'. So, i is a copy of the dynamically created int.

Ali



Re: Why is null lowercase?

2013-01-24 Thread Rob T

On Thursday, 24 January 2013 at 12:56:03 UTC, Matthew Caron wrote:

This is probably a question for Walter, but maybe others know.

Of all of the differences between C and D, the one which I have 
the most difficulty adapting to is null being lowercase. Does 
anyone know why this decision was made?


You'll get used to it, it's actually much better than typing in 
NULL, and it's a real type instead on an int, which never worked 
well in C.


Just be warned that when checking for null *do not* use equality 
operator


if ( ptr == null) ...

instead use the identity operator is

if ( ptr is null) ...

for not null checks

if ( ptr !is null) ...

BTW, half of what you thought worked well in C/C++ will get 
turned upside down if you stick with D, and once you get it, 
moving back to C/C++ becomes unbearable.


--rt


Getting the parameters of a struct/class constructor

2013-01-24 Thread Joseph Rushton Wakeling

Hello all,

Is there a way to construct a tuple of the types that need to be passed to a 
struct or class's constructor?


I tried using ParameterTypeTuple either on the class or its constructor:

ParameterTypeTuple!A

or

ParameterTypeTuple!(A.this)

... but neither works: the former generates an error,

Error: template instance ParameterTypeTuple!(A) ParameterTypeTuple!(A) does 
not match template declaration ParameterTypeTuple(func...) if (func.length == 1 
 isCallable!(func))


while the latter generates,

Error: identifier expected following '.', not 'this'

A (broken) bit of sample code is attached which illustrates what I'm trying to 
achieve.  Can anyone advise?


Thanks  best wishes,

 -- Joe
import std.stdio, std.traits;

struct A
{
	private immutable int _a;
	private immutable double _b;

	this(int a, double b)
	{
		_a = a;
		_b = b;
	}

	auto alpha() @property
	{
		return _a;
	}

	auto beta() @property
	{
		return _b;
	}
}

struct B
{
	A one;
	A two;

	this(ParameterTypeTuple!A inputOne, ParameterTypeTuple!A inputTwo)
	{
		one = A(inputOne);
		two = A(inputTwo);
	}
}


void main()
{
	auto join = B(1, 3.2, 5, 6.9);
	writeln(join.one.alpha, \t, join.one.beta);
	writeln(join.two.alpha, \t, join.two.beta);
}


Re: Singleton Pattern with struct

2013-01-24 Thread Maxim Fomin

On Thursday, 24 January 2013 at 17:00:44 UTC, Ali Çehreli wrote:

On 01/24/2013 08:52 AM, ParticlePeter wrote:

 This method here ( my first approach ) does return a
reference to an
 object on the heap, right ?

Yes, but the caller does not get a reference.


Actually the caller gets the reference (which is a pointer from 
low-level POV), but allocates on stack struct object, and then 
does copy from returned reference to that stack object.



 static ref Singleton instance() {
 if ( s is null )
 s = new Singleton( 0 ) ;
 return * s ;
 }

 so when I use it with:
 auto another_s = Singleton.instance ;

 Why is the s inside the struct and another_s not identical ?
 Afaik that is the purpose of the ref keyword ?

When you print the type of another_s you will see that it is 
not a ref, because unlike C++, D does not have local ref 
variables; it has pointers for that purpose.




Yes, that the point - D does not have references like C++. And I 
should thought about C++ influence on understanding D :)



import std.stdio;

ref int foo()
{
return *new int;
}

void main()
{
auto i = foo();
writeln(typeid(i));
}

Prints 'int', not 'ref int'. So, i is a copy of the dynamically 
created int.


Ali




Re: Singleton Pattern with struct

2013-01-24 Thread Artur Skawina
On 01/24/13 17:52, ParticlePeter wrote:
 Yes, but this can be broken by:

 import core.stdc.stdio : printf;

 struct Singleton  {

 private :
 this( int a = 0 ) {} ;
 static Singleton * s ;

 public :
 @disable this() ;
 static Singleton* instance()  {
 if ( s is null )
 s = new Singleton(0) ;
 return s ;
 }

 int val = 0 ;
 }

 void main()
 {
 Singleton s = * Singleton.instance;
 printf( %d\n, s.val ) ; //
 Singleton.instance.val = 2 ;
 printf( %d\n, s.val ) ; //0
 }

 Here s is explicitly defined to be a struct object, not pointer (reference), 
 so main.s is independent of further modification of Singleton.instance.
 
 O.k. good to know, I'll try to avoid this. But one thing is still not clear,
 This method here ( my first approach ) does return a reference to an object 
 on the heap, right ?
 
 static ref Singleton instance()  {
 if ( s is null )
 s = new Singleton( 0 ) ;
 return * s ;
 }
 
 so when I use it with:
 auto another_s = Singleton.instance ;
 
 Why is the s inside the struct and another_s not identical ?
 Afaik that is the purpose of the ref keyword ?

There currently are no reference variables in D [1]; the only way to get
a reference to something is via function arguments (including implicit
method ones) and function returns. So assigning a ref-return means a copy.

You can workaround it like this:

struct Singleton  {
private:
this( int a = 0 ) {} ;
static Singleton* s ;

public:
@disable this();
@disable this(this);
static instance() @property {
static struct Ref(T) { T* obj; ref g() @property { return *obj; } alias 
obj this; @disable this(this); }
if ( s is null )
s = new Singleton( 0 ) ;
return Ref!(typeof(this))(s) ;
}

int val = 0 ;
}

though, that's not how I'd do it.

artur

[1] Classes don't count; they are a reference /types/.


Re: Getting the parameters of a struct/class constructor

2013-01-24 Thread Andrej Mitrovic
On 1/24/13, Andrej Mitrovic andrej.mitrov...@gmail.com wrote:
 On 1/24/13, Joseph Rushton Wakeling joseph.wakel...@webdrake.net wrote:
  ParameterTypeTuple!(A.this)

 Use ParameterTypeTuple!(A.__ctor)


If you have multiple constructors you can pick the parameters with a
helper template:

import std.traits, std.string;

struct A
{
this(int a, double b)
{
}

this(float y)
{
}
}

template PickCtorParams(Type, size_t index)
{
enum ctorLen = __traits(getOverloads, Type, __ctor).length;
static if (index  ctorLen)
{
alias ParameterTypeTuple!(__traits(getOverloads, A,
__ctor)[index]) PickCtorParams;
}
else
{
static assert(0,
format(index %s exceeds %s ctors for type %s, index,
ctorLen, Type.stringof));
}
}

void main()
{
pragma(msg, PickCtorParams!(A, 0));  // (int, double)
pragma(msg, PickCtorParams!(A, 1));  // (float)
pragma(msg, PickCtorParams!(A, 2));  // out of bounds
}


Re: Singleton Pattern with struct

2013-01-24 Thread Artur Skawina
On 01/24/13 18:14, Artur Skawina wrote:
 struct Singleton  {
 private:
 this( int a = 0 ) {} ;
 static Singleton* s ;
 
 public:
 @disable this();
 @disable this(this);
 static instance() @property {
 static struct Ref(T) { T* obj; ref g() @property { return *obj; } 
 alias obj this; @disable this(this); }
 if ( s is null )
 s = new Singleton( 0 ) ;
 return Ref!(typeof(this))(s) ;
 }
 
 int val = 0 ;
 }

Grr. What I meant to write was of course:

 static struct Ref(T) { T* obj; ref g() @property { return *obj; } alias g 
this; @disable this(this); }

Sorry,

artur


Re: Singleton Pattern with struct

2013-01-24 Thread ParticlePeter

On Thursday, 24 January 2013 at 17:00:44 UTC, Ali Çehreli wrote:

On 01/24/2013 08:52 AM, ParticlePeter wrote:

 This method here ( my first approach ) does return a
reference to an
 object on the heap, right ?

Yes, but the caller does not get a reference.

 static ref Singleton instance() {
 if ( s is null )
 s = new Singleton( 0 ) ;
 return * s ;
 }

 so when I use it with:
 auto another_s = Singleton.instance ;

 Why is the s inside the struct and another_s not identical ?
 Afaik that is the purpose of the ref keyword ?

When you print the type of another_s you will see that it is 
not a ref, because unlike C++, D does not have local ref 
variables; it has pointers for that purpose.


import std.stdio;

ref int foo()
{
return *new int;
}

void main()
{
auto i = foo();
writeln(typeid(i));
}

Prints 'int', not 'ref int'. So, i is a copy of the dynamically 
created int.


Ali


Thanks, I re-read the purpose of ref type function() in the D 
programming language, and the sole purpose is that such a 
function call can be directly a parameter to another function 
expecting a ref ? As:


ref int foo()  {  return some class member ;  }
void bar( ref int data )  {  do something with data ;  }

This means, it is never ever possible to initialize any variable 
with a reference some class/struct member data ? Unless I return 
the address of the member data ?





Re: Getting the parameters of a struct/class constructor

2013-01-24 Thread Joseph Rushton Wakeling

On 01/24/2013 06:14 PM, Andrej Mitrovic wrote:

On 1/24/13, Joseph Rushton Wakeling joseph.wakel...@webdrake.net wrote:

  ParameterTypeTuple!(A.this)


Use ParameterTypeTuple!(A.__ctor)


Brilliant.  Thanks very much. :-)



Re: Singleton Pattern with struct

2013-01-24 Thread ParticlePeter

On Thursday, 24 January 2013 at 17:21:38 UTC, Artur Skawina wrote:

On 01/24/13 17:52, ParticlePeter wrote:

Yes, but this can be broken by:

import core.stdc.stdio : printf;

struct Singleton  {

private :
this( int a = 0 ) {} ;
static Singleton * s ;

public :
@disable this() ;
static Singleton* instance()  {
if ( s is null )
s = new Singleton(0) ;
return s ;
}

int val = 0 ;
}

void main()
{
Singleton s = * Singleton.instance;
printf( %d\n, s.val ) ; //
Singleton.instance.val = 2 ;
printf( %d\n, s.val ) ; //0
}

Here s is explicitly defined to be a struct object, not 
pointer (reference), so main.s is independent of further 
modification of Singleton.instance.


O.k. good to know, I'll try to avoid this. But one thing is 
still not clear,
This method here ( my first approach ) does return a reference 
to an object on the heap, right ?


static ref Singleton instance()  {
if ( s is null )
s = new Singleton( 0 ) ;
return * s ;
}

so when I use it with:
auto another_s = Singleton.instance ;

Why is the s inside the struct and another_s not identical ?
Afaik that is the purpose of the ref keyword ?


There currently are no reference variables in D [1]; the only 
way to get
a reference to something is via function arguments (including 
implicit
method ones) and function returns. So assigning a ref-return 
means a copy.


You can workaround it like this:

struct Singleton  {
private:
this( int a = 0 ) {} ;
static Singleton* s ;

public:
@disable this();
@disable this(this);
static instance() @property {
static struct Ref(T) { T* obj; ref g() @property { 
return *obj; } alias obj this; @disable this(this); }

if ( s is null )
s = new Singleton( 0 ) ;
return Ref!(typeof(this))(s) ;
}

int val = 0 ;
}

though, that's not how I'd do it.

artur

[1] Classes don't count; they are a reference /types/.


Well ... I think I as well would not wanna do it like this, 
thanks :-)
I'm fine with returning and using a pointer, fortunately there is 
no difference in syntax as in c, so it doesn't matter.




Re: Singleton Pattern with struct

2013-01-24 Thread Ali Çehreli

On 01/24/2013 09:26 AM, ParticlePeter wrote:

 Thanks, I re-read the purpose of ref type function() in the D
 programming language, and the sole purpose is that such a function call
 can be directly a parameter to another function expecting a ref ?

As Maxim Fomin noted, I didn't word it correctly: The caller does get a 
reference to the returned object.


So, the sole purpose is not to pass a variable to a ref-taking function.

 As:

 ref int foo() { return some class member ; }
 void bar( ref int data ) { do something with data ; }

 This means, it is never ever possible to initialize any variable with a
 reference some class/struct member data ? Unless I return the address of
 the member data ?

Not true. There are no local ref variables nor ref member variables in 
D. All you need to do is to use pointers instead:


ref int foo()
{
return *new int;
}

struct S
{
int i;
int * j;

this(int i)
{
this.i = i;
this.j = foo();  // member pointer
}
}

void main()
{
int* i = foo();  // local pointer
}

No, the pointer syntax is not the cleanest. :)

Ali



Re: Singleton Pattern with struct

2013-01-24 Thread Artur Skawina
On 01/24/13 18:35, ParticlePeter wrote:
 On Thursday, 24 January 2013 at 17:21:38 UTC, Artur Skawina wrote:
 On 01/24/13 17:52, ParticlePeter wrote:
 Why is the s inside the struct and another_s not identical ?
 Afaik that is the purpose of the ref keyword ?

 There currently are no reference variables in D [1]; the only way to get
 a reference to something is via function arguments (including implicit
 method ones) and function returns. So assigning a ref-return means a copy.

 You can workaround it like this:

 struct Singleton  {
 private:
 this( int a = 0 ) {} ;
 static Singleton* s ;

 public:
 @disable this();
 @disable this(this);
 static instance() @property {
 static struct Ref(T) { T* obj; ref g() @property { return *obj; } 
 alias g this; @disable this(this); }
 if ( s is null )
 s = new Singleton( 0 ) ;
 return Ref!(typeof(this))(s) ;
 }

 int val = 0 ;
 }

 Well ... I think I as well would not wanna do it like this, thanks :-)
 I'm fine with returning and using a pointer, fortunately there is no 
 difference in syntax as in c, so it doesn't matter.

Careful, at some point you'll end up doing s[1] etc, and /then/ it matters.
The Ref struct is actually the way to deal with ref types in D; what I meant
by 'that's not how I'd do it' is that it might be better to use a global
(well, thread-local module-field in D) etc.

artur


Re: Why is null lowercase?

2013-01-24 Thread Ali Çehreli

On 01/24/2013 04:56 AM, Matthew Caron wrote:

This is probably a question for Walter, but maybe others know.

Of all of the differences between C and D, the one which I have the most
difficulty adapting to is null being lowercase. Does anyone know why
this decision was made?


Similarly, the common macros TRUE and FALSE are replaced by the 'true' 
and 'false' keywords.


Ali


Re: Getting the parameters of a struct/class constructor

2013-01-24 Thread Rob T
There may be more than one this, so you'll have to specify the 
args for each specific constructor manually.


Disclaimer: Someone else may have a better solution as I'm not 
that much of an expert in this area.


This sample may point you in the right direction ...

import std.typetuple;

struct X
{
alias TypeTuple!(int, double) CONSTUCT1;
alias TypeTuple!(int, double, string) CONSTUCT2;

this( CONSTUCT1 args )
{
alias args[0] a_int;
alias args[0] a_double;

_a = a_int;
_b = b_double;

}

this( CONSTUCT2[0] a_int, CONSTUCT2[1] b_double, CONSTUCT2[2] 
c_string  )

{

_a = a_int;
_b = b_double;
writeln(c_string);
}

int _a;
double _b;

}


void foo(X.CONSTUCT1[0] a, X.CONSTUCT1[1] b )
{

  ...

}

void bar(X.CONSTUCT2 args )
{

   alias args[0] a_int;
   alias args[1] a_double;
   alias args[2] a_string;
  ...

}

Hope this helps.

--rt


Re: Singleton Pattern with struct

2013-01-24 Thread ParticlePeter

On Thursday, 24 January 2013 at 17:35:58 UTC, Ali Çehreli wrote:

On 01/24/2013 09:26 AM, ParticlePeter wrote:

 Thanks, I re-read the purpose of ref type function() in the D
 programming language, and the sole purpose is that such a
function call
 can be directly a parameter to another function expecting a
ref ?

As Maxim Fomin noted, I didn't word it correctly: The caller 
does get a reference to the returned object.


So, the sole purpose is not to pass a variable to a ref-taking 
function.


 As:

 ref int foo() { return some class member ; }
 void bar( ref int data ) { do something with data ; }

 This means, it is never ever possible to initialize any
variable with a
 reference some class/struct member data ? Unless I return the
address of
 the member data ?

Not true. There are no local ref variables nor ref member 
variables in D. All you need to do is to use pointers instead:


ref int foo()
{
return *new int;
}

struct S
{
int i;
int * j;

this(int i)
{
this.i = i;
this.j = foo();  // member pointer
}
}

void main()
{
int* i = foo();  // local pointer
}

No, the pointer syntax is not the cleanest. :)

Ali


This is what I meant :-) I can't return a reference ( with 
reference I don't mean reference type, but semantically a 
reference ) to a class member, but I can return the address of 
this member, which, to my understanding is an implicit pointer.


struct Foo  {
int val = 3 ;
auto getValPtr()  {  return  val ;  }
}

Foo foo ;
writeln( foo.val ) ; // = 3
auto valPtr = foo.getValPtr() ;
* valPtr  = 7 ;
writeln( foo.val ) ; // = 7



Re: Singleton Pattern with struct

2013-01-24 Thread Era Scarecrow

On Thursday, 24 January 2013 at 16:49:53 UTC, Maxim Fomin wrote:
On Thursday, 24 January 2013 at 16:17:34 UTC, Era Scarecrow 
wrote:
Hmmm. You could separate the data and remove the pointer... 
then use alias this.


[code]
 struct Singleton {
   static SingletonData single;
   alias single this;
   @disable this(this);
   //disable copy/assignment? Not that it would matter...
   //copying nothing does nothing, as there's nothing here.

   private static struct SingletonData {
 //methods and data here.
   }
[/code]


I agree, but disabling ctors makes creating module-level object 
tricky. Static struct initialization might help.


 I'll have to agree. But in that case don't disable the default 
ctor (not that the Singleton has any contents anyways); Actually 
opAssign/postblit only needs to be disabled inside SingletonData. 
I'd think that would work.


[code]
  struct Singleton {
static SingletonData single;
alias single this;

private static struct SingletonData {
  @disable void opAssign();
  //methods and data here.
}
  }
[/code]


Re: Getting the parameters of a struct/class constructor

2013-01-24 Thread mist
You can use magic functions __ctor and __dtor which actually 
serve as constructor and destructor implementations behind the 
scene.


Example and proof-of-concept: http://dpaste.1azy.net/fd924332

Have no idea if it is explicitly defined by spec somewhere though.


Re: Assembly - 64-bit registers supported?

2013-01-24 Thread Mike Wey

On 01/24/2013 01:08 AM, dale wrote:

I am following these helpful suggestions, but still having trouble
linking properly. I have Visual Studio 10 and its 64-bit extension
installed, and I believe the amd64\link.exe is getting called, but I
must have something configured incorrectly, because it does not appear
to find all of the libraries correctly.

C:\prj\Ddmd -m64 hello64B.d

C:\d\dmd2\windows\bin\..\lib\shell32.lib : warning LNK4003: invalid
library format; library ignored
C:\d\dmd2\windows\bin\..\lib\kernel32.lib : warning LNK4003: invalid
library format; library ignored
phobos64.lib(dmain2_4a8_47b.obj) : error LNK2019: unresolved external
symbol GetCommandLineW referenced in function _d_run_main
phobos64.lib(dmain2_4a8_47b.obj) : error LNK2019: unresolved external
symbol CommandLineToArgvW referenced in function _d_run_main
...

And zillions more unresolved externals follow.

Why is it trying to include shell32.lib and kernel32.lib for a 64-bit
app? Is that a problem?

Any hints as to what I'm missing?

Thanks,
dale


I think this has come up before, and it has something to do with some 
environment variables set in sc.ini and the MS linker picking up the 
libs supplied be dmd for win32 because of it.


--
Mike Wey


Re: endless loop with ref and non-ref parameter

2013-01-24 Thread Jonathan M Davis
On Thursday, January 24, 2013 18:24:32 Namespace wrote:
 In relation to this post:
 http://forum.dlang.org/thread/hlyospppnjiziyokf...@forum.dlang.org?page=2#po
 st-qxqvreqpniftjnwxvqgt:40forum.dlang.org
 
 I dicided to test a bit with manual auto ref.
 This Code works as expected.
 
 [code]
 import std.stdio;
 
 struct A {
 public:
 
 }
 
 void foo(A a) {
 writeln(without ref);
 foo(a);
 }
 
 void foo(ref A a) {
 writeln(with ref);
 }
 
 void main() {
 foo(A());
 }
 [/code]
 
 it prints:
 without ref
 with ref
 
 but if I change
 ref A a
 to
 ref const A a
 
 it turns into an endless loop.
 
 My question is:
 Is this behavior intended?
 I know const is part of the type, but shouldn't recognize the
 compiler this case?

It's intended. constness matters more than refness when selecting a function 
overload. From the docs ( http://dlang.org/function.html#ufunction/u-
overloading ):

-
Func­tions are over­loaded based on how well the ar­gu­ments to a func­tion 
can match up with the pa­ra­me­ters. The func­tion with the best match is se­
lected. The lev­els of match­ing are: 

no match
match with im­plicit con­ver­sions
match with con­ver­sion to const
exact match
-

So, you need to put const on the parameters for both functions, or you need to 
create other overloads which do. In general, if you're overloading on ref, 
make sure that the constness matches, or you're going to get infinite 
recursion. So, if you're mixing const and ref, then you're probably either 
going to want 4 different overloads (non-ref, ref, const non-ref, const ref) or 
2 overloads which use inout instead of const (inout and inout ref).

- Jonathan M Davis


Re: endless loop with ref and non-ref parameter

2013-01-24 Thread Ali Çehreli

On 01/24/2013 11:33 AM, Jonathan M Davis wrote:

 It's intended. constness matters more than refness when selecting a 
function

 overload. From the docs ( http://dlang.org/function.html#ufunction/u-
 overloading ):

 -
 Functions are overloaded based on how well the arguments to a function
 can match up with the parameters. The function with the best match is se
 lected. The levels of matching are:

 no match
 match with implicit conversions
 match with conversion to const
 exact match
 -

That doesn't explain why the first case selects the ref function:

void foo(A a) {
writeln(without ref);
foo(a);// -- why is this foo(ref A)?
}

void foo(ref A a) {
writeln(with ref);
}

foo(A) is the exact match there because the type of a is A.

What is also considered in function selection is the rvalue-lvalue 
distinction, which shouldn't affect the outcome here either.


Ali



Re: endless loop with ref and non-ref parameter

2013-01-24 Thread Era Scarecrow

On Thursday, 24 January 2013 at 20:06:34 UTC, Ali Çehreli wrote:

On 01/24/2013 11:33 AM, Jonathan M Davis wrote:

It's intended. constness matters more than refness when 
selecting a function overload. From the docs ( 
http://dlang.org/function.html#ufunction/u-overloading ):


-
Functions are overloaded based on how well the arguments to a 
function can match up with the parameters. The function with 
the best match is selected. The levels of matching are:



no match
match with implicit conversions
match with conversion to const
exact match
-


That doesn't explain why the first case selects the ref 
function:


void foo(A a) {
writeln(without ref);
foo(a);// -- why is this foo(ref A)?
}


 Because your local variable (in the signature) becomes a lvalue 
and thereby reference-able.




void foo(ref A a) {
writeln(with ref);
}

foo(A) is the exact match there because the type of a is A.


What is also considered in function selection is the 
rvalue-lvalue distinction, which shouldn't affect the outcome 
here either.


 In case David's explanation was too confusing, then let's look 
at it. If your variable is non-const, it will always select a 
non-const matching one first. If there is no matching non-const, 
it converts it to const, then tries again.


  void foo(A a) {
writeln(without ref);
//a is an lvalue but not const
//Foo(A) matches closer. Infinite loop
foo(a);
  }

  void foo(const ref A a) {
writeln(with ref);
  }

  void foo2(A a) {
writeln(foo2 - without ref);
//const lvalue, foo(const ref A) is closer
foo(cast(const A) a)

//rvalue, postblit call foo(A) (if it can)
foo(cast(const A) A());
  }


 I know this very issue seems like a big annoyance, to me too. 
I'd say the order of preference should be const ref, const 
non-ref, ref, non-ref. But then you can't have const  non const 
versions unless the signature differs, like ref, more input 
variables or the function itself is const.


 Until/unless that is changed all 4 versions need to be written 
(as David said) to make the proper calls.


Re: Why is null lowercase?

2013-01-24 Thread Matthew Caron

On 01/24/2013 12:50 PM, Ali Çehreli wrote:

Similarly, the common macros TRUE and FALSE are replaced by the 'true'
and 'false' keywords.


Ironically, those don't bother me because I never used them.

--
Matthew Caron, Software Build Engineer
Sixnet, a Red Lion business | www.sixnet.com
+1 (518) 877-5173 x138 office


Re: Why is null lowercase?

2013-01-24 Thread Matthew Caron

On 01/24/2013 12:04 PM, Rob T wrote:

You'll get used to it, it's actually much better than typing in NULL,
and it's a real type instead on an int, which never worked well in C.

Just be warned that when checking for null *do not* use equality operator


Yeah, the compiler helped me find that one out. That takes a little 
getting used to as well. Old habits and such.



for not null checks

if ( ptr !is null) ...


And too much perl has me wanting to write:

if (ptr is not null)


BTW, half of what you thought worked well in C/C++ will get turned
upside down if you stick with D, and once you get it, moving back to
C/C++ becomes unbearable.


It already is. I have very little desire to do anything in any other 
language. C and C++ are too primitive. Java and C# don't play as nicely 
with native libraries as I'd like and require a whole VM which consumes 
gobs of memory and takes forever to start. D gives me the features I 
want from Java and C# while falling somewhere between them and C in 
terms of speed. I can get more done, faster, in D.


Meanwhile, it seems like the rest of the world is moving towards writing 
everything in JavaScript, and that's just leaving me scratching my head 
in amazement.

--
Matthew Caron, Software Build Engineer
Sixnet, a Red Lion business | www.sixnet.com
+1 (518) 877-5173 x138 office


Re: endless loop with ref and non-ref parameter

2013-01-24 Thread Jonathan M Davis
On Thursday, January 24, 2013 12:06:33 Ali Çehreli wrote:
 On 01/24/2013 11:33 AM, Jonathan M Davis wrote:
  It's intended. constness matters more than refness when selecting a
 
 function
 
  overload. From the docs ( http://dlang.org/function.html#ufunction/u-
  overloading ):
  
  -
  Functions are overloaded based on how well the arguments to a function
  can match up with the parameters. The function with the best match is se
  lected. The levels of matching are:
  
  no match
  match with implicit conversions
  match with conversion to const
  exact match
  -
 
 That doesn't explain why the first case selects the ref function:
 
 void foo(A a) {
 writeln(without ref);
 foo(a); // -- why is this foo(ref A)?
 }
 
 void foo(ref A a) {
 writeln(with ref);
 }
 
 foo(A) is the exact match there because the type of a is A.
 
 What is also considered in function selection is the rvalue-lvalue
 distinction, which shouldn't affect the outcome here either.

Whether an argument is an lvalue or rvalue is very important to the issue. 
That's _exactly_ why the ref overload gets called in the first case. If the 
argument is an lvalue, the ref overload is selected. If the argument is an 
rvalue, the non-ref overload is selected. const only enters into it _after_ 
that.

- Jonathan M Davis


Re: endless loop with ref and non-ref parameter

2013-01-24 Thread Maxim Fomin

On Thursday, 24 January 2013 at 20:06:34 UTC, Ali Çehreli wrote:

On 01/24/2013 11:33 AM, Jonathan M Davis wrote:

 It's intended. constness matters more than refness when
selecting a function
 overload. From the docs (
http://dlang.org/function.html#ufunction/u-
 overloading ):

 -
 Functions are overloaded based on how well the arguments to a
function
 can match up with the parameters. The function with the best
match is se
 lected. The levels of matching are:

 no match
 match with implicit conversions
 match with conversion to const
 exact match
 -

That doesn't explain why the first case selects the ref 
function:


void foo(A a) {
writeln(without ref);
foo(a);// -- why is this foo(ref A)?
}

void foo(ref A a) {
writeln(with ref);
}

foo(A) is the exact match there because the type of a is A.

What is also considered in function selection is the 
rvalue-lvalue distinction, which shouldn't affect the outcome 
here either.


Ali


From http://dlang.org/function.html

If two or more functions have the same match level, then partial 
ordering is used to try to find the best match. Partial ordering 
finds the most specialized function. If neither function is more 
specialized than the other, then it is an ambiguity error. 
Partial ordering is determined for functions f() and g() by 
taking the parameter types of f(), constructing a list of 
arguments by taking the default values of those types, and 
attempting to match them against g(). If it succeeds, then g() is 
at least as specialized as f().


It is possible to pass an lvalue to both ref and non-ref 
parameters, however rvalue cannot be passed to ref-parameter. 
Hence ref version for lvalue is more specialized and selected.


Re: Getting the parameters of a struct/class constructor

2013-01-24 Thread Rob T

On Thursday, 24 January 2013 at 18:41:31 UTC, mist wrote:
You can use magic functions __ctor and __dtor which actually 
serve as constructor and destructor implementations behind the 
scene.


Example and proof-of-concept: http://dpaste.1azy.net/fd924332

Have no idea if it is explicitly defined by spec somewhere 
though.


If you have more than one ctor it seems to take the first one

http://dpaste.1azy.net/b994fdf3

I don't know if you will able to rely on the order unless it's a 
part of the spec.


--rt


Re: Segfault in _d_dynamic_cast ()

2013-01-24 Thread Minas Mina

On Thursday, 24 January 2013 at 13:22:20 UTC, Maxim Fomin wrote:

On Thursday, 24 January 2013 at 10:14:29 UTC, Minas Mina wrote:
I am trying to create a BVH tree structure to speed up 
raytracing. So far it has been fine. I have created the BVH 
tree. It works for 202 triangles/spheres.


skipped

Thanks.


Requests for debugging help without source code are likely to 
be buried in archives silently. Perhaps you can look at 
_d_dynamic_cast source code 
(https://github.com/D-Programming-Language/druntime/blob/master/src/rt/cast_.d#L69) 
and figure out the exact statement which produces segfault.


The code can be found here:
https://github.com/minas1/D_Raytracing

The code that creates the BVH tree is in bvh.d.
The code that prints the tree is in main.d.


Re: Getting the parameters of a struct/class constructor

2013-01-24 Thread Philippe Sigaud
On Thu, Jan 24, 2013 at 10:34 PM, Rob T al...@ucora.com wrote:
 On Thursday, 24 January 2013 at 18:41:31 UTC, mist wrote:

 You can use magic functions __ctor and __dtor which actually serve as
 constructor and destructor implementations behind the scene.

 Example and proof-of-concept: http://dpaste.1azy.net/fd924332

 Have no idea if it is explicitly defined by spec somewhere though.


 If you have more than one ctor it seems to take the first one

 http://dpaste.1azy.net/b994fdf3

 I don't know if you will able to rely on the order unless it's a part of the
 spec.

IIRC, you can use __traits(getOverloads, mytype.__ctor) to get all
constructor overloads.
See:
http://dlang.org/traits.html#getOverloads

I used this in conjunction with __traits(getMember, ...) to get the
entire list of member, overloads included.


Re: Getting the parameters of a struct/class constructor

2013-01-24 Thread Andrej Mitrovic
On 1/24/13, Philippe Sigaud philippe.sig...@gmail.com wrote:
 IIRC, you can use __traits(getOverloads, mytype.__ctor) to get all
 constructor overloads.
 See:
 http://dlang.org/traits.html#getOverloads

 I used this in conjunction with __traits(getMember, ...) to get the
 entire list of member, overloads included.


I don't understand why, but it seems DForum doesn't show up any of my
posts. I've posted this as my second reply (hope this makes it):

If you have multiple constructors you can pick the parameters with a
helper template:

import std.traits, std.string;

struct A
{
this(int a, double b)
{
}

this(float y)
{
}
}

template PickCtorParams(Type, size_t index)
{
enum ctorLen = __traits(getOverloads, Type, __ctor).length;
static if (index  ctorLen)
{
alias ParameterTypeTuple!(__traits(getOverloads, A,
__ctor)[index]) PickCtorParams;
}
else
{
static assert(0,
format(index %s exceeds %s ctors for type %s, index,
ctorLen, Type.stringof));
}
}

void main()
{
pragma(msg, PickCtorParams!(A, 0));  // (int, double)
pragma(msg, PickCtorParams!(A, 1));  // (float)
pragma(msg, PickCtorParams!(A, 2));  // out of bounds
}


Re: Coping files and folders

2013-01-24 Thread Joel

Brilliant! Thanks.

I think the silent one has errors. But I've used the first 
function in my program now. With mine, strait after doing the 
copying is was supposed then update a file, but didn't. Your one 
seems to work though.


On Thursday, 24 January 2013 at 08:58:06 UTC, monarch_dodra wrote:
On Thursday, 24 January 2013 at 07:41:23 UTC, Jacob Carlborg 
wrote:

On 2013-01-24 07:28, Joel wrote:
How does one copy folders (with files in them) including sub 
folders,

and creating any needed folders?

Like:
land\house\cat.d
land\house\rat.exe
land\house\bedroom\ants.txt

to
root\island\house\cat.d
root\island\house\rat.exe
root\island\house\bedroom\ants.txt

One work around is to use 'system' (under std.process).


I don't think Phobos currently has any functions for this. 
Someone posted code in these newsgroups of a parallel 
implementation of copy and remove.


Mustn't be very hard to manually write copyDir.

The problem with copyDir is its transactional behavior: What 
should it do in case of a failure mid copy? Bail? Cleanup? 
Continue?


Anyways, I just threw this together. The first version bails on 
first error.
The second version keeps going as much as it can, and returns 
true on success.


The caller is then free to (or not to) call rmdirRecurse in 
case of failure.


//Throws exception on first error.
void copyDir(string inDir, string outDir)
{
if (!exists(outDir))
mkdir(outDir);
else
if (!isDir(outDir))
throw new FileException(format(Destination path %s 
is not a folder., outDir));


foreach (entry; dirEntries(inDir.idup, SpanMode.shallow))
{
auto fileName = baseName(entry.name);
auto destName = buildPath(outDir, fileName);
if (entry.isDir())
copyDir(entry.name, destName);
else
copy(entry.name, destName);
}
}

//Silently keeps going as much as it can, then returns true on 
success,

//or false if an error occured.
bool copyDirSilent(string inDir, string outDir)
{
if (!exists(outDir))
{
auto e = collectException(mkdir(outDir));
if (e !is null)
return false;
}
else
if (!isDir(outDir))
return false;

foreach (entry; dirEntries(inDir, SpanMode.shallow))
{
auto fileName = baseName(entry.name);
auto destName = buildPath(outDir, fileName);
if (entry.isDir())
{
bool b = copyDirSilent(entry.name, destName);
if (b == false)
return false;
}
else
{
auto e = collectException(mkdir(outDir));
if (e !is null)
return false;
}
}
return true;
}




Re: Getting the parameters of a struct/class constructor

2013-01-24 Thread Rob T
On Thursday, 24 January 2013 at 22:49:33 UTC, Andrej Mitrovic 
wrote:

On 1/24/13, Philippe Sigaud philippe.sig...@gmail.com wrote:
IIRC, you can use __traits(getOverloads, mytype.__ctor) to get 
all

constructor overloads.
See:
http://dlang.org/traits.html#getOverloads

I used this in conjunction with __traits(getMember, ...) to 
get the

entire list of member, overloads included.



I don't understand why, but it seems DForum doesn't show up any 
of my

posts. I've posted this as my second reply (hope this makes it):



The thread got split up into two separate threads. Your missing 
post shows up in the split. I really hate it when it does this.


--rt


Re: endless loop with ref and non-ref parameter

2013-01-24 Thread Ali Çehreli

On 01/24/2013 12:25 PM, Era Scarecrow wrote:

 What is also considered in function selection is the rvalue-lvalue
 distinction, which shouldn't affect the outcome here either.

 In case David's explanation was too confusing, then let's look at it. If
 your variable is non-const, it will always select a non-const matching
 one first. If there is no matching non-const, it converts it to const,
 then tries again.

 void foo(A a) {
 writeln(without ref);
 //a is an lvalue but not const
 //Foo(A) matches closer. Infinite loop

And that's exactly why this issue is so confusing.

Normally, const vs. immutable parameters are different in the way that 
they accept arguments:


- immutable is limiting because it insists that the argument is immutable.

- const is welcoming because it accepts mutable, const, and immutable.

However, according to your example and explanation above, in this case 
const is not welcoming but limiting! What the example shows is that, 
because the following function takes 'const ref A', now it wants 
'const A' but not 'A'. See, how in this case 'const' is not welcoming?


That is the problem in this whole confusing situation.

If there is another explanation that would bring sanity to the way I see 
things, I would love to hear about it. Does my understanging above 
regarding limiting vs. welcoming off? Perhaps that's where I go wrong?


 foo(a);
 }

 void foo(const ref A a) {
 writeln(with ref);
 }

 void foo2(A a) {
 writeln(foo2 - without ref);
 //const lvalue, foo(const ref A) is closer
 foo(cast(const A) a)

 //rvalue, postblit call foo(A) (if it can)
 foo(cast(const A) A());
 }

Ali



Re: Why is null lowercase?

2013-01-24 Thread Ali Çehreli

On 01/24/2013 12:42 PM, Matthew Caron wrote:

 for not null checks

 if ( ptr !is null) ...

 And too much perl has me wanting to write:

 if (ptr is not null)

IIRC, the !is operator is thanks to bearophile. We would have to reverse 
the logic before he insisted on !is: :)


if (!(ptr is null))

Ali



Re: S-Expressions

2013-01-24 Thread bearophile

qznc:


We're even now ;)

http://rosettacode.org/wiki/Rosetta_Code/Rank_languages_by_popularity#D


I have cut some lines, and I have used a more functional style, 
that fits well for this entry. Compared to the C++ entry this D 
entry is nicer.


I greatly prefer the verbose option of the Python regex. And 
g for regexes should be the default.



This D code:

auto pairs = categories.match(r2)
 .filter!(m = languages.canFind(m[1]))()
 .map!(m = tuple(m[2].to!uint(), m[1].dup))()
 .array();

With a Python-like syntax becomes nicer:

auto pairs = [(r.to!uint, l.dup) for l,r in
  categories.match(r2)
  if l in languages];

Bye,
bearophile


Re: endless loop with ref and non-ref parameter

2013-01-24 Thread Jonathan M Davis
On Thursday, January 24, 2013 17:13:36 Ali Çehreli wrote:
 On 01/24/2013 12:25 PM, Era Scarecrow wrote:
  What is also considered in function selection is the rvalue-lvalue
  distinction, which shouldn't affect the outcome here either.
  
  In case David's explanation was too confusing, then let's look at it. If
  your variable is non-const, it will always select a non-const matching
  one first. If there is no matching non-const, it converts it to const,
  then tries again.
  
  void foo(A a) {
  writeln(without ref);
  //a is an lvalue but not const
  //Foo(A) matches closer. Infinite loop
 
 And that's exactly why this issue is so confusing.
 
 Normally, const vs. immutable parameters are different in the way that
 they accept arguments:
 
 - immutable is limiting because it insists that the argument is immutable.
 
 - const is welcoming because it accepts mutable, const, and immutable.
 
 However, according to your example and explanation above, in this case
 const is not welcoming but limiting! What the example shows is that,
 because the following function takes 'const ref A', now it wants
 'const A' but not 'A'. See, how in this case 'const' is not welcoming?
 
 That is the problem in this whole confusing situation.
 
 If there is another explanation that would bring sanity to the way I see
 things, I would love to hear about it. Does my understanging above
 regarding limiting vs. welcoming off? Perhaps that's where I go wrong?

I've never heard anyone describe it that way before. const is more generic, 
whereas immutable is more specific. But from the compiler's point of view, 
passing a non-const object to a const function means doing a conversion (from 
mutable to const), whereas calling a function of the same type does not 
require a conversion. I believe that _that_ is the core of why ref takes 
precedence over const.

The overload rules avoid converting types as much as possible. So, if you have

auto foo(A a) {...} //#1
auto foo(const A a) {...} //#2

A a;
const A ca;
foo(a); //calls #1
foo(ca); //calls #2

The same goes with ref. When passing an lvalue, the ref requires no conversion 
or copy, whereas without ref, a copy is required. So,

auto foo(A a) {...} //#1 
auto foo(ref A a) {...} //#2

A a;
foo(a); //calls #2
foo(createA()); //calls #1

The question is what happens when you start mixing const and ref. You have to 
choose which has precedence. It's obvious what to do when you have all of the 
combinations

auto foo(A a) {...} //#1
auto foo(ref A) {...} #2
auto foo(const A) {...} //#3
auto foo(ref const A) {...} //#4

A a;
const A ca;
foo(a); //Calls #2
foo(ca); //Calls #4
foo(createA()); //Calls #1
foo(createConstA()); //Calls #3

The problem is what to do when you only have a subset:

auto foo(ref A) {...} #2
auto foo(const A) {...} //#3

A a;
const A ca;
foo(a); //Calls #2
foo(ca); //Calls #3
foo(createA()); //Calls #3
foo(createConstA()); //Calls #3

or

auto foo(A a) {...} //#1
auto foo(ref const A) {...} //#4

A a;
const A ca;
foo(a); //Calls #4
foo(ca); //Calls #4
foo(createA()); //Calls #1
foo(createConstA()); //Calls #1

or etc...

The compiler _has_ to pick either const or ref as having higher precedence. 
ref was almost certainly chosen as having higher precedence because it avoids 
a conversion, but also by picking ref, you end up with fewer unnecessary 
copies, making it the more efficient choice. So, from the standpoint of both 
type conversions and efficiency, it makes more sense for ref to have precedence 
over const than the other way around.

The reality of the matter is that regardless of whether const or ref had 
precedence, you'd still need all 4 overloads or you'd have problems. auto ref 
and inout can help reduce the number of overloads required, but the function 
needs to accept all of the type combinations in order to avoid having to 
convert the type or make unnecessary copies.

- Jonathan M Davis


From package import syntax

2013-01-24 Thread bearophile
This is the current syntax to import several modules from the std 
package:


import std.stdio, std.algorithm, std.range, std.array;


This is the syntax to import names from a module:

import std.stdio: writeln, write;


Currently this is not accepted, but do you like a syntax to 
import modules that is more consistent (the same as the one used 
to import names from a module)?


import std: stdio, algorithm, range, array;

Bye,
bearophile


Re: From package import syntax

2013-01-24 Thread Andrej Mitrovic
On 1/25/13, bearophile bearophileh...@lycos.com wrote:
 Currently this is not accepted, but do you like a syntax to
 import modules that is more consistent (the same as the one used
 to import names from a module)?

 import std: stdio, algorithm, range, array;

FWIW this was filed as an enhancement a few years ago:
http://d.puremagic.com/issues/show_bug.cgi?id=3603


Re: From package import syntax

2013-01-24 Thread bearophile

Andrej Mitrovic:


FWIW this was filed as an enhancement a few years ago:
http://d.puremagic.com/issues/show_bug.cgi?id=3603


Thank you. Commented and voted.

Bye,
bearophile


Re: endless loop with ref and non-ref parameter

2013-01-24 Thread Era Scarecrow
On Friday, 25 January 2013 at 01:57:02 UTC, Jonathan M Davis 
wrote:
The compiler _has_ to pick either const or ref as having higher 
precedence. ref was almost certainly chosen as having higher 
precedence because it avoids a conversion, but also by picking 
ref, you end up with fewer unnecessary copies, making it the 
more efficient choice. So, from the standpoint of both type 
conversions and efficiency, it makes more sense for ref to have 
precedence over const than the other way around.


The reality of the matter is that regardless of whether const 
or ref had precedence, you'd still need all 4 overloads or 
you'd have problems. auto ref and inout can help reduce the 
number of overloads required, but the function needs to accept 
all of the type combinations in order to avoid having to 
convert the type or make unnecessary copies.


 Personally that doesn't seem like it makes sense. I know it does 
logically, but at the same time it seems silly. If you have 
something as const, why do you need a non-const version?


 Example might be if you were to re-write strlen for C, you have 
a const version but no need for a non-const version as the data 
will never change.  Having multiple ones doing different behavior 
likely can only get confusing. Say we have the following.


  ///public interface
  int strlen(const char[] input);

  //no public/DDoc interface
  //does what the above does but also swaps upper/lower case
  int strlen(char[] input);

 Now when you change something from const to non-const the 
behavior changes drastically. Even if the Behavior didn't change, 
there shouldn't be a need for two versions of it for the same 
name in order for it to work.


 There's cases where I've tried to make use of only incorporating 
a few const/ref differences and yet it fails terribly unless I 
fill in the other two with unexpected behavior. I see a variable 
with 'const' and it's I declare 'this variable cannot be changed 
by me', where as for a function signature it's 'I promise (in 
good Faith) not to change this'. In these aspects the const 
should have equal footing as the non-const when determining which 
to call.


 Here's a older example although I'll have to redo it.

  struct S {
//move semantics as it's rvalue
void opAssign(S s);

//If lvalue, we only want to reference it and
//make manual updates to this one
void opAssign(const ref S s);
  }

 In this case the opAssign(S) would always be called unless you 
made the lvalue (or cast it) as const. This personally seems 
wrong. If const ref had the highest priority the issue goes away, 
although you cannot have a non-const ref otherwise with the same 
signature, but why would you need one? It seems to be causing 
more issues than it helps, kinda like multiple inheritance.


//with above if const ref was highest
void opAssign(ref S s); //error, opAssign(const ref S) trumps

 If auto ref does get accepted, then it will help alleviate some 
of the problems, but doesn't feel like all of them will be 
handled.


Re: endless loop with ref and non-ref parameter

2013-01-24 Thread Jonathan M Davis
On Friday, January 25, 2013 05:14:45 Era Scarecrow wrote:
 On Friday, 25 January 2013 at 01:57:02 UTC, Jonathan M Davis
 
 wrote:
  The compiler _has_ to pick either const or ref as having higher
  precedence. ref was almost certainly chosen as having higher
  precedence because it avoids a conversion, but also by picking
  ref, you end up with fewer unnecessary copies, making it the
  more efficient choice. So, from the standpoint of both type
  conversions and efficiency, it makes more sense for ref to have
  precedence over const than the other way around.
  
  The reality of the matter is that regardless of whether const
  or ref had precedence, you'd still need all 4 overloads or
  you'd have problems. auto ref and inout can help reduce the
  number of overloads required, but the function needs to accept
  all of the type combinations in order to avoid having to
  convert the type or make unnecessary copies.
 
   Personally that doesn't seem like it makes sense. I know it does
 logically, but at the same time it seems silly. If you have
 something as const, why do you need a non-const version?

With templated code, it can be important. But then again, if there's no point 
in having a non-const overload, you can simply not declare any overloads 
without const. You only run into problems when you mix const and non-const.

The compiler has to be able to deal with various combinations of const and ref 
regardless of what it actually makes sense to declare. The only way that I can 
think of to get rid of that problem is to make it illegal to declare both 
const and non-const overloads at the same time, which seems unnecessarily 
restrictive (especially with regards to generic code), even if it doesn't 
normally make sense to overload on const.

- Jonathan M Davis


Re: Coping files and folders

2013-01-24 Thread Jay Norwood
On Thursday, 24 January 2013 at 07:41:23 UTC, Jacob Carlborg 
wrote:


Someone posted code in these newsgroups of a parallel 
implementation of copy and remove.


I posted a parallel implementation a while back, and also put it 
on github.


The parallel trick is to create the folder structure first, then 
populate the folders with the files.  Best for ssd drives.


I also wrote a copy version that orders file sequence on disk 
efficiently, using write through, and posted it.  This speeds up 
any subsequent file system operations done in the directory order 
as if you have done a defrag. Great for hard drives, but not 
needed for ssd.


https://github.com/jnorwood


Re: endless loop with ref and non-ref parameter

2013-01-24 Thread Era Scarecrow
On Friday, 25 January 2013 at 04:26:18 UTC, Jonathan M Davis 
wrote:
With templated code, it can be important. But then again, if 
there's no point in having a non-const overload, you can simply 
not declare any overloads without const. You only run into 
problems when you mix const and non-const.


The compiler has to be able to deal with various combinations 
of const and ref regardless of what it actually makes sense to 
declare. The only way that I can think of to get rid of that 
problem is to make it illegal to declare both const and 
non-const overloads at the same time, which seems unnecessarily 
restrictive (especially with regards to generic code), even if 
it doesn't normally make sense to overload on const.


 True, but still it seems overtly annoying. I noticed most of 
this from TDPL. pg 257


[quote]
  The problem is that opAssign as defined expects a ref Widget, 
that is, an lvalue of type Widget. To accept assignment from 
rvalue in addition to lvalues, Widget must define two assignment 
operators:


  import std.algorithm;

  struct Widget {
private int[] array;
ref Widget opAssign(ref Widget rhs) {
  array = rhs.array.dup;
  return this;
}
ref Widget opAssign(Widget rhs) {
  swap(array, rhs.array);
  return this;
}
  }

 There's no more .dup in the version takint an rvalue. Why? Well 
the rvalue (with it's array in tow) is practically owned by the 
second opAssign: It was copied prior to entering the function and 
will be destroyed just before the function returns. This means 
there's no more need to duplicate rhs.array because nobody will 
miss it. Swapping rhs.array with this.array is enough. When 
opAssign returns, rhs goes away with this's old array, and this 
stays with rhs's old array--perfect conservation of state.


 We now could remove the first overload of opAssign altogether: 
The one taking rhs by value takes care of everything (lvalues are 
automatically converted to rvalues). But keeping the lvalue 
version allows for a useful optimization: instead of .duping the 
source, opAssign can check whether the current array has space 
for accommodating the new contents, in which case an overwrite is 
enough.

[/quote]

 The whole time I look at the example code, I can see how the ref 
Widget can be const and continue to work perfectly, but the 
non-ref cannot be const (without ugly unsafe casting). But if you 
try to pass const data to opAssign it will either try to copy it 
(if it's POD or postblit it), or fail outright. In my mind I 
shouldn't have to double the functions to have it 'do the right 
thing', even if it's just to forward them. This is not a case 
where 'auto ref' could help, as lvalue/rvalue distinction needs 
to be kept.


Re: endless loop with ref and non-ref parameter

2013-01-24 Thread Jonathan M Davis
On Thursday, January 24, 2013 21:38:42 Ali Çehreli wrote:
 If const really requires a conversion then we have a language design
 problem here.

No. const T is _not_ the same type as T, therefore assigning a T to a const T 
_is_ a type conversion. _Any_ time that a variable of one type is assigned to 
a variable of another type is a conversion regardless of the types involved. 
True, the bits of the object won't have changed when converting from T to 
const T (assuming that no alias this has been declared for the conversion 
anyway), but it's still a type conversion.

   So, if you have
 
 [...]
 
 These examples are great but as I said, they don't help the programmer
 at function signature stage.
 
 immutable is easy: If I am going to need immutable data, then I make the
 parameter immutable.
 
 By-value is also understandable: I don't care about the original.
 Additionally, when a 'ref' overload exists, by-value gives me the chance
 to move because only the rvalue can be bound to by-value. Pretty
 indirect way of thinking but we can deal with it...
 
 const should be easy as well: I am not going to modify. Just like in
 C++... Unfortunately that is not the case.

I don't see what could be done to make it simpler other than making it illegal 
to overload on constness or refness, which would cause other problems. When 
you're dealing with a variety of overloads, it's always going to get 
complicated on some level. Stuff like auto ref and inout help, but it's 
complicated by its very nature. Besides, the simple rule of making sure that 
either all of your overloads match in terms of constness or that you have 
overloads for both const and non-const parameters of matching refness solves 
the problem. And if you screw it up, it's obvious _very_ quickly, since it 
causes infinite recursion.

- Jonathan M Davis


Re: Coping files and folders

2013-01-24 Thread Joel

Sounds cool. I've bookmarked your github hub link.

Just wondering with this:

// parallel foreach for regular files
foreach(fn ; taskPool.parallel(files,100)) {
string dfn = destRoot ~ fn[srcLen..$];
copy(fn,dfn);
}

What is the 100 number for?

On Friday, 25 January 2013 at 05:30:11 UTC, Jay Norwood wrote:
On Thursday, 24 January 2013 at 07:41:23 UTC, Jacob Carlborg 
wrote:


Someone posted code in these newsgroups of a parallel 
implementation of copy and remove.


I posted a parallel implementation a while back, and also put 
it on github.


The parallel trick is to create the folder structure first, 
then populate the folders with the files.  Best for ssd drives.


I also wrote a copy version that orders file sequence on disk 
efficiently, using write through, and posted it.  This speeds 
up any subsequent file system operations done in the directory 
order as if you have done a defrag. Great for hard drives, but 
not needed for ssd.


https://github.com/jnorwood




Re: S-Expressions

2013-01-24 Thread qznc

On Friday, 25 January 2013 at 01:52:27 UTC, bearophile wrote:

qznc:


We're even now ;)

http://rosettacode.org/wiki/Rosetta_Code/Rank_languages_by_popularity#D


I have cut some lines, and I have used a more functional style, 
that fits well for this entry. Compared to the C++ entry this D 
entry is nicer.


I greatly prefer the verbose option of the Python regex. And 
g for regexes should be the default.



This D code:

auto pairs = categories.match(r2)
 .filter!(m = languages.canFind(m[1]))()
 .map!(m = tuple(m[2].to!uint(), m[1].dup))()
 .array();

With a Python-like syntax becomes nicer:

auto pairs = [(r.to!uint, l.dup) for l,r in
  categories.match(r2)
  if l in languages];



I completely agree. The functional style is better and I miss 
list comprehensions as well. It does not require new keywords, so 
maybe it can be added to D at some point.