Re: Source code annotations alla Java

2014-01-30 Thread Mengu
On Thursday, 20 January 2011 at 18:19:21 UTC, Jacob Carlborg 
wrote:

On 2011-01-20 14:47, Justin Johansson wrote:
Not long ago the Java Language people introduced the idea of 
annotations

together with an annotation processing tool (apt).

Now perhaps the idea of source code annotations is not 
actually a Java
invention per se, however for someone learning D is there any 
equivalent

idiom [of Java annotations] in the D language?


Depending on what you want to do you can create a template 
mixin that accepts string(s)/alias(es). For example: for the 
serialization library (http://dsource.org/projects/orange) I'm 
working on the following syntax is used:


class Foo
{
int x;
int y;
int z;

mixin NonSerialized!(z);
}

The above mixin indicates that the z instance variable 
shouldn't be serialized. This is (currently) achieved by 
defining a field in the mixed in template (which will be added 
to the class) which is a struct containing the string of the 
filed which shouldn't be serialized. Then I iterate over all 
the fields in the class with .tupleof and collects all mixed in 
fields in a list. Then I know what fields to skip later during 
the serialization.


let's assume you are building a web application and you want to 
keep that controller only for the logged in users. in java you 
can create an annotation class called @RequireLogin and put your 
logic there. mixins are not the way for this.


Reference parent type

2014-01-30 Thread Frustrated

Suppose I have

class A
{
mixin t!A;
}

is there a way to replace the mixin template's dependence on the
class name?

e.g.,

class A
{
mixin t!This; // This turns in to A
}

(so, for example, renaming the above class only has to rename one
place instead of two)


Re: core.stdc.config

2014-01-30 Thread Gary Willoughby
On Thursday, 30 January 2014 at 03:28:57 UTC, Craig Dillabaugh 
wrote:

So, there is a module core.stdc.config (referenced here):

http://dlang.org/interfaceToC.html

That is presumably part of the D Standard library.  I am 
curious to know why no mention of this library is included at:


http://dlang.org/phobos/index.html

Is it not part of Phobos? Are there standard modules in D that 
are not included in Phobos?  If so, where would one find the 
list of these modules.


The way i see what's available is to take a look at the files 
installed by the compiler. The directory is different for all 
operating systems but it's great to look at the source code of 
all the different modules.


For example on Mac OSX 10.8.5 'core.stdc.config' is located at 
'/usr/share/dmd/src/druntime/src/core/stdc/config.d'. There you 
can see how the types are constructed and what they represent. 
For Linux just type 'locate config.d' in the terminal. For 
Windows it's all in 'C:\d' i think.


Re: Reference parent type

2014-01-30 Thread Stanislav Blinov

On Thursday, 30 January 2014 at 09:03:17 UTC, Frustrated wrote:

mixin t!(typeof(this))


Re: Array as an argument, ambiguous behaviour.

2014-01-30 Thread Stanislav Blinov

On Thursday, 30 January 2014 at 09:14:43 UTC, Cooler wrote:


Please stop explain me how fun3() works. I know that.
One of the main idea of D is that things must work as planned, 
or would not compile at all. First and second variants follow 
this idea. But fun3() can work not as planned on the caller 
side (depends on fun3() body's implementation).
The question again - may be prohibit fun3() variant? If we 
prohibit it, what use cases we could not implement with fun1() 
and fun2()?


Goodness... You've been shown this use case like a zillion times 
already: the caller manages her buffer, fun3() is allowed to 
change contents, but not reallocate caller's buffer.


fun1() can't provide that (const), fun2() cannot either, because 
it explicitly allows reallocation (ref). This behavior is only 
provided by fun3().


So it's either that, or indeed cases of I don't care about this 
array, which Maxim Fomin has mentioned.


Re: Keywords: How to trick the compiler?

2014-01-30 Thread Chris
On Wednesday, 29 January 2014 at 17:12:57 UTC, Stanislav Blinov 
wrote:
On Wednesday, 29 January 2014 at 17:11:32 UTC, Ary Borenszweig 
wrote:


Yes, as there are other ways for body: _body, _body, Body, 
HtmlBody, etc. But body is the best one.


torso? ;)


offspring = document.createElement(div);

document.torso.addOffspring(div);


Re: Array as an argument, ambiguous behaviour.

2014-01-30 Thread Maxim Fomin

On Thursday, 30 January 2014 at 09:14:43 UTC, Cooler wrote:
If you want to modify the slice and make changes visible in 
caller, you should use ref. If you don't care whether changes 
are visible in caller, you can omit any attributes and use 
plain array. This belongs to the case you are asking about. If 
you don't want to change array in callee, pass it as const 
qualified.


Now, after rethinking the issue I am inclining that don't 
care whether changes are visible for caller is not very 
wrong, but not very good design. Ideally it should be 
specified to avoid unexpected problems to pop up. So yes, it 
is better to qualify array.


Another point. This casino games of whether changes would be 
visible or not is direct consequence of how slices are 
implemented (and how runtime service them). Remember, that 
many features in D work in a strange way not because of wise 
design but as a consequence of not fully thought design (like 
array). As a result, some features work in not best way they 
should. Although many folks in newsgroups would eagerly say 
that you don't understand the lang, it wouldn't make a bad 
design a good one.


Please stop explain me how fun3() works. I know that.


This is first problem. You are being explained what is the 
*purpose* of the fun3() but you repeatedly fail to accept it.


One of the main idea of D is that things must work as planned, 
or would not compile at all.


Outcryingly wrong. Study bugzilla which shows how some things go 
wrong and read DIPs to learn that there are some issues in the 
language for which the communitty still struggles to formulate 
good solution.


First and second variants follow this idea. But fun3() can work 
not as planned on the caller side (depends on fun3() body's 
implementation).


Many things can work not as intended. Please read forums, 
bugzilla, etc. I bet passing array will not be the only thing you 
find confusing.



The question again - may be prohibit fun3() variant?


Prohibiting code like:
void foo(int[] arr) {}

would break hell of a code and pose doubts on what happens with 
arrays if so simple construction is prohibited. In addition, I 
mentioned that don't care is probably sometimes an option. 
Emitting warning here has some merits but it would be consitently 
ignored (I expect).


Re: Keywords: How to trick the compiler?

2014-01-30 Thread Stanislav Blinov

On Thursday, 30 January 2014 at 10:15:10 UTC, Chris wrote:


offspring = document.createElement(div);

document.torso.addOffspring(div);


Looks great! :D


Question about dynamic arrays and slices

2014-01-30 Thread Ary Borenszweig

Hi,

I just read this nice article about slices: 
http://dlang.org/d-array-article.html


So I tried this code to see if I understood it correctly:

---
import std.stdio;

void main() {
  auto a = new int[5];
  auto b = a;

  a[0] = 1;

  for(auto i = 0; i  100; i++) {
a ~= 0;
  }

  a[0] = 2;

  writefln(a[0] = %d, a[0]);
  writefln(b[0] = %d, b[0]);
}
---

This prints:

a[0] = 2
b[0] = 1

That is, a was resized to a point where it needed to reallocate its 
contents. b still holds a reference to the old data. When, after the 
for loop, I change a's data, b's data doesn't change.


Is this expected behaviour?

How can I safely pass around a dynamic array without being afraid 
someone will keep an old copy of the data?


Re: Question about dynamic arrays and slices

2014-01-30 Thread Tobias Pankrath

This prints:

a[0] = 2
b[0] = 1

That is, a was resized to a point where it needed to 
reallocate its contents. b still holds a reference to the old 
data. When, after the for loop, I change a's data, b's data 
doesn't change.


Is this expected behaviour?


That's how it is.

How can I safely pass around a dynamic array without being 
afraid someone will keep an old copy of the data?


I don't understand your exact requirements. Do you want to make 
sure that everyone sees the updates to the array, even after a 
relocation?


Re: Array as an argument, ambiguous behaviour.

2014-01-30 Thread bearophile

Cooler:

Again - stop consider current state of D implementation. 
Consider how we can make D better. I think fun3() push 
programmers to make errors.


I think functions like void fun(int[] a){} are bug prone, because 
you seem to change the length of the array inside the function, 
or if you perform an append you modify a new memory zone, but 
such changes are invisible from the caller. Some times this is 
what you want, and in some cases this is a programmer mistake 
(this bug happened to me several times).


But I don't know what to change and if this situation can be 
improved now. Perhaps all that's left to improve is to add tests 
to a D lint that warns against this possible source of bugs.


Bye,
bearophile


Re: Array as an argument, ambiguous behaviour.

2014-01-30 Thread Maxim Fomin

On Thursday, 30 January 2014 at 10:49:42 UTC, Cooler wrote:
Now I am trying to speak ideally. What ideal language should 
be, not the practical implementation.



...

Again - don't look back. Consider how we can make D better.


...
Again - stop consider current state of D implementation. 
Consider how we can make D better. I think fun3() push 
programmers to make errors.


Looks like you are overestimating yourself.

Now, try:
1) write pull request to reject the code
2) convince developers somehow that your proposal is good
3) convince Walter to accept the change
4) after merging pull convince angry maintainers that it is good 
idea to reject unqualified array passing because Cooler tries to 
make the language better


Interfaces allow member definitions?

2014-01-30 Thread Frustrated

I was, I think, able to call an interface's method. I had the
code like the following


interface A
{
 void foo();
}

class B : A { void foo() { writeln(Hey); } }
class C : A { void foo() { writeln(You); } }

yet, when I called a.foo(); I did not get any output. (A being of
type A)


Now, I was doing some weird stuff but either in the vtable for A,
there are empty functions that do nothing or I just happen to
call bogus memory that did not throw an exception.

The real question is, do interface methods actually support
function definitions?

Is there anything that stops us from actually doing

interface A
{
 void foo() { writeln(What up!!); }
}

internally? I know member functions require a this but in this
case foo does not require this so it any this would work.

Basically, does the vtable contain storage for the interface's
members but blocks us from using them due to the issue with this?

If so, then shouldn't we be able to create functions in an
interface as long as they do not reference this? (basically
static functions that can be overriden as dynamic functions in
the class)

e.g.,

interface A
{
 // default behavior for foo and bar
 void foo() { writeln(asdasdfasdfasdf); }
void bar() { writeln(1234); }

}

class B : A
{
void foo() { writeln(help); }
}

void main()
{
A a = new B;
 a.foo(); // prints help
 a.bar(); // prints 1234
 B b = new B;
 b.foo(); // prints help
 b.bar(); // prints 1234
}


This would allow one to sort of add default behavior to an
interface(limited since no fields could be used but properties
help with it).

basically the vtable just needs an extra spot for the interface
methods and calls them with null or the object it contains for
this... which doesn't matter since this is never used in the body
of the function.


Re: Interfaces allow member definitions?

2014-01-30 Thread TheFlyingFiddle

On Thursday, 30 January 2014 at 11:19:58 UTC, Frustrated wrote:

I was, I think, able to call an interface's method. I had the
code like the following


interface A
{
 void foo();
}

class B : A { void foo() { writeln(Hey); } }
class C : A { void foo() { writeln(You); } }

yet, when I called a.foo(); I did not get any output. (A being 
of

type A)


Now, I was doing some weird stuff but either in the vtable for 
A,

there are empty functions that do nothing or I just happen to
call bogus memory that did not throw an exception.

The real question is, do interface methods actually support
function definitions?

Is there anything that stops us from actually doing

interface A
{
 void foo() { writeln(What up!!); }
}

internally? I know member functions require a this but in this
case foo does not require this so it any this would work.

Basically, does the vtable contain storage for the interface's
members but blocks us from using them due to the issue with 
this?


If so, then shouldn't we be able to create functions in an
interface as long as they do not reference this? (basically
static functions that can be overriden as dynamic functions in
the class)

e.g.,

interface A
{
 // default behavior for foo and bar
 void foo() { writeln(asdasdfasdfasdf); }
void bar() { writeln(1234); }

}

class B : A
{
void foo() { writeln(help); }
}

void main()
{
A a = new B;
 a.foo(); // prints help
 a.bar(); // prints 1234
 B b = new B;
 b.foo(); // prints help
 b.bar(); // prints 1234
}


This would allow one to sort of add default behavior to an
interface(limited since no fields could be used but properties
help with it).

basically the vtable just needs an extra spot for the interface
methods and calls them with null or the object it contains for
this... which doesn't matter since this is never used in the 
body

