Re: Challenge Tuples

2024-05-01 Thread Andrey Zherikov via Digitalmars-d-learn

On Friday, 26 April 2024 at 13:25:34 UTC, Salih Dincer wrote:
You have a 5-item data tuples as Tuple(1, 2, 3, [1, 3], 5) and 
implement the sum (total = 15) with the least codes using the 
sum() function of the language you are coding...



Let's start with D:

```d
import std.typecons : tuple;
import std.algorithm : sum;

void main()
{
  auto t = tuple(1, 2, 3, [1, 3], 5);

  int[] arr;
  t.each!(e => arr ~= e);
  assert(arr.sum == 15);
}
```

and bonus:

```d
import std.typecons : tuple;
import std.stdio : writeln;
void main()
{
  auto t = tuple(1, 2, 3, [1, 3], 5);
  auto results = [0];

  foreach (data; t)
  {
static
if (is(typeof(data) == int[]))
{
  int sum;
  foreach (d; data)
  {
sum += d;
  }
  results ~= sum;
}
else
{
  results ~= data;
}
  }
  results.writeln; // [0, 1, 2, 3, 4, 5]
```

I bet you won't be able to do it this easily with other 
languages!  Note: I tried with C# and Python and it didn't work!


SDB@79



Shorter and without allocations:
```d
import std.typecons : tuple;
import std.algorithm : sum, each;

auto sum(int i) => i;

void main()
{
  auto t = tuple(1, 2, 3, [1, 3], 5);

  int res=0;
  t.each!(e => res += sum(e));
  assert(res == 15);
}
```



Re: Is a shorter statement possible in this case?

2023-11-05 Thread Andrey Zherikov via Digitalmars-d-learn

On Sunday, 5 November 2023 at 18:36:40 UTC, Ctn-Dev wrote:


Is there a more concise way of getting the same result?


Try this:
```d
switch(range.map!(_ => (_== "Two" ? 2 : _=="One" ? 1 : 
0)).fold!((a,b) => a | b)(0)) {

case 3: writeln("both"); break;
case 2: writein("only two"); break;
case 1: writeln("only one"); break;
default: writeln("none"); break;
}
```
Where `range` is input array.


Re: DUB: Is it possible to set release as a default build for a dub package?

2023-11-03 Thread Andrey Zherikov via Digitalmars-d-learn

On Friday, 3 November 2023 at 19:21:42 UTC, BoQsc wrote:
However I would want to try to enforce this behaviour from the 
`dub.json` or `dub.sdl` file.


IMHO this is not something that should be enforced from package 
build configuration, however there can be a way to configure it 
on system level (like in `dub.conf` if it exists).


Re: Keyword "package" prevents from importing a package module "package.d"

2023-11-03 Thread Andrey Zherikov via Digitalmars-d-learn
On Friday, 3 November 2023 at 18:04:58 UTC, Jonathan M Davis 
wrote:

- Jonathan M Davis


Thanks a lot for detailed explanation!


Re: Keyword "package" prevents from importing a package module "package.d"

2023-11-03 Thread Andrey Zherikov via Digitalmars-d-learn

On Friday, 3 November 2023 at 00:52:18 UTC, H. S. Teoh wrote:

Supposedly you can do this:

/* Original: */

// pkg/mymodule.d
module mymodule;
... // code here

// main.d
import mymodule;
void main() { ... }

/* Split */

// pkg/mymodule/pub_submod.d
module mymodule.pub_submod;
... // code here

// pkg/mymodule/priv_submod.d
module mymodule.priv_submod;
... // code here

// pkg/mymodule/package.d
module mymodule;
public import priv_submod;

// main.d
import mymodule;
void main() { ... }

Barring the issues listed above, of course.


I know how to do this with package.d but my question was about 
"package.d is bad design decision" - How would I do this 
refactoring without dedicated "main package file"?

Python, for example, has __init__.py as well



Re: Keyword "package" prevents from importing a package module "package.d"

2023-11-02 Thread Andrey Zherikov via Digitalmars-d-learn

On Thursday, 2 November 2023 at 19:43:01 UTC, Adam D Ruppe wrote:
On Thursday, 2 November 2023 at 19:30:58 UTC, Jonathan M Davis 
wrote:
The entire reason that it was added to the language was to be 
able to split up existing modules without breaking code. And 
it does that well.


No, it doesn't do that well at all. In fact, it does that so 
extremely poorly that (as you might recall) there were a very 
large number of support requests shortly after Phobos started 
using it about broken builds, since it would keep the old file 
and the new file when you updated and this stupid, idiotic 
design can't handle that situation.


This only subsided because enough time has passed that nobody 
tries using it to break up existing modules anymore.


It is just a *terrible* design that never should have passed 
review. It is randomly inconsistent with the rest of the 
language and this manifests as several bugs.


(including but not limited to:

https://issues.dlang.org/show_bug.cgi?id=14687 doesn't work 
with .di
https://issues.dlang.org/show_bug.cgi?id=17699 breaks if you 
try to use it for its intended purpose
https://issues.dlang.org/show_bug.cgi?id=20563 error messages 
hit random problems
 all-at-once vs separate compilation of 
package leads to inconsistent reflection results


im sure the list went on if i spent a few more minutes looking 
for my archives)



package.d is indeed completely unnecessary for creating a 
module that publicly imports other modules in order to be able 
to import a single module and get several modules.


Yeah, it is a terrible feature that is poorly designed, hackily 
implemented, and serves no legitimate use case.


Is there any guide how one can refactor single-module package 
into multi-module package with distinction between public and 
private modules?


Re: Key and value with ranges

2023-10-03 Thread Andrey Zherikov via Digitalmars-d-learn
On Tuesday, 3 October 2023 at 19:57:06 UTC, christian.koestlin 
wrote:
On Tuesday, 3 October 2023 at 01:55:43 UTC, Andrey Zherikov 
wrote:
On Monday, 2 October 2023 at 18:46:14 UTC, christian.koestlin 
wrote:

[...]


Slightly improved:
```d
import std;

[...]


Thanks .. the thing with ref result is very clever!
Should `ref result` be `return result`?


`ref` might not be necessary fo AA but I'm not sure.

`fold` requires function to return something (see 
[doc](https://dlang.org/phobos/std_algorithm_iteration.html#fold)):
for each element x in range, result = fun(result, x) gets 
evaluated.


Re: Key and value with ranges

2023-10-02 Thread Andrey Zherikov via Digitalmars-d-learn
On Monday, 2 October 2023 at 18:46:14 UTC, christian.koestlin 
wrote:

On Monday, 2 October 2023 at 02:47:37 UTC, Joel wrote:

How can I improve this code? Like avoiding using foreach.


You could fold into a hash that counts the occurrences like 
that:


```d
import std.uni : toLower;
import std.array : split, array;
import std.stdio : writeln;
import std.algorithm : fold, sort, map;


auto data="I went for a walk, and fell down a hole. a went";

int main(string[] args)
{
int[string] wc;
data
.toLower
.split
.fold!((result, element) { result[element] += 1; return 
result; })(wc)

.byKeyValue
.array
.sort!((pair1, pair2) => pair1.value > pair2.value)
.map!(pair => pair.key)
.writeln
;
return 0;
}
```

Not sure how to get rid of the declaration of the empty wc hash 
though.


Kind regards,
Christian


Slightly improved:
```d
import std;

auto data="I went for a walk, and fell down a hole. a went";

