Re: metaprogramming question

2010-04-18 Thread Philippe Sigaud
On Mon, Apr 19, 2010 at 07:43, Justin Spahr-Summers <
justin.spahrsumm...@gmail.com> wrote:

>
> Yes, sorry. That's what I was trying to do originally, but I couldn't
> quite spit it out. Indeed, templating the actual arguments is a horrible
> idea.
>

Sorry to comment on it, then. I'm discovering all this by myself, so I don't
know if what I generally post is a well-known established practice or a nice
trick few people use... (or a brillant idea only a genius could utter, but
hey...)

Just to complete it, and as it's on my mind: I found one case, yesterday,
when you have to pass the args as CT args: filtering on a tuple. Strange
idea maybe, but fun to code.
That is:

auto t = tuple(1, 'a', "abc", 3.14159);
auto f = filterTuple!(polymorphicPredicate)(t); // should return a smaller
tuple, with 1, 'a',... filtered according to polymPredicate

This does not work, because I have to determine the return type of
filterTuple as CT, obviously. And this return type in turn depends on the
_values_ stored inside the tuple. At CT, I can check the types, but not the
values, unless I use them as CT args:
auto f = filterTuple!(polymorphicPredicate, t)();

But then, I'm limited by what you can use as a template parameter (not all
possible D types are allowed, I think). Maybe as an alias...

I'll stop, now, before derailing the thread. I'm trying to use tuples as a
sort-of cousin of ranges, by mapping, chaining or truncating them...

Philippe


Re: metaprogramming question

2010-04-18 Thread Philippe Sigaud
On Mon, Apr 19, 2010 at 07:31, BCS  wrote:

> Or you can mangel that a bit:
>
> template check(alias func) {
>  bool check(EL ...)() {
>
> GError* err;
> bool ok = func(EL, &err);
> if (!ok)
>throw new Exception((*err).message);
> return ok;
>  }
> }
>
> that should allow you to call it like:
>
> check!(fooXXX)(arg1, ..., argN);


(I guess you meant bool check(EL...)(EL el) in the second stage.)

Yes, this example is even more powerful. The version I posted already allows
you to write

check!fun(params); // no need to give explictly the EL, the compiler wil
deduce them for you

 but yours allow you to 'store' the checking of fun and then to use it for
any parameter typetuple. Maybe not useful for the OP, but mighty handy in
some other cases.
I discovered this trick a few weeks ago and, though a bitch to code
sometimes, it's very nice to have.

Usage:

alias check!foo fooCheck; // checkFoo is a templated function, so it's _not_
a function. You cannot assign it to a variable.
 // use alias instead.

// some other code //
auto check1 = fooCheck(1,2,3);
//
auto check2 = fooCheck("a","b", 2.34);

It's particularly useful when foo is polymorphic. Again, not interesting for
the OP, but very fun.

Philippe


Re: metaprogramming question

2010-04-18 Thread Justin Spahr-Summers
On Mon, 19 Apr 2010 07:28:09 +0200, Philippe Sigaud 
 wrote:
> 
> On Mon, Apr 19, 2010 at 05:21, Justin Spahr-Summers <
> justin.spahrsumm...@gmail.com> wrote:
> 
> > You can use some expression tuple magic to accomplish something like
> > that:
> >
> > bool check(alias func, EL ...)() {
> >GError* err;
> >bool ok = func(EL, &err);
> > if (!ok)
> >throw new Exception((*err).message);
> >
> > return ok;
> > }
> >
> > // used like:
> > check!(fooXXX, arg1, ..., argN);
> >
> >
> But in this case, you need to know the ELs at compile-time. You can make
> them run-time values that way:
> 
> bool check(alias func, EL ...)(EL el) {
>GError* err;
>bool ok = func(el, &err);
> if (!ok)
>throw new Exception((*err).message);
> 
> return ok;
> }
> 
> // used like:
> check!fooXXX(arg1, ..., argN);

Yes, sorry. That's what I was trying to do originally, but I couldn't 
quite spit it out. Indeed, templating the actual arguments is a horrible 
idea.


Re: metaprogramming question

2010-04-18 Thread BCS

Hello Justin Spahr-Summers,


On Mon, 19 Apr 2010 00:12:28 + (UTC), Graham Fawcett
 wrote:


Hi folks,

