Re: Error: llroundl cannot be interpreted at compile time, because it has no available source code

2020-06-08 Thread mw via Digitalmars-d-learn
On Monday, 8 June 2020 at 19:05:45 UTC, Steven Schveighoffer 
wrote:

On 6/8/20 2:53 PM, mw wrote:
And with a symbol-to-c-func table, it should be able to just 
call that C func.


Consider that the libc available to the compiler might not be 
the same as the libc for the target (e.g. cross compilation).


Not just that, but this opens the compiler up to a huge hole of 
unpredictability and security.


I head that.

But, can we take a pragmatic approach, not the "all-or-none" 
approach as I talked about in the other MI thread: 
(https://forum.dlang.org/post/lsnhqdoyatkzbzqbs...@forum.dlang.org)


We can have an approved list of C funcs that allowed to be called 
during CTFE? e.g. math funcs about numbers, but not network or 
string C funcs.


Most people define static const for some numerical values, allow 
C math func at CTFE may solve a large part of the problems 
(80-90%? just my guess).




Re: Error: llroundl cannot be interpreted at compile time, because it has no available source code

2020-06-08 Thread Steven Schveighoffer via Digitalmars-d-learn

On 6/8/20 2:53 PM, mw wrote:
And with a symbol-to-c-func table, it should be able to just call that C 
func.


Consider that the libc available to the compiler might not be the same 
as the libc for the target (e.g. cross compilation).


Not just that, but this opens the compiler up to a huge hole of 
unpredictability and security.


-Steve


Re: Error: llroundl cannot be interpreted at compile time, because it has no available source code

2020-06-08 Thread mw via Digitalmars-d-learn

On Monday, 8 June 2020 at 18:43:58 UTC, Stanislav Blinov wrote:

On Monday, 8 June 2020 at 18:08:57 UTC, mw wrote:

2) even it does so, but why such simple function as lroundl 
cannot be CTFE-ed?


Because, as the error message states, there's no source for it 
:) std.math calls into C math library.


OK, but the compiler knows it's external C func:

  return core.stdc.math.llroundl(x);

And with a symbol-to-c-func table, it should be able to just call 
that C func.


This is dramatically enhance CTFE's eval ability, esp for math 
funcs.


Re: Error: llroundl cannot be interpreted at compile time, because it has no available source code

2020-06-08 Thread Steven Schveighoffer via Digitalmars-d-learn

On 6/8/20 2:08 PM, mw wrote:

Hi,

I'm trying to build this package:

https://code.dlang.org/packages/fixed

however, the compiler error out:

ldc2-1.21.0-linux-x86_64/bin/../import/std/math.d(5783,39): Error: 
llroundl cannot be interpreted at compile time, because it has no 
available source code


Looks like it does some CTFE, but

1) I cannot find where CTFE happens in:

https://github.com/jaypha/fixed/blob/master/src/jaypha/fixed.d


Are you statically initializing a Fixed type?

e.g. (in global scope):

auto myFixedVal = Fixed!2("1.5");

That constructor call is done via CTFE. The constructor calls 
std.math.lround. lround uses libc, which has no source available.


2) even it does so, but why such simple function as lroundl cannot be 
CTFE-ed?


The simplicity of the function has nothing to do with whether it can be 
CTFE. It has to do with the source code being available (as the error 
message indicates).


Note that the fix for the package would be to have an alternate CTFE 
branch, or to quit using libc.


An alternative package was created here to fix a different issue (that 
strings are converted to double to convert to the proper integer type), 
but it too will use libc when initializing a fixed point type from a 
double: https://github.com/m3m0ry/fixedpoint


So depending on your usage, it may solve your problem. Plus, it's 
actually being currently maintained, I don't think the original package is.


-Steve


Re: Dub Error Message "Invalid variable: DUB"

2020-06-08 Thread Andre Pany via Digitalmars-d-learn

On Monday, 8 June 2020 at 18:38:17 UTC, Paul Backus wrote:

On Monday, 8 June 2020 at 17:55:24 UTC, Andre Pany wrote:


I had a second look on the descriptions and from a non native 
speaker view it sounds correct.
But you are right from a native speaker view the wording might 
be incorrect.


If you have time, could you check the wording and make a 
proposal?


https://github.com/dlang/dub-docs/blob/master/views/inc.package_format.envvars.dt

Kind regards
Andre


https://github.com/dlang/dub-docs/pull/26


Thanks a lot.

Kind regards
Andre


Re: Error: llroundl cannot be interpreted at compile time, because it has no available source code

2020-06-08 Thread Stanislav Blinov via Digitalmars-d-learn

