Re: How to update Associative Array?

2022-02-18 Thread kdevel via Digitalmars-d-learn

On Monday, 14 February 2022 at 01:04:08 UTC, Ali Çehreli wrote:

[...]

Point taken but how deep should we understand library code, not 
all being Phobos. My pet peeve:


import std.stdio;

void main(string[] args) {
  writefln!"hello"(42);
}

/usr/include/dlang/dmd/std/stdio.d(4442): Error: no property 
`msg` for type `string`


I am happy that it's caught at compile time but what 'msg' 
property are we talking about? What does it have to be with me?


I would like it if the

It would be better if the compilation error said:

  Must satify formatSpecsMatchArgs!("hello", int)


Interestingly

   writefln ("hello", 42);

does not throw at runtime.




Re: How to update Associative Array?

2022-02-13 Thread Ali Çehreli via Digitalmars-d-learn

On 2/13/22 05:58, kdevel wrote:
> On Sunday, 13 February 2022 at 01:27:45 UTC, Ali Çehreli wrote:
>> [...]
>> > If I remove the constraint (the if-stuff) I get
>> >
>> > v1.d(12): Error: cannot implicitly convert expression
>> `kv.value()`
>> > of type `byte` to `string`
>> > v1.d(23): Error: template instance
>> `v1.update!(string[int],
>> > byte[short])` error instantiating
>>
>> That's inferior because now the error message is pointing at the
>> implementation of a library function and confuses everyone.
>
> It confuses me not really. (Function) templates are by their very nature
> visible to the user and I got used to reading the implementations.

Point taken but how deep should we understand library code, not all 
being Phobos. My pet peeve:


import std.stdio;

void main(string[] args) {
  writefln!"hello"(42);
}

/usr/include/dlang/dmd/std/stdio.d(4442): Error: no property `msg` for 
type `string`


I am happy that it's caught at compile time but what 'msg' property are 
we talking about? What does it have to be with me?


I would like it if the

It would be better if the compilation error said:

  Must satify formatSpecsMatchArgs!("hello", int)

I am not sure whether it's practical or efficient at compile time.

> The constraints appear artificial to me: Neither are there means which
> ensure
> that a list of Constraints is complete nor is it ensured that a list of
> constraints is not overly restrictive.

Agreed.

> It seems that these Constraints
> constitute
> another class of things which may get out of sync with the actual code
> (besides program documentation, program comments and function names).

Agreed.

>
> Doesn't this re-iteration of what is already implicitly contained in the
> line
>
> target[kv.key] = kv.value;

I don't agree with that because there is no 'target', 'kv', etc. in the 
programmer's code. Should we really expect the programmers be 
programmers? :p


> violate the DRY principle?

Agreed.

Ali



Re: How to update Associative Array?

2022-02-13 Thread kdevel via Digitalmars-d-learn

On Sunday, 13 February 2022 at 01:27:45 UTC, Ali Çehreli wrote:

[...]
> If I remove the constraint (the if-stuff) I get
>
> v1.d(12): Error: cannot implicitly convert expression
`kv.value()`
> of type `byte` to `string`
> v1.d(23): Error: template instance
`v1.update!(string[int],
> byte[short])` error instantiating

That's inferior because now the error message is pointing at 
the implementation of a library function and confuses everyone.


It confuses me not really. (Function) templates are by their very 
nature

visible to the user and I got used to reading the implementations.
Nonetheless may the compiler-generated checks be moved into the 
interface:


   void update(Target, From)(ref Target target, From from, Target 
dummy = From.init)


For this function template dmd reports in case of incompatible 
types:


   cannot implicitly convert expression `null` of type 
`byte[short]` to `string[int]`



[...]


