Random Access I/O
I need to be able to perform random access I/O against a file, creating a new file if it doesn't exist, or opening as-is (no truncation) if it already exists. None of the access modes for std.stdio.File seem to allow that. Any usage of the "w" mode causes my code to consider the file empty if it pre-exists (though, it doesn't always actually truncate the disk on file?) If I was coding in C, I would use open() as it gives more options for access: http://pubs.opengroup.org/onlinepubs/009695399/functions/open.html However, I don't see this exposed in phobos anywhere?
Static convertability testing?
I have a template function that gets values out of a tree of variant types. My goal is to be able to write code like; node.get!string("path", "to", "leaf"); Inside get(), I would like to use std.conv to dynamically convert (where able) to the target type (T) or, if that is not possible, to return T.init. If I wanted to force the user to request the correct type as is stored in the structure, I could write code like: switch (leafType) { case STRING: static if (is(T : string)) { return leftValue; } else { return T.init } break; ... But since I want to allow all possiblities that std.conv supports, I want something like: static if (isConvertible!(T, string)) { return leftValue.to!T; } else { return T.init; } Is there something like isConvertible() in the library somewhere?
Re: Time from timestamp?
On Saturday, 31 January 2015 at 00:14:37 UTC, Steven Schveighoffer wrote: On 1/30/15 5:18 PM, Chris Williams wrote: I'm attempting to print a human-readable version of a timestamp. The timestamp is coming from an external service, via JSON. An example is: 1421865781342 Which I know to be: 2015-01-21T18:43:01.342Z http://dlang.org/phobos/std_datetime.html#.unixTimeToStdTime It's kind of convoluted because there is no epoch, but you can make one: import std.datetime; import std.stdio; void main(string[] args) { // can't make this enum because of time zone... auto epoch = SysTime(unixTimeToStdTime(0), UTC()); writeln(epoch + 1_421_865_781_342.msecs); } output: 2015-Jan-21 18:43:01.342Z Note the reason your code didn't work is because SysTime uses 1/1/1 as the epoch. -Steve D'oh, I missed that in the description: "and convert it to hnsecs in UTC since midnight, January 1st, 1 A.D. UTC" That does explain it. I also didn't spot the declaration of unixTimeToStdTime(), which assuredly helps. Thank you!
Re: Time from timestamp?
On Saturday, 31 January 2015 at 00:20:07 UTC, ketmar wrote: On Sat, 31 Jan 2015 00:03:43 +, Chris Williams wrote: since most database software probably stores birthdates (many of which are pre-1970) in this format O_O a perfectly broken software. And stdc: http://h50146.www5.hp.com/products/software/oe/tru64unix/manual/v51a_ref/HTML/MAN/MAN3/3955.HTM And UNIX: http://www.lehman.cuny.edu/cgi-bin/man-cgi?mktime+3
Re: Time from timestamp?
On Friday, 30 January 2015 at 23:50:53 UTC, ketmar wrote: On Fri, 30 Jan 2015 23:42:04 +, Chris Williams wrote: On Friday, 30 January 2015 at 22:38:21 UTC, Chris Williams wrote: On Friday, 30 January 2015 at 22:22:27 UTC, Rikki Cattermole wrote: On a slightly related note, I have code for UTC+0 to unix time stamp. https://github.com/Devisualization/util/blob/ b9ab5758e755c4e33832ac4aed0a5d7f2c728faf/source/core/devisualization/util/ core/time.d Unix timestamps can be negative, so you should probably be using longs instead of ulongs. Yup, there was a world before January 1st, 1970. not for unix timestamps. please, stop that, unix timestamp was not designed to present any dates before 1970. "negative timestamp" is a bug in code. Unless you know something I don't, everything I've ever read says that a negative unix timestamp is meant to refer to a time before 1970. It may not have been intentional, but since most database software probably stores birthdates (many of which are pre-1970) in this format, having a library be unable to support them just makes the library useless for many situations.
Re: Time from timestamp?
On Friday, 30 January 2015 at 22:38:21 UTC, Chris Williams wrote: On Friday, 30 January 2015 at 22:22:27 UTC, Rikki Cattermole wrote: On a slightly related note, I have code for UTC+0 to unix time stamp. https://github.com/Devisualization/util/blob/b9ab5758e755c4e33832ac4aed0a5d7f2c728faf/source/core/devisualization/util/core/time.d Unix timestamps can be negative, so you should probably be using longs instead of ulongs. Yup, there was a world before January 1st, 1970.
Re: Time from timestamp?
On Friday, 30 January 2015 at 22:22:27 UTC, Rikki Cattermole wrote: On a slightly related note, I have code for UTC+0 to unix time stamp. https://github.com/Devisualization/util/blob/b9ab5758e755c4e33832ac4aed0a5d7f2c728faf/source/core/devisualization/util/core/time.d Unix timestamps can be negative, so you should probably be using longs instead of ulongs.
Time from timestamp?
I'm attempting to print a human-readable version of a timestamp. The timestamp is coming from an external service, via JSON. An example is: 1421865781342 Which I know to be: 2015-01-21T18:43:01.342Z The only method I see which takes an epoch-style timestamp, so that I can convert it to something printable, is the SysTime constructor: pure nothrow @safe this(long stdTime, immutable TimeZone tz = null); According to the reference, this seems to take the value in hnsecs. My expectation would be that this means multiplying my initial value by 1_000_000. But if I do that, I get a random date 2500 years in the future. I created this sample code: void main() { long time = 1421865781342L; writefln("%s", SysTime(time)); writefln("%s", SysTime(time * 10L)); writefln("%s", SysTime(time * 100L)); writefln("%s", SysTime(time * 1_000L)); writefln("%s", SysTime(time * 10_000L)); writefln("%s", SysTime(time * 100_000L)); writefln("%s", SysTime(time * 1_000_000L)); writefln("%s", Clock.currTime.stdTime); } Outputs: 0001-Jan-02 07:36:48.5781342 0001-Jan-17 03:04:47.781342 0001-Jun-14 05:44:39.81342 0005-Jul-04 08:23:20.1342 0046-Jan-21 10:50:03.342 0451-Jul-28 11:17:15.42 4506-Sep-18 16:42:14.2 635582516 My expectation would be that the final line would be something beginning with "14" at least. Playing around with possible multipliers, there doesn't even seem to be any integer value that would allow conversion between the timestamp I received and whatever SysTime expects. I'm using: DMD64 D Compiler v2.066.1 Ubuntu from .deb package Is this a bug, or am I doing something wrong?
Re: Using std.net.curl to stream data
On Wednesday, 28 January 2015 at 14:18:38 UTC, Trollgeir wrote: I'm having some trouble trying to stream data to my plot.ly graph: https://plot.ly/62/~Trollgeir/ The API: https://plot.ly/streaming/ I am able to post messages that get recorded into the stream live, although right after curl uploads it, it just seems to wait for a response it's not getting, and eventually timeouts. Does anyone have any advice? auto client = HTTP("stream.plot.ly"); client.addRequestHeader("plotly-streamtoken","e8bg6omat6"); client.verbose = true; string msg = "{ \"x\": 500, \"y\": 500 } \n"; client.postData(msg); client.perform; You have to define a handler for HTTP.onReceive before calling HTTP.perform. It will receive ubyte arrays for each packet that comes in. For most purposes, you just copy that onto the end of a string in an external scope. But if you're streaming content, you'll need to do something more fancy.
Re: How to copy object of class A to another object of class B?
On Wednesday, 28 January 2015 at 09:44:29 UTC, zhmt wrote: Sometime , I need to copy them: thrift.Card tc; db.Card dc; dc.id = tc.id; dc.pwd = tc.pwd; ... It is boring coding, I want a solution to copy them automatically: void copyObj(SRC,DEST)(SRC src,DEST dest) { foreach (i, type; typeof(SRC.tupleof)) { auto name = SRC.tupleof[i].stringof; __traits(getMember, dest, name) = __traits(getMember, src, name); writeln(name); } } Unfortunitely, it doesnt work, how to improve it? Assuming that the hibernated class isn't auto-generated and you can redefine its contents freely, the following style may be an alternative that works for you: struct Foo { public: string a; int b; } class FooClass { public: union { struct { string a; int b; }; Foo foo; } } void main() { Foo f = Foo("a", 10); FooClass c = new FooClass(); c.foo = f; writefln("%s %s", c.a, c.b); } Probably the anonymous struct will break the UDAs, but it should be worth testing.
Re: how convert the range to slice ?
On Wednesday, 28 January 2015 at 22:43:36 UTC, bearophile wrote: Nordlöw: Is there any chance we could add logic to dmd+phobos that hints user about this? It's such a fundamental part of D+Phobos that newbies are forced to learn this quickly. On the other hand an informative error message could be useful... What error message do you suggest? Bye, bearophile Range is not castable to array. See std.array.array to generate an array from a Range.
Re: Russian translation of the "range" term?
On Wednesday, 12 November 2014 at 11:38:52 UTC, thedeemon wrote: On Tuesday, 11 November 2014 at 11:50:18 UTC, Ivan Kazmenko wrote: Hi! I'm unsure what is the Russian equivalent for the term "range", as in "D range", the generalization of a pair of iterators. I think "последовательность" (sequence) is the most appropriate, because the defining characteristic of an input range (most common one) is ability to provide data sequentially. Also, afaik, some languages like F# and Clojure use this term (often shortened to 'seq') for the same thing that D calls ranges. While sequence makes more sense for how std.range thinks of ranges, I think the history of the term is closer to how we use slices. So another (English) alternative to try might be a "view". It's a fairly common term in SQL databases, so presumably there's a translation for it in Russian.
Re: Why do some language-defined attributes have @ and some not?
On Thursday, 23 October 2014 at 07:39:21 UTC, Gary Willoughby wrote: On Thursday, 23 October 2014 at 00:59:26 UTC, Shriramana Sharma via Digitalmars-d- I submit that the syntax for attributes should be streamlined. Shall I go and open a Bugzilla item? No need: http://wiki.dlang.org/DIP64 Besides the @ symbols, isn't there also some inconsistency on whether attributes go before or after the declaration? @property public static void foo() const @safe pure nothrow I've never bothered to ascertain how much of the positioning is optional, but definitely none of it makes sense.
Re: Search Engine
On Wednesday, 8 October 2014 at 18:15:08 UTC, ANtlord wrote: It would be stable? I mean program, that will use C++ extern interface. Trying to link to C++ code will cause some work to solve build issues, but there shouldn't be any stability impacts other than recognizing that C++ won't be using memory management.
Re: Momentary Eh?! for a Dynamic Language Programmmer. Tuples vs Arrays. Just rambling.
On Monday, 23 June 2014 at 22:08:59 UTC, John Carter wrote: On Monday, 23 June 2014 at 21:26:19 UTC, Chris Williams wrote: More likely what you want are variants: Hmm. Interesting. Yes, Variant and VariantArray are much closer to the dynamic language semantics... But the interesting thing is Tuple is much closer to "What I Mean" when I create these things. I probably should used Rubies http://ruby-doc.org/core-2.0/Struct.html but apart from naming the elements it gives me nothing beyond more keystrokes to enter. Tuple is very similar, but also grants type safety. D has structs. If you have any problem working with Tuples, you might consider moving over.
Re: Momentary Eh?! for a Dynamic Language Programmmer. Tuples vs Arrays. Just rambling.
On Monday, 23 June 2014 at 21:18:39 UTC, John Carter wrote: I guess between perl and Ruby and Scheme etc. I got used to creating hybrid containers Want a pair of [string, fileList]? Just make an Array with two items, one a string, one and array of strings. Done. D barfed... leaving me momentarily stunned... then Oh Yes, type safety, Tuple's are the answer where Tuples where Tuples... Eventually found http://dlang.org/tuple.html and more specifically the somewhat unexpectedly named http://dlang.org/phobos/std_typecons.html and off I went... I do have a personal design guideline of when you adding too much behaviour to a heterocontainer, refactor into a class. But I guess I have never realised how often I do casually create heterogenous containers Just rambling and musing. More likely what you want are variants: http://dlang.org/library/std/variant/variantArray.html http://dlang.org/library/std/variant.html Tuples can hold multiple types, but they're only available during compile time.
Re: Separate allocation and construction?
On Thursday, 5 June 2014 at 22:25:03 UTC, Adam D. Ruppe wrote: On Thursday, 5 June 2014 at 22:22:16 UTC, Chris Williams wrote: If I wanted to allocate memory for a class and then call its constructor as two separate steps, while still having the object be managed by the garbage collector, is there any way to do that? Check out std.conv.emplace http://dlang.org/phobos/std_conv.html#emplace First, allocate the memory block for the class. The size is __traits(classInstanceSize, Yourclass). Then slice it: enum size = __traits(classInstanceSize, YourClass); auto memory = GC.malloc(size)[0 .. size]; Why slice? There seems to be a version of emplace that accepts a pointer, which is what GC.malloc() seems to return.
Separate allocation and construction?
If I wanted to allocate memory for a class and then call its constructor as two separate steps, while still having the object be managed by the garbage collector, is there any way to do that? I believe that I've figured out a way to accomplish the first step, but not the second. import std.stdio; class Foo { this(string bar) { writeln(bar); } } void main() { Foo f = (new Foo[1])[0]; f("Hello"); // doesn't compile }
Re: two questions on enums
On Thursday, 3 April 2014 at 23:16:14 UTC, Eric wrote: Okay - I'm new to D, and I'm comming from a java background. Suppose you are designing an API, and you want the user to supply arguments as an enum. But the user needs to define the enum, so how can the API know in advance what enum to require? The solution is to require an enum that implements a known interface. This is easy to do in java, but I haven't yet tried it in D. I suspect it could be done with CTFE or something. An example where I use this is for electronics software. If I need the user to supply a set of pins, the pins are supplied as an enum which implements an interface. By using the interface, it also forces the user to include all of the attributes of each pin such as direction, max load, DC current, etc. Since class type enums are references, they are light, - and they should be immutable - so they are thread safe aslo. I'm not sure how you're using your enum. In Java, the only way to perform a switch over an enum is if you know all the values during compile time. Passing a type Enum into a function (i.e. as opposed to "enum MyEnumType') requires using introspection to pull the actual values out, and then a loop to scan through them for your target value. But if you've programmed a switch for a known enum type, then that means the enum has already been implemented and there is no chance for more than one type to be passed in. So I'm confused.
Re: Musings on infinite loops and not reachable returns
On Tuesday, 25 March 2014 at 20:49:57 UTC, bearophile wrote: Note how the opApply() of Foo should not end with a return, while the opApply() of Bar is required by the D compiler to end with a return. Yet, Foo is contains an infinite loop, so the result of Bar will not be reached. But the type system of D is not strong enough to see that. I'm not seeing it. "while (true)" is no more an infinite loop than "for (i = 0; i < x; i++)", if the body of the while has a break or return statement. int i = 0; while (true) { if (i < x) break; i++; }
Re: Alias template param - Undefined Identifier
On Wednesday, 19 March 2014 at 00:07:04 UTC, Chris Williams wrote: ...probably something along the lines of making all of my functions a static function in a struct, which I then pass into a template which processes UDAs to generate functions at the top with the same names as the originals in the struct, which call the struct variants. It's also a longer to write and debug. Here's a simple (unsafe and inflexible) implementation, should anyone want to build it out into something that can accept multiple arguments and return types. import std.stdio; string wrap(string wrapperName, string structName, string innerName) { return "void " ~ innerName ~ "() {" ~wrapperName~ "( &"~structName~"."~innerName~" );}"; } template decorate(T) { template ForeachMember(Mbr...) { static if (__traits(getAttributes, __traits(getMember, T, Mbr[0])).length > 0) { static if (Mbr.length > 1) { enum ForeachMember = wrap( __traits(identifier, __traits(getAttributes, __traits(getMember, T, Mbr[0]))[0]), __traits(identifier, T), Mbr[0] ) ~ ForeachMember!(Mbr[1..$]) ; } else { enum ForeachMember = wrap( __traits(identifier, __traits(getAttributes, __traits(getMember, T, Mbr[0]))[0]), __traits(identifier, T), Mbr[0] ) ; } } else { static if (Mbr.length > 1) { enum ForeachMember = "" ~ ForeachMember!(Mbr[1..$]); } else { enum ForeachMember = ""; } } } enum decorate = ForeachMember!(__traits(allMembers, T)); } void BeforeAfter(void function() fun) { writeln("Before"); write("\t"); fun(); writeln("After"); } void Llama(void function() fun) { writeln("Llama"); write("\t"); fun(); writeln("Llama"); } struct Foo { @BeforeAfter static void hello() { writeln("Hello"); } @Llama static void and() { writeln("and"); } @BeforeAfter static void goodbye() { writeln("Goodbye"); } } mixin(decorate!(Foo)); void main() { hello(); and(); goodbye(); }
Re: Function to print a diamond shape
On Thursday, 20 March 2014 at 21:25:03 UTC, Ali Çehreli wrote: What interesting, boring, efficient, slow, etc. ways are there? Ali Well one of the more convoluted methods that I can think of would be to define a square as a set of four vectors, rotate 45 degrees, and then create a rasterizer that checks for the presence of the rect at sequential points, and plots those to the console.
Re: bool Associative Array Synchronized
On Thursday, 20 March 2014 at 18:06:18 UTC, Etienne wrote: Right, I was assuming it was always ordered, but modern processor pipelines are different I guess. Even without rearranging the order of your code, your bit exists in RAM but all the logic takes place in a CPU register, meaning that any time you operate with the bit, there's at least two copies. When the CPU switches threads (which could be at any point), it empties the CPU into RAM. If the thread it's switching to then tries to interact with the bit, it's going to create a third copy. Now whichever of the two threads is slower to write back to the original location is going to smash the other's.
Re: Alias template param - Undefined Identifier
On Tuesday, 18 March 2014 at 23:33:12 UTC, bearophile wrote: Chris Williams: But I also like to know how most-effectively to write a C-style macro in D, so it seemed worth checking what the state of the art is. This is an antipattern :-) Bye, bearophile As are goto, pointers, and conditional compilation. That doesn't mean that there aren't cases where those are the best solution, because other solutions would be longer and more convoluted or too inefficient. In Python, I could write a wrapping function that I could apply (using decorators) to each function with this behavior, based on the presence of a UDA. I could roughly build something like that for D, but the whole framework for it would be far more convoluted and harder to maintain than a simple three line macro. ...probably something along the lines of making all of my functions a static function in a struct, which I then pass into a template which processes UDAs to generate functions at the top with the same names as the originals in the struct, which call the struct variants. It's also a longer to write and debug. Unfortunately, at the moment, I don't believe that there's any way to use UDAs to process a file and generate interceptors -- which would be the sort of pattern that we'd like.
Re: Alias template param - Undefined Identifier
On Tuesday, 18 March 2014 at 23:05:51 UTC, bearophile wrote: Chris Williams: I could put a wrapper around the calls to these functions that performs this action, but I figured a little macro would be sufficient for my needs (it's just a little script.) I suggest to keep the code simpler. Bye, bearophile I could. I could simply allow the current working directory to drift as the application performs operations, but I prefer the consistency of knowing that methods I call restore state before I continue to the next method. I sense that in the long run it will make life easier. But I also like to know how most-effectively to write a C-style macro in D, so it seemed worth checking what the state of the art is.
Re: Alias template param - Undefined Identifier
On Tuesday, 18 March 2014 at 22:42:20 UTC, anonymous wrote: You can pass the variable name as a string: Or you can get the variable name from the alias parameter: import std.string: format; template gotoPath(alias path) { enum gotoPath = format(q{ ... fs.chdir(%s); }, path.stringof); } I think I've read that .stringof shouldn't be used for code generation, but I can't think of anything better. Your memory seems to be correct: http://forum.dlang.org/thread/bug-1103...@http.d.puremagic.com/issues/ It looks like the issue is that .stringOf is something generated according to AST information and is thus intrinsically compiler-specific. The ticket it links to suggest using __traits(identifier, X) or 'one of the Phobos helper functions such as "fullyQualifiedName".' Annoying that formatting the string is required. I think you're right that it's ignoring my alias parameter because I'm not using it. Formatting doesn't accomplish anything except to use the parameter. But in exchange, you have to relate your format arguments to the %s entries, instead of the q{} contents just being code. import fs = std.file; import std.stdio; import std.string: format; template gotoPath(alias path) { enum gotoPath = format(q{ string currPath = fs.getcwd(); scope (exit) fs.chdir(currPath); fs.chdir(%s); }, __traits(identifier, path)); } void doStuff(string targetDirectory) { mixin(gotoPath!(targetDirectory)); writefln("b %s", fs.getcwd()); } void main() { writefln("a %s", fs.getcwd()); doStuff("/etc"); writefln("c %s", fs.getcwd()); }
Alias template param - Undefined Identifier
I have a series of functions that each needs to change directory, perform an action, and then revert to the original working directory. I could put a wrapper around the calls to these functions that performs this action, but I figured a little macro would be sufficient for my needs (it's just a little script.) import fs = std.file; import std.stdio; template gotoPath(alias path) { enum gotoPath = q{ string currPath = fs.getcwd(); scope (exit) fs.chdir(currPath); fs.chdir(path); }; } void doStuff(string targetDirectory) { mixin(gotoPath!(targetDirectory)); writefln("b %s", fs.getcwd()); } void main() { writefln("a %s", fs.getcwd()); doStuff("/etc"); writefln("c %s", fs.getcwd()); } When I try to compile (DMD 2.064), I get the following error: test.d(16): Error: undefined identifier path I can fix the issue by removing the alias parameter and hardcoding the name of the variable in the template: import fs = std.file; import std.stdio; template gotoPath() { enum gotoPath = q{ string currPath = fs.getcwd(); scope (exit) fs.chdir(currPath); fs.chdir(targetDirectory); }; } void doStuff(string targetDirectory) { mixin(gotoPath!()); writefln("b %s", fs.getcwd()); } void main() { writefln("a %s", fs.getcwd()); doStuff("/etc"); writefln("c %s", fs.getcwd()); } However, it seems like that shouldn't be necessary. The alias parameter should create a local alias for the external variable which can be utilized by the generated code. Is there something wrong with my syntax?
Re: Get Compile Errors - Command Line
On Friday, 14 March 2014 at 17:10:46 UTC, Bauss wrote: I'm using dmd.exe and not cmd.exe dmd.exe doesn't have a GUI. You're probably running dmd.exe inside cmd.exe. dmd foo.d > mylog.txt
Re: Regarding fixed size arrays
On Saturday, 15 March 2014 at 00:11:22 UTC, bearophile wrote: Do you think it's useful/worth supporting code like that? My expectation would be that your code is implicitly the same as: int[5] foo(int[2] a, int[3] b) { int[5] staticArray; int[] dynamicArray = a ~ b; staticArray = dynamicArray; return staticArray; } Based on the information at http://dlang.org/arrays.html, my expectation would be that a copy requires the slice operator, which isn't in your code. Thus it's trying to initialize staticArray as a new dynamic array -- which obviously wouldn't work. Since your code doesn't have access to the hidden staticArray variable, there's no way to write the correct code: staticArray[] = dynamicArray; Short of changing the standard to consider "a = b" to be equivalent to "a[] = b" when both a and b are arrays, I don't think your code should be handled. And I think such a change would be dangerous. The following works, and I think is probably acceptable. int[5] foo(int[2] a, int[3] b) { int[5] ret; ret[] = a ~ b; return ret; }
Re: to! converting 1D to 2D array
On Friday, 14 March 2014 at 04:36:27 UTC, ed wrote: As to whether or not this should work: int[4] a=[1,2,3,4]; int[2][2] b; b=a; is up to the D language gurus. I think it should... but I'm no language developer, there may be other side-effects I haven't thought about. Cheers, ed In C, any array is just a starting address in memory. Accessing indexes is accomplished during compile time, where the compiler does some math based on the size of the objects in the array and how many dimensions the array has, then more-or-less hardcodes an offset to add to the starting address. All arrays are mutually exchangeable because they're just a pointer. In D, an array is a struct (struct Array), with an address and a length value. A multi-dimensional array is an Array with an address pointing to an array of Arrays. So with an int[2][2] array, you have a layout like: @1000 Array(address=1016, length=2) @1016 [Array(address=1048, length=2),Array(address=1056, length=2)] @1048 [1,2] @1056 [3,4] In this particular case, the data at 1056 is directly following the data at 1048. There's no gap between them, so considering the buffer at 1048 to be a single array of 4 or two arrays of two is inconsequential. But that's no guarantee. Those two arrays could be off in entirely separate chunks of RAM. In that case, setting a=b would force a copy to occur, since a requires the items to be continguous, where b=a results in both variables pointing to the same underlying data (changing one changes the other). Now that's assuming that the compiler is actually trying to convert one into the other. There's the other option of considering a and b to both be of type Array. As such, you can simply copy the values in one over to the other. a=b; // equivalent to a.address=b.address; a.length=b.length; b=a; // equivalent to b.address=a.address; b.length=a.length; This makes complete sense, other than it trashes the settee's type. What was int[2][2] effectively becomes int[4] (or vise-versa), which should then make an access to b[0][1] fail, since the value at entry [0] isn't an Array struct. Personally, I don't like the inconsistency of the former strategy. People should be forced to implement their own strategy for converting array types (whether to create a copy or point to the same underlying data). For the latter strategy, changing an lvalue's type by setting into it seems like it should only be allowed if you cast. Though since it's the lvalue changing, it would be the lvalue that you would have to cast, and usually a cast only lasts for that line not the rest of time, which wouldn't be the case here so cast(int[4])b = a; // ??? Overall, I don't think the compiler should allow the original code. Even if the specification specifies what should happen, the minutiae of it seems prone to creating bugs.
Re: to! converting 1D to 2D array
On Thursday, 13 March 2014 at 03:31:09 UTC, ed wrote: On Thursday, 13 March 2014 at 00:15:19 UTC, Chris Williams wrote: [snip] It shouldn't and probably isn't working. It is working and in fact it is in a "const pure @safe" function. So I will trust it :-) Well it's like a broken watch being correct twice a day. The correct result doesn't mean that something is working. I'm glad you've found a solution though.
Re: to! converting 1D to 2D array
On Wednesday, 12 March 2014 at 03:37:49 UTC, ed wrote: My understanding of your explanation is that it shouldn't work. It shouldn't and probably isn't working. If nothing else, when you use to!(x)(y), "x" should be the type that you're trying to convert into. So I would expect your code to be to!(int[2][2])(a). I would still be impressed if that worked, since std.conv is intended more for parsing strings into ints and stuff, not for splitting and grouping arrays. Your assertion probably succeeds because in memory a two dimensional array is arranged with the first row followed by the second row. So a flat array of four items and a 2-D array of two arrays of two items end up laying out the same in memory. Some how it's going straight to memory and comparing them that way (maybe).
Re: Any way to print compile-time generated code?
On Monday, 10 March 2014 at 18:25:10 UTC, Adam D. Ruppe wrote: Change the mixin(x) line to pragma(msg, x);. It will then print out the generated string at compile time instead of mixing it in so you can take a look at it. That just gives me an error: source/app.d(29): Error: Cannot interpret ProtocolBufferFromString!"\x0amessage Person {\x0a required string name = 1;\x0a required int32 id = 2;\x0a optional string email = 3;\x0a\x0a enum PhoneType {\x0a MOBILE = 0;\x0aHOME = 1;\x0aWORK = 2;\x0a }\x0a\x0a message PhoneNumber {\x0arequired string number = 1;\x0aoptional PhoneType type = 2 [default = HOME];\x0a }\x0a\x0a repeated PhoneNumber phone = 4;\x0a}\x0a" at compile time
Any way to print compile-time generated code?
I'm toying with the dproto library and have encountered an issue where I can't remove items from a "repeated" list of items. I'd like to see what the mixins are producing in terms of actual D code, so that I can figure out how I can correctly try to delete an entry or find the code that's generating the array and add whatever corrections are necessary to expose this ability. Is there any way to push a mixin into a string, instead of into the code, or otherwise to view the output of the "preprocessor"?
Re: convert int[][] to int**
On Friday, 21 February 2014 at 19:13:13 UTC, Chris Williams wrote: On Thursday, 20 February 2014 at 17:02:15 UTC, Dicebot wrote: You can't do it without allocation because memory layout is different for int** and int[][] in D - are.ptr in latter points to slice struct (pointer+length) as opposed to raw pointer in former. You should only have to copy the top list, though. int*[] temp = new int*[ arr.length ]; for (size_t i = 0; i < arr.length; i++) { temp[i] = arr[i].ptr; } int** output = temp.ptr; Untested. Addendum: Note that bearophile's code probably works out to the same thing.
Re: convert int[][] to int**
On Thursday, 20 February 2014 at 17:02:15 UTC, Dicebot wrote: You can't do it without allocation because memory layout is different for int** and int[][] in D - are.ptr in latter points to slice struct (pointer+length) as opposed to raw pointer in former. You should only have to copy the top list, though. int*[] temp = new int*[ arr.length ]; for (size_t i = 0; i < arr.length; i++) { temp[i] = arr[i].ptr; } int** output = temp.ptr; Untested.
Re: Why function template 'among' is of complexity O(1) and not O(n)?
On Thursday, 20 February 2014 at 02:10:50 UTC, anonymous wrote: The foreach is definitely always evaluated at compile time. That's independent of the values being known statically. It generates a couple of if statements. But optimizing those if statements away for static values is not guaranteed or expected. Ah, roger.
Re: Why function template 'among' is of complexity O(1) and not O(n)?
On Thursday, 20 February 2014 at 00:36:38 UTC, anonymous wrote: On Wednesday, 19 February 2014 at 22:46:45 UTC, Chris Williams wrote: When the template writes out the definition of the function, if the parameters can be interpreted during compile-time, then the foreach ( O(n) ) will be run by the compiler to detect the correct parameter and the function will be written out as just as a return statement in the body, without the loop. So during runtime, the function would have an O(1) runtime. That's an optimization the compiler may do, but it's not guaranteed. And `among` is not special in this regard. I think "expected to do" is probably the better phrasing at the moment. Traits/annotations would be largely unusable unless foreach was able to behave as a static construct. And since there is no way for one to declare "static foreach", the only way foreach can be used for running over traits, is for the compiler to detect constant values in the parameters to the statement.
Re: Why function template 'among' is of complexity O(1) and not O(n)?
On Wednesday, 19 February 2014 at 22:05:49 UTC, Peter Alexander wrote: If you want to get even more anal about it, searching an array is technically O(1) because an array cannot be bigger than size_t.max, and since size_t.max is a constant, O(size_t.max) is O(1). Again, completely misleading but technically correct in an esoteric, academic way. That's basically saying that on any linear bouded automaton, all algorithms (except an infinite loop) are O(1) - which is silly. To the OP: The among() function is defined to template out into multiple versions of itself depending on the number of arguments, rather than using variadic parameter checking during runtime. When the template writes out the definition of the function, if the parameters can be interpreted during compile-time, then the foreach ( O(n) ) will be run by the compiler to detect the correct parameter and the function will be written out as just as a return statement in the body, without the loop. So during runtime, the function would have an O(1) runtime. If the parameters can't be determined during compile-time then the function will be written out with the contents of the foreach copied into the body as many times as there are parameters, making the runtime O(n), where n is the number of parameters to the function. Where people are getting a bit technical is that, because the function is generated by a template the following two calls: among("a", "b", "c"); among("a", "b", "c", "d"); end up declaring two separate functions, one which accepts three parameters and the other which accepts four. The version which accepts three parameters will always run the same speed no matter what you call it - since it does the same thing exactly three times. The version which accepts four parameters is the same. Since they don't have any logic - they just run through a constant list of operations with no loop - one can say that they are O(1). Technically, it's true, but also a mildly pointless distinction to make.
Re: Optimize my code =)
On Friday, 14 February 2014 at 16:00:09 UTC, Robin wrote: this(size_t rows, size_t cols) { this.dim = Dimension(rows, cols); this.data = new T[this.dim.size]; enum nil = to!T(0); foreach(ref T element; this.data) element = nil; } Your foreach here is unnecessary. You can zero out an array using the syntax: this.data[] = 0; // probably compiles out as memset() And while I would expect to!T(0) to compile down to something with no particular logic, it still is a function call not a macro, so you're better to let the compiler figure out the best conversion from 0 for type T than to use a library function for it. I think and hope that this is getting optimized via inlining. =) This works similar for opIndexAssign. From complaints that I have seen, very little gets inlined at the moment. Matrix opMul(ref const(Matrix) other) { if (this.dim.rows != other.dim.cols || this.dim.cols != ther.dim.rows) { // TODO - still have to learn exception handling first ... } auto m = new Matrix(this.dim.rows, other.dim.cols); auto s = new Matrix(other).transposeAssign(); Since you don't return s, it's probably better to not allocate an instance. I would also be curious to see your constructor which copies one matrix into a new one. Besides that I can't find a way how to make a use of move semantics like in C++. For example a rvalue-move-constructor or a move-assign would be a very nice thing for many tasks. Do you mean something like this? this.data[] = other.data[]; // probably compiles out as memcpy() this.data = other.data.dup; // different syntax, but should be the same Another nice thing to know would be if it is possible to initialize an array before it is default initialized with T.init where T is the type of the array's fields. I believe so, but I would have to scour about to find the syntax. Hopefully, someone else knows.
Re: Is it possible to convert a delegate into a function?
On Thursday, 6 February 2014 at 22:15:00 UTC, Dicebot wrote: assert(!dg.ptr); Note that Dicebot's version works only because he chose a delegate that points to something that doesn't need an external state. The below method, Foo.dump(), would fail the assert because it requires a reference to an instance of Foo in order to grab the state of a.value or b.value. It does look like one is allowed to write into the delegate .ptr and .funcptr variables, so reconstructing a delegate from parts is possible. (I'm surprised that the definition of funcptr is "void function()" instead of "void function(Foo)"?). import std.stdio; class Foo { private: int value; public: this(int v) { value = v; } void dump() { writeln(value); } } void doDump(void* obj, void function() func) { void delegate() dg; dg.ptr = obj; dg.funcptr = func; dg(); } void main() { Foo a = new Foo(42); Foo b = new Foo(255); auto dgA = &a.dump; auto dgB = &b.dump; writefln("%x %x", dgA.funcptr, dgB.funcptr); // Same void function() func = dgA.funcptr; doDump(dgA.ptr, func); doDump(dgB.ptr, func); }
Re: Is it possible to convert a delegate into a function?
On Thursday, 6 February 2014 at 21:26:06 UTC, Gary Willoughby wrote: I know you can convert functions into delegates using: http://dlang.org/phobos/std_functional.html#.toDelegate but can you do this the other way around? I have a method that needs a function pointer but it would be nice to use a converted delegate pointer instead. A function is the address of a block of code in memory. A delegate also has the address to a block of code (a function) but it also has the pointer to an object that is to be passed as the first parameter to the function. It's pretty easy to drop a parameter, so writing a wrapper method that passes all the other parameters on to the target function is pretty easy. But unless the function that you're calling can accept a reference to the object that the delegate references and use that and the function pointer to reconstruct the delegate, you're definitely out of luck. Whether there is a means to manually construct a delegate or not, I'm not sure.
Re: std.parallelism: How to wait all tasks finished?
On Wednesday, 5 February 2014 at 15:38:14 UTC, Cooler wrote: Will not help. I don't know beforehand what tasks will be created. procData is recursive and it decides create new task or not. You seem to be saying that you want to be able to wait for all tasks to complete an indefinite number of times, adding more tasks after each one. Why would you want to do that? The queue for the pool is infinitely long, so just keep adding tasks till you have no more tasks to add. Or if you have a progression of types, like all tasks of type A have to be complete before you can start running the tasks of type B, then you should be able to have a separate thread pool for each type.
Re: Do you have any suggestions for project directory structure?
On Wednesday, 5 February 2014 at 21:50:17 UTC, Orfeo wrote: Suppose I have a project "protocols" that uses DMock and a library Foo. I would like to use a structure dub style..Which solution is better: A. protocols ├── bin │ └── protocols.a ├── dmocks │ └── *.d ├── foo │ └── *.d ├── src │ └── protocols │ └── *.d B. protocols ├── bin │ └── protocols.a ├── src │ ├── dmocks │ │└── *.d │ ├── foo │ │└── *.d │ └── protocols │└── *.d Or another solution? Thanks I would probably advise against having the outside libraries inside your project at all. Have them parallel to protocols either add a /lib folder to protocols that can hold their binaries or pull from the outside (you'll need to point your includes outside your own project anyways).
Re: Performant method for reading huge text files
Parsing should be faster than I/O. Set up two buffers and have one thread reading into buffer A while you parse buffer B with a second thread. ...and then flip buffers whenever the slower of the two has completed.
Re: Performant method for reading huge text files
On Tuesday, 4 February 2014 at 00:04:23 UTC, Rene Zwanenburg wrote: On Monday, 3 February 2014 at 23:50:54 UTC, bearophile wrote: Rene Zwanenburg: The problem is speed. I'm using LockingTextReader in std.stdio, but it't not nearly fast enough. On my system it only reads about 3 MB/s with one core spending all it's time in IO calls. Are you reading the text by lines? In Bugzilla there is a byLineFast: https://d.puremagic.com/issues/show_bug.cgi?id=11810 Bye, bearophile Nope, I'm feeding it to csvReader which uses an input range of characters. Come to think of it.. Well this is embarassing, I've been sloppy with my profiling :). It appears the time is actually spent converting strings to doubles, done by csvReader to read a row into my Record struct. No way to speed that up I suppose. Still I find it surprising that parsing doubles is so slow. Parsing should be faster than I/O. Set up two buffers and have one thread reading into buffer A while you parse buffer B with a second thread.
Re: Enum of functions?
On Tuesday, 26 November 2013 at 05:13:00 UTC, Shammah Chancellor wrote: What is the practical purpose of such a thing? -Shammah The two cases I can think of are: 1. To define a set of supported handlers which can be passed in as a parameter to a call. Rather than writing a switch in your method that calls the correct function, based on the supported values in the enum, you build the handlers right into the enum. It pulls your code into one. 2. If you have a quick and easy method for serializing an enum - for example, converting the name to a string and back - then you can write can write code that deserializes and calls a function in a single line. But mostly, I was just curious.
Re: Enum of functions?
On Tuesday, 26 November 2013 at 00:27:25 UTC, IgorStepanov wrote: You can write enum Foo : void function() { WOMBAT = function void () {writeln("Wombat");} } or enum Foo { WOMBAT = function void () {writeln("Wombat");} } `() {writeln("Wombat");}` literal recognized by compiler as delegate, not function. Thank you. It looks like 2.063 only handled the first case (and only if there was a single entry), but with 2.064 it works perfectly.
Enum of functions?
Is there any way to do something like this? import std.stdio; enum Foo : void function() { WOMBAT = () {writeln("Wombat");} } void doStuff(Foo f) { f(); } int main() { doStuff( Foo.WOMBAT ); return 0; } Currently, I get the errors: hello.d(4): Error: non-constant nested delegate literal expression __lambda1 hello.d(12): Error: delegate hello.Foo.__lambda1 is a nested function and cannot be accessed from D main I can fix it by declaring a function outside of Foo and setting WOMBAT = &fname, but it seems like I should be able to create a hidden lambda.
Traits and UDAs
I decided to write up a little application to test using User Defined Attributes and have one question. Here is a working application that allows me to mark certain members of a function to be dumped: import std.stdio; enum Dump = "Dump"; template Dumper(T) { void dump() { foreach (mem; __traits(allMembers, T)) { auto attributes = __traits(getAttributes, __traits(getMember, T, mem)); static if ( attributes.length > 0 && __traits(getAttributes, __traits(getMember, T, mem))[0] == Dump ) { writeln(mem); } } } } class Foo { @Dump int hello; @Dump int world; int bye; mixin Dumper!(Foo); } int main(string[] args) { Foo f = new Foo(); f.dump(); return 0; } The eighth line bothers me, though. It seems like I should be able to write: if (attributes.length > 0 && attributes[0] == Dump) However, that fails to compile with the message: test.d(7): Error: variable _attributes_field_0 cannot be read at compile time test.d(8): Error: expression !!(_attributes_field_0 == "Dump") is not constant or does not evaluate to a bool test.d(7): Error: variable _attributes_field_0 cannot be read at compile time test.d(8): Error: expression !!(_attributes_field_0 == "Dump") is not constant or does not evaluate to a bool Any thoughts?
TickDuration = Divide by Zero
I have the following code: import std.datetime; const TickDuration a; static this() { a = TickDuration.from!"msecs"(15_000); } int main() { writefln("Hello world!"); // is never printed return 0; } When I run it, I get the following output: object.Error: Integer Divide by Zero I presume that TickDuration is trying to access something that it doesn't have access to yet, during startup. Is there another way to make my constant a constant?
Re: Sharing unlocked, unchanging data between threads?
== Quote from Jonathan M Davis (jmdavisp...@gmail.com)'s article > Well, unless it's declared shared, it's going to be thread-local, and then each > thread is going to have their own copy. Now, if it were declared shared and you > never changed it after initially setting all of its values, then you shouldn't > have any problems as far as I'm aware. Just accessing an associative array > shouldn't change it. > - Jonathan M Davis I'm using D 1.0. I don't believe it has a "shared" keyword. But, globals are shared as well, I presume.
Sharing unlocked, unchanging data between threads?
I'm writing a fairly large, multithreaded application and some part of it is causing periodic access errors. Say that I have an associative array like: uint[ char[] ] nameToId; If I set all values before I start my threads going and never change anything after that point -- all access is read only -- is there any way that having multiple threads access it at the same time would mess anything up? I'm doing this in several places as locking a read-only data structure doesn't strike me as something which should be necessary. I don't know what D's associative arrays look like internally though, so perhaps it is dangerous to do. It would be a major hassle to port it all over to locking everything, to test if it fixes the problem. So, hopefully someone can say whether this is worth checking.
Shifting values within an array
I would like to be able to do something like this: class A { int i; } int main() { A[] list; for (uint L = 0; L < 3; L++) { for (uint L2 = 0; L2 < 3; L2++) { uint index = L + L2; uint copyAmount = list.length - index; list.length = list.length + 1; if (copyAmount > 0) { // Move data after index one slot later to make room A[] sliceFrom = list[index .. (index + copyAmount)]; A[] sliceTo = list[(index + 1) .. (index + 1 + copyAmount)]; sliceTo[] = sliceFrom[]; } list[index] = new A(); list[index].i = index; } } return 0; } I have a running implementation which uses C's memmove(), but I gather that this isn't a safe means to do it as the garbage collector might run while the references to the object are being manipulated. Is there a way to do this outside of a loop?
Re: Multiple Inheritance, Mixins, and Constructors
Ary Borenszweig Wrote: > > You can do this: > > template TFoo() { > // Never use this variable directly :-P > SomeObject _s_o; > > SomeObject s_o() { > if (_s_o is null) > _s_o = new SomeObject(); > return _s_o; > } > > // And if you want to make it assignable too > SomeObject s_o(SomeObject x) { > _s_o = x; > } > > void bar() { > s_o.x = 10; > // code > // ... > } > } Well I ended up converting my object to a struct, which solved the issue. Your solution would probably work, but for what I'm doing, I'd rather not incur the overhead of a branch and (possible) function call for every access of the object. It seems like object initialization outside of a method should be magically moved to the top of the constructor. But ah well. Thank you.
Multiple Inheritance, Mixins, and Constructors
Well so I had a case where I needed to do something like multiple inheritance. Here's an example solution: interface IFoo { void bar(); } template TFoo() { void bar() { // code // ... } } class Base { // variables } class Thing : Base, IFoo { mixin TFoo; } Well so that's all well and good. The problem comes if I have an object declared in TFoo. For instance: template TFoo() { SomeObject s_o; void bar() { s_o.x = 10; // code // ... } } It compiles fine, but when I go to run it, trying to set so.x gets an error because s_o hasn't been instantiated. If I try: template TFoo() { SomeObject s_o = new SomeObject(); void bar() { s_o.x = 10; // code // ... } } Then I get a compile-time error that I can't do that. Now I'd love to define a constructor in TFoo that instantiated s_o, but I'm pretty sure that would conflict should anyone try to add a constructor to (for instance) class Thing. My solution was to add an initFoo() definition in IFoo, and say that it needs to be called in the constructor of anyone using IFoo/TFoo, but that seems pretty wonky. Admittedly the whole interface/mixin thing is already a bit wonky, but it seems like there should be a solution to at least the object initialization problem.