Re: typeof map

2013-06-25 Thread monarch_dodra

On Tuesday, 25 June 2013 at 04:26:00 UTC, Timothee Cour wrote:

I think it's because each lambda litteral is treated unique.
can dmd be changed to recognize identical lambda litterals as 
identical? Is

there any particular issue making that difficult?
it already recognizes identical string literals as identical


I could be wrong, but the difference might be that it *can* 
recognize string literals as idential, but it doesn't actually 
guarantee it as spec. This is not an issue for strings, but...


Imagine I have a module, where I declare alias T = R!some_labda.

Then in another module, I declare alias U = R!some_labda.

Then in a third module, would I be able to declare a T, and store 
it inside a U ? Would the compiler be able to see that both 
lambdas are actually the same? I honestly don't know.


But it seems dangerous to me: Lambdas specifically don't have 
names, and are unique. If you type two of them that have the same 
body, that shouldn't mean they are actually the same.


Also, doing this would create symbol collisions, where a user has 
defined two different lambdas, that have the same body, but 
expected different definitions. EG:


alias T = R!some_lambda;
alias U = R!some_same_lambda
void foo(T t);
void foo(U u); //Nope, foo(U) already declared; What?


Re: Warning: explicit element-wise assignment (this.vector)[] = vec.vector[cast(ulong)0..cast(ulong)dimension]

2013-06-25 Thread David
Am 24.06.2013 22:50, schrieb bearophile:
 David:
 
 What kind of bugs does it avoid?
 I can't think of a single bug which could happen...
 (Ranges/Lengths are checked at runtime...)
 
 Some reasons:
 - Syntax uniformity: similar behaviours should look similar. This is a
 general rule of language design, that avoids troubles you don't even
 know. All array ops use [], so it's right for vector assignment to use
 them.
 - The second rule is that in a language as D we want to denote different
 code complexities with different code. This is the reason given in the
 Changelog, and it explains while length and walkLength have different
 names.
 In past you were not able to tell from a look at the syntax what's
 happening:
 
 void main() {
 int[][3] x;
 int[]y;
 int[]z;
 
 x[] = z; // copies just the z pointer
 y[] = z; // copies the elements in z
 }
 
 
 More details:
 http://d.puremagic.com/issues/show_bug.cgi?id=7444
 Coming from this older:
 http://d.puremagic.com/issues/show_bug.cgi?id=3971
 
 You are welcome,
 bearophile

This really sucks...
I guess I can workaround it with a static foreach and do an
elementwise copy.
Thanks for the explanation.


Re: Trouble with lockstep

2013-06-25 Thread Andrej Mitrovic
On 6/25/13, Andrej Mitrovic andrej.mitrov...@gmail.com wrote:
 It's a regression which I've caused. I've made a fixup pull:

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

 I'm very sorry for this mishap.

