Re: using enums as key in associative array

2011-03-08 Thread Wilfried Kirschenmann
 enum deviceType {cpu, gpu}
 auto execDeviceSuffix = [deviceType.cpu:.cpu, deviceType.gpu:.gpu];

 The way to get what you want to work in this case is to use a module
 constructor. So, you'd do something like this:

 string[deviceType] execDeviceSuffix;

 static this()
 {
        execDeviceSuffix[deviceType.cpu] = cpu;
        execDeviceSuffix[deviceType.gpu] = gpu;
 }

 The module constructor will be run before main does, so execDeviceSuffix will 
 be
 properly filled in by then.

I didn't get to the point where module constructors are introduced in
Andrei's book yet. I really like this idea !
I found a similar workaround which used an useless class so that I
could use the static constructor but this is even better !


Re: Access 'this' in inline assembly

2011-03-08 Thread bearophile
Brad Roberts:

It's not by design.  It's a quality of implementation issue that's solvable 
given some time to work on it.  I intend to, eventually, unless someone has 
gotten to it ahead of me.

Good, I am glad to be wrong then.

Currently in LDC you have two different ways to tell the compiler to inline 
some Asm. Such syntaxes are not present in D/DMD. So do you plan to add 
something like those two syntaxes to D/DMD too?

One of them is this pragma:
http://www.dsource.org/projects/ldc/wiki/Docs#allow_inline

int add(int a, int b) {
  pragma(allow_inline);
  asm { mov EAX, a; add EAX, b; }
}



And the other one is Inline asm expressions:
http://www.dsource.org/projects/ldc/wiki/InlineAsmExpressions

That are used like this:

// store val into dst
void store(ref int dst, int val) {
  __asm(ldw r4, $1 ; stw r4, $0, =*m,r,~{r4}, dst, val);
}

Bye,
bearophile


Re: Struct constructor and opCall confussion

2011-03-08 Thread bearophile
Tom:

 Am I missing something or is this another major bug?

A major bug (that is not recognized as major, I think).
I don't remember its number in bugzilla, sorry (anyone remembers it?).

See also:
http://d.puremagic.com/issues/show_bug.cgi?id=4053

Bye,
bearophile


Re: dmd gdc in archlinux

2011-03-08 Thread %u
== Quote from Jonathan M Davis (jmdavisp...@gmx.com)'s article
 On Monday, March 07, 2011 12:10:27 %u wrote:
  == Quote from Jonathan M Davis (jmdavisp...@gmx.com)'s article
 
   and add /path/to/unzipped/dmd2/linux/bin to your path.
 
  how can i add path ?
 Put it in the appropriate bashrc file - be it your personal .bashrc or
 /etc/bash.bashrc.local or whatever is appropriate for your system. On my Arch
 system, I believe that I put it in /etc/bash.bashrc.local. Regardless, you 
 add a
 line similar to this to your bashrc file:
 export PATH=$PATH:/path/to/unzipped/dmd2/linux/bin
 On my system, it's
 export PATH=$PATH:/home/jmdavis/dmd2/linux/bin
 - Jonathan M Davis

Jonathan M Davis you are the best

thanks



Re: using enums as key in associative array

2011-03-08 Thread spir

On 03/08/2011 09:26 AM, Wilfried Kirschenmann wrote:

enum deviceType {cpu, gpu}
auto execDeviceSuffix = [deviceType.cpu:.cpu, deviceType.gpu:.gpu];



The way to get what you want to work in this case is to use a module
constructor. So, you'd do something like this:

string[deviceType] execDeviceSuffix;

static this()
{
execDeviceSuffix[deviceType.cpu] = cpu;
execDeviceSuffix[deviceType.gpu] = gpu;
}

The module constructor will be run before main does, so execDeviceSuffix will be
properly filled in by then.


I didn't get to the point where module constructors are introduced in
Andrei's book yet. I really like this idea !
I found a similar workaround which used an useless class so that I
could use the static constructor but this is even better !


This is a very nice feature, yes. But I personly see it as a workaround for the 
limitation that dmd, apparently, is not able to correctly evaluate many kinds 
of assignment expressions. And it's ugly when one has hordes of definitions -- 
the module is (mainly) a piece of data description: all symbols must first be 
declared /outside/, then redefined /inside/ static this(). Else, D would be a 
great data-definition language, in addition to its other qualities, thank to 
its literals for everything (and conversely its standard to!string for 
everything, which needs improvements). Think a static Lua.


Denis
--
_
vita es estrany
spir.wikidot.com



Re: using enums as key in associative array

2011-03-08 Thread Jonathan M Davis
On Tuesday 08 March 2011 04:54:45 spir wrote:
 On 03/08/2011 09:26 AM, Wilfried Kirschenmann wrote:
  enum deviceType {cpu, gpu}
  auto execDeviceSuffix = [deviceType.cpu:.cpu, deviceType.gpu:.gpu];
  
  The way to get what you want to work in this case is to use a module
  constructor. So, you'd do something like this:
  
  string[deviceType] execDeviceSuffix;
  
  static this()
  {
  
  execDeviceSuffix[deviceType.cpu] = cpu;
  execDeviceSuffix[deviceType.gpu] = gpu;
  
  }
  
  The module constructor will be run before main does, so execDeviceSuffix
  will be properly filled in by then.
  
  I didn't get to the point where module constructors are introduced in
  Andrei's book yet. I really like this idea !
  I found a similar workaround which used an useless class so that I
  could use the static constructor but this is even better !
 
 This is a very nice feature, yes. But I personly see it as a workaround for
 the limitation that dmd, apparently, is not able to correctly evaluate
 many kinds of assignment expressions. And it's ugly when one has hordes of
 definitions -- the module is (mainly) a piece of data description: all
 symbols must first be declared /outside/, then redefined /inside/ static
 this(). Else, D would be a great data-definition language, in addition to
 its other qualities, thank to its literals for everything (and conversely
 its standard to!string for everything, which needs improvements). Think a
 static Lua.

