function-local template specialization error

2010-07-14 Thread canalpay
void main()
{
T input(T)()
{}
 
T input(T : string)()
{}
}

Error message :

isimsiz.d(6): found 'input' when expecting ';' following statement
isimsiz.d(6): found ':' when expecting ')'
isimsiz.d(6): found 'string' when expecting ';' following statement
isimsiz.d(6): found ')' instead of statement
isimsiz.d(8): unrecognized declaration
 
Shouldn't that work?

And

void main()
{
void input(T)()
{}
 
void input(T : string)()
{}
}

Again, Shouldn't that work?

Error message:
isimsiz.d(6): Error: declaration input(T : string) is already defined

there is no problem when the templates are in the global namespace.


object.reserve() and array size

2010-07-14 Thread Lars T. Kyllingstad
Is object.reserve() only useful for large arrays, or should I always use 
it if I intend to append to an array?

Let's say I want to read some data, and I expect there to be ~100 bytes 
of data.  Is there any point in using reserve() first, or will there 
always be that much memory available to an array?

  byte[] buffer;
  buffer.reserve(100);
  foreach(byte b; dataSource) buffer ~= b;

-Lars



Re: function-local template specialization error

2010-07-14 Thread bearophile
canalpay:
> void main()
> {
> T input(T)()
> {}
>  
> T input(T : string)()
> {}
> }

In D2 you can't define templates inside functions.

Bye,
bearophile


Re: object.reserve() and array size

2010-07-14 Thread Steven Schveighoffer
On Wed, 14 Jul 2010 06:01:10 -0400, Lars T. Kyllingstad  
 wrote:



Is object.reserve() only useful for large arrays, or should I always use
it if I intend to append to an array?

Let's say I want to read some data, and I expect there to be ~100 bytes
of data.  Is there any point in using reserve() first, or will there
always be that much memory available to an array?

  byte[] buffer;
  buffer.reserve(100);
  foreach(byte b; dataSource) buffer ~= b;


Yes, you should always reserve if you know how much data is coming.  If  
you do not here is what happens:


Upon adding the first byte, a block of 16 bytes is allocated
Upon adding the 16th byte (there is one byte for padding), a *new* block  
of 32 bytes is allocated, and the 15 previous bytes are copied to the  
32-byte block.  The original 16 byte block is left allocated because there  
could be other aliases to the data.
Upon adding the 32nd byte, a block of 64 bytes is allocated, rinse and  
repeat.

Upon adding the 64th byte, a block of 128 bytes is allocated, same deal.

Then the block will hold 100 bytes.

If you reserve 100 bytes, then a block of 128 bytes is allocated, and your  
data all goes in there.


OT, I assume you realize that reading data in this way is horribly  
inefficient :)  You should read a block at once if possible.


-Steve


Re: function-local template specialization error

2010-07-14 Thread canalpay
bearophile Wrote:
> In D2 you can't define templates inside functions.
> 
> Bye,
> bearophile

Thanks, But this example works:
void main()
{
T input(T)()
{}

}

 Why ?


Re: object.reserve() and array size

2010-07-14 Thread Lars T. Kyllingstad
On Wed, 14 Jul 2010 10:35:19 -0400, Steven Schveighoffer wrote:

> On Wed, 14 Jul 2010 06:01:10 -0400, Lars T. Kyllingstad
>  wrote:
> 
>> Is object.reserve() only useful for large arrays, or should I always
>> use it if I intend to append to an array?
>>
>> Let's say I want to read some data, and I expect there to be ~100 bytes
>> of data.  Is there any point in using reserve() first, or will there
>> always be that much memory available to an array?
>>
>>   byte[] buffer;
>>   buffer.reserve(100);
>>   foreach(byte b; dataSource) buffer ~= b;
> 
> Yes, you should always reserve if you know how much data is coming.  If
> you do not here is what happens:
> 
> Upon adding the first byte, a block of 16 bytes is allocated Upon adding
> the 16th byte (there is one byte for padding), a *new* block of 32 bytes
> is allocated, and the 15 previous bytes are copied to the 32-byte block.
>  The original 16 byte block is left allocated because there could be
> other aliases to the data.
> Upon adding the 32nd byte, a block of 64 bytes is allocated, rinse and
> repeat.
> Upon adding the 64th byte, a block of 128 bytes is allocated, same deal.
> 
> Then the block will hold 100 bytes.
> 
> If you reserve 100 bytes, then a block of 128 bytes is allocated, and
> your data all goes in there.
> 
> OT, I assume you realize that reading data in this way is horribly
> inefficient :)  You should read a block at once if possible.


