Re: implicit conversion

2014-08-12 Thread uri via Digitalmars-d-learn
Sorry should add this is on 2.066.0-rc2 and it used to work on 
2.064.


Cheers,
uri

On Tuesday, 12 August 2014 at 06:21:19 UTC, uri wrote:

Hi,

I'm trying to allow implicit conversions for my own type 
happening. I have the following:



import std.math;
import std.traits;

struct S(T)
if(isFloatingPoint!T)
{
T val;
alias val this;
}
void main()
{

auto s = S!float();
assert(isNaN(s));
s = 10.0;
assert(!isNaN(s));
}


But I get a compile time error:


Error: template std.math.isNaN cannot deduce function from 
argument types !()(S!float), candidates are:


std/math.d(4171):std.math.isNaN(X)(X x) if 
(isFloatingPoint!X)



Is there a way I can to do this, maybe opCall/opCast (I tried 
these but failed)?


Cheers,
uri




implicit conversion

2014-08-12 Thread uri via Digitalmars-d-learn

Hi,

I'm trying to allow implicit conversions for my own type 
happening. I have the following:



import std.math;
import std.traits;

struct S(T)
if(isFloatingPoint!T)
{
T val;
alias val this;
}
void main()
{

auto s = S!float();
assert(isNaN(s));
s = 10.0;
assert(!isNaN(s));
}


But I get a compile time error:


Error: template std.math.isNaN cannot deduce function from 
argument types !()(S!float), candidates are:


std/math.d(4171):std.math.isNaN(X)(X x) if 
(isFloatingPoint!X)



Is there a way I can to do this, maybe opCall/opCast (I tried 
these but failed)?


Cheers,
uri


Re: implicit conversion

2014-08-12 Thread Jonathan M Davis via Digitalmars-d-learn
On Tue, 12 Aug 2014 06:21:17 +
uri via Digitalmars-d-learn digitalmars-d-learn@puremagic.com wrote:

 Hi,

 I'm trying to allow implicit conversions for my own type
 happening. I have the following:

 
 import std.math;
 import std.traits;

 struct S(T)
 if(isFloatingPoint!T)
 {
  T val;
  alias val this;
 }
 void main()
 {

  auto s = S!float();
  assert(isNaN(s));
  s = 10.0;
  assert(!isNaN(s));
 }
 

 But I get a compile time error:

 
 Error: template std.math.isNaN cannot deduce function from
 argument types !()(S!float), candidates are:

 std/math.d(4171):std.math.isNaN(X)(X x) if
 (isFloatingPoint!X)
 

 Is there a way I can to do this, maybe opCall/opCast (I tried
 these but failed)?

The problem is that isNaN is now templatized, and its constraint uses
isFloatingPoint, which requires that the type _be_ a floating point type, not
that it implicitly convert to one. So, as it stands, isNAN cannot work with
any type which implicitly converts to a floating point value. Either it will
have to be instantiated with the floating point type - e.g. isNaN!float(s) -
or you're going to have to explicitly cast s to a floating point type.

You can open a bug report - https://issues.dlang.org - and mark it as a
regression, and it might get changed, but the reality of the matter is that
templates don't tend to play well with implicit conversions. It's _far_ too
easy to allow something in due to an implicit conversion and then have it not
actually work, because the value is never actually converted. In general, I
would strongly advise against attempting to give types implicit conversions
precisely because they tend to not play nicely with templates.

- Jonathan M Davis


Re: implicit conversion

2014-08-12 Thread uri via Digitalmars-d-learn
On Tuesday, 12 August 2014 at 06:37:45 UTC, Jonathan M Davis via 
Digitalmars-d-learn wrote:

On Tue, 12 Aug 2014 06:21:17 +
uri via Digitalmars-d-learn digitalmars-d-learn@puremagic.com 
wrote:



Hi,

I'm trying to allow implicit conversions for my own type
happening. I have the following:


import std.math;
import std.traits;

struct S(T)
if(isFloatingPoint!T)
{
 T val;
 alias val this;
}
void main()
{

 auto s = S!float();
 assert(isNaN(s));
 s = 10.0;
 assert(!isNaN(s));
}


But I get a compile time error:


Error: template std.math.isNaN cannot deduce function from
argument types !()(S!float), candidates are:

std/math.d(4171):std.math.isNaN(X)(X x) if
(isFloatingPoint!X)


Is there a way I can to do this, maybe opCall/opCast (I tried
these but failed)?


The problem is that isNaN is now templatized, and its 
constraint uses
isFloatingPoint, which requires that the type _be_ a floating 
point type, not
that it implicitly convert to one. So, as it stands, isNAN 
cannot work with
any type which implicitly converts to a floating point value. 
Either it will
have to be instantiated with the floating point type - e.g. 
isNaN!float(s) -
or you're going to have to explicitly cast s to a floating 
point type.


You can open a bug report - https://issues.dlang.org - and mark 
it as a
regression, and it might get changed, but the reality of the 
matter is that
templates don't tend to play well with implicit conversions. 
It's _far_ too
easy to allow something in due to an implicit conversion and 
then have it not
actually work, because the value is never actually converted. 
In general, I
would strongly advise against attempting to give types implicit 
conversions

precisely because they tend to not play nicely with templates.

- Jonathan M Davis


Thanks for the info. I'm happy to change my code and remove the 
implicit conversion. It was just for a convenience factor (floats 
with accumulated error).



Cheers,
uri



Re: Identifying 32 vs 64 bit OS?

2014-08-12 Thread Jeremy DeHaan via Digitalmars-d-learn
On Monday, 11 August 2014 at 06:17:22 UTC, ketmar via 
Digitalmars-d-learn wrote:

On Mon, 11 Aug 2014 05:18:59 +
Jeremy DeHaan via Digitalmars-d-learn
digitalmars-d-learn@puremagic.com wrote:

why do you need that info? D types has well-defined sizes (i.e 
uint is

always 32 bits, and so on).


I came up with a better solution for what I actually needed, but 
I was toying with some things in a rdmd build script for 
different kinds of compilation.




Very vague compiler error message

2014-08-12 Thread Jeremy DeHaan via Digitalmars-d-learn

I recently got this error messege when building my library:

dmd: cppmangle.c:154: void 
CppMangleVisitor::cpp_mangle_name(Dsymbol*): Assertion `0' failed.


I have no idea what it means and haven't found much information 
about it. I think I have narrowed it down to the file that is 
giving this error, but does anyone know what the heck causes 
something like this?  Talk about a nondescript error.


Re: Very vague compiler error message

2014-08-12 Thread ketmar via Digitalmars-d-learn
On Tue, 12 Aug 2014 07:16:49 +
Jeremy DeHaan via Digitalmars-d-learn
digitalmars-d-learn@puremagic.com wrote:

 but does anyone know what the heck causes something like this?
it's internal compiler error, the thing that should never happen.

try to use dustmite to build minimalictic test case and fill the bug.


signature.asc
Description: PGP signature


Re: Very vague compiler error message

2014-08-12 Thread Rikki Cattermole via Digitalmars-d-learn

On 12/08/2014 7:16 p.m., Jeremy DeHaan wrote:

I recently got this error messege when building my library:

dmd: cppmangle.c:154: void CppMangleVisitor::cpp_mangle_name(Dsymbol*):
Assertion `0' failed.

I have no idea what it means and haven't found much information about
it. I think I have narrowed it down to the file that is giving this
error, but does anyone know what the heck causes something like this?
Talk about a nondescript error.


That error is being generated from within dmd itself.
In other words you've found an edge case congratulations!

Look for functions/methods using the extern(C++) mangling.
Mock them out into D versions and see which fails maybe?


Re: Sorting algorithms

2014-08-12 Thread Era Scarecrow via Digitalmars-d-learn

 Rewatching lectures... And a thought came to me.

 Most sorting algorithms work with handling one element at a 
time; Although you may do a binary tree to sort getting NlogN, 
the optimal number of compares is still out of reach due to the 
number of extra compares done.


 However to build a proper comparing to try and get the minimal 
number of compares, you (consciously or not) are effectively 
doing a binary tree if you want to or not.


 So what if you merge trees instead of elements?

 Consider: You have a tree of even numbers. 2 4 6 8 10. 6 would 
be the top and being balanced. Now you have a tree of odd numbers 
also evenly distributed, so 1 3 5 7 9 and 5 would be the head.


 If you are merging the odd with the even, then the first compare 
of 5 vs 6 which it's less. So you break the tree in half since 
you know everything on the left side of the odd's tree is already 
less than 6 so you don't need to compare those. So the tree half 
of 1 3 5 follows the left tree down and gets slightly 
restructured so it's evenly distributed once more before doing 
the comparison with 4. The remainder (7  9) might get 
re-compared against 6, or passed to the right tree depending on 
how it handles duplicates.


 I'm working on a prototype to see if this passes... I just 
wonder if the overhead would cancel out the potential benefit; Of 
course that depends on how expensive the compare is. Against ints 
you might not get much benefit, but large string compares or 
large numbers you'd get a performance boost.


 It's probably possible to add this idea/feature to already 
existing tree structures like red/black trees. So going out of my 
way to build something new might be a waste except as a concept.


 Thoughts?


Re: overloads and parents. __traits confusion

2014-08-12 Thread John Colvin via Digitalmars-d-learn

On Tuesday, 12 August 2014 at 05:23:53 UTC, Dicebot wrote:

On Monday, 11 August 2014 at 13:00:27 UTC, John Colvin wrote:

   alias Parent = TypeTuple!(__traits(parent, foo!float))[0];


Say hello to optional parens - you are trying to call 
foo!float() here and apply result to trait.


I thought so. Ugh.

This works though:


void foo(float v){}
void foo(int a){}

alias Parent = TypeTuple!(__traits(parent, foo))[0];

pragma(msg, __traits(getOverloads, Parent, foo));


so it seems that instantiated function templates in this case are 
called parenthesis-free, whereas normal functions are passed by 
name/alias/whatever.


All expressions that are used as compile-time args (whether in 
udas, traits or as template arguments) should require parenthesis 
to be called. Anything else is madness.


A!(foo1().foo2()) //pass result
A!(foo1.foo2())   //pass result
A!(foo1.foo2) //pass function
A!(foo1)  //pass function
foo(foo1) //pass result


Re: overloads and parents. __traits confusion

2014-08-12 Thread anonymous via Digitalmars-d-learn

On Monday, 11 August 2014 at 13:00:27 UTC, John Colvin wrote:

can someone talk me through the reasoning behind this:

import std.typetuple;

void foo(T)(T v){}
void foo(){}

version(ThisCompiles)
{
alias Parent = TypeTuple!(__traits(parent, foo))[0];

pragma(msg, __traits(getOverloads, Parent, foo));
// tuple()
}
else
{
alias Parent = TypeTuple!(__traits(parent, foo!float))[0];

pragma(msg, __traits(getOverloads, Parent, foo));
/*
/d54/f131.d(8): Error: foo (float v) is not callable using 
argument types () /d54/f131.d(8): Error: (__error).foo cannot 
be resolved

tuple()
*/
}


(I'm not sure if the following is completely correct, but it
makes a lot of sense to me at the moment.)

For clarity, the verbose version of that template:

template foo(T) /* the (eponymous) template */
{
 void foo(T v) {} /* the function; the eponymous member */
}