??? It's for stuff that has to be defined at runtime. There's plenty of stuff 
that 
_has_ to be done at runtime and could _never_ be done at compile time no matter 
how great the language is. For instance, what if you want to have a variable 
with the time that the program started running? You certainly couldn't do that 
at compile time. Sure, there are things that you'd ideally be able to set with 
CTFE and currenly can't, but it's not like a better CTFE would negate the need 
for static constructors.

And honestly, in other cases, such as when you have to use a module constructor 
because of interdependencies between variables when initializing them and 
they're mutable, the fact that you can't do that at compile time is 
_fantastic_. 
In other programming languages, you run into problems because of the order of 
evaluation of the declarations of such variables. D makes them it so the order 
truly doesn't matter, because when it does, you have to use a module 
constructor. That's _huge_.

I really don't understand your problem with module constructors. They're 
fantastic.

- Jonathan M Davis


Re: using enums as key in associative array

2011-03-08 Thread spir

On 03/08/2011 03:48 PM, Jonathan M Davis wrote:

I really don't understand your problem with module constructors. They're
fantastic.


I may be wrong, but I think this point of view is a where I can from 
statement. C's char* are fantastic when you have never used a PL with builtin 
strings. There are languages in which you don't need to list twice everything 
just to have them available at import time.


// data definition
X foo;
Y bar;
Z baz;
...
static this {
   foo = ...;
   bar = ...;
   baz = ...;
   ...
}

Denis
--
_
vita es estrany
spir.wikidot.com



Re: Struct constructor and opCall confussion

2011-03-08 Thread Tom

El 08/03/2011 05:32, bearophile escribió:

Tom:


Am I missing something or is this another major bug?


A major bug (that is not recognized as major, I think).
I don't remember its number in bugzilla, sorry (anyone remembers it?).

See also:
http://d.puremagic.com/issues/show_bug.cgi?id=4053

Bye,
bearophile


Think I found it:

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

This is indeed a major bug. Why not tag it as major? I think it's a 
straight loss of functionality and it happens under almost any 
circumstance in which one wishes to simply use opCall and a struct...


Tom;


Re: using enums as key in associative array

2011-03-08 Thread Wilfried Kirschenmann

 I really don't understand your problem with module constructors. They're
 fantastic.

 I may be wrong, but I think this point of view is a where I can from
 statement. C's char* are fantastic when you have never used a PL with
 builtin strings. There are languages in which you don't need to list twice
 everything just to have them available at import time.

 // data definition
 X foo;
 Y bar;
 Z baz;
 ...
 static this {
   foo = ...;
   bar = ...;
   baz = ...;
   ...
 }


The question is : what are in the dots :
static this {
// get information from environment
...
// load information from a module configuration file
...
// make some complex computation
...

// initialize data in any order
baz = ...;
bar = ...;
foo = functionOf(baz, bar);
}

This way, you have made independent the initialization of a module
from the initialization of the user's application.

However, I agree to the fact that for statically known value (such as
my first example), this far from optimal.

Wilfried


Re: Struct constructor and opCall confussion

2011-03-08 Thread Steven Schveighoffer

On Tue, 08 Mar 2011 10:52:38 -0500, Tom t...@nospam.com wrote:


El 08/03/2011 05:32, bearophile escribió:

Tom:


Am I missing something or is this another major bug?


A major bug (that is not recognized as major, I think).
I don't remember its number in bugzilla, sorry (anyone remembers it?).

See also:
http://d.puremagic.com/issues/show_bug.cgi?id=4053

Bye,
bearophile


Think I found it:

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


Those two bugs look almost identical, I think they should be combined...

-Steve


Re: Struct constructor and opCall confussion

2011-03-08 Thread Tom

El 08/03/2011 13:05, Steven Schveighoffer escribió:

On Tue, 08 Mar 2011 10:52:38 -0500, Tom t...@nospam.com wrote:


El 08/03/2011 05:32, bearophile escribió:

Tom:


Am I missing something or is this another major bug?


A major bug (that is not recognized as major, I think).
I don't remember its number in bugzilla, sorry (anyone remembers it?).

See also:
http://d.puremagic.com/issues/show_bug.cgi?id=4053

Bye,
bearophile


Think I found it:

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


Those two bugs look almost identical, I think they should be combined...

-Steve


I agree. They should be combined into a major (severity) bug.


std.traits and std.string incompatible ?

2011-03-08 Thread Wilfried Kirschenmann
Hi,

When running the following file:

#!../dmd2/linux/bin/rdmd -unittest
import std.string, std.traits;
void main(string[] args){
bool test = isNumeric(args[0]);
}

I get the error :
dmd2/linux/bin/../../src/phobos/std/traits.d(2576): Error: template
std.traits.isNumeric(T) is not a function template

Is this a bug or is there something deprecated ?

Wilfried


Templated struct doesn't need the parameterized type in return type definitions?

2011-03-08 Thread Andrej Mitrovic
import std.stdio;
import std.traits;
import std.exception;

struct CheckedInt(N) if (isIntegral!N)
{
private N value;

ref CheckedInt opUnary(string op)() if (op == ++)
{
enforce(value != value.max);
++value;
return this;
}

this(N _value)
{
value = _value;
}
}

I didn't know you could define a return type of a templated struct without 
defining the type it is parameterized on. I mean this line:

ref CheckedInt opUnary(string op)() if (op == ++)

I thought for sure I always had to write the parameterized type like so:

ref CheckedInt!(N) opUnary(string op)() if (op == ++)

So I guess this really isn't a question but more of a oh, I didn't know you 
could do that. In fact I rarely see this kind of code in Phobos, most of the 
time the parameterized type is specified in these types of cases. Is this 
feature described somewhere, because I must have missed it if it is?

As a side-note, auto ref is useful in this case, which is pretty cool:
auto ref opUnary(string op)() if (op == ++)


Re: Templated struct doesn't need the parameterized type in return type definitions?

2011-03-08 Thread Steven Schveighoffer

