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

2022-05-02 Thread Stanislav Blinov via Digitalmars-d-learn

On Monday, 2 May 2022 at 20:16:04 UTC, ag0aep6g wrote:

On 02.05.22 21:17, Stanislav Blinov wrote:

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

[...]

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


I take it your answer is that T must be int. But that's 
nonsense. MyAlias maps all types to int. It's not a bijection, 
you can't turn it around.


That's not my answer. And it is nonsense, because my answer is - 
what T is irrelevant, MyAlias maps *all* types to int. Therefore 
`simp` takes an int, which is what the caller is passing.


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

2022-05-02 Thread Stanislav Blinov via Digitalmars-d-learn

On Monday, 2 May 2022 at 20:08:48 UTC, Ali Çehreli wrote:

On 5/2/22 12:17, 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.

That's fine because D does not promise to solve such problems. 
It follows simple deduction rules.


Words, dear guru. Words have a meaning. It is very possible to 
deduce here (note the premise). D just isn't trying. That's what 
I said. You can say "it doesn't promise". Doesn't exactly change 
the meaning, does it? :)



> The function takes an int.

How would the solution be? Wouldn't the compiler have to parse 
all accessible template bodies to figure out which ones fit?


Err... yes? That's what it *is* doing already, for all templates.


Imagine the following two other templates:

template YourAlias(T) {
  alias YourAlias = int;  // Is it this one?
}

template HerAlias(T) {
  // ...
  alias HerAlias = HisAlias!SomeNameInThisScope;  // Or thi?
}


No. HerAlias and YourAlias are different symbols.

The compiler would have to solve this problem by digging into 
HisAlias's SomeNameInThisScope instantiation as well. As far as 
know, the D language does not work that way. Prolog and friends 
perhaps?


Nope. MyAlias is an alias. A template alias, but an alias 
nonetheless. It should be resolved prior to trying the overloads.



> Doesn't take a rocket
> scientist to figure that one out.

I think this is one of those cases where it is easier for a 
human. Although, I think I would have difficulty if there were 
more than one template parameter.


That's what we have compilers for.


> I might as well forego the templates and
> just write explicit overloads. At which point I would
question why use
> templates at all.

Templates allow single implementations to work for many types, 
manifest constants, aliases, etc. I wouldn't want to write (or 
mix-in?) sort() for MyType. Templates are wonderful and their 
implementation in D is refreshing.


It is, until is isn't. Question du jeour is one of those.




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

2022-05-02 Thread Stanislav Blinov via Digitalmars-d-learn

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.


  simp( cast(MyAlias!string) 4);//Also invalid since 
MyAlias!string is exactly int


Yes, invalid, as well it should be.


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


No issue here.

Instead to use aliases it's better (both in D and in C++) to 
use constraints/concepts.


No. It *would* be better if compiler didn't play stupid here. I 
shouldn't have to write 50+ more lines boilerplate for what the 
compiler should be able to figure out. I might as well forego the 
templates and just write explicit overloads. At which point I 
would question why use templates at all.





Re: CTFE and BetterC compatibility

2022-04-27 Thread Stanislav Blinov via Digitalmars-d-learn

On Wednesday, 27 April 2022 at 14:21:15 UTC, Claude wrote:

This is a long-standing pain point with BetterC (see 
https://issues.dlang.org/show_bug.cgi?id=19268).


As for this:

If I compile without the BetterC switch, compilation actually 
works but I'll have some linker issues:

```
$ gcc test.d -o test
First digit=5
/tmp/ccuPwjdv.o : In function 
« _D5test5parseFNaAyaZS5test4Data » :

test.d:(.text+0x137) : undefined reference to « _d_arraybounds »
test.d:(.text+0x183) : undefined reference to « _d_arraybounds »

etc...
```


When not using BetterC, but not linking against druntime either, 
you have to provide your own implementation for those functions. 
This is e.g. so you can replace druntime with your own version.


Re: std.typecons Typedef initializers?

2022-04-25 Thread Stanislav Blinov via Digitalmars-d-learn

On Monday, 25 April 2022 at 23:41:47 UTC, Chris Katko wrote:

So to use a typedef'd struct... I have to basically add the 
original type on top of the typedef'd type every time? Surely 
it's not this clunky?


I mean, why even use a typedef then. Why not use just pair, 
sPair, vPair, etc as  separate types with identical members and 
cast as necessary? I'm not sure what the benefit typedef is 
adding here.


Thanks


It could just be an oversight in implementation and worth 
submitting an enhancement request on bugzilla.


Current implementation only defines a constructor that takes 
rvalue of original type, while what it ought to be doing is 
defining a variadic template constructor that would forward the 
arguments to underlying type's constructor.


To be fair, as far as your example code goes, it'd almost be 
easier to indeed simply duplicate the implementations, but have 
the compiler do it for you, e.g. like this:


```d
enum Space
{
unspecified,
screen,
viewport,
}

struct TPair(Space space) { float x, y; }

alias Pair = Pair!(Space.unspecified);
alias sPair = Pair!(Space.screen);
alias vPair = Pair!(Space.viewport);
```


Re: Assigning to array of structs with custom constructor

2022-04-25 Thread Stanislav Blinov via Digitalmars-d-learn

On Monday, 25 April 2022 at 14:36:25 UTC, cc wrote:

```d
struct Foo {
string s;
this(string s) { this.s = s; }
}
Foo foo = "a";
Foo[] foos = ["a"]; // Error: cannot implicitly convert 
expression `["a"]` of type `string[]` to `Foo[]`
Foo[] foos = cast(Foo[]) ["a"]; // Error: e2ir: cannot cast 
`"a"` of type `string` to type `Foo`

```

Was there a way to do this?  I thought I recalled seeing 
something like this before, but I can't seem to find it.


Make it explicit:

```d
Foo[] foos = [Foo("a")];
```


Re: How to use destroy and free.

2022-04-25 Thread Stanislav Blinov via Digitalmars-d-learn

On Monday, 25 April 2022 at 10:13:43 UTC, Alain De Vos wrote:

Ali, thanks for the answer but i rephrase my question.
How to destroy,free , for garbage-collection-cycle in the 
destructor of this code :


// But How to force destroy and free , GC-cycle for heap object 
i ?


Short answer: use `destroy`. Long answer: don't do that.

https://dlang.org/spec/class.html#destructors

GC is not guaranteed to call destructors, and in fact it may run 
into situations when it can't (i.e. objects pointing to one 
another). Neither does it specify in what order destructors of 
GC-allocated objects are run (when they are run). If you need 
deterministic destruction e.g. for resource management, do not 
use GC.


Re: Variables & kind of memory

2022-04-23 Thread Stanislav Blinov via Digitalmars-d-learn

On Saturday, 23 April 2022 at 03:41:17 UTC, Alain De Vos wrote:


Feel free to elaborate.


Variables declared at module scope, and static variables in 
function/aggregate scopes, unless also annotated as `shared` or 
`__gshared`, are thread-local, therefore are placed in 
thread-local storage. That's why you see difference in addresses 
between e.g.  and  in `main`.


Re: Lambda Tuple with Map Reduce

2022-04-20 Thread Stanislav Blinov via Digitalmars-d-learn

On Wednesday, 20 April 2022 at 08:37:09 UTC, Salih Dincer wrote:

On Wednesday, 20 April 2022 at 08:04:42 UTC, Salih Dincer wrote:
I get an unexpected result inside the second foreach() loop. 
Anyone know your reason?



It's my fault, here is the solution:
```d
  foreach(fun; funs)
  {
range.map!(a => fun(a))
 .reduce!sum
 .write(" "); // Ok!
  }
  writeln; // "1115 188 102 86 47"
```


With the original version, I'm getting expected results with 
2.098.1. run.dlang.io with 'dmd' also shows expected results.


Re: save and load a 2d array to a file

2022-04-19 Thread Stanislav Blinov via Digitalmars-d-learn

On Tuesday, 19 April 2022 at 06:05:27 UTC, Ali Çehreli wrote:

One quirk of rawWrite and rawRead is that they want slices of 
objects. It is a little awkward when there is just one thing to 
write and read. Uncompiled but something like this:


  int i = 42;
  file.rawWrite(*cast((int[1]*)()));  // Casted to be an 
array of 1


Yuck :)

```d
file.rawWrite(()[0..1]);
```


Re: Nested function requires forward declaration?

2022-04-14 Thread Stanislav Blinov via Digitalmars-d-learn

On Thursday, 14 April 2022 at 08:55:25 UTC, Chris Katko wrote:

Using DMD. v2.098-beta-2

Not sure if right terminology. But I just wrote a nested 
function that uses a variable outside its body. The capture 
(right term?) is obvious where the invocation is. However, I 
have to move the declaration of the variable to above the 
nested function for it to compile.


Declarations in function scope are processed in order. This 
includes nested functions:


https://dlang.org/spec/function.html#nested (see #8).




Re: How to implement this?

2022-04-08 Thread Stanislav Blinov via Digitalmars-d-learn

On Friday, 8 April 2022 at 05:53:03 UTC, Elvis Zhou wrote:


assumeNoEscapeOrWhatever!DynamicArray structs;
structs ~= cast(A*)

is it possible?


That's what `@trusted` is for. And that's also why it should be 
used with care, and on the smallest code possible.


```d
struct A {}
struct B { A a; }
struct C { A a; }

void main()
{
A*[] structs;

B b;
C c;

() @trusted {
structs ~= cast(A*)
structs ~= cast(A*)
} ();
}
```


Re: A weird example of .toUTF16z concatination side-effects in wcsncat

2022-04-07 Thread Stanislav Blinov via Digitalmars-d-learn

On Thursday, 7 April 2022 at 10:50:35 UTC, BoQsc wrote:


wchar_t* clang_string = cast(wchar_t *)"AA";


You're witnessing undefined behavior. "AA" is a string 
literal and is stored in the data segment. Mere cast to wchar_t* 
does not make writing through that pointer legal. Moreover, even 
if it was legal to write through it, that alone wouldn't be 
sufficient. From documentation of `wcsncat`:


The behavior is undefined if the destination array is not large 
enough for the contents of both str and dest and the 
terminating null wide character.


`wcsncat` does not allocate memory, it expects you to provide a 
sufficiently large mutable buffer. For example, like this:


```d
// ...
auto cls = new wchar_t[256];
cls[] = 0;
cls[0..10] = 'A';
wchar_t* clang_string = cls.ptr;
// ...
```


Re: How to print or check if a string is "\0" (null) terminated in the D programming language?

2022-04-06 Thread Stanislav Blinov via Digitalmars-d-learn

On Wednesday, 6 April 2022 at 08:55:43 UTC, BoQsc wrote:
I have a feeling that some parts of my code contains 
unterminated strings and they do overflow into other string 
that is to be combined. I'd like to take a look at strings, 
analyse them manually and see if any of them end up terminated 
or not.


Please provide any relevant examples of how you do this.


