digitalmars.D.learn - Templates for DRY code
- =?UTF-8?Q?Ali_=c3=87ehreli?= (33/33) Jan 05 2018 Nothing new here... I'm just reminded of how templates can help with DRY...
- codephantom (12/20) Jan 05 2018 The problem with this, in my opinion, is that your template
- =?UTF-8?Q?Ali_=c3=87ehreli?= (5/25) Jan 05 2018 I agree with your point as well. A better name can help there a little.
- codephantom (22/26) Jan 05 2018 Code is something that humans write and read (and read far more
- Paul Backus (4/8) Jan 06 2018 This works:
- codephantom (16/26) Jan 06 2018 I guess this brings us back to Ali's point about finding the
- Mark (3/13) Jan 08 2018 I think you can just do:
- codephantom (9/11) Jan 06 2018 void ConvertAndAppend(T, S)(ref T[] arr, S s) {
Nothing new here... I'm just reminded of how templates can help with DRY (don't repeat yourself) code. Here is a piece of code that uses an alias to be flexible on the element type: import std.conv; alias MyType = double; // <-- Nice, MyType is used twice below void main() { MyType[] a; // ... string s = "1.2"; a ~= s.to!MyType; // <-- This usage is troubling } Although to!MyType looks like a good idea there, the two usages of MyType must be kept in sync manually. Why should we repeat MyType when it's already known to be ElementType!(typeof(a)) anyway. (Unfortunately, that syntax is not very clear in code.) One solution is to wrap ~= in a function template. Now the conversion is automatically made to the element type of the array: import std.conv; void append(T, S)(ref T[] arr, S s) { arr ~= s.to!T; } void main() { double[] a; // <-- Removed MyType alias as well // ... string s = "1.2"; a.append(s); } In simple cases like this, one may not even need the alias. 'double' appears in just one place there. I think append() could be a part of std.array but I can't find anything like that in Phobos. Ali
Jan 05 2018
On Saturday, 6 January 2018 at 01:33:11 UTC, Ali Çehreli wrote:One solution is to wrap ~= in a function template. Now the conversion is automatically made to the element type of the array: ... ..... I think append() could be a part of std.array but I can't find anything like that in Phobos. AliThe problem with this, in my opinion, is that your template 'append' is doing a conversion behind the scenes..ie. I wouldn't know that 'append' actually means 'convert & then append'. When I read: double[] a; string s = "1.2"; a.append(s); I think to myself...wtf is going on here? How can you append a string to an array of doubles? That's when I'd have go and find the append template and work out what it is really doing.
Jan 05 2018
On 01/05/2018 06:14 PM, codephantom wrote:On Saturday, 6 January 2018 at 01:33:11 UTC, Ali Çehreli wrote:I agree with your point as well. A better name can help there a little. It's hard to find a balance between fully explicit and fully automatic. I find myself going back and forth between those two extremes. AliOne solution is to wrap ~= in a function template. Now the conversion is automatically made to the element type of the array: ... ..... I think append() could be a part of std.array but I can't find anything like that in Phobos. AliThe problem with this, in my opinion, is that your template 'append' is doing a conversion behind the scenes..ie. I wouldn't know that 'append' actually means 'convert & then append'. When I read: double[] a; string s = "1.2"; a.append(s); I think to myself...wtf is going on here? How can you append a string to an array of doubles? That's when I'd have go and find the append template and work out what it is really doing.
Jan 05 2018
On Saturday, 6 January 2018 at 03:08:19 UTC, Ali Çehreli wrote:It's hard to find a balance between fully explicit and fully automatic. I find myself going back and forth between those two extremes. AliCode is something that humans write and read (and read far more than write). So I prefer to optimise for mental processing ;-) By this, I mean reducing the amount of information I need to chunk, to make sense of something (whether that be writing, or reading). e.g double[] a; string s = "1.2"; a.append(s) requires me to go off and discover what append is doing, since 'append' is clearly not correctly describing what is actually going on here, in this little chunk. So, now I have to go off and discover the extra chunk I need, in order to make sense of this little chunk. Suddenly, the chunk has become a lot larger than it needed to be. so yeah, a simple rename of append would help.. or even.. a.append( s.to!ConvertToElementType(a) ); That's not valid code of course, but the semantics are all contained in that single chunk.
Jan 05 2018
On Saturday, 6 January 2018 at 03:38:35 UTC, codephantom wrote:or even.. a.append( s.to!ConvertToElementType(a) ); That's not valid code of course, but the semantics are all contained in that single chunk.This works: import std.range.primitives: ElementType; a ~= s.to!(ElementType!(typeof(a)));
Jan 06 2018
On Saturday, 6 January 2018 at 23:32:42 UTC, Paul Backus wrote:On Saturday, 6 January 2018 at 03:38:35 UTC, codephantom wrote:I guess this brings us back to Ali's point about finding the balance between being explicit and fully automatic. I certainly prefer: a.append(s); vs a ~= s.to!(ElementType!(typeof(a))); // this hurts by brain ;-) The only problem with the Ali's suggestion of using append, is we always bring background knowledge everytime we read and write code, and, we all know that you cannot append a string to an array of doubles (that is our background knowledge). I guess if we knew that you can do that now, then 'a.append(s);' would be just fine. But I'm not a big fan of 'implicit' conversions in type safe languages, even when those conversion are type safe. So there's yet another balance to get right.or even.. a.append( s.to!ConvertToElementType(a) ); That's not valid code of course, but the semantics are all contained in that single chunk.This works: import std.range.primitives: ElementType; a ~= s.to!(ElementType!(typeof(a)));
Jan 06 2018
On Saturday, 6 January 2018 at 23:32:42 UTC, Paul Backus wrote:On Saturday, 6 January 2018 at 03:38:35 UTC, codephantom wrote:I think you can just do: s.to!(typeof(a[0]));or even.. a.append( s.to!ConvertToElementType(a) ); That's not valid code of course, but the semantics are all contained in that single chunk.This works: import std.range.primitives: ElementType; a ~= s.to!(ElementType!(typeof(a)));
Jan 08 2018
On Saturday, 6 January 2018 at 03:08:19 UTC, Ali Çehreli wrote:I agree with your point as well. A better name can help there a little.void ConvertAndAppend(T, S)(ref T[] arr, S s) { arr ~= s.to!T; } problem solved ;-) btw. I never thought that I would be able (or actually..willing) to program using templates, still I found D. Thanks to those responsible for making them so easy to use (presumably Walter and Andrei).
Jan 06 2018