Re: UI Library
On Friday, 20 May 2022 at 02:37:48 UTC, harakim wrote: I need to write a piece of software to track and categorize some purchases. It's the kind of thing I could probably write in a couple of hours in C#/Java + html/css/javascript. However, something keeps drawing me to D and as this is a simple application, it would be a good one to get back in after almost a year hiatus. [...] Maybe you can use minigui from arsd https://github.com/adamdruppe/arsd
Re: Bug in std.json or my problem
On Wednesday, 22 April 2020 at 18:35:49 UTC, CraigDillabaugh wrote: On Wednesday, 22 April 2020 at 18:23:48 UTC, Anonymouse wrote: On Wednesday, 22 April 2020 at 17:48:18 UTC, Craig Dillabaugh wrote: clip File an issue if you have the time, maybe it will get attention. Unreported bugs can only be fixed by accident. I thought it might be worth filing a bug, but wanted to confirm if others thought this was actually a bug. I had encountered an identical issue with vibe-d years ago. Thanks for the feedback. After some digging it appears there is already a fix for this (though a bit old) … maybe I am the only person who cares about std.json after all :o) https://github.com/dlang/phobos/pull/5005/commits/e7d8fb83d2510b252cd8cfd2b744310de6fa84e5
Bug in std.json or my problem
So perhaps I am the only person in the world using std.json, but I was wondering if the following code should work. = import std.json; import std.conv; import std.stdio; struct Person { string name; float income; this (string name, float income) { this.name = name; this.income = income; } this(JSONValue js) { this.name = to!string(js["name"]); /* This next line crashes with .. JSONValue is not floating type. * to!float( js["income"].toString()) works. */ this.income = js["income"].floating; } JSONValue toJSON() { JSONValue json; json["name"] = JSONValue(this.name); json["income"] = JSONValue(this.income); return json; } } int main(string[] argv) { Person bob = Person("Bob", 0.0); string bob_json = bob.toJSON().toString(); Person sonofbob = Person(parseJSON(bob_json)); writeln(sonofbob.toJSON().toPrettyString()); return 0; } === The crash is caused because the 'income' field with value 0.0 is output as 0 (rather than 0.0) and when it is read this is interpreted as an integer. Shouldn't this work?
Re: How the hell to split multiple delims?
On Saturday, 15 February 2020 at 11:32:42 UTC, AlphaPurned wrote: I've tried 10 different ways with split and splitter, I've used all the stuff that people have said online but nothing works. I always get a template mismatch error. Why is something so easy to do so hard in D? auto toks = std.regex.split(l, Regex("s")); auto toks = std.regex.splitter(l, Regex("s")); auto toks = std.regex.splitter(l, ctRegex!r"\."); I had the same problem myself recently, and almost ended up here to ask the same question as you but stumbled across the following (ugly) solution without using regexs. char[] line = "Split this by#space or#sign." auto parts = line.splitter!(a => a=='#' | a==' ').array;
Re: To learn D
On Friday, 5 July 2019 at 12:00:15 UTC, Binarydepth wrote: I've considering learning full D. I remembered that D is not recommended as a first language, So I read time ago. So my question, is learning C and Python a good intro before learning D? TY Ali's book is targeted at beginners (see link below). I don't see why D wouldn't make a good first language. If your objective is to learn D, then I don't think learning C or Python is going to be help that much. Obviously if you know C/Python you can learn D more quickly, but I doubt the effort is worth it if D is the ultimate goal. http://ddili.org/ders/d.en/index.html
Re: more OO way to do hex string to bytes conversion
On Wednesday, 7 February 2018 at 03:25:05 UTC, rikki cattermole wrote: On 06/02/2018 8:46 PM, Craig Dillabaugh wrote: On Tuesday, 6 February 2018 at 18:46:54 UTC, H. S. Teoh wrote: [...] clip [...] clip [...] Wouldn't it be more accurate to say OO is not the correct tool for every job rather than it is "outdated". How would one write a GUI library with chains and CTFE? But you could with signatures and structs instead ;) I am not sure how this would work ... would this actually be a good idea, or are you just saying that technically it would be possible?
Re: more OO way to do hex string to bytes conversion
On Tuesday, 6 February 2018 at 18:46:54 UTC, H. S. Teoh wrote: On Tue, Feb 06, 2018 at 06:33:02PM +, Ralph Doncaster via Digitalmars-d-learn wrote: clip OO is outdated. D uses the range-based idiom with UFCS for chaining operations in a way that doesn't require you to write loops yourself. For example: import std.array; import std.algorithm; import std.conv; import std.range; // No need to use .toStringz unless you're interfacing with C auto hex = "deadbeef";// let compiler infer the type for you auto bytes = hex.chunks(2) // lazily iterate over `hex` by digit pairs .map!(s => s.to!ubyte(16))// convert each pair to a ubyte .array; // make an array out of it // Do whatever you wish with the ubyte[] array. writefln("%(%02X %)", bytes); clip T Wouldn't it be more accurate to say OO is not the correct tool for every job rather than it is "outdated". How would one write a GUI library with chains and CTFE? Second, while 'auto' is nice, for learning examples I think putting the type there is actually more helpful to someone trying to understand what is happening. If you know the type why not just write it ... its not like using auto saves you any work in most cases. I understand that its nice in templates and for ranges and the like, but for basic types I don't see any advantage to using it.
Re: Object oriented programming and interfaces
On Monday, 4 December 2017 at 20:43:27 UTC, Dirk wrote: Hi! I defined an interface: interface Medoid { float distance( Medoid other ); uint id() const @property; } and a class implementing that interface: class Item : Medoid { float distance( Item i ) {...} uint id() const @property {...} } The compiler says: Error: class Item interface function 'float distance(Medoid other)' is not implemented Is there a way to implement the Item.distance() member function taking any object whose class is Item? Interfaces are expected to implement static or final functions. See #6 at: https://dlang.org/spec/interface.html interface Medoid { static float distance( Medoid other ); uint id() const @property; } class Item : Medoid { static float distance( Item i ) { return 0.0f; } uint id() const @property { return 1; } }
Re: Help with an algorithm!
On Thursday, 15 June 2017 at 13:41:07 UTC, MGW wrote: On Thursday, 15 June 2017 at 13:16:24 UTC, CRAIG DILLABAUGH wrote: The purpose - search of changes in file system. Sorting is a slow operation as well as hashing. Creation of a tree, is equally in sorting. So far the best result: string[] rez; foreach(str; m2) { bool fFind; int j; foreach(int i, s; m1) { if(str == s) { fFind = true; j = i; break; } } if(!fFind) { rez ~= str; } else {m1[j] = m1[$-1]; m1.length = m1.length - 1; } } // rez => rezult How to parallel on thred? radix sort is O(N) time, which is as fast as you can hope. But given your specific problem domain (the strings are paths) an initial radix sort step likely won't gain you much, as everything is going to be sorted into a small subset of the buckets. So I guess you can scrap that idea. Knowing that your strings are actually file paths I think building some sort of tree structure over M1 wouldn't be unreasonable. You say go two or three levels deep on your directory structure (ie nodes are labelled with directory name) and use that to split M1 into buckets. If some bucket has too many entries you could apply this recursively. Since you are only building a constant number of levels and the number of nodes is not likely to be too large you should do much better than N log N * c time for this step. Then you search with the elements of M2. You should be able to do this in a multi-threaded way since once built, your data structure on M1 is read-only you could just split M2 over X threads and search. I am not an expert in this regard though, so perhaps someone better informed than I can chime in. Since strings will tend to have long common prefix's Ivan's Trie idea would also work well.
Re: Help with an algorithm!
On Thursday, 15 June 2017 at 11:48:54 UTC, Ivan Kazmenko wrote: On Thursday, 15 June 2017 at 06:06:01 UTC, MGW wrote: There are two arrays of string [] mas1, mas2; Size of each about 5M lines. By the size they different, but lines in both match for 95%. It is necessary to find all lines in an array of mas2 which differ from mas1. The principal criterion - speed. There are the 8th core processor and it is good to involve a multithreading. The approaches which come to mind are: clip taking constant time. Ivan Kazmenko. As a follow up to this, if your alphabet is reasonably small perhaps could run radix sort based on the first few characters to split your arrays up into smaller subsets, and then use one of Ivan's suggestions within each subset. Subset searches could be easily run in parallel.
Re: Check of point inside/outside polygon
On Wednesday, 27 July 2016 at 14:56:13 UTC, Suliman wrote: On Wednesday, 27 July 2016 at 12:47:14 UTC, chmike wrote: On Wednesday, 27 July 2016 at 09:39:18 UTC, Suliman wrote: clip Sorry, its my issue I am thinging about polygons, but for me would be enought points. The problem is next. I am writhing geo portal where user can draw shape. I need to get users images that user shape cross. But as temporal solution it would be enough to detect if image central point inside this polygon (I know its coordinates). I can do its on DB level, but I would like to use SQLite that do bot have geometry support. So i am looking for any solution. I can use gdal but its _very_ heavy So when you say you want polygon intersection, is one of the polygons you are interested in the shape of the images (ie. roughly a rectangle)? If this is the case then you can likely just take the bounding rectangle (easily calculated) of your polygon and check if that intersects the bounding rectangle for the the image and that should work 95% of the time.
Re: Check of point inside/outside polygon
On Wednesday, 27 July 2016 at 09:39:18 UTC, Suliman wrote: On Wednesday, 27 July 2016 at 08:40:15 UTC, chmike wrote: The algorithm is to draw a horizontal (or vertical) half line starting at your point and count the number of polygon edges crossed by the line. If that number is even, the point is outside the polygon, if it's odd, the point is inside. Let (x,y) be the point to test and (x1,y1)(x2,y2) the end points on each segment. Let n be the number of crossing that you initialize to 0. (x1,y1)(x2,y2) are also the corners of the rectangle enclosing the segment. You then have to examine each segment one after the other. The nice thing is that there are only two cases to consider. 1. When the point is on the left side of the rectangle enclosing the segment. 2. When the point is inside the rectangle enclosing if (y1 <= y2) { if ((y1 <= y) && (y2 >= y)) { if ((x1 < x) && (x2 < x)) { // case 1 : point on the left of the rectangle ++n; } else if (((x1 <= x) && (x2 >= x)) || ((x1 >= x) && (x2 <= x))) { // case 2 : point is inside of the rectangle if ((x2 - x1)*(y - y1) >= (y2 - y1)*(x - x1)) ++n; // Increment n because point is on the segment or on its left } } } else { if ((y1 >= y) && (y2 <= y)) { if ((x1 < x) && (x2 < x)) { // case 1 : point on the left of the rectangle ++n; } else if (((x1 <= x) && (x2 >= x)) || ((x1 => x) && (x2 <= x))) { // case 2 : point is inside of the rectangle if ((x2 - x1)*(y - y2) >= (y1 - y2)*(x - x1)) ++n; // Increment n because point is on the segment or on its left } } } This algorithm is very fast. I didn't tested the above code. You might have to massage it a bit for corner cases. It should give you a good push to start. Big thanks! Ehm... Now I should add iteration on array of points in first and second polygon? If it's not hard for you could you show how it should look please. Easiest solution (if you don't care about performance) is to pairwise compare every segment of both polygons to see if they intersect, and if that fails, then run point-in-polygon algorithm with one vertex from each polygon and the other (catches the case where one polygon is entirely contained within the other). Now you have the point in polygon algorithm (kindly provided by chmike) and testing for segment intersection is a basic primitive geometric operation, so there are lots of examples on the web. You should certainly be able to find working C code for this without much trouble.
Re: AA with dynamic array value
On Wednesday, 6 July 2016 at 02:33:02 UTC, ketmar wrote: On Wednesday, 6 July 2016 at 02:19:47 UTC, Craig Dillabaugh wrote: [...] this is true for any dynamic array, including AAs. until something is added to array, it actually a `null` pointer. i.e. arrays (and AAs) generally consisting of pointer to data and some length/info field. while array is empty, pointer to data is `null`. and when you passing your dynamic array slice/AA to function, it makes a copy of those internal fields. reallocing `null` doesn't affect the original variable. generally speaking, you should use `ref` if you plan to make your dynamic array/AA grow. i.e. void insertValue (ref int[][string]aa, string key, int value) Thanks for giving me the correct solution, and for the explanation. Cheers, Craig
Re: AA with dynamic array value
On Wednesday, 6 July 2016 at 02:03:54 UTC, Adam D. Ruppe wrote: On Wednesday, 6 July 2016 at 01:58:31 UTC, Craig Dillabaugh wrote: *(keyvalue) ~ value; // This line fails. That should prolly be ~= instead of ~. Ahh, I was so close. Thank you that seems to do the trick. However, now I have another issue. For the following main function: int main( string[] args) { int[][string] myAA; //int[] tmp; //tmp ~= 7; //myAA["world"] = tmp; insertValue( myAA, "hello", 1 ); insertValue( myAA, "goodbye", 2 ); insertValue( myAA, "hello", 3 ); foreach (k; myAA.keys.sort) { writefln("%3s %d", k, myAA[k].length); } return 0; } If I run this, it prints out nothing. However, if I uncomment adding an element for 'world' then it prints (as expected): goodbye 1 hello 2 world 1 Why doesn't my function allow me to insert elements into an empty associative array, but succeeds for an AA with some element in it?
AA with dynamic array value
How can I create (and update) and associative array where the key is a string, and the value is a dynamic array of integers? For example: void insertValue( int[][string]aa, string key, int value ) { int[]* keyvalue; keyvalue = ( key in aa ); if ( keyvalue !is null ) { *(keyvalue) ~ value; // This line fails. } else { int[] tmp; tmp ~= value; aa[key] = tmp; } } int main( string[] args) { int[][string] myAA; insertValue( myAA, "hello", 1 ); insertValue( myAA, "goodbye", 2 ); insertValue( myAA, "hello", 3 ); return 0; } Fails with: ...(16): Error: ~ has no effect in expression (*keyvalue ~ value) Thanks for any help.
Re: Issue with 2.071: Regression or valid error?
On Wednesday, 6 April 2016 at 19:01:58 UTC, Craig Dillabaugh wrote: On Wednesday, 6 April 2016 at 15:10:45 UTC, Andre wrote: clip Not so up to date on D's OOP stuff, but don't you want create() to be protected, not private. You can typically access a private method through a base class, which is what you are doing with cat.create(). You CAN'T typically access a private ...
Re: Issue with 2.071: Regression or valid error?
On Wednesday, 6 April 2016 at 15:10:45 UTC, Andre wrote: Hi, With 2.071 following coding does not compile anymore and somehow I feel it should compile. The issue is with line "cat.create();". Cat is a sub type of Animal. Animal "owns" method create and I want to call the method create within the class Animal for cat. Is the error message "no property create for type 'b.cat'" valid or not? Kind regards André module a; import b; class Animal { private void create() {} void foo(Cat cat) { cat.create(); // >> no property create for type 'b.cat' } } void main() {} -- module b; import a; class Cat: Animal {}; compile with rdmd a b Not so up to date on D's OOP stuff, but don't you want create() to be protected, not private. You can typically access a private method through a base class, which is what you are doing with cat.create().
Re: How is D doing?
On Thursday, 24 December 2015 at 00:16:16 UTC, rsw0x wrote: On Tuesday, 22 December 2015 at 21:38:22 UTC, ZombineDev wrote: On Tuesday, 22 December 2015 at 17:49:34 UTC, Jakob Jenkov wrote: clip removed C++ because it just dwarfs the others. D, as I expected, has a massive following in Japan. I'm still not quite sure why. Hey, this can be D's theme song: https://www.youtube.com/watch?v=Cg6rp20OGLo
Re: DUB linking to local library
On Tuesday, 4 August 2015 at 08:18:58 UTC, John Colvin wrote: On Tuesday, 4 August 2015 at 03:20:38 UTC, Craig Dillabaugh wrote: I can now run it with: LD_LIBRARY_PATH=/home/craig2/code/gdal-2.0.0/lib64 ./gdaltest But it appears the LD_LIBRARY_PATH hack is causing havoc with other libraries, as I get errors loading other shared libraries when I do that. At the very least you want to do: LD_LIBRARY_PATH=/home/craig2/code/gdal-2.0.0/lib64:$LD_LIBRARY_PATH ./gdaltest Thanks!
Re: DUB linking to local library
On Tuesday, 4 August 2015 at 04:21:27 UTC, Joakim Brännström wrote: On Tuesday, 4 August 2015 at 03:20:38 UTC, Craig Dillabaugh wrote: clip Linkers, so fun they are... https://wiki.debian.org/RpathIssue As you can see in the search order RPATH takes precedence over LD_LIBRARY_PATH. If we assume that you want LD_LIBRARY_PATH to be able to override the lib you could use the following flags. lflags : [ --enable-new-dtags, -rpath=/home/craig2/code/gdal-2.0.0/lib64/, -L/home/craig2/code/gdal-2.0.0/lib64/ ] you can see what it is in the binary with: readelf --dynamic gdaltest|grep PATH This should make LD_LIBRARY_PATH redundant. //Joakim I knew using LD_LIBRARY_PATH was frowned upon, thanks for enlightening me on the correct way to handle this. Works beautifully now.
DUB linking to local library
I have been writing bindings for the GDAL library (www.gdal.org). I recently updated my bindings to the latest release of GDAL (2.0). Before adding my bindings to code.dlang.org I want to run some tests. I've built GDAL2 locally and want to link my bindings to this library. However, I also have the older GDAL libraries (1.11) installed system wide on my machine. My GDAL bindings have the following dub.json file: { name: gdald, description: D bindings for the Geospatial Data Abstraction Library (GDAL)., homepage: https://github.com/craig-dillabaugh/TBD;, homepage: http://www.gdal.org/;, importPaths:[.], targetType:sourceLibrary, license: MIT, authors: [ Craig Dillabaugh ], libs : [gdal] } While my test program appears as follows: { name: gdaltest, description: Test cases for GDAL D., copyright: Copyright © 2014, Craig Dilladub bubaugh., authors: [ Craig R. Dillabaugh ], dependencies: { gdald : {version: ~master} }, lflags : [ -L/home/craig2/code/gdal-2.0.0/lib64/libgdal.so.20.0.0 ], libs : [gdal], targetPath : ., targetType : executable } I used add-local so that my test program could see my bindings. My issue is that while everything compiles OK (with dub build) the resulting executable gdaltest seems to be linked with the system gdal.so file and not the libgdal.so.20.0.0 file I specified with lflags. ldd prints out: ldd gdaltest linux-vdso.so.1 (0x7ffe417e2000) libgdal.so.1 = /usr/lib64/libgdal.so.1 (0x7faabacf8000) So how can I force my application to link to my local copy of GDAL2 at /home/craig2/code/gdal-2.0.0/lib64. Any help is appreciated. Craig
Re: DUB linking to local library
On Tuesday, 4 August 2015 at 02:45:21 UTC, Joakim Brännström wrote: On Tuesday, 4 August 2015 at 02:26:17 UTC, Craig Dillabaugh wrote: So how can I force my application to link to my local copy of GDAL2 at /home/craig2/code/gdal-2.0.0/lib64. Any help is appreciated. Hi, I recently ran into similare problems, different lib. Try changing: lflags : [-L/home/craig2/code/gdal-2.0.0/lib64/libgdal.so.20.0.0 ] libs : [gdal] to: lflags : [-L/home/craig2/code/gdal-2.0.0/lib64/ ] libs : [:libgdal.so.20.0.0] observe the flags dub passes on to dmd by using --vverbose //Joakim Thanks. Everything compile perfectly, and now the correct libs are linked it seems, but I still have an issue with the executable: ldd gdaltest linux-vdso.so.1 (0x7ffe63381000) libgdal.so.20 = not found I can now run it with: LD_LIBRARY_PATH=/home/craig2/code/gdal-2.0.0/lib64 ./gdaltest But it appears the LD_LIBRARY_PATH hack is causing havoc with other libraries, as I get errors loading other shared libraries when I do that.
Re: Binding Nested C Structs
On Friday, 10 July 2015 at 03:38:49 UTC, Craig Dillabaugh wrote: I am trying to bind to a C union with a number of nested structs declared as follows: typedef union { int Integer; struct { int nCount; int *paList; } IntegerList; struct { int nCount; GIntBig *paList; } Integer64List; } OGRField; According to http://wiki.dlang.org/D_binding_for_C#Nested_Structs I should attempt to write something like (last example shown): extern(C) union OGRField { int Integer; struct { int nCount; int* paList; } struct { int nCount; GIntBig* paList; } } But that is obviously not going to work. Does anyone know the right way to handle nested C structs of that form. OK Found the answer elsewhere on the same page: extern(C) union OGRField { int Integer; struct _IntegerList { int nCount; int* paList; } _IntegerList IntegerList; struct _Integer64List { int nCount; GIntBig* paList; } _Integer64List Integer64List; }
Binding Nested C Structs
I am trying to bind to a C union with a number of nested structs declared as follows: typedef union { int Integer; struct { int nCount; int *paList; } IntegerList; struct { int nCount; GIntBig *paList; } Integer64List; } OGRField; According to http://wiki.dlang.org/D_binding_for_C#Nested_Structs I should attempt to write something like (last example shown): extern(C) union OGRField { int Integer; struct { int nCount; int* paList; } struct { int nCount; GIntBig* paList; } } But that is obviously not going to work. Does anyone know the right way to handle nested C structs of that form.
Re: Converting void* to D array
On Wednesday, 15 April 2015 at 04:43:39 UTC, Daniel Kozák wrote: On Wed, 15 Apr 2015 04:24:20 + Craig Dillabaugh via Digitalmars-d-learn digitalmars-d-learn@puremagic.com wrote: Hi. I want to call a C library function that returns a data buffer as a void*. How do I convert the resulting void* into something I can process in D? //I have the following function from the GDAL C library. extern(C) CPLErr GDALReadBlock( GDALRasterBandH, int, int, void* ); So I have (GByte is defined in the GDAL library): void* buffer = malloc( GByte.sizeof * x_block_size * y_block_size ); I fill the buffer (and ignore any errors :o) GDALReadBlock( AGDALRasterBandHInstance, xblock, yblock, buffer ); Now, how can I access the data in buffer? Or you probably can do it like this: auto buffer = new GByte[xblock*yblock]; GDALReadBlock( AGDALRasterBandHInstance, xblock, yblock, (cast void*)buffer.ptr ); Thank you very much. Works like a charm. Make that last line: GDALReadBlock( AGDALRasterBandHInstance, xblock, yblock, cast(void*)buffer.ptr );
Converting void* to D array
Hi. I want to call a C library function that returns a data buffer as a void*. How do I convert the resulting void* into something I can process in D? //I have the following function from the GDAL C library. extern(C) CPLErr GDALReadBlock( GDALRasterBandH, int, int, void* ); So I have (GByte is defined in the GDAL library): void* buffer = malloc( GByte.sizeof * x_block_size * y_block_size ); I fill the buffer (and ignore any errors :o) GDALReadBlock( AGDALRasterBandHInstance, xblock, yblock, buffer ); Now, how can I access the data in buffer?
Contributing to Phobos Documentation
Motivated by this thread: http://forum.dlang.org/thread/measc3$qic$1...@digitalmars.com I was hoping to see if I could do some work on the Phobos documentation, but I am curious to know what the easiest way for someone with limited/no ddoc experience to get involved in this would be. I checked the CONTRIBUTING.md file in phobos and it is a bit on the 'light' side. I assume just fixing stuff in my local repo and sending PRs would be insufficient, as I should be 'testing' my documentation changes. Is there a resource where I can learn how to generate the phobos documentation for phobos locally. Second question, can I generate documentation for a single module rather than all of phobos each time I try to update something. Craig
Re: Contributing to Phobos Documentation
On Saturday, 21 March 2015 at 21:53:00 UTC, H. S. Teoh wrote: On Sat, Mar 21, 2015 at 05:48:40PM +, Craig Dillabaugh via Digitalmars-d-learn wrote: Motivated by this thread: http://forum.dlang.org/thread/measc3$qic$1...@digitalmars.com I was hoping to see if I could do some work on the Phobos documentation, but I am curious to know what the easiest way for someone with limited/no ddoc experience to get involved in this would be. I checked the CONTRIBUTING.md file in phobos and it is a bit on the 'light' side. I assume just fixing stuff in my local repo and sending PRs would be insufficient, as I should be 'testing' my documentation changes. Is there a resource where I can learn how to generate the phobos documentation for phobos locally. On Posix: git clone https://github.com/D-Programming-Language/dlang.org cd dlang.org make -f posix.mak phobos-prerelease cd .. ln -s dlang.org/web . cd ../phobos make -f posix.mak html You should now be able to point your browser at web/phobos-prerelease/index.html and see the generated docs. Or copy web/* into your web folder of your local webserver and point your browser to the appropriate URL. Note that for this to work, the dlang.org and phobos repos must share a common parent directory, as the makefiles currently make a lot of assumptions about your directory layout, and may die horribly if you use a non-standard layout. Second question, can I generate documentation for a single module rather than all of phobos each time I try to update something. [...] You could just run `make -f posix.mak html` and it should only update those files that changed since you last ran it. (In theory, anyway. Make is unreliable and sometimes you have to delete the generated files in order to refresh them, but hopefully this will be rare.) T Thanks very much. Craig
Re: Dlang seems like java now,but why not let d more like C# Style?
On Saturday, 14 March 2015 at 09:59:05 UTC, dnewer wrote: yes,java is good lang,but i dont think it's better than c#,if no oracle or google support java will less and less. C# is a good and easy lang. i like C# . but,C# cant compiled to native code. So far, I have been searching for a language, like c # write efficiency, but more secure than that of c #, more efficient (runs), stronger (system-level, driving level) What has led you to this conclusion? I don't personally find D very much like Java. It definitely doesn't push OO design on you like Java (even where it isn't needed), and code is much more concise in my experience. I also find D very much more flexible. I don't have any C# experience so I can't compare those languages much, but I've heard people say their are D / C# similarities. Anyway, this isn't a criticism of your comment, I was just curious what (other than the shared C++ syntax heritage) you find so Java-like in D? Cheers, Craig
Re: Getting started with vibe.d
On Tuesday, 3 June 2014 at 16:16:10 UTC, Chris Saunders wrote: I've made my first attempt to use dub/vibe.d and I'm running into some issues I can't find on the list. I'm on Ubuntu 14.04/x86_64, using the latest stable dub (0.9.21). I can create a new dub project: “”” $ dub init test vibe.d Successfully created an empty project in '/home/csaunders/devel/csaunders/mongoSB/test' “”” ...but then I'm having trouble building: “”” $ cd test $ dub build --compiler=ldc2 vibe-d: [vibe-d, libevent, openssl] test: [test, vibe-d, libevent, openssl] Building vibe-d configuration libevent, build type debug. FAIL ../../../../.dub/packages/vibe-d-0.7.19/.dub/build/libevent-debug-linux.posix-x86_64-ldc2-0C180158569265198380A4CE65BB2C41 vibe-d staticLibrary Error executing command build: No LDC static libraries supported “”” ...I've tried a few variations on this but haven't had any luck. This is using the latest ldc: “”” $ ldc2 --version LDC - the LLVM D compiler (0.12.1): based on DMD v2.063.2 and LLVM 3.3.1 Default target: x86_64-unknown-linux-gnu Host CPU: corei7 http://dlang.org - http://wiki.dlang.org/LDC Registered Targets: x86- 32-bit X86: Pentium-Pro and above x86-64 - 64-bit X86: EM64T and AMD64 “”” Any pointers? Just curious, can you get it to work with DMD? Also, you might consider posting on the Rejected Software forums (although this forum isn't a bad idea). http://forum.rejectedsoftware.com/
Re: Getting started with vibe.d
On Tuesday, 3 June 2014 at 17:41:27 UTC, Chris Saunders wrote: Thanks, I somehow missed the vibe.d forums... I'd need an ldc solution in the end, but trying dmd is a good idea. The result is some kind of link error to libevent?: dub build vibe-d: [vibe-d, libevent, openssl] test: [test, vibe-d, libevent, openssl] Target is up to date. Using existing build in /home/csaunders/.dub/packages/vibe-d-0.7.19/.dub/build/libevent-debug-linux.posix-x86_64-dmd-AB0707232CA963B5DA23C2232BBED51B/. Use --force to force a rebuild. Building test configuration application, build type debug. Compiling... Linking... .dub/build/application-debug-linux.posix-x86_64-dmd-6EEB0831D66A347BFD0076DC383B442F/test.o:(.data._D162TypeInfo_S3std8typecons130__T5TupleTS3std9container54__T5ArrayTS4vibe4core7drivers9libevent212TimeoutEntryZ5ArrayVAyaa6_5f73746f7265TmVAyaa7_5f6c656e677468Z5Tuple6__initZ+0x60): undefined reference to `_D3std8typecons130__T5TupleTS3std9container54__T5ArrayTS4vibe4core7drivers9libevent212TimeoutEntryZ5ArrayVAyaa6_5f73746f7265TmVAyaa7_5f6c656e677468Z5Tuple15__fieldPostBlitMFZv' collect2: error: ld returned 1 exit status --- errorlevel 1 FAIL .dub/build/application-debug-linux.posix-x86_64-dmd-6EEB0831D66A347BFD0076DC383B442F test executable Error executing command build: Link command failed with exit code 1 Just a guess, but do you have the dev libraries for libevent installed?
Re: D Newbie Trying to Use D with Major C Libraries
On Thursday, 15 May 2014 at 22:25:47 UTC, Tom Browder via Digitalmars-d-learn wrote: I am a volunteer developer with the well-known 3D CAD FOSS project BRL-CAD: http://brlcad.org I have wanted to use D for a long time but I hadn't taken the plunge. Yesterday I advertised to the BRL-CAD community my new project to attempt to create D bindings for BRL-CAD's C libraries, and I created a branch for the project. I have been looking for specific information on creating D bindings from C headers for which there seems to be sufficient information available, but I would appreciate recommendations as to the best method. I have successfully built my first pure D program but now need to test the feasibility of my project. What I have not seen yet is the exact way to build a D program which uses D bindings and its matching C library. I have just created a Cookbook page on the D Wiki where I show my first attempt for a real GNU Makefile as an example for the project. The page link is here: http://wiki.dlang.org/Using_C_libraries_for_a_D_program I would appreciate it if an experienced D user would correct that recipe so it should compile the desired binary source correctly (assuming no errors in the input files). Thanks for any help. Best regards, -Tom Hi Tom, Sadly, I lack the expertise to give you much advice. I did read through your Wiki posting though. One thing that came to mind was you used GMake. Perhaps you should consider using DUB. For example here is the DUB config file for one of my library bindings (in my case I used a static library though): { name: shplib, description: D bindings for Shapelib. Shapefile reader., homepage: https://github.com/craig-dillabaugh/shplib.d;, homepage: http://shapelib.maptools.org/;, importPaths:[.], targetType: sourceLibrary, authors: [ Craig Dillabaugh ], sourcePaths: [./source], libs-posix : [libshp] } A little nicer that GMake, more the D way, and cross platform ... I think. Not sure exactly how you change that for linking to a .so lib. Cheers, Craig
Re: D Newbie Trying to Use D with Major C Libraries
On Friday, 16 May 2014 at 01:16:46 UTC, Craig Dillabaugh wrote: On Thursday, 15 May 2014 at 22:25:47 UTC, Tom Browder via Digitalmars-d-learn wrote: I am a volunteer developer with the well-known 3D CAD FOSS project BRL-CAD: http://brlcad.org I have wanted to use D for a long time but I hadn't taken the plunge. Yesterday I advertised to the BRL-CAD community my new project to attempt to create D bindings for BRL-CAD's C libraries, and I created a branch for the project. I have been looking for specific information on creating D bindings from C headers for which there seems to be sufficient information available, but I would appreciate recommendations as to the best method. I have successfully built my first pure D program but now need to test the feasibility of my project. What I have not seen yet is the exact way to build a D program which uses D bindings and its matching C library. I have just created a Cookbook page on the D Wiki where I show my first attempt for a real GNU Makefile as an example for the project. The page link is here: http://wiki.dlang.org/Using_C_libraries_for_a_D_program I would appreciate it if an experienced D user would correct that recipe so it should compile the desired binary source correctly (assuming no errors in the input files). Thanks for any help. Best regards, -Tom Hi Tom, Sadly, I lack the expertise to give you much advice. I did read through your Wiki posting though. One thing that came to mind was you used GMake. Perhaps you should consider using DUB. For example here is the DUB config file for one of my library bindings (in my case I used a static library though): { name: shplib, description: D bindings for Shapelib. Shapefile reader., homepage: https://github.com/craig-dillabaugh/shplib.d;, homepage: http://shapelib.maptools.org/;, importPaths:[.], targetType: sourceLibrary, authors: [ Craig Dillabaugh ], sourcePaths: [./source], libs-posix : [libshp] } A little nicer that GMake, more the D way, and cross platform ... I think. Not sure exactly how you change that for linking to a .so lib. Cheers, Craig Some info on DUB can be found at: http://code.dlang.org/
Writing to stdin of a process
I want to be able to write to the stdin stream of an external process using std.process. I have the following small test app. myecho.d -- import std.stdio; void main(string[] args) { foreach (line; stdin.byLine()) { stdout.writeln(line); } } -- If I call this from the command line, it echo's back whatever I write to it. Then I have the following program. testpipes.d --- import std.process; import std.stdio; void main( string[] args ) { auto pipes = pipeProcess(./myecho, Redirect.stdin ); scope(exit) wait(pipes.pid); pipes.stdin().writeln(Hello world); } If I compile and run testpipes.d, nothing happens. I was expecting it to echo back Hello world to me. Can anyone tell me what I am dong wrong.
Re: Writing to stdin of a process
On Saturday, 26 April 2014 at 13:30:41 UTC, Adam D. Ruppe wrote: On Saturday, 26 April 2014 at 08:45:59 UTC, Craig Dillabaugh wrote: Can anyone tell me what I am dong wrong. In this case, I'd close the pipe when you're done. pipes.stdin().writeln(Hello world); pipes.stdin.close; myecho loops on stdin until it receives everything; until the pipe is closed. testpipes waits for myecho to complete before termination. The two processes are waiting on each other: testpipes won't close the file until it exits, and myecho won't exit until testpipes closes the file. an explicit call to close breaks the deadlock. In this case, flushing would cause the one line to appear, because of the buffering yazd talked about, but the program still wouldn't terminate since a flushed buffer still potentially has more coming so echo would see that line, then wait for more.. Thank you Adam, and yazd for your responses, now it works. Thanks also for the explanations, I was wondering how myecho.d would know when the input was finished so it could terminate.
Re: Example of parse whole json answer.
On Thursday, 24 April 2014 at 12:17:42 UTC, Nicolas wrote: I have a json string saved in a file ( example of json tweeter answer: https://dev.twitter.com/docs/api/1.1/get/statuses/user_timeline ). I am trying to read the whole json answer and print specific data (created_at, retweet_count, ..) . I am new at D Programming language and i was wondering if someone can help me or post some example that show how to parse json strings using std.json library. Thanks in advance. Here is something to get you started. The initial version of this code was from Ali Cehreli, I can't remember what modifications are mine, or if this is all straight form Ali. If you intend to do any serious work with Json, I highly recommend you check out Vibe.d (www.vibed.org) - more stuff to learn but its JSON capabilities are awesome compared to what std.json gives you. import std.stdio; import std.json; import std.conv; import std.file; /** Ali's example. */ struct Employee { string firstName; string lastName; } void readEmployees( string employee_json_string ) { JSONValue[string] document = parseJSON(employee_json_string).object; JSONValue[] employees = document[employees].array; foreach (employeeJson; employees) { JSONValue[string] employee = employeeJson.object; string firstName = employee[firstName].str; string lastName = employee[lastName].str; auto e = Employee(firstName, lastName); writeln(Constructed: , e); } } void main() { // Assumes UTF-8 file auto content = `{ employees: [ { firstName:Walter , lastName:Bright }, { firstName:Andrei , lastName:Alexandrescu }, { firstName:Celine , lastName:Dion } ] }`; readEmployees( content ); //Or to read the same thing from a file readEmployees( readText( employees.json ) ); }
Re: Improving IO Speed
On Friday, 14 March 2014 at 18:00:58 UTC, TJB wrote: I have a program in C++ that I am translating to D as a way to investigate and learn D. The program is used to process potentially hundreds of TB's of financial transactions data so it is crucial that it be performant. Right now the C++ version is orders of magnitude faster. Here is a simple example of what I am doing in D: import std.stdio : writefln; import std.stream; align(1) struct TaqIdx { align(1) char[10] symbol; align(1) int tdate; align(1) int begrec; align(1) int endrec; } void main() { auto input = new File(T201212A.IDX); TaqIdx tmp; int count; while(!input.eof()) { input.readExact(tmp, TaqIdx.sizeof); // Do something with the data } } Do you have any suggestions for improving the speed in this situation? Thank you! TJB I am not sure how std.stream buffers data (the library has been marked for removal, so perhaps not very efficiently), but what happens if you read in a large array of your TaqIdx structs with each read.
Re: DMD exit code -9
On Thursday, 20 February 2014 at 08:10:06 UTC, simendsjo wrote: On Wednesday, 19 February 2014 at 22:15:47 UTC, Craig Dillabaugh wrote: (...) I just realized that I tried to build this on my Linode, where DMD tends to choke and die with anything Vibe-d related (basic Linodes have very little RAM). To many terminals open! Same code/build config work fine at my workstation. (...) Just a little heads up in case you begin experiencing the same issues as me. I've also choked my Linode and found out it's better to compile from my desktop. One problem though is that I'm running x86_64 on my desktop and x86 on my Linode. The compiled x86 program crashes on my desktop, but runs fine in my Linode. Took some time before I actually tried running the crashing program on Linode... Thanks for the tip. My Host OS and my Linode are identical OpenSuse 13.1 (x86_64) and I did as you did (compile on my PC then copy the executable to the Linode). So far, so good for me.
Re: DMD exit code -9
On Wednesday, 19 February 2014 at 23:45:12 UTC, Etienne Cimon wrote: On 2014-02-19 17:15, Craig Dillabaugh wrote: However, I would still be interested in finding out where I could get a listing of what the various exit codes mean ... or do I need to delve into the DMD source code? That seems to be the SIGKILL signal from linux kernel (-9). DMD didn't have a chance to react when the OOME occured. Thanks.
Re: [video tutorial] Defensive programming with Design By Contract basics
On Thursday, 20 February 2014 at 10:28:45 UTC, simendsjo wrote: http://youtu.be/wFqHTCBt72M Thanks for posting these. They are well done. What text editor are you using, emacs?
DMD exit code -9
I am trying to build a small application (I am using DUB) and when I try to build, I get the following output: dub build dub: /usr/lib64/libcurl.so.4: no version information available (required by dub) vibe-d: [vibe-d, libevent, openssl] vibe-d: [vibe-d, libevent, openssl] libd: [libd, vibe-d, libevent, openssl] classify: [classify, vibe-d, libevent, openssl, libd, vibe-d, libevent, openssl] Building vibe-d configuration libevent, build type debug. Running dmd... FAIL ../../../../../.dub/packages/vibe-d-master/.dub/build/libevent-debug-linux.posix-x86_64-dmd-7A48A3727C6BBE022213B1765700F4A5 vibe-d staticLibrary Error executing command build: DMD compile run failed with exit code -9 Does anyone know what 'exit code -9' means, or where I could even go to find a listing of what the various exit codes for DMD mean. I've searched around the WWW a bit and can't find any such list.
Re: DMD exit code -9
On Wednesday, 19 February 2014 at 22:07:55 UTC, Craig Dillabaugh wrote: I am trying to build a small application (I am using DUB) and when I try to build, I get the following output: dub build dub: /usr/lib64/libcurl.so.4: no version information available (required by dub) vibe-d: [vibe-d, libevent, openssl] vibe-d: [vibe-d, libevent, openssl] libd: [libd, vibe-d, libevent, openssl] classify: [classify, vibe-d, libevent, openssl, libd, vibe-d, libevent, openssl] Building vibe-d configuration libevent, build type debug. Running dmd... FAIL ../../../../../.dub/packages/vibe-d-master/.dub/build/libevent-debug-linux.posix-x86_64-dmd-7A48A3727C6BBE022213B1765700F4A5 vibe-d staticLibrary Error executing command build: DMD compile run failed with exit code -9 Does anyone know what 'exit code -9' means, or where I could even go to find a listing of what the various exit codes for DMD mean. I've searched around the WWW a bit and can't find any such list. I just realized that I tried to build this on my Linode, where DMD tends to choke and die with anything Vibe-d related (basic Linodes have very little RAM). To many terminals open! Same code/build config work fine at my workstation. However, I would still be interested in finding out where I could get a listing of what the various exit codes mean ... or do I need to delve into the DMD source code?
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; } I am no expert at optimizing D code, so this is a bit of a shot in the dark, but does your speed improve at all if you replace: this.data = new T[this.dim.size]; with: this.data.length = this.dim.size
Re: Optimize my code =)
On Friday, 14 February 2014 at 16:47:32 UTC, John Colvin wrote: On Friday, 14 February 2014 at 16:40:31 UTC, Craig Dillabaugh wrote: 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; } I am no expert at optimizing D code, so this is a bit of a shot in the dark, but does your speed improve at all if you replace: this.data = new T[this.dim.size]; with: this.data.length = this.dim.size Why would that make a difference here? They're (almost) identical are they not? Certainly the body of the work, the allocation itself, is the same. Well, in my defense I did start with a disclaimer. For some reason I thought using .length was the proper way to size arrays. It is likely faster if you are resizing an existing array (especially downward), but in this case new memory is being allocated anyway. In fact I ran some tests (just allocating a matrix over and over) and it seems using new is consistently faster than using .length (by about a second for 5 matrices). Shows how much I know.
Re: How can i find my LAN IP Address using std.socket?
On Tuesday, 4 February 2014 at 15:48:50 UTC, Vladimir Panteleev wrote: On Tuesday, 4 February 2014 at 13:02:26 UTC, TheFlyingFiddle wrote: I'm trying to find my own ip address using std.socket with little success. How would i go about doing this? (It should be a AddressFamily.INET socket) This program will print all of your computer's IP addresses: import std.socket; import std.stdio; void main() { foreach (addr; getAddress(Socket.hostName)) writeln(addr.toAddrString()); } This includes IPv6 addresses. You can filter the address family by checking addr's addressFamily property. I am a bit lost in anything networking related, so I ran this on my machine just for fun and it printed: 127.0.0.1 127.0.0.1 127.0.0.1 which based on my understanding is the local loopback address (I am not completely, 100% ignorant). However if I run /sbin/ifconfig I get: enp7s0Link encap:Ethernet HWaddr 50:E5:49:9B:29:49 inet addr:10.1.101.52 Bcast:10.1.101.255 Mask:255.255.255.0 inet6 addr: fe80::52e5:49ff:fe9b:2949/64 Scope:Link loLink encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 inet6 addr: ::1/128 Scope:Host This computer is on a network with dynamically assigned IP address (DHCP). So shouldn't the 10.1.101.52 address have been reported?
Re: How can i find my LAN IP Address using std.socket?
On Tuesday, 4 February 2014 at 16:13:33 UTC, Dicebot wrote: On Tuesday, 4 February 2014 at 16:02:33 UTC, Craig Dillabaugh wrote: However if I run /sbin/ifconfig I get: enp7s0Link encap:Ethernet HWaddr 50:E5:49:9B:29:49 inet addr:10.1.101.52 Bcast:10.1.101.255 Mask:255.255.255.0 inet6 addr: fe80::52e5:49ff:fe9b:2949/64 Scope:Link loLink encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 inet6 addr: ::1/128 Scope:Host This computer is on a network with dynamically assigned IP address (DHCP). So shouldn't the 10.1.101.52 address have been reported? It results in all addresses you hostname resolvs to. On all desktop linux machines /etc/hosts is configured to resolve hostname to localhost by default. On servers it usually resolves to externally accessible one. Thanks.
Re: 3d vector struct
5) I notice that a lot of other people online prefer using fixed arrays not structs for Vectors in D, why? It does make some calculations more straightforward. For example I have code that calculates distance between points as follows: double euclideanDistance( double[] pt1, double[] pt2 ) in { assert( pt1.length == pt2.length ); } body { return sqrt( 0.0.reduce!( (sum,pair) = sum + (pair[0]-pair[1])^^2)(zip(pt1, pt2)) ); } Now a point is not a vector, but they are similar in many respects. That fact that I use an array for my points makes such calculations possible. Furthermore you can always add methods to your struct that let users access the appropriate indices as x, y and z. If you use UFCS (I haven't yet) you could make these appear to user code just as if you had named your variables x, y, and z. Finally, maybe as some point you want to support vectors of varied dimension ... it then becomes easier to port your struct. 6) Any other comments or suggestions? Once you have your design more or less settled you should make it generic (if not for practical reasons just for fun and experience). You likely want your type to support only floating-point values, so you can see here how types can be restricted to FP (see line 50). https://github.com/craig-dillabaugh/phobos/blob/master/std/complex.d Thats my fork of the Phobos libraries, likely a bit out of date, but I was too lazy to look up the prope URL.
Re: core.stdc.config
On Thursday, 30 January 2014 at 07:26:51 UTC, Jacob Carlborg wrote: On 2014-01-30 05:42, Mike Parker wrote: All of the core.* modules are part of DRuntime, not Phobos. Unfortunately none of the core.stdc.* modules are documented. It's understandable that duplicating the documentation of the C library is not done since that would require extra work. But it would be nice to at least see which modules and declarations are available. I agree. Even if they are part of DRuntime, and even if there is no desire to write full documentation for them, people looking through the D site's Library Reference should at least be made aware of their existence.
Re: core.stdc.config
On Thursday, 30 January 2014 at 09:03:47 UTC, Gary Willoughby wrote: On Thursday, 30 January 2014 at 03:28:57 UTC, Craig Dillabaugh wrote: So, there is a module core.stdc.config (referenced here): http://dlang.org/interfaceToC.html That is presumably part of the D Standard library. I am curious to know why no mention of this library is included at: http://dlang.org/phobos/index.html Is it not part of Phobos? Are there standard modules in D that are not included in Phobos? If so, where would one find the list of these modules. The way i see what's available is to take a look at the files installed by the compiler. The directory is different for all operating systems but it's great to look at the source code of all the different modules. For example on Mac OSX 10.8.5 'core.stdc.config' is located at '/usr/share/dmd/src/druntime/src/core/stdc/config.d'. There you can see how the types are constructed and what they represent. For Linux just type 'locate config.d' in the terminal. For Windows it's all in 'C:\d' i think. I did as you suggested and had a look through what was on my system. Having done so I now think that the documentation at: http://dlang.org/phobos/index.html is out of date. If you look at the section under Imports, this appears to be describing what is available under from C, but it appears to suggest that you use std.c.config - or at least that is how I would have read it.
core.stdc.config
So, there is a module core.stdc.config (referenced here): http://dlang.org/interfaceToC.html That is presumably part of the D Standard library. I am curious to know why no mention of this library is included at: http://dlang.org/phobos/index.html Is it not part of Phobos? Are there standard modules in D that are not included in Phobos? If so, where would one find the list of these modules.
Re: Simplest way to create an array from an associative array which its contains keys and values?
On Friday, 3 January 2014 at 17:38:16 UTC, Gary Willoughby wrote: Simplest way to create an array from an associative array which its contains keys and values? For example if i have an associative array like this: [one:1, two:2] What's the easiest way to create a dynamic array that looks like this: [one, 1, two, 2] I know it can be done via a loop, but is there a more idiomatic way to achieve this? As someone with little experience with functional programming, I am just curious - having browsed through the thread - if the various solutions proposed here would really be considered more 'idiomatic' D. Or if they were posted because the OP asked about avoiding the foreach() loop. In other words while: auto range = aa.byKey.map!(a = chain(a.only, aa[a].only)); string[] array = range.join; Saves a few lines of code, and looks cooler, it seems that the trivial foreach loop version is very easy: string[] array; foreach (key, value; aa) { array ~= key; array ~= value; }
Re: Simplest way to create an array from an associative array which its contains keys and values?
On Tuesday, 7 January 2014 at 20:52:40 UTC, H. S. Teoh wrote: On Tue, Jan 07, 2014 at 08:38:10PM +, Craig Dillabaugh wrote: [...] As someone with little experience with functional programming, I am just curious - having browsed through the thread - if the various solutions proposed here would really be considered more 'idiomatic' D. Or if they were posted because the OP asked about avoiding the foreach() loop. In other words while: auto range = aa.byKey.map!(a = chain(a.only, aa[a].only)); string[] array = range.join; Saves a few lines of code, and looks cooler, it seems that the trivial foreach loop version is very easy: string[] array; foreach (key, value; aa) { array ~= key; array ~= value; } [...] Even better, encapsulate this in a function: CommonType!(K,V)[] aaToArray(K,V)(V[K] aa) if (is(CommonType!(V, K))) { typeof(return) result; foreach (key, value; aa) { result ~= key; result ~= value; } return result; } Then you can use it in a single line next time: string[] arr = aaToArray([a: aa, b : bb]); int[] arr = aaToArray([1: 2, 3: 4]); ... // etc. T Yes, I would imagine if this was not a 'one off' operation, you would likely want to create a function. That one looks nice. I posted my question mainly because D advertises itself as a 'multi-paradigm' language. It seems that a number of the more experienced posters on here seem to like functional approaches using the algorithms in std.algorithm. However, it seems to me sometimes the obvious/simple solution that avoids using std.algorithm results in more readable code. So I was curious to know if using std.algorithm functions are generally considered preferable for simple cases like this, or if it is simply a matter of taste. As an aside, the trade-off is even more blatant in C++ where a simple hand-rolled solution often comes out looking so much nicer than the STL algorithm alternative.
A good advertisement for 'static if'
I am not sure if this belongs in D.learn, but it might be of interest. I was writing some C++ code for a project at work and have a class that stores image data from a file. The image data can be in just about any numeric (int/float/complex) type, so I wanted a 'wrapper' class/struct that could hold any type of data without being 'parameterized' (we use templates for image access). My class contains a union ( called 'data') with every possible type of pointer and parameter for indicating the data type. However, at some point code eventually needs to get at the data, so I have the following beauty of a template method, (calling the image structure RAWImageDataStore was a bad design decision on my part, need to change that soon, its very Java-esque): template class T RAWImageDataStoreT* getBandData( ) { T t; //Check struct data type vs template type. if( datatype == TYPE_8u typeid(t) == typeid(uint8_t) ) { return reinterpret_cast RAWImageDataStoreT* ( data.t8u ); } else if ( datatype == TYPE_16s typeid(t) == typeid(int16_t) ) { return reinterpret_cast RAWImageDataStoreT* ( data.t16s ); } //a number of types left out, I am sure you get the idea. //but you need to see the complex types, they are beautiful. else if ( datatype == TYPE_C16s typeid(t) == typeid(std::complexint16_t) ) { return reinterpret_cast RAWImageDataStoreT* ( data.tC16s ); } \\OK, you only really needed to see one of the complex types :o) else if( datatype == TYPE_UNKNOWN ) { std::cerr Cannot access band with unknown data type. std::endl; return 0; } //+ a bit more error handling code. Initially this didn't compile because I was missing the reinterpret_cast statements. They effectively do nothing. If the template type is int8_t then I return the data.t8u pointer, which is a RAWImageDataStoreint8_t*, but have to cast it to RAWImageDataStoreint8_t*. I must do this because when I call the method type int16_t my return data.t8u returns the wrong type of pointer for the method, even though I know that if the type is int16_t this statement can never be reached. I know there was some debate in the C++ community about whether they should adopt D-like static if, which would have solved this problem, since it would compile the illegal code right out of existence. Maybe there is a better way to do this in C++, but I thought I would post here as a case-study in the usefulness of 'static if'. Craig
Re: A good advertisement for 'static if'
On Thursday, 12 December 2013 at 17:34:13 UTC, FreeSlave wrote: On Thursday, 12 December 2013 at 14:55:28 UTC, Craig Dillabaugh wrote: I am not sure if this belongs in D.learn, but it might be of interest. I was writing some C++ code for a project at work and have a class that stores image data from a file. The image data can be in just about any numeric (int/float/complex) type, so I wanted a 'wrapper' class/struct that could hold any type of data without being 'parameterized' (we use templates for image access). clip Maybe there is a better way to do this in C++, but I thought I would post here as a case-study in the usefulness of 'static if'. Craig In C++ you can use partial specialization to achieve what you want. class Storage { public: union { float* fdata; int* idata; } data; }; templatetypename T T* get(Storage stor) { return 0; //or throw exception } template float* getfloat(Storage stor) { return stor.data.fdata; } template int* getint(Storage stor) { return stor.data.idata; } int main() { Storage stor; float* fdata = getfloat(stor); return 0; } Thanks for this suggestion, it avoids the reinterpret cast nicely. I've used template specialization in other cases, but it didn't occur to me in this case (plus adding the 'reinterpret_cast' required less refactoring on my part at the time). However, I may switch my code to use this method since the resulting executable should be smaller/faster since the big if ... else statement isn't inserted with every template instantiation. However neither solution is as nice as 'static if' in D. The benefits of having all my type checks in one space, and the 'dead' code is eliminated in the instantiations. Cheers, Craig
Re: Help Finding Strange Memory Bug (Code linked to C library)
On Saturday, 7 December 2013 at 23:11:39 UTC, Rémy Mouëza wrote: My strategy here would be to: A. run the program in a debugger, say GDB, to get a exhaustive stacktrace for hints about where to look at. B. have a quick look at the library directly (the Use the Source Luke strategy). Since I was curious about your problem (you had everything correct - this should not fail), and have no access to your code, I checked out the shapelib code from its cvs public repository and found out that the last pointer, `double * padfMaxBound` is actually a pointer to an array of 4 elements: in shapelib/shpopen.c: SHPGetInfo: starting line 823: for( i = 0; i 4; i++ ) { if( padfMinBound != NULL ) padfMinBound[i] = psSHP-adBoundsMin[i]; if( padfMaxBound != NULL ) padfMaxBound[i] = psSHP-adBoundsMax[i]; } This also explains why it does not segfault when you pass a null pointer: no array out of bounds happen then. padfMaxBound should point to a `double []` or `double [4]` instead of a mere `double`. I also ended checking the API documentation (http://shapelib.maptools.org/shp_api.html) and they do document that padfMinBound and padfMaxbound are pointers to 4 values X, Y, Z and M in a four entry array. You may want to check if there isn't any other of those C tricks hiding in your D bindings. Good catch. Now that you pointed it out I cannot for the life of me figure out why I didn't think to check that! To make matters worse I didn't even have to go check the CVS, because I compiled the library from source and had all the C code sitting just a couple of 'cd's away. For some reason it never occurred to me that it might be expecting an array - even though one might reasonably assume that the bounds on a multidimensional dataset would have more than one dimension. Thank you. On 12/07/2013 04:29 PM, Craig Dillabaugh wrote: Hello, I recently wrote bindings to the C-library Shapelib (it reads/writes a common file format used in Geographic Information Systems). I've been trying to write a small test program to make sure my bindings 'work' and I've come across a bizarre memory bug. I THINK I've identified the code that causes the problem, but I have no idea why. My test-suite includes this function: void shapeRead(string filename) { SHPHandle hShp = SHPOpen( std.string.toStringz( filename ), rb ); int n, shp_type; double pad_min_bound, pad_max_bound; SHPGetInfo( hShp, n, shp_type, pad_min_bound, pad_max_bound); SHPClose( hShp ); } If I comment out the SHPGetInfo call, then the segmentation fault doesn't happen, but if its there then the program segfaults AFTER the shapeRead function exits (eg. SHPClose runs fine) ). In fact if I call SHPGetInfo as follows, the crash doesn't occur: SHPGetInfo( hShp, n, shp_type, pad_min_bound, null); //NULL pointer last arg. So in C the function SHPGetInfo is: void SHPAPI_CALL SHPGetInfo( SHPHandle hSHP, int * pnEntities, int * pnShapeType, double * padfMinBound, double * padfMaxBound ); While my D binding is (pretty much the same): extern( C ) void SHPGetInfo( SHPHandle hSHP, int* pnEntities, int* pnShapeType, double* padfMinBound, double* padfMaxBound ); I have no idea what is going on. The sizes of ints and doubles are 4 and 8 bytes using gcc on my system (which is how I compiled my C library) so those match the sizes of the corresponding D types [I thought maybe there was a type-size mismatch and that was causing something to be overwritten, but it doesn't appear that way]. Any hints on where to look next would be appreciated. Craig
Re: Help Finding Strange Memory Bug (Code linked to C library)
On Saturday, 7 December 2013 at 23:35:49 UTC, Ali Çehreli wrote: On 12/07/2013 03:11 PM, Rémy Mouëza wrote: the last pointer, `double * padfMaxBound` is actually a pointer to an array of 4 elements: Great sleuthing! :) This thread is a good example of C's Biggest Mistake: http://www.drdobbs.com/architecture-and-design/cs-biggest-mistake/228701625 Ali If by C's Biggest Mistake you mean Craig's Biggest Mistake you are incorrect. As hard as it may be to imagine I've done even dumber things:o) It is too bad that when I do do something dumb I tend to post about it on the internet! Cheers
Help Finding Strange Memory Bug (Code linked to C library)
Hello, I recently wrote bindings to the C-library Shapelib (it reads/writes a common file format used in Geographic Information Systems). I've been trying to write a small test program to make sure my bindings 'work' and I've come across a bizarre memory bug. I THINK I've identified the code that causes the problem, but I have no idea why. My test-suite includes this function: void shapeRead(string filename) { SHPHandle hShp = SHPOpen( std.string.toStringz( filename ), rb ); int n, shp_type; double pad_min_bound, pad_max_bound; SHPGetInfo( hShp, n, shp_type, pad_min_bound, pad_max_bound); SHPClose( hShp ); } If I comment out the SHPGetInfo call, then the segmentation fault doesn't happen, but if its there then the program segfaults AFTER the shapeRead function exits (eg. SHPClose runs fine) ). In fact if I call SHPGetInfo as follows, the crash doesn't occur: SHPGetInfo( hShp, n, shp_type, pad_min_bound, null); //NULL pointer last arg. So in C the function SHPGetInfo is: void SHPAPI_CALL SHPGetInfo( SHPHandle hSHP, int * pnEntities, int * pnShapeType, double * padfMinBound, double * padfMaxBound ); While my D binding is (pretty much the same): extern( C ) void SHPGetInfo( SHPHandle hSHP, int* pnEntities, int* pnShapeType, double* padfMinBound, double* padfMaxBound ); I have no idea what is going on. The sizes of ints and doubles are 4 and 8 bytes using gcc on my system (which is how I compiled my C library) so those match the sizes of the corresponding D types [I thought maybe there was a type-size mismatch and that was causing something to be overwritten, but it doesn't appear that way]. Any hints on where to look next would be appreciated. Craig
Re: How to convert these constructs to D?
On Sunday, 1 December 2013 at 18:51:51 UTC, Gary Willoughby wrote: On Sunday, 1 December 2013 at 03:20:49 UTC, Craig Dillabaugh wrote: On Saturday, 30 November 2013 at 14:53:35 UTC, Gary Willoughby wrote: I'm porting some C headers and wondered how would i convert the following to D: #define pthread_self() GetCurrentThreadId() #define pthread_handler_t void * __cdecl typedef void * (__cdecl *pthread_handler)(void *); #define set_timespec_nsec(ABSTIME,NSEC) { \ GetSystemTimeAsFileTime(((ABSTIME).tv.ft)); \ (ABSTIME).tv.i64+= (__int64)(NSEC)/100; \ (ABSTIME).max_timeout_msec= (long)((NSEC)/100); \ } Maybe you have already solved all your problems, but have you tried DStep with this header? I used it on FFTW3, which is basically one GIANT C 100 line macro, and it 'seems' to have done a great job on that. However, in other cases it just seems to have dropped some defines altogether, so your mileage may vary. Craig To be honest i didn't. The last time i tried DStep i had problems with compilation. I'll take another look though. I'm basically porting all the mysql-client headers which i thought would be pretty straight forward but it's taking a little more thought than i anticipated. I think you end up with a bit nicer interface if you hand role your own, but at least DStep can take care of a good bit of the grunt work for you. I had some trouble getting it running the first time (mostly my own fault), but am now glad I made the effort.
Re: How to convert these constructs to D?
On Saturday, 30 November 2013 at 14:53:35 UTC, Gary Willoughby wrote: I'm porting some C headers and wondered how would i convert the following to D: #define pthread_self() GetCurrentThreadId() #define pthread_handler_t void * __cdecl typedef void * (__cdecl *pthread_handler)(void *); #define set_timespec_nsec(ABSTIME,NSEC) { \ GetSystemTimeAsFileTime(((ABSTIME).tv.ft)); \ (ABSTIME).tv.i64+= (__int64)(NSEC)/100; \ (ABSTIME).max_timeout_msec= (long)((NSEC)/100); \ } Maybe you have already solved all your problems, but have you tried DStep with this header? I used it on FFTW3, which is basically one GIANT C 100 line macro, and it 'seems' to have done a great job on that. However, in other cases it just seems to have dropped some defines altogether, so your mileage may vary. Craig
How to pass a null pointer to a C function
Since questions about calling C from D seem to be popular today, I thought I would throw this one out there. I am trying to call a C function which takes as parameters several arrays of doubles. It is valid to have some arrays passed a NULL pointers in the C code. To call this from D I've come up with the following, but it seems like a bit of a hack. double[] x1 = [ 2.4, 3.7, 9.7, 4.5 ]; double[] y1 = [ 2.4, 9.8, 9.1, 3.4 ]; double[] empty; SHPObject*[] shape_ptrs; shape_ptrs ~= SHPCreateSimpleObject( SHPT_POLYGON, to!int(x1.length), x1.ptr, y1.ptr, empty.ptr ); It should be clear what is going on. A POLYGON is defined as a set of points (provided as arrays of doubles), with X,Y and optional Z coordinates. In this case I want a 2D polygon, so I want the final Z array to be empty. I wanted to just write 0 as the final parameter, but that didn't work, so I tried to!(double*)(0), and that didn't make the compiler happy either. I guess using the empty.ptr bit makes sense, in that the final array is meant to be empty, so pass it a pointer to an empty array. But it seems a bit hackish that I need to declare an additional empty array just to call this function. Is there an accepted 'proper' way of passing NULL pointers to C functions from D?
Re: How to pass a null pointer to a C function
On Sunday, 1 December 2013 at 04:11:57 UTC, Simen Kjærås wrote: On 2013-12-01 04:46, Craig Dillabaugh wrote: Since questions about calling C from D seem to be popular today, I thought I would throw this one out there. I am trying to call a C function which takes as parameters several arrays of doubles. It is valid to have some arrays passed a NULL pointers in the C code. To call this from D I've come up with the following, but it seems like a bit of a hack. double[] x1 = [ 2.4, 3.7, 9.7, 4.5 ]; double[] y1 = [ 2.4, 9.8, 9.1, 3.4 ]; double[] empty; SHPObject*[] shape_ptrs; shape_ptrs ~= SHPCreateSimpleObject( SHPT_POLYGON, to!int(x1.length), x1.ptr, y1.ptr, empty.ptr ); It should be clear what is going on. A POLYGON is defined as a set of points (provided as arrays of doubles), with X,Y and optional Z coordinates. In this case I want a 2D polygon, so I want the final Z array to be empty. I wanted to just write 0 as the final parameter, but that didn't work, so I tried to!(double*)(0), and that didn't make the compiler happy either. I guess using the empty.ptr bit makes sense, in that the final array is meant to be empty, so pass it a pointer to an empty array. But it seems a bit hackish that I need to declare an additional empty array just to call this function. Is there an accepted 'proper' way of passing NULL pointers to C functions from D? Well, there is null. -- Simen Simen and Mike. Thanks! Now I feel stupid.
Re: Two Questions about Linking to C libraries
On Wednesday, 27 November 2013 at 07:30:58 UTC, Jacob Carlborg wrote: On 2013-11-27 02:26, Craig Dillabaugh wrote: 2. Once I think my bindings are stable I would like to add them to Deimos or DUB registries. Are there any recommendations for testing bindings? I checked through some other bindings on GitHub and didn't see any unit tests or the like. Are there any 'best practices' out there for testing bindings? I don't think there's an easy way to do unit testing for bindings. What you could do is port the original unit tests if available. Or create some new unit tests if none exists. Thanks. There were no unit tests with the original code. I will take a shot at it.
Two Questions about Linking to C libraries
I recently created bindings to the C libary shapelib. http://shapelib.maptools.org/ I generated my own bindings by hand, and another set of bindings with DStep. I created a small test program to test my bindings. My current test program in its entirety is: import std.stdio; import std.string; import std.conv; import shapefil; int main( string args[] ) { const char* filename = std.string.toStringz( args[1] ); SHPHandle hShp = SHPOpen(filename, rb); int num_entities; int shp_type; double pad_min_bound; double pad_max_bound; SHPGetInfo( hShp, num_entities, shp_type, pad_min_bound, pad_max_bound); writeln(Shapefile contains ~ to!string(num_entities) ~ entities.); writeln(Of type ~ to!string( SHPTypeName( shp_type) )); writeln(Bounds = [ ~to!string(pad_min_bound) ~ , ~ to!string(pad_max_bound) ~ ]); SHPClose( hShp ); return 0; } It simply reads a Shape File, the name for which is passed from the command line. When I execute this I get the following message: ./shapetest data/dresden/gis.osm_water_v06.shp Shapefile contains 799 entities. Of type Polygon Bounds = [13.5274,50.9632] Segmentation fault The first three lines output are what I expected, but then it segfaults on exit. Running it in GDB I get the following error message: Program received signal SIGSEGV, Segmentation fault. 0x00443fc7 in rt.dmain2._d_run_main() () Printing the backtrace provides no additional information. The same problem occurs whether I used my hand-rolled binds or the DStep version. So my two questions are: 1. Does anyone have any idea why my program is segfaulting. It seems to crash at exit and I read somewhere (can't recall where) that uncollected C style strings may cause the GC to fail. Perhaps this is my problem. I tried commenting out some of the statements (eg. the SHPTypeName( shp_type) line, which returns a const char *, but I still get a segfault. Any ideas on how to find the root cause? 2. Once I think my bindings are stable I would like to add them to Deimos or DUB registries. Are there any recommendations for testing bindings? I checked through some other bindings on GitHub and didn't see any unit tests or the like. Are there any 'best practices' out there for testing bindings?
Re: Two Questions about Linking to C libraries
On Wednesday, 27 November 2013 at 02:36:01 UTC, Jesse Phillips wrote: Don't have answers. Do you still get segfault removing SHPClose( hShp ); Yep. Other comment: writeln(Bounds = [ ~to!string(pad_min_bound) ~ , ~ to!string(pad_max_bound) ~ ]); writeln(Bounds = [, pad_min_bound, ,, pad_max_bound, ]); Thanks, thats look a bit nicer.
Re: Immutable Red-Black trees
On Tuesday, 26 November 2013 at 00:28:34 UTC, bearophile wrote: Bartosz Milewski has written the second article about immutable data structures in C++11, this time about Red-Black trees: http://bartoszmilewski.com/2013/11/25/functional-data-structures-in-c-trees/ The C++11 code with few small changes (like using enum class instead of enum): http://codepad.org/AEVVnfSc D has GC and transitive immutability, so I have tried a D translation, a first draft: http://dpaste.dzfl.pl/a48452af3 In the D code there are some problems with C++ lines as: return RBTree(Color::R, RBTree(), x, RBTree()); And I don't know if this is public: Color rootColor() const { Bye, bearophile What do you mean by an 'immutable' data structure. The linked article talks about Persistent data structures. Are these the same thing? When I saw Immutable I figured it didn't support insertion/deletion - which would sort eliminate the need for a Red-Black tree anyways.
Re: Immutable Red-Black trees
On Tuesday, 26 November 2013 at 01:21:49 UTC, Craig Dillabaugh wrote: On Tuesday, 26 November 2013 at 00:28:34 UTC, bearophile wrote: clip Bye, bearophile What do you mean by an 'immutable' data structure. The linked article talks about Persistent data structures. Are these the same thing? When I saw Immutable I figured it didn't support insertion/deletion - which would sort eliminate the need for a Red-Black tree anyways. While I am at it, I might as well ask another question. How is it that your 'insert' function is const? I thought I understood const, but apparently not! Cheers
Re: Immutable Red-Black trees
On Tuesday, 26 November 2013 at 01:31:11 UTC, bearophile wrote: Craig Dillabaugh: What do you mean by an 'immutable' data structure. The linked article talks about Persistent data structures. Are these the same thing? When I saw Immutable I figured it didn't support insertion/deletion - which would sort eliminate the need for a Red-Black tree anyways. In those articles Bartosz is implementing in C++11 the immutable data structures from the book by Okasaki. Immutable doesn't mean you can't change them :-) It means you can't modify the single data items, and you have referential transparency. Bye, bearophile Ok, that make sense.
Re: DStep
On Sunday, 24 November 2013 at 13:05:04 UTC, Jacob Carlborg wrote: On 2013-11-24 06:37, Craig Dillabaugh wrote: Thanks. That is how I started out trying to fix it (Well, I used symlinks rather than copy the files, but basically the same). I got it to stop complaining about stddef.h and stdarg.h, but at the third header (can't recall something obscure though) I gave up because I figured I was going to be adding symlinks to half the headers on my system! Thats when I decided to try compiling from scratch. You need some kind of hearers, either system headers or headers from Clang. stddef.h and stdarg.h are somewhat special headers, they're builtin includes and you need to get them from Clang. I have clang installed on my machine. Is there anyway to point dstep to the right headers when I invoke it? Is this issue supposed to be fixed with new versions of clang? I don't know, I don't think so. No I hadn't tried that. I will give it a shot. You will need Tango as well. All this is in the readme. Please let me know if there's something that is not clear in the readme. I already got Tango working - that was clear from your docs. At first I resisted, figuring I was sure to have problems getting Tango to work (Murphy's Law seems to apply strongly for me), but Tango turned out to be a piece of cake. I will give compiling DStep another shot in the next day or two and report back!
Re: DStep
On Sunday, 24 November 2013 at 14:04:32 UTC, Jacob Carlborg wrote: On 2013-11-24 14:58, Craig Dillabaugh wrote: I have clang installed on my machine. Is there anyway to point dstep to the right headers when I invoke it? Yes, use the -I flag. In addition to the listed flags, DStep accept all flags Clang accepts. I already got Tango working - that was clear from your docs. At first I resisted, figuring I was sure to have problems getting Tango to work (Murphy's Law seems to apply strongly for me), but Tango turned out to be a piece of cake. I will give compiling DStep another shot in the next day or two and report back! I plan to use dub to compile DStep. So the following command works (at least on my system): dstep -I/usr/lib64/clang/3.2/include shapefil.h Thanks for your help.
Re: DStep
On Saturday, 23 November 2013 at 20:16:32 UTC, Jacob Carlborg wrote: On 2013-11-22 15:35, Craig Dillabaugh wrote: I am trying to use DStep on OpenSuse 12.3. I downloaded one of the binaries (it was for Debian, so I guess that is my problem), and when I run DStep I get the following error: craigkris@linux-s9qf:~/code/DShape/D dstep shapefil.h File(850DF8, )/usr/include/stdio.h:33:11: fatal error: 'stddef.h' file not found Unfortunately this is a known issue. What I did is was to place stddef.h and stdarg.h (shipped with Clang) into /use/include. Please see the readme for more info. Thanks. That is how I started out trying to fix it (Well, I used symlinks rather than copy the files, but basically the same). I got it to stop complaining about stddef.h and stdarg.h, but at the third header (can't recall something obscure though) I gave up because I figured I was going to be adding symlinks to half the headers on my system! Thats when I decided to try compiling from scratch. Is this issue supposed to be fixed with new versions of clang? https://github.com/jacob-carlborg/dstep#libclang build.sh dstep/driver/Application.d(13): Error: module Application is in file 'dstack/application/Application.d' which cannot be read Did you clone the submodules? Run: $ git clone --recursive g...@github.com:jacob-carlborg/dstep.git No I hadn't tried that. I will give it a shot. I am actually not urgently in need of DStep for my current project anymore, since my hand-written bindings seem to be doing the trick. However, as this was my first bind D to C attempt, I wanted to run DStep and see how close my bindings come to its output. Once I have my small initial project working though I am hoping to write bindings to a much larger library, and DStep would certainly come in handy there :o) Cheers, Craig
Re: Optimization tips for alpha blending / rasterization loop
On Friday, 22 November 2013 at 10:27:12 UTC, bearophile wrote: Craig Dillabaugh: Do you want to use a ubyte instead of a byte here? See: http://d.puremagic.com/issues/show_bug.cgi?id=3850 Bye, bearophile Yes it is pretty easy to mix that up. A lot of my work is with images with single byte pixels, so I am pretty used to using ubyte now. I can't remember if I ever used byte, and if I did I was likely a bug. Craig
DStep
I am trying to use DStep on OpenSuse 12.3. I downloaded one of the binaries (it was for Debian, so I guess that is my problem), and when I run DStep I get the following error: craigkris@linux-s9qf:~/code/DShape/D dstep shapefil.h File(850DF8, )/usr/include/stdio.h:33:11: fatal error: 'stddef.h' file not found This seems to be some problem with clang (when I googled around I found similar errors). I actually started trying to fix this by adding symlinks to the offending header files in my /usr/include folder, but that is looking like a losing proposition. Has anyone successfully overcome this before. I also tried downloading dstep from gitHub and building from scratch, but I am getting all sort of errors there (eg.) build.sh dstep/driver/Application.d(13): Error: module Application is in file 'dstack/application/Application.d' which cannot be read Any help would be appreciated. Craig
Re: std.json
On Monday, 26 March 2012 at 07:14:50 UTC, Ali Çehreli wrote: On 03/25/2012 08:26 AM, AaronP wrote: Could I get a hello, world example of parsing json? The docs look simple enough, but I could still use an example. For what it's worth, I've just sent the following program to a friend before seeing this thread. 1) Save this sample text to a file named json_file { employees: [ { firstName:John , lastName:Doe }, { firstName:Anna , lastName:Smith }, { firstName:Peter , lastName:Jones } ] } 2) The following program makes struct Employee objects from that file: import std.stdio; import std.json; import std.conv; import std.file; struct Employee { string firstName; string lastName; } void main() { // Assumes UTF-8 file auto content = to!string(read(json_file)); JSONValue[string] document = parseJSON(content).object; JSONValue[] employees = document[employees].array; foreach (employeeJson; employees) { JSONValue[string] employee = employeeJson.object; string firstName = employee[firstName].str; string lastName = employee[lastName].str; auto e = Employee(firstName, lastName); writeln(Constructed: , e); } } The output of the program: Constructed: Employee(John, Doe) Constructed: Employee(Anna, Smith) Constructed: Employee(Peter, Jones) Ali So I was thinking of adding an example to the std.json documents, and was going to ask to rip-off Ali's example here. However, I thought I would be nice to have an example going the other way (ie. taking some data structure and converting to JSON format). I came up with the following using Ali's Employee struct: /** * Generate a JSON string from an array of employees using std.json, * even though the code to generate the same by hand would be shorter * and easier to follow :o) */ string employeesToJSON( Employee[] employees ) { JSONValue emp_array; emp_array.type = JSON_TYPE.ARRAY; emp_array.array = []; foreach( e; employees ) { JSONValue emp_object; emp_object.type = JSON_TYPE.OBJECT; emp_object.object = null; JSONValue first_name; first_name.str = e.firstName; first_name.type = JSON_TYPE.STRING; JSONValue last_name; last_name.str = e.lastName; last_name.type = JSON_TYPE.STRING; emp_object.object[firstName] = first_name; emp_object.object[lastName] = last_name; emp_array.array ~= emp_object; } JSONValue root; root.type = JSON_TYPE.OBJECT; root.object[] = emp_array; return toJSON( root ); } Then if I call it using the following code: Employee[] employees = [ { Walter, Bright }, { Andrei, Alexandrescu}, { Celine, Dion } ]; writeln( employeesToJSON( employees ) ); It prints out: {:[{lastName:Bright,firstName:Walter},{lastName:Alexandrescu,firstName:Andrei},{lastName:Dion,firstName:Celine}]} Which isn't exactly what I want as I have the extra at the start. So I have two questions: 1. Is there a nicer way to generate my JSONValue tree. 2. How do I insert my JSONValue.array of employees into my root JSONValue. I tried: root.object[] = emp_array; // generates { : [ ... } root.object[null] = emp_array; // generates { : [ ... } root.object = emp_array; //Syntax error //Error: cannot implicitly convert expression //(emp_array) of type JSONValue to JSONValue[string] I want my returned string as { [ ... ] } Cheers, Craig
Re: std.json
On Wednesday, 20 November 2013 at 13:20:48 UTC, Dicebot wrote: For tasks that imply conversion between D types and JSON text (alike to serialization), vibe.d module is really much superior because it provides functions like http://vibed.org/api/vibe.data.json/serializeToJson which just work on many user types. I absolutely agree. However, I wanted to come up with an example for std.json, and this mess was the best I could do. I was curious if someone could come up with a nicer mess than mine. Also for small jobs it might be preferable to use std.json - if you don't want the vibe.d dependency.
Re: std.json
On Wednesday, 20 November 2013 at 13:29:54 UTC, Dicebot wrote: What I mean is that std.json does not seem to be written with such usage mode in mind, it is more about direct DOM manipulation/construction. So probably examples should probably not highlight how bad it is at tasks it is really bad at :P So I was basically wasting my time trying to figure out how to drive a nail with a screwdriver :o)
Re: std.json
On Wednesday, 20 November 2013 at 13:48:37 UTC, Orvid King wrote: On 11/20/13, Craig Dillabaugh cdill...@cg.scs.carleton.ca wrote: On Wednesday, 20 November 2013 at 13:29:54 UTC, Dicebot wrote: What I mean is that std.json does not seem to be written with such usage mode in mind, it is more about direct DOM manipulation/construction. So probably examples should probably not highlight how bad it is at tasks it is really bad at :P So I was basically wasting my time trying to figure out how to drive a nail with a screwdriver :o) But driving a nail with a screwdriver works very well! Or at least it does if you have a large enough screwdriver :P Regardless, if your looking to avoid the vibe.d dependency, my serialization framework does support JSON, and still has the simple API that vibe.d's module does. https://github.com/Orvid/JSONSerialization Thanks, I may have a look. Craig
Re: T[] (array of generic type)
On Monday, 18 November 2013 at 20:32:25 UTC, Philippe Sigaud wrote: On Mon, Nov 18, 2013 at 9:20 PM, seany se...@uni-bonn.de wrote: I read that book, but dont find this constructtion, that is why the question. IIRC I talk a bit about function templates in my tutorial. JR gave the link (thanks!), another, more direct way is to directly download the pdf: https://github.com/PhilippeSigaud/D-templates-tutorial/blob/master/D-templates-tutorial.pdf (click on `view raw` to download) Try p. 28 and following. And I really should take the time to write this thing again... From scratch? :0)
Instantiating templates where type is known only at run time
this question came up in some C++ work I am doing, but since the solutions are likely nicer in D, I wanted to ask how it could be solved in D. First for some motivation. I am doing image processing work where the images are simply an array of data, where the data type can be any numeric type. The data is stored as binary files and assume I have some way of figuring out the data type for an image. Say I want to implement the function along the following lines, and imagine I have a sane reason for wanting to do such a thing: // Assume images are of the same dimensions. Result is // saved in Out. void add(T,U,V)(Image!T A, Image!U B, Image!V Out) { ... } Now assume I have three variables ImgAType, ImgBType, and ImgCType (I refer to these variables without specifying their type, but hopefully it is clear what is going on) then to implement add() I end up with a lengthy if..else statement or nasty nested switch ... case statements to handle all the possible combinations of ubyte, short, uint, float, double for each of the three image types. I will use an if() version example: if( ImgAType == SHT ImgBType == UINT ImgCType == DBL ) { Image!short A = new Image!short( filename_of_A ); Image!uint B = new Image!uint( filename_of_B ); Image!double Out = new Image!double( filename_of_Out ); add(A,B,Out); } else { //next case and so on } Since the types can be any numeric type there are a lot of 'combinations' of images. I won't add a float and double together and generate a ubyte image, but there are still many valid combinations. However, any way you slice it you end up with a very long, repetitive bunch of code. A co-worker of mine came up with (or found) the following solution. I thought is was clever. It cuts down on repetitive code, but man is it ugly: void add( ImgAType, ImgBType, ImgCType, //File names ) { if( ImgAType == UBYTE) AddStep1!ubyte(ImgBType, ImgCType, //Files ); else if( ImgAType == SHT) AddStep1!short(ImgBType, ImgCType, //Files ); //and so on } void AddStep1(T)(ImgBType, ImgCType, //File names ) { if( ImgBType == UBYTE) AddStep2!(T,ubyte)(ImgCType, //Files ); else if( ImgBType == SHT) AddStep2!(T,short)(ImgCType, //Files ); //and so on. } void AddStep2(T,U)(ImgCType, //File names ) { if( ImgCType == UBYTE) AddStep3!(T,U,ubyte)( //Files ); else if(ImgCType == SHT) AddStep3!(T,U,short)( //Files ); //and so on } void AddStep3(T,U,V)( //File names ) { //Do the actual work! } Anyway, I hope that is clear what we are trying to do. So my question is, is there a nice way in D to instantiate all the necessary templated functions, and call the correct version at run time, without resorting one of the methods above. Anyway, thanks to whoever takes the time to read all that, let alone come up with an answer.
Re: Instantiating templates where type is known only at run time
On Tuesday, 19 November 2013 at 12:53:50 UTC, bearophile wrote: Craig Dillabaugh: // Assume images are of the same dimensions. Result is // saved in Out. void add(T,U,V)(Image!T A, Image!U B, Image!V Out) { ... } Take a look at the out annotation in D. Anyway, thanks to whoever takes the time to read all that, let alone come up with an answer. In D there is no type switch but there are type tuples, where you can put a sequence of all your types, and you can iterate on them statically with a foreach, to instantiate your templates. So your C++ code probably becomes nicer in D. Bye, bearophile Thanks very much. Craig
Re: Using reduce() with tuples created by zip()
On Friday, 1 November 2013 at 20:08:15 UTC, Philippe Sigaud wrote: What I'm trying to explain is that reduce takes two arguments: the growing value and the current front. In your case, the current front is indeed a 2-tuple, but that's an unrelated issue. You're trying to get: reduce!( (firstElemOfPair, secondElemOfPair) = ...) (range) to work, whereas reduce signature is: reduce!( (onGoingValue, elem) = ...) (range) OK, NOW I understand what you were trying to point out. The function has to take the running sum (in my case) as one of the arguments. Thanks for your patience.
Re: Using reduce() with tuples created by zip()
On Friday, 1 November 2013 at 09:31:41 UTC, Philippe Sigaud wrote: On Thu, Oct 31, 2013 at 8:59 PM, Craig Dillabaugh cdill...@cg.scs.carleton.ca wrote: Thanks, I will try both your, and Bearophile's ideas and see if I can figure out how they work. reduce takes a range and eagerly (that is, not lazily) builds a value from it. In your case, it builds the squared distance between two points. The returned value can be anything: a numerical value, but also another range, a complex object, an so on. As long as it can be built increasingly, you're good. Given a range [a,b,c,..., z] and a binary function f, reduce!(f)([a,b,c,...]) calculates f(a,b), then f(f(a,b), c), up to f(... f( f( f(a,b),c), d), ...,z). The only question is whether you give it a seed value, or if it takes the first range element as seed (f(seed, a), f(f(seed,a),b) and son on). std.algorithm.reduce provides both overloads. Note the only thing you get is the final result, not the internal f(f(...'s applications. If you want a sum: reduce!( (result,elem) = result + elem )(range) or reduce!( (result,elem) = result + elem )(range, 0) Sum of squares: reduce!( (result, elem) = result + elem^^2 )(range, 0) In your case, the basic element is a tuple, coming from zip. Access to the two elements is done with [0] or [1]. So: reduce!( (result, elem) = result + (elem[0]-elem[1])^^2 )(zippedRange, 0) This is really where my problem arose. I understood everything up to here, but I sort of had this idea, hey zip returns a tuple so that somehow the compiler was going to figure out for me that function(e) has two values and is thus a binary function so this should work (the 0.0 on the end was my start value): reduce!(function(e) { return (e[1]-e[0])*(e[1]-e[0]); })(0.0) However, of course the compiler see's the tuple as just one value - which is where I made my mistake. Of course, it would be easy to write a small n-range reduce helper function, that takes n ranges and reduces them in parallel: reduce!( (result, a, b) = result + (a-b)^^2 )(rangeA, rangeB, 0) Note that reduce is a versatile function: you can duplicate filter and map functionalities with it. The only thing to remember is that, compared to other iteration algorithm/ranges, it's eager. Don't use it on an infinite range! We could also have a slightly different version that lazily produces the intermediate results as a range. IIRC, it's called 'scan' in Haskell. It's sometimes interesting to have it: you can interrupt the ongoing calculation when the result is 'good enough', not waiting for the entire input range to be consumed.
Re: Using reduce() with tuples created by zip()
On Friday, 1 November 2013 at 18:44:23 UTC, Philippe Sigaud wrote: reduce!( (result, elem) = result + (elem[0]-elem[1])^^2 )(zippedRange, 0) This is really where my problem arose. I understood everything up to here, but I sort of had this idea, hey zip returns a tuple so that somehow the compiler was going to figure out for me that function(e) has two values and is thus a binary function so this should work (the 0.0 on the end was my start value): reduce!(function(e) { return (e[1]-e[0])*(e[1]-e[0]); })(0.0) However, of course the compiler see's the tuple as just one value - which is where I made my mistake. The problem is not tuple, it's that reduce needs a binary function to work. Yes, that is more or less what I was trying to say. I was figuring that the compiler could figure out that 'e' was really a pair of values, thus making function(e) binary. Of course, that is asking too much from the compiler.
Using reduce() with tuples created by zip()
I am trying to calculate the Euclidean Distance between two points. I currently have the following function (that doesn't compile): double euclid_dist( double[] pt1, double[] pt2 ) { assert( pt1.length == pt2.length ); return sqrt( zip(pt1, pt2).reduce!(function(e) { return (e[1]-e[0])*(e[1]-e[0]); })(0.0) ); } Hopefully it is clear what I am trying to do. I want zip to create a range that is a tuple of the point's coordinate pairs, and then use reduce to sum the squared differences. I get the following error but can't figure out how to fix my syntax: euclid.d(13): Error: template euclid.euclid_dist.reduce!(__funcliteral2).reduce does not match any function template declaration. Candidates are: /usr/include/dmd/phobos/std/algorithm.d(688): euclid.euclid_dist.reduce!(__funcliteral2).reduce(Args...)(Args args) if (Args.length 0 Args.length = 2 isIterable!(Args[__dollar - 1])) euclid.d(13): Error: template euclid.euclid_dist.reduce!(__funcliteral2).reduce(Args...)(Args args) if (Args.length 0 Args.length = 2 isIterable!(Args[__dollar - 1])) cannot deduce template function from argument types !()(Zip!(double[], double[]), double) Failed: 'dmd' '-v' '-o-' 'euclid.d' '-I.' I know I could use a simple foreach loop with my zip command, or even std.numeric.euclidean( ... ), but I am trying to be cute here! Cheers, Craig
Re: Using reduce() with tuples created by zip()
On Thursday, 31 October 2013 at 19:23:56 UTC, Philippe Sigaud wrote: I think reduce takes two arguments: the growing seed and the current front. You're trying to get (a[0]-b[0])^^2 + (a[1]-b[1])^^2 + ..., right? Yep. The (e[1]-e[0])*(e[1]-e[0]) bit was, I supposed was effectively calculating (a[0]-b[0])^^2 and so on. I forgot about the ^^2 in D. Try this: module euclid; import std.stdio; double euclid_dist( double[] pt1, double[] pt2 ) { assert( pt1.length == pt2.length ); import std.algorithm; import std.math; import std.range; return sqrt(0.0.reduce!( (sum,pair) = sum + (pair[0]-pair[1])^^2 )(zip(pt1, pt2))); } void main() { double[] arr1 = [0.0, 1.0, 0.1]; double[] arr2 = [1.0, -1.0, 0.0]; writeln(euclid_dist(arr1,arr2)); } On Thu, Oct 31, 2013 at 8:12 PM, Craig Dillabaugh cdill...@cg.scs.carleton.ca wrote: clip Cheers, Craig Thanks, I will try both your, and Bearophile's ideas and see if I can figure out how they work. Craig
Set variable at compile time
Hello, I am writing code that uses a structure containing an array of points where the points may be of arbitrary dimension (though generally small). I would like to be able to pass the point dimension to my structure as a template parameter. One solution is to create instances of these structures for all reasonable dimensions and then select the correct instance at run time I suppose. However, I don't really want to set a limit on the point dimension. Since the actual program is quite small, and the datasets I want to apply it to are generally going to be large, I thought it would make sense to generate the program from source for each 'run' and simply specify the dimension at compile time. But that is where I am stuck. I looked at the compiler switches (http://dlang.org/dmd-linux.html) but if there is a compiler switch to do this I missed it. I suppose I could use version() statements, but that seems like a bit of a hack. So my question is, is there some straightforward way of doing what I want here. Cheers, Craig
Re: Set variable at compile time
On Wednesday, 30 October 2013 at 20:19:11 UTC, Adam D. Ruppe wrote: It won't really work on the command line alone, but the way I do it is a two step thing. First, make the thing use a config module: import myproject.config; alias Thing Thing_Impl!dim; then you go ahead and use Thing, which is instantiated with the dimension. Then the user makes a file: module myproject.config; enum dim = 10; // or whatever and compiles it all: dmd main.d yourlib.d config.d and it works out. They can swap out config.d for other files with other values and definitions on the command line to customize it. It would also be possible to provide a default if you go with the whole library route, compiling the default into the .lib and giving the default in the project include path, both of which would be overridden by the user's explicit config source file on the command line. So not as simple as -Ddim=10, but gets the job done. You can also use this technique with static if to version stuff out they don't want and other similar tasks; I actually like it better than -version for the most part. This should work for what I want, and I was thinking of something along these lines, but was hoping there might be a simpler solution. Craig
Re: Set variable at compile time
On Wednesday, 30 October 2013 at 20:23:58 UTC, Ali Çehreli wrote: On 10/30/2013 01:11 PM, Craig Dillabaugh wrote: I am writing code that uses a structure containing an array of points where the points may be of arbitrary dimension (though generally small). I would like to be able to pass the point dimension to my structure as a template parameter. struct Point {} struct S(size_t N) { Point[N] points; } alias S2D = S!2; alias S3D = S!3; void main() {} One solution is to create instances of these structures for all reasonable dimensions and then select the correct instance at run time I suppose. Do you need a common interface, or all of the algoritms will be templatized as well? In other words, what is the type that the following function returns? ??? selectInstance(size_t N) { // return S2D or S3D? } You can have an interface that the template implements: interface SInterface { void foo(); } class S(size_t N) : SInterface { Point[N] points; void foo() { /* implementation for N */ } } Now selectInstance() returns SInterface: SInterface selectInstance(size_t N) { // ... } However, I don't really want to set a limit on the point dimension. All of the instances must be known at compile time. So, your program is always limited with the number of actual instances that the program is using. Ali Ali thanks. The algorithms will be templatized as well. As you point out, I need to know all instances at compile time, but want to 'get around' this, thus my idea of compiling the specific instance I need. Adam's idea should work. I like the interface idea, but just to make sure I understand the purpose - you use the interface to provide a common interface so that the instantiated objects can be used by algorithms which do not have any knowledge of the particular dimension of a given point. Is that correct? Craig
Re: Conflict between std.file write() and std.stdio write()
On Saturday, 5 October 2013 at 02:42:54 UTC, Jonathan M Davis wrote: On Friday, October 04, 2013 16:12:14 Craig Dillabaugh wrote: I guess the more fundamental question is, what is the purpose of the documentation? Is it a quick reference for D users, or is it a resource for people trying to learn the language? I learned C++ using Qt, largely from their online docs. The Qt documentation is a reference, but it also tends to provide lots of explanation. It would never have occurred to me that API documentation would be use for teaching the language - even documentation for the standard library. I would expect people to learn the language first. Yes, the standard library documentation needs to be reasonably accessible to newbies, but I would not expect it to be used as a teaching tool for the language. The documentation on a type or function is there to teach you about how to use that particular type or function, not how to use the language. Of course, I'm also the sort of person who thinks that people are nuts to just jump into a game without reading the entire manual first. - Jonathan M Davis Yes, but the manual (Andrei's book?) barely touches on the standard library (ranges are not even covered). Things are getting better now that Ali's book is getting closer to having a complete English translation. For whatever reason, when I first started trying to use Phobos, I found that the knowledge I had gathered from Andrei's book still left me dazed and confused at times. Cheers, Craig
Re: Conflict between std.file write() and std.stdio write()
On Thursday, 3 October 2013 at 21:58:18 UTC, Jonathan M Davis wrote: On Thursday, October 03, 2013 22:57:22 Craig Dillabaugh wrote: On Thursday, 3 October 2013 at 19:49:07 UTC, Jonathan M Davis wrote: On Thursday, October 03, 2013 20:57:20 Craig Dillabaugh wrote: On Thursday, 3 October 2013 at 18:12:01 UTC, Jonathan M Davis clip - Jonathan M Davis Fair enough. As you point out the fix is pretty simple. However, I can't seem to remember in C++ or any other language (not that I know all that many other languages) coming across a function in the standard library that conflicted with another function in the standard library in this way. I am likely to get corrected on that claim though :o) I'm sure that it could be found somewhere, but C++ avoids it for two reasons: 1. As good as the STL is, it's pathetically small. 2. It only uses one namespace, so it _has_ to avoid conflicts, even if that means using uglier names. Java or C# might have some conflicts (I'm not sure - they certainly have much richer standard libraries than C++ does), but they almost always avoid it, because they're don't even allow free functions, so you only end up having to worry about class names conflicting. Their module systems are also different from D's (particularly C#'s), which changes things a bit. Other languages like python tend to force you to give the full path anyway, which avoids conflicts. The reason that D runs into them is because the default is to pull everything into the current module when you import it. If we'd taken the approach of making you give the full import path by default or forcing you to explicitly import each symbol, then it wouldn't be a problem (though that would obviously cause other problems). And we'll definitely pick different names where appropriate, but if the best names for two different functions in two different modules happen to be the same name, then we're going to use it. And in same cases, we very purposely picked the same name, because the functions did the same type of thing (e.g. the functions in std.ascii and std.uni which do the same thing but for ASCII and Unicode respectively). - Jonathan M Davis That is an excellent explanation. Thank you. Do you think it would be worth noting the conflict in the documentation for readText()/write()? I should have mentioned in my original post that I likely could have figured out the workaround for this, and I posted here more because I was surprised that std.stdio and std.file would have a conflict! It seems like something folks new to D might run into with some frequency, and be thinking whats up with that!. If others think it is a good idea, maybe I will head over to gitHub and try to add something. I'm inclined to think that there's no need, since people learning D should know how the module system works, and I'd prefer not to clutter the documentation, but I also haven't been a newbie for a very long time. - Jonathan M Davis There are two problems with this for newbies: 1. They may not understand the module system well. 2. The may not know that a string = char array, and that as such it may not even occur to them that write() will accept a string. Now a careful reading of the docs for readText() should clue them in that string = char array, but when you are new to a language and trying to absorb the new syntax it is something that can easily be overlooked. I have just enough D experience now that for the most part I don't struggle to follow the documentation, but I remember when I was new to D I found it very frustrating. That is even after reading Anderi's book (maybe I am a slow learner, but I am likely fairly representative of the average coder!) Now part of that is the known shortage of documentation, but often example code can be hard to follow, for example, from write: int[] a = [ 0, 1, 1, 2, 3, 5, 8 ]; write(filename, a); assert(cast(int[]) read(filename) == a); Consider the final 'assert' line. On the one hand, it shows how to concisely use language features and good D coding practices, however, on the other hand there is an awful lot going on in a single line of code. To someone who knows the language it looks trivial, but it can be a bit overwhelming to a newbie who wants to see if they can use this new language to write some text to a file! I guess the more fundamental question is, what is the purpose of the documentation? Is it a quick reference for D users, or is it a resource for people trying to learn the language? I learned C++ using Qt, largely from their online docs. The Qt documentation is a reference, but it also tends to provide lots of explanation. I've seen both, documentation strictly as a reference for those who already know how to use it, and docs with more focus on explaining how things work to the uninitiated. I tend to like the later approach
Re: Conflict between std.file write() and std.stdio write()
On Thursday, 3 October 2013 at 02:57:50 UTC, Andrej Mitrovic wrote: On 10/3/13, Craig Dillabaugh cdill...@cg.scs.carleton.ca wrote: void main( string[] args ) { string str = Hello; write( file.txt, str ); string hello_file = readText(file.txt); writeln( hello_file ); } You can also disambiguate by preferring one symbol over another with an alias: alias write = std.file.write; void main( string[] args ) { string str = Hello; write( file.txt, str ); } You can also put the alias inside the function. Thanks. It seems that std.file should include a writeText() function for the sake of consistency that is the above alias. When you come across readText() in the documentation you sort of expect that such a function would exist, and then you spot write() below it, and think hey that does what I need. Then you hit upon the syntax error if you are also using std.stdio (which is a very commonly used module). Adding writeText() doesn't really add much to the library, but having to jump through hoops (as minor as they may be) to perform such a simple op is a bit of a pain for people new to the language. Craig
Re: Conflict between std.file write() and std.stdio write()
On Thursday, 3 October 2013 at 18:12:01 UTC, Jonathan M Davis wrote: On Thursday, October 03, 2013 15:22:28 Craig Dillabaugh wrote: It seems that std.file should include a writeText() function for the sake of consistency that is the above alias. When you come across readText() in the documentation you sort of expect that such a function would exist, and then you spot write() below it, and think hey that does what I need. Then you hit upon the syntax error if you are also using std.stdio (which is a very commonly used module). Adding writeText() doesn't really add much to the library, but having to jump through hoops (as minor as they may be) to perform such a simple op is a bit of a pain for people new to the language. writeText would be redundant. write will already write arbitrary data to a file - including strings. writeText would add no functionality. Functions should add actual value, or they just clutter up the library. Conflicting functions is just part of life. The module system is designed to let you disambiguate them. We're not going to try and make all of the function names unique just because you might import a module with a conflicting function. If write is the best name for the function, then that's what we'll use, even if it conflicts with a function in another module. To do otherwise would be to ignore the features of the module system and force us to come up with worse names just to avoid conflicts. - Jonathan M Davis Fair enough. As you point out the fix is pretty simple. However, I can't seem to remember in C++ or any other language (not that I know all that many other languages) coming across a function in the standard library that conflicted with another function in the standard library in this way. I am likely to get corrected on that claim though :o) Maybe it would be worth noting this conflict in the documentations for newbies. Craig
Re: Conflict between std.file write() and std.stdio write()
On Thursday, 3 October 2013 at 19:49:07 UTC, Jonathan M Davis wrote: On Thursday, October 03, 2013 20:57:20 Craig Dillabaugh wrote: On Thursday, 3 October 2013 at 18:12:01 UTC, Jonathan M Davis clip - Jonathan M Davis Fair enough. As you point out the fix is pretty simple. However, I can't seem to remember in C++ or any other language (not that I know all that many other languages) coming across a function in the standard library that conflicted with another function in the standard library in this way. I am likely to get corrected on that claim though :o) I'm sure that it could be found somewhere, but C++ avoids it for two reasons: 1. As good as the STL is, it's pathetically small. 2. It only uses one namespace, so it _has_ to avoid conflicts, even if that means using uglier names. Java or C# might have some conflicts (I'm not sure - they certainly have much richer standard libraries than C++ does), but they almost always avoid it, because they're don't even allow free functions, so you only end up having to worry about class names conflicting. Their module systems are also different from D's (particularly C#'s), which changes things a bit. Other languages like python tend to force you to give the full path anyway, which avoids conflicts. The reason that D runs into them is because the default is to pull everything into the current module when you import it. If we'd taken the approach of making you give the full import path by default or forcing you to explicitly import each symbol, then it wouldn't be a problem (though that would obviously cause other problems). And we'll definitely pick different names where appropriate, but if the best names for two different functions in two different modules happen to be the same name, then we're going to use it. And in same cases, we very purposely picked the same name, because the functions did the same type of thing (e.g. the functions in std.ascii and std.uni which do the same thing but for ASCII and Unicode respectively). - Jonathan M Davis That is an excellent explanation. Thank you. Do you think it would be worth noting the conflict in the documentation for readText()/write()? I should have mentioned in my original post that I likely could have figured out the workaround for this, and I posted here more because I was surprised that std.stdio and std.file would have a conflict! It seems like something folks new to D might run into with some frequency, and be thinking whats up with that!. If others think it is a good idea, maybe I will head over to gitHub and try to add something. Craig
Conflict between std.file write() and std.stdio write()
Hello, I have the following program: import std.file; import std.stdio; void main( string[] args ) { string str = Hello; write( file.txt, str ); string hello_file = readText(file.txt); writeln( hello_file ); } When I try to compile this I get: test.d(6): Error: std.stdio.write!(string, string).write at /usr/include/dmd/phobos/std/stdio.d(1656) conflicts with std.file.write at /usr/include/dmd/phobos/std/file.d(318) I think this should work. The example at the end of (D file I/0): http://www.docwiki.net/view.php?pageid=145 Uses write() exactly the way I am using it here. Cheers, Craig
Re: Conflict between std.file write() and std.stdio write()
On Wednesday, 2 October 2013 at 23:39:39 UTC, Craig Dillabaugh wrote: Hello, I have the following program: import std.file; import std.stdio; void main( string[] args ) { string str = Hello; write( file.txt, str ); string hello_file = readText(file.txt); writeln( hello_file ); } When I try to compile this I get: test.d(6): Error: std.stdio.write!(string, string).write at /usr/include/dmd/phobos/std/stdio.d(1656) conflicts with std.file.write at /usr/include/dmd/phobos/std/file.d(318) I think this should work. The example at the end of (D file I/0): http://www.docwiki.net/view.php?pageid=145 Uses write() exactly the way I am using it here. Cheers, Craig D compiler DMD 2.063.2
Re: Conflict between std.file write() and std.stdio write()
On Thursday, 3 October 2013 at 00:04:31 UTC, Jonathan M Davis wrote: On Thursday, October 03, 2013 01:39:38 Craig Dillabaugh wrote: Hello, I have the following program: import std.file; import std.stdio; void main( string[] args ) { string str = Hello; write( file.txt, str ); string hello_file = readText(file.txt); writeln( hello_file ); } When I try to compile this I get: test.d(6): Error: std.stdio.write!(string, string).write at /usr/include/dmd/phobos/std/stdio.d(1656) conflicts with std.file.write at /usr/include/dmd/phobos/std/file.d(318) I think this should work. The example at the end of (D file I/0): http://www.docwiki.net/view.php?pageid=145 Uses write() exactly the way I am using it here. You have to give the full path - std.file.write. As both functions can take the same arguments, and you've imported both, the compiler has no way of knowing which you mean. So, you have to disambiguate for it. It's only a problem because you imported both modules. - Jonathan M Davis Thanks. Seems kind of an odd design decision (or oversight) that two commonly used functions in the standard library would clash in this manner, but I guess it is no big deal. Cheers, Craig
Re: Conflict between std.file write() and std.stdio write()
On Thursday, 3 October 2013 at 00:04:31 UTC, Jonathan M Davis wrote: On Thursday, October 03, 2013 01:39:38 Craig Dillabaugh wrote: Hello, I have the following program: import std.file; import std.stdio; void main( string[] args ) { string str = Hello; write( file.txt, str ); string hello_file = readText(file.txt); writeln( hello_file ); } When I try to compile this I get: test.d(6): Error: std.stdio.write!(string, string).write at /usr/include/dmd/phobos/std/stdio.d(1656) conflicts with std.file.write at /usr/include/dmd/phobos/std/file.d(318) I think this should work. The example at the end of (D file I/0): http://www.docwiki.net/view.php?pageid=145 Uses write() exactly the way I am using it here. You have to give the full path - std.file.write. As both functions can take the same arguments, and you've imported both, the compiler has no way of knowing which you mean. So, you have to disambiguate for it. It's only a problem because you imported both modules. - Jonathan M Davis Thanks. Seems kind of an odd design decision (or oversight) that two commonly used functions in the standard library would clash in this manner, but I guess it is no big deal. Cheers, Craig
Re: Linking Trouble (Linux)
On Sunday, 29 September 2013 at 14:16:21 UTC, 1100110 wrote: https://xkcd.com/979/ Please. You are somebodies hero. Did you actually run into the same problem? If so, glad I could help.
Re: Linking Trouble (Linux)
On Thursday, 12 September 2013 at 20:47:46 UTC, Craig Dillabaugh wrote: clip For anyone who runs into a similar problem using DUB the following package.json files solves the problem: { name: vibe, description: My first vibe project., homepage: http://example.org;, copyright: Me, authors: [ Craig Dillabaugh ], dependencies: { vibe-d: ~master }, libs: [dl, z] } Hopefully starting a thread on a forum and then repeatedly answering yourself isn't a sign of insanity, but I've found the ultimate source of my problems and wanted to post back here in case it might help someone else (myself?) in the future. Anyway my suggested hacks above got my D programs to compile, but when I tried to run anything, I would get seg faults along the following lines: (gdb) backtrace #0 0x004547b9 in std.stdio.__T7writelnTAyaZ.writeln() () #1 0x00454301 in D main () #2 0x00460958 in rt.dmain2._d_run_main() () #3 0x0046048a in rt.dmain2._d_run_main() () #4 0x004609a8 in rt.dmain2._d_run_main() () #5 0x0046048a in rt.dmain2._d_run_main() () #6 0x00460446 in _d_run_main () #7 0x00460293 in main () It seems the source of my troubles was a broken binutils install by openSuse. So I re-installed binutils and now everything purrs along. Thanks to everyone for your help :o)
Re: Linking Trouble (Linux)
On Thursday, 12 September 2013 at 19:46:21 UTC, Craig Dillabaugh wrote: I just upgraded my Linux distro (openSuse) and now when trying to compile a project with dub I am getting linking errors. Compilation goes OK until the linking stage, when I get the following: Linking... dmd -of/home/craig/cloud/vibe-tiles/vibe /home/craig/cloud/vibe-tiles/temp.o -L-levent_pthreads -L-levent -L-lssl -L-lcrypto -g clip Strangely, libdl.so.2 and libz.so.1 are both there and libcrypto is linked to them. clip Craig OK, so I solved my compilation problem by passing the following as the linker command (added -L-ldl and -L-lz): dmd -of/home/craig/cloud/vibe-tiles/vibe /home/craig/cloud/vibe-tiles/temp.o -L-levent_pthreads -L-levent -L-lssl -L-ldl -L-lz -L-lcrypto -g How the GCC linker decides which libraries I need to explicitly specify is indeed a mystery to me. Craig
Linking Trouble (Linux)
I just upgraded my Linux distro (openSuse) and now when trying to compile a project with dub I am getting linking errors. Compilation goes OK until the linking stage, when I get the following: Linking... dmd -of/home/craig/cloud/vibe-tiles/vibe /home/craig/cloud/vibe-tiles/temp.o -L-levent_pthreads -L-levent -L-lssl -L-lcrypto -g /usr/lib64/gcc/x86_64-suse-linux/4.7/../../../../x86_64-suse-linux/bin/ld: warning: libdl.so.2, needed by /usr/lib64/libcrypto.so, not found (try using -rpath or -rpath-link) /usr/lib64/gcc/x86_64-suse-linux/4.7/../../../../x86_64-suse-linux/bin/ld: warning: libz.so.1, needed by /usr/lib64/libcrypto.so, not found (try using -rpath or -rpath-link) /usr/lib64/libcrypto.so: undefined reference to `dlopen@GLIBC_2.2.5' /usr/lib64/libcrypto.so: undefined reference to `dlerror@GLIBC_2.2.5' /usr/lib64/libcrypto.so: undefined reference to `dlclose@GLIBC_2.2.5' /usr/lib64/libcrypto.so: undefined reference to `dlsym@GLIBC_2.2.5' /usr/lib64/libcrypto.so: undefined reference to `dladdr@GLIBC_2.2.5' Strangely, libdl.so.2 and libz.so.1 are both there and libcrypto is linked to them. $ ldd /usr/lib64/libcrypto.so linux-vdso.so.1 (0x7fff7d52) libdl.so.2 = /lib64/libdl.so.2 (0x7f3b2ef98000) libz.so.1 = /lib64/libz.so.1 (0x7f3b2ed8) libc.so.6 = /lib64/libc.so.6 (0x7f3b2e9d) /lib64/ld-linux-x86-64.so.2 (0x7f3b2f5a8000) I've surfed around quite a bit and can't seem to find anything. I solved a similar problem in the past by reinstalling glibc, but that hasn't helped in this case. Any hints on where to look would be appreciated. Craig