Re: container vs standard array

2023-09-19 Thread JG via Digitalmars-d-learn

On Tuesday, 19 September 2023 at 00:34:01 UTC, vino wrote:

Hi All,

 I am trying to understand as to why the below code is throwing 
error


Code
```
import std.stdio: writeln;
import std.container.array;

void main () {
 //auto a = Array!string("Aname");   // throws error
 auto b = Array!char("Bname");// works
 auto c = Array!string("Aname", "Bname");   // works

 //writeln(a);
 writeln("Container Array :", b);
 writeln("Container Array :", c);

 writeln();

 string[] d = ["Dname"]; // works
 string[] e = ["Dname", "Ename"];  // works
 writeln("Standard Array :", d);
 writeln("Standard Array :", e);

}
```
From,
Vino
Looks to me like when it receives a single range it expects the 
elements of that range to match the type. If I am correct in the 
first one if you replace the "Aname" by ["Aname"] it should work




Re: mutable pointers as associative array keys

2023-04-10 Thread JG via Digitalmars-d-learn

On Monday, 10 April 2023 at 18:14:56 UTC, John Colvin wrote:

It seems that it isn't possible, am I missing something?

alias Q = int[int*];
pragma(msg, Q); // int[const(int)*]

Also, is this documented somewhere?


It seems to be so (which is strange) and I can't image it is by 
design since you

can do this:

```d
static struct Pointer(T) { T* val; }
int[Pointer!int] f;
pragma(msg,typeof(f));
int* val = new int;
*val = 5;
f[Pointer!int(val)] = 12;
*val = 6;
f[Pointer!int(val)].writeln;  //12
```



Re: Is there a way to get the name of the current function?

2023-03-07 Thread JG via Digitalmars-d-learn

On Tuesday, 7 March 2023 at 22:11:49 UTC, rempas wrote:

For example, in the given code:

```d
void my_function() {
  import std.stdio;

  writeln("The name of the function is: ", 
);

}
```

Is there something to put in the place of 
`` to get the name of the function?


Yes, see here: 
https://dlang.org/spec/expression.html#specialkeywords


Re: Why not allow elementwise operations on tuples?

2023-01-18 Thread JG via Digitalmars-d-learn

On Monday, 16 January 2023 at 08:30:15 UTC, Sergei Nosov wrote:

On Friday, 13 January 2023 at 15:27:26 UTC, H. S. Teoh wrote:

[...]


Yeah, that's clear that such an implementation is rather 
straightforward. Although, I'm a bit confused with your 
implementation - 1. it doesn't seem to use tuples behind the 
scenes despite your claim (it uses static array) 2. `alias impl 
this;` introduces some unexpected interactions (e.g. `~` and 
`toString` are "intercepted" by the array implementation and 
yield "wrong" results).


Anyway, my original question was primarily about reasoning - 
why there's no implementation specifically for `std.Tuple`? If 
it's a "feature, not a bug" - what's the best way to provide an 
implementation on the client side?


I guess such a method wouldn't be particularly generic since a 
tuple does not need to consist of types that have the same 
operations e.g. Tuple!(int,string) etc


Re: "Little Scheme" and PL Design (Code Critique?)

2022-11-22 Thread JG via Digitalmars-d-learn
On Thursday, 17 November 2022 at 22:05:45 UTC, jwatson-CO-edu 
wrote:
I just pushed a D implementation of "[Little 
Scheme](https://mitpress.mit.edu/9780262560993/the-little-schemer/)", which is a limited educational version of [Scheme](https://en.wikipedia.org/wiki/Scheme_(programming_language)), to [GitHub](https://github.com/jwatson-CO-edu/SPARROW).


[...]


I think using the d garbage collector is a good idea. (I have 
written two implementations of scheme like languages one in c and 
one in d, and I found it a great pleasure not to have to write a 
GC for the d one). On the other hand if you want to write one 
there is no obstruction doing so in d.


Re: Find in assoc array then iterate

2022-10-21 Thread JG via Digitalmars-d-learn

On Friday, 21 October 2022 at 22:03:53 UTC, Kevin Bailey wrote:

I'm trying to do this equivalent C++:

unordered_map map;

for (auto i = map.find(something); i != map.end(); ++i)
...do something with i...

in D, but obviously with an associative array. It seems that 
it's quite
easy to iterate through the whole "map", but not start from the 
middle.

Am I missing something obvious (or not so obvious) ?


You can build a map using a red black tree.
Then you should be able to do what you want.

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




Re: C function taking two function pointers that share calculation

2022-09-14 Thread JG via Digitalmars-d-learn

On Wednesday, 14 September 2022 at 17:23:47 UTC, jmh530 wrote:
There is a C library I sometimes use that has a function that 
takes two function pointers. However, there are some 
calculations that are shared between the two functions that 
would get pointed to. I am hoping to only need to do these 
calculations once.


[...]


Maybe others know better but I would have thought the only way is 
to use globals to do this. Often c libraries that I have used get 
round this by taking a function and a pointer and then the 
library calls your function on the pointer simulating a d 
delegate.


Re: Casting rules

2022-08-27 Thread JG via Digitalmars-d-learn

On Friday, 26 August 2022 at 21:18:15 UTC, ag0aep6g wrote:

On Friday, 26 August 2022 at 20:42:07 UTC, JG wrote:

[...]


Casting immutable/const away: 
https://dlang.org/spec/const3.html#removing_with_cast


The cast itself allowed. Mutating the data is not.

Casting to immutable: 
https://dlang.org/spec/const3.html#creating_immutable_data


The cast is allowed as long as you don't mutate the data 
afterwards.


Conversion to const doesn't need a cast. Mutable and immutable 
both implicitly convert to const.



Thank you very much.


Casting rules

2022-08-26 Thread JG via Digitalmars-d-learn
Where can I find rules about casting. e.g. I assume casting away 
immutable is undefined behavior (or implementation defined 
behavior). What about casting to immutable (I would expect at 
most it only to be allowed if your type has no references e.g. 
ints okay but int[] not etc.) Casting const away (probably not 
allowed)? Casting to const (probably allowed).


Anyhow guessing aside where can I find the rules?




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

2022-08-22 Thread JG via Digitalmars-d-learn

On Monday, 22 August 2022 at 04:39:18 UTC, Andrey Zherikov wrote:

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?


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



Re: This code completely breaks the compiler:

2022-08-18 Thread JG via Digitalmars-d-learn
On Friday, 19 August 2022 at 03:13:03 UTC, Ruby The Roobster 
wrote:
On Friday, 19 August 2022 at 03:10:38 UTC, Ruby The Roobster 
wrote:
This snippet compiles.  Even if `dsds` and `sadsad` are 
defined nowhere, this code compiles.


[SNIP]

The reason why this compiles is because of the varidic 
template parameter, `Mtypes`.


Either there is something I'm missing, or the compiler 
completely breaks when it sees varidic template arguments.


The only way to get the code to not compile is to actually call 
the function.


I think it might help to post the entire code you think should 
not compile (which does). I guess you are aware that templated 
code is only "fully checked" when it is instantiated. E.g. this 
will compile.

```d
import std;

auto nonsense(T)(T t) {
return 5+"six";
}

void main() {
}
```





Re: Better way to achieve the following

2022-06-21 Thread JG via Digitalmars-d-learn
On Tuesday, 21 June 2022 at 17:15:02 UTC, Steven Schveighoffer 
wrote:

On 6/21/22 1:09 PM, JG wrote:

Thoughts?


Use a pointer? Especially if you are using `.method` calls, 
this just works seamlessly.


-Steve


Thanks for the suggestion.  My immediate reaction is that for 
`.method` calls I would agree, but for assignments it is slightly 
less pleasant. Perhaps it is the best option.


Better way to achieve the following

2022-06-21 Thread JG via Digitalmars-d-learn

Suppose we are often writing something like
```d
theFirstName[theFirstIndex].theSecondName[theSecondIndex].thirdName[theThirdIndex]=x;
```
One would like to something like
```d
alias shortName = 
theFirstName[theFirstIndex].theSecondName[theSecondIndex].thirdName[theThirdIndex];

shortName = x;
```
but you can't alias an expression.

You can do
```d
(ref shortName) {
 shortName = x;

}(theFirstName[theFirstIndex].theSecondName[theSecondIndex].thirdName[theThirdIndex]);
```
but that doesn't read well since the ``definition'' of shortName 
comes at the end.


Another option is
```d
auto aliasAs(alias f,T)(ref T x) { return f(x); }

theFirstName[theFirstIndex].theSecondName[theSecondIndex].thirdName[theThirdIndex].aliasAs!
(ref shorName) {
 shortName = x;
}
```

Thoughts?


Re: Failure due to memcpy being called at compile time

2022-06-20 Thread JG via Digitalmars-d-learn

On Tuesday, 21 June 2022 at 01:39:43 UTC, Paul Backus wrote:

On Tuesday, 14 June 2022 at 05:35:46 UTC, JG wrote:

On Monday, 13 June 2022 at 21:45:39 UTC, Paul Backus wrote:

The call to `move` is coming from `SumType.opAssign`:

https://github.com/dlang/phobos/blob/v2.100.0/std/sumtype.d#L681

I've filed a bugzilla issue for this here:

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


Thanks, for doing this.


Update: a new release of [the `sumtype` package on 
code.dlang.org][1] is available that includes the fix for this 
bug.


`std.sumtype` will be fixed in the next Phobos release, 2.100.1.

[1]: https://code.dlang.org/packages/sumtype


That is great. Is this a work around the CFE bug?


Re: Whats the proper way to write a Range next function

2022-06-15 Thread JG via Digitalmars-d-learn

On Wednesday, 15 June 2022 at 17:30:31 UTC, JG wrote:
On Wednesday, 15 June 2022 at 13:52:24 UTC, Christian Köstlin 
wrote:

the naive version would look like

```d
auto next(Range)(Range r) {
r.popFront;
return r.front;
}
```

But looking at a mature library e.g. 
https://github.com/submada/btl/blob/9cc599fd8495215d346ccd62d6e9f1f7ac140937/source/btl/vector/package.d#L229 is looks like there should be tons of annotations/attributes on it.


Kind regards,
Christian


I not sure of your use case. But you need to check if the range 
is empty before and after calling popFront (and decide what to 
if it is). Also unless you want the original range passed in 
mutated you should call save (assuming you have a forward 
range) before calling your next or you need to modify next so 
it calls save.


This is what I would write for next (which should only be called 
after

checking if the range is empty).

It produces a range whose front points at the next element.
```d
auto next(Range)(Range r) {
  auto ret = r.save;
  ret.popFront;
  return ret;
}
```


Re: Whats the proper way to write a Range next function

2022-06-15 Thread JG via Digitalmars-d-learn
On Wednesday, 15 June 2022 at 13:52:24 UTC, Christian Köstlin 
wrote:

the naive version would look like

```d
auto next(Range)(Range r) {
r.popFront;
return r.front;
}
```

But looking at a mature library e.g. 
https://github.com/submada/btl/blob/9cc599fd8495215d346ccd62d6e9f1f7ac140937/source/btl/vector/package.d#L229 is looks like there should be tons of annotations/attributes on it.


Kind regards,
Christian


I not sure of your use case. But you need to check if the range 
is empty before and after calling popFront (and decide what to if 
it is). Also unless you want the original range passed in mutated 
you should call save (assuming you have a forward range) before 
calling your next or you need to modify next so it calls save.


Re: Bug in dmd?

2022-06-15 Thread JG via Digitalmars-d-learn

On Tuesday, 14 June 2022 at 23:56:58 UTC, Andrey Zherikov wrote:

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.


I tried to reproduce it but wasn't able (I guess it is some 
interplay with the rest of your code):

```d
import std.sumtype;



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);
}

struct CommandArguments(T) {
T x;
}
struct Config {}

void main() {
string test;
Config config;
CommandArguments!int commandArguments;
printHelp!(int,string)(test,commandArguments,config);
}
```




Re: Bug?

