Re: abs and minimum values

2021-10-31 Thread Siarhei Siamashka via Digitalmars-d-learn

On Thursday, 28 October 2021 at 21:23:15 UTC, kyle wrote:

```
void main()
{
import std.math : abs, sgn;

alias n_type = short; //or int, long, byte, whatever

assert(n_type.min == abs(n_type.min));
assert(sgn(abs(n_type.min)) == -1);
}
```
I stumbled into this fun today. I understand why abs yields a 
negative value here with overflow and no promotion. I just want 
to know if it should. Should abs ever return a negative number? 
Thanks.


I think that the best way to deal with this stuff without losing 
sanity is to introduce a special constant "n_type.nan" for signed 
integer data types. Then you get "abs(n_type.nan) == n_type.nan", 
which makes more sense.


All the uses of "n_type.min" in your code can be replaced either 
with "n_type.nan" or "-n_type.max", depending on the context and 
your intention. The existing constant "n_type.min" can be 
deprecated for signed integer types. Compilers and static 
analysis tools could warn about its use.




Re: abs and minimum values

2021-10-31 Thread Imperatorn via Digitalmars-d-learn

On Friday, 29 October 2021 at 08:05:35 UTC, Dom DiSc wrote:

On Thursday, 28 October 2021 at 21:26:04 UTC, kyle wrote:


Okay I checked the phobos docs and it does say "Limitations
Does not work correctly for signed intergal types and value 
Num.min." Should have looked there first, I know. Still seems 
pretty silly.


I recommend to implement your own abs function this way (was 
not accepted for phobos, as it now does NOT return the same 
type as the argument, which was considered a "breaking change" 
:-( ):

```D
/// get the absolute value of x as unsigned type. always 
succeeds, even for T.min

Unsigned!T abs(T)(const(T) x) if(isIntegral!T)
{
   static if(isSigned!T) if(x < 0) return cast(Unsigned!T)-x;
   return x;
}
```


Just fix it for floats and it would be all round 100 times better 
than what we currently have ☀


Re: Does associative array change the location of values?

2021-10-31 Thread H. S. Teoh via Digitalmars-d-learn
On Sat, Oct 30, 2021 at 07:56:35PM -0700, Ali Çehreli via Digitalmars-d-learn 
wrote:
> On 10/30/21 3:47 PM, Elronnd wrote:
> 
> > If the GC were moving, it would also have to move the pointers you
> > took to AA elements.
> 
> I doubt D's GC can ever change pointer values because the values may
> be hiding inside e.g. ulong variables. And we would definitely not
> want the GC to change ulong values just because it thought they were
> familiar pointer values in disguise. :)
[...]

The current spec explicitly states that masking pointers this way is UB.


T

-- 
Без труда не выловишь и рыбку из пруда. 


Re: abs and minimum values

2021-10-31 Thread Imperatorn via Digitalmars-d-learn
On Sunday, 31 October 2021 at 10:12:49 UTC, Siarhei Siamashka 
wrote:

On Sunday, 31 October 2021 at 05:04:33 UTC, Dom DiSc wrote:

On Friday, 29 October 2021 at 14:20:09 UTC, Ali Çehreli wrote:

[...]


This should be no surprise. You need to know what the 
resulting type of int + uint should be. And it is .. uint! 
 which is one of the stupit integer-promotion rules inherited 
from C.


Then let's change the example to:

   int b = -4;
   writeln(-abs(b));

What would one normally expect to be printed here? Should the 
unary minus operator also do some kind of implicit "unsigned -> 
signed" type change magic to accommodate this modified version 
of the abs function and make it behave in a non-surprising way?


What I would like is for it to mirror math.


The type inference everywhere

2021-10-31 Thread Salih Dincer via Digitalmars-d-learn

```d
auto foo(int value, auto s = Section(2, 60)) {
   int max;  /*   ^--- ?
   ...*/
   return Section (0, max)
 }
```
Is possible something like above pointed. OK, I know it isn't 
because I tried! Well, wouldn't it be nice if it did?


Why shouldn't the inference be possible on default argument? Peek 
out of rvalue...


Thanks...


Re: abs and minimum values

2021-10-31 Thread Siarhei Siamashka via Digitalmars-d-learn

On Sunday, 31 October 2021 at 05:04:33 UTC, Dom DiSc wrote:

