Re: Getting a range over a const Container
On Thursday, July 19, 2012 04:39:26 Francisco Soulignac wrote: > So, my question is how can I (correctly) traverse a const SList, > const DList, etc? Right now? I'm pretty sure that that's impossible. Hopefully that will change, but getting const and ranges to work together can be rather difficult, and std.container needs more work in that regard. - Jonathan M Davis
Re: Getting a range over a const Container
Hi all, it's been a while since this question, and I don't know how to solve it either. The following code passes all the test using the last version of dmd (2.059). import std.container, std.algorithm; //non const case void assertequal(T)(SList!(T) l, int[] r) { assert(equal(l[], r)); } //const case void const_assertequal(T)(const SList!(T) l, int[] r) { assert(equal(l[], r)); } unittest{ SList!(int) l; l.insertFront(2); l.insertFront(1); assertequal (l, [1,2]); assert(!__traits(compiles, const_assertequal(l, [1,2]))); } The conflict with the last assertion is that opSplice can't be applied to const. So, I looked at the container module, and made a minimal example of a list myself (emulating SList). struct List { struct Node { Node* next; int val; } private Node* first; struct Range { //sorry about "actual", it should have been current private Node* actual; this(Node* first) {actual = first;} @property front() {return actual.val;} @property empty() const {return !actual;} void popFront() {assert(!empty); actual = actual.next;} Range save() {return this;} } unittest{static assert(isForwardRange!(Range));} void add(int v) { Node * next = first; first = new Node; first.val = v; first.next = next; } Range opSlice() { return Range(first); } } void assertequal(L : List)(L l, int[] r) { assert(equal(l[], r)); } void assertequal_const(L : List)(L l, int[] r) { assert(equal(l[], r)); } unittest{ List l; l.add(2); l.add(1); assert(equal(l[], [1,2])); assertequal (l, [1,2]); assert(!__traits(compiles, const_assertequal(l, [1,2]))); } As far as I know, the problem comes with the transitivity of const. In assertequal_const, l.first has type const(Node*), thus it can't be converted to Node* in Range's constructor. I can't manage to find a workaround here, because l.first will always have type const(Node*), but for traversing the list I require to copy l.first into some node, say actual, whose type is Node* so that I can move it doing actual = actual.next. I would be happy to do actual = cast(Node*)(l.first) actual = actual.next; but that code is suppose to be undefined, isn't it? (http://dlang.org/const3.html : Removing Immutable With A Cast). So, my question is how can I (correctly) traverse a const SList, const DList, etc? Best, Francisco. PS: sorry for the long mail.
Re: ufcs and integer params
On Thursday, 19 July 2012 at 02:57:05 UTC, Brad Roberts wrote: The clear argument for me is that it must be trivial to take an existing member variable and change it to a property function pair _and vice versa_. I can see some value in that. The other bits about non-@property functions is significantly less important as far as I'm concerned. Question to everybody: how would you feel about this compromise: the strictness is opt in. So, if you don't use @property, you get the status quo. These functions can be called either way, but if there's ambiguity, it tends toward treating them as a function. If you do use @property, it becomes strict. This would cover your concerns while keeping the dual-syntax benefits, and it minimizes code breakage of existing stuff. It'd also discourage a lot of the questions of to @property or not to @property, since you can just ask "is it a real property" without falsely marking stuff for UFCS chaining or whatever. It'd save me a lot of headaches on my range.empty's too. If we switch to this compromise position, I'm about 98% sure I'd vote yes (would have to actually try it to be certain).
Re: ufcs and integer params
On 7/18/2012 5:30 AM, Adam D. Ruppe wrote: > On Wednesday, 18 July 2012 at 11:37:43 UTC, David Nadlinger wrote: >> Arguments! Yay! > > I've gone over this a dozen times on the group and on > bugzilla, and I'm kinda sick of repeating it. > > -property breaks craploads of code. That's a huge negative, > and nobody has even come close to countering that. > > "-property will be the standard" is utterly worthless, yet > that's really the only thing I see brought up again. The clear argument for me is that it must be trivial to take an existing member variable and change it to a property function pair _and vice versa_. If someone has @property int foo() and @property void foo(int) as members of a class and call sites add (), then yanking those back to just int foo; will fail, badly. So that must be explicitly disallowed. THAT is the argument for enforcing the lack of parens after properties, imho. The other bits about non-@property functions is significantly less important as far as I'm concerned. My 2 cents, Brad
Re: Compilation failure
On 07/19/2012 12:42 AM, bearophile wrote: Timon Gehr: You are right; this is a bug. This discussion is not about an obscure language detail, it's a common situation. FWIW, I have never run across it before. So if you think this is a bug, then please Timon file it in Bugzilla. Usually bugs are reported by the guy who finds them, but here you go: http://d.puremagic.com/issues/show_bug.cgi?id=8400
Re: Object Pointer
On Wednesday, July 18, 2012 20:37:50 Namespace wrote: > Only for correctness: > If i allocate memory on the GC Heap in e.g. a struct and don't > free the memory in the DTor, then the GC free the memory > automatically? You don't normally _ever_ free memory from the GC heap. That's the GC's job. That's what garbage collectors _do_. There are cases where it may be valuable to explicitly free GC memory for performance reasons, but it's risky and opens yourself up to the possibility of accessing freed memory and the like. That's one of the reasons why delete is being deprecated. So, no, you don't have to free GC allocated memory in a struct's destructor. The GC takes care of it. - Jonathan M Davis
Re: Compilation failure
Timon Gehr: You are right; this is a bug. This discussion is not about an obscure language detail, it's a common situation. So if you think this is a bug, then please Timon file it in Bugzilla. Bye, bearophile
Re: Is this actually supposed to be legal?
On 07/18/2012 01:37 AM, Jonathan M Davis wrote: On Tuesday, July 17, 2012 23:11:43 Timon Gehr wrote: This issue is unrelated to CRTP. (also, you probably want to negate that static if condition, otherwise the code is valid and poses no challenge to a compiler.) It's not that it makes the compiler's life hard. It's the fact that conditional compilation relies on state that doesn't exist yet. It's messed up to be checking whether an object defines something when you're in the middle of defining that object. ... Declarations in D are declarative. There is no notion of state.
Re: Is this actually supposed to be legal?
On 07/18/2012 11:08 PM, monarch_dodra wrote: On Tuesday, 17 July 2012 at 23:38:04 UTC, Jonathan M Davis wrote: It's not that it makes the compiler's life hard. It's the fact that conditional compilation relies on state that doesn't exist yet. It's messed up to be checking whether an object defines something when you're in the middle of defining that object. [snip] - Jonathan M Davis Well, while you "can" do it in C++ as the "Curiously Recursive Template Pattern" (particularly popular way of implementing the singleton pattern BTW), you can't just do anything you feel like doing with it. If I remember correctly, in C++, you can't access any of T's members, or create any (stack) instances of T, or (I think) call T's any of T's static members, because "T is not correctly formed yet". Did you try anything more advanced? For example, this outright _crashes_ my (r)dmd: class MyBase(T) { int a = T.hello(); } class MySubA : MyBase!MySubA { static int hello(){return 0;} } Well, that is a bug. I'm not entirely sure how valid the comparison with C++'s CRTP is, because D's classes are actually pointer to implementation, but I think it is a safe bet that what C++ can't do, neither can D. Careful there. D allows forward references. This is all supposed to work in D. (but DMD is poor when it comes to tricky symbol lookup tasks.)
Re: Is this actually supposed to be legal?
On Tuesday, 17 July 2012 at 23:38:04 UTC, Jonathan M Davis wrote: It's not that it makes the compiler's life hard. It's the fact that conditional compilation relies on state that doesn't exist yet. It's messed up to be checking whether an object defines something when you're in the middle of defining that object. [snip] - Jonathan M Davis Well, while you "can" do it in C++ as the "Curiously Recursive Template Pattern" (particularly popular way of implementing the singleton pattern BTW), you can't just do anything you feel like doing with it. If I remember correctly, in C++, you can't access any of T's members, or create any (stack) instances of T, or (I think) call T's any of T's static members, because "T is not correctly formed yet". Did you try anything more advanced? For example, this outright _crashes_ my (r)dmd: class MyBase(T) { int a = T.hello(); } class MySubA : MyBase!MySubA { static int hello(){return 0;} } I'm not entirely sure how valid the comparison with C++'s CRTP is, because D's classes are actually pointer to implementation, but I think it is a safe bet that what C++ can't do, neither can D.
Re: opDot == alias this?
Understand. Many thanks to you both.
Re: Object Pointer
Only for correctness: If i allocate memory on the GC Heap in e.g. a struct and don't free the memory in the DTor, then the GC free the memory automatically?
Re: opDot == alias this?
On Wednesday, July 18, 2012 16:58:34 Namespace wrote: > First: > Why is opDot not listed here: > http://dlang.org/operatoroverloading.html ? > How much other operators exists which are not listed there? > > And: > Is opDot the same as alias this? I think so. opDot is going to be deprecated and really should have been already ( http://d.puremagic.com/issues/show_bug.cgi?id=2327 ). Don't use it. alias this and opDispatch give you the same thing, only better. http://stackoverflow.com/questions/9880064/d2-what-are-semantics-of-opdot - Jonathan M Davis
Re: foreach for ranges?
On 07/18/2012 08:21 AM, Mike L. wrote: >> Also, UFCS makes no sense on overloaded operators, because they don't get >> called with ".", and all UFCS is is changing obj.func(params) to >> func(obj, >> params). >> >> - Jonathan M Davis > > Ok, that's basically what I was wondering. I had assumed foreach(e; > someThing) {} could possibly have been converted to someThing.opApply() > . Thanks for clarifying. But that is still true and opApply receives the body of the foreach loop as a delegate: someThing.opApply(delegate int(/* loop variables */) { // ... the body of foreach ... return terminationCode; // whether the user did 'break;' }); Also, the following bug (that is already fixed) is somewhat related to this discussion: http://d.puremagic.com/issues/show_bug.cgi?id=5605 Ali
Re: Segmentation fault while creating a class object by dlsym-ed function
Probably you mean the same problem that is described in the thread avobe, see "using GC needs particular skills?" Every time after execution my code I got very frustating access violation and the problem was misunderstanding garbage collector because I've never used it before.
Re: opDot == alias this?
On Wed, 18 Jul 2012 16:58:34 +0200, Namespace wrote: First: Why is opDot not listed here: http://dlang.org/operatoroverloading.html ? How much other operators exists which are not listed there? I believe it's being deprecated. As far as I know, no other operators are unmentioned. Is opDot the same as alias this? I think so. They are related, but not the same. opDot allows access to the returned type's members and functions, but not the type itself. What are the advantages and disadvantages of both? alias this allows implicit type conversions, opDot does not. That's about it, I think. Which of them should i use? Depends. Look above. If you want a type to be usable as if another type, use alias this. If you just want to be able to access members of the other type, use opDot. Will one of them disappear in the future? As stated above, I believe opDot is scheduled for deprecation, but I'm unsure if (not to mention when) it will happen. I think opDot is more flexible as alias this. You can have one alias this for one class/struct, but various opDot's, as this example shows: TDPL states that multiple alias this should be supported, but it has not yet been implemented in the compiler. -- Simen
Re: Magic type return
On Tue, 17 Jul 2012 15:23:05 +0100, bearophile wrote: Andrea Fontana: class Known { void* data; // external data by c api int type; // 0 for int, 1 for string, etc. .. } How can I implement a method like this? Known known; // <-- suppose known.type == 1; string s = known.value(); // <-- automatic To do this Known.value() needs to return different types according to the run-time value of Known.type. This is not possible in a statically typed language... You need to find other solutions. Unless we had overload based on return type, right? e.g. class Known { string value() { if (type != 1) throw..; return cast(string)data; } int value() { if (type != 0) throw ..; return cast(int)data; } } The compiler could produce the correct code/call for the line string s = known.value(); then, but it's not a feature we're likely to see any time soon. R -- Using Opera's revolutionary email client: http://www.opera.com/mail/
Re: foreach for ranges?
Also, UFCS makes no sense on overloaded operators, because they don't get called with ".", and all UFCS is is changing obj.func(params) to func(obj, params). - Jonathan M Davis Ok, that's basically what I was wondering. I had assumed foreach(e; someThing) {} could possibly have been converted to someThing.opApply() . Thanks for clarifying.
opDot == alias this?
First: Why is opDot not listed here: http://dlang.org/operatoroverloading.html ? How much other operators exists which are not listed there? And: Is opDot the same as alias this? I think so. This code [code] class Foo { public: void echo() const { writeln("Foo"); } } class Test { private: Foo _f; public: this(ref Foo f) { this._f = f; } @property ref Foo opDot() { return this._f; } } [/code] Works exactly as these: [code] class Test2 { private: Foo _f; public: this(ref Foo f) { this._f = f; } @property ref Foo Get() { return this._f; } alias Get this; } [/code] But with opDot it is shorter. What are the advantages and disadvantages of both? Which of them should i use? Will one of them disappear in the future? I think opDot is more flexible as alias this. You can have one alias this for one class/struct, but various opDot's, as this example shows: [code] class Foo { public: void echo() const { writeln("Foo"); } } class Bar { public: void echo() const { writeln("Bar"); } } class Test3 { private: Foo _f; Bar _b; public: this(ref Foo f, ref Bar b) { this._f = f; this._b = b; } @property ref Foo opDot() { return this._f; } @property const(Bar) opDot() const { return this._b; } } [/code] If Test3 is unconst, it prints with Foo, otherwise with Bar.
Re: Magic type return
Yes I did it using Variant and it works fine Il giorno mer, 18/07/2012 alle 16.42 +0200, Philippe Sigaud ha scritto: > > class Known > > { > > void* data; // external data by c api > > int type; // 0 for int, 1 for string, etc. .. > > } > > > > How can I implement a method like this? > > > > Known known; // <-- suppose known.type == 1; > > string s = known.value(); // <-- automatic > > > > I just know how to do this: > > > > string s = know.value!string(); > > As bearophile said, you cannot change a value's type (which is a > compile-time construct) with a runtime value, as is Known.type. > > Second point, in D, the rhs is fully evaluated before being assigned > to the lhs, I think. So, known.value() must evaluate to *something*, > without knowing it will be assigned to a string. > In your example, what happens if known.type != 1? > > You can use Phobos Variant, (or Algebraic if the range of types you > plan to use is known beforehand). Then, you should test typeid before > using it. >
Re: Is this actually supposed to be legal?
> That being said, I have never used CRTP in D so far, since template mixins seem to be the better choice in almost all situations. FWIW, CRTP is the main reason I used classes in Pegged, to allow grammar rules to refer to themselves. My earlier attempts with structs did not work. So, given a grammar rule like: Expr <- '(' Expr ')' / ... I use: class Expr : Or! (Sequence!(Literal!("("), Expr, Literal!(")")) , ...) { ... } As you can see, class Expr refer to itself while it's not defined yet. It's the main use I've found for this idiom. Many C++ parsers use the same trick and I was particularly glad to see it worked in D too. Most of the times I use mixins, but could not find a way to do the same recursive rule definition with them. IIRC, I talk a bit about the CRTP in my tutorial on D templates , on Github. Philippe
Re: Magic type return
> class Known > { > void* data; // external data by c api > int type; // 0 for int, 1 for string, etc. .. > } > > How can I implement a method like this? > > Known known; // <-- suppose known.type == 1; > string s = known.value(); // <-- automatic > > I just know how to do this: > > string s = know.value!string(); As bearophile said, you cannot change a value's type (which is a compile-time construct) with a runtime value, as is Known.type. Second point, in D, the rhs is fully evaluated before being assigned to the lhs, I think. So, known.value() must evaluate to *something*, without knowing it will be assigned to a string. In your example, what happens if known.type != 1? You can use Phobos Variant, (or Algebraic if the range of types you plan to use is known beforehand). Then, you should test typeid before using it.
Re: using GC needs particular skills?
18.07.2012 8:00, Mike Parker пишет: Destructors are unreliable. There is no guarantee that a destructor will be called before the garbage collector is terminated. When the program exits, the runtime will call gc_term which will then call destructors on any objects that haven't yet been cleaned up. But the order in which those destructors are called is unpredictable. This is a recipe for all sorts of problems. Static class destructors and module destructors are more reliable in that you know they will be called in a particular order. But, they are called before the gc is terminated. Your particular problem is this. Derelict-style bindings load shared libraries dynamically via system calls. That means that every bound function is actually a function pointer. The shared library is then unloaded in a static module destructor. When DRuntime exits, it calls all the module destructors *before* calling gc_term. So what's happening is: 1. The module destructors are run 2. Derelict unloads the shared library, thereby causing all of the function pointers into that library to become invalid. 3. gc_term is run 4. The destructor of one of your objects is called and it tries to call a function from the Derelict binding, but since that function pointer is no longer valid, you get a segfault. When cleaning up resources in D, you should generally not rely on class destructors to do so. You'll want to include some sort of process to clean up everything yourself. What I tend to do is something like this: void term() { // initiate cleanup here } void main() { scope(exit) term(); init(); run(); } The scope(exit) will ensure that the cleanup is run regardless of how the program exits. Every subsystem in my program will have term() function or method that substitutes for a destructor. This works fine and I have no problems with it. Of course, you can still use destructors for scoped object instances in cases where you want RAII inside a particular scope. Thank you very much for your help! Now I undestand it - I've never used gc before.
Re: Compilation failure
On Wednesday, 18 July 2012 at 12:15:52 UTC, Lemonfiend wrote: On Wednesday, 11 July 2012 at 02:30:47 UTC, Timon Gehr wrote: On 07/11/2012 04:25 AM, ixid wrote: in some way it sees global immutables almost as enums This seems like a bad idea. Consistency of behaviour would seem to be a good principle to expect of a language. You are right; this is a bug. Has someone reported this bug? I can't seem to find it in the tracker. If not, how should I go about reporting it? Also, I don't think I'm clear enough about the differences between immutables, consts and enums to write a bug report about this.
Re: ufcs and integer params
On Wednesday, 18 July 2012 at 12:30:46 UTC, Adam D. Ruppe wrote: 2) -property doesn't even get that right anyway. Not kidding, try it. -property might as well be renamed -break-my-code-and- give-me-ABSOLUTELY-NOTHING-in-return. Why, why would we ever consent to having that standard? I actually tend to agree with this part – I see -property more like an experiment help determining the behavior we want to make the default with real-world testing. We should definitely try to fix/improve the implementation of -property before we consider to make it the default. But without it, the discussion might have never gotten to the point where we are now, so I still consider it a success. David
Re: ufcs and integer params
On Wednesday, 18 July 2012 at 11:37:43 UTC, David Nadlinger wrote: Arguments! Yay! I've gone over this a dozen times on the group and on bugzilla, and I'm kinda sick of repeating it. -property breaks craploads of code. That's a huge negative, and nobody has even come close to countering that. "-property will be the standard" is utterly worthless, yet that's really the only thing I see brought up again. The other most common thing is "I don't like how writeln = 10 looks". Easy response: then don't write that. If you're going to break code because someone might write something you find ugly - note this is different than the arguments people like Crockford make about, say, Javascript's ==, which he argues is a bug 95% of the time you see it, this is just "I don't like how that looks". But if we're going to let the possibility for subjective ugliness be justification for BREAKING CODE, I can't stress that enough, we might as well just nuke the whole language. BTW, a common fallacy I also here is bringing up the edge cases like returning a delegate in a property. Two points: 1) That has *nothing* to do with syntax. The @property decoration takes care of that, regardless of syntax. Why do we have to break a common case to fix an edge case especially when we /can/ have our cake and eat it too? 2) -property doesn't even get that right anyway. Not kidding, try it. -property might as well be renamed -break-my-code-and- give-me-ABSOLUTELY-NOTHING-in-return. Why, why would we ever consent to having that standard?
Re: Compilation failure
On Wednesday, 11 July 2012 at 02:30:47 UTC, Timon Gehr wrote: On 07/11/2012 04:25 AM, ixid wrote: in some way it sees global immutables almost as enums This seems like a bad idea. Consistency of behaviour would seem to be a good principle to expect of a language. You are right; this is a bug. Has someone reported this bug? I can't seem to find it in the tracker. If not, how should I go about reporting it?
Re: ufcs and integer params
On Wednesday, 18 July 2012 at 07:30:10 UTC, Marco Leise wrote: Am Sun, 15 Jul 2012 19:17:11 +0200 schrieb Philippe Sigaud : […] auto distance = 100.km; auto speed = 120.km/hour; auto timeToDestination = distance/speed; // timeToDest is a time (seconds) The version on Github is grossly limited (it's just a sketch), but it gives an idea of what's possible. My goal is to code a generic unit system generator, given user inputs such as a list of units and sub-units. […] Sounds fun. I mean, it makes me happy to see code written like this instead of Distance distance = new Kilometers(100); Speed speed = Speed.fromDistanceByTime(new Kilometers(120), new Hours(1)); I find multiplication to read much more natural: --- enum km = kilo * meter; auto distance = 100.0 * km; auto speed = 100.0 * km / hour; auto timeToDest = distance / speed; --- See http://klickverbot.at/code/units/ for a slightly neglected implementation of this scheme. It supports stuff like defining new units with arbitrary (potentially runtime) conversion factors, properly typechecked affine units (think degrees celsius), etc. – but any error messages and symbol names will probably look like if the compiler had a seizure. David
Re: ufcs and integer params
On Monday, 16 July 2012 at 23:18:10 UTC, Adam D. Ruppe wrote: I'm another who is /vehemently/ against the utter idiocy that is the -property switch. Arguments! Yay!
Re: Segmentation fault while creating a class object by dlsym-ed function
Thank you for your replies! I've found a working solution - all I needed is to change wstring to const wstring, and pass it not as func("something"), but as wstring tmp = "something"; func(tmp); That's really odd, because I don't understand, how those changes made segfault disappear. Here's the working code: test.d: import std.c.linux.linux; import std.stdio; import testclass; int main(string[] args) { void* handle = dlopen("./testclass.so", RTLD_LAZY | RTLD_LOCAL); testclass function(const wstring) a; a = cast(testclass function(const wstring))dlsym(handle, "loadClass"); wstring tmp = "Test"; testclass b = a(tmp); return 0; } testclass.di: class testclass { this(const wstring loadmsg); ~this(); wstring foo(); }; testclass.d: import std.stdio; class testclass { private wstring msg; this(const wstring loadmsg) { writeln("Class constructor"); this.msg = loadmsg; } ~this() { } wstring foo() { return msg; } }; extern(C) testclass loadClass(const wstring loadmsg) { return new testclass(loadmsg); } dmd test.d -L-ldl dmd testclass.d -fPIC -shared
Re: Segmentation fault while creating a class object by dlsym-ed function
On 18-07-2012 06:51, Konstantin J. Chernov wrote: Hello. When I'm trying to create a class object by using a dlsym-ed function, I'm getting a segmentation fault after execution of program. However, if I'm deleting that object before 'return 0' in main (by using 'delete b'), everything is going fine. I'm just started to learn D after using C++ for more than 5 years, so some things look really strange for me (especially that 'new className()' doesn't return a pointer). What am I doing wrong here? Is there any way to do what I'm trying to do right way? Thanks. test.d: import std.c.linux.linux; import std.stdio; import testclass; int main(string[] args) { void* handle = dlopen("./testclass.so", RTLD_LAZY | RTLD_LOCAL); testclass function(wstring) a; a = cast(testclass function(wstring))dlsym(handle, "loadClass"); testclass b = a("test"); return 0; } testclass.di: class testclass { this(const wstring loadmsg); ~this(); wstring foo(); }; testclass.d: import std.stdio; class testclass { private wstring msg; this(const wstring loadmsg) { writeln("Class constructor"); this.msg = loadmsg; } ~this() { } wstring foo() { return msg; } }; extern(C) testclass loadClass(const wstring loadmsg) { return new testclass(loadmsg); } As Jacob said, the D runtime isn't quite ready for shared libraries yet. What you can do, however, is provide a bit of inversion of control to make the allocation happen from the runtime linked statically to your application: import std.conv; alias extern (C) void* function(size_t) Allocator; extern (C) testclass loadClass(Allocator allocator, const wstring loadmsg) { auto size = __traits(classInstanceSize, testclass); auto mem = allocator(size); return emplace!testclass(mem[0 .. size], loadmsg); } Then in the application: import core.memory; import core.sys.posix.dlfcn; import std.stdio; import testclass; void* allocate(size_t size) { return GC.malloc(size); } int main(string[] args) { auto h = dlopen("./testclass.so", RTLD_LAZY | RTLD_LOCAL); auto a = cast(testclass function(Allocator, wstring))dlsym(h, "loadClass"); auto b = a(&allocate, "test"); return 0; } This should make allocation work, but I haven't actually tested it. Note also that even if it does work, things get more complicated when the class you're allocating has a finalizer, for example (see http://dlang.org/phobos/core_memory.html#FINALIZE). -- Alex Rønne Petersen a...@lycus.org http://lycus.org
Re: is() and const
On Wednesday, July 18, 2012 10:43:23 Andrea Fontana wrote: > So: > const(int) : int <-- true const int is implicitly convertible to int, because it's a value type, and assigning a const int to an int (or vice versa) makes a copy. > const(PP) : PP <-- false const PP is not implicitly convertible to PP, because it's a reference type. So, assigning a PP to a PP doesn't make a copy. It just copies the reference. And a const PP can't be converted to a mutable PP, because that would be dropping the const, invalidating const's guarantees. If PP were a struct with no pointers, arrays, or reference types (or it had a postblit constructor), then it would be a value type, and const PP _would_ implicitly convert to PP. > Is this behaviour correct? Yes. > And how can I check if T is of a certain class ignoring consts (and > avoiding double checks)? is(Unqual!T == T) Unqual is in std.traits. - Jonathan M Davis
Re: is() and const
It seems to works (but i use Unqual!T directly) Thank you :) Il giorno mer, 18/07/2012 alle 11.13 +0200, bearophile ha scritto: > Andrea Fontana: > > > const(int) : int <-- true > > const(PP) : PP <-- false > > > > Is this behaviour correct? > > I think it's correct, and it's caused by the difference between > value types and reference types. > > > > And how can I check if T is of a certain class ignoring consts > > (and avoiding double checks)? > > There are some different ways to do it, one of them is to use > something like (untested): > > is(Unqual!typeof(x) == PP) > > Where Unqual is in Phobos, std.traits.Unqual. > > Bye, > bearophile
Re: Segmentation fault while creating a class object by dlsym-ed function
On 2012-07-18 10:17, Konstantin J. Chernov wrote: What am I doing wrong here? Is there any way to do what I'm trying to do right way? Dynamic libraries aren't properly supported by the runtime. That's terrible:( It's so nice to make an interface, and create classes that inherit this interface dynamically, without linking... Maybe there's another way? No, not that I can think of for now. But it's a known problem that is being worked on: https://github.com/dawgfoto/druntime/tree/SharedRuntime -- /Jacob Carlborg
Re: Segmentation fault while creating a class object by dlsym-ed function
Konstantin J. Chernov: testclass.di: class testclass { this(const wstring loadmsg); ~this(); wstring foo(); }; And usually you don't need to write .di files in D. Bye, bearophile
Re: is() and const
Andrea Fontana: const(int) : int <-- true const(PP) : PP <-- false Is this behaviour correct? I think it's correct, and it's caused by the difference between value types and reference types. And how can I check if T is of a certain class ignoring consts (and avoiding double checks)? There are some different ways to do it, one of them is to use something like (untested): is(Unqual!typeof(x) == PP) Where Unqual is in Phobos, std.traits.Unqual. Bye, bearophile
is() and const
Run this code: class PP {} void what(T)(T val) { static if (is(T == int)) writeln ("T == int"); static if (is(T == const(int))) writeln ("T == const(int)"); static if (is(T : int)) writeln ("T : int"); static if (is(T == PP)) writeln ("T == PP"); static if (is(T == const(PP))) writeln ("T == const(PP)"); static if (is(T : PP)) writeln ("T : PP"); } void main(string[] args) { const int aa = 10; int ab; const PP ba = new PP; PP bb = new PP; writeln("- Testing const(int)"); what(aa); writeln(); writeln("- Testing int"); what(ab); writeln(); writeln("- Testing const(PP)"); what(ba); writeln(); writeln("- Testing PP"); what(bb); writeln(); return; } It says: - Testing const(int) T == const(int) T : int - Testing int T == int T : int - Testing const(PP) T == const(PP) - Testing PP T == PP T : PP So: const(int) : int <-- true const(PP) : PP <-- false Is this behaviour correct? And how can I check if T is of a certain class ignoring consts (and avoiding double checks)?
Re: Segmentation fault while creating a class object by dlsym-ed function
What am I doing wrong here? Is there any way to do what I'm trying to do right way? Dynamic libraries aren't properly supported by the runtime. That's terrible:( It's so nice to make an interface, and create classes that inherit this interface dynamically, without linking... Maybe there's another way?
Re: ufcs and integer params
Am Sun, 15 Jul 2012 19:17:11 +0200 schrieb Philippe Sigaud : > > On Sunday, July 15, 2012 05:30:55 Jay Norwood wrote: > > > I see from this other discussions that it looks like 2.059 ( or > > > maybe 2.060) does support something like 3.cm(). Not sure from > > > the discussion if it would also accept 3.cm as in the xtext/xtend > > > example. > > Hi Jay, > > I had a little fun with coding a units (SI units) system in D and pushed an > incomplete version on Github a few weeks ago: > > https://github.com/PhilippeSigaud/Units > > It allows things like: > > auto distance = 100.km; > auto speed = 120.km/hour; > > auto timeToDestination = distance/speed; // timeToDest is a time (seconds) > > The version on Github is grossly limited (it's just a sketch), but it gives > an idea of what's possible. My goal is to code a generic unit system > generator, given user inputs such as a list of units and sub-units. > > cheers, > > Philippe Sounds fun. I mean, it makes me happy to see code written like this instead of Distance distance = new Kilometers(100); Speed speed = Speed.fromDistanceByTime(new Kilometers(120), new Hours(1)); :D -- Marco