Re: Windows SetConsoleScreenBufferSize() returning an odd error code

2013-10-10 Thread webwraith
On Saturday, 5 October 2013 at 21:33:32 UTC, Andrej Mitrovic 
wrote:

On 10/5/13, webwraith webwra...@fastmail.fm wrote:

I don't know about you, but it's beginning to look to me like
SetConsoleScreenBufferSize() takes pixels as its unit of
measurement, and not columns and rows, as is stated in its
documentation. I don't suppose you could confirm this?


I don't know, but maybe these are helpful:

http://stackoverflow.com/a/9237971/279684
http://msdn.microsoft.com/en-us/library/windows/desktop/ms686125%28v=vs.85%29.aspx


thanks for the help Andrej. I had asked the question over on 
GameDev.net as well, and they ended up pointing me at the DOSBox 
sources, which gave me exactly what I needed. After mulling it 
over quickly, I realized it was a cnp to get it to work in D. I 
have the link here:

http://sourceforge.net/p/dosbox/code-0/HEAD/tree/dosbox/trunk/src/debug/debug_win32.cpp


Re: mutable, const, immutable guidelines

2013-10-10 Thread Daniel Davidson

On Wednesday, 9 October 2013 at 23:05:27 UTC, qznc wrote:
On Wednesday, 9 October 2013 at 15:50:55 UTC, Daniel Davidson 
wrote:

void foo(const(MutableType) mt);
void foo(immutable(MutableType) mt);

Naturally the inclination is to choose the second as it is a 
stronger guarantee that no threads are changing the data. 
Cool. But wait, the first one still probably requires the same 
guarantee, even if it does not state it. If in the const case 
another thread changes the state of mt during the function foo 
then it will fail. foo actually requires that mt not be change 
by other threads during its operation - that is the only sane 
way of using the data in the function.


Why the first one still probably requires the same guarantee?
Why would foo fail if in the const case  another thread 
changes the state of mt?

If foo is not thread-safe, then it should require immutable.

Take, for example, LinearCongruentialEngine from random.d. It 
has a function:


   bool opEquals(ref const LinearCongruentialEngine rhs) const

Why is it using const here instead of immutable? Does it not 
care about other threads? No - it just is not smart enough to 
deal with it. It assumes other threads won't be changing it or 
if they are caveat developer. So when do you use immutable as 
a signal that not only will this function not change it, no 
thread will change it either? Probably when you know you have 
to deal with threading. But that then would be coupling two 
maybe orthogonal decisions - the threading of a program and 
the signature of functions.


Hm, that actually looks like a bug. If LinearCongruentialEngine 
is instantiated with a UIntType larger than size_t, it is not 
thread-safe, but this seems to be claimed in the section header.


Why are those two decisions orthogonal? The signature of a 
function is a contract between caller and callee. If an 
argument is const, it means the callee says he can handle 
others changing the state concurrently.


I don't think that is how people interpret and use const. The 
general guideline is, for function parameters use const because 
it is most accepting - it takes mutable, immutable and const. If 
there are multiple threads developer beware.


Threading is or can be somewhat orthogonal to function signatures 
simply because you can write a whole lot of code with the const 
guideline above. Then with proper serialized access use that 
thread unaware code in multi-threaded context.


fill array using a lambda function

2013-10-10 Thread dominic jones

Hello,

I want to fill an array with random numbers without resorting to 
loops, i.e. by doing something like the following, if it were 
possible:


  fill!(function double(){ return uniform(0.0, 1.0);})(x[]);

Is there a simple way of doing this?

Thank you,
Dominic Jones

P.S. I am aware of the function uniformDistribution, but it makes 
the sum of the elements equal to 1, which I don't want.


Re: fill array using a lambda function

2013-10-10 Thread bearophile

dominic jones:

I want to fill an array with random numbers without resorting 
to loops, i.e. by doing something like the following, if it 
were possible:


  fill!(function double(){ return uniform(0.0, 1.0);})(x[]);

Is there a simple way of doing this?