of the function.


You can already do this using the Non-virtual interface ideom


interface Foo
{
   final void bar() { writeln(Something); }
   void baz() { writeln(Something Else); }
}

Note the final keyword it is imortant here. This will make bar 
simply be a non-virutal method in Foo.


If you want to provide some basic implementation but still 
forward to a base class you can do something like this.


interface Foo2
{
   final void bar(uint i)
   {
   // Does some basic stuff here.
   bar_impl(i);
   }

   protected void bar_impl(uint i);
}


class A : Foo2
{
   protected void bar_impl(uint i)
   {
  //Do some specific stuff here.
   }
}

This pattern allows you to do some basic stuff in bar and more 
specialized stuff in bar_impl. It does require that you overload 
bar_impl though which may not be what you want.


Re: N-body bench

2014-01-30 Thread Stanislav Blinov
On Wednesday, 29 January 2014 at 18:05:41 UTC, Stanislav Blinov 
wrote:


Yep, doesn't seem to be simd-related:

struct S(T) { T v1, v2; }

void main() {
alias T = double; // integrals and float are ok :\
version (workaround) {
S!T[1] p = void;
} else {
S!T[1] p;
}
}

Anyway, here's the revised (and bugfixed :o)) code, if anyone's 
interested:


http://dpaste.dzfl.pl/52d9e1fdc0fd

On my machine, dmd -release -O -inline -noboundscheck is only 6 
times slower than that C++ version :D


I'll try to get around to making it work with ldc on the weekend.


Re: Array as an argument, ambiguous behaviour.

2014-01-30 Thread Dicebot

On Wednesday, 29 January 2014 at 14:34:54 UTC, Cooler wrote:

Here is ambiguity.
void fun3(int[] x){ x ~= 5; ... }
auto a = new int[10];
fun3(a); // Here content of a may be changed or may be not 
changed. Depends on the buffer size that system will allocate 
for a array.


You use very subjective meaning for ambiguity, one that is 
never normally used in programming language context. Normally 
term ambiguity is applied only when _compiler_ can't reliably 
decide meaning of the code snippet and needs to resort to special 
casing.


You are correct in notion that you can't make any reasonable 
judgement yourself about content of a after `fun3` call but same 
applies to `fun2` - it can be or not be modified. It is expected 
- to express all semantics of function body in function signature 
one would have needed to make it of comparable length and 
complexity.


In practice you need always to assume the worst - everything is 
modified and nothing can be trusted unless explicitly qualified 
other way around.


Re: Question about dynamic arrays and slices

2014-01-30 Thread John Colvin

On Thursday, 30 January 2014 at 12:50:34 UTC, John Colvin wrote:
On Thursday, 30 January 2014 at 10:43:55 UTC, Ary Borenszweig 
wrote:

Hi,

I just read this nice article about slices: 
http://dlang.org/d-array-article.html


So I tried this code to see if I understood it correctly:

---
import std.stdio;

void main() {
 auto a = new int[5];
 auto b = a;

 a[0] = 1;

 for(auto i = 0; i  100; i++) {
   a ~= 0;
 }

 a[0] = 2;

 writefln(a[0] = %d, a[0]);
 writefln(b[0] = %d, b[0]);
}
---

This prints:

a[0] = 2
b[0] = 1

That is, a was resized to a point where it needed to 
reallocate its contents. b still holds a reference to the 
old data. When, after the for loop, I change a's data, b's 
data doesn't change.


Is this expected behaviour?

How can I safely pass around a dynamic array without being 
afraid someone will keep an old copy of the data?


pass the array by ref, or make a wrapper struct that holds a 
pointer to a slice, or a wrapper class that holds the slice.


Alternatively, make a wrapper struct that disallows the append 
operator and always use std.array.refAppender


woops, sorry that last one doesn't help.


Re: Question about dynamic arrays and slices

2014-01-30 Thread John Colvin
On Thursday, 30 January 2014 at 10:43:55 UTC, Ary Borenszweig 
wrote:

Hi,

I just read this nice article about slices: 
http://dlang.org/d-array-article.html


So I tried this code to see if I understood it correctly:

---
import std.stdio;

void main() {
  auto a = new int[5];
  auto b = a;

  a[0] = 1;

  for(auto i = 0; i  100; i++) {
a ~= 0;
  }

  a[0] = 2;

  writefln(a[0] = %d, a[0]);
  writefln(b[0] = %d, b[0]);
}
---

This prints:

a[0] = 2
b[0] = 1

That is, a was resized to a point where it needed to 
reallocate its contents. b still holds a reference to the old 
data. When, after the for loop, I change a's data, b's data 
doesn't change.


Is this expected behaviour?

How can I safely pass around a dynamic array without being 
afraid someone will keep an old copy of the data?


pass the array by ref, or make a wrapper struct that holds a 
pointer to a slice, or a wrapper class that holds the slice.


Alternatively, make a wrapper struct that disallows the append 
operator and always use std.array.refAppender


Re: Question about dynamic arrays and slices

2014-01-30 Thread Steven Schveighoffer
On Thu, 30 Jan 2014 05:43:55 -0500, Ary Borenszweig a...@esperanto.org.ar  
wrote:



Hi,

I just read this nice article about slices:  
http://dlang.org/d-array-article.html


So I tried this code to see if I understood it correctly:

---
import std.stdio;

void main() {
   auto a = new int[5];
   auto b = a;

   a[0] = 1;

   for(auto i = 0; i  100; i++) {
 a ~= 0;
   }

   a[0] = 2;

   writefln(a[0] = %d, a[0]);
   writefln(b[0] = %d, b[0]);
}
---

This prints:

a[0] = 2
b[0] = 1

That is, a was resized to a point where it needed to reallocate its  
contents. b still holds a reference to the old data. When, after the  
for loop, I change a's data, b's data doesn't change.


Is this expected behaviour?


Yes, it is intrinsic on how slices and arrays work.

How can I safely pass around a dynamic array without being afraid  
someone will keep an old copy of the data?


You can't. Why is that important? The use case (or case that you are  
troubled by) would help to explain I think.


-Steve


Re: Interfaces allow member definitions?

2014-01-30 Thread Casper Færgemand
Compiling with DMD 2.064, I am NOT able to get any function in 
interfaces accepted unless they are final. This means you cannot 
provide default behavior in the interface, at least not in the 
ways shown above.


Re: Array as an argument, ambiguous behaviour.

2014-01-30 Thread Steven Schveighoffer

kOn Wed, 29 Jan 2014 05:55:56 -0500, Cooler kul...@hotbox.ru wrote:


Consider 3 functions taking array as an argument:

void fun1(in  int[] x){...}
void fun2(ref int[] x){...}
void fun3(int[] x){...}

auto a = new int[10];

fun1(a); // Guaranteed that a will not be changed
fun2(a); // Guaranteed that we will see any change to a, made in fun2()
fun3(a); // Changes to a in fun3() may be or may be not visible to the  
caller


In case of fun3() we have ambiguous behaviour, depending on the body of  
the function.


Am I right?


Yes.


Is that intentional?


Yes.

I read the rest of the discussion. Arrays are hard to understand in D,  
especially if you have preconceived notions from other languages. But I  
would point out that fun2 does not guarantee anything more than fun3:


void fun2(ref int [] x)
{
   fun3(x);
}

It is an intrinsic property of slices that they do not own the data  
pointed at. You cannot guarantee that one slice's changes will affect  
another slice, AS LONG AS one slice is increasing its length. If you avoid  
increasing the length, then the results are deterministic. As I said in  
the article, avoid increasing the length, and THEN changing the original  
data. If you do that, you should have quite predictable results. If your  
code must do otherwise, explain in the documentation what should happen  
(i.e. don't use the passed-in slice after the function), and use some of  
the tricks to avoid it (use ref, or return the new slice data).


-Steve


Re: core.stdc.config

2014-01-30 Thread Craig Dillabaugh
On Thursday, 30 January 2014 at 07:26:51 UTC, Jacob Carlborg 
wrote:

On 2014-01-30 05:42, Mike Parker wrote:


All of the core.* modules are part of DRuntime, not Phobos.


Unfortunately none of the core.stdc.* modules are documented. 
It's understandable that duplicating the documentation of the C 
library is not done since that would require extra work. But it 
would be nice to at least see which modules and declarations 
are available.


I agree.  Even if they are part of DRuntime, and even if there is 
no desire to write full documentation for them, people looking 
through the D site's Library Reference should at least be made 
aware of their existence.


Re: Interfaces allow member definitions?

2014-01-30 Thread TheFlyingFiddle
On Thursday, 30 January 2014 at 13:43:49 UTC, Casper Færgemand 
wrote:
Compiling with DMD 2.064, I am NOT able to get any function in 
interfaces accepted unless they are final. This means you 
cannot provide default behavior in the interface, at least not 
in the ways shown above.


Yes the void baz() method is incorrect. The rest should be fine 
though.


Re: core.stdc.config

2014-01-30 Thread Craig Dillabaugh
On Thursday, 30 January 2014 at 09:03:47 UTC, Gary Willoughby 
wrote:
On Thursday, 30 January 2014 at 03:28:57 UTC, Craig Dillabaugh 
wrote:

So, there is a module core.stdc.config (referenced here):

http://dlang.org/interfaceToC.html

That is presumably part of the D Standard library.  I am 
curious to know why no mention of this library is included at:


http://dlang.org/phobos/index.html

Is it not part of Phobos? Are there standard modules in D that 
are not included in Phobos?  If so, where would one find the 
list of these modules.


The way i see what's available is to take a look at the files 
installed by the compiler. The directory is different for all 
operating systems but it's great to look at the source code of 
all the different modules.


For example on Mac OSX 10.8.5 'core.stdc.config' is located at 
'/usr/share/dmd/src/druntime/src/core/stdc/config.d'. There you 
can see how the types are constructed and what they represent. 
For Linux just type 'locate config.d' in the terminal. For 
Windows it's all in 'C:\d' i think.


I did as you suggested and had a look through what was on my 
system.  Having done so I now think that the documentation at:


http://dlang.org/phobos/index.html

is out of date.

If you look at the section under Imports, this appears to be 
describing what is available under from C, but it appears to 
suggest that you use std.c.config - or at least that is how I 
would have read it.


Re: N-body bench

2014-01-30 Thread Stanislav Blinov

Ok, didn't need to wait for the weekend :)

Looks like both dmd and ldc don't optimize slice operations yet, 
had to revert to loops (shaved off ~1.5 seconds for ldc, ~9 
seconds for dmd). Also, my local pull of ldc had some issues with 
to!int(string), reverted that to atoi :)


Here's the code:

http://dpaste.dzfl.pl/4b6df0771696

C++ version compiled with the provided flags.

dmd -release -O -inline -noboundscheck

ldc2 -release -O3 -disable-boundscheck -vectorize -vectorize-loops

Here are the results on my machine (i3 2100 @3.1GHz):

time ./nbody-cpp 5000:
-0.169075164
-0.169059907
0:05.20 real, 5.18 user, 0.00 sys, 532 kb, 99% cpu

time ./nbody-ldc 5000:
-0.169075164
-0.169059907
0:07.84 real, 7.82 user, 0.00 sys, 1324 kb, 99% cpu

time ./nbody-dmd 5000:
-0.169075164
-0.169059907
0:23.35 real, 23.29 user, 0.00 sys, 1184 kb, 99% cpu



Re: Interfaces allow member definitions?

2014-01-30 Thread Frustrated

On Thursday, 30 January 2014 at 11:29:55 UTC, TheFlyingFiddle
wrote:

On Thursday, 30 January 2014 at 11:19:58 UTC, Frustrated wrote:

I was, I think, able to call an interface's method. I had the
code like the following


interface A
{
void foo();
}

class B : A { void foo() { writeln(Hey); } }
class C : A { void foo() { writeln(You); } }

yet, when I called a.foo(); I did not get any output. (A being 
of

type A)


Now, I was doing some weird stuff but either in the vtable for 
A,

there are empty functions that do nothing or I just happen to
call bogus memory that did not throw an exception.

The real question is, do interface methods actually support
function definitions?

Is there anything that stops us from actually doing

interface A
{
void foo() { writeln(What up!!); }
}

internally? I know member functions require a this but in this
case foo does not require this so it any this would work.

Basically, does the vtable contain storage for the interface's
members but blocks us from using them due to the issue with 
this?


