normal function and template function conflict

2012-07-26 Thread monarch_dodra
I was trying to write a PRNG, and I wanted to give it two seed 
methods. The first is to seed from a unique UIntType, and the 
other is to seed from an entire range of seeds. Like so:



void seed(UIntType value = default_seed)
{...}

void seed(Range)(Range range)
  if (isInputRange!Range)
{...}

Where UIntType is a template parameter of the struct.

However, this makes the compiler complain, because of a 
conflict...? Is mixing normal functions with parametrized ones 
impossible?


I *fixed* the issue by contemplating the first call with:

void seed(T)(T value = default_seed)
  if (is(typeof(T == UIntType)))
{...}

Problems:
1) It is ugly as sin.
2) The default parameter doesn't work anymore.

So here are my two questions:
1) Is what I was originally trying to do actually illegal, or is 
it some sort of compiler limitation? TDPL implies this should 
work perfectly fine...

2) Is there a correct workaround?


Re: normal function and template function conflict

2012-07-26 Thread Simen Kjaeraas
On Thu, 26 Jul 2012 19:18:21 +0200, monarch_dodra monarchdo...@gmail.com  
wrote:



So here are my two questions:
1) Is what I was originally trying to do actually illegal, or is it some  
sort of compiler limitation? TDPL implies this should work perfectly  
fine...


Compiler limitation. It's supposed to work.



2) Is there a correct workaround?


Exactly what you did. Though, for brevity, you would write this:

void seed(T : UIntType)(T value = default_seed)


--
Simen


Re: normal function and template function conflict

2012-07-26 Thread monarch_dodra

On Thursday, 26 July 2012 at 17:57:31 UTC, Simen Kjaeraas wrote:
On Thu, 26 Jul 2012 19:18:21 +0200, monarch_dodra 
monarchdo...@gmail.com wrote:

2) Is there a correct workaround?


Exactly what you did. Though, for brevity, you would write this:

void seed(T : UIntType)(T value = default_seed)


Thanks

I haven't seen this construct before. Can you tell me a bit more
about it, or link me to some documentation about it?

I suppose it means T must be UIntType, but I'd enjoy having a 
broader understanding of it :)


Re: normal function and template function conflict

2012-07-26 Thread Ali Çehreli

On 07/26/2012 11:14 AM, monarch_dodra wrote:

On Thursday, 26 July 2012 at 17:57:31 UTC, Simen Kjaeraas wrote:

On Thu, 26 Jul 2012 19:18:21 +0200, monarch_dodra
monarchdo...@gmail.com wrote:

2) Is there a correct workaround?


Exactly what you did. Though, for brevity, you would write this:

void seed(T : UIntType)(T value = default_seed)


Thanks

I haven't seen this construct before. Can you tell me a bit more
about it, or link me to some documentation about it?

I suppose it means T must be UIntType, but I'd enjoy having a broader
understanding of it :)


Search for specialization in the following resources:

  http://dlang.org/template.html


https://github.com/PhilippeSigaud/D-templates-tutorial/blob/master/dtemplates.pdf

  http://ddili.org/ders/d.en/templates.html

Ali


Re: normal function and template function conflict

2012-07-26 Thread Simen Kjaeraas
On Thu, 26 Jul 2012 20:14:10 +0200, monarch_dodra monarchdo...@gmail.com  
wrote:



On Thursday, 26 July 2012 at 17:57:31 UTC, Simen Kjaeraas wrote:
On Thu, 26 Jul 2012 19:18:21 +0200, monarch_dodra  
monarchdo...@gmail.com wrote:

2) Is there a correct workaround?


Exactly what you did. Though, for brevity, you would write this:

void seed(T : UIntType)(T value = default_seed)


Thanks

I haven't seen this construct before. Can you tell me a bit more
about it, or link me to some documentation about it?

I suppose it means T must be UIntType, but I'd enjoy having a broader  
understanding of it :)


Ali gave the general, I'll give the specifics.

is(T : Foo), void bar(T : Foo)(T t), and a few others (not really others,
they're exactly the same!) means 'T is implicitly convertible to Foo'.

What's the difference, you ask?

Consider:

void foo(T)(T value) if (is(T == uint)) {}

Could you call this function like this:

foo(3);

The answer is no. The compiler translates this to:

foo!(typeof(3))(3);

And typeof(3) is not uint, it's int.

In contrast,

void foo(T : uint)(T value) {}
foo(3);

is also translated to

foo!(typeof(3))(3);

and the compiler then checks if int is implicitly convertible to uint.
And so it is, so the compiler moves happily onwards.

There is a reason I included is(T : Foo) in the beginning, for you
can write the exact same constraint like this:

void foo(T)(T value) if (is(T : uint)) {}

and it will compile just the same.


For more information on this construct, I would, in addition to the
links Ali provided, recommend you read this:

http://dlang.org/expression.html#IsExpression

IsExpressions are, however, probably the most hairy part of D, and
their understanding has proven troublesome to many (myself included,
though I believe I have grasped them now). Hence, most of their
functionality is wrapped in more easily understandable templates in
std.traits.

--
Simen


Re: normal function and template function conflict

2012-07-26 Thread monarch_dodra

On Thursday, 26 July 2012 at 18:21:18 UTC, Ali Çehreli wrote:

Search for specialization in the following resources:


Oh... Specialization.

What with D's ability to conditionally implement, I had
completely forgotten about specialization. So that's how it's
done in D. Cool.

Thanks a lot.


Re: normal function and template function conflict

2012-07-26 Thread Jacob Carlborg

On 2012-07-26 19:57, Simen Kjaeraas wrote:


2) Is there a correct workaround?


Exactly what you did. Though, for brevity, you would write this:

void seed(T : UIntType)(T value = default_seed)


Since a template function is actually not wanted this would be the 
correct workaround:


void seed () (UIntType value = default_seed)

Less typing as well.

--
/Jacob Carlborg


Re: normal function and template function conflict

2012-07-26 Thread Andrej Mitrovic
On 7/26/12, Jacob Carlborg d...@me.com wrote:
 void seed () (UIntType value = default_seed)

 Less typing as well.

Yep. It's funny how this works at all. I mean a template with no
template parameters is somehow still a template. :)


Re: normal function and template function conflict

2012-07-26 Thread Jonathan M Davis
On Thursday, July 26, 2012 21:49:35 Andrej Mitrovic wrote:
 On 7/26/12, Jacob Carlborg d...@me.com wrote:
  void seed () (UIntType value = default_seed)
  
  Less typing as well.
 
 Yep. It's funny how this works at all. I mean a template with no
 template parameters is somehow still a template. :)

It _is _ bit funny, but Ibelieve that  it comes from permitting empty template 
parameter lists. Without that, recursion with eponymous templates would become 
problematic. e.g.

enum template myTemplate(T...)
{
static if(T.length == 0)
enum myTemplate = 42;
else
enum myTemplate = T[0] * 3 + myTemplate!(T[1 .. $]);
}

needs to be able to take an empty parameter list. It's probably possible to 
make that work without allowing an outright empty parameter list that isn't 
even a variadic template, but I suspect that it's just easier to allow it.

- Jonathan M Davis