Generally it's a good idea to use only pure functions inside the 
higher order functions of Phobos. using impure functions like 
uniforms could lead to bugs or performance problems.


This is a way to do it (untested):

x.copy(x.length.iota.map!(_ = uniform(0.0, 1.0));

Bye,
bearophile


Call a function with a function pointer

2013-10-10 Thread Namespace

I have this function:

void foo(T)(void function(T*) test) { }


And want to call it with a C function:

foo!(SDL_Surface)(SDL_FreeSurface);


but I get:
Fehler	1	Error: foo (void function(SDL_Surface*) test) is not 
callable using argument types (extern (C) void 
function(SDL_Surface*) nothrow)


What would be the smartest solution?


Re: Call a function with a function pointer

2013-10-10 Thread Dicebot

On Thursday, 10 October 2013 at 14:13:47 UTC, Namespace wrote:

I have this function:

void foo(T)(void function(T*) test) { }


And want to call it with a C function:

foo!(SDL_Surface)(SDL_FreeSurface);


but I get:
Fehler	1	Error: foo (void function(SDL_Surface*) test) is not 
callable using argument types (extern (C) void 
function(SDL_Surface*) nothrow)


What would be the smartest solution?


Wrap it in a lambda. Or change foo() signature to accept 
`extern(C)` functions - you can't just mix calling convention.


Re: Call a function with a function pointer

2013-10-10 Thread Benjamin Thaut

Am 10.10.2013 16:13, schrieb Namespace:

I have this function:

void foo(T)(void function(T*) test) { }


And want to call it with a C function:

foo!(SDL_Surface)(SDL_FreeSurface);


but I get:
Fehler1Error: foo (void function(SDL_Surface*) test) is not
callable using argument types (extern (C) void function(SDL_Surface*)
nothrow)

What would be the smartest solution?


If you can change the signature of foo just add a extern(c) to the 
function pointer declaration.


Otherwise just wrap the SDL_FreeSurface call into a delegate on the 
caller side.


--
Kind Regards
Benjamin Thaut


Re: Call a function with a function pointer

2013-10-10 Thread Dicebot

On Thursday, 10 October 2013 at 14:40:09 UTC, Namespace wrote:

Example? I do not use lambdas often.


void foo(T)(void function(T*) test)
{
}

extern(C) void bar(int*) { }

void main()
{
foo( (int* a) = bar(a) );
}

I don't know to what extent IFTI can work here though.


Re: Call a function with a function pointer

2013-10-10 Thread Namespace

On Thursday, 10 October 2013 at 14:28:20 UTC, Dicebot wrote:

On Thursday, 10 October 2013 at 14:13:47 UTC, Namespace wrote:

I have this function:

void foo(T)(void function(T*) test) { }


And want to call it with a C function:

foo!(SDL_Surface)(SDL_FreeSurface);


but I get:
Fehler	1	Error: foo (void function(SDL_Surface*) test) is not 
callable using argument types (extern (C) void 
function(SDL_Surface*) nothrow)


What would be the smartest solution?


Wrap it in a lambda.


Example? I do not use lambdas often.


Re: Call a function with a function pointer

2013-10-10 Thread Namespace

On Thursday, 10 October 2013 at 14:44:00 UTC, Dicebot wrote:

On Thursday, 10 October 2013 at 14:40:09 UTC, Namespace wrote:

Example? I do not use lambdas often.


void foo(T)(void function(T*) test)
{
}

extern(C) void bar(int*) { }

void main()
{
foo( (int* a) = bar(a) );
}

I don't know to what extent IFTI can work here though.


That works. Thanks.


Re: Call a function with a function pointer

2013-10-10 Thread Namespace

On Thursday, 10 October 2013 at 15:15:45 UTC, bearophile wrote:

Namespace:


You mean like this?

void foo(T)(extern(C) void function(T*) func) {

}


That prints: Error: basic type expected, not extern 


In theory that's correct, in practice the compiler refuses 
that, it's in Bugzilla, so try to define the type outside the 
signature (untested):


alias TF = extern(C) void function(T*);

void foo(T)(TF func) {}

Bye,
bearophile


/d917/f732.d(8): Error: basic type expected, not extern
/d917/f732.d(8): Error: semicolon expected to close alias 
declaration
/d917/f732.d(8): Error: no identifier for declarator void 
function(T*)


Re: Call a function with a function pointer

2013-10-10 Thread bearophile

Namespace:


/d917/f732.d(8): Error: basic type expected, not extern
/d917/f732.d(8): Error: semicolon expected to close alias 
declaration
/d917/f732.d(8): Error: no identifier for declarator void 
function(T*)


It seems that even the new alias syntax doesn't support the 
extern :-) Perhaps this bug is not yet in Bugzilla.