In general, you shouldn't do that. In D, a `string`, `wstring` 
and `dstring` are slices of corresponding character types, and 
are *not* null-terminated (and in fact can contain 0 within their 
representation). However, as Andrea Fontana points out, string 
literals are null-terminated (but note that the terminator itself 
isn't included in a `string` initialized with such a literal), 
and also convert to pointers - these two properties allow using 
them as arguments to C functions.


Thus, since null terminator isn't normally included as part of a 
string, you'd have to read past array bounds to check if there's 
a 0 there, and doing so leads to undefined behavior.


In fact, you should simply assume that any D string you encounter 
is not null-terminated. And if you want to ensure you're always 
passing around null-terminated strings, you should either use the 
greedy allocating functions such as `toStringz`, or perhaps make 
your own type that always allocates extra space for a 0.


Re: Is it safe to read to memory after it has been allocated with `pureMalloc` and `pureRealloc`?

2022-04-04 Thread Stanislav Blinov via Digitalmars-d-learn

On Monday, 4 April 2022 at 07:32:00 UTC, rempas wrote:
In other terms, do these functions auto-initialize memory to be 
ready for use?


No. Neither `malloc` nor `realloc` (for which D's `pure...` 
variants are mere wrappers) are specified to initialize allocated 
memory. `calloc`, however, is - it initializes allocated block 
with zeroes.


Re: Help needed to learn templates

2022-03-19 Thread Stanislav Blinov via Digitalmars-d-learn
On Saturday, 19 March 2022 at 13:38:42 UTC, Vinod K Chandran 
wrote:
On Saturday, 19 March 2022 at 11:47:53 UTC, Stanislav Blinov 
wrote:


No.

First of all Thanks for the reply. The answer "No" is a wonder 
to me. Because, from my point of view, `U` is coming from 
nowhere. My understanding is, we can use any parameter of a 
template inside the template. So in this case `U` is not in the 
parameter list. It is suddenly appearing in that `static if`.


It is appearing not in the `static if`, but in the `is` 
expression, which I described further in the rest of my first 
reply. Sorry if that wasn't clear.





The test is not `T t == U[]`. It is `is(T t == U[], U)`.


Okay, I understand.

Actually, the lower case `t` is not needed there, you can 
simply write `is(T == U[], U)`.


So the `T` is not the type. It's the parameter. Right ? So a 
template doesn't need a type. Only the parameter, right ? (I 
think I am too dumb to ask this. Please forgive me.)


Oh don't worry, this topic is not at all obvious with the `is` 
expression having its own syntax and semantics. `T` is a type, a 
type you instantiate `rank` with. `template rank(T)` *does* 
expect a type as a parameter. The other template syntax - 
`template foo(alias T)` can take as `T` any symbol, not just a 
type.


Yes, and `U` then becomes `int[][]`. Which is why the template 
recurses down and instantiates itself with `U`, until `T` 
fails the test.


In order to understand this, I need to understand from where 
the `U` comes.


It comes from you, the programmer. Like I said before, `is(T == 
U[], U)` means "is T an array of some type, the type which I (the 
programmer) would like to refer to as U?". That's all there is to 
it (well, not quite, but it should suffice for starters). You're 
simply introducing an identifier. So, when `T` is an `int[][][]`, 
naturally, `U` becomes an alias to `int[][]` (look at the 
converse - when `U` is `int[][]`, `U[]` is naturally an 
`int[][][]`).


You can think of that test as this:

```d
import std.traits : isDynamicArray;

// ...

static if (isDynamicArray!T)
{
alias U = typeof(T.init[0]);
// ...
}
```

...which would roughly be the same thing - you test if `T` is a 
dynamic array of some type, and then make an alias for that 
array's element type. It's just that the `is` expression allows 
you to create such alias in situ.


Re: Help needed to learn templates

2022-03-19 Thread Stanislav Blinov via Digitalmars-d-learn
On Saturday, 19 March 2022 at 05:54:26 UTC, Vinod K Chandran 
wrote:


Question 1 - `U` is appearing in the first static if statement. 
But we had to write `U` on the template line, right? Like - 
`template rank(T, U)`


No.

Question 2 - The statif if test is - `T t == U[ ]` What does 
that mean ?


The test is not `T t == U[]`. It is `is(T t == U[], U)`.

https://dlang.org/spec/expression.html#is-identifier-equal

```
is ( Type Identifier == TypeSpecialization )

The condition is satisfied if Type is semantically correct and is 
the same as TypeSpecialization. The Identifier is declared to be 
either an alias of the TypeSpecialization or, if 
TypeSpecialization is dependent on Identifier, the deduced type.

```

You simply introduce new identifiers. Basically, the test means 
"is T an array of some type which I would like referred to as 
U?". Actually, the lower case `t` is not needed there, you can 
simply write `is(T == U[], U)`.


Question 3 - if `T t == U[ ]` is the test, then I think when we 
pass

```d
rank!(int[ ][ ][ ])
```
The test will be `int[ ][ ][ ] == U[ ]`, Right ?


Yes, and `U` then becomes `int[][]`. Which is why the template 
recurses down and instantiates itself with `U`, until `T` fails 
the test.


Re: How to remove all characters from a string, except the integers?

2022-03-04 Thread Stanislav Blinov via Digitalmars-d-learn

On Friday, 4 March 2022 at 19:51:44 UTC, matheus wrote:

OK but there is another problem, I tested your version and mine 
and there is a HUGE difference in speed:



string s, str = "4A0B1de!2C9~6";


Unless I did something wrong (If anything please tell). By the 
way on DMD was worse, it was like 5x slower in your version.


To add to the already-mentioned difference in allocation 
strategies, try replacing the input with e.g. a command-line 
argument. Looping over a literal may be skewing the results.




Re: How to remove all characters from a string, except the integers?

2022-03-03 Thread Stanislav Blinov via Digitalmars-d-learn

On Thursday, 3 March 2022 at 12:14:13 UTC, BoQsc wrote:


I need to check if a string contains integers,
and if it contains integers, remove all the regular string 
characters.
I've looked around and it seems using regex is the only closest 
solution.


```d
import std.stdio;
import std.algorithm : find, filter;
import std.conv : to;
import std.uni : isNumber;

void main(string[] args){
if (args.length > 1){

auto filtered = () {
auto r = args[1].find!isNumber; // check if a string 
contains integers

return r.length ?
   r.filter!isNumber.to!string // and if it does, 
keep only integers
   : args[1];  // otherwise keep 
original

} ();

filtered.writeln;

} else {
write("Please write an argument.");
}
}
```



Re: Detecting ElementType of OutputRange

2022-02-26 Thread Stanislav Blinov via Digitalmars-d-learn

On Saturday, 26 February 2022 at 12:26:21 UTC, Vijay Nayar wrote:
On Saturday, 26 February 2022 at 11:44:35 UTC, Stanislav Blinov 
wrote:

https://dlang.org/phobos/std_range_primitives.html#isOutputRange


This method requires the caller to explicitly declare the 
output range element type, which I was hoping to have to avoid, 
if it can be detected using reasonable assumptions.


Considering that `put` is quite typically implemented as a 
template, I don't think that would be possible in general.


The question is, do you really need that? Your 
`BufferedOutputRange` can test the underlying range using 
`isOutputRange` in its own implementation of `put`, where the 
type of element is known, i.e. to test whether it can bulk-write 
a slice (or a range of) elements or has to make per-element calls 
to `put`.


Re: Detecting ElementType of OutputRange

2022-02-26 Thread Stanislav Blinov via Digitalmars-d-learn

https://dlang.org/phobos/std_range_primitives.html#isOutputRange


Re: Differences between lambda function and regular functions in higher order functions

2022-02-21 Thread Stanislav Blinov via Digitalmars-d-learn

On Monday, 21 February 2022 at 10:04:16 UTC, steve wrote:
I am trying to implement a simple map function. I found code to 
do this in another post but it only seems to work with lambda 
functions and I do not understand why. Any help would be 
greatly appreciated


```
import std.stdio;

T[] map_vals(T,S)(scope T function(S) f, S[] a){
auto b = new T[a.length];
foreach(i,x;a) b[i] = f(x);
return b;
}
```



As partypooper says, with that singature it'll only work if you 
pass function pointer (whereas a lambda converts to one). 
Alternatively (and how it is typically done in i.e. D's standard 
library), you can pass your callable as a compile-time argument. 
This also has an advantage of supporting UFCS, as shown in this 
example:


```d
import std.stdio;

// original, needs a function pointer
T[] map_vals(T,S)(scope T function(S) f, S[] a){
auto b = new T[a.length];
foreach(i,x;a) b[i] = f(x);
return b;
}

// Takes the callable as a compile-time argument
auto map_vals(alias f,S)(S[] a)
if (is(typeof(f(a[0]
{
alias T = typeof(f(a[0]));
auto b = new T[a.length];
foreach (i, ref x; a) b[i] = f(x);
return b;
}

auto timestwo(float x) {
return 2*x;
}

void main(){
float[] my_array = [1., 2., 3.];
auto ff = (float x)=>2*x;

// This works
writeln(map_vals(ff, my_array));

// this works with pointer to timestwo
writeln(map_vals(, my_array));

// and this works by just passing the symbol name,
// also note UFCS syntax:
my_array.map_vals!timestwo.writeln;

// as does this:
my_array.map_vals!ff.writeln;

// and this:
my_array.map_vals!(x => 2*x).writeln;
}
```

Note that `map` already exists in Phobos 
(https://dlang.org/phobos/std_algorithm_iteration.html#map), and 
that one makes a lazy range and doesn't allocate.


Re: Function Parameters without Names?

2022-02-20 Thread Stanislav Blinov via Digitalmars-d-learn

On Saturday, 19 February 2022 at 23:37:01 UTC, Vijay Nayar wrote:


What is the main motivator to allow parameters with no names?


1) `extern(C) void* malloc(size_t);`

No need for parameter name at all as that is only a declaration. 
You don't have an implementation thus don't need a name for the 
parameter.


2) As Ali says, unused parameters (i.e. in template 
specializations, virtual function overrides, dummy parameters for 
overload resolution purposes, etc.)


Re: Member function forwarding

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


Actually the answer is `NO`. I have to do `auto 
foo(ARGS...)(auto ref ARGS args) { return

a.foo(args); }`.


This also doesn't forward correctly. It'll always try to copy all 
arguments. What would fowrard is


```
import core.lifetime : forward;

auto foo(Args...)(auto ref Args args) { return 
a.foo(forward!args); }

```




Re: what's meaning of "(a) =>"

2022-02-05 Thread Stanislav Blinov via Digitalmars-d-learn

On Saturday, 5 February 2022 at 15:10:19 UTC, step8 wrote:

I'm trying to study D programming
Following is code from vibe's example(web_ajax) code:

void getDataFiltered(Fields field, string value)
{
	auto table = users.filter!((a) => value.length==0 || 
a[field]==value)().array();

render!("createTable.dt", table)();
}

I can't understand the expression "(a) =>",there is no 
defination of "a",how does this work?

thanks for help


`(a) => value.length==0 || a[field]==value`

is a https://dlang.org/spec/expression.html#FunctionLiteral (see 
e.g. #10 there).


