Re: retro() on a `string` creates a range of `dchar`, causing array() pains

2012-04-17 Thread Jakob Ovrum

On Tuesday, 17 April 2012 at 15:18:49 UTC, bearophile wrote:

Jakob Ovrum:


return array(strippedTail);
}

The type of the return expression is dstring, not string.

What is the most elegant way or correct way to solve this 
friction?


(Note: the function is used in CTFE)


Try "text" instead of "array".

Bye,
bearophile


Thanks, that did it :)

(I also forgot to retro() a second time to make it build the 
array in the original direction, before anyone points it out)


Re: retro() on a `string` creates a range of `dchar`, causing array() pains

2012-04-17 Thread Jakob Ovrum

On Tuesday, 17 April 2012 at 15:36:39 UTC, Ali Çehreli wrote:


The reason is, a sequence of UTF-8 code units are not a valid 
UTF-8 when reversed (or retro'ed :p). But a dchar array can be 
reversed.


Ali


It is absolutely possible to walk a UTF-8 string backwards.

The problem here is that arrays of char are ranges of dchar; 
hence you can't go the regular generic path and have to use 
text() instead.


Re: Not-so-unpredictable seed?

2012-04-17 Thread jerro
On Wednesday, 18 April 2012 at 05:05:20 UTC, Joseph Rushton 
Wakeling wrote:

On 18/04/12 06:43, jerro wrote:

According to the comment the call to prime() is necessary
so that the result doesn't always start with the same element.
But prime() uses the gen member which is only assigned after 
the
constructor completes. So at the time when prime() is called 
the

gen member is in some default state, so the prime() call in the
constructor always does the same thing. The fix would be to
either modify the constructor to take random generator as a
parameter if Random type parameter is not void, or to move the
call to prime() out of constructor and into all the 
randomSample

functions. In the ones that have a random generator parameter,
the call to prime should come after gen is asigned.


Ahhh, clear.  I should have worked that out from the code, 
brain not working right today. :-P


It still looks like a serious bug to me, so I've filed a report.
http://d.puremagic.com/issues/show_bug.cgi?id=7936


Well, off course it's a bug :D. I opened a pull request:

https://github.com/D-Programming-Language/phobos/pull/542



Re: Not-so-unpredictable seed?

2012-04-17 Thread Joseph Rushton Wakeling

On 18/04/12 06:43, jerro wrote:

According to the comment the call to prime() is necessary
so that the result doesn't always start with the same element.
But prime() uses the gen member which is only assigned after the
constructor completes. So at the time when prime() is called the
gen member is in some default state, so the prime() call in the
constructor always does the same thing. The fix would be to
either modify the constructor to take random generator as a
parameter if Random type parameter is not void, or to move the
call to prime() out of constructor and into all the randomSample
functions. In the ones that have a random generator parameter,
the call to prime should come after gen is asigned.


Ahhh, clear.  I should have worked that out from the code, brain not working 
right today. :-P


It still looks like a serious bug to me, so I've filed a report.
http://d.puremagic.com/issues/show_bug.cgi?id=7936




Re: Not-so-unpredictable seed?

2012-04-17 Thread jerro

On Wednesday, 18 April 2012 at 03:47:31 UTC, Joseph Rushton
Wakeling wrote:
Can anyone explain to me why, when I compile & run this code, 
the two samples seeded with the unpredictableSeed always come 
out with the same starting value?


//
import std.random, std.range, std.stdio;

void main()
{
auto s = randomSample(iota(0, 100), 5);

foreach(uint i; s)
writeln(i);

writeln();

auto s2 = randomSample(iota(0, 100), 5);

foreach(uint i; s2)
writeln(i);

writeln();

auto urng3 = Random(unpredictableSeed);
auto s3 = randomSample(iota(0, 100), 5, urng3);

foreach(uint i; s3)
writeln(i);

writeln();

auto urng4 = Random(unpredictableSeed);
auto s4 = randomSample(iota(0, 100), 5, urng4);

foreach(uint i; s4)
writeln(i);
}
//

In fact it's not just the unpredictable seed -- no matter what 
seed I pass, so long as an RNG is passed to the randomSample 
function, the first entry is always the same.


Note that this is Phobos' randomSample, not my tweaked 
implementation.


Anyone got any ideas?


When you pass in your own random generator, you use this function:

auto randomSample(R, Random)(R r, size_t n, Random gen)
if (isInputRange!R && hasLength!R && isUniformRNG!Random)
{
 auto ret = RandomSample!(R, Random)(r, n, r.length);
 ret.gen = gen;
 return ret;
}

which calls this constructor:

this(R input, size_t howMany, size_t total)
{
 _input = input;
 _available = total;
 _toSelect = howMany;
 enforce(_toSelect <= _available);
 // we should skip some elements initially so we don't always
 // start with the first
 prime();
}

According to the comment the call to prime() is necessary
so that the result doesn't always start with the same element.
But prime() uses the gen member which is only assigned after the
constructor completes. At the time when prime() is called the
gen member is in some default state, so the prime() call in the
constructor always does the same thing. The fix would be to
either modify the constructor to take random generator as a
parameter if Random type parameter is not void, or to move the
call to prime() out of constructor and into all the randomSample
functions. In the ones that have a random generator parameter,
the call to prime should come after gen is asigned.


Re: appending newly initialized struct to array

2012-04-17 Thread Ali Çehreli

On 04/17/2012 02:00 PM, simendsjo wrote:

> Sounds like a bug. C style initializers work in other cases:

I try not to use them. I think they have this 'feature' of leaving 
unspecified members uninitialized:


struct S
{
int i;
double d;
}

void main()
{
S s = { 42 };   // <-- no initializer for S.d
assert(s.i == 42);
assert(s.d == double.nan);  // <-- fails (may work for you)
}

Is that a bug or a feature? I might have opened it but I don't remember 
now. :)


Ali



Re: Not-so-unpredictable seed?

2012-04-17 Thread jerro

On Wednesday, 18 April 2012 at 03:47:31 UTC, Joseph Rushton
Wakeling wrote:
Can anyone explain to me why, when I compile & run this code, 
the two samples seeded with the unpredictableSeed always come 
out with the same starting value?


//
import std.random, std.range, std.stdio;

void main()
{
auto s = randomSample(iota(0, 100), 5);

foreach(uint i; s)
writeln(i);

writeln();

auto s2 = randomSample(iota(0, 100), 5);

foreach(uint i; s2)
writeln(i);

writeln();

auto urng3 = Random(unpredictableSeed);
auto s3 = randomSample(iota(0, 100), 5, urng3);

foreach(uint i; s3)
writeln(i);

writeln();

auto urng4 = Random(unpredictableSeed);
auto s4 = randomSample(iota(0, 100), 5, urng4);

foreach(uint i; s4)
writeln(i);
}
//

In fact it's not just the unpredictable seed -- no matter what 
seed I pass, so long as an RNG is passed to the randomSample 
function, the first entry is always the same.


Note that this is Phobos' randomSample, not my tweaked 
implementation.


Anyone got any ideas?


When you pass in your own random generator, you use this function:

auto randomSample(R, Random)(R r, size_t n, Random gen)
if (isInputRange!R && hasLength!R && isUniformRNG!Random)
{
  auto ret = RandomSample!(R, Random)(r, n, r.length);
  ret.gen = gen;
  return ret;
}

which calls this constructor:

this(R input, size_t howMany, size_t total)
{
  _input = input;
  _available = total;
  _toSelect = howMany;
  enforce(_toSelect <= _available);
  // we should skip some elements initially so we don't always
  // start with the first
  prime();
}

According to the comment the call to prime() is necessary
so that the result doesn't always start with the same element.
But prime() uses the gen member which is only assigned after the
constructor completes. So at the time when prime() is called the
gen member is in some default state, so the prime() call in the
constructor always does the same thing. The fix would be to
either modify the constructor to take random generator as a
parameter if Random type parameter is not void, or to move the
call to prime() out of constructor and into all the randomSample
functions. In the ones that have a random generator parameter,
the call to prime should come after gen is asigned.


Not-so-unpredictable seed?

2012-04-17 Thread Joseph Rushton Wakeling
Can anyone explain to me why, when I compile & run this code, the two samples 
seeded with the unpredictableSeed always come out with the same starting value?


//
import std.random, std.range, std.stdio;

void main()
{
auto s = randomSample(iota(0, 100), 5);

foreach(uint i; s)
writeln(i);

writeln();

auto s2 = randomSample(iota(0, 100), 5);

foreach(uint i; s2)
writeln(i);

writeln();

auto urng3 = Random(unpredictableSeed);
auto s3 = randomSample(iota(0, 100), 5, urng3);

foreach(uint i; s3)
writeln(i);

writeln();

auto urng4 = Random(unpredictableSeed);
auto s4 = randomSample(iota(0, 100), 5, urng4);

foreach(uint i; s4)
writeln(i);
}
//

In fact it's not just the unpredictable seed -- no matter what seed I pass, so 
long as an RNG is passed to the randomSample function, the first entry is always 
the same.


Note that this is Phobos' randomSample, not my tweaked implementation.

Anyone got any ideas?


Re: appending newly initialized struct to array

2012-04-17 Thread Kenji Hara

On Tuesday, 17 April 2012 at 21:00:55 UTC, simendsjo wrote:
On Tue, 17 Apr 2012 22:28:31 +0200, maarten van damme 
 wrote:


Just for fun I decided to complete some codejam challenges in 
D. At some
point I wanted to add structs to an array but I got a compiler 
error. What

am I doing wrong?

code:
struct test{
int x;
int y;
}
void main(){
test[] why;
why~={3,5};
}

error:
wait.d(7): found '}' when expecting ';' following statement
wait.d(8): found 'EOF' when expecting ';' following statement
wait.d(8): found 'EOF' when expecting '}' following compound 
statement


Is there any reason a why this wouldn't work?


Sounds like a bug. C style initializers work in other cases:

struct S { int i; }
void main() {
S[] arr;
S s = { 1 };
arr ~= S(1);
// But the following barfs
//arr ~= { 1 };
//arr ~= { i:1 };
//arr[0] = { 1 };
}


No, it is designed. {3,5} is struct initializer:
http://dlang.org/declaration.html#StructInitializer
And it is only allowed in initializer of variable declarations.


why~={3,5};


This is concat assign expression, so you should use test(3,5)
instead of {3,5}. That is StructLiteral:
http://dlang.org/struct.html#StructLiteral
and it is an expression.

Bye.

Kenji Hara


Re: Sampling algorithms for D

2012-04-17 Thread Joseph Rushton Wakeling

On 13/04/12 10:04, Dmitry Olshansky wrote:

OK, I'll see what I can do. I'd like to discuss and refine the design a
bit further before making any pull request -- should I take things over
to the Phobos mailing list for this ... ?


I'm no authority but there is this d.D newsgroup which is perfectly fine for
this kind of thing. A lot of nice people just don't (have time to) mess with
unwashed masses in D.learn :)


Tweaked version, an revision of RandomSample from std.random, is available from
https://github.com/WebDrake/RandomSample

Feedback on code details and on tests would be very welcome.  It seems about 10% 
slower than the original code I wrote, which I guess is down to factors in the 
design of the RandomSample struct.


Re: Aquivalent References as in C++?

2012-04-17 Thread bearophile

Namespace:
Another idea: instead scope, "in" can get a new functionality. 
Instead as a synonym for "const" it could mean "not null" for 
objects.


Note that currently in D2 "in" means "scope const".

Bye,
bearophile


Re: Aquivalent References as in C++?

2012-04-17 Thread Namespace
Another idea: instead scope, "in" can get a new functionality. 
Instead as a synonym for "const" it could mean "not null" for 
objects.


Re: appending newly initialized struct to array

2012-04-17 Thread bearophile

simendsjo:


