digitalmars.D.learn - using the full range of ubyte with iota
- Dominikus Dittes Scherkl (13/13) Jan 24 2015 Maybe I'm just too stupid, but I cannot manage to call a simple
- Tobias Pankrath (3/16) Jan 24 2015 iota(0, 256).map!(x => foo(cast(ubyte) x))
- Dominikus Dittes Scherkl (5/10) Jan 24 2015 Ok, thank you very much.
- ketmar (4/16) Jan 24 2015 people that are new to D aren't used to D lambdas, so it's fairly common...
- Dominikus Dittes Scherkl (15/19) Jan 24 2015 Oh, I am aware, but I didn't thought it would be necessary in
- ketmar (5/30) Jan 24 2015 you can always write your own iota replacement, which will do "[]" and=2...
- Vlad Levenfeld (4/11) Jan 24 2015 I think closedInterval!T (T left, T right) would be a nice name
- bearophile (4/6) Jan 25 2015 It's an enhancement I have proposed.
- Dominikus Dittes Scherkl (13/17) Jan 25 2015 Hm. I had more something in mind like "paramCast" - a kind of big
- Tobias Pankrath (3/10) Jan 25 2015 http://dpaste.dzfl.pl/07b1fa3c2dad
- Dominikus Dittes Scherkl (11/26) Jan 25 2015 Hey cool.
- bearophile (6/7) Jan 25 2015 Right, but it's still a cast. And in D you want to minimize the
- Dominikus Dittes Scherkl (15/20) Jan 25 2015 I don't case too much, if I have ensured the cast is safe by
- ketmar (6/32) Jan 25 2015 this is true for C and C++ too, as all three languages doing "integer=20
- Dominikus Dittes Scherkl (20/30) Jan 25 2015 in normal assignments I never use auto - it's not simpler than
- ketmar (22/32) Jan 25 2015 sure, it can't be happy, as `x` is promoted to int in the expression, so...
- bearophile (6/7) Jan 24 2015 In Bugzilla I have proposed to solve this problem with this
- H. S. Teoh via Digitalmars-d-learn (7/13) Jan 24 2015 [...]
- ketmar (3/20) Jan 24 2015 auto myRange =3D iota(0, 256).map!(a =3D> foo(cast(ubyte)a));
- ketmar (1/1) Jan 24 2015 juicy question!=
Maybe I'm just too stupid, but I cannot manage to call a simple function with all 256 possible values of ubyte with iote: int foo(ubyte c); auto myRange = iota(0,256).map!foo; --> Error: function foo(ubyte c) is not callable using argument types (int) and this is because of the f*** end-type cannot be ubyte because in phobos everywhere end is excluded, so I have to define it too large by one. Has anyone any idea how to work around this? I would have no problem using an explicit cast, but where should I apply it?
Jan 24 2015
On Saturday, 24 January 2015 at 20:49:03 UTC, Dominikus Dittes Scherkl wrote:Maybe I'm just too stupid, but I cannot manage to call a simple function with all 256 possible values of ubyte with iote: int foo(ubyte c); auto myRange = iota(0,256).map!foo; --> Error: function foo(ubyte c) is not callable using argument types (int) and this is because of the f*** end-type cannot be ubyte because in phobos everywhere end is excluded, so I have to define it too large by one. Has anyone any idea how to work around this? I would have no problem using an explicit cast, but where should I apply it?iota(0, 256).map!(x => foo(cast(ubyte) x))
Jan 24 2015
On Saturday, 24 January 2015 at 21:00:06 UTC, Tobias Pankrath wrote:On Saturday, 24 January 2015 at 20:49:03 UTC, Dominikus Dittes Scherkl wrote:Ok, thank you very much. 4 times exactly the same answer - seems to be a common solution to a well known problem. :-/I would have no problem using an explicit cast, but where should I apply it?iota(0, 256).map!(x => foo(cast(ubyte) x))
Jan 24 2015
On Sat, 24 Jan 2015 22:57:57 +0000, Dominikus Dittes Scherkl wrote:On Saturday, 24 January 2015 at 21:00:06 UTC, Tobias Pankrath wrote:people that are new to D aren't used to D lambdas, so it's fairly common.=20 if you'll stay with D, you'll find yourself dreaming about such handy=20 thing in another compiled languages very soon. ;-)=On Saturday, 24 January 2015 at 20:49:03 UTC, Dominikus Dittes Scherkl wrote:=20 Ok, thank you very much. =20 4 times exactly the same answer - seems to be a common solution to a well known problem. :-/I would have no problem using an explicit cast, but where should I apply it?iota(0, 256).map!(x =3D> foo(cast(ubyte) x))
Jan 24 2015
On Saturday, 24 January 2015 at 23:19:11 UTC, ketmar wrote:people that are new to D aren't used to D lambdas, so it's fairly common.Oh, I am aware, but I didn't thought it would be necessary in this pace.if you'll stay with D, you'll find yourself dreaming about such handy thing in another compiled languages very soon. ;-)I don't consider to use any other language as long as I have a choice :-) But in the end, my one short and beautiful solution auto myRange = iota(start, end).map!foo; changed into something quite klumsy: auto myRange = iota(start, end).map!(x => foo(cast(ParameterTypeTuple!foo[0])x)); which I think is against the philosophy of D as it turns away the eye of the reader from what is really going on, especially if previous constraints ensured that start and end-1 are of the correct type :-( But ok, still far, far better than what would be neccessary in C++
Jan 24 2015
On Sun, 25 Jan 2015 00:12:18 +0000, Dominikus Dittes Scherkl wrote:On Saturday, 24 January 2015 at 23:19:11 UTC, ketmar wrote:you can always write your own iota replacement, which will do "[]" and=20 use ubytes, for example. writing that things is way easier than in C++.=20 something like "myIota!ubyte(0, 255)", for example -- to make it visible=20 that it emits ubytes.=people that are new to D aren't used to D lambdas, so it's fairly common.Oh, I am aware, but I didn't thought it would be necessary in this pace. =20if you'll stay with D, you'll find yourself dreaming about such handy thing in another compiled languages very soon. ;-)=20 I don't consider to use any other language as long as I have a choice :-) =20 But in the end, my one short and beautiful solution =20 auto myRange =3D iota(start, end).map!foo; =20 changed into something quite klumsy: =20 auto myRange =3D iota(start, end).map!(x =3D> foo(cast(ParameterTypeTuple!foo[0])x)); =20 which I think is against the philosophy of D as it turns away the eye of the reader from what is really going on, especially if previous constraints ensured that start and end-1 are of the correct type :-( =20 But ok, still far, far better than what would be neccessary in C++
Jan 24 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.
Jan 24 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
Jan 25 2015
On Sunday, 25 January 2015 at 10:42:51 UTC, bearophile wrote:Vlad Levenfeld: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 :-/What's this about !`[]` and std.range.uniform?? It's not in the documentation.It's an enhancement I have proposed.
Jan 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
Jan 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: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!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
Jan 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
Jan 25 2015
On Sunday, 25 January 2015 at 13:03:16 UTC, bearophile wrote:Dominikus Dittes Scherkl: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!!!!!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.
Jan 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:this is true for C and C++ too, as all three languages doing "integer=20 promotion". the only difference is that D forbids potentially lossy=20 assigns. you best bet is to not use `auto`, but specify required type explicitly.=20 or use ints/uints and cast to bytes only when it is necessary.=Dominikus Dittes Scherkl:I don't case too much, if I have ensured the cast is safe by constraints beforehand. =20 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: =20 ubyte x =3D 50; auto y =3D x & 0x11; // y is int! I hate that! =20 even if I use unsigned literals: auto z =3D x & 0x12u; // z is uint - better but still bad. More so as & should result in the smaller of the two types!! =20 But I need not even use literals (which unfortunately cannot be makred as "ubyte" or "short"). Look at this: =20 auto x2 =3D (x>>4) | (x<<4); // swap nibbles - but result in an int!!!!!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.
Jan 25 2015
On Sunday, 25 January 2015 at 18:59:04 UTC, ketmar wrote: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.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.
Jan 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 happysure, it can't be happy, as `x` is promoted to int in the expression, so=20 the expression result is `int`. better range analysis can prove that the=20 resuit can be fit in `ubyte`, of course. or you can do `&0xff` -- the=20 compiler is intelligent enough to see that this fits to ubyte too.or if you index with a long, even after explicit check: =20 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`=20 type for this. anyway, what you talking about is a missing integer range analysis in=20 complier. i'm not sure that it worth adding, as it slows down compilation=20 and hiding some potentially bad code. i can grep for `cast`s to see where=20 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=20 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=20 generate any warning?! D design decision to silently allow conversion of=20 `int` to `uint`/`ulong` is conceptually flawed. but this is one of the=20 things that will never be fixed, so we have to live with it.=
Jan 25 2015
Dominikus Dittes Scherkl:Has anyone any idea how to work around this?In Bugzilla I have proposed to solve this problem with this syntax taken from std.range.uniform: iota!"[]"(ubyte.min, ubyte.max) Bye, bearophile
Jan 24 2015
On Sat, Jan 24, 2015 at 08:49:01PM +0000, Dominikus Dittes Scherkl via Digitalmars-d-learn wrote:Maybe I'm just too stupid, but I cannot manage to call a simple function with all 256 possible values of ubyte with iote: int foo(ubyte c); auto myRange = iota(0,256).map!foo;[...] Try: auto myRange = iota(0, 256).map!(a => foo(cast(ubyte)a)); T -- Shin: (n.) A device for finding furniture in the dark.
Jan 24 2015
On Sat, 24 Jan 2015 20:49:01 +0000, Dominikus Dittes Scherkl wrote:Maybe I'm just too stupid, but I cannot manage to call a simple function with all 256 possible values of ubyte with iote: =20 int foo(ubyte c); =20 auto myRange =3D iota(0,256).map!foo; =20 --> Error: function foo(ubyte c) is not callable using argument types (int) =20 and this is because of the f*** end-type cannot be ubyte because in phobos everywhere end is excluded, so I have to define it too large by one. =20 Has anyone any idea how to work around this? I would have no problem using an explicit cast, but where should I apply it?auto myRange =3D iota(0, 256).map!(a =3D> foo(cast(ubyte)a)); =
Jan 24 2015