January 25, 2015 Re: using the full range of ubyte with iota | ||||
---|---|---|---|---|
| ||||
Posted in reply to ketmar |
> you can always write your own iota replacement, which will do "[]" and
> use ubytes, for example. writing that things is way easier than in C++.
> something like "myIota!ubyte(0, 255)", for example -- to make it visible
> that it emits ubytes.
I think closedInterval!T (T left, T right) would be a nice name for it.
What's this about !`[]` and std.range.uniform?? It's not in the documentation.
|
January 25, 2015 Re: using the full range of ubyte with iota | ||||
---|---|---|---|---|
| ||||
Posted in reply to Vlad Levenfeld | Vlad Levenfeld:
> What's this about !`[]` and std.range.uniform?? It's not in the documentation.
It's an enhancement I have proposed.
Bye,
bearophile
|
January 25, 2015 Re: using the full range of ubyte with iota | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | On Sunday, 25 January 2015 at 10:42:51 UTC, bearophile wrote: > Vlad Levenfeld: > >> What's this about !`[]` and std.range.uniform?? It's not in the documentation. > > It's an enhancement I have proposed. Hm. I had more something in mind like "paramCast" - a kind of big scissors that cut everything a function is called with to the size it can cope with, so replacing map!fn not with map!(x => fn(cast(ParameterTypeTuple!fn[0])x) but instead with map!(paramCast!fn) Because this is useful in more situations, e.g. in every place where you know the values would fit into the parameter (and for a single call would use a cast). But so far I couldn't manage to make this work :-/ |
January 25, 2015 Re: using the full range of ubyte with iota | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dominikus Dittes Scherkl | On Sunday, 25 January 2015 at 12:25:35 UTC, Dominikus Dittes Scherkl wrote: > > map!(x => fn(cast(ParameterTypeTuple!fn[0])x) > > but instead with > > map!(paramCast!fn) > > Because this is useful in more situations, e.g. in every place where you know the values would fit into the parameter (and for a single call would use a cast). > > But so far I couldn't manage to make this work :-/ http://dpaste.dzfl.pl/07b1fa3c2dad |
January 25, 2015 Re: using the full range of ubyte with iota | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dominikus Dittes Scherkl | Dominikus Dittes Scherkl:
> Because this is useful in more situations,
Right, but it's still a cast. And in D you want to minimize the number of usages of casts. The proposed syntax iota!"[]" is cast-safe.
Bye,
bearophile
|
January 25, 2015 Re: using the full range of ubyte with iota | ||||
---|---|---|---|---|
| ||||
Posted in reply to Tobias Pankrath | On Sunday, 25 January 2015 at 12:56:14 UTC, Tobias Pankrath wrote: > On Sunday, 25 January 2015 at 12:25:35 UTC, Dominikus Dittes Scherkl wrote: >> >> map!(x => fn(cast(ParameterTypeTuple!fn[0])x) >> >> but instead with >> >> map!(paramCast!fn) >> >> Because this is useful in more situations, e.g. in every place where you know the values would fit into the parameter (and for a single call would use a cast). >> >> But so far I couldn't manage to make this work :-/ > > http://dpaste.dzfl.pl/07b1fa3c2dad Hey cool. With unary function I can even remove the string and mixin magic: template paramCast(alias fn) { ReturnType!fn paramCast(T)(T x) { return fn(cast(ParameterTypeTuple!fn[0])x); } } Many Thanks! |
January 25, 2015 Re: using the full range of ubyte with iota | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | On Sunday, 25 January 2015 at 13:03:16 UTC, bearophile wrote:
> Dominikus Dittes Scherkl:
>
>> Because this is useful in more situations,
>
> Right, but it's still a cast. And in D you want to minimize the number of usages of casts. The proposed syntax iota!"[]" is cast-safe.
>
I don't case too much, if I have ensured the cast is safe by constraints beforehand.
I need to cast often anyway, because I work with small types and most operators permanently change everything to "int", especially the bit-operations for which a signed type makes no sense at all:
ubyte x = 50;
auto y = x & 0x11; // y is int! I hate that!
even if I use unsigned literals:
auto z = x & 0x12u; // z is uint - better but still bad. More so as & should result in the smaller of the two types!!
But I need not even use literals (which unfortunately cannot be makred as "ubyte" or "short"). Look at this:
auto x2 = (x>>4) | (x<<4); // swap nibbles - but result in an int!!!!!
|
January 25, 2015 Re: using the full range of ubyte with iota | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dominikus Dittes Scherkl Attachments: | On Sun, 25 Jan 2015 14:11:09 +0000, Dominikus Dittes Scherkl wrote:
> On Sunday, 25 January 2015 at 13:03:16 UTC, bearophile wrote:
>> Dominikus Dittes Scherkl:
>>
>>> Because this is useful in more situations,
>>
>> Right, but it's still a cast. And in D you want to minimize the number of usages of casts. The proposed syntax iota!"[]" is cast-safe.
>>
> I don't case too much, if I have ensured the cast is safe by constraints beforehand.
>
> I need to cast often anyway, because I work with small types and most operators permanently change everything to "int", especially the bit-operations for which a signed type makes no sense at all:
>
> ubyte x = 50;
> auto y = x & 0x11; // y is int! I hate that!
>
> even if I use unsigned literals:
> auto z = x & 0x12u; // z is uint - better but still bad. More so as &
> should result in the smaller of the two types!!
>
> But I need not even use literals (which unfortunately cannot be makred as "ubyte" or "short"). Look at this:
>
> auto x2 = (x>>4) | (x<<4); // swap nibbles - but result in an int!!!!!
this is true for C and C++ too, as all three languages doing "integer promotion". the only difference is that D forbids potentially lossy assigns.
you best bet is to not use `auto`, but specify required type explicitly. or use ints/uints and cast to bytes only when it is necessary.
|
January 25, 2015 Re: using the full range of ubyte with iota | ||||
---|---|---|---|---|
| ||||
Posted in reply to ketmar | On Sunday, 25 January 2015 at 18:59:04 UTC, ketmar wrote:
>> auto x2 = (x>>4) | (x<<4); // swap nibbles - but result in an int!!!!!
>
> this is true for C and C++ too, as all three languages doing "integer
> promotion". the only difference is that D forbids potentially lossy
> assigns.
>
> you best bet is to not use `auto`, but specify required type explicitly.
> or use ints/uints and cast to bytes only when it is necessary.
in normal assignments I never use auto - it's not simpler than writing the type explicit but later makes it more complicated to see what type it is.
But in a function you need the cast anyway:
ubyte swapNibbles(ubyte x) { return (x>>4) | (x>>4); } // compiler not happy
or if you index with a long, even after explicit check:
int foo(ulong x)
{
int[10] a;
return (x < 10) ? a[x] : 0; // cannot index with long
}
So there are plenty of places in D where cast is necessary but should not be.
I think both of above cases should be safe without cast, and enhancing the compilerr that it can handle these cases is more important than a iota!"[]".
Until then I prefer paramCast!fn, because this is more flexible than the iota extension and my code is full of casts anyway.
|
January 25, 2015 Re: using the full range of ubyte with iota | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dominikus Dittes Scherkl Attachments: | On Sun, 25 Jan 2015 20:42:47 +0000, Dominikus Dittes Scherkl wrote: > But in a function you need the cast anyway: > ubyte swapNibbles(ubyte x) { return (x>>4) | (x>>4); } // compiler not > happy sure, it can't be happy, as `x` is promoted to int in the expression, so the expression result is `int`. better range analysis can prove that the resuit can be fit in `ubyte`, of course. or you can do `&0xff` -- the compiler is intelligent enough to see that this fits to ubyte too. > or if you index with a long, even after explicit check: > > int foo(ulong x) > { > int[10] a; > return (x < 10) ? a[x] : 0; // cannot index with long > } why do you index with `ulong`s in the first place? there is ugly `size_t` type for this. anyway, what you talking about is a missing integer range analysis in complier. i'm not sure that it worth adding, as it slows down compilation and hiding some potentially bad code. i can grep for `cast`s to see where author is playing with fire, but i can't grep for range analysis. ;-) p.s. `a[x&size_t.max]` works fine in your sample. and to be honest, i prefer either this, or `cast` -- any form of explicit type transformation. p.p.s. what is bad is that compiler happily accepts this: int foo (int x) { int[10] a; return a[x]; } WTF?! why, in the name of Ruler of Hell, array indexing with int doesn't generate any warning?! D design decision to silently allow conversion of `int` to `uint`/`ulong` is conceptually flawed. but this is one of the things that will never be fixed, so we have to live with it. |
Copyright © 1999-2021 by the D Language Foundation