Try:

alias extern(C) void function(T*) TF;
void foo(T)(TF func) {}

Bye,
bearophile


Re: Call a function with a function pointer

2013-10-10 Thread Dicebot

On Thursday, 10 October 2013 at 15:15:45 UTC, bearophile wrote:

Namespace:


You mean like this?

void foo(T)(extern(C) void function(T*) func) {

}


That prints: Error: basic type expected, not extern 


In theory that's correct, in practice the compiler refuses 
that, it's in Bugzilla, so try to define the type outside the 
signature (untested):


alias TF = extern(C) void function(T*);

void foo(T)(TF func) {}

Bye,
bearophile


That is limitation of current extern - it can only be attached to 
symbol declarations, not types. AFAIK you need to do `extern(C) 
alias TF = ...` but anyway this method is very likely to break 
IFTI completely.




How to check for instantiation of specific template?

2013-10-10 Thread H. S. Teoh
I have a template used for storing compile-time values:

template Def(int x, string y) {
alias impl = TypeTuple!(x,y);
}

How do I define a template isDef that, given some template alias A,
evaluates to true if A is some instantiation of Def?

template isDef(alias A) {
enum A = ... /* what to put here? */
}

The intent is to be able to write signature constraints like this:

auto myFunc(alias def)(...)
if (isDef!def)
{
...
}

...
// Pass an instantiation of Def to myFunc
auto x = myFunc!(Def!(1, abc))(args);

I tried using std.traits.isInstanceOf but apparently it expects the
second argument to be an actual type, which doesn't work in this case
because Def is a typetuple of compile-time values, not an actual type.


T

-- 
Help a man when he is in trouble and he will remember you when he is in trouble 
again.


Re: Call a function with a function pointer

2013-10-10 Thread Namespace


import std.stdio;

void foo1(void function(void*) fp) { }
void foo2(void function(int) fp) { }
void foo3(void*) { }

void main()
{
foo1((void* ptr) = ( assert(ptr is null) ));
	foo2((int a) = ( a + 1 )); /// Fails: Error: function foo2 
(void function(int) fp) is not callable using argument types (int 
function(int a) pure nothrow @safe)


foo1(foo3);

void foo4(void function(void*) fp) { }
	foo1(foo4); /// Fails: Error: function foo1 (void 
function(void*) fp) is not callable using argument types (void 
delegate(void function(void*) fp))

}

Can someone explain that to me?


Re: How to check for instantiation of specific template?

2013-10-10 Thread Simen Kjaeraas

On 2013-10-10, 19:23, H. S. Teoh wrote:


I have a template used for storing compile-time values:

template Def(int x, string y) {
alias impl = TypeTuple!(x,y);
}

How do I define a template isDef that, given some template alias A,
evaluates to true if A is some instantiation of Def?

template isDef(alias A) {
enum A = ... /* what to put here? */
}


This seems to be impossible. The standard way of doing this would be
with an isExpression[0], but that only works for types.

A solution would be to beef up your Def template by turning it into
a struct:

struct Def(int x, string y) {
alias impl = TypeTuple!(x,y);
}

With this definition, the following works:

template isDef(alias A) {
enum isDef = is(A == Def!T, T...);
// Or enum isDef = is(A == Def!(x, y), int x, string y);
}

This is a shortcoming of the language, and I have filed an enhancement
request for it[1].

