Re: Python's features, which requires D
On Sunday, 24 May 2015 at 02:43:47 UTC, Idan Arye wrote: I'm a fan of lisp(Clojure being my favorite. Too bad it takes about a century just to load the runtime...), and yet I find it quite ironic that Paul Graham claims lisp to be the most powerful language right after claiming that programmers can't understand - and therefore disregard - the power of languages more powerful than the ones they use... This is not ironic, because I did neglect the power of Lisp, because not quite understand it fully :) The power of Lisp - his worst enemy. Strange Lisp syntax allows you to write powerful macros, which is unique in other languages, but many programmers do not understand Lisp syntax (and therefore may find it funny).
Re: Python's features, which requires D
On Sunday, 24 May 2015 at 11:07:19 UTC, Dennis Ritchie wrote: On Sunday, 24 May 2015 at 02:43:47 UTC, Idan Arye wrote: I'm a fan of lisp(Clojure being my favorite. Too bad it takes about a century just to load the runtime...), and yet I find it quite ironic that Paul Graham claims lisp to be the most powerful language right after claiming that programmers can't understand - and therefore disregard - the power of languages more powerful than the ones they use... This is not ironic, because I did neglect the power of Lisp, because not quite understand it fully :) The power of Lisp - his worst enemy. Strange Lisp syntax allows you to write powerful macros, which is unique in other languages, but many programmers do not understand Lisp syntax (and therefore may find it funny). This IS ironic, because Paul Graham claims lisp to be the most powerful, but if he have ever encounter a more powerful language he couldn't accept it is more powerful than lisp due to the very same Blub Paradox he describes himself.
Re: is expression with static if matches wrong type
On Saturday, 23 May 2015 at 04:40:28 UTC, tcak wrote: [snip] Yup, you need to use == to match the exact type. Btw, you can use enum templates from std.traits, to accomplish the same with less code: public void setMarker(M)( size_t markerIndex, M markerValue ) if(isScalarType!M) { //... } http://dlang.org/phobos/std_traits.html#isScalarType
Re: is expression with static if matches wrong type
On Sunday, 24 May 2015 at 14:46:52 UTC, ZombineDev wrote: [snip] Correction: not exactly the same, because isScalar also allows wchar, dchar and const and immutable versions of those 'scalar' types.
Re: Python's features, which requires D
On Sunday, 24 May 2015 at 14:15:55 UTC, Idan Arye wrote: This IS ironic, because Paul Graham claims lisp to be the most powerful, but if he have ever encounter a more powerful language he couldn't accept it is more powerful than lisp due to the very same Blub Paradox he describes himself. Probably! But, in my opinion, it has not yet appeared stronger language Lisp, so Blub Paradox is not yet threatened with Graham :)
ctfe and static arrays
I'm a bit confused by the documentation of the ctfe limitations wrt static arrays due to these seemingly conflicting statements, and the examples didn't seem to clear anything up. I was wondering if anyone has examples of clever things that might be done with static arrays and pointers using ctfe. 2.Executed expressions may not reference any global or local static variables. C-style semantics on pointer arithmetic are strictly enforced. Pointer arithmetic is permitted only on pointers which point to static or dynamic array elements.
Re: ctfe and static arrays
On Sunday, 24 May 2015 at 17:35:39 UTC, Jay Norwood wrote: I'm a bit confused by the documentation of the ctfe limitations wrt static arrays due to these seemingly conflicting statements, and the examples didn't seem to clear anything up. I was wondering if anyone has examples of clever things that might be done with static arrays and pointers using ctfe. 2.Executed expressions may not reference any global or local static variables. C-style semantics on pointer arithmetic are strictly enforced. Pointer arithmetic is permitted only on pointers which point to static or dynamic array elements. Static array has a special meaning. It does not mean static variable with an array type. Static arrays are those of the form Type[size]. That is, the size is known statically. Examples: 1) static int[5] x; -- x is a static variable with a static array type 2) static int[] x; -- static variable, dynamic array 3) int[5] x; -- non-static variable, static array 4) int[] x; -- non-static variable, dynamic array So, CTFE can't handle examples 1 and 2, because they're static variables. 3 and 4 are fine.
Re: Weird result of getsockopt
On Sunday, 24 May 2015 at 16:51:44 UTC, CodeSun wrote: Hello guys, Today, I found a weird problem when I was learning to enable SO_KEEPALIVE for a specific socket. I use setsockopt to enable keepalive firstly, and then use getsockopt to show if it is enabled correctly. My code snippet is listed below: Dlang version: import core.sys.posix.sys.socket; import core.sys.posix.netinet.in_; import std.c.stdio; void main() { int sfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); int flag = 1; size_t size; setsockopt(sfd, SOL_SOCKET, SO_KEEPALIVE, flag, cast(socklen_t)flag.sizeof); flag = 0; getsockopt(sfd, SOL_SOCKET, SO_KEEPALIVE, flag, cast(socklen_t*)size); printf(%d\n, flag); } C version: #include sys/socket.h #include arpa/inet.h #include stdio.h int main() { int sfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); int flag = 1; size_t size; setsockopt(sfd, SOL_SOCKET, SO_KEEPALIVE, flag, (socklen_t)sizeof(flag)); flag = 0; getsockopt(sfd, SOL_SOCKET, SO_KEEPALIVE, flag, (socklen_t*)size); printf(%d\n, flag); return 0; } Dlang version always prints 0, which means keepalive is not enabled, while C version can almost display 1 all the time as expected. So is there anything wrong inside the code? If not, whose behavior is correct? Could you check the return value of setsockopt? Make sure it returns 0 as an indicator of successful operation. If so, then we can think about it further.
Re: ctfe and static arrays
On Sunday, 24 May 2015 at 18:14:19 UTC, anonymous wrote: Static array has a special meaning. It does not mean static variable with an array type. Static arrays are those of the form Type[size]. That is, the size is known statically. PS: You may also see the term fixed-size array which means the same as static array but avoids the confusion with static variables.
Re: Python's features, which requires D
On Sunday, 24 May 2015 at 15:40:21 UTC, Dennis Ritchie wrote: On Sunday, 24 May 2015 at 14:15:55 UTC, Idan Arye wrote: This IS ironic, because Paul Graham claims lisp to be the most powerful, but if he have ever encounter a more powerful language he couldn't accept it is more powerful than lisp due to the very same Blub Paradox he describes himself. Probably! But, in my opinion, it has not yet appeared stronger language Lisp, so Blub Paradox is not yet threatened with Graham :) But according to the Blub Paradox, your(Or mine. Or Paul Graham's) opinion on whether or not a stronger language than Lisp has appeared can not be trusted!
Weird result of getsockopt
Hello guys, Today, I found a weird problem when I was learning to enable SO_KEEPALIVE for a specific socket. I use setsockopt to enable keepalive firstly, and then use getsockopt to show if it is enabled correctly. My code snippet is listed below: Dlang version: import core.sys.posix.sys.socket; import core.sys.posix.netinet.in_; import std.c.stdio; void main() { int sfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); int flag = 1; size_t size; setsockopt(sfd, SOL_SOCKET, SO_KEEPALIVE, flag, cast(socklen_t)flag.sizeof); flag = 0; getsockopt(sfd, SOL_SOCKET, SO_KEEPALIVE, flag, cast(socklen_t*)size); printf(%d\n, flag); } C version: #include sys/socket.h #include arpa/inet.h #include stdio.h int main() { int sfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); int flag = 1; size_t size; setsockopt(sfd, SOL_SOCKET, SO_KEEPALIVE, flag, (socklen_t)sizeof(flag)); flag = 0; getsockopt(sfd, SOL_SOCKET, SO_KEEPALIVE, flag, (socklen_t*)size); printf(%d\n, flag); return 0; } Dlang version always prints 0, which means keepalive is not enabled, while C version can almost display 1 all the time as expected. So is there anything wrong inside the code? If not, whose behavior is correct?
Re: Python's features, which requires D
On Sunday, 24 May 2015 at 15:53:24 UTC, Idan Arye wrote: But according to the Blub Paradox, your(Or mine. Or Paul Graham's) opinion on whether or not a stronger language than Lisp has appeared can not be trusted! Based on an article Graham about Blub Paradox, I can conclude that Blub Paradox programmers only acts on a certain age. It is possible that this occurs after the age of 25 years. And since I am under 25 years old, I think I can be trusted completely :) - Paul Graham: This idea is rarely followed to its conclusion, though. After a certain age, programmers rarely switch languages voluntarily. Whatever language people happen to be used to, they tend to consider just good enough. ... But I don't expect to convince anyone (over 25) to go out and learn Lisp.
Re: ctfe and static arrays
On Sunday, 24 May 2015 at 20:53:03 UTC, Jay Norwood wrote: On Sunday, 24 May 2015 at 18:14:19 UTC, anonymous wrote: [...] 1) static int[5] x; -- x is a static variable with a static array type 2) static int[] x; -- static variable, dynamic array 3) int[5] x; -- non-static variable, static array 4) int[] x; -- non-static variable, dynamic array So, CTFE can't handle examples 1 and 2, because they're static variables. 3 and 4 are fine. From your description, I would expect this to fail since I would expect it to be included in 2 above, but it builds and prints ok. import std.stdio; struct A { int me; int next; int prev;} A[] initA(int n) { if (!__ctfe){ assert(false); } A[] v = new A[n]; foreach (i; 0..n){ v[i].me = i; v[i].prev = i-1; v[i].next = i+1; } return v; } int main(string[] argv) { enum int N = 100; static A[] linkedA = initA(N); I'm guessing you mean that this line would fall under case 2. Only the right hand side, i.e. initA(N), is done in CTFE here. The result is then used to initialize linkedA -- that step is not CTFE anymore. You're not referencing any static variable in initA, so everything's fine.
Re: Weird result of getsockopt
On Sunday, 24 May 2015 at 16:51:44 UTC, CodeSun wrote: Hello guys, Today, I found a weird problem when I was learning to enable SO_KEEPALIVE for a specific socket. I use setsockopt to enable keepalive firstly, and then use getsockopt to show if it is enabled correctly. My code snippet is listed below: Dlang version: import core.sys.posix.sys.socket; import core.sys.posix.netinet.in_; import std.c.stdio; void main() { int sfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); int flag = 1; size_t size; setsockopt(sfd, SOL_SOCKET, SO_KEEPALIVE, flag, cast(socklen_t)flag.sizeof); flag = 0; getsockopt(sfd, SOL_SOCKET, SO_KEEPALIVE, flag, cast(socklen_t*)size); printf(%d\n, flag); } C version: #include sys/socket.h #include arpa/inet.h #include stdio.h int main() { int sfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); int flag = 1; size_t size; setsockopt(sfd, SOL_SOCKET, SO_KEEPALIVE, flag, (socklen_t)sizeof(flag)); flag = 0; getsockopt(sfd, SOL_SOCKET, SO_KEEPALIVE, flag, (socklen_t*)size); printf(%d\n, flag); return 0; } Dlang version always prints 0, which means keepalive is not enabled, while C version can almost display 1 all the time as expected. So is there anything wrong inside the code? If not, whose behavior is correct? Cause your code is wrong: If the size of the option value is greater than option_len, the value stored in the object pointed to by the option_value argument shall be silently truncated. Otherwise, the object pointed to by the option_len argument shall be modified to indicate the actual length of the value. So because you have size set to 0 it will not work, you mast call it again and than it will probably work. In C this work because size is not initialize which mean it could be anything
Re: Weird result of getsockopt
On Sunday, 24 May 2015 at 21:13:02 UTC, Daniel Kozak wrote: On Sunday, 24 May 2015 at 21:11:34 UTC, Daniel Kozak wrote: On Sunday, 24 May 2015 at 16:51:44 UTC, CodeSun wrote: Hello guys, Today, I found a weird problem when I was learning to enable SO_KEEPALIVE for a specific socket. I use setsockopt to enable keepalive firstly, and then use getsockopt to show if it is enabled correctly. My code snippet is listed below: Dlang version: import core.sys.posix.sys.socket; import core.sys.posix.netinet.in_; import std.c.stdio; void main() { int sfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); int flag = 1; size_t size; setsockopt(sfd, SOL_SOCKET, SO_KEEPALIVE, flag, cast(socklen_t)flag.sizeof); flag = 0; getsockopt(sfd, SOL_SOCKET, SO_KEEPALIVE, flag, cast(socklen_t*)size); printf(%d\n, flag); } C version: #include sys/socket.h #include arpa/inet.h #include stdio.h int main() { int sfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); int flag = 1; size_t size; setsockopt(sfd, SOL_SOCKET, SO_KEEPALIVE, flag, (socklen_t)sizeof(flag)); flag = 0; getsockopt(sfd, SOL_SOCKET, SO_KEEPALIVE, flag, (socklen_t*)size); printf(%d\n, flag); return 0; } Dlang version always prints 0, which means keepalive is not enabled, while C version can almost display 1 all the time as expected. So is there anything wrong inside the code? If not, whose behavior is correct? Cause your code is wrong: If the size of the option value is greater than option_len, the value stored in the object pointed to by the option_value argument shall be silently truncated. Otherwise, the object pointed to by the option_len argument shall be modified to indicate the actual length of the value. So because you have size set to 0 it will not work, you mast call it again and than it will probably work. In C this work because size is not initialize which mean it could be anything *call it again with right size and than it will probably work I mean call it with something big enought, size than should be modified to real size
Re: Idiomatic way to call base method in generic code
On Sunday, 24 May 2015 at 23:32:52 UTC, ZombineDev wrote: ... Small correction for clarity: void main() { Derived d = new Derived(); d.x = 13; d.y = 15; // 1) writeln(callMethod!(Derived, Derived.toString)(d)); - Should print 15 // 2) writeln(callBaseMethod!(Derived, Derived.toString)(d)); - Should print 13 // 3) writeln(d.Base.toString()); - Prints 13 }
Re: ctfe and static arrays
On Sunday, 24 May 2015 at 18:14:19 UTC, anonymous wrote: Static array has a special meaning. It does not mean static variable with an array type. Static arrays are those of the form Type[size]. That is, the size is known statically. Examples: 1) static int[5] x; -- x is a static variable with a static array type 2) static int[] x; -- static variable, dynamic array 3) int[5] x; -- non-static variable, static array 4) int[] x; -- non-static variable, dynamic array So, CTFE can't handle examples 1 and 2, because they're static variables. 3 and 4 are fine. From your description, I would expect this to fail since I would expect it to be included in 2 above, but it builds and prints ok. import std.stdio; struct A { int me; int next; int prev;} A[] initA(int n) { if (!__ctfe){ assert(false); } A[] v = new A[n]; foreach (i; 0..n){ v[i].me = i; v[i].prev = i-1; v[i].next = i+1; } return v; } int main(string[] argv) { enum int N = 100; static A[] linkedA = initA(N); writefln(%s,linkedA); return 0; }
Idiomatic way to call base method in generic code
import std.stdio, std.conv, std.traits; class Base { int x; override string toString() const { return x.to!string; } } class Derived : Base { int y; override string toString() const { return y.to!string; } } void callMethod(T, alias Method)(const T thiz) { thiz.fun(); } void callBaseMethod(SubClass, alias Method)(const SubClass thiz) { alias FirstSuperClass = BaseClassesTuple!(SubClass)[0]; thiz.FirstSuperClass.Method(); } void main() { Derived d = new Derived(); d.y = 15; d.x = 13; // 1) callMethod!(Derived, Derived.toString)(d); // 2) callBaseMethod!(Derived, Derived.toString)(d); // 3) writeln(d.Base.toString()); } I know I can call a base implementation of a method like in 3), but I need to do it generically like in 2). Does anybody now how I can achieve this? Additionally is there a way to make 1) work without using string mixins?
Re: Weird result of getsockopt
On Sunday, 24 May 2015 at 21:11:34 UTC, Daniel Kozak wrote: On Sunday, 24 May 2015 at 16:51:44 UTC, CodeSun wrote: Hello guys, Today, I found a weird problem when I was learning to enable SO_KEEPALIVE for a specific socket. I use setsockopt to enable keepalive firstly, and then use getsockopt to show if it is enabled correctly. My code snippet is listed below: Dlang version: import core.sys.posix.sys.socket; import core.sys.posix.netinet.in_; import std.c.stdio; void main() { int sfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); int flag = 1; size_t size; setsockopt(sfd, SOL_SOCKET, SO_KEEPALIVE, flag, cast(socklen_t)flag.sizeof); flag = 0; getsockopt(sfd, SOL_SOCKET, SO_KEEPALIVE, flag, cast(socklen_t*)size); printf(%d\n, flag); } C version: #include sys/socket.h #include arpa/inet.h #include stdio.h int main() { int sfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); int flag = 1; size_t size; setsockopt(sfd, SOL_SOCKET, SO_KEEPALIVE, flag, (socklen_t)sizeof(flag)); flag = 0; getsockopt(sfd, SOL_SOCKET, SO_KEEPALIVE, flag, (socklen_t*)size); printf(%d\n, flag); return 0; } Dlang version always prints 0, which means keepalive is not enabled, while C version can almost display 1 all the time as expected. So is there anything wrong inside the code? If not, whose behavior is correct? Cause your code is wrong: If the size of the option value is greater than option_len, the value stored in the object pointed to by the option_value argument shall be silently truncated. Otherwise, the object pointed to by the option_len argument shall be modified to indicate the actual length of the value. So because you have size set to 0 it will not work, you mast call it again and than it will probably work. In C this work because size is not initialize which mean it could be anything *call it again with right size and than it will probably work
Re: Checking template parameter types of class
On Monday, May 25, 2015 03:42:22 tcak via Digitalmars-d-learn wrote: On Monday, 25 May 2015 at 03:35:22 UTC, Jonathan M Davis wrote: On Monday, May 25, 2015 03:19:29 tcak via Digitalmars-d-learn wrote: Is there any syntax for something like that: class Resource(T) if( is(T: FileResource) ){ } I tried it as above, but it is not accepted. Maybe I am following a wrong syntax. I tried class Resource(T: FileResource){ } But it is not accepted as well. What about it isn't accepted? This code compiles just fine class FileResource { } class SubFileResource : FileResource { } class Resource(T) if(is(T : FileResource)) { } void main() { Resource!SubFileResource foo; } - Jonathan M Davis Well, if I do not check the line number of error, this happens. It was giving error on the line of creating a new instance. Line 243: auto fileResourceList = new shared FileResourceList( 2 ); main.d(243): Error: class main.FileResourceList(T) if (is(T : FileResource)) is used as a type shared(FileResourceList) is not implicitly convertible to FileResource. It may be implicitly convertible to shared(FileResource), but not FileResource). Code that uses shared usually has to be written specifically for shared. Also, any time that you construct a templated type, you have to provide the template argument. IFTI (implicit function template instantiation) doesn't work with constructors. To make that work, you need a wrapper function - e.g. auto resource(T)(T t) { return new Resource!T(t); } So, I suspect that you're either running into problems, because you're using shared, and Resource's template constraint requires non-shared, and/or because you aren't explicitly instantiating Resource with a template argument. - Jonathan M Davis
Re: Checking template parameter types of class
On Monday, May 25, 2015 03:19:29 tcak via Digitalmars-d-learn wrote: Is there any syntax for something like that: class Resource(T) if( is(T: FileResource) ){ } I tried it as above, but it is not accepted. Maybe I am following a wrong syntax. I tried class Resource(T: FileResource){ } But it is not accepted as well. What about it isn't accepted? This code compiles just fine class FileResource { } class SubFileResource : FileResource { } class Resource(T) if(is(T : FileResource)) { } void main() { Resource!SubFileResource foo; } - Jonathan M Davis
Re: Checking template parameter types of class
On Monday, 25 May 2015 at 03:35:22 UTC, Jonathan M Davis wrote: On Monday, May 25, 2015 03:19:29 tcak via Digitalmars-d-learn wrote: Is there any syntax for something like that: class Resource(T) if( is(T: FileResource) ){ } I tried it as above, but it is not accepted. Maybe I am following a wrong syntax. I tried class Resource(T: FileResource){ } But it is not accepted as well. What about it isn't accepted? This code compiles just fine class FileResource { } class SubFileResource : FileResource { } class Resource(T) if(is(T : FileResource)) { } void main() { Resource!SubFileResource foo; } - Jonathan M Davis Well, if I do not check the line number of error, this happens. It was giving error on the line of creating a new instance. Line 243: auto fileResourceList = new shared FileResourceList( 2 ); main.d(243): Error: class main.FileResourceList(T) if (is(T : FileResource)) is used as a type
Re: Checking template parameter types of class
On Monday, 25 May 2015 at 04:07:06 UTC, Jonathan M Davis wrote: On Monday, May 25, 2015 03:42:22 tcak via Digitalmars-d-learn wrote: Well, if I do not check the line number of error, this happens. It was giving error on the line of creating a new instance. Line 243: auto fileResourceList = new shared FileResourceList( 2 ); main.d(243): Error: class main.FileResourceList(T) if (is(T : FileResource)) is used as a type shared(FileResourceList) is not implicitly convertible to FileResource. It may be implicitly convertible to shared(FileResource), but not FileResource). Code that uses shared usually has to be written specifically for shared. Also, any time that you construct a templated type, you have to provide the template argument. IFTI (implicit function template instantiation) doesn't work with constructors. To make that work, you need a wrapper function - e.g. auto resource(T)(T t) { return new Resource!T(t); } So, I suspect that you're either running into problems, because you're using shared, and Resource's template constraint requires non-shared, and/or because you aren't explicitly instantiating Resource with a template argument. - Jonathan M Davis Nah. Its all about giving the T value on object creation. auto fileResourceList = new shared FileResourceList!FileResource( 2 ); Then it works. The error message is not indicating directly this, though logically it is still correct.
Re: Weird result of getsockopt
On Sunday, 24 May 2015 at 21:11:34 UTC, Daniel Kozak wrote: On Sunday, 24 May 2015 at 16:51:44 UTC, CodeSun wrote: Hello guys, Today, I found a weird problem when I was learning to enable SO_KEEPALIVE for a specific socket. I use setsockopt to enable keepalive firstly, and then use getsockopt to show if it is enabled correctly. My code snippet is listed below: Dlang version: import core.sys.posix.sys.socket; import core.sys.posix.netinet.in_; import std.c.stdio; void main() { int sfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); int flag = 1; size_t size; setsockopt(sfd, SOL_SOCKET, SO_KEEPALIVE, flag, cast(socklen_t)flag.sizeof); flag = 0; getsockopt(sfd, SOL_SOCKET, SO_KEEPALIVE, flag, cast(socklen_t*)size); printf(%d\n, flag); } C version: #include sys/socket.h #include arpa/inet.h #include stdio.h int main() { int sfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); int flag = 1; size_t size; setsockopt(sfd, SOL_SOCKET, SO_KEEPALIVE, flag, (socklen_t)sizeof(flag)); flag = 0; getsockopt(sfd, SOL_SOCKET, SO_KEEPALIVE, flag, (socklen_t*)size); printf(%d\n, flag); return 0; } Dlang version always prints 0, which means keepalive is not enabled, while C version can almost display 1 all the time as expected. So is there anything wrong inside the code? If not, whose behavior is correct? Cause your code is wrong: If the size of the option value is greater than option_len, the value stored in the object pointed to by the option_value argument shall be silently truncated. Otherwise, the object pointed to by the option_len argument shall be modified to indicate the actual length of the value. So because you have size set to 0 it will not work, you mast call it again and than it will probably work. In C this work because size is not initialize which mean it could be anything You are right, thx.
Re: How to append range to array?
On 5/23/15 4:27 AM, Jonathan M Davis via Digitalmars-d-learn wrote: On Saturday, May 23, 2015 07:03:33 Vladimir Panteleev via Digitalmars-d-learn wrote: int[] arr = [1, 2, 3]; auto r = iota(4, 10); // ??? assert(equal(arr, iota(1, 10))); Hopefully in one GC allocation (assuming we know the range's length). I tried std.range.primitives.put but its behavior seems a little mysterious: This compiles but asserts at runtime: int[] arr = [1, 2, 3]; arr.put(iota(4, 10)); And this is even weirder, can you guess what it will print? int[] arr = [1, 2, 3]; arr.put(4); writeln(arr); For better or worse, put does not append to arrays. It fills them. If you want to append using put, then using std.array.Appender. Yes, think of an array as a buffer. When you put into it, you are overwriting the contents. In addition to using Appender (which BTW will add an allocation), you can extend the array and then fill the extended slice: auto oldlen = arr.length; arr.length += someRange.length; put(arr[oldlen..$], someRange); I wish there was a shorter way to do this... -Steve
Re: How to append range to array?
On Sunday, May 24, 2015 22:13:25 Steven Schveighoffer via Digitalmars-d-learn wrote: On 5/23/15 4:27 AM, Jonathan M Davis via Digitalmars-d-learn wrote: On Saturday, May 23, 2015 07:03:33 Vladimir Panteleev via Digitalmars-d-learn wrote: int[] arr = [1, 2, 3]; auto r = iota(4, 10); // ??? assert(equal(arr, iota(1, 10))); Hopefully in one GC allocation (assuming we know the range's length). I tried std.range.primitives.put but its behavior seems a little mysterious: This compiles but asserts at runtime: int[] arr = [1, 2, 3]; arr.put(iota(4, 10)); And this is even weirder, can you guess what it will print? int[] arr = [1, 2, 3]; arr.put(4); writeln(arr); For better or worse, put does not append to arrays. It fills them. If you want to append using put, then using std.array.Appender. Yes, think of an array as a buffer. When you put into it, you are overwriting the contents. In addition to using Appender (which BTW will add an allocation), you can extend the array and then fill the extended slice: auto oldlen = arr.length; arr.length += someRange.length; put(arr[oldlen..$], someRange); I wish there was a shorter way to do this... Honestly, I think that output ranges need at least a minor redesign. They haven't been used as heavily as input ranges and really aren't ironed out as well. A prime example of this is that output ranges assume that put will succeed, and there's no way to even ask how much room an output range has left or whether a call to put will succeed or not. The current state of things works reasonably well with Appender, but it's abysmal if you're dealing with arrays. - Jonathan M Davis
Checking template parameter types of class
Is there any syntax for something like that: class Resource(T) if( is(T: FileResource) ){ } I tried it as above, but it is not accepted. Maybe I am following a wrong syntax. I tried class Resource(T: FileResource){ } But it is not accepted as well.