Re: getTid wrapper
On Tuesday, 4 March 2014 at 06:31:24 UTC, Timothee Cour wrote: that gives tid of spawned thread, not 'self'. The link you mentioned says it is stored in the special variable thisTid.
Re: Reading a string in binary mode
"bearophile" schrieb im Newsbeitrag news:qqcdemwimcylaizjy...@forum.dlang.org... > Christof Schardt: > >> By "trickery" I meant having to know about things like >> "import std.exception : assumeUnique" for this basic kind of task. > > Your function has signature (you use "ref" instead of "in" or "out" > because it performs read/write): > > void rw(ref string x) > > A string is a immutable(char)[], that is a dynamic array of immutable > (UTF-8) chars. In D a dynamic array is a struct (so it's a value) that > contains a length of the string (here in multiple of char.sizeof, that are > bytes) and a pointer to the actual string data. Your function gets a > string by reference, so it's a pointer to a mutable struct that points to > immutable chars. > > The else branch suggested by John Colvin was: > >> else >> { >> size_t size; >> _f.rawRead((&size)[0..1]); >> auto tmp = new char[size]; >> _f.rawRead(tmp); >> import std.exception : assumeUnique; >> x = tmp.assumeUnique; >> } > > This allocated a GC-managed dymamic array of chars (the buffer tmp), and > loads the data into them: > > auto tmp = new char[size]; > _f.rawRead(tmp); > > Now you can't just perform: > > x = tmp; > > D manages the pointer to the dynamic array x automatically, so x can be > seen as a dynamic array array. But their type is different, x refers to > immutable(char)[] while tmp is a char[]. In general you can't implicitly > convert immutable data with indirections to mutable data with > indirections, because this breaks the assumptions immutability is based on > (while in D you can assign a char[] to a const(char)[] variable. It's the > difference between const an immutable). So the "trickery" comes from > satisfying the strong typing of D. It's the price you have to pay for > safety and (in theory) a bit of improvements in concurrent code. > > assumeUnique is essentially a better documented cast, that converts > mutable to immutable. It's similar to cast(immutable). D doesn't have > uniqueness typing so in many cases the D compiler is not able to infer the > uniqueness of data for you (and unique data can be implicitly converted to > immutable). But the situation on this is improving (this is already > partially implemented and merged, and will be present in D 2.066: > http://wiki.dlang.org/DIP29 ). > > when the function you are calling is pure (unlike rawRead) you don't need > assumeUnique: > > import std.exception: assumeUnique; > > void foo(out char[] s) pure { > foreach (immutable i, ref c; s) > c = cast(char)i; > } > > // Using assumeUnique: > void bar1(ref string s) { > auto tmp = new char[10]; > foo(tmp); > s = tmp.assumeUnique; > } > > // Using the D type system: > void bar2(ref string s) { > static string local() pure { > auto tmp = new char[10]; > foo(tmp); > return tmp; > } > s = local; > } > > void main() {} > > Bye, > bearophile Great, thanks for this insight. Christof
Re: How to build DMD on windows ?
Am 03.03.2014 21:49, schrieb Remo: On Monday, 3 March 2014 at 19:51:45 UTC, Benjamin Thaut wrote: Am 28.02.2014 21:14, schrieb Remo: How to build DMD on windows ? And then run all the test for it? README.md is pretty empty at the moment. Of course it is possible to wait for some Fixes in DMD compiler may be it could be faster just to fix them by my self and then hope that the fix will be accepted... Easiest way (but you need visual studio): 1) checkout the latest version (or a tag) from https://github.com/D-Programming-Language/dmd 2) Open the Visual Studio solution src/dmd_msc_vs10.sln and build using the release target. Benefit from a compiler which is 3 times faster compared to a dmd build with dmc. Kind Regards Benjamin Thaut Thanks, I already found Visual Studio solution. By the way it compiles with VS2012 but not with VS2013. I think no one tried with 2013 yet. Whats the problem?
Re: runtime loading D shared library as a standalone (with it's own GC etc)
On Fri, Feb 28, 2014 at 10:27 AM, Martin Nowak wrote: > On 02/26/2014 10:16 PM, Timothee Cour wrote: > >> Currently (on OSX) I can runtime load a D dll from a C program, but not >> from a D program, which seems silly. >> >> Is it possible to runtime load a D shared library as a standalone (ie >> without sharing GC, runtime or any other data), treating it as if we >> were loading from a C program (making no attempt at sharing druntime or >> otherwise). >> >> What do I need to change in druntime to make this possible? >> >> Depends on why it doesn't work. > Here's an example. If it works from inside C++ there should be a way to make it work from inside D isn't there? (eg by isolating the GC of the shared library from the GC of the main program, etc). main.d: call a D shared library via dlopen/dlsym foo.d: extern(C) void foo(){ printf("inside_foo\n"); //ok import core.runtime; bool ret=Runtime.initialize();//will segfault below with or without that assert(ret);//ok int[]a; a.length=2;//segfault } dmd -g -oflibfoo.dylib -shared foo.d dmd -g -oftest main.d ./test #Loading shared libraries isn't yet supported on OSX. #inside_foo #segfault at first occurence of gc (a.length=2 above) under lldb: * thread #1: test D2rt12sections_osx9tlsOffsetFPvZm + 109, stop reason = EXC_BAD_ACCESS (code=EXC_I386_GPFLT) frame #0: test D2rt12sections_osx9tlsOffsetFPvZm + 109 frame #1: test __tls_get_addr + 20 frame #2: libfoo.dylib _d_arraysetlengthT + 3701 ...
Re: Final class and interface
On Mon, 03 Mar 2014 21:48:16 -0500, Casper Færgemand wrote: Is there any loss in performance instantiating an interface variable as a final class implementing only that interface, as opposed to a class variable? You mean the difference between: final class C : I {...} // this I i = new C; // and this C c = new C; ??? The difference in performance is huge. As a final class, no virtual calls are needed. In itself, this is not a huge deal, as a virtual call is not too much worse than a standard call. However, method calls on the concrete class can be inlined, and an inline call is generally very quick when compared to any kind of other call. -Steve
Final class and interface
Is there any loss in performance instantiating an interface variable as a final class implementing only that interface, as opposed to a class variable?
Re: Disabling the Garbage Collector
On Monday, 3 March 2014 at 12:23:49 UTC, Jeroen Bollen wrote: If I were to compile without linking to the garbage collector, what would and what wouldn't work in D? You can get almost everything to work, though some built-in features will need to be replaced/supplemented by library things and some care will be needed to avoid memory leaks. Specifically: * the a ~ b operator is a bad idea without the GC. (and with the GC in performance critical code) * delegate closures are a bad idea without the GC (though you can make them work) * Your classes will be written pretty differently * ~=, .dup and .length on built in arrays will need to be replaced by a library thing I think the rest can be made to work off the top of my head. Though, I think the cases where you want to go without the GC entirely are pretty rare. Normally, I'd just be careful about where you trigger it instead.
Issus with DMD 2.065
Ever since I installed the latest DMD 2.065 I cant seem to compile and run .d files anymore. I'm installing dmd using the .deb file on Ubuntu. When it is installed and I try to compile a .d file the console gives me this. cannot find source code for runtime library file 'object.d' dmd might not be correctly installed. Any suggestions?
Re: adding static return?
I don't get it. That should be a static assert, not static if. Why would you even add into your build order a module that will never be actually compiled? If anything, static assert will prevent dead imports while such "static return" will silently swallow them. How would you propose handling module constructors and module-scope variables in presence of such return?
Re: GC.BlkAttr.FINALIZE
It sounds suspicious. Clearly, you are not accessing a1 there, and clearly a1 is set before being used. Any chance to reduce it? -Steve I don't know. But I know that my little trick doesn't work in lifetime.d although it works locally. Here what I tried: import std.stdio; struct Foo { int id; } void main() { Foo[] fs; fs ~= Foo(45); fs ~= Foo(46); fs ~= Foo(47); fs ~= Foo(48); auto ti = typeid(fs); writeln("&ti = ", &ti); void* p = fs.ptr; void[] arr = *cast(void[]*) p; void* tp = cast(void*)((&arr) - cast(void*) 8); TypeInfo ti2 = *cast(TypeInfo*) tp; writeln(ti, " versus ", ti2); } Since rt_finalize and the GC have the same pointer as 'fs.ptr' I cast it to an array struct. From the pointer of this struct I subtract 8 (8 because of try and error until the pointer was equal the real TypeInfo pointer). This I can cast to the TypeInfo: it works. But not in lifetime.d. Was a try, but I have no idea why it doesn't work (the pointers aren't equal). An idea or alternative?
Re: std.algorithm.find and array of needles?
On 2014-03-03 16:19, John Colvin wrote: On Monday, 3 March 2014 at 22:03:24 UTC, captaindet wrote: On 2014-03-03 14:58, John Colvin wrote: On Monday, 3 March 2014 at 19:35:53 UTC, captaindet wrote: std.algorithm.find has an overload that works with several needles: // phobos doc example: int[] a = [ 1, 4, 2, 3 ]; assert(find(a, [ 1, 3 ], 4) == tuple([ 4, 2, 3 ], 2)); the function i want to write has to deal with variadic arguments serving as needles. unfortunately, i failed trying to make find work with the needles provided in an array: int[] a = [ 9, 8, 7, 6, 5, 4, 3, 2, 1 ]; int[][] ns = [ [ 7, 6 ], [ 4, 3 ] ]; auto res = find( a, ns ); //Error: template std.algorithm.find does not match any function template declaration. Candidates are: any ideas how this can be achieved? thanks /det You can use a variadic template function instead of variadic slice construction: void foo(A, T ...)(A[] a, T ns) { //use find as follows. For example: return a.find(ns); } assert(foo([1,2,3,4], 3, 6, 2) == Tuple!([2,3,4], 2)); thanks, john. i was afraid that this is the hoop i might have to jump through ;) which is fine for the simple case i asked for. in another case, i would need to construct a needle proper from each pre-needle that is one the variadic arguments. this seems impossible now. so i probably have to make the pre-needles template parameters and enter the dreadful realm of std.typetuple... guess staticMap is my friend here. cheers /det Luckily, you don't have to. foreach over tuples is awesome: import std.typecons; import std.algorithm; auto makeProperNeedle(T)(T needle) { //do something to needle return needle; } auto foo(A, T ...)(A[] a, T preNeedles) { Tuple!T needles; foreach(i, preNeedle; preNeedles) { needles[i] = makeProperNeedle(preNeedle); } //use find as follows. For example: return a.find(needles.expand); } unittest { assert(foo([1,2,3,4], 3, 6, 2) == tuple([2,3,4], 3)); } awesome indeed - works like a charm! many thanks /det
Re: Reading a string in binary mode
Christof Schardt: By "trickery" I meant having to know about things like "import std.exception : assumeUnique" for this basic kind of task. Your function has signature (you use "ref" instead of "in" or "out" because it performs read/write): void rw(ref string x) A string is a immutable(char)[], that is a dynamic array of immutable (UTF-8) chars. In D a dynamic array is a struct (so it's a value) that contains a length of the string (here in multiple of char.sizeof, that are bytes) and a pointer to the actual string data. Your function gets a string by reference, so it's a pointer to a mutable struct that points to immutable chars. The else branch suggested by John Colvin was: else { size_t size; _f.rawRead((&size)[0..1]); auto tmp = new char[size]; _f.rawRead(tmp); import std.exception : assumeUnique; x = tmp.assumeUnique; } This allocated a GC-managed dymamic array of chars (the buffer tmp), and loads the data into them: auto tmp = new char[size]; _f.rawRead(tmp); Now you can't just perform: x = tmp; D manages the pointer to the dynamic array x automatically, so x can be seen as a dynamic array array. But their type is different, x refers to immutable(char)[] while tmp is a char[]. In general you can't implicitly convert immutable data with indirections to mutable data with indirections, because this breaks the assumptions immutability is based on (while in D you can assign a char[] to a const(char)[] variable. It's the difference between const an immutable). So the "trickery" comes from satisfying the strong typing of D. It's the price you have to pay for safety and (in theory) a bit of improvements in concurrent code. assumeUnique is essentially a better documented cast, that converts mutable to immutable. It's similar to cast(immutable). D doesn't have uniqueness typing so in many cases the D compiler is not able to infer the uniqueness of data for you (and unique data can be implicitly converted to immutable). But the situation on this is improving (this is already partially implemented and merged, and will be present in D 2.066: http://wiki.dlang.org/DIP29 ). when the function you are calling is pure (unlike rawRead) you don't need assumeUnique: import std.exception: assumeUnique; void foo(out char[] s) pure { foreach (immutable i, ref c; s) c = cast(char)i; } // Using assumeUnique: void bar1(ref string s) { auto tmp = new char[10]; foo(tmp); s = tmp.assumeUnique; } // Using the D type system: void bar2(ref string s) { static string local() pure { auto tmp = new char[10]; foo(tmp); return tmp; } s = local; } void main() {} Bye, bearophile
adding static return?
I thought it could be nice to have a static return. My Idea is to remove unnecessary bracket encapsulation made with some static if statements. It will works like this : module xxx.opengl; import buildSettings; // contains some global constants static if (renderMode == directX) return; ... So there will no more need to scope the module code and indent it. Is it a good idea?
Re: Reading a string in binary mode
"John Colvin" schrieb im Newsbeitrag news:zjsykclxreagfhqsq...@forum.dlang.org... > On Monday, 3 March 2014 at 22:22:06 UTC, Christof Schardt wrote: >> "John Colvin" schrieb im Newsbeitrag >> news:dyfkblqonigrtmkwt...@forum.dlang.org... >>> On Monday, 3 March 2014 at 21:44:16 UTC, Christof Schardt wrote: I'm evaluating D and try to write a binary io class. I got stuck with strings: void rw(ref string x) { if(_isWriting) { int size = x.length; _f.rawWrite((&size)[0..1]); _f.rawWrite(x); } else { int size; _f.rawRead((&size)[0..1]); ... what now? } } Writing is ok, but how do I read the bytes to the string x after having its size? >>> >>> >>> Assuming you're not expecting pre-allocation (which I infer from your >>> choice of "ref string" instead of "char[]"), you could do this: >>> void rw(ref string x) { if(_isWriting) { size_t size = x.length; _f.rawWrite((&size)[0..1]); _f.rawWrite(x); } else { size_t size; _f.rawRead((&size)[0..1]); auto tmp = new char[size]; _f.rawRead(tmp); import std.exception : assumeUnique; x = tmp.assumeUnique; } } >> >> Thanks, John, this works. >> >> Though it feels a bit strange, that one has to do such trickery in order >> to >> perform basic things like binary io of strings. > > Doesn't seem like trickery to me; you just make a new array of the correct > size and then fill it from the file. Is that not what you expected to do? > > The only thing that is unusual is assumeUnique, but if you understand that > string is an alias to immutable(char)[] then it should be apparent why > it's there. You could just write "x = cast(string)tmp;" instead, it's the > same. By "trickery" I meant having to know about things like "import std.exception : assumeUnique" for this basic kind of task. Anyway, since D has an incredible community, which answers questions like mine within minutes, this is not really an obstacle.
Re: Nobody understands templates?
On Monday, 3 March 2014 at 18:46:24 UTC, Chris wrote: On Monday, 3 March 2014 at 18:03:12 UTC, Frustrated wrote: On Sunday, 2 March 2014 at 11:47:39 UTC, Steve Teale wrote: On Sunday, 2 March 2014 at 10:05:05 UTC, Dicebot wrote: There is nothing wrong about not using templates. Almost any compile-time design can be moved to run-time and expressed in more common OOP form. And using tool you have mastery of is usually more beneficial in practice than following the hype. Yes DB, we can soldier on happily, but it would not do any harm to understand templates. The documentation examples quickly make your eyes glaze over, looking at the code in Phobos is doubtless instructive, but you can wade through a lot of that without finding what you want. Also I discovered an interesting fact today. the word 'mixin' does not appear in the language reference Templates section of dlang.org. It should be used in at least one example. I just discovered by trial and error that I could use 'mixin' in Templates (as opposed to Template Mixins), and when you know that it seems likely that you can accomplish lots of stuff you couldn't before. While I'm here, has anyone discovered a way to fudge a constructor super(..) call in a mixin template that's included in a class constructor. Since the mixin template is evaluated in the scope of the constructor, it seems like it should be OK. I'm sure I'll get there in time ;=) Steve You've got to learn to think a bit more abstractly. Templates are generalizations of things. I think the problem is not that people don't understand templates in the sense that they are abstractions. The question is whether there are loads and loads of use cases for them. It is irrelevant if there are loads and loads of use cases for them. Just because people don't use something doesn't mean it is useless. Suppose I want to add two numbers using a function. int add(int, int)? double add(double, int)? float add(float, int)? char add(char, double)? etc which one? Do you want to have to create a function every time for every time? This is a typical use case and always mentioned in tutorials. The question is how many of these "typical" cases one encounters while writing software. Look at the STL library if you do't believe templates are useful... I think another problem with templates is that it is not always clear what is abstracted. The type or the logic? Both? In the above example the logic remains the same and is reproduced by the compiler for each type. Sometimes the logic can be abstracted for which type independence is important. But I'm not sure if that can be called a template in the purest sense. E.g. an algorithm that finds the first instance of something might be different for each type (string, char, int) and the "abstract" implementation has to differentiate internally (if string > else if int > else if ...). But this is no longer a template, or is it? Both logic and types are abtracted. Even though the template might use the same operator, the compiler must determine which concrete operator to use. The addition between the two abstract objects also requires an abstract operator. The great thing is, because the abstract logic is identical("adding two things") makes the template actually useful. If it wasn't we would have to specialize the template for all the different possible binary combinations and then it would defeat the simplification that abstract is suppose to offer. The the logical process is used when one looks at procedural code and realizes that one can "simplify" it by using oop. Templates give you the same power over oop that oop gives over non-oop. But just because templates[oop] are available doesn't mean you have to use it or it is always the best solution. I use templates all the time. I create them to simplify some task then put them in a library. For me, templates allow me to streamline things that I couldn't otherwise do. Any time I feel like something is being repeated a lot I automatically think that a templates will help. I hate "copying and pasting" and so I tend to use templates a lot. One of the main uses of templates is compile time type safety. This is necessary with oop because oop allows one to create types at compile time. Hence, the need to be able to make your oop "safe" is a natural step and templates help you accomplish that. e.g., Array's of objects vs Array's of a Type. One is much safer, informs the about what your intentions are so it can make better informed decisions. e.g., Array!Type allows the Array to determine if the Type supports certain things at **compile time**. Array!Object can't do this at compile time. If you can't see the benefit of Array!Type vs Array!Object then you are beyond help. (this is not to say Array!Object is always useless, but it is the most generic you can get and the compiler can do little to help the situation)
Re: GC.BlkAttr.FINALIZE
On Mon, 03 Mar 2014 15:34:18 -0500, Namespace wrote: On Monday, 3 March 2014 at 18:36:56 UTC, Steven Schveighoffer wrote: On Mon, 03 Mar 2014 12:03:12 -0500, Namespace wrote: On Monday, 3 March 2014 at 02:44:09 UTC, Namespace wrote: It's working now, I get all my debug infos I need. But: I have absolutly no idea how to get the correct TypeInfo in rt_finalize2. The ClassInfo is identified by casting the void* pointer to a void** and then cast this void** to ClassInfo*. But for other TypeInfos this weird trick doesn't work. How can I extract the correct TypeInfo from this void**? :P I get the real TypeInfo (not sure if this was intended this way) and in my test base it works! But in druntime I get the weird error: src\rt\lifetime.d(1256): Error: variable a1 used before set if (gc_getAttr(p) & BlkAttr.APPENDABLE) { void[] a1 = *cast(void[]*) ppv; //printf("len = %d\n", a1.length); void* p_a1 = &a1; void* tp = p_a1 + 12; TypeInfo* ti = cast(TypeInfo*) tp; import std.string : toStringz; string s = ti.toString(); // line 1256 printf("Type = %s\n", toStringz(s)); return; } Any call to ti will invoke the error. Any idea why? Not really any clue. But if this is in druntime, it should not be importing anything from std. Even without I get this weird error. Is this a bug? It sounds suspicious. Clearly, you are not accessing a1 there, and clearly a1 is set before being used. Any chance to reduce it? -Steve
Re: Nobody understands templates?
On Monday, 3 March 2014 at 19:32:51 UTC, Dicebot wrote: On Monday, 3 March 2014 at 18:46:24 UTC, Chris wrote: E.g. an algorithm that finds the first instance of something might be different for each type (string, char, int) and the "abstract" implementation has to differentiate internally (if string > else if int > else if ...). But this is no longer a template, or is it? What makes you think so? Template with specializations is still a template. Maybe I'm a bit too philosophical about this. But consider the following (made up) case: struct MyTemp(T) { // ... T add(T a, T b) { if (a is string && b is string) { return a~b; // or return a~"+"~b; or whatever } else if (a is integer && a is integer) { return a+b; } } } I don't know if this can be considered a "pure" template. It is a template of sorts, but the type specialization in the function add makes it a watered-down template, imo. You could have a version of MyTemp that handles only strings (and dchars, wchars) and one that handles only numbers. But this you also have in OO where this is achieved by inheritance and interfaces. I think the confusion about templates often arises from the fact that it is mainly about types, i.e. that the compiler fills in the template with the appropriate type. But it is not an abstraction of the logic behind a function. The logic in a+b is the same for int + int; float + float; float + int ... and thus not an abstraction of adding one thing to another. It is different for string + string. Of course, we can have separate templates, one for numbers, one for strings, one for arrays etc. But then it is less general. I am not against templates, far from it, I like them, and std.algorithm is a brilliant example of how useful they are. However, I wonder to what extent they can be useful when writing a specialized program as opposed to a general library. Walter mentioned that he uses them a lot these days. How? I want to learn.
Re: Reading a string in binary mode
On Monday, 3 March 2014 at 22:22:06 UTC, Christof Schardt wrote: "John Colvin" schrieb im Newsbeitrag news:dyfkblqonigrtmkwt...@forum.dlang.org... On Monday, 3 March 2014 at 21:44:16 UTC, Christof Schardt wrote: I'm evaluating D and try to write a binary io class. I got stuck with strings: void rw(ref string x) { if(_isWriting) { int size = x.length; _f.rawWrite((&size)[0..1]); _f.rawWrite(x); } else { int size; _f.rawRead((&size)[0..1]); ... what now? } } Writing is ok, but how do I read the bytes to the string x after having its size? Assuming you're not expecting pre-allocation (which I infer from your choice of "ref string" instead of "char[]"), you could do this: void rw(ref string x) { if(_isWriting) { size_t size = x.length; _f.rawWrite((&size)[0..1]); _f.rawWrite(x); } else { size_t size; _f.rawRead((&size)[0..1]); auto tmp = new char[size]; _f.rawRead(tmp); import std.exception : assumeUnique; x = tmp.assumeUnique; } } Thanks, John, this works. Though it feels a bit strange, that one has to do such trickery in order to perform basic things like binary io of strings. Doesn't seem like trickery to me; you just make a new array of the correct size and then fill it from the file. Is that not what you expected to do? The only thing that is unusual is assumeUnique, but if you understand that string is an alias to immutable(char)[] then it should be apparent why it's there. You could just write "x = cast(string)tmp;" instead, it's the same.
Re: Reading a string in binary mode
On 03/03/2014 02:25 PM, Christof Schardt wrote: > Thanks, Ali, this works. Yay! :) > book be equipped with a TOC and an index? Yes, all of that will happen after I get back to working on the book and its ever increasing list of to-dos. :) Ali
Re: Reading a string in binary mode
"Ali Çehreli" schrieb im Newsbeitrag news:lf2ude$1njf$1...@digitalmars.com... > On 03/03/2014 01:44 PM, Christof Schardt wrote:> I'm evaluating D and try > to write a binary io class. > > I got stuck with strings: > > > > void rw(ref string x) > > { > > if(_isWriting) > > { > > int size = x.length; > > _f.rawWrite((&size)[0..1]); > > _f.rawWrite(x); > > } > > else > > { > > int size; > > _f.rawRead((&size)[0..1]); > > > > ... what now? > > You need to have a buffer of 'size'. Not tested: > > auto s = new char[size]; > s = _f.rawRead(s); > x = s; > > However, the last line will not compile due to difference in mutability. > So will need to do something like this: > > import std.exception : assumeUnique; > > x = assumeUnique(s); > > > } > > } > > > > Writing is ok, but how do I read the bytes to the > > string x after having its size? > > Ali Thanks, Ali, this works. BTW: will your excellent book be equipped with a TOC and an index? I find it hard to look for answers to questions like above in all the D docs I have (dpl.org, TDPL, your book)
Re: Reading a string in binary mode
"John Colvin" schrieb im Newsbeitrag news:dyfkblqonigrtmkwt...@forum.dlang.org... > On Monday, 3 March 2014 at 21:44:16 UTC, Christof Schardt wrote: >> I'm evaluating D and try to write a binary io class. >> I got stuck with strings: >> >> void rw(ref string x) >> { >> if(_isWriting) >> { >> int size = x.length; >> _f.rawWrite((&size)[0..1]); >> _f.rawWrite(x); >> } >> else >> { >> int size; >> _f.rawRead((&size)[0..1]); >> >> ... what now? >> } >> } >> >> Writing is ok, but how do I read the bytes to the >> string x after having its size? > > > Assuming you're not expecting pre-allocation (which I infer from your > choice of "ref string" instead of "char[]"), you could do this: > >> void rw(ref string x) >> { >> if(_isWriting) >> { >> size_t size = x.length; >> _f.rawWrite((&size)[0..1]); >> _f.rawWrite(x); >> } >> else >> { >> size_t size; >> _f.rawRead((&size)[0..1]); >> auto tmp = new char[size]; >> _f.rawRead(tmp); >> import std.exception : assumeUnique; >> x = tmp.assumeUnique; >> } >> } Thanks, John, this works. Though it feels a bit strange, that one has to do such trickery in order to perform basic things like binary io of strings.
Re: std.algorithm.find and array of needles?
On Monday, 3 March 2014 at 22:03:24 UTC, captaindet wrote: On 2014-03-03 14:58, John Colvin wrote: On Monday, 3 March 2014 at 19:35:53 UTC, captaindet wrote: std.algorithm.find has an overload that works with several needles: // phobos doc example: int[] a = [ 1, 4, 2, 3 ]; assert(find(a, [ 1, 3 ], 4) == tuple([ 4, 2, 3 ], 2)); the function i want to write has to deal with variadic arguments serving as needles. unfortunately, i failed trying to make find work with the needles provided in an array: int[] a = [ 9, 8, 7, 6, 5, 4, 3, 2, 1 ]; int[][] ns = [ [ 7, 6 ], [ 4, 3 ] ]; auto res = find( a, ns ); //Error: template std.algorithm.find does not match any function template declaration. Candidates are: any ideas how this can be achieved? thanks /det You can use a variadic template function instead of variadic slice construction: void foo(A, T ...)(A[] a, T ns) { //use find as follows. For example: return a.find(ns); } assert(foo([1,2,3,4], 3, 6, 2) == Tuple!([2,3,4], 2)); thanks, john. i was afraid that this is the hoop i might have to jump through ;) which is fine for the simple case i asked for. in another case, i would need to construct a needle proper from each pre-needle that is one the variadic arguments. this seems impossible now. so i probably have to make the pre-needles template parameters and enter the dreadful realm of std.typetuple... guess staticMap is my friend here. cheers /det Luckily, you don't have to. foreach over tuples is awesome: import std.typecons; import std.algorithm; auto makeProperNeedle(T)(T needle) { //do something to needle return needle; } auto foo(A, T ...)(A[] a, T preNeedles) { Tuple!T needles; foreach(i, preNeedle; preNeedles) { needles[i] = makeProperNeedle(preNeedle); } //use find as follows. For example: return a.find(needles.expand); } unittest { assert(foo([1,2,3,4], 3, 6, 2) == tuple([2,3,4], 3)); }
Re: Reading a string in binary mode
On 03/03/2014 01:44 PM, Christof Schardt wrote:> I'm evaluating D and try to write a binary io class. > I got stuck with strings: > > void rw(ref string x) > { > if(_isWriting) > { > int size = x.length; > _f.rawWrite((&size)[0..1]); > _f.rawWrite(x); > } > else > { > int size; > _f.rawRead((&size)[0..1]); > > ... what now? You need to have a buffer of 'size'. Not tested: auto s = new char[size]; s = _f.rawRead(s); x = s; However, the last line will not compile due to difference in mutability. So will need to do something like this: import std.exception : assumeUnique; x = assumeUnique(s); > } > } > > Writing is ok, but how do I read the bytes to the > string x after having its size? Ali
Re: Reading a string in binary mode
On Monday, 3 March 2014 at 21:44:16 UTC, Christof Schardt wrote: I'm evaluating D and try to write a binary io class. I got stuck with strings: void rw(ref string x) { if(_isWriting) { int size = x.length; _f.rawWrite((&size)[0..1]); _f.rawWrite(x); } else { int size; _f.rawRead((&size)[0..1]); ... what now? } } Writing is ok, but how do I read the bytes to the string x after having its size? Assuming you're not expecting pre-allocation (which I infer from your choice of "ref string" instead of "char[]"), you could do this: void rw(ref string x) { if(_isWriting) { size_t size = x.length; _f.rawWrite((&size)[0..1]); _f.rawWrite(x); } else { size_t size; _f.rawRead((&size)[0..1]); auto tmp = new char[size]; _f.rawRead(tmp); import std.exception : assumeUnique; x = tmp.assumeUnique; } }
Re: std.algorithm.find and array of needles?
On 2014-03-03 14:58, John Colvin wrote: On Monday, 3 March 2014 at 19:35:53 UTC, captaindet wrote: std.algorithm.find has an overload that works with several needles: // phobos doc example: int[] a = [ 1, 4, 2, 3 ]; assert(find(a, [ 1, 3 ], 4) == tuple([ 4, 2, 3 ], 2)); the function i want to write has to deal with variadic arguments serving as needles. unfortunately, i failed trying to make find work with the needles provided in an array: int[] a = [ 9, 8, 7, 6, 5, 4, 3, 2, 1 ]; int[][] ns = [ [ 7, 6 ], [ 4, 3 ] ]; auto res = find( a, ns ); //Error: template std.algorithm.find does not match any function template declaration. Candidates are: any ideas how this can be achieved? thanks /det You can use a variadic template function instead of variadic slice construction: void foo(A, T ...)(A[] a, T ns) { //use find as follows. For example: return a.find(ns); } assert(foo([1,2,3,4], 3, 6, 2) == Tuple!([2,3,4], 2)); thanks, john. i was afraid that this is the hoop i might have to jump through ;) which is fine for the simple case i asked for. in another case, i would need to construct a needle proper from each pre-needle that is one the variadic arguments. this seems impossible now. so i probably have to make the pre-needles template parameters and enter the dreadful realm of std.typetuple... guess staticMap is my friend here. cheers /det
Reading a string in binary mode
I'm evaluating D and try to write a binary io class. I got stuck with strings: void rw(ref string x) { if(_isWriting) { int size = x.length; _f.rawWrite((&size)[0..1]); _f.rawWrite(x); } else { int size; _f.rawRead((&size)[0..1]); ... what now? } } Writing is ok, but how do I read the bytes to the string x after having its size?
Re: std.algorithm.find and array of needles?
On Monday, 3 March 2014 at 19:35:53 UTC, captaindet wrote: std.algorithm.find has an overload that works with several needles: // phobos doc example: int[] a = [ 1, 4, 2, 3 ]; assert(find(a, [ 1, 3 ], 4) == tuple([ 4, 2, 3 ], 2)); the function i want to write has to deal with variadic arguments serving as needles. unfortunately, i failed trying to make find work with the needles provided in an array: int[] a = [ 9, 8, 7, 6, 5, 4, 3, 2, 1 ]; int[][] ns = [ [ 7, 6 ], [ 4, 3 ] ]; auto res = find( a, ns ); //Error: template std.algorithm.find does not match any function template declaration. Candidates are: any ideas how this can be achieved? thanks /det You can use a variadic template function instead of variadic slice construction: void foo(A, T ...)(A[] a, T ns) { //use find as follows. For example: return a.find(ns); } assert(foo([1,2,3,4], 3, 6, 2) == Tuple!([2,3,4], 2));
Re: How to build DMD on windows ?
On Monday, 3 March 2014 at 19:51:45 UTC, Benjamin Thaut wrote: Am 28.02.2014 21:14, schrieb Remo: How to build DMD on windows ? And then run all the test for it? README.md is pretty empty at the moment. Of course it is possible to wait for some Fixes in DMD compiler may be it could be faster just to fix them by my self and then hope that the fix will be accepted... Easiest way (but you need visual studio): 1) checkout the latest version (or a tag) from https://github.com/D-Programming-Language/dmd 2) Open the Visual Studio solution src/dmd_msc_vs10.sln and build using the release target. Benefit from a compiler which is 3 times faster compared to a dmd build with dmc. Kind Regards Benjamin Thaut Thanks, I already found Visual Studio solution. By the way it compiles with VS2012 but not with VS2013.
Re: How to build DMD on windows ?
On Monday, 3 March 2014 at 19:51:45 UTC, Benjamin Thaut wrote: Am 28.02.2014 21:14, schrieb Remo: How to build DMD on windows ? And then run all the test for it? README.md is pretty empty at the moment. Of course it is possible to wait for some Fixes in DMD compiler may be it could be faster just to fix them by my self and then hope that the fix will be accepted... Easiest way (but you need visual studio): 1) checkout the latest version (or a tag) from https://github.com/D-Programming-Language/dmd 2) Open the Visual Studio solution src/dmd_msc_vs10.sln and build using the release target. Benefit from a compiler which is 3 times faster compared to a dmd build with dmc. Kind Regards Benjamin Thaut Thanks, good to know! :)
Re: GC.BlkAttr.FINALIZE
On Monday, 3 March 2014 at 18:36:56 UTC, Steven Schveighoffer wrote: On Mon, 03 Mar 2014 12:03:12 -0500, Namespace wrote: On Monday, 3 March 2014 at 02:44:09 UTC, Namespace wrote: It's working now, I get all my debug infos I need. But: I have absolutly no idea how to get the correct TypeInfo in rt_finalize2. The ClassInfo is identified by casting the void* pointer to a void** and then cast this void** to ClassInfo*. But for other TypeInfos this weird trick doesn't work. How can I extract the correct TypeInfo from this void**? :P I get the real TypeInfo (not sure if this was intended this way) and in my test base it works! But in druntime I get the weird error: src\rt\lifetime.d(1256): Error: variable a1 used before set if (gc_getAttr(p) & BlkAttr.APPENDABLE) { void[] a1 = *cast(void[]*) ppv; //printf("len = %d\n", a1.length); void* p_a1 = &a1; void* tp = p_a1 + 12; TypeInfo* ti = cast(TypeInfo*) tp; import std.string : toStringz; string s = ti.toString(); // line 1256 printf("Type = %s\n", toStringz(s)); return; } Any call to ti will invoke the error. Any idea why? Not really any clue. But if this is in druntime, it should not be importing anything from std. -Steve Even without I get this weird error. Is this a bug?
Re: How to build DMD on windows ?
Am 28.02.2014 21:14, schrieb Remo: How to build DMD on windows ? And then run all the test for it? README.md is pretty empty at the moment. Of course it is possible to wait for some Fixes in DMD compiler may be it could be faster just to fix them by my self and then hope that the fix will be accepted... Easiest way (but you need visual studio): 1) checkout the latest version (or a tag) from https://github.com/D-Programming-Language/dmd 2) Open the Visual Studio solution src/dmd_msc_vs10.sln and build using the release target. Benefit from a compiler which is 3 times faster compared to a dmd build with dmc. Kind Regards Benjamin Thaut
std.algorithm.find and array of needles?
std.algorithm.find has an overload that works with several needles: // phobos doc example: int[] a = [ 1, 4, 2, 3 ]; assert(find(a, [ 1, 3 ], 4) == tuple([ 4, 2, 3 ], 2)); the function i want to write has to deal with variadic arguments serving as needles. unfortunately, i failed trying to make find work with the needles provided in an array: int[] a = [ 9, 8, 7, 6, 5, 4, 3, 2, 1 ]; int[][] ns = [ [ 7, 6 ], [ 4, 3 ] ]; auto res = find( a, ns ); //Error: template std.algorithm.find does not match any function template declaration. Candidates are: any ideas how this can be achieved? thanks /det
Re: Nobody understands templates?
On Monday, 3 March 2014 at 18:46:24 UTC, Chris wrote: E.g. an algorithm that finds the first instance of something might be different for each type (string, char, int) and the "abstract" implementation has to differentiate internally (if string > else if int > else if ...). But this is no longer a template, or is it? What makes you think so? Template with specializations is still a template.
Re: Nobody understands templates?
On Monday, 3 March 2014 at 17:24:08 UTC, Dominikus Dittes Scherkl wrote: On Monday, 3 March 2014 at 16:40:09 UTC, Chris wrote: I'm always willing to use templates, but maybe in fact the use cases are limited. I have a class for html elements (that implements DOM functionality), and a class for building trees with the tags. Of course, for html tags only string as a type makes sense. Really? Did you consider that there are three different flavors of "string"? Does your function really only deal with string? Or would someone need wstring or dstring? Good point. Of course! I was thinking in an abstract way of "string". class HTMLElement(T) if (is (T == string)) } [...] I don't know [...] if I won't have to modify the template to adapt to new data types (which kinda defeats the purpose). Not much if the different types have common features. Most times it is still a big save of code to implement, even if the types need to be handled different in some places. But it's no longer a template then, is it?
Re: Nobody understands templates?
On Monday, 3 March 2014 at 18:03:12 UTC, Frustrated wrote: On Sunday, 2 March 2014 at 11:47:39 UTC, Steve Teale wrote: On Sunday, 2 March 2014 at 10:05:05 UTC, Dicebot wrote: There is nothing wrong about not using templates. Almost any compile-time design can be moved to run-time and expressed in more common OOP form. And using tool you have mastery of is usually more beneficial in practice than following the hype. Yes DB, we can soldier on happily, but it would not do any harm to understand templates. The documentation examples quickly make your eyes glaze over, looking at the code in Phobos is doubtless instructive, but you can wade through a lot of that without finding what you want. Also I discovered an interesting fact today. the word 'mixin' does not appear in the language reference Templates section of dlang.org. It should be used in at least one example. I just discovered by trial and error that I could use 'mixin' in Templates (as opposed to Template Mixins), and when you know that it seems likely that you can accomplish lots of stuff you couldn't before. While I'm here, has anyone discovered a way to fudge a constructor super(..) call in a mixin template that's included in a class constructor. Since the mixin template is evaluated in the scope of the constructor, it seems like it should be OK. I'm sure I'll get there in time ;=) Steve You've got to learn to think a bit more abstractly. Templates are generalizations of things. I think the problem is not that people don't understand templates in the sense that they are abstractions. The question is whether there are loads and loads of use cases for them. Suppose I want to add two numbers using a function. int add(int, int)? double add(double, int)? float add(float, int)? char add(char, double)? etc which one? Do you want to have to create a function every time for every time? This is a typical use case and always mentioned in tutorials. The question is how many of these "typical" cases one encounters while writing software. I think another problem with templates is that it is not always clear what is abstracted. The type or the logic? Both? In the above example the logic remains the same and is reproduced by the compiler for each type. Sometimes the logic can be abstracted for which type independence is important. But I'm not sure if that can be called a template in the purest sense. E.g. an algorithm that finds the first instance of something might be different for each type (string, char, int) and the "abstract" implementation has to differentiate internally (if string > else if int > else if ...). But this is no longer a template, or is it? [snip]
Re: GC.BlkAttr.FINALIZE
On Mon, 03 Mar 2014 12:03:12 -0500, Namespace wrote: On Monday, 3 March 2014 at 02:44:09 UTC, Namespace wrote: It's working now, I get all my debug infos I need. But: I have absolutly no idea how to get the correct TypeInfo in rt_finalize2. The ClassInfo is identified by casting the void* pointer to a void** and then cast this void** to ClassInfo*. But for other TypeInfos this weird trick doesn't work. How can I extract the correct TypeInfo from this void**? :P I get the real TypeInfo (not sure if this was intended this way) and in my test base it works! But in druntime I get the weird error: src\rt\lifetime.d(1256): Error: variable a1 used before set if (gc_getAttr(p) & BlkAttr.APPENDABLE) { void[] a1 = *cast(void[]*) ppv; //printf("len = %d\n", a1.length); void* p_a1 = &a1; void* tp = p_a1 + 12; TypeInfo* ti = cast(TypeInfo*) tp; import std.string : toStringz; string s = ti.toString(); // line 1256 printf("Type = %s\n", toStringz(s)); return; } Any call to ti will invoke the error. Any idea why? Not really any clue. But if this is in druntime, it should not be importing anything from std. -Steve
Re: Nobody understands templates?
On Monday, 3 March 2014 at 18:03:12 UTC, Frustrated wrote: If you don't attempt to use templates, even in example code, you won't get it. What I don't get in this discussion is that all those fine phobos examples are neglected. Yes, it is library code, but writef/formattedWrite/std.conv.to, std.container, std.range, std.algorithm are only possible with meta-programming and are fine examples of the usefulness of templates. This thread looks like this to me: I bought a new hammer, but not everything is a nail. Give me back my money!
Re: Mutexes and locking
On Monday, 3 March 2014 at 08:18:04 UTC, alexhairyman wrote: On Monday, 3 March 2014 at 07:38:05 UTC, Ali Çehreli wrote: On 03/02/2014 10:38 PM, alexhairyman wrote: > I think I'm missing something big, but I'm having troubles with mutexes > (using in a parallel foreach loop somewhere else); Why do the trylocks > return true shouldn't they return false because the mutex is already > locked? The documentation says that Mutex is a recursive lock, meaning that the holder of the lock can lock it even further. :) There is an internal reference count so that the lock must be unlocked the equal number of times that it has been locked. Oh okay, that makes sense. > I don't think this is a phobos bug, I'm on OSX using dmd > 2.065 > > import core.sync.mutex; > import std.stdio; > > void main() > { > Mutex m = new Mutex; > m.lock(); > writefln("%s", m.tryLock()); > writefln("%s", m.tryLock()); The lock count is now 3. You must unlock it 3 times so that another thread can lock it. > return; > } > > produces: > true > true > > Thanks! > Alex Ali Okay, so when doing something like this Mutex hashlock; void tdigest(string path) { MD5Digest thasher = new MD5Digest; thasher.put(read(path)); //read the path in to the MD5 API hashlock.lock(); hashkey[path] = thasher.finish(); hashlock.unlock(); } void main() { hashlock = new Mutex(); ... other stuff foreach(string s ; tp.parallel(array of strings)) { tdigest(s); } ... even more stuff } it will fail because the parallel foreach uses the main thread is being used which does some funky stuff? I'm trying to figure out how to implement this (for reference I'm just trying to create a big hash map of files and their md5's) You have to remember that global scope variables are thread-local by default. So your hashlock mutex is actually only initialized in the main thread. Try adding __gshared before declaring hashlock and see if it works.
Re: Nobody understands templates?
On Sunday, 2 March 2014 at 11:47:39 UTC, Steve Teale wrote: On Sunday, 2 March 2014 at 10:05:05 UTC, Dicebot wrote: There is nothing wrong about not using templates. Almost any compile-time design can be moved to run-time and expressed in more common OOP form. And using tool you have mastery of is usually more beneficial in practice than following the hype. Yes DB, we can soldier on happily, but it would not do any harm to understand templates. The documentation examples quickly make your eyes glaze over, looking at the code in Phobos is doubtless instructive, but you can wade through a lot of that without finding what you want. Also I discovered an interesting fact today. the word 'mixin' does not appear in the language reference Templates section of dlang.org. It should be used in at least one example. I just discovered by trial and error that I could use 'mixin' in Templates (as opposed to Template Mixins), and when you know that it seems likely that you can accomplish lots of stuff you couldn't before. While I'm here, has anyone discovered a way to fudge a constructor super(..) call in a mixin template that's included in a class constructor. Since the mixin template is evaluated in the scope of the constructor, it seems like it should be OK. I'm sure I'll get there in time ;=) Steve You've got to learn to think a bit more abstractly. Templates are generalizations of things. Suppose I want to add two numbers using a function. int add(int, int)? double add(double, int)? float add(float, int)? char add(char, double)? etc which one? Do you want to have to create a function every time for every time? Whats the only significant difference between all of them? If you can't answer this then you can't abstract and which is the reason you don't understand templates. I could use one template function to handle all those cases above. That's what makes it powerful. I can basically write one function when you have to write 8, 10, 20 or whatever. S add(S, T)(S a, T b) { return cast(S)(a + b); } The compiler then generates all the concrete use cases for me. (and using oop can make it more powerful, S and T could be vectors) As long as the first type has an binary addition operator on it that takes the second type it will work and the template will work without change. But you want to continue using the hold way. It is analogous to those that want to continue to write procedural code because they don't see the what oop has to offer. BTW, how did you learn oop? Did you understand it all perfectly by reading a book or did you learn best by writing code that used it? If you don't attempt to use templates, even in example code, you won't get it.
Re: Disabling the Garbage Collector
Anonymouse: To write tidy code? Much like const correctness, avoiding magic numbers and globals, not polluting namespace overly, only import what you need etc etc. In general avoiding the self initialization of the GC doesn't make your code more tidy. Totally not activating the GC is only for special situations and special D code. Bye, bearophile
Re: Nobody understands templates?
On Monday, 3 March 2014 at 16:40:09 UTC, Chris wrote: I'm always willing to use templates, but maybe in fact the use cases are limited. I have a class for html elements (that implements DOM functionality), and a class for building trees with the tags. Of course, for html tags only string as a type makes sense. Really? Did you consider that there are three different flavors of "string"? Does your function really only deal with string? Or would someone need wstring or dstring? class HTMLElement(T) if (is (T == string)) { } [...] I don't know [...] if I won't have to modify the template to adapt to new data types (which kinda defeats the purpose). Not much if the different types have common features. Most times it is still a big save of code to implement, even if the types need to be handled different in some places.
Re: Is it possible to elegantly craft a class that can be used as shared and as normal?
On Monday, 3 March 2014 at 16:42:10 UTC, Gary Willoughby wrote: class Test { private int number; public void setNumber(int newValue) { number = newValue; } public int getNumber() { return number; } } I need to instantiate that class twice like this: auto a = new Test(); auto b = new shared Test(); And be able to use the methods of 'a' and 'b' without an error. How can i do this without overloading the methods is the big question. Casting the object is not an option in my particular use case. You can't and you shouldn't be able to. Why are you so inclined on subverting the type system? If you're sharing an instance that doesn't support 'shared', then you're providing thread-safety mechanisms (i.e. synchronization) and cast away shared. If you're sharing an instance that does support 'shared', it should provide its own thread-safety mechanisms (that you shouldn't care about beyond documentation). Note that even using plain operators on shared *scalars* is disallowed (though not yet implemented, https://d.puremagic.com/issues/show_bug.cgi?id=3672). Because implementation of those operators on shared variables is supposed to be different (i.e. atomicOp). The same goes for classes and structs too: 'void method()' and 'void method() shared' can't be expected to have the same implementation (and wouldn't). Were it different, there would be no sense in explicit sharing.
Re: GC.BlkAttr.FINALIZE
On Monday, 3 March 2014 at 02:44:09 UTC, Namespace wrote: It's working now, I get all my debug infos I need. But: I have absolutly no idea how to get the correct TypeInfo in rt_finalize2. The ClassInfo is identified by casting the void* pointer to a void** and then cast this void** to ClassInfo*. But for other TypeInfos this weird trick doesn't work. How can I extract the correct TypeInfo from this void**? :P I get the real TypeInfo (not sure if this was intended this way) and in my test base it works! But in druntime I get the weird error: src\rt\lifetime.d(1256): Error: variable a1 used before set if (gc_getAttr(p) & BlkAttr.APPENDABLE) { void[] a1 = *cast(void[]*) ppv; //printf("len = %d\n", a1.length); void* p_a1 = &a1; void* tp = p_a1 + 12; TypeInfo* ti = cast(TypeInfo*) tp; import std.string : toStringz; string s = ti.toString(); // line 1256 printf("Type = %s\n", toStringz(s)); return; } Any call to ti will invoke the error. Any idea why?
Re: Is it possible to elegantly craft a class that can be used as shared and as normal?
On Monday, 3 March 2014 at 12:07:15 UTC, Tolga Cakiroglu wrote: Have you got a small example? import std.stdio; class Test{ private int number; public void setNumber( int newValue ) shared{ number = newValue; } public int getNumber() shared{ return number; } } void main(){ auto test = new Test(); (cast(shared)test).setNumber( 5 ); writeln("Value = ", (cast(shared)test).getNumber() ); } But do not forget the fact that because of the object `test` is not shared, therefore the attribute `number` is not shared. Thus, this will not be working multi-threded. I still don't understand this example. To be more clear lets take the following class: class Test { private int number; public void setNumber(int newValue) { number = newValue; } public int getNumber() { return number; } } I need to instantiate that class twice like this: auto a = new Test(); auto b = new shared Test(); And be able to use the methods of 'a' and 'b' without an error. How can i do this without overloading the methods is the big question. Casting the object is not an option in my particular use case.
Re: Nobody understands templates?
On Sunday, 2 March 2014 at 18:59:23 UTC, Steve Teale wrote: On Sunday, 2 March 2014 at 15:23:03 UTC, H. S. Teoh wrote: This is a pretty good primer to templates: https://semitwist.com/articles/article/view/template-primer-in-d The trouble is with most of these tutorials that they offer examples that are things you would probably never want to do. I can already add an int to an int, or a double to a double, or an int to a double. Perhaps the examples should pick on something like vector operations, but then who would be doing those with int, or some class? It would be doubles or pairs of, as in struct Coord. I believe readers would study documentation and examples much more carefully if they were things they might realistically want to do. And that won't be type conversion - std.conv already does a pretty good job on that. So what? We could really do with a place where template savvy open source contributors could publish interesting examples of template use. Otherwise, Joe Soap, like me, can spend a great deal of time and effort in: a) Determining when the use of a template might be advantageous, b) Hacking at test programs to determine what the documentation means, and what works, and what doesn't. c) After that, deciding whether it would be just as effective to use two or three separate methods. Steve Steve I'm always willing to use templates, but maybe in fact the use cases are limited. I have a class for html elements (that implements DOM functionality), and a class for building trees with the tags. Of course, for html tags only string as a type makes sense. class Element(T) { } or class HTMLElement(T) if (is (T == string)) { } Tree(T) { } I implemented it as a template, because I thought it might be useful for other types as well, if I want to build a hierarchical tree of extracted data, be it integers, floating point numbers or whatever at a later point. However, I don't know a) if this will ever be the case and b) if I won't have to modify the template to adapt to new data types (which kinda defeats the purpose). I'm not against templates, I'm just not sure, if there are so many general or generalizable cases in programming for which templates are _the_ solution.
Re: Disabling the Garbage Collector
On Monday, 3 March 2014 at 01:48:23 UTC, bearophile wrote: Jeroen Bollen: Is there maybe a way to disable the garbage collector from running unless you explicitly call it? I often seem to ask silly questions, but why do you need that? Bye, bearophile To write tidy code? Much like const correctness, avoiding magic numbers and globals, not polluting namespace overly, only import what you need etc etc.
2.065 and MacPorts
MacPorts DMD is still 2.064. There appears to be a notice that the maintainer position for this port is "vacant". I have no knowledge of creating or updating ports so cannot really volunteer to do this myself, but it would be good if some people did. I would be happy to be involved if others were as well. -- 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
Re: Disabling the Garbage Collector
On Monday, 3 March 2014 at 02:33:49 UTC, Adam D. Ruppe wrote: On Sunday, 2 March 2014 at 23:21:49 UTC, Jeroen Bollen wrote: Is there maybe a way to disable the garbage collector from running unless you explicitly call it? That's really the default. The GC in D runs if and only if you do a GC allocation and there isn't enough memory in its existing pool. Then it tries to do a collection to make room (and if that fails, it asks the operating system for more memory to grow its arena, and if that fails, it throws OutOfMemoryError). If you call GC.disable, it just sets a flag to skip the try collection step. But, in any case, the GC doesn't sit around in the background constantly running at random times. It only runs when you call on it to allocate. If I were to compile without linking to the garbage collector, what would and what wouldn't work in D?
Re: Is it possible to elegantly craft a class that can be used as shared and as normal?
Have you got a small example? import std.stdio; class Test{ private int number; public void setNumber( int newValue ) shared{ number = newValue; } public int getNumber() shared{ return number; } } void main(){ auto test = new Test(); (cast(shared)test).setNumber( 5 ); writeln("Value = ", (cast(shared)test).getNumber() ); } But do not forget the fact that because of the object `test` is not shared, therefore the attribute `number` is not shared. Thus, this will not be working multi-threded.
Re: Mutexes and locking
On Monday, 3 March 2014 at 07:38:05 UTC, Ali Çehreli wrote: On 03/02/2014 10:38 PM, alexhairyman wrote: > I think I'm missing something big, but I'm having troubles with mutexes > (using in a parallel foreach loop somewhere else); Why do the trylocks > return true shouldn't they return false because the mutex is already > locked? The documentation says that Mutex is a recursive lock, meaning that the holder of the lock can lock it even further. :) There is an internal reference count so that the lock must be unlocked the equal number of times that it has been locked. Oh okay, that makes sense. > I don't think this is a phobos bug, I'm on OSX using dmd 2.065 > > import core.sync.mutex; > import std.stdio; > > void main() > { >Mutex m = new Mutex; >m.lock(); >writefln("%s", m.tryLock()); >writefln("%s", m.tryLock()); The lock count is now 3. You must unlock it 3 times so that another thread can lock it. >return; > } > > produces: > true > true > > Thanks! >Alex Ali Okay, so when doing something like this Mutex hashlock; void tdigest(string path) { MD5Digest thasher = new MD5Digest; thasher.put(read(path)); //read the path in to the MD5 API hashlock.lock(); hashkey[path] = thasher.finish(); hashlock.unlock(); } void main() { hashlock = new Mutex(); ... other stuff foreach(string s ; tp.parallel(array of strings)) { tdigest(s); } ... even more stuff } it will fail because the parallel foreach uses the main thread is being used which does some funky stuff? I'm trying to figure out how to implement this (for reference I'm just trying to create a big hash map of files and their md5's)