Re: float[] → Vertex[] – decreases performance by 1000%

2012-07-27 Thread dennis luehring

Am 26.07.2012 21:18, schrieb David:

Hm. Do you ever do pointer arithmetic on Vertex*?  Is the size and
offsets are correct (like in Vertex vs float)?


No, yes. I really have no idea why this happens, I saved the contents of
my buffers and compared them with the buffers of the `float[]` version
(thanks to `git checkout`) and they were exactly 100% the same.
It's a mystery.




can you create a version of you code thats allows switching 
(version(Vertex) else ...) between array and Vertex? or provide both 
versions here again


you checked dmd and ldc output so it can't be a backend thing (maybe 
frontend or GC) - or mysterious GL bugs


Re: Writing very large files 50+ GB

2012-07-27 Thread Regan Heath

On Fri, 27 Jul 2012 02:50:56 +0100, wmunger wmun...@gmail.com wrote:

I need to write to a file that is 50 to 250GB on all three major  
operating systems.


I tried to use the c function pwrite64.  But it is not available on the  
Mac.


I have seen where some have used the iostream in C++ but this does not  
seem to work on the Mac.


Is there any way to write in D very large files.  After all I would  
rather write in D than wrap C or C++ code.


Have you looked for open, lseek(64) and write?

R

--
Using Opera's revolutionary email client: http://www.opera.com/mail/


Assert prints an array of char when used why to!string

2012-07-27 Thread monarch_dodra

Code:


import std.conv;
void main() {
  static assert(
is(typeof((Failure:  ~ to!string(55)) == string))
  );

  static assert(0 , (Failure:  ~ to!string(55)));
}

main.d(7): Error: static assert  
['F','a','i','l','u','r','e',':',' ','5','5']



The problem is the ugly-ass print as array of individual 
characters.


I really don't understand what is going on, since the compile 
type of my string is indeed string.


If I remove the to!string, I get:

main.d(7): Error: static assert  Failure


1) Is this the normal behavior, or a known limitation?
2) Is there a workaround?

FYI, this was originally produced by code from Phobos, but was 
trimmed by me here.


A few questions

2012-07-27 Thread Namespace

1.
Why are these two method header identitcal?