If so, then shouldn't we be able to create functions in an
interface as long as they do not reference this? (basically
static functions that can be overriden as dynamic functions in
the class)

e.g.,

interface A
{
// default behavior for foo and bar
void foo() { writeln(asdasdfasdfasdf); }
void bar() { writeln(1234); }

}

class B : A
{
void foo() { writeln(help); }
}

void main()
{
A a = new B;
a.foo(); // prints help
a.bar(); // prints 1234
B b = new B;
b.foo(); // prints help
b.bar(); // prints 1234
}


This would allow one to sort of add default behavior to an
interface(limited since no fields could be used but properties
help with it).

basically the vtable just needs an extra spot for the interface
methods and calls them with null or the object it contains for
this... which doesn't matter since this is never used in the 
body

of the function.


You can already do this using the Non-virtual interface ideom


interface Foo
{
   final void bar() { writeln(Something); }
   void baz() { writeln(Something Else); }
}

Note the final keyword it is imortant here. This will make bar 
simply be a non-virutal method in Foo.


If you want to provide some basic implementation but still 
forward to a base class you can do something like this.


interface Foo2
{
   final void bar(uint i)
   {
   // Does some basic stuff here.
   bar_impl(i);
   }

   protected void bar_impl(uint i);
}


class A : Foo2
{
   protected void bar_impl(uint i)
   {
  //Do some specific stuff here.
   }
}

This pattern allows you to do some basic stuff in bar and more 
specialized stuff in bar_impl. It does require that you 
overload bar_impl though which may not be what you want.




But this is not what I am talking about. Obviously one could use
a multitude of ways to accomplish the same task but nothing is
simple, direct, and elegant.

Do you realize you have to define two functions in the interface?

I'm not asking about a work around but if what I am talking about
can actually be done(does the vtable support this or can made to
support it?)


Re: N-body bench

2014-01-30 Thread Stanislav Blinov
On Thursday, 30 January 2014 at 14:17:16 UTC, Stanislav Blinov 
wrote:


Forgot one slice assignment in toDobule2(). Now the results are 
more interesting:


time ./nbody-cpp 5000:
-0.169075164
-0.169059907
0:05.20 real, 5.18 user, 0.00 sys, 532 kb, 99% cpu

time ./nbody-ldc 5000:
-0.169075164
-0.169059907
0:05.94 real, 5.92 user, 0.00 sys, 1320 kb, 99% cpu

time ./nbody-dmd 5000:
-0.169075164
-0.169059907
0:19.62 real, 19.57 user, 0.00 sys, 1188 kb, 99% cpu

:)


Re: Array as an argument, ambiguous behaviour.

2014-01-30 Thread Steven Schveighoffer

On Thu, 30 Jan 2014 09:18:40 -0500, Cooler kul...@hotbox.ru wrote:


Forgot to mention :)

I read the rest of the discussion. Arrays are hard to understand in D,  
especially if you have preconceived notions from other languages. But  
I would point out that fun2 does not guarantee anything more than  
fun3:


void fun2(ref int [] x)
{
  fun3(x);
}
But I would point out that fun2 does not guarantee anything more than  
fun3: - fun2() cannot guarantee anything because it calls fun3() which  
in turn cannot guarantee anything.


Right, but you said this:


fun2(a); // Guaranteed that we will see any change to a, made in fun2()


Which is false. That was my point.

-Steve


Re: Array as an argument, ambiguous behaviour.

2014-01-30 Thread Steven Schveighoffer

On Thu, 30 Jan 2014 09:07:14 -0500, Cooler kul...@hotbox.ru wrote:

If I don't want that fun() will change my array, i have to use fun1()  
variant.
If I want fun() will change my array, i have to use fun2() variant. What  
fun2() do with it's argument inside it's body - not my business.


No. You can use fun3 variant as well:

void fun3(int[] x)
{
   x[] = 0; // guaranteed to be seen by caller.
}



1. For example somebody already implemented fun1() and fun2() variants,  
as in my first post. This variants understandable and predictable. What  
can push me to ask another person for fun3() implementation, while it  
result is unpredictable, until you know fun3() body?


The only reason to have both fun2 and fun3 variants is if you want to  
handle both l-value and r-value options differently. There would be very  
few use cases which make sense AND return void.


You usually want one or the other.



2. You wrote If your code must do otherwise, explain in the  
documentation what
should happen. That exactly what I am trying to discuss here. Instead  
of writing some documentation, just warn (and may be prohibit in far-far  
future) about such possible unpredictability during compilation.


No, because you are not understanding the effect of the attributes, and  
who is responsible for what.


1. Banning such signatures does NOT accomplish what you want.
2. Such signatures do NOT guarantee what happens inside the function.

Having the compiler ban the problem where you expect the caller to see  
your changes, but they don't, is akin to just making the compiler able to  
detect all logic bugs. It's not possible (NP complete). The compiler just  
doesn't know what you really want to do.


-Steve


Re: Interfaces allow member definitions?

2014-01-30 Thread John Chapman

On Thursday, 30 January 2014 at 14:31:05 UTC, Frustrated wrote:
I'm not asking about a work around but if what I am talking 
about

can actually be done(does the vtable support this or can made to
support it?)


It would work if you changed the interface to an abstract class.


Re: Interfaces allow member definitions?

2014-01-30 Thread Steven Schveighoffer

On Thu, 30 Jan 2014 09:31:05 -0500, Frustrated c1514...@drdrb.com wrote:



I'm not asking about a work around but if what I am talking about
can actually be done(does the vtable support this or can made to
support it?)


Yes. Interfaces have no concrete vtable. Only classes do. A concrete class  
can decide what the vtable has in it, and if you had a default  
implementation, the compiler could stick that in there. Note that the  
default implementation only can call other member functions within the  
interface or module-level functions, interfaces cannot access any derived  
data or members.


Whether such a change would be accepted? No clue.

-Steve


Re: Array as an argument, ambiguous behaviour.

2014-01-30 Thread Steven Schveighoffer

On Thu, 30 Jan 2014 10:24:14 -0500, Cooler kul...@hotbox.ru wrote:


On Thursday, 30 January 2014 at 14:40:36 UTC, Dicebot wrote:

On Thursday, 30 January 2014 at 13:42:53 UTC, Cooler wrote:
If I use fun2() I expect that fun2() will change the content of my  
array, and all changes I will see. If I don't want any change to my  
array, I will use fun1(). What should I want to use fun3()?


For changes to content of array but not array itself.


I agree. I just want that the case can be expressed in language syntax  
more obvious - something like fun(int[] const x){} to emphasize that I  
understand that fun() can change content of array, and cannot change the  
{pointer,size} pair.


That's what fun(int[] x) does :)

-Steve


Re: N-body bench

2014-01-30 Thread bearophile

Stanislav Blinov:

Forgot one slice assignment in toDobule2(). Now the results are 
more interesting:


Is the latest link shown the last version?

I need the 0.13.0-alpha1 to compile the code.
I am seeing a significant performance difference between C++ and 
D-ldc2.


Bye,
bearophile


Re: Array as an argument, ambiguous behaviour.

2014-01-30 Thread Tobias Pankrath

On Thursday, 30 January 2014 at 15:49:35 UTC, Cooler wrote:
I agree. I just want that the case can be expressed in 
language syntax more obvious - something like fun(int[] 
const x){} to emphasize that I understand that fun() can 
change content of array, and cannot change the {pointer,size} 
pair.


That's what fun(int[] x) does :)

-Steve


Again...
void fun(int[] x){ x ~= 5; }
auto a = new int[10];
fun(a); // Can you predict the content of 'a'?



It's [0, 0, 0, 0, 0, 0, 0, 0, 0, 0].


How to call opCall as template?

2014-01-30 Thread Namespace

Here: http://dlang.org/operatoroverloading.html#FunctionCall
is this example:

import std.stdio;

struct F {
int opCall() {
return 0;
}

int opCall(int x, int y, int z) {
return x * y * z;
}
}

void main() {
F f;
int i;

i = f();  // same as i = f.opCall();
i = f(3,4,5); // same as i = f.opCall(3,4,5);
}


And it works of course. But what if I want to templatize opCall? 
How can I call it?



import std.stdio;

struct F {
T opCall(T = int)(int a, int b, int c) {
return cast(T)(a * b * c);
}
}

void main() {
F f;
int i = f(3,4,5);
float f_ = f!float(6, 7, 8);
}


Does not work, it fails with:
Error: template instance f!float f is not a template declaration, 
it is a variable


import expression with paths

2014-01-30 Thread Lemonfiend

This does not compile on Windows, but does compile on Mac:

---
module main;

void main()
{
import std.path;
enum bar = import(`dir` ~ dirSeparator ~ `bar.txt`);
}
---

The docs say:
http://dlang.org/expression.html#ImportExpression
Implementations may restrict the file name in order to avoid 
directory traversal security vulnerabilities. A possible 
restriction might be to disallow any path components in the file 
name.


So, I suppose it's valid code. But it's still surprising to 
encounter.

Should it not simply be disallowed completely?


Re: Array as an argument, ambiguous behaviour.

2014-01-30 Thread Steven Schveighoffer

On Thu, 30 Jan 2014 10:49:34 -0500, Cooler kul...@hotbox.ru wrote:


On Thursday, 30 January 2014 at 15:29:50 UTC, Steven Schveighoffer wrote:

On Thu, 30 Jan 2014 10:24:14 -0500, Cooler kul...@hotbox.ru wrote:


On Thursday, 30 January 2014 at 14:40:36 UTC, Dicebot wrote:


I agree. I just want that the case can be expressed in language syntax  
more obvious - something like fun(int[] const x){} to emphasize that  
I understand that fun() can change content of array, and cannot change  
the {pointer,size} pair.


That's what fun(int[] x) does :)

-Steve


Again...
void fun(int[] x){ x ~= 5; }
auto a = new int[10];
fun(a); // Can you predict the content of 'a'?


I suspect you mean:

void fun(int[] x) {x.length += 1; x[0] = 5;}

I cannot predict what the caller will see. But this is not a problem of  
*signatures*. The caller will not see ANY changes to {pointer,size} pair  
of x. That is the point -- it's passed by value.


Note that this implementation is completely predictable:

void fun(int[] x) {x[0] = 5; x.length += 1;}

I want to stress that just because you can find an implementation that has  
a bug doesn't mean that there is an opportunity for the compiler to detect  
that bug, especially a logic bug. The compiler simply cannot know what you  
are thinking.



In your case:
void fun(int[] x){ x = [1, 2]; } // Compilation ok. Implementation's  
error.
The fun() implementer made error and think that caller will get new  
array. But it will get it only at runtime!

If we for example (just for example) have
void fun(int[] const x){ x = [1, 2]; } // Compilation error.


I see very little value in that. We don't need to obliterate a tremendous  
amount of slice usage (not mentioning how much code will have to be  
updated) in order to help newbies understand how slices work.


-Steve


Re: How to call opCall as template?

2014-01-30 Thread Stanislav Blinov

void main() {
F f;
int i = f(3,4,5);
float f_ = f!float(6, 7, 8);
}


Does not work, it fails with:
Error: template instance f!float f is not a template 
declaration, it is a variable


f.opCall!float(6, 7, 8);


Re: How to call opCall as template?

2014-01-30 Thread Namespace
On Thursday, 30 January 2014 at 16:24:00 UTC, Stanislav Blinov 
wrote:

void main() {
F f;
int i = f(3,4,5);
float f_ = f!float(6, 7, 8);
}


Does not work, it fails with:
Error: template instance f!float f is not a template 
declaration, it is a variable


f.opCall!float(6, 7, 8);


... Yes, of course. But where is the sense to use opCall if I 
need to call it explicitly?


Re: N-body bench

2014-01-30 Thread bearophile

Stanislav Blinov:


You mean with your current version of ldc?


Yes. The older version of LDC2 doesn't even compile the code. I 
need to use 0.13.0-alpha1.


Your D code with small changes:
http://codepad.org/xqqScd42

Asm generated by G++ for the advance function (that is the one 
that uses most of the run time):

http://codepad.org/tApRNsVy

Asm generated by ldc2:
http://codepad.org/jKSJcOAZ

With N = 5_000_000 my timings on an old CPU are 2.23 seconds for 
ldc2 and 1.83 seconds for g++. So there's some performance 
difference.


I have tried to unroll manually the loop in the D code, but I see 
worse performance. I'll try some more later.


