Re: Digger 2.3 verstr.h problem
On Sunday, 23 August 2015 at 11:27:32 UTC, Robert M. Münch wrote: Hi, just trying to build the latest DMD with Digger 2.3 and get this: uffer.d root/port.d root/response.d root/rmem.d root/rootobject.d root/speller.d root/stringtable.d newdelete.o glue.a backend.a globals.d(293): Error: file verstr.h cannot be found or not in a path specified with -J make: *** [dmd] Error 1 digger: Saving to cache. digger: Clearing temporary cache Fatal error: Command [make, -f, posix.mak, MODEL=64, HOST_DC=/Volumes/Daten/Windows/d/develop/d-language/Digger/dl/dmd-2.067.1/dmd2/osx/bin/dmd, dmd] failed with status 2 mac-pro:Digger robby$ find . -name verstr.h ./repo/dmd/src/verstr.h mac-pro:Digger robby$ find . -name globals.d ./repo/dmd/src/globals.d mac-pro:Digger robby$ I'm wondering why the verstr.h file can't be found... it's in the same dir as from where the import happens. Any ideas? almost certainly a consequence of the recent switchover to the dmd frontend being written in D. Have you tried building the latest Digger git HEAD first? If that doesn't work I suggest reporting it here for Vladimir (CyberShadow) to look at: https://github.com/CyberShadow/Digger/issues/new
Re: Trying to compile weather program
On Sunday, 23 August 2015 at 16:00:19 UTC, Tony wrote: /usr/bin/ld: cannot find -lcurl Just the other day I had a similar problem (compiling vibenews, ld complained of missing -levent and -lssl), which I managed to solve simply by installing the development versions of the libraries (i.e. libevent-dev and libssl-dev). Maybe if you install libcurl-dev you will have the same luck I had. (But hopefully someone will give a more enlightened reply.)
Re: How to use ranges?
On Sunday, 23 August 2015 at 17:58:44 UTC, Doolan wrote: ... Read this for a nice introduction: http://ddili.org/ders/d.en/ranges.html Then watch this: https://www.youtube.com/watch?v=A8Btr8TPJ8c
Re: How to use ranges?
Generally, dynamic arrays / slices are random-access ranges. Narrow strings (string/wstring/char[]/wchar[]/...) are a notable exception to this. They are dynamic arrays of UTF-8/UTF-16 code units. But they're not random-access ranges of Unicode code units. Instead, they're _forward_ ranges of Unicode code _points_ (dchar). They have special range primitives that to the decoding. So slices are random-access ranges... I understand the random-access part... but are they inheriting from Range, do they just include a Range? Why is int[] an array when I declare, but variable[] a Range?? Or isn't it a Range? A range is just any type that satisfies certain properties (e.g. has front, empty, popFront in the most basic case). int[] is a range because front, empty and popFront are defined for it in std.range, which can be called with uniform function call syntax (UFCS) as if they were members of the type int[] itself.
Re: Trying to compile weather program
On Sunday, 23 August 2015 at 16:00:19 UTC, Tony wrote: Thanks for the replies. It compiles OK with just. However, it isn't linking: /usr/bin/ld: cannot find -lcurl I do have some versions of libcurl on my system: /usr/lib/x86_64-linux-gnu/libcurl.so.3 /usr/lib/x86_64-linux-gnu/libcurl.so.4.3.0 /usr/lib/x86_64-linux-gnu/libcurl.so.4 I see there is a -L option to pass things to the linker -Llinkerflag pass linkerflag to link but I am not sure how to use it. I tried ld weather_report.o -lcurl -L/usr/lib/x86_64-linux-gnu and ld weather_report.o -lcurl -L /usr/lib/x86_64-linux-gnu but it also says it can't find libcurl: ld: cannot find -lcurl
Re: post on using go 1.5 and GC latency
On Saturday, 22 August 2015 at 06:54:43 UTC, Ola Fosheim Grøstad wrote: On Saturday, 22 August 2015 at 06:48:48 UTC, Russel Winder wrote: But one that Google are entirely happy to fully fund. Yes, they have made Go fully supported on Google Cloud now, so I think it is safe to say that Google management is backing Go fully. I'm kinda hoping for Go++... The other day I thought it'd be hilarious if I did a Bjarne and wrote a preprocessor to generate Go code that would accept a superset of Go syntax but added generics, function overloading, etc. And, of course, called it Go++. Alas, 'tis too much work for just the lulz. I'd rather spend the time making D better. Atila
Re: How to use ranges?
On Sunday 23 August 2015 19:58, Doolan wrote: You can use typeof to get the type of a range expression when typing it out is impractical/impossible. What if I want to save a range in a struct? Or is a range more of a verb than a noun..? Can still use typeof then: struct S { import std.range: tee; import std.stdio: writeln; typeof((int[]).init.tee!writeln) teeing; this(int[] a) { teeing = a.tee!writeln; } } void main() { auto s = S([1, 2, 3, 4]); foreach(x; s.teeing) {} } Alternatively you can get classy and use std.range.interfaces: struct S { import std.range: tee; import std.range.interfaces: InputRange, inputRangeObject; import std.stdio: writeln; InputRange!int teeing; this(int[] a) { teeing = inputRangeObject(a.tee!writeln); } } void main() { auto s = S([1, 2, 3, 4]); foreach(x; s.teeing) {} } I need to compress some data, and luckily it's very suited for Running Length Encoding, so I've gone with doing that. Occasionally changes need to be made to this data and so rather than extracting the data, changing it, and then recompressing it, I can just do the equivalent of leaving a post-it note reminding the decompression function to sprinkle these changes in after decompression. Occasionally, I also need to grab some values out of this data without decompressing it, but for every additional value I look for I have to search the post-it notes and it gets a little fiddly. Here's a quick implementation of a run-length decoder range, and some example usage. I'm not sure how to go about the post-it note concept, or how practical it is. The decoder is not a random-access range, so when you want to edit the data and access individual items, then decode-edit-encode may work better. You don't have to shoehorn something into ranges just because ranges are cool. But if you want to apply a bunch of transformations to the whole thing, then ranges shine. import std.range: empty, front, popFront, save; import std.stdio; struct RunLengthItem(T) { T value; size_t length; } struct RunLengthDecoder(T) { RunLengthItem!T[] items; size_t currentRun = 0; @property bool empty() const {return items.empty;} @property T front() {return items.front.value;} void popFront() { ++currentRun; if(currentRun = items.front.length) { items.popFront(); currentRun = 0; } } @property RunLengthDecoder save() {return this;} } void main() { /* two 'f's, three 'o's, five 'b's, seven 'a's, eleven 'r's */ RunLengthItem!dchar[] data = [ RunLengthItem!dchar('f', 2), RunLengthItem!dchar('o', 3), RunLengthItem!dchar('b', 5), RunLengthItem!dchar('a', 7), RunLengthItem!dchar('r', 11) ]; auto decoder = RunLengthDecoder!dchar(data); /* Just print the elements (writeln is aware of ranges): */ writeln(decoder.save); /* ffooobaaarrr */ /* Uppercase when printing: */ import std.uni: asUpperCase; writeln(decoder.save.asUpperCase); /* FFOOOBAAARRR */ /* Filter out the 'b's, uppercase, and put an underscore every five characters: */ import std.algorithm: filter, joiner; import std.range: chunks; auto r = decoder.save .filter!(c = c != 'b') .asUpperCase .chunks(5).joiner(_); writeln(r); /* FFOOO_A_AARRR_R_RRR */ } So, I vaguely know what ranges are, and I've heard you can chain them together, and my code would be much more readable if I could cut up access to the data and splice in changes... but I don't even know how to define a range of the right type... Sounds like you may have some specific code you could use help with. If so, don't be afraid to post that code and ask how it can be range-ified. So slices are random-access ranges... I understand the random-access part... but are they inheriting from Range, do they just include a Range? There's no inheritance going on. Inheritance is a class thing. Arrays/slices are not classes. std.range defines the necessary range operations for slices: empty, front, popFront, etc. That's how slices are ranges. Why is int[] an array when I declare, but variable[] a Range?? Or isn't it a Range? Every int[] is a dynamic array, a slice, and a range. Doesn't matter where that int[] comes from.
Re: post on using go 1.5 and GC latency
On Sunday, 23 August 2015 at 12:49:35 UTC, Russel Winder wrote: You are mixing too many factors here. General purpose has nothing to do with performance, it is to do with can the language describe most if not all forms of computation. Go is a general purpose programming language just like C, C++, D, Rust, Haskell, OCaml. Yes, of course it is, but given it's typical use context I find it odd that they didn't go more towards higher level constructs. For me Go displaces Python where more speed is required, though I wish it was more pythonic… (neither C++, Rust or D are really eligible)
Re: Trying to compile weather program
On Sunday 23 August 2015 11:54, Tony wrote: weather_report.d(32): Error: undefined identifier centerJustifier `centerJustifier` is new in 2.068. You're probably using an older version of D. You can replace `centerJustifier` with `center` here.
Re: Trying to compile weather program
On Sunday, 23 August 2015 at 09:54:37 UTC, Tony wrote: I found this weather program on the main page (it seems to rotate what it here): [...] try with `center()` or update the compiler. centerJustifier() was added on 25 Apr 2015 so after 2.066.1 release: https://github.com/D-Programming-Language/phobos/commit/f85101eea1b875311e5716143cd6346fe4655f02
Re: Trying to compile weather program
Thanks for the replies. It compiles OK with just. However, it isn't linking: /usr/bin/ld: cannot find -lcurl I do have some versions of libcurl on my system: /usr/lib/x86_64-linux-gnu/libcurl.so.3 /usr/lib/x86_64-linux-gnu/libcurl.so.4.3.0 /usr/lib/x86_64-linux-gnu/libcurl.so.4 I see there is a -L option to pass things to the linker -Llinkerflag pass linkerflag to link but I am not sure how to use it.
Re: How to use ranges?
On Sunday, 23 August 2015 at 13:46:30 UTC, anonymous wrote: On Sunday 23 August 2015 12:17, Doolan wrote: And the use of auto everywhere makes it really hard to tell what types I should be using for anything. My compiler talks about RangeT!(whatever) but you try to use RangeT!(whatever) and you find out RangeT is private... You can use typeof to get the type of a range expression when typing it out is impractical/impossible. What if I want to save a range in a struct? Or is a range more of a verb than a noun..? Can someone give me a short summary of how to use ranges? I'm not sure what exactly you're looking for. The documentation for tee has some example code. How about you show something you're having trouble with? The possibility of using ranges comes up a lot, but here's today's example: I need to compress some data, and luckily it's very suited for Running Length Encoding, so I've gone with doing that. Occasionally changes need to be made to this data and so rather than extracting the data, changing it, and then recompressing it, I can just do the equivalent of leaving a post-it note reminding the decompression function to sprinkle these changes in after decompression. Occasionally, I also need to grab some values out of this data without decompressing it, but for every additional value I look for I have to search the post-it notes and it gets a little fiddly. So, I vaguely know what ranges are, and I've heard you can chain them together, and my code would be much more readable if I could cut up access to the data and splice in changes... but I don't even know how to define a range of the right type... And how do they relate to slices? That line is really blurry... Slice is a synonym for what the spec calls a dynamic array, i.e. a structure containing a pointer and a length. Slicing a dynamic array, static array, or pointer produces a dynamic array, referencing (not copying) the sliced elements: int[] d = [1, 2, 3, 4]; /* dynamic array */ int[] slice = d[1 .. 3]; assert(slice == [2, 3]); d[1] = 20; assert(slice[0] == 20); int[4] s = [1, 2, 3, 4]; /* static array */ slice = s[]; assert(slice == [1, 2, 3, 4]); int* p = [1, 2, 3, 4].ptr; /* pointer */ slice = p[1 .. 3]; assert(slice == [2, 3]); Note that the source types are different, but slicing them yields the same type every time: int[]. Generally, dynamic arrays / slices are random-access ranges. Narrow strings (string/wstring/char[]/wchar[]/...) are a notable exception to this. They are dynamic arrays of UTF-8/UTF-16 code units. But they're not random-access ranges of Unicode code units. Instead, they're _forward_ ranges of Unicode code _points_ (dchar). They have special range primitives that to the decoding. So slices are random-access ranges... I understand the random-access part... but are they inheriting from Range, do they just include a Range? Why is int[] an array when I declare, but variable[] a Range?? Or isn't it a Range?
Re: How to use ranges?
On Sunday, 23 August 2015 at 17:58:44 UTC, Doolan wrote: ... Ali's book has a very nice chapter about ranges: http://ddili.org/ders/d.en/ranges.html
Re: Digger 2.3 verstr.h problem
On Sunday, 23 August 2015 at 20:07:39 UTC, Robert M. Münch wrote: On 2015-08-23 17:01:07 +, Vladimir Panteleev said: [...] Ok, good. So it should be fixable on my side. [...] Not really sure what's going on there... If I could reproduce it, I'd try building DMD manually - if it still occurred, build DMD 2.067.1 from source and add debugging printfs to see why it's not finding verstr.h.
Re: Digger 2.3 verstr.h problem
On Sunday, 23 August 2015 at 11:27:32 UTC, Robert M. Münch wrote: Hi, just trying to build the latest DMD with Digger 2.3 and get this: uffer.d root/port.d root/response.d root/rmem.d root/rootobject.d root/speller.d root/stringtable.d newdelete.o glue.a backend.a globals.d(293): Error: file verstr.h cannot be found or not in a path specified with -J make: *** [dmd] Error 1 digger: Saving to cache. digger: Clearing temporary cache Fatal error: Command [make, -f, posix.mak, MODEL=64, HOST_DC=/Volumes/Daten/Windows/d/develop/d-language/Digger/dl/dmd-2.067.1/dmd2/osx/bin/dmd, dmd] failed with status 2 mac-pro:Digger robby$ find . -name verstr.h ./repo/dmd/src/verstr.h mac-pro:Digger robby$ find . -name globals.d ./repo/dmd/src/globals.d mac-pro:Digger robby$ I'm wondering why the verstr.h file can't be found... it's in the same dir as from where the import happens. Any ideas? Can't reproduce this on Windows, Linux or OS X 10.10.3. Can you include more of the build log (specifically, the entire failing command line)? It should have a -J. in it.
Re: Digger 2.3 verstr.h problem
On 2015-08-23 17:01:07 +, Vladimir Panteleev said: Can't reproduce this on Windows, Linux or OS X 10.10.3. Ok, good. So it should be fixable on my side. Can you include more of the build log (specifically, the entire failing command line)? It should have a -J. in it. CC=g++ /Volumes/Daten/Windows/d/develop/d-language/Digger/dl/dmd-2.067.1/dmd2/osx/bin/dmd -ofdmd -m64 -vtls -J. -d access.d aggregate.d aliasthis.d apply.d argtypes.d arrayop.d arraytypes.d attrib.d backend.d builtin.d canthrow.d clone.d complex.d cond.d constfold.d cppmangle.d ctfeexpr.d dcast.d dclass.d declaration.d delegatize.d denum.d dimport.d dinifile.d dinterpret.d dmacro.d dmangle.d dmodule.d doc.d dscope.d dstruct.d dsymbol.d dtemplate.d dunittest.d dversion.d entity.d errors.d escape.d expression.d func.d globals.d hdrgen.d id.d identifier.d impcnvtab.d imphint.d init.d inline.d intrange.d json.d lexer.d lib.d link.d mars.d mtype.d nogc.d nspace.d opover.d optimize.d parse.d sapply.d sideeffect.d statement.d staticassert.d target.d tokens.d traits.d utf.d visitor.d objc.d root/aav.d root/array.d root/file.d root/filename.d root/longdouble.d root/man.d root/outbuffer.d root/port.d root/response.d root/rmem.d root/rootobject.d root/speller.d root/stringtable.d newdelete.o glue.a backend.a globals.d(293): Error: file verstr.h cannot be found or not in a path specified with -J make: *** [dmd] Error 1 digger: Saving to cache. digger: Clearing temporary cache Fatal error: Command [make, -f, posix.mak, MODEL=64, HOST_DC=/Volumes/Daten/Windows/d/develop/d-language/Digger/dl/dmd-2.067.1/dmd2/osx/bin/dmd, dmd] failed with status 2 AFAIU it does has the -J. included. -- Robert M. Münch http://www.saphirion.com smarter | better | faster
Re: (De)Serializing interfaces
On Sunday, 23 August 2015 at 03:09:03 UTC, Rikki Cattermole wrote: Anyway to summise why D doesn't yet have something akin to Java or C#. Simply put, we generally work with the actual type not an interface. So libraries like Orange can serialize/deserialize with great certainty that it got everything. However if you need any help with making such a library, please let me know! Actually I'm coming from C++ but I know a little bit about C# so your explanation was helpful anyway! Thanks! As I really need a working serialization library I'll try making one myself now. However I'm not very experienced with D in general and its reflection in particular so I could use some help. I think in order to keep it simple I'll just have the user to write a function called Serialize() which calls the serializer which then just writes the values one after the other in a binary file (and, of course, for arrays and strings the length too). As all classes implement an interface called Serializable (with the function Serialize()), finding the right class to serialize won't be too hard (at least I think so). However then we have to make sure that we deserialize (instantiate) the right class. Does the runtime have a function which give you something like a unique type id and another one which instantiates the type with the given id? Something like: int id = _magic_runtime_functions.getUniqueTypeId(typeid(T)) Serializable t = _magic_runtime_functions.createTypeOfId(...) In order to make this clear I wrote some (untested and unfinished) code and pushed it into GitHub: https://github.com/nims1/interface-serialization-d/blob/master/Serializer.d I know it still has a lot of problems (hopefully, D has a better way of writing binary files into memory...). It's just a quick draft.
How to use ranges?
I keep running into areas of my code where it looks like I'd benefit from using ranges, and then I try to do some range stuff and my compiler tells me I'm using the wrong types, or there's this problem, or that problem... so I'm scared off and I just figure ways to work around using ranges. I've tried reading the documentation, but for a language priding itself on being readable and nice to look at, it really should have less complicated docs: auto tee(Flag!pipeOnPop pipeOnPop = Yes.pipeOnPop, R1, R2)(R1 inputRange, R2 outputRange) if (isInputRange!R1 isOutputRange!(R2, ElementType!R1)); auto tee(alias fun, Flag!pipeOnPop pipeOnPop = Yes.pipeOnPop, R1)(R1 inputRange) if (is(typeof(fun) == void) || isSomeFunction!fun); (That's fine as secondary information, but this is the heading for this function...) And the use of auto everywhere makes it really hard to tell what types I should be using for anything. My compiler talks about RangeT!(whatever) but you try to use RangeT!(whatever) and you find out RangeT is private... I don't mean to complain so hard, I obviously like D enough to want to use it, just the current amount/layout of documentation can be frustrating at times. Can someone give me a short summary of how to use ranges? And how do they relate to slices? That line is really blurry...
Re: (De)Serializing interfaces
On Sunday, 23 August 2015 at 08:38:14 UTC, Rikki Cattermole wrote: What I was thinking was having a serialize method take an output range which you will just pass in a value. I'm not really sure what you mean. Replacing the operator by a range function or serializing everything automatically? A hash? Yeah, TypeInfo_Class should. It will take a pointer. https://github.com/D-Programming-Language/druntime/blob/master/src/object.d#L261 size_t hash = typeid(avalue).getHash(avalue); But keep in mind avalue must be an rvalue. Sounds good! How do I then create an instance having the same type? My suggestion would be evaluate the type down aka get immutable(char) from immutable(char)[] aka string. So don't try to serialize the string straight. Grab the length put that to the output range, then try to serialize each of the values of the array individually as another function call to itself. Same sort of deal with other classes, check that they have the interface and if so, call it's serialize method with yourself. A little confusing I must admit. I'm sorry I didn't get that. Would you have a piece of code for illustration?
Re: (De)Serializing interfaces
On Sunday, 23 August 2015 at 03:25:27 UTC, Kapps wrote: I've never used Orange, but one thing you could try is casting your object from MyInterface to Object, and registering the type Foobar like in http://dsource.org/projects/orange/wiki/Tutorials/SerializeBase, then serializing/deserializing it as Object rather than MyInterface. I'm not sure if this will work, but it's worth a try if it doesn't handle interfaces. Interfaces are a bit odd in some ways, as they are not necessarily classes (and thus not implicitly convertible to Object) I suspect that's what Orange is having trouble with. /usr/local/include/d/orange/serialization/Serializer.di(254): Error: function pointer *serializer (Serializer, const(Object), Mode) is not callable using argument types (Serializer, MyInterface, Mode) /usr/local/include/d/orange/serialization/Serializer.di(902): Error: template orange.serialization.Serializer.Serializer.serializeBaseTypes cannot deduce function from argument types !()(MyInterface), candidates are: /usr/local/include/d/orange/serialization/Serializer.di(970): orange.serialization.Serializer.Serializer.serializeBaseTypes(T : Object)(inout T value) /usr/local/include/d/orange/serialization/Serializer.di(259): Error: template instance orange.serialization.Serializer.Serializer.objectStructSerializeHelper!(MyInterface) error instantiating /usr/local/include/d/orange/serialization/Serializer.di(157): instantiated from here: serializeObject!(MyInterface) /usr/local/include/d/orange/serialization/Serializer.di(386): instantiated from here: serializeInternal!(MyInterface) /usr/local/include/d/orange/serialization/Serializer.di(892): instantiated from here: serializePointer!(MyInterface*) /usr/local/include/d/orange/serialization/Serializer.di(259): ... (2 instantiations, -v to show) ... /usr/local/include/d/orange/serialization/Serializer.di(129): instantiated from here: serializeInternal!(Foobar) test.d(27):instantiated from here: serialize!(Foobar) I also can't cast MyInterface to Foo because at compile time I have no idea whether Foo or another type implementing MyInterface is behind it. Registering doesn't change that.
Re: post on using go 1.5 and GC latency
On Sun, 2015-08-23 at 11:26 +, rsw0x via Digitalmars-d-learn wrote: […] https://groups.google.com/forum/#!msg/golang -dev/pIuOcqAlvKU/C0wooVzXLZwJ 25-50% performance decrease across the board in 1.4 with the addition of write barriers, to an already slow language. Garbage collection is a hard problem for performance oriented code. I am sure someone will come up with a way of improving the Go one. Across the board though does worry me, my codes never get a sweep. D's garbage collector could also do with some work. random benchmarks of Go performing 3x(+) slower than C/C++/D, some of these predate Go 1.4. https://github.com/kostya/benchmarks https://benchmarksgame.alioth.debian.org/u64/benchmark.php?test=alll ang=golang2=gccdata=u64 https://togototo.wordpress.com/2013/07/23/benchmarking-level -generation-go-rust-haskell-and-d/ (gcc-go performed the _worst_) https://togototo.wordpress.com/2013/08/23/benchmarks-round-two -parallel-go-rust-d-scala-and-nimrod/ (and again) https://github.com/logicchains/LPATHBench/blob/master/writeup.md (once again, Go is nowhere near C/C++/D/Rust. Where is it? Hanging out with C#/Mono.) Thanks for those pointers, I shall have a look at them. Sadly though not for a couple of weeks due to various commitments. Go is slow. These aren't cherrypicked, just random samples from a quick Googling. But why use absolutes. Go may be slow for you in your context, but that doesn't mean the observation applies everywhere (note the interesting turn of phrase). For my (admittedly small) codes that do not cause a garbage collect and are basically just a loop, I find things are fine. So for a π approximation sequential code using 64-bit: C, gcc -O3: 8.847241 C++, gcc -O3: 8.916043 Fortran, gfortran -O3: 8.893000 D, ldc -O -release: 8.722329 D, dmd -O -release: 8.787744 Rust, cargo --release: 8.715818 Go, gccgo: 8.823525 Go, 6g: 8.824643 Go is definitely not slow there then. Thus Go is not slow. Where is Go performing C-level speeds at? D claims this, and D shows it does. Go falls into the fast enough category, because it is _not_ a general purpose programming language. So unless multiple randomly sampled benchmarks are all wrong, I'm going to stick with 'Go is slow.' You are mixing too many factors here. General purpose has nothing to do with performance, it is to do with can the language describe most if not all forms of computation. Go is a general purpose programming language just like C, C++, D, Rust, Haskell, OCaml. If for you Go is not performant enough, that is fine. But for many people in various contexts, Go is more the comparable with other languages. This is not just Go is fast enough, but Go is as fast as any other option. -- Russel. = Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.win...@ekiga.net 41 Buckmaster Roadm: +44 7770 465 077 xmpp: rus...@winder.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder signature.asc Description: This is a digitally signed message part
Re: (De)Serializing interfaces
On 8/23/2015 10:17 PM, nims wrote: On Sunday, 23 August 2015 at 08:38:14 UTC, Rikki Cattermole wrote: What I was thinking was having a serialize method take an output range which you will just pass in a value. I'm not really sure what you mean. Replacing the operator by a range function or serializing everything automatically? Oh not quite. Humm, how to explain this. import std.traits : isBasicType, isArray; interface Serializable { void serialize(OutputRange!ubyte); void deserialize(InputRange!ubyte); final void putValue(T)(OutputRange!ubyte output, ref T value) { static if (isArray!T) { putValue(output, value.length); foreach(v; value) putValue(v); } else static if (isBasicType!T) { // convert to ubytes ext. ext. and call put on output. } else if (Serializable sv = cast(Serializable)value) { sv.serialize(output); } else { static assert(0, I don't know how to handle this); } } final T getValue(T)(InputRange!ubyte input) { ubyte[T.sizeof] ret; foreach(i; 0 .. T.sizeof) ret[i] = input.moveFront; return to!T(ret); } } class ... : Serializable { int x, y; float z; void serialize(OutputRange!ubyte output) { output.putValue(x); output.putValue(y); output.putValue(z); } void deserialize(InputRange!ubyte input) { x = input.getValue!int; y = input.getValue!int; z = input.getValue!float; } } A hash? Yeah, TypeInfo_Class should. It will take a pointer. https://github.com/D-Programming-Language/druntime/blob/master/src/object.d#L261 size_t hash = typeid(avalue).getHash(avalue); But keep in mind avalue must be an rvalue. Sounds good! How do I then create an instance having the same type? The hash value won't help you much really. It's meant for comparing instances. My suggestion would be evaluate the type down aka get immutable(char) from immutable(char)[] aka string. So don't try to serialize the string straight. Grab the length put that to the output range, then try to serialize each of the values of the array individually as another function call to itself. Same sort of deal with other classes, check that they have the interface and if so, call it's serialize method with yourself. A little confusing I must admit. I'm sorry I didn't get that. Would you have a piece of code for illustration? Take a look at the top code snippet. You will probably want a couple of free functions be the function you call to serialize and deserialize. That way it can control embedding e.g. the class name as the first set of values. Which is trivial to use with the help of e.g. Object.factory or with the help of TypeInfo.init. On that note I'll see about getting you a snippet of code that may interest you here. If you can please come on[0] to make it slightly easier for me. [0] https://gitter.im/rikkimax/chatWithMe
Re: How to use ranges?
On 8/23/2015 10:17 PM, Doolan wrote: I keep running into areas of my code where it looks like I'd benefit from using ranges, and then I try to do some range stuff and my compiler tells me I'm using the wrong types, or there's this problem, or that problem... so I'm scared off and I just figure ways to work around using ranges. I've tried reading the documentation, but for a language priding itself on being readable and nice to look at, it really should have less complicated docs: auto tee(Flag!pipeOnPop pipeOnPop = Yes.pipeOnPop, R1, R2)(R1 inputRange, R2 outputRange) if (isInputRange!R1 isOutputRange!(R2, ElementType!R1)); auto tee(alias fun, Flag!pipeOnPop pipeOnPop = Yes.pipeOnPop, R1)(R1 inputRange) if (is(typeof(fun) == void) || isSomeFunction!fun); (That's fine as secondary information, but this is the heading for this function...) And the use of auto everywhere makes it really hard to tell what types I should be using for anything. My compiler talks about RangeT!(whatever) but you try to use RangeT!(whatever) and you find out RangeT is private... I don't mean to complain so hard, I obviously like D enough to want to use it, just the current amount/layout of documentation can be frustrating at times. Can someone give me a short summary of how to use ranges? And how do they relate to slices? That line is really blurry... Have a read of: https://github.com/rikkimax/twp-d/blob/master/manuscript/content/idioms/ranges.md Let me know what you think :)
Re: (De)Serializing interfaces
On 8/23/2015 8:15 PM, nims wrote: On Sunday, 23 August 2015 at 03:09:03 UTC, Rikki Cattermole wrote: Anyway to summise why D doesn't yet have something akin to Java or C#. Simply put, we generally work with the actual type not an interface. So libraries like Orange can serialize/deserialize with great certainty that it got everything. However if you need any help with making such a library, please let me know! Actually I'm coming from C++ but I know a little bit about C# so your explanation was helpful anyway! Thanks! As I really need a working serialization library I'll try making one myself now. However I'm not very experienced with D in general and its reflection in particular so I could use some help. I think in order to keep it simple I'll just have the user to write a function called Serialize() which calls the serializer which then just writes the values one after the other in a binary file (and, of course, for arrays and strings the length too). As all classes implement an interface called Serializable (with the function Serialize()), finding the right class to serialize won't be too hard (at least I think so). However then we have to make sure that we deserialize (instantiate) the right class. What I was thinking was having a serialize method take an output range which you will just pass in a value. Does the runtime have a function which give you something like a unique type id and another one which instantiates the type with the given id? A hash? Yeah, TypeInfo_Class should. It will take a pointer. https://github.com/D-Programming-Language/druntime/blob/master/src/object.d#L261 Something like: int id = _magic_runtime_functions.getUniqueTypeId(typeid(T)) This should work size_t hash = typeid(avalue).getHash(avalue); But keep in mind avalue must be an rvalue. Serializable t = _magic_runtime_functions.createTypeOfId(...) In order to make this clear I wrote some (untested and unfinished) code and pushed it into GitHub: https://github.com/nims1/interface-serialization-d/blob/master/Serializer.d I know it still has a lot of problems (hopefully, D has a better way of writing binary files into memory...). It's just a quick draft. My suggestion would be evaluate the type down aka get immutable(char) from immutable(char)[] aka string. So don't try to serialize the string straight. Grab the length put that to the output range, then try to serialize each of the values of the array individually as another function call to itself. Same sort of deal with other classes, check that they have the interface and if so, call it's serialize method with yourself. A little confusing I must admit. Also small tip, std.traits is awesome. Especially isBasicType ;)
Re: post on using go 1.5 and GC latency
On Sat, 2015-08-22 at 11:06 +, Laeeth Isharc via Digitalmars-d -learn wrote: […] Builds in Go 1.5 will be slower by a factor of about two. The automatic translation of the compiler and linker from C to Go resulted in unidiomatic Go code that performs poorly compared to well-written Go. Analysis tools and refactoring helped to improve the code, but much remains to be done. Further profiling and optimization will continue in Go 1.6 and future releases. For more details, see these slides and associated video. This is about compiler performance, not about generated code performance. Anyone interested in performance with Go currently uses gccgo: the standard Go compiler does not generate particularly well optimized code. This has been a resourcing choice to date, it is not a failing. gccgo on the other hand makes use of the whole GCC optimization chain. On the other hand gc is blindingly fast at compilation compared to gccgo. This seems reminiscent of dmd vs. ldc and gdc! -- Russel. = Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.win...@ekiga.net 41 Buckmaster Roadm: +44 7770 465 077 xmpp: rus...@winder.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder signature.asc Description: This is a digitally signed message part
Re: post on using go 1.5 and GC latency
On Sat, 2015-08-22 at 09:27 +, rsw0x via Digitalmars-d-learn wrote: […] The performance decrease has been there since 1.4 and there is no way to remove it - write barriers are the cost you pay for concurrent collection. Go was already much slower than other compiled languages, now it probably struggles to keep up with mono. I know Walter hates it when people mention the word but: benchmarks. As soon as someone say things like it probably struggles to keep up with mono further discussion of the topic is probably not worth entertaining without getting some agreed codes and running them all on the same machine. I agree the standard Go compiler generates not well optimized code, but gccgo generally does, and generally performs at C-level speeds. Of course Java often performs far better than that, and often fails to. You have to be careful with benchmarking and performance things generally. -- Russel. = Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.win...@ekiga.net 41 Buckmaster Roadm: +44 7770 465 077 xmpp: rus...@winder.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder signature.asc Description: This is a digitally signed message part
Re: (De)Serializing interfaces
On Sunday, 23 August 2015 at 10:37:11 UTC, Rikki Cattermole wrote: On 8/23/2015 10:17 PM, nims wrote: On Sunday, 23 August 2015 at 08:38:14 UTC, Rikki Cattermole wrote: What I was thinking was having a serialize method take an output range which you will just pass in a value. I'm not really sure what you mean. Replacing the operator by a range function or serializing everything automatically? Oh not quite. Humm, how to explain this. import std.traits : isBasicType, isArray; interface Serializable { void serialize(OutputRange!ubyte); void deserialize(InputRange!ubyte); final void putValue(T)(OutputRange!ubyte output, ref T value) { static if (isArray!T) { putValue(output, value.length); foreach(v; value) putValue(v); } else static if (isBasicType!T) { // convert to ubytes ext. ext. and call put on output. } else if (Serializable sv = cast(Serializable)value) { sv.serialize(output); } else { static assert(0, I don't know how to handle this); } } final T getValue(T)(InputRange!ubyte input) { ubyte[T.sizeof] ret; foreach(i; 0 .. T.sizeof) ret[i] = input.moveFront; return to!T(ret); } } class ... : Serializable { int x, y; float z; void serialize(OutputRange!ubyte output) { output.putValue(x); output.putValue(y); output.putValue(z); } void deserialize(InputRange!ubyte input) { x = input.getValue!int; y = input.getValue!int; z = input.getValue!float; } } A hash? Yeah, TypeInfo_Class should. It will take a pointer. https://github.com/D-Programming-Language/druntime/blob/master/src/object.d#L261 size_t hash = typeid(avalue).getHash(avalue); But keep in mind avalue must be an rvalue. Sounds good! How do I then create an instance having the same type? The hash value won't help you much really. It's meant for comparing instances. My suggestion would be evaluate the type down aka get immutable(char) from immutable(char)[] aka string. So don't try to serialize the string straight. Grab the length put that to the output range, then try to serialize each of the values of the array individually as another function call to itself. Same sort of deal with other classes, check that they have the interface and if so, call it's serialize method with yourself. A little confusing I must admit. I'm sorry I didn't get that. Would you have a piece of code for illustration? Take a look at the top code snippet. You will probably want a couple of free functions be the function you call to serialize and deserialize. That way it can control embedding e.g. the class name as the first set of values. Which is trivial to use with the help of e.g. Object.factory or with the help of TypeInfo.init. On that note I'll see about getting you a snippet of code that may interest you here. If you can please come on[0] to make it slightly easier for me. [0] https://gitter.im/rikkimax/chatWithMe Short summary of code snippets: ~~~ module dnetdev.webserver.common.classfinder; Interface findAndCreateClass(Interface)(string name) if (is(Interface == class) || is(Interface == interface)) { import std.experimental.allocator; auto alloc = theAllocator(); auto classinfo = TypeInfo_Class.find(name); if (classinfo is null) return null; size_t issize = classinfo.init.length; void[] dataallocated = alloc.allocate(issize); Object obj; dataallocated[] = cast(void[])classinfo.init[]; if (dataallocated is null) return null; obj = cast(Object)dataallocated.ptr; if (obj !is null) { if (classinfo.defaultConstructor !is null) (cast(void function(Object))classinfo.defaultConstructor)(obj); if (Interface obj2 = cast(Interface)obj) { return obj2; } else { alloc.dispose(obj); return null; } } else { alloc.dispose(dataallocated); return null; } } ~~~ ~~~ void main() { int x; foo!x(x); } void foo(alias T)(typeof(T) v) { pragma(msg, T.stringof); } import std.stdio; interface Foo { final void func(this T)(/* output */) { writeln(T.stringof); foreach(v; __traits(allMembers, T)) writeln(v); } } class Bar : Foo { int x; } void main() { Bar b = new Bar; b.func(); } ~
Re: How to use ranges?
On Sunday 23 August 2015 12:17, Doolan wrote: And the use of auto everywhere makes it really hard to tell what types I should be using for anything. My compiler talks about RangeT!(whatever) but you try to use RangeT!(whatever) and you find out RangeT is private... You can use typeof to get the type of a range expression when typing it out is impractical/impossible. Can someone give me a short summary of how to use ranges? I'm not sure what exactly you're looking for. The documentation for tee has some example code. How about you show something you're having trouble with? And how do they relate to slices? That line is really blurry... Slice is a synonym for what the spec calls a dynamic array, i.e. a structure containing a pointer and a length. Slicing a dynamic array, static array, or pointer produces a dynamic array, referencing (not copying) the sliced elements: int[] d = [1, 2, 3, 4]; /* dynamic array */ int[] slice = d[1 .. 3]; assert(slice == [2, 3]); d[1] = 20; assert(slice[0] == 20); int[4] s = [1, 2, 3, 4]; /* static array */ slice = s[]; assert(slice == [1, 2, 3, 4]); int* p = [1, 2, 3, 4].ptr; /* pointer */ slice = p[1 .. 3]; assert(slice == [2, 3]); Note that the source types are different, but slicing them yields the same type every time: int[]. Generally, dynamic arrays / slices are random-access ranges. Narrow strings (string/wstring/char[]/wchar[]/...) are a notable exception to this. They are dynamic arrays of UTF-8/UTF-16 code units. But they're not random-access ranges of Unicode code units. Instead, they're _forward_ ranges of Unicode code _points_ (dchar). They have special range primitives that to the decoding.
Re: How to use ranges?
There was a talk on ranges in Dconf 2015 https://www.youtube.com/watch?v=A8Btr8TPJ8clist=PLEDeq48KhndP-mlE-0Bfb_qPIMA4RrrKoindex=10
Re: post on using go 1.5 and GC latency
On Saturday, 22 August 2015 at 12:48:31 UTC, rsw0x wrote: The problem with D's GC is that there's no scaffolding there for it, so you can't really improve it. At best you could make the collector parallel. If I had the runtime hooks and language guarantees I needed I'd begin work on a per-thread GC immediately. If you had a fiber local reference type and some guarantees related to that, you probably could do a per-fiber GC and collect when fibers are waiting.
Trying to compile weather program
I found this weather program on the main page (it seems to rotate what it here): // Get your local weather report pragma(lib, curl); import std.functional, std.json, std.net.curl, std.stdio, std.string; alias getJSON = pipe!(get, parseJSON); auto K2C = (float f) = f - 273.15; auto K2F = (float f) = f / 5 * 9 - 459.67; void main() { auto loc = getJSON(ipinfo.io/)[loc] .str.split(,); auto resp = getJSON( api.openweathermap.org/data/2.5/weather ~ ?lat= ~ loc[0] ~ lon= ~ loc[1]); auto city = resp[name].str; auto country = resp[sys][country].str; auto desc = resp[weather][0][description].str; auto temp = resp[main][temp].floating; writefln(` +-+ |%s| +-+ | weather | %-23s| +-+ | temperature | %.2f°C (%.2f°F) | +-+ `.outdent, centerJustifier(city ~ , ~ country, 41), desc, temp.K2C, temp.K2F); } I am compiling on Ubuntu 14.02 with DMD v2.066.1 I get this compile error: weather_report.d(32): Error: undefined identifier centerJustifier
Digger 2.3 verstr.h problem
Hi, just trying to build the latest DMD with Digger 2.3 and get this: uffer.d root/port.d root/response.d root/rmem.d root/rootobject.d root/speller.d root/stringtable.d newdelete.o glue.a backend.a globals.d(293): Error: file verstr.h cannot be found or not in a path specified with -J make: *** [dmd] Error 1 digger: Saving to cache. digger: Clearing temporary cache Fatal error: Command [make, -f, posix.mak, MODEL=64, HOST_DC=/Volumes/Daten/Windows/d/develop/d-language/Digger/dl/dmd-2.067.1/dmd2/osx/bin/dmd, dmd] failed with status 2 mac-pro:Digger robby$ find . -name verstr.h ./repo/dmd/src/verstr.h mac-pro:Digger robby$ find . -name globals.d ./repo/dmd/src/globals.d mac-pro:Digger robby$ I'm wondering why the verstr.h file can't be found... it's in the same dir as from where the import happens. Any ideas? -- Robert M. Münch http://www.saphirion.com smarter | better | faster
Re: post on using go 1.5 and GC latency
On Sunday, 23 August 2015 at 11:06:20 UTC, Russel Winder wrote: On Sat, 2015-08-22 at 09:27 +, rsw0x via Digitalmars-d-learn wrote: […] The performance decrease has been there since 1.4 and there is no way to remove it - write barriers are the cost you pay for concurrent collection. Go was already much slower than other compiled languages, now it probably struggles to keep up with mono. I know Walter hates it when people mention the word but: benchmarks. As soon as someone say things like it probably struggles to keep up with mono further discussion of the topic is probably not worth entertaining without getting some agreed codes and running them all on the same machine. I agree the standard Go compiler generates not well optimized code, but gccgo generally does, and generally performs at C-level speeds. Of course Java often performs far better than that, and often fails to. You have to be careful with benchmarking and performance things generally. https://groups.google.com/forum/#!msg/golang-dev/pIuOcqAlvKU/C0wooVzXLZwJ 25-50% performance decrease across the board in 1.4 with the addition of write barriers, to an already slow language. random benchmarks of Go performing 3x(+) slower than C/C++/D, some of these predate Go 1.4. https://github.com/kostya/benchmarks https://benchmarksgame.alioth.debian.org/u64/benchmark.php?test=alllang=golang2=gccdata=u64 https://togototo.wordpress.com/2013/07/23/benchmarking-level-generation-go-rust-haskell-and-d/ (gcc-go performed the _worst_) https://togototo.wordpress.com/2013/08/23/benchmarks-round-two-parallel-go-rust-d-scala-and-nimrod/ (and again) https://github.com/logicchains/LPATHBench/blob/master/writeup.md (once again, Go is nowhere near C/C++/D/Rust. Where is it? Hanging out with C#/Mono.) Go is slow. These aren't cherrypicked, just random samples from a quick Googling. Where is Go performing C-level speeds at? D claims this, and D shows it does. Go falls into the fast enough category, because it is _not_ a general purpose programming language. So unless multiple randomly sampled benchmarks are all wrong, I'm going to stick with 'Go is slow.'
Re: How to use ranges?
On 8/24/2015 12:52 AM, Doolan wrote: On Sunday, 23 August 2015 at 10:38:53 UTC, Rikki Cattermole wrote: On 8/23/2015 10:17 PM, Doolan wrote: Have a read of: https://github.com/rikkimax/twp-d/blob/master/manuscript/content/idioms/ranges.md Let me know what you think :) I think I'm a little more confused than before... this says there are two kinds of ranges and I thought there were five?? There are more, but input/output ranges are the core two. They underpin all the others. Generally speaking these are the two that you will be using. The others such as ForwardRange are really just optional extras.
Re: How to use ranges?
On Sunday, 23 August 2015 at 10:38:53 UTC, Rikki Cattermole wrote: On 8/23/2015 10:17 PM, Doolan wrote: Have a read of: https://github.com/rikkimax/twp-d/blob/master/manuscript/content/idioms/ranges.md Let me know what you think :) I think I'm a little more confused than before... this says there are two kinds of ranges and I thought there were five??
order of declaration/definition
enum A = 1; enum B = C; //Error static if(A) enum C = 0; enum D = C; //OK Is order supposed to matter here?
Templates and writing variable number of arguments
Hi everyone, It's me again. Now I'm struggling with the `output` member function which should output a string either to stdout or to a file, depending on the parameter. However, I would like it to work like `writefln` with variable number of arguments: output(Hello %s!, world); // should be OK output(%s %s: %s %d times, I, say, Hello world!, 500); // Should also be OK Here is my code: final void output(T)(string text, T params...) const { if (this.outFile == ) { writefln(text, params); } else { // Output to a file auto f = File(this.outFile, w); try { f.writefln(text, params); } catch(Exception e) { writefln(Unable to write to %s: %s, this.outFile, e.msg); } } } And the compiler says it can't deduce the type of arguments. What am I doing wrong here? Maybe, I don't need such a function and all and there is a way to make it more elegant? Thanks! -- With best regards from Ukraine, Andre Skype: Francophile Twitter: @m_elensule; Facebook: menelion My blog: http://menelion.oire.org/
Re: Templates and writing variable number of arguments
try replacing: final void output(T)(string text, T params...) const { with final void output(T...)(string text, T params) const { Andre Polykanine via Digitalmars-d-learn wrote: Hi everyone, It's me again. Now I'm struggling with the `output` member function which should output a string either to stdout or to a file, depending on the parameter. However, I would like it to work like `writefln` with variable number of arguments: output(Hello %s!, world); // should be OK output(%s %s: %s %d times, I, say, Hello world!, 500); // Should also be OK Here is my code: final void output(T)(string text, T params...) const { if (this.outFile == ) { writefln(text, params); } else { // Output to a file auto f = File(this.outFile, w); try { f.writefln(text, params); } catch(Exception e) { writefln(Unable to write to %s: %s, this.outFile, e.msg); } } } And the compiler says it can't deduce the type of arguments. What am I doing wrong here? Maybe, I don't need such a function and all and there is a way to make it more elegant? Thanks!