Re: regarding what seems (to me) unnecessary casts on integer expressions

2021-06-04 Thread Adam D. Ruppe via Digitalmars-d-learn

On Saturday, 5 June 2021 at 02:38:50 UTC, someone wrote:
Furthermore, if, **at least**, there was a way to clearly state 
what is short (eg 1S a la 1L) things will improve a lot


That actually doesn't matter. The compiler actually will 
automatically type it to the most narrow thing it fits. The 
implementation there is actually quite nice - inside a single 
expression, the compiler tracks the possible range.


Try:

ubyte a = 5 + 3; // just works, it knows 5+3 = 8 which can be byte

ubyte b = a & 0xff; // also works, it knows the mask limits the 
range



And various combinations like that. It works as long as it is in 
one statement.


But if you cross them:

ubyte c = a + 1;

Now it assumes a might be the maximum of 255... and 255 + 1 
doesn't fit in the ubyte, thus it will not allow the assignment 
back.



Masking operations are a possible alternative to casting btw... 
but still a hassle.



ushort a; a = cast(ushort) a - cast(ushort) 1;


This doesn't do anything since the promotion is done  anyway. The 
compiler already knows both are ushort there, it is the 
arithmetic that assumes worst case scenario.




ushort a; a = cast(ushort)(a - 1);


this does work though.

a -= 1; // also works

At first sight I got the impression that any type could be 
unambiguously stated in D. Seems I was wrong.


Again, it is not the type of the literal that is the problem.

D follows the C rule that all arithmetic promotes. (Seriously, 
try it in C, it also converts to int first before doing an add or 
subtract.)


But C allows it to convert back without hassle, so it is easy to 
ignore this annoying promotion thing. D only allows the 
conversion back if the compiler can prove it fits.



for a string "" should not the same as null


its not. They're very similar but it is NOT the same. Check the 
.ptr property.



and 0 for a integer should not be the same as null


Its not. The type system won't allow those to cross.

and this is obviously **really useful** for database apps and a 
lot of other things.


I've done tons of database apps in D, I've been doing web stuff 
with D since 2008. There's various ways to do nullable sql, it 
isn't a big problem.


Re: regarding what seems (to me) unnecessary casts on integer expressions

2021-06-04 Thread someone via Digitalmars-d-learn

On Saturday, 5 June 2021 at 02:07:03 UTC, Adam D. Ruppe wrote:


This design was a mistake.


Of all the great things I learned and read about it, this 
behavior was totally unexpected to me.


It is really difficult to code strong-typed apps this way -this 
behavior is really wonderful for writing loose scripts and the 
like and forgetting about types just to build prototypes or 
whatever, but, for really critical strong-typed apps is ... I'm 
not hurrying up to say game-over but, I can't see the way to go 
forward right now unless I am missing something.


Furthermore, if, **at least**, there was a way to clearly state 
what is short (eg 1S a la 1L) things will improve a lot, since 
any integer not having S or L could be assumed a normal integer, 
since byte has its own declaration. Writing code like:


ushort a; a = a - cast(ushort) 1; would be totally acceptable.

But writing code like:

ushort a; a = cast(ushort) a - cast(ushort) 1;

or

ushort a; a = cast(ushort)(a - 1);

would be totally silly and a waste of time I guess.

Right now I am totally immersed on Ali's book (and of course the 
tutorial and the dlang online reference) but one of the sections 
of Alexandrescu's book (have it in dead-tree-media) that I liked 
very much was the one depicting how to differentiate base types 
from one another with is flow charts.


At first sight I got the impression that any type could be 
unambiguously stated in D. Seems I was wrong.


One of the things that also immediately stuck me with D was the 
lack of proper nulls for all base types -meaning, for example for 
a string "" should not the same as null and 0 for a integer 
should not be the same as null, null (actually meaning dunno), 
and this is obviously **really useful** for database apps and a 
lot of other things.


Re: regarding what seems (to me) unnecessary casts on integer expressions

2021-06-04 Thread Adam D. Ruppe via Digitalmars-d-learn

On Saturday, 5 June 2021 at 01:46:45 UTC, someone wrote:
What's the point of declaring, for instance ushort's if then 
nothing will treat them as ushort's and I have to manually 
cast() everything to ushort() all the time ?


