Is this a bug or a VERY sneaky case?

rempas rempas at tutanota.com
Thu Dec 30 08:26:17 UTC 2021


On Tuesday, 28 December 2021 at 15:25:30 UTC, WebFreak001 wrote:

Thanks a lot for your huge answer! Yeah, I don't want my program 
to pay a big price in runtime so I agree with you that "static 
ifs" are fine. Now I will quote some other stuff but in general 
thanks a lot

> I think your current code is good as it is. (for base 10 at 
> least). For base 2 the biggest number would then be 64 
> characters, still very manageable.

Yeah you are right and here are how bugs happen and I don't 
notice them. I will fix it right away!

> - use [contracts](https://dlang.org/spec/function#contracts) 
> for stuff like the base to indicate, that only bases 2..16 are 
> allowed:
>   `char* to_str(T)(T num, u8 base) in(base >= 2 && base <= 16) 
> { ...`
>   (nice for documentation and catches accidental bugs in 
> development, in release builds these checks are omitted - which 
> is part of the reason why you should never catch AssertError, 
> Error or Throwable!)

Thanks! Yeah tbh I don't know a lot of D "very advanced" stuff 
yet and I only use the features that I need. This looks awesome 
but one problem with it is that it will not allow me to give a 
custom message in case of a failure and it will also not print 
the line from where the function was called but rather the line 
of the function itself. So I don't know...

> - use D's datatypes, not your own ones (if you want others to 
> look/work on your code too it's better to use the common names 
> for stuff) - but ofc staying consistent across your code is 
> more important

I suppose you mean about "str" right? In this case, I would love 
using D's "string" if it wasn't immutable by default. It pisses 
me A LOT when a language tries to "protect" me from myself. There 
are a lot of other stuff that I would like "string" to have but I 
wouldn't mind them so much if string was mutable by default (or 
even better if string literals were "char*" like C and could get 
automatically casted so I could use char[] without the need of an 
".dup"). Another thing is that I'm making a library so people 
will probably read the definition of "str" out of interest anyway 
and learn it if they want to use the library as users. And even 
for people that want to only contribute to a specific place in 
the code and not use the library (which why would you do that 
anyway?), the way "str" is used in the code, is similar to how 
"string" is used (check how they both have a ".ptr" property to 
get the actual pointer for example) so I don't really think that 
there is a problem with that.

> - use `is(T == ubyte)` etc. instead of your custom 
> `is_same!(val, ubyte)` (same reason as above, people need to 
> read the definition of is_same first)

This is a simple definition actually so why is it such of a big 
deal? Also we shouldn't use "is(T == ubyte)" but instead 
"is(typeof(val) == ubyte)" just like I'm doing it. This is 
because in variadic functions, "T" will have different type for 
each argument so it will not work (I made this mistake and people 
told me so that's how I know). So why do we have to type this 
much when we can automate this with a simple definition? There is 
also one for checking if a type is a number (integer), a floating 
point, a string (including my "str") etc. I don't find these hard 
to learn and memorize so I don't find a reason to not make my 
(our) life easier and just use "macros". This is the main reason 
I use D and not [Vox](https://github.com/MrSmith33/vox) in the 
first place (and the fact that in Vox you cannot fully work with 
Variadic functions yet).

> - work with slices, not with pointers (if you plan to use your 
> code from D, it's much cleaner and avoids bugs! does not need a 
> trailing null terminator and works with @safe code)

Slices are objects tho and this means paying a runtime cost 
versus just using a variable. Also the only place I used pointers 
are with C-type string (char* or u8* in my custom "str") and one 
member (_count) in my custom "str" struct. And all of this cases 
were checked very carefully and they are very specific. People 
that will use the library should rarely need to use pointers and 
this is what I try to do with my library and why I don't use 
"libc". However! When it comes to the actual library itself, I 
want to go as low level as possible and have a library that is as 
performant as possible.


More information about the Digitalmars-d mailing list