It's now fixed in git-head. Chances are we're not going to have
another 2.063 point release (I'm only speculating) so you may have to
use the latest git-head version to use lockstep.


Re: Problems building docs

2013-06-25 Thread Jesse Phillips

On Monday, 24 June 2013 at 19:20:44 UTC, H. S. Teoh wrote:
For me personally, I find that nesting dmd/druntime/phobos 
inside the
git checkout of d-programming-language.org a tad ugly, so I use 
this

instead:

parent/d-programming-language.org
parent/d-programming-language.org/web
parent/dmd
parent/druntime
parent/phobos


d-programming-language.org was changed to dlang.org, that is most 
likely the problem. No need for the web/ directory that will be 
created if everything else is placed correctly.


Re: Trouble with lockstep

2013-06-25 Thread Joseph Rushton Wakeling

On Tuesday, 25 June 2013 at 10:52:22 UTC, Andrej Mitrovic wrote:

On 6/25/13, Andrej Mitrovic andrej.mitrov...@gmail.com wrote:
It's now fixed in git-head. Chances are we're not going to have
another 2.063 point release (I'm only speculating) so you may 
have to

use the latest git-head version to use lockstep.


That's a shame, I'd like to think there'd be a commitment to 
release regression fixes. Anyway, thanks for getting a fix made, 
and don't feel too guilty about the regression -- you're just 
pushing people towards the superior zip :-)


Besides DMD, this fix needs to be propagated to GDC and LDC.


mutable constant?

2013-06-25 Thread Namespace
I want to ask if this code should compile or if it's a bug, 
because I circumvent the const system:



import std.stdio;

struct Point {
int x, y;
}

Point*[] points;

struct TplPoint(T) {
public:
Point _point;

T x, y;

const uint id;

this(T x, T y) {
this.x = x;
this.y = y;

points ~= this._point;

id = points.length - 1;
}

@property
inout(Point)* ptr() inout {
points[this.id].x = cast(int) this.x;
points[this.id].y = cast(int) this.y;

return cast(inout Point*) points[this.id];
}
}

void main() {
const TplPoint!float my = TplPoint!float(42, 23);
writeln(my._point, ::, my._point);
writeln(*my.ptr, ::, my.ptr);
}


Or is the fact that it compiles ok and it's only unsafe?


Re: mutable constant?

2013-06-25 Thread Simen Kjaeraas
On Wed, 26 Jun 2013 00:07:38 +0200, Namespace rswhi...@googlemail.com  
wrote:


I want to ask if this code should compile or if it's a bug, because I  
circumvent the const system:



import std.stdio;

struct Point {
int x, y;
}

Point*[] points;

struct TplPoint(T) {
public:
Point _point;

T x, y;

const uint id;

this(T x, T y) {
this.x = x;
this.y = y;

points ~= this._point;

id = points.length - 1;
}

@property
inout(Point)* ptr() inout {
points[this.id].x = cast(int) this.x;
points[this.id].y = cast(int) this.y;

return cast(inout Point*) points[this.id];
}
}

void main() {
const TplPoint!float my = TplPoint!float(42, 23);
writeln(my._point, ::, my._point);
writeln(*my.ptr, ::, my.ptr);
}


Or is the fact that it compiles ok and it's only unsafe?


This is perfectly fine.

--
Simen


Re: mutable constant?

2013-06-25 Thread Jonathan M Davis
On Wednesday, June 26, 2013 00:07:38 Namespace wrote:
 I want to ask if this code should compile or if it's a bug,
 because I circumvent the const system:
 
 
 import std.stdio;
 
 struct Point {
 int x, y;
 }
 
 Point*[] points;
 
 struct TplPoint(T) {
 public:
 Point _point;
 
 T x, y;
 
 const uint id;
 
 this(T x, T y) {
 this.x = x;
 this.y = y;
 
 points ~= this._point;
 
 id = points.length - 1;
 }
 
 @property
 inout(Point)* ptr() inout {
 points[this.id].x = cast(int) this.x;
 points[this.id].y = cast(int) this.y;
 
 return cast(inout Point*) points[this.id];
 }
 }
 
 void main() {
 const TplPoint!float my = TplPoint!float(42, 23);
 writeln(my._point, ::, my._point);
 writeln(*my.ptr, ::, my.ptr);
 }
 
 
 Or is the fact that it compiles ok and it's only unsafe?

I could certainly be missing something here, but I don't understand what
about the code you're even concerned about. Where in here would you be
breaking the type system? I don't see any place in here where you're
mutating a const variable or anything like that. The worst thing I see
about the code is that it won't compile on 64-bit machines thanks to

id = points.length - 1;

- Jonathan M Davis


Re: mutable constant?

2013-06-25 Thread Namespace

If you change uint to size_t it works fine AFAIK.


Re: mutable constant?

2013-06-25 Thread Jonathan M Davis
On Wednesday, June 26, 2013 00:52:58 Namespace wrote:
 If you change uint to size_t it works fine AFAIK.

Yes. It's easy enough to fix, but it _is_ arguably a bug in the code, and it's 
the only one that's obvious to me. I don't understand what about the code 
makes you think that it might be violating the type system.

- Jonathan M Davis


P.S. Please always quote at least a portion of the post that you're replying 
to. Clients frequently do not manage to thread posts correctly, and it's not 
always clear which post a post is replying to if it doesn't quote any of its 
parent. In this particular case, based on what you said, I expect that you 
were replying to me, but it's threaded in my client as being a responsed to 
Simen. Also, not all posters even use a threaded view. So, relying on 
threading to make it clear which post you're replying to is not a good idea.


Re: mutable constant?

2013-06-25 Thread Ali Çehreli

With apologies, I have unrelated comments to make.

On 06/25/2013 03:07 PM, Namespace wrote:

  this(T x, T y) {
  this.x = x;
  this.y = y;

  points ~= this._point;

I have seen similar designs in the past where constructors had 
side-effects such as registering the object in a global state. (Exactly 
what the last line is doing above.)


It has almost always been cause of trouble. It is better to register an 
object from the outside after constructing it.


Sometimes I had attempted to remove seemingly unused objects only to be 
reminded by a comment that it should not be:


// Do not remove! Registers itself in the points array
auto p = Point();

  @property
  inout(Point)* ptr() inout {
  points[this.id].x = cast(int) this.x;
  points[this.id].y = cast(int) this.y;

That looks questionable as well: ptr() looks like an accessor but it 
makes changes to a global state.


Ali



Re: typeof map

2013-06-25 Thread cal

On Tuesday, 25 June 2013 at 06:58:33 UTC, monarch_dodra wrote:

On Tuesday, 25 June 2013 at 04:26:00 UTC, Timothee Cour wrote:

I think it's because each lambda litteral is treated unique.
can dmd be changed to recognize identical lambda litterals as 
identical? Is

there any particular issue making that difficult?
it already recognizes identical string literals as identical


I could be wrong, but the difference might be that it *can* 
recognize string literals as idential, but it doesn't actually 
guarantee it as spec. This is not an issue for strings, but...


I also thought it was to do with identical lambda literals being 
unique, and that the code should have compiled, but I've changed 
my mind after seeing your argument.





Overload of ! operator

2013-06-25 Thread Eric


Is there a way to overload the ! operator?  I can't seem to get
it to work with the standard unaryOp method.  I need this because
I am making a wrapper for a C++ API that has ! overloaded.

-Eric


Re: Overload of ! operator

2013-06-25 Thread bearophile

Eric:


Is there a way to overload the ! operator?  I can't seem to get
it to work with the standard unaryOp method.  I need this 
because

I am making a wrapper for a C++ API that has ! overloaded.


D is not a superset of C++ and I think there is no way to 
overload the ! alone. This is by design. But you can define a 
bang property method.


Maybe other people can give you a better answer.

Bye,
bearophile


Re: Overload of ! operator

2013-06-25 Thread Jonathan M Davis
On Wednesday, June 26, 2013 04:50:44 Eric wrote:
 Is there a way to overload the ! operator?  I can't seem to get
 it to work with the standard unaryOp method.  I need this because
 I am making a wrapper for a C++ API that has ! overloaded.

TDPL does not list it as an overloadable operator, so it probably can't be 
overloaded (especially if you've tried it, and it doesn't work). But you 
should be able to simply have a wrapper function which is a normal function 
rather than an overloaded operator.

- Jonathan M Davis


Re: Overload of ! operator

2013-06-25 Thread cal

On Wednesday, 26 June 2013 at 02:50:51 UTC, Eric wrote:


Is there a way to overload the ! operator?  I can't seem to get
it to work with the standard unaryOp method.  I need this 
because

I am making a wrapper for a C++ API that has ! overloaded.

-Eric


According to http://dlang.org/operatoroverloading.html#Cast, the 
following are rewritten:


if (e) = if (e.opCast!(bool))
if (!e) = if (!e.opCast!(bool))

So perhaps you need to override opCast!(bool).


Re: Overload of ! operator

2013-06-25 Thread Jonathan M Davis
On Wednesday, June 26, 2013 05:35:03 cal wrote:
 On Wednesday, 26 June 2013 at 02:50:51 UTC, Eric wrote:
  Is there a way to overload the ! operator?  I can't seem to get
  it to work with the standard unaryOp method.  I need this
  because
  I am making a wrapper for a C++ API that has ! overloaded.
  
  -Eric
 
 According to http://dlang.org/operatoroverloading.html#Cast, the
 following are rewritten:
 
 if (e) = if (e.opCast!(bool))
 if (!e) = if (!e.opCast!(bool))
 
 So perhaps you need to override opCast!(bool).

Yeah, that should work for the conditions in if, while, and for loops but 
won't work for anything else (_maybe_ ternary operators, but I'm not sure). 
So, if you need to be able to do !obj in the general case, that's not going to 
work, but if you only need it for conditions, then it would. And of course 
this all assumes that the C++ code is overloading ! to do something sane with 
bool rather than redefining it to mean something completely different.

- Jonathan M Davis


Re: Overload of ! operator

2013-06-25 Thread Ali Çehreli

On 06/25/2013 09:05 PM, Jonathan M Davis wrote:

 On Wednesday, June 26, 2013 05:35:03 cal wrote:
 On Wednesday, 26 June 2013 at 02:50:51 UTC, Eric wrote:
 Is there a way to overload the ! operator?  I can't seem to get
 it to work with the standard unaryOp method.  I need this
 because
 I am making a wrapper for a C++ API that has ! overloaded.

 -Eric

 According to http://dlang.org/operatoroverloading.html#Cast, the
 following are rewritten:

 if (e) = if (e.opCast!(bool))
 if (!e) = if (!e.opCast!(bool))

 So perhaps you need to override opCast!(bool).

 Yeah, that should work for the conditions in if, while, and for loops but
 won't work for anything else (_maybe_ ternary operators, but I'm not 
sure).


Works for ternary as well.

The other option is 'alias this' but it is a little dangerous because 
bool is an arithmetic type. So, opCast would be better.


import std.stdio;

struct S
{
int i;

bool truth() const
{
return i == 42;
}

alias truth this;
}

void foo(bool b)
{
writeln(b);
}

void main()
{
auto s = S(42);

if (s){
}

while (s) {
break;
}

int i = s ? 4 : 5;

foo(s);

// What does it mean?
writeln(s + 2);
writeln(!s - 7);
}

 So, if you need to be able to do !obj in the general case, that's not 
going to

 work

It surprisingly works both with opCast and 'alias this'.

Ali



Re: eof

2013-06-25 Thread lx

On Monday, 24 June 2013 at 21:13:31 UTC, bearophile wrote:
I am very confused that ctrl+z didn't teminate the input of 
console,it result in a dead loop.


I think this is a library bug, I noticed it some times, but I 
didn't file it. Maybe it's worth filing in Bugzilla.


I have added this bug report, is this the issue you are 
seeing/having?


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

Bye,
bearophile
I read those information and yes,it is the issue I am having.I 
should have handled it in right way.Ctrl+z seems close the 
stream.So,if I want to input another batch of data,it became 
impossilbe.So,how to reopen the stream again to allow me to input 
another batch of data?


And,another problem:if I input ctrl+c,the code will terminate 
abnormally.Why this happened?

Thanks.
lx



Re: eof

2013-06-25 Thread Ali Çehreli

On 06/25/2013 09:26 PM, lx wrote:

 Ctrl+z seems close the stream.So,if I want
 to input another batch of data,it became impossilbe.So,how to reopen the
 stream again to allow me to input another batch of data?

Making a copy of stdin works on Linux (where the stream is terminated by 
Ctrl-D in the console):


import std.stdio;
import std.algorithm;

void main()
{
auto stdin_dup = stdin;

stdin
.byLine(KeepTerminator.yes)
.copy(stdout.lockingTextWriter);

writeln(done);

stdin_dup
.byLine(KeepTerminator.yes)
.copy(stdout.lockingTextWriter);

writeln(done again);
}

Ali



Re: Overload of ! operator

2013-06-25 Thread Eric

On Wednesday, 26 June 2013 at 04:16:30 UTC, Ali Çehreli wrote:

On 06/25/2013 09:05 PM, Jonathan M Davis wrote:

 On Wednesday, June 26, 2013 05:35:03 cal wrote:
 On Wednesday, 26 June 2013 at 02:50:51 UTC, Eric wrote:
 Is there a way to overload the ! operator?  I can't seem to
get
 it to work with the standard unaryOp method.  I need this
 because
 I am making a wrapper for a C++ API that has ! overloaded.

 -Eric

 According to http://dlang.org/operatoroverloading.html#Cast,
the
 following are rewritten:

 if (e) = if (e.opCast!(bool))
 if (!e) = if (!e.opCast!(bool))

 So perhaps you need to override opCast!(bool).

 Yeah, that should work for the conditions in if, while, and
for loops but
 won't work for anything else (_maybe_ ternary operators, but
I'm not sure).

Works for ternary as well.

The other option is 'alias this' but it is a little dangerous 
because bool is an arithmetic type. So, opCast would be better.


import std.stdio;

struct S
{
int i;

bool truth() const
{
return i == 42;
}

alias truth this;
}

void foo(bool b)
{
writeln(b);
}

void main()
{
auto s = S(42);

if (s){
}

while (s) {
break;
}

int i = s ? 4 : 5;

foo(s);

// What does it mean?
writeln(s + 2);
writeln(!s - 7);
}

 So, if you need to be able to do !obj in the general case,
that's not going to
 work

It surprisingly works both with opCast and 'alias this'.

Ali



Thanks for all the insignt. But I think I'm just going to fudge 
this one

with a bang() method...

Incidently, for this project I figured out an interesting use of 
alias.
The C++ classes I am wrapping have a lot of virtual methods with 
all primitive arguments.   So I create an D-interface for them, 
and wrap the rest with C methods.  The wrapper class then makes 
methods that call the C methods, and then aliases the interface 
reference to this so that the wrapper class instance points to 
both the C++ native methods as well as the C-wrapped methods.


-Eric










Re: Overload of ! operator

2013-06-25 Thread cal
On Wednesday, 26 June 2013 at 04:06:05 UTC, Jonathan M Davis 
wrote:
Yeah, that should work for the conditions in if, while, and for 
loops but
won't work for anything else (_maybe_ ternary operators, but 
I'm not sure).
So, if you need to be able to do !obj in the general case, 
that's not going to

work

...

import std.stdio;

struct S {
  int x;
  bool opCast(T)() if (is(T == bool)) {
return x == 0;
  }
}

void main() {   
  auto s = S(1);
  auto b = !s;
  writeln(b);   // true
}

Is this not supposed to work?


Re: Overload of ! operator

2013-06-25 Thread Jonathan M Davis
On Wednesday, June 26, 2013 06:59:14 cal wrote:
 On Wednesday, 26 June 2013 at 04:06:05 UTC, Jonathan M Davis
 
 wrote:
  Yeah, that should work for the conditions in if, while, and for
  loops but
  won't work for anything else (_maybe_ ternary operators, but
  I'm not sure).
  So, if you need to be able to do !obj in the general case,
  that's not going to
  work
 
 ...
 
 import std.stdio;
 
 struct S {
int x;
bool opCast(T)() if (is(T == bool)) {
  return x == 0;
}
 }
 
 void main() {
auto s = S(1);
auto b = !s;
writeln(b);// true
 }
 
 Is this not supposed to work?

No, it's not. That would require an implicit cast (which requires using alias 
this). opCast gives you an explicit cast only. Where that becomes confusing is 
the fact that the compiler inserts explicitly casts to bool in conditions for 
if statements, loops, and the ternary operator. e.g.