After all, everything that the programmer needs is spelled out 
here. It requires following some types:



  with `Target = string[int],
   From = byte[short]`
  must satisfy the following constraint:
 isImplicitlyConvertible!(ValueType!From, 
ValueType!Target)`


The only thing that's not readily available there is ValueType 
but at least it's very readable.


The constraints appear artificial to me: Neither are there means 
which ensure
that a list of Constraints is complete nor is it ensured that a 
list of
constraints is not overly restrictive. It seems that these 
Constraints constitute
another class of things which may get out of sync with the actual 
code (besides program documentation, program comments and 
function names).


Doesn't this re-iteration of what is already implicitly contained 
in the line


   target[kv.key] = kv.value;

violate the DRY principle?




Re: How to update Associative Array?

2022-02-12 Thread Ali Çehreli via Digitalmars-d-learn

On 2/12/22 13:37, kdevel wrote:
> On Thursday, 10 February 2022 at 17:09:23 UTC, Ali Çehreli wrote:
>> import std.traits : isAssociativeArray, isImplicitlyConvertible,
>> KeyType, ValueType;
>>
>> void update(Target, From)(ref Target target, From from)
>> if (isAssociativeArray!Target &&
>> isAssociativeArray!From &&
>> isImplicitlyConvertible!(KeyType!From, KeyType!Target) &&
>> isImplicitlyConvertible!(ValueType!From, ValueType!Target))
>> {
>>   foreach (kv; from.byKeyValue) {
>> target[kv.key] = kv.value;
>>   }
>> }
>
> [...]
>
>> Yes, it may look scary to newcomers to D but the template constraint
>> is just for improved usability.
>
> It also looks scary to me and I use D now for quite a while. Assume I
> have this client code:
>
> string[int] q;
> byte[short] r;
> q.update (r);

So, that code is not valid because a 'byte' cannot implicitly be 
converted to a 'string'.


> It produces this error message from your version:
>
> $ dmd -checkaction=context -unittest -run v1
> v1.d(21): Error: template `v1.update` cannot deduce function from
> argument types `!()(string[int], byte[short])`
> v1.d(3):Candidate is: `update(Target, From)(ref Target
> target, From from)`
>   with `Target = string[int],
>From = byte[short]`
>   must satisfy the following constraint:
> `   isImplicitlyConvertible!(ValueType!From, ValueType!Target)`

That looks like a wall of text but is much better than before. Now, the 
compiler is telling us what requirement could not be met.


Additionally, the compilation fail in user code; telling the user why 
their code is not valid.


> If I remove the constraint (the if-stuff) I get
>
> v1.d(12): Error: cannot implicitly convert expression `kv.value()`
> of type `byte` to `string`
> v1.d(23): Error: template instance `v1.update!(string[int],
> byte[short])` error instantiating

That's inferior because now the error message is pointing at the 
implementation of a library function and confuses everyone. We have such 
functions in Phobos.


> Can this really be improved?

I am not sure.

Here is an idea, which doesn't seem to add much as is:

'if' constraints could have a message for an improved error message like 
"This function template could not be used because 'byte' cannot 
implicitly be converted to 'string'." Note that there could be many 
candidates like "And this function template could not be used because 42 
is not prime", etc. The programmer would read all those and figure out 
usable parameters.


But I think those would just be translations of the error messages.

Another idea is perhaps the compiler could resolve ValueType!From to 
'byte' and provide the more readable


  isImplicitlyConvertible!(byte, string)

I don't know how feasible that is.

Still, I am glad the error messages today are much better. After all, 
everything that the programmer needs is spelled out here. It requires 
following some types:



  with `Target = string[int],
   From = byte[short]`
  must satisfy the following constraint:
 isImplicitlyConvertible!(ValueType!From, ValueType!Target)`

The only thing that's not readily available there is ValueType but at 
least it's very readable.


Sorry, I rambled but I'm under the impression that this complexity is 
inherent.


Ali



Re: How to update Associative Array?

2022-02-12 Thread kdevel via Digitalmars-d-learn

On Thursday, 10 February 2022 at 17:09:23 UTC, Ali Çehreli wrote:
import std.traits : isAssociativeArray, 
isImplicitlyConvertible, KeyType, ValueType;


void update(Target, From)(ref Target target, From from)
if (isAssociativeArray!Target &&
isAssociativeArray!From &&
isImplicitlyConvertible!(KeyType!From, KeyType!Target) &&
isImplicitlyConvertible!(ValueType!From, ValueType!Target))
{
  foreach (kv; from.byKeyValue) {
target[kv.key] = kv.value;
  }
}


[...]

Yes, it may look scary to newcomers to D but the template 
constraint is just for improved usability.


It also looks scary to me and I use D now for quite a while. 
Assume I have this client code:


   string[int] q;
   byte[short] r;
   q.update (r);

It produces this error message from your version:

   $ dmd -checkaction=context -unittest -run v1
   v1.d(21): Error: template `v1.update` cannot deduce function 
from argument types `!()(string[int], byte[short])`
   v1.d(3):Candidate is: `update(Target, From)(ref Target 
target, From from)`

 with `Target = string[int],
  From = byte[short]`
 must satisfy the following constraint:
   `   isImplicitlyConvertible!(ValueType!From, 
ValueType!Target)`


If I remove the constraint (the if-stuff) I get

   v1.d(12): Error: cannot implicitly convert expression 
`kv.value()` of type `byte` to `string`
   v1.d(23): Error: template instance `v1.update!(string[int], 
byte[short])` error instantiating


Can this really be improved?

Stefan


Re: How to update Associative Array?

2022-02-10 Thread Ali Çehreli via Digitalmars-d-learn

On 2/10/22 05:42, novice2 wrote:
> On Thursday, 10 February 2022 at 12:08:07 UTC, tastyminerals wrote:
>> I meant a different thing though. I am looking for
>> `mydic.update(another_dic)` analogue where `{"a": 1, "b": 2}` update
>> `{"c": 3, "a": -1}` becomes `{"a":-1, "b": 2, "c": 3}`.
>
> you need "merge"?
> https://forum.dlang.org/post/fhhuupczjnhehxplj...@forum.dlang.org
>