Yeah, it totally sucks.

D inherited a silly rule from C - the promote rules actually come 
from there - but then added a well-intentioned but pretty 
annoying in practice rule that discarding bits from arithmetic 
require an implicit cast. (Unless it is the bits over 32... then 
who cares. lol)


The += operator is exempt from it so use it where you can. But 
otherwise your only real hope is to do a user defined type with 
op overloads and what an enormous hassle.


This design was a mistake.


Re: regarding what seems (to me) unnecessary casts on integer expressions

2021-06-04 Thread someone via Digitalmars-d-learn

On Saturday, 5 June 2021 at 01:34:06 UTC, Kyle Ingraham wrote:

It looks like you’re being caught by D’s arithmetic 
conversions: 
https://dlang.org/spec/type.html#usual-arithmetic-conversions


“If the signed type is larger than the unsigned type, the 
unsigned type is converted to the signed type.”


Your pint variables are ushorts but the 1 you subtract is an 
int literal so the result gets promoted to an int.


As I am writing code today I am encountering a lot of these 
situations.


cast(ushort)(this.pintBottom1 - 1)

My first walkaround for this was intuitive:

this.pintBottom1 - cast(ushort) 1 /// I didn't know if eg: 1S was 
possible which should have been the proper way to handle it


... since pintBottom was already defined as ushort, but it didn't 
work also, so I ended with cast(ushort)(this.pintBottom1 - 1). I 
don't understand how to write typed code in D then. What's the 
point of declaring, for instance ushort's if then nothing will 
treat them as ushort's and I have to manually cast() everything 
to ushort() all the time ?


Re: regarding what seems (to me) unnecessary casts on integer expressions

2021-06-04 Thread Kyle Ingraham via Digitalmars-d-learn

On Saturday, 5 June 2021 at 00:24:01 UTC, someone wrote:

On Saturday, 5 June 2021 at 00:24:01 UTC, someone wrote:

? 0 : cast(ushort)(this.pintBottom1 - 1); }


It looks like you’re being caught by D’s arithmetic conversions: 
https://dlang.org/spec/type.html#usual-arithmetic-conversions


“If the signed type is larger than the unsigned type, the 
unsigned type is converted to the signed type.”


Your pint variables are ushorts but the 1 you subtract is an int 
literal so the result gets promoted to an int.


Also, I don’t believe there is an unambiguous way to write a 
ushort literal: https://dlang.org/spec/type.html#basic-data-types


You should be ok with “u” if the function’s return is ushort. The 
compiler should be able to figure it out from there. I’m hoping 
I’m not wrong there as I haven’t tried it myself.


regarding what seems (to me) unnecessary casts on integer expressions

2021-06-04 Thread someone via Digitalmars-d-learn
Consider the following code to keep track of rectangle positions 
on the screen; eg: (1,2)(3,2) ie: (left,top)(right,bottom), 
providing get/set properties for one-based positions but only get 
properties for zero-based positions:


```d
public struct gudtPosition {

   final public void reset() { pintLeft1 = pintTop1 = pintRight1 
= pintBottom1 = 0; }


   private ushort pintLeft1 = 0;
   private ushort pintTop1 = 0;
   private ushort pintRight1 = 0;
   private ushort pintBottom1 = 0;

   final public const ushort left1() { return this.pintLeft1; }
   final public const ushort top1() { return this.pintTop1; }
   final public const ushort right1() { return this.pintRight1; }
   final public const ushort bottom1() { return this.pintBottom1; 
}


   final public ushort left0() { return this.pintLeft1 = 0 ? 0 : 
cast(ushort)(this.pintLeft1 - 1); }
   final public ushort top0() { return this.pintTop1 = 0 ? 0 : 
cast(ushort)(this.pintTop1 - 1); }
   final public ushort right0() { return this.pintRight1 = 0 ? 0 
: cast(ushort)(this.pintRight1 - 1); }
   final public ushort bottom0() { return this.pintBottom1 = 0 ? 
0 : cast(ushort)(this.pintBottom1 - 1); }


   final public void left1(const ushort lintPosition) { 
this.pintLeft1 = lintPosition; }
   final public void top1(const ushort lintPosition) { 
this.pintTop1 = lintPosition; }
   final public void right1(const ushort lintPosition) { 
this.pintRight1 = lintPosition; }
   final public void bottom1(const ushort lintPosition) { 
this.pintBottom1 = lintPosition; }


   final public string caption0() { return /// eg: from (24,24) 
to (48,48)

  r"from ("c ~
  std.format.format(r"%d"c, this.left0) ~
  r","c ~
  std.format.format(r"%d"c, this.top0) ~
  r") to ("c ~
  std.format.format(r"%d"c, this.right0) ~
  r","c ~
  std.format.format(r"%d"c, this.bottom0) ~
  r")"c;
   }

   final public string caption1() { return /// eg: from (24,24) 
to (48,48)

  r"from ("c ~
  std.format.format(r"%d"c, this.pintLeft1) ~
  r","c ~
  std.format.format(r"%d"c, this.pintTop1) ~
  r") to ("c ~
  std.format.format(r"%d"c, this.pintRight1) ~
  r","c ~
  std.format.format(r"%d"c, this.pintBottom1) ~
  r")"c;
   }

}
```