if(foo) {...}

becomes

if(cast(bool)foo) {...}

So, if you've overloaded opCast to bool, then it'll get used in the conditions 
for if statements, loops, and the ternary operator. But no explicit cast is 
added just for putting ! in front of a variable. It works with something like

if(!foo) {...}

simply because that becomes

if(!cast(bool)foo) {...}

But nothing special is done for !, and !a will not call opCast.

- Jonathan M Davis


Re: Overload of ! operator

2013-06-25 Thread cal
On Wednesday, 26 June 2013 at 05:08:07 UTC, Jonathan M Davis 
wrote:

On Wednesday, June 26, 2013 06:59:14 cal wrote:

On Wednesday, 26 June 2013 at 04:06:05 UTC, Jonathan M Davis

wrote:
 Yeah, that should work for the conditions in if, while, and 
 for

 loops but
 won't work for anything else (_maybe_ ternary operators, but
 I'm not sure).
 So, if you need to be able to do !obj in the general case,
 that's not going to
 work

...

import std.stdio;

struct S {
   int x;
   bool opCast(T)() if (is(T == bool)) {
 return x == 0;
   }
}

void main() {
   auto s = S(1);
   auto b = !s;
   writeln(b);  // true
}

Is this not supposed to work?


No, it's not. That would require an implicit cast (which 
requires using alias
this). opCast gives you an explicit cast only. Where that 
becomes confusing is
the fact that the compiler inserts explicitly casts to bool in 
conditions for

