www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.announce - Blog series to teach and show off D's metaprogramming by creating a

reply SealabJaster <sealabjaster gmail.com> writes:
https://bradley.chatha.dev/Home/Blog?post=JsonSerialiser1

Currently only the first post is out, as I'd like to collect 
feedback before writing any more.

The series is aimed at people new to D, or people who have heard 
of D, but haven't really explored its metaprogramming too much, 
hence certain things such as calling D's metaprogramming "often 
overlooked" as that tends to be true for non/new users of D.

Sorry in advance if this is the wrong forum group to post to, I 
didn't know whether to put it here or in the Learn group.

Future plans for this series:
  * Serialising structs (next up).

  * Serialising enums via their names, rather than values (and 
certain complications such as is(SomeEnum == int) being true).

  * Serialising classes.

  * Using UDAs to let classes and structs customise their fields.

  * Using __traits(compiles) to determine if a struct or class 
implements a custom (de)serialisation function.

  * Trying to think of how I can shoe horn mixin templates in, 
just so they're shown off.

I'm welcome to any other ideas to try and fit into the series. 
The serialiser won't be overly robust in terms of edge cases 
(such as nested classes/structs needing to be filtered out 
sometimes), but I'll try to mention them and provide a workaround 
where possible.

I've also taken to certain decisions in the code snippets, to try 
and reduce the amount of things I need to explain at once, and to 
hopefully make things more readable. e.g. Using "const string" 
instead of just "const" or "enum" (and then having to explain why 
not to use "enum" for strings), giving all if and else statements 
brackets to make things more readable (that's the plan at least), 
etc.

As for release schedule, I'm planning on getting at least one 
post out a week.

Other than feedback for the actual content of the blog, I'd also 
appreciate any feedback on visual style of the blog, since I'm 
quite a novice at CSS, let alone writing things like this.

While I'm not really capable of contributing to D in terms of 
improving phobos, or writing quality libraries, I'm hoping to at 
least be able to provide some educational material on what I feel 
makes D worth it as a way of contribution.
Oct 30 2019
next sibling parent reply GreatSam4sure <greatsam4sure gmail.com> writes:
On Thursday, 31 October 2019 at 00:05:06 UTC, SealabJaster wrote:
 https://bradley.chatha.dev/Home/Blog?post=JsonSerialiser1

 Currently only the first post is out, as I'd like to collect 
 feedback before writing any more.

 [...]
This is truly beautiful. Good work, a great tutorial indeed. Can you pick up the topic of compile time from the ground up. I will also love tutorial on DasbetterC. No tutorial that i am aware in this aspect of D Thanks a million times. I am awaiting the rest part of the tutorial
Oct 30 2019
parent SealabJaster <sealabjaster gmail.com> writes:
On Thursday, 31 October 2019 at 06:35:07 UTC, GreatSam4sure wrote:
 On Thursday, 31 October 2019 at 00:05:06 UTC, SealabJaster 
 wrote:
 https://bradley.chatha.dev/Home/Blog?post=JsonSerialiser1

 Currently only the first post is out, as I'd like to collect 
 feedback before writing any more.

 [...]
This is truly beautiful. Good work, a great tutorial indeed. Can you pick up the topic of compile time from the ground up. I will also love tutorial on DasbetterC. No tutorial that i am aware in this aspect of D Thanks a million times. I am awaiting the rest part of the tutorial
I'll definitely cover compile time in more depth at some point, but I don't want to put too much on myself right now, so any other topics will have to wait until after this current series is done. I'll admit I haven't messed around with DasBetterC since I haven't really had a use case for it yet. I'll mess around with it and maybe write something up, but no promises (and of course, it'll wait until after the serialiser series). Thank you for the kind words as well.
Oct 31 2019
prev sibling next sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
Looks like a very nice initiative! Looking forward to more!

A thought - host it on github? That way people can easily contribute
suggestions 
to it. You'd be in charge, of course, with what to do with those suggestions.
Oct 31 2019
parent reply SealabJaster <sealabjaster gmail.com> writes:
On Thursday, 31 October 2019 at 07:38:46 UTC, Walter Bright wrote:
 Looks like a very nice initiative! Looking forward to more!

 A thought - host it on github? That way people can easily 
 contribute suggestions to it. You'd be in charge, of course, 
 with what to do with those suggestions.
Happy to say it is on github, https://github.com/SealabJaster/PersonalWebsite Issue is though, since it's my personal website I never thought anyone else would even look at the source, so it's got a bit of jank in it. For example, each blog post is going to be hand written HTML https://github.com/SealabJaster/PersonalWebsite/blob/master/PersonalWebsite/Views/BlogPosts/JsonSerialiser1.cshtml Though I might bother making it so I can write in markdown instead.
Oct 31 2019
parent Walter Bright <newshound2 digitalmars.com> writes:
On 10/31/2019 2:51 AM, SealabJaster wrote:
 On Thursday, 31 October 2019 at 07:38:46 UTC, Walter Bright wrote:
 Looks like a very nice initiative! Looking forward to more!

 A thought - host it on github? That way people can easily contribute 
 suggestions to it. You'd be in charge, of course, with what to do with those 
 suggestions.
Happy to say it is on github, https://github.com/SealabJaster/PersonalWebsite
Excellent!
 Issue is though, since it's my personal website I never thought anyone else 
 would even look at the source, so it's got a bit of jank in it.
Github is an opportunity for you to build your brand and career.
 For example, each blog post is going to be hand written HTML 
 https://github.com/SealabJaster/PersonalWebsite/blob/master/PersonalWebsite/Views/BlogPosts/Js
nSerialiser1.cshtml 
 
 Though I might bother making it so I can write in markdown instead.
Markdown is a good choice. I've done the hand written HTML, it's agony.
Oct 31 2019
prev sibling next sibling parent reply Paolo Invernizzi <paolo.invernizzi gmail.com> writes:
On Thursday, 31 October 2019 at 00:05:06 UTC, SealabJaster wrote:
 https://bradley.chatha.dev/Home/Blog?post=JsonSerialiser1

 Currently only the first post is out, as I'd like to collect 
 feedback before writing any more.

 [...]
Great Job, keep pushing! If you don't know it, I suggest to have a look to the venerable Philippe Sigaud "D Template Tutorial" for inspiration [1]. It was by far the most complete and comprensive tutorial covering every aspect of the D Template programming. It would be great to have also an updated version of it ... [1] https://github.com/PhilippeSigaud/D-templates-tutorial
Oct 31 2019
parent reply GreatSam4sure <greatsam4sure gmail.com> writes:
On Thursday, 31 October 2019 at 09:02:07 UTC, Paolo Invernizzi 
wrote:
 On Thursday, 31 October 2019 at 00:05:06 UTC, SealabJaster 
 wrote:
 https://bradley.chatha.dev/Home/Blog?post=JsonSerialiser1

 Currently only the first post is out, as I'd like to collect 
 feedback before writing any more.

 [...]
Great Job, keep pushing! If you don't know it, I suggest to have a look to the venerable Philippe Sigaud "D Template Tutorial" for inspiration [1]. It was by far the most complete and comprensive tutorial covering every aspect of the D Template programming. It would be great to have also an updated version of it ... [1] https://github.com/PhilippeSigaud/D-templates-tutorial
The tutorial you referred to is very comprehensive but i am confess is hard to understand. I have read it twice but i did not understand. It might be my fault but i will prefer a simple start with the newbie in mind
Oct 31 2019
parent reply Paolo Invernizzi <paolo.invernizzi gmail.com> writes:
On Thursday, 31 October 2019 at 09:07:18 UTC, GreatSam4sure wrote:
 On Thursday, 31 October 2019 at 09:02:07 UTC, Paolo Invernizzi 
 wrote:
 On Thursday, 31 October 2019 at 00:05:06 UTC, SealabJaster 
 wrote:
 https://bradley.chatha.dev/Home/Blog?post=JsonSerialiser1

 Currently only the first post is out, as I'd like to collect 
 feedback before writing any more.

 [...]
Great Job, keep pushing! If you don't know it, I suggest to have a look to the venerable Philippe Sigaud "D Template Tutorial" for inspiration [1]. It was by far the most complete and comprensive tutorial covering every aspect of the D Template programming. It would be great to have also an updated version of it ... [1] https://github.com/PhilippeSigaud/D-templates-tutorial
The tutorial you referred to is very comprehensive but i am confess is hard to understand. I have read it twice but i did not understand. It might be my fault but i will prefer a simple start with the newbie in mind
I agree with you, a simple start is valuable, so I think it's good to have someone who is covering that, so thanks! On the other side, I'm missing an updated version of a "advanced" tutorial, mainly because, as you have noticed, advanced template programming is not so easy to learn! Thanks for your job!
Oct 31 2019
parent SealabJaster <sealabjaster gmail.com> writes:
On Thursday, 31 October 2019 at 09:11:59 UTC, Paolo Invernizzi 
wrote:
 On Thursday, 31 October 2019 at 09:07:18 UTC, GreatSam4sure 
 wrote:
 On Thursday, 31 October 2019 at 09:02:07 UTC, Paolo Invernizzi 
 wrote:
 On Thursday, 31 October 2019 at 00:05:06 UTC, SealabJaster 
 wrote:
 [...]
Great Job, keep pushing! If you don't know it, I suggest to have a look to the venerable Philippe Sigaud "D Template Tutorial" for inspiration [1]. It was by far the most complete and comprensive tutorial covering every aspect of the D Template programming. It would be great to have also an updated version of it ... [1] https://github.com/PhilippeSigaud/D-templates-tutorial
The tutorial you referred to is very comprehensive but i am confess is hard to understand. I have read it twice but i did not understand. It might be my fault but i will prefer a simple start with the newbie in mind
I agree with you, a simple start is valuable, so I think it's good to have someone who is covering that, so thanks! On the other side, I'm missing an updated version of a "advanced" tutorial, mainly because, as you have noticed, advanced template programming is not so easy to learn! Thanks for your job!
Ooh, that's quite the undertaking. I'll definitely give it some thought though, but as I said in another post, it'll have to be until after the serialiser set of posts are done. Would be an interesting thing to slowly work on over time though.
Oct 31 2019
prev sibling next sibling parent reply Jacob Carlborg <doob me.com> writes:
On Thursday, 31 October 2019 at 00:05:06 UTC, SealabJaster wrote:
 https://bradley.chatha.dev/Home/Blog?post=JsonSerialiser1
FYI, string is a built-in type. Regarding exercise 2. I would be very careful with deserializing a single character from JSON. First, because JSON doesn't support single characters. Second, you'll run into issues with Unicode. For example, you would need to know the exact JSON content, not just the type, to specify the type that should be deserialized. Example: assert(json.deserialise!char() == 'πŸ˜€'); The above will not work, because the type of 'πŸ˜€' is not `char`, it's `dchar`. The deserialization would need to throw an exception in this case, because 'πŸ˜€' won't fit in a `char`. It's much simpler to just not allow this use case. -- /Jacob Carlborg
Nov 01 2019
next sibling parent reply Ethan <gooberman gmail.com> writes:
On Friday, 1 November 2019 at 10:39:42 UTC, Jacob Carlborg wrote:
 FYI, string is a built-in type.
string is immutable(char)[], as we all know. Syntactic sugar, not exactly a built in type but treating it like one is often valuable. To follow on from this, I'll share my experience with doing exactly what SealabJaster is illustrating several times previously: You also want to catch const(char)[] and just plain char[] for JSON serialisation purposes. So a template constraint that catches all those is what you want instead of just is( T == string ). Dealing with wstring and dstring can be handled for bonus points... but eh, you only need to really worry about that if you are writing a library (or heavily use Phobos...).
Nov 01 2019
next sibling parent reply Jacob Carlborg <doob me.com> writes:
On Friday, 1 November 2019 at 11:29:11 UTC, Ethan wrote:

 string is immutable(char)[], as we all know. Syntactic sugar, 
 not exactly a built in type but treating it like one is often 
 valuable.
It's an alias, but what it's aliased to is a built-in type. -- /Jacob Carlborg
Nov 01 2019
parent Ethan <gooberman gmail.com> writes:
On Friday, 1 November 2019 at 12:50:09 UTC, Jacob Carlborg wrote:
 It's an alias, but what it's aliased to is a built-in type.
A *slice* of a built-in type *with qualifiers*. The only way to simplify that description is to call it "syntactic sugar". "Built-in type" to describe the entire thing is only a half-truth.
Nov 01 2019
prev sibling parent reply SealabJaster <sealabjaster gmail.com> writes:
On Friday, 1 November 2019 at 11:29:11 UTC, Ethan wrote:
 You also want to catch const(char)[] and just plain char[] for 
 JSON serialisation purposes. So a template constraint that 
 catches all those is what you want instead of just is( T == 
 string ).
I was definitely thinking of putting that in the first post, but thought it'd be better to leave it for later. Someone newer to D might not realise that a string is just a normal array/slice, instead of a special type (like in C++), so I didn't want to have to explain that yet. I'd also need to explain the differences between const and immutable briefly. I'm planning on going over it though in a post that goes over serialising arrays, which will likely be either the 4th or 5th one. Though, there's always the possiblity I'm just worrying and overthinking too much about putting too much into each post. I'm trying to make things easy to digest, and since I'm not used to writing things like this, I don't have a great grasp on how a person newer to D would be able to follow it.
Nov 01 2019
parent reply SealabJaster <sealabjaster gmail.com> writes:
On Friday, 1 November 2019 at 21:14:56 UTC, SealabJaster wrote:
 ...
comments on this thread. I'd also like to clarify that the main purpose of this series is to demonstrate some of the thing of what D's metaprogramming can do, via the creation of the serialiser. The serialiser is just a by-product, so don't have the expectation that it's going to be amazingly robust. Though, maybe this is the wrong way to go about thing... If anything, I just hope to not spread mis-information, or overly bad practices.
Nov 03 2019
parent reply SealabJaster <sealabjaster gmail.com> writes:
On Sunday, 3 November 2019 at 08:35:42 UTC, SealabJaster wrote:
 On Friday, 1 November 2019 at 21:14:56 UTC, SealabJaster wrote:
 ...
Sorry, seems it cut out the first half of that reply. New posts are out, and I don't want to spam Announce with new threads, so I'm just replying to this one. https://bradley.chatha.dev/Home/Blog?post=JsonSerialiser1_1 https://bradley.chatha.dev/Home/Blog?post=JsonSerialiser2
Nov 03 2019
next sibling parent reply JN <666total wp.pl> writes:
On Sunday, 3 November 2019 at 08:37:07 UTC, SealabJaster wrote:
 On Sunday, 3 November 2019 at 08:35:42 UTC, SealabJaster wrote:
 On Friday, 1 November 2019 at 21:14:56 UTC, SealabJaster wrote:
 ...
Sorry, seems it cut out the first half of that reply. New posts are out, and I don't want to spam Announce with new threads, so I'm just replying to this one. https://bradley.chatha.dev/Home/Blog?post=JsonSerialiser1_1 https://bradley.chatha.dev/Home/Blog?post=JsonSerialiser2
"This often seems to confuse people at first, especially those coming from other languages" I think what's confusing people is that enum (short for ENUMERATION) is suddenly used like a constant/alias.
Nov 03 2019
parent reply Patrick Schluter <Patrick.Schluter bbox.fr> writes:
On Sunday, 3 November 2019 at 21:35:18 UTC, JN wrote:
 On Sunday, 3 November 2019 at 08:37:07 UTC, SealabJaster wrote:
 On Sunday, 3 November 2019 at 08:35:42 UTC, SealabJaster wrote:
 On Friday, 1 November 2019 at 21:14:56 UTC, SealabJaster 
 wrote:
 ...
Sorry, seems it cut out the first half of that reply. New posts are out, and I don't want to spam Announce with new threads, so I'm just replying to this one. https://bradley.chatha.dev/Home/Blog?post=JsonSerialiser1_1 https://bradley.chatha.dev/Home/Blog?post=JsonSerialiser2
"This often seems to confuse people at first, especially those coming from other languages" I think what's confusing people is that enum (short for ENUMERATION) is suddenly used like a constant/alias.
I don't get why it confuses people. In all languages I know (C, C++, Java, Pascal, etc..) they are used to associate a compile time symbols with some quantities, i.e. the definition of constants. When an enumeration only consists of 1 value, then the enumeration is this value itself.
Nov 04 2019
next sibling parent Martin Tschierschke <mt smartdolphin.de> writes:
On Monday, 4 November 2019 at 08:25:11 UTC, Patrick Schluter 
wrote:
 On Sunday, 3 November 2019 at 21:35:18 UTC, JN wrote:
 On Sunday, 3 November 2019 at 08:37:07 UTC, SealabJaster wrote:
 On Sunday, 3 November 2019 at 08:35:42 UTC, SealabJaster 
 wrote:
 On Friday, 1 November 2019 at 21:14:56 UTC, SealabJaster 
 wrote:
 ...
Sorry, seems it cut out the first half of that reply. New posts are out, and I don't want to spam Announce with new threads, so I'm just replying to this one. https://bradley.chatha.dev/Home/Blog?post=JsonSerialiser1_1 https://bradley.chatha.dev/Home/Blog?post=JsonSerialiser2
"This often seems to confuse people at first, especially those coming from other languages" I think what's confusing people is that enum (short for ENUMERATION) is suddenly used like a constant/alias.
I don't get why it confuses people. In all languages I know (C, C++, Java, Pascal, etc..) they are used to associate a compile time symbols with some quantities, i.e. the definition of constants. When an enumeration only consists of 1 value, then the enumeration is this value itself.
Yes and no, because the fist case for using enum described at [1] is something very different:
 This defines a new type X which has values X.A=0, X.B=1, X.C=2:
 enum X { A, B, C }  // named enum
[1] https://dlang.org/spec/enum.html And it might be good to change the docs to point out the very often taken use case for declaring a singe compile time constant.
Nov 04 2019
prev sibling parent Laurent =?UTF-8?B?VHLDqWd1aWVy?= <laurent.treguier.sink gmail.com> writes:
On Monday, 4 November 2019 at 08:25:11 UTC, Patrick Schluter 
wrote:
 I don't get why it confuses people.
 In all languages I know (C, C++, Java, Pascal, etc..) they are 
 used to associate a compile time symbols with some quantities, 
 i.e. the definition of constants.
 When an enumeration only consists of 1 value, then the 
 enumeration is this value itself.
If I'm not mistaken `enum` must come from "enumerate" or "enumeration", so it's easy to instinctively think of enums as having multiple possible values; using such a word for a single value is a bit counter-intuitive IMO.
Nov 04 2019
prev sibling parent reply SealabJaster <sealabjaster gmail.com> writes:
On Sunday, 3 November 2019 at 08:37:07 UTC, SealabJaster wrote:
 ...
Next post is out, I feel kind of iffy over how I went over classes, but I think for the most part it came out ok. I probably won't touch classes specifically in any future post though, unless I can think of something interesting to do with them. https://bradley.chatha.dev/Home/Blog?post=JsonSerialiser3 that shows how __traits(hasMember), __traits(getMember)/__traits(allMembers), alongside some things in std.traits like Parameters and ReturnType, could be used instead of __traits(compiles). Also, until run.dlang.io's ability to create links is fixed, the usual links to snippets won't take you anywhere.
Nov 10 2019
parent reply JN <666total wp.pl> writes:
On Sunday, 10 November 2019 at 10:22:17 UTC, SealabJaster wrote:
 Next post is out, I feel kind of iffy over how I went over 
 classes, but I think for the most part it came out ok. I 
 probably won't touch classes specifically in any future post 
 though, unless I can think of something interesting to do with 
 them.
It's outside of the scope of the tutorial, but the "tough" part in serializing classes is realizing that they're a reference type rather than value type. Just like with serializing pointers, I could have two references pointing to the same class object, and a smart deserializer would create only one class object and point both references to it.
Nov 10 2019
parent Steven Schveighoffer <schveiguy gmail.com> writes:
On 11/10/19 5:50 PM, JN wrote:
 On Sunday, 10 November 2019 at 10:22:17 UTC, SealabJaster wrote:
 Next post is out, I feel kind of iffy over how I went over classes, 
 but I think for the most part it came out ok. I probably won't touch 
 classes specifically in any future post though, unless I can think of 
 something interesting to do with them.
It's outside of the scope of the tutorial, but the "tough" part in serializing classes is realizing that they're a reference type rather than value type. Just like with serializing pointers, I could have two references pointing to the same class object, and a smart deserializer would create only one class object and point both references to it.
The tough part about serializing classes is if the class is not final, how do you serialize the derived data. It requires some sort of user help to tell it how to get at the data. -Steve
Nov 11 2019
prev sibling parent SealabJaster <sealabjaster gmail.com> writes:
On Friday, 1 November 2019 at 10:39:42 UTC, Jacob Carlborg wrote:
 On Thursday, 31 October 2019 at 00:05:06 UTC, SealabJaster 
 wrote:
 https://bradley.chatha.dev/Home/Blog?post=JsonSerialiser1
FYI, string is a built-in type.
I feel it's more of a weird gray area. As Ethan said it's more syntax sugar than a built-in type. However most code seems to treat strings as built-in; the language's string literals are useable with `string`; and they're common enough that they may as well be defined as built-in. So yea, even if I agree with Ethan that it's a "half-truth", I feel there's likely less confusion if I decide to clump it in as being built-in, so that'll be changed soon.
 Regarding exercise 2. I would be very careful with 
 deserializing a single character from JSON. First, because JSON 
 doesn't support single characters. Second, you'll run into 
 issues with Unicode. For example, you would need to know the 
 exact JSON content, not just the type, to specify the type that 
 should be deserialized. Example:

 assert(json.deserialise!char() == 'πŸ˜€');

 The above will not work, because the type of 'πŸ˜€' is not `char`, 
 it's `dchar`. The deserialization would need to throw an 
 exception in this case, because 'πŸ˜€' won't fit in a `char`. It's 
 much simpler to just not allow this use case.

 --
 /Jacob Carlborg
To be honest, those are all good points, and I can't really think of a counter argument. Regarding `wchar` and `dchar` though (and their string versions), I'm just not going to acknowledge they exist, since it's not a hard requirement, and it's just more things I need to explain, meaning more overhead on the reader.
Nov 01 2019
prev sibling parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 10/30/19 8:05 PM, SealabJaster wrote:
 https://bradley.chatha.dev/Home/Blog?post=JsonSerialiser1
 
 Currently only the first post is out, as I'd like to collect feedback 
 before writing any more.
 
 The series is aimed at people new to D, or people who have heard of D, 
 but haven't really explored its metaprogramming too much, hence certain 
 things such as calling D's metaprogramming "often overlooked" as that 
 tends to be true for non/new users of D.
 
 Sorry in advance if this is the wrong forum group to post to, I didn't 
 know whether to put it here or in the Learn group.
 
 Future plans for this series:
  Β * Serialising structs (next up).
 
  Β * Serialising enums via their names, rather than values (and certain 
 complications such as is(SomeEnum == int) being true).
 
  Β * Serialising classes.
 
  Β * Using UDAs to let classes and structs customise their fields.
 
  Β * Using __traits(compiles) to determine if a struct or class 
 implements a custom (de)serialisation function.
 
  Β * Trying to think of how I can shoe horn mixin templates in, just so 
 they're shown off.
 
 I'm welcome to any other ideas to try and fit into the series. The 
 serialiser won't be overly robust in terms of edge cases (such as nested 
 classes/structs needing to be filtered out sometimes), but I'll try to 
 mention them and provide a workaround where possible.
 
 I've also taken to certain decisions in the code snippets, to try and 
 reduce the amount of things I need to explain at once, and to hopefully 
 make things more readable. e.g. Using "const string" instead of just 
 "const" or "enum" (and then having to explain why not to use "enum" for 
 strings), giving all if and else statements brackets to make things more 
 readable (that's the plan at least), etc.
 
 As for release schedule, I'm planning on getting at least one post out a 
 week.
 
 Other than feedback for the actual content of the blog, I'd also 
 appreciate any feedback on visual style of the blog, since I'm quite a 
 novice at CSS, let alone writing things like this.
 
 While I'm not really capable of contributing to D in terms of improving 
 phobos, or writing quality libraries, I'm hoping to at least be able to 
 provide some educational material on what I feel makes D worth it as a 
 way of contribution.
Looks like a great idea! Sounds very similar to what I've been learning over the past 5 years or so. See my dconf presentation from this year. Also, if you want some inspiration for serialization/deserialization, check out jsoniopipe: http://code.dlang.org/packages/jsoniopipe Simply put, I think it's great to use D overloading as much as possible instead of static if (reading your first article). OK, now reading the "alternate function layout", I see you did do that :) That's how I did mine, and I think it reads much nicer. -Steve
Nov 11 2019
parent reply SealabJaster <sealabjaster gmail.com> writes:
On Monday, 11 November 2019 at 16:56:31 UTC, Steven Schveighoffer 
wrote:
 On 10/30/19 8:05 PM, SealabJaster wrote:
 ...
Looks like a great idea! Sounds very similar to what I've been learning over the past 5 years or so. See my dconf presentation from this year.
I had a quick skim, and seems like it touches upon a lot of stuff I want to talk about. Will give it a proper watch later today :)
 Also, if you want some inspiration for 
 serialization/deserialization, check out jsoniopipe: 
 http://code.dlang.org/packages/jsoniopipe