This one is polymorphic, somewhat equivalent to defining a 
function such as


`bool func(T)(T a) { return value.length==0 || a[field]==value; }`

(assuming `value` is accessible to `func`).


Re: ldc executable crashes with this code

2022-02-04 Thread Stanislav Blinov via Digitalmars-d-learn

On Friday, 4 February 2022 at 11:26:42 UTC, forkit wrote:

If I had wrote the code below, then I should not expect 
anything, whatsoever, from the compiler.


() @trustMe_I_am_a_complete_idiot { char[] palindrome = 
cast(char[])"able was I ere I saw elba";  } ();


This is almost exactly what you have to do today, assuming you're 
using @safe. You'll **have** to write this then:


`() @trusted { auto palindrome = cast(char[])"able was I ere I 
saw elba"; } ();`


Instead, you opted to comment out `@safe`. Unfortunately, "@safe 
by default" idea was brutally eviscerated.


As others have already stated, casting immutability away is 
something that has to be supported, e.g. to interface with 
const-agnostic APIs. `@safe` requires such casts to be more 
verbose, with good reason.


Re: passing a variadic parameter to randomSample

2022-01-26 Thread Stanislav Blinov via Digitalmars-d-learn

On Tuesday, 25 January 2022 at 22:07:43 UTC, Ali Çehreli wrote:

On 1/25/22 13:55, forkit wrote:

> auto RandomChoice(R...)(R r)

Watch out though: The compiler will compile a different 
function per set of values. For example, there will be separate 
RandomChoice instances for ("hello") vs. ("world").


Huh? Perhaps you meant "for ("hello") vs. ("hello", "world")"? 
Because it would be the same instantiation for a single string 
argument :)





Re: Linkage question

2022-01-24 Thread Stanislav Blinov via Digitalmars-d-learn

On Monday, 24 January 2022 at 17:23:01 UTC, frame wrote:

I understand that the linkage must match but besides the name 
mangling, what's happen here? What is the difference if I 
remove the `extern (C)` part from the T alias?


The difference is in how arguments are being passed, which you 
seem to have discovered already :)



Would like to know where the linkage format is defined, thx.


It should be here: https://dlang.org/spec/abi.html although IIRC 
it might not be 100% up to date.


Re: map question

2022-01-23 Thread Stanislav Blinov via Digitalmars-d-learn
On Sunday, 23 January 2022 at 09:38:57 UTC, Siarhei Siamashka 
wrote:
On Sunday, 23 January 2022 at 09:08:46 UTC, Stanislav Blinov 
wrote:
Using `iota` here incurs additional computation and argument 
copies that are actually never used, i.e. wasted work. So I'd 
say go with `generate`, as that seems the intent.


Isn't this normally a compiler's job to eliminate all unused 
computations and copies?


It is the programmer's job long before it is the compiler's. It 
can do wonders on your "minimal" code but it's not its job to 
read your mind.



```D
auto foobar1(size_t n)
{
return n.iota.map!(_ => 123).array;
}

auto foobar2(size_t n)
{
return generate!(() => 123).take(n).array;
}
```

LDC with "-O -release" command line options generates pretty 
much identical code for foobar1 and foobar2 (I'm only showing 
the main loop, but the rest is also the same):

```
  20:   48 39 c8cmp%rcx,%rax
  23:   74 18   je 3d 
<_D2zz7foobar1FNaNbNfmZAi+0x3d>

  25:   c7 04 8a 7b 00 00 00movl   $0x7b,(%rdx,%rcx,4)
  2c:   48 83 c1 01 add$0x1,%rcx
  30:   48 39 cbcmp%rcx,%rbx
  33:   75 eb   jne20 
<_D2zz7foobar1FNaNbNfmZAi+0x20>

```

```
  20:   48 39 c8cmp%rcx,%rax
  23:   74 18   je 3d 
<_D2zz7foobar2FNaNbNfmZAi+0x3d>

  25:   c7 04 8a 7b 00 00 00movl   $0x7b,(%rdx,%rcx,4)
  2c:   48 83 c1 01 add$0x1,%rcx
  30:   48 39 cbcmp%rcx,%rbx
  33:   75 eb   jne20 
<_D2zz7foobar2FNaNbNfmZAi+0x20>

```

Do you have a better example to demonstrate `generate`'s 
superiority?


Try actual work instead of returning a literal :) Like e.g. 
calling dice(50, 50).


One thing to note though - `generate` will always eagerly call 
its function at least once. Which of course should also be 
considered in choosing the desired implementation. I.e. if your 
`n` comes from user and is allowed to be 0, then `generate` 
becomes an inferior choice.


Re: map question

2022-01-23 Thread Stanislav Blinov via Digitalmars-d-learn

On Saturday, 22 January 2022 at 23:54:27 UTC, forkit wrote:
On Saturday, 22 January 2022 at 19:55:43 UTC, Stanislav Blinov 
wrote:




thanks for the explanation. That really helped :-)

writeln( generate!(() => dice(0.6, 1.4)).take(howManyTimes) );
[1, 1, 1, 1, 0]

(or after reading Ali's response - getting rid of rnd, and 
using _ )


writeln( howManyTimes.iota.map!(_ => dice(0.6, 1.4)) );
[1, 0, 1, 1, 1]

They produce exactly the same thing, so I guess it comes down 
to personal choice now.


Using `iota` here incurs additional computation and argument 
copies that are actually never used, i.e. wasted work. So I'd say 
go with `generate`, as that seems the intent.


Re: map question

2022-01-22 Thread Stanislav Blinov via Digitalmars-d-learn

On Saturday, 22 January 2022 at 19:32:07 UTC, forkit wrote:

trying to make sense of the below:


// ---
module test;

import std;

void main()
{
auto rnd = Random(unpredictableSeed);

int howManyTimes = 5;

// ok - using 'e =>' makes sense
writeln(howManyTimes.iota.map!(e => rnd.dice(0.6, 
1.4)).format!"%(%s,%)");


// ok - though using 'howManyTimes =>' doesn't make much 
sense??
writeln(howManyTimes.iota.map!(howManyTimes => 
rnd.dice(0.6, 1.4)).format!"%(%s,%)");


// NOT ok - using '5 =>' - but isn't this effectively the 
same as above line?
//writeln(howManyTimes.iota.map!(5 => rnd.dice(0.6, 
1.4)).format!"%(%s,%)");

}

// ---


No, it's not the same. 'Tis not really a "map question", looks 
more like a question about


https://dlang.org/spec/expression.html#function_literals (see 
#10).


In the second case, you're defining a lambda with single 
parameter named `howManyTimes`, which is not at all related to 
your local variable of the same name. Third case is invalid, as 
you're effectively trying to do this:


auto func(T)(T 5) { return rnd.dice(0.6, 1.4); }

Which, of course, doesn't make any sense, does it? :)

Given your use case (call a function N times), I think `generate` 
would be more appropriate here:


```d
import std.random;
import std.stdio;
import std.range : generate, take;

void main()
{
auto rnd = Random(unpredictableSeed);
int howManyTimes = 5;
generate!(() => rnd.dice(0.6, 
1.4)).take(howManyTimes).writeln;

}

```


Re: forward tuple arg to local variable + dtor

2022-01-22 Thread Stanislav Blinov via Digitalmars-d-learn

On Saturday, 22 January 2022 at 18:00:58 UTC, vit wrote:


I want implement something like this:


Scratch the previous reply, 'twas a brain fart... Simply take by 
value, no need for extra copies at all in that case. Arguments 
themselves will become those copies as needed.


```d
import std.meta : allSatisfy;

enum bool isRcPtr(T) = is(T == RcPtr!U, U);

//@safe access to data of multiple ref counted objects:
public auto apply(alias fn, Args...)(Args args)
if (allSatisfy!(isRcPtr, Args)) {

@property auto ref elm(alias param)()@trusted{
return param.get();
}

return fn(staticMap!(elm, args));
}
```


Re: forward tuple arg to local variable + dtor

2022-01-22 Thread Stanislav Blinov via Digitalmars-d-learn

On Saturday, 22 January 2022 at 18:00:58 UTC, vit wrote:


I want implement something like this:
...


Take by value and make a copy without forwarding:

```d
import std.typecons : Tuple;
import std.meta : allSatisfy;

enum bool isRcPtr(T) = is(T == RcPtr!U, U);

//@safe access to data of multiple ref counted objects:
public auto apply(alias fn, Args...)(Args args)
if (allSatisfy!(isRcPtr, Args)) {

Tuple!Args params = args; // borrow all

@property auto ref elm(alias param)()@trusted{
return param.get();
}

return fn(staticMap!(elm, args)); // staticMap over original 
args tuple

}
```

Or make a helper function that takes by value and forward to that:

```d
template apply(alias fn)
{
private auto impl(Args...)(Args args)
{
@property auto ref elm(alias param)()@trusted{
return param.get();
}
return fn(staticMap!(elm, args));
}

auto apply(Args...)(auto ref Args args)
if (allSatisfy!(isRcPtr, Args))
{
import core.lifetime : forward;
return impl(forward!args); // impl takes by value - 
RcPtrs passed by reference will be copied

}
}
```


Re: automate tuple creation

2022-01-21 Thread Stanislav Blinov via Digitalmars-d-learn

On Friday, 21 January 2022 at 03:50:37 UTC, forkit wrote:

I might have to use a kindof stringbuilder instead, then write 
a massive string once to the file.


You're using writeln, which goes through C I/O buffered writes. 
Whether you make one call or several is of little consequence - 
you're limited by buffer size and options.


Re: automate tuple creation

2022-01-20 Thread Stanislav Blinov via Digitalmars-d-learn

On Thursday, 20 January 2022 at 12:15:56 UTC, forkit wrote:


void createUniqueIDArray(ref int[] idArray, int recordsNeeded)
{
idArray.reserve(recordsNeeded);
debug { writefln("idArray.capacity is %s", 
idArray.capacity); }


// id needs to be 9 digits, and needs to start with 999
// below will contain 1_000_000 records that we can choose 
from.
int[] ids = iota(999_000_000, 1_000_000_000).array; // 
NOTE: does NOT register with -profile=gc


int i = 0;
int x;
while(i != recordsNeeded)
{
   x = ids.choice(rnd);

   // ensure every id added is unique.
   if (!idArray.canFind(x))
   {
   idArray ~= x; // NOTE: does NOT register with 
-profile=gc

   i++;
   }
}
}


Allocating 4 megs to generate 10 numbers??? You can generate a 
random number between 99900 and 10.


```
immutable(int)[] createUniqueIDArray(int recordsNeeded)
{
import std.random;
import std.algorithm.searching : canFind;
int[] result = new int[recordsNeeded];

int i = 0;
int x;
while(i != recordsNeeded)
{
// id needs to be 9 digits, and needs to start with 999
   x = uniform(999*10^^6, 10^^9);

   // ensure every id added is unique.
   if (!result[0 .. i].canFind(x))
   result[i++] = x;
}
import std.exception : assumeUnique;
return result.assumeUnique;
}

void main()
{
import std.stdio;
createUniqueIDArray(10).writeln;
}
```