Sounds like a bug. C style initializers work in other cases:


D language is so much irregular, so many special cases that don't 
work :-)


Bye,
bearophile


Re: appending newly initialized struct to array

2012-04-17 Thread simendsjo
On Tue, 17 Apr 2012 22:28:31 +0200, maarten van damme  
 wrote:



Just for fun I decided to complete some codejam challenges in D. At some
point I wanted to add structs to an array but I got a compiler error.  
What

am I doing wrong?

code:
struct test{
int x;
int y;
}
void main(){
test[] why;
why~={3,5};
}

error:
wait.d(7): found '}' when expecting ';' following statement
wait.d(8): found 'EOF' when expecting ';' following statement
wait.d(8): found 'EOF' when expecting '}' following compound statement

Is there any reason a why this wouldn't work?


Sounds like a bug. C style initializers work in other cases:

struct S { int i; }
void main() {
S[] arr;
S s = { 1 };
arr ~= S(1);
// But the following barfs
//arr ~= { 1 };
//arr ~= { i:1 };
//arr[0] = { 1 };
}


Re: appending newly initialized struct to array

2012-04-17 Thread H. S. Teoh
On Tue, Apr 17, 2012 at 10:28:31PM +0200, maarten van damme wrote:
> Just for fun I decided to complete some codejam challenges in D. At
> some point I wanted to add structs to an array but I got a compiler
> error. What am I doing wrong?
> 
> code:
> struct test{
> int x;
> int y;
> }
> void main(){
> test[] why;
> why~={3,5};
> }
> 
> error:
> wait.d(7): found '}' when expecting ';' following statement
> wait.d(8): found 'EOF' when expecting ';' following statement
> wait.d(8): found 'EOF' when expecting '}' following compound statement
> 
> Is there any reason a why this wouldn't work?

Try this:

why ~= test(3,5);


T

-- 
Tell me and I forget. Teach me and I remember. Involve me and I understand. -- 
Benjamin Franklin


Re: Metaprogramming work around

2012-04-17 Thread Erèbe

On Tuesday, 17 April 2012 at 12:46:28 UTC, Kenji Hara wrote:

On Tuesday, 17 April 2012 at 12:04:44 UTC, Erèbe wrote:
[snip]


There is something I still don't understand :

mixin template Foo( T... )
{
//Code here
}

mixin Foo!( "Hello", "Word" ); < Good


T is TemplateTypeParameter, and matches any kind of template 
arguments - types, values, and symbols. The both arguments 
"Hello" and "World" are values, so you can bind them with T.


http://dlang.org/template.html#TemplateTupleParameter




"mixin template Foo( A, T... )
{
//code here
}

mixin Foo!( "Hello", "Word" ); <--- Fail !
mixin Foo!( string, "Word" ); < Good



'A' is TemplateTypeParameter, and it matches only types. In the 
first instantiation of Foo, A doesn't match with the value 
"hello".
In the second instantiation, string is type, and T matches with 
it.


http://dlang.org/template.html#TemplateTypeParameter


mixin template Foo( alias A, T... )
{
//code here
}

mixin Foo!( "Hello", "world" ); <--- Good
mixin Foo!( string, "world" ); <--- Fail !

-


'alias A' is TemplateAliasParameter, and it matches both 
symbols and values.
Then A matches with the value "Hello", but doesn't with the 
type string.
(string is an aliased name of immutable(char)[], and it is 
built-in array type.)


http://dlang.org/template.html#TemplateAliasParameter

Kenji Hara



Thanks a lot Kenji Hara,
I have a better understanding of it now !




Re: retro() on a `string` creates a range of `dchar`, causing array()

2012-04-17 Thread bearophile

Ali Çehreli:


Agreed.

But I am not that sure about this particular function anymore 
because for the function to be not 'strongly exception safe', 
the input string must be invalid UTF-8 to begin with.


I am not sure how bad it is to not preserve the actual 
invalidness of the string in that case. :)


I see. This is a matter of design. I see some possible solutions:
1) Do nothing, assume input is well-formed UTF-8, otherwise 
output will be wrong (or it will throw an exception unsafely). 
This is what Phobos may be doing in this case.
2) Put a UTF validate inside the function pre-condition if the 
input is a narrow string. This will slow down code in non-release 
mode, maybe too much.
3) Use a stronger type system, that enforces pre-conditions and 
post-conditions in a smarter way. This means if the return value 
of a function that has 'validate' inside its post-condition is 
given as input to a function that has 'validate' inside its 
pre-condition, the validate is run only once even in non-release 
mode. Generally if you use many string functions this leads to 
the saving of lot of 'validate' functions. This solution is 
appreciated by Eiffel languages.
4) Use two different types, one for validated UTF-8 and one for 
unvalidated UTF-8. Unless you have bad bugs in your code this 
will avoid most calls to 'validate'. This solution is very simple 
because it doesn't require a smart compiler, and it's appreciated 
in languages like Haskell (example, see: http://www.yesodweb.com/ 
).


Bye,
bearophile


appending newly initialized struct to array

2012-04-17 Thread maarten van damme
Just for fun I decided to complete some codejam challenges in D. At some
point I wanted to add structs to an array but I got a compiler error. What
am I doing wrong?

code:
struct test{
int x;
int y;
}
void main(){
test[] why;
why~={3,5};
}

error:
wait.d(7): found '}' when expecting ';' following statement
wait.d(8): found 'EOF' when expecting ';' following statement
wait.d(8): found 'EOF' when expecting '}' following compound statement

Is there any reason a why this wouldn't work?


Re: Aquivalent References as in C++?

2012-04-17 Thread Namespace

On Tuesday, 17 April 2012 at 19:56:11 UTC, Timon Gehr wrote:

On 04/17/2012 09:16 PM, Namespace wrote:

But C++ does not do that either.
Are you asking for a full-blown non-null type system?


Yes, but of course only with a special Keyword/Storage class.


If it is not the default, how would you enforce it at the 
caller side?


By the compiler who throws an error message or a warning.
A warning or a better error message would help also, if a 
null-reference was in use.
But only the message "Access violation" without any information 
isn't enough, imo.


It seems that not-null references wouldn't be a part of D in near 
future.


Re: retro() on a `string` creates a range of `dchar`, causing array()

2012-04-17 Thread Ali Çehreli

On 04/17/2012 12:57 PM, bearophile wrote:

>> The algorithm
>> above is not exception-safe because stride() may throw. But this way off
>> topic on this thread. :)
>

> You can't expect Phobos to be perfect, it needs to be improved
> iteratively. If you think that's not exception safe and and there are 
simple
> means to do it, then please add this in Bugzilla. Being formally 
aware of a

> problem is the second step toward improving the situation.

Agreed.

But I am not that sure about this particular function anymore because 
for the function to be not 'strongly exception safe', the input string 
must be invalid UTF-8 to begin with.


I am not sure how bad it is to not preserve the actual invalidness of 
the string in that case. :)


Ali



Re: retro() on a `string` creates a range of `dchar`, causing array()

2012-04-17 Thread bearophile
Ali:

> The algorithm is smart.

The basic idea for that algorithm was mine, and Andrei was very gentle to 
implement it, defining it a "Very fun exercise" :-)
http://d.puremagic.com/issues/show_bug.cgi?id=7086


> The algorithm
> above is not exception-safe because stride() may throw. But this way off 
> topic on this thread. :)

You can't expect Phobos to be perfect, it needs to be improved iteratively. If 
you think that's not exception safe and and there are simple means to do it, 
then please add this in Bugzilla. Being formally aware of a problem is the 
second step toward improving the situation.

Bye,
bearophile


Re: Aquivalent References as in C++?

2012-04-17 Thread Timon Gehr

On 04/17/2012 09:16 PM, Namespace wrote:

But C++ does not do that either.
Are you asking for a full-blown non-null type system?


Yes, but of course only with a special Keyword/Storage class.


If it is not the default, how would you enforce it at the caller side?


Re: Hacking on Phobos

2012-04-17 Thread Dmitry Olshansky

On 17.04.2012 23:27, Joseph Rushton Wakeling wrote:

On 17/04/12 20:29, Dmitry Olshansky wrote:

First things first - development of phobos is done with dmd. Just
because gdc is
(logically so) somewhat behind dmd and new compiler features are still
coming
with every release.


Fair enough. I've followed the instructions here:
https://xtzgzorex.wordpress.com/2011/07/31/d-building-dmd-and-phobos-on-linux/



I suggest to just modify phobos sources directly. It's DVCS after all
so you
always have a luxury of commit/revert.


I want to do some side-by-side tests of current and new, so it makes
sense to just have a myrandom.d.


and rdmd --main -unittest /path/to/std/random.d
works wonders in development cycle.


Oddly enough building rdmd with my newly-build dmd results in error:


Just feed it -d switch ;)
Still somebody has to step up and upgrade rdmd to use the new way of Phobos.


--
Dmitry Olshansky


Re: Hacking on Phobos

2012-04-17 Thread Joseph Rushton Wakeling

On 17/04/12 20:47, H. S. Teoh wrote:

The convention is to create a branch for making changes, this way it's
very easy to generate pull requests on github if you ever wanted to
contribute your code to the official codebase. Branches are super-cheap
in git anyway, and you can edit source files to your heart's content
since you can easily switch back to master if you mess something up.


Yea, I know; normally I would, but I want to do some side-by-side tests of the 
new and old RandomSample class, and it seems like a PITA to have to go through 
checkout-compile-copy to /usr/local/lib/-etc.etc. to do comparisons.


Yes, there are unittests and (once I compile rdmd successfully:-) I can probably 
use these, but in the short term it seems simpler to just make a new file 
containing the bits I need and tweak it there.




Re: Hacking on Phobos

2012-04-17 Thread Joseph Rushton Wakeling

On 17/04/12 20:29, Dmitry Olshansky wrote:

First things first - development of phobos is done with dmd. Just because gdc is
(logically so) somewhat behind dmd and new compiler features are still coming
with every release.


Fair enough.  I've followed the instructions here:
https://xtzgzorex.wordpress.com/2011/07/31/d-building-dmd-and-phobos-on-linux/


I suggest to just modify phobos sources directly. It's DVCS after all so you
always have a luxury of commit/revert.


I want to do some side-by-side tests of current and new, so it makes sense to 
just have a myrandom.d.



and rdmd --main -unittest /path/to/std/random.d
works wonders in development cycle.


Oddly enough building rdmd with my newly-build dmd results in error:

rdmd.d(197): Error: function std.path.rel2abs!().rel2abs is deprecated
/usr/local/include/d2/std/algorithm.d(4226): Error: template 
std.algorithm.endsWith does not match any function template declaration
/usr/local/include/d2/std/algorithm.d(4184): Error: template 
std.algorithm.endsWith cannot deduce template function from argument types !("a 
== b")(string,string,string,string,string)
/usr/local/include/d2/std/algorithm.d(4226): Error: template instance 
endsWith!("a == b") errors instantiating template
/usr/local/include/d2/std/algorithm.d(4226): Error: template 
std.algorithm.endsWith does not match any function template declaration
/usr/local/include/d2/std/algorithm.d(4184): Error: template 
std.algorithm.endsWith cannot deduce template function from argument types !("a 
== b")(string,string,string,string,string)
/usr/local/include/d2/std/algorithm.d(4226): Error: template instance 
endsWith!("a == b") errors instantiating template
/usr/local/include/d2/std/algorithm.d(4226): Error: template 
std.algorithm.endsWith does not match any function template declaration
/usr/local/include/d2/std/algorithm.d(4184): Error: template 
std.algorithm.endsWith cannot deduce template function from argument types !("a 
== b")(string,string,string,string,string)
/usr/local/include/d2/std/algorithm.d(4226): Error: template instance 
endsWith!("a == b") errors instantiating template
/usr/local/include/d2/std/algorithm.d(4226): Error: template 
std.algorithm.endsWith does not match any function template declaration
/usr/local/include/d2/std/algorithm.d(4184): Error: template 
std.algorithm.endsWith cannot deduce template function from argument types !("a 
== b")(string,string,string,string,string)
/usr/local/include/d2/std/algorithm.d(4226): Error: template instance 
endsWith!("a == b") errors instantiating template
/usr/local/include/d2/std/algorithm.d(4226): Error: template 
std.algorithm.endsWith does not match any function template declaration
/usr/local/include/d2/std/algorithm.d(4184): Error: template 
std.algorithm.endsWith cannot deduce template function from argument types !("a 
== b")(string,string,string,string,string)
/usr/local/include/d2/std/algorithm.d(4226): Error: template instance 
endsWith!("a == b") errors instantiating template




Re: Aquivalent References as in C++?

2012-04-17 Thread Namespace

But C++ does not do that either.
Are you asking for a full-blown non-null type system?


Yes, but of course only with a special Keyword/Storage class.


Re: Aquivalent References as in C++?

2012-04-17 Thread Timon Gehr

On 04/17/2012 08:40 PM, Namespace wrote:

Define 'ensure'.


Guarantee, that the given object parameter isn't a null reference.


But C++ does not do that either.
Are you asking for a full-blown non-null type system?


Re: Hacking on Phobos

2012-04-17 Thread H. S. Teoh
On Tue, Apr 17, 2012 at 10:29:24PM +0400, Dmitry Olshansky wrote:
> On 17.04.2012 22:10, Joseph Rushton Wakeling wrote:
> >Hello all,
> >
> >As per earlier discussion I'm trying to hack on Phobos to update the
> >random sampling code.
> >
> >To do this I've just copied random.d into a new file, randomsample.d,
> >which I'm modifying and messing around with; I'm trying to build against
> >a local copy of the GitHub Phobos sources.
> >
> >When I try and compile,
> >
> >gdc -nophoboslib -I../phobos/ -o randomsample randomsample.d
> >
> 
> First things first - development of phobos is done with dmd. Just
> because gdc is (logically so) somewhat behind dmd and new compiler
> features are still coming with every release.
> 
> The process usually involves git cloning dmd, druntime and phobos.
> Then building all of them in the order of dmd, druntime, phobos.
> The the tricky part is replacing older binaries and library.

You can just edit /etc/dmd.conf to that effect (if it conflicts with
your stable version of dmd, you could try to change the git dmd source
to look for dmd.conf in a different place, say /usr/src/d-devel/dmd.conf
or something, and so you can completely isolate the two installations).


> After fresh cutting phobos edge builts make sure Phobos unittests
> all pass (make -fposix.mak unittest).
> I suggest to just modify phobos sources directly. It's DVCS after
> all so you always have a luxury of commit/revert.

The convention is to create a branch for making changes, this way it's
very easy to generate pull requests on github if you ever wanted to
contribute your code to the official codebase. Branches are super-cheap
in git anyway, and you can edit source files to your heart's content
since you can easily switch back to master if you mess something up.


T

-- 
My program has no bugs! Only unintentional features...


Re: Aquivalent References as in C++?

2012-04-17 Thread Namespace

Define 'ensure'.


Guarantee, that the given object parameter isn't a null reference.


Re: Templates in classes => what is wrong?

2012-04-17 Thread Xan

On Tuesday, 17 April 2012 at 18:25:21 UTC, Ali Çehreli wrote:

On 04/17/2012 11:13 AM, Xan wrote:

> The idea is behind this https://gist.github.com/2407923
> But I receive:
>
> $ gdmd-4.6 algorisme_code.d
> algorisme_code.d:22: Error: variable codi cannot be read at
compile time
> algorisme_code.d:22: Error: argument to mixin must be a
string, not (codi)

mixin is about code generation. For that reason the string that 
is given to it must be available at compile time. Upon 
analyzing the code, that is the case in your example, but 
because mixin() appears inside the constructor, it cannot use a 
string parameter.


That's why I had used a template parameter for the function 
string. There may be a number of solutions but only you can 
decide on what to do. One solution is to mixin the delegate 
outside of the constructor and pass as an argument along with 
its string representation:


// Untested code
this(... Funcio funcio, string funcioText) {
...
}

In main:

enum funcioText = "...";
auto funcio = mixin(funcioText);

... new Algorisme(..., funcio, funcioText);

Ali


What is change is this code? Is it the same as this 
https://gist.github.com/2407923 (I revise the code)?


With my (v. 2) code I receive the errors:

$ gdmd-4.6 algorisme_code.d
algorisme_code.d:44: Error: variable codi cannot be read at 
compile time
algorisme_code.d:44: Error: argument to mixin must be a string, 
not (codi)
algorisme_code.d:45: Error: constructor 
algorisme_code.Algorisme!(int,int).Algorisme.this (string nom, 
uint versio, int function(int) funcio, string codi) is not 
callable using argument types (string,int,_error_,string)



Why the string is not given at compile code? I don't understand 
it!


Xan.


Re: Hacking on Phobos

2012-04-17 Thread Dmitry Olshansky

On 17.04.2012 22:10, Joseph Rushton Wakeling wrote:

Hello all,

As per earlier discussion I'm trying to hack on Phobos to update the
random sampling code.

To do this I've just copied random.d into a new file, randomsample.d,
which I'm modifying and messing around with; I'm trying to build against
a local copy of the GitHub Phobos sources.

When I try and compile,

gdc -nophoboslib -I../phobos/ -o randomsample randomsample.d



First things first - development of phobos is done with dmd. Just 
because gdc is (logically so) somewhat behind dmd and new compiler 
features are still coming with every release.


The process usually involves git cloning dmd, druntime and phobos.
Then building all of them in the order of dmd, druntime, phobos.
The the tricky part is replacing older binaries and library.

After fresh cutting phobos edge builts make sure Phobos unittests all 
pass (make -fposix.mak unittest).
I suggest to just modify phobos sources directly. It's DVCS after all so 
you always have a luxury of commit/revert.


and rdmd --main -unittest /path/to/std/random.d
works wonders in development cycle.


Thanks & best wishes,

-- Joe



--
Dmitry Olshansky


Re: Templates in classes => what is wrong?

2012-04-17 Thread Ali Çehreli

On 04/17/2012 11:13 AM, Xan wrote:

> The idea is behind this https://gist.github.com/2407923
> But I receive:
>
> $ gdmd-4.6 algorisme_code.d
> algorisme_code.d:22: Error: variable codi cannot be read at compile time
> algorisme_code.d:22: Error: argument to mixin must be a string, not 
(codi)


mixin is about code generation. For that reason the string that is given 
to it must be available at compile time. Upon analyzing the code, that 
is the case in your example, but because mixin() appears inside the 
constructor, it cannot use a string parameter.


That's why I had used a template parameter for the function string. 
There may be a number of solutions but only you can decide on what to 
do. One solution is to mixin the delegate outside of the constructor and 
pass as an argument along with its string representation:


// Untested code
this(... Funcio funcio, string funcioText) {
...
}

In main:

enum funcioText = "...";
auto funcio = mixin(funcioText);

... new Algorisme(..., funcio, funcioText);

Ali



Re: Hacking on Phobos

2012-04-17 Thread Jonathan M Davis
On Tuesday, April 17, 2012 20:10:51 Joseph Rushton Wakeling wrote:
> Hello all,
> 
> As per earlier discussion I'm trying to hack on Phobos to update the random
> sampling code.
> 
> To do this I've just copied random.d into a new file, randomsample.d, which
> I'm modifying and messing around with; I'm trying to build against a local
> copy of the GitHub Phobos sources.
> 
> When I try and compile,
> 
> gdc -nophoboslib -I../phobos/ -o randomsample randomsample.d
> 
> I get a huge list of errors, beginning with:
> 
> /usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info):
> relocation 0 has invalid symbol index 10
> /usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info):
> relocation 1 has invalid symbol index 11
> /usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info):
> relocation 2 has invalid symbol index 2
> /usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info):
> relocation 3 has invalid symbol index 2
> /usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info):
> relocation 4 has invalid symbol index 10
> /usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info):
> relocation 5 has invalid symbol index 12
> /usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info):
> relocation 6 has invalid symbol index 12
> /usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info):
> relocation 7 has invalid symbol index 12
> /usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info):
> relocation 8 has invalid symbol index 2
> /usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info):
> relocation 9 has invalid symbol index 2

You need to link in librt. core.time requires it.

- Jonathan M Davis


Re: Aquivalent References as in C++?

2012-04-17 Thread Timon Gehr

On 04/17/2012 08:10 PM, Namespace wrote:

> Best of all solutions would be that a
> special keyword, for example scope, ensure that lvalues would
except but
> _no_ null-references.

Yes, the keyword would be a little shorter than the assert() or
enforce() above but D already has very many keywords. :)


Yes, but scope is an unused storage keyword, isn't it?


It is used.


So it could be an idea to avoid speed losses with the current method and
ensure that the object is not null, if it's intentional.


Define 'ensure'.


Re: Aquivalent References as in C++?

2012-04-17 Thread Namespace

> Best of all solutions would be that a
> special keyword, for example scope, ensure that lvalues would
except but
> _no_ null-references.

Yes, the keyword would be a little shorter than the assert() or 
enforce() above but D already has very many keywords. :)


Yes, but scope is an unused storage keyword, isn't it?
So it could be an idea to avoid speed losses with the current 
method and ensure that the object is not null, if it's 
intentional.


Re: Templates in classes => what is wrong?

2012-04-17 Thread Xan

On Tuesday, 17 April 2012 at 18:00:55 UTC, Xan wrote:

On Tuesday, 17 April 2012 at 15:59:25 UTC, Ali Çehreli wrote:

On 04/17/2012 08:42 AM, Xan wrote:

> How to get the "code" of a function or delegate
>
> |___string toString() {
> |___|___return format("%s (versió %s): Domini -> Recorregut,
%s(x) =
> %s", nom, versio, nom, &funcio);
>
> |___}
>
> does not produce the desired result and &funcio without
ampersand
> produces me an error.
>
> So, my doubts are:
> given a function:
>
> - how can I get the domain
> - how can I get the range

I did not understand those. :(


Domain is the set of values that we pass to the function and 
Range is the set of Values which are returned by function.


V delegate (U) f;
f has Domain U and Range V

I want to "print" the type of "U" and "V".

Something like:

class Algorisme(U,V) {
string nom;
uint versio;
alias V delegate (U) Funcio;
Funcio funcio;


this(string nom, uint versio, Funcio funcio) {
this.nom = nom;
this.versio = versio;
this.funcio = funcio;
}

string toString() {
		return format("%s (versió %s): %s -> %s, %s(x) = %s", nom, 
versio, V, U, nom, &funcio);


}
}


but I receive

algorisme.d:24: Error: type int has no value
algorisme.d:24: Error: type int has no value

when I call with Algorisme!(int, int) intead of receiving "int" 
and "int" as Domain and Range




> - how can I get the code of the function?
>
> See https://gist.github.com/2394274
>

I don't think D has any help there. You can keep the function 
as a string yourself and convert to actual code at compile 
time with a string mixin. For that to happen, the function 
text may be an additional template parameter:


import std.conv, std.stdio, std.stream, std.string;
import std.socket, std.socketstream;
import std.datetime;

class Algorisme(U,V,string funcioText) {
string nom;
uint versio;
alias V delegate (U) Funcio;
Funcio funcio;


this(string nom, uint versio) {
this.nom = nom;
this.versio = versio;
this.funcio = mixin(funcioText);
}

string toString() {
   return format("%s (versió %s): Domini -> 
Recorregut, %s(x) = %s",

 nom, versio, nom, funcioText);
}
}


alias Algorisme!(int, int, "(int a) { return 2 * a; }") 
AlgorismeEnters;


void main(string [] args)
{

auto alg = new AlgorismeEnters("Doblar", 1);
writeln(alg);

}

Ali


It's ugly code. I think I could call some procedure like f.code 
(f is a function) to obtain the "code" how f is defined. But 
stricly in mathematical thinking it's not adequate, because 
more codes could result in the same (mathematical function): x 
+ x is the double of x; and 2*x is too.


Perhaps if I change Algorisme and add the string field "code" 
and if there is any procedure to copy the 3rd argument in the 
constructor and pass as string in the 4th argument (in the 
constructor)


class Algorisme(U,V) {
|___string nom;
|___uint versio;
|___alias V delegate (U) Funcio;
|___Funcio funcio;
|___string code;


|___this(string nom, uint versio, Funcio funcio) {
|___|___this.nom = nom;
|___|___this.versio = versio;
|___|___this.funcio = funcio;
this.code = funcio.WHAT PROCEDURE?;
|___}


Regards,
Xan.



The idea is behind this https://gist.github.com/2407923
But I receive:

$ gdmd-4.6 algorisme_code.d
algorisme_code.d:22: Error: variable codi cannot be read at 
compile time
algorisme_code.d:22: Error: argument to mixin must be a string, 
not (codi)


What can I do?

Thanks,
Xan.


Hacking on Phobos

2012-04-17 Thread Joseph Rushton Wakeling

Hello all,

As per earlier discussion I'm trying to hack on Phobos to update the random 
sampling code.


To do this I've just copied random.d into a new file, randomsample.d, which I'm 
modifying and messing around with; I'm trying to build against a local copy of 
the GitHub Phobos sources.


When I try and compile,

   gdc -nophoboslib -I../phobos/ -o randomsample randomsample.d

I get a huge list of errors, beginning with:

/usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): 
relocation 0 has invalid symbol index 10
/usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): 
relocation 1 has invalid symbol index 11
/usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): 
relocation 2 has invalid symbol index 2
/usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): 
relocation 3 has invalid symbol index 2
/usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): 
relocation 4 has invalid symbol index 10
/usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): 
relocation 5 has invalid symbol index 12
/usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): 
relocation 6 has invalid symbol index 12
/usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): 
relocation 7 has invalid symbol index 12
/usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): 
relocation 8 has invalid symbol index 2
/usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): 
relocation 9 has invalid symbol index 2


... and continuing on with a huge number of undefined reference errors.

To check if it was the source of the problem, I tried downloading and building a 
local copy of the latest druntime, but the build process fails:


$ make -f posix.mak MODEL=64

[lots of successful stuff, followed by ...]

src/object_.d(237): Error: function object.TypeInfo.toHash of type @trusted 
ulong() overrides but is not covariant with object.Object.toHash of type nothrow 
@trusted ulong()
src/object_.d(237): Error: function object.TypeInfo.toHash does not override any 
function
src/object_.d(347): Error: function object.TypeInfo_Vector.getHash of type 
ulong(const(void*) p) overrides but is not covariant with 
object.TypeInfo.getHash of type nothrow @trusted ulong(const(void*) p)
src/object_.d(347): Error: function object.TypeInfo_Vector.getHash does not 
override any function


I can't find any easy or friendly "get started hacking on Phobos" page, so can 
anyone advise how to get set up correctly?


Thanks & best wishes,

-- Joe


Re: Range returned by iota and const

2012-04-17 Thread Jonathan M Davis
On Tuesday, April 17, 2012 19:22:30 André Stein wrote:
> Hi,
> 
> I'm trying to pass the range returned by iota to a function accepting
> the parameter as const. I got compilation errors when trying to use the
> index operator and after some investigation it turned out that opSlice
> of iota.Result isn't declared as const.
> 
> The function body of opSlice of iota.Result doesn't seem to mutate the
> range so is there any special reason why it isn't declared as such? (the
> same holds for opSlice).