foo is the template:
   `foo.stringof` = foo(T)(T v).
Its parent is the module:
   `__traits(parent, foo).stringof` = module test.
This is what you use in version(ThisCompiles). No problems.

foo!float is an instance of the template. Since the template is
eponymous, instantiations resolve to the eponymous member,
always. So foo!float is the function:
   `foo!float.mangleof.demangle` =
   pure nothrow @nogc @safe void test7.foo!(float).foo(float)
Its parent is the template instance, which resolves right back to
the function:
   `__traits(parent, foo!float).mangleof.demangle` =
   pure nothrow @nogc @safe void test7.foo!(float).foo(float)
   (just foo!float again)

Apparently, you cannot get out of an eponymous template
instantiation with __traits(parent, ...). Maybe __traits(parent,
...) of an eponymous template instance should be the parent of
the template. The current behaviour seems useless to me.

Simple test case without functions (no additional trouble from
optional parentheses):

struct S(T) {}
/* All print S!int: */
pragma(msg, S!int);
pragma(msg, __traits(parent, S!int));
pragma(msg, __traits(parent, __traits(parent, S!int)));


Deprecation: Read-modify-write operations are not allowed for shared variables

2014-08-12 Thread Timothee Cour via Digitalmars-d-learn
dmd 2.066(rc) generates warning: 'Deprecation: Read-modify-write operations
are not allowed for shared variables. Use core.atomic.atomicOp!-=(a, 1)
instead.' for following code:

synchronized {
  ++a;
}

Is that correct given that it's inside synchronized?


Re: Destroy two assumptions: interface implementation generated by TMP

2014-08-12 Thread John Colvin via Digitalmars-d-learn

On Monday, 11 August 2014 at 18:21:04 UTC, Baz wrote:
Hi, I try to get why the last way of generating an interface 
implementation fails. I've put assumptions: is it right ?

---
module itfgen;

import std.stdio;

interface itf{
void a_int(int p);
void a_uint(uint p);
}

class impl3: itf{
void tmp(T)(T p){};
alias a_int = tmp!int;
alias a_uint = tmp!uint;
}


Part of me feels that ought to work. There may well be good 
reasons why not though.


Currently you do have to have method implementations/overrides 
written out as normal functions.


Demangling GCC Languages

2014-08-12 Thread Nordlöw
What's the easiest way to get support for demangling of 
GCC-supported languages of symbols extracted from GCC compiled 
ELF files?


Are the demangle algorithms complex? Could they be ported to D 
easily?


Re: Demangling GCC Languages

2014-08-12 Thread Nordlöw

On Tuesday, 12 August 2014 at 11:30:24 UTC, Nordlöw wrote:
What's the easiest way to get support for demangling of 
GCC-supported languages of symbols extracted from GCC compiled


In D, that is.


Re: Destroy two assumptions: interface implementation generated by TMP

2014-08-12 Thread anonymous via Digitalmars-d-learn

On Monday, 11 August 2014 at 18:21:04 UTC, Baz wrote:

interface itf{
void a_int(int p);
void a_uint(uint p);
}

[...]
// FAILS because: alias are probably generated after the itf 
check

class impl3: itf{
void tmp(T)(T p){};
alias a_int = tmp!int;
alias a_uint = tmp!uint;
}

[...]
'Error: class itfgen.impl3 interface function 'void a_int(int 
p)' is not implemented'.


I think the problem is that impl3.tmp is not virtual because it's
a template, and interfaces need to be implemented by virtual
methods.


Re: Very vague compiler error message