On Tue, 08 Mar 2011 12:06:08 -0500, Andrej Mitrovic n...@none.none wrote:


import std.stdio;
import std.traits;
import std.exception;

struct CheckedInt(N) if (isIntegral!N)
{
private N value;
   ref CheckedInt opUnary(string op)() if (op == ++)
{
enforce(value != value.max);
++value;
return this;
}
   this(N _value)
{
value = _value;
}
}

I didn't know you could define a return type of a templated struct  
without defining the type it is parameterized on. I mean this line:


ref CheckedInt opUnary(string op)() if (op == ++)

I thought for sure I always had to write the parameterized type like so:

ref CheckedInt!(N) opUnary(string op)() if (op == ++)

So I guess this really isn't a question but more of a oh, I didn't know  
you could do that. In fact I rarely see this kind of code in Phobos,  
most of the time the parameterized type is specified in these types of  
cases. Is this feature described somewhere, because I must have missed  
it if it is?


It is described, but not directly.

Look on this page:

http://www.digitalmars.com/d/2.0/template.html

  From there we have these two descriptions:



If a template has exactly one member in it, and the name of that member is
the same as the template name, that member is assumed to be referred to in
a template instantiation:
template Foo(T)
{
  T Foo;// declare variable Foo of type T
}

void test()
{
  Foo!(int) = 6;// instead of Foo!(int).Foo
}



If a template declares exactly one member, and that member is a class with
the same name as the template:
template Bar(T)
{
  class Bar
  {
T member;
  }
}

then the semantic equivalent, called a ClassTemplateDeclaration can be
written as:
class Bar(T)
{
  T member;
}



Also note that structs have the same description.

So if you think about it, your code is equivalent to:

template CheckedInt(N) if(isIntegral!N)
{
   struct CheckedInt
   {
  ...
   }
}

If you look at it this way, it makes complete sense that within the struct  
that's within the template, the struct can refer to itself without the  
specific instantiation parameters.


I think this should really be laid out properly in the docs.  I discovered  
this trick while writing dcollections by accident and thought it so  
awesome that I changed all my code which self-returned (quite a bit).


-Steve


Re: std.traits and std.string incompatible ?

2011-03-08 Thread Ali Çehreli

On 03/08/2011 08:24 AM, Wilfried Kirschenmann wrote:
 Hi,

 When running the following file:

 #!../dmd2/linux/bin/rdmd -unittest
 import std.string, std.traits;
 void main(string[] args){
bool test = isNumeric(args[0]);
 }

 I get the error :
 dmd2/linux/bin/../../src/phobos/std/traits.d(2576): Error: template
 std.traits.isNumeric(T) is not a function template

 Is this a bug or is there something deprecated ?

 Wilfried


isNumeric is a template. You are supposed to give it a type:

  if (isNumeric!SomeType)

or at compile time:

  static if (isNumeric!SomeType)

It doesn't work with string values. Although unnecessary, you could do this:

bool test = isNumeric!(typeof(args[0]));

Ali


Empty field doesn't exist for arrays, right?

2011-03-08 Thread Andrej Mitrovic
module test;

struct MyArray(T)
{
private T[] data;

bool opCast(T)() if (is(T == bool))
{
return !data.empty;
}
}

void main()
{
auto foo = MyArray!(int)();
auto state = foo ? true : false;
}

test.d(13): Error: undefined identifier module test.empty
test.d(20): Error: template instance test.MyArray!(int).MyArray.opCast!(bool) 
error instantiating

This is straight from the book. Did .empty exist for arrays before? Perhaps 
this was just a typo in the book, and it was supposed to be:

bool opCast(T)() if (is(T == bool))
{
return data.length != 0;
}

Also, that error message *really* needs to improve. It's not module 'test' 
which is missing the method, it's 'data'. This is one of the most confusing 
error messages that I know of and it pops up all the time. 


Re: Empty field doesn't exist for arrays, right?

2011-03-08 Thread Andrej Mitrovic
Nevermind, I'm dumb. It's in std.array, I just need to import it. This needs to 
be said in TDPL however.


Re: Struct constructor and opCall confussion

2011-03-08 Thread bearophile
Steven Schveighoffe:

 Those two bugs look almost identical, I think they should be combined...

Right, they look similar. I have linked each with the other, so if one gets 
fixed it's very easy to see if the fix fixes the other too. One bug has 4 votes 
and one bug 1 vote.

Bye,
bearophile


Re: Empty field doesn't exist for arrays, right?

2011-03-08 Thread Andrej Mitrovic
On 3/8/11, bearophile bearophileh...@lycos.com wrote:
 empty is not an array method, it's a free function that is used with a
 funny syntax.

Yes but the compiler doesn't know that until std.array is imported. A
better error message is that empty isn't a property of that array.
It's much easier to reason about this way.


Re: Empty field doesn't exist for arrays, right?

2011-03-08 Thread Jesse Phillips
Andrej Mitrovic Wrote:

 On 3/8/11, bearophile bearophileh...@lycos.com wrote:
  empty is not an array method, it's a free function that is used with a
  funny syntax.
 
 Yes but the compiler doesn't know that until std.array is imported. A
 better error message is that empty isn't a property of that array.
 It's much easier to reason about this way.

What if you are trying to create a method which will act as a property for the 
array? If you get it wrong you would get the error that an array doesn't have 
the property and scream, I know that is why I'm building a function for it. 
Why won't it find my function stead of looking at what array provides!

Also doesn't TDPL introduce Ranges by implementing them for arrays and then 
tell you that you don't have to do this every time because it is an the 
standard labrary std.array?


Re: Empty field doesn't exist for arrays, right?

2011-03-08 Thread Andrej Mitrovic
On 3/8/11, Jesse Phillips jessekphillip...@gmail.com wrote:
 What if you are trying to create a method which will act as a property for
 the array? If you get it wrong you would get the error that an array doesn't
 have the property and scream, I know that is why I'm building a function
 for it. Why won't it find my function stead of looking at what array
 provides!