Very little on ranges ends up being marked const, because const ranges tend to 
be useless (since you can't iterate over them). There are a few cases where 
you could use a range function even if the range is const (this at least 
appears to be one of them), but const typically gets forgotten simply because 
const ranges are generally useless. You can open an enhancement request ( 
d.puremagic.com/issues ) for this though.

- Jonathan M Davis


Re: Templates in classes => what is wrong?

2012-04-17 Thread Xan

On Tuesday, 17 April 2012 at 18:00:55 UTC, Xan wrote:

On Tuesday, 17 April 2012 at 15:59:25 UTC, Ali Çehreli wrote:

On 04/17/2012 08:42 AM, Xan wrote:

> How to get the "code" of a function or delegate
>
> |___string toString() {
> |___|___return format("%s (versió %s): Domini -> Recorregut,
%s(x) =
> %s", nom, versio, nom, &funcio);
>
> |___}
>
> does not produce the desired result and &funcio without
ampersand
> produces me an error.
>
> So, my doubts are:
> given a function:
>
> - how can I get the domain
> - how can I get the range

I did not understand those. :(


Domain is the set of values that we pass to the function and 
Range is the set of Values which are returned by function.


V delegate (U) f;
f has Domain U and Range V

I want to "print" the type of "U" and "V".

Something like:

class Algorisme(U,V) {
string nom;
uint versio;
alias V delegate (U) Funcio;
Funcio funcio;


this(string nom, uint versio, Funcio funcio) {
this.nom = nom;
this.versio = versio;
this.funcio = funcio;
}

string toString() {
		return format("%s (versió %s): %s -> %s, %s(x) = %s", nom, 
versio, V, U, nom, &funcio);


}
}


but I receive

algorisme.d:24: Error: type int has no value
algorisme.d:24: Error: type int has no value



Solved with typeid:

string toString() {
|___|___return format("%s (versió %s): %s -> %s, %s(x) = %s", 
nom, versio, typeid(V), typeid(U), nom, &funcio);


|___}




Re: Aquivalent References as in C++?

2012-04-17 Thread Ali Çehreli

On 04/17/2012 10:37 AM, Namespace wrote:
>> Yes, you must because whetheer obj is null is only known at runtime.
>
> Yes, but if i forget the assert i get an Access Violation error with no
> more informations. Problem is nobody knows _why_ he gets this error,
> because the error message gives no information.

In order to get a meaningful error, the compiler would have to inject 
code that checked every access through a class reference. Unfortunately 
that would bring too much overhead and not be acceptable in a system 
language.


But it could be a part of the non-release builds. I don't have any idea 
how slow program would become if every class dereferencing would be 
checked against null like that. (?)


> So it must be a better solution then to write in every method
> "assert(obj_param !is null");".

Not in every method, but only in methods that actually dereference that 
pointer. Intermediate functions that simply pass the parameter to 
another function need not check the condition.


In the end, null references are a part of D. The code must be written in 
a way to accept it.


As an aside, enforce() may be more suitable and a little shorter:

  enforce(obj_param, "Even with a message");

Whether to use assert() or enforce() depends on the function.

> Best of all solutions would be that a
> special keyword, for example scope, ensure that lvalues would except but
> _no_ null-references.

Yes, the keyword would be a little shorter than the assert() or 
enforce() above but D already has very many keywords. :)


Finally, actually it is possible to have bugs of the same sort even with 
references in C++:


// C++ code

struct S
{
int i;

S(int param_i)
:
i(param_i)
{}
};

S * make_S(int i)
{
return (i == 42) ? new S(i) : 0;
}

void use_S(const S & s)
{
int i = s.i;
}

int main()
{
use_S(*make_S(100));
}

The output is the same as in D:

Segmentation fault

So, as you see, neither C++ provide any help here.

C++'s references have these meanings:

* On the parameter list: "I would like to have a real object please." As 
seen above, it is so easy to violate that. The caller of use_S() 
realizes that a reference is needed and just dereferences the pointer at 
hand. See, the caller must ensure even in C++ that the pointer that is 
available is not NULL.


* On the return type: "What I give you is an alias to an existing 
object." Even this is a false promise without tool support, because the 
reference may be of an automatic local object.


Ali



Re: Templates in classes => what is wrong?

2012-04-17 Thread Xan

On Tuesday, 17 April 2012 at 15:59:25 UTC, Ali Çehreli wrote:

On 04/17/2012 08:42 AM, Xan wrote:

> How to get the "code" of a function or delegate
>
> |___string toString() {
> |___|___return format("%s (versió %s): Domini -> Recorregut,
%s(x) =
> %s", nom, versio, nom, &funcio);
>
> |___}
>
> does not produce the desired result and &funcio without
ampersand
> produces me an error.
>
> So, my doubts are:
> given a function:
>
> - how can I get the domain
> - how can I get the range

I did not understand those. :(


Domain is the set of values that we pass to the function and 
Range is the set of Values which are returned by function.


V delegate (U) f;
f has Domain U and Range V

I want to "print" the type of "U" and "V".

Something like:

class Algorisme(U,V) {
string nom;
uint versio;
alias V delegate (U) Funcio;
Funcio funcio;


this(string nom, uint versio, Funcio funcio) {
this.nom = nom;
this.versio = versio;
this.funcio = funcio;
}

string toString() {
		return format("%s (versió %s): %s -> %s, %s(x) = %s", nom, 
versio, V, U, nom, &funcio);


}
}


but I receive

algorisme.d:24: Error: type int has no value
algorisme.d:24: Error: type int has no value

when I call with Algorisme!(int, int) intead of receiving "int" 
and "int" as Domain and Range




> - how can I get the code of the function?
>
> See https://gist.github.com/2394274
>

I don't think D has any help there. You can keep the function 
as a string yourself and convert to actual code at compile time 
with a string mixin. For that to happen, the function text may 
be an additional template parameter:


import std.conv, std.stdio, std.stream, std.string;
import std.socket, std.socketstream;
import std.datetime;

class Algorisme(U,V,string funcioText) {
string nom;
uint versio;
alias V delegate (U) Funcio;
Funcio funcio;


this(string nom, uint versio) {
this.nom = nom;
this.versio = versio;
this.funcio = mixin(funcioText);
}

string toString() {
return format("%s (versió %s): Domini -> 
Recorregut, %s(x) = %s",

  nom, versio, nom, funcioText);
}
}


alias Algorisme!(int, int, "(int a) { return 2 * a; }") 
AlgorismeEnters;


void main(string [] args)
{

auto alg = new AlgorismeEnters("Doblar", 1);
writeln(alg);

}

Ali


It's ugly code. I think I could call some procedure like f.code 
(f is a function) to obtain the "code" how f is defined. But 
stricly in mathematical thinking it's not adequate, because more 
codes could result in the same (mathematical function): x + x is 
the double of x; and 2*x is too.


Perhaps if I change Algorisme and add the string field "code" and 
if there is any procedure to copy the 3rd argument in the 
constructor and pass as string in the 4th argument (in the 
constructor)


class Algorisme(U,V) {
|___string nom;
|___uint versio;
|___alias V delegate (U) Funcio;
|___Funcio funcio;
|___string code;


|___this(string nom, uint versio, Funcio funcio) {
|___|___this.nom = nom;
|___|___this.versio = versio;
|___|___this.funcio = funcio;
this.code = funcio.WHAT PROCEDURE?;
|___}


Regards,
Xan.





Re: Aquivalent References as in C++?

2012-04-17 Thread Namespace
Yes, you must because whetheer obj is null is only known at 
runtime.


Yes, but if i forget the assert i get an Access Violation error 
with no more informations. Problem is nobody knows _why_ he gets 
this error, because the error message gives no information.
So it must be a better solution then to write in every method 
"assert(obj_param !is null");". Best of all solutions would be 
that a special keyword, for example  scope, ensure that lvalues 
would except but _no_ null-references.




Range returned by iota and const

2012-04-17 Thread André Stein

Hi,

I'm trying to pass the range returned by iota to a function accepting 
the parameter as const. I got compilation errors when trying to use the 
index operator and after some investigation it turned out that opSlice 
of iota.Result isn't declared as const.


The function body of opSlice of iota.Result doesn't seem to mutate the 
range so is there any special reason why it isn't declared as such? (the 
same holds for opSlice).


Regards,
André


Re: Aquivalent References as in C++?

2012-04-17 Thread Namespace
For that, you have static if contitions, and indeed you can 
make it a compile-time error.


Can you show me this as code? And are there any plans to realize 
non-null references or strategies to avoid such things? Otherwise 
there would really be something important missing in D.




Re: retro() on a `string` creates a range of `dchar`, causing array() pains

2012-04-17 Thread Ali Çehreli

On 04/17/2012 09:12 AM, Timon Gehr wrote:
> On 04/17/2012 06:09 PM, Ali Çehreli wrote:

>> The algorithm must be building a local string.

> It does not have to build a local string, see
> http://dlang.org/phobos/std_utf.html#strideBack

I never said otherwise. :p

I was too lazy to locate where 2.059's algorithm.d was placed under. 
Apparently it is here:


  /usr/include/x86_64-linux-gnu/dmd/phobos/std/algorithm.d

The algorithm is smart. It reverses individual Unicode characters 
in-place first and then reverses the whole string one last time:


void reverse(Char)(Char[] s)
if (isNarrowString!(Char[]) && !is(Char == const) && !is(Char == immutable))
{
auto r = representation(s);
for (size_t i = 0; i < s.length; )
{
immutable step = std.utf.stride(s, i);
if (step > 1)
{
.reverse(r[i .. i + step]);
i += step;
}
else
{
++i;
}
}
reverse(r);
}

Ali

P.S. Being a C++ programmer, exception-safety is always warm in my mind. 
Unfortunately the topic does not come up much in D forums. The algorithm 
above is not exception-safe because stride() may throw. But this way off 
topic on this thread. :)




Re: retro() on a `string` creates a range of `dchar`, causing array() pains

2012-04-17 Thread Timon Gehr

On 04/17/2012 06:09 PM, Ali Çehreli wrote:

On 04/17/2012 08:58 AM, bearophile wrote:
 > Ali Çehreli:
 >
 >> The reason is, a sequence of UTF-8 code units are not a valid UTF-8
 >> when reversed (or retro'ed :p).
 >
 > But reversed(char[]) now works :-)

That's pretty cool. :) (You meant reverse()).

Interesting, because there could be no other way anyway because
reverse() is in-place. Iterating by dchar without damaging the other end
must have been challenging because the first half of the string may have
been all multi-bype UTF-8 code units and all of the rest of single-bytes.

The algorithm must be building a local string.

 > Bye,
 > bearophile

Ali



It does not have to build a local string, see
http://dlang.org/phobos/std_utf.html#strideBack


Re: retro() on a `string` creates a range of `dchar`, causing array() pains

2012-04-17 Thread Ali Çehreli

On 04/17/2012 08:58 AM, bearophile wrote:
> Ali Çehreli:
>
>> The reason is, a sequence of UTF-8 code units are not a valid UTF-8
>> when reversed (or retro'ed :p).
>
> But reversed(char[]) now works :-)

That's pretty cool. :) (You meant reverse()).

Interesting, because there could be no other way anyway because 
reverse() is in-place. Iterating by dchar without damaging the other end 
must have been challenging because the first half of the string may have 
been all multi-bype UTF-8 code units and all of the rest of single-bytes.


The algorithm must be building a local string.

> Bye,
> bearophile

Ali



Re: Templates in classes => what is wrong?

2012-04-17 Thread Ali Çehreli

On 04/17/2012 08:42 AM, Xan wrote:

> How to get the "code" of a function or delegate
>
> |___string toString() {
> |___|___return format("%s (versió %s): Domini -> Recorregut, %s(x) =
> %s", nom, versio, nom, &funcio);
>
> |___}
>
> does not produce the desired result and &funcio without ampersand
> produces me an error.
>
> So, my doubts are:
> given a function:
>
> - how can I get the domain
> - how can I get the range

I did not understand those. :(

> - how can I get the code of the function?
>
> See https://gist.github.com/2394274
>

I don't think D has any help there. You can keep the function as a 
string yourself and convert to actual code at compile time with a string 
mixin. For that to happen, the function text may be an additional 
template parameter:


import std.conv, std.stdio, std.stream, std.string;
import std.socket, std.socketstream;
import std.datetime;

class Algorisme(U,V,string funcioText) {
string nom;
uint versio;
alias V delegate (U) Funcio;
Funcio funcio;


this(string nom, uint versio) {
this.nom = nom;
this.versio = versio;
this.funcio = mixin(funcioText);
}

string toString() {
return format("%s (versió %s): Domini -> Recorregut, %s(x) 
= %s",

  nom, versio, nom, funcioText);
}
}


alias Algorisme!(int, int, "(int a) { return 2 * a; }") AlgorismeEnters;

void main(string [] args)
{

auto alg = new AlgorismeEnters("Doblar", 1);
writeln(alg);

}

Ali



Re: retro() on a `string` creates a range of `dchar`, causing array() pains

2012-04-17 Thread bearophile

Ali Çehreli:

The reason is, a sequence of UTF-8 code units are not a valid 
UTF-8 when reversed (or retro'ed :p).


But reversed(char[]) now works :-)

Bye,
bearophile


Re: Aquivalent References as in C++?

2012-04-17 Thread Ali Çehreli

On 04/17/2012 08:49 AM, Ali Çehreli wrote:

> That fails because null is a compile time value and you have a special
> template code for that that fails the compilation.

Scratch the 'template' part. You don't have templates there but what I 
said is still valid. Basically, you have some code that fails at compile 
time.


Ali



Re: Aquivalent References as in C++?

2012-04-17 Thread Ali Çehreli

On 04/17/2012 02:39 AM, Namespace wrote:

>> Bar b = new Bar(42);
>>
>> new Foo(b); // works
>> new Foo(null); // compiler error

That fails because null is a compile time value and you have a special 
template code for that that fails the compilation.


>> new Foo(Bar(23)); // works
>> new Foo(Bar(25)); // works
>
>
> But if I write
>
> Bar bn;
> new Foo(bn);
>
> it works also and doesn't throw a compiler error.

There, bn is a variable that has it's own life at runtime. Although the 
compiler can analyze the code to determine that bn never becomes 
anything but null, we may not want it to be too smart.


Imagine that there are lines after Bar bn; that you have just commented out:

Bar bn;
// bn = foo();
new Foo(bn);

Now the compilation would failure would be an annoyance. That's part of 
the reason why the compiler does not go that deep in its analysis.


> To avoid this, I have to write an assert(obj !is null); again.

Yes, you must because whetheer obj is null is only known at runtime.

> This really sucks. If anybody else works with my Code and puts a null
> reference to any method he gets no compiler error and wonder why he gets
> a runtime error instead.
> Thats very annoying...

Ali



Re: retro() on a `string` creates a range of `dchar`, causing array() pains

2012-04-17 Thread Ali Çehreli

On 04/17/2012 08:12 AM, Jakob Ovrum wrote:
> Consider this simple function:
>
> private string findParameterList(string typestr)
> {
> auto strippedHead = typestr.find("(")[1 .. $];
> auto strippedTail = retro(strippedHead).find(")");
>
> strippedTail.popFront(); // slice off closing parenthesis
>
> return array(strippedTail);
> }
>
> The type of the return expression is dstring, not string.

The reason is, a sequence of UTF-8 code units are not a valid UTF-8 when 
reversed (or retro'ed :p). But a dchar array can be reversed.


Ali



Re: Templates in classes => what is wrong?

2012-04-17 Thread Xan

On Tuesday, 17 April 2012 at 15:30:36 UTC, Ali Çehreli wrote:

On 04/17/2012 08:17 AM, Xan wrote:

Off-topic, could can I define toString having this structure:

 (versió ):  -> 
,



?

(For example, in https://gist.github.com/2394274 I want that 
Doblar

displays as:
Doblar (versió 1): int -> int, { return 2 * a; }


Thanks a lot,
Xan.


std.string.format is easy:

format("%s%s", 42, "hello");

Ali


How to get the "code" of a function or delegate

|___string toString() {
|___|___return format("%s (versió %s): Domini -> Recorregut, 
%s(x) = %s", nom, versio, nom, &funcio);


|___}

does not produce the desired result and &funcio without ampersand 
produces me an error.


So, my doubts are:
given a function:

- how can I get the domain
- how can I get the range
- how can I get the code of the function?

See https://gist.github.com/2394274



Re: Aquivalent References as in C++?

2012-04-17 Thread Dejan Lekic

On Tuesday, 17 April 2012 at 09:39:10 UTC, Namespace wrote:

On Tuesday, 17 April 2012 at 08:02:02 UTC, Namespace wrote:
Now i have something like this. It works and manipulates 
lvalues so that i can pass my objects by ref to except null.


But is this smart?

class Bar {
public:
int x;

static ref Bar opCall(int x) {
static Bar b;

b = new Bar(x);

return b;
}

this(int x) {
this.x = x;
}
}

class Foo {
private:
Bar _bar;

public:
int y;

this() { }

this(ref Bar b) {
//assert(b !is null);

writefln("B.x %d", b.x);
}
}

Bar b = new Bar(42);

new Foo(b); // works
new Foo(null); // compiler error
new Foo(Bar(23)); // works
new Foo(Bar(25)); // works



But if I write

Bar bn;
new Foo(bn);

it works also and doesn't throw a compiler error.
To avoid this, I have to write an assert(obj !is null); again.
This really sucks. If anybody else works with my Code and puts 
a null reference to any method he gets no compiler error and 
wonder why he gets a runtime error instead.

Thats very annoying...


For that, you have static if contitions, and indeed you can make 
it a compile-time error.


Re: Templates in classes => what is wrong?

2012-04-17 Thread Ali Çehreli

On 04/17/2012 08:17 AM, Xan wrote:

Off-topic, could can I define toString having this structure:

 (versió ):  -> ,


?

(For example, in https://gist.github.com/2394274 I want that Doblar
displays as:
Doblar (versió 1): int -> int, { return 2 * a; }


Thanks a lot,
Xan.


std.string.format is easy:

format("%s%s", 42, "hello");

Ali


Re: "shared" status

2012-04-17 Thread Dejan Lekic
On Saturday, 14 April 2012 at 10:48:16 UTC, Luis Panadero 
Guardeño wrote:

What is the status of "shared" types ?

I try it with gdmd v4.6.3
And I not get any warring/error when I do anything over a 
shared variable

without using atomicOp. It's normal ?

shared ushort ram[ram_size];


ram[i] = cast(ushort) (bytes[0] | bytes[1] << 8);


Shared is crucial for concurrency/parallelism since the switch to 
the thread local storage as default storage.


Immutable values are IMPLICITLY SHARED while for your mutable 
data you have to explicitly use "shared" keyword.


This basically means that SHARED data are used everywhere in D 
applications nowadays.


Re: Templates in classes => what is wrong?

2012-04-17 Thread Xan

On Tuesday, 17 April 2012 at 15:21:30 UTC, Dejan Lekic wrote:

On Tuesday, 17 April 2012 at 14:57:18 UTC, Xan wrote:

On Tuesday, 17 April 2012 at 01:31:43 UTC, Kenji Hara wrote:

On Monday, 16 April 2012 at 18:48:52 UTC, Xan wrote:

On Sunday, 15 April 2012 at 19:30:27 UTC, Ali Çehreli wrote:

On 04/15/2012 11:39 AM, Xan wrote:
> On Sunday, 15 April 2012 at 11:23:37 UTC, John Chapman 
> wrote:

>> On Sunday, 15 April 2012 at 11:16:43 UTC, Xan wrote:
>>>
>>> int main(string [] args)
>>> {
>>> auto alg = Algorisme!(int,int);
>>
>> Should be:
>> auto alg = new Algorisme!(int, int);
>>
>>> alg.nom = "Doblar";
>>> alg.versio = 1;
>>> alg.funcio = (int a) {return 2*a};
>>
>> Should be:
>> alg.funcio = (int a) { return 2 * a; };
>> or:
>> alg.funcio = a => 2 * a;
>>
>>> }
>
>
> It does not work:
>
> $ gdmd-4.6 algorisme.d
> algorisme.d:18: Error: variable algorisme.main.alg voids 
> have

no value
> algorisme.d:18: Error: expression class Algorisme is void 
> and

has no value
>
> with the code https://gist.github.com/2394274
>
> What fails now?
>
> Thanks,
> Xan.

Your code is still missing 'new':

auto alg = new Algorisme!(int, int);


With only this change, I receive this error:

$ gdmd-4.6 algorisme.d
algorisme.d:21: Error: cannot implicitly convert expression 
(__dgliteral1) of type int delegate(int a) pure nothrow to 
int function(int)




Unrelated recommendations:

- Return 0 from main() for successful exit, anything else 
by convention means some sort of error.


- Take advantage of constructors (and 'alias') to simplify 
syntax and risk of bugs:


import std.conv, std.stdio, std.stream, std.string;
import std.socket, std.socketstream;
import std.datetime;

class Algorisme(U,V) {
string nom;
uint versio;
alias V function (U) Funcio;
Funcio funcio;

this(string nom, uint versio, Funcio funcio)
{
this.nom = nom;
this.versio = versio;
this.funcio = funcio;
}
}

int main(string [] args)
{
alias Algorisme!(int, int) MeuAlgorism;
auto alg = new MeuAlgorism("Doblar", 1,
   (int a) { return 2 * a; });

return 0;
}

Ali


With all of your suggestion 
[https://gist.github.com/2394274], I get:


$ gdmd-4.6 algorisme.d
algorisme.d:30: Error: constructor 
algorisme.Algorisme!(int,int).Algorisme.this (string nom, 
uint versio, int function(int) funcio) is not callable using 
argument types (string,int,int delegate(int a) pure nothrow)
algorisme.d:30: Error: cannot implicitly convert expression 
(__dgliteral1) of type int delegate(int a) pure nothrow to 
int function(int)
algorisme.d:27: Error: function D main has no return 
statement, but is expected to return a value of type int



What fails?

PS: Thanks for your recommendations...
PPS: By the other hand, I see you have learned catalan 
("MeuAlgorisme"?) ;-)


Problem may be here:


alg.funcio = (int a) { return 2 * a; };


2.057 and earlier (You may use gdc 2.057 and command line 
wrapper gdmd), function literal always deduced as 'delegate'. 
So this expression raises an error about type mismatching Lhs 
of 'int function(int)' and  Rhs of 'int delegate(int) pure 
nothrow'.


Then, specifying explicit 'function' will resolve issue:

alg.funcio = function(int a) { return 2 * a; };

Bye.

Kenji Hara


Thanks, Kenji. If I change function to delegate in declaration 
of field, it works too. What do you recommend to have 
delegates or functions? What are the benefits and ...


Thanks,
Xan.


For an example, you can't use function-pointer to access 
non-static methods, while with delegates you can. You can see 
some examples on http://www.dlang.org (Languate Reference).


So, I deduce it's better to use delegater than function?


Re: Templates in classes => what is wrong?

2012-04-17 Thread Dejan Lekic

On Tuesday, 17 April 2012 at 14:57:18 UTC, Xan wrote:

On Tuesday, 17 April 2012 at 01:31:43 UTC, Kenji Hara wrote:

On Monday, 16 April 2012 at 18:48:52 UTC, Xan wrote:

On Sunday, 15 April 2012 at 19:30:27 UTC, Ali Çehreli wrote:

On 04/15/2012 11:39 AM, Xan wrote:
> On Sunday, 15 April 2012 at 11:23:37 UTC, John Chapman 
> wrote:

>> On Sunday, 15 April 2012 at 11:16:43 UTC, Xan wrote:
>>>
>>> int main(string [] args)
>>> {
>>> auto alg = Algorisme!(int,int);
>>
>> Should be:
>> auto alg = new Algorisme!(int, int);
>>
>>> alg.nom = "Doblar";
>>> alg.versio = 1;
>>> alg.funcio = (int a) {return 2*a};
>>
>> Should be:
>> alg.funcio = (int a) { return 2 * a; };
>> or:
>> alg.funcio = a => 2 * a;
>>
>>> }
>
>
> It does not work:
>
> $ gdmd-4.6 algorisme.d
> algorisme.d:18: Error: variable algorisme.main.alg voids 
> have

no value
> algorisme.d:18: Error: expression class Algorisme is void 
> and

has no value
>
> with the code https://gist.github.com/2394274
>
> What fails now?
>
> Thanks,
> Xan.

Your code is still missing 'new':

auto alg = new Algorisme!(int, int);


With only this change, I receive this error:

$ gdmd-4.6 algorisme.d
algorisme.d:21: Error: cannot implicitly convert expression 
(__dgliteral1) of type int delegate(int a) pure nothrow to 
int function(int)




Unrelated recommendations:

- Return 0 from main() for successful exit, anything else by 
convention means some sort of error.


- Take advantage of constructors (and 'alias') to simplify 
syntax and risk of bugs:


import std.conv, std.stdio, std.stream, std.string;
import std.socket, std.socketstream;
import std.datetime;

class Algorisme(U,V) {
 string nom;
 uint versio;
 alias V function (U) Funcio;
 Funcio funcio;

 this(string nom, uint versio, Funcio funcio)
 {
 this.nom = nom;
 this.versio = versio;
 this.funcio = funcio;
 }
}

int main(string [] args)
{
 alias Algorisme!(int, int) MeuAlgorism;
 auto alg = new MeuAlgorism("Doblar", 1,
(int a) { return 2 * a; });

 return 0;
}

Ali


With all of your suggestion 
[https://gist.github.com/2394274], I get:


$ gdmd-4.6 algorisme.d
algorisme.d:30: Error: constructor 
algorisme.Algorisme!(int,int).Algorisme.this (string nom, 
uint versio, int function(int) funcio) is not callable using 
argument types (string,int,int delegate(int a) pure nothrow)
algorisme.d:30: Error: cannot implicitly convert expression 
(__dgliteral1) of type int delegate(int a) pure nothrow to 
int function(int)
algorisme.d:27: Error: function D main has no return 
statement, but is expected to return a value of type int



What fails?

PS: Thanks for your recommendations...
PPS: By the other hand, I see you have learned catalan 
("MeuAlgorisme"?) ;-)


Problem may be here:


alg.funcio = (int a) { return 2 * a; };


2.057 and earlier (You may use gdc 2.057 and command line 
wrapper gdmd), function literal always deduced as 'delegate'. 
So this expression raises an error about type mismatching Lhs 
of 'int function(int)' and  Rhs of 'int delegate(int) pure 
nothrow'.


Then, specifying explicit 'function' will resolve issue:

 alg.funcio = function(int a) { return 2 * a; };

Bye.

Kenji Hara


Thanks, Kenji. If I change function to delegate in declaration 
of field, it works too. What do you recommend to have delegates 
or functions? What are the benefits and ...


Thanks,
Xan.


For an example, you can't use function-pointer to access 
non-static methods, while with delegates you can. You can see 
some examples on http://www.dlang.org (Languate Reference).


Re: retro() on a `string` creates a range of `dchar`, causing array() pains

2012-04-17 Thread bearophile

Jakob Ovrum:


return array(strippedTail);
}

The type of the return expression is dstring, not string.

What is the most elegant way or correct way to solve this 
friction?


(Note: the function is used in CTFE)


Try "text" instead of "array".

Bye,
bearophile


Re: Templates in classes => what is wrong?

2012-04-17 Thread Xan

Off-topic, could can I define toString having this structure:

 (versió ):  -> 
, 


?

(For example, in https://gist.github.com/2394274 I want that 
Doblar displays as:

Doblar (versió 1): int -> int, { return 2 * a; }


Thanks a lot,
Xan.


Re: "No stack address"

2012-04-17 Thread Andrej Mitrovic
On 4/17/12, Somedude  wrote:
> Do you have any idea where this is explained

rdmd --help


retro() on a `string` creates a range of `dchar`, causing array() pains

2012-04-17 Thread Jakob Ovrum

Consider this simple function:

private string findParameterList(string typestr)
{
auto strippedHead = typestr.find("(")[1 .. $];
auto strippedTail = retro(strippedHead).find(")");

strippedTail.popFront(); // slice off closing parenthesis

return array(strippedTail);
}

The type of the return expression is dstring, not string.

What is the most elegant way or correct way to solve this 
friction?


(Note: the function is used in CTFE)


Re: Templates in classes => what is wrong?

2012-04-17 Thread Xan

On Tuesday, 17 April 2012 at 01:31:43 UTC, Kenji Hara wrote:

On Monday, 16 April 2012 at 18:48:52 UTC, Xan wrote:

On Sunday, 15 April 2012 at 19:30:27 UTC, Ali Çehreli wrote:

On 04/15/2012 11:39 AM, Xan wrote:
> On Sunday, 15 April 2012 at 11:23:37 UTC, John Chapman 
> wrote:

>> On Sunday, 15 April 2012 at 11:16:43 UTC, Xan wrote:
>>>
>>> int main(string [] args)
>>> {
>>> auto alg = Algorisme!(int,int);
>>
>> Should be:
>> auto alg = new Algorisme!(int, int);
>>
>>> alg.nom = "Doblar";
>>> alg.versio = 1;
>>> alg.funcio = (int a) {return 2*a};
>>
>> Should be:
>> alg.funcio = (int a) { return 2 * a; };
>> or:
>> alg.funcio = a => 2 * a;
>>
>>> }
>
>
> It does not work:
>
> $ gdmd-4.6 algorisme.d
> algorisme.d:18: Error: variable algorisme.main.alg voids 
> have

no value
> algorisme.d:18: Error: expression class Algorisme is void 
> and

has no value
>
> with the code https://gist.github.com/2394274
>
> What fails now?
>
> Thanks,
> Xan.

Your code is still missing 'new':

auto alg = new Algorisme!(int, int);


With only this change, I receive this error:

$ gdmd-4.6 algorisme.d
algorisme.d:21: Error: cannot implicitly convert expression 
(__dgliteral1) of type int delegate(int a) pure nothrow to int 
function(int)




Unrelated recommendations:

- Return 0 from main() for successful exit, anything else by 
convention means some sort of error.


- Take advantage of constructors (and 'alias') to simplify 
syntax and risk of bugs:


import std.conv, std.stdio, std.stream, std.string;
import std.socket, std.socketstream;
import std.datetime;

class Algorisme(U,V) {
  string nom;
  uint versio;
  alias V function (U) Funcio;
  Funcio funcio;

  this(string nom, uint versio, Funcio funcio)
  {
  this.nom = nom;
  this.versio = versio;
  this.funcio = funcio;
  }
}

int main(string [] args)
{
  alias Algorisme!(int, int) MeuAlgorism;
  auto alg = new MeuAlgorism("Doblar", 1,
 (int a) { return 2 * a; });

  return 0;
}

Ali


With all of your suggestion [https://gist.github.com/2394274], 
I get:


$ gdmd-4.6 algorisme.d
algorisme.d:30: Error: constructor 
algorisme.Algorisme!(int,int).Algorisme.this (string nom, uint 
versio, int function(int) funcio) is not callable using 
argument types (string,int,int delegate(int a) pure nothrow)
algorisme.d:30: Error: cannot implicitly convert expression 
(__dgliteral1) of type int delegate(int a) pure nothrow to int 
function(int)
algorisme.d:27: Error: function D main has no return 
statement, but is expected to return a value of type int



What fails?

PS: Thanks for your recommendations...
PPS: By the other hand, I see you have learned catalan 
("MeuAlgorisme"?) ;-)


Problem may be here:


alg.funcio = (int a) { return 2 * a; };


2.057 and earlier (You may use gdc 2.057 and command line 
wrapper gdmd), function literal always deduced as 'delegate'. 
So this expression raises an error about type mismatching Lhs 
of 'int function(int)' and  Rhs of 'int delegate(int) pure 
nothrow'.


Then, specifying explicit 'function' will resolve issue:

  alg.funcio = function(int a) { return 2 * a; };

Bye.

Kenji Hara


Thanks, Kenji. If I change function to delegate in declaration of 
field, it works too. What do you recommend to have delegates or 
functions? What are the benefits and ...


Thanks,
Xan.



Re: arrays and foreach

2012-04-17 Thread Ali Çehreli

On 04/17/2012 12:42 AM, Somedude wrote:


Sorry for hijacking this thread, but since you're around, I hope you'll
see this message. As a D beginner, I'm browsing through your book.
I wanted to tell you that there is something essential missing in it:
how to compile. It's actually quite hard to find it in the official
website, and since the first chapters are targetted at complete
beginners, I thought it would be nice to add a few lines or pages about
compilation, linking, debugging, etc.
What do you think ?


Thank you very much for the feedback. I will do something about that.

Although there is no hello world compilation, the dmd command line 
appears multiple times throughout the chapters.


The 'assert and enforce' chapter shows it for the -release compiler 
switch and coincidentally I am on the 'Unit Testing' chapter as we 
speak, which includes the -unittest switch. :)


But you are right, both dmd and rdmd command lines must appear earlier.

Thank you,
Ali



Re: "shared" status

2012-04-17 Thread Ali Çehreli

On 04/17/2012 06:05 AM, Luis wrote:

Thanks! It's very useful.

Ali Çehreli wrote:


synchronized (job) {
*job.slice ~= appendValue;
}

So shared, at least share data across threads. And using synchronized( )
I could do lock-based access to shared data.



Yes. I've used the same Job object there but any class is a lock. (This 
has been a new concept for me. The "lock part" of the object is called 
the monitor.)


Ali


Re: "shared" status

2012-04-17 Thread Luis
Thanks! It's very useful.
 
Ali Çehreli wrote:

> synchronized (job) {
> *job.slice ~= appendValue;
> }
So shared, at least share data across threads. And using synchronized( ) 
I could do lock-based access to shared data.



Re: "No stack address"

2012-04-17 Thread Somedude
Le 17/04/2012 09:30, Somedude a écrit :
> Anyway, I think I'll add this simple piece of info somewhere in the
> wiki. I've already cleaned it up a little.

Ok, here it is: http://prowiki.org/wiki4d/wiki.cgi?HowTo/UnitTests


Re: Metaprogramming work around

2012-04-17 Thread Kenji Hara

On Tuesday, 17 April 2012 at 12:04:44 UTC, Erèbe wrote:
[snip]


There is something I still don't understand :

mixin template Foo( T... )
{
//Code here
}

mixin Foo!( "Hello", "Word" ); < Good


T is TemplateTypeParameter, and matches any kind of template 
arguments - types, values, and symbols. The both arguments 
"Hello" and "World" are values, so you can bind them with T.


http://dlang.org/template.html#TemplateTupleParameter




"mixin template Foo( A, T... )
{
//code here
}

mixin Foo!( "Hello", "Word" ); <--- Fail !
mixin Foo!( string, "Word" ); < Good



'A' is TemplateTypeParameter, and it matches only types. In the 
first instantiation of Foo, A doesn't match with the value 
"hello".
In the second instantiation, string is type, and T matches with 
it.


http://dlang.org/template.html#TemplateTypeParameter


mixin template Foo( alias A, T... )
{
//code here
}

mixin Foo!( "Hello", "world" ); <--- Good
mixin Foo!( string, "world" ); <--- Fail !

-


'alias A' is TemplateAliasParameter, and it matches both symbols 
and values.
Then A matches with the value "Hello", but doesn't with the type 
string.
(string is an aliased name of immutable(char)[], and it is 
built-in array type.)


http://dlang.org/template.html#TemplateAliasParameter

Kenji Hara


Re: Compiling Was: arrays and foreach

2012-04-17 Thread David

In this case, I had to type:
rdmd -unittest --main test.d

Without the --main, I would get linker errors, and couldn't find the
reason for these errors. Happily, someone here explained me that the
effect of the --main flag was to insert a main() function just for this
case.


That's not surprising, try to write a C program with no main:

─[ArchBox][/tmp]╼ touch foo.c
─[ArchBox][/tmp]╼ LANG=C gcc foo.c
/usr/lib/gcc/i686-pc-linux-gnu/4.7.0/../../../crt1.o: In function `_start':
(.text+0x18): undefined reference to `main'
collect2: error: ld returned 1 exit status

You get the linker errors, because there is no entry-point for your 
program, but that has nothing to do with D, it's a common behaviour for 
C, C++, D and other languages.



And the unittest(-switch) is also good relativly good explained at 
http://dlang.org/unittest.html (dlang -> search -> unittest)


Re: Metaprogramming work around

2012-04-17 Thread Erèbe

On Tuesday, 17 April 2012 at 10:29:56 UTC, Kenji Hara wrote:

On Tuesday, 17 April 2012 at 08:28:45 UTC, Erèbe wrote:

Hi,

I'm working on some metaprogramming code which implement a 
Factory and generate an enum from a list of string.


So here my questions :

1) The documentation say mixin templates could take as 
TemplateParameterList
a "TemplateParameter , TemplateParameterList" but all my tried 
to instaciate this template failed lamentably.


mixin template Foo(T, R...)
{

  anotherTemplate!(T);
  Foo!(R);

}

mixin Foo!( string, string, string);

Is something wrong with variadic template and mixin, do i miss 
something ?



2) Below some code I writed and I wanted to know if you have 
some advice to improve it (Right maner to do it, TypeChecking, 
Safety, ...) <- variaidc arguments



The code is working is purpose is to create an enum of 
commands and to create a factory which returns me the command 
associated to a string.


Thanks !

===Code
import std.stdio;
import std.traits;
import std.conv;


//Use to create the enums of every commands
mixin template enumGenerator( T... )
{

   template generate( T... )
   {
   enum string value = T[0] ~ ", " ~ generate!( T[2..$] 
).value;

   }

   template generate() { enum string value = "UNKNOW"; }


   //Here the creation of the enum
   mixin("enum Command { " ~ generate!(T).value ~ "};");

}

//Generate a function which return a command in regard of a 
string

mixin template factoryGenerator( T... )
{
   template generate( T... )
   {
   enum string value = "if( cmd == \"" ~ T[1] ~ "\")"
   ~ "return Command." ~ T[0] ~ ";"
   ~ "else "
   ~ generate!(T[2..$]).value;
   }

   template generate() { enum string value = "return 
Command.UNKNOW;"; }


   //The function in question
   auto CommandFactory( string cmd )
   {
   mixin( generate!(T).value );
   }

}


mixin template IrcCommands( T... )
{

  mixin enumGenerator!( T );
  mixin factoryGenerator!( T );

}


void main()
{

  /*Command*/ /*String associated*/
  mixin IrcCommands!( "Connected","001",
  "NicknameUsed", "433",
  "Message",  "PRIVMSG",
  "UserLeaved",   "PART",
  "UserJoined",   "JOIN",
  "UserQuit", "QUIT"


 "UserQuit", "QUIT",   // lack of 
comma



  "Ping", "PING" );

  writefln( to!string(CommandFactory("001")) );


}


You can debug templates with adding static assertions in some 
where, like:


mixin template enumGenerator( T... )
{
template generate( T... )
{
static assert(T.length%2==0 && is(typeof(T[0]) : 
string));  // check
enum string value = T[0] ~ ", " ~ generate!( T[2..$] 
).value;

}
//[snip]
}

mixin template factoryGenerator( T... )
{
template generate( T... )
{
static assert(T.length%2==0 && is(typeof(T[1]) : 
string));  // check

enum string value = "if( cmd == \"" ~ T[1] ~ "\")"
~ "return Command." ~ T[0] ~ ";"
~ "else "
~ generate!(T[2..$]).value;
}
//[snip]
}

Bye.

Kenji Hara


Thanks for the comma !

The issue with static assert (in my case) is that the compiler 
blow you a full page of "template's instatiation error" before 
the message of your assert. Ok not even a page of the size of c++ 
template error, but that lead to your message be less noticeable.

While browsering the standard librairy I found this :

static if ( expression )
 //put your code here
else
  assert(false, "your message");

With this, the compiler print just one line, "your message". That 
pretty neat and readable enough for me :)


Stick in the magic pragma(msg, value); in here you won't regret 
it ;)
Another important thing to note here is that you should really 
reconsider using plain if/else if it's a production code not 
some toy to learn meta programming.
At very least try to generate switch over strings but I don't 
think any D compiler optimizes it. (but it should in future)
Real world options are binary search on string table or even 
better built-in hash table.


Thanks for pragma, it's awesome !

You guessed right, this code is just for the sake of learning 
some D meta programming. But I will try with an built-in hash 
table.




There is something I still don't understand :

mixin template Foo( T... )
{
//Code here
}

mixin Foo!( "Hello", "Word" ); < Good



mixin template Foo( A, T... )
{
//code here
}

mixin Foo!( "Hello", "Word" ); <--- Fail !
mixin Foo!( string, "Word" ); < Good


mixin template Foo( alias A, T... )
{
//code here
}

mixin Foo!( "Hello", "world" ); <--- Good

Re: Compiling Was: arrays and foreach

2012-04-17 Thread Somedude
Le 17/04/2012 12:19, Mike Parker a écrit :
> On 4/17/2012 4:42 PM, Somedude wrote:
> 
>>>
>>> Ali
>>>
>>>
>> Hi Ali,
>>
>> Sorry for hijacking this thread, but since you're around, I hope you'll
>> see this message. As a D beginner, I'm browsing through your book.
>> I wanted to tell you that there is something essential missing in it:
>> how to compile. It's actually quite hard to find it in the official
>> website, and since the first chapters are targetted at complete
>> beginners, I thought it would be nice to add a few lines or pages about
>> compilation, linking, debugging, etc.
>> What do you think ?
> 
> In the sidebar at dlang.org, under Documentation, is a link labeled
> "Tutorial". The very first code example shows a minimal program and how
> to compile it.

Well, yes, that's sufficient for "Hello, world", but not for something
barely more complex, i.e a function with a unit test.

In this case, I had to type:
rdmd -unittest --main test.d

Without the --main, I would get linker errors, and couldn't find the
reason for these errors. Happily, someone here explained me that the
effect of the --main flag was to insert a main() function just for this
case.

Now, I see there is a mention of this in http://dlang.org/rdmd.html
But without rdmd, I would compile with dmd, which has no --main switch,
and it would still fail to link, because of lack of main(). The code I
posted wasn't my code, and I knew it had worked, so I assumed it was
correct, I didn't figure out that adding a main() was necessary given
there was a unit test.

And anyway, explaining in the book how to link is a necessary step imho.
This is why I made this page more visible in the Wiki:
http://prowiki.org/wiki4d/wiki.cgi?D__Tutorial/CompilingLinkingD


Re: Metaprogramming work around

2012-04-17 Thread Dmitry Olshansky

On 17.04.2012 12:28, "Erèbe" wrote:

Hi,

I'm working on some metaprogramming code which implement a Factory and
generate an enum from a list of string.

So here my questions :

1) The documentation say mixin templates could take as
TemplateParameterList
a "TemplateParameter , TemplateParameterList" but all my tried to
instaciate this template failed lamentably.

mixin template Foo(T, R...)
{

anotherTemplate!(T);
Foo!(R);

}

mixin Foo!( string, string, string);

Is something wrong with variadic template and mixin, do i miss something ?


2) Below some code I writed and I wanted to know if you have some advice
to improve it (Right maner to do it, TypeChecking, Safety, ...) <-
variaidc arguments


