Re: Don't expect class destructors to be called at all by the GC
On Thursday, 21 December 2017 at 18:20:19 UTC, H. S. Teoh wrote: Even calling GC.collect directly did not guarantee the DB handle was closed at the right time. This may have been a bug in my code that left dangling references to it, or perhaps the array of Database handles was still scanned through by the GC even though the only remaining array slice has a shorter length. Whatever the reason was, it left me with the very unpleasant prospect of silently accumulating file descriptor leaks. Last I checked, the GC doesn't understand arrays. It only understands "segment of memory that might contain pointers" and "segment of memory that doesn't contain pointers". You might have gotten better results if you had nulled out the reference in the array. Of course, that relies on not having any remaining references on the stack or in registers, neither of which is easy to guarantee.
Re: Don't expect class destructors to be called at all by the GC
On Thursday, 21 December 2017 at 19:43:16 UTC, Steven Schveighoffer wrote: On 12/20/17 9:57 PM, Mike Franklin wrote: [...] It's implementation defined :) The gist is, you cannot expect that destructors will be run in a timely manner, or at all. They may be called, and most of the time they are. But the language nor the current implementation makes a guarantee that they will be called. For this reason, any classes that use non-memory resources should clean up those resources before becoming garbage. This is why most of the time, such items are managed by structs. Note that the same non-guarantee exists in other GC'd languages, such as Java or C#. -Steve Except for that in C# you have the IDisposable interface, which can actually be used to prevent this kind of stuff and generally used to clean up non-GC memory.
Re: can't run libuid examples
On Thursday, 21 December 2017 at 18:41:28 UTC, greatsam4sure wrote: I am having problem with running the examples of libuid on Windows and how to use libuid on a project without errors. I am using dmd version 2.076 Okay, but how are we supposed to help if you don't show us what errors you get? Errors can depend on many things like your compiler-setup, paths, linker, your code, packages, compiler-flags and so on.
Re: Version Cygwin
On 21/12/2017 4:22 PM, Anonymouse wrote: Cygwin is a reserved version[1], alongside Windows and linux and the like. However it doesn't seem to be automatically recognised. import std.stdio; void main() { version(Cygwin) writeln("Cygwin"); } Compiled from a Cygwin prompt this prints nothing. So I thought to add versions: [ "Cygwin" ] to dub.json, but dub refuses. Error: version identifier `Cygwin` is reserved and cannot be set Is there any way to force Cygwin or should I resign to creating an alternative lowercase "cygwin" version? The use-case is to version stdout.flush() here and there to counter that the default Cygwin terminal (mintty) doesn't update when text is written to the terminal. I forget the reason why it doesn't. [1]: https://dlang.org/spec/version.htm You are not using a Cygwin build. It doesn't matter who calls a process, it doesn't change the version's by itself. As far as I know, nobody supports Cygwin like this.
Re: Fold in Parallelism
On Friday, 22 December 2017 at 00:18:40 UTC, Seb wrote: On Friday, 22 December 2017 at 00:12:45 UTC, Vino wrote: On Thursday, 21 December 2017 at 06:31:52 UTC, Ali Çehreli wrote: [...] Hi Ali, Thank you very much, the pull request is in open state, so can you please let me know when can we can test the same. From, Vino.B It will take a couple of days for this pull request to reach a ready form and to be approved. The best way to help it to move forward is to review it yourself or at least vote for it on GitHub ;-) Once merged it will appear on dmd-nightly on the next day, but I'm not sure why you depend on his pull request? Can't you just use the code directly? Hi Seb, I am fine waiting for a couple of days for this pull request to reach to teh ready form and approved. Sure will vote on GItHub. From, Vino.B
Re: Don't expect class destructors to be called at all by the GC
On Friday, 22 December 2017 at 00:09:31 UTC, Mike Franklin wrote: What condition(s) would cause a destructor for an object that is managed by the GC to potentially not be called? Here: === import std.stdio; class Clazz { ~this() { writeln("Class dest"); } } void makeClazz() { auto clazz = new Clazz; } void main() { makeClazz(); } static ~this() { writeln("Static dest"); } This outputs: Static dest Class dest The class destructor is not run during the lifetime of the program. The fact that it's run during runtime termination is an implementation detail. Another implementation might not run a finalization at termination. So the destructors (finalizers) are only run when an object is collected. No collection, no destructor call.
Re: Fold in Parallelism
On Friday, 22 December 2017 at 00:12:45 UTC, Vino wrote: On Thursday, 21 December 2017 at 06:31:52 UTC, Ali Çehreli wrote: On 12/19/2017 02:32 AM, Vino wrote: > even though it is a simple code copy+paste The change was a little more complicated than my naive adaptation from std.algorithm.fold. Here is the pull request: https://github.com/dlang/phobos/pull/5951 Ali Hi Ali, Thank you very much, the pull request is in open state, so can you please let me know when can we can test the same. From, Vino.B It will take a couple of days for this pull request to reach a ready form and to be approved. The best way to help it to move forward is to review it yourself or at least vote for it on GitHub ;-) Once merged it will appear on dmd-nightly on the next day, but I'm not sure why you depend on his pull request? Can't you just use the code directly?
Re: Fold in Parallelism
On Thursday, 21 December 2017 at 06:31:52 UTC, Ali Çehreli wrote: On 12/19/2017 02:32 AM, Vino wrote: > even though it is a simple code copy+paste The change was a little more complicated than my naive adaptation from std.algorithm.fold. Here is the pull request: https://github.com/dlang/phobos/pull/5951 Ali Hi Ali, Thank you very much, the pull request is in open state, so can you please let me know when can we can test the same. From, Vino.B
Re: Don't expect class destructors to be called at all by the GC
On Thursday, 21 December 2017 at 19:43:16 UTC, Steven Schveighoffer wrote: The gist is, you cannot expect that destructors will be run in a timely manner, or at all. They may be called, and most of the time they are. But the language nor the current implementation makes a guarantee that they will be called. I understand that we can't deterministically predict when a destructor will be called, but if we can't deterministically predict if a destructor will be called, that seems asinine. What condition(s) would cause a destructor for an object that is managed by the GC to potentially not be called? Thanks, Mike
Re: No of threads
On Thursday, 21 December 2017 at 00:32:50 UTC, codephantom wrote: On Wednesday, 20 December 2017 at 13:41:06 UTC, Vino wrote: Hi Ali, Thank you very much, below are the observations, our program is used to calculate the size of the folders, and we don't see any improvements in the execution speed from the below test, are we missing something. Basically we expected the total execution time for the test 2 , as the time taken to calculate the size of the biggest folder + few additional mins, the biggest folder size is of 604 GB. Memory usage is just 12 MB, whereas the server has 65 GB and hardly 30% - 40% is used at any given point in time, so there is no memory constrain. Are you running this over the network, or on (each) server that contains the actual folders? Hi, Yes, the file system used is a NetApp file system mapped on Windows server. From, Vino.B
Re: No of threads
On Wednesday, 20 December 2017 at 17:31:20 UTC, Ali Çehreli wrote: On 12/20/2017 05:41 AM, Vino wrote: > auto TL = dFiles.length; > auto TP = new TaskPool(TL); I assume dFiles is large. So, that's a lot of threads there. > foreach (d; TP.parallel(dFiles[],1)) You tried with larger work unit sizes, right? More importantly, I think all these threads are working on the same disk. If the access is serialized by the OS or a lower entity, then all threads necessarily wait for each other, making the whole exercise serial. > auto SdFiles = Array!ulong(dirEntries(d, SpanMode.depth).map!(a => > a.size).fold!((a,b) => a + b) (x))[].filter!(a => a > Size); > Thread.sleep(5.seconds); You don't need that at all. I had left it in there just to give me a chance to examine the number of threads the program was using. Ali Hi Ali, Below are the answers. "I think all these threads are working on the same disk. If the access is serialized by the OS or a lower entity, then all threads necessarily wait for each other, making the whole exercise serial." The File system that is used here to scan and find the folder size is an NetApp File system mapped on Windows 2008. The file system is exported using NFS v3 so you are right that the disk access is serialized. The no of folders are from 2 NetApp file system and no of folders in each file system is as below File system 1 : 76 folders and File system 2: 77 folders. You don't need that at all. I had left it in there just to give me a chance to examine the number of threads the program was using. We have not update your main code yet, it was a test that we performed on test server. From, Vino.B
Re: Don't expect class destructors to be called at all by the GC
On Thursday, 21 December 2017 at 18:48:38 UTC, H. S. Teoh wrote: Alas, RefCounted doesn't work well with inheritance... Oh? What's the issue? Implicit casts don't work so you can't pass a RefCounted!Class as RefCounted!Interface except in simple cases using alias this tricks.
Re: One liner for creating an array filled by a factory method
On 12/21/17 4:00 PM, kerdemdemir wrote: I have a case like : http://rextester.com/NFS28102 I have a factory method, I am creating some instances given some enums. My question is about : void PushIntoVector( BaseEnum[] baseEnumList ) { Base[] baseList; foreach ( tempEnum; baseEnumList ) { baseList ~= Factory(tempEnum); } } I don't want to use "foreach" loop. Is there any cool std function that I can call ? Something like baseEnumList.CoolStdFunc!( a=> Factory(a) )(baseList); https://dlang.org/phobos/std_algorithm_iteration.html#map -Steve
One liner for creating an array filled by a factory method
I have a case like : http://rextester.com/NFS28102 I have a factory method, I am creating some instances given some enums. My question is about : void PushIntoVector( BaseEnum[] baseEnumList ) { Base[] baseList; foreach ( tempEnum; baseEnumList ) { baseList ~= Factory(tempEnum); } } I don't want to use "foreach" loop. Is there any cool std function that I can call ? Something like baseEnumList.CoolStdFunc!( a=> Factory(a) )(baseList); Erdem
Re: Don't expect class destructors to be called at all by the GC
On 12/20/17 9:57 PM, Mike Franklin wrote: "Don't expect class destructors to be called at all by the GC" I was a bit shocked to read that here: https://p0nce.github.io/d-idioms/#The-trouble-with-class-destructors The document tries to clarify with: "The garbage collector is not guaranteed to run the destructors for all unreferenced objects." Unfortunately, that doesn't really shed much light on this oddity. So, specifically, under what circumstances are destructors not called? It's implementation defined :) The gist is, you cannot expect that destructors will be run in a timely manner, or at all. They may be called, and most of the time they are. But the language nor the current implementation makes a guarantee that they will be called. For this reason, any classes that use non-memory resources should clean up those resources before becoming garbage. This is why most of the time, such items are managed by structs. Note that the same non-guarantee exists in other GC'd languages, such as Java or C#. -Steve
Re: Don't expect class destructors to be called at all by the GC
On Thu, Dec 21, 2017 at 06:45:27PM +, Adam D. Ruppe via Digitalmars-d-learn wrote: > On Thursday, 21 December 2017 at 18:20:19 UTC, H. S. Teoh wrote: > > When the scoped destruction of structs isn't an option, RefCounted!T > > seems to be a less evil alternative than an unreliable class dtor. > > :-/ > > Alas, RefCounted doesn't work well with inheritance... Oh? What's the issue? > Though, what you could do is make the refcounted owners and borrow the > actual reference later. Yeah, I figured that I pretty much have to use a proxy struct with RefCounted, and have the struct dtor do the actual cleanup of the class reference, something like: class Resource { void cleanup(); // inheritable } struct Proxy { private Resource res; this(Resource _res) { res = _res; } ~this() { res.cleanup(); } } ... auto obj = RefCounted!Proxy(allocateResource()); T -- The problem with the world is that everybody else is stupid.
Re: Don't expect class destructors to be called at all by the GC
On Thursday, 21 December 2017 at 18:20:19 UTC, H. S. Teoh wrote: When the scoped destruction of structs isn't an option, RefCounted!T seems to be a less evil alternative than an unreliable class dtor. :-/ Alas, RefCounted doesn't work well with inheritance... Though, what you could do is make the refcounted owners and borrow the actual reference later.
can't run libuid examples
I am having problem with running the examples of libuid on Windows and how to use libuid on a project without errors. I am using dmd version 2.076
Re: Don't expect class destructors to be called at all by the GC
On Thu, Dec 21, 2017 at 06:50:44AM +, Mike Parker via Digitalmars-d-learn wrote: [...] > I just don't even bother with class destructors. Without a guarantee > that they can run and without any sort of deterministic behavior, it's > really not appropriate to refer to them as destructors and they're > about as useful as Java finalizers, which means not at all. In order > to make them less error prone, we need to separate the concept of > destruction from finalization and allow both destructors and > finalizers. That's what I've taken to doing manually, by implementing > a `terminate` function in my classes that I either call directly or > via a ref-counted templated struct called Terminator. I recently ran into this problem while using Adam Ruppe's lightweight SQLite binding (arsd/sqlite.d). Originally, I kept an open database handle (which is a class instance) throughout the lifetime of the program; in this case, I could just use a scoped reference and it would ensure the DB is closed when the handle went out of scope, just what I want. But as my code developed, I began to need to cache multiple DB handles for performance, and scope no longer helps me there. At first I thought, no problem, the GC would handle this for me. Right? Wrong. Even calling GC.collect directly did not guarantee the DB handle was closed at the right time. This may have been a bug in my code that left dangling references to it, or perhaps the array of Database handles was still scanned through by the GC even though the only remaining array slice has a shorter length. Whatever the reason was, it left me with the very unpleasant prospect of silently accumulating file descriptor leaks. I ended up calling .destroy on the class instance explicitly just so the destructor would run at the right time, right before nulling the reference so that the GC would collect the memory. This makes using classes in D an even dimmer prospect than it already generally is (nowadays, and I don't seem to be the only one, I prefer to just use structs and templates instead of runtime polymorphism, where possible). When the scoped destruction of structs isn't an option, RefCounted!T seems to be a less evil alternative than an unreliable class dtor. :-/ T -- MACINTOSH: Most Applications Crash, If Not, The Operating System Hangs
Re: GUI program on Mac OS in D?
On Thursday, 21 December 2017 at 15:45:32 UTC, Adam D. Ruppe wrote: oh sorry i forgot to post this sooner here's my code so far. when i'm reasonably happy with it, it will be part of my simpledisplay.d. I might leave it undocumented, but if you wanted to dive into my source the final version will be in there somewhere. Thanks for sharing! Your solution is more complete for sure. I think I will borrow a few ideas here :)
Re: It's possible to declare a variable inside a static foreach()?
On Thursday, 21 December 2017 at 16:38:36 UTC, Anonymouse wrote: On Thursday, 21 December 2017 at 16:25:00 UTC, Marc wrote: For example, I'd like to declare a variable inside a static foreach like in below code, just for better organization, otherwise, I have to use the value directly instead of the variable. If the value is used more than once, it might be inviable. enum allMembers = __traits(derivedMembers, C); static foreach(enum string member; allMembers) { enum attributes = __traits(getAttributes, __traits(getMember, C, member)); static foreach(C c; attributes) { writeln(c); } } I got redefinition erros of "atributes" on this. Can I have this only at compile time? I don't think you need static for foreach of __traits allMembers/derivedMembers and .tupleof. It unrolls at compile-time and builds fine for me if I just remove the statics. https://run.dlang.io/is/Ln3kVZ /*static*/ foreach(C c; attributes) Mind that c will not be of type C but of the type of the attribute. The trick with static foreach is to create a new scope: https://run.dlang.io/is/wODA0x DIP1010 [1] suggested __local but while this is implemented, it it's not exposed yet. There's also a bit of discussion about this at [2]. [1] https://github.com/dlang/DIPs/blob/master/DIPs/DIP1010.md#local-declarations [2] https://github.com/dlang/phobos/pull/5729
Re: It's possible to declare a variable inside a static foreach()?
On Thursday, 21 December 2017 at 16:25:00 UTC, Marc wrote: For example, I'd like to declare a variable inside a static foreach like in below code, just for better organization, otherwise, I have to use the value directly instead of the variable. If the value is used more than once, it might be inviable. enum allMembers = __traits(derivedMembers, C); static foreach(enum string member; allMembers) { enum attributes = __traits(getAttributes, __traits(getMember, C, member)); static foreach(C c; attributes) { writeln(c); } } I got redefinition erros of "atributes" on this. Can I have this only at compile time? I don't think you need static for foreach of __traits allMembers/derivedMembers and .tupleof. It unrolls at compile-time and builds fine for me if I just remove the statics. https://run.dlang.io/is/Ln3kVZ /*static*/ foreach(C c; attributes) Mind that c will not be of type C but of the type of the attribute.
It's possible to declare a variable inside a static foreach()?
For example, I'd like to declare a variable inside a static foreach like in below code, just for better organization, otherwise, I have to use the value directly instead of the variable. If the value is used more than once, it might be inviable. enum allMembers = __traits(derivedMembers, C); static foreach(enum string member; allMembers) { enum attributes = __traits(getAttributes, __traits(getMember, C, member)); static foreach(C c; attributes) { writeln(c); } } I got redefinition erros of "atributes" on this. Can I have this only at compile time?
Version Cygwin
Cygwin is a reserved version[1], alongside Windows and linux and the like. However it doesn't seem to be automatically recognised. import std.stdio; void main() { version(Cygwin) writeln("Cygwin"); } Compiled from a Cygwin prompt this prints nothing. So I thought to add versions: [ "Cygwin" ] to dub.json, but dub refuses. Error: version identifier `Cygwin` is reserved and cannot be set Is there any way to force Cygwin or should I resign to creating an alternative lowercase "cygwin" version? The use-case is to version stdout.flush() here and there to counter that the default Cygwin terminal (mintty) doesn't update when text is written to the terminal. I forget the reason why it doesn't. [1]: https://dlang.org/spec/version.htm
Re: Don't expect class destructors to be called at all by the GC
On Thursday, 21 December 2017 at 06:50:44 UTC, Mike Parker wrote: On Thursday, 21 December 2017 at 04:10:56 UTC, user1234 wrote: [...] [...] [...] The root of the problem is that in D, class destruction and finalization are conflated. It would be much more accurate to refer to ~this in classes as a finalizer. Then this sort of confusion wouldn't be so widespread. [...] Have you considered writing a DIP on this?
Re: std way to remove multiple indices from an array at once
On 12/20/17 7:52 PM, Nicholas Wilson wrote: On Thursday, 21 December 2017 at 00:23:08 UTC, Steven Schveighoffer wrote: On 12/20/17 6:01 PM, aliak wrote: Hi, is there a way to remove a number of elements from an array by a range of indices in the standard library somewhere? I wrote one (code below), but I'm wondering if there's a better way? Also, can the below be made more efficient? auto without(T, R)(T[] array, R indices) if (isForwardRange!R && isIntegral!(ElementType!R) && !isInfinite!R) { T[] newArray; ElementType!R start = 0; foreach (i; indices) { newArray ~= array[start .. i]; start = i + 1; } newArray ~= array[start .. $]; return newArray; } // Usage long[] aa = [1, 2, 3, 4] aa = aa.without([1, 3]) Thanks! I'm assuming here indices is sorted? Because it appears you expect that in your code. However, I'm going to assume it isn't sorted at first. Now: import std.range; import std.algorithm; auto indices = [1,2,3,4]; aa = aa.enumerate.filter!(a => !indicies.canFind(a[0])).map(a => a[1]).array; Now, this is going to be O(n^2), but if indices is sorted, you could use binary search: auto sortedIdxs = indices.assumeSorted; // also could be = indices.sort() arr = arr.enumerate.filter!(a => !sortedIdxs.contains(a[0])).map(a => a[1]).array; Complexity would be O(n lg(n)) It's not going to be as good as hand-written code, complexity wise, but it's definitely shorter to write :) isn't that n log(m), where n is length of array and m is length of indices? Strictly speaking, yes :) But lg(n) and lg(m) are going to be pretty insignificantly different. If indices is sorted with no duplicates and random access then you can do it in linear time. int i; int ii; int[] indicies = ...; arr = arr.filter!((T t) { scope(exit) i++; if (i == indicies[ii]) { ii++; return false; } return true; }).array; Very nice! as aliak mentioned, however, you have a bug, as ii might extend beyond the size of indicies. So should be if(ii < indices.length && indicies[ii] == i). We are always focused on using a chained one-liner, but your lambda stretches that ;) Here's a similar solution with an actual range: https://run.dlang.io/is/gR3CjF Note, all done lazily. However, the indices must be sorted/unique. -Steve
Re: GUI program on Mac OS in D?
On Thursday, 14 December 2017 at 19:10:26 UTC, mrphobby wrote: This looks pretty awesome and very much like something I was looking for. Would really appreciate if you could share your work. Otherwise I'll have to roll up my sleeves and try hacking it on my own :) oh sorry i forgot to post this sooner here's my code so far. when i'm reasonably happy with it, it will be part of my simpledisplay.d. I might leave it undocumented, but if you wanted to dive into my source the final version will be in there somewhere. CODE MODULE - import helper_module; import core.stdc.math; import core.stdc.stdio; void main() { auto delegate_ = AppDelegate.alloc.init; assert(delegate_, "AppDelegate null"); NSApp.delegate_ = delegate_; NSApp.setActivationPolicy(NSApplicationActivationPolicy.regular); NSApp.run(); } @ObjCParentOverride("NSObject") extern (Objective-C) interface AppDelegate : NSApplicationDelegate { mixin IVar!(NSWindow, "window"); mixin IVar!(ViewController, "controller"); extern (C) @ObjCMethodOverride("applicationShouldTerminateAfterLastWindowClosed:") static bool applicationShouldTerminateAfterLastWindowClosed(AppDelegate self, SEL sel, NSNotification notification) { return true; } extern (C) @ObjCMethodOverride("applicationDidFinishLaunching:") static void applicationDidFinishLaunching(AppDelegate self, SEL sel, NSNotification notification) { NSApp.menu = mainMenu(); immutable style = NSWindowStyleMask.resizable | NSWindowStyleMask.closable | NSWindowStyleMask.miniaturizable | NSWindowStyleMask.titled; auto window = NSWindow.alloc.initWithContentRect( NSMakeRect(10, 10, 300, 300), style, NSBackingStoreType.buffered, false ); window.title = "D Rox"; auto controller = ViewController.alloc.init; window.contentView = controller.view; window.center(); self.window = window; self.controller = controller; window.makeKeyAndOrderFront(null); NSApp.activateIgnoringOtherApps(true); } // copy these two lines on any class typeof(this) init() @selector("init"); mixin RegisterObjCClass; } extern (Objective-C) interface ViewController : NSViewController { extern (C) @ObjCMethodOverride("loadView") static void loadView(ViewController self, SEL sel) { printf("loadView\n"); } extern (C) @ObjCMethodOverride("viewDidLoad") static void viewDidLoad(ViewController self, SEL sel) { printf("viewDidLoad\n"); } ViewController init() @selector("init"); mixin RegisterObjCClass; } NSMenu mainMenu() { auto mainMenu = NSMenu.alloc.init("MainMenu".toNSString); auto title = "Apple"; auto menu = NSMenu.alloc.init(title.toNSString); auto item = mainMenu.addItem(title.toNSString, null, "".toNSString); mainMenu.setSubmenu(menu, item); menu.addItem(NSMenuItem.alloc.init("Quit", "stop:", "q")); return mainMenu; } - HELPER MODULE: - version(OSX) { /* */ // Obj-C / Cocoa bindings and helpers /* */ // Special thanks to Jacob Carlborg // see: http://forum.dlang.org/thread/qzitebxwvavcfamsl...@forum.dlang.org /// Add an instance var to an Obj-C subclass mixin template IVar(T, string name) { extern(D) final { mixin("@IVarAttr T " ~ name ~ "() { return this.ivar!(name, T); }"); mixin("void " ~ name ~ "(T v) { this.ivar!(name, T) = v; }"); } } /// Add to your extern(Objective-C) interfaces if you need the parent class to be different /// from what in inherits from struct ObjCParentOverride { string parentClassName; } /// Attach to a method like `extern(C) static R name(typeof(this) self, SEL sel, Args...)` /// to give it a selector to override. struct ObjCMethodOverride { string selector; } /// And mix this in to your subclasses of the extern(Objective-C) interfaces mixin template RegisterObjCClass() { mixin ClassTrait; private static objc_method method(alias imp, string selector, const char* type = null)() { return objc_method(sel_registerName(selector.ptr), type, cast(IMP) ); } shared static this() {
Re: Write native GUI applications for Windows
On Monday, 18 December 2017 at 07:55:25 UTC, Andrey wrote: Hello! I have a question about creating native GUI applications for Windows 7 or/and Windows 10. Hi,here is a very good native d gui lib,it's name is "dgui": https://github.com/FrankLIKE/DguiT/ I fork and modify ,let it work on DMD2.077 for win7 or win10. It can make the x64 lib. You can try it. Injoy it. Frank.
Re: GUI program on Mac OS in D?
On Thursday, 14 December 2017 at 19:10:26 UTC, mrphobby wrote: On Thursday, 14 December 2017 at 14:07:25 UTC, Adam D. Ruppe wrote: I was playing with this myself based on Jacob's code and made it look like this: extern (Objective-C) interface ViewController : NSViewController { extern (C) @ObjCMethodOverride("loadView") static void loadView(ViewController self, SEL sel) { printf("loadView\n"); } extern (C) @ObjCMethodOverride("viewDidLoad") static void viewDidLoad(ViewController self, SEL sel) { printf("viewDidLoad\n"); } ViewController init() @selector("init"); mixin RegisterObjCClass; } This looks pretty awesome and very much like something I was looking for. Would really appreciate if you could share your work. Otherwise I'll have to roll up my sleeves and try hacking it on my own :) Ok, I finally had some time to work this out today. Thanks to the ideas posted here I was able to wrap something up despite my very limited knowledge of D and its compile time features :) Basically this is what your classes will look like: extern (Objective-C) @ObjCSuperClass("NSObject") interface AppDelegate : NSApplicationDelegate { mixin ObjCClass; AppDelegate init() @selector("init"); extern (C): @ObjCMethod("applicationDidFinishLaunching:") static void applicationDidFinishLaunching(AppDelegate self, SEL sel, NSNotification notification) { writefln("applicationDidFinishLaunching"); } } In this case I needed to add the explicit superclass attribute since NSApplicationDelegate is a protocol and not a class. If your object inherits from an interface representing a regular Objective-C class you don't need this. The actual registration and setup principle is based on Jacobs code and I added stuff to handle the attributes. Obviously you need declarations for Objective-C runtime calls but you can find those in Jacobs example source as well. Anyway, hope this helps. Feel free to fork and improve! https://gist.github.com/mrphobby/a247deb15d38aea86b3346079f32ce58
Re: Don't expect class destructors to be called at all by the GC
On Thursday, 21 December 2017 at 14:26:55 UTC, Guillaume Piolat wrote: On Thursday, 21 December 2017 at 06:50:44 UTC, Mike Parker wrote: That's what I've taken to doing manually, by implementing a `terminate` function in my classes that I either call directly or via a ref-counted templated struct called Terminator. I feel like I'm rambling but.. The problem with that approach is that you can't reuse Unique, RefCounted, scoped!T because they rely on .destroy I'm not proposing it as a general solution. It's easy to implement and it works for my use case, so it's one possible solution.
Re: Don't expect class destructors to be called at all by the GC
On Thursday, 21 December 2017 at 06:50:44 UTC, Mike Parker wrote: That's what I've taken to doing manually, by implementing a `terminate` function in my classes that I either call directly or via a ref-counted templated struct called Terminator. I feel like I'm rambling but.. The problem with that approach is that you can't reuse Unique, RefCounted, scoped!T because they rely on .destroy
Re: std way to remove multiple indices from an array at once
On Thursday, 21 December 2017 at 00:52:29 UTC, Nicholas Wilson wrote: On Thursday, 21 December 2017 at 00:23:08 UTC, Steven Schveighoffer wrote: I'm assuming here indices is sorted? Because it appears you expect that in your code. However, I'm going to assume it isn't sorted at first. auto sortedIdxs = indices.assumeSorted; // also could be = It's not going to be as good as hand-written code, complexity wise, but it's definitely shorter to write :) -Steve If indices is sorted with no duplicates and random access then you can do it in linear time. Ah yes, I guess sorted and unique as well would be the expected input. But nice to see the handling of non-sorted indices. I tried to search for an assumeUnique function as well (the assumeSorted one was nice to see) but it's not what I thought it'd be - seems to be more of an assumeUnaliased. And I guess there's no assumeUniqueElements. And the filter approach is nice! :) (just need to account for the last ii++ (when filter comes back in I think one case would be ii == indices.length and you'd get a range error) Thanks for the feedback!
Re: How to pack a struct to a ubyte[] in a more "The D way" style ?
hi Davis, Thanks for your great help to me! Yeah, the library may had a design principle when it was designed, as you can see the buffer appender is not that suitable for an application-defined structured data packing. And after I turn to the bitfield, I then got another trouble: The bitfield template only allows (8, 64) bits to be packed, so in a real application, and obviously, in my application, the packet is greater than 8 bytes. So, the appender and bitfield are not practical for my situation. And now, I realized that the problem what I have done is only using bit-shift other than using direct cast operator. In C, one can directly cast a struct to memory bytes, for D, the struct can have methods, and the alignment is also more complex. So, I think that handy packing and unpacking elements in a struct to D array is just OK. And better than C, the D array is autoincremented, this feature already makes the thing more simpler to understand. So, before I can write my own template for generating the packing and unpacking code, I would just remove the bit shit. Again, Thank you very much! On Thursday, 21 December 2017 at 12:21:55 UTC, Jonathan M Davis wrote: On Monday, December 18, 2017 08:45:32 Binghoo Dang via Digitalmars-d-learn wrote: hi Davis, I read the std.bitmanip, and I tried to test the code like below: ``` import std.stdio; import std.array; import std.bitmanip; void main(string[] args) { align(1) struct c { ushort c1; uint c2; //ubyte[8] c3; } ubyte[] buffer; auto ap = appender(); uint a = 0x11223344; ushort b = 0x6677; ap.append!uint(a); ap.append!ushort(b); c cobj; cobj.c1 = 0xEEFF; cobj.c2 = 0xDEADBEAF; //cobj.c3 = [0x12, 0x34, 0x56, 0x78]; ap.append(cobj); ubyte[3] d = [0xAA, 0xBB, 0xCC]; ap.append(d); foreach(e; buffer) { writef("%02X ", e); } } ``` For compiling this code, I got error like this > onlineapp.d(22): Error: template std.bitmanip.append cannot > deduce function from >argument types > !()(RefAppender!(ubyte[]), > > c), candidates are: >/dlang/dmd/linux/bin64/../../src/phobos/std/bitmanip.d(3623): >std.bitmanip.append(T, Endian endianness = > Endian.bigEndian, > >R)(R range, T value) >if (canSwapEndianness!T && >isOutputRange!(R, ubyte)) >onlineapp.d(25): Error: template std.bitmanip.append cannot >deduce function from >argument types >!()(RefAppender!(ubyte[]), >ubyte[3]), candidates are: > >/dlang/dmd/linux/bin64/../../src/phobos/std/bitmanip.d(3623): >std.bitmanip.append(T, Endian endianness = > Endian.bigEndian, > >R)(R range, T value) >if (canSwapEndianness!T && >isOutputRange!(R, ubyte)) It seems that the appending is just allow using the fundamental types like uint, ushort, it does not support struct, and can't support dynamic array too. As the hardware protocol is a dynamic-length style, so I also need to support append array or another buffer directly. It seems that I can't get the point how to using the bitmanip to do the packing I need, and also I have no idea what the unpacking will look like. write, append, peek, and read all operate on integral types only. If you have an array of int or whatnot that you want to put into an array of ubyte, then just use a loop, and if you have a struct, then write or append each of the members individually. Those functions are for making it clean and easy to write integral types to an array or range of ubyte (or to read them back out again) while properly taking endianness into account, not for directly serializing objects. I really don't know what to tell you if the examples in the docs aren't enough to figure out how to use the functions, because if I were trying to show you how, I'd give very similar examples, and I don't know why the docs wouldn't be clear as they are or how they could be made clearer for you. - Jonathan M Davis
Re: A DUB Case Study: Compiling DMD as a Library
On 2017-12-21 05:12, Venkat wrote: I did a fresh clone of dmd and added that as a dependency. That fixed it. Should've thought of it !! Thankyou. Great that it works :) -- /Jacob Carlborg
Re: How to pack a struct to a ubyte[] in a more "The D way" style ?
On Monday, December 18, 2017 08:45:32 Binghoo Dang via Digitalmars-d-learn wrote: > hi Davis, > > I read the std.bitmanip, and I tried to test the code like below: > > ``` > import std.stdio; > import std.array; > import std.bitmanip; > void main(string[] args) > { > align(1) struct c { > ushort c1; > uint c2; > //ubyte[8] c3; > } > ubyte[] buffer; > auto ap = appender(); > uint a = 0x11223344; > ushort b = 0x6677; > ap.append!uint(a); > ap.append!ushort(b); > > c cobj; > cobj.c1 = 0xEEFF; > cobj.c2 = 0xDEADBEAF; > //cobj.c3 = [0x12, 0x34, 0x56, 0x78]; > ap.append(cobj); > > ubyte[3] d = [0xAA, 0xBB, 0xCC]; > ap.append(d); > > foreach(e; buffer) { > writef("%02X ", e); > } > } > ``` > For compiling this code, I got error like this > > > onlineapp.d(22): Error: template std.bitmanip.append cannot > > deduce function from >argument types !()(RefAppender!(ubyte[]), > > > > c), candidates are: > >/dlang/dmd/linux/bin64/../../src/phobos/std/bitmanip.d(3623): > >std.bitmanip.append(T, Endian endianness = Endian.bigEndian, > > > >R)(R range, T value) >if (canSwapEndianness!T && > >isOutputRange!(R, ubyte)) > >onlineapp.d(25): Error: template std.bitmanip.append cannot > >deduce function from >argument types !()(RefAppender!(ubyte[]), > >ubyte[3]), candidates are: > > > >/dlang/dmd/linux/bin64/../../src/phobos/std/bitmanip.d(3623): > >std.bitmanip.append(T, Endian endianness = Endian.bigEndian, > > > >R)(R range, T value) >if (canSwapEndianness!T && > >isOutputRange!(R, ubyte)) > > It seems that the appending is just allow using the fundamental > types like uint, ushort, it does not support struct, and can't > support dynamic array too. As the hardware protocol is a > dynamic-length style, so I also need to support append array or > another buffer directly. > > It seems that I can't get the point how to using the bitmanip to > do the packing I need, and also I have no idea what the unpacking > will look like. write, append, peek, and read all operate on integral types only. If you have an array of int or whatnot that you want to put into an array of ubyte, then just use a loop, and if you have a struct, then write or append each of the members individually. Those functions are for making it clean and easy to write integral types to an array or range of ubyte (or to read them back out again) while properly taking endianness into account, not for directly serializing objects. I really don't know what to tell you if the examples in the docs aren't enough to figure out how to use the functions, because if I were trying to show you how, I'd give very similar examples, and I don't know why the docs wouldn't be clear as they are or how they could be made clearer for you. - Jonathan M Davis
Re: How to pack a struct to a ubyte[] in a more "The D way" style ?
On Monday, December 18, 2017 05:32:02 Binghoo Dang via Digitalmars-d-learn wrote: > Thanks for your idea. > > On Monday, 18 December 2017 at 05:08:24 UTC, Jonathan M Davis > > wrote: > >> ubyte[] makeCMDPacket(RCPCmd cmd, in ubyte[] data) > >> { > >> > >> this.preamble = RCPPKT_PRE; > >> this.hdr.msgtype = RCPMSG_CMD; > >> this.hdr.cmdcode = cast (ubyte) cmd; > >> this.hdr.len = 0x & data.length; > > > > Why are you using & instead of simply casting to ushort? > > Casting would be more idiomatic. Or you can use to!ushort if > > you want to verify the size at runtime and have a ConvException > > thrown if the value is too large. > > I'm using & because I'm using a C-Style. and the length needs to > be packed into 2bytes, for casting, I don't know what will happen > if data.length is greater. In C & C++, this kind of the cast will > cause errors. I don't know what D will do for this. This assertion never fails: void main() { foreach(i; 0 .. uint.max) assert((i & 0x) == cast(ushort)i); } - Jonathan M Davis
Re: GC in D and synadard library.
On Thursday, 21 December 2017 at 10:49:46 UTC, Dan Partelly wrote: I started to look into D very recently. I would like to know the following, if you guys are so nice to help me: 1. What is the performance of D's GC, what trade-offs where done in design , and if a in-deep primer on efficient usage and gotchas of the current implementation exists. I've never independently measured it myself, so I can't say. 2. GC is never good enough. What are the current plans in this area for D. The -betterC feature come to mind. Walter is trying to convert the DMD compiler's backend to D (It's still written in C-like C++; only the frontend is in D). For reasons I don't quite understand, he wants to use -betterC and RAII: https://github.com/dlang/dmd/pull/7421#issuecomment-350874126 But the GC isn't required. D is an extraordinarily powerful language with which you can work around just about any limitation. https://wiki.dlang.org/Memory_Management https://p0nce.github.io/d-idioms/#The-impossible-real-time-thread In general, please point me to the place where current work on D is done. Work on the D programming language is done primarily in 3 different repositories: DMD (reference compiler) - https://github.com/dlang/dmd DRuntime (language runtime library) - https://github.com/dlang/druntime Phobos (standard library) - https://github.com/dlang/phobos 3. I need to be able to run with GC totally disabled sometimes. In the light of this: - are there any features of core language which depend on garbage collection ? (i.e unbound arrays, strings ..) Yes, Exceptions, classes, dynamic arrays, and associative arrays come to mind. But, keep in mind that there are always ways to word around this. - are there any features from standard library which depend on active garbage collection? I'm not a big user of the standard library, but I believe most features of the standard library require the GC. - Please point me to a list where there is an exhaustive enumeration of which language features *and* library features requires GC active. Looking at standard library docs I did not seen markings which identify clearly and unequivocally what requires GC active and what not. I don't think such a list exists. You can compile code with the @nogc attribute and the compiler emit errors if you attempt to use the GC. The -vgc compiler option will also tell you where you have GC allocations. 4. Is Andrei Alexandrescu's book from 2009 on D still actual, or the language evolution made it obsolete ? I think there is still great information in that book, and Andrei is always a fun author to read. However, "Programming in D" is probably the best place to start - http://ddili.org/ders/d.en/index.html Some D books are currently on sale for $5 at Packt Publishing: http://forum.dlang.org/post/mbczecvrworfwacmz...@forum.dlang.org Mike
Re: GC in D and synadard library.
On Thursday, 21 December 2017 at 10:49:46 UTC, Dan Partelly wrote: I started to look into D very recently. I would like to know the following, if you guys are so nice to help me: 1. What is the performance of D's GC, what trade-offs where done in design , and if a in-deep primer on efficient usage and gotchas of the current implementation exists. 2. GC is never good enough. What are the current plans in this area for D. In general, please point me to the place where current work on D is done. 3. I need to be able to run with GC totally disabled sometimes. In the light of this: - are there any features of core language which depend on garbage collection ? (i.e unbound arrays, strings ..) - are there any features from standard library which depend on active garbage collection? - Please point me to a list where there is an exhaustive enumeration of which language features *and* library features requires GC active. Looking at standard library docs I did not seen markings which identify clearly and unequivocally what requires GC active and what not. I redirect your questions 1-3 to the excellent GC series: https://dlang.org/blog/the-gc-series 4. Is Andrei Alexandrescu's book from 2009 on D still actual, or the language evolution made it obsolete ? With thanks. A few things changed, but not that much. Imho it's still an excellent book to learn D as Andrei explains the reasoning behind D's design decisions and you get a look behind the scenes.
Re: GC in D and synadard library.
On 21/12/2017 10:49 AM, Dan Partelly wrote: I started to look into D very recently. I would like to know the following, if you guys are so nice to help me: 1. What is the performance of D's GC, what trade-offs where done in design , and if a in-deep primer on efficient usage and gotchas of the current implementation exists. 2. GC is never good enough. What are the current plans in this area for D. In general, please point me to the place where current work on D is done. Ref counting isn't perfect but it is good enough. Scope attribute still needs more work but again may work in some cases. 3. I need to be able to run with GC totally disabled sometimes. In the light of this: https://dlang.org/phobos/core_memory.html#.GC.disable import core.memory : GC; GC.disable; That will disable the GC to attempt to collect (you can ask it to later on or renewable at your pleasure). But bare in mind, the GC will only ever try to collect when you allocate memory. - are there any features of core language which depend on garbage collection ? (i.e unbound arrays, strings ..) Yes, lambdas, new, .length changing and that includes ~=. - are there any features from standard library which depend on active garbage collection? Available lots. Enabled, I highly doubt that part. Just remember, you can quite easily call into C and allocate memory the hard way of malloc. int[] data = (cast(int*)malloc(int.sizeof * 8))[0 .. 8]; free(data.ptr); Of course, preallocating and using buffers is always the best approach, doesn't matter if it was allocated by the GC or not.
GC in D and synadard library.
I started to look into D very recently. I would like to know the following, if you guys are so nice to help me: 1. What is the performance of D's GC, what trade-offs where done in design , and if a in-deep primer on efficient usage and gotchas of the current implementation exists. 2. GC is never good enough. What are the current plans in this area for D. In general, please point me to the place where current work on D is done. 3. I need to be able to run with GC totally disabled sometimes. In the light of this: - are there any features of core language which depend on garbage collection ? (i.e unbound arrays, strings ..) - are there any features from standard library which depend on active garbage collection? - Please point me to a list where there is an exhaustive enumeration of which language features *and* library features requires GC active. Looking at standard library docs I did not seen markings which identify clearly and unequivocally what requires GC active and what not. 4. Is Andrei Alexandrescu's book from 2009 on D still actual, or the language evolution made it obsolete ? With thanks.
Re: WARN on implicit super?
On Thursday, 21 December 2017 at 06:47:25 UTC, Ali Çehreli wrote: On 12/20/2017 10:36 PM, Chris Katko wrote: Is there any way to get a warning anytime an implicit super constructor is called in a sub-class/child-class? There can be a number of solutions but can you please demonstrate the issue with compilable code? My attempt does not agree with your description: super() is called *before* the subclass constructor. (Compiled with DMD64 D Compiler v2.077.1-384-gc6829a8) import std.stdio; // To get the code compile: enum : int { BMP_PLACEHOLDER, BMP_BUILDING } alias bitmap_t = int; class object_t { bitmap_t bmp; float x,y; this() { writeln("super()"); bmp = BMP_PLACEHOLDER; } this(float _x, float _y) { writeln("super(float, float)"); bmp = BMP_PLACEHOLDER; x = _x; y = _y; } } class building_t : object_t { this(float _x, float _y) { //super(_x, _y); // ^^ If I forget this, it implicitly gets called AFTER // this function is done. Which resets bmp to BMP_PLACEHOLDER! // AND, it'll call the DEFAULT constructor this() with no arguments. writeln("setting in building_t"); bmp = BMP_BUILDING; } } void main() { auto b = new building_t(10, 20); assert(b.bmp != BMP_PLACEHOLDER); } Prints super() setting in building_t Ali This is what I would believe __IS__ and __SHOULD__ be the default behavior too, because that's how it generally is in other languages. It doesn't make much sense to call a super constructer after and it's very rare cases that you need too. The only time you really call super constructors after is if the parameters are different. Ex. class Foo { int baz; int boo; this() { ... } this(int baz, int boo) { ... } } class Bar : Foo { this() { int baz =getBazFromSomewhere(); int boo = getBooFromSomewhere(); super(baz, boo); } } In that case it makes sense to call super() after, but you rarely end up in cases like that and thus you should generally be able to omit the call. If super() is ever called explicit after (if no call to a super constructor has been done.) then I can only imagine A LOT of code will break, because it's a general concept and known behavior from most languages that base/super constructors are called before.
Re: Fold in Parallelism
On Wed, 2017-12-20 at 22:31 -0800, Ali Çehreli via Digitalmars-d-learn wrote: > On 12/19/2017 02:32 AM, Vino wrote: > > > even though it is a simple code copy+paste > > The change was a little more complicated than my naive adaptation > from > std.algorithm.fold. Here is the pull request: > >https://github.com/dlang/phobos/pull/5951 > > Ali Thanks for doing this. Having consistency is a good thing. -- Russel. === Dr Russel Winder t: +44 20 7585 2200 41 Buckmaster Roadm: +44 7770 465 077 London SW11 1EN, UK w: www.russel.org.uk signature.asc Description: This is a digitally signed message part
Re: Behavior of joining mapresults
On 21.12.17 08:41, Jonathan M Davis wrote: > I would think that it would make a lot more sense to simply put the whole > thing in an array than to use memoize. e.g. > > auto arr = iota(1, 5).map!parse().array(); thats also possible, but i wanted to make use of the laziness ... e.g. if i then search over the flattened stuff, i do not have to parse the 10th file. i replaced joiner by a primitive flatten function like this: #!/usr/bin/env rdmd -unittest unittest { import std.stdio; import std.range; import std.algorithm; import std.string; import std.functional; auto parse(int i) { writeln("parsing %s".format(i)); return [1, 2, 3]; } writeln(iota(1, 5).map!(parse)); writeln("---"); writeln((iota(1, 5).map!(parse)).joiner); writeln("---"); writeln((iota(1, 5).map!(memoize!parse)).joiner); writeln("---"); writeln((iota(1, 5).map!(parse)).flatten); } auto flatten(T)(T input) { import std.range; struct Res { T input; ElementType!T current; this(T input) { this.input = input; this.current = this.input.front; advance(); } private void advance() { while (current.empty) { if (input.empty) { return; } input.popFront; if (input.empty) { return; } current = input.front; } } bool empty() { return current.empty; } auto front() { return current.front; } void popFront() { current.popFront; advance(); } } return Res(input); } void main() {} With this implementation my program behaves as expected (parsing the input data only once).