Re: bool passed by ref, safe or not ?

2024-06-04 Thread Paul Backus via Digitalmars-d-learn

On Tuesday, 4 June 2024 at 16:58:50 UTC, Basile B. wrote:

```d
void main(string[] args)
{
ushort a = 0b;
bool* b = cast(bool*)&a;
setIt(*b);
assert(a == 0b); // what actually happens
assert(a == 0b1110); // what would be safe
}
```


[...]


Do I corrupt memory here or not ?
Is that a safety violation ?


`cast(bool*)&a` is a safety violation.

The only [safe values][1] for a `bool` are 0 (false) and 1 
(true). By creating a `bool*` that points to a different value, 
you have violated the language's safety invariants. Because of 
this, operations that would normally be safe (reading or writing 
through the `bool*`) may now result in undefined behavior.


[1]: https://dlang.org/spec/function.html#safe-values


Re: Associative Array, get value instead of poiter using `if (auto ..)`, possible?

2024-08-31 Thread Paul Backus via Digitalmars-d-learn

On Saturday, 31 August 2024 at 22:06:26 UTC, kdevel wrote:

Is that functionally different from

```
void main()
{
import std.stdio;

int[string] test = ["hello": 42];

if (auto p = "hello" in test)
{
writeln("hello => ", *p);
}
}
```


It's essentially the same. I only suggested it because the 
original question was about alternatives to pointers, and 
`Nullable` isn't a pointer.


I suppose it goes to show that avoiding language features just 
for the sake of it ("no pointers", "no templates", "no imports", 
...) is unlikely to accomplish anything useful. :)


Re: Associative Array, get value instead of poiter using `if (auto ..)`, possible?

2024-08-31 Thread Paul Backus via Digitalmars-d-learn

On Saturday, 31 August 2024 at 12:47:25 UTC, ryuukk_ wrote:

```D
void main()
{
int[string] test;

test["hello"] = 42;

if (auto it = "hello" in test)
{

}

}
```
Is there a way to get the value instead of a pointer? while 
keeping the conciseness (one line)


Once the next release of Phobos comes out, with [PR 9039][1] 
merged, you'll be able to do it like this:


```d
import std.typecons;

Nullable!V maybeGet(K, V)(V[K] aa, K key)
{
if (auto ptr = key in aa)
return nullable(*ptr);
else
return Nullable!V.init;
}

void main()
{
import std.stdio;

int[string] test = ["hello": 42];

if (auto it = test.maybeGet("hello"))
{
writeln("hello => ", it.get);
}
}
```

[1]: https://github.com/dlang/phobos/pull/9039


Re: Is it possible to use templates to implement something like the `@show` macro from the Julia programming langauge in D?

2024-09-08 Thread Paul Backus via Digitalmars-d-learn

On Sunday, 8 September 2024 at 22:01:10 UTC, WraithGlade wrote:
Basically, I want there to be a way to print both an expression 
and its value but to only have to write the expression once 
(which also aids refactoring). Such a feature is extremely 
useful for faster print-based debugging.


Thus, instead of having to write something like this:

```
writeln("1 + 2 == ", 1 + 2);
```

I want to just be able to write this:

```
show!(1 + 2)
```