int main(string[] args)
{
data
.toLower
.split
.fold!((ref result, element) { ++result[element]; return 
result; })(uint[string].init)

.byKeyValue
.array
.sort!((pair1, pair2) => pair1.value > pair2.value)
.each!(pair => writeln("Word: ", pair.key, " - number of 
instances: ", pair.value))

;
return 0;
}
```

Output:
```
Word: a - number of instances: 3
Word: went - number of instances: 2
Word: and - number of instances: 1
Word: i - number of instances: 1
Word: hole. - number of instances: 1
Word: for - number of instances: 1
Word: down - number of instances: 1
Word: fell - number of instances: 1
Word: walk, - number of instances: 1
```


Re: Function template as template parameter

2022-12-11 Thread Andrey Zherikov via Digitalmars-d-learn

On Sunday, 11 December 2022 at 16:24:30 UTC, Ali Çehreli wrote:

On 12/11/22 05:54, Salih Dincer wrote:
> On Sunday, 11 December 2022 at 09:43:34 UTC, Andrey Zherikov
wrote:
>> Note that callback parameter must be compile-time parameter
as it
>> represents a member of a type during introspection done by
`foo`.
>
> I can't quite understand the question, this already works:

I think the OP is trying to create an anonymous template.


Yes

The following does not work when one attempts to use the 
template anonymously. Just trying to pass a template just like 
a lambda


Thanks for confirming this.


Function template as template parameter

2022-12-11 Thread Andrey Zherikov via Digitalmars-d-learn

I have this (very simplified) code:
```d
void foo(alias callback)()
{
callback!5;
}

static void print(int i)() { writeln(i); }
foo!print;
```

Is there a way to merge two last lines into one of a form like 
`foo!(...something...)`?


Note that callback parameter must be compile-time parameter as it 
represents a member of a type during introspection done by `foo`.


Re: Is defining get/set methods for every field overkill?

2022-11-19 Thread Andrey Zherikov via Digitalmars-d-learn

On Saturday, 19 November 2022 at 10:17:19 UTC, []() {}() wrote:

On Saturday, 19 November 2022 at 09:51:09 UTC, []() {}() wrote:

...
no. in C# it breaks ABI. that is why its not acceptable in my 
team.




of course that's not the reason we don't use public member 
variables in classes.


the reason we don't use them, is because (1) we always 
anticpiate change including the need to implement (and change) 
business rules associated with the objects data (using 
setter/getters), and (2) we always prioritise the stability of 
the public interface of a class at the time of design.


if neither of those are your concern, in production-level code, 
I'd be really surprised (and shocked).


We don't use public members either in most cases - we use them in 
simple structs. We have teams that do care and prioritize 
stability of public interface because they ship their libraries 
to end-users. Other teams care much less because all their users 
are internal so they can fix whatever they break.


Regarding ABI compatibility: it's usually driven by what 
dependencies your software has. In your case (as far as I got) 
you ship .dll that is used by already deployed software so your 
library must be ABI compatible with it. In our case, our software 
has only system-level dependencies like C runtime, WinSocks so we 
don't have such a thing as ABI incompatibility between different 
parts of our software but we care about system-level ABI.


Re: Is defining get/set methods for every field overkill?

2022-11-19 Thread Andrey Zherikov via Digitalmars-d-learn
On Saturday, 19 November 2022 at 09:49:18 UTC, thebluepandabear 
wrote:

I am too dumb to know what ABI is


https://en.wikipedia.org/wiki/Application_binary_interface



Re: Is defining get/set methods for every field overkill?

2022-11-19 Thread Andrey Zherikov via Digitalmars-d-learn

On Saturday, 19 November 2022 at 09:51:09 UTC, []() {}() wrote:
no. in C# it breaks ABI. that is why its not acceptable in my 
team.


Every company works differently. Yours are using .net and (I 
guess) ships dlls so you must care about ABI with existing 
software. In my company we use static linking so the only ABI 
compatibility we care about is with libc.



I expect it would also break ABI in D.


I'd like to know the answer so I hope someone from D core step in 
and shed a light on it.






Re: Is defining get/set methods for every field overkill?

2022-11-19 Thread Andrey Zherikov via Digitalmars-d-learn
On Saturday, 19 November 2022 at 09:12:26 UTC, thebluepandabear 
wrote:
That's the point many people have given here which is not 
convincing him, even though it is quite great.


I think we all know the answer here 


IMHO you are both right :)
You are speaking about API compatibility, `[]() {}()` speaks 
about ABI compatibility. The latter makes sense in long-running 
production software. So we know that there are no issues in API 
compatibility but we don't know anything about ABI.


Re: Is defining get/set methods for every field overkill?

2022-11-19 Thread Andrey Zherikov via Digitalmars-d-learn
On Saturday, 19 November 2022 at 09:12:26 UTC, thebluepandabear 
wrote:
That's the point many people have given here which is not 
convincing him, even though it is quite great.


I think we all know the answer here 


IMHO you are both right :)
You are speaking about API compatibility, `[]() {}()` speaks 
about ABI compatibility. The latter makes sense in long-running 
production software. So we know that there are no issues in API 
compatibility but we don't know anything about ABI.


Re: Is defining get/set methods for every field overkill?

2022-11-19 Thread Andrey Zherikov via Digitalmars-d-learn

On Saturday, 19 November 2022 at 09:05:42 UTC, []() {}() wrote:
Once you refactor your class (creating actual private member 
variables and creating getter/setter methods, you are almost 
certainly going to break binary compatability, and when you 
send your update compiler library to your customer, there code 
will stop working - cause they'll have to recompile it against 
the new library.


I think you are speaking about shipping dynamic library to users. 
I think compiler authors can clarify whether introducing 
getters/setters breaks ABI or not. On the other side if it breaks 
then it can be easily checked: create simple program that uses 
dynamic library, then change the latter to use getters/setters 
and run program again without recompiling.


Re: Is defining get/set methods for every field overkill?

2022-11-19 Thread Andrey Zherikov via Digitalmars-d-learn

On Saturday, 19 November 2022 at 04:13:33 UTC, []() {}() wrote:
oh. so i get it now. you have to refactor your class (change 
member variable names and also do it in all places where they 
are used througout the class. then add new methods, overloading 
them in this way and that way, all because you're initial 
design never factored in the possibility of change (or even 
some validation of the vale being returned to the client, or 
validation of value coming from the client).


You are not required to rename everything, just actual members.

D has nice feature to convert `foo.bar` to `foo.bar()` and 
`foo.bar = value` to `foo.bar(value)` that doesn't exist in C/C++ 
for example. This reduces some headache in planning the API ahead.


Let's we have this class and its usage:
```d
class Rect2D {
int width;
int height;

auto area() const { return width * height; }
}

Rect2D rect = new Rect2D();
rect.width = 5;
rect.height = 5;

writeln(rect.area);   // note that this is seamlessly translated 
to rect.area()

```

Then you decided that you want getters/setters so you add them 
without changing anything:

```d
class Rect2D {
int width_;
int height_;

auto width() const { return width_; }
void width(int w) { width_ = w; }

auto height() const { return height_; }
void height(int h) { height_ = h; }

auto area() const { return width * height; }   // no changes 
here - using getters

}

Rect2D rect = new Rect2D();
rect.width = 5;   // no changes here - using setter
rect.height = 5;  // no changes here - using setter

writeln(rect.area);
```

You can also use UFCS instead of class members but it has a 
caveat: plain `width`/`height` won't work within class so you 
have to either use `width_`/`height_` directly or 
`this.width`/`this.height`:

```d
class Rect2D {
int width_;
int height_;

auto area() const { return this.width * this.height; }  // 
UFCS calls to global width() and height() functions

}

// These functions have to be in global scope for UFCS to work
auto width(const Rect2D rect) { return rect.width_; }
void width(ref Rect2D rect, int w) { rect.width_ = w; }

auto height(const Rect2D rect) { return rect.height_; }
void height(ref Rect2D rect, int h) { rect.height_ = h; }

void main()
{
// Still no changes in user code
Rect2D rect = new Rect2D();
rect.width = 5;
rect.height = 5;

writeln(rect.area);
}
```


Re: ImportC linking issue

2022-11-13 Thread Andrey Zherikov via Digitalmars-d-learn

On Saturday, 12 November 2022 at 10:02:12 UTC, confuzzled wrote:
Why would I have to search for libcrypto, libminizip, libexpat, 
and more that I haven't even figured out what library they are? 
I thought those dependencies would already be linked into 
libxlsxio_read.a which is a statically linked library.


This is called transitive dependencies.

For Unix systems linking a static library is not a linking per 
se, it means putting object files (.o) into an archive (.a) using 
[ar](https://linux.die.net/man/1/ar). So "libfoo.a" is just a set 
of object files that don't know anything about their dependencies 
and if you use something from libfoo.a, you might need to add 
another library to you link line. Technically there are two 
possible cases: (1) function that you use doesn't depend on 
anything else, then you don't need to add anything to your link 
line; and (2) function uses something from,  say libbar.a - then 
you have to add libbar.a to your link line.


Dynamic libraries (.so) are treated the same way as executables: 
they are created by linker ([ld](https://linux.die.net/man/1/ld) 
for example) and so they have to have all symbols resolved.  This 
means that if libfoo.so depends on libbar.a then the latter is 
already baked in into the former so your don't need to specify it 
when you link with libfoo.so. TBH I don't remember whether you 
should add libbar.so (dynamic library) which is a dependency of 
libfoo.so to your link line.


Re: Is "auto t=T();" not the same as "T t;"?

2022-10-26 Thread Andrey Zherikov via Digitalmars-d-learn

On Wednesday, 26 October 2022 at 04:40:17 UTC, Salih Dincer wrote:
On Tuesday, 25 October 2022 at 13:51:30 UTC, Andrey Zherikov 
wrote:
Does the second piece of code shows a bug or my expectation is 
not correct (and why if so)?


As a result, if this is a bug, Andrey has the right to report 
it.


Bug tracking system doesn't work with gmail emails so I'm not 
able to report.





Re: Is "auto t=T();" not the same as "T t;"?

2022-10-25 Thread Andrey Zherikov via Digitalmars-d-learn

On Tuesday, 25 October 2022 at 14:53:50 UTC, Adam D Ruppe wrote:
On Tuesday, 25 October 2022 at 13:51:30 UTC, Andrey Zherikov 
wrote:

A[] a = [A.init];


This is a problem - this is referring to a static array 
instance, shared across all copies of B. You almost certainly 
don't want this.


That B.a[0] is the *same object* across different 
default-constructed Bs... unless the optimizer hits it or 
something.


Is it a bad idea to trigger copy on write before modification of 
B.a so it behaves as below?

```d
B b1;
b1.a = b1.a.dup;   // copy on write
b1.a[0].i ~= '1';
b1.a ~= A.init;
b1.a[0].i ~= '2';
b1.a[1].i ~= '3';
b1.writeln;// B([A("12"), A("3")])

B b2;
b2.writeln;// B([A("")])
```


Re: Is "auto t=T();" not the same as "T t;"?

2022-10-25 Thread Andrey Zherikov via Digitalmars-d-learn

On Tuesday, 25 October 2022 at 14:53:50 UTC, Adam D Ruppe wrote:
But just don't do this. Only basic values and immutable strings 
are good to initialize this way. With the array or class 
objects, you're liable to get some shared thing.


If you change this to be initialized in a constructor (which 
will require an argument in D) or factory function, you'll get 
far more consistent behavior as each instance will have its own 
array.


I'd like to tune default ctor but structs can't have custom one.
Adding a ctor with parameter seems a hack to me - and compiler 
still allows default construction even when default ctor is 
disabled:


```d
struct A
{
int[] i;
}
struct B
{
A[] a;
@disable this();
this(bool)
{
A[] a = [A.init];
}
}
void main()
{
auto b1 = B.init;
b1.a[0].i ~= 1;
b1.a ~= A.init;
b1.a[0].i ~= 11;
b1.a[1].i ~= 12;
b1.writeln;

auto b2 = B.init;
b2.writeln;
}
```
This fails in run time, not compile time:
```
core.exception.ArrayIndexError@onlineapp.d(19): index [0] is out 
of bounds for array of length 0


??:? _d_arraybounds_indexp [0x55b558b8ec55]
./onlineapp.d:19 _Dmain [0x55b558b6bd5f]
```

As for why B() and B.init are different here... i don't know, 
probably some subtly of the compiler's implementation.


Actually `auto b = B.init;` behaves the same way as `auto b = 
B();` but they don't do the same as `B b;`


Is "auto t=T();" not the same as "T t;"?

2022-10-25 Thread Andrey Zherikov via Digitalmars-d-learn

I have the following types (simplified version of my code):
```d
struct A
{
int[] i;
}
struct B
{
A[] a = [A.init];
}
```

This code:
```d
auto b1 = B.init;
b1.a[0].i ~= 1;
b1.a ~= A.init;
b1.a[0].i ~= 11;
b1.a[1].i ~= 12;
b1.writeln;

auto b2 = B();
b2.writeln;
```
prints this as expected:
```
B([A([1, 11]), A([12])])
B([A([])])
```

But this code:
```d
B b1;  // auto b1 = B.init;
b1.a[0].i ~= 1;
b1.a ~= A.init;
b1.a[0].i ~= 11;
b1.a[1].i ~= 12;
b1.writeln;

B b2; // auto b2 = B();
b2.writeln;
```
prints this which is not expected:
```
B([A([1, 11]), A([12])])
B([A([1])])
```

Does the second piece of code shows a bug or my expectation is 
not correct (and why if so)?


Re: Hipreme's #2 Tip of the day - Reducing .di files dependency

2022-10-25 Thread Andrey Zherikov via Digitalmars-d-learn

On Sunday, 23 October 2022 at 20:12:46 UTC, Hipreme wrote:
This will greatly reduce the number of import and dependencies 
you need if you ever need to distribute a library.


Could you elaborate more on the benefit? Does it reduce 
compilation time for dependency? If so then how much?


Re: rotate left an array

2022-10-03 Thread Andrey Zherikov via Digitalmars-d-learn

On Monday, 3 October 2022 at 18:09:05 UTC, Fausto wrote:

Hello all,

I am trying to rotate left an array.
I found a very basic way, and I am not sure if there is 
something clever than this :) maybe using slices...
the external for represents how many times you are rotating (in 
this case 2).


If you don't need to add or remove the data from your array then 
I'd go with constant array and translating external index to an 
internal one for this array. So it's gonna be something like a 
"rotated view".


Re: How I can pass the WndProc as a parameter?

2022-09-10 Thread Andrey Zherikov via Digitalmars-d-learn

On Saturday, 10 September 2022 at 10:39:12 UTC, Injeckt wrote:
server.d(29): Error: function `server.WndProc(void* hwnd, uint 
message, uint wParam, int lParam)` is not callable using 
argument types `()`


I think you need to get address of a function:
```d
wndclass.lpfnWndProc = 
```


Re: Validate static asserts

2022-09-09 Thread Andrey Zherikov via Digitalmars-d-learn

On Friday, 9 September 2022 at 15:22:30 UTC, Ali Çehreli wrote:
I added and removed '&& false' to every 'static assert' 
condition manually one by one. :/


It's not CI-friendly :(

Perhaps a new compiler switch can compile every 'static assert' 
with an automatic 'false' and dump all their text to the output.


What's about new `compileOutput` trait that returns compiler 
output?

```d
static assert(__traits(compileOutput, {  }) == 
"message");

```


Validate static asserts

2022-09-09 Thread Andrey Zherikov via Digitalmars-d-learn
I have bunch of `static assert(, )` in my 
code and would like to validate that specific code triggers 
specific assert by checking what `` is thrown.


Right now I do `static assert(!__traits(compiles, {  
}));` but since `` might not compile due to many 
different reasons, I might not be testing original `static 
assert` and might miss breaking change.


One way to do this is to extract `` and `` 
into some function and test it outside of `static assert`:

```d
auto check()
{
return tuple(false, // check result  ('false' is just for 
example)

 "message");
}

void f()
{
enum result = check();
static assert(result.condition, result.message);
}

unittest
{
enum result = check();
static assert(result.condition);
static assert(result.message == "message");
}
```
But I don't like this approach because unit test doesn't really 
test `f()` (it tests duplicated code) so it can't guarantee that 
`f()` works as expected.



Is there a way to validate static asserts in unit tests?


Re: typeof(func!0) != typeof(func!0())

2022-08-22 Thread Andrey Zherikov via Digitalmars-d-learn

On Monday, 22 August 2022 at 17:40:59 UTC, Andrey Zherikov wrote:
I'm providing a struct (`U` in examples above) with some API 
and I'm looking for this struct as an UDA (through 
`hasUDA`/`getUDAs`). And actually I already have a mix of 
member-functions and free-functions in my API so it's gonna be 
more consistent if I make all of them free-functions.


Just checked - free functions work so I'll migrate API to them.

Thanks everyone for answering my questions.


Re: typeof(func!0) != typeof(func!0())

2022-08-22 Thread Andrey Zherikov via Digitalmars-d-learn

On Monday, 22 August 2022 at 16:42:50 UTC, Paul Backus wrote:
It's probably not worth completely changing your API design 
just to work around this issue. Also, even if you do this, it 
is still possible for a user to run into a same problem with a 
member function of one of their own types; for example:


```d
import your.library;

struct MyStruct {
U myFunc() { /* ... */ }
}

@(MyStruct.myFunc) whatever;
```


This will be users' issue then, not mine :)

I'm providing a struct (`U` in examples above) with some API and 
I'm looking for this struct as an UDA (through 
`hasUDA`/`getUDAs`). And actually I already have a mix of 
member-functions and free-functions in my API so it's gonna be 
more consistent if I make all of them free-functions.


Re: typeof(func!0) != typeof(func!0())

2022-08-22 Thread Andrey Zherikov via Digitalmars-d-learn

On Monday, 22 August 2022 at 15:20:46 UTC, Paul Backus wrote:
On Monday, 22 August 2022 at 14:43:24 UTC, Andrey Zherikov 
wrote:
But the question is still opened: why is `typeof(U().func!0)` 
not the same as `typeof(U().func!0())`?


Probably because if it were the same, it would be completely 
impossible to introspect on the type of `U.func!0` directly. 
The closest you could get would be to examine 
`typeof(!0)`; i.e., the type of the function pointer 
rather than the function itself.


I'm not totally convinced that the current behavior is the 
correct decision here, but there is a real tradeoff.


I have an impression that template function can be called without 
parenthesis if it doesn't have run-time parameters so `func!0` is 
the same as `func!0()`. Am I wrong?



If we consider free function vs. member function, why is 
`typeof(u.func!0)` not the same as `typeof(u.func2!0)` here?

```d
struct U
{
ref U func(int i)() { return this; }
}
ref U func2(int i)(ref U u) { return u; }

void main()
{
U u;
pragma(msg, typeof(u.func!0));	// pure nothrow @nogc ref 
@safe U() return

pragma(msg, typeof(u.func2!0)); // U
}
```

Is `typeof(u.func2!0)` correct in this case? If so then I'll just 
convert my API to free-standing functions and everything will 
work as a magic (without my own implementation of `getUDA`).


Re: typeof(func!0) != typeof(func!0())

2022-08-22 Thread Andrey Zherikov via Digitalmars-d-learn

On Monday, 22 August 2022 at 15:15:22 UTC, Paul Backus wrote:
My first instinct is to say that this is the user's mistake. 
UDAs are not evaluated like normal expressions, and anyone 
using UDAs is going to have to learn that sooner or later.


My feeling was that UDA expression is just an expression that's 
evaluated at compile time. Am I wrong? Where can I read about the 
differences between UDA and 'normal' expressions?



That said, if you want to try and present a nicer API, my 
recommendation would be to accept *either* (a) an instance of 
`U`, or (b) a callable that returns a `U`, which you can do 
with code like the following:


```d
import std.traits, std.meta;

enum isOrReturnsU(alias attr) = is(typeof(attr) == U) || 
is(typeof(attr()) == U);

alias getMyUDAs(alias sym) = Filter!(isOrReturnsU, getUDAs!sym);
```

Or if you want to generalize to arbitrary predicates:

```d
alias filterUDAs(alias sym, alias pred) = Filter!(pred, 
getUDAs!sym);

```


Thanks for this suggestion, I'll try it out!


Re: typeof(func!0) != typeof(func!0())

2022-08-22 Thread Andrey Zherikov via Digitalmars-d-learn
But the question is still opened: why is `typeof(U().func!0)` not 
the same as `typeof(U().func!0())`?


There is also inconsistency within UFCS - type depends on whether 
function is a member or standalone (even if I replace `auto ref` 
with `ref U`):

```d
struct U
{
ref U func(int i)() { return this; }
}
ref U func2(int i)(ref U u) { return u; }

void main()
{
U u;
pragma(msg, typeof(u.func!0));	// pure nothrow @nogc ref 
@safe U() return

pragma(msg, typeof(u.func2!0)); // U
}
```


Re: typeof(func!0) != typeof(func!0())

2022-08-22 Thread Andrey Zherikov via Digitalmars-d-learn

On Monday, 22 August 2022 at 12:04:09 UTC, Paul Backus wrote:
On Monday, 22 August 2022 at 11:24:59 UTC, Andrey Zherikov 
wrote:

On Monday, 22 August 2022 at 06:01:11 UTC, JG wrote:

Why not just change to:
alias type = typeof(U().func!0());


This is user's code and `U().func!0` is legit syntax.


Workaround: wrap it in a lambda.


```d
import std.traits;

alias type = ReturnType!(() => U().func!0);
```


My situation is that user can write some UDA expression and I'm 
checking whether it's of a type `U` using `hasUDA!(sym, U)` and 
`getUDAs!(sym, U)`. Is the users uses `U()` or `U().func!0()`, 
everything works. But `U().func!0` does not because its type is 
not `U`. So to handle this use case it seems I need to implement 
my own `hasUDA` and `getUDAs` based on

`ReturnType`.



Re: typeof(func!0) != typeof(func!0())

2022-08-22 Thread Andrey Zherikov via Digitalmars-d-learn

On Monday, 22 August 2022 at 06:01:11 UTC, JG wrote:

Why not just change to:
alias type = typeof(U().func!0());


This is user's code and `U().func!0` is legit syntax.


Re: typeof(func!0) != typeof(func!0())

2022-08-22 Thread Andrey Zherikov via Digitalmars-d-learn

On Monday, 22 August 2022 at 05:25:50 UTC, Ali Çehreli wrote:

This is where the @property keyword makes a difference:

@property auto ref func(int i)() { return this; }

Now U().func!0 will be a call in your expression.


Is original `U().func!0` not a call?

But I think std.traits.ReturnType is more explicit and does 
work in this case:


import std.traits;
alias type = ReturnType!(U().func!0);


This works but looks strange - I'm checking the type of UDA 
expression:

```d
@(U().func!0) int b;

pragma(msg, __traits(getAttributes, b)); 		// 
tuple(U().func)
pragma(msg, typeof(__traits(getAttributes, b)[0]));  		// pure 
nothrow @nogc ref @safe U() return

pragma(msg, ReturnType!(__traits(getAttributes, b)[0]));// U
pragma(msg, is(typeof(__traits(getAttributes, b)[0]) : U)); // 
false

pragma(msg, hasUDA!(b, U)); // false
```


typeof(func!0) != typeof(func!0())

2022-08-21 Thread Andrey Zherikov via Digitalmars-d-learn

I have this simple code:
```d
struct U
{
auto ref func(int i)() { return this; }
}

void main()
{
{
alias type = typeof(U().func!0);
pragma(msg, type);  		// pure nothrow @nogc ref @safe U() 
return

pragma(msg, is(type : U));  // false

auto u = U().func!0;
pragma(msg, typeof(u)); // U
}
{
alias type = typeof(U().func!0());
pragma(msg, type);  // U
pragma(msg, is(type : U));  // true

auto u = U().func!0();
pragma(msg, typeof(u)); // U
}
}
```
Why does `typeof(U().func!0)` != `U`? How can I check that the 
returned value has type `U` in this case?


Re: My programs issues

2022-08-10 Thread Andrey Zherikov via Digitalmars-d-learn

On Wednesday, 10 August 2022 at 14:08:59 UTC, pascal111 wrote:
This version has modern features, it's 1) functional 2) 
goto-less.


There is nothing modern ;-D


Re: My programs issues

2022-08-10 Thread Andrey Zherikov via Digitalmars-d-learn

On Wednesday, 10 August 2022 at 13:34:53 UTC, pascal111 wrote:

So, the program will be like this:


Is this clearer?

```d

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

double getNumber()
{
double x;

write("Enter a number: ");
readf(" %s\n", );
writeln;

return x;
}

int getChoice()
{
while(true)
{
writeln("1) addition 2) subtraction 3) multiplication 4) 
division 0) exit -1) new");

": ".write;

int choice;
readf(" %s\n", );

if(only(1,2,3,4,0,-1).canFind(choice))
return choice;
}
}