The code should be, I guess, self-explanatory to read. I do have 
some things to learn here on the D-specifics:


- is there a way to unambiguously specify short integers values 
like there is for long ones (eg: 1L means 1 long integer like: 
long pintSomething = 1L;) ?


- that follows to what seems to be unnecessary castings in my 
code snippet; if I write: ushort a = 1; ushort b = 2; ushort c; 
why can't I write c = a + b; ? ... DMD refuses the last one 
unless I explicitly write: c = cast(ushort) a + b; ... if all the 
variables I defined are of the same type ... why should I do have 
to cast() them afterwards ?


Re: a=1;b=1;c=1; fine ... now a,b,c=1; ... something like this possible ?

2021-06-04 Thread someone via Digitalmars-d-learn

On Friday, 4 June 2021 at 20:02:28 UTC, drug wrote:


a = b = c = 1;


fantastic ... спасибо :) !


a=1; b=1; c=1; fine ... now a,b,c=1; ... something like this possible ?

2021-06-04 Thread someone via Digitalmars-d-learn

I think not -just in case.


Re: How to compile Phobos with other D code to create a shared library?

2021-06-04 Thread bachmeier via Digitalmars-d-learn

On Friday, 4 June 2021 at 15:33:32 UTC, Alain De Vos wrote:

Dub is probably not much of a help :)


That's right. I typically don't use Dub when I'm calling D 
functions from R. It's the only way you can use a Dub package 
like Mir, though, so that's why you might want it to generate a 
dub.sdl for you.


Re: How to compile Phobos with other D code to create a shared library?

2021-06-04 Thread Alain De Vos via Digitalmars-d-learn

Dub is probably not much of a help :)


Re: How to compile Phobos with other D code to create a shared library?

2021-06-04 Thread bachmeier via Digitalmars-d-learn

On Friday, 4 June 2021 at 07:26:53 UTC, data pulverizer wrote:

Thanks. Looks like I have some more reading to do. I did know 
about embedr, but I saw it had dependencies and I wanted a 
standalone and fully transparent D solution.


It requires an R package if you want to call D functions from R. 
You need to link to R itself if you want to do something like 
pass a vector from R to D and then access that data from D. Since 
R is aware of the location of all the underlying libraries, it's 
easiest to let it generate the dub.sdl for you.