Yeah, that was just an artificial example. :)  The actual use case was 
building a string from substrings.

Thanks!

-Lars


Re: function-local template specialization error

2010-07-14 Thread bearophile
canalpay:
> Thanks, But this example works:
> void main()
> {
> T input(T)()
> {}
> 
> }
> 
>  Why ?

You are right. Beside allowing nested functions (this is well known), it seems 
D2 also accepts the definition (with template constraint too) and instantiation 
of simple templates inside functions, I didn't know this.

But currently nested functions can't be overloaded. Probably for similar 
reasons inside a function you can't define more than one template with the same 
name. I presume this limit can be removed, so if you really need this you can 
ask for an enhancement request and if you can add a patch too to increase a bit 
the probability to see it fulfilled someday.

Bye,
bearophile


Some testing?

2010-07-14 Thread bearophile
This small D2 program compiles with no errors:

T foo(T)(T x) {}
void main() {}

But there is no way it can compile, regardless of the type T, because foo()() 
lacks a return statement. 
So is it possible for the D compiler to perform some sanity tests for the 
template functions too, to catch a bugs like this one?

Bye,
bearophile


Re: Some testing?

2010-07-14 Thread Jonathan M Davis
On Wednesday, July 14, 2010 11:55:57 bearophile wrote:
> This small D2 program compiles with no errors:
> 
> T foo(T)(T x) {}
> void main() {}
> 
> But there is no way it can compile, regardless of the type T, because
> foo()() lacks a return statement. So is it possible for the D compiler to
> perform some sanity tests for the template functions too, to catch a bugs
> like this one?
> 
> Bye,
> bearophile

You get an error if you use foo. My guess would be that foo effectively doesn't 
exist until you instantiate it, so there's not really a function to give you an 
error on.

- Jonathan M Davis


Re: Some testing?

2010-07-14 Thread Mafi

Am 14.07.2010 20:55, schrieb bearophile:

This small D2 program compiles with no errors:

T foo(T)(T x) {}
void main() {}

But there is no way it can compile, regardless of the type T, because foo()() 
lacks a return statement.
So is it possible for the D compiler to perform some sanity tests for the 
template functions too, to catch a bugs like this one?


Imagine T was void. Then no return was ok. It wouldn't (shouldn't) 
compile anyways because a parameter of type void is (should be) invalid. 
However to enforce the compiler to see that T can't be void is a bit to 
complicated, I think.


Mafi



Re: function-local template specialization error

2010-07-14 Thread Don

bearophile wrote:

canalpay:

Thanks, But this example works:
void main()
{
T input(T)()
{}

}

 Why ?


You are right. Beside allowing nested functions (this is well known), it seems 
D2 also accepts the definition (with template constraint too) and instantiation 
of simple templates inside functions, I didn't know this.

But currently nested functions can't be overloaded. Probably for similar 
reasons inside a function you can't define more than one template with the same 
name. I presume this limit can be removed, so if you really need this you can 
ask for an enhancement request and if you can add a patch too to increase a bit 
the probability to see it fulfilled someday.

Bye,
bearophile


The spec explicitly says:
"Unlike module level declarations, declarations within function scope 
are processed in order. This means that two nested functions cannot 
mutually call each other:


[snip]

Future directions: This restriction may be removed."

My guess is that it will become possible eventually.


Re: Some testing?

2010-07-14 Thread Don

bearophile wrote:

This small D2 program compiles with no errors:

T foo(T)(T x) {}
void main() {}

But there is no way it can compile, regardless of the type T, because foo()() lacks a return statement. 
So is it possible for the D compiler to perform some sanity tests for the template functions too, to catch a bugs like this one?


Bye,
bearophile


Yes, it'd be possible for such simple cases, but would it be worthwhile?
Since an error message will occur for ANY instantiation of foo, the only 
errors that would catch are when there's absolutely no testing or use of 
foo. In which case you have much bigger problems.
And unfortunately it doesn't scale to more complex situations where it 
might actually help.


Re: Some testing?