int main()
{
double x, y;

y = getNumber();

while(true)
{
int choice = getChoice();

if(choice==0)
return 0;
else if(choice==-1)
y = getNumber();
else
{
write("Enter a number: ");
readf(" %s\n", );

switch(choice){

case 1: y+=x; break;
case 2: y-=x; break;
case 3: y*=x; break;
case 4: y/=x; break;
default: break;}

y.writeln;
}
}
}
```


Re: A look inside "filter" function defintion

2022-08-02 Thread Andrey Zherikov via Digitalmars-d-learn

On Monday, 1 August 2022 at 23:35:13 UTC, pascal111 wrote:

I think this line needs explanation:

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



Create an object of type `FilterResult!(unaryFun!predicate, 
Range)` by passing `range` to its ctor, then return that object.


Re: Breaking ";" rule with lambda functions

2022-08-02 Thread Andrey Zherikov via Digitalmars-d-learn

On Monday, 1 August 2022 at 14:15:31 UTC, pascal111 wrote:
We all know the strange syntax of lambda function within filter 
algorithm like "auto r = chain(a, b).filter!(a => a > 0);".


TBH I don't find lambda syntax strange - it's pretty nice and 
there are two forms (unlike in C++): short one (`a => a > 0`) and 
long one (`(a) { return a > 0; }`).


Compare to C++ lambda syntax: `[](auto a) { return a > 0; }`

My note is, don't we break D rules by leaving ";" after lambda 
function syntax?!


There is no breakage: `a => a > 0` in this example is a 
(template) parameter to `filter` function. You can rewrite it in 
different ways, like: `filter!((a) { return a > 0; })` or


```d
alias criteria = (a) { return a > 0; };
auto r = chain(a, b).filter!criteria;
```

or even longer:

```d
auto criteria(T)(T a)
{
return a > 0;
}

