Re: how to make private class member private
On Sunday, 18 March 2018 at 18:45:23 UTC, Steven Schveighoffer wrote: If we could go back in time and talk with a young Walter about the consequences of choosing the scheme the way it is, maybe he might have made different choices, but at this point, it's hard to change it. I think this highlights the real problem with D. Power is too centralised, and kinda arbitrary. I'm going back to Java ;-)
Re: how to make private class member private
On Sunday, 18 March 2018 at 11:12:46 UTC, Alex wrote: ´´´ Are there any scenarios in which the person writing the class, would want to encapsulate their class, or some parts of it, from the rest of a module (while being forced to put the class in this module)? ´´´ The answer is no. As the person which is writing the class has always the power to decide which module to edit to put the class in. And due this fact, the statement The fact is, the creator of the class is also the creator of the module.. is the coolest semantic statement of the whole thread so far, I think :) Well, it seems to me, that the only real objection one can have to improving encapsulation within a module, is objecting to improving encapsulation within a module. The fact that the creator of a class, is also the creator of the module that contains that class, is not a valid reason for not seeking to improve encapsulation of that class.
Re: Testing D database calls code for regression
On Sun, Mar 18, 2018 at 07:51:18PM +, aberba via Digitalmars-d-learn wrote: > On Friday, 16 March 2018 at 21:15:33 UTC, H. S. Teoh wrote: > > On Fri, Mar 16, 2018 at 08:17:49PM +, aberba via Digitalmars-d-learn > > wrote: > > > [...] > > > > The usual way I do this is to decouple the code from the real > > database backend by templatizing the database driver. Then in my > > unittest I can instantiate the template with a mock database driver > > that only implements the bare minimum to run the test. > > > > [...] > > Mocking a fake database can also be huge pain. Especially when > something like transactions and prepared statements are involved. It depends on what your test is looking for. The idea is that the mock database only implements a (small!) subset of a real database, basically just enough for the test to run, and nothing more. Of course, sometimes it may not be easy to do this, if the code being tested is very complex. > Imagine testing your mock for introduced by future extension. If you find yourself needing to test your mock database, then you're doing it wrong. :-D It's supposed to be helping you test your code, not to create more code that itself needs to be tested! Basically, this kind of testing imposes certain requirements on the way you write your code. Certain kinds of code are easier to test than others. For example, imagine trying to test a complex I/O pipeline implemented as nested loops. It's basically impossible to test it except as a blackbox testing (certain input sets must produce certain output sets). It's usually impractical for the test to target specific code paths nested deep inside a nested loop. The only thing you can do is to hope and pray that your blackbox tests cover enough of the code paths to ensure things are correct. But you're likely to miss certain exceptional cases. But if said I/O pipeline is implemented as series of range compositions, for example, then it becomes very easy to test each component of the range composition. Each component is decoupled from the others, so it's easy for the unittest to check all code paths. Then it's much easier to have the confidence that the composed pipeline itself is correct. I/O pipelines are an easy example, but understandably, in real-world code things are rarely that clean. So you'll have to find a way of designing your database code such that it's more easily testable. Otherwise, it's going to be a challenge no matter what. No matter what you do, testing a function made of loops nested 5 levels deep is going to be very hard. Similarly, if your database code has very complex interdependencies, then it's going to be hard to test no matter how you try. Anyway, on the more practical side of things, depending on what your test is trying to do, a mock database could be as simple as: struct MockDb { string prebakedResponse; auto query(string sql) { if (sql == "SELECT * FROM data") return prebakedResponse; else if (sql == "UPDATE * SET ... ") prebakedResponse = ... else assert(0, "Time to rewrite your unittest :-P"); } } I.e., you literally only need to implement what the test case will actually invoke. Anything that isn't strictly required is fair game to just outright ignore. Also, keep in mind that MockDb can be a completely different thing per unittest. Trying to use the same mock DB for all unittests will just end up with writing your own database engine, which kinda defeats the purpose. :-P But the ability to do this depends on how decoupled the code is. Code with complex interdependencies will generally give you a much harder time than more modular, decoupled code. T -- Knowledge is that area of ignorance that we arrange and classify. -- Ambrose Bierce
Re: Should the "front" range primitive be "const" ?
On Monday, March 19, 2018 00:14:11 Drone1h via Digitalmars-d-learn wrote: > I am not sure whether I can make it work with "inout" instead of > "const". Perhaps I am missing something. ... > May I ask that you confirm that this is what you suggested ? > Thank you. Marking a empty or front with inout has most of the problems that const has. The difference is that if the range is mutable, then the return value will be treated as mutable. The internals of the function, however, must still work with const or inout, and that's not true for most ranges. It can work just fine to mark empty or front as inout or const if you're in full control of the element types and aren't wrapping other ranges, but as soon as you start wrapping other ranges, you pretty much must give up on inout and const, because most ranges won't work with them - even to just call empty or front. And in many cases, they can't be made to work with const or inout, because that often causes serious problems with the return type. The range API simply does not include const or inout, so you can't assume that any range will compile with them, meaning that ranges that wrap other ranges can only use const or inout when they're intended to wrap a very specific set of ranges that do work with const or inout. Ranges that generically wrap other ranges cannot use const or inout, or they will not compile with many (most?) ranges. > > [...] const ranges are utterly useless, because they can't be > > mutated and thus can't be iterated. [...] > > I am considering a function that takes as parameter a (reference > to) const range. It should be able to check whether the range is > "empty" and, if not empty, it should be able to access the > "front" element. > > Now the caller of that function can rest assured that the > function is not going to modify the range by "popFront". > > The function might be more useful than a function that just takes > as parameter a value (the result of "front") because it may be > called with an empty range and it can detect that. This is > similar to getting as parameter a (possibly null) pointer to a > value instead of getting as parameter a value. > > Therefore, it seems to me that a const range might be useful. > > If you have already considered this and have actually seen > one-step ahead of me, may I ask that you confirm, please ? Most ranges do not work with const in any way shape or form. _Some_ will work if all you're doing is looking at is empty or front. But if all you're doing is looking at the front, in general, why pass a range? Just call front and pass it, and then the function will work with more than just ranges. Yes, if you want a function that does something like auto frontOrInit(R)(R range) { return range.empty ? ElementType!R.init : range.front; } then you can make the range const, but in general, a function is either going to be iterating over the range (so the range can't be const), or what the function is doing really has nothing to do with ranges and would be far more flexible if it just took the range's element type. Functions like frontOrInit where it would make sense to only call front or empty on a range are rare. And honestly, making a function like frontOrInit accept the range by const doesn't buy you much if a range's front and empty are const, and it makes the function useless with most ranges, because most ranges don't - and many can't - mark front or empty as const. Honestly, I think that you will be far better off if you just don't try and use const or inout with ranges. You can make it work in very restricted circumstances, but you will constantly be fighting problems where code does not compile. I'd suggest that you read this: http://jmdavisprog.com/articles/why-const-sucks.html - Jonathan M Davis
Re: Should the "front" range primitive be "const" ?
First of all, thank you all for the replies. It has taken me some time to learn a bit more to be able to understand at least some parts of them. I have a further question below the quotes. On Tuesday, 30 January 2018 at 01:20:09 UTC, Jonathan M Davis wrote: On Tuesday, January 30, 2018 01:05:54 Drone1h via Digitalmars-d-learn wrote: [...] I am trying to implement a ("struct template" ? what is the correct word ?) range that just forwards its primitives ("empty", "front", "popFront") to another range, possibly with some very limited filtering/alteration, as std.range.Take (just to learn). Initially, the "front" member function (property) used to be declared "const", but that was not accepted when the underlying range (denoted "R" in the code below) was std.stdio.File.ByChunk ("Error: mutable method std.stdio.File.ByChunk.front is not callable using a const object"). [...] If you want to put an attribute on it, inout is better, because then it will work with any constness I am not sure whether I can make it work with "inout" instead of "const". Perhaps I am missing something. Here is my code: auto Take2 (R) (R r, size_t n) { import std.range.primitives; struct Result { private: R _r; size_t _n; size_t _i; public: @property bool empty () const { return _i >= _n || _r.empty; } @property auto ref front () const // Replace "const" with "inout" here ? { return _r.front; } void popFront () { ++_i; if (_i < _n) _r.popFront (); } this (R r, size_t n) { _r = r; _n = n; _i = 0; } } return Result (r, n); } unittest { import std.stdio; auto file = File ("Example", "rb"); foreach (c; file.byChunk (0x100).Take2 (5)) stdout.rawWrite (c); } I get compile error: Error: mutable method `std.stdio.File.ByChunkImpl.front` is not callable using a `const` object If I replace "const" with "inout" for the "front" function, i.e. "@property auto ref front () inout", I get similar error: Error: mutable method `std.stdio.File.ByChunkImpl.front` is not callable using a `inout` object May I ask that you confirm that this is what you suggested ? Thank you. [...] const ranges are utterly useless, because they can't be mutated and thus can't be iterated. [...] I am considering a function that takes as parameter a (reference to) const range. It should be able to check whether the range is "empty" and, if not empty, it should be able to access the "front" element. Now the caller of that function can rest assured that the function is not going to modify the range by "popFront". The function might be more useful than a function that just takes as parameter a value (the result of "front") because it may be called with an empty range and it can detect that. This is similar to getting as parameter a (possibly null) pointer to a value instead of getting as parameter a value. Therefore, it seems to me that a const range might be useful. If you have already considered this and have actually seen one-step ahead of me, may I ask that you confirm, please ? Thank you respectfully.
Re: Logging Function Parameters
On Saturday, 17 March 2018 at 10:34:41 UTC, dom wrote: Hi, I am looking for a method to log the current function name + parameters. Getting the name of the current function is simply possible with __PRETTY_FUNCTION__ Is there some possibility to generically access the parameters of a function such that they can be iterated and printed out? currently i have something like this: log.info(__PRETTY_FUNCTION__, " ", parameter1, " ", parameter2); i would like to get to something like that: log.info(__PRETTY_FUNCTION__, " ", parameters.join(", ")); You can't get the parameters names at the moment, but there's a PR for it: https://github.com/dlang/dmd/pull/7821
Re: Logging Function Parameters
On Sunday, 18 March 2018 at 22:57:15 UTC, aliak wrote: // But you get a: // Error: Using the result of a comma expression is not allowed // writeln(mixin(arguments!f)); You can't mix part of a function call in: "Mixed in text must form complete declarations, statements, or expressions." (https://dlang.org/articles/mixin.html) In this case, it evaluates to a comma expression, which is deprecated. If you put the "writeln();" inside the mixin string it should form a complete statement and compile.
Re: Does the compiler inline the predicate functions to std.algorithm.sort?
On Sunday, 18 March 2018 at 14:15:37 UTC, Stefan Koch wrote: On Sunday, 18 March 2018 at 12:59:06 UTC, tipdbmp wrote: I can't read assembly but it seems to me that it doesn't: https://godbolt.org/g/PCsnPT I think C++'s sort can take a "function object" that can get inlined. Correct it does not get in-lined. Even with -O3 it does not. The reason is that the code the sort instantiation produces is too big for the inliner cost function. If you have a look at the the cg file produced when you specify -vcg-ast you can see that it's a massive amount of code. I believe the original poster was asking about the *predicate* to sort, which is indeed inlined with optimizations on. (@tipdbmp: The string gets turned into the function _D3std10functional__T9binaryFunVAyaa5_61203c2062VQra1_61VQza1_62Z__TQBvTiTiZQCdFNaNbNiNfKiKiZb. No references to it remain with -O3; the LLVM IR obtained with -output-ll might be easier to read than assembly.) — David
Re: Logging Function Parameters
On Saturday, 17 March 2018 at 10:34:41 UTC, dom wrote: Hi, I am looking for a method to log the current function name + parameters. Getting the name of the current function is simply possible with __PRETTY_FUNCTION__ Is there some possibility to generically access the parameters of a function such that they can be iterated and printed out? currently i have something like this: log.info(__PRETTY_FUNCTION__, " ", parameter1, " ", parameter2); i would like to get to something like that: log.info(__PRETTY_FUNCTION__, " ", parameters.join(", ")); You may be able to do something with a mixin. I tried this but I think I'm hitting a compiler bug, or I'm just using mixins wrong. import std.stdio; string arguments(alias f)() { import std.meta: AliasSeq; import std.traits: ParameterIdentifierTuple; import std.array: join; string[] args; foreach (a; [AliasSeq!(ParameterIdentifierTuple!f)]) { args ~= `"` ~ a ~ `: ", ` ~ a; } return args.join(`, ", ", `); } // calling writeln(mixin(arguments!f)) should do what you want. void f(int a, int b, int c) { // But you get a: // Error: Using the result of a comma expression is not allowed // writeln(mixin(arguments!f)); auto value = arguments!f; // "a: ", a, ", ", "b: ", b, ", ", "c: ", c writeln(value); // This is ok: writeln("a: ", a, ", ", "b: ", b, ", ", "c: ", c); } void main() { f(1, 2, 3); } You might be able to start with that and get something that works. Or maybe someone knows how to make the mixin part above compile. I have a feeling you may need to make the arguments() function return a string("p0: ", arg0, ", p1: ", arg1" ...) instead so that it's a full string instead of a comma separated expression maybe. Cheers
Re: how to make private class member private
On Sunday, 18 March 2018 at 18:04:13 UTC, Tony wrote: On Tuesday, 13 March 2018 at 06:03:11 UTC, Mike Parker wrote: D is not C++, C#, or Java. C++ uses friend to get around the issue. Java has no solution. I don't know about C#. Java has four protection levels. If you don't explicitly specify [private, protected, public] the protection level is implicitly "package-private". That means that any class in the same package can access that attribute. I believe that Java packages are identical to D packages. https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/accessibility-levels C# has 6 accessibility levels: public - Access is not restricted. protected - Access is limited to the containing class or types derived from the containing class. private - Access is limited to the containing type. internal - Access is limited to the current assembly. protected internal - Access is limited to the current assembly or types derived from the containing class. private protected - Access is limited to the containing class or types derived from the containing class within the current assembly. Available since C# 7.2. What is a C# Assembly? Someone says on a forum: "An assembly is a "unit of deployment" for .NET, almost always a .exe or .dll. In C# terms, it's basically a single C# project." And also refers to https://social.msdn.microsoft.com/Forums/en-US/088ce8ed-ef9b-4dea-88b3-ca016885e26d/what-is-an-assembly-in-terms-of-c?forum=csharplanguage which says: "Assemblies are the building blocks of .NET Framework applications; they form the fundamental unit of deployment, version control, reuse, activation scoping, and security permissions. An assembly is a collection of types and resources that are built to work together and form a logical unit of functionality. An assembly provides the common language runtime with the information it needs to be aware of type implementations. To the runtime, a type does not exist outside the context of an assembly."
Re: Testing D database calls code for regression
On Sunday, March 18, 2018 19:51:18 aberba via Digitalmars-d-learn wrote: > On Friday, 16 March 2018 at 21:15:33 UTC, H. S. Teoh wrote: > > On Fri, Mar 16, 2018 at 08:17:49PM +, aberba via > > > > Digitalmars-d-learn wrote: > >> [...] > > > > The usual way I do this is to decouple the code from the real > > database backend by templatizing the database driver. Then in > > my unittest I can instantiate the template with a mock database > > driver that only implements the bare minimum to run the test. > > > > [...] > > Mocking a fake database can also be huge pain. Especially when > something like transactions and prepared statements are involved. > > Imagine testing your mock for introduced by future extension. The other way would be to create a test database (or databases) and use those with the normal code, though you have less control over some stuff that way. What makes the most sense depends on what you're doing and how much you're able to really unit test the pieces as opposed to component testing large chunks of the code at once. And the reality of the matter is that sometimes testing is a pain, though in the long run, it pretty much always saves time and pain even if it's a pain to get set up. - Jonathan M Davis
Re: how to make private class member private
On Sunday, March 18, 2018 18:59:39 Tony via Digitalmars-d-learn wrote: > On Sunday, 18 March 2018 at 18:32:42 UTC, Jonathan M Davis wrote: > > They're similar, but there are differences. For instance, you > > can do package(a) in D in order to do something like put the > > stuff in a.b.c in package a rather than a.b. > > Is there a known situation where it makes sense to put module c > in directory/package b - rather than directory/package a, and > then tell the D compiler to treat it like it was in > directory/package a? I don't think that you can have anything in a/b/c.d marked as if it were in package a/z. It's only for putting stuff higher up in the package hierarchy while allowing it to be placed in modules deeper in the hierarchy, not for moving it laterally within the package hierarchy. One place where it's used (and which IIRC was the motivating reason for its implementation) is std.internal.* in Phobos. At least some of what's there is marked with package(std) (and probably all of it should be, but a lot of it predates the improvement to package). That way, stuff that's essentially private to Phobos can be organized there but be used by anything in Phobos, whereas without the improvement to package, they'd all have to be modules directly under std (probably all with internal in their module names) in order to have them being treated as being in the std package. So, ultimately, it's about better organization and probably is something that only makes sense for when entire modules are essentially private to a library and not for modules that mix public and package symbols. - Jonathan M Davis
Re: Testing D database calls code for regression
On Friday, 16 March 2018 at 21:15:33 UTC, H. S. Teoh wrote: On Fri, Mar 16, 2018 at 08:17:49PM +, aberba via Digitalmars-d-learn wrote: [...] The usual way I do this is to decouple the code from the real database backend by templatizing the database driver. Then in my unittest I can instantiate the template with a mock database driver that only implements the bare minimum to run the test. [...] Mocking a fake database can also be huge pain. Especially when something like transactions and prepared statements are involved. Imagine testing your mock for introduced by future extension.
Re: core.stdc.stdlib._compare_fp_t and qsort
On Sunday, 18 March 2018 at 19:01:11 UTC, Joe wrote: I managed to get it working by declaring a D dynamic array, appending n_recs pointers to it and using it as argument to sort. Unfortunately, I then had to copy from the dynamic array to the fixed array in order to continue using the latter. Any shortcuts around this? I just saw your other reply. Passing recs[0..n_recs] does the trick. Thanks.
Re: core.stdc.stdlib._compare_fp_t and qsort
On Sunday, 18 March 2018 at 18:11:02 UTC, Dmitry Olshansky wrote: Well since recs is array of pointers this looks like a null pointer in your data. The usual ways to fix that is either print stuff or poke around in debugger to see if a Record* is null or .name is null. The problem is that although the "recs" array is declared as having 10 pointers, not all pointers are used. In the qsort case, the second argument limited the sort to just the first n_recs (valid) pointers. There doesn't seem to be a way to tell std.algorithm.sorting.sort to only look at part of the fixed array. I managed to get it working by declaring a D dynamic array, appending n_recs pointers to it and using it as argument to sort. Unfortunately, I then had to copy from the dynamic array to the fixed array in order to continue using the latter. Any shortcuts around this?
Re: how to make private class member private
On Sunday, 18 March 2018 at 18:32:42 UTC, Jonathan M Davis wrote: They're similar, but there are differences. For instance, you can do package(a) in D in order to do something like put the stuff in a.b.c in package a rather than a.b. Is there a known situation where it makes sense to put module c in directory/package b - rather than directory/package a, and then tell the D compiler to treat it like it was in directory/package a?
Re: how to make private class member private
On 3/17/18 5:56 AM, Nick Treleaven wrote: On Tuesday, 13 March 2018 at 13:59:00 UTC, Steven Schveighoffer wrote: If you limit to class members, then you have to do something like C++ friends, which are unnecessarily verbose. Not if you also have a module-level visibility modifier, which could have been `module`. If we could go back in time and talk with a young Walter about the consequences of choosing the scheme the way it is, maybe he might have made different choices, but at this point, it's hard to change it. Note, again, you can do pretty much every privacy scheme you want with package modules today. Before, it was a lot less nice. It's pretty simple: all your friends go into the module. All your external functions that should only use the public API have to go elsewhere. I think the thing that bites people is simply that they aren't used to it. IMO, the module-level encapsulation is the right choice. It helps with a lot of key features: 1. IFTI factory methods Aren't these mainly because constructors can't use IFTI, unlike C++17, While this is a limitation that I wish wasn't there, constructors aren't always the best way to build a type. But there are other reasons to put functions that access private pieces outside the aggregate. For instance, if you want to accept a struct by value. 2. unittests Documented unittests should not be allowed to use private symbols, I just filed this: https://issues.dlang.org/show_bug.cgi?id=18623 Why not? unittest { auto foo = new Foo; assert(foo.internalbuffer.empty); // note, this is a private symbol. } I can do the same thing in ddoc, but without the benefit of having the unit test run. Forcing me to do it that way is just annoying (I will have to duplicate the code). -Steve
Re: core.stdc.stdlib._compare_fp_t and qsort
On Sunday, 18 March 2018 at 18:11:02 UTC, Dmitry Olshansky wrote: On Sunday, 18 March 2018 at 16:45:16 UTC, Joe wrote: [...] No it just creates a pair of pointer to recs[0] + length of recs, like this: struct Array { size_t length; Record* ptr; } In D it’s typed as Record[] and has a number of nice properties, like not losing its length;) [...] Well since recs is array of pointers this looks like a null pointer in your data. Or rather if 10 is capacity and num_recs is actual length, then: recs[0..num_recs] is the slice with data that you want to sort.
Re: how to make private class member private
On Sunday, March 18, 2018 18:04:13 Tony via Digitalmars-d-learn wrote: > On Tuesday, 13 March 2018 at 06:03:11 UTC, Mike Parker wrote: > > D is not C++, C#, or Java. C++ uses friend to get around the > > issue. Java has no solution. I don't know about C#. > > Java has four protection levels. If you don't explicitly specify > [private, protected, public] the protection level is implicitly > "package-private". That means that any class in the same package > can access that attribute. I believe that Java packages are > identical to D packages. They're similar, but there are differences. For instance, you can do package(a) in D in order to do something like put the stuff in a.b.c in package a rather than a.b. Also, package functions in D are never virtual, which I expect is not the case for Java. The whole situation is also complicated somewhat by the fact that D allows pretty much anything at module-level, whereas as Java requires one class per module, though I'm not sure that that has much direct effect on package itself other than the fact that it's possible in D to mark stuff package that isn't in a class. - Jonathan M Davis
Re: core.stdc.stdlib._compare_fp_t and qsort
On Sunday, 18 March 2018 at 16:45:16 UTC, Joe wrote: On Sunday, 18 March 2018 at 13:10:08 UTC, Dmitry Olshansky wrote: Do this to get the usual ptr + length: sort!((a, b) => to!string((*a).name) < to!string((*b).name))(recs[]); Also to!string would be computed on each compare anew. May want to use schwartzSort to avoid that, on 10 elements there is no real difference though. The 10 elements are just because it's a small test program. What does changing "recs" to "recs[]" as the argument actually do? Does it duplicate the fixed array on the fly? [I guess I have to study more!] No it just creates a pair of pointer to recs[0] + length of recs, like this: struct Array { size_t length; Record* ptr; } In D it’s typed as Record[] and has a number of nice properties, like not losing its length;) The change does pass the compiler, but at runtime it causes a segfault. The next to last frame in the backtrace shows (having changed from to!string to fromStringz and using a string template instead of a lambda): Well since recs is array of pointers this looks like a null pointer in your data. The usual ways to fix that is either print stuff or poke around in debugger to see if a Record* is null or .name is null. #6 0x55565760 in std.algorithm.sorting.sort!("fromStringz((*a).name.ptr) < fromStringz((*b).name.ptr)", 0, testd.Record*[]).sort(testd.Record*[]) (r=...) Also you don’t need (*a).name, D understands that . can access data through pointer (what would be an error in C and require ->). Then it goes through quickSortImpl, shortSort and sort5, moving on to either std.functional.binaryFun or processing of the lambda, with a and b equal to 0, ending with a segfault in a ?? call from fromStringz or in memcpy called from object._dup (in the to!string case).
Re: how to make private class member private
On Tuesday, 13 March 2018 at 06:03:11 UTC, Mike Parker wrote: D is not C++, C#, or Java. C++ uses friend to get around the issue. Java has no solution. I don't know about C#. Java has four protection levels. If you don't explicitly specify [private, protected, public] the protection level is implicitly "package-private". That means that any class in the same package can access that attribute. I believe that Java packages are identical to D packages.
Re: RBTree delegates and types
On 3/18/18 8:34 AM, Viktor wrote: Hey, I'm trying to convert an old legacy app to D and have a couple of questions. It has been a very fun weekend! First, I could not make std.container.rbtree use a delegate for a comparator. The docs say it should be possible, but I got a weird error. I tracked it down to RedBlackTreee.opEquals() using explicit function when calling equals(): return equal!(function(Elem a, Elem b) => !_less(a,b) && !_less(b,a))(thisRange, thatRange); When I removed the "function" things started compiling (I have yet to test the code due to question #2 below). I've done a dub -b unittest without issues so it might be OK. So, the first...several questions are: do you think this change is safe and should I raise an issue in the bugzilla or do a PR for it on github? Yes, seems like an oversight. RedBlackTree.opEquals was added almost 6 years ago, and it's possible this wouldn't have worked back then (https://github.com/dlang/phobos/pull/900) Should it include a new unittest that makes sure rbtree can be instantiated with a delegate? Definitely. Thanks for thinking of this! The other part I'm still struggling with is about auto types. Can I store the rbtree type in the following class so it can be used from another method? class Indexer(T, alias pred) { alias RBType = RedBlackTree!(uint, (a, b) => comp(a, b)); this(T storage) { this.storage = storage; this.index = new RBType(); } void dumpIndex() { // how to get my dirty hands on the index here? // answer: just use it? } bool comp(uint i1, uint i2) { auto rec1 = storage[i1]; auto rec2 = storage[i2]; return pred(rec1, rec2); } private T storage; RBType index; } -Steve
Re: core.stdc.stdlib._compare_fp_t and qsort
On Sunday, 18 March 2018 at 13:10:08 UTC, Dmitry Olshansky wrote: Do this to get the usual ptr + length: sort!((a, b) => to!string((*a).name) < to!string((*b).name))(recs[]); Also to!string would be computed on each compare anew. May want to use schwartzSort to avoid that, on 10 elements there is no real difference though. The 10 elements are just because it's a small test program. What does changing "recs" to "recs[]" as the argument actually do? Does it duplicate the fixed array on the fly? [I guess I have to study more!] The change does pass the compiler, but at runtime it causes a segfault. The next to last frame in the backtrace shows (having changed from to!string to fromStringz and using a string template instead of a lambda): #6 0x55565760 in std.algorithm.sorting.sort!("fromStringz((*a).name.ptr) < fromStringz((*b).name.ptr)", 0, testd.Record*[]).sort(testd.Record*[]) (r=...) Then it goes through quickSortImpl, shortSort and sort5, moving on to either std.functional.binaryFun or processing of the lambda, with a and b equal to 0, ending with a segfault in a ?? call from fromStringz or in memcpy called from object._dup (in the to!string case).
Re: How to delete element from array container or dlist?
On Sunday, 18 March 2018 at 15:42:18 UTC, Andrey Kabylin wrote: On Sunday, 18 March 2018 at 15:32:47 UTC, Michael wrote: On Sunday, 18 March 2018 at 14:58:52 UTC, Andrey Kabylin wrote: In DList we have method remove, but I can't understand how this method works, I want write somethink like this: void unsubscribe(EventsSubscriber subscriber) { subscribers.remove(subscriber); } So I guess you would want something like subscribers.remove!(a => a == subscriber)); which is the different definition of remove available here: https://dlang.org/phobos/std_algorithm_mutation.html#.remove.2 Yes this works, thanks! No problem, glad to help!
Re: How to delete element from array container or dlist?
On Sunday, 18 March 2018 at 15:32:47 UTC, Michael wrote: On Sunday, 18 March 2018 at 14:58:52 UTC, Andrey Kabylin wrote: In DList we have method remove, but I can't understand how this method works, I want write somethink like this: void unsubscribe(EventsSubscriber subscriber) { subscribers.remove(subscriber); } So I guess you would want something like subscribers.remove!(a => a == subscriber)); which is the different definition of remove available here: https://dlang.org/phobos/std_algorithm_mutation.html#.remove.2 Yes this works, thanks!
Re: How to delete element from array container or dlist?
On Sunday, 18 March 2018 at 14:58:52 UTC, Andrey Kabylin wrote: In DList we have method remove, but I can't understand how this method works, I want write somethink like this: void unsubscribe(EventsSubscriber subscriber) { subscribers.remove(subscriber); } The remove function seems to expect an index, not an element.
Re: How to delete element from array container or dlist?
On Sunday, 18 March 2018 at 14:58:52 UTC, Andrey Kabylin wrote: In DList we have method remove, but I can't understand how this method works, I want write somethink like this: void unsubscribe(EventsSubscriber subscriber) { subscribers.remove(subscriber); } So I guess you would want something like subscribers.remove!(a => a == subscriber)); which is the different definition of remove available here: https://dlang.org/phobos/std_algorithm_mutation.html#.remove.2
How to delete element from array container or dlist?
In DList we have method remove, but I can't understand how this method works, I want write somethink like this: void unsubscribe(EventsSubscriber subscriber) { subscribers.remove(subscriber); }
Re: How to build static linked executable
On 2018-03-17 16:42, Seb wrote: Yes, use -static Here's how we build the DTour: https://github.com/dlang-tour/core/blob/master/dub.sdl FYI, -static is not support on macOS. -- /Jacob Carlborg
Re: Does the compiler inline the predicate functions to std.algorithm.sort?
On Sunday, 18 March 2018 at 12:59:06 UTC, tipdbmp wrote: I can't read assembly but it seems to me that it doesn't: https://godbolt.org/g/PCsnPT I think C++'s sort can take a "function object" that can get inlined. Correct it does not get in-lined. Even with -O3 it does not. The reason is that the code the sort instantiation produces is too big for the inliner cost function. If you have a look at the the cg file produced when you specify -vcg-ast you can see that it's a massive amount of code.
Re: Does the compiler inline the predicate functions to std.algorithm.sort?
On Sunday, 18 March 2018 at 12:59:06 UTC, tipdbmp wrote: I can't read assembly but it seems to me that it doesn't: https://godbolt.org/g/PCsnPT I think C++'s sort can take a "function object" that can get inlined. add "-O3" also to the compiler switches.
Re: core.stdc.stdlib._compare_fp_t and qsort
On Sunday, 18 March 2018 at 11:29:47 UTC, Joe wrote: On Monday, 12 March 2018 at 03:50:42 UTC, Joe wrote: On Monday, 12 March 2018 at 03:13:08 UTC, Seb wrote: Out of interest: I wonder what's your usecase for using qsort. Or in other words: why you can't use the high-level std.algorithm.sorting.sort? This is only temporary. I will be using std.algorithm.sorting.sort. I was converting a C program and it annoyed me that I couldn't get the qsort invocation past the D compiler. Now that I'm trying to use std.algorithm.sorting, I'm again puzzled by what I need to use for the "less" predicate. My first try was: sort!((a, b) => to!string((*a).name) < to!string((*b).name))(recs); This results in the error: Error: template std.algorithm.sorting.sort cannot deduce function from argument types !((a, b) => to!string((*a).name) < to!string((*b).name))(Record*[10]), This basically says you have fixed size array, in D they don’t decay to slices/pointers for safety reasons (it’s stack memory that is easy to leak out of scope with disasterous consequences). Do this to get the usual ptr + length: sort!((a, b) => to!string((*a).name) < to!string((*b).name))(recs[]); Also to!string would be computed on each compare anew. May want to use schwartzSort to avoid that, on 10 elements there is no real difference though.
Does the compiler inline the predicate functions to std.algorithm.sort?
I can't read assembly but it seems to me that it doesn't: https://godbolt.org/g/PCsnPT I think C++'s sort can take a "function object" that can get inlined.
RBTree delegates and types
Hey, I'm trying to convert an old legacy app to D and have a couple of questions. It has been a very fun weekend! First, I could not make std.container.rbtree use a delegate for a comparator. The docs say it should be possible, but I got a weird error. I tracked it down to RedBlackTreee.opEquals() using explicit function when calling equals(): return equal!(function(Elem a, Elem b) => !_less(a,b) && !_less(b,a))(thisRange, thatRange); When I removed the "function" things started compiling (I have yet to test the code due to question #2 below). I've done a dub -b unittest without issues so it might be OK. So, the first...several questions are: do you think this change is safe and should I raise an issue in the bugzilla or do a PR for it on github? Should it include a new unittest that makes sure rbtree can be instantiated with a delegate? The other part I'm still struggling with is about auto types. Can I store the rbtree type in the following class so it can be used from another method? class Indexer(T, alias pred) { this(T storage) { this.storage = storage; auto index = new RedBlackTree!(uint, (a,b) => comp(a, b)); // how to store index? } void dumpIndex() { // how to get my dirty hands on the index here? } bool comp(uint i1, uint i2) { auto rec1 = storage[i1]; auto rec2 = storage[i2]; return pred(rec1, rec2); } private T storage; ??? index; }
Re: core.stdc.stdlib._compare_fp_t and qsort
On Monday, 12 March 2018 at 03:50:42 UTC, Joe wrote: On Monday, 12 March 2018 at 03:13:08 UTC, Seb wrote: Out of interest: I wonder what's your usecase for using qsort. Or in other words: why you can't use the high-level std.algorithm.sorting.sort? This is only temporary. I will be using std.algorithm.sorting.sort. I was converting a C program and it annoyed me that I couldn't get the qsort invocation past the D compiler. Now that I'm trying to use std.algorithm.sorting, I'm again puzzled by what I need to use for the "less" predicate. My first try was: sort!((a, b) => to!string((*a).name) < to!string((*b).name))(recs); This results in the error: Error: template std.algorithm.sorting.sort cannot deduce function from argument types !((a, b) => to!string((*a).name) < to!string((*b).name))(Record*[10]), candidates are: /usr/lib/ldc/x86_64-linux-gnu/include/d/std/algorithm/sorting.d(1851):std.algorithm.sorting.sort(alias less = "a < b", SwapStrategy ss = SwapStrategy.unstable, Range)(Range r) if ((ss == SwapStrategy.unstable && (hasSwappableElements!Range || hasAssignableElements!Range) || ss != SwapStrategy.unstable && hasAssignableElements!Range) && isRandomAccessRange!Range && hasSlicing!Range && hasLength!Range) which is not very helpful. It's a bit different from the "no function match" that Adam complains about, but I presume it's because now we're dealing with templates, and although the compiler finds a single candidate, it's not satisfactory but it can't tell the user anything further. I've tried using fromStringz((*x).name.ptr) instead of to!string (I'm still unclear to what extent can templates be used within templates). I also tried using an explicit cast(Record *)x because I'm also unsure that type information is passed down. Neither change helped.
Re: how to make private class member private
On Sunday, 18 March 2018 at 10:45:55 UTC, psychoticRabbit wrote: On Sunday, 18 March 2018 at 10:14:30 UTC, Alain Soap wrote: [...] " Private - All fields and methods that are in a private block, can only be accessed in the module (i.e. unit) that contains the class definition. They can be accessed from inside the classes’ methods or from outside them (e.g. from other classes’ methods)" " Strict Private - All fields and methods that are in a strict private block, can only be accessed from methods of the class itself. Other classes or descendent classes (even in the same unit) cannot access strict private members. " https://www.freepascal.org/docs-html/ref/refse34.html interesting...someone else clearly had the idea. hey..perhaps I'm not a moron after all. Change your pseudo.
Re: how to make private class member private
On Sunday, 18 March 2018 at 09:56:31 UTC, psychoticRabbit wrote: However, are there no scenarios in which the person writing that module, would not want to encapsulate their class, or some parts of it, from the rest of the module (while not being forced to put the class in it's own file)? If the answer is certainly no, not under any circumstances, then fine, my idea is not worth any further consideration. And by no, I mean no for all, not just you. I assume, that the following statement is equivalent to yours: ´´´ Are there any scenarios in which the person writing the class, would want to encapsulate their class, or some parts of it, from the rest of a module (while being forced to put the class in this module)? ´´´ The answer is no. As the person which is writing the class has always the power to decide which module to edit to put the class in. And due this fact, the statement The fact is, the creator of the class is also the creator of the module.. is the coolest semantic statement of the whole thread so far, I think :)
Re: how to make private class member private
On Sunday, 18 March 2018 at 10:14:30 UTC, Alain Soap wrote: BTW i think adding this can be useful. The FreePascal language has `strict private` for example. " Private - All fields and methods that are in a private block, can only be accessed in the module (i.e. unit) that contains the class definition. They can be accessed from inside the classes’ methods or from outside them (e.g. from other classes’ methods)" " Strict Private - All fields and methods that are in a strict private block, can only be accessed from methods of the class itself. Other classes or descendent classes (even in the same unit) cannot access strict private members. " https://www.freepascal.org/docs-html/ref/refse34.html interesting...someone else clearly had the idea. hey..perhaps I'm not a moron after all.
Re: how to make private class member private
On Saturday, 17 March 2018 at 23:54:22 UTC, psychoticRabbit wrote: On Saturday, 17 March 2018 at 21:33:01 UTC, Adam D. Ruppe wrote: On Saturday, 17 March 2018 at 21:22:44 UTC, arturg wrote: maybe extend that to a list of types? this is basically what C++ friend does and D was trying to avoid the complexity of Really, the complexity of 'friend' comes from people abusing it. In D, I would prefer no breaking change here. Leave private as it is. Just a simple attribute that only applies within a class, and only to private members within that class. @strictly private string firstName_; Nothing outside of the class, not even the module, can access this now. It's all encapsulated. It breaks nothing (AFAIK). It's very clear what the intention is here. It's an easy attribute to remember. It restores the principle of class enscapsulation within a module, for when it's really needed. Now D programmers would have the best of both worlds. Yesterday i thought to reuse `super`: struct Foo { super private: int _stats; int _field; public: int field(){_stats++; return _field;} void field(int value){_stats++; _field = value;} } BTW i think adding this can be useful. The FreePascal language has `strict private` for example.
Re: Convert output range to input range
On Saturday, 17 March 2018 at 17:51:50 UTC, John Chapman wrote: I'm trying to replace the old std.streams in my app with ranges. I'm interfacing with a networking library to which I supply a callback that when invoked provides the requested data. I write that data to an output range, but later on I need to read that data from the range too - which of course you can't do. So what I'm looking for is the range-based equivalent of a MemoryStream. I suggest you to give a fast read to this [1], reactive streams. The D implementation [2] uses as a base an output range. They are pretty good in handling time based series event, it this is your usecase... [1] http://reactivex.io [2] https://github.com/lempiji/rx /Paolo
Re: how to make private class member private
On Sunday, 18 March 2018 at 05:01:39 UTC, Amorphorious wrote: The fact is, the creator of the class is also the creator of the module.. and preventing him from having full access to the class is ignorant. He doesn't need to encapsulate himself. Encapsulation is ONLY meant to reduce dependencies. If the programmer, probably someone like you, can't trust himself to understand his own code then he shouldn't be coding. btw. I am talking here about 'encapsulation' not 'information hiding' (although the two terms are often considered related). Clearly, there is no point in hiding information contained within the module, from the implementer of the module. That's just silly. However, are there no scenarios in which the person writing that module, would not want to encapsulate their class, or some parts of it, from the rest of the module (while not being forced to put the class in it's own file)? If the answer is certainly no, not under any circumstances, then fine, my idea is not worth any further consideration. And by no, I mean no for all, not just you.
Re: how to make private class member private
On Saturday, 17 March 2018 at 23:54:22 UTC, psychoticRabbit wrote: In D, I would prefer no breaking change here. Leave private as it is. My suggestion has no breaking change and it works just like the package attribute already works. Also you shouldn't allow multiple types for it, that would defeat the purpose of private again and in that case you should just use as is, since module-level private can already ensure that. If you need to share it with types outside of the module, then it's pointless, because you're essentially just duck-taping an issue of your program design and not the language design.
Re: how to make private class member private
On Sunday, 18 March 2018 at 05:01:39 UTC, Amorphorious wrote: Why do you insist that you know how everything works and you are the harbinger of truth. The fact is, you don't know squat about what you are talking about and you just want to conform D to your naive ignorant ...etc...etc..etc..etc..etc you're funny. and btw. My suggestion would not stop anyone from doing what they're currently doing within modules. It would just return class encapsulation, within a module, for when it was deemed worthwhile (as opposed to being forced to move the class out of the module). It's just an idea, not a request. One day I might do a data matching analysis of the dmail-archive, to find out who you really are.