But wouldn't this case be much more obvious with the property error
message? Or maybe it wouldn't.. all I know is I got bitten by this
error message a couple of times and it always got me that WTF look on
my face.

How common are typos in invoking methods versus typos in implementing
methods like a UFCS function?


Re: Templated struct doesn't need the parameterized type in return type definitions?

2011-03-08 Thread spir

On 03/08/2011 06:20 PM, Steven Schveighoffer wrote:

On Tue, 08 Mar 2011 12:06:08 -0500, Andrej Mitrovic n...@none.none wrote:


import std.stdio;
import std.traits;
import std.exception;

struct CheckedInt(N) if (isIntegral!N)
{
private N value;
ref CheckedInt opUnary(string op)() if (op == ++)
{
enforce(value != value.max);
++value;
return this;
}
this(N _value)
{
value = _value;
}
}

I didn't know you could define a return type of a templated struct without
defining the type it is parameterized on. I mean this line:

ref CheckedInt opUnary(string op)() if (op == ++)

I thought for sure I always had to write the parameterized type like so:

ref CheckedInt!(N) opUnary(string op)() if (op == ++)

So I guess this really isn't a question but more of a oh, I didn't know you
could do that. In fact I rarely see this kind of code in Phobos, most of the
time the parameterized type is specified in these types of cases. Is this
feature described somewhere, because I must have missed it if it is?


It is described, but not directly.

Look on this page:

http://www.digitalmars.com/d/2.0/template.html

 From there we have these two descriptions:



If a template has exactly one member in it, and the name of that member is
the same as the template name, that member is assumed to be referred to in
a template instantiation:
template Foo(T)
{
T Foo; // declare variable Foo of type T
}

void test()
{
Foo!(int) = 6; // instead of Foo!(int).Foo
}



If a template declares exactly one member, and that member is a class with
the same name as the template:
template Bar(T)
{
class Bar
{
T member;
}
}

then the semantic equivalent, called a ClassTemplateDeclaration can be
written as:
class Bar(T)
{
T member;
}



Also note that structs have the same description.

So if you think about it, your code is equivalent to:

template CheckedInt(N) if(isIntegral!N)
{
struct CheckedInt
{
...
}
}

If you look at it this way, it makes complete sense that within the struct
that's within the template, the struct can refer to itself without the specific
instantiation parameters.

I think this should really be laid out properly in the docs. I discovered this
trick while writing dcollections by accident and thought it so awesome that I
changed all my code which self-returned (quite a bit).

-Steve


I don't share your enthusiasm, Steven, for this feature (which I did not know). 
In fact, I tend to consider it a mis-feature. Yet another syntactic 
special-case for special cases in the language. In this case, there are even 3 
ways to write the same thing:

CheckedInt
CheckedInt!N
CheckedInt!(N)
And note these variants are low-level ones, morphological rather than syntactic 
properly speaking.


Denis
--
_
vita es estrany
spir.wikidot.com



Re: Empty field doesn't exist for arrays, right?

2011-03-08 Thread spir

On 03/08/2011 06:56 PM, Andrej Mitrovic wrote:

module test;

struct MyArray(T)
{
 private T[] data;

 bool opCast(T)() if (is(T == bool))
 {
 return !data.empty;
 }
}

void main()
{
 auto foo = MyArray!(int)();
 auto state = foo ? true : false;
}

test.d(13): Error: undefined identifier module test.empty
test.d(20): Error: template instance test.MyArray!(int).MyArray.opCast!(bool) 
error instantiating

This is straight from the book. Did .empty exist for arrays before? Perhaps 
this was just a typo in the book, and it was supposed to be:

 bool opCast(T)() if (is(T == bool))
 {
 return data.length != 0;
 }

Also, that error message *really* needs to improve. It's not module 'test' 
which is missing the method, it's 'data'. This is one of the most confusing 
error messages that I know of and it pops up all the time.


Agreed. But do you understand why dmd throws that error, anyway? I'm not sure, 
the following may be plain shit. My guess is, since UFCS (universal function 
call syntax) exists for arrays, when dmd decodes data.empty and does not find 
any empty slot on 'data' or on its type, it tries rewriting it into 
empty(data). Right? then, to execute that, it looks for an empty func in 
the module, which it does not find... thus the message.
Note that if one of your imports happened to hold an empty func, either it 
would execute by plain chance, or you would get a type error!

HTH

Denis
--
_
vita es estrany
spir.wikidot.com



Re: Templated struct doesn't need the parameterized type in return type definitions?

2011-03-08 Thread David Nadlinger

On 3/8/11 8:20 PM, spir wrote:

[…] Yet another
syntactic special-case for special cases in the language. In this case,
there are even 3 ways to write the same thing: […]


I don't quite get how you think this would be a syntactic special case. 
As Steve pointed out, »class Foo(T) {}« is merely syntax sugar for 
»template Foo(T) { class Foo{} }«, and because of this, it would rather 
be a special case *not* to allow referring to Foo using just that name. 
When considering this, don't forget that templates in D are little more 
than parametrized, named scopes.


I guess you could argue that »class Foo(T)« as a shorthand is an 
unnecessary special case, but I very much prefer the benefit in brevity 
here…


David


Re: Templated struct doesn't need the parameterized type in return type definitions?

2011-03-08 Thread Steven Schveighoffer

On Tue, 08 Mar 2011 14:20:40 -0500, spir denis.s...@gmail.com wrote:


On 03/08/2011 06:20 PM, Steven Schveighoffer wrote:
On Tue, 08 Mar 2011 12:06:08 -0500, Andrej Mitrovic n...@none.none  
wrote:



import std.stdio;
import std.traits;
import std.exception;

struct CheckedInt(N) if (isIntegral!N)
{
private N value;
ref CheckedInt opUnary(string op)() if (op == ++)
{
enforce(value != value.max);
++value;
return this;
}
this(N _value)
{
value = _value;
}
}