The problems of using an actual type for this, is that someone might
instantiate that type (unlikely), and that the compiler will generate
TypeInfo for it, which will bloat your executable. A Sufficienctly
Smart Compiler[2] would see that the type is never used and thus not
include the TypeInfo. Something which the compiler could do without
a lot of smarts, is optimize away final abstract classes, which you
cannot derive from and cannot instantiate. That oughta be enough.

[0]: http://dlang.org/expression#IsExpression
[1]: http://d.puremagic.com/issues/show_bug.cgi?id=11219
[2]: http://c2.com/cgi/wiki?SufficientlySmartCompiler
--
Simen


Re: fill array using a lambda function

2013-10-10 Thread Simen Kjaeraas

On 2013-10-10, 16:04, bearophile wrote:


dominic jones:

I want to fill an array with random numbers without resorting to loops,  
i.e. by doing something like the following, if it were possible:


  fill!(function double(){ return uniform(0.0, 1.0);})(x[]);

Is there a simple way of doing this?


Generally it's a good idea to use only pure functions inside the higher  
order functions of Phobos. using impure functions like uniforms could  
lead to bugs or performance problems.


This is a way to do it (untested):

x.copy(x.length.iota.map!(_ = uniform(0.0, 1.0));


You've got the order wrong - copy takes first the source, then the target.
Also, is it faster to use .length.iota than simply mapping on x?
My solution:

x.map!(_=uniform(0.0, 1.0)).copy(x);

--
Simen


Re: fill array using a lambda function

2013-10-10 Thread bearophile

Simen Kjaeraas:

You've got the order wrong - copy takes first the source, then 
the target.


I'd like it to be (re)named copyTo to avoid me such common 
mistake.


Bye,
bearophile


Re: mutable, const, immutable guidelines

2013-10-10 Thread Christian Köstlin

On 10/10/13 1:05 , qznc wrote:
Very interesting discussion!

 contract between caller and callee. If an argument is const, it means
 the callee says he can handle others changing the state concurrently.
i think what the usual understanding of const for an argument to callee 
is, what is written at http://dlang.org/const3.html. that means for me, 
that callee promises not to change the data itself. perhaps a bettr 
description would be readonly.


usually you would think that no one else should change the data while 
callee runs. but at least with c++ i could imagine running callee in a 
thread with a reference to a const thing which changes underneath and 
while callee is running.




Re: Call a function with a function pointer

2013-10-10 Thread Dicebot

On Thursday, 10 October 2013 at 17:47:54 UTC, Namespace wrote:


import std.stdio;

void foo1(void function(void*) fp) { }
void foo2(void function(int) fp) { }
void foo3(void*) { }

void main()
{
foo1((void* ptr) = ( assert(ptr is null) ));
	foo2((int a) = ( a + 1 )); /// Fails: Error: function foo2 
(void function(int) fp) is not callable using argument types 
(int function(int a) pure nothrow @safe)


foo1(foo3);

void foo4(void function(void*) fp) { }
	foo1(foo4); /// Fails: Error: function foo1 (void 
function(void*) fp) is not callable using argument types (void 
delegate(void function(void*) fp))

}

Can someone explain that to me?


You are using short lambda syntax a = b. Here `b` is always 
return statement. It is equivalent to (a) { return b; }. And 
your `foo2` signature expects lambda returning void, like (a) { 
return; }


Second error is DMD incompetence in deducing minimal required 
type of nested function. It always treats them as delegates (== 
having hidden context pointer) even if those do not refer any 
actual context. And plain lambdas are of course binary 
incompatible with delegates (closures) because of that extra 
pointer field.


Begining with D

2013-10-10 Thread Alejandro

Hi

I'm new in D, have some experience in JavaScript and PHP, and 
learned, for long time ago, C and a bit little C++


I remember that when I learned C with console output, it was two 
easy ways to catch input : one witch a required  Enter keydown, 
and an other witch catched a single character, a single keydown. 
I liked very much this last function (I think it was get()), very 
useful when making small programs for learning purposes.