Only one allocation, and it would be tracked with -profile=gc...


Re: why there is a [] at the end of assocArray

2022-01-19 Thread Stanislav Blinov via Digitalmars-d-learn

On Wednesday, 19 January 2022 at 13:15:35 UTC, michaelbi wrote:

	foreach(line; > 
File("input.txt").byLine.map!(a=>a.idup).array.transposed)



so why there is a [] at the end of assocArray printed? thanks.


...because there's an empty line at the end of input.txt?


Re: A slice consisting of non-consecutive elements of an array?

2022-01-13 Thread Stanislav Blinov via Digitalmars-d-learn

On Thursday, 13 January 2022 at 19:52:27 UTC, forkit wrote:


Any idea on how I can get a ptr (without hardcoding C style)

e.g. something like this:

immutable(string)*[] pointers = strings.filter!(x => x == 
"one").to!pointers.array;


```d
import std.stdio : writeln;
import std.algorithm : filter, map, each;
import std.range : array;

void main() @safe
{
immutable strings = ["one", "one", "two", "one", "two", 
"one", "one", "two"];
immutable(string)*[] pointers = strings.filter!(x => x == 
"one").map!((ref x) @trusted => ).array;

pointers.each!(p => writeln(p - [0]));
}
```


Re: Returning value by ref does not create a ref. Is this intentional?

2022-01-04 Thread Stanislav Blinov via Digitalmars-d-learn

On Wednesday, 5 January 2022 at 04:35:12 UTC, Tejas wrote:

```d
import std.stdio:writeln;

ref int func(return ref int a){
a = 6; // modifies a as expected
return a;
}
void main(){
int a = 5;
auto c = func(a); // I expected c to alias a here
c = 10; // Expected to modify a as well
writeln(a); // prints 6 :(
}
```