The code is working is purpose is to create an enum of commands and to
create a factory which returns me the command associated to a string.

Thanks !

===Code
import std.stdio;
import std.traits;
import std.conv;


//Use to create the enums of every commands
mixin template enumGenerator( T... )
{

template generate( T... )
{
enum string value = T[0] ~ ", " ~ generate!( T[2..$] ).value;
}

template generate() { enum string value = "UNKNOW"; }


//Here the creation of the enum
mixin("enum Command { " ~ generate!(T).value ~ "};");

}

//Generate a function which return a command in regard of a string
mixin template factoryGenerator( T... )
{
template generate( T... )
{
enum string value = "if( cmd == \"" ~ T[1] ~ "\")"
~ "return Command." ~ T[0] ~ ";"
~ "else "
~ generate!(T[2..$]).value;


Stick in the magic pragma(msg, value); in here you won't regret it ;)


}


Another important thing to note here is that you should really 
reconsider using plain if/else if it's a production code not some toy to 
learn meta programming.
At very least try to generate switch over strings but I don't think any 
D compiler optimizes it. (but it should in future)
Real world options are binary search on string table or even better 
built-in hash table.



--
Dmitry Olshansky


Re: Metaprogramming work around

2012-04-17 Thread Kenji Hara

On Tuesday, 17 April 2012 at 08:28:45 UTC, Erèbe wrote:

Hi,

I'm working on some metaprogramming code which implement a 
Factory and generate an enum from a list of string.


So here my questions :

1) The documentation say mixin templates could take as 
TemplateParameterList
a "TemplateParameter , TemplateParameterList" but all my tried 
to instaciate this template failed lamentably.