Bye,
bearophile


Re: How to call opCall as template?

2014-01-30 Thread Frustrated

On Thursday, 30 January 2014 at 16:28:42 UTC, Namespace wrote:
On Thursday, 30 January 2014 at 16:24:00 UTC, Stanislav Blinov 
wrote:

void main() {
F f;
int i = f(3,4,5);
float f_ = f!float(6, 7, 8);
}


Does not work, it fails with:
Error: template instance f!float f is not a template 
declaration, it is a variable


f.opCall!float(6, 7, 8);


... Yes, of course. But where is the sense to use opCall if I 
need to call it explicitly?


Could you not use opDispatch? Not sure if you can templatize it
or not though...


Re: How to call opCall as template?

2014-01-30 Thread Namespace

On Thursday, 30 January 2014 at 16:47:46 UTC, Frustrated wrote:

On Thursday, 30 January 2014 at 16:28:42 UTC, Namespace wrote:
On Thursday, 30 January 2014 at 16:24:00 UTC, Stanislav Blinov 
wrote:

void main() {
F f;
int i = f(3,4,5);
float f_ = f!float(6, 7, 8);
}


Does not work, it fails with:
Error: template instance f!float f is not a template 
declaration, it is a variable


f.opCall!float(6, 7, 8);


... Yes, of course. But where is the sense to use opCall if I 
need to call it explicitly?


Could you not use opDispatch? Not sure if you can templatize it
or not though...


Example? I did not know how.


Re: Interfaces allow member definitions?

2014-01-30 Thread Frustrated

On Thursday, 30 January 2014 at 15:28:24 UTC, Steven
Schveighoffer wrote:
On Thu, 30 Jan 2014 09:31:05 -0500, Frustrated 
c1514...@drdrb.com wrote:



I'm not asking about a work around but if what I am talking 
about
can actually be done(does the vtable support this or can made 
to

support it?)


Yes. Interfaces have no concrete vtable. Only classes do. A 
concrete class can decide what the vtable has in it, and if you 
had a default implementation, the compiler could stick that 
in there. Note that the default implementation only can call 
other member functions within the interface or module-level 
functions, interfaces cannot access any derived data or members.


Whether such a change would be accepted? No clue.

-Steve


Basically I see no reason why the compiler can't treat the
interface as a class and allow default methods. (it would have
to allow multiple inheritance on that class though)

All it would do is make it easy to provide a default
implementation(more of a static implementation but allows it to
be overriden, which makes it useful).

For example, when creating a design you would no longer have to
specifically create a corresponding class to use for the
interface. You could just provide some default implementations of
everything(throw errors, write stuff, etc...)

I think it would be probably rather easy to do by extending the
vtable to have one lower level, the interface methods, which, in
fact, could use this(so you could have a this in them but only
reference other members of the interface).


Essentially what it boils down to is treating interfaces like
classes that have no fields). To avoid the diamond problem simply
always choose the method that is not from the interface(since it
is default), which is done naturally with the vtable.

Of course, maybe this just creates the diamond problem for
interfaces: which default implementation to use... which I'm
not sure if it's a problem?





Re: How to call opCall as template?

2014-01-30 Thread Meta

On Thursday, 30 January 2014 at 15:59:28 UTC, Namespace wrote:

Here: http://dlang.org/operatoroverloading.html#FunctionCall
is this example:

import std.stdio;

struct F {
int opCall() {
return 0;
}

int opCall(int x, int y, int z) {
return x * y * z;
}
}

void main() {
F f;
int i;

i = f();  // same as i = f.opCall();
i = f(3,4,5); // same as i = f.opCall(3,4,5);
}


And it works of course. But what if I want to templatize 
opCall? How can I call it?



import std.stdio;

struct F {
T opCall(T = int)(int a, int b, int c) {
return cast(T)(a * b * c);
}
}

void main() {
F f;
int i = f(3,4,5);
float f_ = f!float(6, 7, 8);
}


Does not work, it fails with:
Error: template instance f!float f is not a template 
declaration, it is a variable


This is probably a bug. You should file it in Bugzilla.


Re: N-body bench

2014-01-30 Thread Stanislav Blinov

On Thursday, 30 January 2014 at 16:53:22 UTC, bearophile wrote:

Yes. The older version of LDC2 doesn't even compile the code. I 
need to use 0.13.0-alpha1.


Hmm.


Your D code with small changes:
http://codepad.org/xqqScd42


That won't compile with dmd (at least, with 2.064.2): it expects 
constants as initializers for vectors. :( That's why I rolled up 
that toDouble2() function.


With N = 5_000_000 my timings on an old CPU are 2.23 seconds 
for ldc2 and 1.83 seconds for g++. So there's some performance 
difference.


What about 50_000_000?



I have tried to unroll manually the loop in the D code, but I 
see worse performance. I'll try some more later.


I'm also fiddling :)


Re: Array as an argument, ambiguous behaviour.

2014-01-30 Thread Steven Schveighoffer

On Thu, 30 Jan 2014 11:48:50 -0500, Cooler kul...@hotbox.ru wrote:



Please understand - I am not against void foo(int[] x){}


From an earlier post by you:

May be just prohibit at language level the case of fun3() function, to  
do not allow unpredictable behavior?


I thought that this meant you were against it?

I am for predictability of behavior. You suggest to describe function's  
behavior in documentation - quotation from your article It is a good  
idea to note in the documentation how the passed in slice might or might  
not be
overwritten. My idea is that all potential errors must be detected as  
soon as possible.


You cannot eradicate all errors. The intentions of a function are not  
apparent to the compiler. Maybe the intention is to use the argument as a  
buffer, and the caller should not care what happens to the buffer inside  
the function.


Adding yet another attribute is going to increase language complexity for  
almost no benefit. It does not guarantee unambiguity because you have no  
idea what the author of the function is going to do.


The D principle - The program compile and runs as expected, or not  
compile at all.


This is a fantasy. The compiler cannot know what you expect.

If you really need to call function that can change content of an array,  
but cannot change size of an array the language syntax should allow  
express it in function signature. I consider void fun(int[] const x){}  
more error prone than void fun(int[] x){} and for the caller and for  
implemeter.


Not sure if something is mixed up there. I think void fun(int[] x) is  
sufficient to describe what you say. The function cannot alter x's array  
bounds at all, and can alter it's data.




I see very little value in that. We don't need to obliterate a  
tremendous  amount of slice usage (not mentioning how much code will  
have to be  updated) in order to help newbies understand how slices  
work.

Any idea can be rejected by this sentence.


No, only ideas that force people to change millions of lines of code, and  
provide scant benefits instead of taking 5 minutes to explain no, just  
use x[0..2] = [1, 2] or just use ref int[] x depending on the goal.


-Steve


Re: Array as an argument, ambiguous behaviour.

2014-01-30 Thread Steven Schveighoffer

On Thu, 30 Jan 2014 12:07:07 -0500, Cooler kul...@hotbox.ru wrote:


On Thursday, 30 January 2014 at 16:18:33 UTC, Steven Schveighoffer wrote:



void foo(int x)
{
   x = 5;
}

hey, why doesn't that work! Setting a parameter to another value  
should be illegal!


Difference is here.
void foo(int x){} - the caller will NEVER see any change to 'x'.
void foo(int[] x){} - the caller MAY or MAY NOT see changes to 'x'.


This is incorrect:

foo(int[] x){} - The caller will see changes to data 'x' references.

A slice is a reference type, it references a specific block of data. It's  
more akin to a pointer than an int.


I could change my example:

void foo(int *x)
{
   int n = 3;
   x = n;
}

hey, why doesn't x now point to 3? Should be illegal!

-Steve


Re: Array as an argument, ambiguous behaviour.

2014-01-30 Thread Maxim Fomin

On Thursday, 30 January 2014 at 16:48:51 UTC, Cooler wrote:
On Thursday, 30 January 2014 at 16:18:33 UTC, Steven 
Schveighoffer wrote:

void foo(int x)
{
  x = 5;
}

hey, why doesn't that work! Setting a parameter to another 
value should be illegal!


-Steve


Please understand - I am not against void foo(int[] x){}
I am for predictability of behavior.


Predictability of behavior is not a principle of D and even if it 
would be, it can't be applied blindly. D is not a formal 
mathematic system.


You suggest to describe function's behavior in documentation - 
quotation from your article It is a good idea to note in the 
documentation how the passed in slice might or might not be
overwritten. My idea is that all potential errors must be 
detected as soon as possible.


It is impossible to detect all errors in D per se, let alone 
taking into account separate compilation model. In some 
circumstances compiler can guess possible ways, but particular 
case we discussing is so common, that nothing can be done to 
'fix' it. By the way, this case is not strictly speaking an 
error. It is error in context when caller cares about changes but 
this can be hardly verified at compile time (compiler need to 
read brain to know it).


The D principle - The program compile and runs as expected, or 
not compile at all.


It is all talk. Trying to apply this 'principle' in all cases is 
too naive.


If you really need to call function that can change content of 
an array, but cannot change size of an array the language 
syntax should allow express it in function signature. I 
consider void fun(int[] const x){} more error prone than 
void fun(int[] x){} and for the caller and for implemeter.




Personally this syntax is awful.

By the way, there is another similar issue in D:

import std.stdio;

void foo(int[int] aa)
{
aa[1] = 1;
}

void main()
{
int[int] aa;
foo(aa);
writeln(aa); // []
aa[0] = 0;
foo(aa);
writeln(aa); // [0:0, 1:1]
aa = null;
foo(aa);
writeln(aa); // []
}

Here changes in AA array will be visible conditional that array 
is non null. If it is null, changes will be lost. This is another 
example of situation of the caller MAY or MAY NOT see changes 
to (citing your post above). In general, such 
semivalue-semireference semantic is produced when there is 
pointer wrapped into struct (doesn't matter whether it is opaque 
lang type or user defined). This happens in some language types, 
but may be also in user defined types. I don't think that 
verifying arbitrary semantic is compiler job.


Re: Interfaces allow member definitions?

2014-01-30 Thread Steven Schveighoffer

On Thu, 30 Jan 2014 11:58:15 -0500, Frustrated c1514...@drdrb.com wrote:



Essentially what it boils down to is treating interfaces like
classes that have no fields). To avoid the diamond problem simply
always choose the method that is not from the interface(since it
is default), which is done naturally with the vtable.


It's simpler than that. A function is a block of code. A vtable entry  
points to a block of code. Just point the vtable entry at the block of  
code that is the default implementation.


-Steve


Re: core.stdc.config

2014-01-30 Thread Gary Willoughby
On Thursday, 30 January 2014 at 14:10:37 UTC, Craig Dillabaugh 
wrote:
I did as you suggested and had a look through what was on my 
system.  Having done so I now think that the documentation at:


http://dlang.org/phobos/index.html

is out of date.

If you look at the section under Imports, this appears to be 
describing what is available under from C, but it appears to 
suggest that you use std.c.config - or at least that is how I 
would have read it.


The 'std.c.*' modules are just publicly importing 'core.stdc.*' 
modules and AFAIK discouraged as it gives the impression they are 
part of Phobos. Using 'core.stdc.*' is informing other developers 
this is core runtime stuff.


Forget 'std.c.*', use 'core.stdc.*'. And you are right, the 
documentation needs a big update!


Re: Interfaces allow member definitions?

2014-01-30 Thread Frustrated

On Thursday, 30 January 2014 at 17:11:24 UTC, Steven
Schveighoffer wrote:
On Thu, 30 Jan 2014 11:58:15 -0500, Frustrated 
c1514...@drdrb.com wrote:




Essentially what it boils down to is treating interfaces like
classes that have no fields). To avoid the diamond problem 
simply
always choose the method that is not from the interface(since 
it

is default), which is done naturally with the vtable.


It's simpler than that. A function is a block of code. A vtable 
entry points to a block of code. Just point the vtable entry at 
the block of code that is the default implementation.


-Steve


Right, this was my original point and why I thought there was
already entries for the interface in the vtable(since I seemed to
have called some function that did nothing when it should have).

