Re: regarding what seems (to me) unnecessary casts on integer expressions
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
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
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
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
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
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 ?
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 ?
I think not -just in case.
Re: How to compile Phobos with other D code to create a shared library?
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?
Dub is probably not much of a help :)
Re: How to compile Phobos with other D code to create a shared library?
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?
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?
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?
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
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
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?
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.