if statements, loops, and the ternary operator. e.g.

if(foo) {...}

becomes

if(cast(bool)foo) {...}

So, if you've overloaded opCast to bool, then it'll get used in 
the conditions
for if statements, loops, and the ternary operator. But no 
explicit cast is
added just for putting ! in front of a variable. It works with 
something like


if(!foo) {...}

simply because that becomes

if(!cast(bool)foo) {...}

But nothing special is done for !, and !a will not call opCast.

- Jonathan M Davis


But that code I posted does work, and gives the output shown. Am 
I misunderstanding?


Re: eof

2013-06-25 Thread Ali Çehreli

On 06/25/2013 09:26 PM, lx wrote:

 I input ctrl+c,the code will terminate
 abnormally.Why this happened?

Ctrl-C appears as SIGINT under POSIX systems. You need to register a 
handler for that signal:


import std.stdio;
import std.string;
import core.sys.posix.signal;

bool isDone = false;

extern(C) void mySIGINThandler(int) nothrow @system
{
isDone = true;
}

void main()
{
signal(SIGINT, mySIGINThandler);

while (true) {
string line = chomp(readln());

if (stdin.eof() || isDone) {
break;

} else {
writefln(Nice line: %s, line);
}
}
}

Ali



Re: Overload of ! operator