auto r = chain(a, b).filter!criteria;
```

Many of D rules are taken from C, we know that, so a general 
basic rule is to put ";" after each statement


I think this is more or less correct but I personally like that I 
don't need to put ";" after definition of a class or struct 
unlike in C.


so the previous statement of filter should be "auto r = 
chain(a, b).filter!(a => a > 0;);"? Why D leaves ";" in this 
case?


No. it should not. The statement here is `auto r = chain(a, 
b).filter!(a => a > 0);`, not `a => a > 0`. If you use longer 
version of lambda syntax then yes, you'll see ";" there: `auto r 
= chain(a, b).filter!((a) { return a > 0; });` but ";" is not 
after lambda function, it's inside because you have `{...}` 
function body (which, I believe, is defined as a sequence of 
statements so you have ";" there).


Again, both `a => a > 0` and `(a) { return a > 0; }` are just 
parameters to `filter` function. Parameters are not terminated 
with ";". This is the same as in C - you are not adding ";" after 
function parameter:

```cpp
auto is_even = [](int i){ return i%2 == 0; };
auto result = std::find(..., ..., is_even);
```


Re: Is this a violation of const?

2022-07-29 Thread Andrey Zherikov via Digitalmars-d-learn

On Friday, 29 July 2022 at 22:16:26 UTC, H. S. Teoh wrote:

This totally makes sense. Thanks for explanation!


Re: A converting problem in using "among" with arrays

2022-07-29 Thread Andrey Zherikov via Digitalmars-d-learn

On Friday, 29 July 2022 at 22:09:47 UTC, pascal111 wrote:
I next code, we have a data type problem 
"54.among(to!uint[10](y)).writeln;":


module main;

import std.stdio;
import std.string;
import std.conv;
import dcollect;
import std.math;
import std.algorithm;

int main(string[] args)
{
int[] x=[23, 34,-88, 54, -90, -34];

auto y=x.filter!(a=>a<0);

foreach(i; y)
i.write(", ");

54.among(to!uint[10](y)).writeln;

return 0;
}

Error message:
"hello.d|19|error: only one index allowed to index void|"


Did you mean `to!(uint[10])(y)`? This converts to `uint[10]`.


Is this a violation of const?

2022-07-29 Thread Andrey Zherikov via Digitalmars-d-learn
In the example below `func` changes its `const*` argument. Does 
this violates D's constness?


```d
import std;

struct S
{
string s;

void delegate(string s) update;
}

void func(const S* s)
{
writeln(*s);
s.update("func");
writeln(*s);
}

void main()
{
auto s = S("test");
s.update = (_) { s.s = _; };

writeln(s);
func();
writeln(s);
}
```

The output is:
```
S("test", void delegate(string))
const(S)("test", void delegate(string))
const(S)("func", void delegate(string))
S("func", void delegate(string))
```


Re: Bug in dmd?

2022-06-16 Thread Andrey Zherikov via Digitalmars-d-learn

On Wednesday, 15 June 2022 at 16:53:13 UTC, mw wrote:

Create a simple test case, file bug at:

https://issues.dlang.org/


I tried. No luck.


Re: Bug in dmd?

2022-06-15 Thread Andrey Zherikov via Digitalmars-d-learn

On Wednesday, 15 June 2022 at 09:24:35 UTC, Dukc wrote:
Now when I think of it, perhaps the fact that private 
`printHelp` has the same name as the public `printHelp` is 
somehow confusing dmd. If you try to rename the private 
`printHelp` and it's call in the public one to something else, 
you might get some insight on what triggers this behaviour.


I tried `private void printHelp` -> `package void printHelp1`. It 
didn't help.


Re: Bug in dmd?

2022-06-15 Thread Andrey Zherikov via Digitalmars-d-learn

On Wednesday, 15 June 2022 at 09:21:28 UTC, user1234 wrote:

On Tuesday, 14 June 2022 at 13:39:12 UTC, Andrey Zherikov wrote:
I have [pretty simple code in my 
library](https://github.com/andrey-
[Line (2) 
produces](https://github.com/andrey-zherikov/argparse/runs/6880350900?check_suite_focus=true#step:5:12) `undefined reference to '_D3std7sumtype__T7SumTypeTS8argparse4help2AATSQtQm2BBZQBl6__dtorMFNaNbNiNfZv'` (it demangles to `pure nothrow @nogc @safe void std.sumtype.SumType!(argparse.help.AA, argparse.help.BB).SumType.__dtor()`)


If I comment line (2) then everything is good (no link 
errors). Note that there is the same code at (1) which doesn't 
produce any error. Any idea what's going on?


That can be a template instance that's emitted somewhere else, 
i.e the thing is there but the mangle is different. maybe try 
to find if the dtor is there with `mn -S` on each object.


Another thing to try in these situations is to see if that 
works with `-allinst`.


I tried to call dmd the same way as dub does with `-allinst` 
added to all calls. Got the same linker issue.


`nm` shows that `app.d` refers to dtor which is not defined in 
`.a`:

```bash
$ nm .../liball_argparse.a|egrep 'argparse.+dtor'
$ nm .../all_getting_started-basic.o|egrep 'argparse.+dtor'
 U 
_D3std7sumtype__T7SumTypeTS8argparse4help2AATSQtQm2BBZQBl6__dtorMFNaNbNiNfZv