2022-06-15 Thread JG via Digitalmars-d-learn
On Tuesday, 14 June 2022 at 19:49:39 UTC, Steven Schveighoffer 
wrote:

On 6/14/22 3:35 PM, JG wrote:

Hi,

Is this a bug?
```d
import std;

template test(alias f) {

     auto test(I)(I i) { return f(i); }
}

void main()
{
     alias t = test!(x=>x+1);
     1.t.writeln; //<--Doesn't compile
     1.test!(x=>x+1).writeln;
     t(1).writeln;
}
```


Not a bug. Local symbols can't be used as UFCS functions.

-Steve


Thanks very much. I left wondering why that design decision was 
made.


Bug?

2022-06-14 Thread JG via Digitalmars-d-learn

Hi,

Is this a bug?
```d
import std;

template test(alias f) {

auto test(I)(I i) { return f(i); }
}

void main()
{
alias t = test!(x=>x+1);
1.t.writeln; //<--Doesn't compile
1.test!(x=>x+1).writeln;
t(1).writeln;
}
```


Re: Failure due to memcpy being called at compile time

2022-06-13 Thread JG via Digitalmars-d-learn

On Monday, 13 June 2022 at 21:45:39 UTC, Paul Backus wrote:

On Monday, 13 June 2022 at 19:48:06 UTC, JG wrote:

Hi,

I reduced my code to the following.  Could anyone help me to 
discover why the line marked with //THIS LINE


causes memcpy to be called, and how can I avoid this?


Reduced further:

```d
import std.sumtype;

struct Tuple
{
void opAssign(Tuple rhs) {}
}

alias ParseErrorOr = SumType!Tuple;

auto parserOr() {
ParseErrorOr cur;
cur = ParseErrorOr(Tuple());
return cur;
}

void main()
{
enum a = parserOr();
}
```

The call to `move` is coming from `SumType.opAssign`:

https://github.com/dlang/phobos/blob/v2.100.0/std/sumtype.d#L681

I've filed a bugzilla issue for this here:

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


Thanks, for doing this.


Re: Failure due to memcpy being called at compile time

2022-06-13 Thread JG via Digitalmars-d-learn
On Monday, 13 June 2022 at 20:25:00 UTC, Steven Schveighoffer 
wrote:

On 6/13/22 4:09 PM, JG wrote:
Thanks. It seems to be something to do with the variadic 
template since this

works:

```d
import std;

struct ParseError { string msg; }

alias ParseErrorOr(T) = SumType!(ParseError,T);
auto parseErrorOr(T)(T x) { return ParseErrorOr!T(x); }

auto parserOr(I,alias f, alias g)(I i) {
   auto cur = f(i);
   if(cur.match!((ParseError e)=>false,_=>true)) { return cur; 
}

   return g(i);
}

auto parseNothing(I)(I i) {
     return parseErrorOr(tuple(i[0..0],i));
}

void main()
{
     enum a = 
parserOr!(string,parseNothing!string,parseNothing!string)("hello");

}
```


Given that it's inside `moveEmplace`, I'd suspect something 
deep in `SumType`.


-Steve


Really strange. I can also work around it like this:

```d
auto parserOr(I,fs...)(I i) if(fs.length>=2) {
  auto cur = fs[0](i);
  if(cur.match!((ParseError e)=>false,_=>true)) { return cur; 
}

  static if(fs.length==2) { return fs[1](i); }
  else { return parserOr!(I,fs[1..$])(i); }
}
```


Re: Failure due to memcpy being called at compile time

2022-06-13 Thread JG via Digitalmars-d-learn
On Monday, 13 June 2022 at 19:59:16 UTC, Steven Schveighoffer 
wrote:

On 6/13/22 3:48 PM, JG wrote:

Hi,

I reduced my code to the following.  Could anyone help me to 
discover why the line marked with //THIS LINE


causes memcpy to be called, and how can I avoid this?


```d
import std;

struct ParseError { string msg; }

alias ParseErrorOr(T) = SumType!(ParseError,T);
auto parseErrorOr(T)(T x) { return ParseErrorOr!T(x); }

auto parserOr(I,fs...)(I i) {
   alias RetType = typeof(fs[0](I.init));
   auto cur = RetType(ParseError.init);
   foreach(f;fs) {
     if(cur.match!((ParseError e)=>false,_=>true)) { return 
cur; }

     cur = f(i); //THIS LINE
   }
   return cur;
}

auto parseNothing(I)(I i) {
     return parseErrorOr(tuple(i[0..0],i));
}

void main()
{
     enum a = 
parserOr!(string,parseNothing!string,parseNothing!string)("hello");

}
```





Happens in `moveEmplaceImpl` in `core.lifetime`. Somebody is 
calling that.


https://github.com/dlang/druntime/blob/v2.099.1/src/core/lifetime.d#L2192

No stack trace though, that would actually be nice to have in 
the CTFE interpreter.


I imagine if you solved that call, you would get out to a place 
where it tries to cast to the actual type and fail there 
instead.


-Steve


Thanks. It seems to be something to do with the variadic template 
since this

works:

```d
import std;

struct ParseError { string msg; }

alias ParseErrorOr(T) = SumType!(ParseError,T);
auto parseErrorOr(T)(T x) { return ParseErrorOr!T(x); }

auto parserOr(I,alias f, alias g)(I i) {
  auto cur = f(i);
  if(cur.match!((ParseError e)=>false,_=>true)) { return cur; }
  return g(i);
}

auto parseNothing(I)(I i) {
return parseErrorOr(tuple(i[0..0],i));
}

void main()
{
enum a = 
parserOr!(string,parseNothing!string,parseNothing!string)("hello");

}
```


Failure due to memcpy being called at compile time

2022-06-13 Thread JG via Digitalmars-d-learn

Hi,

I reduced my code to the following.  Could anyone help me to 
discover why the line marked with //THIS LINE


causes memcpy to be called, and how can I avoid this?


```d
import std;

struct ParseError { string msg; }

alias ParseErrorOr(T) = SumType!(ParseError,T);
auto parseErrorOr(T)(T x) { return ParseErrorOr!T(x); }

auto parserOr(I,fs...)(I i) {
  alias RetType = typeof(fs[0](I.init));
  auto cur = RetType(ParseError.init);
  foreach(f;fs) {
if(cur.match!((ParseError e)=>false,_=>true)) { return cur; }
cur = f(i); //THIS LINE
  }
  return cur;
}

auto parseNothing(I)(I i) {
return parseErrorOr(tuple(i[0..0],i));
}

void main()
{
enum a = 
parserOr!(string,parseNothing!string,parseNothing!string)("hello");

}
```





Re: Generating unique identifiers at compile time

2022-06-12 Thread JG via Digitalmars-d-learn

On Sunday, 12 June 2022 at 18:45:27 UTC, Paul Backus wrote:

On Thursday, 9 June 2022 at 21:20:27 UTC, JG wrote:

[...]

[...]

[...]


Here's a `gensym` implementation I came up with a while back:

```d
enum gensym = q{"_gensym" ~ __traits(identifier, 
{})["__lambda".length .. $]};


// Works multiple times on the same line
pragma(msg, mixin(gensym)); pragma(msg, mixin(gensym));
```

This takes advantage of the fact that the compiler generates a 
unique identifier for every lambda function it encounters. 
While you can't actually use those identifiers in your code, 
they are visible in error messages and can be accessed via 
`__traits(identifier)`.


Hi,

This is great thanks.



Re: Generating unique identifiers at compile time

2022-06-12 Thread JG via Digitalmars-d-learn

On Friday, 10 June 2022 at 06:17:54 UTC, bauss wrote:

On Thursday, 9 June 2022 at 23:50:10 UTC, user1234 wrote:


There's [been attempts] to expose it, exactly so that users 
can generate unique names, but that did not found its path in 
the compiler.


[been attempts]: https://github.com/dlang/dmd/pull/10131


You can generate unique names actually by using CTFE RNG, so 
it's not really necessary to have it exposed to achieve that.


See my hacky example of hidden class members here:

https://forum.dlang.org/thread/siczwzlbpikwlevvi...@forum.dlang.org


Thanks for the answers. In my particular I found a way to generate
a new depending on the the left hand side.


Generating unique identifiers at compile time

2022-06-09 Thread JG via Digitalmars-d-learn

Hi,

As an experiment I have implemented the following kind of pattern 
matching

(by parsing the part of the string before '=').

```d
struct S {
int x;
int y;
}

struct T {
int w;
S s;
}
void main()
{
mixin(matchAssign(q{auto T(first,S(second,third)) = 
T(1,S(2,3));}));

first.writeln;  // 1
second.writeln; // 2
third.writeln;  // 3
}
```
In doing so I wanted to produce unique identifiers (something 
like gensym in racket.) I did this in a very hacky way:


```d
auto hopefullyUniqueName(size_t n, size_t line=__LINE__) {
return 
format!"var___%s%s"(n,line);

}
```

where I pass in the hash of the right hand side in the assignment 
in place of n.


Is there some way to ask the compiler for a unique name or a 
better way of achieving this?







Re: static assert("nothing")

2022-05-31 Thread JG via Digitalmars-d-learn

On Tuesday, 31 May 2022 at 08:51:45 UTC, realhet wrote:

Hi,

In my framework I just found a dozen of compile time error 
handling like:


...else static assert("Invalid type");

This compiles without error. And it was useless for detecting 
errors because I forgot the first "false" or "0" parameter.


I think it is because of the weird case of "every string casted 
to bool is true".


There is an example in Phobos also:  
https://github.com/dlang/phobos/blob/master/std/uni/package.d

at line 8847: static assert("Unknown normalization form "~norm);

It is easy to make this mistake, but does static assert(string) 
has any meaningful use cases?


I was going to suggest to do something like:

```d
import std;

string compileError(string msg) {
  import std.format;
  return format("static assert(0,%(%s%));",[msg]);
}

auto doGreatThings(T)(T x)
{
static if(is(T==int))
{
return "great things!";
}
else mixin(compileError("Invalid type."));
}

void main()
{
   doGreatThings!int(123).writeln;
   doGreatThings!string("oh dear").writeln;
}
```

But (a) why should you need to and (b) this makes the message 
more obscure.


onlineapp.d-mixin-14(14): Error: static assert:  "Invalid type."
onlineapp.d(20):instantiated from here: 
`doGreatThings!string`


Bug?

2022-05-26 Thread JG via Digitalmars-d-learn

Hi,