On Monday, 8 June 2020 at 18:08:57 UTC, mw wrote:

2) even it does so, but why such simple function as lroundl 
cannot be CTFE-ed?


Because, as the error message states, there's no source for it :) 
std.math calls into C math library.


Re: Dub Error Message "Invalid variable: DUB"

2020-06-08 Thread Paul Backus via Digitalmars-d-learn

On Monday, 8 June 2020 at 17:55:24 UTC, Andre Pany wrote:


I had a second look on the descriptions and from a non native 
speaker view it sounds correct.
But you are right from a native speaker view the wording might 
be incorrect.


If you have time, could you check the wording and make a 
proposal?


https://github.com/dlang/dub-docs/blob/master/views/inc.package_format.envvars.dt

Kind regards
Andre


https://github.com/dlang/dub-docs/pull/26


Error: llroundl cannot be interpreted at compile time, because it has no available source code

2020-06-08 Thread mw via Digitalmars-d-learn

Hi,

I'm trying to build this package:

https://code.dlang.org/packages/fixed

however, the compiler error out:

ldc2-1.21.0-linux-x86_64/bin/../import/std/math.d(5783,39): 
Error: llroundl cannot be interpreted at compile time, because it 
has no available source code


Looks like it does some CTFE, but

1) I cannot find where CTFE happens in:

https://github.com/jaypha/fixed/blob/master/src/jaypha/fixed.d


2) even it does so, but why such simple function as lroundl 
cannot be CTFE-ed?


Re: Dub Error Message "Invalid variable: DUB"

2020-06-08 Thread Andre Pany via Digitalmars-d-learn

On Sunday, 7 June 2020 at 16:54:48 UTC, Paul Backus wrote:

On Sunday, 7 June 2020 at 16:26:17 UTC, Andre Pany wrote:

On Sunday, 7 June 2020 at 15:37:27 UTC, Paul Backus wrote:

On Sunday, 7 June 2020 at 12:52:12 UTC, Andre Pany wrote:


I am not sure but $DUB is a variable which could be used in 
dub descriptor file but it isn't an environment variable.


$DUB_EXE is an environment variable.

Kind regards
Andre


If what you say is true, the Dub documentation needs to be 
updated:


https://dub.pm/package-format-json.html#environment-variables


Each of the table has an explanation section were they can be 
used. $DUB can only be used within the dub descriptor but not 
within scripts called from the hooks.


From the hooks you can use these environment variables: 
https://github.com/andre2007/dub/blob/376ff5854dcd7bbc6116f72001c8c6d13eb3cbf0/source/dub/generators/generator.d#L763


Kind regards
Andre


The documentations says:

Inside of custom commands directives a number of additional 
variables is available:


...and then lists the variables from the function you linked 
to. "Additional" implies that they are not the only variables 
that can be used in hooks, and that the variables listed 
previously (such as $DUB) can also be used. If this is not the 
case, then the documentation is inaccurate and should be 
updated.


I would also add: if you feel the need to link to the source 
code to explain to use a feature, rather than referring to the 
documentation, that is a good sign that the documentation is 
inadequate.


I had a second look on the descriptions and from a non native 
speaker view it sounds correct.
But you are right from a native speaker view the wording might be 
incorrect.


If you have time, could you check the wording and make a proposal?

https://github.com/dlang/dub-docs/blob/master/views/inc.package_format.envvars.dt

Kind regards
Andre



Re: Mixin and imports

2020-06-08 Thread data pulverizer via Digitalmars-d-learn
On Monday, 8 June 2020 at 16:02:02 UTC, Steven Schveighoffer 
wrote:

On 6/8/20 11:11 AM, jmh530 wrote:

On Monday, 8 June 2020 at 14:27:26 UTC, data pulverizer wrote:

[snip]

Out of curiosity what does the "." in front of `foo` mean? 
[snip]


ag0aep6g provided the link to it [snip]


The dot operator simply specifies that the symbol you are 
looking for is defined at global scope, so it just changes the 
lookup rules.


Even though it makes the code clearer what foo you are looking 
at, it was not necessary -- removing the dot works.


In some cases it is necessary to use the . lookup rule, because 
you have another symbol that will be picked first.


For example:

int x;

template bar(string x)
{
   mixin("alias " ~ x ~ " = .x;");
}

-Steve


Thanks both of you. It's one of those puzzling things that was at 
the back of mind that has just been resolved.




Re: Mixin and imports

2020-06-08 Thread Steven Schveighoffer via Digitalmars-d-learn

On 6/8/20 11:11 AM, jmh530 wrote:

On Monday, 8 June 2020 at 14:27:26 UTC, data pulverizer wrote:

[snip]

Out of curiosity what does the "." in front of `foo` mean? I've seen 
that in some D code on the compiler in GitHub and have no idea what it 
does. I tried Googling it to no avail. It doesn't have anything to do 
with UFCS does it?


Thanks


ag0aep6g provided the link to it, but it's one of those things that has 
been difficult for me to understand as well. I believe the original code 
had `foo` in a template. So in that case it was necessary. I'm not sure 
if it still is in my simplified version.


The dot operator simply specifies that the symbol you are looking for is 
defined at global scope, so it just changes the lookup rules.


Even though it makes the code clearer what foo you are looking at, it 
was not necessary -- removing the dot works.


In some cases it is necessary to use the . lookup rule, because you have 
another symbol that will be picked first.


For example:

int x;

template bar(string x)
{
   mixin("alias " ~ x ~ " = .x;");
}

-Steve


Re: Mixin and imports

2020-06-08 Thread jmh530 via Digitalmars-d-learn

On Monday, 8 June 2020 at 14:27:26 UTC, data pulverizer wrote:

[snip]

Out of curiosity what does the "." in front of `foo` mean? I've 
seen that in some D code on the compiler in GitHub and have no 
idea what it does. I tried Googling it to no avail. It doesn't 
have anything to do with UFCS does it?


Thanks


ag0aep6g provided the link to it, but it's one of those things 
that has been difficult for me to understand as well. I believe 
the original code had `foo` in a template. So in that case it was 
necessary. I'm not sure if it still is in my simplified version.


Re: Metaprogramming with D

2020-06-08 Thread Adam D. Ruppe via Digitalmars-d-learn

On Monday, 8 June 2020 at 14:41:55 UTC, Jan Hönig wrote:

What is the name of this `q` thing?


It is just a string that looks like code.


Re: Metaprogramming with D

2020-06-08 Thread ag0aep6g via Digitalmars-d-learn

On 08.06.20 16:45, ag0aep6g wrote:

On 08.06.20 16:41, Jan Hönig wrote:

On Sunday, 7 June 2020 at 00:45:37 UTC, Ali Çehreli wrote:

[...]

  writeln(q{
  void foo() {
  }
    });


What is the name of this `q` thing?
How do i find it? Are there any recent tutorials on it?


https://dlang.org/spec/lex.html#token_strings
https://ddili.org/ders/d.en/literals.html#ix_literals.q{}


Hm. That second link is somewhat malformed. Better one:
https://ddili.org/ders/d.en/literals.html#ix_literals.q%7B%7D


Re: Metaprogramming with D

2020-06-08 Thread ag0aep6g via Digitalmars-d-learn

On 08.06.20 16:41, Jan Hönig wrote:

On Sunday, 7 June 2020 at 00:45:37 UTC, Ali Çehreli wrote:

[...]

  writeln(q{
  void foo() {
  }
    });


What is the name of this `q` thing?
How do i find it? Are there any recent tutorials on it?


https://dlang.org/spec/lex.html#token_strings
https://ddili.org/ders/d.en/literals.html#ix_literals.q{}


Re: Metaprogramming with D

2020-06-08 Thread Jan Hönig via Digitalmars-d-learn

On Sunday, 7 June 2020 at 00:45:37 UTC, Ali Çehreli wrote:


  dmd -mixin= ...


thanks for the tip!




  writeln(q{
  void foo() {
  }
});


What is the name of this `q` thing?
How do i find it? Are there any recent tutorials on it?



Re: Mixin and imports

2020-06-08 Thread ag0aep6g via Digitalmars-d-learn

On 08.06.20 16:27, data pulverizer wrote:
Out of curiosity what does the "." in front of `foo` mean? I've seen 
that in some D code on the compiler in GitHub and have no idea what it 
does. I tried Googling it to no avail. It doesn't have anything to do 
with UFCS does it?


https://dlang.org/spec/module.html#module_scope_operators


Re: Mixin and imports

2020-06-08 Thread data pulverizer via Digitalmars-d-learn

On Monday, 8 June 2020 at 02:55:25 UTC, jmh530 wrote:


```
...
template foo(string f) {
mixin("alias foo = .foo!(" ~ f ~ ");");
}
...
```


Out of curiosity what does the "." in front of `foo` mean? I've 
seen that in some D code on the compiler in GitHub and have no 
idea what it does. I tried Googling it to no avail. It doesn't 
have anything to do with UFCS does it?


Thanks


Re: Metaprogramming with D

2020-06-08 Thread FunkyD via Digitalmars-d-learn