I'd like to wrap a family of C functions that look like this:

gboolean fooXXX(arg1, ..., argN, GError** err)

Their signatures and arities vary, but they all have a GError** as
their last argument. If a function returns false, then 'err' will be
set to a relevant Error struct.

I would like to write a wrapper that would let me call these
functions sort of like this:

check!(fooXXX(arg1, ..., argN))

where the 'check' expression would be equivalent to:

GError* err;
bool ok = fooXXX(arg1, ..., argN, &err);
if (!ok)
throw new Exception((*err).message);
Does D (2.0) offer a metaprogramming technique I could use to
accomplish this -- particularly, to inject that 'err' argument into
the tail of the fooXXX call?

Thanks,
Graham

You can use some expression tuple magic to accomplish something like
that:

bool check(alias func, EL ...)() {
GError* err;
bool ok = func(EL, &err);
if (!ok)
throw new Exception((*err).message);
return ok;
}
// used like:
check!(fooXXX, arg1, ..., argN);


IIRC that should be:

check!(fooXXX, argType1, ..., argTypeN)(arg1, ..., argN);


See http://digitalmars.com/d/2.0/template.html#TemplateTupleParameter



Or you can mangel that a bit:

template check(alias func) {
  bool check(EL ...)() {
 GError* err;
 bool ok = func(EL, &err);
 if (!ok)
throw new Exception((*err).message);
 return ok;
  }
}

that should allow you to call it like:

check!(fooXXX)(arg1, ..., argN);

--
... <





Re: metaprogramming question

2010-04-18 Thread BCS

Hello Philippe,



Of course, it'd be nice to check the EL at CT to see if they
correspond to func parameters types.


The call inside check will coever that for you as long as you don't mind 
getting the error in an odd place.


--
... <





Re: metaprogramming question

2010-04-18 Thread Philippe Sigaud
On Mon, Apr 19, 2010 at 05:21, Justin Spahr-Summers <
justin.spahrsumm...@gmail.com> wrote:

> You can use some expression tuple magic to accomplish something like
> that:
>
> bool check(alias func, EL ...)() {
>GError* err;
>bool ok = func(EL, &err);
> if (!ok)
>throw new Exception((*err).message);
>
> return ok;
> }
>
> // used like:
> check!(fooXXX, arg1, ..., argN);
>
>
But in this case, you need to know the ELs at compile-time. You can make
them run-time values that way:

bool check(alias func, EL ...)(EL el) {
   GError* err;
   bool ok = func(el, &err);
if (!ok)
   throw new Exception((*err).message);

return ok;
}

// used like:
check!fooXXX(arg1, ..., argN);


Of course, it'd be nice to check the EL at CT to see if they correspond to
func parameters types. I don't know if you can do this with C functions, but
for D funcs you can add:

import std.traits;
bool check(alias func, EL ...)(EL el) if (is(ParameterTypeTuple!func[0..$-1]
== TypeTuple!(EL, GError*))
{
...

It's a bit strict, as it doesn't deal with implicit conversions.

Cheers,

  Philippe


Re: metaprogramming question

2010-04-18 Thread Daniel Keep

http://while-nan.blogspot.com/2007/06/wrapping-functions-for-fun-and-profit.html

It shouldn't be too difficult to inject an extra parameter; just add it
to the end of the call to the wrapped function after args.


Re: metaprogramming question

2010-04-18 Thread Justin Spahr-Summers
On Mon, 19 Apr 2010 00:12:28 + (UTC), Graham Fawcett 
 wrote:
> 
> Hi folks,
> 
> I'd like to wrap a family of C functions that look like this:
> 
>   gboolean fooXXX(arg1, ..., argN, GError** err)
> 
> Their signatures and arities vary, but they all have a GError** as
> their last argument. If a function returns false, then 'err' will be
> set to a relevant Error struct.
> 
> I would like to write a wrapper that would let me call these functions
> sort of like this:
> 
>   check!(fooXXX(arg1, ..., argN))
> 
> where the 'check' expression would be equivalent to:
> 
>   GError* err;
>   bool ok = fooXXX(arg1, ..., argN, &err);
>   if (!ok)
> throw new Exception((*err).message);
> 
> Does D (2.0) offer a metaprogramming technique I could use to
> accomplish this -- particularly, to inject that 'err' argument into
> the tail of the fooXXX call?
> 
> Thanks,
> Graham

You can use some expression tuple magic to accomplish something like 
that:

bool check(alias func, EL ...)() {
GError* err;
bool ok = func(EL, &err);
if (!ok)
throw new Exception((*err).message);

return ok;
}

// used like:
check!(fooXXX, arg1, ..., argN);

See http://digitalmars.com/d/2.0/template.html#TemplateTupleParameter


metaprogramming question

2010-04-18 Thread Graham Fawcett
Hi folks,

I'd like to wrap a family of C functions that look like this:

  gboolean fooXXX(arg1, ..., argN, GError** err)

Their signatures and arities vary, but they all have a GError** as
their last argument. If a function returns false, then 'err' will be
set to a relevant Error struct.

I would like to write a wrapper that would let me call these functions
sort of like this:

  check!(fooXXX(arg1, ..., argN))

where the 'check' expression would be equivalent to:

  GError* err;
  bool ok = fooXXX(arg1, ..., argN, &err);
  if (!ok)
throw new Exception((*err).message);

Does D (2.0) offer a metaprogramming technique I could use to
accomplish this -- particularly, to inject that 'err' argument into
the tail of the fooXXX call?

Thanks,
Graham


Re: Newsgroups, off-topic

2010-04-18 Thread Simen kjaeraas

Jérôme M. Berger  wrote:


Actually, gcc doesn't require Walter to give away all rights to his
work just to use it as a backend (or else the gdc project wouldn't
exist). It would require ceding the rights only if Walter wanted D
to be part of the official gcc distribution.


You're right, I'm sorry.

--
Simen


Re: reading a global external (C) char* in D2

2010-04-18 Thread Lars T. Kyllingstad

Graham Fawcett wrote:

On Sun, 18 Apr 2010 19:14:33 +0200, Lars T. Kyllingstad wrote:


Graham Fawcett wrote:

Hi folks,

I'm having trouble reading an external(C) global value in D2. I think
I'm using __gshared properly to sidestep the TLS issues, but I'm still
getting an incorrect result.

[...]

Am I doing something wrong?

Thanks,
Graham


Try adding a second 'extern':

   extern(C) extern __gshared char* gdbm_version;


That did it! Thank you. I have much to learn.



No problem. :)  I ran into the same issue myself a few weeks ago, and it 
took a while before I figured it out.  I believe the explanation is that


 - 'extern(C)' means that it is a C variable, i.e. its name isn't
   mangled like a D variable in the object file.

- 'extern' means that it's not a part of the current module, and
  has to be linked in from elsewhere.


-Lars


Re: Newsgroups, off-topic

2010-04-18 Thread Jérôme M. Berger
Simen kjaeraas wrote:
> Joseph Wakeling  wrote:
> 
>> Maybe true, but I was thinking of it from a different angle -- why the
>> main D2 development does not switch backends.
> 
> So which do you suggest be used instead - the one that doesn't work on
> Windows (no exceptions) or the one that requires Walter to give away
> all rights to his work?
> 
Actually, gcc doesn't require Walter to give away all rights to his
work just to use it as a backend (or else the gdc project wouldn't
exist). It would require ceding the rights only if Walter wanted D
to be part of the official gcc distribution.

Jerome
-- 
mailto:jeber...@free.fr
http://jeberger.free.fr
Jabber: jeber...@jabber.fr



signature.asc
Description: OpenPGP digital signature


Re: reading a global external (C) char* in D2

2010-04-18 Thread Graham Fawcett
On Sun, 18 Apr 2010 19:14:33 +0200, Lars T. Kyllingstad wrote:

> Graham Fawcett wrote:
>> Hi folks,
>> 
>> I'm having trouble reading an external(C) global value in D2. I think
>> I'm using __gshared properly to sidestep the TLS issues, but I'm still
>> getting an incorrect result.
>> 
>> Consider the two following programs, one in C, the other D2:
>> 
>> // testc.c
>> #include 
>> extern char *gdbm_version;   // or #include 
>> 
>> int main() {
>>   printf("VERSION (C): %s.\n", gdbm_version);
>> }
>> 
>> $ gcc -o testc testc.c -lgdbm && ./testc VERSION (C): GDBM version
>> 1.8.3. 10/15/2002 (built Nov  5 2008 02:36:47).
>> 
>> // testd.d
>> import std.stdio;
>> import std.conv;
>> 
>> __gshared extern (C) char *gdbm_version;
>> 
>> void main() {
>>   string v = to!string(gdbm_version);
>>   writef("VERSION (D): %s.\n", v);
>> }
>> 
>> $ dmd testd.d -L-lgdbm && ./testd
>> VERSION (D): .
>> 
>> Am I doing something wrong?
>> 
>> Thanks,
>> Graham
> 
> 
> Try adding a second 'extern':
> 
>extern(C) extern __gshared char* gdbm_version;

That did it! Thank you. I have much to learn.

Cheers,
Graham


> 
> -Lars



Re: reading a global external (C) char* in D2

2010-04-18 Thread Lars T. Kyllingstad

Graham Fawcett wrote:

Hi folks,

I'm having trouble reading an external(C) global value in D2. I think
I'm using __gshared properly to sidestep the TLS issues, but I'm still
getting an incorrect result.

Consider the two following programs, one in C, the other D2:

// testc.c
#include 
extern char *gdbm_version;  // or #include 

int main() {
  printf("VERSION (C): %s.\n", gdbm_version);
}

$ gcc -o testc testc.c -lgdbm && ./testc
VERSION (C): GDBM version 1.8.3. 10/15/2002 (built Nov  5 2008 02:36:47).

// testd.d
import std.stdio;
import std.conv;

__gshared extern (C) char *gdbm_version;

void main() {
  string v = to!string(gdbm_version);
  writef("VERSION (D): %s.\n", v);
}

$ dmd testd.d -L-lgdbm && ./testd
VERSION (D): .

Am I doing something wrong? 


Thanks,
Graham



Try adding a second 'extern':

  extern(C) extern __gshared char* gdbm_version;

-Lars


reading a global external (C) char* in D2

2010-04-18 Thread Graham Fawcett
Hi folks,

I'm having trouble reading an external(C) global value in D2. I think
I'm using __gshared properly to sidestep the TLS issues, but I'm still
getting an incorrect result.

Consider the two following programs, one in C, the other D2:

// testc.c
#include 
extern char *gdbm_version;  // or #include 

int main() {
  printf("VERSION (C): %s.\n", gdbm_version);
}

$ gcc -o testc testc.c -lgdbm && ./testc
VERSION (C): GDBM version 1.8.3. 10/15/2002 (built Nov  5 2008 02:36:47).

// testd.d
import std.stdio;
import std.conv;

__gshared extern (C) char *gdbm_version;

void main() {
  string v = to!string(gdbm_version);
  writef("VERSION (D): %s.\n", v);
}

$ dmd testd.d -L-lgdbm && ./testd
VERSION (D): .

Am I doing something wrong? 

Thanks,
Graham


Re: Newsgroups, off-topic

2010-04-18 Thread Simen kjaeraas

Joseph Wakeling  wrote:


Maybe true, but I was thinking of it from a different angle -- why the
main D2 development does not switch backends.


So which do you suggest be used instead - the one that doesn't work on
Windows (no exceptions) or the one that requires Walter to give away
all rights to his work?

--
Simen


Re: Newsgroups, off-topic

2010-04-18 Thread BCS

Hello Joseph,


I can also see the desire to have a backend
that is fully under the control of the main developers.


There is also the point that if Walter never looks at the source for another 
compiler, it is nearly impossible for him to be sued for stealing from them.


--
... <





Re: Newsgroups, off-topic

2010-04-18 Thread Joseph Wakeling
Moritz Warning wrote:
> I think many people behind these compilers lack the personal motivation
> to integrate the D2 front end.
> That may change, but it may take time.

Maybe true, but I was thinking of it from a different angle -- why the
main D2 development does not switch backends.  To be fair, the work
involved would surely detract from the main development effort on the
language and features.  I can also see the desire to have a backend that
is fully under the control of the main developers.

> - not everybody likes the road the D2 design takes

What are the concerns here ... ?  I don't currently have a strong enough
sense of the differences.

> anyway, gdc has D2 support already (but not up to date/DMD), see http://
> bitbucket.org/goshawk/gdc/overview

I've been following that D2 work for a while now, and am looking forward
to where it is going ... :-)

Best wishes,

-- Joe