Probably but Python's update updates the original dictionary. I came up 
with the following function:


import std.traits : isAssociativeArray, isImplicitlyConvertible, 
KeyType, ValueType;


void update(Target, From)(ref Target target, From from)
if (isAssociativeArray!Target &&
isAssociativeArray!From &&
isImplicitlyConvertible!(KeyType!From, KeyType!Target) &&
isImplicitlyConvertible!(ValueType!From, ValueType!Target))
{
  foreach (kv; from.byKeyValue) {
target[kv.key] = kv.value;
  }
}

unittest {
  auto a = [ "a": 1, "b": 2 ];
  a.update([ "c": 3, "a": -1 ]);
  assert(a == [ "a": -1, "b": 2, "c": 3 ]);
}

void main() {
}

Yes, it may look scary to newcomers to D but the template constraint is 
just for improved usability. (Still, I suspect it's not complete.) 
Otherwise, the following is the same thing:


void update(Target, From)(ref Target target, From from) {
  foreach (kv; from.byKeyValue) {
target[kv.key] = kv.value;
  }
}

'ref' is needed there to work with null AAs. Without 'ref', the 
following would not work:


  int[string] aa;
  aa.update([ "x" : 42 ]);

'aa' would be null! Welcome to AA reference semantics. :)

Ali



Re: How to update Associative Array?

2022-02-10 Thread novice2 via Digitalmars-d-learn
On Thursday, 10 February 2022 at 12:08:07 UTC, tastyminerals 
wrote:
I meant a different thing though. I am looking for 
`mydic.update(another_dic)` analogue where `{"a": 1, "b": 2}` 
update `{"c": 3, "a": -1}` becomes `{"a":-1, "b": 2, "c": 3}`.


you need "merge"?
https://forum.dlang.org/post/fhhuupczjnhehxplj...@forum.dlang.org



Re: How to update Associative Array?

2022-02-10 Thread tastyminerals via Digitalmars-d-learn

On Thursday, 10 February 2022 at 12:04:04 UTC, bauss wrote:
On Thursday, 10 February 2022 at 10:59:17 UTC, tastyminerals 
wrote:

[...]


You can just do:

aa[key] = value.

If the key exist then it's updated, if it doesn't then it's 
added.


The reason for the update function is simply in cases where you 
want to use the oldvalue etc. perhaps it has a timestamp that 
you need to keep etc.


But in general you shouldn't need it.


I meant a different thing though. I am looking for 
`mydic.update(another_dic)` analogue where `{"a": 1, "b": 2}` 
update `{"c": 3, "a": -1}` becomes `{"a":-1, "b": 2, "c": 3}`.


Re: How to update Associative Array?

2022-02-10 Thread bauss via Digitalmars-d-learn
On Thursday, 10 February 2022 at 10:59:17 UTC, tastyminerals 
wrote:
Not sure if the `update` method got changed but I am having 
trouble with understanding it now.
I assumed it would work as easy as in Python:) Just do 
`mydic.update(dic)` or `mydic["key"].update(anotherDic)`.


The docs have the following example.

```
class C{}
C[string] aa;

C older;
C newer;
aa.update("a",
{
newer = new C;
return newer;
},
(ref C c)
{
older = c;
newer = new C;
return newer;
});
```

This looks pretty scary and confusing to me tbo. Also, why is 
there an example with class and not simple `int[string]`? I 
just need to know how can I update let's say `int[string]` or 
nested `int[string][string]` AA. Should I also initialise and 
additional C classes before calling this method as in the 
example?


Considering this is the only example in the docs I could find 
on how to update AA, imagine someone from Python world comes 
and sees this. Next thing he does, is close the page and never 
come back to D again :(


You can just do:

aa[key] = value.

If the key exist then it's updated, if it doesn't then it's added.

The reason for the update function is simply in cases where you 
want to use the oldvalue etc. perhaps it has a timestamp that you 
need to keep etc.


But in general you shouldn't need it.


How to update Associative Array?

2022-02-10 Thread tastyminerals via Digitalmars-d-learn
Not sure if the `update` method got changed but I am having 
trouble with understanding it now.
I assumed it would work as easy as in Python:) Just do 
`mydic.update(dic)` or `mydic["key"].update(anotherDic)`.


The docs have the following example.

```
class C{}
C[string] aa;

C older;
C newer;
aa.update("a",
{
newer = new C;
return newer;
},
(ref C c)
{
older = c;
newer = new C;
return newer;
});
```

This looks pretty scary and confusing to me tbo. Also, why is 
there an example with class and not simple `int[string]`? I just 
need to know how can I update let's say `int[string]` or nested 
`int[string][string]` AA. Should I also initialise and additional 
C classes before calling this method as in the example?


Considering this is the only example in the docs I could find on 
how to update AA, imagine someone from Python world comes and 
sees this. Next thing he does, is close the page and never come 
back to D again :(