Will also give that a look over.
 Simply put, I think it's great to use D overloading as much as 
 possible instead of static if (reading your first article). OK, 
 now reading the "alternate function layout", I see you did do 
 that :) That's how I did mine, and I think it reads much nicer.
I do actually prefer to go with overloads (I usually use a hybrid of overloads + static ifs, depending on the case), but it made the code snippets a bit harder to read and follow (imo) so I went with a single function instead.
 The tough part about serializing classes is if the class is not 
 final, how do you serialize the derived data. It requires some 
 sort of user help to
 tell it how to get at the data.
And if you do allow things such as letting classes have a 'deserialise' member function which can be overloaded, you still need to create or be given an instance of the class beforehand, which brings things back around to the "constructor issue" in the latest post. I don't quite know if there's actually an automatic solution for classes that covers most cases? Anything I can think of places limitations in some form or another.
Nov 12 2019
next sibling parent Steven Schveighoffer <schveiguy gmail.com> writes:
On 11/12/19 4:15 AM, SealabJaster wrote:
 On Monday, 11 November 2019 at 16:56:31 UTC, Steven Schveighoffer wrote:
 The tough part about serializing classes is if the class is not final, 
 how do you serialize the derived data. It requires some sort of user 
 help to
 tell it how to get at the data.
And if you do allow things such as letting classes have a 'deserialise' member function which can be overloaded, you still need to create or be given an instance of the class beforehand, which brings things back around to the "constructor issue" in the latest post. I don't quite know if there's actually an automatic solution for classes that covers most cases? Anything I can think of places limitations in some form or another.
There's definitely not an automatic solution. However, in my jsoniopipe code, the base class can have a static function fromJSON that initializes the requested type. Such a thing has to be a member, but in theory could just be a registered callback. In my use case, I have a base class and all the derivatives in the same module (they are just messages). Here is some code that returns the base type that is portable to any such situation: static Base fromJSON(JT)(ref JT tokenizer, ReleasePolicy relPol) { // this creates a rewind point, so I can go back and parse the // object after finding the type. tokenizer.startCache(); if(tokenizer.parseTo("type")) // this part depends on the encoding { string t; // get the type name tokenizer.deserialize(t); import std.meta; // alias to the module for Base, which also contains all the // derivatives alias mod = __traits(parent, Base); enum isBase(string s) = is(__traits(getMember, mod, s) : Base) && !is(__traits(getMember, mod, s) == Base); // this gets all the classes in this module that are // derivatives of Base (except Base). D is so cool ;) alias Derivatives = Filter!(isBase, __traits(allMembers, mod)); // reset the tokenizer to read the whole JSON data for this object tokenizer.rewind(); tokenizer.endCache(); switch(t) { static foreach(typename; Derivatives) { // Note: MyType is the JSON string that designates the // type, your implementation may vary. case __traits(getMember, mod, typename).MyType: { auto result = new __traits(getMember, mod, typename); // defined by the library, does a rote // serialization of members. tokenizer.deserializeAllMembers(result, relPol); return result; } } default: assert(false, "Unknown type identifier: " ~ t); } } assert(false, "Couldn't find type identifier"); } Basically, I never have to touch this again, thanks D. Just add a new type that derives from Base with a proper MyType member, and it gets added to the list. It just has to be added to the module itself. If your class hierarchy is spread out in different files, you can make some kind of registration scheme to handle the deserialization. -Steve
Nov 12 2019
prev sibling next sibling parent reply SealabJaster <sealabjaster gmail.com> writes:
On Tuesday, 12 November 2019 at 09:15:28 UTC, SealabJaster wrote:
 ...