2010-07-14 Thread bearophile
Mafi:
> Imagine T was void. Then no return was ok. It wouldn't (shouldn't) 
> compile anyways because a parameter of type void is (should be) invalid. 
> However to enforce the compiler to see that T can't be void is a bit to 
> complicated, I think.

You are right, this different version runs:

T foo(T)() {}
void main() {
foo!void();
}

Thanks for all the answers, to you, Don and Jonathan.
A question like this was probably more at home in the IRC channel.

Bye,
bearophile


Re: Multi dimensional array question.

2010-07-14 Thread Heywood Floyd
Lars T. Kyllingstad Wrote:

> 
> But then arrays would be different from all other types!  If you have an 
> array of 3 Ts, that is written T[3], regardless of what T is.  Now 
> consider these two cases:
> 
>A. T is an int.  Then T[3] becomes int[3].
> 
>B. T is an int[string].  Then T[3] becomes int[string][3].
> 
> In case A, the first element of the array is accessed like this:
> 
>int[3] a;
>int firstA = a[0];
> 
> Since a is an array of int, firstA is of course an int.
> 
> But then, since b is an array of int[string], we have
> 
>int[string][3] b;
>int[string] firstB = b[0];
> 
> If we again want to access element "foo" of the associative array which 
> is firstB, we write firstB["foo"].  And so we have the following three 
> ways to get to that element, which *must* be equivalent because that's 
> how the language is defined:
> 
>// Using firstB as an intermediate step
>int[string] firstB = b[0];
>int x = firstB["foo"];
> 
>// Drop the intermediate variable firstB
>int x = (b[0])["foo"];
> 
>// Drop the redundant parentheses
>int x = b[0]["foo"];
> 
> So you see, it can't be any other way than the way it is. :)
> 
> -Lars

Thank you for the elaborate answer!

When you put it like that, it does make sense. But I'm sorry. I refuse. The 
reason I refuse is those examples are void of any higher semantic meaning. Once 
we add a semantic meaning, it simply becomes backwards:

int[MAX_WIDTH][MAX_HEIGHT] map2d;
map2d[x][y] = 9; // Wrong!

At least in my head, this is cognitive dissonance. To me, the language acts as 
if it's low-level semantics outweighs my high-level semantics and I should 
correct my thinking for that. I refuse! Seems to me it could just as well work 
as:

int[string][3] b;
int[3] firstB = b["foo"];
int i = firstB[0];
int j = (b["foo"])[0];
int k = b["foo"][0];

But I feel like I'm the only one feeling this, so I'll just let it go and hope 
my dear C-style arrays stay in :)

BR
/HF

PS. Never thought I'd find a reason to love C.. DS.



Re: Multi dimensional array question.

2010-07-14 Thread Jonathan M Davis
On Wednesday, July 14, 2010 13:57:13 Heywood Floyd wrote:
> 
> Thank you for the elaborate answer!
> 
> When you put it like that, it does make sense. But I'm sorry. I refuse. The
> reason I refuse is those examples are void of any higher semantic meaning.
> Once we add a semantic meaning, it simply becomes backwards:
> 
> int[MAX_WIDTH][MAX_HEIGHT] map2d;
> map2d[x][y] = 9; // Wrong!
> 
> At least in my head, this is cognitive dissonance. To me, the language acts
> as if it's low-level semantics outweighs my high-level semantics and I
> should correct my thinking for that. I refuse! Seems to me it could just
> as well work as:
> 
> int[string][3] b;
> int[3] firstB = b["foo"];
> int i = firstB[0];
> int j = (b["foo"])[0];
> int k = b["foo"][0];
> 
> But I feel like I'm the only one feeling this, so I'll just let it go and
> hope my dear C-style arrays stay in :)
> 
> BR
> /HF
> 
> PS. Never thought I'd find a reason to love C.. DS.

Personally, I don't like it, but I also don't think that it necessarily makes 
sense to change it. From the point of view of how the compiler deduces types, 
it's exactly how it should work. The problem, of course, is that it doesn't 
match how we think. However, in order for us to be able to deduce complicated 
types, the compiler must be totally consistent in how it deduces the type. A 
prime example would be function pointers (particularly using the C syntax). To 
be able to pick it apart properly, you're going to have to understand how the 
compiler does it. The type is complicated enough that you're stuck. To read 
arrays in the reverse order that is done now, you'd have to read everything 
else 
in the reverse order to be consistent, which would really mean types like this:

