Re: Structural exhaustive matching
On Wednesday, 22 April 2015 at 04:54:39 UTC, Martin Nowak wrote: On Tuesday, 21 April 2015 at 15:36:28 UTC, Jadbox wrote: What's the best equivalent to Rust's structural enum/pattern (match)ing? Is it also possible to enforce exhaustive matches? Basically, I'm curious on what the best way to do ADTs in D. If it needs to be really fast, use final switch on the tag of a discriminated union. enum Tag { A, B, C } struct Val { Tag tag; union { A a; B b; C c; } } void too(Val val) { final switch (val.tag) { case Tag.A: writeln(val.a); break; case Tag.B: writeln(val.b); break; case Tag.C: writeln(val.c); break; } } there's no reason this should be faster than Algebraic(restricted variant) from std.variant, is there? implementation issue?
Re: extern(C++) linker errors
bitwise writes: > I am trying to interface to C++, and getting linker errors. Below are > my 3 source files and 2 build scripts with their associated > errors. Can anyone see what I'm doing wrong? Hi, I think both examples need libstdc++ added when you link (-L-lstdc++). That should resolve the missing C++ operators. For script1.sh with ldc2 I see an extra underscore in C++ mangled names. You must be on OS X. ldc was just fixed in merge-2.067 branch to remove an extra underscore on OS X. If you want to experiment, you can build https://github.com/ldc-developers/ldc/tree/merge-2.067 and check it out. There are still a few tests to reolve, but it works pretty well for me. -- Dan
Re: Structural exhaustive matching
On Tuesday, 21 April 2015 at 15:36:28 UTC, Jadbox wrote: What's the best equivalent to Rust's structural enum/pattern (match)ing? Is it also possible to enforce exhaustive matches? Basically, I'm curious on what the best way to do ADTs in D. If it needs to be really fast, use final switch on the tag of a discriminated union. enum Tag { A, B, C } struct Val { Tag tag; union { A a; B b; C c; } } void too(Val val) { final switch (val.tag) { case Tag.A: writeln(val.a); break; case Tag.B: writeln(val.b); break; case Tag.C: writeln(val.c); break; } }
extern(C++) linker errors
Hello! I am trying to interface to C++, and getting linker errors. Below are my 3 source files and 2 build scripts with their associated errors. Can anyone see what I'm doing wrong? / test.cpp #include class Test { public: virtual void Foo(){ printf("Foobar\n"); } }; Test* CreateTest() { return new Test; } void DestroyTest(Test *test) { delete test; } / Test.d module TestMod; extern(C++) { interface Test { void Foo(); } Test CreateTest(); void DestroyTest(Test test); } / main.d module main; import TestMod; void main(string[] args) { Test test = CreateTest(); test.Foo(); DestroyTest(test); test = null; } / script1.sh clang++ test.cpp -olibTest.o -c -emit-llvm ar rcs libTest.a libTest.o ldc2 main.d Test.d libTest.a -ofTest Error: Undefined symbols for architecture x86_64: "___Z10CreateTestv", referenced from: __Dmain in main.o "___Z11DestroyTestP4Test", referenced from: __Dmain in main.o ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation) Error: /usr/bin/gcc failed with status: 1 / script2.sh g++ test.cpp -olibTest.o -c ar rcs libTest.a libTest.o dmd main.d Test.d libTest.a -ofTest Error: Undefined symbols for architecture x86_64: "vtable for __cxxabiv1::__class_type_info", referenced from: typeinfo for Test in libTest.a(libTest.o) NOTE: a missing vtable usually means the first non-inline virtual member function has no definition. "operator delete(void*)", referenced from: DestroyTest(Test*) in libTest.a(libTest.o) "operator new(unsigned long)", referenced from: CreateTest() in libTest.a(libTest.o) ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation) --- errorlevel 1
Re: Observing exceptions in a destructor
Oh well :(. Yeah, it's just for debugging. I want to publish a script that automatically gathers relevant debug information so that my users can just copy paste it all into one place, ready for me to take a look even if I can't repro. One of the primitives in my script is a wrapper around std.process that caches the result, and I wanted to make it so that if the program throws an exception while one of the CacheResult objects is in scope, it dumps its contents out to a pastebin and logs the URL. I ended up manually adding some scope (failure)s at the call sites and putting the relevant code in a member function... but it would have been nice to not need to duplicate the scope (failure)s and have it simply live in the destructor.
Re: Observing exceptions in a destructor
On Wednesday, April 22, 2015 01:02:15 Mark Isaacson via Digitalmars-d-learn wrote: > I'd like to be able to know if my destructor is being called > because an exception was thrown. Any way to do that? > > I tried this: http://ideone.com/JbXH2w > > (Pasted here for convenience): > > import std.stdio, std.exception; > > struct Catcher { > ~this() { > try {} catch (Exception e) { > writeln("W!"); > throw e; > } > scope (failure) { > writeln("W w!"); > } > writeln("Destructing..."); > } > } > > void main() { > scope (failure) writeln("Sensible"); > scope (exit) writeln("Always written"); > Catcher c1; > scope auto c2 = Catcher(); > throw new Exception("Foobar"); > } > > Which does not print the "Wooo" lines, but does print all the > others. The exception isn't being thrown in the destructor, so there's no exception to catch. It's more like catch(Exception e) { call_destructor_on_c1(); throw e; } AFAIK, there is no way to detect whether a destructor is being called because of an exception being thrown. Why would you need to know anyway? Just for debugging purposes? I can't think of any case where it would matter. - Jonathan M Davis
Re: Observing exceptions in a destructor
On Wed, 22 Apr 2015 01:02:15 +, Mark Isaacson wrote: > I'd like to be able to know if my destructor is being called because an > exception was thrown. Any way to do that? sorry, you can't. signature.asc Description: PGP signature
Observing exceptions in a destructor
I'd like to be able to know if my destructor is being called because an exception was thrown. Any way to do that? I tried this: http://ideone.com/JbXH2w (Pasted here for convenience): import std.stdio, std.exception; struct Catcher { ~this() { try {} catch (Exception e) { writeln("W!"); throw e; } scope (failure) { writeln("W w!"); } writeln("Destructing..."); } } void main() { scope (failure) writeln("Sensible"); scope (exit) writeln("Always written"); Catcher c1; scope auto c2 = Catcher(); throw new Exception("Foobar"); } Which does not print the "Wooo" lines, but does print all the others.
Re: how does isInputRange(T) actually work?
On 04/21/2015 12:06 PM, kevin wrote: enum bool isInputRange = is(typeof( (inout int = 0) { R r = R.init; // can define a range object if (r.empty) {} // can test for empty r.popFront(); // can invoke popFront() auto h = r.front; // can get the front of the range })); ... is the current implementation in Phobos. But I can't seem to understand this syntax. What is (inout int = 0)? Why can a block follow it? My guess is that this is declaring some sort of function and testing if it is syntactically valid, but this is still strange to me. I try to explain that syntax here: http://ddili.org/ders/d.en/templates_more.html#ix_templates_more.named%20template%20constraint Ali
Re: CT-String as a Symbol
On Tuesday, 21 April 2015 at 20:30:00 UTC, Vlad Levenfeld wrote: Should work for any case I can think of (assuming integral indices). Thanks.
Re: CT-String as a Symbol
template dimensionality (S) { template count_dim (uint i = 0) { static if (is (typeof(S.init.opSlice!i (0,0 enum count_dim = count_dim!(i+1); else static if (i == 0 && (isInputRange!S || is (typeof(S.init[0]))) enum count_dim = 1; else enum count_dim = i; } alias dimensionality = count_dim!(); } Should work for any case I can think of (assuming integral indices).
Re: CT-String as a Symbol
On Tuesday, 21 April 2015 at 19:46:03 UTC, Nordlöw wrote: On Tuesday, 21 April 2015 at 07:46:03 UTC, Vlad Levenfeld wrote: Then you throw in some more stuff to detect 1-dimensional cases. Could you please elaborate a bit? Well assuming the type is not multidimensional (does not define opSlice!i) then testing for input range primitives or opIndex(0) is probably enough to conclude that a type is 1d.
Re: CT-String as a Symbol
On Tuesday, 21 April 2015 at 07:46:03 UTC, Vlad Levenfeld wrote: Then you throw in some more stuff to detect 1-dimensional cases. Could you please elaborate a bit?
Re: how does isInputRange(T) actually work?
On Tuesday, 21 April 2015 at 19:17:56 UTC, kevin wrote: On Tuesday, 21 April 2015 at 19:13:34 UTC, Meta wrote: On Tuesday, 21 April 2015 at 19:11:43 UTC, John Colvin wrote: On Tuesday, 21 April 2015 at 19:06:39 UTC, kevin wrote: enum bool isInputRange = is(typeof( (inout int = 0) { R r = R.init; // can define a range object if (r.empty) {} // can test for empty r.popFront(); // can invoke popFront() auto h = r.front; // can get the front of the range })); [...] Don't lambdas need a => token? No, D has two variants of function/delegate literal or lambda syntax: 1) with "=>": parameters => expression Some examples: (int a) => a + 2 a => a + 2 (a, b) => a + b () => 2 2) with braces: (parameters) {statements} Same examples as above: (int a) {return a + 2;} (a) {return a + 2;} (a, b) {return a + b;} {return 2;} As you can see, a lot is optional there. In the spec: http://dlang.org/expression.html#FunctionLiteral Also, what is the purpose of typeof? I would have expected a simple is() to work just fine. (In this most simple form,) `is` evaluates to true if the argument is a valid type. A function/delegate literal isn't a type. If you passed the lambda expression itself to `is`, the result would always be false. As it is, the result is true when the lambda expression compiles (so it has a valid type). More about the IsExpression: http://dlang.org/expression.html#IsExpression
Re: how does isInputRange(T) actually work?
On 4/21/15 3:11 PM, John Colvin wrote: On Tuesday, 21 April 2015 at 19:06:39 UTC, kevin wrote: enum bool isInputRange = is(typeof( (inout int = 0) { R r = R.init; // can define a range object if (r.empty) {} // can test for empty r.popFront(); // can invoke popFront() auto h = r.front; // can get the front of the range })); ... is the current implementation in Phobos. But I can't seem to understand this syntax. What is (inout int = 0)? Why can a block follow it? My guess is that this is declaring some sort of function and testing if it is syntactically valid, but this is still strange to me. It's defining a lambda function and checking that it is *semantically* valid. No idea what the `(inout int = 0)` is there for, I would have thought it would be fine without it. inout has a rule that you can't declare a type of inout as a local variable unless there is an inout parameter/return. I'm not sure if this rule still exists (it causes weird shit like the above to be required). I know some inout rules that I devised have been relaxed for the benefit of generic function sanity. The inout int = 0 gives the lambda an inout parameter, in case you are doing isInputRange!(inout(int)[]), then you can validly declare a range of type R inside your function. Alternatively, you could have the lambda take an R as a parameter. Or fix the semantics so that inout local variable acts like immutable inside a non-inout function. -Steve
Re: how does isInputRange(T) actually work?
On Tuesday, 21 April 2015 at 19:13:34 UTC, Meta wrote: On Tuesday, 21 April 2015 at 19:11:43 UTC, John Colvin wrote: On Tuesday, 21 April 2015 at 19:06:39 UTC, kevin wrote: enum bool isInputRange = is(typeof( (inout int = 0) { R r = R.init; // can define a range object if (r.empty) {} // can test for empty r.popFront(); // can invoke popFront() auto h = r.front; // can get the front of the range })); ... is the current implementation in Phobos. But I can't seem to understand this syntax. What is (inout int = 0)? Why can a block follow it? My guess is that this is declaring some sort of function and testing if it is syntactically valid, but this is still strange to me. It's defining a lambda function and checking that it is *semantically* valid. No idea what the `(inout int = 0)` is there for, I would have thought it would be fine without it. `inout int = 0` is just `inout int n = 0` without the variable name, which is just `inout int n` with a default argument of 0. Thanks for your responses. Don't lambdas need a => token? Also, what is the purpose of typeof? I would have expected a simple is() to work just fine.
Re: how does isInputRange(T) actually work?
On Tuesday, 21 April 2015 at 19:11:43 UTC, John Colvin wrote: On Tuesday, 21 April 2015 at 19:06:39 UTC, kevin wrote: enum bool isInputRange = is(typeof( (inout int = 0) { R r = R.init; // can define a range object if (r.empty) {} // can test for empty r.popFront(); // can invoke popFront() auto h = r.front; // can get the front of the range })); ... is the current implementation in Phobos. But I can't seem to understand this syntax. What is (inout int = 0)? Why can a block follow it? My guess is that this is declaring some sort of function and testing if it is syntactically valid, but this is still strange to me. It's defining a lambda function and checking that it is *semantically* valid. No idea what the `(inout int = 0)` is there for, I would have thought it would be fine without it. `inout int = 0` is just `inout int n = 0` without the variable name, which is just `inout int n` with a default argument of 0.
Re: how does isInputRange(T) actually work?
On Tuesday, 21 April 2015 at 19:06:39 UTC, kevin wrote: enum bool isInputRange = is(typeof( (inout int = 0) { R r = R.init; // can define a range object if (r.empty) {} // can test for empty r.popFront(); // can invoke popFront() auto h = r.front; // can get the front of the range })); ... is the current implementation in Phobos. But I can't seem to understand this syntax. What is (inout int = 0)? Why can a block follow it? My guess is that this is declaring some sort of function and testing if it is syntactically valid, but this is still strange to me. It's defining a lambda function and checking that it is *semantically* valid. No idea what the `(inout int = 0)` is there for, I would have thought it would be fine without it.
how does isInputRange(T) actually work?
enum bool isInputRange = is(typeof( (inout int = 0) { R r = R.init; // can define a range object if (r.empty) {} // can test for empty r.popFront(); // can invoke popFront() auto h = r.front; // can get the front of the range })); ... is the current implementation in Phobos. But I can't seem to understand this syntax. What is (inout int = 0)? Why can a block follow it? My guess is that this is declaring some sort of function and testing if it is syntactically valid, but this is still strange to me.
Re: Structural exhaustive matching
On 2015-04-21 17:36, Jadbox wrote: What's the best equivalent to Rust's structural enum/pattern (match)ing? Is it also possible to enforce exhaustive matches? Basically, I'm curious on what the best way to do ADTs in D. There's something call "castSwitch" [1], perhaps not what you're looking for. [1] http://dlang.org/phobos/std_algorithm_comparison.html#.castSwitch -- /Jacob Carlborg
Re: User defined properties signatures
This isn't about type system per se but about preferred style of syntax. Original example that caused my hatred looked like this: `let i : uint = from_str("42")`. Fortunately this has been deprecated in favor of `parse` but same principle applies - Rust authors encourage you to use declaration for type deduction instead of expression. Same thing can be rewritten as `let i = from_str::("42")` without compromising any type strictness Rust is proud of. In this form RHS expression has clear unambiguous type and can be copied anywhere. But this is discouraged form. More than that, when I was pointing out ugly template syntax, I got some comments that it is OK exactly because you are always supposed to put type on LHS. This is purely matter of style decisions and it sucks hard.
Re: User defined properties signatures
On Tuesday, 21 April 2015 at 13:53:15 UTC, Dicebot wrote: On Tuesday, 21 April 2015 at 13:27:48 UTC, Marc Schütz wrote: On Monday, 20 April 2015 at 20:22:40 UTC, Jonathan M Davis wrote: There may be languages out there which take the the return type into account when overloading, but I've never seen one. Rust does, as far as I know. And this is incredibly frustrating approach that harms both readability and maintainability (you can't cut/paste RHS of an expression anymore without additional changes to the context). I have actually mentioned that when doing "first impressions" post about Rust. Considering ownership and all the compile-time checks Rust does, I'd say you generally can't just cut/paste any part of an expression, or even whole statements, and expect it to just work. Also, in Rust's case this doesn't really count as overloading but as a template instantiation. BTW, the scope of this feature is much wider. Take a look at the channels example from the online book: http://doc.rust-lang.org/1.0.0-beta.2/book/concurrency.html#channels. Rust's type system is super strict, but mpsc::channel() doesn't specify the type of the stuff sent into the channel, and yet it is set correctly for both tx and rx. What's happening here is this: 1) tx.send receives an argument(or doesn't receive an argument), which lets the compiler know what the type of tx is. 2) Now that the compiler knows what the type of tx is, it knows what the type of mpsc::channel is, because it needs to match tx. 3) At this point, type inferring rx's type is straightforward. Now, Rust can do this because it has a super-strict type system. For D to be able to do this, it would have to completely reinvent it's type system, discarding many of it's idioms along the way, resulting at quite a different language.
Re: Structural exhaustive matching
On Tuesday, 21 April 2015 at 15:36:28 UTC, Jadbox wrote: What's the best equivalent to Rust's structural enum/pattern (match)ing? Is it also possible to enforce exhaustive matches? Basically, I'm curious on what the best way to do ADTs in D. D's ADTs are in std.variant, the equivalent of matching is the .visit property AFAIK
Re: Structural exhaustive matching
On Tue, 21 Apr 2015 15:36:27 +, Jadbox wrote: > What's the best equivalent to Rust's structural enum/pattern (match)ing? > Is it also possible to enforce exhaustive matches? > Basically, I'm curious on what the best way to do ADTs in D. std.variant.Algebraic implements ADTs: import std.variant, std.string; struct Foo { ... } alias A = Algebraic!(int, double, Foo); A a = 1; // std.variant.visit enforces that all possible types are handled, so this // is an error: auto res = a.visit!( (int x) => format("Got an int: %s", x), (double x) => format("Got a double: %s", x), (Foo x) => "Got a Foo" ); You can also dispatch to a function with the appropriate overloads/ template instantiations like so: foreach (T; A.AllowedTypes) if (a.type is typeid(T)) myfunc(a.get!T); This also exhaustively guarantees that myfunc can be called with all possible types of a.
Re: Structural exhaustive matching
Jadbox: I'm curious on what the best way to do ADTs in D. Sometimes there's no best way, there are several alternative ways with different tradeoffs. D isn't a functional language and there's no really good way to do ADTs in D. You can use plus a "final switch". Or you can use Algebraic from Phobos. Sometimes you can use another Phobos function that simulates an improved switch. Or often you can just give up at using ADTs in D and use what other solutions D offers you (like OOP). Bye, bearophile
Structural exhaustive matching
What's the best equivalent to Rust's structural enum/pattern (match)ing? Is it also possible to enforce exhaustive matches? Basically, I'm curious on what the best way to do ADTs in D.
Re: User defined properties signatures
On Tuesday, 21 April 2015 at 13:27:48 UTC, Marc Schütz wrote: On Monday, 20 April 2015 at 20:22:40 UTC, Jonathan M Davis wrote: There may be languages out there which take the the return type into account when overloading, but I've never seen one. Rust does, as far as I know. And this is incredibly frustrating approach that harms both readability and maintainability (you can't cut/paste RHS of an expression anymore without additional changes to the context). I have actually mentioned that when doing "first impressions" post about Rust.
Re: Reuse object memory?
On Monday, 20 April 2015 at 21:36:35 UTC, Ali Çehreli wrote: final class Foo { uint id; @nogc this(uint id) { this.id = id; } } C reuse(C, T...)(ref C old, T ctorParams) { import std.conv; import std.typetuple; enum objectSize = __traits(classInstanceSize, C); void* oldPlace = cast(void*)old; It's probably better to call the destructor here before calling emplace, to complete the lifecycle of the old object. C newObject = emplace!C(oldPlace[0..objectSize], ctorParams); old = null; return newObject; } void main() { Foo f = new Foo(42); auto f2 = f.reuse(43); assert(f is null); assert(f2.id == 43); } Ali
Re: User defined properties signatures
On Monday, 20 April 2015 at 20:22:40 UTC, Jonathan M Davis wrote: There may be languages out there which take the the return type into account when overloading, but I've never seen one. Rust does, as far as I know. I don't think that the ambiguities are an insurmountable obstacle. It's probably sufficient to error out when a call is ambiguous in its context, as can already happen during overloading. Also note that, as Ali pointed out, with multiple alias this we will be able to implement this indirectly. Which means that the compiler needs to deal with exactly the same ambiguities anyway. Might as well just take the return type into consideration directly.
Re: multiSort for sorting AA by value
Maybe something like bearophile's example should go into the documentation of std.algorithm.sorting.multiSort. It's a common enough thing in programming.
Re: multiSort for sorting AA by value
On Tuesday, 21 April 2015 at 11:46:24 UTC, bearophile wrote: Chris: I'm happy with it, but maybe there is a more concise implementation? This is a bit shorter and a bit better (writefln is not yet able to format tuples nicely): void main() { import std.stdio: writeln; import std.algorithm.sorting: multiSort; import std.array: array; const size_t[string] wCount = [ "hamster": 5, "zorro": 80, "troll": 90, "algorithm": 80, "beer": 80 ]; auto pairs = wCount.byKeyValue.array; assert(wCount.length == pairs.length); pairs.multiSort!(q{a.value > b.value}, q{a.key < b.key}); assert(pairs[2].key == "beer"); foreach (const ref it; pairs) writeln(it.key, ": ", it.value); } Bye, bearophile Nice!
Re: multiSort for sorting AA by value
Chris: I'm happy with it, but maybe there is a more concise implementation? This is a bit shorter and a bit better (writefln is not yet able to format tuples nicely): void main() { import std.stdio: writeln; import std.algorithm.sorting: multiSort; import std.array: array; const size_t[string] wCount = [ "hamster": 5, "zorro": 80, "troll": 90, "algorithm": 80, "beer": 80 ]; auto pairs = wCount.byKeyValue.array; assert(wCount.length == pairs.length); pairs.multiSort!(q{a.value > b.value}, q{a.key < b.key}); assert(pairs[2].key == "beer"); foreach (const ref it; pairs) writeln(it.key, ": ", it.value); } Bye, bearophile
Re: std.datetime.parseRFC822DateTime
On Tuesday, 21 April 2015 at 10:28:32 UTC, Jonathan M Davis wrote: On Tuesday, April 21, 2015 08:14:10 Jakob Ovrum via Digitalmars-d-learn wrote: std.datetime contains parseRFC822DateTime to convert from an RFC822/RFC5322 formatted string (ala "Sat, 6 Jan 1990 12:14:19 -0800") to a SysTime. Does it contain anything for the converse - converting from a SysTime to "Sat, 6 Jan 1990 12:14:19 -0800"? If not, should it? No, it does not contain the reverse. It was added specifically for the installer. If it weren't for that, std.datetime wouldn't support it at all. It's a horrible format that should just die. The only reason to use it is because the e-mail spec (and thus specs like HTTP) unfortunately uses it. However, anyone that's going to need to generate the format for anything like that is going to need a lot more than that that Phobos doesn't provide anyway, so I really don't think that it's much of a loss. Regardless, I'm strongly of the opinion that anything dealing with that format should be restricted to a library for e-mail or HTTP, and if it weren't for the fact that the installer needed to be able to read it (I forget why), I would have argued strongly against adding parseRFC822DateTime to Phobos. - Jonathan M Davis I needed it for the If-Modified-Since HTTP header, through std.net.curl.HTTP.addRequestHeader. Phobos has HTTP support and this is the preferred date format according to spec. Phobos should support it.
std.net.curl.get failing to resolve google.com
test.d --- void main() { import std.net.curl; import std.stdio; writeln(get("http://google.com";)); } --- rdmd -g test.d --- std.net.curl.CurlException@std\net\curl.d(3691): couldn't resolve host name on handle 26B4878 0x0040572A in pure @safe void std.exception.bailOut!(std.net.curl.CurlException).bailOut(immutable(char)[], uint, const(char[])) at d:\Programming\D\dmd.2.067.0.windows\dmd2\windows\bin\..\..\src\phobos\std\exception.d(400) 0x004056D2 in pure @safe bool std.exception.enforce!(std.net.curl.CurlException, bool).enforce(bool, lazy const(char)[], immutable(char)[], uint) at d:\Programming\D\dmd.2.067.0.windows\dmd2\windows\bin\..\..\src\phobos\std\exception.d(352) 0x00431356 in void std.net.curl.Curl._check(int) 0x004064F6 in char[] std.net.curl.get!(std.net.curl.HTTP, char).get(const(char)[], std.net.curl.HTTP) at d:\Programming\D\dmd.2.067.0.windows\dmd2\windows\bin\..\..\src\phobos\std\net\curl.d(405) 0x004020A4 in char[] std.net.curl.get!(std.net.curl.AutoProtocol, char).get(const(char)[], std.net.curl.AutoProtocol) at d:\Programming\D\dmd.2.067.0.windows\dmd2\windows\bin\..\..\src\phobos\std\net\curl.d(419) 0x0040202A in _Dmain 0x00423C0A in D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ6runAllMFZ9__lambda1MFZv 0x00423BDF in void rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).runAll() 0x00423AF7 in _d_run_main 0x004237A0 in main 0x0046E025 in mainCRTStartup 0x76D0338A in BaseThreadInitThunk 0x77269F72 in RtlInitializeExceptionChain 0x77269F45 in RtlInitializeExceptionChain --- Using DMD32 D Compiler v2.067.0 (release version) on Windows. google.com resolves fine when using ping or a browser, so what could be causing this? It happens with every other host name I've tried, too.
multiSort for sorting AA by value
The following works great. It sorts an AA by value: 1. by frequency of word 2. by alphabetic order (if two or more words have the same value) import std.stdio : writefln; import std.algorithm.sorting : multiSort; void main() { size_t[string] wcount = [ "hamster":5, "zorro":80, "troll":90, "algorithm":80, "beer":80 ]; struct Word { string word; size_t count; } Word[] sorter; foreach (ref k, ref v; wcount) sorter ~= Word(k, v); assert(wcount.length == sorter.length); sorter.multiSort!("a.count > b.count", "a.word < b.word"); assert(sorter[2].word == "beer"); foreach (ref it; sorter) writefln("%s : %d", it.word, it.count); } I'm happy with it, but maybe there is a more concise implementation?
Re: std.datetime.parseRFC822DateTime
On Tuesday, April 21, 2015 08:14:10 Jakob Ovrum via Digitalmars-d-learn wrote: > std.datetime contains parseRFC822DateTime to convert from an > RFC822/RFC5322 formatted string (ala "Sat, 6 Jan 1990 12:14:19 > -0800") to a SysTime. > > Does it contain anything for the converse - converting from a > SysTime to "Sat, 6 Jan 1990 12:14:19 -0800"? > > If not, should it? No, it does not contain the reverse. It was added specifically for the installer. If it weren't for that, std.datetime wouldn't support it at all. It's a horrible format that should just die. The only reason to use it is because the e-mail spec (and thus specs like HTTP) unfortunately uses it. However, anyone that's going to need to generate the format for anything like that is going to need a lot more than that that Phobos doesn't provide anyway, so I really don't think that it's much of a loss. Regardless, I'm strongly of the opinion that anything dealing with that format should be restricted to a library for e-mail or HTTP, and if it weren't for the fact that the installer needed to be able to read it (I forget why), I would have argued strongly against adding parseRFC822DateTime to Phobos. - Jonathan M Davis
Re: CT-String as a Symbol
As an aside, I've put a bit of work into the generic multidimensional containers problem lately and have an interface generating library as a result. https://github.com/evenex/autodata It's still in the nascent stages but contains a lot of tools for working with multidimensional structures. You can take a look at the definition in the spaces/ and topology/ folder (and the unittests in operators/) to get an idea of how it works - basically generates all the opIndex/opSlice stuff (with safety checks) under a unified system; end result being that you just write the business logic for your types, mixin the operators, and they will all interoperate with uniform semantics. The definitions for the types themselves tend to be very short and to-the-point as a result. I've taken old containers of mine whose defs were pushing 300 lines and reimplemented them in ~50 using the autodata operators. A full set of traits and multidim range compositions (map, zip, take, cycle, repeat) are present as well. A lot of them are full or partial reimplementations of Phobos stuff. It's pretty poorly documented (for now) but I'm happy to answer questions (and make documentation based on that) if you decide to check it out.
Re: CT-String as a Symbol
On Tuesday, 21 April 2015 at 08:09:38 UTC, Per Nordlöw wrote: On Tuesday, 21 April 2015 at 07:46:03 UTC, Vlad Levenfeld wrote: template dimensionality (S) { template count_dim (uint i = 0) { static if (is (typeof(S.init.opSlice!i (0,0 enum count_dim = count_dim!(i+1); else enum count_dim = i; } alias dimensionality = count_dim!(); } Then you throw in some more stuff to detect 1-dimensional cases. Great! I guess a template restriction on opSlice would be in Place aswell. One thing: Why aren't you using opIndex instead? If there are types that have opIndex but not opSlice defined then dimensionality() could cover more types, right? So, if the type is multidimensional, that means its using the new opIndex/opSlice syntax that was designed for multidimensional structures. So I know that, if dim > 1, opSlice!i must be defined, and (assuming we are only working with integral indices here) I can instantiate it with opSlice!i (0,0). For other types, you would throw in a test for a length member, or for front, and know that you have a 1-dimensional type. Alternatively, if we're assuming only integral indices, a recursive attempt to get the typeof(opIndex (Repeat!(i, 0))) would probably handle all the opIndex-but-not-opSlice cases (but you still need to handle non-indexed ranges and D arrays specially).
std.datetime.parseRFC822DateTime
std.datetime contains parseRFC822DateTime to convert from an RFC822/RFC5322 formatted string (ala "Sat, 6 Jan 1990 12:14:19 -0800") to a SysTime. Does it contain anything for the converse - converting from a SysTime to "Sat, 6 Jan 1990 12:14:19 -0800"? If not, should it?
Re: CT-String as a Symbol
On Tuesday, 21 April 2015 at 07:46:03 UTC, Vlad Levenfeld wrote: template dimensionality (S) { template count_dim (uint i = 0) { static if (is (typeof(S.init.opSlice!i (0,0 enum count_dim = count_dim!(i+1); else enum count_dim = i; } alias dimensionality = count_dim!(); } Then you throw in some more stuff to detect 1-dimensional cases. Great! I guess a template restriction on opSlice would be in Place aswell. One thing: Why aren't you using opIndex instead? If there are types that have opIndex but not opSlice defined then dimensionality() could cover more types, right?
Re: CT-String as a Symbol
On Tuesday, 21 April 2015 at 07:01:27 UTC, Per Nordlöw wrote: On Tuesday, 21 April 2015 at 06:56:33 UTC, Per Nordlöw wrote: On Monday, 20 April 2015 at 13:49:41 UTC, John Colvin wrote: On Thursday, 16 April 2015 at 18:12:35 UTC, Nordlöw wrote: Is there a way to CT-query the arity of all opIndex and opSlice overloads? Further, this is slightly related to a way to query the dimensions of a data-type. If possible I would like to have a type trait for this. This type-trait could then be used both for this challenge but also for figuring out how to create randomized instances of multi-dimensional structures. This can be used for automatic generation of data instances of parameters in algorithm testing and benchmarking. template dimensionality (S) { template count_dim (uint i = 0) { static if (is (typeof(S.init.opSlice!i (0,0 enum count_dim = count_dim!(i+1); else enum count_dim = i; } alias dimensionality = count_dim!(); } Then you throw in some more stuff to detect 1-dimensional cases.
Re: CT-String as a Symbol
On Tuesday, 21 April 2015 at 06:56:33 UTC, Per Nordlöw wrote: On Monday, 20 April 2015 at 13:49:41 UTC, John Colvin wrote: On Thursday, 16 April 2015 at 18:12:35 UTC, Nordlöw wrote: Is there a way to CT-query the arity of all opIndex and opSlice overloads? Further, this is slightly related to a way to query the dimensions of a data-type. If possible I would like to have a type trait for this. This type-trait could then be used both for this challenge but also for figuring out how to create randomized instances of multi-dimensional structures. This can be used for automatic generation of data instances of parameters in algorithm testing and benchmarking.
Re: CT-String as a Symbol
On Monday, 20 April 2015 at 13:49:41 UTC, John Colvin wrote: On Thursday, 16 April 2015 at 18:12:35 UTC, Nordlöw wrote: Is there a way to CT-query the arity of all opIndex and opSlice overloads? Ideally you don't want to have to do that. You'd have to consider alias this and inheritance. How do you plan on overriding the behaviour of opIndex and opSlice with alias this and inheritance? We don't want to limit this classes only. Fixed-dimensional matrices (in 2D/3D graphics) is a typically example of where we want to use structs instead. Typical use case is a Matrix class having index dimension RowIndex and ColumnIndex.