I'm looking for something like that in D, widthout finding it. 
I'm sorry coming here width my bad English asking a question like 
that, I see everyone here has a hight level in coding D, but 
since there is no much documentation around Internet, I don't 
find another solution.


Re: Begining with D

2013-10-10 Thread Ali Çehreli

On 10/10/2013 11:56 AM, Alejandro wrote:

 catched a single character, a single keydown

The following program is based on the following newsgroup post:


http://forum.dlang.org/post/mailman.2665.1300747084.4748.digitalmars-d-le...@puremagic.com

The program prints character codes in hex until it sees Ctrl-D:

import std.stdio : writef, writeln;
import std.c.stdio;
import std.c.linux.termios;

/* The declaration of cfmakeraw, which is missing from standard D 
modules. */

extern(C) void cfmakeraw(termios *termios_p);

void main()
{
/* Saving the existing state of tty. */
termios oldState;
tcgetattr(1, oldState);

/* Ensuring that it will be restored upon exit. */
scope (exit) tcsetattr(1, TCSADRAIN, oldState);

/* Make a new state and set it to raw mode. */
termios  newState;
tcgetattr(1, newState);
cfmakeraw(newState);

/* Use the new state in this terminal. */
tcsetattr(1, TCSADRAIN, newState);

/*
 * We are ready to read characters in this raw mode...
 */

/* This is Ctrl-D, the EOF character under Linux. */
enum endOfFile = '\4';

for (char c; c != endOfFile; ) {
c = cast(char)fgetc(stdin);
writef(%02x , c);
}

writeln();
}

 my bad English

Please don't say that. :) Thank you very much for communicating in English.

Ali



Re: Starting D with a project in mind.

2013-10-10 Thread Adam D. Ruppe

On Thursday, 10 October 2013 at 19:49:15 UTC, Andrew wrote:
Hence my interest in D. I've spent a few hours trying to get 
GDC working on my Pi which is proving to be a bitch but I'm 
hoping that it will be worth it.


I haven't done a serious program on the Pi, but I was able to get 
gdc and some test programs to compile and run successfully for 
it. Took me a couple hours too, the way I did it was with a 
crosstool-ng thingy:

http://gdcproject.org/wiki/Cross%20Compiler/crosstool-NG

so I can compile it on my Linux desktop for the pi. I did hit one 
druntime bug in the process, but I believe it has already been 
fixed so you hopefully won't have to deal with that.


The biggest problem I had was at first I didn't use the gnu-eabi 
option. I think that was in compiling druntime, not sure though, 
my memory is failing as this was several months ago when I played 
with it.



Bottom line though is I know it is possible, but I don't know how 
seamless it will be with a larger program.


Re: How to check for instantiation of specific template?

2013-10-10 Thread simendsjo

On Thursday, 10 October 2013 at 17:24:37 UTC, H. S. Teoh wrote:

I have a template used for storing compile-time values:

template Def(int x, string y) {
alias impl = TypeTuple!(x,y);
}

How do I define a template isDef that, given some template 
alias A,

evaluates to true if A is some instantiation of Def?

template isDef(alias A) {
enum A = ... /* what to put here? */
}

The intent is to be able to write signature constraints like 
this:


auto myFunc(alias def)(...)
if (isDef!def)
{
...
}

...
// Pass an instantiation of Def to myFunc
auto x = myFunc!(Def!(1, abc))(args);

I tried using std.traits.isInstanceOf but apparently it expects 
the
second argument to be an actual type, which doesn't work in 
this case
because Def is a typetuple of compile-time values, not an 
actual type.



T


I've used this horrible hack to solve this. Not very generic as 
you can see:
else static if(T.stringof.length  13  T.stringof[0..13] == 
TupleWrapper!)


Re: Call a function with a function pointer

2013-10-10 Thread Andrej Mitrovic
On 10/10/13, bearophile bearophileh...@lycos.com wrote:
 Perhaps this bug is not yet in Bugzilla.

I'm pretty sure I saw it filed somewhere. Can't find it though..


Re: Call a function with a function pointer