On Friday, 29 October 2021 at 14:20:09 UTC, Ali Çehreli wrote:

Unsigned!T abs(T)(const(T) x) if(isIntegral!T)
{
   static if(isSigned!T) if(x < 0) return cast(Unsigned!T)-x;
   return x;
}

void main() {
  int a = -5;
  int b = -4;
  writeln(a + abs(b)); // -5 + 4 == -1? (No!)
}

The program prints uint.max.


This should be no surprise. You need to know what the resulting 
type of int + uint should be. And it is .. uint!  which is 
one of the stupit integer-promotion rules inherited from C.


Then let's change the example to:

   int b = -4;
   writeln(-abs(b));

What would one normally expect to be printed here? Should the 
unary minus operator also do some kind of implicit "unsigned -> 
signed" type change magic to accommodate this modified version of 
the abs function and make it behave in a non-surprising way?


Re: Does associative array change the location of values?

2021-10-31 Thread Ali Çehreli via Digitalmars-d-learn

On 10/31/21 9:49 AM, H. S. Teoh wrote:

> The current spec explicitly states that masking pointers this way is UB.

Ok. :) What about unions?

union U {
  ulong u;
  void* p;
}

Can the GC deal with that?

Or other smart ways where I store the pointer in two parts as 
page+offset? (Perhaps that's UB as well.)


Ali



srand in D

2021-10-31 Thread pascal111 via Digitalmars-d-learn
Hi! I'm C learner and found the high similarity between C and D, 
and was converting C code into D but couldn't get the equivalent 
of this C statement "srand(time(NULL));".


Re: abs and minimum values

2021-10-31 Thread Ali Çehreli via Digitalmars-d-learn

On 10/30/21 10:04 PM, Dom DiSc wrote:
> On Friday, 29 October 2021 at 14:20:09 UTC, Ali Çehreli wrote:
>> Unsigned!T abs(T)(const(T) x) if(isIntegral!T)
>> {
>>static if(isSigned!T) if(x < 0) return cast(Unsigned!T)-x;
>>return x;
>> }
>>
>> void main() {
>>   int a = -5;
>>   int b = -4;
>>   writeln(a + abs(b)); // -5 + 4 == -1? (No!)
>> }
>>
>> The program prints uint.max.
>
> This should be no surprise. You need to know what the resulting type of
> int + uint should be.

Yes, the programmer knew all that when they wrote that code when abs() 
behaved the way it behaves today.


The code is an example of why abs() cannot be changed today to what you 
propose. It would be a bad kind of breaking change: No compilation 
error, no run-time error (if unlucky), and a weird bug 42 months from today.


Ali




Re: abs and minimum values

2021-10-31 Thread Ola Fosheim Grøstad via Digitalmars-d-learn

On Sunday, 31 October 2021 at 05:04:33 UTC, Dom DiSc wrote:
This should be no surprise. You need to know what the resulting 
type of int + uint should be. And it is .. uint!  which is 
one of the stupit integer-promotion rules inherited from C.


In C++ it is undefined behaviour to take the absolute value of a 
value that has no positive representation. I assume the same is 
true for C? So you can write a compiler that detects it and fails.


You cannot do this in D as int is defined to represent an 
infinite set of numbers (mapped as a circle). So in D, you could 
say that the abs of the most negative value is a positive value 
that is represented as a negative due to circular wrapping.


If this happens in C then it is a bug. If it happens in D, then 
it is a defined feature of the language.


Re: abs and minimum values

2021-10-31 Thread Elronnd via Digitalmars-d-learn

On Sunday, 31 October 2021 at 10:32:50 UTC, Imperatorn wrote:

What I would like is for it to mirror math.


Use bigints.


Re: srand in D

2021-10-31 Thread pascal111 via Digitalmars-d-learn

On Sunday, 31 October 2021 at 17:02:00 UTC, Ali Çehreli wrote:

On 10/31/21 9:54 AM, pascal111 wrote:
Hi! I'm C learner and found the high similarity between C and 
D, and was converting C code into D


Welcome! :) In case it makes to your use cases, check out 
-betterC as well:


  https://dlang.org/spec/betterc.html

> but couldn't get the equivalent of this C

statement "srand(time(NULL));".


Just comment that line out. :) D's pseudo-random generators 
start randomized by default:


import std.stdio;
import std.random;

