Re: counting characters

2016-07-19 Thread celavek via Digitalmars-d-learn

Thank you!

That clarified a lot of things for me.



Re: counting characters

2016-07-19 Thread Jonathan M Davis via Digitalmars-d-learn
On Tuesday, July 19, 2016 12:23:11 celavek via Digitalmars-d-learn wrote:
> On Tuesday, 19 July 2016 at 09:57:27 UTC, Lodovico Giaretta wrote:
> > On Tuesday, 19 July 2016 at 09:42:40 UTC, celavek wrote:
> >
> > Works for me:
> >
> > size_t[char] counts;
> > const string dna_chain =
> > "AGCCATTCTGACTGCAACGGGCAATATGTCTCTGTGTGGATTAAAGAGTGTCTGATAGCAGC";
> > counts['A'] = countchars(dna_chain, "A");
>
> It was failing for me as I was using "countchars!". I thought
> that I should use the "!" in order to instantiate a template in
> D. I'm still confused why it is working without the "!". Anyway
> the compiler message was not very helpful.

! is required for explicit template instantiation, but with functions, you
have use IFTI - Implicit Function Template Instantiation. So, when you have
a function like

auto foo(T)(T bar) {...}

and you call it without a template argument

foo(42);

the compiler infers the type. You can also explicitly instantiate it if you
want to

foo!int(42);

Many functions in Phobos have a template argument which is expected to be
explicit (one which is not the type of any of the function's parameters)
whereas all of the ones associated with the function's parameters are
inferred. e.g.

auto result = map!(a => a % 5)([12, 14, 15]);

map takes a template argument for the function that it calls on each of the
elements in the range it's given, and it takes a function argument that is
the range that's being operated on, and while the type of that range is
indeed a template argument, it's inferred by the compiler rather than being
explicitly given by the programmer. You _could_ give it explicitly, but
there really isn't a reason to, and the code is a lot uglier if you do.

In the case of countchars, you attempted to give the function arguments as
template arguments

size_t countchars(S, S1)(S s, in S1 pattern) @safe pure @nogc
if (isSomeString!S && isSomeString!S1)
{...}

If you do

countchars!(dna_chain, 'A')

then S and S1 are then the template arguments, and they're used as the types
of the function parameters, which doesn't work, since they're not types;
they don't pass the template constraint either (since neither of them is a
type which is a string - they're an actual string and a character, not
types). And to make matters worse, there are then no function arguments. So,
countchars is being given bogus types, the template arguments fail the
template constraint, and it's not being given the function arguments that it
needs.

So, the error is definitely telling you what's going wrong (or at least part
of it) - that the template arguments don't match the template constraint -
but your understanding of D's templates seems to be low enough that I
suppose that it's no surprise that the error message is confusing. I expect
that the reason that it's specifically the template constraints which are
complained about rather than the lack of function arguments or that the
template arguments aren't even types when they're then used as types for the
function parameters is because when you declare

size_t countchars(S, S1)(S s, in S1 pattern) @safe pure @nogc
if (isSomeString!S && isSomeString!S1)
{...}

the compiler lowers it to

template countchars(S, S1)
if (isSomeString!S && isSomeString!S1)
{
size_t countchars(S s, in S1 pattern) @safe pure @nogc
{...}
}

and that's going to fail to compile at the template constraint before it
even looks at the function, because isSomeString is not true for either
dna_chain or 'A' (even if it would be true for the _type_ of dna_chain, it's
not true for dna_chain itself).

If you haven't already, I would suggest that you read

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

I expect that the section

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

would be the most relevant to this discussion, but the book a as a whole
would be good to read if you're new to D.

- Jonathan M Davis



Re: counting characters

2016-07-19 Thread Steven Schveighoffer via Digitalmars-d-learn

On 7/19/16 8:23 AM, celavek wrote:

On Tuesday, 19 July 2016 at 09:57:27 UTC, Lodovico Giaretta wrote:

On Tuesday, 19 July 2016 at 09:42:40 UTC, celavek wrote:

Works for me:

size_t[char] counts;
const string dna_chain =
"AGCCATTCTGACTGCAACGGGCAATATGTCTCTGTGTGGATTAAAGAGTGTCTGATAGCAGC";
counts['A'] = countchars(dna_chain, "A");


It was failing for me as I was using "countchars!". I thought that I
should use the "!" in order to instantiate a template in D. I'm still
confused why it is working without the "!". Anyway the compiler message
was not very helpful.


https://dlang.org/spec/template.html#function-templates

Check out the section a little bit down that talks about implicitly 
deduced template parameters.


-Steve


Re: counting characters

2016-07-19 Thread Lodovico Giaretta via Digitalmars-d-learn

On Tuesday, 19 July 2016 at 12:23:11 UTC, celavek wrote:
On Tuesday, 19 July 2016 at 09:57:27 UTC, Lodovico Giaretta 
wrote:

On Tuesday, 19 July 2016 at 09:42:40 UTC, celavek wrote:

Works for me:

size_t[char] counts;
const string dna_chain = 
"AGCCATTCTGACTGCAACGGGCAATATGTCTCTGTGTGGATTAAAGAGTGTCTGATAGCAGC";

counts['A'] = countchars(dna_chain, "A");


It was failing for me as I was using "countchars!". I thought 
that I should use the "!" in order to instantiate a template in 
D. I'm still confused why it is working without the "!". Anyway 
the compiler message was not very helpful.