On Sunday, 7 June 2020 at 00:45:37 UTC, Ali Çehreli wrote:
On 6/6/20 5:03 PM, FunkyD wrote:> On Saturday, 6 June 2020 at 
09:57:36 UTC, Jan Hönig wrote:


> D is pretty good for meta-programming. For certain other
things it is
> terrible.

I am glad I don't know enough about other technologies to feel 
that way.


Ok, that isn't my fault.



> String mixins simply mix in D code. It lets you build generic
D code.
> The big problem here is debugging. There is ZERO ability to
properly
> debug string mixins.

"Zero" is too strong an assertion and because of the following, 
false:


You know the difference between logic and statistics? Ever heard 
of measure theory?


It's a pretty poor argument to claim that "Oh, logically it is 
not 100% true so it can't be true at all". I'm fine with stating 
something as All if it's true 98%+ of the time when it doesn't 
matter if it's 90% or 100% or anything in between.


If, for example, you had cancer almost all over your body I don't 
think someone you fault you if you said all instead of almost 
all. Pedanticism usually isn't a feature but a fault.







  dmd -mixin= ...

> Well, what it boils down to is writing out the
> string mixin and then debugging that.

When I compile my program and there is an issue with a string 
mixin, Emacs opens the mixin file and shows me the compilation 
there. This is because dmd's error include the exact line in 
the  where my mixin was broken. Not a shiny IDE but 
still pretty awesome support.


> It would be nice if D had a special D code string that the
IDE could
> interpret properly.

I must be misunderstanding you but it must be an IDE limitation 
because of the following:


  writeln(q{
  void foo() {
  }
});

My IDE gives me syntax highlighting in that string, so it works 
somehow.


Syntax highlighting is entirely different from semantic analysis. 
Try getting a line number of an error a multi-line string...




> D basically tries to resolve things after the fact so
>
> R add(T)(T a, T b)
> {
>  return a + b;
> }
>
> this will attempt to + on a and b after the types are known.
If they
> can't be added then an error will occur, which is usually
cryptic for
> templates.

That's why we use template constraints and in some cases 
'static assert' for custom error messages.




Yeah, that is definitely not the way to go... I could just throw 
rocks at my computer until it works too. Just because one can do 
it doesn't mean one should. In this case one is nearly forced.


Claiming that because we have the most primitive form of a 
solution makes up for having a good solution is pretty primitive.





> The issue in using D should not be made based on it's
metaprogramming.

I agree. What feature to use usually emerges by itself. For 
example, when an algorithm is repeated for many types, it is an 
opportunity for templates.


> D, IMO, is not capable of writing sophisticated programs...

"Sophisticated" is relative but such strong assertions can be 
falsified by a single counterexample. For example, Weka's 
product is very sophisticated and is written in D. And there is 
nothing extra or missing in D that makes it incapable in that 
regard.




As you said, sophisticated is quite relative. It seems you seem 
to think this is a math pissing contest. Anyone that makes a 
decision based on logical facts rather than statistical facts for 
statistical problems is quite illogical.



> this is why
> you do not see any.

I think the fact that many smart programmers are hostage to 
other languages is a stronger reason.


Maybe, maybe not... sounds like an excuse. Maybe they are 
actually rational beings who understanding that moving to an 
unpredictable and rather incompletely language is not worth the 
trouble?




> No one writes large commercial apps in D.

False.


Prove it. Saying something is false is not the same as it being 
false. Since you want to play hardball:


Name one commercial D app that has over 1 million in revenue and 
is used by 10k people. Just one. I'll let you play your games. 
Here I'm talking about an actual app that is entirely written in 
D.  You cannot claim an app is written in D when it just imports 
some D library. Nor are we talking about ad revenue generating 
software. I'm talking about something normal people use as an 
application... like a word processor, painting app, web browser, 
etc. Something external users  use, not a internal to a company.



Just one, come on, you said it was easy!



> There is
> not one!

False. And again, even if so, that's not because of D, but 
because of humans. Can you imagine a CTO, say, in Silicon 
Valley to have guts to bring D instead of C++? With C++, the 
CTO will never be blamed; but D, he or she can easily be blamed 
upon failure. Not because of the technologies but because of 
politics.




Now you are claiming that they don't exist. Which is it? Do they 
exist or do they not exist and they don't exist for some ad hoc 
theories you have?



> The 

Re: Mixin and imports

2020-06-08 Thread jmh530 via Digitalmars-d-learn

On Monday, 8 June 2020 at 12:20:46 UTC, Adam D. Ruppe wrote:

[snip]

Why do you even want foo!"fabs"? Usually when I see people 
having this problem it is actually a misunderstanding of what 
is possible with the foo!fabs style - which is better in 
basically every way and can be used in most the same places.