```


Re: Bug in dmd?

2022-06-15 Thread Andrey Zherikov via Digitalmars-d-learn

On Wednesday, 15 June 2022 at 07:38:36 UTC, JG wrote:
I tried to reproduce it but wasn't able (I guess it is some 
interplay with the rest of your code):


I tried this first but got the same result as you. I think my 
small library overheats DMD's template engine.


Re: Bug in dmd?

2022-06-14 Thread Andrey Zherikov via Digitalmars-d-learn

On Tuesday, 14 June 2022 at 21:44:48 UTC, Dukc wrote:
No idea. The functions seems indeed to be exactly the same, so 
I assume this is a DMD bug. It cannot be a bug in 
`std.sumtype`, since that would trigger in both of the 
templates.


This definitely triggers some bug in DMD because this `private 
void printHelp ...` function is not really `private` as it's 
called from [another 
module](https://github.com/andrey-zherikov/argparse/blob/bug/source/argparse/internal.d#L786) and DMD doesn't catch this.


Bug in dmd?

2022-06-14 Thread Andrey Zherikov via Digitalmars-d-learn
I have [pretty simple code in my 
library](https://github.com/andrey-zherikov/argparse/blob/bug/source/argparse/help.d#L27-L47):

```d
alias CC = SumType!(AA,BB);
struct AA {}
struct BB
{
CC[] c;
}

private void ppp(T, Output)(auto ref Output output, in 
CommandArguments!T cmd, in Config config)

{
auto cc = CC(AA());  // (1)
}
private void printHelp(T, Output)(auto ref Output output, in 
CommandArguments!T cmd, in Config config)

{
auto cc = CC(AA());  // (2)
}

void printHelp(T, Output)(auto ref Output output, in Config 
config)

{
ppp(output, CommandArguments!T(config), config);
printHelp(output, CommandArguments!T(config), config);
}
```

[Line (2) 
produces](https://github.com/andrey-zherikov/argparse/runs/6880350900?check_suite_focus=true#step:5:12) `undefined reference to '_D3std7sumtype__T7SumTypeTS8argparse4help2AATSQtQm2BBZQBl6__dtorMFNaNbNiNfZv'` (it demangles to `pure nothrow @nogc @safe void std.sumtype.SumType!(argparse.help.AA, argparse.help.BB).SumType.__dtor()`)


If I comment line (2) then everything is good (no link errors). 
Note that there is the same code at (1) which doesn't produce any 
error. Any idea what's going on?


Re: Templatized delegates

2022-05-31 Thread Andrey Zherikov via Digitalmars-d-learn

On Tuesday, 31 May 2022 at 23:15:24 UTC, Andrey Zherikov wrote:

On Tuesday, 31 May 2022 at 21:53:17 UTC, Paul Backus wrote:

If you want compile-time polymorphism, three's no other way.


Yes, I want compile-time polymorphism.


In case if `S.doSomething` is NOT template function then the 
problem can be solved easily by wrapping access to `S` into 
another delegate:


```d
import std.stdio: writeln;

struct S
{
void doSomething(int value) { value.writeln; }
}

alias DG = void delegate (void delegate(int) doSomething);

auto createDG(T)(T value)
{
return delegate (void delegate(int) doSomething) { 
doSomething(value); };

}

struct R
{
DG dg;

this(int value)
{
dg = createDG(value);
}
}

void main()
{
auto r = R(5);

S s;
r.dg(_ => s.doSomething(_));
}
```

How to do the same for templated `S.doSomething`?


Re: Templatized delegates

2022-05-31 Thread Andrey Zherikov via Digitalmars-d-learn

On Tuesday, 31 May 2022 at 22:34:41 UTC, Christian Köstlin wrote:
Would it help to not create the delegate in R's constructor, 
but feed
the delegate into it (and create the delegate outside). This 
would also resemble your description (R is a delegate holder) 
more.


That's possible but the problem is that `S` is part of `DG`.


Re: Templatized delegates

2022-05-31 Thread Andrey Zherikov via Digitalmars-d-learn

On Tuesday, 31 May 2022 at 21:53:17 UTC, Paul Backus wrote:

If you want compile-time polymorphism, three's no other way.


Yes, I want compile-time polymorphism.


```d
import std.stdio;

struct S
{
// function that should be called from delegate
void doSomething(T)(T value) { value.writeln; }
}

interface I
{
void doSomething(int value);
}

class Adapter : I
{
S s;
this(S s) { this.s = s; }
void doSomething(int value) { s.doSomething(value); }
}

alias DG = void delegate (I i);

auto createDG(int value)
{
return delegate (I i) { i.doSomething(value); };
}

struct R
{
DG dg;

this(int value)
{
dg = createDG(value);
}
}

void main()
{
auto r = R(5);

S s;
r.dg(new Adapter(s));
}
```


Unfortunately this solution looses important feature: there is no 
more templated call to `S.doSomething` as `I.doSomething` is not 
template and adding override for every type is not maintainable.


Templatized delegates

2022-05-31 Thread Andrey Zherikov via Digitalmars-d-learn
I have tightly coupled code which I'd like to decouple but I'm a 
bit stuck.
For simplicity, I reduced the amount of code to something simple 
to understand. So I have a struct `S` that has templated member 
function that does something. On the other side I have delegate 
holder `R` - this delegate takes `S` object as an argument and 
calls that function. My goal is to remove dependency from `R` to 
`S`.


Here is code example:

```d
import std.stdio: writeln;

struct S
{
// function that should be called from delegate
void doSomething(T)(T value) { value.writeln; }
}

alias DG = void delegate (ref S s);

auto createDG(T)(T value)
{
return delegate (ref S s) { s.doSomething(value); };
}

struct R
{
DG dg;

this(int value)
{
dg = createDG(value);
}
}

void main()
{
auto r = R(5);

S s;
r.dg(s);
}
```

An obvious way is to add a type template parameter to `R`, `DG` 
and `createDG` but I would like to avoid this. Is there another 
way to do so?


I think ideal solution would be having templatized delegate `void 
delegate (S)(ref S s)` and then call `r.dg!S(s)` but it's not 
available: `alias DG = void delegate (S) (ref S s)` gives unclear 
`Error: function declaration without return type. (Note that 
constructors are always named 'this')` message.


Re: How to fix "typesafe variadic function parameter"?

2022-05-24 Thread Andrey Zherikov via Digitalmars-d-learn

On Tuesday, 24 May 2022 at 22:51:50 UTC, Adam Ruppe wrote:

On Tuesday, 24 May 2022 at 22:46:55 UTC, Andrey Zherikov wrote:

return S(s);


return S(s.dup);


The variadic lives in a temporary array that expires at the end 
of the function. So copying it out to the GC lets it live on.


Your code was wrong on 2.099 too, but the compiler didn't tell 
you.


That works, thank you!

Can this error message be improved some way so this fix becomes 
obvious?


How to fix "typesafe variadic function parameter"?

2022-05-24 Thread Andrey Zherikov via Digitalmars-d-learn

How to fix this?
```d
struct S
{
string[] s;
}

auto foo(string[] s...)   // Error: typesafe variadic function 
parameter `s` of type `string[]` cannot be marked `return`

{
return S(s);
}

void main()
{
import std.stdio: writeln;

writeln(foo("Hello D"));
}
```

This successfully compiles with dmd 2.099.1 but fails with 2.100.0

I tried to add `return`/`ref` but no luck.


Re: Is T.init allowed?

2022-04-29 Thread Andrey Zherikov via Digitalmars-d-learn

On Friday, 29 April 2022 at 12:05:35 UTC, Dennis wrote:

On Friday, 29 April 2022 at 11:30:49 UTC, Andrey Zherikov wrote:

Is it a compiler issue so this shouldn't be allowed?


Members called `init` are in the process of being deprecated, 
see:


https://github.com/dlang/dmd/pull/12512


That's nice!


Is T.init allowed?

2022-04-29 Thread Andrey Zherikov via Digitalmars-d-learn

Seems compiler allows custom nested type with `init` name:

```d
struct T
{
struct init {}

int b = 2;
}

void main()
{
T t;
writeln(t);// T(2)
//writeln(T.init); // Error: cannot pass type `init` as a 
function argument

}
```

Is it a compiler issue so this shouldn't be allowed?
If this is OK then how can I refer to an initial value of `T` 
(`T.init` doesn't work)?


Re: Calling template member function?

2022-04-19 Thread Andrey Zherikov via Digitalmars-d-learn
On Tuesday, 19 April 2022 at 20:29:01 UTC, Steven Schveighoffer 
wrote:
You can work around the dual context, if you are OK with 
passing the second context explicitly.


The easiest way is to move the member function to a UFCS 
function. an example:


```d
struct X
{
   int x;
   void applyToX(alias fn)() {fn(x);}
}

void applyToX_alt(alias fn)(ref X xval) {
   fn(xval.x);
}

void main()
{
   auto s = X(5);
   int y = 6;
   void fn(ref int x) { x += y; }
   s.applyToX!fn; // error, dual context needed
   s.applyToX_alt!fn; // fine, only single context needed
}
```


I used struct to understand the problem. I don't actually have an 
object context to pass like in your example, the only context I 
have is template parameters.




Re: Calling template member function?

2022-04-19 Thread Andrey Zherikov via Digitalmars-d-learn

On Tuesday, 19 April 2022 at 19:07:37 UTC, Ali Çehreli wrote:

On 4/19/22 11:18, Andrey Zherikov wrote:

> Is there a way/workaround to achieve the desired behavior?

Can you describe the goal a little more. For example, I assume 
you really need a more useful lambda although the example you 
show seems unnecessary:


  enum dg = () => func();

That lambda looks suspiciously trivial. Will it actually need 
its context?


Ali


I have [old API 
function](https://github.com/andrey-zherikov/argparse/blob/master/source/argparse.d#L1228) that gets a function as a parameter and I want it to call (for backward compatibility) [new API function](https://github.com/andrey-zherikov/argparse/blob/remove-main/source/argparse.d#L1630) which accepts a function as a template parameter.


Re: Calling template member function?

2022-04-19 Thread Andrey Zherikov via Digitalmars-d-learn

I get the same error even with just `struct`:
```d
struct S
{
static void f_new(alias func)()
{
func();
}
}

void f_new(alias func)()
{
func();
}