2013-10-10 Thread bearophile

Andrej Mitrovic:


I'm pretty sure I saw it filed somewhere. Can't find it though..


I have just added the new test case :-)
http://d.puremagic.com/issues/show_bug.cgi?id=6754

Bye,
bearophile


Re: Starting D with a project in mind.

2013-10-10 Thread qznc

On Thursday, 10 October 2013 at 19:49:15 UTC, Andrew wrote:

Hi All,

I've been writing a MUD for a little while, initially using 
Haskell but now using C. I develop on MacOS X but deploy to a 
Raspberry Pi. I loved using Haskell especially using the Parsec 
parser but unfortunately I couldn't build on the Pi because the 
resource requirements were just too heavy.


Now I develop in C and the same Makefile builds on Mac and 
Debian equally well and of course I can use the lovely Xcode 
environment. However, as I start to add more advanced features 
it's getting rather tedious. The MUD has an embedded web server 
which supports web sockets for real time play and the back end 
is a Mongo DB. The C code to access DB is very repetitive and 
is slowing me down because of the lack of higher level 
constructs. Similarly the parser is very basic and ropey which 
needs attention.


Hence my interest in D. I've spent a few hours trying to get 
GDC working on my Pi which is proving to be a bitch but I'm 
hoping that it will be worth it.


Before I get too far down this path, would you recommend D for 
this task and will porting from Mac to Pi be seamless ?


As Adam already said D on Pi is adventurous.

For MongoDB and web stuff, you should look into Vibe.d [0]. For 
parsing I would suggest Pegged [1].


Welcome to D and Happy Hacking! :)

[0] http://vibed.org/
[1] https://github.com/PhilippeSigaud/Pegged


how to handle memory ownership when interfacing with C/C++ via internal pointers

2013-10-10 Thread Timothee Cour
Short version:
I have a struct A* aptr allocated in C/C++ with an internal
pointer aptr-ptr (say a double*)
I want to store a reference x (say double[]) in D to aptr only through
aptr-ptr, not through aptr directly as it's inconvenient in my use case.

How do I achieve that, so that when x goes out of scope, some deallocator
for aptr will be called ?

Long version:

suppose I have C++ code:
struct A{
  double*ptr;
  A(size_t n){ptr=(double*)malloc(n);}
  ~A(){free(ptr);}
};

and a D wrapper around it:
extern(C){struct A; A*A_new(size_t n); void A_delete(A*a);
double*A_ptr(A*a);}

I want to use it as follows:

double[] get_x(size_t n){
 return A_new(n).A_ptr[0..n];
}

void main(){
  double[]x=get_x(n);
// do something with x;
}


It's trivial to handle this via a class wrapper:
class A2{
A*a;
this(size_t n){a=A_new(n);}
~this(){A_delete(n);}
double*ptr(){return A_ptr(a);}
}
double[] get_x(size_t n){
 auto a2=new A2(n);
 return a2.ptr;
//this doesn't help much though, A2 will go out of scope when this function
exits.
}


but I don't want to maintain objects of class A2 around, just double[]
slices as above.

Is there some magic involving core.memory.addRoot,addRange (etc) I can use
so that a2 stays alive as long as x stays alive? (in which case when x goes
out of scope, 'a2' will too, and will call A_delete).

Thanks


Re: mutable, const, immutable guidelines

2013-10-10 Thread qznc

On Wednesday, 9 October 2013 at 04:31:55 UTC, Ali Çehreli wrote:

On 10/08/2013 03:12 PM, qznc wrote:
 On Monday, 7 October 2013 at 17:57:11 UTC, Ali Çehreli wrote:
 To look at just one usage example, the following line
carries two
 requirements:

 auto a = T();
 immutable b = a;

 1) b will be an immutable copy of a.

 2) T will always be usable as in that fashion.

 If T appears on an API, it is the responibility of the user
to ensure
 whether they are allowed to treat T in that way. Otherwise,
they risk
 maintainability if the module decides to change T in any way
that fits
 the module's needs. If they have not yet advertised that T