I didn't know you could define a return type of a templated struct  
without

defining the type it is parameterized on. I mean this line:

ref CheckedInt opUnary(string op)() if (op == ++)

I thought for sure I always had to write the parameterized type like  
so:


ref CheckedInt!(N) opUnary(string op)() if (op == ++)

So I guess this really isn't a question but more of a oh, I didn't  
know you
could do that. In fact I rarely see this kind of code in Phobos, most  
of the
time the parameterized type is specified in these types of cases. Is  
this

feature described somewhere, because I must have missed it if it is?


It is described, but not directly.

Look on this page:

http://www.digitalmars.com/d/2.0/template.html

 From there we have these two descriptions:



If a template has exactly one member in it, and the name of that member  
is
the same as the template name, that member is assumed to be referred to  
in

a template instantiation:
template Foo(T)
{
T Foo; // declare variable Foo of type T
}

void test()
{
Foo!(int) = 6; // instead of Foo!(int).Foo
}



If a template declares exactly one member, and that member is a class  
with

the same name as the template:
template Bar(T)
{
class Bar
{
T member;
}
}

then the semantic equivalent, called a ClassTemplateDeclaration can be
written as:
class Bar(T)
{
T member;
}



Also note that structs have the same description.

So if you think about it, your code is equivalent to:

template CheckedInt(N) if(isIntegral!N)
{
struct CheckedInt
{
...
}
}

If you look at it this way, it makes complete sense that within the  
struct
that's within the template, the struct can refer to itself without the  
specific

instantiation parameters.

I think this should really be laid out properly in the docs. I  
discovered this
trick while writing dcollections by accident and thought it so  
awesome that I

changed all my code which self-returned (quite a bit).

-Steve


I don't share your enthusiasm, Steven, for this feature (which I did not  
know). In fact, I tend to consider it a mis-feature. Yet another  
syntactic special-case for special cases in the language. In this case,  
there are even 3 ways to write the same thing:

CheckedInt
CheckedInt!N
CheckedInt!(N)
And note these variants are low-level ones, morphological rather than  
syntactic properly speaking.


Here's another thing I found in dcollections which caught me off guard,  
and which I was glad to be rid of when I switched to not parameterizing  
the names of self returns:


class Collection(T)
{
   Collection!(T) add(T t) { ...; return this; }
   // 20 other functions like add...
}

Hey, wouldn't it be cool if I could add a custom allocator to all  
classes!?...


class Collection(T, alloc = DefaultAllocator!T)
{
   Collection!(T) add(T t) { ...; return this; }
   // 20 other now subtly incorrect functions like add...
}

See the problem?

-Steve


Re: Some weird crashes

2011-03-08 Thread simendsjo

On 08.03.2011 01:32, Andrej Mitrovic wrote:

Sorry for not seeing this sooner. I think you might have set the wrong
calling convention in the translated header file. See my answer on SO.
I hope it works for you now.


Thanks. Just to get the solution here too:

* Use the vs2005 library (to get COFF?)
* coffimplib
* wrap __stdcall in extern(Windows)

One more thing..
Function pointers in structs.. Should they use extern(Windows) too?


Re: Templated struct doesn't need the parameterized type in return

2011-03-08 Thread bearophile
David Nadlinger:

 and because of this, it would rather 
 be a special case *not* to allow referring to Foo using just that name.

Right. On the other hand the current straightforward design leads to some bugs 
too, the give bad error messages:
http://d.puremagic.com/issues/show_bug.cgi?id=3950

Bye,
bearophile


Re: std.traits and std.string incompatible ?

2011-03-08 Thread Nick Sabalausky
Ali Çehreli acehr...@yahoo.com wrote in message 
news:il5pge$nrr$1...@digitalmars.com...
 On 03/08/2011 08:24 AM, Wilfried Kirschenmann wrote:
  Hi,
 
  When running the following file:
 
  #!../dmd2/linux/bin/rdmd -unittest
  import std.string, std.traits;
  void main(string[] args){
  bool test = isNumeric(args[0]);
  }
 
  I get the error :
  dmd2/linux/bin/../../src/phobos/std/traits.d(2576): Error: template
  std.traits.isNumeric(T) is not a function template
 
  Is this a bug or is there something deprecated ?
 
  Wilfried


 isNumeric is a template. You are supposed to give it a type:

   if (isNumeric!SomeType)

 or at compile time:

   static if (isNumeric!SomeType)

 It doesn't work with string values. Although unnecessary, you could do 
 this:

 bool test = isNumeric!(typeof(args[0]));


No, there's an isNumeric in *both* std.traits and std.string. The one in 
std.traits is a template that takes a type. But the one in std.string is a 
function that takes a string and checks if the value of the string is 
numeric.

I'm on the latest D2 (2.052) and I just tried the example and got the same 
result. But if I *only* import std.string then it works. So it sounds like a 
bug: I forget the exact details of the rules involving overloading across 
modules, but one of two things should happen with the original example:

A. It should know that you meant std.string.isNumeric because of how you're 
calling it.

or:

B. It should complain that there's an ambiguity between std.string.isNumeric 
and std.traits.isNumeric and require you to disambiguate with either 
std.traits. or std.string.

I'm not sure which of those it's supposed to do, but it's clearly not doing 
either, so I'd file it as a bug: http://d.puremagic.com/issues/





Re: Empty field doesn't exist for arrays, right?

2011-03-08 Thread Jesse Phillips
Andrej Mitrovic Wrote:

 On 3/8/11, Jesse Phillips jessekphillip...@gmail.com wrote:
  What if you are trying to create a method which will act as a property for
  the array? If you get it wrong you would get the error that an array doesn't
  have the property and scream, I know that is why I'm building a function
  for it. Why won't it find my function stead of looking at what array
  provides!
 
 But wouldn't this case be much more obvious with the property error
 message? Or maybe it wouldn't.. all I know is I got bitten by this
 error message a couple of times and it always got me that WTF look on
 my face.