void f(FUNC)(FUNC func)
{
f_new!(() => func());   // works
// S.f_new!(() => func());  // doesn't work
}
```


Re: Calling template member function?

2022-04-19 Thread Andrey Zherikov via Digitalmars-d-learn

On Tuesday, 19 April 2022 at 18:18:26 UTC, Andrey Zherikov wrote:
Is there a way/workaround to achieve the desired behavior? 
Those two bugs pointed above were reported in 2017 and 2011 (!) 
which makes me think that they won't be fixed any time soon 
(I'm not sure that they are actually the same issue as I faced 
here).


I tried to change the code to this:
```d
void f(FUNC)(FUNC func)
{
enum dg = () => func();
T!int.f_new!dg;
}
```

But I get this error:
```
onlineapp.d(7): Error: delegate `onlineapp.f!(void function() 
@safe).f.__lambda2` is a nested function and cannot be accessed 
from `onlineapp.T!int.f_new!(delegate () @safe

{
(*func)();
return ;
}
).f_new`
```


Re: Calling template member function?

2022-04-19 Thread Andrey Zherikov via Digitalmars-d-learn
On Tuesday, 19 April 2022 at 16:38:42 UTC, Steven Schveighoffer 
wrote:

On 4/19/22 11:46 AM, Paul Backus wrote:
If you remove `static` from `f_new`, you get an error message 
talking about this explicitly:


Interesting that `static` does anything there, since it's a 
no-op.


-Steve


I put `static` because it fixes "dual context" error.

Is there a way/workaround to achieve the desired behavior? Those 
two bugs pointed above were reported in 2017 and 2011 (!) which 
makes me think that they won't be fixed any time soon (I'm not 
sure that they are actually the same issue as I faced here).




Calling template member function?

2022-04-19 Thread Andrey Zherikov via Digitalmars-d-learn
I want to migrate my library API from standalone function that 
takes delegate as argument to a template member function that 
takes delegate as a template parameter but compiler errors out. 
Here is code example:

```d
import std.stdio;

template T(P)
{
static void f_new(alias func)()
{
func();
}
}

void f(FUNC)(FUNC func)
{
T!int.f_new!(() => func());
}

void main()
{
f(function () { __LINE__.writeln; });
}
```

Compiler error:
```
onlineapp.d(7): Error: `static` function `onlineapp.f!(void 
function() @safe).f.f_new!(delegate () @safe

{
(*func)();
return ;
}
).f_new` cannot access delegate `__lambda2` in frame of function 
`onlineapp.f!(void function() @safe).f`

onlineapp.d(13):`__lambda2` declared here
onlineapp.d(13): Error: template instance `onlineapp.f!(void 
function() @safe).f.f_new!(delegate () @safe

{
(*func)();
return ;
}
)` error instantiating
onlineapp.d(18):instantiated from here: `f!(void 
function() @safe)`

```

What confuses me a lot is that if I remove `template T` then 
everything works perfectly:

```d
import std.stdio;

void f_new(alias func)()
{
func();
}

void f(FUNC)(FUNC func)
{
f_new!(() => func());
}

void main()
{
f(function () { __LINE__.writeln; });
}
```

Is there an issue in template processing in compiler?


Re: How to unit-test behavior under "version"?

2022-03-30 Thread Andrey Zherikov via Digitalmars-d-learn

On Wednesday, 30 March 2022 at 04:15:24 UTC, Paul Backus wrote:

Probably the easiest way is to split it into two functions

```d
void f()
{
version (foo)
fVersionFoo();
else
fDefault();
}

void fVersionFoo()
{
/* ... */
}

void fDefault()
{
/* ... */
}
```

Then you can write separate unit tests for both `fVersionFoo` 
and `fDefault`, and they will both be tested regardless of what 
settings you build with.


This is an option when you have big difference between foo and 
not-foo behavior. In my case they are 90% the same so I think 
I'll go this way:


```d
void fImpl(bool fooMode)()
{
static if(fooMode)
writeln("foo");
else
writeln("no foo");
}

version(foo)
alias f = fImpl!true;
else
alias f = fImpl!false;

unittest {
// test fImpl!true
}
unittest {
// test fImpl!false
}
```



Re: How to unit-test behavior under "version"?

2022-03-29 Thread Andrey Zherikov via Digitalmars-d-learn
On Tuesday, 29 March 2022 at 20:20:46 UTC, Steven Schveighoffer 
wrote:
So keep in mind that versions are *module-wide*, and usually 
*compilation-wide*. Which means that you won't be testing 
multiple version configurations in the same build.


...

In the case where version is going to *affect the results of 
the function*, as yours does above, then what I would do is 
repeat the version tree as above, putting an individual 
unittest in each branch. But you could potentially do it inside 
the unittest itself. I just find that a bit convoluted.


Right, I can do per-version unit tests and the question becomes 
how to build all versions. Since I'm using dub, there is a 
way to express different versions through "configuration" specs 
in dub.json. Is there a way to tell `dub test` to test all 
configurations?




How to unit-test behavior under "version"?

2022-03-29 Thread Andrey Zherikov via Digitalmars-d-learn
I have a function below (just an example). What's the recommended 
way to unit-test it for all `version` cases?

```d
void f()
{
import std.stdio: writeln;

version(foo)
writeln("foo");
else
writeln("no foo");
}
```


Re: Template with default parameter

2022-03-11 Thread Andrey Zherikov via Digitalmars-d-learn

On Friday, 11 March 2022 at 12:53:56 UTC, Adam D Ruppe wrote:

On Friday, 11 March 2022 at 12:01:27 UTC, Andrey Zherikov wrote:
There is some inconsistency between templates and template 
functions as this works as I want to:


Yeah, functions have the special feature of implicit 
instantiation from the function arguments. No other template 
do, if you want an instance there, you need to specify it as a 
!(). And since functions can't return aliases to types you 
can't use that to get around it. There's no way to do what you 
want to do, you either need to write the !() or use a different 
alias name.


Thanks for explanation!


Re: Template with default parameter

2022-03-11 Thread Andrey Zherikov via Digitalmars-d-learn
There is some inconsistency between templates and template 
functions as this works as I want to:

```d
import std.stdio;

void f(int i=3)()
{
writeln(i);
}

void main()
{
f!1;  // 1
f!(); // 3
f;// 3
}
```


Re: Template with default parameter

2022-03-11 Thread Andrey Zherikov via Digitalmars-d-learn

On Friday, 11 March 2022 at 07:06:15 UTC, bauss wrote:

Create an alias for T!() is the best you can do.

Ex.

```
alias t = T!();
```

There isn't really any better method as far as I know.


I'd like to preserve the name (`t` != `T`) but `alias T = T!()` 
gives me `Error: declaration `T` is already defined`


Template with default parameter

2022-03-10 Thread Andrey Zherikov via Digitalmars-d-learn

I have simple template:
```d
template T(int i=3)
{
mixin template M(int m)
{
enum t = i;
}
}

{
mixin T!1.M!1;
pragma(msg, t);   // 1
}
{
mixin T!().M!1;
pragma(msg, t);   // 3
}
{
	mixin T.M!1;  // Error: identifier `M` of `T.M` is not 
defined

  // Error: mixin `M!1` is not defined
pragma(msg, t);   // Error: undefined identifier `t`
  //while evaluating 
`pragma(msg, t)`
}
```

What should I do to be able to write `T.M!...`? I want to omit 
verbose `!()` for `T`. Note that mixins are essential here.


Re: How to check that a member function is generated by compiler?

2022-02-25 Thread Andrey Zherikov via Digitalmars-d-learn

On Friday, 25 February 2022 at 16:24:46 UTC, Paul Backus wrote:
On Friday, 25 February 2022 at 14:25:22 UTC, Andrey Zherikov 
wrote:


Another interesting observation - is there any explanation why 
`typeof` returns different results for generated `opAssign`?

[...]


If I move `foreach` loop into a function (e.g. `main`) then 
the first pragma prints the same as the others.


It sounds like this is probably an inconsistency in 
`.stringof`, not `typeof`. I couldn't say what causes it, but 
it's not the first time I've seen `.stringof` give inconsistent 
results. (E.g., https://issues.dlang.org/show_bug.cgi?id=18269)


I see. Thanks


Re: How to check that a member function is generated by compiler?

2022-02-25 Thread Andrey Zherikov via Digitalmars-d-learn

On Friday, 25 February 2022 at 05:25:14 UTC, Ali Çehreli wrote:

On 2/24/22 20:44, Andrey Zherikov wrote:

How can I check that `opAssign` is generated by compiler and 
doesn't exist in the original code?


I think this one:

  https://dlang.org/phobos/std_traits.html#hasElaborateAssign

Ali


This take a struct as an argument, not a member, so I need to do 
`if(sym == "opAssign")`. I gave this another thought and checking 
the symbol against `"opAssign"` would be good enough for my use 
case.


Another interesting observation - is there any explanation why 
`typeof` returns different results for generated `opAssign`?

```d
import std.sumtype: SumType;

struct A
{
SumType!int b;
}

static foreach(sym; __traits(allMembers, A))
{
// ref A(A p) return,opAssign
pragma(msg,
  typeof(__traits(getMember, A, 
sym)).stringof,",",sym);


// true,pure nothrow @nogc ref @safe A(A p) return,opAssign

pragma(msg,
   is(typeof(__traits(getMember, A, sym)) == 
function),",",
  typeof(__traits(getMember, A, 
sym)).stringof,",",sym);


// pure nothrow @nogc ref @safe A(A p) return,opAssign
pragma(msg,
  typeof(__traits(getMember, A, 
sym)).stringof,",",sym);

}
```

If I move `foreach` loop into a function (e.g. `main`) then the 
first pragma prints the same as the others.


How to check that a member function is generated by compiler?

2022-02-24 Thread Andrey Zherikov via Digitalmars-d-learn

This code
```d
import std.sumtype: SumType;

struct A
{
SumType!int b;
}