can be used
 as immutable, it should not be.

 I do not agree with you, that the user has the responsibility.

I have difficulty agreeing with myself as well. :) However, the 
power of immutable makes me think so. Interestingly, once a 
user creates an immutable variable of a type, that type must 
support that use.


 Rather I
 think the provider of T has the responsibility to maintain
backwards
 compatibility.

Agreed but I don't know how. Here is challenge: Let's start 
with the following program:


// Library type
struct MyInt
{
int i;
}

void main()
{
// User code
auto a = MyInt(1);
immutable b = a;
}

Let's assume that the library adds a private dynamic array of 
ints to that type:


// Library type
struct MyInt
{
int i;
private int[] history;// -- Added
}

void main()
{
// User code
auto a = MyInt(1);
immutable b = a;  // -- Existing code breaks
}

Error: cannot implicitly convert expression (a) of type MyInt 
to immutable(MyInt)


Maybe the fact that D allows this implicit copy to immutable is 
the problem? If one could require the use of a specific function, 
this function could be overridden with working behavior. The 
following code works.


import std.exception: assumeUnique;

struct MyInt
{
  int i;
  private int[] history;// -- Added
}

// idup for creating immutable MyInts
immutable(MyInt) idup(const MyInt mi) pure nothrow @trusted {
  MyInt cpy = MyInt(mi.i);
  return cast(immutable) cpy;
}

// special version for performance
immutable(MyInt) idup(immutable MyInt mi) pure nothrow @trusted {
  return mi;
}

unittest {
  auto a = MyInt(1);
  immutable b = a.idup; // -- Code does not break
}

D could either remove the implicit-copy-to-immutable or provide a 
special copy-constructor for immutable structs.


Re: mutable, const, immutable guidelines

2013-10-10 Thread qznc
On Thursday, 10 October 2013 at 18:39:32 UTC, Christian Köstlin 
wrote:

On 10/10/13 1:05 , qznc wrote:
Very interesting discussion!

 contract between caller and callee. If an argument is const,
it means
 the callee says he can handle others changing the state
concurrently.
i think what the usual understanding of const for an argument 
to callee is, what is written at http://dlang.org/const3.html. 
that means for me, that callee promises not to change the data 
itself. perhaps a bettr description would be readonly.


The linked page clearly says It may, however, be changed by 
another reference to that same data.


usually you would think that no one else should change the data 
while callee runs. but at least with c++ i could imagine 
running callee in a thread with a reference to a const thing 
which changes underneath and while callee is running.


A const argument gives information to both sides. For the caller 
it means callee does not modify the data. For the callee it means 
somebody else (another thread) may modify the data at any time.


An immutable argument means the same for the caller, but gives an 
additional guarantee to the callee that nobody modifies the data.


Re: mutable, const, immutable guidelines

2013-10-10 Thread Daniel Davidson

On Thursday, 10 October 2013 at 23:06:23 UTC, qznc wrote:
Maybe the fact that D allows this implicit copy to immutable is 
the problem? If one could require the use of a specific 
function, this function could be overridden with working 
behavior. The following code works.




Yes - the issue arises because the language has different 
behavior for structs with mutable aliasing and structs without. 
For structs without mutable aliasing a copy is safe so crossing 
bounds between any of (mutable, const, immutable) is easily 
achieved.



import std.exception: assumeUnique;

struct MyInt
{
  int i;
  private int[] history;// -- Added
}

// idup for creating immutable MyInts
immutable(MyInt) idup(const MyInt mi) pure nothrow @trusted {
  MyInt cpy = MyInt(mi.i);
  return cast(immutable) cpy;
}

// special version for performance
immutable(MyInt) idup(immutable MyInt mi) pure nothrow @trusted 
{

  return mi;
}

unittest {
  auto a = MyInt(1);
  immutable b = a.idup; // -- Code does not break
}

D could either remove the implicit-copy-to-immutable or provide 
a special copy-constructor for immutable structs.


See this discussion: 
http://forum.dlang.org/thread/fmhkvogowjlduqerc...@forum.dlang.org


