Re: GC-proof resource classes
On Monday, 31 August 2015 at 13:35:54 UTC, ponce wrote: On Monday, 31 August 2015 at 12:54:05 UTC, Sebastiaan Koppe wrote: What about: ``` class MyResource { void* handle; this() { handle = create_handle(); } close() { if (handle) free_handle(handle) handle = null; } ~this() { enforce(!handle,"Resource leak"); } } ``` Unique!T destructor calls delete which calls ~this() not close() RefCounted!T and scoped!T call .destroy which calls ~this() not close() We really want one thing there. I normally stick with this pattern when dealing with resource, though I would only uses a class if I needed an interface or inheritance.. ``` class MyResource { void* handle; this() { handle = create_handle(); } close() { if (handle !is null) { synchronized { if (handle !is null) { free_handle(handle); } } handle = null; } } ~this() { close(); } } ```
Re: Phobos: test suite
On Friday, 17 July 2015 at 05:45:06 UTC, Tofu Ninja wrote: On Friday, 17 July 2015 at 03:17:08 UTC, Rikki Cattermole wrote: https://issues.dlang.org/show_bug.cgi?id=3420 I have always hated that sub directories were not allowed. A flat file directory simply sucks when you have a couple hundred string imports... why walter... why /3 I wonder if windows support can be added using PathCanonicalize and PathFileExists seems about as secure as using realpath on posix https://msdn.microsoft.com/en-us/library/windows/desktop/bb773569(v=vs.85).aspx https://msdn.microsoft.com/en-us/library/windows/desktop/bb773584(v=vs.85).aspx
Re: How to use core.thread.Thread
On Friday, 17 July 2015 at 07:56:48 UTC, aki wrote: On Thursday, 16 July 2015 at 09:17:47 UTC, Daniel Kozák wrote: class DerivedThread : Thread { shared int count = 0; } I thought shared is only for whole of the object. auto thr = new DerivedThread(); Here, thr is not shared but it's member thr.count is shared? But if it's not shared, thr object referred by main thread and this reference of DerivedThread.run() are different? What happen if there are both shared and unshared member exists? class DerivedThread : Thread { shared int count = 0; int foo = 0; } Umm. I can't imagine what's the memory layout of this object. Since I have yet to use or see anyone use shared in a useful way I avoid it. But I normally think of it like const (not immutable). Shared wont change the memory layout (last time I checked) its purpose is meant to help you write correct threaded code, ie make sure you synchronize access to it, its not synced for you. You should read the chapter from Andrie's book. There is also a lot of good stuff in the std lib the helps avoid doing things manually.
Re: How to convert byte array to float
On Friday, 17 July 2015 at 18:43:27 UTC, DLangLearner wrote: Excuse me for my trivial question, but I'd like to know how to convert byte array to float? What I could think of are cast(float)(byte[]) and to!float(byte[]) but they do not work for me. Thanks! You want to include [] in the cast so: byte[] b = [1, 2, 3, 4] byte[] f = cast(float[])b; writeln(b); writeln(f); You can even cast on a slice: byte[] b = [1, 2, 3, 4, 5, 6, 7, 8] byte[] f = cast(float[])b[4..8];
Re: How to convert byte array to float
On Friday, 17 July 2015 at 18:53:24 UTC, byron wrote: On Friday, 17 July 2015 at 18:43:27 UTC, DLangLearner wrote: Excuse me for my trivial question, but I'd like to know how to convert byte array to float? What I could think of are cast(float)(byte[]) and to!float(byte[]) but they do not work for me. Thanks! You want to include [] in the cast so: byte[] b = [1, 2, 3, 4] byte[] f = cast(float[])b; writeln(b); writeln(f); You can even cast on a slice: byte[] b = [1, 2, 3, 4, 5, 6, 7, 8] byte[] f = cast(float[])b[4..8]; Ah I miss read, if you want as a float, not a float array you can do: byte[] b = [1, 2, 3, 4]; float f = *cast(float*)b.ptr; not sure if there is a better way
Re: How to convert byte array to float
On Friday, 17 July 2015 at 19:03:46 UTC, Jacob Carlborg wrote: On 2015-07-17 20:58, byron wrote: Ah I miss read, if you want as a float, not a float array you can do: byte[] b = [1, 2, 3, 4]; float f = *cast(float*)b.ptr; not sure if there is a better way I think a union can be used as well, not sure if it's better though. not a bad idea. testing on asm.dlang.org both reduce to the same assembly (-release -inline -O) float pointerTest(inout byte[4] b) { return *cast(float*)b.ptr; } float unionTest(inout byte[4] b) { union U { byte[4] b; float f; } return U(b).f; }
Re: How to use core.thread.Thread
On Thursday, 16 July 2015 at 21:48:06 UTC, byron wrote: On Thursday, 16 July 2015 at 07:57:13 UTC, aki wrote: [...] If I remember a synchronized method requires this to be shared, you should be fine using a synchronized block in the method for non-shared instances. But using atomicOp will avoid a lock. void inc() { synchronized { ++count; } } You are locking on this object instance by default Also this is from Andrie's book http://www.informit.com/articles/article.aspx?p=1609144
Re: Environment variable for application storage under OSX ?
On Thursday, 16 July 2015 at 21:12:05 UTC, anonymous wrote: I have the following code, working under Win and Linux: --- import std.process: environment; immutable string p; static this() { version(Win32) p = environment.get(APPDATA); version(linux) p = /home/ ~ environment.get(USER); version(OSX) p = ?; } --- what would be the OSX equivalent (to get the path where the applications data are commonmly stored)? Maybe checkout http://code.dlang.org/packages/standardpaths
Re: How to use core.thread.Thread
On Thursday, 16 July 2015 at 07:57:13 UTC, aki wrote: I can't resolve the compile errors: import core.thread; class DerivedThread : Thread { int count = 0; this() { super(run); } private void run() { inc(); //testThread.d(8): Error: shared method testThread.DerivedThread.inc is not callable using a non-shared object } synchronized void inc() { ++count; //testThread.d(11): Deprecation: read-modify-write operations are not allowed for shared variables. Use core.atomic.atomicOp!+=(this.count, 1) instead. } } void main() { auto thr = new DerivedThread(); thr.start(); thr.inc(); //testThread.d(17): Error: shared method testThread.DerivedThread.inc is not callable using a non-shared object thr.join(); } 1. Should I declare thr as shared? But auto thr = new shared DerivedThread(); does not resolve it. 2. Why ++count cause an error? I think it is safe because it is marked as synchronized. If it is forced to use atomicOp all the time, it's painful. 3. Are there any tutorials about using Thread class? Aki. If I remember a synchronized method requires this to be shared, you should be fine using a synchronized block in the method for non-shared instances. But using atomicOp will avoid a lock. void inc() { synchronized { ++count; } } You are locking on this object instance by default
enum template shorthand and short circuit evaluation
Should this work? It seems like the short circuit booleans are not working: import std.traits; enum isPrimitive(T) = isBasicType!T || (isArray!T isBasicType! (ForeachType!T)); void main() { assert(isPrimitive!int); assert(isPrimitive!char); assert(isPrimitive!string); assert(isPrimitive!(byte[])); assert(!isPrimitive!test1); assert(!isPrimitive!test2); assert(!isPrimitive!test3); } class test1 {} struct test2 {} interface test3 {} dmd test C:\D\dmd2\windows\bin\..\..\src\phobos\std\traits.d(5762): Error: invalid foreach aggregate 0 test.d(5): Error: template instance std.traits.ForeachType!int error instantiating test.d(9):instantiated from here: isPrimitive!int test.d(9): Error: template instance test.isPrimitive!int error instantiating C:\D\dmd2\windows\bin\..\..\src\phobos\std\traits.d(5762): Error: invalid foreach aggregate '\xff' test.d(5): Error: template instance std.traits.ForeachType!char error instantiating test.d(10):instantiated from here: isPrimitive!char test.d(10): Error: template instance test.isPrimitive!char error instantiating C:\D\dmd2\windows\bin\..\..\src\phobos\std\traits.d(5762): Error: invalid foreach aggregate null test.d(5): Error: template instance std.traits.ForeachType!(test1) error instantiating test.d(14):instantiated from here: isPrimitive!(test1) test.d(14): Error: template instance test.isPrimitive!(test1) error instantiating C:\D\dmd2\windows\bin\..\..\src\phobos\std\traits.d(5762): Error: invalid foreach aggregate test2() test.d(5): Error: template instance std.traits.ForeachType!(test2) error instantiating test.d(15):instantiated from here: isPrimitive!(test2) test.d(15): Error: template instance test.isPrimitive!(test2) error instantiating C:\D\dmd2\windows\bin\..\..\src\phobos\std\traits.d(5762): Error: invalid foreach aggregate null test.d(5): Error: template instance std.traits.ForeachType!(test3) error instantiating test.d(16):instantiated from here: isPrimitive!(test3) test.d(16): Error: template instance test.isPrimitive!(test3) error instantiating DMD32 D Compiler v2.065 But this style works: template isPrimitive(T) { static if(isBasicType!T || (isArray!T isBasicType!(ForeachType!T))) { enum isPrimitive = true; } else { enum isPrimitive = false; } } -Byron
scope exit in mixin template
Can we not use scope(..) in a mixin template? struct bar {} bar* c_make() { return new bar(); } void c_free(bar* b) { b = null; } mixin template Foo() { auto b = c_make; scope(exit) if(b) c_free(b); } void main() { mixin Foo; } I get Error: Declaration expected, not '(' -Byron
Re: Livestreaming DConf?
On Fri, 09 May 2014 12:48:28 -0700, Andrei Alexandrescu wrote: Hi folks, We at Facebook are very excited about the upcoming DConf 2014. In fact, so excited we're considering livestreaming the event for the benefit of the many of us who can't make it to Menlo Park, CA. Livestreaming entails additional costs so we're trying to assess the size of the online audience. Please follow up here and on twitter: https://twitter.com/D_Programming/status/464854296001933312 Thanks, Andrei +1
Re: API
On Mon, 05 May 2014 17:10:35 -0700, Andrei Alexandrescu wrote: So I'm looking at creation functions and in particular creation functions for arrays. 1. Follow the new int[n] convention: auto a = allok.make!(int[])(42); assert(a.length == 42); assert(a.equal(repeat(0, 42)); Why not use make for length only 2. Follow the [ literal ] convention: auto a = allok.make!(int[])(42); assert(a.length == 1); assert(a[0] == 42); And build here for building up the array
Re: Parallel execution of unittests
On Thu, 01 May 2014 11:44:11 +, w0rp wrote: On Thursday, 1 May 2014 at 11:05:55 UTC, Jacob Carlborg wrote: On 2014-04-30 23:35, Andrei Alexandrescu wrote: Agreed. I think we should look into parallelizing all unittests. -- Andrei I recommend running the tests in random order as well. This is a bad idea. Tests could fail only some of the time. Even if bugs are missed, I would prefer it if tests did exactly the same thing every time. Running tests in random order helps find hidden dependencies, but I wouldn't want it as a default. I lot of unittesting libraries offer this. If you don't run tests often it doesn't help much, but if you do TDD it can help.
Re: Parallel execution of unittests
On Wed, 30 Apr 2014 09:02:54 -0700, Andrei Alexandrescu wrote: I think indeed a small number of unittests rely on order of execution. Those will be still runnable with a fork factor of 1. We'd need a way to specify that - either a flag or: static shared this() { Runtime.unittestThreads = 1; } Andrei Named tested seems like a no brainier to me. Maybe nested unittests? unittest OrderTests { // setup for all child tests? unittest a { } unittest b { } } I also wonder if its just better to extend/expose the unittest API for more advanced things like order of execution, test reporting, and parallel execution. And we can just support an external unittesting library to do all the advanced testing options.
Re: D For A Web Developer
On Wed, 30 Apr 2014 17:17:01 +, Ola Fosheim Grøstad wrote: 4. server unwraps the data and blindly inserts it into the database u.. wtf? This is why hackers keep stealing my credit card Client side validation should only be used for giving users immediate fed back and saving cycles. You do know I can look at your js, find all of your ajax calls and send what ever data I want right..
Re: DIP61: redone to do extern(C++,N) syntax
On Sun, 27 Apr 2014 12:54:51 -0700, Walter Bright wrote: http://wiki.dlang.org/DIP61 I really like this. I think it is clean simple and a better approach then adding the namespace keyword. Plus when people come to D from C++ they wont misuse namespace. Since D has awesome module aliasing we don't have to worry to much about module/namespace conflicts. Though it would be interesting to alias the extern directly (if we cant already). alias lib1 = extern(C++, company.lib1) { }; My only concern is when libraries have extension libraries that add to the main libraries namespace. ie: big_library_everyone_loves_to_use.c++ namespace biglib { namespace core { ... } } small_helper_lib_a_few_people_use.c++ namespace biglib { void helper1() ... // I call 50 functions so you dont have to! namespace core() { ... } // I add extra special memory handlers } With the current DIP you have to combine the d/di files to merge the extern namespaces. Makes it hard to maintain these as separate libraries. Specially when your library has a lot of extension libs. Maybe someone can write a cleaver mixin for this problem. Also is there any plans on dealing with newing c++ memory? Having to add factories to all of the c++ libs feels a little goofy, but either way this DIP gets us a lot closer to C++/D bliss!
Re: DIP61: redone to do extern(C++,N) syntax
On Mon, 28 Apr 2014 10:27:19 -0400, Steven Schveighoffer wrote: On Sun, 27 Apr 2014 15:54:51 -0400, Walter Bright newshou...@digitalmars.com wrote: http://wiki.dlang.org/DIP61 I think there is a big problem with name lookup here. Consider this code: module foo; void func() {} module bar; extern(C) func(); module prog; import foo; import bar; void main() { func(); // error foo.func(); // ok bar.func(); // ok, uses C binding (no name mangling) } In this case, even though the C function is not mangled or in any other namespace, the module can be used for unambiguous calling. But in your proposal, the name qualifiers could be either C++ namespaces or D modules. This presents an unnecessary ambiguity. e.g. module foo; void func() {} module bar; extern(C++, foo) void func(); // foo::func in C++ land module prog; import foo; import bar; void main() { func(); // error foo.func(); // ALSO error bar.func(); // Not error, BUT it's actually calling foo::func from C++ land! } I think we cannot change name lookup rules for C++ symbols, because the D module system already owns those. An alternative is that you could create an alternate way to disambiguate. Let's pick a strawman called _cpp, just to illustrate: void main() { func(); // error still foo.func(); // calls D's foo module's func bar.func(); // calls D's bar module's func (defined as foo::func) _cpp.func(); // error, _cpp denotes we are using namespace qualifiers, and there is no global C++ func _cpp.foo.func(); // calls D's bar module's func. bar._cpp.foo.func(); // ditto } Really, _cpp could be anything. But I think hijacking D's module qualifiers does not help. To make things seamless, you could make it ::, but I know many people have objections to that. -Steve why not import _cpp = bar; ?
Re: DIP61: redone to do extern(C++,N) syntax
On Sun, 27 Apr 2014 12:54:51 -0700, Walter Bright wrote: http://wiki.dlang.org/DIP61 Would nesting imported namespaces work? lib/package.d public export(C++, a) { public import lib.b; } lib/b.d export(C++, b) { void foo(); } main.d import lib; a.b.foo();
Re: DIP61: redone to do extern(C++,N) syntax
On Mon, 28 Apr 2014 10:45:14 -0400, Steven Schveighoffer wrote: On Mon, 28 Apr 2014 10:37:36 -0400, Byron byron.he...@gmail.com wrote: why not import _cpp = bar; ? That doesn't help. foo.func() is still ambiguous. With this proposal, you have hijacked the meaning of namespace lookup. When I say x.y.z, it doesn't just mean look for symbol z in module x/y.d, it can also mean to look for symbol z in C++ namespace x::y. This was not the case with C binding, which continued to use D modules for symbol lookup. Consider that a boatload of C++ code is named std::something. Now, std.string has an ambiguous meaning wherever it is used! -Steve bar is renamed, thus you have to access via _cpp.[namespace] renames were added to prevent hijacking.
Re: DIP61: redone to do extern(C++,N) syntax
On Mon, 28 Apr 2014 10:56:24 -0400, Steven Schveighoffer wrote: Most definitely no. When the compiler builds b.d, he has no idea it's imported from inside another namespace! We don't want #include-style issues. -Steve So we would have to include the entire namespace in a single d file or is this okay: a/package.d extern(C++, a) {} public import a.b; a/b.d extern(C++, a.b) {}
Re: DIP61: redone to do extern(C++,N) syntax
On Mon, 28 Apr 2014 10:54:17 -0400, Steven Schveighoffer wrote: That doesn't help. foo.func() is still ambiguous. With this proposal, you have hijacked the meaning of namespace lookup. When I say x.y.z, it doesn't just mean look for symbol z in module x/y.d, it can also mean to look for symbol z in C++ namespace x::y. This was not the case with C binding, which continued to use D modules for symbol lookup. Consider that a boatload of C++ code is named std::something. Now, std.string has an ambiguous meaning wherever it is used! -Steve bar is renamed, thus you have to access via _cpp.[namespace] renames were added to prevent hijacking. That renames the bar module, but not the foo C++ namespace, which can be assumed when calling foo.func. In reality, you could fix the situation by renaming the foo D module, and then foo.func would unambiguously refer to bar's func :) Another alternative fix would be to allow renaming C++ namespaces. I strongly recommend against that. The better alternative is to reserve qualified name lookup to D modules alone. Adding a mechanism that is possibly ugly, but that does NOT conflict with module lookup, in order to disambiguate C++ symbols is fine. -Steve I am confused now, cross module renaming?? I was thinking this: a.d extern(C++, std) { ... class string ... } b.d import std.string; import cpp = a; // a must be accessed via cpp std.string /// okay D version cpp.std.string ... /// okay c++ version string ... /// Okay D version cpp.string /// Okay C++ version
Re: DIP61: redone to do extern(C++,N) syntax
On Mon, 28 Apr 2014 11:21:52 -0400, Steven Schveighoffer wrote: On Mon, 28 Apr 2014 11:09:38 -0400, Byron byron.he...@gmail.com wrote: I am confused now, cross module renaming?? I was thinking this: a.d extern(C++, std) { ... class string ... } class string now has two fully-qualified names. a.string, and std.string (assuming the current DIP is implemented). b.d import std.string; import cpp = a; // a must be accessed via cpp This renames the a *module*, but not the C++ namespace. The C++ namespace is entirely separate from D's module imports. So now, a's string has two names, cpp.string and std.string (still). std.string /// okay D version Error. Refers both to the std.string module, and the string class within the std C++ namespace. cpp.std.string ... /// okay c++ version I don't think this would work either. This is a mix of D modules, and C++ namespaces. The DIP does not mention this possibility. string ... /// Okay D version I think this may work. cpp.string /// Okay C++ version Yes. -Steve Awesome this help me understand your point. So why does the namespace live outside of the module? They have to live in the imported scope? This seems like a big problem to me. Or I am missing something else? -Byron
Re: DIP60: @nogc attribute
On Thu, 17 Apr 2014 11:55:14 +, w0rp wrote: I'm not convinced that any automatic memory management scheme will buy much with real time applications. Generally with real-time processes, you need to pre-allocate. I think GC could be feasible for a real-time application if the GC is precise and collections are scheduled, instead of run randomly. Scoped memory also helps. I thought the current GC only ran on allocations? If so @nogc is *very* useful to enforce critical paths. If we added a @nogcscan on blocks that do not contain pointers we maybe able to reduce the collection time, not as good as a precise collector. I would think we can get decent compiler support for this (ie. no refs, pointers, class, dynamic array).
Re: DIP60: @nogc attribute
On Fri, 18 Apr 2014 16:17:10 +, Brad Anderson wrote: You can actually prevent scanning/collection already without much difficulty: GC.disable(); scope(exit) GC.enable(); I feel like @nogc is most useful in avoiding surprises by declaring your assumptions. Problems like how toUpperInPlace would still allocate (with gusto) could much more easily be recognized and fixed with @nogc available. I am talking more about hinting to the conservative GC about blocks it doesn't need to scan for addresses. struct Vertex { int x, y, z, w; } @nogcscan Vertex vertexs[10_000]; so when a GC scan does happen it can skip scanning the vertexs memory block completely since we are promising not to hold on to addresses in it.