It seems so simple and offers some benefit(would at the very
least stop requiring one to implement a class every time they
want test a design. When programming to interfaces and using some
type of factory it makes even more sense.

It then could also be used to test is something is
implemented(possibly for versioning).

e.g.,

interface A
{
void hasSomeFeature() { assert(0, Not implemented yet); }
}

Someone can come along and implement the feature and you(the
interface) knows it's implemented if it doesn't assert, set a
flag, or whatever.

Are you 100% sure no default space is created for the vtable?
(trying to reconcile why that case I mentioned worked. I'll try
to throw an example up... may have just been coincidence I didn't
get a segfault)


Re: How to call opCall as template?

2014-01-30 Thread Frustrated

On Thursday, 30 January 2014 at 16:53:33 UTC, Namespace wrote:

On Thursday, 30 January 2014 at 16:47:46 UTC, Frustrated wrote:

On Thursday, 30 January 2014 at 16:28:42 UTC, Namespace wrote:
On Thursday, 30 January 2014 at 16:24:00 UTC, Stanislav 
Blinov wrote:

void main() {
F f;
int i = f(3,4,5);
float f_ = f!float(6, 7, 8);
}


Does not work, it fails with:
Error: template instance f!float f is not a template 
declaration, it is a variable


f.opCall!float(6, 7, 8);


... Yes, of course. But where is the sense to use opCall if I 
need to call it explicitly?


Could you not use opDispatch? Not sure if you can templatize it
or not though...


Example? I did not know how.



doesn't seem to work with templates, I suppose you could try and
add it as a feature request?

module main;

import std.stdio;

interface A
{
void foo();
static final New() { }
}

class B : A
{
void foo() { writeln(this is B.foo); }

void opDispatch(string s, T)(int i) {
writefln(C.opDispatch('%s', %s), s, i);
}

}


void main() {
B a = new B;
//a.foo();

a.test!int(3); // any *good* reason why this shouldn't work?

}


Re: Interfaces allow member definitions?

2014-01-30 Thread Steven Schveighoffer

On Thu, 30 Jan 2014 12:30:04 -0500, Frustrated c1514...@drdrb.com wrote:


On Thursday, 30 January 2014 at 17:11:24 UTC, Steven
Schveighoffer wrote:
On Thu, 30 Jan 2014 11:58:15 -0500, Frustrated c1514...@drdrb.com  
wrote:




Essentially what it boils down to is treating interfaces like
classes that have no fields). To avoid the diamond problem simply
always choose the method that is not from the interface(since it
is default), which is done naturally with the vtable.


It's simpler than that. A function is a block of code. A vtable entry  
points to a block of code. Just point the vtable entry at the block of  
code that is the default implementation.


-Steve


Right, this was my original point and why I thought there was
already entries for the interface in the vtable(since I seemed to
have called some function that did nothing when it should have).


I think your original example should not have happened. Either there was a  
bug in the runtime, compiler, or your memory :)




It seems so simple and offers some benefit(would at the very
least stop requiring one to implement a class every time they
want test a design. When programming to interfaces and using some
type of factory it makes even more sense.


This is a misunderstanding, you still need to declare a class, because an  
interface is not a concrete type. But if there are default implementations  
for all the interface functions, you don't need to implement any of them!




It then could also be used to test is something is
implemented(possibly for versioning).

e.g.,

interface A
{
 void hasSomeFeature() { assert(0, Not implemented yet); }
}

Someone can come along and implement the feature and you(the
interface) knows it's implemented if it doesn't assert, set a
flag, or whatever.

Are you 100% sure no default space is created for the vtable?
(trying to reconcile why that case I mentioned worked. I'll try
to throw an example up... may have just been coincidence I didn't
get a segfault)


I didn't write the compiler, so I'm not 100%, but I'm 99% sure :)

-Steve


Re: N-body bench

2014-01-30 Thread bearophile

Stanislav Blinov:

That won't compile with dmd (at least, with 2.064.2): it 
expects constants as initializers for vectors. :( That's why I 
rolled up that toDouble2() function.


I see. Then probably I will have to put it back...


With N = 5_000_000 my timings on an old CPU are 2.23 seconds 
for ldc2 and 1.83 seconds for g++. So there's some performance 
difference.


What about 50_000_000?


First let me try to fiddle with the code some more :-)

Once done, this should go somewhere (like the wiki) as a simple 
example of SIMD usage in D.


Bye,
bearophile


Re: How to call opCall as template?

2014-01-30 Thread Frustrated

Also,

http://dlang.org/operatoroverloading.html#Dispatch

and possible solution to your problem:

http://www.digitalmars.com/d/archives/digitalmars/D/opDispatch_and_template_parameters_117095.html

Couldn't get code to compile though... but if it did, it should
solve your problem.



Re: How to call opCall as template?

2014-01-30 Thread Namespace

On Thursday, 30 January 2014 at 16:55:01 UTC, Meta wrote:

On Thursday, 30 January 2014 at 15:59:28 UTC, Namespace wrote:

Here: http://dlang.org/operatoroverloading.html#FunctionCall
is this example:

import std.stdio;

struct F {
int opCall() {
return 0;
}

int opCall(int x, int y, int z) {
return x * y * z;
}
}

void main() {
F f;
int i;

i = f();  // same as i = f.opCall();
i = f(3,4,5); // same as i = f.opCall(3,4,5);
}


And it works of course. But what if I want to templatize 
opCall? How can I call it?



import std.stdio;

struct F {
T opCall(T = int)(int a, int b, int c) {
return cast(T)(a * b * c);
}
}

void main() {
F f;
int i = f(3,4,5);
float f_ = f!float(6, 7, 8);
}


Does not work, it fails with:
Error: template instance f!float f is not a template 
declaration, it is a variable


This is probably a bug. You should file it in Bugzilla.


Ok, done:
https://d.puremagic.com/issues/show_bug.cgi?id=12043


Re: Array as an argument, ambiguous behaviour.

2014-01-30 Thread Steven Schveighoffer

On Thu, 30 Jan 2014 12:38:57 -0500, Cooler kul...@hotbox.ru wrote:


The D principle - The program compile and runs as expected, or not  
compile at all.


This is a fantasy. The compiler cannot know what you expect.

The language is needed to express your intentions to the compiler.


Anything that the compiler cannot enforce is just documentation. Does it  
matter whether the documentation is in a comment or part of the signature?


The language should be expressive as possible. My point is to push  
programmers to write correct software. I just ask these forum to think  
about topic. If everybody satisfied by void fun(int[] x){} behavior,  
then I just go...


I'm not trying to be a bully or anything, but you are not understanding  
that what you want is a guarantee of logic, that the compiler cannot  
possibly enforce. Your example (setting a variable to another value) being  
rejected is easy to work around, just use another variable that doesn't  
have that restriction. There are so many examples of behavior-enforcing  
features that result in something that the creator of the feature didn't  
want or expect. Keep in mind there are years of projects that have been  
written assuming that you can use a standard slice in the signature of a  
function, we don't want to invalidate all that code just because  
programmers sometimes write buggy code.


But I encounter a bug in my program that was due to my misusing of such  
signature.


Here's where the gray area is. If you make this error once or twice, but  
never again, is it worth changing the language over? Probably not. But if  
you make this error every day, even KNOWING what will happen, it's worth  
looking into. But any changes have to avoid a negative impact on existing  
code as much as possible. Think of the person who knows how slices work,  
who very seldom makes this mistake, and who now has to go through all his  
code and make this change, never finding an instance where it makes a  
difference.


At this point, I'm not sure what you are proposing, but I don't think  
there is much value in changing the way slice passing works.


If you really need to call function that can change content of an  
array, but cannot change size of an array the language syntax should  
allow express it in function signature. I consider void fun(int[]  
const x){} more error prone than void fun(int[] x){} and for the  
caller and for implemeter.


Not sure if something is mixed up there. I think void fun(int[] x) is  
sufficient to describe what you say. The function cannot alter x's  
array bounds at all, and can alter it's data.


Here is the reason why i post the topic on this forum. You think one  
way, I think another way. I wanted to discuss what think other people.  
But looks like still nobody can understand my point, or may be I cannot  
express it...


By mixed up, I meant that you seemed to be valuing the int[] x version  
over the int[] const x version.


Other than that, what I stated is an indisputable fact -- the function  
cannot alter x's bounds.


-Steve


Re: How to call opCall as template?

2014-01-30 Thread Namespace

On Thursday, 30 January 2014 at 17:46:19 UTC, Frustrated wrote:

Also,

http://dlang.org/operatoroverloading.html#Dispatch

and possible solution to your problem:

http://www.digitalmars.com/d/archives/digitalmars/D/opDispatch_and_template_parameters_117095.html

Couldn't get code to compile though... but if it did, it should
solve your problem.


opDispatch is called if you try to call a non existing member. 
But in this case you don't call a member. ;)


Re: How to call opCall as template?

2014-01-30 Thread Namespace

On Thursday, 30 January 2014 at 18:11:49 UTC, Frustrated wrote:

BTW,

a() is replaced with a.opCall()

and you can use opDispatch on it.

an opCall is a member.

Either approach should work if you can get that archive example
to compile.


I am sure that the error is thrown before.
But please show me your attempts.


Re: Interfaces allow member definitions?

2014-01-30 Thread Steven Schveighoffer

On Thu, 30 Jan 2014 13:06:30 -0500, Frustrated c1514...@drdrb.com wrote:


On Thursday, 30 January 2014 at 17:38:26 UTC, Steven
Schveighoffer wrote:
This is a misunderstanding, you still need to declare a class, because  
an interface is not a concrete type. But if there are default  
implementations for all the interface functions, you don't need to  
implement any of them!




No, the point is, if all methods are defined, there is no need to
create the class. Why create an empty class to instantiate it
when the compiler can do it for you and you can instantiate the
interface? This is what I mean by treating the interface as a
class because for all purposes it is. (an interface is just an
abstract container but it doesn't have to be)

Again, all this could be done by the compiler internally by
creating a class to back an interface and add it to the vtable.
Instantiating the interface just returns that class. Calling a
member on the interface's object calls the member of that class,
who's body is provided in the interface definition.

I can do this now, the whole point is I don't like code
duplication! ;)

interface A
{

  void foo() { writeln(me); }
  void bar();
}

class _A  // created internally by compiler
{
  void foo() { writeln(me); } // added by compiler copied
from A
  void bar() { assert(0, error); } // added by compiler
}


http://dlang.org/phobos/std_typecons.html#.BlackHole

-Steve


Re: Interfaces allow member definitions?

2014-01-30 Thread Steven Schveighoffer
On Thu, 30 Jan 2014 13:16:21 -0500, Steven Schveighoffer  
schvei...@yahoo.com wrote:




http://dlang.org/phobos/std_typecons.html#.BlackHole


Sorry, black hole just does nothing. it's white hole you want:

http://dlang.org/phobos/std_typecons.html#.WhiteHole

-Steve


Re: N-body bench

2014-01-30 Thread bearophile

Stanislav Blinov:

That won't compile with dmd (at least, with 2.064.2): it 
expects constants as initializers for vectors. :( That's why I 
rolled up that toDouble2() function.


Few more changes, but this version still lacks the toDouble2:
http://codepad.org/SpMprWym

Bye,
bearophile


Re: N-body bench

2014-01-30 Thread Stanislav Blinov

On Thursday, 30 January 2014 at 18:29:42 UTC, bearophile wrote:

I see you're compiling with

ldmd2 -wi -O -release -inline -noboundscheck nbody.d

Try

ldc2 -release -O3 -disable-boundscheck -vectorize -vectorize-loops


Re: N-body bench

2014-01-30 Thread bearophile

Stanislav Blinov:

Looks like both dmd and ldc don't optimize slice operations 
yet, had to revert to loops


It's a very silly problem for a statically typed language. The D 
type system knows the static length of those arrays, but it 
doesn't use such information.
(Similarly several algorithms in Phobos force to throw away this 
very precious compile-time information requiring dynamic arrays 
in input.)


I have just suggested a fix for ldc2:
http://forum.dlang.org/thread/qeytzeqnygxpocywy...@forum.dlang.org

I have a similar enhancement request since some time in Bugzilla:
https://d.puremagic.com/issues/show_bug.cgi?id=10523
https://d.puremagic.com/issues/show_bug.cgi?id=10305

Bye,
bearophile


Re: Array as an argument, ambiguous behaviour.

2014-01-30 Thread Steven Schveighoffer

On Thu, 30 Jan 2014 13:58:55 -0500, Cooler kul...@hotbox.ru wrote:

The D principle - The program compile and runs as expected, or not  
compile at all.


This is a fantasy. The compiler cannot know what you expect.

The language is needed to express your intentions to the compiler.


Anything that the compiler cannot enforce is just documentation. Does  
it matter whether the documentation is in a comment or part of the  
signature?
Why we need const keyword, while we can just put I promise do not  
change it in the documentation?


const is only useful in cases where references are involved. In this case,  
you want to make the *copied* data constant, in hopes that you then can't  
accidentally stop referencing the original.


In another example, there is little to be gained from a signature such as:

void foo(const int x);

What does this say about foo? Nothing. I can pass in a mutable, const, or  
immutable int, because a copy is made. It doesn't provide any more  
guarantees to the caller than:


void foo(int x);

Likewise, your proposed int[] const would not guarantee anything extra  
to the caller beyond int[], because both are copies put onto the stack.  
The function has no access to the original values.


Arrays in D are hard to understand. They don't behave like arrays in most  
other languages. But they foster a different mindset I think, that results  
in some of the fastest code on the planet. But one has to understand the  
semantics of syntax if they want to properly use the language. For  
functions which append/extend and then write data to the prior piece (the  
only non-deterministic case), special care has to be taken to explain this  
to the caller. I would think a mechanism to attempt detecting this and  
flagging it would be a worthy lint tool feature. But not a language or  
compiler feature. There is just simply no way to say that is always bad  
or that you know what the intentions of the author are.


The other case you specified, when the author re-assigns a slice and  
expects it to be a memcpy or to re-bind the calling parameter, the result  
is deterministically the wrong result, and the coder will notice it right  
away (and hopefully correct their understanding). I don't think we need a  
language feature for that, just documentation (which I think we have).


Let me also suggest you use scope statements to verify at runtime that the  
case you intend to prevent doesn't actually happen:


void foo(int[] x)
{
   const origx = x;
   scope(exit) assert(origx.ptr == x.ptr);
   ...
}

While not perfect, and not static, it should at least avoid subtle bugs  
(and can be turned off in release mode).


-Steve


Re: Interfaces allow member definitions?

2014-01-30 Thread Frustrated

On Thursday, 30 January 2014 at 17:11:24 UTC, Steven
Schveighoffer wrote:
On Thu, 30 Jan 2014 11:58:15 -0500, Frustrated 
c1514...@drdrb.com wrote:




Essentially what it boils down to is treating interfaces like
classes that have no fields). To avoid the diamond problem 
simply
always choose the method that is not from the interface(since 
it

is default), which is done naturally with the vtable.


It's simpler than that. A function is a block of code. A vtable 
entry points to a block of code. Just point the vtable entry at 
the block of code that is the default implementation.


-Steve


But what if you want to provide some default behavior? We are not
dealing with abstract classes here.

Since there is currently no way to do what I am saying no
solution will be adequate unless it fulfills the behavior.

(again, it's not like we can't accomplish basically the same
thing, the point is mainly about simplification)

The question was about if there was any innate reason why this
type of behavior couldn't be accomplish using the vtable. I'm
assuming there is none and it could easily be done? (the compiler
just has to reserve the space and setup the pointers to the
functions?)


Re: N-body bench

2014-01-30 Thread Stanislav Blinov

On Thursday, 30 January 2014 at 18:43:02 UTC, bearophile wrote:

It's a very silly problem for a statically typed language. The 
D type system knows the static length of those arrays, but it 
doesn't use such information.


I agree.


Unrolling everything except the loop in energy() seems to have 
squeezed the bits neede to outperform c++, at least on my machine 
:)