2013-06-25 Thread Eric

On Wednesday, 26 June 2013 at 04:59:19 UTC, cal wrote:
On Wednesday, 26 June 2013 at 04:06:05 UTC, Jonathan M Davis 
wrote:
Yeah, that should work for the conditions in if, while, and 
for loops but
won't work for anything else (_maybe_ ternary operators, but 
I'm not sure).
So, if you need to be able to do !obj in the general case, 
that's not going to

work

...

import std.stdio;

struct S {
  int x;
  bool opCast(T)() if (is(T == bool)) {
return x == 0;
  }
}

void main() {   
  auto s = S(1);
  auto b = !s;
  writeln(b);   // true
}

Is this not supposed to work?


I should have also added that the overloaded ! method returns a 
class instance and not a bool.


-Eric





Re: Overload of ! operator

2013-06-25 Thread Jonathan M Davis
On Wednesday, June 26, 2013 07:14:36 cal wrote:
 But that code I posted does work, and gives the output shown. Am
 I misunderstanding?

Then my understanding of how ! is handled is wrong. Apparently !s does get 
replaced with !cast(bool)s, or it couldn't work. But note that

bool b = s;

doesn't work, so as I said, it's not the case that opCast gives you an 
implicit cast. It's just the cases where cases where the compiler inserts an 
explicit cast for you that it looks like it gives you an implicit cast. But 
apparently, there was a case that it inserts an explicit cast of which I was 
not aware.

- Jonathan M Davis


Re: Overload of ! operator

2013-06-25 Thread Jonathan M Davis
On Wednesday, June 26, 2013 07:15:19 Eric wrote:
 I should have also added that the overloaded ! method returns a
 class instance and not a bool.

Well, at that point, you're completely out of luck with regards to overloading 
!. In general, D doesn't really support overloading operators in a manner that 
doesn't match how the built-in types work. It does things like assume that , 
=, =, and  will act the same way that they do with the built-in types and 
uses opCmp to extrapolate all of those operators. In some cases, you _can_ 
make overloaded operators return types that make it so that they don't 
function anything like the built-in types (e.g. opBinary with + could return a 
completely unrelated type that had nothing to do with the original type or 
with addition), but in pretty much any case where the compiler can get away 
with using the same overloaded operator for multiple operators, it does it. 
So, a number of decisions were made to better support correctness with types 
that actually try and overload operators to match what the built-in types do 
without caring about how that would affect types that would try and overload 
them to do unrelated stuff.

- Jonathan M Davis