Just wanted to quickly explain the delay for the next post. Basically just boils down to energy levels being non-existant, and run.dlang.io still being broken (Don't want to have a backlog of snippets to make). Hopefully both issues are resolved soon.
Nov 23 2019
parent reply SealabJaster <sealabjaster gmail.com> writes:
On Saturday, 23 November 2019 at 22:38:22 UTC, SealabJaster wrote:
 On Tuesday, 12 November 2019 at 09:15:28 UTC, SealabJaster 
 wrote:
 ...
Just wanted to quickly explain the delay for the next post. Basically just boils down to energy levels being non-existant, and run.dlang.io still being broken (Don't want to have a backlog of snippets to make). Hopefully both issues are resolved soon.
4th post is now out at https://bradley.chatha.dev/Home/Blog?post=JsonSerialiser4 It's on the shorter side, and not terribly interesting due to there being nothing new to explain, but hopefully the next post should sort that out. For both this post, and the 3rd post, I've swapped over to using https://godbolt.org for my snippet needs because I've lost hope of run.dlang.io being fixed anytime soon. Apologies for the delay, especially considering how "meatless" this post was.
Dec 03 2019
parent reply SealabJaster <sealabjaster gmail.com> writes:
On Wednesday, 4 December 2019 at 03:13:28 UTC, SealabJaster wrote:
 ..
Final post of the year (and for a while) is out: https://bradley.chatha.dev/Home/Blog?post=JsonSerialiser5 Once I've worked on the website's design + other things I want to get done, then I'll finish off the series with one or two more posts. After that I'm still thinking of what I may want to talk about. An idea from earlier in this thread is to talk about what exactly "compile-time" is in D, and how to determine what's run at compile-time, and what's ran at run-time. Regardless, I hope these posts are at least a tiny bit useful, even if their overall quality isn't great.
Dec 11 2019
parent reply SealabJaster <sealabjaster gmail.com> writes:
On Wednesday, 11 December 2019 at 12:04:04 UTC, SealabJaster 
wrote:


Final post of this series (also sorry for the necro, but it's 
probably better than making a new post): 
https://bradley.chatha.dev/BlogPost/JsonSerialiser/6-mixin-template-automate-dlang-tutorial-metaprogramming

Pretty unhappy with its content, considering how long it's been 
since I wanted to write it, but hopefully its main purpose (to 
show off mixin template) is good enough.

I'd also like to apologise here for constantly embarrassing 
myself here (and I guess also on the Discord a year or so back), 
I'm likely to just not post here anymore just to save myself from 
the anxiety.

I hope this has been of some use to someone ^^. I want to write 
some more, but have no concrete plans for anything anytime soon.
May 06 2020
next sibling parent reply Greatsam4sure <greatsam4sure yahoo.com> writes:
On Thursday, 7 May 2020 at 00:28:10 UTC, SealabJaster wrote:
 On Wednesday, 11 December 2019 at 12:04:04 UTC, SealabJaster 
 wrote:


 Final post of this series (also sorry for the necro, but it's 
 probably better than making a new post): 
 https://bradley.chatha.dev/BlogPost/JsonSerialiser/6-mixin-template-automate-dlang-tutorial-metaprogramming

 Pretty unhappy with its content, considering how long it's been 
 since I wanted to write it, but hopefully its main purpose (to 
 show off mixin template) is good enough.

 I'd also like to apologise here for constantly embarrassing 
 myself here (and I guess also on the Discord a year or so 
 back), I'm likely to just not post here anymore just to save 
 myself from the anxiety.

 I hope this has been of some use to someone ^^. I want to write 
 some more, but have no concrete plans for anything anytime soon.
This Series of tutorial is really nice. Please keep up the good work. Don't give up. There are those in this group that are guru no doubt but they don't write tutorials for the upcoming ones to learn. Dlang lacks great incentives for beginners. It seems it is a language design for the expert despite dlang is a easy to learn language Your tutorial is really down to earth. I really learn a lot from it.
May 07 2020
parent reply jmh530 <john.michael.hall gmail.com> writes:
On Thursday, 7 May 2020 at 14:15:07 UTC, Greatsam4sure wrote:
 


 [snip]
Yeah, I thought it looked good. I make mistakes all the time. I find that saying dumb things out loud often will help me learn and make fewer mistakes in the future.
May 07 2020
parent drug <drug2004 bk.ru> writes:
07.05.2020 18:03, jmh530 ΠΏΠΈΡˆΠ΅Ρ‚:
 I make mistakes all the time. I find that saying dumb things out loud 
 often will help me learn and make fewer mistakes in the future.
Totally agree
May 07 2020
prev sibling parent Steven Schveighoffer <schveiguy gmail.com> writes:
On 5/6/20 8:28 PM, SealabJaster wrote:
 On Wednesday, 11 December 2019 at 12:04:04 UTC, SealabJaster wrote:

 
 
 Final post of this series (also sorry for the necro, but it's probably 
 better than making a new post): 
 https://bradley.chatha.dev/BlogPost/JsonSerialiser/6-mixin-template-automate-dlang-tuto
ial-metaprogramming 
 
 
 Pretty unhappy with its content, considering how long it's been since I 
 wanted to write it, but hopefully its main purpose (to show off mixin 
 template) is good enough.
 
 I'd also like to apologise here for constantly embarrassing myself here 
 (and I guess also on the Discord a year or so back), I'm likely to just 
 not post here anymore just to save myself from the anxiety.
 
 I hope this has been of some use to someone ^^. I want to write some 
 more, but have no concrete plans for anything anytime soon.
I think you should not be embarrassed. I hope you don't feel bad based on my feedback! It was intended as helpful not as a complaint. It's always good to have more content on D and your blog posts aren't bad. I hope you continue. -Steve
May 07 2020
prev sibling parent Jacob Carlborg <doob me.com> writes:
On Tuesday, 12 November 2019 at 09:15:28 UTC, SealabJaster wrote:

 And if you do allow things such as letting classes have a 
 'deserialise' member function which can be overloaded, you 
 still need to create or be given an instance of the class 
 beforehand, which brings things back around to the "constructor 
 issue" in the latest post.

 I don't quite know if there's actually an automatic solution 
 for classes that covers most cases? Anything I can think of 
 places limitations in some form or another.
They way I handled this in Orange [1] which allows to (de)serialize third party types which you don't have any control of. First, structs have the same problem as classes: there can be private members. They way this is handled is to use `.tupleof`. `.tupleof` will bypass the protection and allows to read and write private fields: module foo; class Foo { private int a; int getA() { return a; } } module main; import std.stdio; import foo; void main() { auto foo = new Foo; foo.tupleof[0] = 3; assert(foo.getA == 3); assert(foo.tupleof[0] == 3); } `.tupleof` is used both for serialization and deserialization. To create an instance of a class use the same way as the runtime does. This function [2] is called by the compiler when the code contains "new Object" (extracted to Orange here [3]). This will not call a constructor, but that's fine since we will set the fields anyway directly after. Orange also offers a way to tweak the (de)serialization process with hooks. You can define methods in your structs or classes with any of the following UDAs: `onSerializing`, `onSerialized`, `onDeserializing` and `onDeserialized`. These method will be called (if they exist) before/after the (de)serialization process [4]. This allows you do preform some post-processing that might be needed since no constructor has been called on deserialization. When it comes to (de)serializing derived types through a base class reference Orange requires you do register all derived types [5]. Then there's the problem with non-mutable fields and instances as well. But you can just cast away those when deserializing. There's also the issue with circular references [6]. But that's pretty easy to solve by storing all serialized instances to see if they have already been serialized or not. [1] http://github.com/jacob-carlborg/orange [2] https://github.com/dlang/druntime/blob/873fac33014c5af680c4bed69bb74cb0f192198a/src/rt/lifetime.d#L73 [3] https://github.com/jacob-carlborg/orange/blob/90f1dbb0097ba4a319805bfb7d109f7038418ac6/orange/util/Reflection.d#L149-L183 [4] https://github.com/jacob-carlborg/orange/blob/master/tests/Events.d [5] https://github.com/jacob-carlborg/orange/blob/90f1dbb0097ba4a319805bfb7d109f7038418ac6/orange/serialization/Serializer.d#L241-L262 [6] https://github.com/jacob-carlborg/orange/blob/master/tests/CircularReference.d -- /Jacob Carlborg
Dec 03 2019