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.




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).


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?









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.


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);
  list.

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.


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: 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.


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: 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)));
```


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: 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: 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-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-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.


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?


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=&f;
ret.data= cast(void*) &s;
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*) &h;
(*cast(int delegate(int)*) ptr)(10).writeln;
d1(10).writeln;
h(10).writeln;
}
```



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).


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=&f;
ret.data= cast(void*) &s;
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*) &h;
(*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: Question on shapes

2022-05-17 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); }
}
```




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: 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.


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: 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`


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: 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.


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.



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: 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");

}
```


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 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.


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: 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.


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: 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: 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: 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?


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: 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.


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: typeof(func!0) != typeof(func!0())

2022-08-21 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());



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: 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.


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: 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: "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: 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: 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: 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: container vs standard array

2023-09-18 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




Tuple poilerplate code

2020-08-31 Thread JG via Digitalmars-d-learn
Is there anyway to remove the boilerplate code of dealing with 
tuples:


I find myself having to write things like this fairly often

auto someRandomName  = f(...); //where f returns a tuple with two 
parts

auto firstPart = someRandomName[0];
auto secondPart = someRandomName[1];


Is to possible to write something so that the above is 
essentially equivalent to:


assignTuple!(firstPart,secondPart) = f(...);

The closest I can produce is using a template mixin so that I 
would have to write:


mixin AssignTuple!(()=>f(...),"firstPart","secondPart");


Re: Tuple poilerplate code

2020-09-01 Thread JG via Digitalmars-d-learn

On Tuesday, 1 September 2020 at 03:51:10 UTC, user1234 wrote:

On Tuesday, 1 September 2020 at 02:08:54 UTC, JG wrote:
Is there anyway to remove the boilerplate code of dealing with 
tuples:


I find myself having to write things like this fairly often

auto someRandomName  = f(...); //where f returns a tuple with 
two parts

auto firstPart = someRandomName[0];
auto secondPart = someRandomName[1];


Is to possible to write something so that the above is 
essentially equivalent to:


assignTuple!(firstPart,secondPart) = f(...);

The closest I can produce is using a template mixin so that I 
would have to write:


mixin AssignTuple!(()=>f(...),"firstPart","secondPart");


---
void assignTuple(S, T...)(auto ref S s, auto ref T t)
{
static foreach (i; 0 .. S.length)
t[i] = s[i];
}

void main()
{
import std;
string a,b;
tuple("a", "b").assignTuple(a,b);
}
---
Thanks for your answer. That helps somewhat, however it is still 
longer and less clear than one would ideally want. In addition 
you need to use explicit types.




Re: Tuple poilerplate code

2020-09-01 Thread JG via Digitalmars-d-learn

Thank you all for the interesting suggestions.


Re: get element index when using each!(x)

2020-09-16 Thread JG via Digitalmars-d-learn

On Thursday, 17 September 2020 at 00:51:54 UTC, dangbinghoo wrote:

hi,

is there any way to get the index for an element when iteration 
using each!(x)?


 I know I can do this using foreach statement, but I prefer 
using the each template.


---
string s = "hello";
foreach(i, c; s) {
}
--

how can I get to ?


Thanks!

binghoo dang


Perhaps there are other ways, but you can use enumerate. For 
example

---
import std.algorithm;
import std.range;
import std.stdio;
void main() {
 string s = "hello";
 s.enumerate.each!(x=>writeln(x[0],":",x[1]));
}
---
Produces
---
0:h
1:e
2:l
3:l
4:o
---


Re: Tuple poilerplate code

2020-09-18 Thread JG via Digitalmars-d-learn

On Wednesday, 2 September 2020 at 03:52:55 UTC, JG wrote:

Thank you all for the interesting suggestions.


Still thinking about this from time to time.

Other than the suggestions given, this is what I have
been playing around with.

-
import std.stdio;
import std.typecons : tuple;


mixin template assignTuple(alias vars, alias tupleFunc)
{
 import std.conv : to;
 auto tmp = tupleFunc();
 static foreach (i, var ; vars)
 {
  mixin("auto " ~ var ~ " = tmp[" ~ i.to!string ~ "];");
 }
}

auto f(int n) { return tuple(n, n+1, n+2, "A string here"); }

void main()
{
 mixin assignTuple!(["x","y","z", "str"],()=>f(3));
 writeln(x," ",y," ", z," \'",str,"\'");
}

-
produces
-
3 4 5 'A string here'
-
I have a few questions:

1. Is the above code "bad" for some reason?
2. Is there a way of "hiding" tmp used in the mixin, so that it 
is not visible in main?





vibe.d get body of HTTPServerResponse

2020-11-02 Thread JG via Digitalmars-d-learn

I am trying to get the body the response generated by:

res.render!("index.dt");

where res is of type HTTPServerResponse

Does anyone know how I might go about this?



Re: vibe.d get body of HTTPServerResponse

2020-11-02 Thread JG via Digitalmars-d-learn
On Monday, 2 November 2020 at 17:02:01 UTC, Steven Schveighoffer 
wrote:

On 11/2/20 10:10 AM, JG wrote:

I am trying to get the body the response generated by:

res.render!("index.dt");

where res is of type HTTPServerResponse

Does anyone know how I might go about this?



That is a convenience wrapper to diet-ng:

https://github.com/vibe-d/vibe.d/blob/70b50fdb9cd4144f1a5007b36e6ac39d4731c140/http/vibe/http/server.d#L337-L346

Instead, create your own output range (maybe a char[] 
appender?) and compile to that yourself:


import diet.html : compileHTMLDietFile;
import std.array : appdender;

auto app = appender!(char[]);
compileHTMLDietFile!("index.dt")(app);

auto resultingHTML = app.data;

-Steve


Thank you very much.


Profiling

2021-02-08 Thread JG via Digitalmars-d-learn
I was trying to profile a d program. So I ran: dub build 
--build=profile. I then ran the program and it produced trace.log 
and trace.def. I then ran d-profile-viewer and got the following 
error:


std.conv.ConvException@/home/jg/dlang/ldc-1.24.0/bin/../import/std/conv.d(2382):
 Unexpected '-' when converting from type char[] to type ulong

??:? [0x564a8630fda5]
??:? [0x564a86333286]
??:? [0x564a863199fd]
/home/jg/dlang/ldc-1.24.0/bin/../import/std/conv.d:2382 
[0x564a862c89a1]
/home/jg/dlang/ldc-1.24.0/bin/../import/std/conv.d:1941 
[0x564a862c86cc]
/home/jg/dlang/ldc-1.24.0/bin/../import/std/conv.d:223 
[0x564a862c869c]

app.d:1095 [0x564a862cdd71]
app.d:1138 [0x564a862ce7ba]
??:? [0x564a863196cb]
??:? [0x564a863195c7]
??:? [0x564a8631941d]
/home/jg/dlang/ldc-1.24.0/bin/../import/core/internal/entrypoint.d:42 
[0x564a862ce7e4]
??:? __libc_start_main [0x7fd482807cb1]

Is d-profile-viewer no longer working? Or did I do something 
wrong?


Re: Profiling

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

On Tuesday, 9 February 2021 at 18:33:16 UTC, drug wrote:

On Tuesday, 9 February 2021 at 07:45:13 UTC, JG wrote:
I was trying to profile a d program. So I ran: dub build 
--build=profile. I then ran the program and it produced 
trace.log and trace.def. I then ran d-profile-viewer and got 
the following error:


std.conv.ConvException@/home/jg/dlang/ldc-1.24.0/bin/../import/std/conv.d(2382):
 Unexpected '-' when converting from type char[] to type ulong


I'm guessing only but it looks like slurp is used to read text 
output but the format used does not correspond to the real data 
format.


Thanks for the suggestions. However, I would prefer not to spend 
time trying to debug d-profile-viewer at the moment.


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


vibe.d selectively include attribute into tag using diet template

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

Hi,

I know that one can do the following:
tag(attribute='#{dexpression}')

But, is there a way to deal with attributes that don't get 
assigned values.

That is, is there a way to produce

or

depending on a boolean variable?

Of course one can do:
- if (booleanVariable)
 tag(attribute)
  include ...
- if (!booleanVariable)
 tag
  include ...

But this seems rather messy.


Re: vibe.d selectively include attribute into tag using diet template

2021-02-27 Thread JG via Digitalmars-d-learn
On Saturday, 27 February 2021 at 19:12:55 UTC, Steven 
Schveighoffer wrote:


Yes, if you assign a boolean value to it directly, then if 
true, the attribute is included, if not, it's not.


e.g.:

tag(attribute=booleanVariable)

Note the lack of quotes.


Thank you very much for this.


If you use an expression without quotes
in diet, it becomes an interpolation.


Would you mind explaining in more detail what this means? How 
could one use this, other than with booleans?


Re: vibe.d selectively include attribute into tag using diet template

2021-03-01 Thread JG via Digitalmars-d-learn
On Sunday, 28 February 2021 at 18:10:26 UTC, Steven Schveighoffer 
wrote:

On 2/28/21 12:29 AM, JG wrote:
On Saturday, 27 February 2021 at 19:12:55 UTC, Steven 
Schveighoffer wrote:


If you use an expression without quotes
in diet, it becomes an interpolation.


Would you mind explaining in more detail what this means? How 
could one use this, other than with booleans?


So if you have an expression as the right side of an attribute 
assignment, it is treated as a D expression, which is then 
evaluated and turned into string form.


So e.g. your original example:

tag(attribute='#{dexpression}')

can be written as:

tag(attribute=dexpression)

-Steve


Thanks



Local library with dub

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

Hi

I want to put some code together in a local library that is then 
used by several other projects. I am running into a few problems. 
Firstly when I try and configure the code to be a library (dub 
init, add d files to source, and remove source/app.d - perhaps 
this wrong) dub test no longer seems to work?


Secondly I am having problems getting dub to add the library code 
to other projects. It seems to work if I run dub add-local 
path/to/library and then add the appropriate dependencies to the 
projects dub.json file. However, I didn't manage to find 
documentation that explains exactly how this should work. Also 
there seems to be some mention getting this to work with versions 
(in the documentation about dub add-path), which I couldn't 
follow.


Does anyone know in more detail how this works or how I can find 
out?


Re: Local library with dub

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

On Tuesday, 20 April 2021 at 18:11:18 UTC, Andre Pany wrote:

On Tuesday, 20 April 2021 at 17:15:15 UTC, JG wrote:

Hi

I want to put some code together in a local library that is 
then used by several other projects. I am running into a few 
problems. Firstly when I try and configure the code to be a 
library (dub init, add d files to source, and remove 
source/app.d - perhaps this wrong) dub test no longer seems to 
work?


Secondly I am having problems getting dub to add the library 
code to other projects. It seems to work if I run dub 
add-local path/to/library and then add the appropriate 
dependencies to the projects dub.json file. However, I didn't 
manage to find documentation that explains exactly how this 
should work. Also there seems to be some mention getting this 
to work with versions (in the documentation about dub 
add-path), which I couldn't follow.


Does anyone know in more detail how this works or how I can 
find out?


You need to add 2 configurations. The first configuration is 
used automatically when you execute `dub build`. Just name the 
config `debug` with targetType `library`. Add a second 
configuration with name `unittest` and targetType `executable` 
and attribute `mainSourceFile` pointing to a module containing 
your main function for your test. For example name this module 
`testapp.d`.
The module `testapp.d` you need to exclude in your 
configuration `debug` using attribute `excludeSourceFiles`.


The configuration `unittest` is automatically used when you 
execute `dub test`.


Kind regards
Andre


Thank you very much. In case someone wants more specific 
instructions:

(a) add a file source/test.d containing:
void main(){}
(b) add configurations to dub.json:
"configurations": [
 { "name": "debug",
   "excludedSourceFiles": ["source/test.d"],
   "targetType": "library"},
 { "name": "unittest",
   "mainSourceFile": "source/test.d",
   "targetType": "executable"}]

This still leaves open the question of how to include a version 
of such a library in another project via dub.


Re: Local library with dub

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

On Wednesday, 21 April 2021 at 00:39:41 UTC, Mike Parker wrote:

On Tuesday, 20 April 2021 at 18:43:28 UTC, JG wrote:



This still leaves open the question of how to include a 
version of such a library in another project via dub.


Execute `dub add-local` followed by the path to the project's 
root directory (the directory containing the `dub.json/sdl`) 
and a version number in semver format.


```
dub add-local path 0.1.0
```

Then you can use the package just as you would any other dub 
dependency.


Thanks. I suppose this means that if you want to able to use 
multiple versions you have to keep each version in a separate 
directory and add them individually, and there is no way of being 
able to get the appropriate version from say a git repository?


Re: Local library with dub

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

On Wednesday, 21 April 2021 at 19:15:19 UTC, Jordan Wilson wrote:

On Wednesday, 21 April 2021 at 15:07:25 UTC, JG wrote:

On Wednesday, 21 April 2021 at 00:39:41 UTC, Mike Parker wrote:

[...]


Thanks. I suppose this means that if you want to able to use 
multiple versions you have to keep each version in a separate 
directory and add them individually, and there is no way of 
being able to get the appropriate version from say a git 
repository?


You can specify git repos as dependencies, if this helps.
https://dlang.org/changelog/2.094.0.html#git-paths

Jordan

Thanks, I will see if I can use this.



moveToGC

2021-05-10 Thread JG via Digitalmars-d-learn
The following compiles with dmd but not with ldc on run.dlang.io. 
Am I doing something wrong?



import core.memory;

void main()
{

struct S
{
int x;
this(this) @disable;
~this() @safe pure nothrow @nogc {}
}

S* p;

// rvalue
p = moveToGC(S(123));
assert(p.x == 123);

// lvalue
auto lval = S(456);
p = moveToGC(lval);
assert(p.x == 456);
assert(lval.x == 0);


}


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.


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: 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.





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: 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: 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.


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?


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


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"?





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?


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.


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?




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



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.


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).




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-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 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: 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: 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: 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 = &func;
createLowLevelThread(&func, 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 = &func;
pragma(msg,typeof(&func));
pragma(msg,typeof(f));
createLowLevelThread(&func, 2<<30);//works
//createLowLevelThread(f, 2<<30);// doesn't  work!!
}
```



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: 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.


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: 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 &x;

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

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 &v 
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?








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)(&s.x);
   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-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.


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: 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?






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: 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?


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: 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?


  1   2   >