Re: A look inside "filter" function defintion

2022-08-09 Thread Meta via Digitalmars-d-learn

On Monday, 1 August 2022 at 23:35:13 UTC, pascal111 wrote:
This is the definition of "filter" function, and I think it 
called itself within its definition. I'm guessing how it works?


'''D
template filter(alias predicate)
if (is(typeof(unaryFun!predicate)))
{
/**
Params:
range = An $(REF_ALTTEXT input range, isInputRange, 
std,range,primitives)

of elements
Returns:
A range containing only elements `x` in `range` for
which `predicate(x)` returns `true`.
 */
auto filter(Range)(Range range) if 
(isInputRange!(Unqual!Range))

{
return FilterResult!(unaryFun!predicate, Range)(range);
}
}
'''

I think this line needs explanation:

'''D
return FilterResult!(unaryFun!predicate, Range)(range);
'''


To give a vastly simplified answer, the term "eponymous template" 
essentially means that if you have an item declared inside a 
template that has a same name as the template:

```D
template SomeTemplate(T)
{
alias SomeTemplate = T;
}
```

It is not a compile error. Instead, when you use the template:
```D
SomeTemplate!int n;
```

The compiler rewrites your code like to:
```D
SomeTemplate!int.SomeTemplate n;
```

Because normally when you instantiate a template, you have to 
refer to the declarations inside it by name:

```D
template SomeOtherTemplate(T)
{
alias SomeAlias = T;
}

//SomeOtherTemplate!int n; Error: `SomeOtherTemplate!int` is used 
as a type

SomeOtherTemplate!int.SomeAlias n; //Ok
```

Except in the special case I outlined above. It's essentially a 
hack that was brought over from C++. It makes using templates 
more ergonomic.




Re: Fix template parameter

2022-08-09 Thread Meta via Digitalmars-d-learn

On Monday, 8 August 2022 at 12:02:02 UTC, Dom Disc wrote:

Hello.
I found in the documentation functions declared like this:

```D
pure @nogc @safe BigInt opAssign(T : BigInt)(T x);
```


This is a template function, even if T is constrained to always 
be BigInt (it may also include anything that is a subtype of 
BigInt... I've received different answers on what exactly `(T: 
SomeType)` means in this context). This means that it cannot be 
virtual, you can't take its address, and as bauss said, it won't 
show up in the object file if it's not used.


As far as I know, there's no advantage to doing this over 
`opAssign(BigInt x)`, UNLESS `(T: BigInt)` means "BigInt and any 
subtype of BigInt", in which case the advantage is similar to 
doing ` void opAssign(T val)` in Java 
(referring to polymorphism; this won't give you virtual dispatch 
like it does in Java).





Re: Colors in Raylib

2022-03-03 Thread meta via Digitalmars-d-learn

On Tuesday, 1 March 2022 at 15:37:55 UTC, Ali Çehreli wrote:

On 3/1/22 07:19, Mike Parker wrote:
> On Tuesday, 1 March 2022 at 13:15:09 UTC, meta wrote:
>
>>
>> enum Color
>> { GRAY }
>>
>> void setColor(Color color);
>>
>> setColor(GRAY);
>
> Then that defeats the purpose of having named enums.

Yes and no.

meta is pointing at a difference between the above and the 
following:


  writeln(GRAY);

In the latter case, the compiler has no clue whether I intended 
to type GRAM. But in the former case, the type is Color. What 
remains is whether the compiler should be looking deep into 
Color and have a list of values to lower GRAY to Color.GRAY.


We heard this before for the switch statement: When the 
variable is Color, the case values can be accepted as Color as 
well (without the qualifier). (Yes, 'with' works as well, but 
the idea is the same.)


It feels the same for even int because we don't write int(42) 
when passing an int argument:


void foo(int) {}

foo(int(42));  // works
foo(42);   // works as well

So the lack of this compiler help does not bother me but still, 
I think the request is meaningful.


Ali


Yes, that's exactly the point I was trying to make, thanks Ali!


Re: Colors in Raylib

2022-03-01 Thread meta via Digitalmars-d-learn
On Tuesday, 1 March 2022 at 12:29:56 UTC, Steven Schveighoffer 
wrote:

On 3/1/22 7:22 AM, meta wrote:
If the type is ``Color`` I think the compiler should allow 
``GRAY`` if it is a member of ``Color``, isn't how strong 
statically typed language should work? I wonder what is the 
rational against it? How hard would it be to allow it?


The problem is how the original source works.

The only way to define a manifest constant for a struct 
instance in C is to #define it.


So I'm sure that if raylib could put that inside the `Color` 
type it would, but it can't.


What a D binding should do is exactly what Mike said -- provide 
a complete binding as expected, and then add machine-generated 
nicer APIs.


I actually have an open issue, in case anyone is interested in 
working on it: https://github.com/schveiguy/raylib-d/issues/8


-Steve


Oh I was talking with regard to D's enum, not about the binding, 
allowing it via D, would make interfacing with C code easier


enum Color
{ GRAY }

void setColor(Color color);

setColor(GRAY);




Re: Colors in Raylib

2022-03-01 Thread meta via Digitalmars-d-learn
If the type is ``Color`` I think the compiler should allow 
``GRAY`` if it is a member of ``Color``, isn't how strong 
statically typed language should work? I wonder what is the 
rational against it? How hard would it be to allow it?


Re: https://run.dlang.io/ vs All dmd compilers (2.060 - latest)

2022-02-27 Thread meta via Digitalmars-d-learn

Is the source of 'run.dlang.io' available somewhere?


Re: split Error - no overload matches

2022-02-15 Thread meta via Digitalmars-d-learn

A trick i use often:

```D
import std;

void main()
{
import uni =  std.uni;
writeln("Learning D is fun".split!(uni.isWhite));
}

