January 25, 2015
> 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
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
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
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
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
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
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
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
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
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.

1 2
Next ›   Last »