[5](int) const a;

The whole thing is ugly. There's no question of that. But to "fix" it breaks 
other stuff. Types are read right to left. Being consistent with that makes it 
possible to understand more complicated types. The downside is that some 
simpler 
types become harder to understand. However, as long as you use dynamic arrays, 
this really isn't a problem.

int[][] a = new int[][](MAX_WIDTH, MAX_HEIGHT);

is totally clear and it works in the order that you think. The problem is when 
you use statically-allocated arrays. Personally, I'd advise you to just use 
dynamic arrays unless you do some profiling and find that a static array is 
better 
in a particular case. Doing things that way makes it so that the weird ordering 
in declarations isn't generally a problem.

I agree that this particular syntactic faux pas is a problem, but I don't think 
that anyone has come up with an appropriate solution. Simply reversing how it 
works now would make reading more complex types much harder. A more complex 
solution would likely be required. As it stands, it's a problem, but it's only 
a 
problem if you're declaring statically-allocated arrays. It's unpleasant, but 
it 
should be manageable.

- Jonathan M Davis


Best practice and module declarations

2010-07-14 Thread Jonathan M Davis
I was wondering what the general consesus was (if there is one) on whether it's 
valuable to always put module declarations in each module.

Obviously, if you need the module to have a name other than the file name, then 
you need to have the module declaration. However, is it necessarily desirable 
to 
have it when the module name matches the file name? Or would there even be a 
reason for it to be desirable _not_ to have the module declaration?

I can't think of any particularly strong reasons to have it or not to have it. 
My first reaction is to just always use it, but thinking about it, I'm not sure 
that there's really much point if the file name and the module name already 
match. Does anyone have reasons why it would matter other than personal 
preference?

- Jonathan M Davis


Re: Best practice and module declarations

2010-07-14 Thread torhu

On 15.07.2010 00:22, Jonathan M Davis wrote:

I was wondering what the general consesus was (if there is one) on whether it's
valuable to always put module declarations in each module.

Obviously, if you need the module to have a name other than the file name, then
you need to have the module declaration. However, is it necessarily desirable to
have it when the module name matches the file name? Or would there even be a
reason for it to be desirable _not_ to have the module declaration?

I can't think of any particularly strong reasons to have it or not to have it.
My first reaction is to just always use it, but thinking about it, I'm not sure
that there's really much point if the file name and the module name already
match. Does anyone have reasons why it would matter other than personal
preference?


Some of the D build tools complain if you don't use module declarations. 
 And IIRC, modules in subdirectories (packages) need to have them.  So 
I end up adding them for anything but single-file test programs.


CT usage only in executable

2010-07-14 Thread strtr
Not that the memory is really significant compared to the rest of my program,
but I have a few fairly large arrays I use only in compile time and I was
wondering why dmd still includes those in the executable (simple text search
dug them up).


Re: CT usage only in executable

2010-07-14 Thread bearophile
strtr:
> Not that the memory is really significant compared to the rest of my program,
> but I have a few fairly large arrays I use only in compile time and I was
> wondering why dmd still includes those in the executable (simple text search
> dug them up).

Are you able to create a smallish test case?

Bye,
bearophile


Re: CT usage only in executable

2010-07-14 Thread strtr
== Quote from bearophile (bearophileh...@lycos.com)'s article
> strtr:
> > Not that the memory is really significant compared to the rest of my 
> > program,
> > but I have a few fairly large arrays I use only in compile time and I was
> > wondering why dmd still includes those in the executable (simple text search
> > dug them up).
> Are you able to create a smallish test case?
> Bye,
> bearophile


module main;

const char[] CT_STRING = "int i=0;";

void main(){
mixin( CT_STRING );
}

The string can be found in the executable.



Is synchronized(mutex) == mutex.lock()?

2010-07-14 Thread Heywood Floyd
Hi!

Breakfast toast: Is there any chance a) and b) below are identical in what they 
do?


auto mutex = new Mutex();
auto cond = new Condition(mutex);

// a)
synchronized(mutex){
   cond.wait();
}

// b)
mutex.lock();
   cond.wait();
mutex.unlock();


I was sprinkling my code with mutex.lock/unlock (for fun) when suddenly I 
realized that, hey, maybe synchronized would work just as well, and be even 
more fun? (If that's even possible.)

BR
/HF