So what's your bigger goal?


There were some other functions in the module that allow the use 
of function!"thinginquotes". However, most of those functions are 
using the "thinginquotes" to avoid writing 
function!(SomeEnum.thinginquotes). That really isn't the thing to 
fix in this case. So I think it makes sense for me to give up 
what I was trying to do.


Re: Mixin and imports

2020-06-08 Thread FunkyD via Digitalmars-d-learn

On Monday, 8 June 2020 at 10:41:53 UTC, jmh530 wrote:

On Monday, 8 June 2020 at 10:28:39 UTC, Paul Backus wrote:

[snip]


Thanks for that suggestion. That works for me.

Unfortunately, it's probably not worth the extra effort though, 
versus doing foo!fabs in my case.


If they are all from std.math you can easily mixin in the 
template.


just import std.math there then it should work.

If you want more general arbitrary functions you can get the 
module of the function by using an alias. Alternatively you can 
just pass the function itself as an alias or template parameter. 
There are ways to do what you want but it's kinda hacky. I can't 
remember the details though. Basically you use mixins and traits 
to get the module the symbol exists in and then you can use a 
string mixin to import that module.




Re: Mixin and imports

2020-06-08 Thread Adam D. Ruppe via Digitalmars-d-learn

On Monday, 8 June 2020 at 02:55:25 UTC, jmh530 wrote:
In the code below, foo!fabs compiles without issue, but 
foo!"fabs" does not because the import is not available in the 
string mixin.


Why do you even want foo!"fabs"? Usually when I see people having 
this problem it is actually a misunderstanding of what is 
possible with the foo!fabs style - which is better in basically 
every way and can be used in most the same places.


So what's your bigger goal?


Re: how to append (ref) int[] to int[][]?

2020-06-08 Thread Paul Backus via Digitalmars-d-learn

On Monday, 8 June 2020 at 06:52:36 UTC, mw wrote:

On Monday, 8 June 2020 at 06:42:44 UTC, Simen Kjærås wrote:


Arrays (technically, slices) in D are essentially this struct:

struct Array(T) {
T* ptr;
size_t length;
// operator overloads
}

So when you have int[][], each element of the outer array is 
an Array!int. These, as simple structs, are copied about, so 
that changing one does not change another.


Thank you for the reply, I think this explanation should be 
added to the top of https://dlang.org/spec/arrays.html


Then people (esp with C/C++ background) can easily understand 
D's array behavior.


A good explanation of D's arrays (which should really be called 
"slices") is available in the "Articles" section of dlang.org:


https://dlang.org/articles/d-array-article.html


Re: how to append (ref) int[] to int[][]?

2020-06-08 Thread Dukc via Digitalmars-d-learn

On Monday, 8 June 2020 at 06:13:36 UTC, mw wrote:


what I really want in (a) is append `ref arr` and output [[3], 
[3], [3]], i.e. the real `arr` be appended instead of its copy.


I tried to change arrs' decl to:

(ref (int[]))[] arrs;  // the intended semantics I want

1) I'm wondering how to achieve what I want? and
2) why "~=" here will append a copy rather than the real `arr` 
itself to arrs?



Thanks.


```
import std.stdio;

void f(ref int[] arr) {
arr ~= 3;
}

void main() {
import std.algorithm;

int[]*[] arrs;
int[]* arr;
foreach (i; 0 .. 3) {
		//stack allocated array pointer would expire on end of 
scope, so must allocate the them on heap since we're keeping 
refeerences on them.

auto arrayAllocation = new int[][1];
arr = [0];
*arr = new int[0];
arrs ~= arr;
f(*arr);
}

//will print an array of addresses otherwise
arrs.map!(ptr => *ptr).writeln;
}
```

But I must say I would generally prefer just calling `f()` on 
`arrs[i]` directly after appending, or calling the function 
before appending. One reason is that needless heap usage is 
generally less efficient than using the stack.


Re: Mixin and imports

2020-06-08 Thread jmh530 via Digitalmars-d-learn

On Monday, 8 June 2020 at 10:28:39 UTC, Paul Backus wrote:

[snip]


Thanks for that suggestion. That works for me.

Unfortunately, it's probably not worth the extra effort though, 
versus doing foo!fabs in my case.


Re: `this` template params for struct not expressing constness.

2020-06-08 Thread Simen Kjærås via Digitalmars-d-learn

On Monday, 8 June 2020 at 09:08:40 UTC, adnan338 wrote:

On Monday, 8 June 2020 at 08:10:19 UTC, Simen Kjærås wrote:

On Monday, 8 June 2020 at 07:35:12 UTC, adnan338 wrote:

Self* searchTree(this Self)(auto in ref T item) const {
if ( is null)
return null;
if (this.item == item)
return 
return (this.item < item) ?
this.right.searchTree(item) :
this.right.searchTree(item);
}


This method is const, which means 'this' is const, while Self 
is not. What you're looking for here is inout 
(https://dlang.org/spec/function.html#inout-functions):


auto searchTree()(auto in ref T item) inout {
if ( is null)
return null;
if (this.item == item)
return 
return (this.item < item) ?
this.right.searchTree(item) :
this.right.searchTree(item);
}

--
  Simen


Thank you. Few followup questions, if you don't mind.

1. What does that blank template parameter mean?


Just forces the function to be a template. The only reason for 
this is it's required for auto ref to work, which you may or may 
not need on that function.



2. Since `inout` acts as a wildcard for 
immutable/const/non-const qualifiers, what should I do to have 
the compiler ensure that my method does not mutate a non-const 
tree inside the body?


Inside inout functions, `this` is treated as const - any attempt 
to modify it should give a compile error. Since D const is 
transitive, anything reachable from `this` is also treated as 
const.  If you're able to mutate a non-const tree inside the 
body, there's a bug in the compiler.



--
  Simen


Re: Mixin and imports

2020-06-08 Thread Paul Backus via Digitalmars-d-learn

On Monday, 8 June 2020 at 10:23:24 UTC, jmh530 wrote:

On Monday, 8 June 2020 at 04:13:08 UTC, Mike Parker wrote:

[snip]


The problem isn't the mixin. It's the template. Templates take 
the scope of their declaration, not their instantiation. So 
the mixin is getting the template's scope.


Anyway, this appears to work:

`double z = foo!"std.math.fabs"(x);`


Thanks, that makes sense.

However, I get the same error with the code below. Am I doing 
something wrong?


double foo(alias f)(double x) {
return f(x);
}

template foo(string f)
{
mixin("alias foo = .foo!(" ~ f ~ ");");
}

void main() {
static import std.math;
double x = 2.0;
double y = foo!(std.math.fabs)(x);
double z = foo!"std.math.fabs"(x);
}


If you want to refer to symbols in the scope where the template 
is instantiated, you will have to move the mixin outside of the 
template:


double foo(alias f)(double x) {
return f(x);
}

template foo(string f)
{
enum foo = "foo!(" ~ f ~ ")";
}

void main() {
import std.math: fabs;
double x = 2.0;
double y = foo!(fabs)(x);
double z = mixin(foo!"fabs")(x);
}


Re: Mixin and imports

2020-06-08 Thread jmh530 via Digitalmars-d-learn

On Monday, 8 June 2020 at 04:13:08 UTC, Mike Parker wrote:

[snip]


The problem isn't the mixin. It's the template. Templates take 
the scope of their declaration, not their instantiation. So the 
mixin is getting the template's scope.


Anyway, this appears to work:

`double z = foo!"std.math.fabs"(x);`


Thanks, that makes sense.

However, I get the same error with the code below. Am I doing 
something wrong?


double foo(alias f)(double x) {
return f(x);
}

template foo(string f)
{
mixin("alias foo = .foo!(" ~ f ~ ");");
}

void main() {
static import std.math;
double x = 2.0;
double y = foo!(std.math.fabs)(x);
double z = foo!"std.math.fabs"(x);
}


Re: `this` template params for struct not expressing constness.

2020-06-08 Thread adnan338 via Digitalmars-d-learn

On Monday, 8 June 2020 at 08:10:19 UTC, Simen Kjærås wrote:

On Monday, 8 June 2020 at 07:35:12 UTC, adnan338 wrote:

Self* searchTree(this Self)(auto in ref T item) const {
if ( is null)
return null;
if (this.item == item)
return 
return (this.item < item) ?
this.right.searchTree(item) :
this.right.searchTree(item);
}


This method is const, which means 'this' is const, while Self 
is not. What you're looking for here is inout 
(https://dlang.org/spec/function.html#inout-functions):


auto searchTree()(auto in ref T item) inout {
if ( is null)
return null;
if (this.item == item)
return 
return (this.item < item) ?
this.right.searchTree(item) :
this.right.searchTree(item);
}

--
  Simen


Thank you. Few followup questions, if you don't mind.

1. What does that blank template parameter mean?
2. Since `inout` acts as a wildcard for immutable/const/non-const 
qualifiers, what should I do to have the compiler ensure that my 
method does not mutate a non-const tree inside the body?




Re: `this` template params for struct not expressing constness.

2020-06-08 Thread Simen Kjærås via Digitalmars-d-learn

On Monday, 8 June 2020 at 07:35:12 UTC, adnan338 wrote:

Self* searchTree(this Self)(auto in ref T item) const {
if ( is null)
return null;
if (this.item == item)
return 
return (this.item < item) ?
this.right.searchTree(item) :
this.right.searchTree(item);
}


This method is const, which means 'this' is const, while Self is 
not. What you're looking for here is inout 
(https://dlang.org/spec/function.html#inout-functions):


auto searchTree()(auto in ref T item) inout {
if ( is null)
return null;
if (this.item == item)
return 
return (this.item < item) ?
this.right.searchTree(item) :
this.right.searchTree(item);
}

--
  Simen


Re: `this` template params for struct not expressing constness.

2020-06-08 Thread evilrat via Digitalmars-d-learn

On Monday, 8 June 2020 at 07:35:12 UTC, adnan338 wrote:
Hi, as far as I understand, the `this` template parameter 
includes constness qualifiers as seen in 
https://ddili.org/ders/d.en/templates_more.html


To apply this I have this following struct:

module bst;

struct Tree(T) {
T item;
Tree!T* parent, left, right;

this(T item) {
this.item = item;
}

Self* searchTree(this Self)(auto in ref T item) const {
if ( is null)
return null;
if (this.item == item)
return 
return (this.item < item) ? this.right.searchTree(item) 
: this.right.searchTree(item);

}
}

unittest {
auto text1 = "Hello", text2 = "World";

auto tree2 = Tree!string(text1);
assert(tree2.searchTree(text2) is null);
assert(tree2.searchTree(text1) !is null);

auto tree1 = Tree!int(4);
assert(tree1.searchTree(5) is null);
assert(tree1.searchTree(4) !is null);

}


When I run the unittest the compiler complains:

cannot implicitly convert expression  of type 
const(Tree!string)* to Tree!string*


Run link: https://run.dlang.io/is/b76DND

Why does this happen?


If I correctly understand what you are trying to do the answer is 
- in D const is transitive (unlike the C++ where it isn't).


And in your searchTree() method you are basically trying to 
escape that constness. You can change the signature to return 
const(Self)*, or maybe add non-const overload depending on your 
needs.


Don't even think about casting away const with `return 
cast(Self*) ` as this UB in D, and it will bite you 
somewhere later because compiler might rely on const for 
optimization.




`this` template params for struct not expressing constness.

2020-06-08 Thread adnan338 via Digitalmars-d-learn
Hi, as far as I understand, the `this` template parameter 
includes constness qualifiers as seen in 
https://ddili.org/ders/d.en/templates_more.html


To apply this I have this following struct:

module bst;

struct Tree(T) {
T item;
Tree!T* parent, left, right;

this(T item) {
this.item = item;
}

Self* searchTree(this Self)(auto in ref T item) const {
if ( is null)
return null;
if (this.item == item)
return 
return (this.item < item) ? this.right.searchTree(item) : 
this.right.searchTree(item);

}
}

unittest {
auto text1 = "Hello", text2 = "World";

auto tree2 = Tree!string(text1);
assert(tree2.searchTree(text2) is null);
assert(tree2.searchTree(text1) !is null);

auto tree1 = Tree!int(4);
assert(tree1.searchTree(5) is null);
assert(tree1.searchTree(4) !is null);

}


When I run the unittest the compiler complains:

cannot implicitly convert expression  of type 
const(Tree!string)* to Tree!string*


Run link: https://run.dlang.io/is/b76DND

Why does this happen?


Re: non-constant expression while initializing two dim array

2020-06-08 Thread Basile B. via Digitalmars-d-learn

On Monday, 8 June 2020 at 06:37:18 UTC, tirithen wrote:

How can I initialize my two dimensional array?

When I try to run the code below I get the error:

Error: non-constant expression ["user":[cast(Capability)0], 
"administrator":[cast(Capability)1]]


Code:

enum Capability {
  self,
  administer
}

alias Capabilities = immutable Capability[];

private Capabilities[string] roleCapabilities = [
  "user" : [Capability.self], "administrator" : 
[Capability.administer]

];

I have tried adding more const and immutable prefixes but it 
still gives me the same error. The goal is that 
roleCapabilities should be an immutable/const two dimensional 
array.


What you declare here is not a two dim array it's an associative 
array.
Associative array implementation have limitations. To initialize 
one that doesn't have const expr as key you can use a static 
module constructor:


---
enum Capability {
  self,
  administer
}

alias Capabilities = immutable Capability[];

private Capabilities[string] roleCapabilities;

static this()
{
roleCapabilities = [
  "user" : [Capability.self], "administrator" : 
[Capability.administer]

];
}
---

which is done at runtime, just before the D main() get executed.

Notes:

1. You can also use a function containing a switch statement 
instead of an assoc array.
2. the other way would work because it would be a static array, 
the enum member giving an integer index:


---
enum Capability {
  self,
  administer
}

alias Capabilities = immutable Capability[];

private string[Capability.max + 1] roleCapabilities = [
Capability.self : "user",
Capability.administer : "administrator",
];
---

but I suppose that is different.


Re: how to append (ref) int[] to int[][]?

2020-06-08 Thread mw via Digitalmars-d-learn

On Monday, 8 June 2020 at 06:42:44 UTC, Simen Kjærås wrote:


Arrays (technically, slices) in D are essentially this struct:

struct Array(T) {
T* ptr;
size_t length;
// operator overloads
}

So when you have int[][], each element of the outer array is an 
Array!int. These, as simple structs, are copied about, so that 
changing one does not change another.


Thank you for the reply, I think this explanation should be added 
to the top of https://dlang.org/spec/arrays.html


Then people (esp with C/C++ background) can easily understand D's 
array behavior.






Re: how to append (ref) int[] to int[][]?

2020-06-08 Thread Simen Kjærås via Digitalmars-d-learn

On Monday, 8 June 2020 at 06:13:36 UTC, mw wrote:

Hi,

I have this program:

import std.stdio;

void f(ref int[] arr) {
arr ~= 3;
}

void main() {
int[][] arrs;
int[] arr;
foreach (i; 0 .. 3) {
arr = new int[0];
arrs ~= arr; //(a) [[], [], []]
f(arr);
// arrs ~= arr; //(b) [[3], [3], [3]]
}

writeln(arrs);
}


This program will print out [[], [], []].

If I comment out (a), and use (b), it will print out [[3], [3], 
[3]]


So based on this behavior, looks like "~=" will append a copy 
of `arr`; but what I really want in (a) is append `ref arr` and 
output [[3], [3], [3]], i.e. the real `arr` be appended instead 
of its copy.


I have to say this semantics surprised me.

I tried to change arrs' decl to:

(ref (int[]))[] arrs;  // the intended semantics I want

But I got compiler error out: "found ( when expecting function 
literal following ref".


1) I'm wondering how to achieve what I want? and
2) why "~=" here will append a copy rather than the real `arr` 
itself to arrs?


Arrays (technically, slices) in D are essentially this struct:

struct Array(T) {
T* ptr;
size_t length;
// operator overloads
}

So when you have int[][], each element of the outer array is an 
Array!int. These, as simple structs, are copied about, so that 
changing one does not change another.


The simple solution here is to call f not on arr, but on 
arrs[$-1] (the last element of arrs). If that is not possible you 
will need arrs to be an int[]*[].


--
  Simen


non-constant expression while initializing two dim array

2020-06-08 Thread tirithen via Digitalmars-d-learn

How can I initialize my two dimensional array?

When I try to run the code below I get the error:

Error: non-constant expression ["user":[cast(Capability)0], 
"administrator":[cast(Capability)1]]


Code:

enum Capability {
  self,
  administer
}

alias Capabilities = immutable Capability[];

private Capabilities[string] roleCapabilities = [
  "user" : [Capability.self], "administrator" : 
[Capability.administer]

];

I have tried adding more const and immutable prefixes but it 
still gives me the same error. The goal is that roleCapabilities 
should be an immutable/const two dimensional array.


how to append (ref) int[] to int[][]?

2020-06-08 Thread mw via Digitalmars-d-learn

Hi,

I have this program:

import std.stdio;

void f(ref int[] arr) {
arr ~= 3;
}

void main() {
int[][] arrs;
int[] arr;
foreach (i; 0 .. 3) {
arr = new int[0];
arrs ~= arr; //(a) [[], [], []]
f(arr);
// arrs ~= arr; //(b) [[3], [3], [3]]
}

writeln(arrs);
}


This program will print out [[], [], []].

If I comment out (a), and use (b), it will print out [[3], [3], 
[3]]


So based on this behavior, looks like "~=" will append a copy of 
`arr`; but what I really want in (a) is append `ref arr` and 
output [[3], [3], [3]], i.e. the real `arr` be appended instead 
of its copy.


I have to say this semantics surprised me.

I tried to change arrs' decl to:

(ref (int[]))[] arrs;  // the intended semantics I want

But I got compiler error out: "found ( when expecting function 
literal following ref".


1) I'm wondering how to achieve what I want? and
2) why "~=" here will append a copy rather than the real `arr` 
itself to arrs?



Thanks.