I don't think so. If you didn't know empty was a library feature then you'd get 
the message, empty is not a property of array. and be confused thinking that 
other code uses it. It would probably result in looking up other code which 
uses it then the properties available to arrays in the documentation and then a 
post to the NG confused on how other code gets away with it.

I don't really know, it just seems like someone is going to be lost no matter 
what it is.

 How common are typos in invoking methods versus typos in implementing
 methods like a UFCS function?

But if you know that empty is a function not a property, then the error makes 
much more sense. I think the confusion comes from not knowing it is a property 
or a function you are trying to call.


Dynamic array void initialization

2011-03-08 Thread Tom

import std.stdio;

struct S {
int i;
int j;
}

int main(string[] args) {
S[] ss = void;
ss.length = 5;
foreach (ref s; ss)
s = S(1, 2);
return 0;
}

Is the above code correct? (it doesn't work... it blows away or just 
give and access violation error).


I need to create a dynamic array of some struct, but don't want defer 
contained elements initialization (for performance reasons).


Tom;


Re: Dynamic array void initialization

2011-03-08 Thread Ali Çehreli

On 03/08/2011 01:34 PM, Tom wrote:

import std.stdio;

struct S {
int i;
int j;
}

int main(string[] args) {
S[] ss = void;
ss.length = 5;
foreach (ref s; ss)
s = S(1, 2);
return 0;
}

Is the above code correct? (it doesn't work... it blows away or just
give and access violation error).

I need to create a dynamic array of some struct, but don't want defer
contained elements initialization (for performance reasons).

Tom;


There is std.array.reserve:

import std.array;

struct S {
int i;
int j;
}

int main(string[] args) {
S[] ss;
reserve(ss, 5);

// or if you want to confuse yourself (and me):
ss.reserve(5);  // same thing as above

foreach (ref s; ss)
s = S(1, 2);

return 0;
}

Ali



Re: Dynamic array void initialization

2011-03-08 Thread Steven Schveighoffer

On Tue, 08 Mar 2011 16:53:08 -0500, Ali Çehreli acehr...@yahoo.com wrote:


On 03/08/2011 01:34 PM, Tom wrote:

import std.stdio;

struct S {
int i;
int j;
}

int main(string[] args) {
S[] ss = void;
ss.length = 5;
foreach (ref s; ss)
s = S(1, 2);
return 0;
}

Is the above code correct? (it doesn't work... it blows away or just
give and access violation error).

I need to create a dynamic array of some struct, but don't want defer
contained elements initialization (for performance reasons).

Tom;


There is std.array.reserve:

import std.array;

struct S {
 int i;
 int j;
}

int main(string[] args) {
 S[] ss;
 reserve(ss, 5);

 // or if you want to confuse yourself (and me):
 ss.reserve(5);  // same thing as above

 foreach (ref s; ss)
 s = S(1, 2);

 return 0;
}


Some clarifications:

it's not std.array.reserve, it's object.reserve, always present, no need  
to import.


I believe if the type contains pointers the GC still writes 0s to the  
unused data to prevent false pointers. However, reserve on an int or a  
struct that just contains ints should not pre-initialize.


reserve ensures appropriate space for appending, it does *not* alter the  
array's length.  So your foreach loop would not execute (at that point,  
ss.length is still 0).


To work properly, you would need to use the append operator.

Bearophile has requested an ability to create a dynamic array  
uninitialized, and I think there is a bug report for that.  Currently,  
there is no easy way to do it.


-Steve


Re: Dynamic array void initialization

2011-03-08 Thread Ali Çehreli

On 03/08/2011 02:03 PM, Steven Schveighoffer wrote:

 it's not std.array.reserve, it's object.reserve, always present, no need
 to import.

Thanks. The reserve that I found in array.d is 
std.array.Appender(T).reserve.


Ali



Re: Dynamic array void initialization

2011-03-08 Thread Tom

El 08/03/2011 19:03, Steven Schveighoffer escribió:

On Tue, 08 Mar 2011 16:53:08 -0500, Ali Çehreli acehr...@yahoo.com wrote:


On 03/08/2011 01:34 PM, Tom wrote:

import std.stdio;

struct S {
int i;
int j;
}

int main(string[] args) {
S[] ss = void;
ss.length = 5;
foreach (ref s; ss)
s = S(1, 2);
return 0;
}

Is the above code correct? (it doesn't work... it blows away or just
give and access violation error).

I need to create a dynamic array of some struct, but don't want defer
contained elements initialization (for performance reasons).

Tom;


There is std.array.reserve:

import std.array;

struct S {
int i;
int j;
}

int main(string[] args) {
S[] ss;
reserve(ss, 5);

// or if you want to confuse yourself (and me):
ss.reserve(5); // same thing as above

foreach (ref s; ss)
s = S(1, 2);

return 0;
}


Some clarifications:

it's not std.array.reserve, it's object.reserve, always present, no need
to import.

I believe if the type contains pointers the GC still writes 0s to the
unused data to prevent false pointers. However, reserve on an int or a
struct that just contains ints should not pre-initialize.

reserve ensures appropriate space for appending, it does *not* alter the
array's length. So your foreach loop would not execute (at that point,
ss.length is still 0).

To work properly, you would need to use the append operator.

Bearophile has requested an ability to create a dynamic array
uninitialized, and I think there is a bug report for that. Currently,
there is no easy way to do it.

-Steve


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