mixin template Foo(T, R...)
{

   anotherTemplate!(T);
   Foo!(R);

}

mixin Foo!( string, string, string);

Is something wrong with variadic template and mixin, do i miss 
something ?



2) Below some code I writed and I wanted to know if you have 
some advice to improve it (Right maner to do it, TypeChecking, 
Safety, ...) <- variaidc arguments



The code is working is purpose is to create an enum of commands 
and to create a factory which returns me the command associated 
to a string.


Thanks !

===Code
import std.stdio;
import std.traits;
import std.conv;


//Use to create the enums of every commands
mixin template enumGenerator( T... )
{

template generate( T... )
{
enum string value = T[0] ~ ", " ~ generate!( T[2..$] 
).value;

}

template generate() { enum string value = "UNKNOW"; }


//Here the creation of the enum
mixin("enum Command { " ~ generate!(T).value ~ "};");

}

//Generate a function which return a command in regard of a 
string

mixin template factoryGenerator( T... )
{
template generate( T... )
{
enum string value = "if( cmd == \"" ~ T[1] ~ "\")"
~ "return Command." ~ T[0] ~ ";"
~ "else "
~ generate!(T[2..$]).value;
}

template generate() { enum string value = "return 
Command.UNKNOW;"; }


//The function in question
auto CommandFactory( string cmd )
{
mixin( generate!(T).value );
}

}


mixin template IrcCommands( T... )
{

   mixin enumGenerator!( T );
   mixin factoryGenerator!( T );

}


void main()
{

   /*Command*/ /*String associated*/
   mixin IrcCommands!( "Connected","001",
   "NicknameUsed", "433",
   "Message",  "PRIVMSG",
   "UserLeaved",   "PART",
   "UserJoined",   "JOIN",
   "UserQuit", "QUIT"


 "UserQuit", "QUIT",   // lack of 
comma



   "Ping", "PING" );

   writefln( to!string(CommandFactory("001")) );


}


You can debug templates with adding static assertions in some 
where, like:


mixin template enumGenerator( T... )
{
template generate( T... )
{
static assert(T.length%2==0 && is(typeof(T[0]) : 
string));  // check
enum string value = T[0] ~ ", " ~ generate!( T[2..$] 
).value;

}
//[snip]
}

mixin template factoryGenerator( T... )
{
template generate( T... )
{
static assert(T.length%2==0 && is(typeof(T[1]) : 
string));  // check

enum string value = "if( cmd == \"" ~ T[1] ~ "\")"
~ "return Command." ~ T[0] ~ ";"
~ "else "
~ generate!(T[2..$]).value;
}
//[snip]
}

Bye.

Kenji Hara


Compiling Was: arrays and foreach

2012-04-17 Thread Mike Parker

On 4/17/2012 4:42 PM, Somedude wrote:



Ali



Hi Ali,

Sorry for hijacking this thread, but since you're around, I hope you'll
see this message. As a D beginner, I'm browsing through your book.
I wanted to tell you that there is something essential missing in it:
how to compile. It's actually quite hard to find it in the official
website, and since the first chapters are targetted at complete
beginners, I thought it would be nice to add a few lines or pages about
compilation, linking, debugging, etc.
What do you think ?


In the sidebar at dlang.org, under Documentation, is a link labeled 
"Tutorial". The very first code example shows a minimal program and how 
to compile it.


Re: Aquivalent References as in C++?

2012-04-17 Thread Namespace

On Tuesday, 17 April 2012 at 08:02:02 UTC, Namespace wrote:
Now i have something like this. It works and manipulates 
lvalues so that i can pass my objects by ref to except null.


But is this smart?

class Bar {
public:
int x;

static ref Bar opCall(int x) {
static Bar b;

b = new Bar(x);

return b;
}

this(int x) {
this.x = x;
}
}

class Foo {
private:
Bar _bar;

public:
int y;

this() { }

this(ref Bar b) {
//assert(b !is null);

writefln("B.x %d", b.x);
}
}

Bar b = new Bar(42);

new Foo(b); // works
new Foo(null); // compiler error
new Foo(Bar(23)); // works
new Foo(Bar(25)); // works



But if I write

Bar bn;
new Foo(bn);

it works also and doesn't throw a compiler error.
To avoid this, I have to write an assert(obj !is null); again.
This really sucks. If anybody else works with my Code and puts a 
null reference to any method he gets no compiler error and wonder 
why he gets a runtime error instead.

Thats very annoying...


Metaprogramming work around

2012-04-17 Thread Erèbe

Hi,

I'm working on some metaprogramming code which implement a 
Factory and generate an enum from a list of string.


So here my questions :

1) The documentation say mixin templates could take as 
TemplateParameterList
a "TemplateParameter , TemplateParameterList" but all my tried to 
instaciate this template failed lamentably.


