March 27, 2013 Re: My thoughts & experiences with D so far, as a novice D coder | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | On 03/27/2013 07:20 PM, Andrei Alexandrescu wrote:
> On 3/27/13 1:23 PM, Timon Gehr wrote:
>>> - Function that never return are inferred void. I would have preferred
>>> typeof(null) as void lead to many static and repetitive code for nothing
>>> when doing metaprograming.
>>
>> I strongly disagree.
>
> Ideally such function should return a "none" type, the bottom of the
> hierarchy lattice. We don't have such, so returning typeof(null) (which
> we do have) is the next best choice as it's just above bottom.
>
> Andrei
Maybe it is one next best choice. It is still a horrible choice.
It's not any more just above bottom than the following type:
struct JustAboveBottom{ }
We should either go with the real thing or do nothing about it.
|
March 28, 2013 Re: My thoughts & experiences with D so far, as a novice D coder | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | On Wednesday, 27 March 2013 at 18:20:49 UTC, Andrei Alexandrescu wrote:
> On 3/27/13 1:23 PM, Timon Gehr wrote:
>>> - Function that never return are inferred void. I would have preferred
>>> typeof(null) as void lead to many static and repetitive code for nothing
>>> when doing metaprograming.
>>
>> I strongly disagree.
>
> Ideally such function should return a "none" type, the bottom of the hierarchy lattice. We don't have such, so returning typeof(null) (which we do have) is the next best choice as it's just above bottom.
>
I thought that typeof(null) was that bottom type. What is the difference ?
Anyway, void isn't the right choice here and is a pain to work with.
|
March 28, 2013 Re: My thoughts & experiences with D so far, as a novice D coder | ||||
---|---|---|---|---|
| ||||
Posted in reply to Vidar Wahlberg | On 2013-03-27 16:34, Vidar Wahlberg wrote: > - I find myself in a world of pain when I want to share data more > complex than the basic data types (int, char, byte, etc) across threads. > Seemingly the magic trick is to "cast(shared) foo" (or > "cast(immutable)") when passing objects/references to another thread, > then "cast(Foo)" back on the receiving end (as most classes/structs in > the standard library refuse to let you call any methods when the object > is shared). The examples in the source and TDPL are fairly limited on > the issue, it mostly covers only those basic data types. Try message passing and serialize the data you want to send. Message passing: http://dlang.org/phobos/std_concurrency.html Serialization: https://github.com/jacob-carlborg/orange -- /Jacob Carlborg |
March 28, 2013 Re: My thoughts & experiences with D so far, as a novice D coder | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On 03/27/2013 12:08 PM, Steven Schveighoffer wrote: > On Wed, 27 Mar 2013 11:34:19 -0400, Vidar Wahlberg > <vidar.wahlberg@gmail.com> wrote: > >> - When casting a value to an enum, there's no checking that the value >> actually is a valid enum value. Don't think I ever found a solution on >> how to check whether the value after casting is a valid enum value, it >> hasn't been a pressing issue. > > Typically, one uses std.conv.to to safely convert one value into > another. Cast should be avoided unless absolutely necessary. > > I just tested it, it works on enum *strings*, but not enum *values* > > For example: > > import std.conv; > > enum X { > i, j, k > } > > void main() > { > X x = to!X("i"); // works! > x = to!X(1); // fails! > } > I think to should be able to do this, but I'm not a good enough guru > with templates and compile-time type info to know if it's possible. > Anyone know if this is possible? If so, I think it should be added. > > -Steve It also works on values.... enum A { B, C, D, } int w; import std.conv; import std.stdio; void main() { auto t = w.to!A.B; writeln(t); } |
March 28, 2013 Re: My thoughts & experiences with D so far, as a novice D coder | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On 03/27/2013 03:47 PM, Steven Schveighoffer wrote:
> On Wed, 27 Mar 2013 14:09:07 -0400, Nick Sabalausky
> <SeeWebsiteToContactMe@semitwist.com> wrote:
>
>> On Wed, 27 Mar 2013 14:07:27 -0400
>> Nick Sabalausky <SeeWebsiteToContactMe@semitwist.com> wrote:
>>
>>> On Wed, 27 Mar 2013 13:08:19 -0400
>>> >
>>> > I just tested it, it works on enum *strings*, but not enum *values*
>>> >
>>> > For example:
>>> >
>>> > import std.conv;
>>> >
>>> > enum X {
>>> > i, j, k
>>> > }
>>> >
>>> > void main()
>>> > {
>>> > X x = to!X("i"); // works!
>>> > x = to!X(1); // fails!
>>> > }
>>> >
>>>
>>> Works for me on 2.063 Win. Keep in mind:
>>>
>>> assert(cast(int)X.i == 0);
>>> assert(cast(int)X.j == 1);
>>>
>>
>> I meant of course 2.062
>>
>
> Hah, I have not yet downloaded 2.062. It did not work in 2.061, not sure
> if that was a bug or it's a new feature.
>
> anyway, that is good to know!
>
> -Steve
It worked for me in 2.061, as that's what I'm currently on.
Waiting to build the release that I hear might have shared objects!
|
March 28, 2013 Re: My thoughts & experiences with D so far, as a novice D coder | ||||
---|---|---|---|---|
| ||||
Posted in reply to deadalnix | On 03/28/2013 04:18 AM, deadalnix wrote: > On Wednesday, 27 March 2013 at 18:20:49 UTC, Andrei Alexandrescu wrote: >> On 3/27/13 1:23 PM, Timon Gehr wrote: >>>> - Function that never return are inferred void. I would have preferred >>>> typeof(null) as void lead to many static and repetitive code for >>>> nothing >>>> when doing metaprograming. >>> >>> I strongly disagree. >> >> Ideally such function should return a "none" type, the bottom of the >> hierarchy lattice. We don't have such, so returning typeof(null) >> (which we do have) is the next best choice as it's just above bottom. >> > > I thought that typeof(null) was that bottom type. What is the difference ? > There is a huge difference. - typeof(null) is a subtype of all _class, interface and pointer_ types because they all _include_ its value, null. - bottom is a subtype of _all_ types, because there is _no_ value of type bottom. > Anyway, void isn't the right choice here and is a pain to work with. typeof(null) would be worse. |
March 28, 2013 Re: My thoughts & experiences with D so far, as a novice D coder | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr | On Thursday, 28 March 2013 at 10:34:35 UTC, Timon Gehr wrote: > On 03/28/2013 04:18 AM, deadalnix wrote: >> On Wednesday, 27 March 2013 at 18:20:49 UTC, Andrei Alexandrescu wrote: >>> On 3/27/13 1:23 PM, Timon Gehr wrote: >>>>> - Function that never return are inferred void. I would have preferred >>>>> typeof(null) as void lead to many static and repetitive code for >>>>> nothing >>>>> when doing metaprograming. >>>> >>>> I strongly disagree. >>> >>> Ideally such function should return a "none" type, the bottom of the >>> hierarchy lattice. We don't have such, so returning typeof(null) >>> (which we do have) is the next best choice as it's just above bottom. >>> >> >> I thought that typeof(null) was that bottom type. What is the difference ? >> > > There is a huge difference. > > - typeof(null) is a subtype of all _class, interface and pointer_ > types because they all _include_ its value, null. > > - bottom is a subtype of _all_ types, because there is _no_ value of > type bottom. > OK I see the difference. >> Anyway, void isn't the right choice here and is a pain to work with. > > typeof(null) would be worse. I don't see how it is worse. |
March 28, 2013 Re: My thoughts & experiences with D so far, as a novice D coder | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | On Wednesday, 27 March 2013 at 16:04:49 UTC, bearophile wrote: > Vidar Wahlberg: [cut] >> That static arrays are value types while dynamic arrays are reference types may not be obvious for those with primarily Java background. > > Java has a semantics more limited compared to a system language as D/Rust. This is not easy to avoid. Especially when keeping the poor C/C++ syntax for declaration instead of Pascal-style declaration syntax where you *name* the kind of array you're using! *Sigh* and some still think that syntax doesn't matter.. renoX |
March 28, 2013 Re: My thoughts & experiences with D so far, as a novice D coder | ||||
---|---|---|---|---|
| ||||
Posted in reply to renoX | To follow up with some new woes I'm currently struggling with: I'm storing some various values in an ubyte array. I discovered that it's probably std.bitmanip I wish to use in order to "convert" i.e. an int to 4 bytes (although I went first to std.conv looking for this feature). So I have "ubyte[] buffer;", and my second thought is that the "append" method (http://dlang.org/phobos/std_bitmanip.html#.append) is what I want to append values to my ubyte-array (my first thought was something like "buffer ~= to!ubyte[](42);", although then I forgot about endianness). In the example in the documentation it does say "auto buffer = appender!(const ubyte[])();", with no explanation as of what "appender" is (I later learned that this is from std.array), but just looking a bit up I see that the "write" method explained just above use "ubyte[] buffer; buffer.write!ubyte(42);", so I assumed that I could use ubyte[] myself instead of this "appender" which I thought was some legacy code. So I write some simple test code: import std.bitmanip, std.stdio; void main() { ubyte[] buffer; buffer.append!ubyte(42); } Run it through rdmd, and get: "core.exception.AssertError@/usr/include/d/std/array.d(591): Attempting to fetch the front of an empty array of ubyte". Just to see what happens I set the size of the buffer ("buffer.length = 1;") before appending and run it again. Now it runs, but instead of appending it behaves like write(), which was not exactly what I wanted. At this time I google for this "appender" used in the example and learn that it comes from std.array, so I import std.array and try again using "auto buffer = appender!(ubyte[])();", and surely enough, now it does append correctly to the buffer. Great, I have a solution, so I go back to my project and implement it like I implemented it in my test code, but when I compile my project after this addition I get a new cryptic error message: "Error: __overloadset isn't a template". After digging a bit I realized that it's because in my project I also import std.file, apparently there are some collisions between std.bitmanip and std.file. Again it's solvable, but it's yet another fight with the language/standard library. I would also assume that it's not that uncommon for a module that use std.bitmanip to also use std.file, meaning that this error potentially may occur often. A bit on the side: It seems to me as importing std.bitmanip somehow adds new properties to my array (".read()" and ".write()", for example). Not necessarily a bad thing, more of "I've not seen this before, I was expecting that I were to concatenate the bytes from the conversion to my buffer using ~". |
March 28, 2013 Re: My thoughts & experiences with D so far, as a novice D coder | ||||
---|---|---|---|---|
| ||||
Posted in reply to Vidar Wahlberg | On Thu, Mar 28, 2013 at 09:24:49PM +0100, Vidar Wahlberg wrote:
> To follow up with some new woes I'm currently struggling with: I'm storing some various values in an ubyte array. I discovered that it's probably std.bitmanip I wish to use in order to "convert" i.e. an int to 4 bytes (although I went first to std.conv looking for this feature).
[...]
There are several ways to convert an int into 4 bytes:
1) Use a union:
static assert(int.sizeof==4);
ubyte[4] intToUbytes(int x) {
union U {
int i;
ubyte[4] b;
}
U u;
u.i = x;
return u.b;
}
2) Use bit operators:
ubyte[4] intToUbytes(int x) {
ubyte[4] bytes;
// Note: this assumes little-endian. For big-endian,
// reverse the order below.
bytes[0] = x & 0xFF;
bytes[1] = (x >> 8) & 0xFF;
bytes[2] = (x >> 16) & 0xFF;
bytes[3] = (x >> 24) & 0xFF;
return bytes;
}
3) Use a pointer cast (warning: un-@safe):
ubyte[4] intToUbytes(int x) @system {
ubyte[4] b;
ubyte* ptr = cast(ubyte*)&x;
b[0] = *ptr++;
b[1] = *ptr++;
b[2] = *ptr++;
b[3] = *ptr;
return b;
}
4) Reinterpret a pointer (warning: un-@safe):
ubyte[4] intToUbytes(int x) @system {
return *cast(ubyte[4]*)&x;
}
I'm sure there are several other ways to do it.
You don't need to use appender unless you're doing a lot of conversions in one go.
--T
|
Copyright © 1999-2021 by the D Language Foundation