void main() {
  // Pick a number between [0,10)
  writeln(uniform(0, 10));
}

The documentation is at

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

Ali



Thanks! the code works now:

/* Acey Ducey game,
originally programmed in
BASIC */


// D programming language

import std.stdio;
import core.stdc.stdlib;
import std.ascii;
import core.stdc.string;
import core.stdc.stdio;
import core.time;
import std.conv;
import std.random;



/*
char* card_name(int); // turning cards valuse into strings 
function


void no_money_test(ref int); // money = 0 test
*/



// turning cards valuse into strings function
void card_name(int x, ref string c)
{

/* char* c=cast(char*) malloc((strlen("queen")+1)*(char.sizeof));

if(!c){
 writeln("A memory allocation failed!");
 exit(EXIT_FAILURE);} */

switch (x)
{

case 11:
c="Jack";
break;

case 12:
c="Queen";
break;

case 13:
c="King";
break;

case 14:
c="Ace";
break;

default:
c=to!string(x);


}


}



// money = 0 test
void no_money_test(ref int your_money)
{

char q;

if (your_money == 0)

{


do
{
writeln("Oops! you have no money to bet with,");
write("do you want playing again (y/n)? ");

readf(" %c", );

} while ((toLower(q)!='y') &&
   (toLower(q)!='n'));

if (toLower(q)=='y') // nasted in 'if money = 0'
{

your_money = 100;

}

else
   exit(EXIT_SUCCESS);

} // if money = 0

}




int main()
{

int your_money=100;
int card_A,
card_B, card_C;

string card_A_name,
card_B_name,
card_C_name;

char q;

int bet_much;

//srand(time(NULL));



do // 1st do
{


writeln("You've ", your_money, "$");


// Generating the two cards:

do
{

card_A = uniform(0, 13)+2; //(rand()%13)+2;
card_B = uniform(0, 13)+2;

} while (!((card_B - card_A) > 2) &&
   !((card_A==2)&&(card_B==14)));


card_name(card_A, card_A_name);
card_name(card_B, card_B_name);

writeln("Here are your two cards: ", card_A_name, " ", 
card_B_name);




// Betting query:


card_C = uniform(0, 13)+2;

do
{

write("Do you'll bet (y/n/e = (exit))? ");
readf(" %c", );

} while ((toLower(q)!='y') &&
   (toLower(q)!='n') &&
   (toLower(q)!='e'));


// agreeing betting

if (toLower(q)=='y')

{


do
{
write("With how much? ");
readf(" %d", _much);

if (bet_much>your_money)
   {

 writeln("You don't have this much to bet with,");
 writeln("you have ", your_money, "$");

   }

} while (!(bet_much<=your_money));


if ((card_C>=card_A) && (card_C<=card_B)) // following agreeing 
betting 'if'

   {


card_name(card_C, card_C_name);
writeln("You are right! ");
writeln("3rd card is: ", card_C_name);

your_money+=bet_much;

   }

else
{

 card_name(card_C, card_C_name);
 writeln("Oops! you are wrong!");
 writeln("3rd card is: ", card_C_name);
 your_money-=bet_much;

}

}

else // 'else if' of agreeing betting 'if'
 if(toLower(q)=='e')
exit(0);
else // considered final 'else' of agreeing betting 'if'
 writeln("CHICKEN!!!");



// Your money = 0 test

no_money_test(your_money);



} while (true); // 1st do




return 0;
}




// C version of the same game

/* Acey Ducey game,
originally programmed in
BASIC */


#include 
#include 
#include 
#include 
#include 
#include 

using namespace std;



char *card_name(int); // turning cards valuse into strings 
function


void no_money_test(int&); // money = 0 test


