Re: Mixin operator 'if' directly
On Saturday, 22 December 2018 at 03:44:09 UTC, Timoses wrote: On Wednesday, 19 December 2018 at 15:40:50 UTC, Neia Neutuladh wrote: On Wed, 19 Dec 2018 15:12:14 +, bauss wrote: Or while instantiating it: mixin template foo() { int _ignoreme() { if (readln.strip == "abort") throw new AbortException; return 1; } int _alsoIgnoreMe = _ignoreme(); } void main() { mixin foo; } Awesome hack! Being a hack, it would be even nicer if it worked ouf of the box: mixin template foo(bool b) { int _impl() { writeln(b); return int.init; } int _ipml2 = _impl(); } vs mixin template foo(bool b) { writeln(b); } Yep, except they will probably disable it in some way. Surely though a template could be created that does all the work. Just pass an lambda in to a template. mixin template Code(alias f) { int _impl2 = (() { f(); return int.init; })(); } mixin Code!(() { writeln("Haha, we inserted code via declarations!");}); So now you can do mixin template foo(bool b) { mixin Code!(() { writeln(b); }); } If it could be made robust, maybe it would be effective. One still can't insert arbitrary code though. So it is not as useful as it looks but still gets over the arbitrary restriction.
Re: Mixin operator 'if' directly
On Wednesday, 19 December 2018 at 15:40:50 UTC, Neia Neutuladh wrote: On Wed, 19 Dec 2018 15:12:14 +, bauss wrote: Or while instantiating it: mixin template foo() { int _ignoreme() { if (readln.strip == "abort") throw new AbortException; return 1; } int _alsoIgnoreMe = _ignoreme(); } void main() { mixin foo; } Awesome hack! Being a hack, it would be even nicer if it worked ouf of the box: mixin template foo(bool b) { int _impl() { writeln(b); return int.init; } int _ipml2 = _impl(); } vs mixin template foo(bool b) { writeln(b); }
Re: Mixin operator 'if' directly
On Thursday, 20 December 2018 at 16:23:39 UTC, H. S. Teoh wrote: On Thu, Dec 20, 2018 at 11:04:19AM +, bauss via Digitalmars-d-learn wrote: On Wednesday, 19 December 2018 at 15:40:50 UTC, Neia Neutuladh wrote: [...] > mixin template foo() > { > int _ignoreme() > { > if (readln.strip == "abort") throw new AbortException; > return 1; > } > int _alsoIgnoreMe = _ignoreme(); > } > void main() > { > mixin foo; > } That's a genius hack. I have to adapt this! Me too! This is awesome! This basically lets you insert arbitrary code via mixin templates with essentially no restrictions! You can even reuse the same ignore-identifiers in multiple instantiations of the same template, e.g.: import std.stdio; mixin template CodeMixin(int i) { int _impl() { static if (i == 0) { writeln("Haha, we inserted code via declarations!"); return int.init; } else static if (i == 1) { writeln("Well whaddya know, we can do multiple mixins!"); return int.init; } else static assert(0); } int _impl2 = _impl(); } void main() { writeln("Does it respect order?"); mixin CodeMixin!0; writeln("I should think so! But you never know..."); mixin CodeMixin!1; writeln("Wow, can we really do multiple mixins of this sort?"); } The output is: Does it respect order? Haha, we inserted code via declarations! I should think so! But you never know... Well whaddya know, we can do multiple mixins! Wow, can we really do multiple mixins of this sort? T Note that it even captures locals: import std.stdio, std.conv; mixin template CodeMixin(int i) { int _impl() { static if (i == 0) { writeln("Haha, we inserted code via declarations! - " ~ to!string(x)); return int.init; } else static if (i == 1) { writeln("Well whaddya know, we can do multiple mixins! - " ~ to!string(x)); return int.init; } else static assert(0); } int _impl2 = _impl(); } void main() { int x = 3; writeln("Does it respect order?"); mixin CodeMixin!0; writeln("I should think so! But you never know..."); x = 4; mixin CodeMixin!1; writeln("Wow, can we really do multiple mixins of this sort?"); getchar(); } Seems like it could be used to replace a lot of string mixins so that real debugging could take place along with CT error checking, etc.
Re: How to reuse the space of RAM of an array of strings?
On 12/21/18 3:41 PM, Giovanni Di Maria wrote: Hi. Can you help me please? I asked also to "General Group" but i haven't solved my problem. I have tried many experiments but without success. I have a dynamic array of strings: string[] vec; After to have inserted dynamically 5_000_000 strings to array, for six times, i measure the RAM with an utility (for example Wise Memory Optimizer), deleting the array every time. Every time I destroy the array, but the RAM is always less. In particular: - at beginning the FREE RAM is 1564 MB; - after first loop the FREE RAM IS 1480 MB - after second loop the FREE RAM IS 1415 MB - after third loop the FREE RAM IS 1402 MB - after forth loop the FREE RAM IS 1338 MB - after fifth loop the FREE RAM IS 1280 MB - after sixth loop the FREE RAM IS 1200 MB - at end the FREE RAM returns to 1564 MB I want to reuse the dynamic array. This is the program: import std.stdio; string[] vec; void main() { alloca(); alloca(); alloca(); alloca(); alloca(); alloca(); } void alloca() Note: alloca is a builtin intrinsic, so I wouldn't use that as a function name. Don't think it's affecting your program, but I wanted to point that out. { vec.destroy; This does NOT free the ram, it simply resets vec to null. If you want to free the memory, use GC.free(vec.ptr); vec = null; writeln("Filling ."); for (int i = 0; i < 500; i++) vec ~= "1234567890ABCDEFGHIL123456"; Note, this allocates a lot of smaller arrays on its way up to the really big array. You are better off doing: vec.reserve(5_000_000); which will pre-allocate the capacity needed. This will make you only allocate once. -Steve
Re: Some Fundamental Paradigm Questions
On Fri, Dec 21, 2018 at 09:26:28PM +, Dennis via Digitalmars-d-learn wrote: > The most fundamental problem that these features tackle is that code > is costly, so making code-bases smaller and more reusable saves effort > spent on maintaining large code-bases and rewriting code to suit a > different situation. I disagree that OO is the best thing since sliced bread. It's useful for certain kinds of problems, but shoehorning everything and the kitchen sink into OO just creates smelly anti-patterns, like singleton classes and needless extra layers of indirection when your problem domain doesn't actually *need* full-out runtime polymorphism. Templates and mixins in D offer a different kind of tool for the job: compile-time polymorphism and meta-programming (esp. code generation). The bottom line is that not only code is costly, but that boilerplate code violates the DRY principle and often leads to bugs that are fixed in one place but not in others because the person making the fix can't possibly know about all the different places where the boilerplate was copy-n-pasted. Templates and mixins let you abstract away needless boilerplate so that you (almost) never have to repeat yourself, and if you later discover a bug in your boilerplate, fixing in one place (i.e., the template) fixes all instances of it, rather than having to chase down the (n-1) other places where the same bug appears. Templates also allow you to abstract the algorithm away from the data it operates on (contrary to OO, where the algorithm is tightly bound to the data, and you're up the creek without a paddle if you want to apply the same algorithm to a different type that the author didn't think of). Instead of forcing your clients to conform to the types that you specify, templates let you write code that adapts itself to a user-given type instead, producing a customized instance that works best with that type with no runtime overhead (because all of this is done at compile-time). Mixins let you generate arbitrary code in response to user-given parameters. It's extremely powerful, though rarely needed. But when necessary, it can let you factorize your code in powerful ways that would otherwise be impossible. A simple example is operator overloading in user-defined arithmetic types, where mixins let you consolidate all the boilerplate of performing some given arithmetic operation `op` on one or two arguments. More advanced examples include code generation from DSLs, that let you process arbitrarily complex strings at compile-time to generate D code for it, e.g., take in a grammar specification and generate parser code optimized for the specifics of your grammar (cf. Pegged). As opposed to writing the parser code yourself (extremely tedious, error-prone, and time-consuming), or using a runtime parser engine (slow because of runtime overhead). // It doesn't mean OO is useless in D, it just means that OO is just another tool for the job, and while it may work really well for certain kinds of programming problems, some other kinds of problems are better solved with other tools. The right tool should be used for the right job; you shouldn't have to contort your problem domain in unnatural ways just so you can say "hooray my code is OO, I'm on the OO bandwagon yay". T -- The problem with the world is that everybody else is stupid.
Re: How to reuse the space of RAM of an array of strings?
On Friday, 21 December 2018 at 21:28:14 UTC, H. S. Teoh wrote: [...] Thank you very much for your replay. I will meditate about your words. Thank you Giovanni
Re: Some Fundamental Paradigm Questions
The most fundamental problem that these features tackle is that code is costly, so making code-bases smaller and more reusable saves effort spent on maintaining large code-bases and rewriting code to suit a different situation. On Friday, 21 December 2018 at 12:39:48 UTC, Ron Tarrant wrote: 1) What problem does mixins solve? - Lots of code is redundant ...and not in an error recovering way but in a "if you don't keep the boilerplate in sync things will break down" kind of way. For example, Java IDEs can create constructors, equals, and toString methods based on fields, but you better not forget to update these when you add a field. A mixin template for these reduces code size and errors. - Interfacing with other code is annoying Mixin allows you to abstract that away cleanly. You can write D code in your own way and let a mixin template do the binding for you. For example, when making a VST (audio effect / instrument plugin) in dplug: https://github.com/AuburnSounds/Dplug/blob/master/examples/simple-mono-synth/simplemonosynth.d#L12 Or when writing D functions that can be called from Excel: https://youtu.be/xJy6ifCekCE?t=3m49s (The link goes to the mixin part directly but I recommend watching the whole video) - Some things are not easily expressed imperatively ...so you may want to use domain specific languages. For example, Pegged allows you to describe a language grammar, and parser code can be mixed in automatically. https://github.com/PhilippeSigaud/Pegged 2) Under what circumstances would I use mixins? Whenever you want to create boilerplate automatically or factor out repeated code. The disadvantage is that code becomes harder to reason about and debug because of the extra indirection. If something can be solved with other features you should generally prefer that over mixins. 3) What problem does a template solve? - Code duplication In Java you have generic List / HashMap containers using Generics. D's templates accomplish the same, but not only can you make a type generic, you can also pass values or aliases as template arguments. - Code often isn't reusable because it makes assumptions about the implementation Apart from templates allowing substitutions of generic names with types and values, they can also inspect those and change behavior accordingly. Take for example design by introspection: https://youtu.be/29h6jGtZD-U?t=30m54s (the timestamp leads to a bit comparing it with libraries that are either larger in code size or less flexible) What should your checked int do on overflow: Saturate, abort, throw an Exception? Just put it in templates and the library user can decide and won't have to choose a different library because they happen to be in a nothrow environment and the library uses exceptions. 4) When would I use a template? Whenever you don't want to assume a specific type, value or behavior, make a template and put the varying parts behind template parameters. 5) Are either mixins, templates, or both intended to make OOP code easier to read, more reliable, or in some other way improve the OOP coding experience? 6) Or, are mixins and templates completely different paradigms intended to solve problems in ways OOP can't? Mixins are great for adding generic methods like constructors, toString, toHash, equals methods. They can also be used to avoid OOP: instead of inheriting features, you can mix them in. I think OOP allows very flexible designs _as long as you're in Object land_. Bringing back Java (I don't know PHP very well sorry): An ArrayList of integers can't use the primitive type int, it has to be a list of Integer objects with some language hacks that allow you to use Integer and int interchangably most of the time. In D, an ArrayList!int would actually generate code that handles on primitive int types. (though in D, you would probably use an int[] instead ;) ) So in a way, templates and mixins are a way to bring the flexibility of OOP outside of Objects so primitive types can also benefit from it, resulting in faster and simpler code. But they can also be used to further improve your OOP designs, it's up to you. 7) Is there a comprehensive stash/repository of GoF patterns implemented in D? I don't know about one, but I think most design patterns in Java can easily be translated to D. When I translated Java to D, substitutions like ClassName() -> this(), extends -> :, and boolean -> bool got me 90% there. However, solving the problems that design patterns address can be done with language features. Instead of the Strategy pattern you can pass function pointers / delegates in D.
Re: How to reuse the space of RAM of an array of strings?
On Fri, Dec 21, 2018 at 08:41:10PM +, Giovanni Di Maria via Digitalmars-d-learn wrote: [...] > After to have inserted dynamically 5_000_000 strings to array, for six > times, i measure the RAM with an utility (for example Wise Memory > Optimizer), deleting the array every time. > > Every time I destroy the array, but the RAM is always less. > In particular: > > - at beginning the FREE RAM is 1564 MB; > - after first loop the FREE RAM IS 1480 MB > - after second loop the FREE RAM IS 1415 MB > - after third loop the FREE RAM IS 1402 MB > - after forth loop the FREE RAM IS 1338 MB > - after fifth loop the FREE RAM IS 1280 MB > - after sixth loop the FREE RAM IS 1200 MB > - at end the FREE RAM returns to 1564 MB > > I want to reuse the dynamic array. [...] You need to understand that generally speaking, the GC does not return memory to the OS; it retains that memory for future use, e.g., when you allocate a new object. Also, not all objects may be freed immediately if the GC can still find references to it somewhere, including on the stack. And if you're in a 32-bit environment, there's a higher chance you might run into the problem of false pointers (non-pointer values that look like a valid pointer into an allocated object, causing the GC to think the object is still live when it's actually already dead). Furthermore, when allocating large numbers of objects the GC may create additional internal data structures to keep track of said objects, and may continue to retain these structures after the objects have been collected. If you want deterministic deallocation, your best bet is to use malloc/free instead of the GC (that means you'll need to avoid allocating operators like ~, ~=, array literals, and so on). Using @nogc may help here. A more reliable test is if you let your loop run forever, and see if the memory usage eventually plateaus. It should stop increasing at a certain point once you've reached steady state; if not, that would be stronger proof of memory leakage. Furthermore, if you want to reuse existing memory for the array, you should just write to it directly instead of deallocating / reallocating. I.e., instead of doing this: foreach (i; 0 .. 1_000_000) { auto arr = new int[1_000_000]; ... // do stuff with arr arr = null; // or arr.destroy or whatever } do this: auto arr = new int[1_000_000]; // only allocate once foreach (i; 0 .. 1_000_000) { ... // overwrite any previous contents of arr with new data ... // do stuff with arr } For your array of strings, you probably want to use a string buffer / pool somewhere, i.e., a contiguous block of memory that you allocate once, and take slices of as you populate your string array, instead of allocating once per array element. This will give you better control over your memory usage, and also reduce GC load (so collection cycles will generally be faster, since there's less stuff that needs to be marked and collected). T -- Give a man a fish, and he eats once. Teach a man to fish, and he will sit forever.
How to reuse the space of RAM of an array of strings?
Hi. Can you help me please? I asked also to "General Group" but i haven't solved my problem. I have tried many experiments but without success. I have a dynamic array of strings: string[] vec; After to have inserted dynamically 5_000_000 strings to array, for six times, i measure the RAM with an utility (for example Wise Memory Optimizer), deleting the array every time. Every time I destroy the array, but the RAM is always less. In particular: - at beginning the FREE RAM is 1564 MB; - after first loop the FREE RAM IS 1480 MB - after second loop the FREE RAM IS 1415 MB - after third loop the FREE RAM IS 1402 MB - after forth loop the FREE RAM IS 1338 MB - after fifth loop the FREE RAM IS 1280 MB - after sixth loop the FREE RAM IS 1200 MB - at end the FREE RAM returns to 1564 MB I want to reuse the dynamic array. This is the program: import std.stdio; string[] vec; void main() { alloca(); alloca(); alloca(); alloca(); alloca(); alloca(); } void alloca() { vec.destroy; writeln("Filling ."); for (int i = 0; i < 500; i++) vec ~= "1234567890ABCDEFGHIL123456"; writeln("Array occupation: ", vec.capacity); writeln("Press "); readln(); } P.S. I have tried: free(), destroy(), minimize(), GC, collect(), etc but without success. Can you help me please? Thank you very much Giovanni Di Maria
Re: D1 question: does anyone has bud (build) tool available for download?
On 12/21/18 8:25 AM, jicman wrote: There used to be a tool called 'build', later named 'bud', that would build applications. Does anyone know where I can download it? I tried the old spot, dsource, http://www.dsource.org/projects/build but the links for download are not working. Any help would be greatly appreciated. Thanks. josé Try going here: http://www.dsource.org/projects/build/browser/downloads Then click on the file you want, on the bottom, there is a download link. Works for me. -Steve
Re: D1 question: does anyone has bud (build) tool available for download?
On Friday, 21 December 2018 at 13:25:17 UTC, jicman wrote: There used to be a tool called 'build', later named 'bud', that would build applications. Does anyone know where I can download it? I tried the old spot, dsource, http://www.dsource.org/projects/build but the links for download are not working. Any help would be greatly appreciated. Thanks. josé Is there a reason you want to use D1? There are really no advantages in using D1 unless you have projects using it.
Re: using dub to compile plugins
On Fri, 21 Dec 2018 10:56:39 +, Atila Neves wrote: > I don't see how you can do this with dub, and I wouldn't attempt it > either. Just use make, and have make call dub for the main project (and > potentially any plugins that need it). Remember to make the dub targets > `.PHONY` since you don't want to be managing the D dependencies by hand. Or you could have it depend on dub.sdl, dub.selections.json, your D source files, and your string import files. Which is a bit more work but will result in a little less recompilation.
Defining a class toHash() that include the typeinfo
What's the preferred way of defining a `toHash()` for a concrete class that includes the TypeInfo [1] in the hash? Is it ok to hash only the address of the typeinfo pointer, assuming it's statically allocated? [1] https://dlang.org/library/object/type_info.html
D1 question: does anyone has bud (build) tool available for download?
There used to be a tool called 'build', later named 'bud', that would build applications. Does anyone know where I can download it? I tried the old spot, dsource, http://www.dsource.org/projects/build but the links for download are not working. Any help would be greatly appreciated. Thanks. josé
Some Fundamental Paradigm Questions
Reading through an abstract of what makes the D language tick, I found terms like mixins and templates, concepts I haven't run across in the other languages I've learned. I have a basic understanding of WHAT mixins and templates are, but what I don't understand is WHY they're part of the language, and thus my questions: 1) What problem does mixins solve? 2) Under what circumstances would I use mixins? 3) What problem does a template solve? 4) When would I use a template? Learning PHP was my first exposure to OOP and it strikes me that OOP is the greatest thing since sliced bread (within reason, of course) and that leads me to wonder: 5) Are either mixins, templates, or both intended to make OOP code easier to read, more reliable, or in some other way improve the OOP coding experience? 6) Or, are mixins and templates completely different paradigms intended to solve problems in ways OOP can't? So far in my searches, I've only found a tiny handful of GoF pattern examples in D, and so: 7) Is there a comprehensive stash/repository of GoF patterns implemented in D? I'm mostly interested in factory, builder, mediator, and command patterns. I did find a very good thread-safe singleton example already (thank you David Simcha).
Re: using dub to compile plugins
On Wednesday, 19 December 2018 at 12:57:14 UTC, Codifies wrote: I am currently using this dub.sdl name"runz80" targetType "executable" lflags "libz80/libz80.a" however I will be creating a number of plugins, each plugin will consist of a single source file, I'd like the plugin source directory to be separate from main source directory and compile the plugins (.so) to a (binary) plugins directory (the plugins will be dynamically loaded at runtime - I've previously done this in C so I don't anticipate any particular issues - famous last words!) I could do this with a few simple rules in a Makefile, but I have no clue how to achieve this using dub. can someone show me a concrete example of doing this ? Ideally just dropping a new source file into the plugins source folder should produce a new .so the next time dub is run, without having to explicitly add each plugin to the dub file... Unless the plugins have dub dependencies, don't use dub for it. Plugins that do can have their own dub.sdl/json with targetType "dynamicLibrary". Ideally just dropping a new source file into the plugins source folder should produce a new .so the next time dub is run, without having to explicitly add each plugin to the dub file... I don't see how you can do this with dub, and I wouldn't attempt it either. Just use make, and have make call dub for the main project (and potentially any plugins that need it). Remember to make the dub targets `.PHONY` since you don't want to be managing the D dependencies by hand.