building a simple json tree
what's the right syntax for building a JSON tree ? I try to do like in an AA but the program throw because the Key doesn't exist: --- import std.stdio, std.json; void main(string[] args) { struct Foo{ string a, b; void writeToJson(ref JSONValue target) { target["a"] = JSONValue(a); target["b"] = JSONValue(b); } } JSONValue root = parseJSON("{}"); root["items"] = JSONValue([""]); Foo*[] foos; foos ~= new Foo("a1","b1"); foos ~= new Foo("a2","b2"); foreach(foo; foos) { root["items"].array.length += 1; root["items"].array[$-1] = parseJSON("{}"); foo.writeToJson(root["items"].array[$-1]); } } ---
Re: A naive attempt at a refcounted class proxy
On Tuesday, 13 January 2015 at 18:52:25 UTC, ketmar via Digitalmars-d-learn wrote: On Tue, 13 Jan 2015 18:36:15 + aldanor via Digitalmars-d-learn wrote: On Tuesday, 13 January 2015 at 18:19:42 UTC, ketmar via Digitalmars-d-learn wrote: > and then you can go with structures in the first place, i > think. > remember that you have that k00l `alias this` trick for them! Which doesn't always help in case of multiple inheritance :( e.g. the blasted hdf c++ class hierarchy example. multiple `alias this` may help here... to some extent. ;-) Are they even enabled in dmd already? 2.65 still reports the "there can only be one alias this" error.
Why foreach do not print value during every single Insert request in SQL?
void IMGsInsert(string [] fullimgurl) { foreach (url; fullimgurl) { string sqlinsert = (sqlrequest) writeln(sqlinsert); write("|"); auto rs = stmt.executeUpdate(sqlinsert); } } I expect nice progress indicator "|" which move forward after every Insert request. Like: and so on. The problem that App wait some time and only in prints a heap of "|". Why?
Re: A naive attempt at a refcounted class proxy
On Thu, 15 Jan 2015 11:48:23 + Francesco Cattoglio via Digitalmars-d-learn wrote: > On Tuesday, 13 January 2015 at 18:52:25 UTC, ketmar via > Digitalmars-d-learn wrote: > > On Tue, 13 Jan 2015 18:36:15 + > > aldanor via Digitalmars-d-learn > > > > wrote: > > > >> On Tuesday, 13 January 2015 at 18:19:42 UTC, ketmar via > >> Digitalmars-d-learn wrote: > >> > and then you can go with structures in the first place, i > >> > think. > >> > remember that you have that k00l `alias this` trick for them! > >> Which doesn't always help in case of multiple inheritance :( > >> e.g. > >> the blasted hdf c++ class hierarchy example. > > multiple `alias this` may help here... to some extent. ;-) > > Are they even enabled in dmd already? 2.65 still reports the > "there can only be one alias this" error. the PR is approved for inclusion, so eventually it will be in 2.067. at least i hope it will. sorry, i tend to forget that not everybody using HEAD builds with custom patches applied. ;-) signature.asc Description: PGP signature
Re: Why foreach do not print value during every single Insert request in SQL?
On 16/01/2015 1:05 a.m., Suliman wrote: void IMGsInsert(string [] fullimgurl) { foreach (url; fullimgurl) { string sqlinsert = (sqlrequest) writeln(sqlinsert); write("|"); auto rs = stmt.executeUpdate(sqlinsert); } } I expect nice progress indicator "|" which move forward after every Insert request. Like: and so on. The problem that App wait some time and only in prints a heap of "|". Why? That writeln won't be helping anything. Other then that? No idea sorry.
Re: Why foreach do not print value during every single Insert request in SQL?
On Thursday, 15 January 2015 at 12:05:24 UTC, Suliman wrote: void IMGsInsert(string [] fullimgurl) { foreach (url; fullimgurl) { string sqlinsert = (sqlrequest) writeln(sqlinsert); write("|"); auto rs = stmt.executeUpdate(sqlinsert); } } I expect nice progress indicator "|" which move forward after every Insert request. Like: and so on. The problem that App wait some time and only in prints a heap of "|". Why? Terminal output is line-buffered by default. To display an incomplete line to the user, add "stdout.flush()" after your "write" call.
Re: building a simple json tree
On 16/01/2015 12:16 a.m., anonymous wrote: what's the right syntax for building a JSON tree ? I try to do like in an AA but the program throw because the Key doesn't exist: --- import std.stdio, std.json; void main(string[] args) { struct Foo{ string a, b; void writeToJson(ref JSONValue target) { target["a"] = JSONValue(a); target["b"] = JSONValue(b); } } JSONValue root = parseJSON("{}"); root["items"] = JSONValue([""]); Foo*[] foos; foos ~= new Foo("a1","b1"); foos ~= new Foo("a2","b2"); foreach(foo; foos) { root["items"].array.length += 1; root["items"].array[$-1] = parseJSON("{}"); foo.writeToJson(root["items"].array[$-1]); } } --- import std.stdio, std.json; void main(string[] args) { struct Foo{ string a, b; void writeToJson(ref JSONValue target) { target["a"] = JSONValue(a); target["b"] = JSONValue(b); } } JSONValue root = ["items": cast(string[])[]]; Foo[] foos; foos ~= Foo("a1","b1"); foos ~= Foo("a2","b2"); foreach(foo; foos) { root["items"].array ~= JSONValue(foo.a); root["items"].array ~= JSONValue(foo.b); } writeln(root.toString()); } I would recommend keeping away from std.json. Its an old piece of code, that needs to be replaced. Vibe.d has a much nicer implementation that is really decent. I would recommend that, if you are up to using the build manager dub.
Re: redirecting the unittests error output
On 1/15/2015 4:32 AM, ref2401 wrote: Unfortunately i'm new to using shells. I use standard windows cmd. Here is my script: dmd main.d -debug -unittest -wi if %errorLevel% equ 0 ( start main.exe ) else ( echo --- Building failed! --- pause ) I wrote "start main.exe 2> errorFile" but it doesn't work. errorFile is empty. Open up a command prompt and execute dmd with a nonexistent file name. dmd foo.d 2> err.txt You will find that dmd prints an error to err.txt, specifically that it can't find foo.d. (You can find more info about stdio handles and the command line at [1]). Now execute it like this: start dmd foo.d 2> err.txt And you will find an empty err.txt. This is because you are redirecting the output of stderr from the *start* program, and not from dmd (you can read more about the start command at [2]). I'm not aware of anyway to redirect the output of a command or program executed by start.
Re: building a simple json tree
On Thursday, 15 January 2015 at 12:10:09 UTC, Rikki Cattermole wrote: On 16/01/2015 12:16 a.m., anonymous wrote: what's the right syntax for building a JSON tree ? I try to do like in an AA but the program throw because the Key doesn't exist: --- import std.stdio, std.json; void main(string[] args) { struct Foo{ string a, b; void writeToJson(ref JSONValue target) { target["a"] = JSONValue(a); target["b"] = JSONValue(b); } } JSONValue root = parseJSON("{}"); root["items"] = JSONValue([""]); Foo*[] foos; foos ~= new Foo("a1","b1"); foos ~= new Foo("a2","b2"); foreach(foo; foos) { root["items"].array.length += 1; root["items"].array[$-1] = parseJSON("{}"); foo.writeToJson(root["items"].array[$-1]); } } --- import std.stdio, std.json; void main(string[] args) { struct Foo{ string a, b; void writeToJson(ref JSONValue target) { target["a"] = JSONValue(a); target["b"] = JSONValue(b); } } JSONValue root = ["items": cast(string[])[]]; Foo[] foos; foos ~= Foo("a1","b1"); foos ~= Foo("a2","b2"); foreach(foo; foos) { root["items"].array ~= JSONValue(foo.a); root["items"].array ~= JSONValue(foo.b); } writeln(root.toString()); } I would recommend keeping away from std.json. Its an old piece of code, that needs to be replaced. Vibe.d has a much nicer implementation that is really decent. I would recommend that, if you are up to using the build manager dub. Thx, but actually I initially liked to get an array of object with each identifier: currently it produces: {"items":["a1","b1","a2","b2"]} while it'd be more desirable to have {"items":[{"a":"a1","b":"b1"}, {"a":"a2","b":"b2"}]} because the reader will test the presence of each the key "a" and "b" in each element of "items". Would it be a complete non-sense to assign an element with opIndexAssign(), just like I wrote initially ? I know this is wrong but the syntax seemed natural and logic. Reading from std.json is straightforward but writing looks a bit messy.
Re: building a simple json tree
On 16/01/2015 1:37 a.m., anonymous wrote: On Thursday, 15 January 2015 at 12:10:09 UTC, Rikki Cattermole wrote: On 16/01/2015 12:16 a.m., anonymous wrote: what's the right syntax for building a JSON tree ? I try to do like in an AA but the program throw because the Key doesn't exist: --- import std.stdio, std.json; void main(string[] args) { struct Foo{ string a, b; void writeToJson(ref JSONValue target) { target["a"] = JSONValue(a); target["b"] = JSONValue(b); } } JSONValue root = parseJSON("{}"); root["items"] = JSONValue([""]); Foo*[] foos; foos ~= new Foo("a1","b1"); foos ~= new Foo("a2","b2"); foreach(foo; foos) { root["items"].array.length += 1; root["items"].array[$-1] = parseJSON("{}"); foo.writeToJson(root["items"].array[$-1]); } } --- import std.stdio, std.json; void main(string[] args) { struct Foo{ string a, b; void writeToJson(ref JSONValue target) { target["a"] = JSONValue(a); target["b"] = JSONValue(b); } } JSONValue root = ["items": cast(string[])[]]; Foo[] foos; foos ~= Foo("a1","b1"); foos ~= Foo("a2","b2"); foreach(foo; foos) { root["items"].array ~= JSONValue(foo.a); root["items"].array ~= JSONValue(foo.b); } writeln(root.toString()); } I would recommend keeping away from std.json. Its an old piece of code, that needs to be replaced. Vibe.d has a much nicer implementation that is really decent. I would recommend that, if you are up to using the build manager dub. Thx, but actually I initially liked to get an array of object with each identifier: currently it produces: {"items":["a1","b1","a2","b2"]} while it'd be more desirable to have {"items":[{"a":"a1","b":"b1"}, {"a":"a2","b":"b2"}]} because the reader will test the presence of each the key "a" and "b" in each element of "items". Would it be a complete non-sense to assign an element with opIndexAssign(), just like I wrote initially ? I know this is wrong but the syntax seemed natural and logic. Reading from std.json is straightforward but writing looks a bit messy. It makes sense to do it. But like I said std.json is rubbish. Just so you can see why I'm saying vibe.d's json implementation is better[0]. [0] https://github.com/rejectedsoftware/vibe.d/blob/master/source/vibe/data/json.d#L1670
Re: redirecting the unittests error output
Thank you.
Re: redirecting the unittests error output
[1] http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/redirection.mspx?mfr=true [2] https://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/start.mspx?mfr=true
Re: building a simple json tree
On Thursday, 15 January 2015 at 12:50:59 UTC, Rikki Cattermole wrote: On 16/01/2015 1:37 a.m., anonymous wrote: On Thursday, 15 January 2015 at 12:10:09 UTC, Rikki Cattermole wrote: On 16/01/2015 12:16 a.m., anonymous wrote: what's the right syntax for building a JSON tree ? I try to do like in an AA but the program throw because the Key doesn't exist: --- import std.stdio, std.json; void main(string[] args) { struct Foo{ string a, b; void writeToJson(ref JSONValue target) { target["a"] = JSONValue(a); target["b"] = JSONValue(b); } } JSONValue root = parseJSON("{}"); root["items"] = JSONValue([""]); Foo*[] foos; foos ~= new Foo("a1","b1"); foos ~= new Foo("a2","b2"); foreach(foo; foos) { root["items"].array.length += 1; root["items"].array[$-1] = parseJSON("{}"); foo.writeToJson(root["items"].array[$-1]); } } --- import std.stdio, std.json; void main(string[] args) { struct Foo{ string a, b; void writeToJson(ref JSONValue target) { target["a"] = JSONValue(a); target["b"] = JSONValue(b); } } JSONValue root = ["items": cast(string[])[]]; Foo[] foos; foos ~= Foo("a1","b1"); foos ~= Foo("a2","b2"); foreach(foo; foos) { root["items"].array ~= JSONValue(foo.a); root["items"].array ~= JSONValue(foo.b); } writeln(root.toString()); } I would recommend keeping away from std.json. Its an old piece of code, that needs to be replaced. Vibe.d has a much nicer implementation that is really decent. I would recommend that, if you are up to using the build manager dub. Thx, but actually I initially liked to get an array of object with each identifier: currently it produces: {"items":["a1","b1","a2","b2"]} while it'd be more desirable to have {"items":[{"a":"a1","b":"b1"}, {"a":"a2","b":"b2"}]} because the reader will test the presence of each the key "a" and "b" in each element of "items". Would it be a complete non-sense to assign an element with opIndexAssign(), just like I wrote initially ? I know this is wrong but the syntax seemed natural and logic. Reading from std.json is straightforward but writing looks a bit messy. It makes sense to do it. But like I said std.json is rubbish. Just so you can see why I'm saying vibe.d's json implementation is better[0]. [0] https://github.com/rejectedsoftware/vibe.d/blob/master/source/vibe/data/json.d#L1670 Also, look at the new std.json candidate: http://code.dlang.org/packages/std_data_json
commonLength
I want a variant of commonPrefix(a, b) at http://dlang.org/phobos/std_algorithm.html#commonPrefix that only counts returns the length of commonPrefix(a, b) Is commonPrefix lazy enough to make commonPrefix(a, b).count as fast as zip(a, b).count!(ab => ab[0] == ab[1]) ?
Re: commonLength
On Thursday, 15 January 2015 at 13:01:50 UTC, Nordlöw wrote: I want a variant of commonPrefix(a, b) at http://dlang.org/phobos/std_algorithm.html#commonPrefix that only counts returns the length of commonPrefix(a, b) Is commonPrefix lazy enough to make commonPrefix(a, b).count as fast as zip(a, b).count!(ab => ab[0] == ab[1]) ? I just discovered that zip has StoppingPolicy so why does auto commonPrefixLength(R...)(R ranges) if (ranges.length == 2) { import std.range: zip; return zip!((a, b) => a[0] != b[1])(ranges); } unittest { assert(commonPrefixLength([1, 2, 3, 10], [1, 2, 4, 10]) == 2); } error as algorithm_ex.d(1709,40): Error: template std.range.zip cannot deduce function from argument types !((a, b) => a[0] != b[1])(int[], int[]), candidates are: std/range/package.d(3247,6): std.range.zip(Ranges...)(Ranges ranges) if (Ranges.length && allSatisfy!(isInputRange, Ranges)) std/range/package.d(3265,6): std.range.zip(Ranges...)(StoppingPolicy sp, Ranges ranges) if (Ranges.length && allSatisfy!(isInputRange, Ranges)) algorithm_ex.d(1714,30): Error: template instance algorithm_ex.commonPrefixLength!(int[], int[]) error instantiating
Re: commonLength
On Thursday, 15 January 2015 at 13:13:57 UTC, Nordlöw wrote: return zip!((a, b) => a[0] != b[1])(ranges); Update: should be return zip!((a, b) => a != b)(ranges); but still fails with same error.
Re: commonLength
I just discovered that zip has StoppingPolicy so why does auto commonPrefixLength(R...)(R ranges) if (ranges.length == 2) { import std.range: zip; return zip!((a, b) => a[0] != b[1])(ranges); } unittest { assert(commonPrefixLength([1, 2, 3, 10], [1, 2, 4, 10]) == 2); } StoppingPolicy is not a template parameter, it is this one: http://dlang.org/phobos/std_range.html#.StoppingPolicy
Re: Endless static this call when used a thread in it
On 1/13/15 8:56 AM, tcak wrote: When I defined static init with shared public shared static this() it works normal now. But it doesn't explain above issue. What's the relation between a new thread and a module's initialiser? In case it's not clear -- shared static this runs ONCE at the beginning of the program (before main() starts), static this runs for EVERY thread that starts, before the thread starts execution. The reason is that "static this" initializes thread local data. "shared static this" initializes global data (i.e. shared and __gshared). Hope this helps. -Steve
Re: vibe.d Subdirectory?
On 1/14/15 11:31 AM, Laeeth Isharc wrote: To be very clear: in the simple case when you compile your vibe application from multiple source files and diet templates etc, and you will end up with an executable. This can act as a server directly, or you can make it an internal server on localhost called by php, or you can call it from nginx as a CGI type application depending on the URL. Pardon me for asking kind of a side question, but is there any online information on how to do this? I am contemplating migrating my in-house php-based application to vibe.d, but I wondered if I have to do it whole-sale (not much gratification until the whole thing is done) or piecemeal (then some parts are php, some are vibe.d, until whole thing is ported). I thought I could do the latter, but I don't know how to interact apache/php with vibe.d. The biggest question I have is how vibe.d and php can share session data. But I also have no idea which server should be in front, and how to call one another ;) Thanks -Steve
Re: vibe.d Subdirectory?
On Thursday, 15 January 2015 at 14:38:16 UTC, Steven Schveighoffer wrote: vibe.d and php can share session data. But I also have no idea which server should be in front, and how to call one another ;) If you are going to replace php then you probably want to have the d-server in front and just relay requests to the php server? If you create your own session solution on the d-server I'd just create a mapping to php-sessions so that you can map back an forth when relaying. That way you can replace php bit-by-bit and eventually phase it out.
Shared and GC
I am trying to understand the idea behind "shared" typing fully. If I am only allowed to share objects with another thread if it is typed "shared", doesn't that imply that it should be allocated as shared too and only be allowed to contain pointers to "shared"? That would be nice, because then a precise garbage collector could choose between local collection scans and global collection scans. Is this the intended semantics for shared?
Re: vibe.d Subdirectory?
On Thursday, 15 January 2015 at 14:38:16 UTC, Steven Schveighoffer wrote: Pardon me for asking kind of a side question, but is there any online information on how to do this? I am contemplating migrating my in-house php-based application to vibe.d, but I wondered if I have to do it whole-sale (not much gratification until the whole thing is done) or piecemeal (then some parts are php, some are vibe.d, until whole thing is ported). I thought I could do the latter, but I don't know how to interact apache/php with vibe.d. The biggest question I have is how vibe.d and php can share session data. But I also have no idea which server should be in front, and how to call one another ;) Thanks -Steve Generally easiest way is to make Apache forward some of URLs to vibe.d process (acting as HTTP proxy) while keeping to serve remaining PHP scripts. The more gets implemented in vibe.d process, the more URLs can be forwarded. I am not sure about session data part though. Quite likely you will need to implement session storage as a dedicated persistent process that gets queried by both vibe.d and PHP script. But this is not my domain of knowledge.
Re: Shared and GC
On Thursday, 15 January 2015 at 15:24:55 UTC, Ola Fosheim Grøstad wrote: I am trying to understand the idea behind "shared" typing fully. If I am only allowed to share objects with another thread if it is typed "shared", doesn't that imply that it should be allocated as shared too and only be allowed to contain pointers to "shared"? Yes, shared is transitive. struct S { int* p; } void main() { S s1; shared S s2 = s1; // error, but ok if p is int. } That would be nice, because then a precise garbage collector could choose between local collection scans and global collection scans. I think something like this is part of the plan, but shared semantics are still up in the air.
Re: vibe.d Subdirectory?
If your php stores sessions in files, you can just read those files from D. Though that's horribly slow and I don't think php does that by default any more. But it really depends on how the PHP is configured to see how easy it will be. It might just be a cookie to read then index into a database, or maybe a signed cookie too... no way to tell without looking at the actual thing. But the php session formats, however they are stored, aren't terribly complex so you should be able to get into it.
Re: Shared and GC
On Thursday, 15 January 2015 at 15:31:17 UTC, Peter Alexander wrote: On Thursday, 15 January 2015 at 15:24:55 UTC, Ola Fosheim Grøstad wrote: That would be nice, because then a precise garbage collector could choose between local collection scans and global collection scans. I think something like this is part of the plan, but shared semantics are still up in the air. That sounds like a very important aspect of a plan to get fast GC without completely changing the language and non-gc performance. I've looked at bit at how to do a fast stop-the-thread GC. Estimates on what the hardware supports (bandwidth and cache performance) suggests that it is possible to get acceptable rates for not-densely-linked heaps with some tweaks to semantics: - shared-awareness in new-expressions to support local collection - removing class-destructors - locating traceable pointers to the same cachelines in class instances (negative offsets is the easy solution) Then you cn use a ache-optimized collector using batched non-caching queues with prefetching to get bitmaps that fits in 1st level cache without wrecking the cache for other threads and having collection dominated by cache misses.
Re: Shared and GC
On Thursday, 15 January 2015 at 17:05:32 UTC, Ola Fosheim Grøstad wrote: On Thursday, 15 January 2015 at 15:31:17 UTC, Peter Alexander wrote: On Thursday, 15 January 2015 at 15:24:55 UTC, Ola Fosheim Grøstad wrote: That would be nice, because then a precise garbage collector could choose between local collection scans and global collection scans. I think something like this is part of the plan, but shared semantics are still up in the air. That sounds like a very important aspect of a plan to get fast GC without completely changing the language and non-gc performance. I've looked at bit at how to do a fast stop-the-thread GC. Estimates on what the hardware supports (bandwidth and cache performance) suggests that it is possible to get acceptable rates for not-densely-linked heaps with some tweaks to semantics: - shared-awareness in new-expressions to support local collection - removing class-destructors - locating traceable pointers to the same cachelines in class instances (negative offsets is the easy solution) Then you cn use a ache-optimized collector using batched non-caching queues with prefetching to get bitmaps that fits in 1st level cache without wrecking the cache for other threads and having collection dominated by cache misses. Yah, this was all discussed at length not that long ago, although I can't find the thread just now.
Re: commonLength
On Thursday, 15 January 2015 at 13:59:04 UTC, Tobias Pankrath wrote: StoppingPolicy is not a template parameter, it is this one: http://dlang.org/phobos/std_range.html#.StoppingPolicy Ok, great! However, none of the variants of zip, including all the three policies, fulfills my needs in assert(commonPrefixLength([1, 2, 3, 10], [1, 2, 3]), 3); which fails because commonPrefixLength([1, 2, 3, 10], [1, 2, 3]) evaluates to -1. This seems like a serious limitation that should be realized in yet another policy.
Re: commonLength
On Thursday, 15 January 2015 at 18:16:36 UTC, Nordlöw wrote: On Thursday, 15 January 2015 at 13:59:04 UTC, Tobias Pankrath wrote: StoppingPolicy is not a template parameter, it is this one: http://dlang.org/phobos/std_range.html#.StoppingPolicy Ok, great! However, none of the variants of zip, including all the three policies, fulfills my needs in assert(commonPrefixLength([1, 2, 3, 10], [1, 2, 3]), 3); which fails because commonPrefixLength([1, 2, 3, 10], [1, 2, 3]) evaluates to -1. This seems like a serious limitation that should be realized in yet another policy. In the mean while how should I generalize auto commonPrefixLength(S, T)(S a, T b) { import std.range: zip; import std.algorithm: countUntil; return zip(a, b).countUntil!(ab => ab[0] != ab[1]); } to - work as expected with the unittest above - work with 3 or more arguments like zip do. How do check that all elements of a tuple are equal? I believe this is an important issue because the function commonPrefixLength together with sort can be used to implement - completions (in widgets and intellisense) - find rhymes (retro + commonPrefixLength + sort)
Re: commonLength
On Thursday, 15 January 2015 at 13:13:57 UTC, Nordlöw wrote: I just discovered that zip has StoppingPolicy so why does auto commonPrefixLength(R...)(R ranges) if (ranges.length == 2) { import std.range: zip; return zip!((a, b) => a[0] != b[1])(ranges); } I did a silly mistake. The correct version is auto commonPrefixLength(S, T)(S a, T b) { import std.range: zip, StoppingPolicy; import std.algorithm: countUntil, count; const hit = zip(a, b).countUntil!(ab => ab[0] != ab[1]); return hit == -1 ? zip(a, b).count : hit; } This however needs to process zip(a, b) how do I avoid the extra count? If countUntil returned zip(a, b).count upon failure I would have been done...
Re: commonLength
On Thursday, 15 January 2015 at 19:24:16 UTC, Nordlöw wrote: On Thursday, 15 January 2015 at 13:13:57 UTC, Nordlöw wrote: I just discovered that zip has StoppingPolicy so why does auto commonPrefixLength(R...)(R ranges) if (ranges.length == 2) { import std.range: zip; return zip!((a, b) => a[0] != b[1])(ranges); } I did a silly mistake. The correct version is auto commonPrefixLength(S, T)(S a, T b) { import std.range: zip, StoppingPolicy; import std.algorithm: countUntil, count; const hit = zip(a, b).countUntil!(ab => ab[0] != ab[1]); return hit == -1 ? zip(a, b).count : hit; } This however needs to process zip(a, b) how do I avoid the extra count? If countUntil returned zip(a, b).count upon failure I would have been done... What's wrong with commonPrefix(..).length?
Re: commonLength
On 01/15/2015 11:24 AM, "Nordlöw" wrote: On Thursday, 15 January 2015 at 13:13:57 UTC, Nordlöw wrote: I just discovered that zip has StoppingPolicy so why does auto commonPrefixLength(R...)(R ranges) if (ranges.length == 2) { import std.range: zip; return zip!((a, b) => a[0] != b[1])(ranges); } I did a silly mistake. The correct version is auto commonPrefixLength(S, T)(S a, T b) { import std.range: zip, StoppingPolicy; import std.algorithm: countUntil, count; const hit = zip(a, b).countUntil!(ab => ab[0] != ab[1]); return hit == -1 ? zip(a, b).count : hit; } This however needs to process zip(a, b) how do I avoid the extra count? If countUntil returned zip(a, b).count upon failure I would have been done... The predicate version of count() seems to work for your case. If I misunderstood, please explain with an added failing unit test: auto commonPrefixLength(S, T)(S a, T b) { import std.range: zip; import std.algorithm: count; return zip(a, b).count!(ab => ab[0] == ab[1]); } unittest { assert(commonPrefixLength("açde", "") == 0); assert(commonPrefixLength("açde", "xyz") == 0); assert(commonPrefixLength("açd", "açde") == 3); assert(commonPrefixLength("açdef", "açdef") == 5); } void main() {} Ali
Re: vibe.d Subdirectory?
On Thursday, 15 January 2015 at 14:38:16 UTC, Steven Schveighoffer wrote: On 1/14/15 11:31 AM, Laeeth Isharc wrote: To be very clear: in the simple case when you compile your vibe application from multiple source files and diet templates etc, and you will end up with an executable. This can act as a server directly, or you can make it an internal server on localhost called by php, or you can call it from nginx as a CGI type application depending on the URL. Pardon me for asking kind of a side question, but is there any online information on how to do this? I am contemplating migrating my in-house php-based application to vibe.d, but I wondered if I have to do it whole-sale (not much gratification until the whole thing is done) or piecemeal (then some parts are php, some are vibe.d, until whole thing is ported). I thought I could do the latter, but I don't know how to interact apache/php with vibe.d. The biggest question I have is how vibe.d and php can share session data. But I also have no idea which server should be in front, and how to call one another ;) It may be that you have a reason for going with apache, but in case you have not looked into it (or the situation has changed since you last looked), you might consider nginx as a front end given better stability and performance. If you make D read the PHP authentication then you need to write a new auth scheme when you have gotten rid of PHP. So it might be worth at some point considering moving this to an external service called by both D and PHP when you can do so without breaking anything. This might be worth a read: http://merbist.com/2012/04/04/building-and-implementing-a-single-sign-on-solution/
Re: commonLength
On Thursday, 15 January 2015 at 19:49:14 UTC, Ali Çehreli wrote: auto commonPrefixLength(S, T)(S a, T b) { import std.range: zip; import std.algorithm: count; return zip(a, b).count!(ab => ab[0] == ab[1]); } unittest { assert(commonPrefixLength("açde", "") == 0); assert(commonPrefixLength("açde", "xyz") == 0); assert(commonPrefixLength("açd", "açde") == 3); assert(commonPrefixLength("açdef", "açdef") == 5); } I want to terminate count on first mismatch like assert(commonPrefixLength("abc_d", "abc-d") == 3); Your version will assert(commonPrefixLength("abc_d", "abc-d") == 4);
Re: commonLength
On Thursday, 15 January 2015 at 19:30:21 UTC, Tobias Pankrath wrote: On Thursday, 15 January 2015 at 19:24:16 UTC, Nordlöw wrote: On Thursday, 15 January 2015 at 13:13:57 UTC, Nordlöw wrote: I just discovered that zip has StoppingPolicy so why does auto commonPrefixLength(R...)(R ranges) if (ranges.length == 2) { import std.range: zip; return zip!((a, b) => a[0] != b[1])(ranges); } I did a silly mistake. The correct version is auto commonPrefixLength(S, T)(S a, T b) { import std.range: zip, StoppingPolicy; import std.algorithm: countUntil, count; const hit = zip(a, b).countUntil!(ab => ab[0] != ab[1]); return hit == -1 ? zip(a, b).count : hit; } This however needs to process zip(a, b) how do I avoid the extra count? If countUntil returned zip(a, b).count upon failure I would have been done... What's wrong with commonPrefix(..).length? Only works if all input arguments have length property. I would have implemented countUntil() to return -length upon failure instead of -1 . Then I could have just returned abs of the return value from commonUntil. However auto commonPrefixLengthAlt(S, T)(S a, T b) @safe pure @nogc nothrow { import std.algorithm: commonPrefix, count; return commonPrefix(a, b).count; } works on dmd git master! Limited to 2 arguments, though, but I'm find with that for now :)
Re: commonLength
On Thursday, 15 January 2015 at 20:21:26 UTC, Nordlöw wrote: I would have implemented countUntil() to return -length upon failure instead of -1 . Then I could have just returned abs of the return value from commonUntil. I wonder if we could add an extra overload to countUntil in Phobos that takes an enum as first argument similar to zip's StoppingPolicy. Something like FailCountPolicy.
Re: commonLength
On Thursday, 15 January 2015 at 19:30:21 UTC, Tobias Pankrath wrote: What's wrong with commonPrefix(..).length? Ahh, sorry that works too. I'm surprised :) DMD/Phobos has become really clever at avoiding allocation. Seems there may be need for both commonPrefixCount and commonPrefixLength depending on whether string auto-decoding is needed or not.
Re: Map Lambda with Side-Effects
On Wednesday, 14 January 2015 at 01:15:57 UTC, Tobias Pankrath wrote: Is it possible to - detect that a lambda is has-side-effects and that - the map hasn't been used? Thing is: I'm regularly doing that on purpose. Could you show me a code example? I'm curious. Actually, isn't your closure even weakly pure in your example, because arr is part of the closure and thus an argument to it. I'm fully understand the meaning of weakly and strongly pure functions in D. However I'm not enough familiar with closure purity semantics in D. Could you elaborate a bit, please?
Re: vibe.d Subdirectory?
Thanks everyone for the tips. -Steve