new Type[count] takes too much?

2013-10-31 Thread Namespace
I'm sure we had already this conversation but I don't find the 
thread.


T[] buffer = new T[N]; assumes more space than stated (in average 
2010 elements more. See: http://dpaste.dzfl.pl/af92ad22c). It 
behaves exactly like reserve and that is IMO wrong. If I reserve 
memory with buffer.reserve(N), I want to have at least N 
elements. That behaviour is correct. But if I use new T[N] I 
mostly want exactly N elements and no extra space.


Thoughts?


Re: new Type[count] takes too much?

2013-10-31 Thread bearophile

Namespace:

T[] buffer = new T[N]; assumes more space than stated (in 
average 2010 elements more. See: 
http://dpaste.dzfl.pl/af92ad22c). It behaves exactly like 
reserve and that is IMO wrong. If I reserve memory with 
buffer.reserve(N), I want to have at least N elements. That 
behaviour is correct. But if I use new T[N] I mostly want 
exactly N elements and no extra space.


Thoughts?


In Python if you append items to an array, it sovra-allocates, 
but if you create an array with the [x] * n syntax, then it 
creates a list (array) exactly of size n.


Bye,
bearophile


Re: Error when trying to compile with --profile.

2013-10-31 Thread bearophile

Wolftein:

Using --debug or --release works fine. But when i use --profile 
i get:


c:\Program Files 
(x86)\DLang\dmd2\windows\bin\..\..\src\phobos\std\path.d(2187):

 Error: balancedParens is not nothrow
c:\Program Files 
(x86)\DLang\dmd2\windows\bin\..\..\src\phobos\std\path.d(2188):

 Error: balancedParens is not nothrow
Error: this.__invariant is not nothrow
Error: this.__invariant is not nothrow


Is this bug in Bugzilla? DMD 2.064 should not come out with this
problem.

Do you have a small test case?

Bye,
bearophile


Re: new Type[count] takes too much?

2013-10-31 Thread Namespace

On Thursday, 31 October 2013 at 09:27:11 UTC, bearophile wrote:

Namespace:

T[] buffer = new T[N]; assumes more space than stated (in 
average 2010 elements more. See: 
http://dpaste.dzfl.pl/af92ad22c). It behaves exactly like 
reserve and that is IMO wrong. If I reserve memory with 
buffer.reserve(N), I want to have at least N elements. That 
behaviour is correct. But if I use new T[N] I mostly want 
exactly N elements and no extra space.


Thoughts?


In Python if you append items to an array, it sovra-allocates,

Never heard of 'sovra'. What does it mean?

but if you create an array with the [x] * n syntax, then it 
creates a list (array) exactly of size n.


Bye,
bearophile


So you agree with me.



improving '$' to work with other functions (eg: indexed)

2013-10-31 Thread Timothee Cour
can we support this and similar use cases ?

import std.range;
void main(){
  auto a=[1,2,3,4];
  auto b1=a.indexed([0,a.length-1]);//OK
  auto b2=a.indexed([0,$-1]);//NG
}


howto make a function get a types form compilte-time-parameters AND from the arguments ?

2013-10-31 Thread Uplink_Coder
(this is my first post so please alert me to any breaches of 
forum etiquette)


Hello,
I have a problem with a helper function I'm writeting.

T[] makeArray(T,U)(immutable U[] paramArray) {
T[] result;
foreach (param;paramArray) {
result ~= T(param);
}
return result;
}

and I would like not to take the compile-time-parameter U but 
insead infering it form the argumet.


is it possible ?
and if. how ?



Uplink_Coder


Re: new Type[count] takes too much?

2013-10-31 Thread safety0ff

On Thursday, 31 October 2013 at 09:15:53 UTC, Namespace wrote:
I'm sure we had already this conversation but I don't find the 
thread.


T[] buffer = new T[N]; assumes more space than stated (in 
average 2010 elements more. See: 
http://dpaste.dzfl.pl/af92ad22c). It behaves exactly like 
reserve and that is IMO wrong. If I reserve memory with 
buffer.reserve(N), I want to have at least N elements. That 
behaviour is correct. But if I use new T[N] I mostly want 
exactly N elements and no extra space.


Thoughts?


To me it looks like it is derived directly from the way the GC 
allocates chunks:
Next power of two if less than 4096 otherwise some multiple of 
4096.


Unless you modify the GC, this behaviour is present whether you 
can see it or not (http://dpaste.dzfl.pl/5481ffc2 .)


Re: improving '$' to work with other functions (eg: indexed)

2013-10-31 Thread Jonathan M Davis
On Thursday, October 31, 2013 02:46:32 Timothee Cour wrote:
 can we support this and similar use cases ?
 
 import std.range;
 void main(){
   auto a=[1,2,3,4];
   auto b1=a.indexed([0,a.length-1]);//OK
   auto b2=a.indexed([0,$-1]);//NG
 }

Aren't you creating new arrays to pass to indexed here? If that's the case, $ 
isn't associated with any particular array, and I don't see how it could work.

Now, there's issue# 7177

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

which aims at getting opDollar to work with ranges which have length (which it 
generally doesn't at this point), so that might be related to what you're 
looking for, but if what you're looking for is [0, $-1] to work on its own, I 
don't see how that could ever work, because $ only works when slicing or 
indexing, and [0, $-1] in the context above is an array literal.

- Jonathan M Davis


Re: new Type[count] takes too much?

2013-10-31 Thread Jonathan M Davis
On Thursday, October 31, 2013 10:15:51 Namespace wrote:
 I'm sure we had already this conversation but I don't find the
 thread.
 
 T[] buffer = new T[N]; assumes more space than stated (in average
 2010 elements more. See: http://dpaste.dzfl.pl/af92ad22c). It
 behaves exactly like reserve and that is IMO wrong. If I reserve
 memory with buffer.reserve(N), I want to have at least N
 elements. That behaviour is correct. But if I use new T[N] I
 mostly want exactly N elements and no extra space.
 
 Thoughts?

You're making the assumption that it would be normal to not want to then 
append to something you allocated with new T[N], and I don't think that that's 
a valid assumption. Also, from what I understand of how allocators work, they 
normally grab memory in sizes which are a multiple of 2, so I would expect it 
to be highly abnormal to ever get exactly the amount of memory that you 
requested. You're pretty much always going to get extra.

- Jonathan M Davis


Re: new Type[count] takes too much?

2013-10-31 Thread Namespace

On Thursday, 31 October 2013 at 09:48:23 UTC, safety0ff wrote:

On Thursday, 31 October 2013 at 09:15:53 UTC, Namespace wrote:
I'm sure we had already this conversation but I don't find the 
thread.


T[] buffer = new T[N]; assumes more space than stated (in 
average 2010 elements more. See: 
http://dpaste.dzfl.pl/af92ad22c). It behaves exactly like 
reserve and that is IMO wrong. If I reserve memory with 
buffer.reserve(N), I want to have at least N elements. That 
behaviour is correct. But if I use new T[N] I mostly want 
exactly N elements and no extra space.


Thoughts?


To me it looks like it is derived directly from the way the GC 
allocates chunks:
Next power of two if less than 4096 otherwise some multiple of 
4096.


Unless you modify the GC, this behaviour is present whether you 
can see it or not (http://dpaste.dzfl.pl/5481ffc2 .)


Maybe (and hopefully) I'm wrong, but it seems that the static 
array is on the heap?


Re: Error when trying to compile with --profile.

2013-10-31 Thread Dmitry Olshansky

31-Oct-2013 13:28, bearophile пишет:

Wolftein:


Using --debug or --release works fine. But when i use --profile i get:

c:\Program Files
(x86)\DLang\dmd2\windows\bin\..\..\src\phobos\std\path.d(2187):
 Error: balancedParens is not nothrow
c:\Program Files
(x86)\DLang\dmd2\windows\bin\..\..\src\phobos\std\path.d(2188):
 Error: balancedParens is not nothrow
Error: this.__invariant is not nothrow
Error: this.__invariant is not nothrow


Is this bug in Bugzilla? DMD 2.064 should not come out with this
problem.



It would unless the above is a regression. The release can't be stalled 
forever.



Do you have a small test case?

Bye,
bearophile



--
Dmitry Olshansky


Re: new Type[count] takes too much?

2013-10-31 Thread Jonathan M Davis
On Thursday, October 31, 2013 10:59:48 Namespace wrote:
 On Thursday, 31 October 2013 at 09:48:23 UTC, safety0ff wrote:
  On Thursday, 31 October 2013 at 09:15:53 UTC, Namespace wrote:
  I'm sure we had already this conversation but I don't find the
  thread.
  
  T[] buffer = new T[N]; assumes more space than stated (in
  average 2010 elements more. See:
  http://dpaste.dzfl.pl/af92ad22c). It behaves exactly like
  reserve and that is IMO wrong. If I reserve memory with
  buffer.reserve(N), I want to have at least N elements. That
  behaviour is correct. But if I use new T[N] I mostly want
  exactly N elements and no extra space.
  
  Thoughts?
  
  To me it looks like it is derived directly from the way the GC
  allocates chunks:
  Next power of two if less than 4096 otherwise some multiple of
  4096.
  
  Unless you modify the GC, this behaviour is present whether you
  can see it or not (http://dpaste.dzfl.pl/5481ffc2 .)
 
 Maybe (and hopefully) I'm wrong, but it seems that the static
 array is on the heap?

T[] buffer = new T[N];

is a dynamic array. Now, in the code in your dpaste link, you have a static 
array which is in a struct which is on the heap, so that's different, but now 
you're dealing with the amount of memory that gets allocated on the heap for 
the struct, and as the GC is going to allocate in multiples of 2, more than 
the size of the struct is going to be allocated. It might be that some of the 
memory beyond the end of the struct might actually be used for another object 
rather than the struct using the memory block by itself (I'm not sure what the 
GC does in that regard), but it's definitely going to allocate in multiples of 
2, so if the GC has to go up another multiple of 2 to make the struct fit, 
it'll go up another multiple of 2.

- Jonathan M Davis


Re: new Type[count] takes too much?

2013-10-31 Thread Namespace
On Thursday, 31 October 2013 at 10:12:10 UTC, Jonathan M Davis 
wrote:

On Thursday, October 31, 2013 10:59:48 Namespace wrote:

On Thursday, 31 October 2013 at 09:48:23 UTC, safety0ff wrote:
 On Thursday, 31 October 2013 at 09:15:53 UTC, Namespace 
 wrote:
 I'm sure we had already this conversation but I don't find 
 the

 thread.
 
 T[] buffer = new T[N]; assumes more space than stated (in

 average 2010 elements more. See:
 http://dpaste.dzfl.pl/af92ad22c). It behaves exactly like
 reserve and that is IMO wrong. If I reserve memory with
 buffer.reserve(N), I want to have at least N elements. That
 behaviour is correct. But if I use new T[N] I mostly want
 exactly N elements and no extra space.
 
 Thoughts?
 
 To me it looks like it is derived directly from the way the 
 GC

 allocates chunks:
 Next power of two if less than 4096 otherwise some multiple 
 of

 4096.
 
 Unless you modify the GC, this behaviour is present whether 
 you

 can see it or not (http://dpaste.dzfl.pl/5481ffc2 .)

Maybe (and hopefully) I'm wrong, but it seems that the static
array is on the heap?


T[] buffer = new T[N];

is a dynamic array. Now, in the code in your dpaste link, you 
have a static
array which is in a struct which is on the heap, so that's 
different, but now
you're dealing with the amount of memory that gets allocated on 
the heap for
the struct, and as the GC is going to allocate in multiples of 
2, more than
the size of the struct is going to be allocated. It might be 
that some of the
memory beyond the end of the struct might actually be used for 
another object
rather than the struct using the memory block by itself (I'm 
not sure what the
GC does in that regard), but it's definitely going to allocate 
in multiples of
2, so if the GC has to go up another multiple of 2 to make the 
struct fit,

it'll go up another multiple of 2.

- Jonathan M Davis


Hm, seems not very performant for a *system* language. But fine, 
thanks for your explanation. :)


Re: howto make a function get types form compile-time-parameters AND from arguments ?

2013-10-31 Thread Uplink_Coder


Maybe I shuold be more specific :
for now It's:
T[] arr = makeArray!(T,U)([some,instances,of,U]);

but I would like it to be:

auto arr = makeArray!(T)([some,instances,of,U]);






Re: new Type[count] takes too much?

2013-10-31 Thread Jonathan M Davis
On Thursday, October 31, 2013 11:16:35 Namespace wrote:
 Hm, seems not very performant for a *system* language. But fine,
 thanks for your explanation. :)

I believe that C's malloc does the same thing.

- Jonathan M Davis


Re: howto make a function get types form compile-time-parameters AND from arguments ?

2013-10-31 Thread John Colvin

On Thursday, 31 October 2013 at 10:18:25 UTC, Uplink_Coder wrote:


Maybe I shuold be more specific :
for now It's:
T[] arr = makeArray!(T,U)([some,instances,of,U]);

but I would like it to be:

auto arr = makeArray!(T)([some,instances,of,U]);


void foo(T,U)(U arg){}

int a;
foo!(double)(a); //U is inferred as int


void bar(T,U)(U[] arg){}

long[] b;
foo!(double)(b); //U is in inferred as long


However, be aware that you can't pass mutable or const data as an 
immutable argument. Perhaps the signature that would work better 
for you would be


T[] makeArray(T,U)(const U[] paramArray)


Re: std.range.chunk without length

2013-10-31 Thread Stephan Schiffels

On Wednesday, 30 October 2013 at 20:43:54 UTC, qznc wrote:
On Wednesday, 30 October 2013 at 00:20:12 UTC, Stephan 
Schiffels wrote:

Hi,

I'd like a version of std.range.chunk that does not require 
the range to have the length property.


As an example, consider a file that you would like parse by 
lines and always lump together four lines, i.e.


import std.stdio;
void main() {
 auto range = File(test.txt, r).byLine();
 foreach(c; range.chunks(4)) { //doesn't compile
   writefln(%s %s, c[0], c[1]);
 }
}


Your wish was granted. Monarchdodra was sent back in time [0], 
so it is already fixed in HEAD. You could try the dmd beta [1].



[0] https://github.com/D-Programming-Language/phobos/pull/992
[1] 
http://forum.dlang.org/thread/526dd8c5.2040...@digitalmars.com


Ah, awesome! Should have updated my github clone then.
Thanks,
Stephan



Re: howto make a function get types form compile-time-parameters AND from arguments ?

2013-10-31 Thread Uplink_Coder

by changeing
T[] makeArray(T,U)(immutable U[] paramArray)
into
T[] makeArray(T,U)(const U paramArray) if (isAggregateType!(U) || 
is Array!(U))

everything works perfectly

Thanks very much

---
Uplink_Coder


UFCS and error messages

2013-10-31 Thread Andrea Fontana

Check this simple code:

import std.stdio;
import std.conv;

bool is_zero(T)(T i) { return to!int(i) == 0; }

void main() { 0.is_zero.writeln; }

This code print true of course.

If you replace to!int(i) == 0 with i == 0 compiler gives this 
error:


Error: no property 'is_zero' for type 'string'

But:

is_zero(0)

instead gives this:

Error: incompatible types for ((i) == (0)): 'string' and 'int'

Shoudn't 0.is_zero give this error too?


Re: UFCS and error messages

2013-10-31 Thread bearophile

Andrea Fontana:


Shoudn't 0.is_zero give this error too?


Possibly yes. I put this enhancement request in Bugzilla few 
months ago, but I don't remember its number now.


Bye,
bearophile


Re: UFCS and error messages

2013-10-31 Thread Marco Leise
Am Thu, 31 Oct 2013 11:58:18 +0100
schrieb Andrea Fontana nos...@example.com:

 Check this simple code:
 
 import std.stdio;
 import std.conv;
 
 bool is_zero(T)(T i) { return to!int(i) == 0; }
 
 void main() { 0.is_zero.writeln; }
 
 This code print true of course.
 
 If you replace to!int(i) == 0 with i == 0 compiler gives this 
 error:
 
 Error: no property 'is_zero' for type 'string'
 
 But:
 
 is_zero(0)
 
 instead gives this:
 
 Error: incompatible types for ((i) == (0)): 'string' and 'int'
 
 Shoudn't 0.is_zero give this error too?

If you see it as a universal function call, yes.
But if you see it as an augmented property of string, then no.

-- 
Marco



Re: Cast delegate and functions.

2013-10-31 Thread Wolftein

On Thursday, 31 October 2013 at 13:12:31 UTC, Wolftein wrote:

void delegate(Event)
void delegate(T) Where T is a class that inherits Event.

I'm trying to cast (void delegate(T)) to (void delegate(Event)) 
to be able to store them in a map, but when i cast them i get 
null exeception.


Same thing for cast things like this

TemplateClass!Plugin
TemplateClass!OtherTypeOfPlugin - Being OtherTypeOfPlugin 
inherit Plugin


Using C++ this is allowed.


Well with the last verion delegate and function cast works fine, 
but not for TemplateClass.


Cast delegate and functions.

2013-10-31 Thread Wolftein

void delegate(Event)
void delegate(T) Where T is a class that inherits Event.

I'm trying to cast (void delegate(T)) to (void delegate(Event)) 
to be able to store them in a map, but when i cast them i get 
null exeception.


Same thing for cast things like this

TemplateClass!Plugin
TemplateClass!OtherTypeOfPlugin - Being OtherTypeOfPlugin 
inherit Plugin


Using C++ this is allowed.


Re: Cast delegate and functions.

2013-10-31 Thread qznc

On Thursday, 31 October 2013 at 13:12:31 UTC, Wolftein wrote:

void delegate(Event)
void delegate(T) Where T is a class that inherits Event.

I'm trying to cast (void delegate(T)) to (void delegate(Event)) 
to be able to store them in a map, but when i cast them i get 
null exeception.


Same thing for cast things like this

TemplateClass!Plugin
TemplateClass!OtherTypeOfPlugin - Being OtherTypeOfPlugin 
inherit Plugin


Using C++ this is allowed.


It is not safe to allow this.

  auto f = delegate(T x) { x.methodOfT(); }
  auto g = cast(void delegate(Event)) f;
  g(new Event());

This would call methodOfT on an Event object, which does not have 
that method.


Co- and Contravariance for such stuff is tricky. Here is a 
discussion on how C# 4.0 approaches it:


http://stackoverflow.com/questions/245607/how-is-generic-covariance-contra-variance-implemented-in-c-sharp-4-0


Re: D / GtkD for SQL Server

2013-10-31 Thread ilya-stromberg

On Sunday, 27 October 2013 at 00:06:35 UTC, John Joyus wrote:

On 10/25/2013 04:04 AM, Gary Willoughby wrote:


1). Does D has any support for MSSQL?


See here:
http://forum.dlang.org/thread/qcxoafwuachwnnwqk...@forum.dlang.org


Thanks for the link, but what I meant by MSSQL is Microsoft SQL 
Server. Not MySQL.


John, It's interesting if you can connect to the MS SQL.


fieldPostBlit - what is wrong with this and workarounds

2013-10-31 Thread Daniel Davidson

Given this code:

  import plus.tvm.rate_curve;
  struct T {
RateCurve m;
  }
  struct S {
const(T) rc;
  }

I get this error: Error: mutable method 
plus.models.dossier.__unittestL42_1.T.__fieldPostBlit is not 
callable using a const object


Is this fundamentally incorrect? I abandoned immutable in hopes 
that const would be more manageable and so far it has. But these 
types of issues still crop up and stop me in my tracks.


What are the requirements on RateCurve and T for this to work?

Thanks
Dan


Re: fieldPostBlit - what is wrong with this and workarounds

2013-10-31 Thread bearophile

Daniel Davidson:

I get this error: Error: mutable method 
plus.models.dossier.__unittestL42_1.T.__fieldPostBlit is not 
callable using a const object


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

Bye,
bearophile


structs holding on to reference data by pointer

2013-10-31 Thread Daniel Davidson
The following seems to work, but feels like luck. When foo 
returns rc should be taken off the stack. If I recall, in C++ 
something like this would crash, but why not here?


import std.stdio;
struct RC {
  this(this) { data = data.dup; }
  int[] data;
}
struct T {
  const(RC) *rc;
  void goo() {
writeln(Data is , rc.data);
  }
}

T foo() {
  RC rc = { [1,2,3] };
  return T(rc);
}

void main() {
  T t = foo();
  t.goo();
}

I'm trying to get around issues with

struct T {
   const(S) s;
}

by avoiding the postblit and having const(S) *s. I just want to 
know that it is always safe and if it is how?


Thanks
Dan




Re: fieldPostBlit - what is wrong with this and workarounds

2013-10-31 Thread Daniel Davidson

On Thursday, 31 October 2013 at 14:28:31 UTC, bearophile wrote:

Daniel Davidson:

I get this error: Error: mutable method 
plus.models.dossier.__unittestL42_1.T.__fieldPostBlit is not 
callable using a const object


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

Bye,
bearophile


Thanks but I don't see the relation.


Re: fieldPostBlit - what is wrong with this and workarounds

2013-10-31 Thread Maxim Fomin
On Thursday, 31 October 2013 at 14:03:28 UTC, Daniel Davidson 
wrote:

Given this code:

  import plus.tvm.rate_curve;
  struct T {
RateCurve m;
  }
  struct S {
const(T) rc;
  }

I get this error: Error: mutable method 
plus.models.dossier.__unittestL42_1.T.__fieldPostBlit is not 
callable using a const object


Is this fundamentally incorrect? I abandoned immutable in hopes 
that const would be more manageable and so far it has. But 
these types of issues still crop up and stop me in my tracks.


What are the requirements on RateCurve and T for this to work?

Thanks
Dan


D language is fundamentally incorrect here. There are sufficient 
issues in bugzilla (one which bearophile provided is actually 
relevant, it shows same problem from a little bit different 
aspect) and the problem tends to pop up quire regularly. It looks 
like nothing is done because it is design issue and although 
there were attempts to come up with, no idea is viewed as final 
solution. The easiest way to solve problem is to strip const.


Re: structs holding on to reference data by pointer

2013-10-31 Thread bearophile

Daniel Davidson:


import std.stdio;
struct RC {
  this(this) { data = data.dup; }
  int[] data;
}
struct T {
  const(RC) *rc;
  void goo() {
writeln(Data is , rc.data);
  }
}

T foo() {
  RC rc = { [1,2,3] };
  return T(rc);
}

void main() {
  T t = foo();
  t.goo();
}


That's wrong code, you are escaping a reference to memory (of rc 
variable) allocated in the stack frame of foo(). The D compiler 
is not smart enough to recognize the bug. There are optimizations 
that patch and avoid this bug (like inlining, or allocating rc 
inside the stack frame of the main) but you can't rely on them.


Bye,
bearophile


Re: fieldPostBlit - what is wrong with this and workarounds

2013-10-31 Thread Daniel Davidson

On Thursday, 31 October 2013 at 15:56:45 UTC, Maxim Fomin wrote:
On Thursday, 31 October 2013 at 14:03:28 UTC, Daniel Davidson 
wrote:

Given this code:

 import plus.tvm.rate_curve;
 struct T {
   RateCurve m;
 }
 struct S {
   const(T) rc;
 }

I get this error: Error: mutable method 
plus.models.dossier.__unittestL42_1.T.__fieldPostBlit is not 
callable using a const object


Is this fundamentally incorrect? I abandoned immutable in 
hopes that const would be more manageable and so far it has. 
But these types of issues still crop up and stop me in my 
tracks.


What are the requirements on RateCurve and T for this to work?

Thanks
Dan


D language is fundamentally incorrect here. There are 
sufficient issues in bugzilla (one which bearophile provided is 
actually relevant, it shows same problem from a little bit 
different aspect) and the problem tends to pop up quire 
regularly. It looks like nothing is done because it is design 
issue and although there were attempts to come up with, no idea 
is viewed as final solution. The easiest way to solve problem 
is to strip const.


I'm think you may be correct... but what specifically is 
incorrect about the language?
When I see __fieldPostBlit I get the feeling it is more an 
implementation issue than the language.


If as you suggest, D language is fundamentally broken - is it 
possible we can just get a plan for fixing it? To me this seems 
like a huge design hole and I come back to the threads with 
questions again and again and I really don't know how others 
manage the use of const/immutable.


I've already given up on immutable. If I have to strip const as 
well then that is a huge pain and unfortunate since the concept 
seems sound and well argued in TDPL. Trying to mess with 
mutable/const/immutable on mostly working code is like playing 
whack a mole.




Re: structs holding on to reference data by pointer

2013-10-31 Thread Daniel Davidson

On Thursday, 31 October 2013 at 16:16:36 UTC, bearophile wrote:


That's wrong code, you are escaping a reference to memory (of 
rc variable) allocated in the stack frame of foo(). The D 
compiler is not smart enough to recognize the bug. There are 
optimizations that patch and avoid this bug (like inlining, or 
allocating rc inside the stack frame of the main) but you can't 
rely on them.




Ahh ok. Because of issues with const members (copying them when 
they are composed in other classes does not work well) I'm trying 
to get around the copy by storing reference data as const(T) *. 
This is why I'm asking. So here are some follow ups:


- As I see it there is grave risk. Is the risk introduced by the 
fact that I am storing a member as const(T)*?
- I assume that if I had created the RC instance on the heap 
there would be no problems. Is there a way in general to ensure 
that a const(T)* is referring to something on the heap as opposed 
to the stack (ideally at compile time).
- What is the root problem - having a const(T)* member which then 
requires code to take address, or taking address? My first 
thought was, just never take address of local static variable - 
which is generally good advice. But once you are in a function 
that takes ref const(T) you can take the address of that as well 
- see modification below. This suffers the same problem but in a 
less obvious way.


Any suggestions welcome.

Thanks
Dan

import opmix.mix;
import plus.tvm.rate_curve;
import std.stdio;

struct RC {
  this(this) { data = data.dup; }
  int[] data;
}

struct T {
  const(RC) *rc;
  void goo() {
writeln(Data is , rc.data);
  }
}

T goo(ref RC rc) {
  return T(rc);
}

T foo() {
  RC rc = { [1,2,3] };
  writeln(Address is , rc);
  return goo(rc);
}

void main() {
  T t = foo();
  t.goo();
  writeln(Address is , t.rc);
}


Re: structs holding on to reference data by pointer

2013-10-31 Thread Maxim Fomin
On Thursday, 31 October 2013 at 17:34:21 UTC, Daniel Davidson 
wrote:

On Thursday, 31 October 2013 at 16:16:36 UTC, bearophile wrote:


That's wrong code, you are escaping a reference to memory (of 
rc variable) allocated in the stack frame of foo(). The D 
compiler is not smart enough to recognize the bug. There are 
optimizations that patch and avoid this bug (like inlining, or 
allocating rc inside the stack frame of the main) but you 
can't rely on them.




Ahh ok. Because of issues with const members (copying them when 
they are composed in other classes does not work well) I'm 
trying to get around the copy by storing reference data as 
const(T) *. This is why I'm asking. So here are some follow ups:


- As I see it there is grave risk. Is the risk introduced by 
the fact that I am storing a member as const(T)*?


Risk is that pointer to local variable is escaped, not because it 
is stored in const qualified pbject.


- I assume that if I had created the RC instance on the heap 
there would be no problems. Is there a way in general to ensure 
that a const(T)* is referring to something on the heap as 
opposed to the stack (ideally at compile time).


Yes, you can explicitly allocate on heap. You can check whether 
data is on heap, stack, tls, or just global object by inspecting 
pointer at runtime. Ideally there would be such function in 
druntime. It is impossible to do this in CT (except if comiler 
support flow analysis and can prove in some scenarious that data 
is on stack or not, but due to separate compilation it is 
impossible to do in general case) (and probably shouldn't).


- What is the root problem - having a const(T)* member which 
then requires code to take address, or taking address? My first 
thought was, just never take address of local static variable - 
which is generally good advice. But once you are in a function 
that takes ref const(T) you can take the address of that as 
well - see modification below. This suffers the same problem 
but in a less obvious way.


Any suggestions welcome.

Thanks
Dan

import opmix.mix;
import plus.tvm.rate_curve;
import std.stdio;

struct RC {
  this(this) { data = data.dup; }
  int[] data;
}

struct T {
  const(RC) *rc;
  void goo() {
writeln(Data is , rc.data);
  }
}

T goo(ref RC rc) {
  return T(rc);
}

T foo() {
  RC rc = { [1,2,3] };
  writeln(Address is , rc);
  return goo(rc);
}

void main() {
  T t = foo();
  t.goo();
  writeln(Address is , t.rc);
}


Yes, this is known issue. There are lots of other tricks to break 
the language.


Re: fieldPostBlit - what is wrong with this and workarounds

2013-10-31 Thread Maxim Fomin
On Thursday, 31 October 2013 at 17:22:07 UTC, Daniel Davidson 
wrote:


I'm think you may be correct... but what specifically is 
incorrect about the language?
When I see __fieldPostBlit I get the feeling it is more an 
implementation issue than the language.


__postblit also looks like implementation detail but it is same 
problem. Field postblit means that aggregate has some members 
which have postblits so they should be called. This is same 
problem which blows in higher level.


If as you suggest, D language is fundamentally broken - is it 
possible we can just get a plan for fixing it? To me this seems 
like a huge design hole and I come back to the threads with 
questions again and again and I really don't know how others 
manage the use of const/immutable.


This is probable tenth thread about const postblits which I do 
remember for all my (only) 2 years in D. D2 (version currently in 
use) dates back to 2004 AFAIK and Andrei (helping to design the 
language) is in D since 2006, also AFAIK. Draw your own 
conclusions.


I've already given up on immutable. If I have to strip const as 
well then that is a huge pain and unfortunate since the concept 
seems sound and well argued in TDPL. Trying to mess with 
mutable/const/immutable on mostly working code is like playing 
whack a mole.


One can do: 1) revise the design to challange whether consts are 
really necessary 2a) use workarounds like const pointer 2b) use 
cast to break const or another tricks (explicit casts are better 
because holes in type system may be fixed in some point in the 
feature)


Re: structs holding on to reference data by pointer

2013-10-31 Thread bearophile

Maxim Fomin:

You can check whether data is on heap, stack, tls, or just 
global object by inspecting pointer at runtime. Ideally there 
would be such function in druntime.


This seems like a nice enhancement request for Bugzilla :-) Are 
you going to open it? It seems useful for me too.



It is impossible to do this in CT (except if comiler support 
flow analysis and can prove in some scenarious that data is on 
stack or not, but due to separate compilation it is impossible 
to do in general case) (and probably shouldn't).


You can do it even with separate compilation (at compile time) if 
your language has different kinds of pointers as Rust. Perhaps in 
D this can be done using Phobos-defined smart pointers.


Bye,
bearophile


Intelligent Scope Hierarchy

2013-10-31 Thread Stretto

Hi, I'm new to D and stumbled on the new allocators thread. In
the help there is code like

 auto buffer = Mallocator.it.allocate(1024 * 1024 * 4);
 scope(exit) Mallocator.it.deallocate(buffer);

which seems redundant and error prone.

Would it not be possible for allocate to automatically add itself
to the parent scope by default?

This way code like

 auto buffer = Mallocator.it.allocate(1024 * 1024 * 4);

would automatically expand to

 auto buffer = Mallocator.it.allocate(1024 * 1024 * 4);
 scope(exit) Mallocator.it.deallocate(buffer);

If, say, we needed to raise the scope(exit) of allocate to act
on the parent of the parent scope then we could do something like

 auto MyAllocate(size)
 {
 return scope(raise) { Mallocator.it.allocate(size); };
 auto scope(parent) { print(Happy times); };
 }

 auto buffer = MyAllocate(1024 * 1024 * 4);

So that allocate inside MyAllocate won't release the buffer on
the return of MyAllocate on use scope.

with scope hierarchy the above would translate into

 auto buffer = MyAllocate(1024 * 1024 * 4);
 Mallocator.it.deallocate(buffer);
 print(Happy times);

This will allow wrapping automatic scope exits to behave properly.

Of course with such a feature one would also need to prevent
automatic scope assignment:

 auto buffer = scope(none) MyAllocate(1024 * 1024 * 4);

would prevent any auto scope from My Allocate and subcalls from
being called.


This is just a rough suggestion that hopefully will lead to more
potent scope control and less error prone allocators. I believe
it should be somewhat easily implemented by having some type of
vtable like control for each function that is called after each
function to deal with the scope chaining.






[challenge] Lazy flatten/avoiding type forward reference with map

2013-10-31 Thread David Nadlinger
A while back, somebody raised the topic of implementing a lazy 
range for traversing/flattening a tree structure on #d.


The obvious (in terms of Phobos primitives) solution would be 
something along the lines of this:

---
struct Node(T) {
   T val;
   Node!T[] children;
}

auto flatten(T)(Node!T root) {
   import std.algorithm, std.range;
   return only(root.val).chain(map!flatten(root.children).joiner);
}

void main() {
   alias N = Node!int;
   auto a = N(1, [
  N(2, [
 N(3, [
N(4)
 ])
  ]),
  N(5)
   ]);

   import std.stdio;
   writeln(a.flatten); // [1, 2, 3, 4, 5]
}
---

But of course, that piece of code does not compile with current 
DMD, as the return type of flatten() can't refer to the function 
itself (during name mangling).


Now, one way around this would be to add an array() call at the 
end of the return statement, which hides the type of map!flatten, 
but at the cost of many unnecessary memory allocations. A second 
option would be to use inputRangeObject to convert the return 
value to ForwardRange!T (well, that is if it actually worked, due 
to an implementation bug it leads to a runtime crash).


But can you think of a more simple/elegant workaround?

(Note aside: Obviously, the fact that the code relies on 
recursion might be an issue, and a simple opApply-based solution 
with a worklist stack would likely perform better. Still, I think 
it's a simple, yet interesting problem.)


David


Re: structs holding on to reference data by pointer

2013-10-31 Thread Maxim Fomin

On Thursday, 31 October 2013 at 18:51:46 UTC, bearophile wrote:

Maxim Fomin:

You can check whether data is on heap, stack, tls, or just 
global object by inspecting pointer at runtime. Ideally there 
would be such function in druntime.


This seems like a nice enhancement request for Bugzilla :-) Are 
you going to open it? It seems useful for me too.




You are expert in making enhacement request :)

It is impossible to do this in CT (except if comiler support 
flow analysis and can prove in some scenarious that data is on 
stack or not, but due to separate compilation it is impossible 
to do in general case) (and probably shouldn't).


You can do it even with separate compilation (at compile time) 
if your language has different kinds of pointers as Rust. 
Perhaps in D this can be done using Phobos-defined smart 
pointers.


Bye,
bearophile


But I don't believe that D being system laguage will diverge from 
traidtional C/C++ pointer model. Right, in runtime smart pointers 
can probably do some job by guessing allocation kind looking at 
pointer.


Using reduce() with tuples created by zip()

2013-10-31 Thread Craig Dillabaugh

I am trying to calculate the Euclidean Distance between two
points. I currently have the following function (that doesn't
compile):

double euclid_dist( double[] pt1, double[] pt2 ) {
   assert( pt1.length == pt2.length );

   return sqrt(
 zip(pt1, pt2).reduce!(function(e) { return
(e[1]-e[0])*(e[1]-e[0]); })(0.0)
   );
}

Hopefully it is clear what I am trying to do.  I want zip to
create a range that is a tuple of the point's coordinate pairs,
and then use reduce to sum the squared differences.  I get the
following error but can't figure out how to fix my syntax:

euclid.d(13): Error: template
euclid.euclid_dist.reduce!(__funcliteral2).reduce does not match
any function template declaration. Candidates are:
/usr/include/dmd/phobos/std/algorithm.d(688):
euclid.euclid_dist.reduce!(__funcliteral2).reduce(Args...)(Args
args) if (Args.length  0  Args.length = 2 
isIterable!(Args[__dollar - 1]))
euclid.d(13): Error: template
euclid.euclid_dist.reduce!(__funcliteral2).reduce(Args...)(Args
args) if (Args.length  0  Args.length = 2 
isIterable!(Args[__dollar - 1])) cannot deduce template function
from argument types !()(Zip!(double[], double[]), double)
Failed: 'dmd' '-v' '-o-' 'euclid.d' '-I.'


I know I could use a simple foreach loop with my zip command, or
even std.numeric.euclidean( ... ), but I am trying to be cute
here!

Cheers,
Craig


Re: Using reduce() with tuples created by zip()

2013-10-31 Thread Philippe Sigaud
I think reduce takes two arguments: the growing seed and the current front.
You're trying to get (a[0]-b[0])^^2 + (a[1]-b[1])^^2 + ..., right?

Try this:

module euclid;


import std.stdio;

double euclid_dist( double[] pt1, double[] pt2 ) {
assert( pt1.length == pt2.length );
import std.algorithm;
import std.math;
import std.range;

return sqrt(0.0.reduce!( (sum,pair) = sum + (pair[0]-pair[1])^^2
)(zip(pt1, pt2)));
}

void main()
{
double[] arr1 = [0.0, 1.0, 0.1];
double[] arr2 = [1.0, -1.0, 0.0];
writeln(euclid_dist(arr1,arr2));
}



On Thu, Oct 31, 2013 at 8:12 PM, Craig Dillabaugh 
cdill...@cg.scs.carleton.ca wrote:

 I am trying to calculate the Euclidean Distance between two
 points. I currently have the following function (that doesn't
 compile):

 double euclid_dist( double[] pt1, double[] pt2 ) {
assert( pt1.length == pt2.length );

return sqrt(
  zip(pt1, pt2).reduce!(function(e) { return
 (e[1]-e[0])*(e[1]-e[0]); })(0.0)
);
 }

 Hopefully it is clear what I am trying to do.  I want zip to
 create a range that is a tuple of the point's coordinate pairs,
 and then use reduce to sum the squared differences.  I get the
 following error but can't figure out how to fix my syntax:

 euclid.d(13): Error: template
 euclid.euclid_dist.reduce!(__**funcliteral2).reduce does not match
 any function template declaration. Candidates are:
 /usr/include/dmd/phobos/std/**algorithm.d(688):
 euclid.euclid_dist.reduce!(__**funcliteral2).reduce(Args...)(**Args
 args) if (Args.length  0  Args.length = 2 
 isIterable!(Args[__dollar - 1]))
 euclid.d(13): Error: template
 euclid.euclid_dist.reduce!(__**funcliteral2).reduce(Args...)(**Args
 args) if (Args.length  0  Args.length = 2 
 isIterable!(Args[__dollar - 1])) cannot deduce template function
 from argument types !()(Zip!(double[], double[]), double)
 Failed: 'dmd' '-v' '-o-' 'euclid.d' '-I.'


 I know I could use a simple foreach loop with my zip command, or
 even std.numeric.euclidean( ... ), but I am trying to be cute
 here!

 Cheers,
 Craig



Assertion failure: '0' on line 1215 in file 'glue.c'

2013-10-31 Thread Wolftein

Assertion failure: '0' on line 1215 in file 'glue.c'

When trying to compile this:

TypeTuple!(void delegate(Event), EventPriority, ulong)[uint] 
_ownerList;


Is that a compiler bug or i'm doing something that i don't 
suppose to do.


Re: fieldPostBlit - what is wrong with this and workarounds

2013-10-31 Thread Jonathan M Davis
On Thursday, October 31, 2013 15:03:26 Daniel Davidson wrote:
 Given this code:
 
 import plus.tvm.rate_curve;
 struct T {
 RateCurve m;
 }
 struct S {
 const(T) rc;
 }
 
 I get this error: Error: mutable method
 plus.models.dossier.__unittestL42_1.T.__fieldPostBlit is not
 callable using a const object
 
 Is this fundamentally incorrect? I abandoned immutable in hopes
 that const would be more manageable and so far it has. But these
 types of issues still crop up and stop me in my tracks.
 
 What are the requirements on RateCurve and T for this to work?

const and postblit fundamentally don't mix, because for it to work, you have 
to violate the type system. With postblits, the struct gets memcpied and then 
the postblit constructor has the chance to mutate the resulting object to make 
the pieces different that need to be different. However, to do that mutation 
when the object is const would mean mutating a const object which violates the 
type system. What we really need is copy constructors, but they haven't been 
added yet. At one point, Andrei was saying that he and Walter had a solution, 
but he didn't elaborate on it. I assume that it involved introducing copy 
constructors, but I don't know, and this issue has not yet been resolved.

Now, in your particular code example, you don't define postblit constructor, 
but my guess would be that RateCurve defines one, making it so that a postblit 
constructor is generated for T which uses the one for RateCurve, and the S 
gets one which uses T's. And because const doesn't work with postblit 
constructors, S becomes uncopyable, and if there's any code that requires that 
a copy be made, then it'll fail to compile (I'm not sure whether the fact that 
it's uncopyable will result in an error if no attempts to copy it are made, 
but you'll definitely get an error if an attempt to copy is made).

Hopefully, this problem will be resolved, but regardless of that, I would 
advise against ever having a const member variable in a struct. Even if you 
don't have any postblit issues, such a struct can never be assigned to, and it 
becomes essentially unusuable in any situation where you would have to assign 
a value to it (e.g. if it were in an array). You can certainly make a struct's 
member variable const if you want to, but you're going to run into stuff that 
won't work as a result. It's far better to just provide a property for it 
which is const (probably returning the member by const ref if you want to 
avoid copying it when using the property) rather than making the member 
variable itself const.

- Jonathan M Davis


Re: Assertion failure: '0' on line 1215 in file 'glue.c'

2013-10-31 Thread bearophile

Wolftein:


Assertion failure: '0' on line 1215 in file 'glue.c'

When trying to compile this:

TypeTuple!(void delegate(Event), EventPriority, ulong)[uint] 
_ownerList;


Is that a compiler bug or i'm doing something that i don't 
suppose to do.


It seems both a compiler bug fit for bugzilla, and a bug in your 
code (TypeTuples are not meant for delegates, I think).


Create a minimal example for Bugzilla...

Bye,
bearophile


Re: Assertion failure: '0' on line 1215 in file 'glue.c'

2013-10-31 Thread Jonathan M Davis
On Thursday, October 31, 2013 20:30:25 Wolftein wrote:
 Assertion failure: '0' on line 1215 in file 'glue.c'
 
 When trying to compile this:
 
 TypeTuple!(void delegate(Event), EventPriority, ulong)[uint]
 _ownerList;
 
 Is that a compiler bug or i'm doing something that i don't
 suppose to do.

Any and all assertions in the compiler which are triggered when compileng are 
a bug in the compiler. So, yes, this is a compiler bug - regardless of whether 
your code is valid or not (though I don't see anything obviously wrong with 
it).

- Jonathan M Davis


Re: Assertion failure: '0' on line 1215 in file 'glue.c'

2013-10-31 Thread Wolftein

On Thursday, 31 October 2013 at 19:39:37 UTC, bearophile wrote:

Wolftein:


Assertion failure: '0' on line 1215 in file 'glue.c'

When trying to compile this:

TypeTuple!(void delegate(Event), EventPriority, ulong)[uint] 
_ownerList;


Is that a compiler bug or i'm doing something that i don't 
suppose to do.


It seems both a compiler bug fit for bugzilla, and a bug in 
your code (TypeTuples are not meant for delegates, I think).


Create a minimal example for Bugzilla...

Bye,
bearophile


TypeTuple!(uint, uint)[uint] - won't work neither

There seems to be a problem with TypeTuple and associative arrays 
in general.


Re: Using reduce() with tuples created by zip()

2013-10-31 Thread bearophile

Craig Dillabaugh:


I know I could use a simple foreach loop with my zip command, or
even std.numeric.euclidean( ... ), but I am trying to be cute
here!



import std.stdio, std.algorithm, std.range, std.math, 
std.functional;


alias sum(T) = curry!(reduce!q{a + b}, cast(T)0);

double euclidDistance(double[] xs, double[] ys)
in {
assert(xs.length == ys.length);
} body {
return zip(xs, ys)
   .map!(xy = (xy[0] - xy[1]) ^^ 2)
   .sum!double
   .sqrt;
}

void main() {
auto xs = [0.0,  1.0, 0.1];
auto ys = [1.0, -1.0, 0.0];
euclidDistance(xs, ys).writeln;
}


Bye,
bearophile


Re: Using reduce() with tuples created by zip()

2013-10-31 Thread Craig Dillabaugh

On Thursday, 31 October 2013 at 19:23:56 UTC, Philippe Sigaud
wrote:
I think reduce takes two arguments: the growing seed and the 
current front.
You're trying to get (a[0]-b[0])^^2 + (a[1]-b[1])^^2 + ..., 
right?

Yep. The (e[1]-e[0])*(e[1]-e[0]) bit was, I supposed was
effectively
calculating (a[0]-b[0])^^2 and so on.  I forgot about the ^^2 in
D.



Try this:

module euclid;


import std.stdio;

double euclid_dist( double[] pt1, double[] pt2 ) {
assert( pt1.length == pt2.length );
import std.algorithm;
import std.math;
import std.range;

return sqrt(0.0.reduce!( (sum,pair) = sum + 
(pair[0]-pair[1])^^2

)(zip(pt1, pt2)));
}

void main()
{
double[] arr1 = [0.0, 1.0, 0.1];
double[] arr2 = [1.0, -1.0, 0.0];
writeln(euclid_dist(arr1,arr2));
}



On Thu, Oct 31, 2013 at 8:12 PM, Craig Dillabaugh 
cdill...@cg.scs.carleton.ca wrote:


clip

Cheers,
Craig


Thanks, I will try both your, and Bearophile's ideas and see if I
can figure out how they work.
Craig


Re: Assertion failure: '0' on line 1215 in file 'glue.c'

2013-10-31 Thread Wolftein

On Thursday, 31 October 2013 at 19:48:19 UTC, Wolftein wrote:

On Thursday, 31 October 2013 at 19:39:37 UTC, bearophile wrote:

Wolftein:


Assertion failure: '0' on line 1215 in file 'glue.c'

When trying to compile this:

TypeTuple!(void delegate(Event), EventPriority, ulong)[uint] 
_ownerList;


Is that a compiler bug or i'm doing something that i don't 
suppose to do.


It seems both a compiler bug fit for bugzilla, and a bug in 
your code (TypeTuples are not meant for delegates, I think).


Create a minimal example for Bugzilla...

Bye,
bearophile


TypeTuple!(uint, uint)[uint] - won't work neither

There seems to be a problem with TypeTuple and associative 
arrays in general.


Reported :) http://d.puremagic.com/issues/show_bug.cgi?id=11404


Re: Using reduce() with tuples created by zip()

2013-10-31 Thread bearophile

alias sum(T) = curry!(reduce!q{a + b}, cast(T)0);

double euclidDistance(double[] xs, double[] ys)
in {
assert(xs.length == ys.length);
} body {
return zip(xs, ys)
   .map!(xy = (xy[0] - xy[1]) ^^ 2)
   .sum!double
   .sqrt;
}

void main() {
auto xs = [0.0,  1.0, 0.1];
auto ys = [1.0, -1.0, 0.0];
euclidDistance(xs, ys).writeln;
}


In D functions are written in camelCase like euclidDistance, 
instead of euclid_distance.


Function pre-conditions and post-conditions are generally better 
put in the pre and post part of functions.


I have defined a sum because it's a generally useful function, 
but it's a toy because it assumes cast(T)0 as the identity 
element of the monoid with the plus operator.


Bye,
bearophile


Re: new Type[count] takes too much?

2013-10-31 Thread Marco Leise
Am Thu, 31 Oct 2013 02:52:49 -0700
schrieb Jonathan M Davis jmdavisp...@gmx.com:

 On Thursday, October 31, 2013 10:15:51 Namespace wrote:
  I'm sure we had already this conversation but I don't find the
  thread.
  
  T[] buffer = new T[N]; assumes more space than stated (in average
  2010 elements more. See: http://dpaste.dzfl.pl/af92ad22c). It
  behaves exactly like reserve and that is IMO wrong. If I reserve
  memory with buffer.reserve(N), I want to have at least N
  elements. That behaviour is correct. But if I use new T[N] I
  mostly want exactly N elements and no extra space.
  
  Thoughts?

Maybe run a comparison with another popular GC enabled
language and check the memory use to find pathological cases.
I'd assume that D's GC doesn't waste more memory than any
other for dynamic arrays.

 You're making the assumption that it would be normal to not want to then 
 append to something you allocated with new T[N], and I don't think that 
 that's 
 a valid assumption.

That doesn't happen much in my programming practice. I'm with
the OP on this.

 Also, from what I understand of how allocators work, they 
 normally grab memory in sizes which are a multiple of 2, so I would expect it 
 to be highly abnormal to ever get exactly the amount of memory that you 
 requested. You're pretty much always going to get extra.
 
 - Jonathan M Davis

That's true. Although now I wonder if you could gain anything
from having memory pages split into chunks of T.sizeof from
which you can allocate single objects or whole arrays of T
with a compact layout...

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|T|T|T[6]   |T|T|   |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

-- 
Marco



Re: C/C++ struct interfacing

2013-10-31 Thread Rémy Mouëza

Below is a solution to get it to work as a C binding.

- Your structure should not be enclosed in the `extern (C)` 
block; leave it as regular D code.
- cppcall should be declared `extern (C)` in D and `extern C` 
in C++;
- depending on your platform, you need to link to the C++ 
standard lib ; on my Ubuntu 12.04, I added the `-L-lstdc++` on 
the dmd command line.



I already used that pattern in some binding for the RtMidi lib:
https://github.com/remy-j-a-moueza/drtmidi

dRtMidi.d defines a templated structure :

struct answer (T) {
int success;
T value;
const (char) * errMsg;
}

and so does cRtMidi.cpp :

template typename T
struct answer {
int success;
T value;
const char * errMsg;
};

I declared a bunch of `extern (C)` and `extern C` function that 
pass that data arround. It works only if the T data type as the 
same size in both languages.


You can check the size correspondance on this page : 
http://dlang.org/interfaceToC.html


And for more tricky types, you can get some inspiration from 
Jacob Carlborg dstep project, especially :
- translateType () in Type.d : 
https://github.com/jacob-carlborg/dstep/blob/master/dstep/translator/Type.d


- and the static constructor of the IncludeHandler class, to get 
to import the right D core module : 
https://github.com/jacob-carlborg/dstep/blob/master/dstep/translator/IncludeHandler.d





On Sunday, 27 October 2013 at 12:20:49 UTC, Oleg B wrote:

Hello.
I want use one struct in two language.
How to declare the same structure in different languages​​?

D code: calling C++ function with my struct
code
extern(C++)
{
struct vec(size_t N, T=float)
{ //  line 6
alias vec!(N,T) thistype;
T[N] data;

auto opBinary(string op)( in thistype rhs ) const
{
thistype ret;
foreach( i; 0 .. N ) ret.data[i] = data[i] + 
rhs.data[i];

return ret;
}
}

void cppcall( vec!(3,float) d );
}

void main()
{
vec!3 a, b;
a.data[0] = 10;
a.data[1] = 7;
a.data[2] = 3;

b.data[0] = 13;
b.data[1] = 9;
b.data[2] = 4;

cppcall( a + b );
}
/code

C++ code: use struct data
code
#include cstdio

struct vec
{
float data[3];
};

void cppcall( vec d )
{
printf( %f %f %f\n, d.data[0], d.data[1], d.data[2] );
}
/code

compilation failed with unclear error

$ g++ -c ctypestest.cpp -o ctypestest.o
$ dmd ctypestest.d ctypestest.o -ofctypestest
ctypestest.d(6): Error: struct ctypestest.vec!(3, float).vec 
C++ static variables not supported


Re: new Type[count] takes too much?

2013-10-31 Thread Marco Leise
Am Thu, 31 Oct 2013 10:42:35 +0100
schrieb Namespace rswhi...@googlemail.com:

 On Thursday, 31 October 2013 at 09:27:11 UTC, bearophile wrote:
  In Python if you append items to an array, it sovra-allocates,
 Never heard of 'sovra'. What does it mean?

That's bearophilian for 'over'. :p

-- 
Marco



Re: new Type[count] takes too much?

2013-10-31 Thread Ali Çehreli

On 10/31/2013 01:10 PM, Marco Leise wrote:

Am Thu, 31 Oct 2013 10:42:35 +0100
schrieb Namespace rswhi...@googlemail.com:


On Thursday, 31 October 2013 at 09:27:11 UTC, bearophile wrote:

In Python if you append items to an array, it sovra-allocates,

Never heard of 'sovra'. What does it mean?


That's bearophilian for 'over'. :p


Apparently, a variation of Italian prefix sopra- :)

  http://en.wiktionary.org/wiki/sopra-

Ali



Re: new Type[count] takes too much?

2013-10-31 Thread H. S. Teoh
On Thu, Oct 31, 2013 at 01:28:13PM -0700, Ali Çehreli wrote:
 On 10/31/2013 01:10 PM, Marco Leise wrote:
 Am Thu, 31 Oct 2013 10:42:35 +0100
 schrieb Namespace rswhi...@googlemail.com:
 
 On Thursday, 31 October 2013 at 09:27:11 UTC, bearophile wrote:
 In Python if you append items to an array, it sovra-allocates,
 Never heard of 'sovra'. What does it mean?
 
 That's bearophilian for 'over'. :p
 
 Apparently, a variation of Italian prefix sopra- :)
 
   http://en.wiktionary.org/wiki/sopra-
[...]

http://en.wiktionary.org/wiki/sovra

:)


T

-- 
Nearly all men can stand adversity, but if you want to test a man's character, 
give him power. -- Abraham Lincoln


Re: D / GtkD for SQL Server

2013-10-31 Thread Jacob Carlborg

On 2013-10-31 14:47, ilya-stromberg wrote:


John, It's interesting if you can connect to the MS SQL.


Just use FreeTDS, nothing special about it. See:

http://forum.dlang.org/thread/l403bf$139g$1...@digitalmars.com#post-l4089g:241723:241:40digitalmars.com

--
/Jacob Carlborg


Re: Assertion failure: '0' on line 1215 in file 'glue.c'

2013-10-31 Thread Jonathan M Davis
On Thursday, October 31, 2013 20:39:36 bearophile wrote:
 Wolftein:
  Assertion failure: '0' on line 1215 in file 'glue.c'
  
  When trying to compile this:
  
  TypeTuple!(void delegate(Event), EventPriority, ulong)[uint]
  _ownerList;
  
  Is that a compiler bug or i'm doing something that i don't
  suppose to do.
 
 It seems both a compiler bug fit for bugzilla, and a bug in your
 code (TypeTuples are not meant for delegates, I think).

Ah, yeah. TypeTuple won't work there (I missed that and thought that he was 
using a Tuple). TypeTuple is really only for metaprogramming, and it's a 
compile-time only entity, so it won't work in an AA. std.typecons.Tuple is 
what he'd have to use.

- Jonathan M Davis


Re: [challenge] Lazy flatten/avoiding type forward reference with map

2013-10-31 Thread Ali Çehreli

On 10/31/2013 12:09 PM, David Nadlinger wrote:

A while back, somebody raised the topic of implementing a lazy range for
traversing/flattening a tree structure on #d.

The obvious (in terms of Phobos primitives) solution would be something
along the lines of this:
---
struct Node(T) {
T val;
Node!T[] children;
}

auto flatten(T)(Node!T root) {
import std.algorithm, std.range;
return only(root.val).chain(map!flatten(root.children).joiner);
}

void main() {
alias N = Node!int;
auto a = N(1, [
   N(2, [
  N(3, [
 N(4)
  ])
   ]),
   N(5)
]);

import std.stdio;
writeln(a.flatten); // [1, 2, 3, 4, 5]
}
---

But of course, that piece of code does not compile with current DMD, as
the return type of flatten() can't refer to the function itself (during
name mangling).

Now, one way around this would be to add an array() call at the end of
the return statement, which hides the type of map!flatten, but at the
cost of many unnecessary memory allocations. A second option would be to
use inputRangeObject to convert the return value to ForwardRange!T
(well, that is if it actually worked, due to an implementation bug it
leads to a runtime crash).

But can you think of a more simple/elegant workaround?

(Note aside: Obviously, the fact that the code relies on recursion might
be an issue, and a simple opApply-based solution with a worklist stack
would likely perform better. Still, I think it's a simple, yet
interesting problem.)

David


Y Combinator? (No, I have not solved it yet. :) )

  http://rosettacode.org/wiki/Y_combinator#D

Ali



Re: [challenge] Lazy flatten/avoiding type forward reference with map

2013-10-31 Thread Ali Çehreli

On 10/31/2013 02:19 PM, Ali Çehreli wrote:

 Y Combinator? (No, I have not solved it yet. :) )


   http://rosettacode.org/wiki/Y_combinator#D


Ok, I was actually trying to find the following one:


https://github.com/gecko0307/atrium/blob/master/dlib/functional/combinators.d

Ali



Re: improving '$' to work with other functions (eg: indexed)

2013-10-31 Thread Timothee Cour
well it can be made to work with following rule:

$ binds as follows, using the 1st pattern matched rule:

very roughly:

identifier [$] if typeof(a.length) = a[a.length] //likewise with s/[]/()/
primary_expression . identifier if typeof(primary_expression.length)
= primary_expression . identifier [identifier.length] (recursively)
if no match is found, error.

eg:

[1,2,3].indexed([0,$-1] ) = indexed.length isn't valid, so it tries to
bind to [1,2,3].

intuitively I believe it makes sense.



On Thu, Oct 31, 2013 at 2:51 AM, Jonathan M Davis jmdavisp...@gmx.comwrote:

 On Thursday, October 31, 2013 02:46:32 Timothee Cour wrote:
  can we support this and similar use cases ?
 
  import std.range;
  void main(){
auto a=[1,2,3,4];
auto b1=a.indexed([0,a.length-1]);//OK
auto b2=a.indexed([0,$-1]);//NG
  }

 Aren't you creating new arrays to pass to indexed here? If that's the
 case, $
 isn't associated with any particular array, and I don't see how it could
 work.

 Now, there's issue# 7177

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

 which aims at getting opDollar to work with ranges which have length
 (which it
 generally doesn't at this point), so that might be related to what you're
 looking for, but if what you're looking for is [0, $-1] to work on its
 own, I
 don't see how that could ever work, because $ only works when slicing or
 indexing, and [0, $-1] in the context above is an array literal.

 - Jonathan M Davis



Re: new Type[count] takes too much?

2013-10-31 Thread Namespace
On Thursday, 31 October 2013 at 09:53:39 UTC, Jonathan M Davis 
wrote:

On Thursday, October 31, 2013 10:15:51 Namespace wrote:

I'm sure we had already this conversation but I don't find the
thread.

T[] buffer = new T[N]; assumes more space than stated (in 
average

2010 elements more. See: http://dpaste.dzfl.pl/af92ad22c). It
behaves exactly like reserve and that is IMO wrong. If I 
reserve

memory with buffer.reserve(N), I want to have at least N
elements. That behaviour is correct. But if I use new T[N] I
mostly want exactly N elements and no extra space.

Thoughts?


You're making the assumption that it would be normal to not 
want to then
append to something you allocated with new T[N], and I don't 
think that that's

a valid assumption.


I disagree. If I want to append I use reserve and I think that is 
the most common approach.


Re: improving '$' to work with other functions (eg: indexed)

2013-10-31 Thread Jonathan M Davis
On Thursday, October 31, 2013 14:46:29 Timothee Cour wrote:
 well it can be made to work with following rule:
 
 $ binds as follows, using the 1st pattern matched rule:
 
 very roughly:
 
 identifier [$] if typeof(a.length) = a[a.length] //likewise with s/[]/()/
 primary_expression . identifier if typeof(primary_expression.length)
 = primary_expression . identifier [identifier.length] (recursively)
 if no match is found, error.
 
 eg:
 
 [1,2,3].indexed([0,$-1] ) = indexed.length isn't valid, so it tries to
 bind to [1,2,3].
 
 intuitively I believe it makes sense.

Well, I can see why you'd think that that makes sense, but it would have 
surprised me greatly if I had seen code like that compile. And given how 
little benefit it really provides, I don't think that it's worth the extra 
complication to the language. So, I'd be against it, but feel free to open an 
enhancement request. Maybe a compiler dev will take a shine to the idea.

- Jonathan M Davis


Re: Intelligent Scope Hierarchy

2013-10-31 Thread Namespace

The 'it' property is only some 'singleton' approach.
You can write:

void foo() {
auto buffer = Mallocator.allocate(42);
/// ... many code
}

And at the end of the scope buffer is cleared because 
Mallocator's destructor call deallocateAll (if I'm not wrong).


Re: new Type[count] takes too much?

2013-10-31 Thread Jonathan M Davis
On Thursday, October 31, 2013 23:06:22 Namespace wrote:
 On Thursday, 31 October 2013 at 09:53:39 UTC, Jonathan M Davis
 
 wrote:
  On Thursday, October 31, 2013 10:15:51 Namespace wrote:
  I'm sure we had already this conversation but I don't find the
  thread.
  
  T[] buffer = new T[N]; assumes more space than stated (in
  average
  2010 elements more. See: http://dpaste.dzfl.pl/af92ad22c). It
  behaves exactly like reserve and that is IMO wrong. If I
  reserve
  memory with buffer.reserve(N), I want to have at least N
  elements. That behaviour is correct. But if I use new T[N] I
  mostly want exactly N elements and no extra space.
  
  Thoughts?
  
  You're making the assumption that it would be normal to not
  want to then
  append to something you allocated with new T[N], and I don't
  think that that's
  a valid assumption.
 
 I disagree. If I want to append I use reserve and I think that is
 the most common approach.

I would fully expect that most people don't bother with reserve or capacity 
and that they simply create the array at whatever size they create it at and 
then append to it without worrying about reserve. But we'd have to get real 
data on that to know for sure one way or the other.

Certainly, most folks who are focusing on append performance seem to use 
Appender, and for the most part, I would suggest that anyone using reserve 
should be using Appender instead.

- Jonathan M Davis


Re: new Type[count] takes too much?

2013-10-31 Thread Namespace
On Thursday, 31 October 2013 at 23:48:19 UTC, Jonathan M Davis 
wrote:

On Thursday, October 31, 2013 23:06:22 Namespace wrote:

On Thursday, 31 October 2013 at 09:53:39 UTC, Jonathan M Davis

wrote:
 On Thursday, October 31, 2013 10:15:51 Namespace wrote:
 I'm sure we had already this conversation but I don't find 
 the

 thread.
 
 T[] buffer = new T[N]; assumes more space than stated (in

 average
 2010 elements more. See: http://dpaste.dzfl.pl/af92ad22c). 
 It

 behaves exactly like reserve and that is IMO wrong. If I
 reserve
 memory with buffer.reserve(N), I want to have at least N
 elements. That behaviour is correct. But if I use new T[N] I
 mostly want exactly N elements and no extra space.
 
 Thoughts?
 
 You're making the assumption that it would be normal to not

 want to then
 append to something you allocated with new T[N], and I don't
 think that that's
 a valid assumption.

I disagree. If I want to append I use reserve and I think that 
is

the most common approach.


I would fully expect that most people don't bother with reserve 
or capacity
and that they simply create the array at whatever size they 
create it at and
then append to it without worrying about reserve. But we'd have 
to get real

data on that to know for sure one way or the other.

Certainly, most folks who are focusing on append performance 
seem to use
Appender, and for the most part, I would suggest that anyone 
using reserve

should be using Appender instead.

- Jonathan M Davis


Currently Appender isn't more performant than built-in arrays. ;)


Re: Dynamic load from another context

2013-10-31 Thread TheFlyingFiddle

On Thursday, 31 October 2013 at 02:45:36 UTC, Wolftein wrote:
so my question is, is it possible to build an associative array 
at compile-time?


Yes, by using ctfe it's possible.

like so:

enum int[string] aa = createAA();

auto createAA()
{
int[string] aa;
aa[hello] = 1;
aa[foo] = 123;
return aa;
}

unittest
{
static assert(aa[hello] == 1);
static assert(aa[foo] == 123);
}

Then i could register some shared variables like events and 
when the plug-in is loaded, iterate over that array and set the 
correct values at runtime.


This is not a good idea. The address values of functions/variables
in a dll changes depending on where in memory the dll gets loaded.

Since the addresses are determined at runtime compiletime 
calculations

will not be correct.

Also you could use the export keyword. This makes it possible to 
load
the variables at runtime using the core.runtime module. However 
there
seems to be problems with the export keyword see the DIP45 
http://wiki.dlang.org/DIP45


I'm currently developing a reflection library for use across 
DLL's. In it

i've done something simillar to what you want to do.

I use annotations to indicate if a variable is sharable across 
dlls and
then the code to handle the sharing is generated from those 
annotations

via a mixin template.

So bascialy i do something like this: (Simplified version)

//Pluggin.d

@DLLShared
__gshared size_t foo;


@DLLShared
void bar(string a)
{
  //Do something cool.
}

//Does not get shared over dll.
void baz() { }

mixin RegisterReflection;

This would be expanded into something like this.

__gshared void*[string] __reflectionData;

export extern(C) void*[string] getReflectionTable()
{
   return __reflectionData;
}

static this()
{
   __reflectionData[foo] = foo;
   __reflectionData[bar] = bar;
}

//MainApp.

alias extern(C) void function() reflection_pt;
void main()
{
   auto pluggin = loadPluggin(some_pluggin.dll);
   auto data = pluggin.findFunc!(reflection_pt)
  (getReflectionTable)();

   auto fooPtr = cast(size_t*)(data[foo]);

   //do something with the foo value.
}

I got a little sidetracked at the end. Hope this helped.





is this invalid code

2013-10-31 Thread Daniel Davidson
The following crashes on writeln, but looks reasonable. Is some 
form of initializing ctor required for RateCurve?


import std.datetime;
import std.range;
import std.stdio;

struct DateRate {
  Date date;
  double value = 0.0;
}

struct RateCurve {
  private immutable(DateRate)[] _data;
}

struct CFS {
  double initialValue;
  RateCurve growth;
}

void main() {
  auto s = CFS(1.0);
  // auto s = CFS(1.0, RateCurve()); // crashes
  // auto s = CFS(1.0, RateCurve([])); // works
  writeln(s);
}

Thanks
Dan


Re: is this invalid code

2013-10-31 Thread Ali Çehreli

On 10/31/2013 08:29 PM, Daniel Davidson wrote:

The following crashes on writeln, but looks reasonable. Is some form of
initializing ctor required for RateCurve?

import std.datetime;
import std.range;
import std.stdio;

struct DateRate {
   Date date;
   double value = 0.0;
}

struct RateCurve {
   private immutable(DateRate)[] _data;
}

struct CFS {
   double initialValue;
   RateCurve growth;
}

void main() {
   auto s = CFS(1.0);
   // auto s = CFS(1.0, RateCurve()); // crashes
   // auto s = CFS(1.0, RateCurve([])); // works
   writeln(s);
}

Thanks
Dan


You are not going to like my answer but this may be the 16-byte struct 
bug. Add something to RateCurve and your code works fine... :-/


struct RateCurve {
  private immutable(DateRate)[] _data;
ubyte b;  // -- ADDED
}

Ali



Re: Intelligent Scope Hierarchy

2013-10-31 Thread Stretto

On Thursday, 31 October 2013 at 22:03:18 UTC, Namespace wrote:

The 'it' property is only some 'singleton' approach.
You can write:

void foo() {
auto buffer = Mallocator.allocate(42);
/// ... many code
}

And at the end of the scope buffer is cleared because 
Mallocator's destructor call deallocateAll (if I'm not wrong).



That doesn't seem right? deallocateAll would deallocate all 
allocated objects? Even outside of foo's scope? Also, how would 
Mallocator.allocate know what to deallocate unless it kept a 
history? Why would the example code explicitly deallocate the 
object at the end of the scope if it were unnecessary?