2014-08-12 Thread H. S. Teoh via Digitalmars-d-learn
On Tue, Aug 12, 2014 at 07:16:49AM +, Jeremy DeHaan via Digitalmars-d-learn 
wrote:
 I recently got this error messege when building my library:
 
 dmd: cppmangle.c:154: void CppMangleVisitor::cpp_mangle_name(Dsymbol*):
 Assertion `0' failed.
 
 I have no idea what it means and haven't found much information about
 it. I think I have narrowed it down to the file that is giving this
 error, but does anyone know what the heck causes something like this?
 Talk about a nondescript error.

That's an ICE (Internal Compiler Error). Please reduce your test case
and file a critical bug.


T

-- 
Stop staring at me like that! It's offens... no, you'll hurt your eyes!


Re: Destroy two assumptions: interface implementation generated by TMP

2014-08-12 Thread John Colvin via Digitalmars-d-learn

On Tuesday, 12 August 2014 at 11:34:01 UTC, anonymous wrote:

On Monday, 11 August 2014 at 18:21:04 UTC, Baz wrote:

interface itf{
   void a_int(int p);
   void a_uint(uint p);
}

[...]
// FAILS because: alias are probably generated after the itf 
check

class impl3: itf{
   void tmp(T)(T p){};
   alias a_int = tmp!int;
   alias a_uint = tmp!uint;
}

[...]
'Error: class itfgen.impl3 interface function 'void a_int(int 
p)' is not implemented'.


I think the problem is that impl3.tmp is not virtual because 
it's

a template, and interfaces need to be implemented by virtual
methods.


The instantiations of the template are just normal functions 
though, no?


Re: Destroy two assumptions: interface implementation generated by TMP

2014-08-12 Thread anonymous via Digitalmars-d-learn

On Tuesday, 12 August 2014 at 12:08:14 UTC, John Colvin wrote:
I think the problem is that impl3.tmp is not virtual because 
it's

a template, and interfaces need to be implemented by virtual
methods.


The instantiations of the template are just normal functions 
though, no?


They are not virtual. Ordinary methods (public, not final, not
templated) are virtual.


Re: implicit conversion

2014-08-12 Thread Meta via Digitalmars-d-learn
On Tuesday, 12 August 2014 at 06:37:45 UTC, Jonathan M Davis via 
Digitalmars-d-learn wrote:
The problem is that isNaN is now templatized, and its 
constraint uses
isFloatingPoint, which requires that the type _be_ a floating 
point type, not
that it implicitly convert to one. So, as it stands, isNAN 
cannot work with
any type which implicitly converts to a floating point value. 
Either it will
have to be instantiated with the floating point type - e.g. 
isNaN!float(s) -
or you're going to have to explicitly cast s to a floating 
point type.


You can open a bug report - https://issues.dlang.org - and mark 
it as a
regression, and it might get changed, but the reality of the 
matter is that
templates don't tend to play well with implicit conversions. 
It's _far_ too
easy to allow something in due to an implicit conversion and 
then have it not
actually work, because the value is never actually converted. 
In general, I
would strongly advise against attempting to give types implicit 
conversions

precisely because they tend to not play nicely with templates.

- Jonathan M Davis


I think this should be considered a bug. A type with alias this 
should work in all cases that the aliased type would. If the 
function fails to be instantiated with S!float, then it should be 
forwarded to the S's val member.


Re: implicit conversion

2014-08-12 Thread Jonathan M Davis via Digitalmars-d-learn
On Tue, 12 Aug 2014 13:17:37 +
Meta via Digitalmars-d-learn digitalmars-d-learn@puremagic.com wrote:

 On Tuesday, 12 August 2014 at 06:37:45 UTC, Jonathan M Davis via
 Digitalmars-d-learn wrote:
  The problem is that isNaN is now templatized, and its
  constraint uses
  isFloatingPoint, which requires that the type _be_ a floating
  point type, not
  that it implicitly convert to one. So, as it stands, isNAN
  cannot work with
  any type which implicitly converts to a floating point value.
  Either it will
  have to be instantiated with the floating point type - e.g.
  isNaN!float(s) -
  or you're going to have to explicitly cast s to a floating
  point type.
 
  You can open a bug report - https://issues.dlang.org - and mark
  it as a
  regression, and it might get changed, but the reality of the
  matter is that
  templates don't tend to play well with implicit conversions.
  It's _far_ too
  easy to allow something in due to an implicit conversion and
  then have it not
  actually work, because the value is never actually converted.
  In general, I
  would strongly advise against attempting to give types implicit
  conversions
  precisely because they tend to not play nicely with templates.
 
  - Jonathan M Davis

 I think this should be considered a bug. A type with alias this
 should work in all cases that the aliased type would. If the
 function fails to be instantiated with S!float, then it should be
 forwarded to the S's val member.

AFAIK, the only time that the implicit conversion would take place is when the
type is being used in a situation where it doesn't work directly but where the
aliased type is used. In that case, the compiler sees the accepted types and
sees that the type can implicitly convert to one of the accepted types and
thus does the conversion. So, it knows that the conversion will work before it
even does it. The compiler never attempts to do the conversion just to see
whether it will work, which is essentially what it would have to do when
attempting to use the type with a templated function. You can certainly create
an enhancement request for such behavior, but I have no idea how likely it is
get implemented. There are currently _no_ cases where the compiler does
anything with template instantiations to try and make them pass if simply
trying to instantiate them with the given type failed.

- Jonathan M Davis


Re: Deprecation: Read-modify-write operations are not allowed for shared variables

2014-08-12 Thread ketmar via Digitalmars-d-learn
On Tue, 12 Aug 2014 03:01:22 -0700
Timothee Cour via Digitalmars-d-learn
digitalmars-d-learn@puremagic.com wrote:

 Is that correct given that it's inside synchronized?
yes. synchronized doesn't lock *any* access to a (consider two
different shared classes, for example), it just prevents simultaneous
access in this given part of code. so to be on the safe side, use
atomic operations.

besides, using atomic operations will allow you to drop synchronize
altogether which makes your code slightly faster.


signature.asc
Description: PGP signature


Re: implicit conversion

2014-08-12 Thread Meta via Digitalmars-d-learn

On Tuesday, 12 August 2014 at 14:26:46 UTC, Jonathan M Davis via
Digitalmars-d-learn wrote:
AFAIK, the only time that the implicit conversion would take 
place is when the
type is being used in a situation where it doesn't work 
directly but where the
aliased type is used. In that case, the compiler sees the 
accepted types and
sees that the type can implicitly convert to one of the 
accepted types and
thus does the conversion. So, it knows that the conversion will 
work before it
even does it. The compiler never attempts to do the conversion 
just to see
whether it will work, which is essentially what it would have 
to do when
attempting to use the type with a templated function. You can 
certainly create
an enhancement request for such behavior, but I have no idea 
how likely it is
get implemented. There are currently _no_ cases where the 
compiler does
anything with template instantiations to try and make them pass 
if simply

trying to instantiate them with the given type failed.

- Jonathan M Davis


What I mean is that this breaks the Liskov Substitution
Principle, which alias this should obey, as it denotes a subtype.
Since S!float has an alias this to float, it should behave as a
float in all circumstances where a float is expected; otherwise,
we've got a big problem with alias this on our hands.


Re: Deprecation: Read-modify-write operations are not allowed for shared variables

2014-08-12 Thread Sean Kelly via Digitalmars-d-learn
On Tuesday, 12 August 2014 at 15:06:38 UTC, ketmar via 
Digitalmars-d-learn wrote:


besides, using atomic operations will allow you to drop 
synchronize altogether which makes your code slightly faster.


... and potentially quite broken.  At the very least, if this 
value is ready anywhere you'll have to use an atomicLoad there in 
place of the synchronized block you would have used.


Re: implicit conversion

2014-08-12 Thread Jonathan M Davis via Digitalmars-d-learn

On Tuesday, 12 August 2014 at 15:39:09 UTC, Meta wrote:

What I mean is that this breaks the Liskov Substitution
Principle, which alias this should obey, as it denotes a 
subtype.

Since S!float has an alias this to float, it should behave as a
float in all circumstances where a float is expected; otherwise,
we've got a big problem with alias this on our hands.


IMHO, it was a mistake to add alias this to the language. It's
occasionally useful, but it's too dangerous. Implicit conversions
wreak havoc with templates, because inevitably what happens is
that a type is tested for whether it implicitly converts to a
particular type, but then the template is instantiated with the
original type, not the implicitly converted one, and then the
template frequently fails to compile - or if it does compile, it
may do weird things, because you're dealing with a type that
doesn't act as expected.

If you're dealing with a template which doesn't accept implicit
conversions (e.g. isNaN), and the implicit conversion were tested
after the actual type failed, and the template was then
instantiated with the implicitly converted type, then maybe that
could work, but that's not how it works now, and in general, I
think alias this is just too dangerous to use.

- Jonathan M Davis


Re: Deprecation: Read-modify-write operations are not allowed for shared variables

2014-08-12 Thread ketmar via Digitalmars-d-learn
On Tue, 12 Aug 2014 16:02:01 +
Sean Kelly via Digitalmars-d-learn digitalmars-d-learn@puremagic.com
wrote:

 ... and potentially quite broken.  At the very least, if this 
 value is ready anywhere you'll have to use an atomicLoad there in 
 place of the synchronized block you would have used.
sure, *any* access to shared variables should be done with atomic ops.
i thought that this is obvious. ;-)


signature.asc
Description: PGP signature


Re: Very vague compiler error message

2014-08-12 Thread Jeremy DeHaan via Digitalmars-d-learn

Awesome, thanks everyone.

I'll take the suggestion to use Dustmite as an excuse to
familiarize myself with it, but if normally extern(C++) types
cause it I know just where to look.


Re: Linked list as a bidirectional range? I have some questions...

2014-08-12 Thread Gary Willoughby via Digitalmars-d-learn

On Monday, 11 August 2014 at 20:02:38 UTC, H. S. Teoh via
Digitalmars-d-learn wrote:

opApplyReverse.


Was that a joke or does opApplyReverse exist?


Re: Linked list as a bidirectional range? I have some questions...

2014-08-12 Thread ketmar via Digitalmars-d-learn
On Tue, 12 Aug 2014 16:50:33 +
Gary Willoughby via Digitalmars-d-learn
digitalmars-d-learn@puremagic.com wrote:

 Was that a joke or does opApplyReverse exist?
it's not a joke.

http://dlang.org/statement.html
ctrl+f, opApplyReverse


signature.asc
Description: PGP signature


Re: Linked list as a bidirectional range? I have some questions...

2014-08-12 Thread Gary Willoughby via Digitalmars-d-learn

On Tuesday, 12 August 2014 at 17:00:26 UTC, ketmar via
Digitalmars-d-learn wrote:

On Tue, 12 Aug 2014 16:50:33 +
Gary Willoughby via Digitalmars-d-learn
digitalmars-d-learn@puremagic.com wrote:


Was that a joke or does opApplyReverse exist?

it's not a joke.

http://dlang.org/statement.html
ctrl+f, opApplyReverse


Ha, awesome!


Re: Emacs d-mode cannot handle backquoted backslashe

2014-08-12 Thread Nordlöw

On Friday, 1 August 2014 at 21:42:02 UTC, Nordlöw wrote:

I just posted a d-mode.el fix to Russel Winder.

See the recent posts at

https://stackoverflow.com/questions/25089090/emacs-d-mode-cannot-handle-backquoted-backslashes

If you can't wait ;)


Capture parameter identifier name in a template?

2014-08-12 Thread Maxime Chevalier-Boisvert via Digitalmars-d-learn
In my JavaScript VM, I have a function whose purpose is to expose 
D/host constants to the JavaScript runtime code running inside 
the VM. This makes for somewhat redundant code, as follows:


vm.defRTConst(OBJ_MIN_CAPw, OBJ_MIN_CAP);
vm.defRTConst(PROTO_SLOT_IDXw, PROTO_SLOT_IDX);
vm.defRTConst(FPTR_SLOT_IDXw, FPTR_SLOT_IDX);
vm.defRTConst(ATTR_CONFIGURABLEw  , ATTR_CONFIGURABLE);
vm.defRTConst(ATTR_WRITABLEw  , ATTR_WRITABLE);
vm.defRTConst(ATTR_ENUMERABLEw, ATTR_ENUMERABLE);
vm.defRTConst(ATTR_DELETEDw   , ATTR_DELETED);
vm.defRTConst(ATTR_GETSETw, ATTR_GETSET);
vm.defRTConst(ATTR_DEFAULTw   , ATTR_DEFAULT);

I'm just wondering if there's a way to template defRTConst so 
that the name of an identifier I'm passing (e.g.: ATTR_DEFAULT) 
can be captured by the template, making it so that I don't also 
need to pass the name as a string. I expect the answer to be no, 
but maybe someone with more knowledge of D template magic knows 
better.


Re: Capture parameter identifier name in a template?

2014-08-12 Thread ketmar via Digitalmars-d-learn
On Tue, 12 Aug 2014 17:36:40 +
Maxime Chevalier-Boisvert via Digitalmars-d-learn
digitalmars-d-learn@puremagic.com wrote:

 I'm just wondering if there's a way to template defRTConst so 
 that the name of an identifier I'm passing (e.g.: ATTR_DEFAULT)
seems that this is the work for mixins.


signature.asc
Description: PGP signature


Re: Capture parameter identifier name in a template?

2014-08-12 Thread H. S. Teoh via Digitalmars-d-learn
On Tue, Aug 12, 2014 at 05:36:40PM +, Maxime Chevalier-Boisvert via 
Digitalmars-d-learn wrote:
 In my JavaScript VM, I have a function whose purpose is to expose
 D/host constants to the JavaScript runtime code running inside the VM.
 This makes for somewhat redundant code, as follows:
 
 vm.defRTConst(OBJ_MIN_CAPw, OBJ_MIN_CAP);
 vm.defRTConst(PROTO_SLOT_IDXw, PROTO_SLOT_IDX);
 vm.defRTConst(FPTR_SLOT_IDXw, FPTR_SLOT_IDX);
 vm.defRTConst(ATTR_CONFIGURABLEw  , ATTR_CONFIGURABLE);
 vm.defRTConst(ATTR_WRITABLEw  , ATTR_WRITABLE);
 vm.defRTConst(ATTR_ENUMERABLEw, ATTR_ENUMERABLE);
 vm.defRTConst(ATTR_DELETEDw   , ATTR_DELETED);
 vm.defRTConst(ATTR_GETSETw, ATTR_GETSET);
 vm.defRTConst(ATTR_DEFAULTw   , ATTR_DEFAULT);
 
 I'm just wondering if there's a way to template defRTConst so that the
 name of an identifier I'm passing (e.g.: ATTR_DEFAULT) can be captured
 by the template, making it so that I don't also need to pass the name
 as a string.  I expect the answer to be no, but maybe someone with
 more knowledge of D template magic knows better.

I know it's possible to get function (runtime) parameter names using
__traits(), but I'm not sure if that can be done for compile-time
parameters. See: std.traits.ParameterIdentifierTuple.


T

-- 
It said to install Windows 2000 or better, so I installed Linux instead.


Re: implicit conversion

2014-08-12 Thread H. S. Teoh via Digitalmars-d-learn
On Tue, Aug 12, 2014 at 04:04:41PM +, Jonathan M Davis via 
Digitalmars-d-learn wrote:
 On Tuesday, 12 August 2014 at 15:39:09 UTC, Meta wrote:
 What I mean is that this breaks the Liskov Substitution
 Principle, which alias this should obey, as it denotes a subtype.
 Since S!float has an alias this to float, it should behave as a
 float in all circumstances where a float is expected; otherwise,
 we've got a big problem with alias this on our hands.
 
 IMHO, it was a mistake to add alias this to the language. It's
 occasionally useful, but it's too dangerous.

I disagree. Alias this is a very powerful tool that we haven't fully
leveraged yet. Not only it allows for implicit conversion to native
types (which makes it very useful for transparent type wrapping and
user-defined numeric types that are on par with built-in types), it also
allows for things like transparent safe dereference handling, as I
demonstrated some time ago.


 Implicit conversions wreak havoc with templates, because inevitably
 what happens is that a type is tested for whether it implicitly
 converts to a particular type, but then the template is instantiated
 with the original type, not the implicitly converted one, and then the
 template frequently fails to compile - or if it does compile, it may
 do weird things, because you're dealing with a type that doesn't act
 as expected.

That's because the template code was wrongly written. If it expects the
basic type, then it should be constrained to take only basic types
(is(T==int) instead of is(T : int)). If it wants a member variable to be
a basic type, then it should use the converted-to type instead of the
original type (if it tests is(T : int) but wants an int, then it should
use int as the target type, not T).

Problems with carelessly-written template code is no fault of alias
this.


 If you're dealing with a template which doesn't accept implicit
 conversions (e.g. isNaN), and the implicit conversion were tested
 after the actual type failed, and the template was then
 instantiated with the implicitly converted type, then maybe that
 could work, but that's not how it works now, and in general, I
 think alias this is just too dangerous to use.
[...]

I disagree. If a template function can take an implicitly-converted
type, then it should assign the original type to the target type if
that's what it wants to use. For example:

auto badCode(T)(T t)
if (is(T : float))
{
T u = 1.0; // does anyone expect this to NOT blow up?
u += t;// or this?
...
}

struct S {
float toFloat() { ... }
alias toFloat this;
}
auto r = badCode(S.init); // oops

auto goodCode(T)(T t)
if (is(T : float))
{
float tf = t; // now we're talking
float u = 1.0; // now this for sure won't blow up
u += tf;
...
}
auto s = goodCode(S.init); // OK

Basically, the root of the problem is that the way C++ and D templates
work, the template body is free to assume *anything* about the incoming
types, with or without verification (mostly without, IME). As a result,
template code often makes unfounded assumptions, like:

auto myFunc(T)(T t)
if (is(T : float))
{
float f = t; // this is about the only safe thing we can
 // do, given the stated assumptions
...
T u; // are we sure the type is instantiable?
u = 1.0; // are we sure the type accepts literal assignment?
auto r = t + 1.0; // are we sure the result type is anything we 
expect?
...
// etc.
}

This example is blatantly obvious, but in practice, things are a lot
more tricky. Classic example:

auto myFunc(R)(R range)
if (isInputRange!R)
{
// what makes us think typeof(range.front) is assignable?
auto f = range.front;
...
range.popFront();

// This fails on transient ranges, but happily compiles
// 'cos isInputRange doesn't ensure the assumption that
// assigned values of .front persist beyond .popFront.
// Basically, it's an unfounded assumption.
if (f == range.front) { ... }
}

Another typical example of poorly-written template code:

auto nextColumn(RoR)(RoR rangeOfRanges)
if (isForwardRange!RoR  isInputRange!(ElementType!RoR))
{
foreach (subrange; rangeOfRanges)
{
// what makes us think this has any persistent
// effect past this iteration of the loop?
subrange.popFront();
}

// For all we 

Re: Capture parameter identifier name in a template?

2014-08-12 Thread Dicebot via Digitalmars-d-learn
On Tuesday, 12 August 2014 at 17:36:41 UTC, Maxime 
Chevalier-Boisvert wrote:
In my JavaScript VM, I have a function whose purpose is to 
expose D/host constants to the JavaScript runtime code running 
inside the VM. This makes for somewhat redundant code, as 
follows:


vm.defRTConst(OBJ_MIN_CAPw, OBJ_MIN_CAP);
vm.defRTConst(PROTO_SLOT_IDXw, PROTO_SLOT_IDX);
vm.defRTConst(FPTR_SLOT_IDXw, FPTR_SLOT_IDX);
vm.defRTConst(ATTR_CONFIGURABLEw  , ATTR_CONFIGURABLE);
vm.defRTConst(ATTR_WRITABLEw  , ATTR_WRITABLE);
vm.defRTConst(ATTR_ENUMERABLEw, ATTR_ENUMERABLE);
vm.defRTConst(ATTR_DELETEDw   , ATTR_DELETED);
vm.defRTConst(ATTR_GETSETw, ATTR_GETSET);
vm.defRTConst(ATTR_DEFAULTw   , ATTR_DEFAULT);

I'm just wondering if there's a way to template defRTConst so 
that the name of an identifier I'm passing (e.g.: ATTR_DEFAULT) 
can be captured by the template, making it so that I don't also 
need to pass the name as a string. I expect the answer to be 
no, but maybe someone with more knowledge of D template magic 
knows better.


Something like this?

enum ATTRS
{
ATTR_GETSET,
ATTR_ENUMERABLE,
ATTR_CONFIGURABLE
}

void foo(ATTRS attr)
{
import std.conv;
foo_impl(attr, to!string(attr));
}

void foo_impl(ATTRS attr, string name)
{
import std.stdio;
writefln(name = %s, attr = %d, name, attr);
}

void main()
{
foo(ATTRS.ATTR_GETSET);
}


Re: implicit conversion

2014-08-12 Thread Jonathan M Davis via Digitalmars-d-learn
On Tuesday, 12 August 2014 at 19:03:58 UTC, H. S. Teoh via 
Digitalmars-d-learn wrote:
tl;dr: there are so many ways template code can go wrong, that 
I don't

it justifies blaming alias this for problems.


Allowing implicit conversions makes the problem much worse IMHO. 
It makes it far too easy to write a template constraint which 
passes due to the implicit conversion (even if an implicit 
conversion wasn't explicitly checked for) but then have the 
function fail to work properly because the implicit conversion 
never actually takes place within the function (and if the 
template constraint doesn't explicitly test for an implicit 
conversion, then the argument that the value should have been 
explicitly converted doesn't hold). Fortunately, in many cases, 
the result is a compilation error rather than weird behavior, but 
in some cases, it will be weird behavior - especially when the 
code involved is highly templatized and generic.


I'm not even vaguely convinced that allowing implicit conversions 
is worth the pain that they cause with templated code. Sure, they 
have their uses, and it would be a loss to have nothing like 
alias this, but on the whole, I'd much rather pay the cost of 
having no implicit conversions than having to deal with the havoc 
they wreak on templated code.


- Jonathan M Davis


Re: Emacs d-mode cannot handle backquoted backslashe

2014-08-12 Thread Nordlöw

On Tuesday, 12 August 2014 at 17:28:25 UTC, Nordlöw wrote:
And a PR:

https://github.com/Emacs-D-Mode-Maintainers/Emacs-D-Mode/pull/22


Re: implicit conversion

2014-08-12 Thread H. S. Teoh via Digitalmars-d-learn
On Tue, Aug 12, 2014 at 08:23:30PM +, Jonathan M Davis via 
Digitalmars-d-learn wrote:
 On Tuesday, 12 August 2014 at 19:03:58 UTC, H. S. Teoh via
 Digitalmars-d-learn wrote:
 tl;dr: there are so many ways template code can go wrong, that I
 don't it justifies blaming alias this for problems.
 
 Allowing implicit conversions makes the problem much worse IMHO. It
 makes it far too easy to write a template constraint which passes due
 to the implicit conversion (even if an implicit conversion wasn't
 explicitly checked for) but then have the function fail to work
 properly because the implicit conversion never actually takes place
 within the function (and if the template constraint doesn't explicitly
 test for an implicit conversion, then the argument that the value
 should have been explicitly converted doesn't hold). Fortunately, in
 many cases, the result is a compilation error rather than weird
 behavior, but in some cases, it will be weird behavior - especially
 when the code involved is highly templatized and generic.
[...]

Y'know, after seeing the recent problem with deprecated functions in
template code, and now this, I'm starting to reconsider whether Concepts
might have been a better way to go. The good thing about concepts is
that the template body won't even compile if it makes unfounded
assumptions on the type that aren't given by what the concept defines.

In the current template system, code like this would easily compile:

auto badCode(T)(T t)
{
// Does T even support such an operation? Who knows. The
// compiler will happily accept this code, and if you
// only unittest this function with numeric types,
// you'll never know there was a problem.
return t+1;
}

In a concepts-based system, however, this code wouldn't compile, even
before you instantiate any templates. You'd have to define a concept
that supports the opBinary!+(int) operation before the compiler would
accept the code. And doing so enforces all incoming types to conform to
that concept or be instantly rejected. This causes the templated code to
be unable to do anything with the incoming type that isn't explicitly
specified in the concept, thus preventing unfounded assumptions. It
furthermore solves the alias this problem, because it would be clear to
the compiler which concept the function is supposed to be operating on,
and if the incoming type implicitly converts to something that
implements that concept, then the compiler knows to perform the
conversion first before perform an operation on it.

Now, it's true that concepts-based systems have their limitations.  But
I wonder if it's possible to extend a concepts-based system to be more
powerful, in the same way D has enhanced and developed C++ templates in
novel ways.

One way I can think of, that kinda sits between the current duck-typing
template system and a full-fledged concepts system, is one where
incoming types do not have to declare what concept they implement (thus,
a kind of duck-typing), but template functions are not allowed to
operate on an incoming type unless they declare a concept it must
conform to. Hypothetical syntax:

// Concept definition
concept InputRange(E) {
alias ElementType = E;
bool empty;
E front;
void popFront();
}

// Concrete type that implements InputRange(E)
// N.B.: don't need to declare what concept it implements: this
// makes it compatible with current code.
struct MyRange {
@property bool empty() { ... }
@property int front() { ... }
void popFront() { ... }

// N.B.: this is *not* part of the concept definition
@property MyRange save() { ... }
}

auto r = rangeFunc(MyRange.init);

auto rangeFunc(R : InputRange!E, E)(R range)
{
while (!range.empty) // OK, .empty defined in InputRange!E
{
auto e = range.front; // OK, .front defined in 
InputRange!E

if (someCond) {
// ERROR: even though MyRange does
// define .save, InputRange doesn't, and
// we have only declared R to be an
// InputRange, so .save is an undefined
// operation on R.
auto tmp = range.save;
}

// OK: .popFront is defined in InputRange!E
range.popFront();
}
return ...;
}


T

-- 
There are two ways to write error-free programs; only the third one works.


Re: Destroy two assumptions: interface implementation generated by TMP

2014-08-12 Thread Baz via Digitalmars-d-learn

On Tuesday, 12 August 2014 at 12:43:46 UTC, anonymous wrote:

On Tuesday, 12 August 2014 at 12:08:14 UTC, John Colvin wrote:
I think the problem is that impl3.tmp is not virtual because 
it's

a template, and interfaces need to be implemented by virtual
methods.


The instantiations of the template are just normal functions 
though, no?


They are not virtual. Ordinary methods (public, not final, not
templated) are virtual.


The virtual stuff is right. I've just realized that it's written 
black on white at the bottom of the manual page which describes 
templates:


Templates cannot be used to add non-static members or virtual 
functions to classes

Templates cannot add functions to interfaces

Sorry for the loss of time.



Re: implicit conversion

2014-08-12 Thread Ary Borenszweig via Digitalmars-d-learn

On 8/12/14, 6:31 PM, H. S. Teoh via Digitalmars-d-learn wrote:

On Tue, Aug 12, 2014 at 08:23:30PM +, Jonathan M Davis via 
Digitalmars-d-learn wrote:

On Tuesday, 12 August 2014 at 19:03:58 UTC, H. S. Teoh via
Digitalmars-d-learn wrote:

tl;dr: there are so many ways template code can go wrong, that I
don't it justifies blaming alias this for problems.


Allowing implicit conversions makes the problem much worse IMHO. It
makes it far too easy to write a template constraint which passes due
to the implicit conversion (even if an implicit conversion wasn't
explicitly checked for) but then have the function fail to work
properly because the implicit conversion never actually takes place
within the function (and if the template constraint doesn't explicitly
test for an implicit conversion, then the argument that the value
should have been explicitly converted doesn't hold). Fortunately, in
many cases, the result is a compilation error rather than weird
behavior, but in some cases, it will be weird behavior - especially
when the code involved is highly templatized and generic.

[...]

Y'know, after seeing the recent problem with deprecated functions in
template code...


Duck typing FTW


LuaD + VisualD link issue

2014-08-12 Thread Johnathan Sunders via Digitalmars-d-learn
I'm having an issue with building programs that link with LuaD 
using VisualD. If I use Dub, it builds without an issue, but 
generating a project file and compiling it through VisualD 
results in Error 162: Bad Type Index reference to type 84A9 
when linking luad.lib(base).


Anyone has any ideas on what may cause this? I've also tried 
building using the VisualD project on LuaD's GitHub in case it 
was a missing configuration setting but that has the same issue 
(running Windows 8 64 bit in case it's relevant).


Re: Emacs d-mode cannot handle backquoted backslashe

2014-08-12 Thread Russel Winder via Digitalmars-d-learn
On Mon, 2014-08-04 at 12:25 +, Atila Neves via Digitalmars-d-learn
wrote:
 I took a look and I don't really know if it's possible without 
 using the Emacs  24 only suggestion in the Stack Overflow 
 comment to your question.
 
 As far as I can see, before that Emacs syntax tables have a 
 notion of what a string is and what an escape character is. The 
 d-mode code adds the backtick as an alternative to double and 
 single quotes but can't do anything about the backslash. Unless 
 it disables backslash as an escape character everywhere.
 
 I tried setting backtick to a function that returns \ instead 
 of the value to see if I could then tailor the function to depend 
 on whether not the point was in a backtick string but that didn't 
 work since `modify-syntax-entry` checks to see if the argument is 
 a string.
 
 BTW, python-mode has the same problem, I checked with r\.

Per Nordlöw has offered a putative fix via a pull request. I'll check
out the claim and if it seems to be true (and I fully expect it to be
so) I'll accept the pull request. People using MELPA should see the new
package quite quickly.

-- 
Russel.
=
Dr Russel Winder  t: +44 20 7585 2200   voip: sip:russel.win...@ekiga.net
41 Buckmaster Roadm: +44 7770 465 077   xmpp: rus...@winder.org.uk
London SW11 1EN, UK   w: www.russel.org.uk  skype: russel_winder


signature.asc
Description: This is a digitally signed message part