mixin template Foo(T, R...)
{

   anotherTemplate!(T);
   Foo!(R);

}

mixin Foo!( string, string, string);

Is something wrong with variadic template and mixin, do i miss 
something ?



2) Below some code I writed and I wanted to know if you have some 
advice to improve it (Right maner to do it, TypeChecking, Safety, 
...) <- variaidc arguments



The code is working is purpose is to create an enum of commands 
and to create a factory which returns me the command associated 
to a string.


Thanks !

===Code
import std.stdio;
import std.traits;
import std.conv;


//Use to create the enums of every commands
mixin template enumGenerator( T... )
{

template generate( T... )
{
enum string value = T[0] ~ ", " ~ generate!( T[2..$] 
).value;

}

template generate() { enum string value = "UNKNOW"; }


//Here the creation of the enum
mixin("enum Command { " ~ generate!(T).value ~ "};");

}

//Generate a function which return a command in regard of a string
mixin template factoryGenerator( T... )
{
template generate( T... )
{
enum string value = "if( cmd == \"" ~ T[1] ~ "\")"
~ "return Command." ~ T[0] ~ ";"
~ "else "
~ generate!(T[2..$]).value;
}

template generate() { enum string value = "return 
Command.UNKNOW;"; }


//The function in question
auto CommandFactory( string cmd )
{
mixin( generate!(T).value );
}

}


mixin template IrcCommands( T... )
{

   mixin enumGenerator!( T );
   mixin factoryGenerator!( T );

}


void main()
{

   /*Command*/ /*String associated*/
   mixin IrcCommands!( "Connected","001",
   "NicknameUsed", "433",
   "Message",  "PRIVMSG",
   "UserLeaved",   "PART",
   "UserJoined",   "JOIN",
   "UserQuit", "QUIT"
   "Ping", "PING" );

   writefln( to!string(CommandFactory("001")) );


}




Re: Thread join behaviour

2012-04-17 Thread Somedude
Le 17/04/2012 08:40, Russel Winder a écrit :
> On Mon, 2012-04-16 at 21:03 +0200, Somedude wrote:
> [...]
> 
> Issue 7919
> 
> http://d.puremagic.com/issues/show_bug.cgi?id=7919
> 
Thanks.


Re: Aquivalent References as in C++?

2012-04-17 Thread Namespace
Now i have something like this. It works and manipulates lvalues 
so that i can pass my objects by ref to except null.


But is this smart?

class Bar {
public:
int x;

static ref Bar opCall(int x) {
static Bar b;

b = new Bar(x);

return b;
}

this(int x) {
this.x = x;
}
}

class Foo {
private:
Bar _bar;

public:
int y;

this() { }

this(ref Bar b) {
//assert(b !is null);

writefln("B.x %d", b.x);
}
}

Bar b = new Bar(42);

new Foo(b); // works
new Foo(null); // compiler error
new Foo(Bar(23)); // works
new Foo(Bar(25)); // works


Re: arrays and foreach

2012-04-17 Thread Somedude
Le 17/04/2012 02:01, Ali Çehreli a écrit :
> On 04/16/2012 04:56 PM, darkstalker wrote:
>> i have this example program:
>>
>> ---
>> void main()
>> {
>> int[3] a;
>> foreach (p; a)
>> p = 42;
>> writeln(a);
>> }
>> ---
>>
>> after running it, i expect to get [42, 42, 42] but instead i get [0, 0,
>> 0] (i know that you can do a[] = 42, it's just a trivial example). So it
>> seems that you cannot write into the array because the elements are
>> being passed by value each iteration. It possible to have 'p' passed by
>> reference?
> 
> Yes:
> 
> foreach (ref p; a)
> 
> Ali
> 
> 
Hi Ali,

Sorry for hijacking this thread, but since you're around, I hope you'll
see this message. As a D beginner, I'm browsing through your book.
I wanted to tell you that there is something essential missing in it:
how to compile. It's actually quite hard to find it in the official
website, and since the first chapters are targetted at complete
beginners, I thought it would be nice to add a few lines or pages about
compilation, linking, debugging, etc.
What do you think ?


Re: "No stack address"

2012-04-17 Thread Somedude
Le 17/04/2012 01:26, Andrej Mitrovic a écrit :
> On 4/17/12, Somedude  wrote:
>> But running the exe crashes immediately at execution with "unauthorized
>> instruction". Why ?
> 
> That's the old exectuable leftover from the previous compile. RDMD
> generates the exe in a temporary folder with a random name and runs it
> immediately. Because the main function doesn't do anything (RDMD
> provides an empty one via --main), the app exited immediately.
> 
>> And how do I execute the unit test ?
> 
> rdmd -unittest --main test.d

Thanks, it works. BTW, I couldn't find this information. Do you have any
idea where this is explained (in particular the --main switch) that I
overlooked ?
Anyway, I think I'll add this simple piece of info somewhere in the
wiki. I've already cleaned it up a little.