Re: mutable, const, immutable guidelines

2013-10-10 Thread Joseph Rushton Wakeling

On 11/10/13 01:43, Daniel Davidson wrote:

That is probably a reasonable interpretation... but I think it will only get you
pain. The fact is, regardless of your interpretation of const arguments - the
general guideline is prefer const because immutables and mutables can be passed
in.


Which makes much sense for code that is intended to be generically useful.


Think of it this way: you are writing a very generic function that requires
inputs that you do not mutate. If you choose immutable you are making your life
easier, I guess, since you know data is not being changed on you. But you are
also preventing your function from being called by any arguments that are
already mutable (assuming the type has mutable aliasing) because crossing the
mutable to immutable divide is not part of the language. So, the only way then
for mutable types to make it into your function is to copy them and this may or
may not even be possible. And if you truly know no code is mutating your data it
is a tougher sell.


If you are insisting that your function receive immutable inputs, you are in 
turn constraining the user of that code.  If you really want your function to be 
generic, isn't the appropriate thing to allow the user the choice of whether 
they want to pass it immutable data, or to take the risk of passing it mutable data?


Surely there's a tradeoff -- you may well feel the resulting safety is worth it, 
and there may be other benefits, such as optimizations, that you can derive from 
having only immutable data.


But for the standard library of a multiparadigm language, it's not appropriate 
to force users to use immutable data.



On the other hand if you go with const parameters, your data could in fact
change on you. Unfortunately, it can cause terrible angst when the only options
make you wish for other options.


Well, that depends.  If you go with const parameters but you pass it immutable 
data, you know it won't change on you.  You, the user, are in control.



Have you actually written nested D data types with mutable aliasing (not just
slices but assoc arrays) and used immutable in the signatures? I have tried and
not succeeded.


Yes, I tried it, and ran into this problem.  But generally these days I use in 
to mark arguments that are not intended to be modified.  I personally prefer 
that -- it has a semantic meaning, and how it translates into code is for the 
compiler.



I guess this just highlights the need for guidelines.


Guidelines are always nice. :-)



Re: Traits

2013-10-10 Thread Ali Çehreli

On 10/10/2013 09:13 PM, Agustin wrote:

 I have a function that needs to check if the template provided inherit a
 class.

 For example:

 public void function(T, A...)(auto ref A values)

function happens to be a keyword. :)

 {
// static assert(IsBaseOf(L, T));
 }

 Check if T inherit class L. Same result that std::is_base_ofL,
 T::value using C++. Any clean way to do it, without a dirty hack.

One of the uses of the is expression determines whether implicitly 
convertible to. It may work for you:


public void foo(T, A...)(auto ref A values)
{
static assert(is (T : L));
}

class L
{}

class LL : L
{}

void main()
{
foo!LL(1, 2.3, 4);
}

Ali



Re: Traits

2013-10-10 Thread Jonathan M Davis
On Thursday, October 10, 2013 21:35:37 Ali Çehreli wrote:
 One of the uses of the is expression determines whether implicitly
 convertible to. It may work for you:
 
 public void foo(T, A...)(auto ref A values)
 {
  static assert(is (T : L));
 }

Actually, checking for implicit conversion will work directly in the template 
signature without a template constraint or static assertion. e.g.

public void foo(T : L, A...)auto ref A values)
{
}

- Jonathan M Davis


Re: Traits

2013-10-10 Thread luminousone

On Friday, 11 October 2013 at 04:13:55 UTC, Agustin wrote:
I have a function that needs to check if the template provided 
inherit a class.


For example:

public void function(T, A...)(auto ref A values)
{
  // static assert(IsBaseOf(L, T));
}

Check if T inherit class L. Same result that 
std::is_base_ofL, T::value using C++. Any clean way to do it, 
without a dirty hack.


import std.traits;

bool ChildInheritsFromParent( parent, child )( ) {

foreach ( k, t; BaseClassesTuple!child ) {
if( typeid(t) == typeid(parent) )
return true;
}
return false;
}