http://dpaste.dzfl.pl/45e98e476daf

(I'm sticking to atoi because my copy of ldc seems to have an 
issue in std.conv).


time ./nbody-cpp 5000:
-0.169075164
-0.169059907
0:05.15 real, 5.14 user, 0.00 sys, 532 kb, 99% cpu

time ./nbody-ldc 5000:
-0.169075164
-0.169059907
0:04.41 real, 4.40 user, 0.00 sys, 1308 kb, 99% cpu

time ./nbody-dmd 5000:
-0.169075164
-0.169059907
0:15.39 real, 15.34 user, 0.00 sys, 1192 kb, 99% cpu



Re: Idiomatic D?

2014-01-30 Thread Dicebot

On Thursday, 30 January 2014 at 20:05:11 UTC, Tofu Ninja wrote:
I hear it thrown around a lot but what does it actually mean? 
What does the ideal D code look like? What kind of things 
should some one think about if they are trying to do idiomatic 
D?


There is no official idiomatic style like, for example, in 
python. When I speak about idiomatic D I usually think about 
style Phobos is written in (omitting legacy modules) as it is the 
code that gets most attention from most experienced D developers.


Idiomatic D?

2014-01-30 Thread Tofu Ninja
I hear it thrown around a lot but what does it actually mean? 
What does the ideal D code look like? What kind of things should 
some one think about if they are trying to do idiomatic D?


Re: Is continuously seeding a random number generator performance intensive?

2014-01-30 Thread monarch_dodra

On Tuesday, 21 January 2014 at 19:00:32 UTC, Jeroen Bollen wrote:

On Tuesday, 21 January 2014 at 17:51:44 UTC, monarch_dodra
Is that your actual code? MersenneTwisterEngine(seed) is not 
valid code, you have to provide the template arguments.


I meant to answer to this by the way, sorry. (in
need of edit feature :P )


https://d.puremagic.com/issues/show_bug.cgi?id=11960

Now resolved fixed.


Re: Interfaces allow member definitions?

2014-01-30 Thread Steven Schveighoffer

On Thu, 30 Jan 2014 14:58:42 -0500, Frustrated c1514...@drdrb.com wrote:


On Thursday, 30 January 2014 at 17:11:24 UTC, Steven
Schveighoffer wrote:
On Thu, 30 Jan 2014 11:58:15 -0500, Frustrated c1514...@drdrb.com  
wrote:




Essentially what it boils down to is treating interfaces like
classes that have no fields). To avoid the diamond problem simply
always choose the method that is not from the interface(since it
is default), which is done naturally with the vtable.


It's simpler than that. A function is a block of code. A vtable entry  
points to a block of code. Just point the vtable entry at the block of  
code that is the default implementation.


-Steve


But what if you want to provide some default behavior? We are not
dealing with abstract classes here.

Since there is currently no way to do what I am saying no
solution will be adequate unless it fulfills the behavior.

(again, it's not like we can't accomplish basically the same
thing, the point is mainly about simplification)

The question was about if there was any innate reason why this
type of behavior couldn't be accomplish using the vtable. I'm
assuming there is none and it could easily be done? (the compiler
just has to reserve the space and setup the pointers to the
functions?)


The interface defines the vtable, the class contains a value for that  
vtable.


If you imagine an interface vtable like this:

interface A
{
   void foo();
}

=

struct A_vtbl
{
   void function() foo;
}

Note the default value is NULL.

When you create a class that inherits, it's class info contains an A_vtbl:

class B : A
{
   void foo() {writeln(hi;}
}

=

struct B_typeinfo
{
   A_vtbl a_interface = {B.foo};
}

And when you call foo on an instance of A, it uses the vtable, knowing  
that the layout is A_vtbl.


(this is simplistic, the real thing is more complex to explain, it's  
somewhere on the docs).


What I'm saying is, if you give a default to the function foo, then our  
straw-man A_vtbl looks like this:


struct A_vtbl
{
   void function() foo = A.default_foo;
}

And when you create B_typeinfo, if you haven't defined foo, it just points  
at that default foo (of course, you have to fill in B.foo, and for that,  
you actually have to do a thunk to convert to the interface I think, but  
this is not hard).


But it's important to note that A does not define an instance of A_vtbl,  
just the layout! You still need a concrete class to get a vtable instance  
to point at.


-Steve


Re: How to call opCall as template?

2014-01-30 Thread Frustrated

import std.stdio;

struct B
{
template opCall(T)
{
void opCall(T x)
{
writeln(x);
}
}
}

template a(T)
{

}

void main() {
B a;
a(3);   // works because template parameter can be deduced from
arguments
a.opCall!(int)(3); // same as about but explicit
a!(int)(3); // works but calls template because a! refers to a
template
// no way to use the above syntax to initiate an opCall on a
because it is template notation.
// at most one might get away with a.!(int)(3) but this is
invalid
}



You'll never be able to do a!()() for the reasons give above. At
most it would have to be implemented the compiler and I doubt it
will ever happen. (for example, one could have the opExclamation
but then one has ambiguity, which is why ! was chosen to avoid in
the first place)


I think for your example, the first case works fine using
deduction.


Re: Interfaces allow member definitions?

2014-01-30 Thread Frustrated

On Thursday, 30 January 2014 at 20:17:23 UTC, Steven
Schveighoffer wrote:
On Thu, 30 Jan 2014 14:58:42 -0500, Frustrated 
c1514...@drdrb.com wrote:



On Thursday, 30 January 2014 at 17:11:24 UTC, Steven
Schveighoffer wrote:
On Thu, 30 Jan 2014 11:58:15 -0500, Frustrated 
c1514...@drdrb.com wrote:




Essentially what it boils down to is treating interfaces like
classes that have no fields). To avoid the diamond problem 
simply
always choose the method that is not from the 
interface(since it

is default), which is done naturally with the vtable.


It's simpler than that. A function is a block of code. A 
vtable entry points to a block of code. Just point the vtable 
entry at the block of code that is the default implementation.


-Steve


But what if you want to provide some default behavior? We are 
not

dealing with abstract classes here.

Since there is currently no way to do what I am saying no
solution will be adequate unless it fulfills the behavior.

(again, it's not like we can't accomplish basically the same
thing, the point is mainly about simplification)

The question was about if there was any innate reason why this
type of behavior couldn't be accomplish using the vtable. I'm
assuming there is none and it could easily be done? (the 
compiler

just has to reserve the space and setup the pointers to the
functions?)


The interface defines the vtable, the class contains a value 
for that vtable.


If you imagine an interface vtable like this:

interface A
{
   void foo();
}

=

struct A_vtbl
{
   void function() foo;
}

Note the default value is NULL.

When you create a class that inherits, it's class info contains 
an A_vtbl:


class B : A
{
   void foo() {writeln(hi;}
}

=

struct B_typeinfo
{
   A_vtbl a_interface = {B.foo};
}

And when you call foo on an instance of A, it uses the vtable, 
knowing that the layout is A_vtbl.


(this is simplistic, the real thing is more complex to explain, 
it's somewhere on the docs).


What I'm saying is, if you give a default to the function foo, 
then our straw-man A_vtbl looks like this:


struct A_vtbl
{
   void function() foo = A.default_foo;
}

And when you create B_typeinfo, if you haven't defined foo, it 
just points at that default foo (of course, you have to fill in 
B.foo, and for that, you actually have to do a thunk to convert 
to the interface I think, but this is not hard).


But it's important to note that A does not define an instance 
of A_vtbl, just the layout! You still need a concrete class to 
get a vtable instance to point at.


-Steve


But what I think you are failing to realize is that regardless
that foo is defined in an interface, since foo does not use this,
it does not depend on the object, so it does not need an
object(for all practical purposes it is a static function but of
course must take an object as the first parameter so it is
compatible as a member function).

Also, regardless that it is an interface, doesn't mean it can't
have a concrete vtable to work with.

The fact is that a vtable is more complex because it has the
ability to call functions defined in a base class. In this case a
base interface.

Just because something doesn't exist there now doesn't mean it
can't exist.

Answer me this

class A { void foo() { } }
class B : A {  }

B b = new B;
b.foo();

are you telling me there are actually two foo functions? or does
b actually call A's foo passing it the object b e.g., the call
made is actually foo(b);


If so, then what if A is an interface? (by interface, I am
talking about one that has a vtable created for it's members)


interface A { void foo() { } }
class B : A {  }

B b = new B;
b.foo();

Whats the difference? Absolutely nothing but your interpretation
of what an interface is.

This is all about semantics. If you want to think of an interface
as some idealized abstract compile time object that doesn't exist
at run time and has no vtable then so be it. But that doesn't
mean it has to be and I'm just saying it is limiting.

Obviously the difference between the two above is that the
compiler does not allow multiple inheritance w.r.t, to classes,
and does not allow fields in interfaces, etc... but these rules
can still be enforced on a class THAT HAS A VTABLE.

I think you still keep trying to fit the square peg in the round
hole. I'm not talking about what the compiler does... we know the
above code as I intend it does not work.


Re: N-body bench

2014-01-30 Thread bearophile

Stanislav Blinov:

Unrolling everything except the loop in energy() seems to have 
squeezed the bits neede to outperform c++, at least on my 
machine :)


That should be impossible, as I remember from my old profilings 
that energy() should use only an irrelevant amount of run time.




http://dpaste.dzfl.pl/45e98e476daf


While I benchmark some variants of this program I am seeing a 
large variety of problems, limitations, bugs and regressions.


You latest D code crashes my ldc2 V.0.12.1, while 0.13.0-alpha1 
compiles it. My older version of your D code runs with both 
compiler versions, but V.0.12.1 generates faster code.


Plus you can't make those double2 immutable, you can't use vector 
ops (because of performance, and also because they aren't nothrow 
in V.0.12.1).


I was also experimenting with (note the align):

align(16) struct Body {
double[3] x, v;
double mass;
}

struct NBodySystem {
private:
__gshared static Body[5] bodies = [
// Sun.
Body([0., 0., 0.],
 [0., 0., 0.],
 solarMass),
...

But this improves the code for V.0.12.1 and worsens it for 
0.13.0-alpha1.



Also I think the __gshared is ignored in V.0.12.1, but this bug 
could be fixed in more recent versions of ldc2.



(I'm sticking to atoi because my copy of ldc seems to have an 
issue in std.conv).


My version seems to use to!() correctly.

If ldc2 developers are reading this thread there is enough 
strange stuff here to give one or two headaches :-)


Now I don't know what final version should I keep of this 
program :-)


Bye,
bearophile


Re: N-body bench

2014-01-30 Thread bearophile

Stanislav Blinov:

ldc2 -release -O3 -disable-boundscheck -vectorize 
-vectorize-loops


All my versions of ldc2 don't even accept -vectorize :-)

ldc2: Unknown command line argument '-vectorize'.  Try: 'ldc2 
-help'

ldc2: Did you mean '-vectorize-slp'?

And -vectorize-loops should be active on default on recent 
versions of ldc2 (including V.0.12.1), and indeed I see no 
performance difference in using it.


Bye,
bearophile


Re: Interfaces allow member definitions?

2014-01-30 Thread Frustrated

On Thursday, 30 January 2014 at 21:16:05 UTC, Steven
Schveighoffer wrote:
On Thu, 30 Jan 2014 15:57:06 -0500, Frustrated 
c1514...@drdrb.com wrote:



On Thursday, 30 January 2014 at 20:17:23 UTC, Steven
Schveighoffer wrote:
But it's important to note that A does not define an instance 
of A_vtbl, just the layout! You still need a concrete class 
to get a vtable instance to point at.


But what I think you are failing to realize is that regardless
that foo is defined in an interface, since foo does not use 
this,

it does not depend on the object, so it does not need an
object(for all practical purposes it is a static function but 
of

course must take an object as the first parameter so it is
compatible as a member function).


But what if it does need an object?

interface A
{
   void foo() { bar();} // need 'this' to call bar
   void bar();
}



I've said many times that the functions could not use this. If
you are going to go that far then why not allow interfaces to
have fields? In this case they would not be any different from
classes.


Also, regardless that it is an interface, doesn't mean it can't
have a concrete vtable to work with.

The fact is that a vtable is more complex because it has the
ability to call functions defined in a base class. In this 
case a

base interface.

Just because something doesn't exist there now doesn't mean it
can't exist.


Keep in mind that an interface vtable exists as part of an 
object. The compiler knows this, and performs thunks when 
necessary.



Answer me this

class A { void foo() { } }
class B : A {  }

B b = new B;
b.foo();

are you telling me there are actually two foo functions? or 
does

b actually call A's foo passing it the object b e.g., the call
made is actually foo(b);


There is one function, but two vtables, one for A, and one for 
B. Both point at the same function.


Yes, and they could point to the function defined in the
interface. When they call it, they would pass themselves as this.
The methods in the interface do not use this, so it doesn't
matter (they could potentially use it but it would require that
it always be valid)


If so, then what if A is an interface? (by interface, I am
talking about one that has a vtable created for it's members)

interface A { void foo() { } }
class B : A {  }

B b = new B;
b.foo();

Whats the difference? Absolutely nothing but your 
interpretation

of what an interface is.


The difference is, now there is only one vtable, and one 
interface vtable inside B. A has no vtables. If you do this:


A a = new B;

a now points at the interface struct *inside B's object*. When 
you call a.foo, it does this:


1. It looks up in the interface vtable for A that's specific 
for B (accessed via the interface struct in the object itself) 
to get the function to call.
2. Included in the interface vtable struct is an offset to add 
so the 'this' pointer actually points at the object itself 
instead of the interface struct.




Who says A doesn't have a vtable? That's something that you are
forcing on it. You have to get off that if we are ever to make
any headway.



This is all about semantics. If you want to think of an 
interface
as some idealized abstract compile time object that doesn't 
exist

at run time and has no vtable then so be it. But that doesn't
mean it has to be and I'm just saying it is limiting.


An interface instance and an object instance are two VERY 
different things, and are handled differently by the compiler.


-Steve


Again, you have to get off of what has been defined. You have the
mentality exactly the same as those that thought the earth was
flat, imaginary numbers were nonsense/useless, man couldn't go to
the moon.

If you define your knowledge on what you already know what is the
point? You just run around in circles nothing changes
you'll just continue believing the earth is flat...


Re: Array as an argument, ambiguous behaviour.

2014-01-30 Thread Jesse Phillips

On Wednesday, 29 January 2014 at 10:55:57 UTC, Cooler wrote:

Consider 3 functions taking array as an argument:

void fun1(in  int[] x){...}
void fun2(ref int[] x){...}
void fun3(int[] x){...}

auto a = new int[10];

fun1(a); // Guaranteed that a will not be changed
fun2(a); // Guaranteed that we will see any change to a, made 
in fun2()
fun3(a); // Changes to a in fun3() may be or may be not 
visible to the caller


In case of fun3() we have ambiguous behaviour, depending on the 
body of the function.


Am I right?
Is that intentional?


I believe what you are asking for is head const. D does not do 
this, search for head const dlang and you'll probably find some 
discussion in it.


Symbol undefined

2014-01-30 Thread Martijn Pot
I'm starting to use D out of curiousity. I've used both Eclipse + 
DDT and Visual Studio + visualD and both give the same error in 
my second test program (second to Hello World of course...) using 
the Transmogrifier/CardboardBox example from TDPL :


 Error 42: Symbol Undefined 
_D1a14Transmogrifier12transmogrifyMFZv (void 
a.Transmogrifier.transmogrify())


Am I not linking module a (containing Transmogrifier and 
CardboardBox)? How can I get either or both IDE's running my test 
program?


Re: Interfaces allow member definitions?

2014-01-30 Thread Frustrated

Simple question.

What are the difference between an interface and a class?

I'm not talking about what the compiler does with them. I'm
talking about what they were created to do, how they came about
etc.

If you have to explain to someone what a class is and what an
interface is, then you diff that, what is your answer?

vtables should not show up in your explanation(they would if I
didn't mention it and it shows that you are stuck on the
implementation aspect and can't see the forest).


Re: N-body bench

2014-01-30 Thread Stanislav Blinov

On Thursday, 30 January 2014 at 21:04:06 UTC, bearophile wrote:

Stanislav Blinov:

Unrolling everything except the loop in energy() seems to have 
squeezed the bits neede to outperform c++, at least on my 
machine :)


That should be impossible, as I remember from my old profilings 
that energy() should use only an irrelevant amount of run time.


I meant that if I unroll it, it's not irrelevant anymore :)

While I benchmark some variants of this program I am seeing a 
large variety of problems, limitations, bugs and regressions...


:)

You latest D code crashes my ldc2 V.0.12.1, while 0.13.0-alpha1 
compiles it.


:))

My older version of your D code runs with both compiler 
versions, but V.0.12.1 generates faster code.


:)))

Plus you can't make those double2 immutable, you can't use 
vector ops (because of performance, and also because they 
aren't nothrow in V.0.12.1).


Well, not being able to make them immutable is not *that* big of 
a problem now, is it? What would be actually cool to have are 
those slice operations.



I was also experimenting with (note the align):

align(16) struct Body {
double[3] x, v;
double mass;
}

struct NBodySystem {
private:
__gshared static Body[5] bodies = [
// Sun.
Body([0., 0., 0.],
 [0., 0., 0.],
 solarMass),


Yeah... I've even thrown away that filler in the latest version 
:o)


But this improves the code for V.0.12.1 and worsens it for 
0.13.0-alpha1.


%|

(I'm sticking to atoi because my copy of ldc seems to have an 
issue in std.conv).


My version seems to use to!() correctly.


I'm using the git head (704ab3, last commit Sun Jan 26 00:00:21). 
I haven't tried the release yet.


If ldc2 developers are reading this thread there is enough 
strange stuff here to give one or two headaches :-)


Indeed.

Now I don't know what final version should I keep of this 
program :-)


I was going to compare the asm listings, but C++ seems to have 
unrolled and inlined the outer loop right inside main(), and now 
I'm slightly lost in it :)


Re: Symbol undefined

2014-01-30 Thread Ali Çehreli

On 01/30/2014 01:28 PM, Martijn Pot wrote:

I'm starting to use D out of curiousity. I've used both Eclipse + DDT
and Visual Studio + visualD and both give the same error in my second
test program (second to Hello World of course...) using the
Transmogrifier/CardboardBox example from TDPL :

  Error 42: Symbol Undefined _D1a14Transmogrifier12transmogrifyMFZv
(void a.Transmogrifier.transmogrify())

Am I not linking module a (containing Transmogrifier and CardboardBox)?
How can I get either or both IDE's running my test program?


You must include a.d on the build line.

  dmd a.d main.d ...

Ali



Re: How to call opCall as template?

2014-01-30 Thread Namespace

I think for your example, the first case works fine using
deduction.


Sure but this is not always possible. ;)

It seems that the problem occurs also with opIndex and so 
probably with all op* methods. See:

http://forum.dlang.org/thread/bug-1204...@https.d.puremagic.com%2Fissues%2F#post-lcegar:241ld2:241:40digitalmars.com


Re: Symbol undefined

2014-01-30 Thread Andrej Mitrovic

On Thursday, 30 January 2014 at 21:28:08 UTC, Martijn Pot wrote:
 Error 42: Symbol Undefined 
_D1a14Transmogrifier12transmogrifyMFZv (void 
a.Transmogrifier.transmogrify())


Typically that means the function isn't implemented, e.g. this:

void transmogrify();

instead of this:

void transmogrify() { }

The NVI examples in TDPL don't really work, as private functions 
in D are currently not virtual.


You could try pasting example code of what you're trying to build 
to show you exactly what goes wrong.


Re: N-body bench

2014-01-30 Thread bearophile

Stanislav Blinov:


I meant that if I unroll it, it's not irrelevant anymore :)


If a function takes no time to run, and you tweak it, your 
program is not supposed to go faster.



I was going to compare the asm listings, but C++ seems to have 
unrolled and inlined the outer loop right inside main(), and 
now I'm slightly lost in it :)


Try using -fkeep-inline-functions.

Bye,
bearophile


Re: Interfaces allow member definitions?

2014-01-30 Thread Steven Schveighoffer

On Thu, 30 Jan 2014 16:23:55 -0500, Frustrated c1514...@drdrb.com wrote:


Again, you have to get off of what has been defined. You have the
mentality exactly the same as those that thought the earth was
flat, imaginary numbers were nonsense/useless, man couldn't go to
the moon.


OK, then. With that, I shall retire from this discussion :)

-Steve


Re: N-body bench

2014-01-30 Thread Stanislav Blinov

On Thursday, 30 January 2014 at 21:33:38 UTC, bearophile wrote:

If a function takes no time to run, and you tweak it, your 
program is not supposed to go faster.


Right.

I was going to compare the asm listings, but C++ seems to have 
unrolled and inlined the outer loop right inside main(), and 
now I'm slightly lost in it :)


Try using -fkeep-inline-functions.


Thanks.

G++:
http://codepad.org/oOZQw1VQ

LDC:
http://codepad.org/5nHoZL1k


LDC basically generated something that I can only call one 
straight *whsh*... This reminds me Andrei's talk on (last 
years?) GoingNative (more instructions is not always slower 
code).


Re: N-body bench

2014-01-30 Thread bearophile

Stanislav Blinov:


G++:
http://codepad.org/oOZQw1VQ

LDC:
http://codepad.org/5nHoZL1k


You seem to have a quite recent CPU, as the G++ code contains 
instructions like vmovsd. So you can try to do the same with 
ldc2, and use AVX or AVX2.


There are the switches:

-march=string- Architecture to generate code for:
-mattr=a1,+a2,-a3,...- Target specific attributes 
(-mattr=help for details)
-mcpu=cpu-name   - Target a specific cpu type 
(-mcpu=help for details)



LDC basically generated something that I can only call one 
straight *whsh*...


:-)

Bye,
bearophile


Re: Symbol undefined

2014-01-30 Thread Andrej Mitrovic
On 1/30/14, Martijn Pot martijnpo...@gmail.com wrote:
 Indeed, making them public solved the problem. Is there more
 stuff in the book that isn't working?

Check the errata page[1], which coincidentally seems to be down. I'll CC Andrei.

[1]: http://erdani.com/tdpl/errata/index.php?title=Main_Page

Another more-recent book (and a free one) is this:
http://ddili.org/ders/d.en/index.html


Re: N-body bench

2014-01-30 Thread Stanislav Blinov

On Thursday, 30 January 2014 at 21:54:17 UTC, bearophile wrote:


You seem to have a quite recent CPU,


An aging i3?

as the G++ code contains instructions like vmovsd. So you can 
try to do the same with ldc2, and use AVX or AVX2.


Hmm...


This is getting a bit silly now. I must have some compile 
switches for g++ wrong:


g++ -Ofast -fkeep-inline-functions -fomit-frame-pointer 
-march=native -mfpmath=sse -mavx -mssse3 -flto --std=c++11 
-fopenmp nbody.cpp -o nbody-cpp


time ./nbody-cpp 5000:
-0.169075164
-0.169059907
0:05.09 real, 5.07 user, 0.00 sys, 1140 kb, 99% cpu

ldc2 -release -O3 -disable-boundscheck -vectorize 
-vectorize-loops -ofnbody-ldc -mattr=+avx,+ssse3 nbody.d


time ./nbody-ldc 5000:
-0.169075164
-0.169059907
0:04.02 real, 4.01 user, 0.00 sys, 1304 kb, 99% cpu


Re: Symbol undefined

2014-01-30 Thread Andrej Mitrovic
On 1/30/14, Andrej Mitrovic andrej.mitrov...@gmail.com wrote:
 On 1/30/14, Martijn Pot martijnpo...@gmail.com wrote:
 Indeed, making them public solved the problem. Is there more
 stuff in the book that isn't working?

 Check the errata page[1], which coincidentally seems to be down. I'll CC
 Andrei.

 [1]: http://erdani.com/tdpl/errata/index.php?title=Main_Page

 Another more-recent book (and a free one) is this:
 http://ddili.org/ders/d.en/index.html

I CC'ed the wrong address, re-sending.


Re: How to call opCall as template?

2014-01-30 Thread Frustrated

On Thursday, 30 January 2014 at 21:33:09 UTC, Namespace wrote:

I think for your example, the first case works fine using
deduction.


Sure but this is not always possible. ;)

It seems that the problem occurs also with opIndex and so 
probably with all op* methods. See:

http://forum.dlang.org/thread/bug-1204...@https.d.puremagic.com%2Fissues%2F#post-lcegar:241ld2:241:40digitalmars.com


Yes, because they all are implicit. It looks like you are calling
a template. D could figure this out but I think it will end up
having similar issues as  has in C++. Is it an a templated op*
on an object or is it template function call?


Re: N-body bench

2014-01-30 Thread bearophile

Stanislav Blinov:


An aging i3?


My CPU is older, it doesn't support AVX2 and AVX.


This is getting a bit silly now. I must have some compile 
switches for g++ wrong:


g++ -Ofast -fkeep-inline-functions -fomit-frame-pointer 
-march=native -mfpmath=sse -mavx -mssse3 -flto --std=c++11 
-fopenmp nbody.cpp -o nbody-cpp


time ./nbody-cpp 5000:
-0.169075164
-0.169059907
0:05.09 real, 5.07 user, 0.00 sys, 1140 kb, 99% cpu

ldc2 -release -O3 -disable-boundscheck -vectorize 
-vectorize-loops -ofnbody-ldc -mattr=+avx,+ssse3 nbody.d


time ./nbody-ldc 5000:
-0.169075164
-0.169059907
0:04.02 real, 4.01 user, 0.00 sys, 1304 kb, 99% cpu


Now the ldc2-compile runs in 4 seconds, this sounds correct. If 
you have paid for a CPU with AVX2 or AVX, it's right to use that 
:-)


Bye,
bearophile


Re: Interfaces allow member definitions?

2014-01-30 Thread Frustrated

On Thursday, 30 January 2014 at 21:42:39 UTC, Steven
Schveighoffer wrote:
On Thu, 30 Jan 2014 16:23:55 -0500, Frustrated 
c1514...@drdrb.com wrote:


Again, you have to get off of what has been defined. You have 
the

mentality exactly the same as those that thought the earth was
flat, imaginary numbers were nonsense/useless, man couldn't go 
to

the moon.


OK, then. With that, I shall retire from this discussion :)

-Steve


It would be nice if you could understand what I'm getting at but
it's like I keep telling you the earth and you don't believe me ;)

Almost surely we are arguing about different things. Mine is more
syntax substitution and yours is more implementation.

In any case, it doesn't matter because it will never be
implemented the way I think it could be so we are just wasting
our time(or I'm wasting yours, how ever you want to see it ;)


Re: Idiomatic D?

2014-01-30 Thread Tofu Ninja

On Thursday, 30 January 2014 at 20:10:01 UTC, Dicebot wrote:

On Thursday, 30 January 2014 at 20:05:11 UTC, Tofu Ninja wrote:
I hear it thrown around a lot but what does it actually mean? 
What does the ideal D code look like? What kind of things 
should some one think about if they are trying to do idiomatic 
D?


There is no official idiomatic style like, for example, in 
python. When I speak about idiomatic D I usually think about 
style Phobos is written in (omitting legacy modules) as it is 
the code that gets most attention from most experienced D 
developers.


Got any tips?


Re: N-body bench

2014-01-30 Thread bearophile
Since my post someone has added a Fortran version based on the 
algorithm used in the C++11 code. It's a little faster than the 
C++11 code and it's much nicer looking:

http://benchmarksgame.alioth.debian.org/u32/program.php?test=nbodylang=ifcid=5


pure subroutine advance(tstep, x, v, mass)
  real*8, intent(in) :: tstep
  real*8, dimension(4,nb), intent(inout) :: x, v
  real*8, dimension(nb), intent(in) :: mass
  real*8 :: r(4,N),mag(N)

  real*8 :: distance, d2
  integer :: i, j, m
  m = 1
  do i = 1, nb
 do j = i + 1, nb
r(1,m) = x(1,i) - x(1,j)
r(2,m) = x(2,i) - x(2,j)
r(3,m) = x(3,i) - x(3,j)
m = m + 1
 end do
  end do

  do m = 1, N
 d2 = r(1,m)**2 + r(2,m)**2 + r(3,m)**2
 distance = 1/sqrt(real(d2))
 distance = distance * (1.5d0 - 0.5d0 * d2 * distance * 
distance)
 !distance = distance * (1.5d0 - 0.5d0 * d2 * distance * 
distance)

 mag(m) = tstep * distance**3
  end do

  m = 1
  do i = 1, nb
 do j = i + 1, nb
v(1,i) = v(1,i) - r(1,m) * mass(j) * mag(m)
v(2,i) = v(2,i) - r(2,m) * mass(j) * mag(m)
v(3,i) = v(3,i) - r(3,m) * mass(j) * mag(m)

v(1,j) = v(1,j) + r(1,m) * mass(i) * mag(m)
v(2,j) = v(2,j) + r(2,m) * mass(i) * mag(m)
v(3,j) = v(3,j) + r(3,m) * mass(i) * mag(m)

m = m + 1
 end do
  end do

  do i = 1, nb
 x(1,i) = x(1,i) + tstep * v(1,i)
 x(2,i) = x(2,i) + tstep * v(2,i)
 x(3,i) = x(3,i) + tstep * v(3,i)
  end do
  end subroutine advance


Bye,
bearophile


Re: Magic infinite loop inside foreach

2014-01-30 Thread MrSmith

On Thursday, 30 January 2014 at 22:56:46 UTC, MrSmith wrote:
I have some function which does some matrix calculations and 
prints them. It is actually calculationg determinant of the 
matrix and i need to call those functions several times in the 
loop, until i get the final result. Here is the code.


void solveAndPrint(T : CoeffMatrix!(ElementType, ElementType), 
ElementType)(T _matrix)

{
auto matrix = _matrix;
TempMatrix!ElementType temp;

foreach(_; 0..3) //3 is just for debug
{
writeln(matrix);
temp = makeTemp(matrix);

writeln(temp);
matrix = solveTemp(temp);

writeln(done1);
stdout.flush();
}
writeln(done2);
stdout.flush();
}

The problem is that after 'done1' is printed it is running 
infinitely consuming all the processor just like if has 
infinite loop inside. done2 is never printed.


Somehow if i comment out
//matrix = solveTemp(temp);
it works, but this method works fine, and after it done1 is 
printed. Strange.


Re: Magic infinite loop inside foreach

2014-01-30 Thread Ali Çehreli

On 01/30/2014 03:08 PM, MrSmith wrote:

 On Thursday, 30 January 2014 at 22:56:46 UTC, MrSmith wrote:
 I have some function which does some matrix calculations and prints
 them. It is actually calculationg determinant of the matrix and i need
 to call those functions several times in the loop, until i get the
 final result. Here is the code.

 void solveAndPrint(T : CoeffMatrix!(ElementType, ElementType),
 ElementType)(T _matrix)
 {
 auto matrix = _matrix;
 TempMatrix!ElementType temp;

 foreach(_; 0..3) //3 is just for debug
 {
 writeln(matrix);
 temp = makeTemp(matrix);

 writeln(temp);
 matrix = solveTemp(temp);

Does that mutate temp in any way? If so, probably the change is 
affecting how solveTemp() works the next time.



 writeln(done1);
 stdout.flush();
 }
 writeln(done2);
 stdout.flush();
 }

 The problem is that after 'done1' is printed it is running infinitely
 consuming all the processor just like if has infinite loop inside.
 done2 is never printed.

 Somehow if i comment out
 //matrix = solveTemp(temp);
 it works, but this method works fine, and after it done1 is printed.
 Strange.

Ali



Re: N-body bench

2014-01-30 Thread Stanislav Blinov

On Thursday, 30 January 2014 at 22:45:45 UTC, bearophile wrote:
Since my post someone has added a Fortran version based on the 
algorithm used in the C++11 code. It's a little faster than the 
C++11 code and it's much nicer looking:


Yup, I saw it. They're cheating, they almost don't have to 
explicitly handle any SSE business :o) I'm wondering how our 
little code could perform on that machine.


It looks nice too, by the way:

http://dpaste.dzfl.pl/a81a475bbcf6

I've rearranged some bits, brought back to!int (turned out there 
wasn't any issues, it's just that ldc generated errors regarding 
to! when there were other compiler errors %\), replaced 
TypeTuples with your Iota... the works :)


Re: Magic infinite loop inside foreach

2014-01-30 Thread Joseph Rushton Wakeling

On 31/01/14 00:08, MrSmith wrote:

Somehow if i comment out
//matrix = solveTemp(temp);
it works, but this method works fine, and after it done1 is printed. Strange.


That does rather suggest that it's that method that is causing things to get 
stuck.  Can you share what's inside it?  And when you say this method works 
fine, do you mean that you've manually tested it with the temp variable that 
goes in before it hangs?


Could it be that whatever printout you're doing of variables like matrix is 
missing some tiny differences -- floating-point rounding errors? -- that are 
responsible for the transformations inside makeTemp or solveTemp behaving 
wrongly and therefore (in the latter case) getting stuck?


Re: Idiomatic D?

2014-01-30 Thread Stanislav Blinov

On Friday, 31 January 2014 at 00:08:02 UTC, Meta wrote:

On Thursday, 30 January 2014 at 22:40:24 UTC, Tofu Ninja wrote:



Got any tips?


Ranges, templates and structs.


~= CTFE ~ UFCS


  1   2   >