const Foo some_function() {

and

Foo some_function() const {

?

IMO that isn't consistent. IMO only the last is valid.
With this example, it is somewhat understandable.

// C++
class Bar {
const Foo getFooObj() const { ... }
const Foo getFooObjRef const { ... }
};

// D
class Bar {
const(Foo) getFooObj() const { ... }
ref Foo getObjRef() { ... }
}

const(Foo) but ref Foo. This is inconsistency, if you ask me.
So why is between C++ and D such a huge difference?
Why isn't it simply const Foo instead of const(Foo)?

2.
What's about a shorthand for debug assertions?
E.g. to avoid not-null references (yes, if you're a windows user, 
you hate them):


Example:

[code]
void some_function(Foo !f) {
[/code]

will automatically converted by the compiler into:

[code]
void some_function(Foo f, string filename = __FILE__, uint line = 
__LINE__) in {
assert(f !is null, format(Null Object @ file %s on line 
%d., filename, line));

} body {
[/code]

That would be avoid many many efforts by writing safe code. And 
it avoids Java code stil with explizit pre- and postconditions 
which blows up code.




Re: A few questions

2012-07-27 Thread monarch_dodra

On Friday, 27 July 2012 at 10:29:15 UTC, Namespace wrote:

1.
Why are these two method header identitcal?

const Foo some_function() {

and

Foo some_function() const {

?

IMO that isn't consistent. IMO only the last is valid.
With this example, it is somewhat understandable.


Some would argue only the *first* should be valid:


@safe const @property nothrow
Foo some_function();


Basically, yeah, you have the option of putting qualifiers before 
or after.


Re: A few questions

2012-07-27 Thread Jacob Carlborg

On 2012-07-27 12:29, Namespace wrote:

1.
Why are these two method header identitcal?

const Foo some_function() {

and

Foo some_function() const {

?


The reason const Foo some_function is allowed is because in D this 
syntax is possible:


class Foo
{
const:

Foo some_function () {}
}


IMO that isn't consistent. IMO only the last is valid.
With this example, it is somewhat understandable.

// C++
class Bar {
 const Foo getFooObj() const { ... }
 const Foo getFooObjRef const { ... }
};

// D
class Bar {
 const(Foo) getFooObj() const { ... }
 ref Foo getObjRef() { ... }
}

const(Foo) but ref Foo. This is inconsistency, if you ask me.
So why is between C++ and D such a huge difference?
Why isn't it simply const Foo instead of const(Foo)?


I think the reason is the same as above. If the return value is const 
you need to use parentheses. I think that the syntax would conflict with 
the const-method syntax otherwise.


The reason for why const is allowed after the paramter list is because 
it can be a bit confusing to have two const next to each other.


class Foo
{
const const (Foo) foo () {}
}

--
/Jacob Carlborg


Re: A few questions

2012-07-27 Thread Jacob Carlborg

On 2012-07-27 13:14, Jacob Carlborg wrote:

On 2012-07-27 12:29, Namespace wrote:



const(Foo) but ref Foo. This is inconsistency, if you ask me.
So why is between C++ and D such a huge difference?
Why isn't it simply const Foo instead of const(Foo)?


I think the reason is the same as above. If the return value is const
you need to use parentheses. I think that the syntax would conflict with
the const-method syntax otherwise.

The reason for why const is allowed after the paramter list is because
it can be a bit confusing to have two const next to each other.

class Foo
{
 const const (Foo) foo () {}
}



Forgot to say, the reason for why the ref(Foo) syntax isn't used is 
because there can be no conflict since methods cannot be declared as const.


--
/Jacob Carlborg


Re: A few questions

2012-07-27 Thread Namespace
The reason const Foo some_function is allowed is because in D 
this syntax is possible:


class Foo
{
const:

Foo some_function () {}
}


Good point. I had completely forgotten, that that is possible.
But it seems that no one would have interest in my second 
proposal. :)


Re: A few questions

2012-07-27 Thread bearophile

Namespace:


Good point. I had completely forgotten, that that is possible.
But it seems that no one would have interest in my second 
proposal. :)


Similar things were discussed a lot. And some people think that 
similar nonnull annotations are a good idea.


Bye,
bearophile


Re: Assert prints an array of char when used why to!string

2012-07-27 Thread bearophile

monarch_dodra:


1) Is this the normal behavior, or a known limitation?


It seems a DMD bug, why don't you add it to Bugzilla?



2) Is there a workaround?


static assert(0, text(Failure: , 55));

Bye,
bearophile


Re: A few questions

2012-07-27 Thread Namespace

On Friday, 27 July 2012 at 11:50:46 UTC, bearophile wrote:

Namespace:


Good point. I had completely forgotten, that that is possible.
But it seems that no one would have interest in my second 
proposal. :)


Similar things were discussed a lot. And some people think that 
similar nonnull annotations are a good idea.


Bye,
bearophile


Then: What is the problem to introduce such shorthand?
To solve the problem with a struct is IMO a really _bad_ idea.
Because then you have to pack the object into the struct (or you 
have to create the object with a function that returns this 
struct, equally as scoped does it currently) and _then_ you can 
pass it to the function/method.

Still the same effort as if you solve it with preconditions.
Completely unnecessary work, and such shorthand can avoid this.


Re: A few questions

2012-07-27 Thread bearophile

Namespace:


Then: What is the problem to introduce such shorthand?


I don't know.
I have a partial enhancement on the topic:
http://d.puremagic.com/issues/show_bug.cgi?id=4571

Bye,
bearophile


Re: A few questions

2012-07-27 Thread Simen Kjaeraas
On Fri, 27 Jul 2012 14:44:35 +0200, bearophile bearophileh...@lycos.com  
wrote:



Namespace:


Then: What is the problem to introduce such shorthand?


I don't know.
I have a partial enhancement on the topic:
http://d.puremagic.com/issues/show_bug.cgi?id=4571

Bye,
bearophile


I believe at least part of the explanation is that Walter wants NotNull to
implemented in a library. That's part of the reason for introducing
@disable this().

Now, one could certainly argue that int? be translated by the compiler into
NotNull!int, and the implementation lie in druntime.

--
Simen


Re: A few questions

2012-07-27 Thread Namespace

Short improvement: http://dpaste.dzfl.pl/f3263def


Re: A few questions

2012-07-27 Thread bearophile

Simen Kjaeraas:

I believe at least part of the explanation is that Walter wants 
NotNull to
implemented in a library. That's part of the reason for 
introducing @disable this().


Yes, I remember part of the discussions. And I agree that 
generally it's better to put meta-features in a language that 
allow library code to implement the desired features.


That's why recently in the main D newsgroup I have said that 
built-in vector ops may be better replaced by library code 
(what's missing is some built-in trick to avoid the creation of 
intermediate arrays in complex expression).


But implementing good non-null types in library code is hard 
(rather harder than implementing vector ops in library code on 
library defined vectors). I think @disable isn't enough to cover 
what Spec# shows good non-null types are meant to be.


Bye,
bearophile


Re: A few questions

2012-07-27 Thread Namespace

What's wrong with the solution that

void some_function(Foo? f) {

is converted to

void some_function(Foo f, string filename = __FILE__, uint line = 
__LINE__)  in {
assert(f !is null, std.string.format(Null Object @ File %s 
on Line %d., filename, line));

} body {

? It isn't a huge effort for the compiler, or?


Re: Assert prints an array of char when used why to!string

2012-07-27 Thread novice2

BTW, in docs about text:

http://dlang.org/phobos/std_conv.html#text

...Convenience functions for converting any number and types of
arguments into text (the three character widths)... 

What is the three character widths note?
Who knows?


Re: Assert prints an array of char when used why to!string

2012-07-27 Thread Adam D. Ruppe

On Friday, 27 July 2012 at 14:40:33 UTC, novice2 wrote:

What is the three character widths note?
Who knows?


string, wstring, and dstring. Width refers to the bit size
of the char (8 bit, 16 bit, or 32 bit).


Re: Assert prints an array of char when used why to!string

2012-07-27 Thread novice2

Ah, thanks!

On Friday, 27 July 2012 at 14:47:49 UTC, Adam D. Ruppe wrote:

On Friday, 27 July 2012 at 14:40:33 UTC, novice2 wrote:

What is the three character widths note?
Who knows?


string, wstring, and dstring. Width refers to the bit size
of the char (8 bit, 16 bit, or 32 bit).





Re: A few questions

2012-07-27 Thread Simen Kjaeraas
On Fri, 27 Jul 2012 16:39:49 +0200, Namespace rswhi...@googlemail.com  
wrote:



What's wrong with the solution that

void some_function(Foo? f) {

is converted to

void some_function(Foo f, string filename = __FILE__, uint line =  
__LINE__)  in {
 assert(f !is null, std.string.format(Null Object @ File %s on Line  
%d., filename, line));

} body {

? It isn't a huge effort for the compiler, or?


Nope.

But, that's just a simple assertion. If we'd had real non-nullable types,
we could remove the check completely, because you'd know it held a valid
object.

Now, a library solution has certain limitations a built-in solution would
not - for instance, new X would return non-nullable.

--
Simen


Just a matter of parentheses

2012-07-27 Thread bearophile

This works in DMD 2.059, but it doesn't in dmd 2.060beta:


import std.algorithm: sort;
void main() {
int[int] foo;
auto bar1 = foo.keys().sort(); // OK
auto bar2 = foo.keys.sort(); // Error: function expected 
before ()...

}


Do you think this should be filed as regression?

Bye,
bearophile



Re: Just a matter of parentheses

2012-07-27 Thread Alex Rønne Petersen

On 27-07-2012 17:23, bearophile wrote:

This works in DMD 2.059, but it doesn't in dmd 2.060beta:


import std.algorithm: sort;
void main() {
 int[int] foo;
 auto bar1 = foo.keys().sort(); // OK
 auto bar2 = foo.keys.sort(); // Error: function expected before ()...
}


Do you think this should be filed as regression?

Bye,
bearophile



Yes. keys is specifically meant to be a property.

--
Alex Rønne Petersen
a...@lycus.org
http://lycus.org


Re: A few questions

2012-07-27 Thread Jonathan M Davis
On Friday, July 27, 2012 12:29:13 Namespace wrote:
 1.
 Why are these two method header identitcal?
 
 const Foo some_function() {
 
 and
 
 Foo some_function() const {
 
 ?

 const(Foo) but ref Foo. This is inconsistency, if you ask me.
 So why is between C++ and D such a huge difference?
 Why isn't it simply const Foo instead of const(Foo)?

Sadly, the reason is consistency. const is an attribute just like pure or 
nothrow, and you can do both

pure Foo func() {}

and

Foo func() pure {}

as well as

pure { Foo func() {} }

and

pure : Foo func() {}

If

const Foo func() {}

made Foo const rather than func, it would be inconsistent with the other 
attributes, and if const on func were only legal on the right (as in C++), 
then it would be inconsistent with the others. Many of us think that

const Foo func() {}

should just become illegal inconsistency or not because of all of this 
confusion, but Walter doesn't buy into that.

 2.
 What's about a shorthand for debug assertions?
 E.g. to avoid not-null references (yes, if you're a windows user,
 you hate them):

Walter's stand on this is that the OS gives you null-dereferencing detection - 
i.e. segfaults and access violations. He's not going to add extra syntax for 
it.

- Jonathan M Davis


A matter of inout

2012-07-27 Thread bearophile

This program used to compile in DMD 2.059:


import std.stdio;
inout(T[]) forwardDifference(T)(inout(T[]) s, in int n) pure {
foreach (_; 0 .. n)
s[] -= s[1 .. $];
return s[0 .. $-n];
}
void main() {
immutable A = [90.5, 47, 58, 29, 22, 32, 55, 5, 55, 73.5];
foreach (level; 0 .. A.length)
writeln(forwardDifference(A.dup, level));
}


Now it gives:

test.d(5): Error: slice s[] is not mutable
test.d(12): Error: template instance 
test.forwardDifference!(double) error instantiating


Is it a 2.060 regression (or it's caused by a bug fix)?

Bye,
bearophile


Re: Assert prints an array of char when used why to!string

2012-07-27 Thread monarch_dodra

On Friday, 27 July 2012 at 11:56:07 UTC, bearophile wrote:

monarch_dodra:


1) Is this the normal behavior, or a known limitation?


It seems a DMD bug, why don't you add it to Bugzilla?



2) Is there a workaround?


static assert(0, text(Failure: , 55));

Bye,
bearophile


Thanks. I'll create an entry in bugzilla.


Re: Just a matter of parentheses

2012-07-27 Thread bearophile

Alex Rønne Petersen:


Yes. keys is specifically meant to be a property.


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

Bye,
bearophile


copying the targets of pointers

2012-07-27 Thread monarch_dodra
This is going to sound stupid, but how do you have two pointers' 
targets copy each other? since pointers are used like reference 
types, how do you write the C++ equivalent of *p1 == *p2


Here is the context of what I'm trying to do:


struct S
{
  struct Payload
  {}
  Payload payload;

  @property
  typeof(this) dup()
  {
typeof(this) ret;
if(payload)
{
  ret.payload = new Payload;
  ret.payload = payload; //Copies the payload? The pointer?
}
return ret;
  }
}


So yeah, that was my question. I'd be tempted to write:
ret.payload.field1 = payload.field1;
ret.payload.field2 = payload.field2;
...

But:
1) It feels hackish and just going around the problem
2) It works for pointer to Struct with fields, but what about 
things like int* ?


Oh yeah, also, if you have a better idea for an better (cleaner) 
implementation of a payload based reference type structs, I'm 
all ears.


Re: A matter of inout

2012-07-27 Thread Dmitry Olshansky

On 27-Jul-12 19:53, bearophile wrote:

This program used to compile in DMD 2.059:


import std.stdio;
inout(T[]) forwardDifference(T)(inout(T[]) s, in int n) pure {
 foreach (_; 0 .. n)
 s[] -= s[1 .. $];
 return s[0 .. $-n];
}
void main() {
 immutable A = [90.5, 47, 58, 29, 22, 32, 55, 5, 55, 73.5];
 foreach (level; 0 .. A.length)
 writeln(forwardDifference(A.dup, level));
}


Now it gives:

test.d(5): Error: slice s[] is not mutable
test.d(12): Error: template instance test.forwardDifference!(double)
error instantiating

Is it a 2.060 regression (or it's caused by a bug fix)?



If it compiled before then I'd think it's a regression.



--
Dmitry Olshansky


Re: A matter of inout

2012-07-27 Thread Artur Skawina
On 07/27/12 17:53, bearophile wrote:
 This program used to compile in DMD 2.059:
 
 
 import std.stdio;
 inout(T[]) forwardDifference(T)(inout(T[]) s, in int n) pure {
 foreach (_; 0 .. n)
 s[] -= s[1 .. $];
 return s[0 .. $-n];
 }
 void main() {
 immutable A = [90.5, 47, 58, 29, 22, 32, 55, 5, 55, 73.5];
 foreach (level; 0 .. A.length)
 writeln(forwardDifference(A.dup, level));
 }
 
 
 Now it gives:
 
 test.d(5): Error: slice s[] is not mutable
 test.d(12): Error: template instance test.forwardDifference!(double) error 
 instantiating
 
 Is it a 2.060 regression (or it's caused by a bug fix)?

'inout' basically means 'local const' - if you'd allow inout
data to be modified then it wouldn't be possible to call the
function with a const or immutable argument - which is the
whole point of inout...
You probably want 'inout(T)[]' if you're going to alter the
array.

artur


Re: copying the targets of pointers

2012-07-27 Thread Artur Skawina
On 07/27/12 18:11, monarch_dodra wrote:
 This is going to sound stupid, but how do you have two pointers' targets copy 
 each other? since pointers are used like reference types, how do you write 
 the C++ equivalent of *p1 == *p2

Exactly the same, there's no difference between C and D pointers, except for 
classes.

 Here is the context of what I'm trying to do:
 
 
 struct S
 {
   struct Payload
   {}
   Payload payload;
 
   @property
   typeof(this) dup()
   {
 typeof(this) ret;
 if(payload)
 {
   ret.payload = new Payload;
   ret.payload = payload; //Copies the payload? The pointer?

'ret.payload' is 'S'; 'new Payload' is '*S'...

If you meant 'Payload* payload;', then just the pointer is copied.

artur


Re: A matter of inout

2012-07-27 Thread bearophile

Artur Skawina:


'inout' basically means 'local const' - if you'd allow inout
data to be modified then it wouldn't be possible to call the
function with a const or immutable argument - which is the
whole point of inout...
You probably want 'inout(T)[]' if you're going to alter the
array.


Using inout(T)[] gives the same error:

import std.stdio;
inout(T)[] forwardDifference(T)(inout(T)[] s, in int n) pure {
foreach (_; 0 .. n)
s[] -= s[1 .. $];
return s[0 .. $ - n];
}
void main() {
immutable A = [90.5, 47, 58, 29, 22, 32, 55, 5, 55, 73.5];
foreach (level; 0 .. A.length)
writeln(forwardDifference(A.dup, level));
}


Bye,
bearophile


Re: A matter of inout

2012-07-27 Thread bearophile

Artur Skawina:


'inout' basically means 'local const' - if you'd allow inout
data to be modified then it wouldn't be possible to call the
function with a const or immutable argument - which is the
whole point of inout...


dmd 2.059 was wrong then.

Bye,
bearophile


Re: A matter of inout

2012-07-27 Thread Artur Skawina
On 07/27/12 19:06, bearophile wrote:
 Artur Skawina:
 
 'inout' basically means 'local const' - if you'd allow inout
 data to be modified then it wouldn't be possible to call the
 function with a const or immutable argument - which is the
 whole point of inout...
 You probably want 'inout(T)[]' if you're going to alter the
 array.
 
 Using inout(T)[] gives the same error:
 
 import std.stdio;
 inout(T)[] forwardDifference(T)(inout(T)[] s, in int n) pure {
 foreach (_; 0 .. n)
 s[] -= s[1 .. $];
 return s[0 .. $ - n];
 }
 void main() {
 immutable A = [90.5, 47, 58, 29, 22, 32, 55, 5, 55, 73.5];
 foreach (level; 0 .. A.length)
 writeln(forwardDifference(A.dup, level));
 }

This alters not only the array, but also modifies the elements.

Using just 'T' instead of 'inout(T)' will do the right thing;
why would you like to use inout in cases like this one? 'inout'
allows you to not write two or more /identical/ function bodies
when the code can deal with immutable/const/mutable; functions
that modify the data in-place obviously can't do that.

artur


Re: copying the targets of pointers

2012-07-27 Thread monarch_dodra

On Friday, 27 July 2012 at 16:47:47 UTC, Artur Skawina wrote:

On 07/27/12 18:11, monarch_dodra wrote:
This is going to sound stupid, but how do you have two 
pointers' targets copy each other? since pointers are used 
like reference types, how do you write the C++ equivalent of 
*p1 == *p2


Exactly the same, there's no difference between C and D 
pointers, except for classes.



Here is the context of what I'm trying to do:


struct S
{
  struct Payload
  {}
  Payload payload;

  @property
  typeof(this) dup()
  {
typeof(this) ret;
if(payload)
{
  ret.payload = new Payload;
  ret.payload = payload; //Copies the payload? The pointer?


'ret.payload' is 'S'; 'new Payload' is '*S'...

If you meant 'Payload* payload;', then just the pointer is 
copied.


artur


Dang it, yes, I meant:

  struct Payload
  {}
  Payload* payload;


And I want to copy the value pointed by payload. Not the pointer.

I'm kind of confused, because every time I see pointer usage, the 
deference operator is omitted?


For example:


struct S
{
void foo(){};
}

S* p = new S();
p.foo();


When and where can/should/shouldn't I dereference?


Re: A matter of inout

2012-07-27 Thread Ali Çehreli

On 07/27/2012 10:13 AM, bearophile wrote:
 Artur Skawina:

 'inout' basically means 'local const' - if you'd allow inout
 data to be modified then it wouldn't be possible to call the
 function with a const or immutable argument - which is the
 whole point of inout...

 dmd 2.059 was wrong then.

I think so.

I have understood that aspect of inout recently: since the function is 
not a template (bear with me please! I know it is a template here :)), 
there will be a single instance of it. Since that instance must work 
with mutable and immutable, the parameter cannot be modified inside the 
function.


Even if the function is never called with immutable, the compiler must 
compile the code as if 'inout' is spelled as 'const'.


The above makes sense for a regular function. I guess the guideline here 
is not to use inout on a template parameter as it doesn't make sense 
because T carries that information anyway.


Ali



Re: copying the targets of pointers

2012-07-27 Thread Ali Çehreli

On 07/27/2012 09:11 AM, monarch_dodra wrote:
 This is going to sound stupid, but how do you have two pointers' targets
 copy each other? since pointers are used like reference types, how do
 you write the C++ equivalent of *p1 == *p2

The type must provide a function to make a copy of itself. Since arrays 
have .dup, that may be a suitable name:


   auto newObject = object.dup;

Ali



Re: A few questions

2012-07-27 Thread Simen Kjaeraas
On Fri, 27 Jul 2012 17:35:19 +0200, Jonathan M Davis jmdavisp...@gmx.com  
wrote:



Many of us think that

const Foo func() {}

should just become illegal inconsistency or not because of all of this
confusion, but Walter doesn't buy into that.


Like monarch_dodra said, this is also a style favored by some:

@pure @property const
int foo() {
//...
}

Having to write that

@pure @property
int foo() const {
//...
}

at the very least feels weird.

int foo()
const @pure @property {
}

could work, I guess. But it feels backward.

--
Simen


Re: Assert prints an array of char when used why to!string

2012-07-27 Thread Ali Çehreli

On 07/27/2012 09:02 AM, monarch_dodra wrote:
 On Friday, 27 July 2012 at 11:56:07 UTC, bearophile wrote:
 monarch_dodra:

 1) Is this the normal behavior, or a known limitation?

 It seems a DMD bug, why don't you add it to Bugzilla?


 2) Is there a workaround?

 static assert(0, text(Failure: , 55));

 Bye,
 bearophile

 Thanks. I'll create an entry in bugzilla.

Thanks. I hope that will fix the Unicode ignorance of 'static assert' as 
well:


static assert(false, aüz);

produces the following output:

  Error: static assert  a\xc3\xbcz

Ali



Re: copying the targets of pointers

2012-07-27 Thread Simen Kjaeraas
On Fri, 27 Jul 2012 19:28:06 +0200, monarch_dodra monarchdo...@gmail.com  
wrote:


I'm kind of confused, because every time I see pointer usage, the  
deference operator is omitted?


For example:


struct S
{
 void foo(){};
}

S* p = new S();
p.foo();


When and where can/should/shouldn't I dereference?


Whenever you need to. :p

Instead of having both . and -, D has only ., and it derefences for
you, when it needs to.

In terms of other D features, we could imagine pointers being
implemented thus:

struct Pointer(T) {
T* payload; // Yes, it's a pointer. I *could* use some other
// type and reinterpret_cast it, but I won't. :p

@property
ref T get() {
return *payload;
}

alias get this;

// Add operator overloading and all sorts of other magic here.
}


This also means that (*foo).bar() is exactly the same as foo.bar().

The only times you need to derefence is when you need direct access
to the pointee, not just its members. That usually means when you
pass it as a parameter, but also when you have multiple indirections,
or if you're going bit-fiddling.

--
Simen


Re: A few questions

2012-07-27 Thread Jonathan M Davis
On Friday, July 27, 2012 19:34:52 Simen Kjaeraas wrote:
 On Fri, 27 Jul 2012 17:35:19 +0200, Jonathan M Davis jmdavisp...@gmx.com
 
 wrote:
  Many of us think that
  
  const Foo func() {}
  
  should just become illegal inconsistency or not because of all of this
  confusion, but Walter doesn't buy into that.
 
 Like monarch_dodra said, this is also a style favored by some:
 
 @pure @property const
 int foo() {
  //...
 }
 
 Having to write that
 
 @pure @property
 int foo() const {
  //...
 }
 
 at the very least feels weird.
 
 int foo()
 const @pure @property {
 }
 
 could work, I guess. But it feels backward.

Personally, I _always_ put the attributes on the right-hand side save for the 
ones which exist in C++ and Java (which is pretty much just the access 
specifiers, static, override, and final), and I think that it's ugly and 
confusing to have them on the left, but that's a matter of personal 
preference. const on the other hand constantly causes issues because - unlike 
the others - it can be applied to the return type as well. And the question 
comes up often enough that I think that it's a real problem and one that 
merits making putting it on the left illegal. At minimum, making it illegal on 
the left without other attributes between it and the return type should be 
illegal IMHO (though that could cause even more confusion depending on the 
error message, since then it might be confusing why you could put it on the 
left but only in some positions). That change isn't going to happen at this 
point, but I think that we'd be better off if it were.

- Jonathan M Davis


Re: copying the targets of pointers

2012-07-27 Thread Jonathan M Davis
On Friday, July 27, 2012 10:32:07 Ali Çehreli wrote:
 On 07/27/2012 09:11 AM, monarch_dodra wrote:
   This is going to sound stupid, but how do you have two pointers' targets
   copy each other? since pointers are used like reference types, how do
   you write the C++ equivalent of *p1 == *p2
 
 The type must provide a function to make a copy of itself. Since arrays
 have .dup, that may be a suitable name:
 
 auto newObject = object.dup;

That's only if you're dealing with references or if the pointers point to 
structs which are reference types (or if they're pointers to arrays, which 
would be a bit weird). If you're dealing with a built-in type or value type 
structs, then no dup is necessary.

- Jonathan M Davis


Re: A few questions

2012-07-27 Thread Namespace


Walter's stand on this is that the OS gives you 
null-dereferencing detection -
i.e. segfaults and access violations. He's not going to add 
extra syntax for

it.

- Jonathan M Davis


That is a huge mistake. My OS prints me only a funny Access 
violation. And so i can search for my little null reference by 
myself. I _must_ debug for a ridiculous null reference. That cost 
time. I have not even a filename or a line number. Only the 
message that something went wrong. And all other i have to find 
by myself. So much time for such little mistakes.


Why would Walter have a language which doesn't support good error 
handling?
D hasn't support for unused variables, unused imports and even 
not for null references. Why should everyone use D instead of any 
other language?
If i have a big project and i use many objects and one of them 
change to null, what now? Should the user really step through 
thousand lines of code because D prints only Access Violation 
without any further information? Or should i use the same 
principle as Java, and write every time again pre- and 
postconditions? I don't see any reasons why anybody should 
realize a big project with D and not with a other language, if 
the error handling and not null support remains as it is. Sorry.


To reject even a such handy shorthand is incomprehensible to me.


Re: A few questions

2012-07-27 Thread Jonathan M Davis
On Friday, July 27, 2012 20:07:56 Namespace wrote:
  Walter's stand on this is that the OS gives you
  null-dereferencing detection -
  i.e. segfaults and access violations. He's not going to add
  extra syntax for
  it.
  
  - Jonathan M Davis
 
 That is a huge mistake. My OS prints me only a funny Access
 violation. And so i can search for my little null reference by
 myself. I _must_ debug for a ridiculous null reference. That cost
 time. I have not even a filename or a line number. Only the
 message that something went wrong. And all other i have to find
 by myself. So much time for such little mistakes.
 
 Why would Walter have a language which doesn't support good error
 handling?

Because a debugger will show you exactly where the problem is. So, why add 
checking that the OS already does for you? That's his logic. There are plenty 
of cases where that really isn't enough (e.g. you get a segfault on a server 
application without core dumps turned on when it's been running for 2 weeks), 
but it is for all the types of programs that Walter works on, so that's the 
way he thinks.

 D hasn't support for unused variables, unused imports and even
 not for null references. Why should everyone use D instead of any
 other language?
 If i have a big project and i use many objects and one of them
 change to null, what now? Should the user really step through
 thousand lines of code because D prints only Access Violation
 without any further information? Or should i use the same
 principle as Java, and write every time again pre- and
 postconditions? I don't see any reasons why anybody should
 realize a big project with D and not with a other language, if
 the error handling and not null support remains as it is. Sorry.
 
 To reject even a such handy shorthand is incomprehensible to me.

Honestly, I think that you're blowing null pointer dereferences way out 
proportion. In my experience, they're rare, and I have to wonder what you're 
doing if you're seeing them all that often.

That being said, what I think we're likely to end up with is a signal handler 
in druntime which prints out a stacktrace when a segfault occurs (and does 
whatever the Windows equivalent would be on Windows). That way, you don't have 
to have null checks everywhere, but you still get the debug information that 
you need. But no one has done that yet.

- Jonathan M Davis


Re: copying the targets of pointers

2012-07-27 Thread Artur Skawina
On 07/27/12 19:28, monarch_dodra wrote:
 On Friday, 27 July 2012 at 16:47:47 UTC, Artur Skawina wrote:
 On 07/27/12 18:11, monarch_dodra wrote:
 This is going to sound stupid, but how do you have two pointers' targets 
 copy each other? since pointers are used like reference types, how do you 
 write the C++ equivalent of *p1 == *p2

 Exactly the same, there's no difference between C and D pointers, except for 
 classes.

 Here is the context of what I'm trying to do:

 
 struct S
 {
   struct Payload
   {}
   Payload payload;

   @property
   typeof(this) dup()
   {
 typeof(this) ret;
 if(payload)
 {
   ret.payload = new Payload;
   ret.payload = payload; //Copies the payload? The pointer?

 'ret.payload' is 'S'; 'new Payload' is '*S'...

 If you meant 'Payload* payload;', then just the pointer is copied.

 artur
 
 Dang it, yes, I meant:
   struct Payload
   {}
   Payload* payload;
 
 And I want to copy the value pointed by payload. Not the pointer.

  Payload* p = new Payload;
  *ret.payload = *p;

or just

  *ret.payload = *new Payload;


 I'm kind of confused, because every time I see pointer usage, the deference 
 operator is omitted?
 
 For example:
 
 
 struct S
 {
 void foo(){};
 }
 
 S* p = new S();
 p.foo();
 
 
 When and where can/should/shouldn't I dereference?

The C '.' and '-' operators are folded into just one D op -- the '.'.
So everywhere where you'd write 'p-foo' in C/C++ you just do 
'p.foo' in D. Since both '-' and '.' C ops wouldn't make sense in
the same context, the compiler will do the right thing automagically.

artur


Re: A few questions

2012-07-27 Thread Namespace
I also get null references (and every time i hate D a bit more), 
but mostly my classmates and other friends whom I've shown D. And 
most of them are already back to C++ or C#. And I can understand 
them.
If you want that D is sometimes taken seriously (and it reached 
only if you win more people for D), then perhaps you should do 
something for more usability.
Such small handy shorthands are easy to implement and even more 
understandable as a stacktrace.


Re: A few questions

2012-07-27 Thread Era Scarecrow

On Friday, 27 July 2012 at 19:01:39 UTC, Namespace wrote:
I also get null references (and every time I hate D a bit 
more), but mostly my classmates and other friends whom I've 
shown D. And most of them are already back to C++ or C#. And I 
can understand them.
If you want that D is sometimes taken seriously (and it reached 
only if you win more people for D), then perhaps you should do 
something for more usability.
Such small handy shorthands are easy to implement and even more 
understandable as a stacktrace.


 I've noticed when debugging the 'segfault' is rather vague, but 
it depends on if you have something to catch it. In some of my 
code I end up surrounding the main function in a try/catch 
wrapper that prints the appropriate data; Like using VisualD.


void main() {
  try {
someFunc(null);
  } catch (Throwable x) {
writeln(x);
  }
}

void someInnerFunc(Object o)
in {
  assert(o, Yo! my object's NULL!);
}
body {
  //something
}
void someFunc(Object o) {
  someInnerFunc(o); //for stacktrace
}

core.exception.AssertError@test.d(111): Yo! my object's NULL!

c:\Users\Era\My Documents\progs\d\test.d(119): void 
test.someFunc(Object)

c:\Users\Era\My Documents\progs\d\test.d(103): _Dmain



change inner function to:

void someInnerFunc(Object o) {
  o.toHash;
  //something
}

object.Error: Access Violation

c:\Users\Era\My Documents\progs\d\test.d(116): void 
test.someFunc(Object)

c:\Users\Era\My Documents\progs\d\test.d(103): _Dmain



Re: A few questions

2012-07-27 Thread Adam D. Ruppe

On Windows, an access violation (from a null pointer or other
causes) is an exception that is thrown and can even be caught.

On Linux, a segfault is a signal that just kills the program,
it doesn't work like a regular exception.


The Windows exceptions can do pretty stack traces, including
on null derefs, if you have some debugging library installed...
and I've done it before, but I don't remember the link right now.
It's something from Microsoft.


Re: A few questions

2012-07-27 Thread Era Scarecrow

On Friday, 27 July 2012 at 19:48:33 UTC, Adam D. Ruppe wrote:

On Windows, an access violation (from a null pointer or other
causes) is an exception that is thrown and can even be caught.

On Linux, a segfault is a signal that just kills the program,
it doesn't work like a regular exception.


 Linux also dumps the state into a file. So I'd have to wonder 
what the problem was, you would have all the information at hand.


Re: A few questions

2012-07-27 Thread Adam D. Ruppe

On Friday, 27 July 2012 at 19:50:46 UTC, Era Scarecrow wrote:

 Linux also dumps the state into a file.


Only if core dumps are enabled... but I think someone did
a Linux stack trace signal handler somewhere for D, but
it never got merged into druntime. (What it'd do is print
out some info before exiting, instead of just saying
segmentation fault. Still not an exception, but a little
more immediately helpful).


Re: A few questions

2012-07-27 Thread Namespace
And that is the explicit way with pre- and postconditions of 
Java, which i want to avoid.


I see, the most of you prefer to write try and catch or use the 
java principle with explicit pre- and post conditions.
The time will show, if D get therewith enough members to get 
serious.

But this is what Java and C# have already.


Re: A few questions

2012-07-27 Thread Artur Skawina
On 07/27/12 21:48, Adam D. Ruppe wrote:
 On Windows, an access violation (from a null pointer or other
 causes) is an exception that is thrown and can even be caught.
 
 On Linux, a segfault is a signal that just kills the program,
 it doesn't work like a regular exception.

It's not a regular D exception, but it is a signal that /can/
be caught and used to print stacktraces, file names, line numbers
etc, not to mention you optionally get a snapshot of the program
as it failed (the core file).

The only non-trivial part is getting at the debug info to map the
addresses to symbols. Simple quick and dirty example below, which
will not only print the address of the instruction that caused the
fault, but also the address that it tried to access, and may even
sometimes succeed in letting the program continue to run.
Making it work with a non-gdc compiler, non-x86 ISA, hooking up w/
a library to get all the symbol names and properly handling all the
required cases is left as an exercise for the reader. :)

But, no, special handling for null dereferencing in the language is
*not* needed. Some more runtime support, maybe.

artur

   import std.stdio;

   template Seq(alias A, alias B, S...) {
  static if(S.length==0)
 alias Seq!(A, B, A) Seq;
  else static if (S[$-1]!=B)
 alias Seq!(A, B, S, S[$-1]+1) Seq;
  else
 alias S Seq;
   }

   struct hack {
  import core.sys.posix.ucontext, core.sys.posix.signal;
  alias int c_int;

  static:
  void* av;
  ubyte* violator;
  void*[4] trace;

  extern (C) void handler(c_int signum, siginfo_t* si, void* _ctx ) {
 auto ctx = cast(ucontext_t*)_ctx;
 av = si._sifields._sigfault.si_addr;
 version (X86) enum REG_RIP = 14;
 violator = cast(ubyte*)ctx.uc_mcontext.gregs[REG_RIP];
 ctx.uc_mcontext.gregs[REG_RIP] += inslen(violator);
 // scan and store backtrace etc.
 version (GNU) {
import gcc.builtins;
foreach (uint i; Seq!(0, trace.length-1))
   trace[i] = __builtin_return_address(i);
 }
 checkav(); // Not something you wanna do from a signal handler...
  }

  void register() {
 sigaction_t sa;
 sa.sa_sigaction = handler;
 sa.sa_flags = SA_SIGINFO;
 if (sigaction(SIGSEGV, sa, null))
throw new Error(sigaction failed);
  }

  version (X86) size_t inslen(in ubyte* c) {
 if (c[0]==0xc6  c[1]==0x05) return 7;
 if (c[0]==0x0f  c[1]==0xb6  c[2]==0x4b) return 4;
 if (c[0]==0x0f  c[1]==0xb6  c[2]==0x43) return 4;
 if (c[0]==0x0f  c[1]==0xb6) return 7;
 if (c[0]==0xa2) return 5;
 if (c[0]==0x65  c[1]==0xc7) return 11;
 if (c[0]==0x88  c[1]==0x4b) return 3;
 // ...
 return 1;
  }

  auto checkav() {
 if (av) {
writefln(0x%08x tried to access 0x%08x, violator, av);
foreach(t; trace)
   writef(0x%08x\n, t);
av = null;
 }
  }
   }

   __gshared ubyte* p = null;

   int main() {
  hack.register();
  p[1] = 1; hack.checkav();
  p[2] = 2; hack.checkav();
  p[3] = 3; hack.checkav();
  p[5] = p[4]; hack.checkav();
  return p[42];
   }




Implementing a Monitor

2012-07-27 Thread Minas Mina
I'm using condition variables to implement a monitor that 
simulates the producer-consumer(unbounded buffer) scenario.


Note:
monitor is __gshared and is initialized in main(). Then the other 
threads are created and run.


There is one producer thread, and 5 consumer threads.

void producer()
{
while( 1 )
{
monitor.produce();
}
}

void consumer()
{
while( 1 )
{
monitor.consume();
}
}

class Monitor
{
Cond cond;

char[] buffer;
ulong sz;

this()
{
		// necessary: The condition variable constructor requires a 
mutex passed to it

cond = new Cond(new Mutex());
}

void produce()
{
// produce a letter a-z
char c = 'a' + rand() % 26;
		writeln(* Producer: Produced a ', c, ' buffer.length = , 
buffer.length, \n);


// put it into the buffer
++buffer.length;
buffer[buffer.length - 1] = c;

//if( buffer.length  1 )
notify(cond); // calls condition.notify()

//Thread.sleep(dur!msecs(1000));
}

void consume()
{
if( buffer.length == 0 )
{
writeln(put to sleep);
cwait(cond); // calls Condition.wait()
}

// take
char c = buffer[buffer.length-1];
--buffer.length;

		writeln(# Consumer has taken a ', c, ' buffer = [, buffer, 
] (, buffer.length,  elements)\n);

}
}





The output is something like:
put to sleep
put to sleep
put to sleep
put to sleep
* Producer: Produced a 'n' buffer.length = 0

put to sleep
* Producer: Produced a 'w' buffer.length = 1

* Producer: Produced a 'l' buffer.length = 2

* Producer: Produced a 'r' buffer.length = 3

* Producer: Produced a 'b' buffer.length = 4

* Producer: Produced a 'b' buffer.length = 5

* Producer: Produced a 'm' buffer.length = 6

* Producer: Produced a 'q' buffer.length = 7

...

Even though the producer calls notify() when he finishes, none of 
the consumer threads is ever resumed... (I ran the program for a 
while and redirected output to a file. Then I searched for # 
that the consumer prints but nothing).


Why is that happening? Is there something wrong with 
Condition.notify()?


Also, is there a function that I can call to immediatly suspend 
the running thread?


Thanks


Re: A few questions

2012-07-27 Thread Namespace

Me again.
What's the matter if i write something for that shorthand and dmd 
has only to switch to it before the compiling begins?

My little test program works with VisualD.
I goto the build events and there i write into Pre-Build 
Command:

[quote]not_null main.d #t[/quote]
and into Post-Build Command:
[quote]del main.d
rename clone_main.d main.d[/quote]

Of course i have to find a way to generate this for all included 
files and not do this manually as

not_null a.d #t
not_null b.d #t

But if dmd would do this e.g. with a compiler flag like 
-notnull it would lighten my workload a lot.


Here is my current example code: http://dpaste.dzfl.pl/8d41468a

It replace Class? obj statements and generate two files. The 
normal file changes to valid D code which can compile. The 
original code with Class? obj statements will copied into 
clone_filename.d


I know it isn't perfect, but maybe it is a beginning.


Re: A few questions

2012-07-27 Thread Jonathan M Davis
On Saturday, July 28, 2012 01:00:22 Namespace wrote:
 Me again.
 What's the matter if i write something for that shorthand and dmd
 has only to switch to it before the compiling begins?

Doing stuff like that makes your code completely unportable. It's _bad_ 
practice. Don't go and try to redesign the language if you want to be playing 
nice with other people. If you can do something completely within the 
language, then that's different (other people may still hate what you're up to, 
but at least they can compile it), but don't use a preprocessor unless you 
really don't care about anyone else ever using your code but you, and even 
then, I'd argue against it, because if you get into the habit of doing that, 
you're screwed when you actually have to interact with other D programmers.

- Jonathan M Davis


Re: A few questions

2012-07-27 Thread Namespace

Therefore i hope that it will be official added into D.
Otherwise of course i use it only for projects between me and my 
other students.


I don't know what is wrong with this shorthand. So why don't give 
it a try?
I'm absolutely sure that Walter will _never_ add real 
non-nullable references.
All what will maybe come are further structs in std.alghorithm 
which blows up your code as assertions even do.


Re: A few questions

2012-07-27 Thread Adam D. Ruppe

I started a not null struct for phobos but then had to
move, added another job, and other real life stuff
that meant I haven't finished it yet.

Fairly usable though. Look for struct NotNull:

https://github.com/adamdruppe/phobos/blob/0c97414bb4aa3c748caa42948ffec25f8a291300/std/typecons.d

(also a pull request, but for some reason, my changes to
never updated here, so the pull request is out of date
and temporarily closed

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


Re: A few questions

2012-07-27 Thread Jonathan M Davis
On Saturday, July 28, 2012 01:16:41 Namespace wrote:
 Therefore i hope that it will be official added into D.
 Otherwise of course i use it only for projects between me and my
 other students.
 
 I don't know what is wrong with this shorthand. So why don't give
 it a try?

I don't even know what the last time I dereferenced a null pointer or null  
reference was. It almost never happens to me. I really think that if you're 
seeing very many null dererences, you're doing something fundamentally wrong 
with your code. At minimum, it indicates that you're not unit testing enough, 
since if you do that right, it'll catch the logic errors which give you null 
pointers/references very quickly.

 I'm absolutely sure that Walter will _never_ add real
 non-nullable references.
 All what will maybe come are further structs in std.alghorithm
 which blows up your code as assertions even do.

We will get a NotNull struct at some point (probably in std.typecons). It'll 
statically prevent assignments from null where it can and use assertions where 
it can't. Adding something to the language doesn't buy you much more than that 
anyway. At this point, any new language feature must meet a very high bar, and 
if we can do it in the library instead, we will. D is incredibly powerful and 
is already plenty complex, so we'll take advantage of that power where we can 
rather than trying to change the language further. D arguably has too many 
features as it is.

And as big a deal as you seem to think that this is, the _only_ C-based 
language that I'm aware of which has non-nullable references as part of the 
language is C#. So, while they may have their uses, it's actually very 
uncommon to have them, and since we can add a library type to do it, we can fix 
the problem without altering the language.

- Jonathan M Davis


Re: A few questions

2012-07-27 Thread Jonathan M Davis
On Saturday, July 28, 2012 01:48:00 bearophile wrote:
 Jonathan M Davis:
  Adding something to the language doesn't buy you much more than
  that anyway.
 
 In the case of not-nullability, this isn't true. Integrating
 not-null in the type system allows the language to do things you
 can't do with NotNull, like:
 
 
 // x is a nullable class reference
 if (x == null) {
  ...
 } else {
  // here the type system sees x as not null.
 }

??? What does it matter if the type system knows whether a pointer is null 
unless it's trying to warn you about dereferencing null? It's not checking for 
it. If we had null checks built in, that would buy you something, but we 
don't, and we're not going to, if nothing else because Walter is completely 
against it.

 There are some other similar things you can't do with NotNull. In
 my enhancement request about not-nullability there are references
 to articles that explain the situation.
 
  D arguably has too many features as it is.
 
 I don't agree, the number of features is not important. What's
 important is how clean and intelligently they are designed, how
 cleanly they interact with the other features. etc.

There's always a cost to having more features. The more there are, the more 
that you have to know, and the more that it takes to learn the language. 
Having the features be well-designed definitely helps, and for the most part, 
I'm fine with the number of features that D has, but there probably are a few 
that ideally would be dropped but can't be at this stage (as was discussed not 
all that long ago in a big thread on what language features weren't useful), 
and adding more does come at a cost. A particular feature may be worth the 
cost that it brings, but the more features that you have, the more value each 
additional feature must bring to the table.

  And as big a deal as you seem to think that this is, the _only_
  C-based language that I'm aware of which has non-nullable
  references as part of the language is C#.
 
 This is not true.

Actually, it is. I said that I'm aware of. I didn't say that there weren't 
others, just that I didn't know of any others. But out of the mainstream C-
based languages, it's definitely rare, much as it may be becoming less rare as 
new languages come along.

 Scala, Rust, some new Java-derived languages,
 and more modern languages have not nullable references. In
 practice I think most or all new languages coming out now have
 this feature. In my opinion in few years programmers will expect
 to have it in all languages that are not too much old and that
 support some kind of nullable references.

It's not necessarily a bad feature, but I do think that it's highly overrated, 
and regardless, there's no way that it's being added to D at this point in its 
life cycle. Maybe they'll be added in D3, but I wouldn't expect to see them 
before then at the earliest. The push right now is to use the language that we 
have to get things done rather than trying to constantly add features and 
tweak existing ones. There are probably some features that we wouldn't even 
have now if we had taken that approach earlier (e.g. base two literals).

- Jonathan M Davis


Re: A few questions

2012-07-27 Thread bearophile

Jonathan M Davis:


// x is a nullable class reference
if (x == null) {
 ...
} else {
 // here the type system sees x as not null.
}


??? What does it matter if the type system knows whether a 
pointer is null

unless it's trying to warn you about dereferencing null?


In the else branch the state of the type of x is not-null, so as 
example in the else branch you are allowed to call a function 
that only accept not null references, with the x variable.
Not-nulls integrated in the type system makes sure you have well 
initialized variables in the class constructors in presence of 
inheritance and other complexities.
It also statically requires you to test for null before 
deferencing a nullable class reference, ans so on.
Those are the fruits that a good not-null implementation gives 
you. You can't do all this with the NotNull toy. NotNull solves 
only the easy part of the whole problem, and it's a small part.




Actually, it is. I said that I'm aware of.


Right :-)

Bye,
bearophile