static foreach(sym; __traits(allMembers, A))
pragma(msg,sym);
```
prints
```
b
opAssign
```

How can I check that `opAssign` is generated by compiler and 
doesn't exist in the original code?


Re: keyword as struct field

2022-02-20 Thread Andrey Zherikov via Digitalmars-d-learn

On Sunday, 20 February 2022 at 11:08:55 UTC, partypooper wrote:

Hello, I'm new to D.

Title is self described, is it possible to use keyword as 
struct field?


Maybe it is XYproblem, so here I will describe a little what I 
need.
I'm parsing some json currently with 
[mir-ion](https://code.dlang.org/packages/mir-ion) 
(better/simpler suggestions for only json de/serialization?), 
that has "version" as one of it's keys, so I can't use that as 
field in my struct. Maybe some annotation in mir library to 
parse "version" into other struct field name, can't find though 
(its docs pretty concise).


Unfortunately I'm not able to help you with mir-ion. But I see 
two questions here:



keyword as struct field


I believe this is the case for the most languages - keyword is 
not allowed as a variable name.



usage of `version` keyword as a variable name


IMO having `version` keyword in D is unexpected language design. 
No one will complain about keywords that are widely used in the 
industry (like `struct`, `int` etc). But `version`?! I hit this 
problem multiple times already and the only solution for me was 
to use `version_` instead.


Re: Member function forwarding

2022-02-17 Thread Andrey Zherikov via Digitalmars-d-learn
On Thursday, 17 February 2022 at 20:59:43 UTC, Andrey Zherikov 
wrote:
Another question: does `auto foo(ARGS...)(ARGS args) { return 
a.foo(args); }` correctly forward `ref`, `const` etc. arguments?


Actually the answer is `NO`. I have to do `auto foo(ARGS...)(auto 
ref ARGS args) { return
a.foo(args); }`. Also if `a.foo` is a `const` function then I 
have to add `const` to this definition as well.


Member function forwarding

2022-02-17 Thread Andrey Zherikov via Digitalmars-d-learn
I have a struct that has struct data member and I'd like to 
forward some (not all) functions from internal data member. Some 
thing like this:

```d
struct A {
void foo() const { writeln("A.foo"); }
}

struct B {
A a;

auto foo(ARGS...)(ARGS args) { return a.foo(args); }
// alias foo = a.foo;
}

void main()
{
B b;
b.foo();   // In "alias" case: Error: `this` for `foo` needs 
to be type `A` not type `B`

}
```

Is there simpler way to achieve this?
I tried `alias foo = a.foo` but it doesn't work: "Error: `this` 
for `foo` needs to be type `A` not type `B`" - when function is 
called (`b.foo()`).


Another question: does `auto foo(ARGS...)(ARGS args) { return 
a.foo(args); }` correctly forward `ref`, `const` etc. arguments?


Re: Template sequence parameter and default value

2022-01-27 Thread Andrey Zherikov via Digitalmars-d-learn

On Thursday, 27 January 2022 at 03:19:59 UTC, Jaime wrote:
You can accomplish this by heading off the template sequence 
parameter with several default template parameters. If you need 
them all under one name, you can recombine them in the function 
body with std.meta.AliasSeq, the effective "kind" of a template 
sequence parameter.


Example:

```d
void foo(string FirstModule = __MODULE__, RestModules...)() {
alias Modules = AliasSeq!(FirstModule, RestModules);
// things
}

// foo!(module1, module2) => alias Modules = (module1, module2)
// foo!() => alias Modules = (__MODULE__)
```


Unfortunately `string FirstModule` doesn't work if I specify the 
module: https://run.dlang.io/is/BZd0KB


The closest solution I have is this:
```d
void foo(MODULES...)()
{
writeln(MODULES.stringof);
}
alias foo(string MODULE = __MODULE__) = foo!(mixin(MODULE));

void main()
{
writeln(1);
foo();
writeln(2);
foo!(onlineapp);
writeln(3);
foo!(onlineapp,onlineapp);
}
```

It prints this:
```
1
tuple(module onlineapp)
2
tuple(module onlineapp)
3
tuple(module onlineapp, module onlineapp)
```

So is it possible to get rid of the alias?


Template sequence parameter and default value

2022-01-26 Thread Andrey Zherikov via Digitalmars-d-learn
What is the best way to emulate a default value for template 
sequence parameter of a function?


I want something like this:
```d
void foo(MODULES... = __MODULE__)() {}

// these should work:
foo!(module1, module2);
foo!(module1);
foo();  // this should use current module (__MODULE__) 
according to default value

```



Re: Any workaround for "closures are not yet supported in CTFE"?

2021-12-08 Thread Andrey Zherikov via Digitalmars-d-learn

On Wednesday, 8 December 2021 at 17:05:49 UTC, Timon Gehr wrote:

```d
import std.stdio, std.traits, core.lifetime;
auto partiallyApply(alias fun,C...)(C context){
return  class(move(context)){
C context;
this(C context) { foreach(i,ref c;this.context) 
c=move(context[i]); }
auto opCall(ParameterTypeTuple!fun[context.length..$] 
args) {

return fun(context,forward!args);
}
}.opCall;
}

alias Action = void delegate();

Action createDelegate(string s){
import std.stdio;
return partiallyApply!((string str) => writeln(str))(s);
}

struct A{ Action[] dg; }

A create(){
A a;
a.dg ~= createDelegate("hello");
a.dg ~= createDelegate("buy");
return a;
}

void main(){
enum a = create();
foreach(dg; a.dg)
dg();
}

```


This is great, thanks you!


Re: Any workaround for "closures are not yet supported in CTFE"?

2021-12-07 Thread Andrey Zherikov via Digitalmars-d-learn

On Tuesday, 7 December 2021 at 18:50:04 UTC, Ali Çehreli wrote:
I don't know whether the workaround works with your program but 
that delegate is the equivalent of the following struct (the 
struct should be faster because there is no dynamic context 
allocation). Note the type of 'dg' is changed accordingly:


The problem with struct-based solution is that I will likely be 
stuck with only one implementation of delegate (i.e. opCall 
implementation). Or I'll have to implement dispatching inside 
opCall based on some "enum" by myself which seems weird to me. Do 
I miss anything?


Any workaround for "closures are not yet supported in CTFE"?

2021-12-07 Thread Andrey Zherikov via Digitalmars-d-learn
I have a struct `A` that stores delegates. The problem is that 
I'm getting "`Error: closures are not yet supported in CTFE`" if 
I create an compile-time constant value of type `A`:


```d
struct A
{
void delegate()[] dg;
}

auto createDelegate(string s)
{
return { s.writeln; };   // Error: closures are not yet 
supported in CTFE

}

A create()
{
A a;
a.dg ~= createDelegate("hello");
a.dg ~= createDelegate("buy");
return a;
}


void main()
{
enum a = create(); // If change 'enum' to 'auto' then 
everything works

foreach(dg; a.dg)
dg();
}
```

How can I workaround this and have compile-time object with 
delegates?


Re: need `this` on trying to use class method with parallelism Task! or task!

2021-11-14 Thread Andrey Zherikov via Digitalmars-d-learn

On Sunday, 14 November 2021 at 16:55:24 UTC, Alexey wrote:




Remove "!"




Re: need `this` on trying to use class method with parallelism Task! or task!

2021-11-14 Thread Andrey Zherikov via Digitalmars-d-learn

On Sunday, 14 November 2021 at 14:41:21 UTC, Alexey wrote:
On Sunday, 14 November 2021 at 14:24:00 UTC, Andrey Zherikov 
wrote:

On Sunday, 14 November 2021 at 12:01:36 UTC, Alexey wrote:




You just need two changes:
- make `threadFunc` function static: `static void threadFunc()`
- use `task` instead of `Task`: `auto t1 = task!threadFunc;`


I need `this` to be available inside of threadFunc



Just do `auto t1 = task()` in `threadCreator` then.


Re: need `this` on trying to use class method with parallelism Task! or task!

2021-11-14 Thread Andrey Zherikov via Digitalmars-d-learn

On Sunday, 14 November 2021 at 12:01:36 UTC, Alexey wrote:




You just need two changes:
- make `threadFunc` function static: `static void threadFunc()`
- use `task` instead of `Task`: `auto t1 = task!threadFunc;`


Re: How to get the location (file, line) of UDA without parens?

2021-11-14 Thread Andrey Zherikov via Digitalmars-d-learn

On Sunday, 14 November 2021 at 07:06:25 UTC, user1234 wrote:
On Sunday, 14 November 2021 at 05:12:58 UTC, Andrey Zherikov 
wrote:

Here is my code:
[...]
`W()` (2) works as expected but is it possible to achieve the 
same without parenthesis so `getAttributes` trait returns 
`tuple(L("app.d", 16LU))` for (1)?


No, without parens this is really the function template, as a 
symbol, that becomes the UDA.


Can this be achieved with any other type of `W`? For example I 
can get the same result with struct (also changing `@W()` to 
`@W!()` on line (2)):

```d
struct W(string f = __FILE__, size_t l = __LINE__)
{
auto loc = L(f,l);
}
```


How to get the location (file, line) of UDA without parens?

2021-11-13 Thread Andrey Zherikov via Digitalmars-d-learn

Here is my code:
```d
struct L
{
string file;
size_t line;
}

auto W(string f = __FILE__,size_t l= __LINE__)()
{
return L(f,l);
}

struct A
{
  @W   // (1): line# 16
  {
int a;
int b;
  }
  @W() // (2): line# 21
  {
int c;
int d;
  }
}

void main()
{
pragma(msg, __traits(getAttributes, A.a)); // tuple(W(string 
f = __FILE__, ulong l = __LINE__)())
pragma(msg, __traits(getAttributes, A.b)); // tuple(W(string 
f = __FILE__, ulong l = __LINE__)())
pragma(msg, __traits(getAttributes, A.c)); // 
tuple(L("app.d", 21LU))
pragma(msg, __traits(getAttributes, A.d)); // 
tuple(L("app.d", 21LU))

}
```

`W()` (2) works as expected but is it possible to achieve the 
same without parenthesis so `getAttributes` trait returns 
`tuple(L("app.d", 16LU))` for (1)?


Re: How to return a reference to structs?

2021-11-06 Thread Andrey Zherikov via Digitalmars-d-learn

On Saturday, 6 November 2021 at 13:57:47 UTC, Ali Çehreli wrote:
Have you considered std.range.indexed, which should at least 
cover the case of accessing:


  https://dlang.org/phobos/std_range.html#indexed


I don't need to iterate over whole collection, but subset of it.

Can you give a little more context for others to come up with a 
better answer?


I have a [CLI-parsing 
library](https://github.com/andrey-zherikov/argparse) that 
creates a set of argument objects based on UDAs. They are [stored 
in 
array](https://github.com/andrey-zherikov/argparse/blob/master/source/argparse.d#L436) right now. I want to introduce some grouping having something like `struct Group { size_t[] args; }` but face the problem of addressing the objects. As of now I need to be able to iterate over the arguments within a group as well as those that satisfy some condition.


Re: How to return a reference to structs?

2021-11-06 Thread Andrey Zherikov via Digitalmars-d-learn

On Saturday, 6 November 2021 at 04:28:05 UTC, Ali Çehreli wrote:

On 11/5/21 5:43 PM, Andrey Zherikov wrote:

In case others want to work, here are the modules that need to 
be imported:


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

> struct A {}
> struct B
> {
>  A[] ar = [A.init];
>  size_t[] idx = [0];

I don't know why but those initial values are the reason for 
the problem. It works without them.


`get()` will return nothing in this case. But I can make them non 
empty in another way:


```d
import std;

