Re: newbie question: Can D do this?

2011-12-21 Thread mta`chrono
In PHP frameworks often use $option arrays which are some kind of key
value pairs. they are merged with the default valuzes inside the function.

pro:
 - you can pass an argument by name
 - you only need to pass those who needed.

cons:
 - hash arrays

it should be possible to create a similar method in d. but I really
don't like this solution in d. it feels bad and looks ugly.


?php

$model-query(array(
   'firstname' = 'John',
   'country' = 'France',
   'order' = 'asc'
));

class Model
{
function query($options = array())
{
// merge with defaults
$options = array_merge(array(
'deep' = true,
'order' = 'desc',
'type' = 'sql',
'backend' = 'mysql'
...
), $options);
}

}

?


Re: How to mixin each element of tuple

2011-12-21 Thread Michal Minich

On 20. 12. 2011 16:20, Timon Gehr wrote:


struct Item1(T){}
struct Item2(T){}

mixin template getItems(Items ...){
static if(Items.length) {
private alias Items[0] _item;
mixin _item!int;
mixin getItems!(Items[1..$]);
}
}

struct Group(Items...)
{
mixin getItems!Items;
}

void main(){
alias Group!(Item1, Item2) G;
}



Thank you. Solution 1 worked well.

The need to introduce new symbol '_item' using alias because one cannot 
mixin Items[0]!int directly seems to me as a bug. Do you happen to know 
if it is already reported?


Re: newbie question: Can D do this?

2011-12-21 Thread Christophe
Timon Gehr , dans le message (digitalmars.D.learn:31142), a écrit :
 On 12/20/2011 03:18 PM, clk wrote:
 Thank you for your quick replies. I'm impressed by the helpfulness and
 dedication of the D community!
 Here's another one. Is there a way to pass arguments to functions by
 keyword as in the calls to f and g below?

 void f(int a = 0, int b = 1) {}
 void g(int a) {}

 void main() {
 f(b = 1, a = 0); // compile error
 g(a = 0); // also compile error
 }


 
 No, there are no named arguments in D. Having them would sometimes be 
 useful,

 but the drawback is that the parameter names become part of the 
 public interface.

Well, that's precisely the point. And it is a drawback if parameters are 
systematically names, but not if it is triggered only on demand.

Example :

void foo(int a, int b:, int c:);

void main() {
foo(1, 2, 3);
foo(1, c: 3, b: 2;
foo(a: 1, b: 2, c: 3); // error : a is not a named parameter.
}

In the example, : is used to make a named parameter to recall the use 
when you call the function.



writing iterators without code duplication. inout?

2011-12-21 Thread pompei2

Hello.

I want to add the option to iterate objects of my class using 
foreach. I need them to be iterable as view-only const and as 
mutable too. I would prefer to iterate using the return a 
delegate but if that's not possible, ranges are fine too. Also, 
I'd prefer a template-less solution over a templated one.



This is what I have, which works but has severe code duplication. 
I hoped inout would help me here, but I just can't figure it out. 
I also gave a try to ranges, but same thing again: I can only get 
it to work if I define my things twice.


(syntax highlight for the coming month: 
http://pastebin.com/TNmWWgsj)



   import std.conv, std.stdio;

   class Container
   {
   this(int from, int to)
   {
   while(from = to) {
   _arr ~= from;
   from++;
   }
   }

   // FIXME: severe code duplication for const/nonconst/ref
   //and I'm not even trying immutable yet
   int delegate(int delegate(ref int)) doIter()
   {
   writeln(calling non-const);

   int doTheIter(int delegate(ref int) dg)
   {
   int result = 0;
   foreach(ref i ; this._arr) {
   result = dg(i);
   if(result)
   break;
   }
   return result;
   }

   return doTheIter;
   }

   int delegate(int delegate(ref int)) doIter() const
   {
   writeln(calling const);

   int doTheIter(int delegate(ref int) dg)
   {
   int result = 0;
   foreach(i ; this._arr) {
   result = dg(i);
   if(result)
   break;
   }
   return result;
   }

   return doTheIter;
   }

   int[] _arr;
   }

   int main(string[] args)
   {
   Container c = new Container(1, 9);
   const Container cc = c;

   foreach(ref e ; c.doIter()) {
   writeln(e);
   e++;
   }

   foreach(e ; cc.doIter()) {
   writeln(e);
   }

   return 0;
   }



Re: writing iterators without code duplication. inout?

2011-12-21 Thread Trass3r

Can't really answer your original question, but
1. Why don't you use opApply?
2. Why do you use ref int even in the const version?
3. You could also use alias this to allow iteration, don't know if that's  
what you want in general though.


Re: writing iterators without code duplication. inout?

2011-12-21 Thread Timon Gehr

On 12/21/2011 04:54 PM, pompei2 wrote:

Hello.

I want to add the option to iterate objects of my class using foreach. I
need them to be iterable as view-only const and as mutable too. I would
prefer to iterate using the return a delegate but if that's not
possible, ranges are fine too. Also, I'd prefer a template-less solution
over a templated one.


This is what I have, which works but has severe code duplication. I
hoped inout would help me here, but I just can't figure it out. I also
gave a try to ranges, but same thing again: I can only get it to work if
I define my things twice.

(syntax highlight for the coming month: http://pastebin.com/TNmWWgsj)


import std.conv, std.stdio;

class Container
{
this(int from, int to)
{
while(from = to) {
_arr ~= from;
from++;
}
}

// FIXME: severe code duplication for const/nonconst/ref
// and I'm not even trying immutable yet
int delegate(int delegate(ref int)) doIter()
{
writeln(calling non-const);

int doTheIter(int delegate(ref int) dg)
{
int result = 0;
foreach(ref i ; this._arr) {
result = dg(i);
if(result)
break;
}
return result;
}

return doTheIter;
}

int delegate(int delegate(ref int)) doIter() const
{
writeln(calling const);

int doTheIter(int delegate(ref int) dg)
{
int result = 0;
foreach(i ; this._arr) {
result = dg(i);
if(result)
break;
}
return result;
}

return doTheIter;
}

int[] _arr;
}

int main(string[] args)
{
Container c = new Container(1, 9);
const Container cc = c;

foreach(ref e ; c.doIter()) {
writeln(e);
e++;
}

foreach(e ; cc.doIter()) {
writeln(e);
}

return 0;
}



Just remove the non-const overload. const member functions work with 
mutable, immutable and const receivers.


Re: writing iterators without code duplication. inout?

2011-12-21 Thread Jakob Ovrum

On Wednesday, 21 December 2011 at 16:31:01 UTC, Jakob Ovrum wrote:
On Wednesday, 21 December 2011 at 16:07:55 UTC, Timon Gehr 
wrote:
Just remove the non-const overload. const member functions 
work with mutable, immutable and const receivers.


The const version does not allow using 'ref' when iterating.


In light of pompei2's recent reply;

the const version *should not* allow using 'ref' when iterating.


Re: writing iterators without code duplication. inout?

2011-12-21 Thread pompei2

On Wednesday, 21 December 2011 at 16:05:24 UTC, Trass3r wrote:

Can't really answer your original question, but
1. Why don't you use opApply?
2. Why do you use ref int even in the const version?
3. You could also use alias this to allow iteration, don't know 
if that's what you want in general though.


13: Because there are different things in my class to iterate 
over. Think foreach(p ; obj.properties()) and foreach(c ; 
obj.components()). (I know, I can make those @property so I don't 
need the ().)


2. Because if not, it says: Error: cannot implicitly convert 
expression (__foreachbody1315) of type int delegate(ref int) to 
int delegate(int)




Re: writing iterators without code duplication. inout?

2011-12-21 Thread Jakob Ovrum

On Wednesday, 21 December 2011 at 16:07:55 UTC, Timon Gehr wrote:
Just remove the non-const overload. const member functions work 
with mutable, immutable and const receivers.


The const version does not allow using 'ref' when iterating.


Re: writing iterators without code duplication. inout?

2011-12-21 Thread Christophe
pompei2 , dans le message (digitalmars.D.learn:31164), a écrit :
 This is what I have, which works but has severe code duplication. 
 I hoped inout would help me here, but I just can't figure it out. 
 I also gave a try to ranges, but same thing again: I can only get 
 it to work if I define my things twice.


It's not optimal, and there is an ugly cast, but maybe this is a 
suitable workarrond for you :

  int delegate(int delegate(ref int)) doIter() const
{
  return (int delegate(ref int) dg)
{
  cast(typeof(this))(this).doIter()((ref int i) { int copy = i; 
dg(copy); });
}   
}


Until
  int delegate(ref inout int) opApply() inout;
and
  int delegate(int delegate(ref inout int)) doIter() inout;
are made to work. (I actually don't know if there is any obstacles to do 
this).


test if object is instance of class at compile time

2011-12-21 Thread Elvis Maehren
This works fine at runtime, but explodes in CTFE:
---
bool isInstanceOf(T, O)(O o) {
return (cast(T) o) !is null;
}
---

CTFE doesn't like !is null (cannot compare [...] at compile time). 

Moreover, in CTFE a failed cast terminates the interpretation (cannot 
reinterpret class from [...] to [...] at compile time). Is this somehow 
catchable? If so, I could do something along these lines:
---
if(__ctfe) {
try {
auto t = cast(T) o;
return true;
} catch {
return false;
}
}
---



Are D classes always garbage collected?

2011-12-21 Thread Froglegs
 From what I understand D classes are reference types, which 
would imply to me that they are either always garbage collected 
or rather less likely, reference counting.


Which is fine and all, but since structs don't support virtual 
functions, doesn't this pretty much force you to use classes and 
therefor GC if you want virtual functions?


So why don't structs support virtual funtions? I would like to 
have a type that is not GC'd or ref counted or any other 
nonsense, but supports virtual functions..


Am I missing something here? Thanks


Re: Are D classes always garbage collected?

2011-12-21 Thread Vladimir Panteleev

On Thursday, 22 December 2011 at 02:29:10 UTC, Froglegs wrote:
From what I understand D classes are reference types, which 
would imply to me that they are either always garbage collected 
or rather less likely, reference counting.


They are garbage-collected.

Which is fine and all, but since structs don't support virtual 
functions, doesn't this pretty much force you to use classes 
and therefor GC if you want virtual functions?


You can allocate classes anywhere, if you're OK with forfeiting 
safety guarantees. For example, see emplace in std.conv:


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

So why don't structs support virtual funtions? I would like to 
have a type that is not GC'd or ref counted or any other 
nonsense, but supports virtual functions..


Value type polymorphism has shown to be problematic. One notable 
problem is object slicing:


http://en.wikipedia.org/wiki/Object_slicing


Am I missing something here? Thanks


I *think* the language allows implementing something akin to 
value type polymorphism (sans syntax sugar), but currently the 
required compiler features (alias this, compile-time 
symbol/address evaluation) are not implemented well-enough to 
test my idea.


Re: test if object is instance of class at compile time

2011-12-21 Thread Vladimir Panteleev
On Wednesday, 21 December 2011 at 20:15:36 UTC, Elvis Maehren 
wrote:

Is this somehow catchable?


I believe that's what __traits(compiles, ...) is for:

http://dlang.org/traits.html#compiles


Re: Are D classes always garbage collected?

2011-12-21 Thread Froglegs


You can allocate classes anywhere, if you're OK with forfeiting 
safety guarantees. For example, see emplace in std.conv:


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


Ah thanks


Value type polymorphism has shown to be problematic. One 
notable problem is object slicing:


http://en.wikipedia.org/wiki/Object_slicing


I see... seems like a pretty weak reason, I've never found that 
to be an issue in C++ as it is exactly what I'd expect to happen 
if I did something like that.



I *think* the language allows implementing something akin to 
value type polymorphism (sans syntax sugar), but currently the 
required compiler features (alias this, compile-time 
symbol/address evaluation) are not implemented well-enough to 
test my idea.


Ah, faking it, hopefully that works out someday :)




Re: Are D classes always garbage collected?

2011-12-21 Thread Froglegs


You can allocate classes anywhere, if you're OK with 
forfeiting safety guarantees. For example, see emplace in 
std.conv:


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


Hum calling emplace ending up calling this bit of code..

T* emplace(T)(T* chunk)
   if (is(T == class))
{
   *chunk = null;
   return chunk;
}

Which returned me a nice fat null pointer.. wth? Perhaps that 
should be a compile time error if you aren't supposed to use 
classes..



I tried placement new syntax but this tells me I need an 
allocator, whatever that means..


I swear D is google proof sigh


Re: Are D classes always garbage collected?

2011-12-21 Thread Froglegs


Which returned me a nice fat null pointer.. wth? Perhaps that 
should be a compile time error if you aren't supposed to use 
classes..


Strange... I'm not sure what the deal is with that overload. I 
meant the last one on the page (that takes a void[]).



Hum I've tried the array version but I believe it contains a 
rather serious bug...


T emplace(T, Args...)(void[] chunk, Args args) if (is(T == class))
{
   enforce(chunk.length = __traits(classInstanceSize, T),
  new ConvException(emplace: chunk size too small));
...

This fails whenever the size is greater or equal to the amount of 
memory required :(



Anyway I need the pointer version for what I was hoping to do, 
unless there is some way to convert a pointer into an array?


Is there any way to do something like this..

void* pData = some_c_function();
void [] fakeArray = pData, size;




Re: Are D classes always garbage collected?

2011-12-21 Thread Froglegs


T emplace(T, Args...)(void[] chunk, Args args) if (is(T == 
class))

{
  enforce(chunk.length = __traits(classInstanceSize, T),
 new ConvException(emplace: chunk size too small));
...

This fails whenever the size is greater or equal to the amount 
of memory required :(


 Hum nevermind that, got confused by the IDE behavior.  Anway 
this emplace function crashes when I call it with a very 
meaningless callstack.


Re: Are D classes always garbage collected?

2011-12-21 Thread Vladimir Panteleev

On Thursday, 22 December 2011 at 06:43:33 UTC, Froglegs wrote:


T emplace(T, Args...)(void[] chunk, Args args) if (is(T == 
class))

{
enforce(chunk.length = __traits(classInstanceSize, T),
   new ConvException(emplace: chunk size too small));
...

This fails whenever the size is greater or equal to the amount 
of memory required :(


Hum nevermind that, got confused by the IDE behavior.  Anway 
this emplace function crashes when I call it with a very 
meaningless callstack.


This works for me:

import std.conv;
class C {
  int i;
  this() { i = 42; }
}
unittest {
  void[__traits(classInstanceSize, C)] data = void;
  auto c = emplace!C(data[]);
  assert(c.i == 42);
}



Re: Are D classes always garbage collected?

2011-12-21 Thread Andrew Wiley
On Wed, Dec 21, 2011 at 10:20 PM, Froglegs lug...@gmail.com wrote:

 Which returned me a nice fat null pointer.. wth? Perhaps that should be a
 compile time error if you aren't supposed to use classes..


 Strange... I'm not sure what the deal is with that overload. I meant the
 last one on the page (that takes a void[]).



 Hum I've tried the array version but I believe it contains a rather serious
 bug...

 T emplace(T, Args...)(void[] chunk, Args args) if (is(T == class))
 {
   enforce(chunk.length = __traits(classInstanceSize, T),
          new ConvException(emplace: chunk size too small));
 ...

 This fails whenever the size is greater or equal to the amount of memory
 required :(


 Anyway I need the pointer version for what I was hoping to do, unless there
 is some way to convert a pointer into an array?

 Is there any way to do something like this..

 void* pData = some_c_function();
 void [] fakeArray = pData, size;



Yes:
void* pData = some_c_function();
void[] fakeArray = pData[0..size];

Although Vladimir's solution is safer.


Re: test if object is instance of class at compile time

2011-12-21 Thread Jacob Carlborg

On 2011-12-21 21:15, Elvis Maehren wrote:

This works fine at runtime, but explodes in CTFE:
---
bool isInstanceOf(T, O)(O o) {
return (cast(T) o) !is null;
}
---

CTFE doesn't like !is null (cannot compare [...] at compile time).

Moreover, in CTFE a failed cast terminates the interpretation (cannot
reinterpret class from [...] to [...] at compile time). Is this somehow
catchable? If so, I could do something along these lines:
---
if(__ctfe) {
try {
auto t = cast(T) o;
return true;
} catch {
return false;
}
}
---



I don't think you can do a test like that during compile time. In your 
above function, isInstanceOf, o will always be of the type O. You 
can always do a comparisons to see if O is the same type as T.


--
/Jacob Carlborg


ctfe bug?

2011-12-21 Thread Johannes Pfau
Hi,
the following code is reduced from a parser generated with Ragel 
(http://www.complang.org/ragel/). That's also the reason why it's
using pointers instead of array access, but Ragel guarantees that there 
won't be any out-of-bound reads.

AFAIK pointers are supported in CTFE now as long as they're pointing to an 
array and there are no out-of-bounds reads. Still, the following code fails:


ubyte[4] testCTFE()
{
ubyte[4] data;
string input = 8ab3060e2cba4f23b74cb52db3bdfb46;
auto p = input.ptr;
p++; p++;
data[0] = parse!ubyte((p-2)[0 .. 2], 16);
p++; p++;
data[1] = parse!ubyte((p-2)[0 .. 2], 16);
p++; p++;
data[2] = parse!ubyte((p-2)[0 .. 2], 16);
p++; p++;
data[3] = parse!ubyte((p-2)[0 .. 2], 16);
p++; p++;
return data;
}
enum ctfe = testCTFE();

void main()
{
import std.stdio;
writeln(testCTFE()); //[138, 179, 6, 14]
writeln(ctfe); //[138, 138, 138, 138]
}


Has this bug already been filed? I could possibly circumvent it by making 
ragel use array indexing instead of pointers, but that'd be a performance 
issue for runtime code as well.