This is really sad. This kind of stuff is a must for performance. D is 
disappointing me too much yet :(




Re: Dynamic array void initialization

2011-03-08 Thread Steven Schveighoffer

On Tue, 08 Mar 2011 17:48:37 -0500, Tom t...@nospam.com wrote:


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

This is really sad. This kind of stuff is a must for performance. D is  
disappointing me too much yet :(




There is always c's malloc, or you can try using the GC malloc directly.   
For application specific needs, it might be sufficient.  However, a  
builtin language/library feature must be very robust and handle all cases.


-Steve


Re: Empty field doesn't exist for arrays, right?

2011-03-08 Thread Andrej Mitrovic
Well, maybe one day we'll have a compiler with lots of front-end
customization options (or some nice analysis tools). In any case this
topic is done here since post #2. :)


Re: Templated struct doesn't need the parameterized type in return type definitions?

2011-03-08 Thread Andrej Mitrovic
On 3/8/11, Steven Schveighoffer schvei...@yahoo.com wrote:
 See the problem?

Yup. Btw, does auto ref still suffer from any bugs that I should know
about? I've heard it had issues.


Re: using enums as key in associative array

2011-03-08 Thread Jonathan M Davis
On Tuesday, March 08, 2011 07:40:08 spir wrote:
 On 03/08/2011 03:48 PM, Jonathan M Davis wrote:
  I really don't understand your problem with module constructors. They're
  fantastic.
 
 I may be wrong, but I think this point of view is a where I can from
 statement. C's char* are fantastic when you have never used a PL with
 builtin strings. There are languages in which you don't need to list twice
 everything just to have them available at import time.
 
 // data definition
 X foo;
 Y bar;
 Z baz;
 ...
 static this {
 foo = ...;
 bar = ...;
 baz = ...;
 ...
 }

In one case, you're declaring a variable. In another, you're giving it a value. 
They're two _very_ different things. In one case, you're telling the compiler 
that a particular variable exists. In the other, you're giving it a value.

Generally, it is ideal to give a variable its initial value (and final value if 
it's not mutable) when you declare it, and there's no question that CTFE is 
currently not as good as we'd like in that regard. However, there are plenty of 
cases where it makes no sense to give a variable its initial value at compile 
time. So, given that D requires that _all_ module variables, class/struct 
variables, and member variables which are directly initialized have that value 
known at compile time, you have to do it separately to do it runtime. Also, 
there are plenty of cases where there are dependcies between variables such 
that 
you need to actually give them values within a function rather than statically. 
Constructors do a beautiful job of dealing with this problem.

The main alternative is to allow you to set module, class/struct,  and member 
variables directly at runtime. Languages such as C++ and Java do this, and it 
causes a host of problems. The order of initialization isn't necessarily 
defined. 
It's possible to end up using variables before they're actually initialized. 
Compilation is slower because of all of the interdependencies, whereas in D 
it's 
possible to parallelize a lot of what the compiler does with declarations, 
because they're not interdependent like they are in C++ or Java. Not to 
mention, 
if you want to be able to initialize them in a manner which requires you to 
essentially have a function rather than set them directly, then you _need_ 
something like a constructor to initialize them. Also, you don't get compile 
time evaluation of variables in languages like C/C++ and Java like you do in D, 
so _every_ variable is initialized at runtime. The occasional irritation with 
the current implementation problems of CTFE is _well_ worth the gain in compile 
time evaluation.

D uses a model similar to C/C++ and Java, but it improves on it _considerably_ 
by doing things the way it does. The order of initialization in D is _well-
defined_ and not bug-prone. It also lends itself to efficient compilation. 
Granted, 
until CTFE is able to do anything in SafeD (as its intended to do eventually), 
there are going to be irritating restrictions with regards to what we can and 
can't initialize directly using CTFE, but that's an implementation detail which 
will improve. D's design in this regard is excellent.

- Jonathan M Davis


Re: std.traits and std.string incompatible ?

2011-03-08 Thread Jonathan M Davis
On Tuesday, March 08, 2011 13:24:44 Nick Sabalausky wrote:
 Ali Çehreli acehr...@yahoo.com wrote in message
 news:il5pge$nrr$1...@digitalmars.com...
 
  On 03/08/2011 08:24 AM, Wilfried Kirschenmann wrote:
   Hi,
   
   When running the following file:
   
   #!../dmd2/linux/bin/rdmd -unittest
   import std.string, std.traits;
   void main(string[] args){
   bool test = isNumeric(args[0]);
   }
   
   I get the error :
   dmd2/linux/bin/../../src/phobos/std/traits.d(2576): Error: template
   std.traits.isNumeric(T) is not a function template
   
   Is this a bug or is there something deprecated ?
   
   Wilfried
  
  isNumeric is a template. You are supposed to give it a type:
if (isNumeric!SomeType)
  
  or at compile time:
static if (isNumeric!SomeType)
  
  It doesn't work with string values. Although unnecessary, you could do
  
  this:
  bool test = isNumeric!(typeof(args[0]));
 
 No, there's an isNumeric in *both* std.traits and std.string. The one in
 std.traits is a template that takes a type. But the one in std.string is a
 function that takes a string and checks if the value of the string is
 numeric.
 
 I'm on the latest D2 (2.052) and I just tried the example and got the same
 result. But if I *only* import std.string then it works. So it sounds like
 a bug: I forget the exact details of the rules involving overloading
 across modules, but one of two things should happen with the original
 example:
 
 A. It should know that you meant std.string.isNumeric because of how you're
 calling it.
 
 or:
 
 B. It should complain that there's an ambiguity between
 std.string.isNumeric and std.traits.isNumeric and require you to
 disambiguate with either std.traits. or std.string.
 
 I'm not sure which of those it's supposed to do, but it's clearly not doing
 either, so I'd file it as a bug: http://d.puremagic.com/issues/

isNumeric in std.string is a function. In std.traits, it's an eponymous 
template. The eponymous template should require the !. There's no function to 
feed the argument to. There shouldn't be any ambiguity of any kind. Overload 
set 
rules and whatnot should have nothing to do with this. This is definitely a bug.

- Jonathan M Davis


Re: std.traits and std.string incompatible ?

2011-03-08 Thread Jonathan M Davis
On Tuesday, March 08, 2011 16:11:09 Jonathan M Davis wrote:
 On Tuesday, March 08, 2011 13:24:44 Nick Sabalausky wrote:
  Ali Çehreli acehr...@yahoo.com wrote in message
  news:il5pge$nrr$1...@digitalmars.com...
  
   On 03/08/2011 08:24 AM, Wilfried Kirschenmann wrote:
Hi,

When running the following file:

#!../dmd2/linux/bin/rdmd -unittest
import std.string, std.traits;
void main(string[] args){
bool test = isNumeric(args[0]);
}

I get the error :
dmd2/linux/bin/../../src/phobos/std/traits.d(2576): Error: template
std.traits.isNumeric(T) is not a function template

Is this a bug or is there something deprecated ?

Wilfried
   
   isNumeric is a template. You are supposed to give it a type:
 if (isNumeric!SomeType)
   
   or at compile time:
 static if (isNumeric!SomeType)
   
   It doesn't work with string values. Although unnecessary, you could do
   
   this:
   bool test = isNumeric!(typeof(args[0]));
  
  No, there's an isNumeric in *both* std.traits and std.string. The one in
  std.traits is a template that takes a type. But the one in std.string is
  a function that takes a string and checks if the value of the string is
  numeric.
  
  I'm on the latest D2 (2.052) and I just tried the example and got the
  same result. But if I *only* import std.string then it works. So it
  sounds like a bug: I forget the exact details of the rules involving
  overloading across modules, but one of two things should happen with the
  original example:
  
  A. It should know that you meant std.string.isNumeric because of how
  you're calling it.
  
  or:
  
  B. It should complain that there's an ambiguity between
  std.string.isNumeric and std.traits.isNumeric and require you to
  disambiguate with either std.traits. or std.string.
  
  I'm not sure which of those it's supposed to do, but it's clearly not
  doing either, so I'd file it as a bug: http://d.puremagic.com/issues/
 
 isNumeric in std.string is a function. In std.traits, it's an eponymous
 template. The eponymous template should require the !. There's no function
 to feed the argument to. There shouldn't be any ambiguity of any kind.
 Overload set rules and whatnot should have nothing to do with this. This
 is definitely a bug.

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

- Jonathan M Davis


Re: Templated struct doesn't need the parameterized type in return type definitions?

2011-03-08 Thread Jonathan M Davis
On Tuesday, March 08, 2011 15:31:37 Andrej Mitrovic wrote:
 On 3/8/11, Steven Schveighoffer schvei...@yahoo.com wrote:
  See the problem?
 
 Yup. Btw, does auto ref still suffer from any bugs that I should know
 about? I've heard it had issues.

I'm not sure that it works correctly with properties at the moment. It _does_ 
appear in the docs now though.

- Jonathan M Davis


Re: Dynamic array void initialization

2011-03-08 Thread Kai Meyer

On 03/08/2011 02:34 PM, Tom wrote:

import std.stdio;

struct S {
int i;
int j;
}

int main(string[] args) {
S[] ss = void;
ss.length = 5;
foreach (ref s; ss)
s = S(1, 2);
return 0;
}

Is the above code correct? (it doesn't work... it blows away or just
give and access violation error).

I need to create a dynamic array of some struct, but don't want defer
contained elements initialization (for performance reasons).

Tom;


Any reason you don't just do this:

S[] ss;
ss.reserve(5)
foreach(i; 0..i)
  ss ~= S(1, 2);

I think that would not do default initialization on any of the elements, 
and it would ensure that the dynamic array is own grown once.


Re: Dynamic array void initialization

2011-03-08 Thread Kai Meyer

On 03/08/2011 05:42 PM, Kai Meyer wrote:

On 03/08/2011 02:34 PM, Tom wrote:

import std.stdio;

struct S {
int i;
int j;
}

int main(string[] args) {
S[] ss = void;
ss.length = 5;
foreach (ref s; ss)
s = S(1, 2);
return 0;
}

Is the above code correct? (it doesn't work... it blows away or just
give and access violation error).

I need to create a dynamic array of some struct, but don't want defer
contained elements initialization (for performance reasons).

Tom;


Any reason you don't just do this:

S[] ss;
ss.reserve(5)
foreach(i; 0..i)
ss ~= S(1, 2);

I think that would not do default initialization on any of the elements,
and it would ensure that the dynamic array is own grown once.


Sorry,
foreach(i; 0..5)

That's what I get for writing code with out trying to run it


Re: Dynamic array void initialization

2011-03-08 Thread Tom

El 08/03/2011 21:42, Kai Meyer escribió:

On 03/08/2011 02:34 PM, Tom wrote:

import std.stdio;

struct S {
int i;
int j;
}

int main(string[] args) {
S[] ss = void;
ss.length = 5;
foreach (ref s; ss)
s = S(1, 2);
return 0;
}

Is the above code correct? (it doesn't work... it blows away or just
give and access violation error).

I need to create a dynamic array of some struct, but don't want defer
contained elements initialization (for performance reasons).

Tom;


Any reason you don't just do this:

S[] ss;
ss.reserve(5)
foreach(i; 0..i)
ss ~= S(1, 2);

I think that would not do default initialization on any of the elements,
and it would ensure that the dynamic array is own grown once.


Nope, you're right. That'll work for me.

Thank you,
Tom;



Re: Some weird crashes

2011-03-08 Thread Bekenn

On 3/8/2011 12:57 PM, simendsjo wrote:


One more thing..
Function pointers in structs.. Should they use extern(Windows) too?


Yes.


Re: Help learning how to interface with c(++)

2011-03-08 Thread Kagamin
Kai Meyer Wrote:

 gcc -m32 -shared -fPIC Test.cpp -o libTest.so

 So I monkeyed around a little bit, and found out that if I change 
 extern (C) to extern (C++), the library links correctly and the 
 program runs.
 
 That lead me to believe that if I added the -cpp option to htod.exe, 
 it would generate extern(C++) functions. But I got a blank Test.d file 
 doing it that way.
 
 So, gcc created a libTest.so with a function in it, and dmd only finds 
 the function with extern(C++) and not with extern(C).
 
 Now I'm just confused, yet pleased something worked.

Because you compile .cpp file, gcc compiles it with g++ as C++ and mangles 
functions accordingly. You can tell gcc to compile the file as C.