I guess you're using the older .C interface [as done 
here](http://users.stat.umn.edu/~geyer/rc/). Good enough if 
passing double* and int* pointers to D functions will suffice. 
Only thing you need to do to initialize the D runtime is add this 
to your D code


```
struct DllInfo;

extern(C) void R_init_libfoo(DllInfo * info) {
Runtime.initialize();
}
```

where foo is the name of the library you're loading (foo.so).


Re: Is it possible to set function attributes conditionally?

2021-06-04 Thread wjoe via Digitalmars-d-learn

On Friday, 4 June 2021 at 11:36:09 UTC, Adam D. Ruppe wrote:

On Friday, 4 June 2021 at 11:33:32 UTC, wjoe wrote:
This is a contrived example. In reality I would use this with 
custom array, hash map and other container implementations so 
I could use them in @nogc territory by just switching out the 
allocator.


If they are templates, just don't specify attributes and the 
compiler will infer them for you.


If they are not templates, you have to do a separate copy under 
version or static if.


That's good to know. Thanks :)
A separate copy is exactly what I wanted to avoid but since they 
are templates it's np.




Re: Is it possible to set function attributes conditionally?

2021-06-04 Thread Adam D. Ruppe via Digitalmars-d-learn

On Friday, 4 June 2021 at 11:33:32 UTC, wjoe wrote:
This is a contrived example. In reality I would use this with 
custom array, hash map and other container implementations so I 
could use them in @nogc territory by just switching out the 
allocator.


If they are templates, just don't specify attributes and the 
compiler will infer them for you.


If they are not templates, you have to do a separate copy under 
version or static if.


Is it possible to set function attributes conditionally?

2021-06-04 Thread wjoe via Digitalmars-d-learn

Hi,

Consider Allocators, e.g.:

```d
struct Mallocator
{
   enum usesGC = false;

   /// implement alloc, free, etc. @nogc
}

struct GCAllocator
{
  enum usesGC = true;

   /// implement alloc, free, etc. via the GC
}
```

Now I want to have the function attributes set depending on the 
allocator implementation


```d
template AutoGC(ALLOCATOR) if (isAllocator!ALLOCATOR)
{
   static if (!ALLOCATOR.usesGC)
  AutoGC = pragma(attrib, @nogc);
   else
  AutoGC = pragma(attrib, none);
}

@AutoGC!ALLOCATOR void fun(ALLOCATOR)() if(isAllocator!ALLOCATOR)
{
   void* p = ALLOCATOR.alloc(1024);
   // do something with p
   ALLOCATOR.free(p);
}
```

So fun!Mallocator would be @nogc and fun!GCAllocator wouldn't be 
@nogc.


This is a contrived example. In reality I would use this with 
custom array, hash map and other container implementations so I 
could use them in @nogc territory by just switching out the 
allocator.


Is it possible to do something like this ?



Re: Question about initialization

2021-06-04 Thread Adam D. Ruppe via Digitalmars-d-learn

On Friday, 4 June 2021 at 11:27:05 UTC, seany wrote:
In my untrained eye, this seems haphazard. One requires the use 
of the new keyword


It doesn't.

T[] a;

just works. it is an array of length 0.


Question about initialization

2021-06-04 Thread seany via Digitalmars-d-learn

Consider initializing a dictionary or associative array :

T[U] AA;

For example :

double [int] AA;


This will be dynamic in size.

Now consider initializing a dynamic array :

T[] A = new T[] (0);

or

U[][] B = new U [][] (0,0);


This will also be dynamic in size.

In my untrained eye, this seems haphazard. One requires the use 
of the new keyword, the other does not. Why is it? Has It got 
something to do with random access mechanism? I would like to 
know the rationale please.


Re: How to compile Phobos with other D code to create a shared library?

2021-06-04 Thread data pulverizer via Digitalmars-d-learn

On Wednesday, 2 June 2021 at 23:23:58 UTC, bachmeier wrote:
Are you aware of my embedr project, which handles all that for 
you, and does a lot of other stuff?


https://embedr.netlify.app

If you want to do it yourself, you can see the boilerplate you 
need to add to call a shared library from R here: 
https://bitbucket.org/bachmeil/embedr/src/bebf67e5b30cd4163214c7f44f9907e7d7490dc0/R/compile.R#lines-99


If you want to read the R manual, the relevant section is here:
https://cran.r-project.org/doc/manuals/r-release/R-exts.html#dyn_002eload-and-dyn_002eunload
If you don't do that, it's unlikely to work unless you get 
lucky. If you want to load foo.so, you need a corresponding 
R_init_foo function where you call Runtime.initialize.


Thanks. Looks like I have some more reading to do. I did know 
about embedr, but I saw it had dependencies and I wanted a 
standalone and fully transparent D solution. I'm already calling 
R routines from D using standalone Rmath and being able to call D 
from R and D have independent full access to R's internals would 
be awesome. But your package certainly provides very useful 
information.


The reference to R's dyn.load internals looks useful and relevant 
and I'll be trying those once I get the time. Probably during the 
weekend.