```

Under-rated way of importing things, you don't bloat your scope 
anymore





Re: What is the meaning of @future ?

2021-09-17 Thread Meta via Digitalmars-d-learn

On Friday, 17 September 2021 at 10:31:34 UTC, bauss wrote:

On Thursday, 16 September 2021 at 20:53:34 UTC, Elmar wrote:

Hello D community.

I was browsing the `__traits` keywords and I found `isFuture` 
whose descriptions says something about `@future`-annotated 
variables.


[link](https://dlang.org/spec/traits.html#isFuture)

I didn't find anything about `@future` for the D programming 
language. I only found that this annotation is used in Apex to 
denote futures (a.k.a. promises) as programming concept.


Is this something which exists, existed, was abandoned early 
as an idea? I remember I had read that D uses a "fiber" 
library to provide coroutines and such.


Maybe somebody knows an answer for this.


It's just another "useless" attribute that the language has 
added before fixing any of the real problems :)


Basically it reserves a symbol for the future.

It's similar to creating ex. an empty function that throws an 
error or something like "Not implemented"


While I understand why it was added and what purpose it serves 
then I fail to see why that  was prioritized over actual issues.


It's solving an almost non-existing issue.


I think the main reason it was added is because Sociomantic asked 
for it, but they are of course not around anymore.


Re: nothrow and std.exception.ifThrown

2021-04-30 Thread Meta via Digitalmars-d-learn
On Friday, 30 April 2021 at 13:42:49 UTC, Steven Schveighoffer 
wrote:

On 4/30/21 9:24 AM, Meta wrote:

My point is that I think marking the *function* nothrow is not 
correct, it's the second parameter that dictates the throwing 
of the result.


And you can probably fix the second parameter to be a templated 
delegate:


```d
CommonType!(T1, T2) ifThrown(E : Throwable = Exception, T1, 
T2)(lazy scope T1 expression, scope T2 errorHandler) if 
(is(typeof(errorHandler(E.init

```

And of course, we get into chicken-and-egg problems with this 
because if you pass in a lambda, there's no types for it to 
figure this stuff out. Another option is to overload on the 
delegate, but meh. I'd really like to see a language change 
that says "infer the attributes of this function based on the 
fact that it calls the delegate passed in."


-Steve


Now that you mention it, I don't see why lazy parameters can't 
have their attributes inferred. What happened to the DIP to 
replace lazy parameters with automatic conversion of passed 
values to delegates, anyway? I.e.:

```
CommonType!(T1, T2) ifThrown(E: Throwable = Exception, T1, 
T2)(scope T1 delegate() expression, scope T2 delegate() 
errorHandler);


//getString() and "some string" automatically converted to 
`string delegate()`

auto s = getString().ifThrown("some string");
```


Re: nothrow and std.exception.ifThrown

2021-04-30 Thread Meta via Digitalmars-d-learn

On Thursday, 29 April 2021 at 20:00:23 UTC, novice2 wrote:

i dont understand why (templates too dificult for me yet),
but if i comment "lazy" from T2,
then compiler allow add "nothrow" to "ifThrown"

```d
CommonType!(T1, T2) ifThrown(E : Throwable = Exception, T1, 
T2)(lazy scope T1 expression, /*lazy*/ scope T2 errorHandler) 
nothrow

```
https://run.dlang.io/is/KTdd3G


This is because marking a function parameter as `lazy` is just 
syntax sugar for the following:

```
CommonType!(T1, T2) ifThrown(E: Throwable = Exception, T1, 
T2)(scope T1 delegate() expression, scope T2 delegate() 
errorHandler);


string def = "some string";
auto s = format("%d", x).ifThrown({ return def; });
```

Behind the scenes, a `lazy` parameter is not really a value - 
it's a function that _returns_ a value. The problem is that this 
function is not `nothrow`, and can't be marked as such (this is 
arguably a gap in the language). Removing `lazy` changes 
`errorHandler` to be a plain old value again - which cannot throw 
an exception, of course - so `ifThrown` can be marked `nothrow`. 
However, you lose all the benefits of `errorHandler` being lazily 
computed.


Re: nothrow and std.exception.ifThrown

2021-04-30 Thread Meta via Digitalmars-d-learn
On Friday, 30 April 2021 at 13:05:00 UTC, Steven Schveighoffer 
wrote:

On 4/29/21 1:50 PM, Meta wrote:



The reason for this, apparently, is in the definition of 
`ifThrown`:

```
CommonType!(T1, T2) ifThrown(E : Throwable = Exception, T1, 
T2)(lazy scope T1 expression, lazy scope T2 errorHandler) 
nothrow

```

It's not marked as `nothrow` in the function's definition, so 
even if the delegate passed to ifThrown _is_ nothrow, the 
compiler can't tell. There's no easy way around this that I 
can think of OTOH that doesn't involve some effort on your 
part.


Wait, I don't get what you are saying. You mean it should be 
marked nothrow? It's a template, so it *should* be inferred 
nothrow if it were actually nothrow.


The current definition is not marked nothrow as you alluded, 
and when I do mark it nothrow, it complains that the lazy 
parameter used for the exception handler is not nothrow.


It seems there's no way to infer the throwing of the lazy 
parameter, lazy parameters are never nothrow.


The higher order function DIP would I think help with this.

-Steve


Change it to a delegate and it's the same thing. ifThrown being a 
template is irrelevant in this case because it is accepting the 
handler as a function argument, not a template argument. You:


1. Need to make it a delegate instead of a lazy argument.

2. Need to mark the delegate as nothrow.

For the function to be inferred as nothrow.


Re: nothrow and std.exception.ifThrown

2021-04-29 Thread Meta via Digitalmars-d-learn

On Thursday, 29 April 2021 at 16:02:20 UTC, novice2 wrote:

Hello.
I need use std.format.format() in nothrow function.
format() can throw.
For this case i have special default string.
I don't want embrace format into try..catch block,
and i found elegant std.exception.ifThrown.
But DMD say "ifThrown not nothrow"

https://run.dlang.io/is/kXtt5q
```d
nothrow string foo(int x, string def) {
import std.format: format;
import std.exception: ifThrown;

return format("%d", x).ifThrown(def);
}

Error: function std.exception.ifThrown!(Exception, string, 
string).ifThrown is not nothrow

```

What i can use instead of ifThrown, or how it can be changed to 
nothrow?

Thanks.


The reason for this, apparently, is in the definition of 
`ifThrown`:

```
CommonType!(T1, T2) ifThrown(E : Throwable = Exception, T1, 
T2)(lazy scope T1 expression, lazy scope T2 errorHandler) nothrow

```

It's not marked as `nothrow` in the function's definition, so 
even if the delegate passed to ifThrown _is_ nothrow, the 
compiler can't tell. There's no easy way around this that I can 
think of OTOH that doesn't involve some effort on your part. One 
thing you can do is wrap ifThrown with 
`std.exception.assumeWontThrow`:

```
import std.exception: ifThrown, assumeWontThrow;
import std.functional: pipe;

alias ifThrown = pipe!(std.exception.ifThrown, assumeWontThrow);

nothrow string foo(int x, string def) nothrow {
import std.format: format;

return format("%d", x).ifThrown(def);
}

```


Re: Is there a more elegant way to do this in D?

2021-04-08 Thread Meta via Digitalmars-d-learn

On Thursday, 8 April 2021 at 18:01:56 UTC, Meta wrote:

On Thursday, 8 April 2021 at 12:19:29 UTC, WebFreak001 wrote:


```d
string to01String(int[] x) @safe
{
auto conv = x.to!(ubyte[]); // allocates new array, so 
later cast to string is OK
conv[] += '0'; // assume all numbers are 0-9, then this 
gives the correct result

return (() @trusted => cast(string)conv)();
}
```


The @trusted lambda can also be replaced with 
[std.exception.assumeUnique](https://dlang.org/library/std/exception/assume_unique.html).


Never mind me, assumeUnique is @system (or at least it's inferred 
as @system), and anyway, you can't implicitly convert 
`immutable(ubyte)[]` to `immutable(char)[]`.


Re: Is there a more elegant way to do this in D?

2021-04-08 Thread Meta via Digitalmars-d-learn

On Thursday, 8 April 2021 at 12:19:29 UTC, WebFreak001 wrote:


```d
string to01String(int[] x) @safe
{
auto conv = x.to!(ubyte[]); // allocates new array, so 
later cast to string is OK
conv[] += '0'; // assume all numbers are 0-9, then this 
gives the correct result

return (() @trusted => cast(string)conv)();
}
```


The @trusted lambda can also be replaced with 
[std.exception.assumeUnique](https://dlang.org/library/std/exception/assume_unique.html).


Re: Is this bug ? format %(%)

2021-04-07 Thread Meta via Digitalmars-d-learn

On Wednesday, 7 April 2021 at 17:31:09 UTC, Paul Backus wrote:

On Wednesday, 7 April 2021 at 17:04:56 UTC, novice2 wrote:

On Wednesday, 7 April 2021 at 13:43:18 UTC, Paul Backus wrote:

So, you should change your code to

writefln("%-(%s, %)", s);


sorry i dont read docs so carefully
thanks


It's not your fault--this is a pretty obscure feature, and it's 
not documented very well. Even after you've found the correct 
page in the documentation (the page for `formattedWrite` [1]), 
you have to scroll down past multiple examples to find the text 
that explains it.


[1] https://dlang.org/phobos/std_format.html#formattedWrite


I have created a pull request that will hopefully make this more 
prominent on the doc page:

https://github.com/dlang/phobos/pull/7944


Re: Immutable

2021-03-27 Thread Meta via Digitalmars-d-learn

On Saturday, 27 March 2021 at 20:44:12 UTC, Brad wrote:
I was looking through lots of sample code on Rosetta Code.  D 
has a lot of solutions out there.  That is really nice but it 
has me wondering - coming from other languages that do not 
support the concept of immutability - do real world programmers 
and/or hobbyists really use it as much as I see it on Rosetta 
Code?  I know it adds a layer of security to your code, but I 
am still thinking "why?".


Thanks for entertaining a newbie question.


FYI, most of those examples were written by someone who goes by 
"Bearophile", and their style of writing D uses 
immutable/const/pure/nothrow/etc. wherever possible. It's not 
necessarily the style that all D programmers use, though there 
are a number of people that do.


As for advantages, when it comes to the basic value types (int, 
float, bool, etc.), it's not all that useful. Where immutable can 
become very useful, though, is with types that have indirections 
(i.e. pointers). D's `string` type, for example, is actually a 
simple alias in Druntime:


alias string = immutable(char)[];

Meaning "a mutable array of immutable chars". This means that you 
can modify the array itself, such as changing its length, 
appending to it, etc., but you cannot its individual elements. 
E.g., the following will work:


string s1 = "this is a string";
s1 ~= '.';
assert(s1 == "this is a string.");

But this will NOT work:

string s2 = "this is a string ";
s2[$ - 1] = '.'; Error: cannot modify immutable expression 
s2[__dollar - 1LU]


This is just a simple example, but it allows the compiler to do 
some major optimizations on string handling code. Something that 
is usually very slow in C/C++ is such code, because strings are 
mutable arrays of mutable characters. Thus, they have to be 
copied around everywhere, which is slow and uses a lot of memory 
unnecessarily.


Not so in D; because strings are mutable arrays of immutable 
characters, you can freely pass out references to the whole 
string, or a subrange of it. This would be very dangerous in 
C/C++, but in D you don't have to worry about the string changing 
out from under you by some code somewhere else in the program 
that you gave a reference to. Thus, string handling code is far 
faster in D than in C/C++.


That is just one example, but you can see how immutable makes 
possible a lot of optimizations that would simply be impossible 
in languages without it.


Re: Very confusing error message when calling a class method from an invariant

2021-03-09 Thread Meta via Digitalmars-d-learn

On Wednesday, 10 March 2021 at 04:57:19 UTC, Paul Backus wrote:

On Wednesday, 10 March 2021 at 03:39:15 UTC, Meta wrote:

class Human {
static immutable MAX_AGE = 122;

bool alive = true;
int age = 0;
//Error: mutable method onlineapp.Human.checkAge is not 
callable using a const object

invariant(checkAge());

[...]


What the hell does this even mean, and where does it come 
from? Adding `inout` to `checkAge` actually does cause it to 
compile and run too. WTF?


From the language spec [1]:


The invariant is in the form of a const member function.


So, inside the invariant, the object is treated as const, which 
means you can't modify it and can only call const methods.


[1] https://dlang.org/spec/class.html#invariants


Now that you mention it, I'm pretty sure I've run into this 
before; I must've forgotten about it. I understand the rationale 
behind this, but it doesn't really make sense IMO that only 
invariants treat the object as const, and not pre/post conditions 
as well. Ah well. Thanks for quick answer.


Very confusing error message when calling a class method from an invariant

2021-03-09 Thread Meta via Digitalmars-d-learn

class Human {
static immutable MAX_AGE = 122;

bool alive = true;
int age = 0;
//Error: mutable method onlineapp.Human.checkAge is not 
callable using a const object

invariant(checkAge());

void growOlder()
in(alive)
out(; checkAge())
{
age++;
if (age > MAX_AGE)
die();
}

void die()
in(alive)
out(; !alive) {
alive = false;
}

bool checkAge() {
return age >= 0 && age <= MAX_AGE || !alive;
}
}

void main() {
Human h = new Human();
h.growOlder();
}

What the hell does this even mean, and where does it come from? 
Adding `inout` to `checkAge` actually does cause it to compile 
and run too. WTF?


Re: opBinary : Static ifs or specialization?

2020-06-23 Thread Meta via Digitalmars-d-learn

On Tuesday, 23 June 2020 at 23:53:36 UTC, claptrap wrote:
So you have opBinary and half a dozen operators to implement. 
Do you use a separate method for each operator or do you have 
one method and a big static if else if to select code path?


I assume they are functionally equivalent? So its just about 
style?


An idiomatic example:

import std.algorithm: among;

struct Test
{
int payload;

Test opBinary(string op)(Test other)
if (op.among!("+", "-", "*", "/")) //Limit supported ops
{
mixin("return Test(payload " ~ op ~ "other.val);");
}

int opBinary(string op)(int n)
//No constraint; support the full range of integer operations
{
mixin("return payload " ~ op ~ "n;");
}
}


Re: Should a parser type be a struct or class?

2020-06-18 Thread Meta via Digitalmars-d-learn

On Wednesday, 17 June 2020 at 11:50:27 UTC, Per Nordlöw wrote:
Should a range-compliant aggregate type realizing a parser be 
encoded as a struct or class? In dmd `Lexer` and `Parser` are 
both classes.


In general how should I reason about whether an aggregate type 
should be encoded as a struct or class?


IMO it doesn't need to be. However, it's worth saying that range 
semantics aren't a great fit for parsers - at least that's been 
my experience. Parsers need to be able to "synchronize" to 
recover from syntax errors, which does not fit into the range API 
very well. You can probably fit it in somewhere in popFront or 
front or empty, as your implementation permits, but I find it's 
just easier to forego the range interface and implement whatever 
primitives you need; *then* you can add a range interface over 
top that models the output of the parser as a range of 
expressions, or whatever you want.


Re: Retrieve the return type of the current function

2020-05-05 Thread Meta via Digitalmars-d-learn

On Tuesday, 5 May 2020 at 18:19:00 UTC, Meta wrote:

mixin template magic()
{
alias CallerRet = typeof(return);
CallerRet magic()
{
return CallerRet.init;
}
}


Small edit: you can remove the "CallerRet" alias by doing the 
following:


mixin template magic()
{
typeof(return) magic()
{
return typeof(return).init;
}
}


Though I wouldn't really recommend it as it's very confusing, 
IMO. This works because "typeof(return)" in the return position 
here refers to the caller's scope, while "typeof(return)" inside 
the function refer's to the function's scope.




Re: Retrieve the return type of the current function

2020-05-05 Thread Meta via Digitalmars-d-learn

On Tuesday, 5 May 2020 at 17:11:53 UTC, learner wrote:

On Tuesday, 5 May 2020 at 16:41:06 UTC, Adam D. Ruppe wrote:


typeof(return)


Thank you, that was indeed easy!

Is it possible to retrieve also the caller return type? 
Something like:


```
int foo() {
return magic();
}

auto magic(maybesomedefaulttemplateargs = ??)() {
alias R = __traits(???); // --> int!
}
```

Mixin templates maybe?


You *can* use mixin templates to access the caller's scope, which 
means typeof(return) will refer to the caller's return type, 
instead of the callee's. However, there's no way to both mixin 
and call the mixin template in a single line, so it's not DRY:


int foo()
{
mixin magic;
return magic();
}

mixin template magic()
{
alias CallerRet = typeof(return);
CallerRet magic()
{
return CallerRet.init;
}
}

void main()
{
foo();
}

Maybe somebody else knows a way to get around having to first 
mixin magic.


Re: Checked!({short, ushort, byte, char}, Throw): compilation fails

2020-04-16 Thread Meta via Digitalmars-d-learn
Unlike C/C++, char is not a numeric type in D; It's a UTF-8 code 
point:


import std.traits;

void main()
{
pragma(msg, isNumeric!char); //Prints false
}


Re: Discord bot written in D

2020-04-07 Thread Meta via Digitalmars-d-learn

On Monday, 6 April 2020 at 21:23:22 UTC, Quantium wrote:
Are there any libraries to creade a simple discord bot using D? 
And if you know these libraries, could you day me their pros 
and cons?


I've used https://github.com/b1naryth1ef/dscord to build a 
Discord bot, a little over a year ago. However, it didn't even 
seem that actively maintained back then; I had to patch over at 
least one bug. Other than that, though, it worked smoothly and 
was easy to get started with.


Re: `in` parameters optimization

2019-12-25 Thread Meta via Digitalmars-d-learn

On Wednesday, 25 December 2019 at 01:24:52 UTC, Adnan wrote:
Does the compiler automatically pass values by reference if 
possible with `in` parameters in higher level of optimization 
flags? I would normally use `in ref` but sometimes it's not 
compatible with different types.


No. "in" is short for "const scope" 
(https://dlang.org/spec/function.html#param-storage). The only 
mechanism D has for expressing "pass this argument by ref if 
possible, and by value otherwise" is "auto ref" 
(https://dlang.org/spec/function.html#auto-ref-functions), which 
requires your function to be templated.


Re: Using map result type

2019-12-11 Thread Meta via Digitalmars-d-learn

On Wednesday, 11 December 2019 at 20:08:37 UTC, Meta wrote:

import std.algorithm;
import std.range;

void mapAccepter(E)(InputRange!E r)
{
import std.array: array;
import std.stdio: writeln;

auto collected = r.array;
writeln(collected);
}

void main()
{
int[] nums = [1, 2, 3];
auto evenness = inputRangeObject(map!(n => n % 2 == 
0)(nums));

mapAccepter(evenness);
}


I guess I should mention, that if you are expecting a range of 
booleans, you can of course write  mapAccepter as a non-templated 
function:


void mapAccepter(InputRange!bool r);

But if you want to support any type of input range, the function 
needs to at least be templated on the element type of the range.


Re: Using map result type

2019-12-11 Thread Meta via Digitalmars-d-learn

On Sunday, 8 December 2019 at 01:10:21 UTC, AA wrote:
I'd like to accept the return type of map. From some previous 
questions that I should accept a template?

So for something like:

```
void mapAccepter(Range)(Range r)
{
import std.array : array;
import std.stdio : writeln;

auto collected = r.array;
writeln(collected);
}

void main()
{
import std.algorithm.iteration : map;

int[] nums = [1, 2, 3];
auto evenness = map!(n => n % 2 == 0)(nums);
mapAccepter(evenness);
}
```


1) Is there any way I can make `mapAccepter` not a templated 
function?


Yes (mostly, anyway), using the interfaces in 
std.range.interfaces:

https://dlang.org/phobos/std_range_interfaces.html

import std.algorithm;
import std.range;

void mapAccepter(E)(InputRange!E r)
{
import std.array: array;
import std.stdio: writeln;

auto collected = r.array;
writeln(collected);
}

void main()
{
int[] nums = [1, 2, 3];
auto evenness = inputRangeObject(map!(n => n % 2 == 0)(nums));
mapAccepter(evenness);
}

`mapAccepter` still needs to be templated on the element type of 
the range,
but there are ways to avoid that as well, if desired. I wouldn't 
recommend it,

however, as it wouldn't be that useful in this case.

2) Is there any way if I need to make `mapAccepter` templated 
to constrain Range to be a range of booleans.


Yup, there are two ways that you you primarily do that. Either
constraining E in the template declaration, or adding a constraint
on the template. Generally option 2 is the more idiomatic D way.

Option 1: constrain E to be of type bool:
void mapAccepter(E: bool)(InputRange!E r);

OR

void mapAccepter(E)(InputRange!E r)
if (is(E == bool));

There's not much difference between these two, but the latter is 
probably preferred.


Option 2: use std.traits and a template constraint:
void mapAccepter(E)(InputRange!E r)
if (is(ElementType!r == bool));



Re: Unexpectedly nice case of auto return type

2019-12-03 Thread Meta via Digitalmars-d-learn

On Tuesday, 3 December 2019 at 22:11:39 UTC, Meta wrote:

On Tuesday, 3 December 2019 at 17:45:27 UTC, H. S. Teoh wrote:
The thing is, `void` means "no return type" (or "no type" in 
some contexts), i.e., void == TBottom in that case.


Not *quite* correct. void is not a bottom type; it's a unit 
type, meaning that it's a type with only 1 value (as is null, 
interestingly). void does not mean "no return type"; it means 
"there's only 1 possible value that can be returned". A 
function returning TBottom means that the function will never 
return, e.g., it loops forever, or throws an exception, etc.


Whoops, skimmed over the post already mentioning this.


Re: Unexpectedly nice case of auto return type

2019-12-03 Thread Meta via Digitalmars-d-learn

On Tuesday, 3 December 2019 at 17:45:27 UTC, H. S. Teoh wrote:
The thing is, `void` means "no return type" (or "no type" in 
some contexts), i.e., void == TBottom in that case.


Not *quite* correct. void is not a bottom type; it's a unit type, 
meaning that it's a type with only 1 value (as is null, 
interestingly). void does not mean "no return type"; it means 
"there's only 1 possible value that can be returned". A function 
returning TBottom means that the function will never return, 
e.g., it loops forever, or throws an exception, etc.


I agree with the OP that it's silly not to give typeof(null) a 
name. As null is a unit type, we could easily have `null` stand 
in for typeof(null) as well. A type that contains only one value 
can be synonymous with that value (see also, Rust's unit type (), 
which has one value, ()).





Re: Alternative to C++ macro in D

2019-11-03 Thread Meta via Digitalmars-d-learn
On Sunday, 3 November 2019 at 16:55:36 UTC, Vinod K Chandran 
wrote:

Hi all,
I can do this in C++. #include 
using namespace std ;

#define end };
#define log(x)  cout << x << endl
#define wait std::cin.get()


int main() {
log("Trying to avoid the visual clutter aused by closing 
curly braces") ;

string myStr = "Now, code looks more elegant" ;
log(myStr) ; mixin template cToD(string code)


`log` and `wait` are straightforward. Just write a function:

import std.stdio;
void log(T)(T x) { writeln(x); }
void wait() { readln(); }

However, you can't do things like `#define end }`. The D language 
intentionally disallows doing stuff like this. If you *really* 
want to do this, you can sort of emulate it with mixins:


mixin template cToD(string code)
{
import std.array: replace;
mixin(code.replace("end", "}"));
}

mixin cToD!`
int main() {
log("Trying to avoid the visual clutter aused by closing 
curly braces") ;

string myStr = "Now, code looks more elegant" ;
log(myStr) ;
wait ;
return 0;
end
`;

But I would strongly recommend against it.


Re: Elegant way to test if members of array A are present in array B?

2019-06-12 Thread Meta via Digitalmars-d-learn

On Tuesday, 11 June 2019 at 17:12:17 UTC, Robert M. Münch wrote:
Is there a simple and elegant way to do this? Or is just using 
a foreach(...) with canFind() the best way?


There are two versions of find that can find a range within 
another:


https://dlang.org/phobos/std_algorithm_searching.html#.find
https://dlang.org/phobos/std_algorithm_searching.html#.find.3


Re: How to debug long-lived D program memory usage?

2019-04-17 Thread Meta via Digitalmars-d-learn

On Wednesday, 17 April 2019 at 22:37:38 UTC, Adam D. Ruppe wrote:
On Wednesday, 17 April 2019 at 19:07:46 UTC, Jacob Carlborg 
wrote:

Perhaps try some of these flags [1] and [2].


oooh, those are very interesting too.

What I was kinda hoping is it would have stats for which file 
and line of code was responsible for most allocations; a 
detailed profile. But even so, this is an interesting gem.


Not at all what you want, but it may be useful for figuring out 
where the leaks are. Have you tried compiling with -vgc? 
https://dlang.org/dmd-windows.html#switch-vgc





Re: Block statements and memory management

2019-03-16 Thread Meta via Digitalmars-d-learn

On Saturday, 16 March 2019 at 03:47:43 UTC, Murilo wrote:
Does anyone know if when I create a variable inside a scope as 
in

{int a = 10;}
it disappears complete from the memory when the scope finishes? 
Or does it remain in some part of the memory? I am thinking of 
using scopes to make optimized programs that consume less 
memory.


I'd recommend against these sorts of micro-optimizations. 
Compilers are every good at doing this kind of thing manually so 
you don't have to worry about it and can concentrate on the 
actual logic of your program.


Re: Query for -dip1000

2019-02-11 Thread Meta via Digitalmars-d-learn

On Sunday, 10 February 2019 at 20:04:29 UTC, Per Nordlöw wrote:
Is there a way to query if the -dip1000 flag has been passed to 
the compiler? I need it for enabling certain DIP-1000 escape 
analysis tests only when -dip1000 has been passed.


For instance

static assert(!__traits(compiles, {
char[] f()
{
char[2] x;
return x[].splitterASCII!(_ => _ == ' 
').front;

}
}));

at

https://github.com/nordlow/phobos-next/blob/bd2fe42978aab2313977042c858d77c5766538e8/src/splitter_ex.d#L110

Or do I have to write a trait myself?


https://issues.dlang.org/show_bug.cgi?id=19669


Re: Implement Interface Using Super

2019-01-29 Thread Meta via Digitalmars-d-learn
On Wednesday, 30 January 2019 at 01:02:37 UTC, Jonathan M Davis 
wrote:

Yeah. It would be like trying to do something like

alias x = this.x;

As it stands, I believe that super is always either used as a 
function call to the constructor or to mean the this pointer 
for the base class. I don't think that it ever means the type 
of the base class - just like this never means the type of the 
current class or struct. And their usage is pretty much 
identical. They're both either used for calling a constructor 
or for accessing the pointer/reference of the object. It's just 
that one of them is for the current class or struct, whereas 
the other is for a base class of the current class. The only 
difference in syntax that I can think of between them at the 
moment is that this is also used to name constructors when 
they're declared, whereas super is not used in that sort of way 
(since any constructor that would be referenced by super would 
be declared with this, not super).


- Jonathan M Davis


Current, you *can* use `super` to mean the type of the base 
class, but it's been deprecated in a recent release (IIRC):


class Super
{
}

class Sub
{
super test()
{
return new Super();
}
}

void main()
{
(new Sub()).test();
}

From DPaste:

Up to  2.080.1: Success and no output
Since  2.081.2: Success with output: onlineapp.d(7): 
Deprecation: Using `super` as a type is deprecated. Use 
`typeof(super)` instead


Re: Implement Interface Using Super

2019-01-28 Thread Meta via Digitalmars-d-learn
On Monday, 28 January 2019 at 22:17:56 UTC, Steven Schveighoffer 
wrote:

On 1/28/19 3:28 PM, Jonathan Levi wrote:

On Sunday, 27 January 2019 at 09:31:46 UTC, bauss wrote:
On Sunday, 27 January 2019 at 05:37:57 UTC, Jonathan Levi 
wrote:

This works in LDC *but not* DMD?
. . .
Is this a bug in DMD *or* in LDC?


There is no bug here.


So... LDC is the one that is bugged?


Yeah, that's odd. It should be the same result, as they both 
have the same semantics for the front end.


I'll defer to an LDC developer to answer that, but in truth, it 
really should be the way LDC implements it, even if that's not 
how the language spec is.


I think it would have been nice to have a way of explicitly 
use the super method to implement an interface without having 
to rewrite the whole signature.  I thought I remember seeing a 
way once, but I must have been dreaming.


I agree.

BTW, the typeof(super) requirement is super-annoying. alias x = 
super.x; is clear, I don't see why we need to specify 
typeof(super) in this context at least.


-Steev


It's because aliases do not support context pointers, I'm pretty 
sure.


Re: Why tuples are not ranges?

2018-06-28 Thread Meta via Digitalmars-d-learn

On Thursday, 28 June 2018 at 17:00:37 UTC, Mr.Bingo wrote:
I mean, if you think about it, the memory layout of a tuple is 
sequential types:


T1
T2
...

So, to popFront a tuple is just changing the starting offset.


You're right; it can definitely be done.

struct TupleRange(T...)
{
size_t index;
Tuple!T store;

@property length()
{
assert(index <= store.length);
return store.length - index;
}

Algebraic!T front()
{
assert(length > 0);
return typeof(return)(store[index]);
}

void popFront()
{
assert(length > 0);
index++;
}
}


Re: foreach DFS/BFS for tree data-structure?

2018-06-14 Thread Meta via Digitalmars-d-learn

On Thursday, 14 June 2018 at 11:31:50 UTC, Robert M. Münch wrote:

I have a simple tree C data-structure that looks like this:

node {
node parent:
vector[node] children;
}

I would like to create two foreach algorthims, one follwing the 
breadth first search pattern and one the depth first search 
pattern.


Is this possible? I read about Inputranges, took a look at the 
RBTree code etc. but don't relly know/understand where to start.


While it's possible to do with input ranges, it's not pretty and 
I'm not sure that it's as performant as the traditional method. I 
would recommend going with one of the other suggestions in this 
thread.


Re: What is the point of nothrow?

2018-06-11 Thread Meta via Digitalmars-d-learn

On Monday, 11 June 2018 at 04:11:38 UTC, Bauss wrote:

On Monday, 11 June 2018 at 00:47:27 UTC, Jonathan M Davis wrote:
On Sunday, June 10, 2018 23:59:17 Bauss via 
Digitalmars-d-learn wrote:
What is the point of nothrow if it can only detect when 
Exception is thrown and not when Error is thrown?


It seems like the attribute is useless because you can't 
really use it as protection to write bugless, safe code since 
the nasty bugs will pass by just fine.


I'm aware that it's a feature that nothrow can throw Error, 
but it makes the attribute completely useless because you 
basically have no safety to guard against writing code that 
throws Error.


To an extend @safe works, but there are tons of stuff that 
throws Error which you can only detect and guard against 
manually.


So what is the point of nothrow when it can only detect 
exceptions you'd catch anyway.


To me it would be so much more useful if you could detect 
code that could possibly throw Error.


Why do you care about detecting code that can throw an Error? 
Errors are supposed to kill the program, not get caught. As 
such, why does it matter if it can throw an Error?


Now, personally, I'm increasingly of the opinion that the fact 
that we have Errors is kind of dumb given that if it's going 
to kill the program, and it's not safe to do clean-up at that 
point, because the program is in an invalid state, then why 
not just print the message and stack trace right there and 
then kill the program instead of throwing anything? But 
unforntunately, that's not what happens, which does put things 
in the weird state where code can catch an Error even though 
it shouldn't be doing that.


As for the benefits of nothrow, as I understand it, they're 
twofold:


1. You know that you don't have to worry about any Exceptions 
being thrown from that code. You don't have to worry about 
doing any exception handling or having to ensure that anything 
gets cleaned up because of an Exception being thrown.


2. If the compiler knows that a function can't throw an 
Exception, then it doesn't have to insert any of the Exception 
handling mechanism stuff that it normally does when a function 
is called. It can assume that nothing ever gets thrown. If an 
Error does get thrown, then none of the proper clean-up will 
get done (e.g. constructors or scope statements), but because 
an Error being thrown means that the program is in an invalid 
state, it's not actually safe to be doing clean-up anyway. So, 
the fact that a function is nothrow gives you a performance 
benefit, because none of that extra Exception handling stuff 
gets inserted. How large a benefit that is in practice, I 
don't know, but it is a gain that can't be had with a function 
that isn't nothrow.


- Jonathan M Davis


Well at least from my point of view I would care about code 
that can throw Error, because if say nothrow could detect that 
then you could prevent writing that code that throws jt at all 
and thus you'd be writing less error prone code.


Maybe not necessarily nothrow, but something else that could 
ensure that your code is "100% safe" to run without any errors 
happening from ex. Accessing out of bounds, accessing invalid 
memory, attempting to access the member of an uninitialized 
class etc. Like you'd have to handle each such cases. Writing 
code in D today you have to think about each statement you 
write and whether it could possibly throw Error because you 
have little to no tools that helps you preventing writing such 
code.


I'm very well aware that Error is not supposed to be caught and 
that the program is in an invalid state, but ehat I'm trying to 
get at is that if nothrow or at least a feature similar existed 
that could detect code that may throw Error, then you could 
prevent writing code that throws it in the first place.


It would be a great tool to writing bugless code.


There's nothing unsafe about Error getting thrown in your code. 
Error makes your program more safe, because it terminates the 
program immediately instead of letting it do stuff like corrupt 
memory or crash the system.


Error getting thrown denotes a logic error in your program. Some 
base assumption you've made is not actually true, and thus the 
program is in an invalid state and must exit immediately. The 
reason why nothrow cannot help you here is because these are 
logic errors that are only detectable at runtime. If it was 
possible to detect these types of errors at compile time, then 
there would be no need for Error.


Re: how to define infix function

2018-06-03 Thread Meta via Digitalmars-d-learn

On Saturday, 2 June 2018 at 23:17:48 UTC, Simen Kjærås wrote:

On Saturday, 2 June 2018 at 22:09:49 UTC, Neia Neutuladh wrote:

On Saturday, 2 June 2018 at 21:44:39 UTC, greatsam4sure wrote:

Sorry for the typo

is it possible to define infix function in D

3.min(5)// 3: where min is a function, works in D
3 min 5 // does not work.

thanks in advance


This is a horrible abuse of D's operator overloading 
discovered by FeepingCreature in the distant past.


You have to delimit your custom infix operator with slashes; 
you can't make `3 min 5` work, but you can make `3 /min/ 5` 
work.


Observe:

struct Min
{
MinIntermediate!T opBinaryRight(string op, T)(T value) if 
(op == "/")

{
return MinIntermediate!T(value);
}
}
struct MinIntermediate(T)
{
T value;
T opBinary(string op, T)(T value2) if (op == "/")
{
if (value < value2) return value;
return value2;
}
}
Min min;
void main()
{
writeln(1 /min/ 2);
}


And of course, this can be generalized:

struct Operator(alias fn, string operator = "/")
{
static auto opBinaryRight(string op : operator, T...)(T 
value1)

{
struct Result
{
auto opBinary(string op : operator, U...)(U value2)
if (__traits(compiles, fn(value1, value2)))
{
return fn(value1, value2);
}
}

Result result;
return result;
}
}

unittest
{
import std.algorithm.comparison;

alias min = Operator!(std.algorithm.comparison.min);

assert(1 /min/ 3 == 1);
}

Note also the use of static opBinaryRight, allowing one to 
eschew the 'min' variable.


All of this said, I would suggest not using this in prod - it's 
a neat trick that shows off some of D's power, but I don't see 
a case where this would be easier to understand than a 
straightforward function call.


--
  Simen


That is interesting. I don't know yet whether it's good or bad, 
but certainly, it's interesting.


Re: try & catch / repeating code - DRY

2018-05-22 Thread Meta via Digitalmars-d-learn

On Tuesday, 22 May 2018 at 18:20:43 UTC, Robert M. Münch wrote:

I see that I'm writing

try {
... different code ...
} catch (myException e) {
... same handling code ...
}

over and over again.

Of course I can put the exception handling code into a function 
to not duplicate it. However, I still need to write this 
construct over and over again. Is there a way to handle it more 
generic? Like:


??? (... code ...);

or

??? { ... code ...};

Where ??? would do the try and re-use the exception handling 
code everytime? I hope this is understandable.


Have you looked at std.exception.ifThrown? You could define a 
handler function and pass it to ifThrown for each expression that 
may throw. If it's a statement, I believe you could wrap it in a 
lambda which is immediately called, then append 
.ifThrown(handler).


Re: Creating a template mixin for explicit casts.

2018-05-17 Thread Meta via Digitalmars-d-learn

On Thursday, 17 May 2018 at 15:25:37 UTC, Sjoerd Nijboer wrote:

Given the following code
`struct Foo(T)
if(isNumeric!T)
{
T t;
.. other code
}

struct Bar(T)
if(isNumeric!T)
{
T t;
.. other code
}

Foo!float foo_float;

Foo!double foo_double;

Bar!float bar_float;
`

I want to make a template mixin that is able to cast one of 
these generic structs to the other explicitly. I have a bunch 
of these structs and therefore I thought it would make sense to 
do it by template mixin. I just don't know what language or 
library features I need to use and how to apply them.


`
fooDouble = cast (Foo!double) foo_float;		// case [1] if 
possible, done by

// an implicit cast. 
Else by
//explicit.

fooFloat = cast (Foo!float) foo_double; // case [2]

barFloat = cast (Bar!float) foo_float;  // case [3]
`

How would I do this in D?


Before you write anything yourself, check whether 
std.conv.castFrom does what you need:


https://dlang.org/phobos/std_conv.html#castFrom


Re: Extra .tupleof field in structs with disabled postblit blocks non-GC-allocation trait

2018-05-10 Thread Meta via Digitalmars-d-learn

On Thursday, 10 May 2018 at 12:55:36 UTC, Uknown wrote:

On Thursday, 10 May 2018 at 11:06:06 UTC, Per Nordlöw wrote:

On Wednesday, 9 May 2018 at 21:09:12 UTC, Meta wrote:
It's a context pointer to the enclosing 
function/object/struct. Mark the struct as static to get rid 
of it.


Ok, but why an extra void* for `S.tupleof` and not for 
`T.tupleof` which is also scoped inside a unittest?


I'm guessing T is a POD, so it doesn't need a context pointer, 
whereas S is not counted as a POD since a member function was 
@disabled.


Yes, exactly. From my tests, if you add _any_ member method to a 
struct, it becomes non-POD. When you think about it, this makes 
perfect sense, as there's no possible way to access anything 
through a context pointer if there is no executable code within 
the struct's scope.


As far an @disabled postblit:

Plain Old Data
A struct or union is Plain Old Data (POD) if it meets the 
following criteria:


it is not nested
it has no postblits, destructors, or assignment operators
it has no ref fields or fields that are themselves non-PO

https://docarchives.dlang.io/v2.079.0/spec/struct.html#POD

Now if you do this:

struct R
{
@disable this(this);
int* _ptr;
}
unittest
{
struct S
{
@disable this(this);
int* _ptr;
}
struct T
{
int* _ptr;
}
pragma(msg, "R: ", typeof(R.tupleof));
pragma(msg, __traits(allMembers, R));

pragma(msg, "S: ", typeof(S.tupleof));
pragma(msg, __traits(allMembers, S));

pragma(msg, "T: ", typeof(T.tupleof));
pragma(msg, __traits(allMembers, T));
}

It prints:

R: (int*)
tuple("__postblit", "_ptr", "__xpostblit", "opAssign")

S: (int*, void*)
tuple("__postblit", "_ptr", "this", "__xpostblit", "opAssign")

T: (int*)
tuple("_ptr")

So it looks like disabling a struct's postblit actually counts as 
having a __postblit and __xpostblit function (don't ask me why), 
in addition to a construction and opAssign... no idea why, and 
maybe this is a bug, but I bet there's a good reason for it.


Anyway, as per my first point, this means it'll need a context 
pointer unless you mark the struct as static.


Re: Extra .tupleof field in structs with disabled postblit blocks non-GC-allocation trait

2018-05-09 Thread Meta via Digitalmars-d-learn

On Wednesday, 9 May 2018 at 18:04:40 UTC, Per Nordlöw wrote:

On Wednesday, 9 May 2018 at 17:52:48 UTC, Meta wrote:
I wasn't able to reproduce it on dmd-nightly: 
https://run.dlang.io/is/9wT8tH


What version of the compiler are you using?


Ahh, the struct needs to be in a unittest block for it to 
happen:


struct R
{
@disable this(this);
int* _ptr;
}
unittest
{
struct S
{
@disable this(this);
int* _ptr;
}
struct T
{
int* _ptr;
}
pragma(msg, "R: ", typeof(R.tupleof));
pragma(msg, "S: ", typeof(S.tupleof));
pragma(msg, "T: ", typeof(T.tupleof));
}

prints

R: (int*)
S: (int*, void*)
T: (int*)

Why is that?


It's a context pointer to the enclosing function/object/struct. 
Mark the struct as static to get rid of it.


Re: Extra .tupleof field in structs with disabled postblit blocks non-GC-allocation trait

2018-05-09 Thread Meta via Digitalmars-d-learn

On Wednesday, 9 May 2018 at 14:07:37 UTC, Per Nordlöw wrote:

Why (on earth) does

struct S
{
@disable this(this);
int* _ptr;
}
pragma(msg, typeof(S.tupleof));

prints

(int*, void*)

when

struct S
{
int* _ptr;
}
pragma(msg, typeof(S.tupleof));

prints

(int*)

?!!!


I wasn't able to reproduce it on dmd-nightly: 
https://run.dlang.io/is/9wT8tH


What version of the compiler are you using?


Re: Ambiguous template parameter names

2018-05-02 Thread Meta via Digitalmars-d-learn

On Thursday, 3 May 2018 at 02:48:10 UTC, jmh530 wrote:

On Thursday, 3 May 2018 at 00:52:58 UTC, Meta wrote:

[snip]

It's not a big per se. It's a consequence of the declaration 
expanding to the real template function form (I can't type it 
all out as I'm on my phone), thus the inner `val` from the 
function shadows the one from the template.



That makes sense. Before creating the example, I would have 
assumed that when you instantiate it as foo!1, then the `val=1` 
would flow through to the inner foo function.


template foo(int val)
{
int foo(int val)
{
return val;
}
}


If you want that, you might be able to do `int val = val` on the 
inner function, though I'm not sure that'll work.


Re: Ambiguous template parameter names

2018-05-02 Thread Meta via Digitalmars-d-learn

On Wednesday, 2 May 2018 at 20:32:43 UTC, jmh530 wrote:
In the function below, there is a template parameter and a 
normal parameter both with the same name. However, the function 
returns the normal parameter. The template parameter is 
effectively ignored. I was surprised by this behavior.


Is this a bug or intentional? I did not see it documented 
anywhere.



```
int foo(int val)(int val)
{
return val;
}

void main()
{
assert(foo!1(2) == 2);
}
```


It's not a big per se. It's a consequence of the declaration 
expanding to the real template function form (I can't type it all 
out as I'm on my phone), thus the inner `val` from the function 
shadows the one from the template.


Re: Create variable for RedBlackTree range

2018-05-02 Thread Meta via Digitalmars-d-learn

On Wednesday, 2 May 2018 at 10:39:29 UTC, ag0aep6g wrote:

On 04/28/2018 06:36 PM, Gerald wrote:
What is the appropriate way to create a variable for the range 
returned by RedBlackTree lowerBound and upperBound. For 
example, given this code:


```
RedBlackTree!long promptPosition = redBlackTree!long();

long row = to!long(vte.getVadjustment().getValue());
RBRange!(RBNode!long*) range;

[...]

}
```

The second line where I declare the range variable as 
RBRange!(RBNode!long*) the compiler complains with the 
following warning:


Deprecation: std.container.rbtree.RBRange(N) is not visible 
from module terminal


Which makes sense since RBRange is a private struct.


RedBlackTree also has public range types: Range, ConstRange, 
ImmutableRange. And `RedBlackTree!long.Range` is an alias for 
`RBRange!(RBNode!long*)`.


So:

RedBlackTree!long promptPosition = redBlackTree!long();
RedBlackTree!long.Range range;


For completeness' sake, and if you don't want to re-specify the 
template parameters you passed to RedBlackTree, you can write:


promptPosition.Range range;


Re: Add property-like Function to Type ?

2018-04-24 Thread Meta via Digitalmars-d-learn

On Tuesday, 24 April 2018 at 21:36:19 UTC, Rubn wrote:
I was wondering if I could create my own property in a way that 
can be used the same way as something like "T.sizeof". Right 
now I have the following to replace length:


uint length32(T)(T[] array)
{
return cast(uint)array.length;
}

I want something similar to be able to do the following:


uint size = T.sizeof32;

The closest I can think of is doing:

uint size = sizeof32!T


That's the best I can do, which is fine but I was wondering if 
there's any other way around that?


If you don't control T and can't add members, then the best thing 
you can probably do is instead write T.init.sizeof32. Actually, 
though, you can be sneaky about it and use a local function to 
shadow Test, but this is probably more trouble than it's worth:


import std.stdio;

struct Test
{
}

@property sizeof32(Test t) { return 1; }

void main()
{
@property Test() { return .Test.init; }
writeln(Test.sizeof32);
}

This is really annoying, though, because you have to declare the 
Test function in every function or struct/class definition you 
use it in. You can create a mixin that does it automatically, but 
you'd still have to do `mixin(testProperties)` (where 
testProperties is an enum you've defined that's just the function 
definition).


Re: Warning on self assignment

2018-04-24 Thread Meta via Digitalmars-d-learn

On Wednesday, 25 April 2018 at 02:32:32 UTC, Per Nordlöw wrote:
On Wednesday, 25 April 2018 at 02:23:04 UTC, Mike Franklin 
wrote:
Are people using self assignment of structs as a way of 
force-running the postblit?  Is there a valid use case for 
that?


Mike


If they are, there should be a better way of force-running the 
postblit.


You can call __postblit or __xpostblit (I think the latter is a 
postblit introduced via a mixin or template mixin).


Re: Better way to append to array than ~= ?

2018-04-03 Thread Meta via Digitalmars-d-learn
On Tuesday, 3 April 2018 at 20:02:46 UTC, Vladimirs Nordholm 
wrote:

On Tuesday, 3 April 2018 at 19:53:11 UTC, Meta wrote:
On Tuesday, 3 April 2018 at 19:02:25 UTC, Vladimirs Nordholm 
wrote:

[...]


In this specific case, since you know the length of `Args`, 
you can pre-allocate an array of that size and loop through it 
doing your initialization.


However, if you want really performant code, you should 
allocate a static array on the stack outside of the function 
and pass it in as a buffer.


I don't think I know the size of the arguments.

If I pass in "123" and MySpecialType('a'), the result should be:

assert(foo("123", MySpecialType('a')) == 
[MySpecialType('1'), MySpecialType('2'), MySpecialType('3'), 
MySpecialType('a')]);


What should the length of the pre-allocated array be?


You know the static types of the arguments, so it is not 
impossible. However, the more flexible you need to be, the more 
complex your code will have to be, and it probably won't be worth 
the added complexity. Anyway, sorry for derailing a bit. That's 
not really your question.


Using Appender!MySpecialType might be marginally faster than ~=, 
but from the looks of it you are already using Appender. I don't 
know if there's much more you can do to speed up appending 
without just rolling your own solution or restructuring your code.


Re: Better way to append to array than ~= ?

2018-04-03 Thread Meta via Digitalmars-d-learn
On Tuesday, 3 April 2018 at 19:02:25 UTC, Vladimirs Nordholm 
wrote:

Hello people.

I currently have a function which multiple times per second 
takes in arguments, and appends the argument as my special 
type. The following code should explain what I do more properly:


struct MySpecialType { char c; }

auto foo(Args...)(Args args)
{
MySpecialType[] bar;

foreach(ref arg; args)
{
static if(is(typeof(arg) == MySpecialType))
{
bar ~= arg;
}
else
{
foreach(c; to!string(arg))
{
bar ~= MySpecialType(c);
}
}
}

// do more stuff
}

Now, from my trace.log, some of the topmost things on the 
timing list are `std.array.Appender!(immutable(char).stuff>`. I also remember reading some years ago that ~= isn't 
optimal for speed.


So my question is: Is there a better and/or faster way of doing 
this, or is this the best approach?


In this specific case, since you know the length of `Args`, you 
can pre-allocate an array of that size and loop through it doing 
your initialization.


However, if you want really performant code, you should allocate 
a static array on the stack outside of the function and pass it 
in as a buffer.


Re: Issue with traits usability

2018-03-23 Thread Meta via Digitalmars-d-learn

On Wednesday, 21 March 2018 at 15:36:01 UTC, Márcio Martins wrote:

Hi!

How do I get past this?


static struct X {
int x;
private enum T = 1;
private alias M = string;
}

foreach (Member; __traits(allMembers, X)) {
	pragma(msg, __traits(getProtection, __traits(getMember, X, 
Member)));

}


Output:

public
private
c.d(1084): Error: argument string has no protection
c.d(1084):while evaluating pragma(msg, 
__traits(getProtection, string))



What I want to achieve essentially is skip all X's aliases and 
templates, but get everything else, like enums and data 
members. How would I go about this in a robust way?

I actually want to skip aliases, and templates.


In addition to Simen's answer, you can you 
std.traits.FieldNameTuple to get only the fields of your struct 
(which only includes struct members that are actually part of the 
struct's memory layout):


import std.traits;

static struct X {
int x;
private enum T = 1;
private alias M = string;
}

void main()
{
foreach (Member; FieldNameTuple!X) {
pragma(msg, __traits(getProtection, __traits(getMember, 
X, Member)));

}
}

This example prints "public" once.


Re: Going from string to identifier

2018-02-21 Thread Meta via Digitalmars-d-learn
On Wednesday, 21 February 2018 at 22:11:04 UTC, Jean-Louis Leroy 
wrote:

Here's what I am trying to do:

mixin template MakeFun(string ID, int X)
{
  int mixin(ID)() { return X; }
}

mixin MakeFun!("one", 1); // int one() { return 1; }

Alas I get:
makefunc.d(3): Error: no identifier for declarator `int`
makefunc.d(3): Error: found `{` when expecting `;`
makefunc.d(3): Error: declaration expected, not `return`
makefunc.d(4): Error: unrecognized declaration

Is there a shorter way than building the entire function 
definition as a string mixin? As in:


mixin template MakeFun(string ID, int X)
{
  import std.format;
  mixin(format("int %s() { return %s; }", ID, X));
}

mixin MakeFun!("one", 1);


Mixins have to be full declarations. You can't mix in bits and 
pieces... except when you can:


import std.stdio;

void main()
{
enum teste = "asdf";
string s = mixin("teste");
writeln(s); //Prints "asdf"
}

It looks like a grammar error as opposed to a semantic one. D's 
grammar just doesn't support `mixin` in the function name 
position. One way you can make it a little more palateable:


mixin template MakeFun(string ID, int X)
{
import std.format;
mixin(q{ int %s { return %s; } }.format(ID, X));
}

`q{}` denotes a token string that must contain valid tokens (I'm 
not sure if the available compiler implementations actually 
enforce this), and I _think_ token strings will be properly 
syntax-highlighted by most tools.


https://dlang.org/spec/lex.html#token_strings


Re: opCast cannot implicitly convert a.opCast of type X to Y

2018-02-14 Thread Meta via Digitalmars-d-learn

On Thursday, 15 February 2018 at 00:27:40 UTC, Meta wrote:

On Wednesday, 14 February 2018 at 23:46:30 UTC, aliak wrote:

On Wednesday, 14 February 2018 at 15:14:24 UTC, Meta wrote:

Ooh yes, of course! Thank you :)


Even better:

import std.conv;

auto b = a.map!(to!float);


Actually, that won't quite work without redefining map a little:

Optional!U map(alias f, U = typeof(f(t.init)))()
{
etc...
}


Re: opCast cannot implicitly convert a.opCast of type X to Y

2018-02-14 Thread Meta via Digitalmars-d-learn

On Wednesday, 14 February 2018 at 23:46:30 UTC, aliak wrote:

On Wednesday, 14 February 2018 at 15:14:24 UTC, Meta wrote:


I think the best way to do this is to implement `map` for your 
optional type.


Optional!U map(U, alias f)()
{
return empty? no!U : some!U(f(t));
}

Optional!int a = 3;
auto b = a.map!(v => cast(float)v);
assert(is(typeof(b) == Optional!float));


Ooh yes, of course! Thank you :)


Even better:

import std.conv;

auto b = a.map!(to!float);


Re: opCast cannot implicitly convert a.opCast of type X to Y

2018-02-14 Thread Meta via Digitalmars-d-learn

On Monday, 12 February 2018 at 02:05:16 UTC, aliak wrote:
From spec: Cast expression: "cast ( Type ) UnaryExpression" 
converts UnaryExpresssion to Type.


And https://dlang.org/spec/operatoroverloading.html#cast makes 
no mention of the return type of opCast. One could think that 
the return type of opCast would be the return type. But it 
seems it must be the same as the template parameter of opCast 
else you get a compile error that seems like it can be much 
better.


---

import std.stdio;

struct B(T) {
T t;
}

struct A(T) {
T t;
auto opCast(U)() {
return B!U(cast(U)t);
}
}

void main() {
auto a = A!int(3);
auto b = cast(float)a; // error
}

Error: cannot implicitly convert expression a.opCast() of type 
B!float to float


Is this deliberate?

The use case I have is making an optional type that you can 
cast to a different type:


auto opCast(U)() const {
static if (isOptional!U)
{
alias V = OptionalTarget!U;
return empty ? no!V : some!V(cast(V)front); // it's a 
range so "front" is the raw value

}
else
{
return empty ? no!U : some!U(cast(U)front);
}
}

It would allow for scenarios like:

Optional!int a = 3;
auto b = cast(float)a;
// b == some!float


Cheers
- Ali


I think the best way to do this is to implement `map` for your 
optional type.


Optional!U map(U, alias f)()
{
return empty? no!U : some!U(f(t));
}

Optional!int a = 3;
auto b = a.map!(v => cast(float)v);
assert(is(typeof(b) == Optional!float));


Re: Error in template instantiation from D-Cookbook example

2018-02-09 Thread Meta via Digitalmars-d-learn

On Friday, 9 February 2018 at 21:31:29 UTC, ShadoLight wrote:

writeln(parse(code));   // to aid with debugging
writeln(convertToD(parse(code)));   // debugging aid
..to..
writeln(parse(code)[]); // to aid with debugging
writeln(convertToD(parse(code))[]); // debugging aid


The problem becomes apparent once you uncomment one of these and 
paste the offending string ("5 5 + 3 - 2 * 1 + 3 /") in. 
`writeln(convertToD(parse("5 5 + 3 - 2 * 1 + 3 /"))[]);` prints 
the following:


push(5);
push(5);
push(call!+(pop(), pop()));
push(3);
push(call!-(pop(), pop()));
push(2);
push(call!*(pop(), pop()));
push(1);
push(call!+(pop(), pop()));
push(3);
push(call!/(pop(), pop()));

If you look at the definition of call:

int call(string op)(int a, int b) {
return mixin("b"~op~"a");
}

So it takes a string as its sole template argument. The problem 
is that the code in convertToD forgot to add the quotes around 
the operators that are supposed to be passed as strings to call. 
If you modify line 14 from the example you pasted to add these 
quotes to the mixin string, it works:


code ~= "push(call!"~piece~"(pop(), pop()));\n";

becomes

code ~= "push(call!\""~piece~"\"(pop(), pop()));\n";

Running the modified code, it prints:

push(5);
push(5);
push(call!"+"(pop(), pop()));
push(3);
push(call!"-"(pop(), pop()));
push(2);
push(call!"*"(pop(), pop()));
push(1);
push(call!"+"(pop(), pop()));
push(3);
push(call!"/"(pop(), pop()));

And `runDslCode!"5 5 + 3 - 2 * 1 + 3 /"();` prints `[5]`.


Re: Rewriting a c++ template to D (replacing iterator with ranges "properly")

2018-01-26 Thread Meta via Digitalmars-d-learn

On Friday, 26 January 2018 at 14:16:04 UTC, aliak wrote:
1) I've seen some phobos code checking for assignability like 
this:


  is(typeof(range.front = false))

... is that an advantage of that over hasAssignableElements? Or 
is that just basically combining constraints 3 and 4 which I 
have above?


Where did you see this? That's got to be some very old code; I 
can't think of any instance where you would not want to use 
`hasAssignableElements` instead.


Re: Cannot use local lambda as parameter to non-global template

2018-01-15 Thread Meta via Digitalmars-d-learn

On Monday, 15 January 2018 at 13:55:57 UTC, Nordlöw wrote:

Why do I get errors like

template instance remove!((_) => _ == 1) cannot use local 
'__lambda5' as parameter to non-global template remove()(in K 
key)


for

x.remove!(_ => _ == 1);

but not for

x.remove!"a == 11";

?

How are these two lambdas different?

The function `remove` is a templated member of a struct 
instance `x`.


Can you give a bit more context? The following code does not 
cause a compile error:


import std.stdio;
import std.algorithm;

void main()
{
auto arr = [1, 2, 3];
arr.remove!(_ => _ == 1);
writeln(arr);
}

Or was that code meant as an example?


Re: structs inheriting from and implementing interfaces

2018-01-01 Thread Meta via Digitalmars-d-learn

On Friday, 29 December 2017 at 12:03:59 UTC, Mike Franklin wrote:

In C#, structs can inherit from and implement interfaces.


using System;

interface IPrint
{
void Print();
}

struct MyStruct : IPrint
{
public void Print()
{
Console.WriteLine(ToString());
}
}

public class Program
{
public static void Main()
{
MyStruct s = new MyStruct();
s.Print();
}
}

https://dotnetfiddle.net/lpXR1O

But in D it doesn't appear possible.

import std.stdio;

interface IPrint
{
void print();
}

// Error: base classes are not allowed for struct, did you mean 
;?
struct MyStruct : IPrint   // Error: base classes are not 
allowed for struct, did you mean ;?

{
void print()
{
writeln("MyStruct");
}
}

void main()
{
MyStruct s;
s.Print();
}

https://run.dlang.io/is/j4xwla

Is that simply because it hasn't been implemented or suggested 
yet for D, or was there a deliberate design decision?


Thanks for your insight,

Mike


You want wrap: https://dlang.org/phobos/std_typecons.html#wrap


Re: Alias example should supposedly be illegal, but runs fine

2017-12-18 Thread Meta via Digitalmars-d-learn

On Monday, 18 December 2017 at 23:44:46 UTC, Michael wrote:

Hello,

I have been looking at the following example found right at the 
end of the section here: 
https://dlang.org/spec/declaration.html#alias


struct S { static int i; }
S s;

alias a = s.i; // illegal, s.i is an expression
alias b = S.i; // ok
b = 4; // sets S.i to 4

and it runs fine to me, including if I add:

a = 3;

So, to me I don't see why either can't be valid, but either way 
something needs to be fixed to reflect that this is no longer 
illegal in DMD v2.077.1.


I think the reason that this works is because i is static, 
meaning that you don't need the `this` reference of S to access 
it and thus it can be aliased. Declaring a static class or struct 
variable is pretty much the same as declaring a global variable, 
just with a tighter scope. If you look at it that way, then this 
makes a lot more sense. If you declare a global variable i at 
module scope, of course you can create an alias for it.


Re: Using enum types

2017-12-04 Thread Meta via Digitalmars-d-learn

On Monday, 4 December 2017 at 22:34:41 UTC, helxi wrote:

Why can't enums be used as types in this (simplified) example?

enum Positivity
{
Positive,
Negative
}

struct Wave
{
public:
Positivity slope;
}

enum Waves
{
Sin = Wave(Positivity.Positive),
Cos = Wave(Positivity.Negative)
}

int nth_value(T : Waves)(int n);

int nth_value(T : Waves.Sin)(int n)
{
return n % 2 ? 1 : -1;
}

int nth_value(T : Waves.Cos)(int n)
{
return n % 2 ? -1 : 1;
}


We Adam said, Waves.Sin and Waves.Cos are values, while Waves 
itself is the type. You want to do the following:


int nth_value(Waves w: Waves.Sin)(int n)
{
//Etc.
}

At least I *think* that's what you want. I'm on mobile and dpaste 
is down so I have no way to double check the syntax, which I can 
never remember.


Re: std.algorithm

2017-11-30 Thread Meta via Digitalmars-d-learn
On Thursday, 30 November 2017 at 20:49:36 UTC, flamencofantasy 
wrote:

Hello,

I have the following csv text;

auto input = "Start Date,End Date,Subject,All day 
event,Categories,Show time as

1/1/2018,1/1/2018,New Year's Day,TRUE,Holiday,3
1/15/2018,1/15/2018,\"Martin Luther King, Jr. 
Day\",TRUE,Holiday,3

2/19/2018,2/19/2018,President's Day,TRUE,Holiday,3
5/28/2018,5/28/2018,Memorial Day,TRUE,Holiday,3
7/4/2018,7/4/2018,Independence Day,TRUE,Holiday,3
9/3/2018,9/3/2018,Labor Day,TRUE,Holiday,3
11/22/2018,11/22/2018,Thanksgiving Day,TRUE,Holiday,3
11/23/2018,11/23/2018,Day after Thanksgiving,TRUE,Holiday,3
12/24/2018,12/24/2018,Christmas Eve,TRUE,Holiday,3
12/25/2018,12/25/2018,Christmas Day,TRUE,Holiday,3";

What is the most clean compact efficient/lazy way to produce a 
range that removes the first line and then retains the second 
and third columns of the following lines, basically producing 
this;



"1/1/2018,New Year's Day
1/15/2018,\"Martin Luther King, Jr. Day\"
2/19/2018,President's Day
5/28/2018,Memorial Day
7/4/2018,Independence Day
9/3/2018,Labor Day,TRUE
11/22/2018,Thanksgiving Day
11/23/2018,Day after Thanksgiving
12/24/2018,Christmas Eve
12/25/2018,Christmas Day"

Thanks a bunch


This *almost* works:

import std.algorithm;
import std.range;
import std.stdio;
import std.string;

void main()
{
auto input = "Start Date,End Date,Subject,All day 
event,Categories,Show time as

1/1/2018,1/1/2018,New Year's Day,TRUE,Holiday,3
1/15/2018,1/15/2018,\"Martin Luther King, Jr. 
Day\",TRUE,Holiday,3

2/19/2018,2/19/2018,President's Day,TRUE,Holiday,3
5/28/2018,5/28/2018,Memorial Day,TRUE,Holiday,3
7/4/2018,7/4/2018,Independence Day,TRUE,Holiday,3
9/3/2018,9/3/2018,Labor Day,TRUE,Holiday,3
11/22/2018,11/22/2018,Thanksgiving 
Day,TRUE,Holiday,3
11/23/2018,11/23/2018,Day after 
Thanksgiving,TRUE,Holiday,3

12/24/2018,12/24/2018,Christmas Eve,TRUE,Holiday,3
12/25/2018,12/25/2018,Christmas 
Day,TRUE,Holiday,3";


input.lineSplitter()
.dropOne()
.map!(l =>
l.splitter(',')
 .dropOne()
 .take(2)
 .joiner(","))
.each!writeln();
}

The only problem is the comma in Martin Luther King, Jr. Day, so 
that line comes out as `1/15/2018,"Martin Luther King`.


Re: Alias on an array element

2017-10-13 Thread Meta via Digitalmars-d-learn

On Friday, 13 October 2017 at 13:22:42 UTC, Adam D. Ruppe wrote:
* Use a @property ref function to return the array element and 
trust the compiler to inline it.


You could also use pragma(inline, true).


Re: Alias on an array element

2017-10-12 Thread Meta via Digitalmars-d-learn

On Friday, 13 October 2017 at 01:12:38 UTC, solidstate1991 wrote:
On Friday, 13 October 2017 at 01:09:56 UTC, solidstate1991 
wrote:
I'm making a struct for easy color handling Here's a code 
sample:


ublic struct Color{
union{
		uint raw;	///Raw representation in integer form, also forces 
the system to align in INT32.
		ubyte[4] colors;	///Normal representation, aliases are used 
for color naming.

ubyte alpha, red, green, blue;
}
version(LittleEndian){
alias alpha = colors[0];
alias red = colors[1];
alias green = colors[2];
alias blue = colors[3];
}else{
alias alpha = colors[3];
alias red = colors[2];
alias green = colors[1];
alias blue = colors[0];
}
}

All the aliases are fail to compile, have not found anything 
about it in any of the documentations I checked.


Edit: ubyte alpha, red, green, blue; was added so I can 
continue debugging after the refactoring until I find a 
solution.


You can only create aliases for symbols, not expressions. You 
could create accessor functions that return the appropriate 
indices.


Re: How to check if string is available at compile time

2017-09-21 Thread Meta via Digitalmars-d-learn
On Thursday, 21 September 2017 at 12:30:15 UTC, David Bennett 
wrote:
On Thursday, 21 September 2017 at 11:42:36 UTC, David Bennett 
wrote:

[snip]

```
string[] escapeCTFE(Args...)(){

static foreach (arg; Args){
static if(__traits(compiles, ###WHATDOIPUTHERE###)){
[snip]



So far the best I've come up with is :

```

enum isCTstring(alias arg) = (!isAssignable!(typeof(arg)) || 
__traits(compiles, mixin(` "foo" ~ `~__traits(identifier, 
arg;


string[] escapeCTFE(Args...)(){

static foreach (arg; Args){
static if(isCTstring!(arg)){
pragma(msg, "Do work on string: ", arg);
}else{
pragma(msg, __traits(identifier, arg), " can only 
be read at runtime");

}
}
return new string[32];
}

```

But this seems quite hackish... any better ideas?


Try __traits(compiles, { enum _ = arg; }). Creating an enum 
necessarily requires that its value is available at compile time.


Re: Choosing between enum arrays or AliasSeqs

2017-08-24 Thread Meta via Digitalmars-d-learn

On Thursday, 24 August 2017 at 19:41:46 UTC, Nordlöw wrote:

Given

   enum e = ['a', 'b', 'c'];

   import std.meta : AliasSeq;
   enum a = AliasSeq!['a', 'b', 'c'];

is it somehow possible to convert (at compile-time) `e` to `a`?

Is it cheaper CT-performance wise to use AliasSeq instead of 
enum static arrays?


My use case is expressed by the TODOs in the following code 
snippet



import std.algorithm : among;

/** English indefinite articles. */
enum englishIndefiniteArticles = [`a`, `an`];

/** English definite articles. */
enum englishDefiniteArticles = [`the`];

/** English definite articles. */
enum englishArticles = englishIndefiniteArticles ~ 
englishDefiniteArticles;


/** Check if $(D c) is a Vowel. */
bool isEnglishIndefiniteArticle(C)(C c)
if (isSomeChar!C)
{
return cast(bool)c.among!(`a`, `an`); // TODO reuse 
englishIndefiniteArticles

}

/** Check if $(D c) is a Vowel. */
bool isEnglishDefiniteArticle(C)(C c)
if (isSomeChar!C)
{
return cast(bool)c.among!(`the`); // TODO reuse 
englishDefiniteArticles

}

/** Check if $(D c) is a Vowel. */
bool isEnglishArticle(C)(C c)
if (isSomeChar!C)
{
return cast(bool)c.among!(`a`, `an`, `the`); // TODO reuse 
englishArticles

}


https://dlang.org/phobos/std_meta.html#aliasSeqOf


Re: Automatic function body writing howto?

2017-08-16 Thread Meta via Digitalmars-d-learn
It's hard to tell offhand but I would recommend that you extract 
the inner string into a function that generates that string, 
allowing you to print out the finished product before mixing it 
in.


Re: Why does stringof not like functions with arguments?

2017-08-10 Thread Meta via Digitalmars-d-learn

On Thursday, 10 August 2017 at 15:55:41 UTC, Jason Brady wrote:
Wow. That makes perfect sense. I forgot stringof works only 
with expressions


It works with symbols too. See the following:

template test(){}
pragma(msg, test.stringof);




Re: Why does stringof not like functions with arguments?

2017-08-10 Thread Meta via Digitalmars-d-learn

On Wednesday, 9 August 2017 at 01:39:07 UTC, Jason Brady wrote:

Why does the following code error out with:

app.d(12,10): Error: function app.FunctionWithArguments (uint 
i) is not callable using argument types ()


Code:

import std.stdio;

void FunctionWithoutArguments() {
}

void FunctionWithArguments(uint i) {
}

void main()
{
writeln(FunctionWithoutArguments.stringof);
writeln(FunctionWithArguments.stringof);
}


Welcome to optional parentheses hell. Please enjoy your stay.

Because function calls in D can optionally omit the parens, 
`FunctionWithArguments.stringof` is actually attempting to call 
`FunctionWithArguments` without any arguments, and then call 
`stringof` on the result. In other words, it's actually trying to 
do this:


writeln(FunctionWithArguments().stringof);

And the D compiler is rightly telling you that you can't call the 
function with no arguments. The easiest solution is to use 
__traits(identifier) instead:


writeln(__traits(identifier, FunctionWithArguments));

You can make a handy template helper to do this for you:

enum stringOf(alias symbol) = __traits(identifier, symbol);
writeln(stringOf!FunctionWithArguments);


Re: if (auto x = cast(C) x)

2017-08-09 Thread Meta via Digitalmars-d-learn

On Wednesday, 9 August 2017 at 21:54:46 UTC, Q. Schroll wrote:
For a class/interface type `A` and a class `C` inheriting from 
`A` one can do


  A a = getA();
  if (auto c = cast(C) a)
  { .. use c .. }

to get a `C` view on `a` if it happens to be a `C`-instance.

Sometimes one cannot find a good new name for `c` while there 
is no advantage of accessing `a` when `c` is available. D does 
not allow to shadow `a` in the if-auto declaration for good 
reasons. How about relaxing the rule for cases like these, 
where the rhs is the lhs with a cast to derived?


  if (auto a = cast(C) a)
  { .. use a typed as C .. }

One can think of `a` being *statically* retyped to `C` as this 
is a (strictly) better type information. Internally, it would 
be a shadowing, but it does not matter as the disadvantages 
don't apply (if I didn't miss something).


One option is to use 
https://dlang.org/library/std/algorithm/comparison/cast_switch.html


Re: Template mixins and selective imports

2017-08-03 Thread Meta via Digitalmars-d-learn

On Thursday, 3 August 2017 at 19:03:55 UTC, Meta wrote:

`mixin vectorize!sin vsin; alias sin = vsin;` and see if it


Should be `alias sin = vsin.sin;`




Re: Template mixins and selective imports

2017-08-03 Thread Meta via Digitalmars-d-learn

On Thursday, 3 August 2017 at 15:29:47 UTC, jmh530 wrote:
I am trying to create a vectorize function that mixes in a new 
version of function with the same name that applies the 
function (to an ndslice).


The code below compiles without error and has the behavior I 
would expect.


However, when I change the function import to a selective 
import (e.g. from import std.math; to import std.math : sin;), 
then I get errors implying that the overload is not actually 
created.


Ideally, I would like to get this working with any kind of 
import.


One thing I noticed is that the fullyQualifiedName of sin 
changes quite a bit depending on whether you use one or the 
other.


This may be related to either of the following:
https://issues.dlang.org/show_bug.cgi?id=16287
https://issues.dlang.org/show_bug.cgi?id=16023



---

import std.traits : isFunction;

private enum _vectorize(string f) = "
import mir.ndslice.slice : SliceKind, Slice;

auto " ~ f ~ "(SliceKind kind, size_t[] packs, Iterator)
   (Slice!(kind, packs, 
Iterator) slice)

{
import mir.ndslice.topology : map;
return slice.map!(f);
}
";

mixin template vectorize(alias f)
if (isFunction!f)
{
mixin(_vectorize!(__traits(identifier, f)));
}

unittest
{
import std.stdio : writeln;
import mir.ndslice.slice : sliced;
import mir.ndslice.topology : map;
import std.math; //import std.math : sin;

auto x = [0.0, 1.0, 2.0, 3.0].sliced;

auto y = x.map!(sin);
writeln(y);

mixin vectorize!(sin);
auto z = sin(x);
writeln(z);
}


I'm not 100% certain, but I believe you have to bring the 
vectorized overload of sin into the overload set, so first try 
`mixin vectorize!sin vsin; alias sin = vsin;` and see if it works.


https://dlang.org/spec/function.html#overload-sets


Re: Pass range to a function

2017-07-28 Thread Meta via Digitalmars-d-learn

On Thursday, 27 July 2017 at 21:16:03 UTC, Chris wrote:
I'm using regex `matchAll`, and mapping it to get a sequence of 
strings. I then want to pass that sequence to a function. What 
is the general "sequence of strings" type declaration I'd need 
to use?


In C#, it'd be `IEnumerable`. I'd rather not do a 
to-array on the sequence, if possible. (e.g. It'd be nice to 
just pass the lazy sequence into my categorize function.)


What is the value of `???` in the following program:


```
import std.stdio, std.regex, std.string, 
std.algorithm.iteration;


auto regexToStrSeq(RegexMatch!string toks) {
  return toks.map!(t => t[0].strip());
}

void categorize(??? toks) {
  foreach (t; toks) {
writeln(t);
  }
}

void main()
{
auto reg = 
regex("[\\s,]*(~@|[\\[\\]{\\}()'`~^@]|\"(?:.|[^\"])*\"|;.*|[^\\s\\[\\]{}('\"`,;)]*)");

auto line = "(+ 1 (* 2 32))";
auto baz = matchAll(line, reg);

categorize(regexToStrSeq(baz).array);
}
```


If for some reason you can't make categorize a template like Ali 
suggested, or you need runtime polymorphism, you can use 
std.range.interfaces:


import std.range.interfaces;

void categorize(InputRange!string toks)
{
foreach (t; toks) {
writeln(t);
}
}

void main()
{
//etc.
categorize(inputRangeObject(regexToStrSeq(baz)));
}


Re: Array of Template instantiations

2017-07-20 Thread Meta via Digitalmars-d-learn

On Thursday, 20 July 2017 at 13:11:56 UTC, Alex wrote:

On Thursday, 20 July 2017 at 12:33:43 UTC, Alex wrote:
The Problem is, i dont know what type WHAT_TYPE is / i don´t 
know how to build a loopable something of futures.


Ok, i think i understood now.

my function `load` returns `KpiResponseEntity`
so

Future!(KpiResponseEntity)[] futures;

seems to work


To get the type you can also use `typeof`.

alias ResponseType = typeof(async( , queryA ));
ResponseType[] futures;
futures ~= async(  , queryA );
futures ~= async(  , queryB );
futures ~= async(  , queryC );


Re: replacement for squeeze and removechars.

2017-07-18 Thread Meta via Digitalmars-d-learn

On Tuesday, 18 July 2017 at 15:28:06 UTC, Antonio Corbi wrote:

Hi all,

I'm trying dmd-2.075.0-rc1 in one of my projects where I use 
`squeeze` and `removechars`. Both of them are flagged as 
obsolete and in the docs we are suggested to use functions from 
std.regex and/or std.algorithm.


Does any one kow a one-liner from std.regex or std.algorithm 
that can take the role of those deprecated functions?


Thank's
A. Corbi


As Seb somewhat undiplomatically put, there are replacements 
listed in the changelog.


Use std.regex.replaceAll to replace std.string.removechars:

import std.string;
import std.regex;

// old
"abc".removechars("a-z");

// new
"abc".replaceAll(regex("[a-z]"), "");



Use std.algorithm.iteration.uniq to replace std.string.squeeze:

import std.algorithm;
import std.string;

// old
"hello".squeeze;

// new
"hello".uniq;



Though it would be nice to have these alternatives listed right 
there in the deprecation message.


Re: Fiber based UI-Toolkit

2017-07-09 Thread Meta via Digitalmars-d-learn

On Sunday, 9 July 2017 at 21:12:24 UTC, bauss wrote:

On Sunday, 9 July 2017 at 19:43:14 UTC, Christian Köstlin wrote:
I wonder if there is any fiber based / fiber compatible 
UI-Toolkit out for dlang. The second question is, if it would 
make sense at all to have such a thing?


christian


It doesn't really make sense to have that, because most (if not 
all) operating systems only allow rendering from a single 
thread and I believe OSX (possibly macOS too.) only allows it 
from the main thread. Which means the only thing you can really 
operate on other threads are events, but you'll always have to 
do callbacks to your UI thread in order to render.


Aren't all fibers executed from a single thread?


Re: Advice wanted on garbage collection of sockets for c++ programmer using D

2017-06-29 Thread Meta via Digitalmars-d-learn

On Wednesday, 28 June 2017 at 15:55:41 UTC, John Burton wrote:

On Tuesday, 27 June 2017 at 09:54:19 UTC, John Burton wrote:
I'm coming from a C++ background so I'm not too used to 
garbage collection and it's implications. I have a function 
that creates a std.socket.Socket using new and connects to a 
tcp server, and writes some stuff to it. I then explicitly 
close the socket, and the socket object goes out of scope.




Am I doing this right? Or is there a better way to do this in 
D?


Thanks.



For my use case here, I'm increasingly thinking that just 
calling the underlying 'C' socket and send calls is better. No 
need for anything complicated at all for my actual program :)


One final piece of advice as this thread seemed to have gone off 
the rails a bit. You can always put a `scope(exit) 
socket.close();` after you create the socket. This will ensure 
that the socket will be closed once the scope is exited no matter 
what... almost, anyway. If an Error is thrown no stack unwinding 
is done but at this point your program is in an unrecoverable 
state anyway and you have a lot more to worry about than a socket 
that hasn't been closed.


Re: Help me escape optional parens hell

2017-06-24 Thread Meta via Digitalmars-d-learn

On Saturday, 24 June 2017 at 08:08:33 UTC, ketmar wrote:

Meta wrote:

So I have no clue what I'm doing wrong. This is driving me 
insane.


h. known $#^#$@^@%.

	enum SymName = ().stringof[2..$]; // this, instead of 
symbol.stringof


dirty hack, let's hope that DMD devs won't change `.toString()` 
output (i.e. first two chars will always be "& ").


besides this, i know no other way to stop compiler from calling 
the function there.


It's dirty but I guess I'll have to go with this hack for the 
time being.


Also, I filed a bug:

https://issues.dlang.org/show_bug.cgi?id=17546


Help me escape optional parens hell

2017-06-24 Thread Meta via Digitalmars-d-learn

The code:

alias Response = Nullable!(string, "empty response (error)");

Response processMessage(string commandModule)(string message, 
bool isCommand)

{
import std.meta;
import std.string;
import std.traits;

import command_uda;

mixin("import " ~ commandModule ~ ';');
bool foundCommandMatch = false;
foreach(symbol; getSymbolsByUDA!(mixin(commandModule), 
Command))

{
enum commandUDA = getUDAs!(symbol, Command)[0];
auto commandPhrase = commandUDA.phrase == "" ? 
symbol.stringof : commandUDA.phrase; //Error: function signature> is not callable using argument types ()
auto commandPhrasePattern = 
regex(`^%s\s`.format(commandPhrase));
if (message.matchFirst(commandPhrasePattern) && 
!foundCommandMatch)

{
version(responseDebug) writeln("Matched command ", 
symbol.stringof, " with phrase '", commandPhrase, "'\n"); //Same 
issue

return Response(symbol(message.strip()));
}
}

return Response.init;
}

I've been banging my head against this and cannot figure out why 
`symbol.stringof` is being called instead of getting a string of 
the symbol. I tried to create a reduced test case but it works 
fine:


import std.stdio;
import std.traits;

enum Attr;

@Attr string test1() { return __FUNCTION__; }
@Attr string test2() { return __FUNCTION__; }

void process()
{
foreach (symbol; getSymbolsByUDA!(mixin(__MODULE__), Attr))
{
		writeln("The result of calling ", symbol.stringof, " is ", 
symbol());

}
}

void main()
{
process();
}

So I have no clue what I'm doing wrong. This is driving me insane.


Re: Builtin array-scalar equality

2017-06-14 Thread Meta via Digitalmars-d-learn

On Wednesday, 14 June 2017 at 21:15:32 UTC, Nordlöw wrote:

Why isn't

bool c = a[] == 4;

allowed when

a[] = b[] + 4;

is?

given that

int[] a, b;


That's just how it is. There are a lot of array-wise operations 
that *could* be implemented in the language but aren't.


Re: Algebra With Types

2017-04-21 Thread Meta via Digitalmars-d-learn

On Friday, 21 April 2017 at 18:54:38 UTC, David Sanders wrote:
Thank-you for your input. With your help, I was able to figure 
out number whether a type is an instantiation of 
std.variant.Algebraic.


Now, I need help on concatenating Template Sequence Parameters. 
See the block comments below.


Thanks,
Dave

import std.stdio;
import std.variant;

alias Zero = void;

struct One{};

struct Sum(T, U) {
static if (is(T == Zero)) {
static if (is(U == Zero)) {
alias type = Zero;
}
else {
alias type = U;
}
} else static if (is(U == Zero)) {
alias type = T;
} else static if (is(T _ == VariantN!V, V...)) {
static if(is(U _ == VariantN!W, W...)) {
alias type = Algebraic!/* Concatenate V[1..$] with 
U[1..$] */
} else {
alias type = Algebraic!/* Concatenate V[1..$] with U */
}
} else static if(is(U _ == VariantN!V, V...)) {
alias type = Algebraic!/* Concatenate T with V[1..$] */
} else {
alias type = Algebraic!(T, U);
}   
}

void main() {
static assert (is(Zero == Sum!(Zero, Zero).type));
static assert (is(One == Sum!(Zero, One).type));
static assert (is(One == Sum!(One, Zero).type));
	static assert (is(Algebraic!(One, One) == Sum!(One, 
One).type));
	static assert (is(Algebraic!(One, One, One) == Sum!(Sum!(One, 
One).type, One).type));

}


As an aside, there's a less convoluted way to do type-level 
arithmetic which is IMO also more concise and looks nicer. You 
don't have to mess around with Algebraic at all:


struct Zero;

struct Succ(N);

alias One = Succ!Zero;

alias Pred(N: Zero)= Zero;
alias Pred(N: Succ!Np, Np) = Np;

alias Add(N1: Zero, N2: Zero) = Zero;
alias Add(N1,   N2: Zero) = N1;
alias Add(N1: Zero, N2)   = N2;
alias Add(N1,   N2)   = Add!(Succ!N1, Pred!N2);

void main()
{
static assert(is(Pred!One == Zero));
static assert(is(Succ!One == Succ!(Succ!Zero)));

static assert(is(Add!(Zero, Zero) == Zero));
static assert(is(Add!(Zero, One) == One));
static assert(is(Add!(One, Zero) == One));
static assert(is(Add!(One, One) == Succ!(Succ!(Zero;

alias Two = Succ!One;
static assert(is(Add!(One, One) == Two));
static assert(is(Add!(One, Two) == Succ!(Succ!(Succ!Zero;

static assert(is(Sub!(Zero, Zero) == Zero));
static assert(is(Sub!(One, Zero) == One));
static assert(is(Sub!(Zero, One) == Zero));
static assert(is(Sub!(Two, One) == One));
static assert(is(Sub!(One, Two) == Zero));
}

Implementing Mul, Div and the integer set is an exercise left to 
the reader.




Re: Algebra With Types

2017-04-21 Thread Meta via Digitalmars-d-learn

On Friday, 21 April 2017 at 16:31:37 UTC, H. S. Teoh wrote:
On Fri, Apr 21, 2017 at 04:16:30PM +, David Sanders via 
Digitalmars-d-learn wrote:
I'm trying to do algebra with types ala 
http://chris-taylor.github.io/blog/2013/02/10/the-algebra-of-algebraic-data-types/


Below you will find my attempts at "adding" types in D. I've 
outlined the parts I'm having trouble with using block 
comments.


1) How do I figure out whether a type is an instantiation of
std.variant.Algebraic?
2) If the type is Algebraic, how do I capture its AllowedTypes?

[...]

static if (is(T : Algebraic!(U...), U))
{
// U now refers to the argument to Algbraic.
}


--T


There's also a private `isAlgebraic` template[1]. Is there any 
reason why we couldn't just make this public?


1. https://github.com/dlang/phobos/blob/master/std/variant.d#L2236


Re: How to get return type of current method?

2017-04-18 Thread Meta via Digitalmars-d-learn

On Wednesday, 19 April 2017 at 00:22:14 UTC, Mike B Johnson wrote:

On Tuesday, 18 April 2017 at 23:49:35 UTC, ketmar wrote:

Mike B Johnson wrote:

How can I get the return type of the current method without 
specifying the name or any complexity? Similar to 
typeof(this).


typeof(return)


Thanks, sweet and simple!


One note: if the function has a return type of `auto`, you cannot 
use `typeof(return)` within the function.


Re: Using template mixin, with or without mixin ?

2017-04-08 Thread Meta via Digitalmars-d-learn

On Saturday, 8 April 2017 at 22:37:18 UTC, ag0aep6g wrote:

On 04/08/2017 11:59 PM, Meta wrote:

enum a = 0;

template test1()
{
enum b1 = a; //Okay, a is in scope at the declaration site
//enum c = d1; Error: undefined identifier d1


This line works just fine, actually. There's really no 
difference between a normal template and a mixin template when 
you use it in a mixin.



}

mixin template test2()
{
enum b2 = a; //Okay, a is in scope at the declaration site
enum c = d1; //Okay, d1 is in scope at the *instantiation* 
site

//enum e = d2; Error: undefined identifier d2
}

void main()
{
enum d1 = 0; //<--d1 is declared here
mixin test1!();
mixin test2!(); //<--so it is in scope here
enum d2 = 0; //d2 was not declared before test2 was mixed 
in

 //so it is not in scope for test2
}


Hmm, you're right, but this is not how it is supposed to behave 
according to the documentation.


https://dlang.org/spec/template-mixin.html


Re: Using template mixin, with or without mixin ?

2017-04-08 Thread Meta via Digitalmars-d-learn

On Saturday, 8 April 2017 at 09:47:07 UTC, biocyberman wrote:

On Friday, 7 April 2017 at 23:53:12 UTC, Ali Çehreli wrote:


The difference is that you can't use funcgen as a regular 
template:


funcgen!(void, void);

Error: template instance funcgen!(void, void) mixin templates 
are not regular templates


I think it's good practice to use 'mixin template' if it's 
intended to be so.


Ali


Thanks for a very concise answer.


In addition to Ali's answer, mixin templates do their symbol 
looking at the instantiation site, while regular templates do it 
at the declaration site. Example:


enum a = 0;

template test1()
{
enum b1 = a; //Okay, a is in scope at the declaration site
//enum c = d1; Error: undefined identifier d1
}

mixin template test2()
{
enum b2 = a; //Okay, a is in scope at the declaration site
enum c = d1; //Okay, d1 is in scope at the *instantiation* site
//enum e = d2; Error: undefined identifier d2
}

void main()
{
enum d1 = 0; //<--d1 is declared here
mixin test1!();
mixin test2!(); //<--so it is in scope here
enum d2 = 0; //d2 was not declared before test2 was mixed in
 //so it is not in scope for test2
}


Re: Is DMD breaking BigInt?

2017-04-08 Thread Meta via Digitalmars-d-learn

On Saturday, 8 April 2017 at 12:14:31 UTC, Russel Winder wrote:
On Fri, 2017-04-07 at 22:47 +, Meta via Digitalmars-d-learn 
wrote:

[…]

Do you have the -dip1000 switch enabled?


Not as far as I know. Why would I want to do that?


You wouldn't as the std lib doesn't work with it yet.


Re: Is DMD breaking BigInt?

2017-04-07 Thread Meta via Digitalmars-d-learn

On Friday, 7 April 2017 at 17:06:31 UTC, Russel Winder wrote:
Simple Dub build of a Factorial example using Unit-Threaded for 
testing. Works fine with ldc2 breaks with dmd. This is on 
Debian Sid fully up to date.


|> ldc2 --version
LDC - the LLVM D compiler (1.1.1):
  based on DMD v2.071.2 and LLVM 3.9.1
  built with LDC - the LLVM D compiler (1.1.0)
  Default target: x86_64-pc-linux-gnu
  Host CPU: broadwell
  http://dlang.org - http://wiki.dlang.org/LDC

|> dmd --version
DMD64 D Compiler v2.073.2

|> dub test --compiler=ldc2
Package factorial (configuration "unittest") defines no import 
paths, use {"importPaths": [...]} or the default package 
directory structure to fix this.

Running custom 'unittest' configuration.
Performing "unittest" build using ldc2 for x86_64.
unit-threaded 0.7.11: target for configuration "library" is up 
to date.

factorial ~master: building configuration "unittest"...
Running pre-build commands...
Building package unit-threaded in 
/home/users/russel/.dub/packages/unit-threaded-0.7.11/unit-threaded/

Performing "$DFLAGS" build using dmd for x86_64.
unit-threaded 0.7.11: building configuration "gen_ut_main"...
Linking...
Running 
../../../../.dub/packages/unit-threaded-0.7.11/unit-threaded/gen_ut_main -f ut_main.d
To force a rebuild of up-to-date targets, run again with 
--force.

Running ./factorial-test

Automatically generated file ut_main.d
Running unit tests from dirs ["."]
factorial.Check the base case for all algorithms.:
factorial.Check the property for all algorithms.:
factorial.Traditional example-based testing.:

Time taken: 34 ms, 363 μs, and 2 hnsecs
3 test(s) run, 0 failed.

OK!

|> dub test
Package factorial (configuration "unittest") defines no import 
paths, use {"importPaths": [...]} or the default package 
directory structure to fix this.

Running custom 'unittest' configuration.
Performing "unittest" build using dmd for x86_64.
unit-threaded 0.7.11: target for configuration "library" is up 
to date.

factorial ~master: building configuration "unittest"...
Running pre-build commands...
Building package unit-threaded in 
/home/users/russel/.dub/packages/unit-threaded-0.7.11/unit-threaded/

Performing "$DFLAGS" build using dmd for x86_64.
unit-threaded 0.7.11: building configuration "gen_ut_main"...
Linking...
Running 
../../../../.dub/packages/unit-threaded-0.7.11/unit-threaded/gen_ut_main -f ut_main.d
factorial.d(71,15): Error: template std.bigint.BigInt.__ctor 
cannot deduce function from argument types !()(string) 
immutable, candidates are:
/usr/include/dmd/phobos/std/bigint.d(64,5):
std.bigint.BigInt.__ctor(Range)(Range s) if 
(isBidirectionalRange!Range && isSomeChar!(ElementType!Range) 
&& !isInfinite!Range)
/usr/include/dmd/phobos/std/bigint.d(146,5):
std.bigint.BigInt.__ctor(T)(T x) if (isIntegral!T)
/usr/include/dmd/phobos/std/bigint.d(162,5):
std.bigint.BigInt.__ctor(T)(T x) if (is(Unqual!T == BigInt))

dmd failed with exit code 1.


If anyone has any useful intelligence as to what happening and 
how I

can workaround it, I'd be a grateful bunny.


Do you have the -dip1000 switch enabled?


Re: Write file at compile time?

2017-04-03 Thread Meta via Digitalmars-d-learn

On Sunday, 2 April 2017 at 19:42:52 UTC, Inquie wrote:
I would like to write the output of a manifest constant at 
compile time to a file instead of console using pragma(msg). Is 
this possible?


D does not allow IO at compile time for security reasons.


Re: Template specialisation for range of types

2017-03-12 Thread Meta via Digitalmars-d-learn

On Sunday, 12 March 2017 at 21:12:13 UTC, data pulverizer wrote:

On Sunday, 12 March 2017 at 20:15:43 UTC, Meta wrote:
auto max(T: const U, U)(T* x, T* y) <- Changed `ConstOf!U` 
to `const U`

{
writeln("Const template");
return *x > *y ? x : y;
}
How detailed can I be about the template specialisation? From 
example in the book "C++ the complete guide" we can have:


/* pointer const reference */
template
inline T* const& max(T* const& a, T* const)
{
return a* < b* ? b : a;
}

/* const reference const pointer */
template
inline T const* const& max(T* const* const& a, T* const* const& 
b)

{
...;
}

What would be the equivalent in D?


Unfortunately this is impossible in D as const is transitive. The 
best you can do is try to emulate it using wrapper types. I'd 
start by taking a look at std.experimental.typecons.Final, which 
implements C++-style head (logical) constness.




Re: Template specialisation for range of types

2017-03-12 Thread Meta via Digitalmars-d-learn

On Sunday, 12 March 2017 at 20:22:33 UTC, ketmar wrote:

Meta wrote:

The reason this doesn't work is when you use ConstOf!U, it's 
not looking for a `const U`, it's looking for the type 
`ConstOf!U`. I'm not sure if this is a bug or not...


no, not a bug. this is the way type deconstruction works: it 
checks if your type was constructed with a given template.


Yeah, it seems to be checking the pattern rather than the type. 
However, ConstOf!T is just an alias for const(T), but the alias 
does not seem to be "unwrapped", even though they are supposed to 
be transparent.


Re: Template specialisation for range of types

2017-03-12 Thread Meta via Digitalmars-d-learn

On Sunday, 12 March 2017 at 18:49:22 UTC, data pulverizer wrote:

Hello all,

I am attempting to write templates for differently qualified 
types using specialisations. Below is an example for const and 
non-const outlining my approach:



``
import std.stdio : writeln;
import std.traits : ConstOf;

auto max(T)(T x, T y)
{
writeln("General template");
return x > y ? x : y;
}


auto max(T: ConstOf!U, U)(T* x, T* y)
{
writeln("Const template");
return *x > *y ? x : y;
}


void main(){
const double p = 2.4, q = 3;
writeln(max(, ));
}
``

I get this output:

General template
7FFE5B3759A8


In this case would like to use the ConstOf specialisation 
instead of the default implementation for the inputs which are 
const.


Thanks for you answers in advance


You need to make one little change for this to work:

import std.stdio : writeln;
import std.traits : ConstOf;

auto max(T)(T x, T y)
{
writeln("General template");
return x > y ? x : y;
}


auto max(T: const U, U)(T* x, T* y) <- Changed `ConstOf!U` to 
`const U`

{
writeln("Const template");
return *x > *y ? x : y;
}


void main(){
const double p = 2.4, q = 3;
writeln(max(, )); //Prints "Const template"
}


The reason this doesn't work is when you use ConstOf!U, it's not 
looking for a `const U`, it's looking for the type `ConstOf!U`. 
I'm not sure if this is a bug or not... Anyway, this will also 
work if we change the following:


void main(){
	ConstOf!double p = 2.4, q = 3; <- Changed `const double` to 
`ConstOf!double`

writeln(max(, )); //Prints "Const template"
}


Re: Comparing Instances of Classes

2017-03-10 Thread Meta via Digitalmars-d-learn

On Friday, 10 March 2017 at 17:08:42 UTC, Whatsthisnow wrote:
I guess i am just too used to the java way of x.equals(object) 
which at the source  is exactly 'return this == object'


Java would return false here too, though, if it actually did 
`this == object` in its default compare method. If I remember 
correctly, comparing two objects with == in Java compares their 
addresses, not their contents.


Re: In Expressions

2017-03-04 Thread Meta via Digitalmars-d-learn

On Saturday, 4 March 2017 at 17:11:46 UTC, Andrey wrote:
Hello, is there any way to using in expression like in python, 
e.g.

if 4 in [1, 3, 4]:
do something


My code in D

if (regionAlign in [RegionAlign.top, RegionAlign.bottom]) {
   ...
}


throws an error:
incompatible types for (((cast(Widget)this).regionAlign()) in 
([top, bottom])): 'RegionAlign' and 'RegionAlign[]'


The reason this is disallowed for normal arrays is that finding a 
key in an array is O(n) while finding a key in an associative 
array is O(1). Rather than let users unknowingly write code that 
looks the same but is far slower for arrays, D doesn't allow 
this. You can use std.algorithm.among, however.


import std.algorithm;

if (regionAlign.among!(RegionAlign.top, RegionAlign.bottom))
{
//etc.
}

http://dlang.org/phobos/std_algorithm_comparison.html#.among


Re: template parameter inference and introspection

2017-02-24 Thread Meta via Digitalmars-d-learn

On Friday, 24 February 2017 at 11:17:46 UTC, John Colvin wrote:
Unfortunately that only works by accident of my example. A 
counterexample:


T foo(Q = float, T = short)(T t) { return t; }

alias Typeof(alias v) = typeof(v);

template getInstantiation(alias f, T...)
{
import std.meta;

alias getInstantiation = f!(staticMap!(Typeof, T));
}

static assert(is(typeof(foo(3)) == int)); // ok
static assert(is(typeof(getInstantiation!(foo, 3)(3)) == int)); 
// fails


This looks like VRP is kicking in when it shouldn't, or maybe 
it's a different bug. 3 should be typed as int by default unless 
we explicitly ask for something else.


Re: template parameter inference and introspection

2017-02-23 Thread Meta via Digitalmars-d-learn

On Thursday, 23 February 2017 at 18:21:51 UTC, Meta wrote:
On Thursday, 23 February 2017 at 16:01:44 UTC, John Colvin 
wrote:
Is there any way to get a reference/alias to the instantiation 
of a template function that would be called, given certain 
parameters? I.e. to get the result of whatever template 
parameter inference (and overload resolution) has occurred?


E.g. for some arbitrarily complex foo:

static assert(__traits(compiles, foo(3)));
alias fooWithInt = someMagic(foo(3));

so if foo was `void foo(T)(T t) {}` then `fooWithInt` would be 
`foo!int`, but if it was `void foo(Q = float, T = long)(T t)` 
then `fooWithInt` would be `foo!(float, int)`


I don't believe so, because foo(3) is a value (void), not a 
type like foo!int would be. You can't get it back after you've 
called the function. You would have to do something like:


alias fooWithInt = someMagic!foo(3);

Where someMagic constructs the alias to foo!int based on the 
type of arguments passed, or something like that.


A quick and rough example I threw together. Annoyingly, I can't 
figure out a way to tell the compiler that I want to printout the 
symbol of fooWithInt, not call it without parens. The best I can 
do is print out its type.


void foo(T)(T t) {}
void foo(Q = float, T = long)(T t) {}

alias Typeof(alias v) = typeof(v);

template getInstantiation(alias f, T...)
{
import std.meta;

alias getInstantiation = f!(staticMap!(Typeof, T));
}

alias fooWithInt = getInstantiation!(foo, 3);
alias fooWithLong = getInstantiation!(foo, 3L);

void main()
{
pragma(msg, typeof(fooWithInt));
pragma(msg, typeof(fooWithLong));
}


Re: template parameter inference and introspection

2017-02-23 Thread Meta via Digitalmars-d-learn

On Thursday, 23 February 2017 at 16:01:44 UTC, John Colvin wrote:
Is there any way to get a reference/alias to the instantiation 
of a template function that would be called, given certain 
parameters? I.e. to get the result of whatever template 
parameter inference (and overload resolution) has occurred?


E.g. for some arbitrarily complex foo:

static assert(__traits(compiles, foo(3)));
alias fooWithInt = someMagic(foo(3));

so if foo was `void foo(T)(T t) {}` then `fooWithInt` would be 
`foo!int`, but if it was `void foo(Q = float, T = long)(T t)` 
then `fooWithInt` would be `foo!(float, int)`


I don't believe so, because foo(3) is a value (void), not a type 
like foo!int would be. You can't get it back after you've called 
the function. You would have to do something like:


alias fooWithInt = someMagic!foo(3);

Where someMagic constructs the alias to foo!int based on the type 
of arguments passed, or something like that.


Re: Append variadic template parameters

2017-02-05 Thread Meta via Digitalmars-d-learn

On Sunday, 5 February 2017 at 20:36:57 UTC, Mark Fisher wrote:

I want to write a template:

static auto ref BindArg(alias Func,alias arg,args...)() {
return Func(arg,args);
}

where Func is called with 'arg' followed by the 'args' 
parameters.

eg:

string f(string a,int b,int c);


BindArg(f,"1",2,3);

You forgot the !



The compiler throws an error:
Error: function f (string a, int b, int c) is not callable 
using argument types ()


How do I append the parameters?





Re: Is it ok to inherit multiple times same templated interface?

2017-01-16 Thread Meta via Digitalmars-d-learn

On Sunday, 15 January 2017 at 23:25:25 UTC, Ryan wrote:

How would overloading work?

Overload resolution works based on function/method parameters, 
not return types. In the example you gave the 3 get functions 
are indistinguishable. If the template parameter was used for a 
method parameter type, then they would be distinguishable.


Since the functions all have the same signature and interfaces 
can't store internal state, it doesn't matter which one is called.


  1   2   3   4   5   >