I was reading the source of std.algorithm cache and saw some code 
that didn't make sense to me with a comment indexing the [bug 
report](https://issues.dlang.org/show_bug.cgi?id=15891). Could 
anyone help to understand if this code is really necessary 
(meaning I have some misconception) or is it a work around a 
compiler bug. Here is the code simplified down as much as I could:


```d
import std.range.primitives;
import std.traits;


struct _Cache(R)
{
private
{
alias UE = Unqual!(ElementType!R);
R source;
UE caches;
}

this(R range)
{
source = range;
if (!range.empty)
{
caches = source.front;
}/*  else {  //Uncomment "else" to fix broken version 
(see below)

   caches = UE.init;
}*/
}
}

struct _ConstructorlessCache(R) {
private
{
alias UE = Unqual!(ElementType!R);
R source;
UE caches;
}
}

auto constructorlessCache(Range)(Range range) {
auto ret = _ConstructorlessCache!Range(range);
if (!range.empty)
{
ret.caches = range.front;
}
return ret;
}

auto cache(Range)(Range range) {
return _Cache!(Range)(range);
}

auto map(alias fun, Range)(Range range) {
return MapResult!(fun,Range)(range);
}


struct MapResult(alias fun, Range)
{
alias R = Unqual!Range;
R _input;

bool empty() { return _input.empty; }

auto ref front() { return fun(_input.front); }
}


void main() {
/* Won't compile unless part near top is uncommented. Gives:
onlineapp.d(21): Error: one path skips field `caches`
onlineapp.d(75): Error: template instance 
`onlineapp.cache!(MapResult!(__lambda1, int[]))` error 
instantiating

*/
//[1].map!(x=>[x].map!(y=>y)).cache;
//What seems to be essentially the same code compiles fine
[1].map!(x=>[x].map!(y=>y)).constructorlessCache;
}

```


Re: Allocate a string via the GC

2022-05-23 Thread JG via Digitalmars-d-learn

On Monday, 23 May 2022 at 11:39:22 UTC, Adam D Ruppe wrote:

On Monday, 23 May 2022 at 09:38:07 UTC, JG wrote:

Hi,

Is there any more standard way to achieve something to the 
effect of:


```d
  import std.experimental.allocator;
  string* name = theAllocator.make!string;
 ```


Why do you want that?

Easiest way I know of is to just wrap it in a struct, then `new 
that_struct`, which is also a better way for all the use cases 
I know but those use cases are pretty rare so there's 
probably a better way to do what you're trying to do.


I am writing an interpreter and I needed access to a string via
a pointer of type void*

I ended up wrapping it in a struct since I needed another value
anyway. Seems odd that one can't do it in a less unusual way.

Thanks.


Allocate a string via the GC

2022-05-23 Thread JG via Digitalmars-d-learn

Hi,

Is there any more standard way to achieve something to the effect 
of:


```d
  import std.experimental.allocator;
  string* name = theAllocator.make!string;
 ```



Re: Question on shapes

2022-05-18 Thread JG via Digitalmars-d-learn

On Tuesday, 17 May 2022 at 00:10:55 UTC, Alain De Vos wrote:
Let's say a shape is ,a circle with a radius ,or a square with 
a rectangular size.
I want to pass shapes to functions, eg to draw them on the 
screen,

draw(myshape) or myshape.draw();
But how do i implement best shapes ?


You could also do something like:
```d
import std;

struct Circle {
double radius;
void draw() {
writeln(format!"Draw a circle of radius %s"(radius));
}
}

struct Rectangle {
double width;
double height;
 void draw() {
writeln(format!"Draw a rectangle of width %s and height 
%s."(width,height));

}
}

alias Shape = SumType!(Circle,Rectangle);


void main() {
  Shape[] shapes = [Shape(Rectangle(2.0,3.)),Shape(Circle(3.0))];

  foreach(shape; shapes) { shape.match!(x=>x.draw); }
}
```

or

```d
import std;

struct Circle {
double radius;
}

struct Rectangle {
double width;
double height;
}

alias Shape = SumType!(Circle,Rectangle);

struct Drawer {
int drawerState;
void drawShape(Shape shape) {
shape.match!(x=>drawShape(x));
}
void drawShape(Circle circle) {
writeln(format!"Draw a circle of radius 
%s"(circle.radius));

}
void drawShape(Rectangle rectangle) {
writeln(format!"Draw a rectangle of width %s and height 
%s."(rectangle.width,rectangle.height));

}
}

void main() {
  Shape[] shapes = [Shape(Rectangle(2.0,3.)),Shape(Circle(3.0))];
  Drawer d;
  foreach(shape; shapes) { d.drawShape(shape); }
}
```




Re: What am I doing wrong here?

2022-05-08 Thread JG via Digitalmars-d-learn

On Saturday, 7 May 2022 at 02:29:59 UTC, Salih Dincer wrote:

On Friday, 6 May 2022 at 18:04:13 UTC, JG wrote:

```d
//...
struct Adder {
int a;
int opCall(int b) { return a+b; }
}
auto adder(int a) {
auto ret = Adder.init;
ret.a=a;
return ret;
}

void main() {
auto g = adder(5);
g(5).writeln; // 10
auto d = toDelegate!(int, int)(g);
d(5).writeln; // 10
// ...
}
```


The value returned by the delegate structure in the above line 
is 10. Its parameter is 5, but if you do it to 21, you will get 
42. So it doesn't have the ability to delegate Adder.


In summary, the sum function isn't executing.  Instead, its 
value gets double.


SDB@79


What do you mean?

```d
import std;

struct Delegate(A,B) {
B function(void* ptr, A a) f;
void* data;
B opCall(A a) {
return f(data,a);
}
}

auto toDelegate(A, B,S)(ref S s) {
static B f(void* ptr, A a) {
return (*(cast(S*) ptr))(a);
}
Delegate!(A,B) ret;
ret.f=
ret.data= cast(void*) 
return ret;
}

struct Adder {
int a;
int opCall(int b) { return a+b; }
}
auto adder(int a) {
auto ret = Adder.init;
ret.a=a;
return ret;
}

void main() {
auto g = adder(5);
g(5).writeln;
auto d = toDelegate!(int, int)(g);
d(41).writeln;
auto a =7;
auto h = (int b)=>a+b;
auto d1 = toDelegate!(int,int)(h);
void* ptr = cast(void*) 
(*cast(int delegate(int)*) ptr)(10).writeln;
d1(21).writeln;
h(32).writeln;
}
```
Output:
10
46
17
28
39

Which is what is expected.




Re: What am I doing wrong here?

2022-05-06 Thread JG via Digitalmars-d-learn

On Friday, 6 May 2022 at 18:35:40 UTC, Ali Çehreli wrote:

On 5/6/22 11:04, JG wrote:
> [...]

This is a segmentation fault. Reduced:

import std;

[...]


Hi, thanks. That was quite silly. (I was thinking the variable 
lives to the end of  scope of main but not thinking about that I 
am passing by value).


What am I doing wrong here?

2022-05-06 Thread JG via Digitalmars-d-learn

This isn't code to be used for anything (just understanding).
```d
import std;

struct Delegate(A,B) {
B function(void* ptr, A a) f;
void* data;
B opCall(A a) {
return f(data,a);
}
}

auto toDelegate(A, B,S)(S s) {
static B f(void* ptr, A a) {
return (*(cast(S*) ptr))(a);
}
Delegate!(A,B) ret;
ret.f=
ret.data= cast(void*) 
return ret;
}

struct Adder {
int a;
int opCall(int b) { return a+b; }
}
auto adder(int a) {
auto ret = Adder.init;
ret.a=a;
return ret;
}

void main() {
auto g = adder(5);
g(5).writeln;
auto d = toDelegate!(int, int)(g);
d(5).writeln;
auto a =7;
auto h = (int b)=>a+b;
auto d1 = toDelegate!(int,int)(h);
void* ptr = cast(void*) 
(*cast(int delegate(int)*) ptr)(10).writeln;
d1(10).writeln;
h(10).writeln;
}
```



String Literals

2022-05-03 Thread JG via Digitalmars-d-learn

Hi,

The specification of string literals has either some errors or I 
don't understand what is meant by a Character.


For instance we have:

WysiwygString:
r" WysiwygCharacters_opt " StringPostfix_opt

WysiwygCharacters:
WysiwygCharacter
WysiwygCharacter WysiwygCharacters

WysiwygCharacter:
Character
EndOfLine

Character:
any Unicode character

Which to me means that e.g.
r"""
should be a WysiwygString, which the compiler thinks is not (not 
surprisingly).


Am I misunderstanding something?


Re: Parameters declared as the alias of a template won't accept the arguments of the same type.

2022-05-02 Thread JG via Digitalmars-d-learn

On Monday, 2 May 2022 at 19:17:19 UTC, Stanislav Blinov wrote:

On Monday, 2 May 2022 at 16:29:05 UTC, Loara wrote:

Template deduction for aliased function parameter is a very 
tricky argument and it's not so simple to handle in certain 
cases. Consider for example this code:


```d
template MyAlias(T){
  alias MyAlias = int;
}

T simp(T)(MyAlias!T val){
  return T.init;
}

int main(){
  simp(3);//Impossible to deduce T


Why? That's the issue. It is very possible to deduce T here. 
Compiler just isn't trying. The function takes an int. Doesn't 
take a rocket scientist to figure that one out.


Maybe I am being silly, but it isn't possible to determine T 
here. Independent of what T is the input parameter would be an 
int (which the compiler can't see but we can) but the output 
depends on T which can't be deduced.


Re: Parameters declared as the alias of a template won't accept the arguments of the same type.

2022-05-02 Thread JG via Digitalmars-d-learn

On Monday, 2 May 2022 at 16:29:05 UTC, Loara wrote:

On Sunday, 1 May 2022 at 03:57:12 UTC, Elfstone wrote:

[...]


Template deduction for aliased function parameter is a very 
tricky argument and it's not so simple to handle in certain 
cases. Consider for example this code:


```d
template MyAlias(T){
  alias MyAlias = int;
}

T simp(T)(MyAlias!T val){
  return T.init;
}

int main(){
  simp(3);//Impossible to deduce T
  simp( cast(MyAlias!string) 4);//Also invalid since 
MyAlias!string is exactly int

  simp!string(4);//Ok, no parameter deduction
}
```



I don't really see what your example is trying to show. This also 
doesn't work,

and in my mind should be equivalent:
```d
T simp(T)(int val) {
return T.init;
}

int main() {
simp(3);//Impossible to deduce T
}
```


Re: Parameters declared as the alias of a template won't accept the arguments of the same type.

2022-05-01 Thread JG via Digitalmars-d-learn

On Sunday, 1 May 2022 at 11:34:49 UTC, JG wrote:

On Sunday, 1 May 2022 at 07:59:57 UTC, Elfstone wrote:

On Sunday, 1 May 2022 at 06:42:26 UTC, Tejas wrote:

[...]


Thanks a lot! So this really is a D "feature".
The current behaviour is so broken. It makes no sense, for a 
language user at least.
I don't understand why it's not yet solved, if it's a known 
issue.


I guess the current best is something like:

```d
enum isVector(V) = is(V==MatrixImpl!(S,1,N),S,size_t N);

@nogc
auto dot1(V)(in V lhs, in V rhs)
if(isVector!V) {
return dot2(lhs,rhs);
}
```

or

```d
enum isVector(V) = is(V==MatrixImpl!(S,1,N),S,size_t N);

@nogc
auto dot1(V)(in V lhs, in V rhs)
if(isVector!V) {
static if(is(V==MatrixImpl!(S,1,N),S,N)) { S ret=0; return 
ret; }

static assert("This should never been shown");
}
```


The static assert isn't needed.


```d
enum isVector(V) = is(V==MatrixImpl!(S,1,N),S,size_t N);

@nogc
auto dot1(V)(in V lhs, in V rhs)
if(isVector!V) {
 static if(is(V==MatrixImpl!(S,1,N),S,N)) { S ret=0; return 
ret; }

}
```



Re: Parameters declared as the alias of a template won't accept the arguments of the same type.

2022-05-01 Thread JG via Digitalmars-d-learn

On Sunday, 1 May 2022 at 07:59:57 UTC, Elfstone wrote:

On Sunday, 1 May 2022 at 06:42:26 UTC, Tejas wrote:

On Sunday, 1 May 2022 at 03:57:12 UTC, Elfstone wrote:

module test;

struct MatrixImpl(S, size_t M, size_t N)
{
}

[...]


AFAICT, I'm afraid you'll have to stick to `dot2` 


This DIP I believe does what you want but... It wasn't looked 
upon favorably...


https://github.com/dlang/DIPs/blob/master/DIPs/other/DIP1023.md


Thanks a lot! So this really is a D "feature".
The current behaviour is so broken. It makes no sense, for a 
language user at least.
I don't understand why it's not yet solved, if it's a known 
issue.


I guess the current best is something like:

```d
enum isVector(V) = is(V==MatrixImpl!(S,1,N),S,size_t N);

@nogc
auto dot1(V)(in V lhs, in V rhs)
if(isVector!V) {
return dot2(lhs,rhs);
}
```

or

```d
enum isVector(V) = is(V==MatrixImpl!(S,1,N),S,size_t N);

@nogc
auto dot1(V)(in V lhs, in V rhs)
if(isVector!V) {
static if(is(V==MatrixImpl!(S,1,N),S,N)) { S ret=0; return 
ret; }

static assert("This should never been shown");
}
```





Re: Reference counting example

2022-04-26 Thread JG via Digitalmars-d-learn

On Tuesday, 26 April 2022 at 06:55:34 UTC, Alain De Vos wrote:
Can someone provide a simple/very simple reference counting or 
refcounted example i can understand. Thanks.


I suggest to look at RefCounted 
[here](https://code.dlang.org/packages/automem) rather than in 
Phobos. There are simple examples.


Re: Understanding alias template parameters

2022-04-22 Thread JG via Digitalmars-d-learn

On Thursday, 21 April 2022 at 21:02:47 UTC, JG wrote:

Hi,

Could someone possibly help me to understand why the commented 
line doesn't compile?



```d
import std;

struct MapResult(R,F)
{
R r;
const F f;
auto empty() { return r.empty; }
auto front() { return f(r.front); }
void popFront() { r.popFront; }
auto save() { return typeof(this)(r.save,f); }
}

auto myMap(alias f, R)(R r) {
return MapResult!(R,typeof(f))(r,f);
}


void main()
{
   int function(int) f = x=>2*x;
   iota(10).myMap!f.writeln;
   //iota(10).myMap!(x=>2*x).writeln; <--- Why doesn't this 
compile?


}
```

(I do know that Phobos's map works differently with better 
performance).



Thank you to all for the great replies. To fix it one could do:

```d
import std;

struct MapResult(R,F) {
R r;
const F f;
auto empty() { return r.empty; }
auto front() { return f(r.front); }
void popFront() { r.popFront; }
auto save() { return typeof(this)(r.save,f); }
}

auto myMap(alias f, R)(R r) {
static if(__traits(compiles,f!(typeof(R.init.front {
auto fun = f!(typeof(R.init.front));
return MapResult!(R,typeof(fun))(r,fun);
} else {
return MapResult!(R,typeof(f))(r,f);
}
}


void main()
{
   int function(int) f = x=>2*x;
   iota(10).myMap!f.writeln;
   iota(10).myMap!(x=>2*x).writeln;

}
```

In response to the change to "alias", which has several upsides
including faster code. I would note it also has some downsides 
including
every lambda produces a new type so that (at the moment) the 
following assert

holds:
```d
auto r = iota(10).map!(x=>x+1);
auto s = iota(10).map!(x=>x+1);
assert(!is(typeof(r)==typeof(s)));
```


Understanding alias template parameters

2022-04-21 Thread JG via Digitalmars-d-learn

Hi,

Could someone possibly help me to understand why the commented 
line doesn't compile?



```d
import std;

struct MapResult(R,F)
{
R r;
const F f;
auto empty() { return r.empty; }
auto front() { return f(r.front); }
void popFront() { r.popFront; }
auto save() { return typeof(this)(r.save,f); }
}

auto myMap(alias f, R)(R r) {
return MapResult!(R,typeof(f))(r,f);
}


void main()
{
   int function(int) f = x=>2*x;
   iota(10).myMap!f.writeln;
   //iota(10).myMap!(x=>2*x).writeln; <--- Why doesn't this 
compile?


}
```

(I do know that Phobos's map works differently with better 
performance).


Re: Lambda Tuple with Map Reduce

2022-04-20 Thread JG via Digitalmars-d-learn

On Wednesday, 20 April 2022 at 08:04:42 UTC, Salih Dincer wrote:

```d
alias type = real;
alias func = type function(type a);

[...]


I think technically you should have save after range in that loop.


Re: RefCounted

2022-04-15 Thread JG via Digitalmars-d-learn

On Wednesday, 13 April 2022 at 20:47:33 UTC, JG wrote:

Hi,

I would have thought that RefCounted!(T, 
RefCountedAutoInitialize.no) is to be used in place T* when I 
want reference counting instead of the usual garbage collection 
(or manual allocation). Perhaps this is wrong?


[...]


In case some one has a similar problem, try: 
https://code.dlang.org/packages/automem


```
import std.stdio;
import std.experimental.allocator.mallocator;
import std.experimental.allocator;
import automem;

struct Node(T) {
  RefCounted!(Node!T) next;
  T val;
}

struct List(T) {
  RefCounted!(Node!T) head;
  bool empty() { return head == null; }
  T front() { return head.val; }
  void popFront() { head = head.next; }
  typeof(this) save() { return typeof(this)(head); }
  void insert(T x) {
head = RefCounted!(Node!T)(head,x);
  }
}

void main() {
  theAllocator = allocatorObject(Mallocator.instance);
  List!long l;
  l.insert(5);
  l.insert(4);
  l.insert(3);
  l.insert(2);
  l.insert(1);
  writeln(l);
}
```


Re: RefCounted

2022-04-13 Thread JG via Digitalmars-d-learn

On Wednesday, 13 April 2022 at 20:47:33 UTC, JG wrote:

Hi,

I would have thought that RefCounted!(T, 
RefCountedAutoInitialize.no) is to be used in place T* when I 
want reference counting instead of the usual garbage collection 
(or manual allocation). Perhaps this is wrong?


[...]


Perhaps I should have added in case it is relevant, I am not 
actually interested in building lists. I eventually want to use 
this in a "persistent" version of a red black tree (where if r is 
such a tree and we set r1=r.insert(x) then r is unaffected and r1 
has the new element inserted - but they share most nodes). This 
data structure is to be used in a multithreaded application 
searching for a solution to some problem. The current version has 
bad performance seemingly due to gc stopping all threads while 
freeing unused nodes.


RefCounted

2022-04-13 Thread JG via Digitalmars-d-learn

Hi,

I would have thought that RefCounted!(T, 
RefCountedAutoInitialize.no) is to be used in place T* when I 
want reference counting instead of the usual garbage collection 
(or manual allocation). Perhaps this is wrong?


If I am correct what am I doing wrong here?

(Sorry for two space squashed style).

```
import std.stdio;
import std.typecons;

struct Node(T) {
  RefCounted!(Node!T, RefCountedAutoInitialize.no) next;
  T val;
}

struct List(T) {
  RefCounted!(Node!T, RefCountedAutoInitialize.no) head;
  bool empty() { return head.refCountedStore.isInitialized; }
  T front() { return head.val; }
  void popFront() { head = head.next; }
  typeof(this) save() { return typeof(this)(head); }
}

void main() {
  List!long l;
}
```
I also tried my own implementation but that is not working (since 
not everything is being freed) and probably
relies on undefined behavior with my casting away inout, which I 
did because
otherwise the compiler kept giving me errors about not being able 
to generate a copy constructor for List.


```
import std.stdio;
import core.stdc.stdlib;


private struct RefCountedPointer(T) {
  static struct Payload(T) {
long cnt=1;
T val;
  }
  Payload!T* ptr;
  this(T x) {
ptr = cast(Payload!T*) calloc(0,Payload!T.sizeof);
*ptr = Payload!T(1,x);
  }
  ~this() {
if(ptr==null) { return; }
(*ptr).cnt--;
if((*ptr).cnt == 0) {
  ptr.val.destroy();
  free(ptr);
}
  }
  @disable this(ref return scope immutable(typeof(this)) rhs);
  this(ref return scope inout(typeof(this)) rhs) {
ptr = cast(Payload!T*) rhs.ptr;
if(ptr==null) { return; }
ptr.cnt++;
  }
  void opAssign(typeof(this) rhs) {
if(this.ptr!=null) { (*this.ptr).cnt--; }
this.ptr = rhs.ptr;
if(this.ptr!=null) { (*this.ptr).cnt++; }
  }
  bool isNull() { return ptr==null; }
  ref auto dref() { assert(!isNull); return (*ptr).val; }
}

private struct Node(T) {
  RefCountedPointer!(Node!T) next;
  T val;
}


struct List(T) {
  private RefCountedPointer!(Node!T) head;
  bool empty() { return head.isNull; }
  T front() { return head.dref.val; }
  void popFront()  { head = head.dref.next;  }
  auto save() { return typeof(this)(head); }
  auto insert(T x) {
head = RefCountedPointer!(Node!T)(Node!T(head,x));
  }
}

void main() {
  List!long list;
  list.insert(8);
import std.stdio;
import core.stdc.stdlib;


private struct RefCountedPointer(T) {
  static struct Payload(T) {
long cnt=1;
T val;
  }
  Payload!T* ptr;
  this(T x) {
ptr = cast(Payload!T*) calloc(0,Payload!T.sizeof);
*ptr = Payload!T(1,x);
  }
  ~this() {
if(ptr==null) { return; }
(*ptr).cnt--;
if((*ptr).cnt == 0) {
  writeln("free");
  ptr.val.destroy();
  free(ptr);
}
  }
  @disable this(ref return scope immutable(typeof(this)) rhs);
  this(ref return scope inout(typeof(this)) rhs) {
ptr = cast(Payload!T*) rhs.ptr;
if(ptr==null) { return; }
ptr.cnt++;
  }
  void opAssign(typeof(this) rhs) {
"here".writeln;
if(this.ptr!=null) { (*this.ptr).cnt--; }
this.ptr = rhs.ptr;
if(this.ptr!=null) { (*this.ptr).cnt++; }
  }
  bool isNull() { return ptr==null; }
  ref auto dref() { assert(!isNull); return (*ptr).val; }
}

private struct Node(T) {
  RefCountedPointer!(Node!T) next;
  T val;
}


struct List(T) {
  private RefCountedPointer!(Node!T) head;
  bool empty() { return head.isNull; }
  T front() { return head.dref.val; }
  void popFront()  { head = head.dref.next;  }
  auto save() { return typeof(this)(head); }
  auto insert(T x) {
head = RefCountedPointer!(Node!T)(Node!T(head,x));
  }
}

void main() {
  List!long list;
  list.insert(8);
import std.stdio;
import core.stdc.stdlib;


private struct RefCountedPointer(T) {
  static struct Payload(T) {
long cnt=1;
T val;
  }
  Payload!T* ptr;
  this(T x) {
ptr = cast(Payload!T*) calloc(0,Payload!T.sizeof);
*ptr = Payload!T(1,x);
  }
  ~this() {
if(ptr==null) { return; }
(*ptr).cnt--;
if((*ptr).cnt == 0) {
  writeln("free");
  ptr.val.destroy();
  free(ptr);
}
  }
  @disable this(ref return scope immutable(typeof(this)) rhs);
  this(ref return scope inout(typeof(this)) rhs) {
ptr = cast(Payload!T*) rhs.ptr;
if(ptr==null) { return; }
ptr.cnt++;
  }
  void opAssign(typeof(this) rhs) {
"here".writeln;
if(this.ptr!=null) { (*this.ptr).cnt--; }
this.ptr = rhs.ptr;
if(this.ptr!=null) { (*this.ptr).cnt++; }
  }
  bool isNull() { return ptr==null; }
  ref auto dref() { assert(!isNull); return (*ptr).val; }
}

private struct Node(T) {
  RefCountedPointer!(Node!T) next;
  T val;
}


struct List(T) {
  private RefCountedPointer!(Node!T) head;
  bool empty() { return head.isNull; }
  T front() { return head.dref.val; }
  void popFront()  { head = head.dref.next;  }
  auto save() { return typeof(this)(head); }
  auto insert(T x) {
head = RefCountedPointer!(Node!T)(Node!T(head,x));
  }
}

void main() {
  List!long list;
  list.insert(8);
  

Re: arsd.minigui

2022-04-03 Thread JG via Digitalmars-d-learn

On Sunday, 3 April 2022 at 17:10:48 UTC, Adam Ruppe wrote:

On Sunday, 3 April 2022 at 16:58:03 UTC, JG wrote:

[...]


Which resizeImage did you use, from the imageresize module? 
What pain you have with it? Some of its settings take some 
tweaking.


[...]


Thank you very much for your quick reply. I see now I was doing 
something silly.


arsd.minigui

2022-04-03 Thread JG via Digitalmars-d-learn

Hi,

I have an png image that I generate (via pdf via pdflatex) that I 
want to scale and display in a widget. Is this possible via 
something in arsd? I tried resizeImage but that doesn't seem to 
do what I expect. Any suggestions?









Variadic templates with default parameters.

2022-04-02 Thread JG via Digitalmars-d-learn

Consider the following code:
```d
import std;

auto logVariadic(T...)(T x,int line=__LINE__,string 
file=__FILE__) {

writeln(file,":",line," ",x);
}

int variadicCnt;
auto logVariadicWrapper(T...)(T x, int line=__LINE__, string 
file=__FILE__) {

 variadicCnt++;
 logVariadic(x,line,file);
}

auto args(T...)(T x) {
static struct Args(T...) {
static foreach(i, t; T) {
mixin(t, " v",i,";");
}
}
return Args!T(x);
}
auto log(Args)(Args args, int line=__LINE__, string 
file=__FILE__) {

writeln(file,":",line," ",args.tupleof);
}
int cnt;
auto logWrapper(Args)(Args args, int line=__LINE__, string 
file=__FILE__) {

 cnt++;
 log(args,line,file);
}

void main()
{
logVariadic("Hello ",1234);
logVariadicWrapper(1234, " is a number."); //produces wrong 
line number and adds line number and file name at the end

writeln(variadicCnt);
log(args("Hello ",1234));
logWrapper(args(1234, " is a number."));
writeln(cnt);
}
```
Produces output:
onlineapp.d:32 Hello 1234
onlineapp.d:10 1234 is a number.33onlineapp.d
1
onlineapp.d:35 Hello 1234
onlineapp.d:36 1234 is a number.
1

Any other ways to be able to achieve the same without double 
wrapping arguments like above? I guess the above is okay but I 
thought I would see other options.
(I know that one can pass line and file as template arguments, 
but that produces a new instance of log or logWrapper per use).


Re: Can std.variant be used with std.container.rbtree?

2022-04-02 Thread JG via Digitalmars-d-learn

On Friday, 1 April 2022 at 22:22:21 UTC, Vijay Nayar wrote:

Consider the following program:
```d
void main()
{   
  import std.stdio;
  import std.container.rbtree;
  import std.variant;

[...]


You need an order on the elements in a red black tree. Am I 
correct in thinking you want a container of the form given a key 
(a string) recover some data (of different types). If so make the 
elements you store in the red black tree tuples (k,d) where k is 
a string and d is a variant. Define the order (k1,d1)<(k2,d2) if 
k1key you get the pair and take the second part. I hope this makes 
sense.




Re: How to create a function that behaves like std.stdio.writeln but prepends output with __FILE__:_LINE_

2022-01-25 Thread JG via Digitalmars-d-learn

On Tuesday, 25 January 2022 at 12:27:16 UTC, Dennis wrote:

On Tuesday, 25 January 2022 at 12:11:01 UTC, JG wrote:
Any ideas how one can achieve what is written in the subject 
line?


```D
void f(T...)(auto ref T args, string file = __FILE__, int line 
= __LINE__)

{
writeln(file, ":", line, ": ", args);
}
```


Thank you very much.


How to create a function that behaves like std.stdio.writeln but prepends output with __FILE__:_LINE_

2022-01-25 Thread JG via Digitalmars-d-learn

Any ideas how one can achieve what is written in the subject line?

f below does achieve this but I one would expect that it produces
significant template bloat.

g achieves the aim but isn't very elegant.

import std;
void f(string file=__FILE__,size_t line=__LINE__,R...)(R r)
{
  writeln(file,":",line," ",r);
}
void g(T)(T t,string file=__FILE__,size_t line=__LINE__)
{
 writeln(file,":",line," ",t.expand);
}

void main()
{
   f("hello ", 123);
   g(tuple("hello ",123));
}


Static indexing

2022-01-12 Thread JG via Digitalmars-d-learn

Hi,

I want to make a type which has two fields x and y but can
also be indexed with [0] and [1] checked at compile time.

Is the following reasonable / correct?

struct Point
{
  double x;
  double y;
  alias expand = typeof(this).tupleof;
  alias expand this;
}
unittest
{
  Point p = Point(1.2,3.4);
  assert(p[0]==1.2);
  assert(p[1]==3.4);
  assert(!__traits(compiles,Point.init[3]));
}


Re: Printing a quoted string

2022-01-02 Thread JG via Digitalmars-d-learn

On Sunday, 2 January 2022 at 17:27:53 UTC, Amit wrote:

Hi!

I would like to print a string in the same format that I would 
write it in the code (with quotes and with special characters 
escaped). Similar to [Go's %q 
format](https://pkg.go.dev/fmt#hdr-Printing). Is there a safe, 
built-in way to do that?


For example:

```
string s = "one \"two\"\nthree four";
writeln(/* ??? */);
```

And get as output

```
"one \"two\"\nthree four"
```

Instead of

```
one "two"
three four
```


Also a bit of a hack.

```
import std.stdio : writeln;
import std.format : format;


void main()
{
string s = "one \"two\"\nthree four";
writeln(format("%(%s%)",[s]));

}
```



Re: SumType

2021-10-28 Thread JG via Digitalmars-d-learn

On Thursday, 28 October 2021 at 13:30:53 UTC, Paul Backus wrote:

On Thursday, 28 October 2021 at 09:02:52 UTC, JG wrote:
I am heavily using SumType (which I like very much). The 
problem I am having is that is seems to be causing slow 
compile times (as can be observed by profiling during the 
compile). The problem seems to be with match (which is 
extremely convenient to use). I looked at the code and it does 
the only reasonable thing too do which is to test each handler 
against each type. The slow compile time makes development 
slower and less pleasant, so I am thinking of replacing 
SumType with my own tagged union and writing out the switches 
by hand. However, I really don't like this idea since it makes 
the code less readable and more prone to errors. Any 
suggestions?


Hi, I'm the author of `SumType`. Thanks for bringing this to my 
attention. The good news is, I have not put a lot of effort so 
far into micro-optimizing the compile-time performance of 
`match`, so there is almost certainly room for improvement.


If you have an example of the kind of code you are seeing poor 
compile-time performance for, I'd be happy to use it as a 
benchmark/profiling target. Any profiling data you've collected 
would also be helpful.


I've created issues for this on Bugzilla and the sumtype Github 
repository:


https://issues.dlang.org/show_bug.cgi?id=22447
https://github.com/pbackus/sumtype/issues/76


Thank you so much for your response (and thanks for the hard work 
that went into SumType). Here is a rather contrived example which 
compiles in around 9 seconds on my machine.


import std;

struct A1 {int val; }
struct A2 {int val; }
struct A3 {int val; }
struct A4 {int val; }
struct A5 {int val; }
struct A6 {int val; }
struct A7 {int val; }
struct A8 {int val; }
struct A9 {int val; }
struct A10 {int val; }
struct A11 {int val; }
struct A12 {int val; }
struct A13 {int val; }
struct A14 {int val; }

alias A = 
SumType!(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14);


T asserter(T)() { assert(0); }

auto op(A1 x, A1 y, A1 z) { return x.val + y.val + z.val; }
auto op(A2 x, A2 y, A2 z) { return x.val + y.val - z.val; }
auto op(A3 x, A3 y, A3 z) { return x.val + y.val * z.val; }
auto op(A4 x, A4 y, A4 z) { return x.val + y.val & z.val; }
auto op(A5 x, A5 y, A5 z) { return x.val - y.val + z.val; }
auto op(A6 x, A6 y, A6 z) { return x.val - y.val - z.val; }
auto op(A7 x, A7 y, A7 z) { return x.val - y.val * z.val; }
auto op(A8 x, A8 y, A8 z) { return x.val - y.val & z.val; }
auto op(A9 x, A9 y, A9 z) { return x.val * y.val + z.val; }
auto op(A10 x, A10 y, A10 z) { return x.val * y.val - z.val; }
auto op(A11 x, A11 y, A11 z) { return x.val * y.val * z.val; }
auto op(A12 x, A12 y, A12 z) { return x.val * y.val & z.val; }
auto op(A13 x, A13 y, A13 z) { return x.val & y.val + z.val; }
auto op(A14 x, A14 y, A14 z) { return x.val & y.val - z.val; }

auto op(A a, A b, A c) {
 return a.match!(
  x=>b.match!(
y=>c.match!(z=>op(x,y,z),
_=>asserter!int),
_=>asserter!int));

}

auto op2(A a, A b, A c) {
 alias doMatch = match!(
(x, y, z) => op(x,y,z),
(_1, _2, _3) => asserter!int
);
 return doMatch(a, b, c);
}

void main()
{
A a = A1(12);
A b = A1(13);
A c = A1(14);
assert(op(a,b,c)==39);
assert(op2(a,b,c)==39);
}



SumType

2021-10-28 Thread JG via Digitalmars-d-learn
I am heavily using SumType (which I like very much). The problem 
I am having is that is seems to be causing slow compile times (as 
can be observed by profiling during the compile). The problem 
seems to be with match (which is extremely convenient to use). I 
looked at the code and it does the only reasonable thing too do 
which is to test each handler against each type. The slow compile 
time makes development slower and less pleasant, so I am thinking 
of replacing SumType with my own tagged union and writing out the 
switches by hand. However, I really don't like this idea since it 
makes the code less readable and more prone to errors. Any 
suggestions?


Re: what's the most efficient way to implement std.container.binaryheap.back()?

2021-10-25 Thread JG via Digitalmars-d-learn

On Monday, 25 October 2021 at 04:49:12 UTC, mw wrote:

Hi,

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

The binary heap induces structure over the underlying store 
such that accessing the largest element (by using the front 
property) is a Ο(1) operation.


I'm wondering what's the most efficient (in terms of both speed 
and memory usage) way to implement 
std.container.binaryheap.back()? i.e accessing the smallest 
element.


Has anyone done this before?

Thanks.


I didn't look at the implementation, but the implementations I 
have looked at are backed by an array (a random access container 
would do). If so you need to find the min of elements from the 
largest "one less than a power of two" less than the size of the 
heap up to the  size of heap.


However, perhaps an alternative data struct would be better? See 
e.g. https://en.m.wikipedia.org/wiki/Min-max_heap


 On Monday, 25 October 2021 at 04:49:12 UTC, mw wrote:


Re: Dustmite and linking error

2021-09-04 Thread JG via Digitalmars-d-learn

On Saturday, 4 September 2021 at 08:54:31 UTC, Mike Parker wrote:

On Saturday, 4 September 2021 at 08:19:53 UTC, JG wrote:


[...]


You should be able to do that now with "sourceFiles" and 
"sourcePaths". Just avoid the default "source" or "src" 
directories and specify the paths and/or files you want for 
each configuration.


I didn't know about this. Thanks you for letting me know.



Re: Dustmite and linking error

2021-09-04 Thread JG via Digitalmars-d-learn

On Saturday, 4 September 2021 at 08:05:16 UTC, JG wrote:
On Saturday, 4 September 2021 at 07:40:07 UTC, Vladimir 
Panteleev wrote:
On Saturday, 4 September 2021 at 07:38:34 UTC, Andre Pany 
wrote:
The Dustmite condition you are using seems very generic, 
therefore this error message can be triggered by various code 
constellations. This might be the reasons why Dustmite is 
running so long.


Overly generic test conditions would be more likely to cause 
DustMite to finish very quickly (and produce the wrong 
result), rather than the other way around.


In the end I did the reduction by hand and discovered that the 
problem is that the behaviour of dub changed. It seems to now 
exclude the mainSourceFile of other configurations in the build 
(which I guess shouldn't matter) except we had an old 
configuration which after some renaming had a wrong 
mainSourceFile which was needed for the build of the 
configuration in question.


Thanks for the suggestions.


As a small comment regarding dub. I can't help wondering if it 
really the best idea for each configuration to include everything 
by default and then have to exclude things? This means that when 
you add another configuration and source files for it you very 
often have to modify all other existing ones. If instead you 
choose what to include this wouldn't happen. Wild cards support 
could be added for included files to make projects with a single 
configuration just as simple as now. Just some thoughts. (I feel 
the same way regarding gitignore, I would rather have the 
opposite.)


Re: Dustmite and linking error

2021-09-04 Thread JG via Digitalmars-d-learn
On Saturday, 4 September 2021 at 07:40:07 UTC, Vladimir Panteleev 
wrote:

On Saturday, 4 September 2021 at 07:38:34 UTC, Andre Pany wrote:
The Dustmite condition you are using seems very generic, 
therefore this error message can be triggered by various code 
constellations. This might be the reasons why Dustmite is 
running so long.


Overly generic test conditions would be more likely to cause 
DustMite to finish very quickly (and produce the wrong result), 
rather than the other way around.


In the end I did the reduction by hand and discovered that the 
problem is that the behaviour of dub changed. It seems to now 
exclude the mainSourceFile of other configurations in the build 
(which I guess shouldn't matter) except we had an old 
configuration which after some renaming had a wrong 
mainSourceFile which was needed for the build of the 
configuration in question.


Thanks for the suggestions.


Re: Dustmite and linking error

2021-09-04 Thread JG via Digitalmars-d-learn

On Saturday, 4 September 2021 at 06:18:52 UTC, JG wrote:

On Friday, 3 September 2021 at 19:56:30 UTC, JG wrote:

[...]


I tried again. What am I doing wrong?

cp source ~/tmp/source
cd ~/tmp/source
dub build --config prog1 2>&1 | grep "collect2: error: ld 
returned 1 exit status"

echo $? #produces 0
find . -name *.o -delete
~/d/DustMite/dustmite -j ./ 'dub build --config prog1 2>&1 | 
grep "collect2: error: ld returned 1 exit status"'

cd ../source.reduced
dub build --config prog1 2>&1 | grep "collect2: error: ld 
returned 1 exit status"

echo $? #produces 1


First line should be: cp -R source ~/tmp/source


Re: Dustmite and linking error

2021-09-04 Thread JG via Digitalmars-d-learn

On Friday, 3 September 2021 at 19:56:30 UTC, JG wrote:
On Thursday, 2 September 2021 at 17:56:54 UTC, Vladimir 
Panteleev wrote:
On Thursday, 2 September 2021 at 11:20:18 UTC, Vladimir 
Panteleev wrote:
One way to get a very rough estimate is to take the square of 
the current reduction (.reduced directory), and divide it by 
the square of the original source.


I meant the square of the size of the respective directory. 
(bytes / LOC / SLOC...)



One week later it is still running (depth 22).


If you are still on the first iteration, you may also try 
switching to the "careful" strategy.


Thanks for the information.

I stopped dustMite and realized I must have done something 
wrong since the reduced test case doesn't reproduce the problem.


I would really like to try and produce a reduced test case of 
this problem. However having spent three or four hours trying 
to figure out what I am doing wrong I think I will have to stop 
at this point.


I tried again. What am I doing wrong?

cp source ~/tmp/source
cd ~/tmp/source
dub build --config prog1 2>&1 | grep "collect2: error: ld 
returned 1 exit status"

echo $? #produces 0
find . -name *.o -delete
~/d/DustMite/dustmite -j ./ 'dub build --config prog1 2>&1 | grep 
"collect2: error: ld returned 1 exit status"'

cd ../source.reduced
dub build --config prog1 2>&1 | grep "collect2: error: ld 
returned 1 exit status"

echo $? #produces 1




Re: Dustmite and linking error

2021-09-03 Thread JG via Digitalmars-d-learn
On Thursday, 2 September 2021 at 17:56:54 UTC, Vladimir Panteleev 
wrote:
On Thursday, 2 September 2021 at 11:20:18 UTC, Vladimir 
Panteleev wrote:
One way to get a very rough estimate is to take the square of 
the current reduction (.reduced directory), and divide it by 
the square of the original source.


I meant the square of the size of the respective directory. 
(bytes / LOC / SLOC...)



One week later it is still running (depth 22).


If you are still on the first iteration, you may also try 
switching to the "careful" strategy.


Thanks for the information.

I stopped dustMite and realized I must have done something wrong 
since the reduced test case doesn't reproduce the problem.


I would really like to try and produce a reduced test case of 
this problem. However having spent three or four hours trying to 
figure out what I am doing wrong I think I will have to stop at 
this point.





Re: Dustmite and linking error

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

On Thursday, 2 September 2021 at 11:19:55 UTC, jfondren wrote:

On Thursday, 2 September 2021 at 11:04:12 UTC, JG wrote:

Hi,

We hit a linking error (after upgrading to dub 1.26.0). I 
thought I would try to use dustmite to create a reduced error 
test case. One week later it is still running (depth 22). I 
don't suppose there is anyway of determining when it will 
finish?


Possibly it's not a compiler error at all but a name-mangling 
change combined with some stale objects in your build.


Thanks for the suggestion.

I thought I was doing this. What I did was run:

dub clean --all-packages
dub build --force

Then I am getting twelve linking errors. Of the form:
..  error: undefined reference to .


Dustmite and linking error

2021-09-02 Thread JG via Digitalmars-d-learn

Hi,

We hit a linking error (after upgrading to dub 1.26.0). I thought 
I would try to use dustmite to create a reduced error test case. 
One week later it is still running (depth 22). I don't suppose 
there is anyway of determining when it will finish?




Re: Profiling

2021-08-24 Thread JG via Digitalmars-d-learn

On Tuesday, 24 August 2021 at 09:45:31 UTC, JG wrote:

On Tuesday, 24 August 2021 at 09:42:29 UTC, JG wrote:

On Tuesday, 24 August 2021 at 09:36:06 UTC, JG wrote:

[...]


In case anyone is interested it seems that it was forked to 
here:


https://github.com/joakim-brannstrom/profdump

Perhaps the dub page could be updated?


Tried to continue following the instructions.
Ran:
profdump -b trace.log trace.log.b
Got:
core.exception.RangeError@source/app.d(134): Range violation

??:? [0x557458c2bad5]
??:? [0x557458c2d556]
??:? [0x557458c147af]
??:? [0x557458c0b458]
??:? [0x557458c0bb47]
app.d:133 [0x557458b96199]
??:? [0x557458c1449b]
??:? [0x557458c14397]
??:? [0x557458c141ed]
/home/jg/dlang/ldc-1.26.0/bin/../import/core/internal/entrypoint.d:42 
[0x557458b979d4]
??:? __libc_start_main [0x7f0f84d39cb1]
??:? [0x557458b4a0cd]


The reason for the crash boils down to the fact that this fails:

foreach(k; sort!"a > b"(funcs.keys)) assert(k in funcs);

funcs is of type ubyte[4][float]

Is this a compiler bug?


Re: Profiling

2021-08-24 Thread JG via Digitalmars-d-learn

On Tuesday, 24 August 2021 at 09:42:29 UTC, JG wrote:

On Tuesday, 24 August 2021 at 09:36:06 UTC, JG wrote:

On Wednesday, 10 February 2021 at 23:42:31 UTC, mw wrote:

[...]


I tried to do this, but I am not sure how to install profdump.
What I did is cloned the repository using git.
Tried to build it using dub but got an error as described here:

[...]


In case anyone is interested it seems that it was forked to 
here:


https://github.com/joakim-brannstrom/profdump

Perhaps the dub page could be updated?


Tried to continue following the instructions.
Ran:
profdump -b trace.log trace.log.b
Got:
core.exception.RangeError@source/app.d(134): Range violation

??:? [0x557458c2bad5]
??:? [0x557458c2d556]
??:? [0x557458c147af]
??:? [0x557458c0b458]
??:? [0x557458c0bb47]
app.d:133 [0x557458b96199]
??:? [0x557458c1449b]
??:? [0x557458c14397]
??:? [0x557458c141ed]
/home/jg/dlang/ldc-1.26.0/bin/../import/core/internal/entrypoint.d:42 
[0x557458b979d4]
??:? __libc_start_main [0x7f0f84d39cb1]
??:? [0x557458b4a0cd]


Re: Profiling

2021-08-24 Thread JG via Digitalmars-d-learn

On Tuesday, 24 August 2021 at 09:36:06 UTC, JG wrote:

On Wednesday, 10 February 2021 at 23:42:31 UTC, mw wrote:

[...]


I tried to do this, but I am not sure how to install profdump.
What I did is cloned the repository using git.
Tried to build it using dub but got an error as described here:

[...]


In case anyone is interested it seems that it was forked to here:

https://github.com/joakim-brannstrom/profdump

Perhaps the dub page could be updated?


Re: Profiling

2021-08-24 Thread JG via Digitalmars-d-learn

On Wednesday, 10 February 2021 at 23:42:31 UTC, mw wrote:

On Wednesday, 10 February 2021 at 11:52:51 UTC, JG wrote:


As a follow up question I would like to know what tool people 
use to profile d programs?


I use this one:

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

e.g.

```
dub build --build=debug --build=profile

# run your program to generate trace.log

profdump -b trace.log trace.log.b
profdump -f --dot --threshold 1 trace.log trace.log.dot
echo 'view it with: xdot trace.log.dot'
```


I tried to do this, but I am not sure how to install profdump.
What I did is cloned the repository using git.
Tried to build it using dub but got an error as described here:

https://github.com/AntonMeep/profdump/issues/6

I then modified the dub.json and got it to build but it only
produced a library. So I modified the dub.json again to tell
it to build an executable and got:

core.exception.AssertError@source/app.d(4): TODO

??:? [0x561af7b38025]
??:? [0x561af7b39aa6]
??:? [0x561af7b1cd8f]
??:? [0x561af7b15469]
app.d:4 [0x561af7aebc62]
??:? [0x561af7b1ca7b]
??:? [0x561af7b1c977]
??:? [0x561af7b1c7cd]
/home/james/dlang/ldc-1.26.0/bin/../import/core/internal/entrypoint.d:42 
[0x561af7aebc94]
??:? __libc_start_main [0x7f5ba99accb1]
??:? [0x561af7aeb62d]
Program exited with code 1

I then looked inside source/app.d and found:

version(unittest) {

} else {
void main() { assert(0, "TODO"); }
}


How does one install profdump?





Re: Vibe.d error

2021-08-20 Thread JG via Digitalmars-d-learn

On Friday, 20 August 2021 at 10:50:12 UTC, WebFreak001 wrote:

On Wednesday, 18 August 2021 at 19:51:00 UTC, JG wrote:

[...]


There might be incompatibilities with how openssl is used and 
the installed openssl version or config.


If you are getting this from having https enabled on the 
server, I would recommend instead switching to HTTP-only and 
using a reverse proxy such as with nginx or caddy to serve it 
with HTTPS.


Thank you very much for your reply. Yes, we are getting this with 
HTTPS enabled. May I ask why you suggest not to use HTTPS?


Vibe.d error

2021-08-18 Thread JG via Digitalmars-d-learn

Hi,

We are intermittently getting the following error:
Accept TLS connection: server
OpenSSL error at ../ssl/record/rec_layer_s3.c:1543: 
error:14094416:SSL routines:ssl3_read_bytes:sslv3 alert 
certificate unknown (SSL alert number 46)
HTTP connection handler has thrown: Accepting SSL tunnel: 
error:14094416:SSL routines:ssl3_read_bytes:sslv3 alert 
certificate unknown (336151574)
Full error: 
object.Exception@/home/jg/.dub/packages/vibe-d-0.9.3/vibe-d/tls/vibe/stream/openssl.d(578): Accepting SSL tunnel: error:14094416:SSL routines:ssl3_read_bytes:sslv3 alert certificate unknown (336151574)



Anyone have any idea what might cause this?


Re: Concurrency message passing

2021-08-17 Thread JG via Digitalmars-d-learn
On Tuesday, 17 August 2021 at 12:24:14 UTC, Steven Schveighoffer 
wrote:

On 8/17/21 7:05 AM, JG wrote:

Hi

I have a program with two threads. One thread produces data 
that is put in a queue
and then consumed by the other thread. I initially built a 
custom queue to do this, but thought this should have some 
standard solution in D? I looked at std.concurrency and 
thought that message passing could be used. However, the 
problem is that I get the following error.


Error: static assert:  "Aliases to mutable thread-local data 
not allowed."


I am not sure how to solve this.  Maybe message parsing isn't 
the correct solution?

Is there some standard solution to this in D?


Data with references needs to be marked either immutable or 
shared in order to be passed using std.concurrency. D is strict 
about not sharing thread-local data, because then you can use 
the type system to prove lock-free code is valid.


However, data that has no references (aliases) should be 
passable regardless of mutability, because you are passing a 
copy.


-Steve


Thanks for the suggestions and explanations. I am not sure what 
to do in my case though. The situation is as follows. I have a 
struct that is populated via user input not necessarily at single 
instance (so that seems to rule out immutable). On the other
hand while it is being populate it is only accessible from one 
thread so that
makes using shared messy. After being populated it should be 
passed to the other thread and no references are kept.


What I am doing currently is populating the struct and casting to 
shared when I push into a synchronized queue (no references to 
its data are kept in the first thread). Is what I am doing wrong 
and can it be achieved using message passing?






Concurrency message passing

2021-08-17 Thread JG via Digitalmars-d-learn

Hi

I have a program with two threads. One thread produces data that 
is put in a queue
and then consumed by the other thread. I initially built a custom 
queue to do this, but thought this should have some standard 
solution in D? I looked at std.concurrency and thought that 
message passing could be used. However, the problem is that I get 
the following error.


Error: static assert:  "Aliases to mutable thread-local data not 
allowed."


I am not sure how to solve this.  Maybe message parsing isn't the 
correct solution?

Is there some standard solution to this in D?


Re: Anyway to achieve the following

2021-08-16 Thread JG via Digitalmars-d-learn

On Sunday, 15 August 2021 at 21:53:14 UTC, Carl Sturtivant wrote:

On Sunday, 15 August 2021 at 07:10:17 UTC, JG wrote:

[...]


What you are asking for are reference variables. C++ has them: 
the example here illustrates the behavior you want.

https://www.geeksforgeeks.org/references-in-c/

[...]


Thanks for the links and code. Looking at the assembly as 
suggested by others it seems that after optimization this not too 
bad.


Re: Anyway to achieve the following

2021-08-15 Thread JG via Digitalmars-d-learn
On Saturday, 14 August 2021 at 20:50:47 UTC, Carl Sturtivant 
wrote:

```
struct S {
  int x = 1234;
}

void main() {
  import std.stdio;
   S s;
   //construction of a using &(s.x)
   auto a = Ref!(int)();
   writeln(a); //displays 1234
   s.x += 1;
   writeln(a); //displays 1235
   a += 1;
   writeln(s.x); //displays 1236
}

struct Ref(T) {
  T* ptr;
  this(T* p) { ptr = p; }
  string toString() { import std.conv; return to!string(*ptr); }
  ref T var() { return *ptr; }
  alias var this;
}
```


Hi,

This is exactly the behaviour I was trying to obtain.

It however comes with a fair amount of overhead, as can be seen 
in the following llvm ir:


define i32 @_Dmain({ i64, { i64, i8* }* } %unnamed) #0 {
  %s = alloca %onlineapp.S, align 4   ; [#uses = 
4, size/byte = 4]
  %a = alloca %"onlineapp.Ref!int.Ref", align 8   ; [#uses = 
5, size/byte = 8]
  %1 = bitcast %onlineapp.S* %s to i8*; [#uses = 
1]
  call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 1 %1, i8* 
align 1 bitcast (%onlineapp.S* @onlineapp.S.__init to i8*), i64 
4, i1 false)
  %2 = bitcast %"onlineapp.Ref!int.Ref"* %a to i8* ; [#uses = 
1]
  call void @llvm.memset.p0i8.i64(i8* align 1 %2, i8 0, i64 
8, i1 false)
  %3 = getelementptr inbounds %onlineapp.S, %onlineapp.S* %s, 
i32 0, i32 0 ; [#uses = 1, type = i32*]
  %4 = call %"onlineapp.Ref!int.Ref"* @pure nothrow ref @nogc 
@safe onlineapp.Ref!(int).Ref 
onlineapp.Ref!(int).Ref.__ctor(int*)(%"onlineapp.Ref!int.Ref"* 
nonnull returned %a, i32* %3) #4 ; [#uses = 0]
  %5 = load %"onlineapp.Ref!int.Ref", 
%"onlineapp.Ref!int.Ref"* %a, align 8 ; [#uses = 1]
  call void @@safe void 
std.stdio.writeln!(onlineapp.Ref!(int).Ref).writeln(onlineapp.Ref!(int).Ref)(%"onlineapp.Ref!int.Ref" %5) #4
  %6 = getelementptr inbounds %onlineapp.S, %onlineapp.S* %s, 
i32 0, i32 0 ; [#uses = 2, type = i32*]
  %7 = load i32, i32* %6, align 4 ; [#uses = 
1]
  %8 = add i32 %7, 1  ; [#uses = 
1]

  store i32 %8, i32* %6, align 4
  %9 = load %"onlineapp.Ref!int.Ref", 
%"onlineapp.Ref!int.Ref"* %a, align 8 ; [#uses = 1]
  call void @@safe void 
std.stdio.writeln!(onlineapp.Ref!(int).Ref).writeln(onlineapp.Ref!(int).Ref)(%"onlineapp.Ref!int.Ref" %9) #4
  %10 = call i32* @pure nothrow ref @nogc @safe int 
onlineapp.Ref!(int).Ref.var()(%"onlineapp.Ref!int.Ref"* nonnull 
%a) #4 ; [#uses = 2]
  %11 = load i32, i32* %10, align 4   ; [#uses = 
1]
  %12 = add i32 %11, 1; [#uses = 
1]

  store i32 %12, i32* %10, align 4
  %13 = getelementptr inbounds %onlineapp.S, %onlineapp.S* 
%s, i32 0, i32 0 ; [#uses = 1, type = i32*]
  %14 = load i32, i32* %13, align 4   ; [#uses = 
1]
  call void @@safe void 
std.stdio.writeln!(int).writeln(int)(i32 %14) #4

  ret i32 0
}


Re: Anyway to achieve the following

2021-08-13 Thread JG via Digitalmars-d-learn

On Friday, 13 August 2021 at 17:19:43 UTC, H. S. Teoh wrote:
On Fri, Aug 13, 2021 at 05:11:50PM +, Rekel via 
Digitalmars-d-learn wrote: [...]
For anyone more experienced with C, I'm not well known with 
references but are those semantically similar to the idea of 
using a type at a predefined location?


References are essentially pointers under the hood. The 
difference is that at the language level they are treated as 
aliases to the original variable, and are therefore guaranteed 
to be non-null.


Note that in D `ref` is not a type constructor but a storage 
qualifier, so you cannot declare a reference variable, you can 
only get one if you pass a variable to a function that takes it 
by ref.



T


Thanks for all the replies.

I had a look at emplace but it does not seem to do exactly what I 
have in mind.


What I had in mind would have the following behaviour. Suppose we 
optionally
allow "in  before the semi-colon at the end of a 
declaration. With the following semantics


T x;
T y in 

assert(x==y);
assert(==);

Note that I am not suggesting that the syntax I wrote is what 
exists or should exist. I think what I am suggesting is not the 
same as say implicitly dereferenced pointers. If you think of the 
underlying machine, variables are aliases for locations in memory 
where values are stored, and what I am asking is whether it is 
possible to alias an arbitrary location (provided it contains the 
correct type.) (I guess what I am saying is only conceptually 
true variables might end up in registers, but from the point of 
view of the language it is true since if v is a variable, then  
is defined to be its address.)


This would allow things like:

Given:

struct S
{
   int x;
   int y;
}

You can write:

S s = S(1,2) in new S;

ending up with s being defined on the heap.

Anyway I hope it is clearer what I mean. Is it possible to do 
this in d?








Anyway to achieve the following

2021-08-13 Thread JG via Digitalmars-d-learn

Suppose one has a pointer p of type T*.
Can on declare variable a of type T which is stored in the 
location pointed to by p?


As an example if we have:

struct S
{
  int x = 1234;
}

void main() {
   S s;
   //unknown construction of a using &(s.x)
   writeln(a); //displays 1234
   s.x = s.x+1;
   writeln(a); //displays 1235
   a = a +1;
   writeln(s.x); //displays 1236
}

Similar behavior can be achieved in the body of the lambda here

import std.stdio;

struct S
{
  int x = 1234;
}


void main() {
S s;
(ref a){
 writeln(a);
 s.x = s.x + 1;
 writeln(a);
 a = a +1;
 writeln(s.x);
}(s.x);
}




Re: Tracy

2021-08-07 Thread JG via Digitalmars-d-learn

On Saturday, 7 August 2021 at 14:36:39 UTC, Dennis wrote:

On Friday, 6 August 2021 at 12:30:16 UTC, JG wrote:

I guess this means that tracy has been integrated?
If this is so is it documented anywhere how to use it?


Stefan Koch's WIP tracy integration in DMD is completely 
separate from Johan Engelen's time tracing added to LDC in 
1.25.0. Note that the latter is not specific to tracy, I just 
recommended using tracy to view the trace file because 
alternatives I tried (Google Chrome and Speedscope) are 
terribly slow, see:

https://forum.dlang.org/post/phuwlvsjigbyfvslk...@forum.dlang.org

I'm not aware of any documentation of the feature.


Thanks, a lot.


Tracy

2021-08-06 Thread JG via Digitalmars-d-learn
There was a message a while back 
(https://forum.dlang.org/post/fyakhpjbcpzqegfev...@forum.dlang.org)

about adding support for tracy.
When I asked a question about compile time performance I received 
the following instructions:

https://forum.dlang.org/post/eevoyuwhbuycyzgxs...@forum.dlang.org

I guess this means that tracy has been integrated?
If this is so is it documented anywhere how to use it?




Re: Passing delegate indirectly to createLowLevelThread doesn't work

2021-07-26 Thread JG via Digitalmars-d-learn

On Monday, 26 July 2021 at 16:46:40 UTC, Tejas wrote:

On Monday, 26 July 2021 at 15:42:44 UTC, Paul Backus wrote:

On Monday, 26 July 2021 at 15:29:26 UTC, Tejas wrote:

```d
import std;
import core.thread.osthread;

void delegate() f;
void main()
{
void func(){}
f = 
createLowLevelThread(, 2<<30);//works
createLowLevelThread(f, 2<<30);// doesn't  work!!
}

```

Can someone help?


The delegate must be `nothrow`:

```d
void delegate() nothrow f;
```


Doesn't seem to matter. I tried that beforehand. And even if it 
did why does passing it directly work without explicitly 
qualifying it as nothrow then?


It does work for me. To me running the following explains why:

```d
import std;
import core.thread.osthread;

void delegate() f;
void main()
{
void func(){}
f = 
pragma(msg,typeof());
pragma(msg,typeof(f));
createLowLevelThread(, 2<<30);//works
//createLowLevelThread(f, 2<<30);// doesn't  work!!
}
```



Re: How to check if variable of some type can be of null value?

2021-07-24 Thread JG via Digitalmars-d-learn

On Saturday, 24 July 2021 at 20:10:37 UTC, JG wrote:

On Saturday, 24 July 2021 at 19:39:02 UTC, Alexey wrote:

[...]


There are probably better ways. However, this seems to work:
```d
import std;
enum canBeSetToNull(T) = __traits(compiles,(T.init is null));

interface I1
{
}

class C1 : I1
{
}

struct S1
{
}

struct S2
{
int a=1;
}

void main()
{
auto c1 = new C1;

I1 i1 = c1;

auto s1 = S1();
auto s2 = S2();

static assert(canBeSetToNull!(typeof(c1)));
static assert(canBeSetToNull!(typeof(i1)));
static assert(!canBeSetToNull!(typeof(s1)));
static assert(!canBeSetToNull!(typeof(s2)));
static assert(!canBeSetToNull!(int));
static assert(canBeSetToNull!(int*));

}```


Sorry, I see that is basically what you had.


Re: How to check if variable of some type can be of null value?

2021-07-24 Thread JG via Digitalmars-d-learn

On Saturday, 24 July 2021 at 19:39:02 UTC, Alexey wrote:

On Saturday, 24 July 2021 at 18:10:07 UTC, Alexey wrote:
I've tried to use ```typeof(t) is cast(t)null```, but compiler 
exits with error and so this can't be used for checking this 
issue.


The goal I with to achieve by this check - is to use template 
and to assign value to variable basing on it's ability to 
accept null as a value.




currently I ended up using ```__traits(compiles, 
cast(T1)null)``` for this check. but don't know is this really 
semantically correct.


There are probably better ways. However, this seems to work:
```d
import std;
enum canBeSetToNull(T) = __traits(compiles,(T.init is null));

interface I1
{
}

class C1 : I1
{
}

struct S1
{
}

struct S2
{
int a=1;
}

void main()
{
auto c1 = new C1;

I1 i1 = c1;

auto s1 = S1();
auto s2 = S2();

static assert(canBeSetToNull!(typeof(c1)));
static assert(canBeSetToNull!(typeof(i1)));
static assert(!canBeSetToNull!(typeof(s1)));
static assert(!canBeSetToNull!(typeof(s2)));
static assert(!canBeSetToNull!(int));
static assert(canBeSetToNull!(int*));

}```


Re: Build time

2021-07-24 Thread JG via Digitalmars-d-learn

On Saturday, 24 July 2021 at 09:12:15 UTC, JG wrote:

On Saturday, 24 July 2021 at 08:26:39 UTC, JG wrote:

On Friday, 23 July 2021 at 20:03:22 UTC, Dennis wrote:

[...]


Thanks for this suggestion. Unfortunately this makes the 
compile use too much memory for my system and so it gets 
killed before the end and no my-trace.tracy file is produced. 
I will try building on parts of the program with this and see 
if I can see what is going on.


Got this to work after removing part of the program, the 
slowest parts are in library code (sumtype match to be 
precise). I will look into whether my usage can be improved.


I should also mention that what I said about compile time was a 
little inaccurate, some of that time linking (which involves 
llvm).


Thanks very much to everyone for the help. With a few minor 
changes so far I have halved the compile time.


Re: Build time

2021-07-24 Thread JG via Digitalmars-d-learn

On Saturday, 24 July 2021 at 08:26:39 UTC, JG wrote:

On Friday, 23 July 2021 at 20:03:22 UTC, Dennis wrote:

On Friday, 23 July 2021 at 18:53:06 UTC, JG wrote:

[...]


You can try profiling it with LDC 1.25 or later. Add this to 
dub.sdl:


[...]


Thanks for this suggestion. Unfortunately this makes the 
compile use too much memory for my system and so it gets killed 
before the end and no my-trace.tracy file is produced. I will 
try building on parts of the program with this and see if I can 
see what is going on.


Got this to work after removing part of the program, the slowest 
parts are in library code (sumtype match to be precise). I will 
look into whether my usage can be improved.


I should also mention that what I said about compile time was a 
little inaccurate, some of that time linking (which involves 
llvm).


Re: Build time

2021-07-24 Thread JG via Digitalmars-d-learn

On Friday, 23 July 2021 at 20:03:22 UTC, Dennis wrote:

On Friday, 23 July 2021 at 18:53:06 UTC, JG wrote:

[...]


You can try profiling it with LDC 1.25 or later. Add this to 
dub.sdl:


[...]


Thanks for this suggestion. Unfortunately this makes the compile 
use too much memory for my system and so it gets killed before 
the end and no my-trace.tracy file is produced. I will try 
building on parts of the program with this and see if I can see 
what is going on.


Re: Build time

2021-07-23 Thread JG via Digitalmars-d-learn

On Friday, 23 July 2021 at 18:57:46 UTC, Adam D Ruppe wrote:

On Friday, 23 July 2021 at 18:53:06 UTC, JG wrote:

The program I writing is around 3000 loc


what's the code?


I am not sure how relevant it is but it is a compiler that I have 
been writing, not something serious (yet - if ever).




Build time

2021-07-23 Thread JG via Digitalmars-d-learn

Hi,

The program I writing is around 3000 loc and recently I noticed a 
large slow down in compile time which after investigation seemed 
to be caused by my computer running out of memory. The compile 
was using more than 15GB memory. I tried using lowmem and that 
did solve the memory problem but the compile still takes around 1 
minute. Any suggestion on how to try and improve the build time. 
I am currently using dub.


Of course one could try to use fewer templates and less meta 
programming but that seems to defeat the purpose of using d.


Documentation

2021-07-15 Thread JG via Digitalmars-d-learn

What is the relationship between
https://dlang.org/library/
and
https://dlang.org/phobos/index.html



Sumtype warning

2021-07-11 Thread JG via Digitalmars-d-learn

I am getting the following message:
Warning: struct SumType has method toHash, however it cannot be 
called with const(SumType!(A,B,C)) this


Could someone point in the right direction to understand what I 
am doing that causes this?




Re: Vibe.d diet templates

2021-06-17 Thread JG via Digitalmars-d-learn

On Thursday, 17 June 2021 at 18:54:41 UTC, WebFreak001 wrote:

On Thursday, 17 June 2021 at 16:26:57 UTC, JG wrote:

[...]

Thanks, this works. I would have thought this would be a 
common enough use case to have support in diet. Anyone else 
wanted this?


Opened an issue here: 
https://github.com/rejectedsoftware/diet-ng/issues/91


Thanks for opening that issue.


Re: Vibe.d diet templates

2021-06-17 Thread JG via Digitalmars-d-learn

On Thursday, 17 June 2021 at 09:16:56 UTC, WebFreak001 wrote:

On Thursday, 17 June 2021 at 08:23:54 UTC, JG wrote:
Suppose I have an array of attributes and values v is there 
any way to apply these attributes to a tag?


So that something like

tag(#{v[0]0]}=#{v[0][1]},...})

becomes



where v[0][0]="attribute0" and v[0][1]="value0"?


I think there is nothing for this built-in in diet, so you have 
to manually emit raw HTML:


```diet
- import std.xml : encode;
- auto start = appender!string;
- start ~= "

Thanks, this works. I would have thought this would be a common 
enough use case to have support in diet. Anyone else wanted this?


Vibe.d diet templates

2021-06-17 Thread JG via Digitalmars-d-learn
Suppose I have an array of attributes and values v is there any 
way to apply these attributes to a tag?


So that something like

tag(#{v[0]0]}=#{v[0][1]},...})

becomes



where v[0][0]="attribute0" and v[0][1]="value0"?





Two interpretations

2021-06-11 Thread JG via Digitalmars-d-learn
Is it specified somewhere which way the following program will be 
interpreted?


import std;

struct A
{
int x=17;
}

int x(A a)
{
return 100*a.x;
}

void main()
{
A a;
   writeln(a.x);
}


Shift operator, unexpected result

2021-06-09 Thread JG via Digitalmars-d-learn
I found the following behaviour, as part of a more complicated 
algorithm, unexpected. The program:


import std;
void main()
{
int n = 64;
writeln(123uL>>n);
}

produces:

123

I would expect 0.

What is the rationale for this behaviour or is it a bug?


Re: Understanding RefCounted

2021-05-12 Thread JG via Digitalmars-d-learn
On Thursday, 13 May 2021 at 00:53:50 UTC, Steven Schveighoffer 
wrote:

On 5/12/21 1:16 PM, JG wrote:

[...]


Ah, ok. So reference counting provides a single thing you can 
point at and pass around without worrying about memory cleanup. 
But only as long as you refer to it strictly through a 
RefCounted struct. If you keep a pointer to something in the 
payload that isn't wrapped in a RefCounted struct (and 
specifically the original RefCounted struct), then it's 
possible the RefCounted struct will free the memory while you 
still hold a reference.


[...]


Thank you. I was just wondering if something like what you wrote 
could be achieved using the range above accidentally.


Re: Issue with small floating point numbers

2021-05-12 Thread JG via Digitalmars-d-learn

On Thursday, 13 May 2021 at 03:48:49 UTC, Tim wrote:

On Thursday, 13 May 2021 at 03:46:28 UTC, Alain De Vos wrote:

Not is is not wrong it is wright.
Because you use not pi but an approximation of pi the result 
is not zero but an approximation of zero.


Oh, of course. Jesus that sucks big time. Any idea on how to 
use assert with an approximate number like this?


You could try and use this 
[this](https://dlang.org/library/std/math/is_close.html)


Re: How to use dub with our own package

2021-05-12 Thread JG via Digitalmars-d-learn

On Wednesday, 12 May 2021 at 13:37:26 UTC, Vinod K Chandran wrote:

Hi all,
I am creating a hobby project related with win api gui 
functions. i would like to work with dub. But How do I use dub 
in my project.
1. All my gui library modules are located in a folder named 
"winglib".

2. And that folder also conatains a d file called "package.d"
3. "package.d" contains all the public imports.
4. Outside this winglib folder, I have my main file called 
"app.d"

5. "app.d" imports "winglib".
So in this setup, how do I use dub ? Thanks in advance.


Have a look at 
[link](https://forum.dlang.org/post/jyxdcotuqhcdfqwwh...@forum.dlang.org).


Re: Understanding RefCounted

2021-05-12 Thread JG via Digitalmars-d-learn
On Wednesday, 12 May 2021 at 13:38:10 UTC, Steven Schveighoffer 
wrote:

On 5/12/21 3:28 AM, JG wrote:
Reading the documentation on RefCounted I get the impression 
that the following can lead to memory errors. Could someone 
explain exactly how that could happen? I suppose that problem 
would be the call something to do with front?



```
private struct RefCountedRangeReturnType(R)
{
     import std.typecons : RefCounted;
     private RefCounted!R r;
     auto empty() { return r.refCountedPayload.empty; }
     auto front() { return r.refCountedPayload.front; }
     void popFront() { r.refCountedPayload.popFront; }
     auto save() { return 
typeof(this)(RefCounted!R(r.refCountedPayload.save)); }

}

auto refCountedRange(R)(R r)
{
     import std.typecons : RefCounted;
     return  RefCountedRangeReturnType!R(RefCounted!R(r));
}
```


You don't need to access refCountedPayload. RefCounted is 
supposed to be like a transparent reference type, and should 
forward all calls to the referenced item.


I don't see how you will get memory errors from your code. 
Maybe you can elaborate why you think that is?


-Steve


To be honest I can't see the problem. But the following from the 
documentation made me wonder if I was doing something that could 
lead to memory problems:


"RefCounted is unsafe and should be used with care. No references 
to the payload should be escaped outside the RefCounted object."


In particular I wondered if in some special case holding a 
reference to front might cause a problem, but perhaps that is 
incorrect.





Understanding RefCounted

2021-05-12 Thread JG via Digitalmars-d-learn
Reading the documentation on RefCounted I get the impression that 
the following can lead to memory errors. Could someone explain 
exactly how that could happen? I suppose that problem would be 
the call something to do with front?



```
private struct RefCountedRangeReturnType(R)
{
import std.typecons : RefCounted;
private RefCounted!R r;
auto empty() { return r.refCountedPayload.empty; }
auto front() { return r.refCountedPayload.front; }
void popFront() { r.refCountedPayload.popFront; }
auto save() { return 
typeof(this)(RefCounted!R(r.refCountedPayload.save)); }

}

auto refCountedRange(R)(R r)
{
import std.typecons : RefCounted;
return  RefCountedRangeReturnType!R(RefCounted!R(r));
}
```


Re: moveToGC

2021-05-12 Thread JG via Digitalmars-d-learn

On Monday, 10 May 2021 at 11:11:06 UTC, Mike Parker wrote:

On Monday, 10 May 2021 at 10:56:35 UTC, JG wrote:
The following compiles with dmd but not with ldc on 
run.dlang.io. Am I doing something wrong?


Please provide the error message(s) when asking questions like 
this. In this case:


```
onlineapp.d(15): Error: undefined identifier moveToGC
onlineapp.d(20): Error: undefined identifier moveToGC
```

Looks like moveToGC was added in 2.096:

https://github.com/dlang/druntime/commit/bf59d2dcc4eae068a37db169977eef3eb394cee6

Adding --version to the ldc command line at run.dlang.io shows 
it's running ldc 1.25.1, which is current with D 2.095.1.


Thank you.


  1   2   >