The declaration is:

countchars(S, S1)(S str, S1 pattern)

So the most verbose way to instantiate it is:

countchars!(string, string)(dna_chain, "A")

But as S and S1 are the types of the two arguments, the compiler 
can easily infer them, so you can write:


countchars(dna_chain, "A")

And have the compiler infer:

countchars!(typeof(dna_chain), typeof("A"))(dna_chain, "A")

The error message is technically correct: you cannot instantiate 
countchars with template parameters `dna_chain` and `"A"`, which 
is what you were actually doing.


Re: counting characters

2016-07-19 Thread celavek via Digitalmars-d-learn

On Tuesday, 19 July 2016 at 09:57:27 UTC, Lodovico Giaretta wrote:

On Tuesday, 19 July 2016 at 09:42:40 UTC, celavek wrote:

Works for me:

size_t[char] counts;
const string dna_chain = 
"AGCCATTCTGACTGCAACGGGCAATATGTCTCTGTGTGGATTAAAGAGTGTCTGATAGCAGC";

counts['A'] = countchars(dna_chain, "A");


It was failing for me as I was using "countchars!". I thought 
that I should use the "!" in order to instantiate a template in 
D. I'm still confused why it is working without the "!". Anyway 
the compiler message was not very helpful.





Re: counting characters

2016-07-19 Thread celavek via Digitalmars-d-learn

On Tuesday, 19 July 2016 at 09:55:43 UTC, Jonathan M Davis wrote:
On Tuesday, July 19, 2016 09:41:32 John via Digitalmars-d-learn 
wrote:


auto result = count(dna_chain, 'A');

or if you know that the string is always going to just contain 
ASCII (as seems likely based on the example), then 
string.representation can be used to convert the string to 
immutable(ubyte)[] in order to avoid the auto-decoding that 
occurs with string and range-based functions. e.g.


auto result = count(dna_chain.representation, 'A');

That's almost certainly the fastest way to do it with Phobos.

- Jonathan M Davis


Thank you. I used what you suggested as I have only ASCII 
characters.


Re: counting characters

2016-07-19 Thread Lodovico Giaretta via Digitalmars-d-learn

On Tuesday, 19 July 2016 at 09:42:40 UTC, celavek wrote:

On Tuesday, 19 July 2016 at 09:41:32 UTC, John wrote:

On Tuesday, 19 July 2016 at 09:34:11 UTC, celavek wrote:

Hi,

I am trying to count characters in a string like:

const string dna_chain = 
"AGCCATTCTGACTGCAACGGGCAATATGTCTCTGTGTGGATTAAAGAGTGTCTGATAGCAGC";

counts['A'] = countchars!(dna_chain, 'A');


countchars(dna_chain, "A");


Not working. Same error.


Works for me:

size_t[char] counts;
const string dna_chain = 
"AGCCATTCTGACTGCAACGGGCAATATGTCTCTGTGTGGATTAAAGAGTGTCTGATAGCAGC";

counts['A'] = countchars(dna_chain, "A");


Re: counting characters

2016-07-19 Thread Jonathan M Davis via Digitalmars-d-learn
On Tuesday, July 19, 2016 09:41:32 John via Digitalmars-d-learn wrote:
> On Tuesday, 19 July 2016 at 09:34:11 UTC, celavek wrote:
> > Hi,
> >
> > I am trying to count characters in a string like:
> >
> > const string dna_chain =
> > "AGCCATTCTGACTGCAACGGGCAATATGTCTCTGTGTGGATTAAAGAGTGTCTGATAGCAGC";
> > counts['A'] = countchars!(dna_chain, 'A');
>
> countchars(dna_chain, "A");

That fixes the call to countchars, but given that the OP is only looking to
count a specific character and is not really using a "pattern" (which is
what countchars looks for), it's bound to be more efficient to just use a
function which counts the number of elements in the array which match a
certain character rather than seaching for a pattern. std.algorithm.count
would be the most idiomatic choice. So, you get something like

auto result = count(dna_chain, 'A');

or if you know that the string is always going to just contain ASCII (as
seems likely based on the example), then string.representation can be used
to convert the string to immutable(ubyte)[] in order to avoid the
auto-decoding that occurs with string and range-based functions. e.g.

auto result = count(dna_chain.representation, 'A');

That's almost certainly the fastest way to do it with Phobos.

- Jonathan M Davis



Re: counting characters

2016-07-19 Thread celavek via Digitalmars-d-learn

On Tuesday, 19 July 2016 at 09:41:32 UTC, John wrote:

On Tuesday, 19 July 2016 at 09:34:11 UTC, celavek wrote:

Hi,

I am trying to count characters in a string like:

const string dna_chain = 
"AGCCATTCTGACTGCAACGGGCAATATGTCTCTGTGTGGATTAAAGAGTGTCTGATAGCAGC";

counts['A'] = countchars!(dna_chain, 'A');


countchars(dna_chain, "A");


Not working. Same error.


Re: counting characters

2016-07-19 Thread John via Digitalmars-d-learn

On Tuesday, 19 July 2016 at 09:34:11 UTC, celavek wrote:

Hi,

I am trying to count characters in a string like:

const string dna_chain = 
"AGCCATTCTGACTGCAACGGGCAATATGTCTCTGTGTGGATTAAAGAGTGTCTGATAGCAGC";

counts['A'] = countchars!(dna_chain, 'A');


countchars(dna_chain, "A");