Re: Supporting and signature-checking all foreach variations
On Sun, Feb 26, 2012 at 5:25 AM, Ali Çehreli wrote: > On 02/25/2012 08:25 AM, Ashish Myles wrote: >> However the code above doesn't seem to work and requires me to >> explicitly invoke the slice operator myself like >> foreach(p; C[]) { ... } >> when my data structure clearly defines the following functions. >> Point3[] opSlice() { return _cpts[]; } >> const (Point3)[] opSlice() const { return _cpts[]; } >> Is this a misunderstanding on my part or an unimplemented feature? > > But I've just verified that the following works with dmd 2.058: > > import std.stdio; > > struct Point3 > {} > > struct MyCollection > { > Point3[] _cpts; > > Point3[] opSlice() { return _cpts; } // <-- _cpts[] works too > > const (Point3)[] opSlice() const { return _cpts; } > } > > void main() > { > auto coll = MyCollection(); > > foreach (i; coll) { > // ... > } > } > Oh good to know. I had downgraded my dmd after some new CTFE bugs resulted in compilation errors on some of my code, and hadn't thought to check with the latest version.
Re: class templates and static if
> Also, 'static' on the enum declaration doesn't really do anything. :) but what if the immutable data changes?! :P But yeah, D's type inference is reasonably good (not as good as Haskell's, but nothing is as good as Haskell's), so doing what seems like the best way is normally the right way around it. If you have a lot of shared code, it might make more sense to just use traditional subclassing. Assuming that the shared code is all mostly Parser stuff then subclassing a Parser type into Request and Response types makes more sense. You can easily add common functionality to the base class, then add specific functionality to the individual classes. It also allows for more reflection, which is easier and probably more powerful than conditional compilation. -- James Miller
Re: class templates and static if
The immutable is not necessary, use: auto h = new Parser!(Type.request)("Hello world"); Otherwise, if you really want to declare the type instead of infering it you can write: Parser!(Type.request) h = new Parser!(Type.request)("Hello world"); You can also do: Parser!(Type.request) h; h = new typeof(h)("Hello world"); or: alias Parser!(Type.request) ParseRequest; ParseRequest h = new ParseRequest("Hello world"); Also, 'static' on the enum declaration doesn't really do anything. :)
Re: Write struct to file
On 2/27/12, Ali Çehreli wrote: > D is awesome compared to C as it enables serializing/deserializing data > with its generic programming and compile-time reflection features like this: > >http://dlang.org/traits.html#allMembers ae's json uses .tupleof, and does it in 40(!)* lines of code. * Well there's a helper function that escapes some strings, but in essence it's 40 lines of code that do most of the work. I think I'm going to print this out, frame it, and put it on a wall because it's just so damn concise: https://github.com/CyberShadow/ae/blob/master/utils/json.d#L69 (This is Vladimir's code for those not in the know) > > ae.utils.json <-- this will be not as "cool" as writing it raw binary? :p > > Must be subjective. I find json output cooler that binary. :p Yeah and again if there are no references he can simply use the cast(void*)[0..len] trick. The challenge would be to implement this for reference types.
Re: std.socket with GDC
On Sunday, 26 February 2012 at 02:01:17 UTC, Andrew Wiley wrote: I recall having some issues because Winsock needs to be on the linker commandline *after* phobos. Try running with `gdc -v` to see what the linker commandline looks like. That's it... any way to get it in the correct order, without having to call the linker separately? :/
Re: Write struct to file
On 02/26/2012 03:22 PM, Chopin wrote: > I don't want to hear the reinvent the wheel :(, I think you > learn a lot by doing thing like this. Agreed. > So, when I POST a blog-entry, I will read it, and write it to a file. I > don't want write strings in a file, like: > > 1--||--Title--||--The entry--||--Date I encourage you to stay with human-readable formats unless there is a reason not to. You can ditch XML, fine, but consider other formats like json. :) But I understand that you want to do this to learn. Fine... > I have little knowledge about system programming, and writing raw files. > But my dream was like: > > SOME_INT_WITH_LENGTH_OF_STRUCT_TO_THE_RIGHT HERE_IS_THE_RAW_STRUCT > SOME_INT_WITH_LENGTH_OF_STRUCT_TO_THE_RIGHT HERE_IS_THE_RAW_STRUCT > etc.etc.etc. You can do that only with structs that contain the entire data. As soon as there is a reference member, you must dereference that member to grab that member's data. For example, when you have strings, slices, associative arrays, class variables, pointers, and other user types with reference semantics, the data is not within the struct itself. No matter how long the string is, the following struct is always the same size: struct S { char[] s; } On the other hand, the following is fine for what you want to do: struct S { char[1000] s; } But is 1000 always enough? Is it wasteful (every instance of S will be very large.)? > Then read those structs in array :) Again, that part is easy as long as the struct doesn't have reference members. > I thought this was kinda easy in C, but I could be very wrong! C has exactly the same issues. As soon as you have a pointer member you must /follow/ that member to reach the actual data. > So I > thought it must be super easy in D! I don't have the knowledge... D is awesome compared to C as it enables serializing/deserializing data with its generic programming and compile-time reflection features like this: http://dlang.org/traits.html#allMembers I don't know their details but I would imagine that serialization libraries must be written taking advantage of allMembers. > ae.utils.json <-- this will be not as "cool" as writing it raw binary? :p Must be subjective. I find json output cooler that binary. :p Ali
class templates and static if
So, here's my code, as it stands currently: import std.stdio; static enum Type { request, response }; class Parser(Type t) { static if (t == Type.request) { string name = "request"; } else { string name = "response"; } string message; this(string message) { this.message = message; } } void main() { immutable Type t = Type.request; Parser!t h = new Parser!t("Hello world"); writefln("%s: %s", h.name, h.message); } The general goal is to make a templated class that will only include the parts that each needs. I would like to keep this all as one class template, because there is a lot of shared code, and I would like to keep it as seamless as possible and not have to separate out code into separate functions. Anyway, my current approach is a little clunky, because it requires an immutable to be created just to tell the compiler what type of parser I need. I was thinking about having two classes, Request and Response, and have parser take a normal template (class Parser (T)), but I wanted to restrict it to just those two classes (for now), so I came up with the enum solution. Is there a better way to do this? What I'd ultimately like to do is have some static if surrounding blocks of code that depends on the input to the template.
Re: Write struct to file
Hello! OP here :) I'm gonna be more precise why I want this. I'm writing my own blog, I will write my own HTTP server etc. and the saving of the data myself. Everything will be done in D! Why? Learn D. I don't want to hear the reinvent the wheel :(, I think you learn a lot by doing thing like this. So, when I POST a blog-entry, I will read it, and write it to a file. I don't want write strings in a file, like: 1--||--Title--||--The entry--||--Date I have little knowledge about system programming, and writing raw files. But my dream was like: SOME_INT_WITH_LENGTH_OF_STRUCT_TO_THE_RIGHT HERE_IS_THE_RAW_STRUCT SOME_INT_WITH_LENGTH_OF_STRUCT_TO_THE_RIGHT HERE_IS_THE_RAW_STRUCT etc.etc.etc. Then read those structs in array :) I thought this was kinda easy in C, but I could be very wrong! So I thought it must be super easy in D! I don't have the knowledge... ae.utils.json <-- this will be not as "cool" as writing it raw binary? :p Well. Thank you all for information, tips and tricks!! Great community! Thanks!
Re: Make alias parameter optional?
On 02/26/2012 03:45 AM, Jacob Carlborg wrote: > On 2012-02-26 11:03, Ali Çehreli wrote: >> On 02/25/2012 05:04 PM, Robert Rouse wrote: >> > On Saturday, 25 February 2012 at 23:10:51 UTC, Ary Manzana wrote: >> >> On 2/25/12 7:31 PM, Robert Rouse wrote: >> >> ... >> >> >>> This means that D can simulate Ruby blocks more than I thought. >> That's >> >>> pretty awesome. I'm loving D more every day. >> >> >> >> How's that like a Ruby block? >> > >> > The D code simulates the following Ruby if you were to make bar print >> > "something" with writeln. >> > >> > def foo(a, b, &block) >> > puts "a is #{a}") >> > b.call >> > yield >> > end >> > >> > f = lambda { puts "good bye" } >> > >> > foo(1, f) { puts "something" } >> > >> > >> > That's what I'm talking about. >> > >> >> I don't know Ruby but from what I've read so far about Ruby blocks, >> their D equivalents may also be D ranges. >> >> Ali > > A Ruby block is basically like a delegate in D and has nothing to do > with ranges. > > Ruby: > > def foo (&block) > block.call > end > > foo do > p "asd" > end > > D: > > void foo (void delegate () block) > { > block(); > } > > void main () > { > foo({ > writeln("asd"); > }); > > foo(() => writeln("asd")); // new lambda syntax > } > > Both examples print "asd". If you want to have a more Ruby looking > syntax in D you do some operator overload abuse: > > struct Block > { > void delegate (void delegate ()) impl; > > void opIn (void delegate () block) > { > impl(block); > } > } > > Block foo () > { > return Block((x) => x()); > } > > void main () > { > foo in { > writeln("asd"); > }; > } > I see, thanks. The reason I thought about ranges is that the yield statement in the Ruby code above reminded me of Python's generators, and that D's ranges can also take the role of generators. Ali
Re: SONAME and D
On 02/26/2012 02:53 PM, bioinfornatics wrote: Le vendredi 24 février 2012 à 15:56 +0100, Mike Wey a écrit : On 02/23/2012 08:29 PM, bioinfornatics wrote: Le jeudi 23 février 2012 à 19:46 +0100, Mike Wey a écrit : On 02/23/2012 05:27 PM, bioinfornatics wrote: dear, for set soname with: - gdc: -Xlinker -soname myLib.so.1 - ldc2: -soname myLib.so.1 - dmd: ? someone know how set soname with dmd ? dmd -L-soname=mylib.so.1 Thanks i will do so a $(SONAME_FLAG) in my makefile and maybe i will do a pull request for gtkd because ldc do not use -L-soname instead of dmd The GtkD Makefile uses: $(LINKERFLAG)-soname=$@.$(call stripBugfix,$(SO_VERSION)) Witch works with all the compilers, $(LINKERFLAG) is either -L or -Xlinker (with a space on th end). this it is good for dmd and gdc but ldc use -soname without -L gdc: -Xlinker -soname ldc: -soname dmd: -L -soname with ldc you do not to do calling the linker with $(LINKERFLAG Well, i am able to build the GtkD shared libs for ldc2 with the current make file. Not sure why ldc has it's own soname flag as only the linker would care about it so using -L to pass it on to the linker works just fine. -- Mike Wey
Re: A very strange bug. DMD 2.058 64-bit Linux
Thanks. I have reported the bug: http://d.puremagic.com/issues/show_bug.cgi?id=7595
Re: A very strange bug. DMD 2.058 64-bit Linux
On 02/26/2012 09:06 PM, Caligo wrote: Once you have those two files, compile with this: dmd -unittest t1.d bug.d and then run t1: ./t1 The output you get should look like this: ... [0, 4, 0, 0, 0, 0, 0, 2, 0, 0, 1, 2, 0, 1, 0, 0] I get: ... [0, 4, 0, 0, 0, 0, 0, 2, 0, 0, 1, 2, 0, 1, 0, 0] Obviously the output is wrong. 'm9' for some reason is getting overwritten. In my project this caused big problems because there are other m# with different values, and their values would literally get copied to m9. Calling inverse() on m9 then would fail because the other matrices are not invertible. Placing a writeln() in inverse() helped me realize that what was being passed to inverse() was being modified somewhere. I'm still now sure how m9 is being modified. Another point, compiling with this: dmd -unittest bug.d t1.d and then running bug: ./bug doesn't trigger the bug. I get: ... [4, 0, 0, 0, 0, 0, 2, 0, 0, 1, 2, 0, 1, 0, 0, 1] Could someone else please confirm this behavior? I have used DMD 2.058 64-bit linux.
A very strange bug. DMD 2.058 64-bit Linux
bug.d >8>8 @trusted: import std.datetime : benchmark; import std.stdio: writefln, writeln; alias double Real; void ben(alias fun)(string msg, uint n = 1_000_000) { auto b = benchmark!fun(n); writefln(" %s %s ms", msg, b[0].to!("msecs", int)); } struct Matrix(int row, int col) { private: alias row Row; alias col Col; alias Real[Row * Col] Data; public: Data _data = void; alias _data this; this(const Real[Row*Col] data) pure nothrow { _data = data; } } M inverse(M)(const auto ref M m) { writeln(m[]); M minv = m; return minv; } unittest { alias Matrix!(4, 4) Matrix4x4; auto m9 = Matrix4x4([4, 0, 0, 0, 0, 0, 2, 0, 0, 1, 2, 0, 1, 0, 0, 1]); ben!( {auto r = inverse(m9);} )("4x4 inverse:"); } 8<8< t1.d >8>8 import std.stdio; void main(){ } 8<8< It took me a long time to pinpoint this because it's tricky to trigger the bug. Once you have those two files, compile with this: dmd -unittest t1.d bug.d and then run t1: ./t1 The output you get should look like this: ... [0, 4, 0, 0, 0, 0, 0, 2, 0, 0, 1, 2, 0, 1, 0, 0] Obviously the output is wrong. 'm9' for some reason is getting overwritten. In my project this caused big problems because there are other m# with different values, and their values would literally get copied to m9. Calling inverse() on m9 then would fail because the other matrices are not invertible. Placing a writeln() in inverse() helped me realize that what was being passed to inverse() was being modified somewhere. I'm still now sure how m9 is being modified. Another point, compiling with this: dmd -unittest bug.d t1.d and then running bug: ./bug doesn't trigger the bug. Could someone else please confirm this behavior?
Re: deh_end
On 02/25/2012 09:06 AM, Jacob Carlborg wrote: _deh_beg and _deh_end is the start and end of the exception handling tables. _tlsstart and _tlsend would be the start and end of the TLS data. As far as I know druntime has not yet been adapted to handle dynamic libraries. I think there's a pull request that fixes this. Guess I'll wait. Thanks for the info.
Re: SONAME and D
Le vendredi 24 février 2012 à 15:56 +0100, Mike Wey a écrit : > On 02/23/2012 08:29 PM, bioinfornatics wrote: > > Le jeudi 23 février 2012 à 19:46 +0100, Mike Wey a écrit : > >> On 02/23/2012 05:27 PM, bioinfornatics wrote: > >>> dear, > >>> for set soname with: > >>> - gdc: -Xlinker -soname myLib.so.1 > >>> - ldc2: -soname myLib.so.1 > >>> - dmd: ? > >>> > >>> someone know how set soname with dmd ? > >>> > >> > >> dmd -L-soname=mylib.so.1 > >> > > > > Thanks > > i will do so a $(SONAME_FLAG) in my makefile and maybe i will do a pull > > request for gtkd because ldc do not use -L-soname instead of dmd > > > > The GtkD Makefile uses: > > $(LINKERFLAG)-soname=$@.$(call stripBugfix,$(SO_VERSION)) > > Witch works with all the compilers, $(LINKERFLAG) is either -L or > -Xlinker (with a space on th end). > this it is good for dmd and gdc but ldc use -soname without -L gdc: -Xlinker -soname ldc: -soname dmd: -L -soname with ldc you do not to do calling the linker with $(LINKERFLAG
Re: SONAME and D
Le vendredi 24 février 2012 à 13:00 -0800, H. S. Teoh a écrit : > On Fri, Feb 24, 2012 at 09:35:57PM +0100, Jordi Sayol wrote: > > Al 24/02/12 20:45, En/na H. S. Teoh ha escrit: > [...] > > > I personally think that phobos *should* be a shared object at some > > > point, but not everyone agrees with me. > > > > > > > I think that phobos should be a shared object too, but only when it > > has some sense (by now, every dmd release breaks previous libraries, > > at least gtkd ones) > [...] > > I suppose D/Phobos is currently still too volatile to start committing > to shared library version numbers yet. One *could* in theory start doing > it and just end up with very large version numbers, which the system in > theory can handle just fine, although people seem aversive to the > possibility of having /usr/lib/libphobos.so.2.x for all x from 0 to some > very large number. > > > T > ldc build already phobos / druntime as shared lib with /usr/lib/libphobos.so.2.x /usr/lib/libphobos.so.2 /usr/lib/libphobos.so.2 and same for druntime
Re: produced binary is quite big
You may try -L--gc-sections (in case of gdc in combination with -ffunction-sections -fdata-sections) and -L-s
Re: struct init() method
On Sunday, February 26, 2012 13:15:51 Alex Rønne Petersen wrote: > On 26-02-2012 12:53, Jonathan M Davis wrote: > > On Sunday, February 26, 2012 12:48:06 Timon Gehr wrote: > >> On 02/26/2012 12:18 AM, Jonathan M Davis wrote: > >>> On Saturday, February 25, 2012 17:07:14 Timon Gehr wrote: > This is useful: > > struct S{ > > @disable enum init = 0; > > } > >>> > >>> I thought that the way that you were supposed to do that was > >>> > >>> @disable this(); > >>> > >>> - Jonathan M Davis > >> > >> struct S{@disable this();} > >> void main(){S s = S.init;} > > > > Well, that's a problem then. It looks like it's bug - either that or I > > completely misunderstood what was going on with @disable and structs. > > > > - Jonathan M Davis > > IMHO .init should yield an error for structs with @disable this(). > Anything else seems illogical. Well, like I said, it's my understanding that @disable this() is the way that you're supposed to disable .init - as in that's the whole point of having added @disable this() to the language (though it can also be used to make classes unconstructable). So, either my understanding is wrong and/or this is a bug. - Jonathan M Davis
Re: struct init() method
On 26-02-2012 12:53, Jonathan M Davis wrote: On Sunday, February 26, 2012 12:48:06 Timon Gehr wrote: On 02/26/2012 12:18 AM, Jonathan M Davis wrote: On Saturday, February 25, 2012 17:07:14 Timon Gehr wrote: This is useful: struct S{ @disable enum init = 0; } I thought that the way that you were supposed to do that was @disable this(); - Jonathan M Davis struct S{@disable this();} void main(){S s = S.init;} Well, that's a problem then. It looks like it's bug - either that or I completely misunderstood what was going on with @disable and structs. - Jonathan M Davis IMHO .init should yield an error for structs with @disable this(). Anything else seems illogical. -- - Alex
Re: struct init() method
On Sunday, February 26, 2012 12:48:06 Timon Gehr wrote: > On 02/26/2012 12:18 AM, Jonathan M Davis wrote: > > On Saturday, February 25, 2012 17:07:14 Timon Gehr wrote: > >> This is useful: > >> > >> struct S{ > >> > >> @disable enum init = 0; > >> > >> } > > > > I thought that the way that you were supposed to do that was > > > > @disable this(); > > > > - Jonathan M Davis > > struct S{@disable this();} > void main(){S s = S.init;} Well, that's a problem then. It looks like it's bug - either that or I completely misunderstood what was going on with @disable and structs. - Jonathan M Davis
Re: Syntax highlighting for CodeRunner
On 2012-02-26 10:26, Joshua Niehus wrote: In the off chance that some of you are running a Mac and using CodeRunner to play around with D, I cooked up the files you need for CodeRunner to highlight D's syntax: https://github.com/jniehus/Dlang-for-CodeRunner I'm using TextMate on Mac with D, it works great. -- /Jacob Carlborg
Re: struct init() method
On 02/26/2012 12:18 AM, Jonathan M Davis wrote: On Saturday, February 25, 2012 17:07:14 Timon Gehr wrote: This is useful: struct S{ @disable enum init = 0; } I thought that the way that you were supposed to do that was @disable this(); - Jonathan M Davis struct S{@disable this();} void main(){S s = S.init;}
Re: Make alias parameter optional?
On 2012-02-26 11:03, Ali Çehreli wrote: On 02/25/2012 05:04 PM, Robert Rouse wrote: > On Saturday, 25 February 2012 at 23:10:51 UTC, Ary Manzana wrote: >> On 2/25/12 7:31 PM, Robert Rouse wrote: ... >>> This means that D can simulate Ruby blocks more than I thought. That's >>> pretty awesome. I'm loving D more every day. >> >> How's that like a Ruby block? > > The D code simulates the following Ruby if you were to make bar print > "something" with writeln. > > def foo(a, b, &block) > puts "a is #{a}") > b.call > yield > end > > f = lambda { puts "good bye" } > > foo(1, f) { puts "something" } > > > That's what I'm talking about. > I don't know Ruby but from what I've read so far about Ruby blocks, their D equivalents may also be D ranges. Ali A Ruby block is basically like a delegate in D and has nothing to do with ranges. Ruby: def foo (&block) block.call end foo do p "asd" end D: void foo (void delegate () block) { block(); } void main () { foo({ writeln("asd"); }); foo(() => writeln("asd")); // new lambda syntax } Both examples print "asd". If you want to have a more Ruby looking syntax in D you do some operator overload abuse: struct Block { void delegate (void delegate ()) impl; void opIn (void delegate () block) { impl(block); } } Block foo () { return Block((x) => x()); } void main () { foo in { writeln("asd"); }; } -- /Jacob Carlborg
Re: Supporting and signature-checking all foreach variations
On 02/25/2012 08:25 AM, Ashish Myles wrote: > I want to define a general-purpose centroid computer for point containers > and ran into a couple of challenges. Firstly, here is the basic code > > Point3 computeCentroid(PointContainer)(const ref PointContainer C) > if (...)// want a signature constraint for usability of foreach > { > Point3 c = Point3(0.0, 0.0, 0.0); > size_t total = 0; > foreach(Point3 p; C) { // enforce that the container supports this > c += p; ++total; > } > if (total> 0) > c /= cast(double)(total); > return c; > } ... > 2. Secondly, TDPL on page 381 says that foreach iterates over C[], if >C defines the opSlice() function without any arguments. Although what you describe also seems useful, that heading seems to be about ranges and specifically about the three InputRange functions. The feature has indeed been implemented recently: http://d.puremagic.com/issues/show_bug.cgi?id=5605 >However the code above doesn't seem to work and requires me to >explicitly invoke the slice operator myself like > foreach(p; C[]) { ... } >when my data structure clearly defines the following functions. > Point3[] opSlice() { return _cpts[]; } > const (Point3)[] opSlice() const { return _cpts[]; } >Is this a misunderstanding on my part or an unimplemented feature? But I've just verified that the following works with dmd 2.058: import std.stdio; struct Point3 {} struct MyCollection { Point3[] _cpts; Point3[] opSlice() { return _cpts; } // <-- _cpts[] works too const (Point3)[] opSlice() const { return _cpts; } } void main() { auto coll = MyCollection(); foreach (i; coll) { // ... } } Ali
Re: Make alias parameter optional?
On 02/25/2012 05:04 PM, Robert Rouse wrote: > On Saturday, 25 February 2012 at 23:10:51 UTC, Ary Manzana wrote: >> On 2/25/12 7:31 PM, Robert Rouse wrote: ... >>> This means that D can simulate Ruby blocks more than I thought. That's >>> pretty awesome. I'm loving D more every day. >> >> How's that like a Ruby block? > > The D code simulates the following Ruby if you were to make bar print > "something" with writeln. > > def foo(a, b, &block) > puts "a is #{a}") > b.call > yield > end > > f = lambda { puts "good bye" } > > foo(1, f) { puts "something" } > > > That's what I'm talking about. > I don't know Ruby but from what I've read so far about Ruby blocks, their D equivalents may also be D ranges. Ali
Re: produced binary is quite big
On 26 February 2012 21:28, Jabba Laci wrote: > Hi, > > I'm new to D. I tried the basic Hello World program ("dmd hello.d") > but it produced a 316 KB big binary. The same thing with C ("gcc > hello.c") is about 9 KB. Is there a way to reduce the size of the > produced binary? > > Thanks, > > Laszlo Phobos (the standard library) is currently not a shared library, due to the fact that shared library support in D is poor at the moment, and D itself is relatively unstable, otherwise we would have 100's of versions of the library floating around... The C version is small because it uses the C library and runtime, which are dynamically linked, so aren't included in the size of the file. Try statically linking the C version, I can't remember exactly how to do that at the moment, and you'll find the sizes to be similar. Also compiling with -release and -O2 would reduce the size, but I'm not sure by how much.
Syntax highlighting for CodeRunner
In the off chance that some of you are running a Mac and using CodeRunner to play around with D, I cooked up the files you need for CodeRunner to highlight D's syntax: https://github.com/jniehus/Dlang-for-CodeRunner
produced binary is quite big
Hi, I'm new to D. I tried the basic Hello World program ("dmd hello.d") but it produced a 316 KB big binary. The same thing with C ("gcc hello.c") is about 9 KB. Is there a way to reduce the size of the produced binary? Thanks, Laszlo