struct A {}
struct B
{
A[] ar;
size_t[] idx;

A*[] get()
{
return idx.map!((idx) => [idx]).array;
}
}

auto foo()
{
B b;
b.ar ~= A.init;
b.idx ~= 0;
return b.get();
}

void main()
{
writeln(foo());
pragma(msg, foo());
}
```

Some one can complain that `foo()` returns pointers that are not 
available in CTFE but remember that the real code is more complex 
and `foo()` cam be return just length (`return b.get().length;`) 
having the same result.


Basically I have a collection of data (`A[] ar`), different 
addressing through the indexes (multiple `size_t[] idx`) and I 
want to manipulate these objects through indexes. If there is 
another way to achieve the same in CFTE, I'd like to hear.


Re: How to return a reference to structs?

2021-11-05 Thread Andrey Zherikov via Digitalmars-d-learn

On Friday, 5 November 2021 at 20:13:02 UTC, Andrey Zherikov wrote:

On Friday, 5 November 2021 at 19:49:50 UTC, Ali Çehreli wrote:
Indexes are typed as size_t, which is ulong for 64-bit and 
uint for 32-bit. If idx elements were indeed indexes, it 
should have been typed as size_t:


size_t[] idx = [1,3,4];  // <-- Here



Ah, good point. Thanks!


Adding a bit of CTFE:
```d
struct A {}
struct B
{
A[] ar = [A.init];
size_t[] idx = [0];

A*[] get()
{
return idx.map!((idx) => [idx]).array;  // Error: 
couldn't find field `ar` of type `A[]` in `MapResult([0LU], null)`

}
}

auto foo()
{
B b;
return b.get();
}

void main()
{
writeln(foo());   // This works
pragma(msg, foo());   // This doesn't work
}
```

How to make this work?


Re: How to return a reference to structs?

2021-11-05 Thread Andrey Zherikov via Digitalmars-d-learn

On Friday, 5 November 2021 at 19:49:50 UTC, Ali Çehreli wrote:
Indexes are typed as size_t, which is ulong for 64-bit and uint 
for 32-bit. If idx elements were indeed indexes, it should have 
been typed as size_t:


size_t[] idx = [1,3,4];  // <-- Here



Ah, good point. Thanks!


Re: How to return a reference to structs?

2021-11-04 Thread Andrey Zherikov via Digitalmars-d-learn

On Thursday, 4 November 2021 at 13:03:54 UTC, Paul Backus wrote:
On Thursday, 4 November 2021 at 11:26:30 UTC, Andrey Zherikov 
wrote:

I have the following code example:

```d
struct A{}

A[5] a;
ulong[] idx = [1,3,4];

auto get()
{
return idx.map!(_ => a[_]);
}

foreach(i; 0 .. a.length)
write([i], " ");
writeln;

foreach(ref b; get())
write(, " ");
writeln;
```

How can I change `get` function so it returns the references 
to the content in `a`?


Have the lambda return by reference:

```d
auto get()
{
return idx.map!(ref (i) => a[i]);
}
```


Making this example a bit complex: I want `get` to return 
additional data to the reference. How should I change the lambda 
then?

```d
auto get()
{
return idx.map!(ref (i) => tuple(a[i], i)); // return ref and 
index for simplicity

}
```


Re: How do you declare manifest constants?

2021-11-04 Thread Andrey Zherikov via Digitalmars-d-learn
On Thursday, 4 November 2021 at 17:09:31 UTC, Steven 
Schveighoffer wrote:

D doesn't have any equivalent for this.


Is it possible to add this feature having `-C VERSION="1.2.3"` 
(`-D` is already used) to be equal to `enum VERSION="1.2.3"` in 
global namespace?



The closest you can get is to turn on `version` identifiers.

There is also a quirky `-version=123` which is IMO, a 
completely useless feature.


I agree - this is useless. `-version myversion=123` would be much 
more useful.


Note, there is at least one dub package which does this for 
you: https://code.dlang.org/packages/gen-package-version


Unfortunately git/hg tags is not the only possible source of 
manifest constants.


How do you declare manifest constants?

2021-11-04 Thread Andrey Zherikov via Digitalmars-d-learn
I want to embed some info from build system - version info, for 
example. I can easily do this with C++ compiler by 
`-DVERSION="1.2.3"` but there is no such an option in dmd. So I'm 
wondering how do people workaround this?
I see only one way: generate a file and add it to the build (file 
might be `.d` source or something included by import expression).


Re: How to return a reference to structs?

2021-11-04 Thread Andrey Zherikov via Digitalmars-d-learn

On Thursday, 4 November 2021 at 13:03:54 UTC, Paul Backus wrote:

Have the lambda return by reference:

```d
auto get()
{
return idx.map!(ref (i) => a[i]);
}
```


That works, thanks!


How to return a reference to structs?

2021-11-04 Thread Andrey Zherikov via Digitalmars-d-learn

I have the following code example:

```d
struct A{}

A[5] a;
ulong[] idx = [1,3,4];

auto get()
{
return idx.map!(_ => a[_]);
}

foreach(i; 0 .. a.length)
write([i], " ");
writeln;

foreach(ref b; get())
write(, " ");
writeln;
```

How can I change `get` function so it returns the references to 
the content in `a`?


Is there a good documentation describing how to avoid copying of 
structs in the code?


Re: Does associative array change the location of values?

2021-10-30 Thread Andrey Zherikov via Digitalmars-d-learn

On Saturday, 30 October 2021 at 00:52:23 UTC, Imperatorn wrote:
On Saturday, 30 October 2021 at 00:49:04 UTC, Stanislav Blinov 
wrote:
On Friday, 29 October 2021 at 21:00:48 UTC, Steven 
Schveighoffer wrote:


This is incorrect, the buckets are each heap allocated. Just 
the array of bucket pointers would change.


In addition, AAs do not deallocate the key/value pairs ever. 
You are safe to obtain a pointer to a value and it will stay 
there, even if you remove the key.




Who's going to document these implementation details? ;) I 
mean, if no one, then the above shouldn't be stated. Wouldn't 
you agree?


Given the premise of the question at hand, it does seem useful 
to know these. But at least one should stress what is and 
isn't subject to change (even if unlikely).


This should be documented for sure


I did small test and it printed the same values three times so 
even rehash doesn't change the address of the value:


```d
long[long] aa = [0:0];
writeln([0]);
foreach(i; 0 .. 100_000_000)
aa[i]=i;
writeln([0]);
aa.rehash;
writeln([0]);
```

So it seems pretty safe to store a pointer to a value in AA. And 
I agree that this should definitely be documented.


Re: Does associative array change the location of values?

2021-10-29 Thread Andrey Zherikov via Digitalmars-d-learn

On Friday, 29 October 2021 at 17:58:24 UTC, Paul Backus wrote:
No, the AA does not guarantee that the value will remain in the 
same location. Inserting or removing *any* keys could cause the 
AA to resize, which may change the locations of all of its 
values.


However, you do not have to worry about undefined behavior, 
because the garbage collector will keep the "stale" copy of the 
value alive as long as you hold a pointer to it.


Thanks a lot for clarification


Does associative array change the location of values?

2021-10-29 Thread Andrey Zherikov via Digitalmars-d-learn
I want to have a pointer to a value in an associative array. Does 
AA guarantee that the value will remain at the same address all 
the time unless I remove the corresponding key? I couldn't find 
any guarantees similar to C++ iterator invalidation in D Language 
Reference.


Re: Cannot access frame pointer of a struct with member function

2021-05-09 Thread Andrey Zherikov via Digitalmars-d-learn

On Sunday, 9 May 2021 at 17:53:07 UTC, SealabJaster wrote:

On Sunday, 9 May 2021 at 17:37:40 UTC, Andrey Zherikov wrote:

Is this a bug?


My best guess is that, since the struct doesn't have any member 
functions the compiler has decided that the struct doesn't need 
any access to the main function's context/frame pointer, so the 
struct has implicitly become a `static struct`.


Marking the struct `static` yourself while keeping the member 
function, will show that it can then compile.


You can also move your `foo` function into the main function 
and it'll compile. Oddly the output ends up becoming: `T(1, 
null)` which I didn't really expect.


Just a guess though.


That's a point! Thanks you!


Cannot access frame pointer of a struct with member function

2021-05-09 Thread Andrey Zherikov via Digitalmars-d-learn

Compilation of this code:
```d
auto foo(T)()
{
return T();   // Error: cannot access frame pointer of 
`onlineapp.main.T`

}

void main()
{
struct T
{
int a=1;
void argsFunc(int a) {} // (1)
}

pragma(msg,foo!T());
}
```
fails with this error:
```
onlineapp.d(3): Error: cannot access frame pointer of 
`onlineapp.main.T`
onlineapp.d(14): Error: template instance `onlineapp.foo!(T)` 
error instantiating

onlineapp.d(14):while evaluating `pragma(msg, foo!(T)())`
```
But when I comment out argsFunc function on line (1), it compiles 
successfully meaning that there is no issue to access frame 
pointer.


Is this a bug?


  1   2   >