The [spec](https://dlang.org/spec/function.html#ref-functions) 
states:


Ref functions allow functions to return by reference, meaning 
that the return value must be an lvalue, and the lvalue is 
returned, not the rvalue.




Then why does  the reference to `a` not get returned ?


It is returned. But initializing `c` with it makes a copy. This 
will mutate `a`:


```
func(a) = 10;
```


Re: Mixin a function into a struct only if no member with that name already exists

2021-12-29 Thread Stanislav Blinov via Digitalmars-d-learn
On Wednesday, 29 December 2021 at 10:14:13 UTC, Tobias Pankrath 
wrote:



How do I mixin a function only if it is not already present?


Perhaps use opDispatch?


Re: AA and struct with const member

2021-12-28 Thread Stanislav Blinov via Digitalmars-d-learn

On Wednesday, 29 December 2021 at 02:33:08 UTC, frame wrote:
On Wednesday, 29 December 2021 at 01:11:13 UTC, Stanislav 
Blinov wrote:


Because opIndexAssign cannot distinguish at compile time 
between initialization and assignment:


```d
Stuff[Key] aa;
aa[key] = Stuff(args); // ostensibly, initialization
aa[key] = otherStuff;  // assignment to existing value
```

Same syntax, different behavior. This can only be caught at 
runtime. `require` and `update` though should be able to pull 
this off, and that they don't is a bug.


Of course but opIndexAssign() isn't there in my example. The 
compiler should call runtime's _aaGetY() or something like that 
directly.


It is doing that. You've asked why that should be compile error, 
and the answer is - because there's no way to distinguish between 
initialization and assignment here. I.e. you can't make one line 
compile and the other - not. Either both compile, or both don't. 
So if you allow them to compile, you'll have to have a runtime 
check, throwing an exception on attempt to assign. Which is just 
horrible. Better to leave the assignment a compile error, and 
make `require` and `update` do the job they're supposed to be 
doing.


Re: Is there a way to make a function parameter accept only values that can be checked at compile time?

2021-12-28 Thread Stanislav Blinov via Digitalmars-d-learn

On Tuesday, 28 December 2021 at 22:30:30 UTC, Ali Çehreli wrote:

On 12/28/21 2:06 PM, Steven Schveighoffer wrote:


   void print_num(int mul)(int num) {


Wasn't there a way of telling whether an 'auto ref' parameter 
is copied or not?


void print_num()(int num, auto ref int mul) {
  // ?
}

And that would indicate  that the argument was an rvalue?


__traits(isRef, mul).

I realize that rvalues are not exactly what the OP is 
interested in.


Yup, different thing.

One can also do this kind of stuff:


```d
import core.stdc.stdio;

struct Literal(alias val)
{
enum value = val;
}

enum lit(alias val) = Literal!val.init;

void print_num(Arg)(int num, Arg mul)
{
static if (is(Arg == Literal!val, alias val))
{
static if (is(typeof(val) == string))
printf("mul by compile-time string \"%s\"!\n", 
val.ptr);

else static if (is(typeof(val) == int) && (val == 3))
printf("mul by compile-time 3!\n");
else
printf("mul by compile-time thing\n");
}
else
{
printf("mul by runtime thing\n");
}
}

void main()
{
print_num(10, lit!"hello"); // mul by compile-time string 
"hello"!

print_num(10, lit!3);   // mul by compile-time 3!
print_num(10, lit!'a'); // mul by compile-time thing
print_num(10, 10);  // mul by runtime thing
}
```


Re: AA and struct with const member

2021-12-28 Thread Stanislav Blinov via Digitalmars-d-learn

On Tuesday, 28 December 2021 at 22:46:16 UTC, frame wrote:

On Tuesday, 28 December 2021 at 10:02:13 UTC, tsbockman wrote:


  // Should be a compile-time error, because it might reassign:
  test[key] = S(value);


This might be a typo in your example but why should it be a 
compile-time error, it cannot know if the key already exists in 
compile time on a variable. First time initialization should 
always work anyway.


Because opIndexAssign cannot distinguish at compile time between 
initialization and assignment:


```d
Stuff[Key] aa;
aa[key] = Stuff(args); // ostensibly, initialization
aa[key] = otherStuff;  // assignment to existing value
```

Same syntax, different behavior. This can only be caught at 
runtime. `require` and `update` though should be able to pull 
this off, and that they don't is a bug.


Re: How to loop through characters of a string in D language?

2021-12-23 Thread Stanislav Blinov via Digitalmars-d-learn

On Thursday, 23 December 2021 at 07:14:35 UTC, Salih Dincer wrote:

It seems faster than algorithms in Phobos. We would love to see 
this in our new Phobos.


```d
  void mallocReplace()



  void normalReplace()
string result = str.replace(';',"");

}/* Console Out:
Replace: 436 msecs
Malloc : 259 msecs
*/
```


You're comparing apples and oranges. When benchmarking, at least 
look at the generated assembly first.


replace is not in Phobos, it's a D runtime vestige. It's not 
getting inlined even in release builds with lto, whereas that 
manual version would. Also, benchmark with runtime strings, not 
literals, otherwise the compiler might even swallow the thing 
whole.


What you're benchmarking is, basically, inlined optimized search 
in a literal versus a function call.


Re: How to properly use variadic templates (functions)?

2021-12-21 Thread Stanislav Blinov via Digitalmars-d-learn

On Tuesday, 21 December 2021 at 15:42:59 UTC, russhy wrote:
Please keep us updated, that'll be interesting to see how a 
pure D printf would look like!


It already exists, it's called std.format.write.formattedWrite, 
in terms of which things like std.stdio.writef are implemented.


Re: How to insert code in place with templates/mixins?

2021-12-20 Thread Stanislav Blinov via Digitalmars-d-learn

On Monday, 20 December 2021 at 18:03:09 UTC, rempas wrote:

> Now the problem is that I want it to get the name of so 
> symbol and add it to a string literal.
Let's check this example: enum state(alias name) = `name` ~ ` = 
10;`;


https://dlang.org/spec/traits.html#identifier




Re: dynamic array + copy ctor

2021-12-19 Thread Stanislav Blinov via Digitalmars-d-learn

On Sunday, 19 December 2021 at 22:29:21 UTC, vit wrote:

Hello,
Why is copy ctor in this example not called?


Because D runtime isn't properly married to copy constructors 
yet. I.e. it's a bug, a variant of this one: 
https://issues.dlang.org/show_bug.cgi?id=20879





Re: How to define property type to Array!struct?

2021-12-15 Thread Stanislav Blinov via Digitalmars-d-learn
On Wednesday, 15 December 2021 at 11:36:41 UTC, Manfred Nowak 
wrote:

On Tuesday, 14 December 2021 at 08:28:01 UTC, WebFreak001 wrote:
[...]
Alternatively, remove the template `()` from your `struct 
Header`


What is the semantic sense of a template having no parameters?

Although the documentation declares such a template to be 
syntactically correct, not a single example suggests a meaning.


To add to other responses, certain features are only available 
for templates, such as constraints and `auto ref` parameters.


Re: Passing a derived class where base class is defined as ref parameter

2021-12-14 Thread Stanislav Blinov via Digitalmars-d-learn

On Tuesday, 14 December 2021 at 17:20:18 UTC, chopchop wrote:

I am using the "ref" here (I put tinyurl to avoid 
over-referencing the post instead of the github page itself):

https://tinyurl.com/bdddkmub

I would like to be able to pass any kind of console to 
updateFoodToken ( Console c ), ie either a winconsole or a 
nixconsole, which are derived from Console.


I mean I probably have a cognitive bias of being a c++ dev. Let 
me explain. If I was coding in C++ I would pass "A&". Not 
"const A&", because I do two function calls with console - for 
example console.gotoxy(...) - but those 2 members functions are 
not suffixed "const". Since it is work in progress, I dont even 
know if I am going to modify those functions at the end or do 
something else with console...


Simple. Don't take a `ref`. Just take a `Console`. Classes in D 
are reference types, you're not making a copy as you would in C++ 
if you were to write `updateFoodToken(Console c)`.


Re: Immutability and arrays

2021-12-14 Thread Stanislav Blinov via Digitalmars-d-learn
On Tuesday, 14 December 2021 at 15:28:30 UTC, Steven 
Schveighoffer wrote:


All the other problems you are having are deriving from this 
problem.


Not exactly. One of the problems seems to be a genuine bug:

```d
struct S
{
int[] x;

// doesn't even participate here, neither would postblit
this(ref return scope inout S other)
{
x = other.x.dup;
}

void opAssign(ref return scope inout S other)
{
x = other.x.dup;
}
}

void main()
{
immutable(S)[] src = [S([1, 2]), S([3, 4])];

auto dst = new S[src.length];

//dst[0 .. $] = src[0 .. $]; // this fails to compile even 
with opAssign defined


// this works:
foreach (i, ref it; dst)
it = src[i];
}
```

Spec: https://dlang.org/spec/arrays.html#array-copying


...contents of the array are the target of the assignment...


Per that wording, slice assignment should perform the equivalent 
of that foreach loop (after overlap checks, etc.). It doesn't, 
just tries implicit conversion, and fails.


Now, since we have copy ctors, slice assignment should, 
ostensibly, attempt to copy-assign elements (i.e. absent 
opAssign, try the copy ctor first).


Re: Immutability and arrays

2021-12-14 Thread Stanislav Blinov via Digitalmars-d-learn

On Tuesday, 14 December 2021 at 08:44:02 UTC, rumbu wrote:
I am trying to understand why in this two different cases 
(Simple and Complex), the compiler behaviour is different.


```d
struct SimpleStruct { int x;}
struct ComplexStruct { int[] x; }

void main()
{
SimpleStruct[] buf1;
immutable(SimpleStruct)[] ibuf1;
buf1[0 .. 10] = ibuf1[0 .. 10];
//this works

ComplexStruct[] buf2;
immutable(ComplexStruct)[] ibuf2;

buf2[0 .. 10] = ibuf2[0 .. 10];
//error cannot implicitly convert expression `ibuf2[0..10]` 
of type `immutable(ComplexStruct)[]` to `ComplexStruct[]`

}
```


Because is(typeof(immutable(ComplexStruct).x) == 
immutable(int[])). Can't bind an array of immutable to array of 
mutable. This would require a deep copy, i.e. copy constructor.


Re: A debug class has started

2021-12-13 Thread Stanislav Blinov via Digitalmars-d-learn

On Monday, 13 December 2021 at 20:58:42 UTC, forkit wrote:

immutable(char)[] replaceChar(char* str, ulong len, char ch1, 
char ch2)

//snip
return to!(immutable(char)[])(str);
}



You're calling a `to` on a char pointer, which, ostensibly, would 
look for null terminator. Which there may not be any if you do a 
.dup.


Re: Why code failed to compile for foo2?

2021-12-11 Thread Stanislav Blinov via Digitalmars-d-learn

On Saturday, 11 December 2021 at 23:44:59 UTC, Adam Ruppe wrote:
On Saturday, 11 December 2021 at 23:17:17 UTC, Stanislav Blinov 
wrote:
? No. If it was unsatisfied constraint, the error would've 
shown that.


And if you try to instantiate it, you'll see it is an 
unsatisfied constraint anyway. There's two layers of failure 
here.


Using Unqual there is pretty iffy, i wouldn't bother with it at 
all, but if you do anything, instead qualify it const.


But either way, then the constraint still fails since int isn't 
unsigned.


I'd really recommend simplifying this a lot.


??? There is no unsatisfied constraint, it doesn't get there :)

unq.d(6): Error: template `unq.foo2` cannot deduce function 
from argument types `!()(int)`

unq.d(2):Candidate is: `foo2(T)(Unqual!T x)`


...because passed argument - `int` - becomes `Unqual!T`, making 
`T` unknown - template arg list is empty. Deduction fails :) If 
`int` is an `Unqual!T`, what is `T`? The constraint is testing 
`T`.


Now, if you explicitly instantiate - sure, you'd get unsatisfied 
constraint. But the OP seems to want IFTI, which simply can't 
work here.


@apz28, I can't figure out the intent here. To convert result of 
abs to an unsigned?


Re: Why code failed to compile for foo2?

2021-12-11 Thread Stanislav Blinov via Digitalmars-d-learn

On Saturday, 11 December 2021 at 22:59:52 UTC, Adam Ruppe wrote:

On Saturday, 11 December 2021 at 22:50:45 UTC, apz28 wrote:

void foo2(T)(Unqual!T x) if(isUnsigned!T) {}


This means it treats foo2 as if it doesn't exist unless T is 
unsigned...


onlineapp.d(15): Error: template `onlineapp.foo2` cannot 
deduce function from argument types `!()(int)`

onlineapp.d(7):Candidate is: `foo2(T)(Unqual!T x)`
*/


And this is telling you it had a signed value - int - which 
means it doesn't match.


For the other ones, the functions still exist, so it does 
whatever conversion it needs. Whereas with the template that 
constraint means the compiler acts like it doesn't exist at all 
and thus doesn't even attempt an automatic conversion.


? No. If it was unsatisfied constraint, the error would've shown 
that. What's going on here is that the argument being passed is 
an int, when the parameter is an Unqual!T. So, 
https://dlang.org/spec/template.html#ifti would fail because 
there is no way of figuring out a T from an Unqual!T. Hence the 
message: cannot deduce function.


Re: How to loop through characters of a string in D language?

2021-12-11 Thread Stanislav Blinov via Digitalmars-d-learn
On Saturday, 11 December 2021 at 09:34:17 UTC, Ola Fosheim 
Grøstad wrote:



void donttrythisathome(string s, char stripchar) @trusted {
import core.stdc.stdlib;
char* begin = cast(char*)alloca(s.length);


A function with that name, and calling alloca to boot, cannot be 
@trusted ;)


Re: How to loop through characters of a string in D language?

2021-12-11 Thread Stanislav Blinov via Digitalmars-d-learn
On Friday, 10 December 2021 at 23:53:47 UTC, Ola Fosheim Grøstad 
wrote:



```d
char[] dontdothis(string s, int i=0, int skip=0){
if (s.length == i) return new char[](i - skip);
if (s[i] == ';') return dontdothis(s, i+1, skip+1);
auto r = dontdothis(s, i+1, skip);
r[i-skip] = s[i];
return r;
}
```


That is about 500% not what I meant. At all. Original code in 
question:


- duplicates string unconditionally as mutable storage
- uses said mutable storage to gather all non-semicolons
- duplicates said mutable storage (again) as immutable

I suggested to make the second duplicate conditional, based on 
amount of space freed by skipping semicolons.


What you're showing is... indeed, don't do this, but I fail to 
see what that has to do with my suggestion, or the original code.


Scanning short strings twice is not all that expensive as they 
will stay in the CPU cache > when you run over them a second 
time.



```d
import std.stdio;

@safe:
string stripsemicolons(string s) @trusted {
int i,n;
foreach(c; s) n += c != ';'; // premature optimization
auto r = new char[](n);
foreach(c; s) if (c != ';') r[i++] = c;
return cast(string)r;
}
```


Again, that is a different algorithm than what I was responding 
to. But sure, short strings - might as well. So long as you do 
track the distinction somewhere up in the code and don't simply 
call this on all strings.


Re: How to loop through characters of a string in D language?

2021-12-10 Thread Stanislav Blinov via Digitalmars-d-learn

On Friday, 10 December 2021 at 13:22:58 UTC, Matheus wrote:


My C way of thinking while using D:

import std;

string stripsemicolons(string input){
char[] s = input.dup;
int j=0;
for(int i=0;i


Oooh, finally someone suggested to preallocate storage for all 
these reinventions of the wheel :D


I would suggest instead of the final idup checking the length and 
only duplicating if certain waste threshold is broken, otherwise 
just doing 
https://dlang.org/phobos/std_exception.html#assumeUnique (or a 
cast to string). The result is unique either way.


Threshold could be relative for short strings and absolute for 
long ones. Makes little sense reallocating if you only waste a 
couple bytes, but makes perfect sense if you've just removed 
pages and pages of semicolons ;)


Be interesting to see if this thread does evolve into a SIMD 
search...


Re: How to loop through characters of a string in D language?

2021-12-08 Thread Stanislav Blinov via Digitalmars-d-learn

On Wednesday, 8 December 2021 at 22:18:23 UTC, forkit wrote:

It's also worth noting the differences in compiler output, as 
well as the time taken to compile, these two approaches:


(1)
string str = "abc;def;ab".filter!(c => c != ';').to!string;

(2)
string str = "abc;def;ab".replace(";", "");

see: https://d.godbolt.org/z/3dWYsEGsr


You're passing a literal. Try passing a runtime value (e.g. a 
command line argument). Also, -O2 -release :) Uless, of course, 
your goal is to look at debug code.


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

2021-12-08 Thread Stanislav Blinov via Digitalmars-d-learn
On Wednesday, 8 December 2021 at 08:07:59 UTC, Petar Kirov 
[ZombineDev] wrote:



```d
interface ICallable
{
void opCall() const;
}

alias Action = void delegate();

struct A
{
Action[] dg;
}
```


At this point why not just call a spade a spade and store an 
array of ICallables directly? :) I mean, why store fat pointers 
to fat pointers?


Re: Mixin template overloads not working

2021-12-03 Thread Stanislav Blinov via Digitalmars-d-learn

On Friday, 3 December 2021 at 10:42:37 UTC, Rumbu wrote:


Bug or feature? Is there any workaround?


The error message explains what to do :)

Error: class `mixinover.AnotherVisitor` use of 
`mixinover.Visitor.visit(S s)` is hidden by `AnotherVisitor`; 
use `alias visit = Visitor.visit;` to introduce base class 
overload set


Re: sleeping vs sched_yield

2021-12-02 Thread Stanislav Blinov via Digitalmars-d-learn

On Thursday, 2 December 2021 at 23:29:17 UTC, Chris Katko wrote:

there's:

```d
  import core.thread;
  Thread.sleep( dur!("msecs")(10) );
```

but what if you want to simply yield all remaining time back to 
the time scheduler?


Is there a D std.library accessible version of POSIX 
sched_yield:




There's 
https://dlang.org/phobos/core_thread_osthread.html#.Thread.yield


It seems I can (thanks to the amazing work of D community) 
simply do:


```d
extern(C) int sched_yield(void);  // #include 
```

however, how does the linker know I need  and not some 
local library, or SDL library, or SDL2.0 library, etc. 
Shouldn't I be specifying the library somewhere?


Linker doesn't need sched.h. Like H.S.Theoh said, it'll look for 
that symbol in libraries you're linking against. sched_yield is 
in libc, and by default you do link against that.



```
source/app.d(226,16): Error: cannot have parameter of type 
`void`

```

Should that be corrected in the compiler? Shouldn't () and 
(void) be interchangeable as long as you're not doing void*?


No: https://dlang.org/articles/ctod.html#funcvoid


Re: bool empty() const for ranges

2021-11-26 Thread Stanislav Blinov via Digitalmars-d-learn

On Friday, 26 November 2021 at 10:44:10 UTC, Salih Dincer wrote:


* Is the const essential for ranges?
* Is it possible to rewind the pointer (```Node * head;```) 
when my head is empty by the const?


`empty` is not required to be `const`, but it is required to 
yield the same result if called multiple times without mutating 
the range (see 
https://dlang.org/phobos/std_range_primitives.html#.isInputRange). In other words, you really ought not to mutate the range in implementation of `empty`, or at least not to the extent you seem to want to.


Re: Include .def definition file information for the linker into a .d source file

2021-11-25 Thread Stanislav Blinov via Digitalmars-d-learn

On Thursday, 25 November 2021 at 09:00:52 UTC, Imperatorn wrote:

What most ppl do in that case is to just provide a script, for 
example build.cmd that just does what it needs. The user just 
clicks the script and it does everything for them.


"How can I make it so that I don't need an extra file written in 
another language?"

"Just add yet another file written in yet another language".

Nice going there :)

Build scripts never have been scalable. A good language shall 
only require a compiler and source file(s). No extra voodoo 
mumbojumbo. This is why we have all those pragmas and the -i 
switch.


Re: Any additions for write-to-file short program

2021-11-18 Thread Stanislav Blinov via Digitalmars-d-learn

On Thursday, 18 November 2021 at 22:20:48 UTC, pascal111 wrote:
In next program that rewrites original written texts into new 
files, I see that it may need some additions or we can accept 
it like this because it's just a simple program that achieve 
its task and doesn't need any philosophical additions.


If "the task" is to copy a file, then this program, as presented, 
may fail at it. If you're going to do any exception handling at 
all, a question must be answered: what to do in case the 
algorithm is interrupted before completing? I.e. if the `while` 
loop throws an exception, which it can do on any line except for 
braces. Is it acceptable to leave the output file containing only 
part of input data, perhaps even no data at all? Or should you 
catch the exception and delete the output file? Will that even be 
possible?..




Re: using __traits to get line number of a member

2021-11-13 Thread Stanislav Blinov via Digitalmars-d-learn

On Sunday, 14 November 2021 at 04:05:45 UTC, forkit wrote:


However, there is no isClass method. Why not?

How do I determine if a member is a class.. I wonder...


```
static if (is(something == class)) { /* ... */ }
```

or, if member is an instance

```
static if (is(typeof(something) == class)) { /* ... */ }
```

Ditto for interfaces, structs, unions.


Re: using __traits to get line number of a member

2021-11-13 Thread Stanislav Blinov via Digitalmars-d-learn

On Saturday, 13 November 2021 at 08:04:56 UTC, forkit wrote:


int i;
foreach(m; __traits(allMembers, mixin(__MODULE__)))
// ...
__traits(getLocation, mixin(m))[1]);


What you really should be doing is this:

```d
static import mod = mixin(__MODULE__);
foreach (i, name; __traits(allMembers, mod))
{
   // ...
   __traits(getLocation, __traits(getMember, mod, i));
   // ...
}
```

Otherwise you might run into name conflicts, and get location of 
a wrong symbol.


Also if you really want to be generic you should couple it with 
`__traits(getOverloads)`, like the docs for getLocation suggest.


Re: using __traits to get line number of a member

2021-11-12 Thread Stanislav Blinov via Digitalmars-d-learn

On Saturday, 13 November 2021 at 05:31:51 UTC, forkit wrote:

Code below is self explanatory.

Any assistance on how to get the line number is welcome ;-)


https://dlang.org/spec/traits.html#getLocation

That?


Re: Completing C code with D style

2021-11-11 Thread Stanislav Blinov via Digitalmars-d-learn

On Thursday, 11 November 2021 at 22:10:04 UTC, forkit wrote:


It's called 'staged learning'.

Staged learning is the only way for humans to learn, due to the 
limitations of the human cognitive system. Specifically, the 
way short-term memory and long-term memory facilitate learning.


Those who lack this understanding of how humans learn, tend to 
throw too much at novices.


Like making a simple program do a bunch of extra work for 
literally no reason?


Also, this apparent drive towards requiring novices to 
understand the implications of their code, in terms of 
optimising the assembly that gets produced, is just nonsense. 
They'll never get pass the for loop!


This has nothing to do with "optimising the assembly".


Re: Completing C code with D style

2021-11-11 Thread Stanislav Blinov via Digitalmars-d-learn

On Thursday, 11 November 2021 at 21:56:19 UTC, Ali Çehreli wrote:

On 11/11/21 11:34 AM, Stanislav Blinov wrote:

> Pessimization, though, is laughably easy, and
> should be avoided at all costs.

I am not passionate about this topic at all and I am here 
mostly because I have fun in this forum. So, I am fine in 
general.


However, I don't agree that pessimization should be avoided at 
all costs. I like D because it allows me to be as sloppy as I 
want to fix my code later on when it really matters.


And when is that? And why is it not now? You mean prototyping? 
You can do that in any language, not sure what's special about D 
here. Sure, prototype away. No one gets everything right in a 
single keystroke.



> Not caring about *that* is just bad engineering.

There wasn't a problem statement with the original code. So, we 
understood and valued it according to our past experiences. For 
example, most of us assumed the program was about 10 integers 
but I am pretty sure that array was just an example and the 
program was meant to deal with larger number of arrays.


What difference does that make? You still don't want to do any 
unnecessary work, whether you're dealing with one puny array or a 
million of them.


Another example is, you seem to value performance over 
maintainability because you chose to separate the selection 
letters without getting any programmatic help from any tool:


I didn't "choose" that. That's Siarhei Siamashka's version, fixed 
up to use `each` instead of `map!text.join`, because latter 
serves no useful purpose.


That is a weird comparison anyway. Performance OVER 
maintainability? There's nothing "more performant" or "less 
maintainable" in the input handling code, as it's the same as 
original.



  write("Would you like in list (e=evens, o=odds, b=both)? ");
  readf(" %c", );

  if ((negativity == 'b') && (even == 'b'))

For example, the 'b's in that last line may be left behind 
unmodified if someone changes the help text alone.


Let me see if I get this straight now... are you seriously 
talking about protecting against this program being altered by a 
goldfish? Because in that case, I'd best not write any code 
altogether. Someone someday may put an extra semicolon somewhere, 
the thing would stop compiling, and I'll be totally ruined.

...Perhaps let's actually stay on this planet?

Someone may find that kind of coding "bad engineering" that 
shoul be avoided at all cost.


Sure. Someone definitely may. It'd certainly be nice to decouple 
input from logic. That doesn't take 14 times more code and AAs to 
do though. Just sayin' ;)


(Not to defend myself but my associative array was exactly 
because I could not bring myself to separate those selection 
letters from the help text. I simply could not show 
unmaintainable code to a beginner.)


The original UI code is four lines. Four. Not fool-proof, input's 
not even validated. But four lines. Yours is fifty five, just to 
construct and present the UI and read input. Consequently, 
original program is about 14 times easier to maintain than yours. 
What did I miss?


Re: Completing C code with D style

2021-11-11 Thread Stanislav Blinov via Digitalmars-d-learn

On Thursday, 11 November 2021 at 00:11:07 UTC, H. S. Teoh wrote:

It depends on what you're doing. In the OP's example, yeah 
worrying about allocations is totally blowing things out of 
proportions.


But that's the thing. How would one ever learn to know where that 
dividing line is if all the learning material they see teaches 
them the opposite - to not know or care?


'Twas a simple task: traverse an array and print numbers out of 
it based on a predicate. That is all the original program did. 
How does doing (LOTS) more than that make any of it easier to 
understand, let alone equivalent to execute?


forkit says: "if I was writing millions of processes across 1000s 
of servers..." No. Just... no. If I've only ever written 
"convenient" pessimized code, I won't magically start lighting up 
those wasted transistors just because I got a new job. I'll just 
be writing the same "convenient" pessimized code, only it would 
now span 1000s of servers. Which is the exact effing situation 
that we're in already!


Re: Completing C code with D style

2021-11-11 Thread Stanislav Blinov via Digitalmars-d-learn

On Wednesday, 10 November 2021 at 23:15:09 UTC, forkit wrote:

On Wednesday, 10 November 2021 at 22:17:48 UTC, russhy wrote:

On Wednesday, 10 November 2021 at 06:47:32 UTC, forkit wrote:
btw. My pc has 24GB of main memory, and my CPU 8MB L3 cache. 
So I really don't give a damn about allocations .. not one 
little bit ;-)




Having the right mindset helps not make these mistakes in the 
future


Changing habits is hard, make sure to train yourself to pick 
the right one, early if possible


Umm.. you kinda missed the last part of my post...

..where I said..'Now if I were running a million processes 
across 1000's of servers, I probably would give a damn.'


Your CPU executes code speculatively, and in parallel. That's 
just the way it is, it's how the machine works. Therefore, you 
simply cannot afford to NOT think about that. You're just wasting 
your machine time if you're not caring about that. Consequently, 
you're wasting your time, someone else's time, and, well, money.
No, it's not a million processes across 1000s of servers, it's at 
least two processes across n cores, each of which has m ALUs. (At 
least two because the OS is involved). But it's two processes 
from you, two processes from me, four from the other guy, and 
pretty soon you have a monster that struggles to utilize even a 
tenth of your machine. All because "I'll care about it tomorrow".


C'mon... nothing in my code was 'unacceptable' in terms of 
speed or efficiency.


Making code transformations to improve speed and efficieny are 
important, but secondary. A newcomer cannot improve code that 
they do not understand ;-)


Yes, optimization is hard. Pessimization, though, is laughably 
easy, and should be avoided at all costs. "I don't care" is the 
number 1 reason for the atrocious situation with software that 
we're in right now. And people tend to come up with all sorts of 
ridiculous excuses, but most of them, distilled, do amount to "I 
don't care".
My phone is a thousand times faster, and has two million times 
more memory, than the thing that guided Apollo 11 to the Moon. 
And yet it sometimes takes longer to react to my keystrokes than 
roundtrip for a radio signal to the Moon *and* back.
My desktop is two times faster, and has eight times more memory, 
than my phone. But it consistently takes THREE TIMES the 
roundtrip of a radio signal to the Moon and back to start Visual 
Studio.
Heck, it will take longer than the roundtrip of a radio signal to 
the Moon and back to post this message after I hit "Send". And 
I'm reasonably certain this news server is not on the Moon. This 
all is, plainly, ridiculous.



Picking understandable code first, IS right.


No. "Understability" is subjective. Show me some code in Scala or 
Fortran, I won't make heads or tails of it, even though it may be 
perfectly obvious to the next guy who also never saw either 
language. What's "right" is writing code that doesn't perform, or 
cause, any unnecessary work. It may not be fast, but at least it 
won't be slow for no reason.


In any case, I say again, this thread is not about writing 
performance code per se, but about presenting code to 
new-comers, that they can make some sense of.


And how does invoking extra work help with that? Coupled with not 
even explaining what that extra work is and why it is there?


Taking some C code, and writing/presenting it in D (or 
vica-versa) in such a way that you can longer make any sense of 
it, is kinda futile.


Original C code from the first post can only fail on I/O, which 
is arguably out of your control. And the meat of it amounts to 10 
conditional stores. Your implementations, in both C and D, are a 
very, very far distance away from that. Like I mentioned before, 
the whole algorithm can already complete even before a single 
`malloc` call starts executing. Not caring about *that* is just 
bad engineering.


If you're writing C, or D, you're not writing pulp fiction for 
the masses. There are other languages for that.


Re: Wrong result with enum

2021-11-11 Thread Stanislav Blinov via Digitalmars-d-learn

On Thursday, 11 November 2021 at 09:11:37 UTC, Salih Dincer wrote:

Unless explicitly set, default type is int. 110 is 
greater than int.max.

11
```d
  enum w = 100_000;
  size_t b = w * w;
  // size_t b = 10 * 10; // ???
  assert(b == 10_000_000_000); // Assert Failure
```
The w!(int) is not greater than the b!(size_t)...


That code is
```
size_t b = int(w) * int(w);
```

That is, `multiply two ints and assign result to a size_t`. 
Multiplication of two ints is still an int though, and you can't 
fit ten billion in an int, so that's overflow. It doesn't matter 
that you declare `b` as `size_t` here. Overflow happens before 
that assignment.


Re: Wrong result with enum

2021-11-10 Thread Stanislav Blinov via Digitalmars-d-learn

On Thursday, 11 November 2021 at 05:37:05 UTC, Salih Dincer wrote:

is this a issue, do you need to case?

```d
enum tLimit = 10_000;  // (1) true result
enum wLimit = 100_000; // (2) wrong result
```


https://dlang.org/spec/enum.html#named_enums

Unless explicitly set, default type is int. 110 is 
greater than int.max.


Re: Completing C code with D style

2021-11-09 Thread Stanislav Blinov via Digitalmars-d-learn

On Wednesday, 10 November 2021 at 06:47:32 UTC, forkit wrote:

btw. My pc has 24GB of main memory, and my CPU 8MB L3 cache. So 
I really don't give a damn about allocations .. not one little 
bit ;-)


That's not the point. The point is the program is doing 
unnecessary non-trivial work while introducing additional failure 
paths. It certainly has ways to go to reach Ali's AA solution, 
but still...


To put things in perspective, the algorithm can easily complete 
before malloc even returns (heck, before it even starts 
executing). There's what, 11 cmovs at most? It would take several 
dozen instructions, a couple of loops and a few other branches 
just to find malloc when you first call it. Not to mention it 
itself making that syscall and setting up its bins...


And I'm not even talking about optimization. Just, uh, 
non-pessimization.


Re: Completing C code with D style

2021-11-09 Thread Stanislav Blinov via Digitalmars-d-learn

On Tuesday, 9 November 2021 at 11:03:09 UTC, forkit wrote:


They both produce exactly the same output.


But do vastly different things.

But I tell ya.. the cognitive load .. well.. it increased 
dramatically ;-)


Of course it did. Cuz you overthunk it. Dramatically.

Your D version allocates memory, for no good reason. I mean, to 
store results, but you already have storage for them, so kinda 
pointless. Your C version, OTOH, stores results on stack (so 
again, why did you allocate for them in D?..), but allocates some 
"string builder" for... what, exactly?


The program is filter, or sort + partition. Requires 0 
allocations in C or D.


Re: auto ref function parameter causes that non copyable struct is copied?

2021-11-08 Thread Stanislav Blinov via Digitalmars-d-learn

On Monday, 8 November 2021 at 23:26:39 UTC, tchaloupka wrote:


```
auto gen() {
Foo f;   // <--- this one
f.n = 42;
return value(f.move());
}

void main() {
Foo f;
f = gen().unwrap.move;
}
```
~this(0)
~this(0)
~this(0)
~this(42) <- this is a copy (that shouldn't exist) being 
destroyed

~this(0)
~this(42)



Is it a copy? I think the first destructor call is one of `f` in 
`gen` (marked by the comment above)


Re: How do I assign attributes of a function to another function?

2021-11-05 Thread Stanislav Blinov via Digitalmars-d-learn

On Friday, 5 November 2021 at 06:19:16 UTC, Li30U wrote:

...e.g.
```d
// ...
mixin ("ReturnType /*...snip...*/ " ~ member ~ "()(Parameters! 
/*...snip...*/

```

Note the `()` before parameter list. This would make your member 
function a function template, for which attributes will be 
inferred by the compiler based on the calls you make in the 
function body.


Of course, making it a template like this makes it non-composable 
with that same type as you're only inspecting functions, so you 
wouldn't be able to do e.g. a Group!(Group!(A, 3), 4);


Re: How do I assign attributes of a function to another function?

2021-11-05 Thread Stanislav Blinov via Digitalmars-d-learn

On Friday, 5 November 2021 at 06:19:16 UTC, Li30U wrote:
I am creating a templated object that is a storehouse for a 
heap object and executes their methods and returns an array of 
results. With the help of a template, I want to achieve this, 
but I want to assign the same attributes to the function. How 
can one pass the attributes of a function to another function?


There's https://dlang.org/spec/traits.html#getFunctionAttributes 
. Or you could define your functions as function templates, 
letting the compiler infer attributes. Especially as it looks 
like you function's attributes may not be made the same as the 
ones you defer to: since you're allocating with the GC, your 
function cannot be @nogc even if a deferred one can.


Re: Completing C code with D style

2021-11-03 Thread Stanislav Blinov via Digitalmars-d-learn
On Wednesday, 3 November 2021 at 00:50:51 UTC, Siarhei Siamashka 
wrote:



!text.join("\n").writeln;


Ahem... You've turned a program that does not allocate to a 
program that allocates who knows how much memory?


And Ali... associative arrays? For this? What are you trying to 
teach the good beginner here? :D

```d
import std.stdio, std.algorithm;

void main()
{
  auto numbers = [-3, 14, 47, -49, -30, 15, 4, -82, 99, 26];
  char negativity, even;

  write("Would you like in list (n=negatives, p=positives, 
b=both)? ");

  readf(" %c", );

  write("Would you like in list (e=evens, o=odds, b=both)? ");
  readf(" %c", );

  if ((negativity == 'b') && (even == 'b'))
  {
  // don't do any unnecessary work
  numbers.each!writeln;
  }
  else
  {
  numbers.filter!(x => !((negativity == 'n' && x > 0) ||
 (negativity == 'p' && x < 0)))
 .filter!(x => !((even == 'e' && (x % 2)) ||
 (even == 'o' && !(x % 2
 .each!writeln;
  }
}
```


Re: Does associative array change the location of values?

2021-10-30 Thread Stanislav Blinov via Digitalmars-d-learn

On Saturday, 30 October 2021 at 22:47:57 UTC, Elronnd wrote:

If the GC were moving, it would also have to move the pointers 
you took to AA elements.  You would never get stale pointers in 
any event.


Who said you would?..


Re: Does associative array change the location of values?

2021-10-30 Thread Stanislav Blinov via Digitalmars-d-learn

On Saturday, 30 October 2021 at 20:19:58 UTC, Imperatorn wrote:


https://dlang.org/spec/garbage.html#pointers_and_gc


What test could be written to verify the behaviour?


Assuming the GC was moving?

You'd need a loop allocating different sizes, storing the 
addresses somewhere the GC won't see (i.e. in memory allocated 
not with the GC: malloc, VirtualAlloc, mmap...), orphaning some 
allocations, repeating a bunch of times, and then comparing 
addresses of remaining allocations with stored ones.


Behavior would very much depend on the GC implementation, so 
would a concrete test. Point is, it's allowed to move so we have 
to assume it would even if it doesn't, and relying on it not 
moving (i.e. depending on concrete addresses) is UB.


Re: Does associative array change the location of values?

2021-10-30 Thread Stanislav Blinov via Digitalmars-d-learn
On Saturday, 30 October 2021 at 18:31:16 UTC, Andrey Zherikov 
wrote:


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


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


Address itself may change though. While the AA won't move stuff 
around, a GC might. I don't think current GC moves anything, but 
it's definitely allowed to. Which would be transparent to your 
code so long as you don't depend on the value of address itself :)


https://dlang.org/spec/garbage.html#pointers_and_gc


Re: Does associative array change the location of values?

2021-10-30 Thread Stanislav Blinov via Digitalmars-d-learn
On Saturday, 30 October 2021 at 17:45:57 UTC, Steven 
Schveighoffer wrote:


You said "deallocating unreferenced elements". I thought you 
meant elements unreferenced by the AA.


Yup, I misunderstood you :)

What I mean is, the AA isn't going to change implementations 
where it now deallocates values that may still have existing 
references. If that's the case, we can state that in the docs.


e.g.:

Removing a key does not deallocate the value that was removed. 
The value's lifetime is managed by the GC and will be alive 
until there are no references to that value.


:whateveritistodoathumbsuphere:


Re: Does associative array change the location of values?

2021-10-30 Thread Stanislav Blinov via Digitalmars-d-learn
On Saturday, 30 October 2021 at 16:55:03 UTC, Steven 
Schveighoffer wrote:



auto v = k in aa;
aa.remove(k);

How can the GC/compiler work out that there is still a 
reference?


??? The same way it does for all other references.

I think either you misunderstood me, or I misunderstood you.



Re: Does associative array change the location of values?

2021-10-30 Thread Stanislav Blinov via Digitalmars-d-learn
On Saturday, 30 October 2021 at 11:59:15 UTC, Steven 
Schveighoffer wrote:


It should be documented. There isn't a valid way to remove 
these requirements, even if they are currently just an 
implementation detail -- code already depends on these 
properties.


And D is a GC-based language, especially when using AAs. There 
is no reason to introduce undefined behavior for existing usage.


You won't introduce UB by deallocating unreferenced elements, 
which a given GC *may* be able to figure out. Therefore I object 
to "AAs do not deallocate the key/value pairs ever" part. 
Strongly :) Until such time that such a requirement is indeed set 
in stone, and not incidental.


Re: Does associative array change the location of values?

2021-10-29 Thread Stanislav Blinov via Digitalmars-d-learn
On Friday, 29 October 2021 at 21:00:48 UTC, Steven Schveighoffer 
wrote:


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


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




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


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





Re: Linker issues with struct postblit

2021-10-29 Thread Stanislav Blinov via Digitalmars-d-learn

On Friday, 29 October 2021 at 11:05:14 UTC, Imperatorn wrote:
On Thursday, 28 October 2021 at 01:39:10 UTC, Thomas Gregory 
wrote:
I am a maintainer of the 
[dhtslib](https://github.com/blachlylab/dhtslib) package and I 
have been running into issues with a new implementation of 
reference counting we are using.


[...]


Postblit?


https://dlang.org/spec/struct.html#struct-postblit


Re: Bitfileds Error: no identifier for declarator

2021-10-27 Thread Stanislav Blinov via Digitalmars-d-learn
On Thursday, 28 October 2021 at 05:20:35 UTC, data pulverizer 
wrote:



I am trying to compile the following items:

struct sxpinfo_struct {
  mixin(bitfields!(
// ...
uint, "debug",1,
// ...
}
```

But I get the error...



`debug` is a language keyword, try a different one, like "debug_".

That error message though, much wow.


Re: What's the point of static arrays ?

2020-07-10 Thread Stanislav Blinov via Digitalmars-d-learn

On Friday, 10 July 2020 at 10:13:23 UTC, wjoe wrote:

So many awesome answers, thank you very much everyone!

Less overhead,
Using/needing it to interface with something else, and
Efficiency are very good points.

However stack memory needs to be allocated at program start. I 
don't see a huge benefit in allocation speed vs. heap 
pre-allocation, or is there?


Stack is allocated by the OS for the process when it's started. 
Reserving space for stack variables, including arrays, is 
effectively free, since the compiler assigns offsets statically 
at compile time.


I mean 1 allocation vs 2 isn't going to noticeably improve 
overall performance.


A GC allocation is way more complex than a mere bump-the-pointer. 
If your program is trivial enough you may actually find that one 
extra GC allocation is significant in its runtime. Of course, if 
you only ever allocate once and your program runs for ages, you 
won't really notice that allocation.



a[]

What happens here exactly ?


This:

int[10] a;
int[] slice = a[];
assert(slice.ptr == [0]);
assert(slice.length == 10);
assert(a.sizeof == 10 * int.sizeof);// 40
assert(slice.sizeof == (int[]).sizeof); // 16 on 64 bit

I read the chapters in Ali's book (thank you very much for such 
a great book, Ali) on arrays and slicing prior to asking this 
question and I came to the following conclusion:


Because a static array is pre-allocated on the stack,
doesn't have a pointer/length pair,
is addressed via the stack pointer, and
due to the fact that a slice is a pointer/length pair
  and because a slice is technically the meta data of a dynamic 
array, a view into (part) of a dynamic array,


No. A slice is just a pointer/length pair - a contiguous view 
into *some* memory, regardless of where that memory came from:


void takeASlice(scope void[] data) // can take any slice since 
any slice converts to void[]

{
import std.stdio;
writefln("%x %d", data.ptr, data.length);
}

int[10] a;
takeASlice(a); // a[]
takeASlice(a[1 .. $-1]); // a[1 .. 9]

struct S
{
float x, y, z;
float dx, dy, dz;
}

S s;
takeASlice(()[0 .. 1]); // Slicing a pointer, not @safe but can 
be done.

takeASlice(new int[10]); // Array, GC allocation
takeASlice([1, 2, 3, 4]); // Array literal, may or may not be 
GC-allocated


`takeASlice` has no knowledge of where the memory came from.

Dynamic arrays only ever come into the picture if you try to 
manipulate the slice itself: resize it, append to it, etc.


that it's not possible to slice a static array because the 
slice would technically be akin to a dynamic array and hence be 
incompatible.


Incompatible to what?

int[10] a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
a[0 .. 2] = a[2 .. 4];
assert(a[0] == 3);
assert(a[1] == 4);
int[10] b = void;
b[] = a[];
assert(b == [3, 4, 3, 4, 5, 6, 7, 8, 9, 10]);


struct SuperSpecializedArray(T, size_t S) if (S > 0)
{
   T[S] elements;

   struct SuperSpecializedArrayRange
   {
  typeof(elements) e;

  this(SuperSpecializedArray a)
  {
 e = a.elements; // copies
  }

  // ...
   }
}

Upon creation of a SuperSpecializedArrayRange, the array is 
copied, but more importantly, data which may not ever be needed 
is copied and that's supposed to be a big selling point for 
ranges - only ever touching the data when it's requested - am I 
wrong ?


Ranges need not be lazy. They can be, and most of them should be 
indeed, but they need not be. And, as you yourself point out, in 
your case `e` can just be a slice, and your range becomes lazy.


Re: How to ensure template function can be processed during compile time

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

On Wednesday, 8 July 2020 at 20:11:05 UTC, IGotD- wrote:


int v;

enum sz = mySize!int // works, returns 46
enum sz2 = mySize(v) // doesn't work. Error: variable v cannot 
be read at compile time


Here we have a difference between C++ and D as C++ was able 
infer the size of v during compile time.


To add to other respondents' replies, you can pass something that 
is known at compile time, for example the .init value:


int v;
enum sz2 = mySize(v.init);
static assert(sz2 == 46);

This way the compiler is able to evaluate `mySize` at compile 
time.


Or use an alias template argument:

auto mySize(alias v)()
{
return v.sizeof + 42;
}

int v;
enum sz = mySize!int;
enum sz2 = mySize!v;
static assert(sz == sz2);
static assert(sz == 46);


Re: constructing labels for static foreach inside switch inside foreach

2020-07-08 Thread Stanislav Blinov via Digitalmars-d-learn
On Wednesday, 8 July 2020 at 02:06:01 UTC, Steven Schveighoffer 
wrote:


Seems simple enough, except that this inner portion is 
unrolled, and if I have more than one type to run this on, I 
already have an "innerloop" label defined.


Is there a way to define a label using a mixin or something? or 
do I have to wrap this in a function?


Is there another way to approach this?


Can't you put a single label after your outer foreach and goto it?


Re: opApply and attributes

2020-07-07 Thread Stanislav Blinov via Digitalmars-d-learn

On Tuesday, 7 July 2020 at 13:33:41 UTC, Paul Backus wrote:


You can make opApply a template:

int opApply(Dg)(Dg dg)
if (is(Dg : scope int delegate(ref E)))
{
// etc.
}

Because `scope int delegate(ref E) @safe` implicitly converts 
to `scope int delegate(ref E)`, this version will accept both 
@safe and non-@safe delegates. (And likewise for the other 
function attributes.)


Yeah, but unfortunately then this won't work:


foreach(elem; test) {
assert(elem == key);
}


you'd have to spell out the types for `elem`.


Re: BetterC Bug? Intended Behavior? Asking Here As Unsure

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

On Monday, 6 July 2020 at 20:06:51 UTC, Kayomn wrote:
Something discovered in the D Language Code Club Discord server 
with the help of Wild is that the following code:


struct Test { ~this() {} }
void tester(Test test, Test[] tests...) { }

extern(C) void main() {
tester(Test(), Test());
}

Raises the "TypeInfo cannot be used with ~betterC" error. It 
seems to be due to an inclusion of both the destructor and the 
non-vararg and vararg argument matching from testing.


Anyone know a way around this without resulting to the rather 
hacky solution of just having 1 argument and always assuming 
that at least 1 argument is present?


Here is a code demo setup for demonstrating the potential 
problem:

https://run.dlang.io/is/A6oIpl


This seems to compile:

struct Test { ~this() {} }
void tester(size_t n)(Test[n] tests...)
if (n > 0)
{}

extern(C) void main() {
tester(Test(), Test());
}

No assumptions, though `tester` does become a template.

I'd say the original error should be reported on bugzilla, if it 
isn't already; if only for the error message which is 
ridiculously obscure.


Re: Print only part of a stack trace

2020-07-01 Thread Stanislav Blinov via Digitalmars-d-learn

On Wednesday, 1 July 2020 at 18:30:15 UTC, Dennis wrote:

I have a function that checks a global error constant of a C 
library (OpenGL) like this:

```
void assertNoOpenGLErrors() {
if (glGetError() != GL_NO_ERROR) {
assert(0); // stack trace points to here instead of 
caller

}
}
```

And I would like to rewrite it to this:
```
void assertNoOpenGLErrors() {
if (glGetError() != GL_NO_ERROR) {
print(getStackTrace().filterTrace());
exit();
}
}
```


void assertNoOpenGLErrors(string file = __FILE__, int line = 
__LINE__, string func = __PRETTY_FUNCTION__)

{
if (glGetError() != GL_NO_ERROR) {
print(file, ":", line, ":", func, ": blah");
exit();
}
}

:)


Re: Progress printing with threads?

2020-07-01 Thread Stanislav Blinov via Digitalmars-d-learn

On Wednesday, 1 July 2020 at 07:52:28 UTC, AB wrote:
Hello. I am unsure how to proceed about printing progress in my 
program.

Is it a good idea to std.concurrency.spawn a new thread?..
This example code shows my situation:

MmFile  input   = new MmFile(/* ... */);
ulong   fileSize= input.length;

for (ulong i = 0; i < fileSize; ++i)
{
// ...
}


If you can only update the progress between iterations I don't 
see why you would use threads here. A timer should suffice:


import std.datetime.stopwatch;

MmFile  input   = new MmFile(/* ... */);
ulong   fileSize= input.length;
autosw  = StopWatch(AutoStart.yes);

for (ulong i = 0; i < fileSize; ++i)
{
  // ...
  if (sw.peek >= 2.seconds)
  {
  writefln("Progress: %5.2f%%", i*100.0/fileSize);
  sw.reset;
  }
}



Re: idiomatic output given -preview=nosharedaccess ,

2020-06-30 Thread Stanislav Blinov via Digitalmars-d-learn
On Tuesday, 30 June 2020 at 20:04:33 UTC, Steven Schveighoffer 
wrote:


The answer is -- update Phobos so it works with -nosharedaccess 
:)


Yeah... and dip1000. And dip1008. And dip... :)



Re: Privatize a few members to allow messing with them #11353

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

On Tuesday, 30 June 2020 at 19:58:05 UTC, matheus wrote:


+loc.linnum = loc.linnum + incrementLoc;

This works because it was declared:

void linnum(uint rhs) { _linnum = rhs; }

Right?


Almost. Given these definitions:

@safe @nogc pure @property
{
const uint linnum() { return _linnum; }
void linnum(uint rhs) { _linnum = rhs; }
}

This:

loc.linnum = loc.linnum + incrementLoc;

is rewritten as:

loc.linnum(loc.linnum() + incrementLoc);


Re: Privatize a few members to allow messing with them #11353

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

On Tuesday, 30 June 2020 at 19:42:57 UTC, matheus wrote:

in this case this was more a style thing than anything else 
right? Or is there something I'm not able to see?


Before the change, linnum and charnum are public variables, one 
can do a += on them. After the change, they become properties 
accessing, as the PR says, private variables:


@safe @nogc pure @property
{
const uint linnum() { return _linnum; }
const uint charnum() { return _charnum; }
void linnum(uint rhs) { _linnum = rhs; }
void charnum(uint rhs) { _charnum = rhs; }
}

...with which the += won't work (at least this variant, as the 
getter isn't returning ref).


Re: scope guard question

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

On Monday, 29 June 2020 at 22:31:12 UTC, Arjan wrote:

So when no inner scope is present, the scope exit 'runs' after 
the return? Is that indeed expected behavior according to the 
specification?


Yes. A scope ends at the '}'. Destructors and scope guards 
execute then, after the return.


Re: [DIP1000] Something I don't quite understand regarding 'scope'

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

On Monday, 29 June 2020 at 06:21:43 UTC, ag0aep6g wrote:

Since `local` and `writeln` are templates, the attributes for 
their parameters are inferred from their bodies. `local!(int*)` 
doesn't do anything with the parameter, so it's inferred as 
`scope`. `writeln!(int*)` apparently does something that 
prevents `scope` from being inferred.


Thanks. It would appear indeed that inference fails for some 
reason. Explicitly marking args as 'scope' for `writeln` and 
`File.write` lets them compile. I wonder if there's a way to find 
exactly what it is in either of those that prevents the compiler 
from inferring 'scope'.


Re: reference variables don't exist, but can simulate them

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

On Monday, 29 June 2020 at 02:11:15 UTC, NonNull wrote:

Deprecation: Cannot use alias this to partially initialize 
variable j of type refer. Use j._()


This is for the line j=3

What is this about? Where does this hidden rule come from?


That one comes from [1]. But there are quite a few more "hidden" 
rules that you're violating here. Try putting @safe on your main 
and compiling with -preview=dip1000 (for dmd, refer to your 
compiler's help if you're using others). The bulk of escape 
analysis is only done for @safe, and only with that DIP enabled 
(IIRC only some trivial checks are done otherwise).


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


  1   2   3   >