int main(void)
{

int your_money=100;
int card_A,
card_B, card_C;

char q;

int bet_much;

srand(time(NULL));



do // 1st do
{


cout << "You've "
 << your_money
 << "$" << endl;


// Generating the two cards:

do
{

card_A = (rand()%13)+2;
card_B = (rand()%13)+2;

} while (!((card_B - card_A) > 2) &&
   !((card_A==2)&&(card_B==14)));


cout << "Here are your two cards: "
 << card_name(card_A) << " "
 << card_name(card_B) << endl;



// Betting query:


card_C = (rand()%13)+2;

do
{

cout << "Do you'll bet (y/n/e = (exit))? ";
cin >> q;

} while ((tolower(q)!='y') &&
   (tolower(q)!='n') &&
   (tolower(q)!='e'));


// agreeing betting

if (tolower(q)=='y')

{


do
{
cout << "With how much? ";
cin >> bet_much;

if (bet_much>your_money)
   {

 cout << "You don't have this much to bet with,"
  << endl << "you have " << your_money << "$"
  << endl;

   }

} while (!(bet_much<=your_money));


if ((card_C>=card_A) && 

Re: The type inference everywhere

2021-10-31 Thread data pulverizer via Digitalmars-d-learn

On Sunday, 31 October 2021 at 18:51:09 UTC, user1234 wrote:


To me it is the right answer. Maybe that OP wanted the 
TemplateType parameter to be implicitly added (and that's why 
Ali interpreted the question as a language proposal)?


Ah, I see. Interesting proposal.


Re: srand in D

2021-10-31 Thread Ali Çehreli via Digitalmars-d-learn

On 10/31/21 9:54 AM, pascal111 wrote:
Hi! I'm C learner and found the high similarity between C and D, and was 
converting C code into D


Welcome! :) In case it makes to your use cases, check out -betterC as well:

  https://dlang.org/spec/betterc.html

> but couldn't get the equivalent of this C

statement "srand(time(NULL));".


Just comment that line out. :) D's pseudo-random generators start 
randomized by default:


import std.stdio;
import std.random;

void main() {
  // Pick a number between [0,10)
  writeln(uniform(0, 10));
}

The documentation is at

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

Ali


Re: Does associative array change the location of values?

2021-10-31 Thread H. S. Teoh via Digitalmars-d-learn
On Sun, Oct 31, 2021 at 09:54:23AM -0700, Ali Çehreli via Digitalmars-d-learn 
wrote:
> On 10/31/21 9:49 AM, H. S. Teoh wrote:
> 
> > The current spec explicitly states that masking pointers this way is UB.
> 
> Ok. :) What about unions?
> 
> union U {
>   ulong u;
>   void* p;
> }
> 
> Can the GC deal with that?

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


Though I have to say, object pinning does impose restrictions on a
moving GC implementation that may negate some of its benefits.


T

-- 
Never criticize a man until you've walked a mile in his shoes. Then when you do 
criticize him, you'll be a mile away and he won't have his shoes.


Re: The type inference everywhere

2021-10-31 Thread Ali Çehreli via Digitalmars-d-learn

On 10/31/21 7:07 AM, Salih Dincer wrote:
> ```d
> auto foo(int value, auto s = Section(2, 60)) {
> int max;  /*   ^--- ?
> ...*/
> return Section (0, max)
>   }
> ```
> Is possible something like above pointed. OK, I know it isn't because I
> tried! Well, wouldn't it be nice if it did?

Makes sense because e.g. the following works:

struct S {
  auto i = 42;
}

I bet the problem with your proposal is "auto" in that position is a 
part of the two-word "auto ref" parameters. I don't know how hard or 
impossible it would be to allow just "auto" there.


In any case, although it would be nice for completeness, the use case is 
so rare that I wouldn't mind repeating the type twice in that usage. But 
I agree with you...


Ali



Re: The type inference everywhere

2021-10-31 Thread data pulverizer via Digitalmars-d-learn

On Sunday, 31 October 2021 at 17:35:35 UTC, Ali Çehreli wrote:

On 10/31/21 7:07 AM, Salih Dincer wrote:
> ```d
> auto foo(int value, auto s = Section(2, 60)) {
> int max;  /*   ^--- ?
> ...*/
> return Section (0, max)
>   }
> ```
> Is possible something like above pointed. OK, I know it isn't
because I
> tried! Well, wouldn't it be nice if it did?

Makes sense because e.g. the following works:

struct S {
  auto i = 42;
}

I bet the problem with your proposal is "auto" in that position 
is a part of the two-word "auto ref" parameters. I don't know 
how hard or impossible it would be to allow just "auto" there.


In any case, although it would be nice for completeness, the 
use case is so rare that I wouldn't mind repeating the type 
twice in that usage. But I agree with you...


Ali


This is a teachable moment for me, so I'll ask the question. Why 
isn't something like this the answer?


```
import std.stdio: writeln;


struct Section
{
  int x;
  int y;
}


auto foo(T)(int value, auto ref T s = Section(2, 60))
{
  //...
  return Section(0, 60);
}

void main()
{
  foo(5).writeln;
}

```




Re: Does associative array change the location of values?

2021-10-31 Thread Ali Çehreli via Digitalmars-d-learn

On 10/31/21 9:54 AM, Ali Çehreli wrote:

Or other smart ways where I store the pointer in two parts as 
page+offset?


Ok, that was silly. There would be no reference to the GC memory if I 
chopped off a pointer. :/


Ali



Re: srand in D

2021-10-31 Thread Paul Backus via Digitalmars-d-learn

On Sunday, 31 October 2021 at 16:54:35 UTC, pascal111 wrote:
Hi! I'm C learner and found the high similarity between C and 
D, and was converting C code into D but couldn't get the 
equivalent of this C statement "srand(time(NULL));".


Since D gives you access to the C standard library, you can use 
pretty much exactly the same code in D:


```d
import core.stdc.stdlib; // bindings for 
import core.stdc.time; // bindings for 

srand(time(null)); // null is lower-case in D
```

If you want to use D's standard library, you can instead use 
[`std.random.rndGen`][1], the default random number generator. 
Its documentation says:


It is allocated per-thread and initialized to an unpredictable 
value for each thread.


In other words, it is seeded for you automatically. So when you 
are converting C code that uses `rand` to D code that uses 
`rndGen`, you can simply delete the line `srand(time(NULL));`, 
and it will work ask expected.


If you wanted to seed it yourself, however, you would do it using 
the `.seed` method, and generate the seed using 
[`std.random.unpredictableSeed`][2].


```d
import std.random;

rndGen.seed(unpredictableSeed());
```

This is mainly useful when you are using a custom RNG instead of 
the default `rndGen`, since custom RNGs are *not* automatically 
seeded.


[1]: https://phobos.dpldocs.info/std.random.rndGen.html
[2]: 
https://phobos.dpldocs.info/std.random.unpredictableSeed.1.html


Re: The type inference everywhere

2021-10-31 Thread user1234 via Digitalmars-d-learn

On Sunday, 31 October 2021 at 17:51:45 UTC, data pulverizer wrote:

On Sunday, 31 October 2021 at 17:35:35 UTC, Ali Çehreli wrote:

On 10/31/21 7:07 AM, Salih Dincer wrote:
> [...]
because I
> [...]

Makes sense because e.g. the following works:

struct S {
  auto i = 42;
}

I bet the problem with your proposal is "auto" in that 
position is a part of the two-word "auto ref" parameters. I 
don't know how hard or impossible it would be to allow just 
"auto" there.


In any case, although it would be nice for completeness, the 
use case is so rare that I wouldn't mind repeating the type 
twice in that usage. But I agree with you...


Ali


This is a teachable moment for me, so I'll ask the question. 
Why isn't something like this the answer?


```
import std.stdio: writeln;


struct Section
{
  int x;
  int y;
}


auto foo(T)(int value, auto ref T s = Section(2, 60))
{
  //...
  return Section(0, 60);
}

void main()
{
  foo(5).writeln;
}

```


To me it is the right answer. Maybe that OP wanted the 
TemplateType parameter to be implicitly added (and that's why Ali 
interpreted the question as a language proposal)?


Re: The type inference everywhere

2021-10-31 Thread Salih Dincer via Digitalmars-d-learn

On Sunday, 31 October 2021 at 17:35:35 UTC, Ali Çehreli wrote:

On 10/31/21 7:07 AM, Salih Dincer wrote:
> ```d
> auto foo(int value, auto s = Section(2, 60)) {
> int max;  /*   ^--- ?
> ...*/
> return Section (0, max)
>   }
> ```
> Is possible something like above pointed. OK, I know it isn't
because I
> tried! Well, wouldn't it be nice if it did?

Makes sense because e.g. the following works:

struct S {
  auto i = 42;
}

I bet the problem with your proposal is "auto" in that position 
is a part of the two-word "auto ref" parameters. I don't know 
how hard or impossible it would be to allow just "auto" there.


In any case, although it would be nice for completeness, the 
use case is so rare that I wouldn't mind repeating the type 
twice in that usage. But I agree with you...


Ali


Actually, foo is  inside a class.  So using T is very easy.  
Moreover,it's possible to do it with ```alias S = Section;```