The only way to write a macro in D that executes code in the 
scope where the macro is *invoked* (rather than the scope where 
it's *defined*) is to use a `mixin`:


```d
enum show(string expr) = `writeln(q"(` ~ expr ~ `)", " == ", ` ~ 
expr ~ `);`;


void main()
{
import std.stdio;

mixin(show!"1 + 2"); // 1 + 2 == 3

const int x = 1 + 2;
mixin(show!"x"); // x == 3
}
```


Re: Is it possible to use templates to implement something like the `@show` macro from the Julia programming langauge in D?

2024-09-08 Thread Paul Backus via Digitalmars-d-learn

On Sunday, 8 September 2024 at 23:01:22 UTC, monkyyy wrote:

On Sunday, 8 September 2024 at 22:01:10 UTC, WraithGlade wrote:

I want to just be able to write this:

```
show!(1 + 2)
```


```d
void show(string s)(){
  auto res=mixin(s);
  writeln(s,"==",res);
}

show!"1+2";
```


This works for `show!"1+2"`, but it won't work for `show!"x"`, 
because `x` is not visible inside the body of the `show` function.


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

2022-03-29 Thread Paul Backus via Digitalmars-d-learn

On Tuesday, 29 March 2022 at 19:55:52 UTC, Andrey Zherikov wrote:
I have a function below (just an example). What's the 
recommended way to unit-test it for all `version` cases?

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

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


Probably the easiest way is to split it into two functions

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

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

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

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


Re: Good to the last drop.

2022-03-31 Thread Paul Backus via Digitalmars-d-learn

On Thursday, 31 March 2022 at 19:44:23 UTC, WhatMeWorry wrote:
Is there a way to programmatically determine the exact maximum 
memory size available to the DRuntime’s array implementation?


Closest you can get is probably [`GC.stats`][1], which will give 
you the total amount of free memory available to the GC.


If what you actually want to do is attempt to grow an array 
without crashing if there isn't enough memory, you can use 
[`GC.extend`][2]. There's an example in the linked documentation 
that shows how to do it.


[1]: https://druntime.dpldocs.info/core.memory.GC.stats.html
[2]: https://druntime.dpldocs.info/core.memory.GC.extend.html


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

2022-04-02 Thread Paul Backus via Digitalmars-d-learn

On Saturday, 2 April 2022 at 14:49:15 UTC, Vijay Nayar wrote:

On Saturday, 2 April 2022 at 14:35:10 UTC, Vijay Nayar wrote:
The `tryMatch` method fails to compile, and instead I get the 
following error:

```d
/dlang/dmd/linux/bin64/../../src/phobos/std/sumtype.d(2004): 
Error: static assert:  "`handlers[0]` of type `int 
function(ref ubyte[] _1, ref ubyte[] _2) pure nothrow @nogc 
@safe` never matches"

```


Through sheer trial and error, I discovered that changing the 
handler arguments from `ref ubyte[]` to `const ref ubyte[]` the 
error goes away. However, I did not find any information in the 
documentation or code that made this requirement clear. It was 
basically a guess based on the fact that `string` has no 
trouble but `ubyte[]` did, and string is basically just 
`immutable(char[])`.


The reason `const` is required is that the arguments to your 
function, `v1` and `v2`, are `const`. In D, the `const` qualifier 
is transitive, so if you have a `const VarType`, whatever value 
it contains will also be qualified with `const`.


So far, I'm finding that learning to use `SumType` is 
significantly more cryptic than `Variant`, by a large margin. 
I'll still give it a shot of course, because I want to get past 
this problem.


It's possible to get more informative error messages using the 
`-verrors=spec` compiler flag, although it's a bit of a hassle. 
The basic process is


1. Recompile the module that the error occurs in with 
`-verrors=spec` and redirect output to a file.


```
dmd -verrors=spec -c source/mymodule.d >verrors.txt 2>&1
```

2. Use `grep` or your text editor's search function to find 
errors that occurred in that source file or in `sumtype.d`.


```
grep -e 'source/mymodule.d' -e 'std/sumtype.d' verrors.txt
```

Following these steps on your example code yields around 20 lines 
of output, which includes the "real" error message:


```
(spec:1) /usr/include/dmd/phobos/std/sumtype.d(1768): Error: 
function literal `__lambda3(ref ubyte[] _1, ref ubyte[] _2)` is 
not callable using argument types `(const(ubyte[]), 
const(ubyte[]))`
(spec:1) /usr/include/dmd/phobos/std/sumtype.d(1768):
cannot pass argument `_param_0` of type `const(ubyte[])` to 
parameter `ref ubyte[] _1`

```


Re: Const Variables

2022-04-03 Thread Paul Backus via Digitalmars-d-learn

On Sunday, 3 April 2022 at 13:50:28 UTC, Salih Dincer wrote:

Hi all,

Do you have a good example of how const variables actually work?

So I'm not talking about system resources and programming 
errors.  I want to say it's good.  Because if everything works 
without it, why does it exist?


This is covered in the const FAQ:

https://dlang.org/articles/const-faq.html


Re: I want to append to lists without using append

2022-04-04 Thread Paul Backus via Digitalmars-d-learn

On Monday, 4 April 2022 at 12:57:28 UTC, V3nom wrote:

define the lists:

(define liste (cons 10(cons 20(cons 30(cons 40 ' ())
(define liste2 (cons 20(cons 30(cons 10(cons 40 ' ())


define the "function":

(define (listapp list1 list2)(
 if (null? (cdr list1))
(cons (car list1) (listapp list2 (cdr list1)))
  (if (null? (cdr list2))
  (cons (car list2) (cdr list2))
(cons (car list1) (listapp (cdr list1)  list2))
  )))

append them:

(listapp liste liste2)

What do i do wrong? i think this should work but it is giving 
me an error message like:mcdr: contract violation expected: 
mpair? given: ()


In this line:

if (null? (cdr list1))

...it is possible for list1 itself to be null. If that happens, 
the call to cdr will fail with an error. Before calling car or 
cdr on a list, you must first check to see if the list is null.


Your code contains several other instances of the same error. 
I'll let you find them on your own. :)


Re: Removing elements from dynamic arrays?

2022-04-05 Thread Paul Backus via Digitalmars-d-learn
On Tuesday, 5 April 2022 at 14:10:44 UTC, Steven Schveighoffer 
wrote:

I'd implement it probably like this (for D2):

```d
auto drop(T)(ref T[] arr, T which)
{
   import std.algorithm, std.range;
   auto f = arr.find(which);
   debug if(f.empty) throw ...;
   auto result = arr.front;
   arr = arr.remove(&f[0] - &arr[0]); // god I hate this
   return result;
}
```


I think you can get rid of the ugly pointer arithmetic using 
`countUntil`:


```d
auto drop(T)(ref T[] arr, T which)
{
import std.algorithm, std.range, std.exception;

auto i = arr.countUntil(which);
debug enforce(i < arr.length, "Not found");
auto result = arr[i];
arr = arr.remove(i);
return result;
}
```


Re: Why do immutable variables need reference counting?

2022-04-11 Thread Paul Backus via Digitalmars-d-learn

On Monday, 11 April 2022 at 12:12:39 UTC, Salih Dincer wrote:

It worked for me in a different way.


1 is (about to be) alive!

2 is (already) dead.
2 is (already) dead.
2 is (already) dead.


2 is (already) dead.

2 is (already) dead.
Hello D!
1 is (already) dead.

Because I changed the code like this.

```d

struct S
{
  . . .

  string toString() { return ""; }
}

//S test(inout S s)/*
S test(S s)//*/
{
  s.i = 2;
  return s;
}

void main()
{
  immutable s = S(1);
  test(s).writeln;
  "Hello".writefln!"%s D!";
}
```

If the inout is set, it does not allow compilation.


Because `S` does not contain any pointers or references, you are 
allowed to create a mutable *copy* of an `S` from an `immutable` 
source. That's what happens when you pass it to `test`.


The extra destructor calls come from the copies made by `test` 
and `writeln`. If you add a copy constructor, you can see this 
happening in the output:


```d
struct S {

/* ... */

this(ref inout typeof(this) other) inout {
this.i = other.i;
writeln(i, " was copied.");
}
}
```

```
1 is (about to be) alive!
1 was copied.
2 was copied.
2 is (already) dead.
2 was copied.
2 was copied.
2 was copied.
2 is (already) dead.
2 is (already) dead.

2 is (already) dead.
2 is (already) dead.
Hello D!
1 is (already) dead.
```

1 constructor call + 5 copies = 6 destructor calls.


Re: Collect the arguments of all the function calls at a compile time in the whole program.

2022-04-15 Thread Paul Backus via Digitalmars-d-learn

On Friday, 15 April 2022 at 18:11:11 UTC, BoQsc wrote:

Let's say I have this example program.
I want to get the arguments of all the `some_function();` in 
the whole program.
**Even if the scope of the function call is never executed.** 
(Ex. due to IF statement being negative.)


You can't do this with any of D's built-in introspection features 
(like `__traits`), because those features have no way of looking 
inside functions.


However, you can probably write a program to do this using the 
DMD frontend as a library.


Dub package (use the `dmd:frontend` subpackage): 
https://code.dlang.org/packages/dmd

Documentation: https://dlang.org/library/dmd/frontend.html

Unfortunately the documentation is somewhat incomplete, so you 
may need to spend some time reading the source code to figure out 
how it all works. Don't hesitate to ask if you have any questions.


Re: Calling template member function?

2022-04-19 Thread Paul Backus via Digitalmars-d-learn

On Tuesday, 19 April 2022 at 13:36:26 UTC, Andrey Zherikov wrote:
I want to migrate my library API from standalone function that 
takes delegate as argument to a template member function that 
takes delegate as a template parameter but compiler errors out. 
Here is code example:

```d
import std.stdio;

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

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

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

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

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

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

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

```

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


The message is different, but I think this error is probably 
related to the "dual context" issue:


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

Basically, `f_new!(() => func())` has two scopes that it "wants" 
to be nested in: `T!int` and `f!(void function() @safe)`. When 
you remove `template T`, there's only one scope, so it's not a 
problem.


If you remove `static` from `f_new`, you get an error message 
talking about this explicitly:


```
onlineapp.d(5): Deprecation: function `onlineapp.f!(void 
function() @safe).f.f_new!(delegate () @safe

{
(*func)();
return ;
}
).f_new` function requires a dual-context, which is deprecated
onlineapp.d(13):instantiated from here: `f_new!(delegate 
() @safe

{
(*func)();
return ;
}
)`
onlineapp.d(18):instantiated from here: `f!(void 
function() @safe)`
onlineapp.d(13): Error: function `onlineapp.f!(void function() 
@safe).f.f_new!(delegate () @safe

{
(*func)();
return ;
}
).f_new` is a nested function and cannot be accessed from 
`onlineapp.f!(void function() @safe).f`

```


Re: unexpected noreturn behavior

2022-04-21 Thread Paul Backus via Digitalmars-d-learn

On Thursday, 21 April 2022 at 12:54:12 UTC, Dennis wrote:

On Thursday, 21 April 2022 at 12:41:08 UTC, WebFreak001 wrote:
which I think is a little bug-prone, but at least that would 
solve my issues.


What issue do you have with it returning `true`?


Presumably the problem is that if you write something like 
`assert(0).match!();`, you get a spew of compiler errors, on 
account of the fact that `match` assumes anything that satisfies 
`isSumType` has properties like `Types` and `get!T`.




Re: Understanding alias template parameters

2022-04-21 Thread Paul Backus 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?


}
```


When you write a lambda without type annotations, like `x => 
2*x`, the compiler interprets it as a function template. So in 
this case, it's the same as if you'd written


```d
T func(T)(T x) { return 2*x; }
iota(10).myMap!func.writeln;
```

The problem is, you can't store a template in a variable:

```d
auto f = func; // doesn't work - func does not have a value
```

So, when you try to create a `MapResult` with the template `x => 
2*x` as one of its member variables, it doesn't work.


By the way, you may have noticed that the error message you got 
says something about variables of type `void` not being allowed. 
That's because of [a long-standing bug][1] that causes `typeof` 
returns `void` when applied to a template. However, that bug is 
not the cause of the error here--even if it were fixed, your code 
still would not work.


[1]: https://issues.dlang.org/show_bug.cgi?id=7947


Re: std.typecons Typedef initializers?

2022-04-25 Thread Paul Backus via Digitalmars-d-learn

On Monday, 25 April 2022 at 08:54:52 UTC, Chris Katko wrote:

D
alias sPair = Typedef!pair; // pair of xy in screen space 
coordinates
alias vPair = Typedef!pair; // pair of xy in viewport space 
coordinates

//etc



This doesn't do what you think it does. Both `sPair` and `vPair` 
are the same type. If you want to create two distinct `Typedef`s 
from the same base type, you must use the optional `cookie` 
argument, as shown in [the examples in the documentation:][1]


```d
alias MoneyEuros = Typedef!(float, float.init, "euros");
alias MoneyDollars = Typedef!(float, float.init, "dollars");

// The two Typedefs are _not_ the same type.
static assert(!is(MoneyEuros == MoneyDollars));
```

[1]: 
https://phobos.dpldocs.info/std.typecons.Typedef.html#examples


Re: Compile delegate with enum into proper function?

2022-05-07 Thread Paul Backus via Digitalmars-d-learn

On Saturday, 7 May 2022 at 18:36:40 UTC, jmh530 wrote:
In the code below, there is a two parameter function `foo` and 
an override of it with only one parameter. In the override 
case, I force the second one to be 1, but ideally there should 
be a way to specify it at compile-time.


Have you tried [`std.functional.partial`][1]? Using it, your 
example could be written like this:


```d
import std.functional: partial;

enum int a = 1;
alias foo2 = partial!(foo, a);
```

Or, if `a` absolutely has to be the second argument, you can 
combine it with [`std.functional.reverseArgs`][2]:


```d
import std.functional: partial, reverseArgs;

enum int a = 1;
alias foo2 = partial!(reverseArgs!foo, a);
```

[1]: https://phobos.dpldocs.info/std.functional.partial.html
[2]: https://phobos.dpldocs.info/std.functional.reverseArgs.html


Re: Compile delegate with enum into proper function?

2022-05-07 Thread Paul Backus via Digitalmars-d-learn

On Saturday, 7 May 2022 at 20:24:39 UTC, jmh530 wrote:

On Saturday, 7 May 2022 at 18:46:03 UTC, Paul Backus wrote:

```d
import std.functional: partial;

enum int a = 1;
alias foo2 = partial!(foo, a);
```

[snip]


Thanks. This is basically equivalent to

```d
int foo(int a)(int x) { return x + a; }
alias foo2 = foo!a;
```

The downside is that you wouldn't be able to `alias foo = 
foo!a`.


Worth noting that you *can* write

```d
alias foo = partial!(foo, a);
```

...which will add the partially-applied version to `foo`'s 
overload set.


Re: What are (were) the most difficult parts of D?

2022-05-11 Thread Paul Backus via Digitalmars-d-learn

On Wednesday, 11 May 2022 at 15:10:28 UTC, Tejas wrote:
That'll be true the day when `@safe` becomes the default... 
Until then, I'll atleast do `@safe:` on top of every module :)


`@safe:` is actually a bad idea if you're writing templated code, 
because it turns inference of `@system` into a compile-time error:


```d
@safe:

auto map(alias fun, T)(T[] arr)
{
auto result = arr.dup;
foreach (ref e; result) e = fun(e);
return result;
}

int safeDouble(int n) @safe { return 2*n; }
int systemDouble(int n) @system { return 2*n; }

void main() @system
{
int[] a = [1, 2, 3];
// ok
auto b = a.map!safeDouble;
// Error: `@safe` function `map!systemDouble` cannot call 
`@system` function `systemDouble`

auto c = a.map!systemDouble;
}
```

Without `@safe:` at the top, `map!systemDouble` would have been 
inferred as `@system`, and calling it from a `@system` `main` 
function would have been allowed.


Re: What are (were) the most difficult parts of D?

2022-05-12 Thread Paul Backus via Digitalmars-d-learn

On Thursday, 12 May 2022 at 18:07:05 UTC, H. S. Teoh wrote:
On Thu, May 12, 2022 at 09:04:09AM -0700, Ali Çehreli via 
Digitalmars-d-learn wrote:
Error: template `std.algorithm.iteration.sum` cannot deduce 
function from

argument types `!()(int[3])`
/usr/include/dlang/dmd/std/algorithm/iteration.d(7234): 
Candidates are:

`sum(R)(R r)`
  with `R = int[3]`
  must satisfy the following constraint:
`   isInputRange!R`

WHAT? :) But the clue is on the last line above.

[...]

Seriously though, that error message is horrendously ugly.  I 
mean I've seen it thousands of times by now, so I know what it 
means and where to look for the actual problem. But it's 
eminently unfriendly to someone who doesn't already know the 
language very well.


Good news: starting from DMD 2.099, this error message has been 
reworded. Instead of "cannot deduce function...". it now says:


Error: none of the overloads of template 
`std.algorithm.iteration.sum` are callable using argument types 
`!()(int[3])`


Re: Why (v1<<8 + v2) different from (v1<<8 | v2)?

2022-05-25 Thread Paul Backus via Digitalmars-d-learn

On Wednesday, 25 May 2022 at 12:42:04 UTC, step8 wrote:

I run following test code:
  int v1 = 22;
  int v2 = 23;
  writeln( v1<<8 + v2 );  
  writeln( v1<<8 | v2 );

result is 0 and 5655
Why ( v1<<8 + v2 ) = 0 ?


`+` has a higher precedence than `<<`, so the first line is 
actually `v1 << (8 + v2)`.


Re: Inferred attributes errors in template function.

2022-05-27 Thread Paul Backus via Digitalmars-d-learn

On Friday, 27 May 2022 at 08:39:08 UTC, vit wrote:

Is in dmd some flag that print errors similarly to this?:

```d
void main()@safe pure{
foo!long();
foo!float();
	//Error: `pure` function `D main` cannot call impure 
function `onlineapp.foo!float.foo`
	//Error: potentially `pure` function 
`onlineapp.foo!float.foo` cannot call impure function 
`onlineapp.bar!float.bar`
	//Error: potentially `pure` function 
`onlineapp.bar!float.bar` cannot access mutable static data `i`

```


No, there is nothing like this, at least not yet. It's being 
worked on, though.


https://github.com/dlang/dmd/pull/13957
https://github.com/dlang/dmd/pull/12383


Re: Templatized delegates

2022-05-31 Thread Paul Backus via Digitalmars-d-learn

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

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


If you want compile-time polymorphism, three's no other way. If 
you're ok with runtime polymorphism, you could replace S with 
something like an interface or a sum type. For example:


```d
import std.stdio;

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

interface I
{
void doSomething(int value);
}

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

alias DG = void delegate (I i);

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

struct R
{
DG dg;

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

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

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


Re: Graphing a D function : possible?

2022-06-02 Thread Paul Backus via Digitalmars-d-learn

On Thursday, 2 June 2022 at 03:37:13 UTC, z wrote:
Is there a quick way of obtaining the graph of D functions like 
these?

```d
T f(T) if (isScalarType!T){}
```
or
```D
T[2] f(T, T)if (isScalarType!T){}
```
I know that there are graphing calculators already, but these 
don't support low level black magic like int <-> float 
conversions and i'm lost because there is no way to know if the 
code i write is correct without a graph or trial and error, 
hence the question.


Many thanks


Probably the easiest way would be to run the function on a bunch 
of different inputs, and plot the input-output pairs as 2D or 3D 
points. Pretty much any plotting software should be able to 
handle a list of points.


Re: Comparing Exceptions and Errors

2022-06-04 Thread Paul Backus via Digitalmars-d-learn

On Saturday, 4 June 2022 at 11:57:32 UTC, kdevel wrote:
2. Since 2017 or so I have written some 10 KLOC of D, maybe 
about two dozen
   classes deriving from Exception. But I did not annotate any 
of my methods or
   function with "nothrow" nor did I author any class deriving 
from `Error`.


   What does that mean? Am I `Error` blind?


Generally you do not need to subclass `Error` yourself. The most 
common way of throwing an `Error` in user code is to use 
`assert`, which (with default compiler flags) throws an 
`AssertError` on failure. Function contracts and struct/class 
invariants work the same way.


3. Can you provide some piece of code which *must* throw 
`Error` and cannot

   throw an appropriate Exception?


This is entirely a question of API design. If it should be the 
caller's responsibility to check for some condition before 
calling the function, then you can throw an `Error` when that 
condition does not hold (or more likely, use an `assert` or an 
`in` contract to check for it). If it should be the callee's 
responsibility to check, you should throw an `Exception` (or use 
`enforce`).


Re: Comparing Exceptions and Errors

2022-06-04 Thread Paul Backus via Digitalmars-d-learn

On Saturday, 4 June 2022 at 22:03:08 UTC, kdevel wrote:

On Saturday, 4 June 2022 at 14:05:14 UTC, Paul Backus wrote:
This is entirely a question of API design. If it should be the 
caller's responsibility to check for some condition before 
calling the function, then you can throw an `Error` when that 
condition does not hold (or more likely, use an `assert` or an 
`in` contract to check for it).


Provided one does not catch `Error`s this means one has to 
isolate such an API design by using a subprocess. This is what 
one usually tries to avoid.


See here:

http://joeduffyblog.com/2016/02/07/the-error-model/#bugs-arent-recoverable-errors

And also the following section:

http://joeduffyblog.com/2016/02/07/the-error-model/#reliability-fault-tolerance-and-isolation

If it should be the callee's responsibility to check, you 
should throw an `Exception` (or use `enforce`).


If the library always throws exceptions it can be used in both 
API "designs". In the case that the implementor of the caller 
expects `Error`s instead of `Exceptions` she could use a small 
wrapper which catches the Exceptions and rethrows them as 
`Error`s. Likewise for error codes.


Using contracts and invariants impedes this approach.


See here:

https://bloomberg.github.io/bde-resources/pdfs/Contracts_Undefined_Behavior_and_Defensive_Programming.pdf



Re: Copy Constructor

2022-06-05 Thread Paul Backus via Digitalmars-d-learn

On Sunday, 5 June 2022 at 18:50:13 UTC, Salih Dincer wrote:

On Sunday, 5 June 2022 at 15:45:17 UTC, Salih Dincer wrote:

Hi,

Let be the structure Foo that wraps an int pointer. Let's 
setup Foo in 3 different ways:

1. Foo one = Foo(1);
2. Foo two = 2;
3. [ Foo(3) ];


There is a fourth possibility:
```d
int[] arr = [ one, two, Foo(3), *(new Foo(4)) ];
```
The 1st, 2nd and 4th elements of array are copied, but the 3rd 
element is not. Could it have something to do with CTFE?

https://tour.dlang.org/tour/en/gems/compile-time-function-evaluation-ctfe


Since the 3rd element is an rvalue, it is moved into the array 
rather than copied.


Re: Range to Nullable conversion

2022-06-10 Thread Paul Backus via Digitalmars-d-learn

On Friday, 10 June 2022 at 17:22:53 UTC, Antonio wrote:
Can this code be written as a **simple** expression?  (without 
having to write helper methods).


```d
import std.range, std.typecons;

Nullable!(ElementType!R) maybeFront(R)(auto ref R r)
if (isInputRange!R)
{
if (r.empty)
return typeof(return)();
else
return nullable(r.front);
}

unittest
{
int[] a = [1, 2, 3];
int[] b;

assert(a.maybeFront == nullable(1));
assert(b.maybeFront.isNull);
}
```


Re: sha256 to bigint

2022-06-11 Thread Paul Backus via Digitalmars-d-learn

On Saturday, 11 June 2022 at 13:09:44 UTC, vc wrote:


Hello, is there any way to represnts a sha256 hash like 
2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824 in BigInt ?


I've try so far auto t = 
BigInt("2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824") and it gives me invalid digit


Just so you know, you can construct a `BigInt` directly from the 
raw bytes of a sha256 hash, without converting to a string first:


```d
import std.digest.sha, std.bigint;

ubyte[32] hash = sha256Of(whatever);
auto t = BigInt(false, hash[]); // sign + magnitude
```

Docs: https://phobos.dpldocs.info/std.bigint.BigInt.this.3.html


Re: Generating unique identifiers at compile time

2022-06-12 Thread Paul Backus via Digitalmars-d-learn

On Thursday, 9 June 2022 at 21:20:27 UTC, JG wrote:
In doing so I wanted to produce unique identifiers (something 
like gensym in racket.) I did this in a very hacky way:

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


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


Re: Failure due to memcpy being called at compile time

2022-06-13 Thread Paul Backus via Digitalmars-d-learn

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


Re: getSymbolsByUDA in constructor/member functions

2022-06-16 Thread Paul Backus via Digitalmars-d-learn

On Thursday, 16 June 2022 at 13:27:25 UTC, frame wrote:
But it looks like a compiler bug since the output of 
`getSymbolsByUDA` is just an alias sequence and nothing should 
happen before consuming it?


Yes, this is a compiler bug. I've filed a report for it on 
bugzilla:


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


Re: UFCS limit

2022-06-16 Thread Paul Backus via Digitalmars-d-learn

On Thursday, 16 June 2022 at 23:59:06 UTC, Antonio wrote:
Is it there any way to apply UFCS on the returned method in the 
same expression?


Nope. The way UFCS works is that allows you to call free 
functions using member-function syntax, and member-function 
syntax is always `object.memberName`, so UFCS only works for 
functions that have a name, not anonymous functions.


Re: UFCS limit

2022-06-16 Thread Paul Backus via Digitalmars-d-learn

On Friday, 17 June 2022 at 05:17:20 UTC, Tejas wrote:

On Friday, 17 June 2022 at 01:04:28 UTC, Paul Backus wrote:



Nope. The way UFCS works is that allows you to call free 
functions using member-function syntax, and member-function 
syntax is always `object.memberName`, so UFCS only works for 
functions that have a name, not anonymous functions.


Would it be worthwhile to extend the scope of UFCS to 
accomodate this use case as well though??


Probably not.


Re: Conpile-Time module constructor

2022-06-19 Thread Paul Backus via Digitalmars-d-learn

On Sunday, 19 June 2022 at 14:51:26 UTC, Ruby The Roobster wrote:
Is it possible to make a module constructor run at 
compile-time?  If so, how?


No, it's not.

What are you trying to accomplish that lead you to ask this 
question? There is probably a different way to do it without 
involving module constructors.


Re: Conpile-Time module constructor

2022-06-19 Thread Paul Backus via Digitalmars-d-learn

On Sunday, 19 June 2022 at 15:34:48 UTC, Ruby The Roobster wrote:

On 6/19/2022 11:19 AM, Paul Backus wrote:
On Sunday, 19 June 2022 at 14:51:26 UTC, Ruby The Roobster 
wrote:
Is it possible to make a module constructor run at 
compile-time?  If so, how?


No, it's not.

What are you trying to accomplish that lead you to ask this 
question? There is probably a different way to do it without 
involving module constructors.


What I was trying to accomplish was to change a compile time 
array whenever a certain module was included.  The value of the 
array needs to be known at compile time.


You can do this with a `static if` check:

static if (__traits(compiles, { import mymodule; }))
{
// mymodule is included
enum compileTimeArray = ...;
}
else
{
// mymodule is not included
enum compileTimeArray = ...;
}


Re: Conpile-Time module constructor

2022-06-19 Thread Paul Backus via Digitalmars-d-learn

On Sunday, 19 June 2022 at 15:57:41 UTC, Ruby The Roobster wrote:

On 6/19/2022 11:55 AM, Paul Backus wrote:


You can do this with a `static if` check:

     static if (__traits(compiles, { import mymodule; }))
     {
     // mymodule is included
     enum compileTimeArray = ...;
     }


Curious - how exactly does this determine if the module is 
included?  I thought __traits(compiles, ...) only checks if an 
expression is SEMANTICALLY correct.


You're right--technically, it doesn't check whether the module is 
*included* in the final build, only whether the module is 
*available* for inclusion at compile time.


Because D supports separate compilation of modules, there is no 
way to check at compile time what modules will be included in the 
final build. If that's what you want to test for, you will have 
to move the check out of the code itself and into your build 
system (for example, by passing a `-version=HasMyModule` flag for 
builds that include the module in question).


Re: Failure due to memcpy being called at compile time

2022-06-20 Thread Paul Backus via Digitalmars-d-learn

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


Re: Failure due to memcpy being called at compile time

2022-06-21 Thread Paul Backus via Digitalmars-d-learn

On Tuesday, 21 June 2022 at 04:30:25 UTC, JG wrote:

On Tuesday, 21 June 2022 at 01:39:43 UTC, Paul Backus wrote:
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?


Yes, it's a workaround to avoid calling memcpy in CTFE.


Re: destroy and @safe

2022-06-21 Thread Paul Backus via Digitalmars-d-learn

On Tuesday, 21 June 2022 at 14:40:41 UTC, Antonio wrote:

The problem:

"use" can't be @safe because it contains a call to "destroy".


`destroy` should be `@safe` as long as the destructor it's 
calling is `@safe`.


If the destructor is `@system`, then the only way to call 
`destroy` in `@safe` code is to (1) determine the conditions 
necessary to call the destructor without violating memory safety, 
(2) ensure that those conditions are met (using compile time 
and/or runtime checks), and (3) wrap the call to `destroy` in a 
`@trusted` function.


Since step (1) depends on the specific details of the destructor 
you want to call, I can't give any more specific advice unless 
you show a complete example that includes the destructor.


Re: destroy and @safe

2022-06-21 Thread Paul Backus via Digitalmars-d-learn

On Tuesday, 21 June 2022 at 17:33:46 UTC, H. S. Teoh wrote:


Does the language allow you to declare a @system delegate 
inside @safe code?


Yes. This compiles:

void main() @safe
{
void delegate() @system dg = () @system { /* do scary 
stuff */ };

}


Re: DIP1000

2022-06-23 Thread Paul Backus via Digitalmars-d-learn
On Thursday, 23 June 2022 at 21:34:27 UTC, Ola Fosheim Grøstad 
wrote:

On Thursday, 23 June 2022 at 21:05:57 UTC, ag0aep6g wrote:

It's a weird rule for sure.


Another slightly annoying thing is that it cares about 
destruction order when there are no destructors.


If there are no destructors the lifetime ought to be considered 
the same for variables in the same scope.


Having different lifetime rules for different types is worse UX 
than having the same lifetime rules for all types.


Imagine writing a generic function which passes all of your unit 
tests, and then fails when you try to use it in real code, 
because you forgot to test it with a type that has a destructor.


Re: How can I check if a type is a pointer?

2022-06-25 Thread Paul Backus via Digitalmars-d-learn

On Saturday, 25 June 2022 at 14:18:10 UTC, rempas wrote:

For example, something like the following:

```d
void main() {
  char accepted_type;
  char* non_accepted_type;

  if (__traits(isPointer, typeof(accepted_type))) {
// The type is not accepted
  }
```


Use an [`is()` expression:][1]

```d
if (is(typeof(accepted_type) == T*, T))
{
// it's a pointer
}
```

In English, you read this as "if `typeof(accepted_type)` matches 
the pattern `T*`, where `T` is a type."


If you want to learn more, I recommend reading [Adam Ruppe's 
explanation of `is()` expressions][2].


[1]: https://dlang.org/spec/expression.html#IsExpression
[2]: 
https://forum.dlang.org/post/xklcgjaqggihvhctc...@forum.dlang.org


Re: Importing module from the perspective of submodule.

2022-07-02 Thread Paul Backus via Digitalmars-d-learn

On Sunday, 3 July 2022 at 05:40:30 UTC, BoQsc wrote:
Is it possible to import module that is not in the module's 
current directory's folder or subfolders?


For example:

I want to import `somemodule2.d` and `somemodule3.d` into a 
**`somemodule.d`**


**.\somefolder\somemodule.d**
.\somemodule2.d
.\someotherfolder\somemodule3.d


Yes. You just have to pass the folders with the modules in them 
to the compiler with the `-I` flag, or (if you're using dub) add 
the folders to your `importPaths`.


```
dmd -Isomeotherfolder -c somefolder\somemodule.d
```


Re: vibe.d Serialize/Deserialize SumType to/from json

2022-07-04 Thread Paul Backus via Digitalmars-d-learn

On Monday, 4 July 2022 at 11:35:24 UTC, Antonio wrote:
(or a way for creating a custom struct "inheriting" SumType 
with serialization capabilities)?


You can "inherit" from a struct using `alias this`:

```d
struct CustomStruct
{
SumType!(A, B, C) unwrap;
alias unwrap this;

// serialization stuff here
}
```

Documentation: https://dlang.org/spec/class.html#alias-this


Re: Unwrap variadic template into vararg of pointers of the same types

2022-07-08 Thread Paul Backus via Digitalmars-d-learn

On Friday, 8 July 2022 at 12:20:13 UTC, ryuukk_ wrote:
The problem when i try to introduce variadic template, is i 
can't seem to understand how to unwrap the parameter as pointer 
type T -> T*



```D
struct Includes(Args...) { alias args = Args; }

void view_it(Includes)(void function(entity_t, Includes.args* ) 
cb)

{
// do stuff
}

```

I get the following:

```Error: cannot have pointer to `(EEntityRemoved)```


You can use [`std.meta.staticMap`][1] to make each type into a 
pointer individually:


```d
import std.meta;

alias Args = AliasSeq!(int, string, double);
struct Includes { alias args = Args; }
struct entity_t {}

alias PointerTo(T) = T*;

void view_it(void function(entity_t, staticMap!(PointerTo, 
Includes.args) ) cb)

{
// do stuff
}
```

However, this will probably not work very well in your original 
code where `view_it` is a template, because the presence of 
`staticMap` in the parameter list will prevent the compiler from 
automatically deducing the template parameters.


So, in this case, I think a better solution is to make the type 
of the callback fully generic, and use a template constraint to 
enforce your requirements:


```d
import std.meta: allSatisfy;
import std.traits: isPointer;

void view_it(Callback)(Callback cb)
if (
is(Callback == void function(entity_t, Args), Args...)
&& allSatisfy!(isPointer, Args)
)
{
// do stuff
}
```

[1]: http://phobos.dpldocs.info/std.meta.staticMap.html


Re: Ascertaining!

2022-07-09 Thread Paul Backus via Digitalmars-d-learn

On Saturday, 9 July 2022 at 10:12:00 UTC, Salih Dincer wrote:

Hi All,

I didn't know compiling was bottom-up. This example proves 
that. Because in single-line expressions, it takes value from 
the right, firstly.


```d
void main()
{
int n; // true (n == 0)
int i = 1; // true (i == 1)
int j = i = n; // all numbers are 0
```


Yes, [the `=` operator is right-associative][1] in pretty much 
all C-like languages, so an expression of the form `a = b = c` is 
equivalent to `a = (b = c)`.


[1]: 
https://en.wikipedia.org/wiki/Operator_associativity#Right-associativity_of_assignment_operators


Re: How to obtain Variant underlying type?

2022-07-10 Thread Paul Backus via Digitalmars-d-learn

On Sunday, 10 July 2022 at 18:31:46 UTC, drug007 wrote:

On 7/10/22 20:26, anonymouse wrote:

On Sunday, 10 July 2022 at 06:26:37 UTC, jfondren wrote:

```d
import std.variant : Variant;

size_t[] shape(Variant v) {
    import std.variant : VariantException;

    size_t[] s;
    try {
    while (true) {
    Variant elem = v[0];
    s ~= v.length;
    v = elem;
    }
    } catch (VariantException e) {
    return s;
    }
}
```


Thank you very much.



I'd like to say that using of exception to break loop is really 
bad. Exception is exceptional thing but in the case above the 
exception is ordinary completion of the loop happens on regular 
basis. Don't do that.


For reference, this is the more correct way:

```d
while (cast(TypeInfo_Array) v.type !is null) {
Variant elem = v[0];
// etc.
}
```

Hard to blame anyone for not coming up with that on their first 
try, especially since `TypeInfo_Array` is not even 
documented--you have to read the source of `object.d` to find out 
about it.


Re: null == "" is true?

2022-07-12 Thread Paul Backus via Digitalmars-d-learn

On Tuesday, 12 July 2022 at 16:40:38 UTC, H. S. Teoh wrote:
Because an empty string is, by default, represented by an empty 
slice of the null pointer.


Do not rely on this, however; it's possible sometimes to get an 
empty string that isn't null, e.g., if you incrementally shrink 
a slice over a string until it's empty. In that case, .ptr will 
not be null, but the string will still be empty.  Always 
compare strings against "" rather than null, because the latter 
may not do what you think it does sometimes.


This is actually 100% reliable when comparing with the `==` 
operator because two empty strings always compare equal with 
`==`, regardless of what they point to.


string s = "hello";
string empty1 = s[0 .. 0];
string empty2 = s[1 .. 1];
assert(empty1 == null);
assert(empty2 == null);
assert(empty1 == empty2);

The real problem is that `s == null` looks like it does one thing 
(test for a null pointer) while actually doing something slightly 
different (test for an empty string).


Re: Why does inputRangeObject fail to derive correctly for RandomAccessInfinite ranges?

2022-07-12 Thread Paul Backus via Digitalmars-d-learn

On Wednesday, 13 July 2022 at 01:23:35 UTC, D Lark wrote:
First, please can someone clarify if the behaviour I expect in 
the last line is consistent with the intention of the library?


Yes, it should behave the way you expect. The current behavior is 
a bug.


I've submitted a report for it here: 
https://issues.dlang.org/show_bug.cgi?id=23242


Re: Unable to use map() and array() inside a class-field's initializer.

2022-07-14 Thread Paul Backus via Digitalmars-d-learn

On Thursday, 14 July 2022 at 13:57:24 UTC, realhet wrote:

Hello,

Somehow it can't reach map and array inside a class field 
initializer. If I put that small expression inside a function, 
it works. If I encapsulate the initializer expression into a 
lambda and evaluate it right away, it also works. Only the nice 
form fails.


Why is that?

```d
import std;

enum E{a, b, c}

static struct S{
const E e;
string otherProperties;
}

//trying to initialize an array inside

static if(1) class D{
  //this fails: Error: function `onlineapp.D.map!(E[]).map` 
need `this` to access member `map`

  auto x = [EnumMembers!E].map!(e => S(e)).array;
}
```


Simpler workaround:

```d
  // Explicit type annotation:   vvv
  auto x = [EnumMembers!E].map!((E e) => S(e)).array;
```

This turns the lambda from a template into a normal function, 
which apparently is enough to un-confuse the compiler. Still 
unclear why it's getting confused in the first place, though.


Re: Why does inputRangeObject fail to derive correctly for RandomAccessInfinite ranges?

2022-07-16 Thread Paul Backus via Digitalmars-d-learn

On Saturday, 16 July 2022 at 08:40:10 UTC, D Lark wrote:

On Wednesday, 13 July 2022 at 01:40:43 UTC, Paul Backus wrote:

On Wednesday, 13 July 2022 at 01:23:35 UTC, D Lark wrote:
First, please can someone clarify if the behaviour I expect 
in the last line is consistent with the intention of the 
library?


Yes, it should behave the way you expect. The current behavior 
is a bug.


I've submitted a report for it here: 
https://issues.dlang.org/show_bug.cgi?id=23242


It looks like the resolution is that this can't be fixed? I'm 
not sure I understand the conclusion. What does this mean for 
this part of the library then? Should the 
RandomAccessInfinite!E interface be removed since it's not 
fully supported?


The interface works fine, it's just that the `InputRangeObject!R` 
instance itself does not satisfy `isRandomAccessRange`:


```d
auto seqObj  = sequence!((a, n) => n).inputRangeObject;
RandomAccessInfinite!size_t seqIface = seqObj;

static assert( isRandomAccessRange!(typeof(seqIface))); // 
interface passes
static assert(!isRandomAccessRange!(typeof(seqObj))); // object 
fails

```

So if you code to the interfaces and ignore the concrete type of 
the range object, you should not have any problems.


Re: mixin template bug with opBinary?

2022-07-22 Thread Paul Backus via Digitalmars-d-learn

On Friday, 22 July 2022 at 12:33:37 UTC, Anthony Quizon wrote:

I get:
```
foo.d(16): Error: mixin `foo.B.opBi!(B, ["+":function (B a, B 
b) pure nothrow @nogc @safe => a])` does not match template 
declaration `opBi(A, A function(A, A)[string] f0)`

```

Is this a bug or am I doing something wrong?


Looks like this bug:

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


Re: does the format of coverage files have a name?

2022-07-28 Thread Paul Backus via Digitalmars-d-learn

On Monday, 25 July 2022 at 13:17:41 UTC, Moth wrote:

or was the .lst extension chosen arbitrarily?

my text editor [notepad++] thinks it's COBOL for some reason 
but that's obviously not correct, so i'm wondering if it has an 
official spec or anything. knowing the name of it would help - 
maybe my editor already has syntax highlighting for it.


I think it's a bespoke format with no official name. The closest 
thing to a spec is this page:


https://dlang.org/articles/code_coverage.html


Re: "strtok" D equivalent

2022-07-28 Thread Paul Backus via Digitalmars-d-learn

On Thursday, 28 July 2022 at 19:17:26 UTC, pascal111 wrote:

What's the "strtok" - C function - D equivalent?

https://en.cppreference.com/w/cpp/string/byte/strtok


Closest thing is probably `std.algorithm.splitter` with a 
predicate:


```d
import std.algorithm: splitter, canFind;
import std.stdio;

void main()
{
string input = "one + two * (three - four)!";
string delimiters = "! +- (*)";
auto tokens = input.splitter!(c => delimiters.canFind(c));
foreach (token; tokens) {
writef("\"%s\" ", token);
}
}
```

Output:

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

Unlike `strtok`, this code does not skip over sequences of 
multiple consecutive delimiters, so you end up with a bunch of 
empty tokens in the output. To exclude them, you can use 
`std.algorithm.filter`:


```d
import std.algorithm: filter;
import std.range: empty;
import std.functional: not;

// ...

auto tokens = input
.splitter!(c => delimiters.canFind(c))
.filter!(not!empty);

// ...
```


Re: "strtok" D equivalent

2022-07-28 Thread Paul Backus via Digitalmars-d-learn

On Thursday, 28 July 2022 at 21:52:28 UTC, pascal111 wrote:

On Thursday, 28 July 2022 at 20:36:31 UTC, Paul Backus wrote:

```d
import std.algorithm: filter;
import std.range: empty;
import std.functional: not;

// ...

auto tokens = input
.splitter!(c => delimiters.canFind(c))
.filter!(not!empty);

// ...
```


I think "tokens" is a range. I didn't read much about it, but I 
figured out that there's no particular way to know the number 
of elements in a range, or how can you know the elements order 
and the length of the range?


In this case, the only way is to convert the range to an array, 
using [`std.array.array`][1]:


```d
import std.array: array;

// ...

string[] tokens = input
.splitter!(c => delimiters.canFind(c))
.filter!(not!empty)
.array;
```

[1]: https://phobos.dpldocs.info/std.array.array.1.html


Re: "strstr" D equivalent

2022-07-29 Thread Paul Backus via Digitalmars-d-learn

On Friday, 29 July 2022 at 14:14:54 UTC, pascal111 wrote:
and if I'm right, with returning back to the definitions of 
"indexOf" @ https://dlang.org/phobos/std_string.html#.indexOf 
we won't find that there is a definition for it with just two 
parameters, so from where you got this new definition of this 
function?!


If you scroll down further, you will see that there is a second 
set of overloads for `indexOf`: 
https://dlang.org/phobos/std_string.html#.indexOf.2


The reason there are two sets of overloads, with separate 
documentation, is that one set searches for a single character in 
a string, while the other set searches for a substring in a 
string.


Re: Exclamation symbol "!" within functions syntax

2022-08-01 Thread Paul Backus via Digitalmars-d-learn

On Monday, 1 August 2022 at 11:35:25 UTC, pascal111 wrote:
I noticed that filter is using the concept of templates but 
this time it's with a lambda function, not with a data type, 
how can we explain this? isn't supposed to use a data type 
after the exclamation mark: "auto r = chain(a, b).filter!(a => 
a > 0);"


https://dlang.org/phobos/std_algorithm_iteration.html#.filter.filter


If you look at the documentation for the filter template [1], you 
will notice that the "predicate" parameter is marked with the 
keyword "alias":


template filter(alias predicate)

Alias template parameters are special. They can accept not only 
types, but also values, names of variables, and even things like 
modules and packages as arguments. You can read more about them 
in the "More Templates" chapter of Ali's book [2], and in the 
official D language specification [3].


[1] https://dlang.org/phobos/std_algorithm_iteration.html#.filter
[2] 
http://ddili.org/ders/d.en/templates_more.html#ix_templates_more.alias,%20template%20parameter

[3] https://dlang.org/spec/template.html#aliasparameters


Re: Breaking ";" rule with lambda functions

2022-08-01 Thread Paul Backus via Digitalmars-d-learn

On Monday, 1 August 2022 at 14:52:03 UTC, pascal111 wrote:
If `foo => bar` == `(foo) { return bar; }`, then  `foo => bar` 
is a function. "=>" is not an operator, it's a special symbol 
for lambda "function".


If A == B, so A's types is the same of B's type. How can it be 
withstanding `foo => bar` == `foo => bar` == `(foo) { return 
bar; }` and `foo => bar` is an expression and the other is a 
function?!! no sense.


From [the relevant section of the language spec:][1]

FunctionLiterals (also known as Lambdas) enable embedding 
anonymous functions and anonymous delegates directly into 
expressions. [...]  The type of a function literal is a 
delegate or a pointer to function.


In other words, a function literal is an expression that 
evaluates to either a delegate or a function pointer.


You are correct that, strictly speaking, it is wrong to say that 
a function literal "is" an anonymous function (rather than 
"refers to" or "points to" one). However, the distinction usually 
does not matter in practice, so most D programmers use the terms 
interchangeably.


[1]: https://dlang.org/spec/expression.html#function_literals


Re: How to cast away shared?

2022-08-03 Thread Paul Backus via Digitalmars-d-learn
On Wednesday, 3 August 2022 at 12:50:17 UTC, Ruby The Roobster 
wrote:

Any way to 'cast away' shared for an unknown type T?


There's actually an `Unshared` template for this in `std.traits`, 
but for some reason it's `private`, so you can't use it directly. 
Fortunately, it's only two lines:


```d
alias Unshared(T) = T;
alias Unshared(T: shared U, U) = U;
```

Once you have this, you can write `cast(Unshared!T)`.


Re: curses/ncurses liberary in D

2022-08-04 Thread Paul Backus via Digitalmars-d-learn

On Thursday, 4 August 2022 at 21:15:39 UTC, pascal111 wrote:

On Wednesday, 3 November 2021 at 05:43:05 UTC, harakim wrote:

https://github.com/adamdruppe/arsd/blob/master/terminal.d


How can I use this terminal module? Is there a document for it?


It is part of the arsd-official package, available on 
code.dlang.org:


https://code.dlang.org/packages/arsd-official

The documentation for the terminal module is here:

http://arsd-official.dpldocs.info/arsd.terminal.html


Re: Hacking C code vs D code

2022-08-04 Thread Paul Backus via Digitalmars-d-learn

On Thursday, 4 August 2022 at 23:11:36 UTC, pascal111 wrote:
One of problems faced me in C programming is hacking data with 
C code that some hackers do with C code which make me needs 
more tools to protect my C code, but I don't have good 
resources in my current time, while I noticed that D code is 
more secure than C code by mean it will be more useful to do my 
codes in my current time.


My question is, to which extent D code is secure and helping in 
protect data?


Probably the biggest safety features of D are bounds checking for 
arrays, garbage collection, and default initialization of 
variables.


If you use `@safe`, you can get even better protection, at the 
cost of some minor restrictions. But even without that, D is a 
lot safer than C.


Re: Unittest Absurdity

2022-08-04 Thread Paul Backus via Digitalmars-d-learn

On Friday, 5 August 2022 at 01:47:07 UTC, Ruby The Roobster wrote:


I found the issue:  opOpAssign isn't getting called at all.  I 
have no idea why, though.


Given that the example works, the problem must be in some other 
part of your code that you haven't posted. If you can post a more 
complete example that reproduces the problem, we can probably 
help you fix it.


Re: Copying and array into another

2022-08-09 Thread Paul Backus via Digitalmars-d-learn

On Tuesday, 9 August 2022 at 18:33:04 UTC, pascal111 wrote:
I tried to copy an array into another without affecting in the 
original array when I try to change the value of any element of 
the new array, but I failed except with this way in the next 
code:


'''D
int[] x=[1,2,3];
int[] y=x.filter!("a==a").array;

y[1]=800;

x.writeln;
y.writeln;
'''


A simpler way to do this is to use the array's built-in .dup 
method [1]:


int[] x = [1, 2, 3];
int[] y = x.dup;
y[1] = 800;

writeln(x); // [1, 2, 3]
writeln(y); // [1, 800, 3]

[1] https://dlang.org/spec/arrays.html#array-properties


Re: Fix template parameter

2022-08-09 Thread Paul Backus via Digitalmars-d-learn

On Tuesday, 9 August 2022 at 21:08:52 UTC, Meta wrote:
(it may also include anything that is a subtype of BigInt... 
I've received different answers on what exactly `(T: SomeType)` 
means in this context).


Yes, this syntax allows anything that implicitly converts to 
`BigInt`; for example:


```d
import std.bigint;

void fun(T : BigInt)(T t)
{
pragma(msg, "Instantiated with T = `" ~ T.stringof ~ "`");
}

struct S
{
BigInt n;
alias n this;
}

void main()
{
S s;
fun(s); // Instantiated with T = `S`
}
```

There is currently no way to write a template specialization that 
requires an exact type, with no implicit conversions. For that, 
you would have to use a template constraint instead:


```d
void fun(T)(T t)
if (is(T == BigInt))
{
// ...
}
```


Re: Fix template parameter

2022-08-09 Thread Paul Backus via Digitalmars-d-learn

On Tuesday, 9 August 2022 at 22:36:23 UTC, Dom Disc wrote:

On Tuesday, 9 August 2022 at 22:32:23 UTC, Dom Disc wrote:

On Tuesday, 9 August 2022 at 21:16:22 UTC, Paul Backus wrote:
Yes, this syntax allows anything that implicitly converts to 
`BigInt`;


Oh, or do you mean I will get two different instances of the 
template, if I call it with two different types with implicit 
conversion?
That would make it even worse than the non-templated 
declaration!


Yes, exactly.


Re: "min" and "max"

2022-08-09 Thread Paul Backus via Digitalmars-d-learn

On Tuesday, 9 August 2022 at 23:35:23 UTC, pascal111 wrote:
"min" and "max" in "std.algorithm" can be used with single 
values to pick up the min and max values, but it didn't mention 
how they can be used with ranges in the documentation:


https://dlang.org/phobos/std_algorithm_comparison.html#.min


The docs do mention `minElement` and `maxElement` (the range 
versions) under the "See Also" heading, but you're right that 
it's not super clear *why* they're mentioned.


Re: std.algorithm.cmp is conflicting with itself.

2022-08-11 Thread Paul Backus via Digitalmars-d-learn

On Thursday, 11 August 2022 at 17:46:00 UTC, realhet wrote:

Here's the utility module:
```d
module testcmpmodule;

//publicly output these modules, like I did in my always used 
'utils' module.

public import std.algorithm, std.math, std.stdio;

import std.range, std.traits;

//create function overload group
public import std.algorithm : cmp;
public import std.math  : cmp;

auto cmp(A, B)(in A a, in B b)
if(!(isInputRange!A && isInputRange!B)  //exclude 
std.algorithm.cmp
&& !(isFloatingPoint!A && isFloatingPoint!B))   //exclude 
std.math.cmp

{
  return a==b ? 0 : a

What's happening here is that the overload set created by the 
utility module is conflicting with the overload set created by 
the `public import` in `testcmpmodule2`. If you remove 
`std.algorithm` from `testcmpmodule2`'s `public import` line, the 
code compiles successfully.


Re: chain of exceptions, next method

2022-08-13 Thread Paul Backus via Digitalmars-d-learn

On Sunday, 14 August 2022 at 02:07:05 UTC, Ali Çehreli wrote:


This automatic "combining" of exceptions happens for cleanup 
code like scope(exit). (I remember bug(s) for scope(failure).):


To be precise, an exception thrown inside a 'finally' block gets 
chained onto the previous exception, but an exception thrown 
inside a 'catch' block does not. scope(exit) and scope(failure) 
are just syntax sugar for 'finally' and 'catch', respectively.


Relevant spec paragraph:

If an exception is raised in the FinallyStatement and is not 
caught before
the original exception is caught, it is chained to the previous 
exception via
the next member of Throwable. Note that, in contrast to most 
other
programming languages, the new exception does not replace the 
original
exception. Instead, later exceptions are regarded as 
'collateral damage'
caused by the first exception. The original exception must be 
caught, and

this results in the capture of the entire chain.


Source: https://dlang.org/spec/statement.html#try-statement

So, once an exception is caught, the chain ends, and any 
exception thrown after that begins a new chain.


Re: How do I get line numbers using pegged?

2022-08-15 Thread Paul Backus via Digitalmars-d-learn

On Monday, 15 August 2022 at 22:55:30 UTC, TheZipCreator wrote:
So I've looked at the [pegged 
library](https://github.com/PhilippeSigaud/Pegged) and used it 
a little bit and it seems really good. But there doesn't seem 
like there's a built-in way to get line numbers of nodes in the 
parse tree (or maybe I'm missing something). This would useful 
because if an error occurs during interpreting/compiling, you 
could give the user a line number where their error occurred by 
just getting the line number of the node that's currently being 
processed. Is there a way to do this in pegged?


It looks like the parse tree in pegged stores the start and end 
byte indices of the portion of the input text it corresponds to:


https://github.com/PhilippeSigaud/Pegged/blob/v0.4.6/pegged/peg.d#L251-L252

It should be possible to compute line numbers based on these 
indices.


Re: Does D actually support flexible array members?

2022-08-18 Thread Paul Backus via Digitalmars-d-learn
On Thursday, 18 August 2022 at 08:41:02 UTC, LinguisticMystic 
wrote:
I'm porting some C code for arena allocator to D, and somehow 
the flexible array members (a feature of C99 for 
dynamically-sized structs) work in D without significant 
changes in the code. Here's my arena definition:


```
struct ArenaChunk {
size_t size;
ArenaChunk* next;
char[] memory; // flexible array member
}

struct Arena {
ArenaChunk* firstChunk;
ArenaChunk* currChunk;
int currInd;
}
```

And here's how I use the FAM's memory for allocating stuff:

```
void* result = cast(void*)(&ar.currChunk.memory + 
ar.currInd);

```


I think the closest way to approximate this in D is to use a 
zero-length static array:


```d
struct ArenaChunk {
size_t size;
ArenaChunk* next;
char[0] memory;
}
```

Then your usage example becomes

```
void* result = cast(void*)(ar.currChunk.memory.ptr + 
ar.currInd);

```

Note that in D you must use `.ptr` to get a pointer to the 
array's first element; it does not decay automatically like in C.


Re: Compile time int to string conversion in BetterC

2022-08-18 Thread Paul Backus via Digitalmars-d-learn
On Wednesday, 17 August 2022 at 11:38:31 UTC, Steven 
Schveighoffer wrote:

On 8/17/22 6:38 AM, Dennis wrote:

On Wednesday, 17 August 2022 at 08:44:30 UTC, Ogi wrote:

Maybe I’m missing something?


I had the same problem, and came up with the following trick:

```D
enum itoa(int i) = i.stringof;
```


I have the same thing in my code:

```d
enum intStr(int x) = x.stringof;
```


I merged a version of this into Phobos (for internal use):

https://github.com/dlang/phobos/blob/v2.100.1/std/conv.d#L5986-L5987

It also comes with a unit test, so we don't get surprise breakage 
if the behavior of `.stringof` ever changes.


Re: Compile time int to string conversion in BetterC

2022-08-19 Thread Paul Backus via Digitalmars-d-learn

On Friday, 19 August 2022 at 10:22:25 UTC, bauss wrote:
Is there a reason why .stringof is implementation defined and 
not clearly defined in the spec how types and declarations 
should be treated when being "converted to a string"?


I find it really odd that it's implementation defined and you 
essentially can't rely on it anywhere.


It's something that has baffled me a lot.

Like are there something I'm missing that means it cannot be 
specified?


Basically, `.stringof` is what the compiler uses when it needs to 
display something in an error message. If it were locked down in 
the spec, then making improvements to error messages would in 
some cases require a deprecation cycle.


That said, it might still be worth specifying the behavior in a 
few specific cases—e.g., guaranteeing that `.stringof` on an 
integer value will always produce a valid integer literal.


Re: Exercise at end of Ch. 56 of "Programming in D"

2022-08-20 Thread Paul Backus via Digitalmars-d-learn

On Monday, 15 August 2022 at 02:59:59 UTC, Ali Çehreli wrote:

class Point {
  int x;
  int y;
  Color color;

  // ...

  override size_t toHash() const {
return x + y;
  }
}

The book is simply forgetting to show that function. 
(Otherwise, I never put any code without testing.)


WARNING: Hash functions can be very tricky. I have a strong 
feeling that adding two integers is not an efficient one.


Fortunately there is no need to invent our own hash function 
here, because we can use the generic hashOf [1] from druntime:


override size_t toHash() const {
return hashOf(y, hashOf(x));
}

The second argument is optional, and is used when you want to 
"accumulate" a single hash value from multiple input values.


[1] https://druntime.dpldocs.info/object.hashOf.1.html


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

2022-08-22 Thread Paul Backus via Digitalmars-d-learn

On Monday, 22 August 2022 at 11:24:59 UTC, Andrey Zherikov wrote:

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

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


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


Workaround: wrap it in a lambda.


```d
import std.traits;

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


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

2022-08-22 Thread Paul Backus via Digitalmars-d-learn

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

`ReturnType`.


My first instinct is to say that this is the user's mistake. UDAs 
are not evaluated like normal expressions, and anyone using UDAs 
is going to have to learn that sooner or later.


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


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

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

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

Or if you want to generalize to arbitrary predicates:

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

```


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

2022-08-22 Thread Paul Backus via Digitalmars-d-learn

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


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


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


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

2022-08-22 Thread Paul Backus via Digitalmars-d-learn

On Monday, 22 August 2022 at 16:06:37 UTC, Andrey Zherikov wrote:

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


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


A UDA can be either an expression or a symbol. Here are some 
examples of symbol UDAs that are not valid expressions:


```d
import std.stdio;
struct S;
template t() {}

@S   // a type
@(std.stdio) // a module
@t   // a template
int n;
```


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

2022-08-22 Thread Paul Backus via Digitalmars-d-learn

On Monday, 22 August 2022 at 16:19:06 UTC, Andrey Zherikov wrote:
I have an impression that template function can be called 
without parenthesis if it doesn't have run-time parameters so 
`func!0` is the same as `func!0()`. Am I wrong?


You're not wrong. This behavior is a special case in `typeof`. I 
was merely attempting to explain why such a special case might 
have been introduced.


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


My guess is that `u.func2!0` is rewritten to `func2!0(u)` during 
semantic analysis, so it does not trigger the special-case 
behavior.


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


It's probably not worth completely changing your API design just 
to work around this issue. Also, even if you do this, it is still 
possible for a user to run into a same problem with a member 
function of one of their own types; for example:


```d
import your.library;

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

@(MyStruct.myFunc) whatever;
```


Re: How to use a non-static objects in string `mixin`?

2022-08-27 Thread Paul Backus via Digitalmars-d-learn

On Saturday, 27 August 2022 at 13:20:13 UTC, hype_editor wrote:
I need to use function `eval` sometimes, but compiler throws an 
error: `Error: variable `firstOperand` cannot be read at 
compile time`.

```d
override public double eval()
{
double firstOperand = firstExpr.eval();
double secondOperand = secondExpr.eval();

return mixin(
format("%d %s %d", firstOperand, operator, 
secondOperand)
);
}
```


`mixin` is not the right tool to use here. Try rewriting the code 
to use a `switch` statement or a series of `if`-`else` statements 
instead.


Re: Why do failed contracts don't dump stack backtrace in unittests?

2022-09-04 Thread Paul Backus via Digitalmars-d-learn

On Sunday, 4 September 2022 at 14:14:55 UTC, Ali Çehreli wrote:
The program output is different whether an Error is thrown from 
main or from the unittest block:


Because the default test runner catches the Error, and doesn't 
print the stack trace:


https://github.com/dlang/dmd/blob/25799d3841ea87246c56532f6f91d9a1e34d8d8f/druntime/src/core/runtime.d#L599-L620

There's even a comment about it:

// TODO: omit stack trace only if assert was thrown
// directly by the unittest.


Re: BetterC stack traces?

2022-09-04 Thread Paul Backus via Digitalmars-d-learn

On Sunday, 4 September 2022 at 17:43:01 UTC, IchorDev wrote:
I'm trying to implement a custom exception system in BetterC. 
Does anyone know how I'd go about getting a stack trace so that 
I can print it to stdout? :)
I was thinking of utilising UDAs & `__LINE__` but it turns out 
that UDAs don't let you inject code, which is a shame!


You can use `libunwind` for this:

https://www.nongnu.org/libunwind/

It's a C library, but it should work for D too.


Re: BetterC stack traces?

2022-09-05 Thread Paul Backus via Digitalmars-d-learn

On Monday, 5 September 2022 at 10:47:38 UTC, IchorDev wrote:
Ah, I'm actually trying to create my own implementation of 
this, so the goal would be to not rely on a dependency.
I can't exactly make head nor tail of the library's source 
other than that it seems to have a unique implementation on 
each processor/OS type.


I'm sure there must be something hidden in `core.internal.` for 
this. I'll look at the implementation of `rt.trace` and see if 
I can find anything.


I think this is what you are looking for:

https://github.com/dlang/dmd/blob/master/druntime/src/rt/deh.d


Re: BetterC stack traces?

2022-09-05 Thread Paul Backus via Digitalmars-d-learn

On Monday, 5 September 2022 at 12:07:35 UTC, Paul Backus wrote:

On Monday, 5 September 2022 at 10:47:38 UTC, IchorDev wrote:
Ah, I'm actually trying to create my own implementation of 
this, so the goal would be to not rely on a dependency.
I can't exactly make head nor tail of the library's source 
other than that it seems to have a unique implementation on 
each processor/OS type.


I'm sure there must be something hidden in `core.internal.` 
for this. I'll look at the implementation of `rt.trace` and 
see if I can find anything.


I think this is what you are looking for:

https://github.com/dlang/dmd/blob/master/druntime/src/rt/deh.d


Digging in a little deeper, it looks like the druntime 
implementation ultimately depends on the [C++ exception handling 
ABI][1], via its platform-independent library interface. Bindings 
are defined in [`core.internal.backtrace.unwind`][2].


There is also what looks like a from-scratch implementation of 
table-based exception handling in [`rt.deh_win64_posix`][3], but 
according to a comment it is no longer used. Might be educational 
to read, though.


[1]: https://itanium-cxx-abi.github.io/cxx-abi/abi-eh.html
[2]: 
https://github.com/dlang/dmd/blob/master/druntime/src/core/internal/backtrace/unwind.d
[3]: 
https://github.com/dlang/dmd/blob/master/druntime/src/rt/deh_win64_posix.d


Re: Comparing slices with std.variant.Algebraic

2022-09-05 Thread Paul Backus via Digitalmars-d-learn

On Monday, 5 September 2022 at 08:58:21 UTC, anonymouse wrote:
On a related note, std.variant.Algebraic has been deprecated 
and the suggested replacement is std.sumtype.SumType. What is 
the proper way to make this conversion? Attempting to do a 
drop-in replacement results in the following errors:


```
axis.d(400): Error: incompatible types for array comparison: 
`SumType!(bool, int, long, float, double, string, DateTime)[]` 
and `double[]`
axis.d(86): Error: incompatible types for `(this.data[i]) + 
(rhs.data[i])`: both operands are of type `SumType!(bool, int, 
long, float, double, string, DateTime)`

axis.d(414): Error: template instance ```


`SumType` does not attempt to forward operators to the contained 
value like `Algebraic` does, so you will have to use 
[`tryMatch`][1] to access the value(s) in cases like these.


```d
// Compare a DataType[] to a double[]

import std.algorithm.comparison: equal;

/+
Will throw an exception if lhs contains a value that can't
be compared to a double.
+/
alias cmp = (DataType lhs, double rhs) => lhs.tryMatch!(value => 
value == rhs);


DataType[] a;
double[] b;
bool result = a.equal!cmp(b);
```

```d
// Add two DataType values

/+
addValues will take two DataTypes as arguments and match on
both simultaneously.

If the two DataTypes do not contain values that can be added
together, an exception will be thrown.

See:
- https://dlang.org/phobos/std_sumtype.html#multiple-dispatch
- 
https://dlang.org/phobos/std_sumtype.html#introspection-based-matching

+/
alias addValues = tryMatch!((lhs, rhs) => lhs + rhs);

DataType a;
DataType b;
DataType result = addValue(a, b);
```

[1]: https://phobos.dpldocs.info/std.sumtype.tryMatch.html




Re: Does D actually support flexible array members?

2022-09-06 Thread Paul Backus via Digitalmars-d-learn

On Tuesday, 6 September 2022 at 11:51:35 UTC, IchorDev wrote:

On Thursday, 18 August 2022 at 11:25:22 UTC, Paul Backus wrote:


I think the closest way to approximate this in D is to use a 
zero-length static array:


```d
struct ArenaChunk {
size_t size;
ArenaChunk* next;
char[0] memory;
}
```


Would Nullable be a good option as well? 
[https://dlang.org/phobos/std_typecons.html#Nullable](https://dlang.org/phobos/std_typecons.html#Nullable)


For a dynamically-sized struct? No, it would not; Nullable has a 
fixed size.


Re: Storing a lambda alongside type-erased data

2022-09-08 Thread Paul Backus via Digitalmars-d-learn

On Thursday, 8 September 2022 at 03:18:08 UTC, Ali Çehreli wrote:
I looked at how std.variant.VariantN prints the correct type 
and failed to understand the magic there. :(


Then I came up with storing a lambda that is created when the 
exact type is known. The following simple variant can carry 
arbitrary set of data because the data is provided as sequence 
template parameters (aka variadic).


This is actually pretty much exactly what VariantN does, except 
instead of storing a pointer to a lambda, it stores a pointer to 
an instance of a template function.


The member variable `fptr` [1] is the equivalent of your 
`dataToStr`. It stores a pointer to an instance of the `handler` 
template [2]. Whenever a new value is assigned to the VariantN, 
`fptr` is updated to point to the template instance corresponding 
to the new value's type [3].


[1] 
https://github.com/dlang/phobos/blob/v2.100.1/std/variant.d#L217-L218
[2] 
https://github.com/dlang/phobos/blob/v2.100.1/std/variant.d#L260-L645
[3] 
https://github.com/dlang/phobos/blob/v2.100.1/std/variant.d#L731


Re: How to add struct definition?

2022-09-08 Thread Paul Backus via Digitalmars-d-learn

On Friday, 9 September 2022 at 00:16:01 UTC, Injeckt wrote:
I need to add this struct definition in my project. But how to 
do that?

This structure:
https://docs.microsoft.com/en-us/windows/win32/api/iptypes/ns-iptypes-ip_adapter_info


import core.sys.windows.iptypes;


Re: Validate static asserts

2022-09-09 Thread Paul Backus via Digitalmars-d-learn
On Friday, 9 September 2022 at 14:35:33 UTC, Andrey Zherikov 
wrote:
I have bunch of `static assert(, )` in my 
code and would like to validate that specific code triggers 
specific assert by checking what `` is thrown.


It sounds like maybe your goal here is to test that attempting to 
compile a specific piece of code will result in a specific error 
message being *shown to the user*.


Unfortunately, the D compiler does not allow you to introspect on 
error messages, so it is impossible to write a `unittest` that 
covers this requirement. Instead, you will have to write an 
external script or program that attempts to compile a test 
program and checks the output for the expected error message.


Re: Function attribute best practices

2022-09-12 Thread Paul Backus via Digitalmars-d-learn

On Monday, 12 September 2022 at 16:14:42 UTC, Ali Çehreli wrote:
Is this accurate: Because Foo is a template, it should not put 
any attribute on member functions? Or only member functions 
that use a member that depends on a template parameter? And 
non-members that are templates?


Yes. Except for `@trusted`, explicit attributes on template code 
are a smell.


Is putting function attributes on unittest blocks for catching 
such issues?


@nogc nothrow pure @safe
unittest
{
// ...
}

No, it isn't because unless my unittest code is impure, I can't 
catch my incorrect 'pure' etc. on my member functions.


To test that a particular piece of code *isn't* pure, you can use 
the following idiom:


static assert(!__traits(compiles, () pure {
// code to test goes here
});


Re: Linker Error with Template Function

2022-09-12 Thread Paul Backus via Digitalmars-d-learn
On Tuesday, 13 September 2022 at 00:57:58 UTC, Kyle Ingraham 
wrote:
I am writing a library where I would like to be able to store 
instances of a type of class to an associative array for later 
usage. Each class stored has to implement a function as part of 
the required interface. The argument given is always the same 
type but the return value should be flexible. I solved this 
with an interface:


```d
interface PathConverter
{
T toD(T)(const string value) @safe;
}
```


https://dlang.org/spec/template.html#limitations

Templates cannot be used to add non-static fields or virtual 
functions to classes or interfaces.


You *should* get an error from the compiler for trying to do 
this, instead of just a linker error somewhere else down the 
line, but either way it's not going to work. You'll have to find 
another solution.




Re: Function attribute best practices

2022-09-13 Thread Paul Backus via Digitalmars-d-learn

On Tuesday, 13 September 2022 at 14:16:39 UTC, Ali Çehreli wrote:

On 9/12/22 09:39, Paul Backus wrote:

> Yes. Except for `@trusted`, explicit attributes on template
code are a
> smell.

Except for 'const' as well because some templates are member 
functions. And 'const' on a member function cannot be left to 
inference because it happens to be a part of the type of the 
function, which can be overloaded.


Yes, good point. In my head, I think of attributes that apply to 
the `this` parameter like `const`, `inout`, `shared`, and so as 
being in a separate category from attributes that apply to the 
function itself, like `@safe` and `@trusted`.


Somebody needs to create a two dimensional table that shows 
what it means for each function attribute on a regular 
function, member function, and templates of those, and 
hopefully come up with some guidelines.


Here's my attempt, covering all the attributes found under 
[`MemberFunctionAttribute`][1] in the language spec:


|Attribute|Affects |Inferred?|
|-||-|
|nothrow  |Function|Yes  |
|pure |Function|Yes  |
|@nogc|Function|Yes  |
|@safe|Function|Yes  |
|@system  |Function|Yes  |
|@trusted |Function|No   |
|@property|Function|No   |
|@disable |Function|No   |
|const|this|No   |
|immutable|this|No   |
|inout|this|No   |
|shared   |this|No   |
|return   |this|Yes  |
|scope|this|Yes  |

In general, attributes with a 'Yes' in the 'Inferred?' column 
should not be applied explicitly to functions that are subject to 
[attribute inference][2]. This includes functions defined inside 
templates, as well as nested functions and functions with an 
inferred return type (i.e., `auto` functions).


[1]: https://dlang.org/spec/function.html#MemberFunctionAttributes
[2]: 
https://dlang.org/spec/function.html#function-attribute-inference


Re: to delete the '\0' characters

2022-09-22 Thread Paul Backus via Digitalmars-d-learn
On Thursday, 22 September 2022 at 10:53:32 UTC, Salih Dincer 
wrote:
Is there a more accurate way to delete the '\0' characters at 
the end of the string? I tried functions in this module: 
https://dlang.org/phobos/std_string.html


```d
auto foo(string s)
{
  string r;
  foreach(c; s)
  {
if(c > 0)
{
  r ~= c;
}
  }
  return r;
}
```


```d
import std.algorithm : filter;
import std.utf : byCodeUnit;
import std.array : array;

string removeZeroes(string s)
{
return s.byCodeUnit
.filter!(c => c != '\0')
.array;
}
```


Re: to delete the '\0' characters

2022-09-23 Thread Paul Backus via Digitalmars-d-learn

On Friday, 23 September 2022 at 18:37:59 UTC, Salih Dincer wrote:
On Thursday, 22 September 2022 at 10:53:32 UTC, Salih Dincer 
wrote:
Is there a more accurate way to delete **the '\0' characters 
at the end of the string?**


* character**S**
* at the **END**
* of the **STRING**


Apologies for the confusion. You can use [`stripRight`][1] for 
this:


```d
import std.string: stripRight;
import std.stdio: writeln;

void main()
{
string[] samples = [
"the one\0", "the two\0\0", "the three\0\0\0", "the 
four\0\0\0\0",

"the five\0\0\0\0\0", "the six\0\0\0\0\0\0",
"the seven\0\0\0\0\0\0\0", "the eight\0\0\0\0\0\0\0\0"
];

foreach (s; samples) {
writeln(s.stripRight("\0"));
}
}
```

[1]: https://phobos.dpldocs.info/std.string.stripRight.2.html


Re: Detect uninitialized class var access

2022-09-25 Thread Paul Backus via Digitalmars-d-learn

On Sunday, 25 September 2022 at 03:04:45 UTC, Tejas wrote:

On Saturday, 24 September 2022 at 23:04:00 UTC, rassoc wrote:

On 9/24/22 15:28, Adam D Ruppe via Digitalmars-d-learn wrote:

gdb --args ./your_program

and then it will tell you all the details you want to know 
about when this happens.


Thank you for your input, Adam.  Real shame that there's no 
built-in compiler solution and probably never will be 
according to [1]. :(


[1] https://issues.dlang.org/show_bug.cgi?id=4595


AFAIK diagnostics like that are not possible because Walter 
doesn't want to implement full blown dataflow analysis in the 
compiler since it will slow down the compilation speed of dmd


Implementing such a diagnostic is equivalent, in the general 
case, to solving the halting problem. So even with dataflow 
analysis, there would always be cases where the compiler either 
fails to detect a potential null dereference (false negative), or 
detects one that can't actually happen at runtime (false 
positive).


Re: Stop writeln from calling object destructor

2022-10-02 Thread Paul Backus via Digitalmars-d-learn

On Sunday, 2 October 2022 at 16:21:47 UTC, data pulverizer wrote:
I've noticed that `writeln` calls the destructor of a struct 
multiple times and would like to know how to stop this from 
happening.


It's because `writeln` is copying the object, and each of the 
copies is being destroyed. If you add a copy constructor to your 
example, you can see it happening:


```d
import std.stdio: writeln;

struct MyObject
{
int id;
this(int id) @nogc
{
this.id = id;
}
this(inout ref MyObject) inout
{
writeln("Object copy constructor...");
}
~this()
{
writeln("Object destructor ...");
}
}



void main()
{
auto obj = MyObject(42);
writeln(obj);
writeln("Goodbye:\n");
}
```

Output:

```d
Object copy constructor...
Object copy constructor...
Object copy constructor...
Object copy constructor...
MyObject(0)Object destructor ...
Object destructor ...

Object destructor ...
Object destructor ...
Goodbye:

Object destructor ...
```


Re: Stop writeln from calling object destructor

2022-10-02 Thread Paul Backus via Digitalmars-d-learn

On Sunday, 2 October 2022 at 18:24:51 UTC, Ali Çehreli wrote:

On 10/2/22 10:55, data pulverizer wrote:
> ```
> this(T)(ref return scope T original)
> if(is(T == RVector!(Type)))
> {
>  //... code ...
> }
> ```

I've just tested. That is used only for explicit constructor 
syntax:


auto b = RVector!int(a);// templatized

>
>
> But this now works:
>
>
> ```
> this(ref return scope RVector!(Type) original)
> {
>  //... code ...
> }
> ```

That one works for both syntaxes:

auto b = RVector!int(a);// templatized
auto c = a; // non-templatized

Certainly confusing and potentially a bug... :/


It's a bug in the documentation.

https://issues.dlang.org/show_bug.cgi?id=23382
https://github.com/dlang/dlang.org/pull/3427


Re: Is `void` the correct way to say "do not initialize this variable"?

2022-10-03 Thread Paul Backus via Digitalmars-d-learn

On Monday, 3 October 2022 at 14:37:35 UTC, kdevel wrote:

On Sunday, 2 October 2022 at 23:37:26 UTC, ryuukk_ wrote:
I got the answer thanks to IRC chat: 
https://dlang.org/spec/declaration.html#void_init


Quote:

   Implementation Defined: If a void initialized variable's 
value is used

   before it is set, its value is implementation defined.

Shouldn't this read

   Unspecified Value: If a void initialized variable's value is 
used

   before it is set, its value is unspecified.


Yes, it should. Many of the contributors to the D spec are not 
very well versed in the precise details of these terms, so 
mistakes like this occasionally slip through.


Re: rotate left an array

2022-10-03 Thread Paul Backus via Digitalmars-d-learn

On Monday, 3 October 2022 at 21:06:36 UTC, Ali Çehreli wrote:

On 10/3/22 13:48, Andrey Zherikov wrote:

a "rotated view".


Without indexes:

import std.range : empty;

auto rotatedView(R)(R range)
in (!range.empty)
{
import std.range : chain, front, only, popFront;
const fr = range.front;
range.popFront();
return chain(range, only(fr));
}


Tiny nitpick: this should use

const fr = range.save.front;

...to ensure that `fr` is not invaliated or overwritten by the 
subsequent call to range.popFront (e.g., think of File.byLine 
here).


  1   2   3   4   5   6   7   8   9   >