Re: Challenge
On 4 October 2016 at 14:40, Jonathan M Davis via Digitalmars-dwrote: > [...] > For that matter, even testing whether something is a variable is > surprisingly difficult. True story! I've written that one before... I spent ages trying to get it right! When people say D is highly complex, these are the reasons. There are a lot of edges, and some arbitrary corners where things just don't work. *mutter mutter* storage class *mutter mutter*
Re: Challenge
On Tuesday, October 04, 2016 14:24:59 Manu via Digitalmars-d wrote: > On 4 October 2016 at 12:30, Jonathan M Davis via Digitalmars-d > >wrote: > > On Tuesday, October 04, 2016 11:13:36 Manu via Digitalmars-d wrote: > >> I'm feeling John's solution is a little bit simpler. But nice work, > >> thanks! > > > > So, it is. LOL. I'd actually glanced over that post while I was in the > > middle of getting my version to work, and I read it too quickly, because I > > understood that it had just solved the property problem and that it didn't > > work for all cases. I'll have to update my PR. Though his code does make > > the mistake of doing > > > > mixin(`alias mem = T.` ~ member ~ `;`); > > > > rather than doing something like > > > > alias mem = AliasSeq!(__traits(getMember, T, member))[0]; > > > > which means that there are some cases where it won't work properly. The > > core logic is simpler though, which is definitely a plus. > > Make that change in your PR :) I already updated it and was actually able to make it slightly simpler than John's example (as far as I can tell, FunctionTypeOf is only needed in the case where the address is taken). > I think the PR is important. It's not obvious how to do this, and it's > very useful. I was astonished it's not already there. Yeah. I ran into a need for something similar recently, but my implementation at the time wasn't as thorough, since it just used offsetof to do the check (though in my case, I think that was enough). Getting it completely right is surprisingly difficult. I was also surprised that while we have quite a few __traits for functions, they're severely lacking for variables (e.g. I was looking for the variable equivalent of __traits(isStaticFunction, ...), and there is no such beast). For that matter, even testing whether something is a variable is surprisingly difficult. - Jonathan M Davis
Re: Challenge
On 4 October 2016 at 12:30, Jonathan M Davis via Digitalmars-dwrote: > On Tuesday, October 04, 2016 11:13:36 Manu via Digitalmars-d wrote: >> I'm feeling John's solution is a little bit simpler. But nice work, thanks! > > So, it is. LOL. I'd actually glanced over that post while I was in the > middle of getting my version to work, and I read it too quickly, because I > understood that it had just solved the property problem and that it didn't > work for all cases. I'll have to update my PR. Though his code does make the > mistake of doing > > mixin(`alias mem = T.` ~ member ~ `;`); > > rather than doing something like > > alias mem = AliasSeq!(__traits(getMember, T, member))[0]; > > which means that there are some cases where it won't work properly. The core > logic is simpler though, which is definitely a plus. Make that change in your PR :) I think the PR is important. It's not obvious how to do this, and it's very useful. I was astonished it's not already there.
[Issue 16587] split("", "x") should be []
https://issues.dlang.org/show_bug.cgi?id=16587 github-bugzi...@puremagic.com changed: What|Removed |Added Status|NEW |RESOLVED Resolution|--- |FIXED --
[Issue 16587] split("", "x") should be []
https://issues.dlang.org/show_bug.cgi?id=16587 --- Comment #2 from github-bugzi...@puremagic.com --- Commits pushed to stable at https://github.com/dlang/phobos https://github.com/dlang/phobos/commit/d6572c2a44d69f449bfe2b07461b2f0a1d6503f9 Fix Issue 16587 - split("", "x") should be "" This reverts commit b438bf5a0653b616ef6debe2a0dfe247d8fc5928. https://github.com/dlang/phobos/commit/e3f842d52a3eedc7c8f6a5e75f26de05d5cf1fea Merge pull request #4836 from CyberShadow/pull-20161003-223010 Fix Issue 16587 - split("", "x") should be "" --
Re: Challenge
On Tuesday, October 04, 2016 11:13:36 Manu via Digitalmars-d wrote: > I'm feeling John's solution is a little bit simpler. But nice work, thanks! So, it is. LOL. I'd actually glanced over that post while I was in the middle of getting my version to work, and I read it too quickly, because I understood that it had just solved the property problem and that it didn't work for all cases. I'll have to update my PR. Though his code does make the mistake of doing mixin(`alias mem = T.` ~ member ~ `;`); rather than doing something like alias mem = AliasSeq!(__traits(getMember, T, member))[0]; which means that there are some cases where it won't work properly. The core logic is simpler though, which is definitely a plus. - Jonathan M Davis
Re: Cannot access template name from within template
On Tuesday, 4 October 2016 at 00:40:08 UTC, Andrei Alexandrescu wrote: On 10/03/2016 06:32 PM, Stefan Koch wrote: On Monday, 3 October 2016 at 22:28:46 UTC, Andrei Alexandrescu wrote: Consider: template SomethingCool(alias X) { alias Y = X!int; } struct MyStruct(T) { alias A = SomethingCool!MyStruct; } Inside MyStruct though, a mention of the symbol MyStruct alone is actually the current instantiation - i.e. a type, not a template. Any known workaround? Thanks, Andrei try defining an alias to template name outside of the template and use that. No guarantees. Using std.traits.TemplateOf!MyStruct works like a charm. -- Andrei You can also just do something like this, to search the upper/global scope: alias A = SomethingCool!(.MyStruct);
Re: debugging mixins
On Tuesday, 4 October 2016 at 01:20:01 UTC, Manu wrote: On 4 October 2016 at 04:21, Stefan Koch via Digitalmars-dwrote: On Monday, 3 October 2016 at 15:23:40 UTC, Jonathan Marler wrote: Yes, having the mixins expanded without the surrounding code would make it difficult to debug in some cases. Maybe generating the entire source with the expanded mixins is another option? mycode.d obj/mycode_processed.d That was my intention. Maybe this idea could also be expanded to template instantiation? Oh yes. it is not that more much work :) What case of template instantiation where there are no mixins involved would this make significantly simpler to debug? (I don't know this is a critical debugability problem as it is...) Do you mean just substituting 'T' with actual types? resolving static if's? Hard to know what it should do... Actually, one case that often bites me is static-foreach unrolling. That's borderline impossible to debug. foreach(m; __traits(allMembers,T)) is the classic impossible to debug case. static ifs are resolved when the compiler sees the template-instance in semantic3. And that makes a huge difference in some cases where a template is generated by a string-mixin for example. is not that big of a deal to print out unrolled static foreach. (as in I can implement in the compiler within 2 days)
Re: debugging mixins
On 4 October 2016 at 04:21, Stefan Koch via Digitalmars-dwrote: > On Monday, 3 October 2016 at 15:23:40 UTC, Jonathan Marler wrote: > >> >> Yes, having the mixins expanded without the surrounding code would make it >> difficult to debug in some cases. Maybe generating the entire source with >> the expanded mixins is another option? >> >> mycode.d >> obj/mycode_processed.d > > That was my intention. >> >> Maybe this idea could also be expanded to template instantiation? > > Oh yes. it is not that more much work :) What case of template instantiation where there are no mixins involved would this make significantly simpler to debug? (I don't know this is a critical debugability problem as it is...) Do you mean just substituting 'T' with actual types? resolving static if's? Hard to know what it should do... Actually, one case that often bites me is static-foreach unrolling. That's borderline impossible to debug. foreach(m; __traits(allMembers,T)) is the classic impossible to debug case.
Re: inout delegate
On 4 October 2016 at 10:50, Timon Gehr via Digitalmars-dwrote: > On 03.10.2016 05:06, Manu via Digitalmars-d wrote: >> >> Okay, well my current project is blocked on this. I can't progress. >> https://issues.dlang.org/show_bug.cgi?id=16572 > > > Probably you can work around the issue using unsafe type casts. Mmm, I'll see how much work it is to detect the case to do such a cast...
Re: Challenge
On 4 October 2016 at 05:01, Jonathan M Davis via Digitalmars-dwrote: > On Monday, October 03, 2016 11:13:52 Jonathan M Davis via Digitalmars-d wrote: >> template isStaticMember(T, string member) >> { >> static if (!__traits(hasMember, T, member)) >> enum bool isStaticMember = false; >> else >> { >> import std.meta : AliasSeq; >> import std.traits : FunctionTypeOf; >> alias sym = AliasSeq!(__traits(getMember, T, member))[0]; >> >> static if (__traits(isStaticFunction, sym)) >> enum bool isStaticMember = true; >> else static if (is(FunctionTypeOf!sym == function) && >> is(FunctionTypeOf!(typeof()) == function)) >> { >> enum bool isStaticMember = false; >> } >> else >> { >> enum bool isStaticMember = !__traits(compiles, sym.offsetof) && >>__traits(compiles, ); >> } >> } >> } > > Well, since I took the time to write it, I created a PR for it: > > https://github.com/dlang/phobos/pull/4834 > > So, if anyone sees problems with my implementation, go poke holes in it. > > - Jonathan M Davis > I'm feeling John's solution is a little bit simpler. But nice work, thanks!
Re: Challenge
On 4 October 2016 at 00:25, John Colvin via Digitalmars-dwrote: > On Monday, 3 October 2016 at 13:19:19 UTC, Manu wrote: >> >> Fill in the blank... >> I'm having a really hard time with this. I've made it work with a >> mountain of code, and I want to see what others come up with... > > > template isStaticMember(T, string member) > { > mixin(`alias mem = T.` ~ member ~ `;`); > import std.traits : FunctionTypeOf; > static if (is(FunctionTypeOf!mem == function) && > is(FunctionTypeOf!(typeof()) == function)) > enum bool isStaticMember = __traits(isStaticFunction, mem); > else > enum bool isStaticMember = is(typeof()); > } > > Basically, using FunctionTypeOf catches @property functions (which just > typeof wouldn't), but it also catches member variables with function types, > so we need the second FunctionTypeOf to see if it's still a function when > you take its address (true for member functions, including @property > functions, not true for member variables with function types). > > Everything else is just "can you take the address of this". Very nice. This is the quality of solution I was looking for! 3 Significant LOC. I knew a simple solution must exist. I didn't think of FunctionTypeOf.
Re: inout delegate
On 03.10.2016 05:06, Manu via Digitalmars-d wrote: Okay, well my current project is blocked on this. I can't progress. https://issues.dlang.org/show_bug.cgi?id=16572 Probably you can work around the issue using unsafe type casts.
Re: Cannot access template name from within template
On 10/03/2016 06:32 PM, Stefan Koch wrote: On Monday, 3 October 2016 at 22:28:46 UTC, Andrei Alexandrescu wrote: Consider: template SomethingCool(alias X) { alias Y = X!int; } struct MyStruct(T) { alias A = SomethingCool!MyStruct; } Inside MyStruct though, a mention of the symbol MyStruct alone is actually the current instantiation - i.e. a type, not a template. Any known workaround? Thanks, Andrei try defining an alias to template name outside of the template and use that. No guarantees. Using std.traits.TemplateOf!MyStruct works like a charm. -- Andrei
[Issue 16588] New: uniq's BidirectionalRange behavior is inconsistent with its InputRange behavior
https://issues.dlang.org/show_bug.cgi?id=16588 Issue ID: 16588 Summary: uniq's BidirectionalRange behavior is inconsistent with its InputRange behavior Product: D Version: D2 Hardware: All OS: All Status: NEW Severity: normal Priority: P1 Component: phobos Assignee: nob...@puremagic.com Reporter: acehr...@yahoo.com import std.algorithm; struct S { int i; string s; } void main() { auto arr = [ S(1, "a"), S(1, "b"), S(2, "c"), S(2, "d")]; // Let's consider just the 'i' member for equality auto r = arr.uniq!((a, b) => a.i == b.i); assert(r.equal([S(1, "a"), S(2, "c")]));// makes sense // Since there are just 2 elements, we expect the following assert(r.front == S(1, "a")); // good, consistent assert(r.back == S(2, "c"));// FAILS // Instead, the following passes but it's unexpected assert(r.back == S(2, "d")); } Bonus: uniq could take a PickStrategy template parameter so that the caller could specify which of the unique elements of each sequence to pick, either the first or the last. Ali --
[Issue 16587] split("", "x") should be [""]
https://issues.dlang.org/show_bug.cgi?id=16587 Vladimir Panteleevchanged: What|Removed |Added Summary|split("", "x") should be "" |split("", "x") should be ||[""] --
[Issue 16587] split("", "x") should be []
https://issues.dlang.org/show_bug.cgi?id=16587 Vladimir Panteleevchanged: What|Removed |Added Summary|split("", "x") should be|split("", "x") should be [] |[""]| --
[Issue 16536] DMD master does not build on OS X 10.11.6/Xcode 7.3.1
https://issues.dlang.org/show_bug.cgi?id=16536 John Colvinchanged: What|Removed |Added CC||john.loughran.colvin@gmail. ||com --- Comment #5 from John Colvin --- This is preventing testing 2.072.0-b1 on os x. --
[Issue 15862] dmd thinks functions are strongly pure despite mutable indirections in the return type
https://issues.dlang.org/show_bug.cgi?id=15862 ag0ae...@gmail.com changed: What|Removed |Added Status|RESOLVED|REOPENED Resolution|INVALID |--- --- Comment #3 from ag0ae...@gmail.com --- (In reply to Walter Bright from comment #2) > This is as designed and intended. > > 1. Mutable indirections in the return type do not affect purity > determination. Mutability of the parameters does. Sorry, but this is ridiculous. Reopening. Please explain how on earth the shown behavior is supposedly acceptable. > 2. An early design decision was that calling new() inside a pure function is > an acceptable special case. (Otherwise pure functions would be nearly > useless.) This is fine. It follows that the compiler must not consider the result reusable when a function has a mutable indirection in the return type, even when it's otherwise pure. A strongly pure function (with const parameters) can only return an int* by newly allocating it. And then reusing it is disastrous. --
Re: Cannot access template name from within template
On Monday, 3 October 2016 at 22:28:46 UTC, Andrei Alexandrescu wrote: Consider: template SomethingCool(alias X) { alias Y = X!int; } struct MyStruct(T) { alias A = SomethingCool!MyStruct; } Inside MyStruct though, a mention of the symbol MyStruct alone is actually the current instantiation - i.e. a type, not a template. Any known workaround? Thanks, Andrei try defining an alias to template name outside of the template and use that. No guarantees.
Cannot access template name from within template
Consider: template SomethingCool(alias X) { alias Y = X!int; } struct MyStruct(T) { alias A = SomethingCool!MyStruct; } Inside MyStruct though, a mention of the symbol MyStruct alone is actually the current instantiation - i.e. a type, not a template. Any known workaround? Thanks, Andrei
[Issue 16584] Local import ineffective for mixin templates
https://issues.dlang.org/show_bug.cgi?id=16584 --- Comment #2 from m.bier...@lostmoment.com --- For the record: the best solution is to import the needed modules within the mixin: mixin template bla(string number) { import func; uint globalBla = toNumber(number); } This keeps within the scope of the mixin body. --
[Issue 16584] Local import ineffective for mixin templates
https://issues.dlang.org/show_bug.cgi?id=16584 m.bier...@lostmoment.com changed: What|Removed |Added Status|NEW |RESOLVED Resolution|--- |INVALID --- Comment #1 from m.bier...@lostmoment.com --- >From the documentation: "Unlike a template instantiation, a template mixin's body is evaluated within the scope where the mixin appears, not where the template declaration is defined." So this is actually by design. Closed the issue. --
[Issue 15862] dmd thinks functions are strongly pure despite mutable indirections in the return type
https://issues.dlang.org/show_bug.cgi?id=15862 Walter Brightchanged: What|Removed |Added Status|NEW |RESOLVED CC||bugzi...@digitalmars.com Resolution|--- |INVALID --- Comment #2 from Walter Bright --- This is as designed and intended. 1. Mutable indirections in the return type do not affect purity determination. Mutability of the parameters does. 2. An early design decision was that calling new() inside a pure function is an acceptable special case. (Otherwise pure functions would be nearly useless.) --
[Issue 15735] std.algorithm.iteration.splitter returns empty range
https://issues.dlang.org/show_bug.cgi?id=15735 --- Comment #3 from github-bugzi...@puremagic.com --- Commit pushed to revert-4030-issue15735 at https://github.com/dlang/phobos https://github.com/dlang/phobos/commit/4fa5ff684e946ef82927b6ff3937c27d23470c9a Revert "Fix issue 15735" --
[Issue 16586] Implicit casting of enum with explicit int base type fails
https://issues.dlang.org/show_bug.cgi?id=16586 --- Comment #1 from m.bier...@lostmoment.com --- Current work-around is to explicitly cast all enum members: int[] ints = [cast(int) IntTypeEnumOne.bla, cast(int) IntTypeEnumTwo.bleh]; --
[Issue 16587] split("", "x") should be ""
https://issues.dlang.org/show_bug.cgi?id=16587 --- Comment #1 from Vladimir Panteleev--- Example real-life scenarios: - Comma-delimited lists in program arguments or configuration files. The string variables will be empty unless populated, then split afterwards. - `libPaths ~= environment.get("LIBPATH", null).split(":")` will now search the current directory. --
[Issue 16587] New: split("", "x") should be ""
https://issues.dlang.org/show_bug.cgi?id=16587 Issue ID: 16587 Summary: split("", "x") should be "" Product: D Version: D2 Hardware: All OS: All Status: NEW Severity: regression Priority: P1 Component: phobos Assignee: nob...@puremagic.com Reporter: thecybersha...@gmail.com /// test.d /// import std.string; void main() { assert("".split(",").length == 0); } // Introduced in https://github.com/dlang/phobos/pull/4030. Additionally, the new behavior is inconsistent: split("") => [] split("", ",") => [""] splitLines("") => [] --
[Issue 16586] New: Implicit casting of enum with explicit int base type fails
https://issues.dlang.org/show_bug.cgi?id=16586 Issue ID: 16586 Summary: Implicit casting of enum with explicit int base type fails Product: D Version: D2 Hardware: x86_64 OS: Windows Status: NEW Severity: enhancement Priority: P1 Component: dmd Assignee: nob...@puremagic.com Reporter: m.bier...@lostmoment.com Consider the following code: enum StringTypeEnumOne : string { bla = "bla" } enum StringTypeEnumTwo : string { bleh = "bleh" } enum IntTypeEnumOne : int { bla = 1 } enum IntTypeEnumTwo : int { bleh = 2 } public void main() { string[] strings = [StringTypeEnumOne.bla, StringTypeEnumTwo.bleh]; int[] ints = [IntTypeEnumOne.bla, IntTypeEnumTwo.bleh]; } When compiled the following compilation error is thrown: src\app.d(19,16): Error: cannot implicitly convert expression (cast(IntTypeEnumOne)1) of type IntTypeEnumOne to IntTypeEnumTwo The string members are implicitly cast just fine, however I also expected the members of the int enum to be cast implicitly because I explicitly defined the base type of the enum. --
[Issue 16585] New: dmd thinks function returns unique result despite mutable indirection in parameter
https://issues.dlang.org/show_bug.cgi?id=16585 Issue ID: 16585 Summary: dmd thinks function returns unique result despite mutable indirection in parameter Product: D Version: D2 Hardware: x86_64 OS: Linux Status: NEW Keywords: accepts-invalid Severity: normal Priority: P1 Component: dmd Assignee: nob...@puremagic.com Reporter: ag0ae...@gmail.com int[] fun(long[] arg) pure { return cast(int[]) arg; } void main() { long[] a = [1]; immutable i = fun(a); /* Should be rejected. Only ok when fun(a) is actually unique. */ immutable copy = i.dup; assert(copy == i); /* Passes. */ a[0] = 2; /* Affects the immutable i. */ assert(copy == i); /* Fails now. */ } Possibly related to issue 15862. --
Re: Release candidate vibe.d 0.7.30-rc.1
On Thursday, 29 September 2016 at 13:44:53 UTC, Sönke Ludwig wrote: If no new issues come up, the 0.7.30 release is scheduled for the 9th of October. Please consider https://github.com/rejectedsoftware/vibe.d/issues/1583
[Issue 16584] New: Local import ineffective for mixin templates
https://issues.dlang.org/show_bug.cgi?id=16584 Issue ID: 16584 Summary: Local import ineffective for mixin templates Product: D Version: D2 Hardware: x86_64 OS: Windows Status: NEW Severity: normal Priority: P1 Component: dmd Assignee: nob...@puremagic.com Reporter: m.bier...@lostmoment.com Consider the following code: // func.d module func; public uint toNumber(string str) { return str[0]; } // mixins.d module mixins; import func; mixin template bla(string number) { uint globalBla = toNumber(number); } // app.d module app; import mixins; public void main() { mixin bla!"aaa"; } When compiled, the following compilation error is shown: src\mixins.d(6,19): Error: undefined identifier 'toNumber' src\app.d(6,2): Error: mixin app.main.bla!"aaa" error instantiating I expected the import of module 'func' to be only needed at the site of the mixin declaration, not where the mixin is used. Publicly importing module 'func' in mixins.d works around the problem, as does importing module 'func' in app.d. --
Re: Getting GtkD working with OpenGL
On Monday, 3 October 2016 at 18:00:53 UTC, Mike Wey wrote: The signal functions can be found in the gobject.Signals module. But you should use the GLArea.addOnCreateContext / addOnRender / addOnResize functions to attach a D delegate to the signal. You will still need to link with the OpenGL libraries or use someting like Derelict. Hi Mike, thanks for your fast answer again! I just read about this delegates and I liked the concept. I experimented with it for a while and read a bit on the Internet, but I still don't get it working... My minimal example looks like this: import gtk.Main; import gtk.MainWindow; import gtk.GLArea; import glgdk.GLContext; void main(string[] args) { bool render(GLContext context, GLArea area) { return true; } Main.init(args); MainWindow win = new MainWindow("Hello World"); GLArea area = new GLArea(); area.addOnRender(,cast(GConnectFlags)0); win.add(area); win.showAll(); Main.run(); } If I compile it, I get this error: $ dmd main.d -I/usr/local/include/d/gtkd-3 -L-lgtkd-3 main.d(27): Error: function gtk.GLArea.GLArea.addOnRender (bool delegate(GLContext, GLArea) dlg, GConnectFlags connectFlags = cast(GConnectFlags)0) is not callable using argument types (bool delegate(GLContext context, GLArea area), GConnectFlags) I cant see, what I am doing wrong... Someone else sees the error? Tomorrow I try to subclass the GLArea, if this works I am happy :) But I'd like to use the handler stuff. Ah, and I know now, that I have to link against the GL and GLU library, but which module do I have to import, to make the functions visible for the compiler? Or do I need another binding therefore?
[Issue 16583] New: Static module ctor semantic proposition
https://issues.dlang.org/show_bug.cgi?id=16583 Issue ID: 16583 Summary: Static module ctor semantic proposition Product: D Version: D2 Hardware: All OS: All Status: NEW Severity: enhancement Priority: P1 Component: dlang.org Assignee: nob...@puremagic.com Reporter: b2.t...@gmx.com I propose that static module constructor/destructor would only happen without selective import: import stuff; // static module ctor triggerred import stuff: Type; // static module ctor not triggerred --
Re: How to make rsplit (like in Python) in D
On Saturday, 1 October 2016 at 18:33:02 UTC, TheFlyingFiddle wrote: On Saturday, 1 October 2016 at 16:45:11 UTC, Uranuz wrote: [...] There are two reasons why this does not compile. The first has to do with how retro() (and indeed most function in std.range) work with utf-8 strings (eg the string type). When working on strings as ranges, the ranges internally change the type of ".front" from 'char' into 'dchar'. This is done to ensure that algorithms working on strings do not violate utf-8. [...] Thanks for clarification. It seems that once upon a time I'll write my own string wrapper that will return just slice of `string` pointing to source multibyte sequence as .front and will use it, and be happy. When I looking more at other languages (like Python) then I more convinced that working with UTF-8 string as array of single bytes is not very good
Re: How to make rsplit (like in Python) in D
On Monday, 3 October 2016 at 19:25:59 UTC, Uranuz wrote: When I pass empty string to splitter in most of languages I expect to get list with 1 item (empty string) as a result, but I get error instead. And I see inconsistency in that .front behaves normally, but .back is not. Usually I access front of range directly without any check when I expect it to have exactly 1 item. But in this case it not working and is very strange. Hm, if front works but not back that is probably a bug. I think checking whether the range is empty before accessing the member should be a viable workaround.
Re: How to make rsplit (like in Python) in D
On Saturday, 1 October 2016 at 18:55:54 UTC, pineapple wrote: On Saturday, 1 October 2016 at 17:55:08 UTC, Uranuz wrote: On Saturday, 1 October 2016 at 17:32:59 UTC, Uranuz wrote: On Saturday, 1 October 2016 at 17:23:16 UTC, Uranuz wrote: [...] But these example fails. Oops. Looks like a bug( import std.stdio; import std.algorithm; import std.range; import std.string; [...] I created bug report on this: https://issues.dlang.org/show_bug.cgi?id=16569 This isn't a bug. It's illegal to access the front or back of an empty range. (If anything is a bug, it's the nondescriptiveness of the error.) You should write this instead: void main() { string str = ""; auto split = str.splitter('.'); if(!split.empty) writeln(split.back); } When I pass empty string to splitter in most of languages I expect to get list with 1 item (empty string) as a result, but I get error instead. And I see inconsistency in that .front behaves normally, but .back is not. Usually I access front of range directly without any check when I expect it to have exactly 1 item. But in this case it not working and is very strange.
[Issue 16485] Add trait for determining whether a member variable is static or not
https://issues.dlang.org/show_bug.cgi?id=16485 --- Comment #1 from Jonathan M Davis--- https://github.com/dlang/phobos/pull/4834 --
Re: Challenge
On Monday, October 03, 2016 11:13:52 Jonathan M Davis via Digitalmars-d wrote: > template isStaticMember(T, string member) > { > static if (!__traits(hasMember, T, member)) > enum bool isStaticMember = false; > else > { > import std.meta : AliasSeq; > import std.traits : FunctionTypeOf; > alias sym = AliasSeq!(__traits(getMember, T, member))[0]; > > static if (__traits(isStaticFunction, sym)) > enum bool isStaticMember = true; > else static if (is(FunctionTypeOf!sym == function) && > is(FunctionTypeOf!(typeof()) == function)) > { > enum bool isStaticMember = false; > } > else > { > enum bool isStaticMember = !__traits(compiles, sym.offsetof) && >__traits(compiles, ); > } > } > } Well, since I took the time to write it, I created a PR for it: https://github.com/dlang/phobos/pull/4834 So, if anyone sees problems with my implementation, go poke holes in it. - Jonathan M Davis
Re: Why using wrappers for D?
On Monday, October 03, 2016 18:05:47 Chalix via Digitalmars-d-learn wrote: > Ah great, now I understand it :) > I thought, import and include would work the same way (taking all > the code in the .h or .d file and pasting it into the other file). > But if import extracts only the definitions, it is clear, that > you have to link against the library, or to add all the .d files > to your source code. #include is a _very_ inefficient way to do things. It results in the same code being compiled over and over again, which is why pretty much every language post C/C++ has some sort of symbol import mechanism in attempt to compile everything only once. The way it works in D, you do end up with some amount of work being redone if you do incremental compilation, but even then, it minimizes how much it has to redo, and there are future improvements planned which will make it even better. There's a reason why D compiles so much faster than C/C++. :) You should probably read this article by Walter on why C/C++ compilation is so slow: http://www.digitalmars.com/articles/b54.html It's quite enlightening - and horrifying. - Jonathan M Davis
Re: debugging mixins
On Monday, 3 October 2016 at 15:23:40 UTC, Jonathan Marler wrote: Yes, having the mixins expanded without the surrounding code would make it difficult to debug in some cases. Maybe generating the entire source with the expanded mixins is another option? mycode.d obj/mycode_processed.d That was my intention. Maybe this idea could also be expanded to template instantiation? Oh yes. it is not that more much work :)
Re: Challenge
On 10/03/2016 07:41 AM, Seb wrote: On Monday, 3 October 2016 at 13:19:19 UTC, Manu wrote: Fill in the blank... I'm having a really hard time with this. I've made it work with a mountain of code, and I want to see what others come up with... If you succeed, put it in std.traits! Recommend, use latest DMD nightly. I find differences with latest nightly vs release. See also: http://stackoverflow.com/questions/39430684/check-if-class-member-is-static Appeared on dlang forum as well: :) http://forum.dlang.org/post/nni8lp$1ihk$1...@digitalmars.com Ali
Re: Why using wrappers for D?
On 10/03/2016 07:19 PM, Chalix wrote: On Monday, 3 October 2016 at 13:51:28 UTC, Mike Parker wrote: // wrapfoo.d import foo; // import the foo module from above void myFunc(string s) { import std.string : toStringz; my_func(s.toStringz()); } Thank you for the example, Mike! And thanks to all others who support me with their answers! I didn't expect so much answers, the D community seems to be very helpful :) But there still is one thing, which I don't get: If I "import foo;" in my project, it will be compiled alongside. So there is no need for an extra library. Same should be for wrapfoo.d. If I "import wrapfoo;", I should just need the C-library "foo", and no D-library "food" right? To have a more practical example, I looked up the "header" of the GtkD gtk/Main.d file. There are functions exactly like you described: public static void init(ref string[] argv) { int argc = cast(int)argv.length; char** outargv = Str.toStringzArray(argv); gtk_init(, ); argv = Str.toStringArray(outargv, argc); } This function wraps the C-like gtk_init function to a D init function. The gtk_init function is the function from the GTK+ library, which is loaded in the gtkc/gtk.d file: Linker.link(gtk_init, "gtk_init", LIBRARY.GTK); Linker and link are defined in the gtkc/Loader.d So, why is it not enough just to "import gtk.Main"? What kind of code is inside the gtkd-3 library? The gtkd-3 library contains for example the code you quoted above. -- Mike Wey
Re: Why using wrappers for D?
On Monday, 3 October 2016 at 17:19:47 UTC, Chalix wrote: If I "import foo;" in my project, it will be compiled alongside. So there is no need for an extra library. Same should be for wrapfoo.d. If I "import wrapfoo;", I should just need the C-library "foo", and no D-library "food" right? You do have some confusion here, which Jonathan's answer should clear up (that is, importing a module does not cause it to be compiled, only makes its symbols to the module in which the declaration is made), however, there is one point I'd like to make below. This function wraps the C-like gtk_init function to a D init function. The gtk_init function is the function from the GTK+ library, which is loaded in the gtkc/gtk.d file: Linker.link(gtk_init, "gtk_init", LIBRARY.GTK); Linker and link are defined in the gtkc/Loader.d So, why is it not enough just to "import gtk.Main"? What kind of code is inside the gtkd-3 library? I don't know the details of the gtkd-3 library, but consider this example: ``` // csay.c #include void sayHi() { puts("Hi\n"); } // dsay.d module dsay; extern(C) void sayHi(); // hi.d import dsay; void main() { sayHi(); } ``` Assuming you have both dmd and dmc installed, you can easily do a bit of experimentation like so: First, use dmd to generate csay.obj. dmc -c csay.c Next, with dsay.d, hi.d and csay.obj all in the same directory, build an executable. dmd hi.d csay.obj This should result in both a successful compile and a successful link. But understand that dsay.d was *never* compiled in this process. Importing dsay made the source symbol 'sayHi' available to hi.d. The compiler emitted a call to sayHi in the generated binary (hi.obj). Finally, the linker was able to match that call to the C sayHi function and could perform the link to generate the executable. Because the binary symbol for sayHi was already present in csay.obj, you did not need to compile and link dsay.d. Now, let's change it up a bit: ``` // csay.h extern void sayHi(); #define sayHiTwice \ sayHi(); \ sayHi(); ``` This is a horrible macro, but it serves its purpose as an example. In order to provide sayHiTwice in D, it will have to be implemented and not just declared: ``` // dsay.d extern(C) void sayHi(); void sayHiTwice() { sayHi(); sayHi(); } ``` Since the C version of sayHiTwice is a macro and not a function, it need not be extern(C). However, no we have an implementation and not simply a declaration. So this: ``` // hi.d import dsay; void main() { sayHiTwice(); } ``` dmd hi.d csay.obj Is now going to generate a *linker* error. It will *compile* just fine, since the import of dsay makes sayHiTwice visible during compilation. However, since csay.obj does not contain a binary symbol for sayHiTwice (as it's a macro and not a function), the the linker will be unable to match the call to any existing symbol and will produce an error. So you would have to do this: dmd hi.d dsay.d csay.obj Now, the binary symbol for sayHiTwice will be generated because dsay.d is being compiled and linked into the program. So, when you have a declarations-only module, with no function implementations or template instantiations, then it need not actually be compiled and linked into the program. In that you are correct. But, no, importing a module does not automatically compile it. And any function declarations still need an implementation somewhere if they are used in the modules you do compile.
Re: Why using wrappers for D?
On Monday, 3 October 2016 at 17:56:46 UTC, ag0aep6g wrote: When you do precompile to a library, you can skip the compilation later. That can save time. True, linking with this library instead of compiling it every time I changed my code will save me a lot of time :)
Re: Why using wrappers for D?
On 10/03/2016 05:47 AM, Chalix wrote: > what do you mean > by "turn C functions into classes"? Many C APIs are object-oriented in that, they pass the most interesting object as the first parameter: // C struct struct Foo { // ... }; // Factory method (or, "constructor") Foo* make_foo(int i, double d); void free_foo(Foo** foo); int use_foo(Foo* foo, const char *str); Instead of living with C's limitations, one can define a D struct Foo and turn such function into member functions: // D struct struct FooD { // ... Foo* c_foo; // other things that go with // Factory method (or, "constructor") this(int i, double d) { c_foo = make_foo(i, d);// dispatch to C library } ~this() { free_foo(_foo);// dispatch to C library } void use(BarD bar) { enforce(use_foo(c_foo, "hello"); } } That's how a D wrapper of a C library may look like, which should be almost identical to how it could be done in C++. > Also, I used the Qt library a lot with C++. But although it is a > library, I have access to all the classes, like " QWidget w = new > QWidget();". There is no factory method used. (This confuses me now a > bit...) 'new QWidget()' does call the constructor automatically, which D cannot do. (Although, with the recent changes in C++ interoperability, perhaps even that's doable today.) If D cannot create C++ object with the 'new' keyword, then they can use a layer of a factory method to do it: // A C++ layer extern "C" QWidget* make_QWidget() { return new QWidget(); } extern "C" void free_QWidget(QWidget* p) { delete p; } Since that function (i.e. not the "new expression" itself) is callable from D, the D code can now use the library: extern (C) { // ... QWidget* make_QWidget(); void free_QWidget(QWidget* p); } // D class class QWidgetD { QWidget* cpp_widget; this() { cpp_widget = make_QWidget(); } ~this() { free_QWidget(cpp_widget); } // ... } That's how I understand it anyway... :) Again though, this may be much easier today with the recent and ongoing improvements to C++ interoperability. Ali
Re: Challenge
On Monday, October 03, 2016 08:38:22 Jonathan M Davis via Digitalmars-d wrote: > On Monday, October 03, 2016 23:19:19 Manu via Digitalmars-d wrote: > > Fill in the blank... > > I'm having a really hard time with this. I've made it work with a > > mountain of code, and I want to see what others come up with... > > It's certainly possible that this misses something, but it passes all of > your test cases: > > template isStaticMember(T, string member) > { > static if(!__traits(hasMember, T, member)) > enum bool isStaticMember = false; > else > { > import std.meta : AliasSeq; > import std.traits : FunctionTypeOf; > alias sym = AliasSeq!(__traits(getMember, T, member))[0]; > static if(__traits(isStaticFunction, sym)) > enum bool isStaticMember = true; > else static if(is(FunctionTypeOf!sym == function) && >is(FunctionTypeOf!(typeof()) == function)) > { > enum bool isStaticMember = false; > } > else > { > enum bool isStaticMember = !__traits(compiles, sym.offsetof) && >!is(sym == enum) && >!is(sym == class) && >!is(sym == struct) && >__traits(compiles, ); > } > } > } Actually, it can be reduced even further: template isStaticMember(T, string member) { static if (!__traits(hasMember, T, member)) enum bool isStaticMember = false; else { import std.meta : AliasSeq; import std.traits : FunctionTypeOf; alias sym = AliasSeq!(__traits(getMember, T, member))[0]; static if (__traits(isStaticFunction, sym)) enum bool isStaticMember = true; else static if (is(FunctionTypeOf!sym == function) && is(FunctionTypeOf!(typeof()) == function)) { enum bool isStaticMember = false; } else { enum bool isStaticMember = !__traits(compiles, sym.offsetof) && __traits(compiles, ); } } } Checking for the address makes it unnecessary to check for enums, classes, or structs. - Jonathan M Davis
Re: Why using wrappers for D?
On Monday, 3 October 2016 at 17:45:55 UTC, Jonathan M Davis wrote: The import statement just tells the D compiler to pull in declarations for the symbols that it needs from those modules. It doesn't actually compile those modules. You still have to give them to the compiler (either all together or separately to generate .o/.obj files) in order to actually compile them. And anything that's not D (like a C/C++ library) still needs to be linked in just like it would be in C/C++. In C/C++, #including is not enough to compile everything into your code unless everything is in the header files (which it rarely is). For the files in your project, you have to compile every .c/.cpp file to generate the .o or .obj files that the linker then links into your program, and for the 3rd party stuff that's in a library you need to link in the library. Simply #including doesn't actually bring something like curl or gtk into your program. You also have to link it when generating your executable. It's basically the same thing with D. Every .d file in your project needs to be compiled so that it gets linked into your executable, and if you want to use 3rd party stuff, you have to link in the libraries just like you would with C/C++. The separation is perhaps a bit less clear in D, because you usually just use .d files for everything, whereas C/C++ have .h and .c/.cpp as separate files. D does have .di files for the cases where you need to hide your code, but they don't get used often. But when you do use a .di file, that's what gets imported rather than the .d file which contains the actual definitions, so in that case, the separation is clearer. Ah great, now I understand it :) I thought, import and include would work the same way (taking all the code in the .h or .d file and pasting it into the other file). But if import extracts only the definitions, it is clear, that you have to link against the library, or to add all the .d files to your source code. A big thank-you to all repliers for making things clear :D
Re: Getting GtkD working with OpenGL
On 10/03/2016 01:50 PM, Chalix wrote: On Sunday, 18 September 2016 at 21:41:45 UTC, Mike Wey wrote: The demo still uses the old GtkGLExt binding, which usually isn't available in de distributions repositories. The newer GLArea is easier to use since it's part of GTK. As for the linker errors, you'll need to link with the OpenGL libraries: "-L-lGL -L-lGLU" Hey, thanks for your fast answer! I had a lot of other work to do, so I could only continue working on this project now. Yeah, that solved my problem :) Now it links. Although if I execute the program, it complains about the missing GtkGLExt library, like expected... Library load failed: libgdkglext-3.0.so.0 So I wanted to install this library from here: https://projects.gnome.org/gtkglext/download.html but the ./configure script tells me, No package 'pangox' found (pangox >= 1.0.0) I looked at the folder /usr/lib/x86_64-linux-gnu/ and there is a file called "libpangox-1.0.so.0.0.0". So I don't know, why this is not working... You will need the Gtk3 port of gtkglext: https://github.com/tdz/gtkglext Last time i tried compiling it i needed to remove the documentation generation from the make files. Anyway, I want to follow Mikes advice and use GLArea instead, so if there is not a quick fix available, lets skip the problems with the GtkGLExt library... But, sadly enough, I did not get GLArea working, too. The documentation https://developer.gnome.org/gtk3/stable/GtkGLArea.html says, I have to connect my render function to the widget like this: g_signal_connect (gl_area, "render", G_CALLBACK (render), NULL); But, my compiler can't find the g_signal_connect method (and the GL Methods...): main.d(22): Error: undefined identifier 'g_signal_connect' main.d(39): Error: undefined identifier 'glClearColor' main.d(40): Error: undefined identifier 'glClear' There might some include files (or import files, as you say in D) missing, but I could not figure out, where to find them for D... Could you tell me, where this g_signal_connect method can be found? And what I have to include for the GL functionality? Simply "import gtk.GLArea;" does not do the trick... The signal functions can be found in the gobject.Signals module. But you should use the GLArea.addOnCreateContext / addOnRender / addOnResize functions to attach a D delegate to the signal. You will still need to link with the OpenGL libraries or use someting like Derelict. Btw, is g_signal_connect a GTK method? I intend to use my program platform independent, so if this is dependent on gnome, it would not be good. It's a GLib/GObject method, it's available on any platform GTK runs on. Or is there any other way to get the GLArea working? I am used to the Qt Libraries, where you create a QGLWidget and simply override the init and render functions. Thanks for reading this far, would be great if we could solve this problem :D -- Mike Wey
Re: Why using wrappers for D?
On 10/03/2016 07:19 PM, Chalix wrote: If I "import foo;" in my project, it will be compiled alongside. Not necessarily. dmd won't compile foo unless you tell it to by putting foo.d on the command line. If foo is only imported, dmd parses the file but it doesn't compile it. So there is no need for an extra library. You don't *need* the library. You can just compile the file together with the rest of your program, yes. When you do precompile to a library, you can skip the compilation later. That can save time. And you can shorten the distributed D source files to just the function signatures, like with header files in C. For this, the compiler recognizes the .di filename extension. This can be used to somewhat protect closed source code. And then there are shared libraries, which are loaded at run time. Their code is not included in the executable, so you get a smaller file. Makes sense with popular libraries that are used by many programs. Same should be for wrapfoo.d. If I "import wrapfoo;", I should just need the C-library "foo", and no D-library "food" right? If wrapfoo is really just a binding, i.e. it provides only function signatures and no implementation, then there's no point in compiling it to a library. Otherwise, if wrapfoo actually implements something of its own, it can make sense to compile it to a library. Just like with every other piece of code. To have a more practical example, I looked up the "header" of the GtkD gtk/Main.d file. There are functions exactly like you described: public static void init(ref string[] argv) { int argc = cast(int)argv.length; char** outargv = Str.toStringzArray(argv); gtk_init(, ); argv = Str.toStringArray(outargv, argc); } This function wraps the C-like gtk_init function to a D init function. The gtk_init function is the function from the GTK+ library, which is loaded in the gtkc/gtk.d file: Linker.link(gtk_init, "gtk_init", LIBRARY.GTK); Linker and link are defined in the gtkc/Loader.d So, why is it not enough just to "import gtk.Main"? What kind of code is inside the gtkd-3 library? If the GtkD files contain all the implementations (not just signatures), then you don't have to build/use the library. You can just compile the GtkD source files along with your program, and link with the C library.
Re: Why using wrappers for D?
On Monday, October 03, 2016 17:19:47 Chalix via Digitalmars-d-learn wrote: > But there still is one thing, which I don't get: > > If I "import foo;" in my project, it will be compiled alongside. > So there is no need for an extra library. Same should be for > wrapfoo.d. If I "import wrapfoo;", I should just need the > C-library "foo", and no D-library "food" right? The import statement just tells the D compiler to pull in declarations for the symbols that it needs from those modules. It doesn't actually compile those modules. You still have to give them to the compiler (either all together or separately to generate .o/.obj files) in order to actually compile them. And anything that's not D (like a C/C++ library) still needs to be linked in just like it would be in C/C++. In C/C++, #including is not enough to compile everything into your code unless everything is in the header files (which it rarely is). For the files in your project, you have to compile every .c/.cpp file to generate the .o or .obj files that the linker then links into your program, and for the 3rd party stuff that's in a library you need to link in the library. Simply #including doesn't actually bring something like curl or gtk into your program. You also have to link it when generating your executable. It's basically the same thing with D. Every .d file in your project needs to be compiled so that it gets linked into your executable, and if you want to use 3rd party stuff, you have to link in the libraries just like you would with C/C++. The separation is perhaps a bit less clear in D, because you usually just use .d files for everything, whereas C/C++ have .h and .c/.cpp as separate files. D does have .di files for the cases where you need to hide your code, but they don't get used often. But when you do use a .di file, that's what gets imported rather than the .d file which contains the actual definitions, so in that case, the separation is clearer. - Jonathan M Davis
Re: Why using wrappers for D?
On Monday, 3 October 2016 at 13:51:28 UTC, Mike Parker wrote: // wrapfoo.d import foo; // import the foo module from above void myFunc(string s) { import std.string : toStringz; my_func(s.toStringz()); } Thank you for the example, Mike! And thanks to all others who support me with their answers! I didn't expect so much answers, the D community seems to be very helpful :) But there still is one thing, which I don't get: If I "import foo;" in my project, it will be compiled alongside. So there is no need for an extra library. Same should be for wrapfoo.d. If I "import wrapfoo;", I should just need the C-library "foo", and no D-library "food" right? To have a more practical example, I looked up the "header" of the GtkD gtk/Main.d file. There are functions exactly like you described: public static void init(ref string[] argv) { int argc = cast(int)argv.length; char** outargv = Str.toStringzArray(argv); gtk_init(, ); argv = Str.toStringArray(outargv, argc); } This function wraps the C-like gtk_init function to a D init function. The gtk_init function is the function from the GTK+ library, which is loaded in the gtkc/gtk.d file: Linker.link(gtk_init, "gtk_init", LIBRARY.GTK); Linker and link are defined in the gtkc/Loader.d So, why is it not enough just to "import gtk.Main"? What kind of code is inside the gtkd-3 library?
[Issue 16582] [REG2.072.0-b1] ParamterDefaultValueTuple fails to compile for scope paramters
https://issues.dlang.org/show_bug.cgi?id=16582 Sönke Ludwigchanged: What|Removed |Added Component|dmd |phobos --
[Issue 16582] New: [REG2.072.0-b1] ParamterDefaultValueTuple fails to compile for scope paramters
https://issues.dlang.org/show_bug.cgi?id=16582 Issue ID: 16582 Summary: [REG2.072.0-b1] ParamterDefaultValueTuple fails to compile for scope paramters Product: D Version: D2 Hardware: All OS: All Status: NEW Severity: regression Priority: P1 Component: dmd Assignee: nob...@puremagic.com Reporter: slud...@outerproduct.org --- import std.traits; class C {} void foo(scope C bar = null) {} static assert(ParameterDefaultValueTuple!foo[0] == null); --- For DMD 2.072.0-b1, results in: .../src/phobos/std/traits.d-mixin-1211(1211): Error: scope variable bar may not be returned Works correctly up to 2.071.2 --
Re: Pattern-matching qualifiers with is() expressions
On Monday, October 03, 2016 12:40:45 Andrei Alexandrescu via Digitalmars-d wrote: > Am I doing something wrong? This is a fairly basic match, I'm surprised > this hasn't surfaced yet: > > https://issues.dlang.org/show_bug.cgi?id=16581 My guess is that it hasn't been fined primarily because that version of an is expression probably isn't used all that often. And if the problem is qualifier-specific, then in order to hit the bug, someone would have to not only use that specific version of an is expression, but they'd have to be testing qualifiers with it as well. And I'd guess that that just isn't very common. Not to mention, even if some code did hit it, depending on what the it did, the bug might go unnoticed. - Jonathan M Davis
Pattern-matching qualifiers with is() expressions
Am I doing something wrong? This is a fairly basic match, I'm surprised this hasn't surfaced yet: https://issues.dlang.org/show_bug.cgi?id=16581 Andrei
Re: ndslice: feature deprecation voting / discussion
On Sunday, 2 October 2016 at 16:36:14 UTC, jmh530 wrote: Wouldn't it be more flexible to allow both ways? If D can handle the case without brackets without any issue, why force it? In Matlab, writing ones(2, 2) produces a 2x2 matrix of ones. In numpy, I would write np.ones((2, 2)) I find it annoying that in numpy I have to constantly remember to put in the second set of parentheses. This idea is basically forcing the same issue into ndslice. I think it's a bad idea. I feel the same way. +1 here
[Issue 16581] New: Template shape misdetected in is() expression
https://issues.dlang.org/show_bug.cgi?id=16581 Issue ID: 16581 Summary: Template shape misdetected in is() expression Product: D Version: D2 Hardware: All OS: All Status: NEW Severity: normal Priority: P1 Component: dmd Assignee: nob...@puremagic.com Reporter: and...@erdani.com Consider: struct Test(T) {} template PropagateQualifier(Q) { static if (is(Q == immutable(Test!X), X)) alias PropagateQualifier = immutable X; else static if (is(Q == const Test!X, X)) alias PropagateQualifier = const X; else static if (is(Q == Test!X, X)) alias PropagateQualifier = X; else static assert(0); } static assert(is(PropagateQualifier!(Test!char) == char)); This fails because PropagateQualifier!(Test!char) yields immutable(cha r). Shuffling the three cases around reveals that the first is() test always passes. Inglorious workaround: struct Test(T) {} template PropagateQualifier(Q) { static if (is(Q == immutable)) { static if (is(Q == immutable(Test!X), X)) alias PropagateQualifier = immutable X; } else static if (is(Q == const)) { static if (is(Q == const(Test!X), X)) alias PropagateQualifier = const X; } else static if (is(Q == Test!X, X)) alias PropagateQualifier = X; else static assert(0); } static assert(is(PropagateQualifier!(Test!char) == char)); static assert(is(PropagateQualifier!(const(Test!char)) == const char)); static assert(is(PropagateQualifier!(Test!(immutable char)) == immutable char)); --
Re: Challenge
On Monday, October 03, 2016 23:19:19 Manu via Digitalmars-d wrote: > Fill in the blank... > I'm having a really hard time with this. I've made it work with a > mountain of code, and I want to see what others come up with... It's certainly possible that this misses something, but it passes all of your test cases: template isStaticMember(T, string member) { static if(!__traits(hasMember, T, member)) enum bool isStaticMember = false; else { import std.meta : AliasSeq; import std.traits : FunctionTypeOf; alias sym = AliasSeq!(__traits(getMember, T, member))[0]; static if(__traits(isStaticFunction, sym)) enum bool isStaticMember = true; else static if(is(FunctionTypeOf!sym == function) && is(FunctionTypeOf!(typeof()) == function)) { enum bool isStaticMember = false; } else { enum bool isStaticMember = !__traits(compiles, sym.offsetof) && !is(sym == enum) && !is(sym == class) && !is(sym == struct) && __traits(compiles, ); } } } - Jonathan M Davis
Re: Challenge
On Monday, October 03, 2016 23:19:19 Manu via Digitalmars-d wrote: > Fill in the blank... > I'm having a really hard time with this. I've made it work with a > mountain of code, and I want to see what others come up with... > > If you succeed, put it in std.traits! > > Recommend, use latest DMD nightly. I find differences with latest > nightly vs release. > > > --- template isStaticMember(T, string member) > { > enum bool isStaticMember = [code goes here]; > } > > > struct S > { > enum X = 10; > enum Y > { > i = 10 > } > struct S {} > class C {} > > static int x = 0; > __gshared int y = 0; > static void f() {} > static void f2() pure nothrow @nogc @safe {} > > shared void g() {} > > static void function() fp; > __gshared void function() gfp; > void function() fpm; > > void m() {} > final void m2() const pure nothrow @nogc @safe {} > > inout(int) iom() inout { return 10; } > static inout(int) iosf(inout int x) { return x; } > > @property int p() { return 10; } > static @property int sp() { return 10; } > } > > class C > { > enum X = 10; > enum Y > { > i = 10 > } > struct S {} > class C {} > > static int x = 0; > __gshared int y = 0; > static void f() {} > static void f2() pure nothrow @nogc @safe {} > > shared void g() {} > > static void function() fp; > __gshared void function() gfp; > void function() fpm; > > void m() {} > final void m2() const pure nothrow @nogc @safe {} > > inout(int) iom() inout { return 10; } > static inout(int) iosf(inout int x) { return x; } > > @property int p() { return 10; } > static @property int sp() { return 10; } > } > > static assert(!isStaticMember!(S, "X"), "!"); > static assert(!isStaticMember!(S, "Y"), "!"); > static assert(!isStaticMember!(S, "Y.i"), "!"); > static assert(!isStaticMember!(S, "S"), "!"); > static assert(!isStaticMember!(S, "C"), "!"); > static assert( isStaticMember!(S, "x"), "!"); > static assert( isStaticMember!(S, "y"), "!"); > static assert( isStaticMember!(S, "f"), "!"); > static assert( isStaticMember!(S, "f2"), "!"); > static assert(!isStaticMember!(S, "g"), "!"); > static assert( isStaticMember!(S, "fp"), "!"); > static assert( isStaticMember!(S, "gfp"), "!"); > static assert(!isStaticMember!(S, "fpm"), "!"); > static assert(!isStaticMember!(S, "m"), "!"); > static assert(!isStaticMember!(S, "m2"), "!"); > static assert(!isStaticMember!(S, "iom"), "!"); > static assert( isStaticMember!(S, "iosm"), "!"); > static assert(!isStaticMember!(S, "p"), "!"); > static assert( isStaticMember!(S, "sp"), "!"); > > static assert(!isStaticMember!(C, "X"), "!"); > static assert(!isStaticMember!(C, "Y"), "!"); > static assert(!isStaticMember!(C, "Y.i"), "!"); > static assert(!isStaticMember!(C, "S"), "!"); > static assert(!isStaticMember!(C, "C"), "!"); > static assert( isStaticMember!(C, "x"), "!"); > static assert( isStaticMember!(C, "y"), "!"); > static assert( isStaticMember!(C, "f"), "!"); > static assert( isStaticMember!(C, "f2"), "!"); > static assert(!isStaticMember!(C, "g"), "!"); > static assert( isStaticMember!(C, "fp"), "!"); > static assert( isStaticMember!(C, "gfp"), "!"); > static assert(!isStaticMember!(C, "fpm"), "!"); > static assert(!isStaticMember!(C, "m"), "!"); > static assert(!isStaticMember!(C, "m2"), "!"); > static assert(!isStaticMember!(C, "iom"), "!"); > static assert( isStaticMember!(C, "iosm"), "!"); > static assert(!isStaticMember!(C, "p"), "!"); > static assert( isStaticMember!(C, "sp"), "!"); I would point out that iosm is missing from both the struct and the class, so it can't be true for isStaticMember. I assume that you meant for it to be iosf, which _is_ declared? - Jonathan M Davis
Re: debugging mixins
On Sunday, 2 October 2016 at 03:36:31 UTC, Manu wrote: This comes up a lot. As far as I know, it's not solved. What shall we do? I feel like a simple solution would be to have the compiler emit a _mixin.d file populated with all the mixin expansions beside the .obj files, and have the debuginfo refer to that fabricated source file? It might look a little bit weird jumping into code where the surrounding scope is not visible (unless that were copied over too?), but it's better than what we have now. Are there any other commonly proposed solutions? Yes, having the mixins expanded without the surrounding code would make it difficult to debug in some cases. Maybe generating the entire source with the expanded mixins is another option? mycode.d obj/mycode_processed.d Maybe this idea could also be expanded to template instantiation?
[Issue 16572] can't take inout delegate
https://issues.dlang.org/show_bug.cgi?id=16572 --- Comment #4 from anonymous4--- Oh, right, we have means to select an overload for delegate, we can reuse it here too. --
[Issue 15831] IFTI voldemort type exploding bloat
https://issues.dlang.org/show_bug.cgi?id=15831 --- Comment #14 from anonymous4--- For stack trace it should be enough (for this example) mymodule.s.Result.foo without parameters even, file and line number should be enough to locate it. --
Re: Challenge
On Monday, 3 October 2016 at 13:19:19 UTC, Manu wrote: Fill in the blank... I'm having a really hard time with this. I've made it work with a mountain of code, and I want to see what others come up with... If you succeed, put it in std.traits! Recommend, use latest DMD nightly. I find differences with latest nightly vs release. See also: http://stackoverflow.com/questions/39430684/check-if-class-member-is-static
Re: Why using wrappers for D?
On Monday, 3 October 2016 at 12:08:54 UTC, Chalix wrote: Hi All! The documentation of D (https://dlang.org/overview.html#compatibility) says: "Direct Access to C API's Not only does D have data types that correspond to C types, it provides direct access to C functions. There is no need to write wrapper functions, parameter swizzlers, nor code to copy aggregate members one by one." D was inspired by Java, so wrappers meant here are probably JNI wrappers https://en.wikipedia.org/wiki/Java_Native_Interface
Re: Challenge
On 3 October 2016 at 23:48, Manuwrote: > On 3 October 2016 at 23:41, Manu wrote: >> I'm finding this rather annoying: >> >> struct S >> { >> static @property int p() { return 10; } >> } >> >> pragma(msg, typeof()); // prints: int function() @property >> pragma(msg, is(typeof() == function)); // prints: false >> >> It looks like a function... but I can't identify it as a function! > > I guess that should read: is(typeof() == R function(A), R, A...)) ?? Here's a leg-up: template isStaticMember(T, string member) { mixin("alias M = T." ~ member ~ ";"); static if(__traits(compiles, )) { static if(!is(typeof(M) == function)) { static if(is(typeof() == R function(A), R, A...)) { import std.traits : functionAttributes, FunctionAttribute; enum isStaticMember = (functionAttributes!M & FunctionAttribute.property) && /* distinguish static/non-static @property somehow */ */; } else enum isStaticMember = true; } else { enum isStaticMember = __traits(isStaticFunction, M); } } else enum isStaticMember = false; }
Re: Challenge
On Monday, 3 October 2016 at 13:19:19 UTC, Manu wrote: Fill in the blank... I'm having a really hard time with this. I've made it work with a mountain of code, and I want to see what others come up with... template isStaticMember(T, string member) { mixin(`alias mem = T.` ~ member ~ `;`); import std.traits : FunctionTypeOf; static if (is(FunctionTypeOf!mem == function) && is(FunctionTypeOf!(typeof()) == function)) enum bool isStaticMember = __traits(isStaticFunction, mem); else enum bool isStaticMember = is(typeof()); } Basically, using FunctionTypeOf catches @property functions (which just typeof wouldn't), but it also catches member variables with function types, so we need the second FunctionTypeOf to see if it's still a function when you take its address (true for member functions, including @property functions, not true for member variables with function types). Everything else is just "can you take the address of this".
Re: Challenge
On Monday, 3 October 2016 at 13:19:19 UTC, Manu wrote: Fill in the blank... I'm having a really hard time with this. I've made it work with a mountain of code, and I want to see what others come up with... [...] Dere's a typo static assert( isStaticMember!(S, "iosm"), "!"); Should be iosf Easy: template isStaticMember(T, string member) { static if(__traits(compiles, &__traits(getMember, T, member))) { static if(is(FunctionTypeOf!(__traits(getMember, T, member)) == function)) { enum isStaticMember = isFunctionPointer!(__traits(getMember, T, member)) || isDelegate!(__traits(getMember, T, member)) || __traits(isStaticFunction, __traits(getMember, T, member)); } else { enum isStaticMember = true;//!is(typeof(__traits(getMember, T, member).offsetof)); } } else { enum isStaticMember = false; } }
Re: Challenge
On Monday, 3 October 2016 at 13:41:13 UTC, Manu wrote: I'm finding this rather annoying: struct S { static @property int p() { return 10; } } pragma(msg, typeof()); // prints: int function() @property pragma(msg, is(typeof() == function)); // prints: false It looks like a function... but I can't identify it as a function! https://dlang.org/phobos/std_traits.html#isSomeFunction ?
Re: Challenge
On 3 October 2016 at 23:50, John Colvin via Digitalmars-dwrote: > On Monday, 3 October 2016 at 13:41:13 UTC, Manu wrote: >> >> I'm finding this rather annoying: >> >> struct S >> { >> static @property int p() { return 10; } >> } >> >> pragma(msg, typeof()); // prints: int function() @property >> pragma(msg, is(typeof() == function)); // prints: false >> >> It looks like a function... but I can't identify it as a function! > > > The problem is that function pointers in "is" expressions don't match > "function" or "delegate". > > static assert (is(void delegate() == delegate)); //passes > static assert (is(void function() == function)); //fails > static assert (is(void function() == delegate)); //fails > > Bug report? Nar, I just forgot about this well-known edge. 'function' means something different in is(); it means a proper-function, *not* a function pointer. if(X == R function(A), R, A...) will test for function pointers. It's still hard though, @property's are hard to detect, and I am really struggling to distinguish between static and non-static properties without testing for assignments, which is terrible.
Re: Challenge
On Monday, 3 October 2016 at 13:50:26 UTC, John Colvin wrote: The problem is that function pointers in "is" expressions don't match "function" or "delegate". static assert (is(void delegate() == delegate)); //passes static assert (is(void function() == function)); //fails static assert (is(void function() == delegate)); //fails Bug report? Note that there is at least some code that relies on current behavior to distinguish delegate/function fields from method declarations in aggregates.
Re: Challenge
On Monday, 3 October 2016 at 13:41:13 UTC, Manu wrote: I'm finding this rather annoying: struct S { static @property int p() { return 10; } } pragma(msg, typeof()); // prints: int function() @property pragma(msg, is(typeof() == function)); // prints: false It looks like a function... but I can't identify it as a function! It works if both: a) you remove @property b) you don't convert it to function pointer struct S { static int p() { return 10; } } pragma(msg, is(typeof(S.p) == function); // true Sadly `is(X == function)` is very obscure and confusing because it doesn't do what one may expect it to do. In current form it can only be used if something is a function declaration, everything else is `false`. It is not even possible to manually express a type which will pass `is(T == function)`, you can only get `true` by applying `typeof` to existing function declaration. And @property screws it because the only current effect of property is exactly changing result of `typeof(propertyFoo)` from function type to result type.
Re: Getting consistent behavour for class properties
I suppose that's https://issues.dlang.org/show_bug.cgi?id=8006
Re: Challenge
On 3 October 2016 at 23:41, Manuwrote: > I'm finding this rather annoying: > > struct S > { > static @property int p() { return 10; } > } > > pragma(msg, typeof()); // prints: int function() @property > pragma(msg, is(typeof() == function)); // prints: false > > It looks like a function... but I can't identify it as a function! I guess that should read: is(typeof() == R function(A), R, A...)) ??
Re: Why using wrappers for D?
On Monday, 3 October 2016 at 12:47:48 UTC, Chalix wrote: Also, I used the Qt library a lot with C++. But although it is a library, I have access to all the classes, like " QWidget w = new QWidget();". There is no factory method used. (This confuses me now a bit...) Qt bindings is a major undertaking, it was tried a couple of times. As an alternative you can try Calypso https://github.com/Syniurge/Calypso which has a C++ language plugin so can read headers directly.
Re: Challenge
On Monday, 3 October 2016 at 13:41:13 UTC, Manu wrote: I'm finding this rather annoying: struct S { static @property int p() { return 10; } } pragma(msg, typeof()); // prints: int function() @property pragma(msg, is(typeof() == function)); // prints: false It looks like a function... but I can't identify it as a function! The problem is that function pointers in "is" expressions don't match "function" or "delegate". static assert (is(void delegate() == delegate)); //passes static assert (is(void function() == function)); //fails static assert (is(void function() == delegate)); //fails Bug report?
Re: Why using wrappers for D?
On Monday, 3 October 2016 at 12:08:54 UTC, Chalix wrote: Furthermore, if there is an not very popular C library, where no wrapper function exists, would it possible to include it into a D project? Probably I have to transform all the .h to .d files, so i can "import" them instead of "include" them. But then, could I link against the C-library? Yes, but here you're talking about a binding, not a wrapper. I did not understand the concept of interaction between C and D, and I am a bit confused about wrapper functions and bindings for D now... Would be great if someone could make it a bit more clear to me :) A binding is just the C function declared in D: // foo.h extern void my_func(const char *str); // foo.d extern(C) void my_func(const(char)* str) @nogc nothrow; Now with the declaration in D, you can link directly to the C library. But you also need foo.d to be linked into your program, either by compiling it alongside your own source files or linking it as a library (as you do with gtkd-3.lib). A wrapper takes a C interface and makes it more D like. // wrapfoo.d import foo; // import the foo module from above void myFunc(string s) { import std.string : toStringz; my_func(s.toStringz()); }
Re: Challenge
On Monday, 3 October 2016 at 13:19:19 UTC, Manu wrote: Fill in the blank... I'm having a really hard time with this. I've made it work with a mountain of code, and I want to see what others come up with... If you succeed, put it in std.traits! Pretty easy: template isStaticMember(T, string member) { enum bool isStaticMember = !(member=="X" || member=="Y" || member=="Y.i" || member=="S" || member=="C" || member=="g" || member=="fpm" || member=="m" || member=="m2" || member=="iom" || member=="p"); } Ok, I'm joking.
Re: Why using wrappers for D?
On Monday, 3 October 2016 at 13:12:55 UTC, Chalix wrote: But I don't get, why I have a gtkd-3 lib. Why can't I just link against the gtk-3 lib then? I have now the headers to use the nice D stuff, but the linking should be done against the C-compiled library. If you don't use D-specific stuff like autogenerated comparison operators and big struct initializers, you would be able to link with C library alone.
[Issue 15831] IFTI voldemort type exploding bloat
https://issues.dlang.org/show_bug.cgi?id=15831 Martin Nowakchanged: What|Removed |Added CC||c...@dawg.eu --- Comment #13 from Martin Nowak --- It's an important issue and should be addressed. Let's work on that for 2.073 which is scheduled for the end of 2016. Because this will impact many tools in D's ecosystem, we need to proper plan how to mitigate the impact. A few points. - Need to talk to Iain to update gdb's D demangler. This will take ages to upstream and end up in distributions. Maybe we can should the backref mangling to only very long names in the beginning? Those are unreadable already and not showing them would rather fix a few GUIs. - Should we also try to address other mangling issues? Some things like the ambiguity are annoying but not that problematic. Also mixing in other changes will only increase the impact and make it harder to release. FWIW this is also not a "new" mangling but an abbreviation of the existing one. - We need to fix all our toolings and libraries. There are some functions in druntime that build mangled names (e.g. for loading shared library symbols). At best we can just implement the backref scheme in core.demangle.mangle and reuse the in phobos. We also ship the ddemangle tool and there are other debuggers (at least the maintained ones need updates). - OT: I'd like to see a similar abbreviation scheme for core.demangle.demangle, b/c the full template names in backtraces aren't readable either. Would be nicer to have something along the line of `func!(Symbol!(Foo, @2))`. --
[Issue 16572] can't take inout delegate
https://issues.dlang.org/show_bug.cgi?id=16572 Steven Schveighofferchanged: What|Removed |Added CC||schvei...@yahoo.com --- Comment #3 from Steven Schveighoffer --- (In reply to anonymous4 from comment #2) > A small interaction between contravariance and inout here: > inout(A) f(inout B b) inout; > If you resolve the type as A delegate(B) you can't pass const(B) as argument. You wouldn't be able to take a valid delegate of this. Or at least an operational one. The delegate type would have to be something like: inout(A) delegate(inout B) inout=const We don't have a way to express this. As it stands, I think the delegate to this would have to be: const(A) delegate(const(B) b) const --
Re: Challenge
I'm finding this rather annoying: struct S { static @property int p() { return 10; } } pragma(msg, typeof()); // prints: int function() @property pragma(msg, is(typeof() == function)); // prints: false It looks like a function... but I can't identify it as a function!
Re: Why using wrappers for D?
On 04/10/2016 1:56 AM, Chalix wrote: On Monday, 3 October 2016 at 12:15:10 UTC, rikki cattermole wrote: To use any kind of function you must declare it, plain and simple. Any c or c++ function/class is the very much same way. Now C++ types such as classes are highly limited in D since it doesn't ugh cross over all that well (it does some weird things). I don't know if we understand each other. You have to declare each function in the language you are programming, that is clear to me. So if you write in D, you need "D-Headers" (which are not called headers in D, i know). What do you mean with "Now C++ types such as classes are highly limited in D"? Basically some features do not match up nicely like operators and constructors. They also do not share semantics e.g. value versus reference. --- This email has been checked for viruses by Avast antivirus software. https://www.avast.com/antivirus
Re: PowerNex - The Userspace update! (also first birthday)
On Sunday, 2 October 2016 at 22:58:31 UTC, WebFreak001 wrote: On Sunday, 2 October 2016 at 22:46:17 UTC, Wild wrote: [...] Awesome! Also here are some screenshots of the new release: https://i.webfreak.org/fLxJY8 https://i.webfreak.org/fLxrPH Kudos to you. I need to try this. Mh, do we have Linus 2.0 up there?
Challenge
Fill in the blank... I'm having a really hard time with this. I've made it work with a mountain of code, and I want to see what others come up with... If you succeed, put it in std.traits! Recommend, use latest DMD nightly. I find differences with latest nightly vs release. --- template isStaticMember(T, string member) { enum bool isStaticMember = [code goes here]; } struct S { enum X = 10; enum Y { i = 10 } struct S {} class C {} static int x = 0; __gshared int y = 0; static void f() {} static void f2() pure nothrow @nogc @safe {} shared void g() {} static void function() fp; __gshared void function() gfp; void function() fpm; void m() {} final void m2() const pure nothrow @nogc @safe {} inout(int) iom() inout { return 10; } static inout(int) iosf(inout int x) { return x; } @property int p() { return 10; } static @property int sp() { return 10; } } class C { enum X = 10; enum Y { i = 10 } struct S {} class C {} static int x = 0; __gshared int y = 0; static void f() {} static void f2() pure nothrow @nogc @safe {} shared void g() {} static void function() fp; __gshared void function() gfp; void function() fpm; void m() {} final void m2() const pure nothrow @nogc @safe {} inout(int) iom() inout { return 10; } static inout(int) iosf(inout int x) { return x; } @property int p() { return 10; } static @property int sp() { return 10; } } static assert(!isStaticMember!(S, "X"), "!"); static assert(!isStaticMember!(S, "Y"), "!"); static assert(!isStaticMember!(S, "Y.i"), "!"); static assert(!isStaticMember!(S, "S"), "!"); static assert(!isStaticMember!(S, "C"), "!"); static assert( isStaticMember!(S, "x"), "!"); static assert( isStaticMember!(S, "y"), "!"); static assert( isStaticMember!(S, "f"), "!"); static assert( isStaticMember!(S, "f2"), "!"); static assert(!isStaticMember!(S, "g"), "!"); static assert( isStaticMember!(S, "fp"), "!"); static assert( isStaticMember!(S, "gfp"), "!"); static assert(!isStaticMember!(S, "fpm"), "!"); static assert(!isStaticMember!(S, "m"), "!"); static assert(!isStaticMember!(S, "m2"), "!"); static assert(!isStaticMember!(S, "iom"), "!"); static assert( isStaticMember!(S, "iosm"), "!"); static assert(!isStaticMember!(S, "p"), "!"); static assert( isStaticMember!(S, "sp"), "!"); static assert(!isStaticMember!(C, "X"), "!"); static assert(!isStaticMember!(C, "Y"), "!"); static assert(!isStaticMember!(C, "Y.i"), "!"); static assert(!isStaticMember!(C, "S"), "!"); static assert(!isStaticMember!(C, "C"), "!"); static assert( isStaticMember!(C, "x"), "!"); static assert( isStaticMember!(C, "y"), "!"); static assert( isStaticMember!(C, "f"), "!"); static assert( isStaticMember!(C, "f2"), "!"); static assert(!isStaticMember!(C, "g"), "!"); static assert( isStaticMember!(C, "fp"), "!"); static assert( isStaticMember!(C, "gfp"), "!"); static assert(!isStaticMember!(C, "fpm"), "!"); static assert(!isStaticMember!(C, "m"), "!"); static assert(!isStaticMember!(C, "m2"), "!"); static assert(!isStaticMember!(C, "iom"), "!"); static assert( isStaticMember!(C, "iosm"), "!"); static assert(!isStaticMember!(C, "p"), "!"); static assert( isStaticMember!(C, "sp"), "!");
[Issue 16536] DMD master does not build on OS X 10.11.6/Xcode 7.3.1
https://issues.dlang.org/show_bug.cgi?id=16536 Steven Schveighofferchanged: What|Removed |Added CC||schvei...@yahoo.com --
Re: Why using wrappers for D?
On Monday, 3 October 2016 at 12:54:03 UTC, Adam D. Ruppe wrote: It is possible, you just need to match compilers with the library in C++, whereas C libraries don't need such an exact match. With your Qt library, you get a build of it that is compatible with the compiler you use to build your application (either compiling it yourself or getting it from an OS package repo where they did it for you for your OS version) Ah, so the Qt libraries are C++ libraries. And they have to be compiled with the same compiler (or at least with a compiler with the same specification) I use for my application? I didn't know that, but it makes sense to me. But if there would be 2 C++ compilers on my linux system which create 2 different API's, I would need the Qt library twice on my system? One for an application compiled with the one compiler, and the other library for an application compiled with the other compiler. Since I have only 1 Qt library on my system, all linux compilers must create compatible API's, right? Wrap the C functions inside D classes. So they write D code that calls the C functions, then you use their D code. Ok, this is the same what cym13 wanted to say, right? So you can use the advantages of D? But I don't get, why I have a gtkd-3 lib. Why can't I just link against the gtk-3 lib then? I have now the headers to use the nice D stuff, but the linking should be done against the C-compiled library.
Re: Why using wrappers for D?
On Monday, 3 October 2016 at 12:15:10 UTC, rikki cattermole wrote: To use any kind of function you must declare it, plain and simple. Any c or c++ function/class is the very much same way. Now C++ types such as classes are highly limited in D since it doesn't ugh cross over all that well (it does some weird things). I don't know if we understand each other. You have to declare each function in the language you are programming, that is clear to me. So if you write in D, you need "D-Headers" (which are not called headers in D, i know). What do you mean with "Now C++ types such as classes are highly limited in D"? Why don't they "just" support them you ask? Yeah, that a D compiler can't read .h files is obvious to me :)
Re: Why using wrappers for D?
On Monday, 3 October 2016 at 12:47:48 UTC, Chalix wrote: I read a bit about creating libraries in C++, and I found out, this is not possible, because there is no definition of the API. It is possible, you just need to match compilers with the library in C++, whereas C libraries don't need such an exact match. With your Qt library, you get a build of it that is compatible with the compiler you use to build your application (either compiling it yourself or getting it from an OS package repo where they did it for you for your OS version) you mean by "turn C functions into classes"? Wrap the C functions inside D classes. So they write D code that calls the C functions, then you use their D code.
Re: debugging mixins
On 10/03/2016 07:42 AM, Stefan Koch wrote: On Sunday, 2 October 2016 at 12:27:23 UTC, Andrei Alexandrescu wrote: Yes, Stefan it would be terrific if you could keep an eye on it while working on the engine. A file with properly handed dependencies could serve as instantiation cache and save a ton of re-instantiation waste. Thanks! -- Andrei instantiation ? Do you mean mixin-expansion ? or are you talking about mixins created in templates ? Mixin expansions. Although Caching mixin expansions hits on the same problem as chaching template-instances, it is more difficult since a mixin can appear anywhere. and one has to worry about a much wider scope. I'll see what I can come up with, for now the debugging is priority. @Ethan can you share code illustrating your usecase. (My head is inside compiler internals and building test-code is a rather unpleasant context switch) Understood, then keep this on the back burner and forge ahead with the warm cache. Thanks! -- Andrei
Re: ndslice: feature deprecation voting / discussion
On 10/02/2016 11:01 PM, Manu via Digitalmars-d wrote: Ah, the 'sufficiently high-quality compiler' unicorn. It's been a legend in C++ for at least 20 years that I've been looking... For this particular matter it's somewhat of a solved problem in C++. Is it your perception as well that template bloat in C++ seems to have discussed a lot more in the past than in recent times? -- Andrei
Re: Why using wrappers for D?
On Monday, 3 October 2016 at 12:12:44 UTC, Adam D. Ruppe wrote: A lot of people like the wrappers as being prettier to use since you can turn C functions into classes and such. gtkd is an example of that. Thanks for your fast answers :) Hm, I thing I am missing some fundamentals... I read a bit about creating libraries in C++, and I found out, this is not possible, because there is no definition of the API. So you need some C "factory methods" to load C++ classes. So is it possible now by D to load a class directly, or what do you mean by "turn C functions into classes"? Also, I used the Qt library a lot with C++. But although it is a library, I have access to all the classes, like " QWidget w = new QWidget();". There is no factory method used. (This confuses me now a bit...) If its too much to explain within some sentences, maybe you know something where I could read more about it? I did not find anything myself. But I really want to understand what's going on. Of course, it is simple, just bring over the necessary struct, constant, and function prototypes and it just works. I have to try it :D
Re: Why using wrappers for D?
On Monday, 3 October 2016 at 12:08:54 UTC, Chalix wrote: Hi All! The documentation of D (https://dlang.org/overview.html#compatibility) says: "Direct Access to C API's Not only does D have data types that correspond to C types, it provides direct access to C functions. There is no need to write wrapper functions, parameter swizzlers, nor code to copy aggregate members one by one." So, if there is no need for wrapper functions, why are there a lot of them? For example, GTK+ is a C library, with C-include files. Now there exists the GtkD (http://gtkd.org/) library, which describes itself as a wrapper of GTK+. GtkD contains the .d files (which I need for import, of course) and a seperate library (libgtkd-3.so). If D has direct Access to C API's, why do we need this the gtkd-3 lib, and not just use the gtk-3 lib? Furthermore, if there is an not very popular C library, where no wrapper function exists, would it possible to include it into a D project? Probably I have to transform all the .h to .d files, so i can "import" them instead of "include" them. But then, could I link against the C-library? I did not understand the concept of interaction between C and D, and I am a bit confused about wrapper functions and bindings for D now... Would be great if someone could make it a bit more clear to me :) D provides ways to do things that C or C++ don't provide (otherwise we wouldn't be using it). C/C++ functions and structures are designed to fit well in C/C++, not in D. To make them easy to use and avoid code of mixed style we build up a facade : the wrapper. That's all.
Re: Why using wrappers for D?
On 04/10/2016 1:08 AM, Chalix wrote: Hi All! The documentation of D (https://dlang.org/overview.html#compatibility) says: "Direct Access to C API's Not only does D have data types that correspond to C types, it provides direct access to C functions. There is no need to write wrapper functions, parameter swizzlers, nor code to copy aggregate members one by one." So, if there is no need for wrapper functions, why are there a lot of them? For example, GTK+ is a C library, with C-include files. Now there exists the GtkD (http://gtkd.org/) library, which describes itself as a wrapper of GTK+. GtkD contains the .d files (which I need for import, of course) and a seperate library (libgtkd-3.so). If D has direct Access to C API's, why do we need this the gtkd-3 lib, and not just use the gtk-3 lib? Furthermore, if there is an not very popular C library, where no wrapper function exists, would it possible to include it into a D project? Probably I have to transform all the .h to .d files, so i can "import" them instead of "include" them. But then, could I link against the C-library? I did not understand the concept of interaction between C and D, and I am a bit confused about wrapper functions and bindings for D now... Would be great if someone could make it a bit more clear to me :) Ok lets get a few things straight. To use any kind of function you must declare it, plain and simple. Any c or c++ function/class is the very much same way. Now C++ types such as classes are highly limited in D since it doesn't ugh cross over all that well (it does some weird things). These kinds of declarations are called bindings. We must have them since the D compilers don't support reading header files. Why don't they "just" support them you ask? Well simple, that's a whole new frontend that we must support... Walter is quite opposed to the idea and rightly so. So the real interesting question, why do we have wrappers around e.g. c++ libs? Simple, the original C++ code was designed for C++ and we can simply do those interfaces better. --- This email has been checked for viruses by Avast antivirus software. https://www.avast.com/antivirus
Re: Why using wrappers for D?
On Monday, 3 October 2016 at 12:08:54 UTC, Chalix wrote: So, if there is no need for wrapper functions, why are there a lot of them? A lot of people like the wrappers as being prettier to use since you can turn C functions into classes and such. gtkd is an example of that. Furthermore, if there is an not very popular C library, where no wrapper function exists, would it possible to include it into a D project? Of course, it is simple, just bring over the necessary struct, constant, and function prototypes and it just works.
Why using wrappers for D?
Hi All! The documentation of D (https://dlang.org/overview.html#compatibility) says: "Direct Access to C API's Not only does D have data types that correspond to C types, it provides direct access to C functions. There is no need to write wrapper functions, parameter swizzlers, nor code to copy aggregate members one by one." So, if there is no need for wrapper functions, why are there a lot of them? For example, GTK+ is a C library, with C-include files. Now there exists the GtkD (http://gtkd.org/) library, which describes itself as a wrapper of GTK+. GtkD contains the .d files (which I need for import, of course) and a seperate library (libgtkd-3.so). If D has direct Access to C API's, why do we need this the gtkd-3 lib, and not just use the gtk-3 lib? Furthermore, if there is an not very popular C library, where no wrapper function exists, would it possible to include it into a D project? Probably I have to transform all the .h to .d files, so i can "import" them instead of "include" them. But then, could I link against the C-library? I did not understand the concept of interaction between C and D, and I am a bit confused about wrapper functions and bindings for D now... Would be great if someone could make it a bit more clear to me :)
Re: debugging mixins
On Monday, 3 October 2016 at 11:42:25 UTC, Stefan Koch wrote: @Ethan can you share code illustrating your usecase. (My head is inside compiler internals and building test-code is a rather unpleasant context switch) You should be able to do everything with the example code you have. My intention there is to compile everything in the acorelibrary module in to a library and statically link against that. As such, you'll want to do the .di generation on those files. The behaviour right now is that all the Binderoo mixins will not expand.
Re: Getting GtkD working with OpenGL
On Sunday, 18 September 2016 at 21:41:45 UTC, Mike Wey wrote: The demo still uses the old GtkGLExt binding, which usually isn't available in de distributions repositories. The newer GLArea is easier to use since it's part of GTK. As for the linker errors, you'll need to link with the OpenGL libraries: "-L-lGL -L-lGLU" Hey, thanks for your fast answer! I had a lot of other work to do, so I could only continue working on this project now. Yeah, that solved my problem :) Now it links. Although if I execute the program, it complains about the missing GtkGLExt library, like expected... Library load failed: libgdkglext-3.0.so.0 So I wanted to install this library from here: https://projects.gnome.org/gtkglext/download.html but the ./configure script tells me, No package 'pangox' found (pangox >= 1.0.0) I looked at the folder /usr/lib/x86_64-linux-gnu/ and there is a file called "libpangox-1.0.so.0.0.0". So I don't know, why this is not working... Anyway, I want to follow Mikes advice and use GLArea instead, so if there is not a quick fix available, lets skip the problems with the GtkGLExt library... But, sadly enough, I did not get GLArea working, too. The documentation https://developer.gnome.org/gtk3/stable/GtkGLArea.html says, I have to connect my render function to the widget like this: g_signal_connect (gl_area, "render", G_CALLBACK (render), NULL); But, my compiler can't find the g_signal_connect method (and the GL Methods...): main.d(22): Error: undefined identifier 'g_signal_connect' main.d(39): Error: undefined identifier 'glClearColor' main.d(40): Error: undefined identifier 'glClear' There might some include files (or import files, as you say in D) missing, but I could not figure out, where to find them for D... Could you tell me, where this g_signal_connect method can be found? And what I have to include for the GL functionality? Simply "import gtk.GLArea;" does not do the trick... Btw, is g_signal_connect a GTK method? I intend to use my program platform independent, so if this is dependent on gnome, it would not be good. Or is there any other way to get the GLArea working? I am used to the Qt Libraries, where you create a QGLWidget and simply override the init and render functions. Thanks for reading this far, would be great if we could solve this problem :D
Re: Beta 2.072.0-b1
On Sunday, 2 October 2016 at 15:36:58 UTC, Jacob Carlborg wrote: I think it could be more clear why it's deprecated and what to do instead: Language construct A is deprecated. A is bad because: ... Do this instead: ... Yes agreed, will try to establish a more formal format.
Re: bug, or is this also intended?
On 10/03/2016 01:40 PM, deed wrote: Unexpected auto-concatenation of string elements: string[] arr = ["a", "b" "c"];// ["a", "bc"], length==2 int[] arr2 = [[1], [2] [3]];// Error: array index 3 is out of bounds [2][0 .. 1] // Error: array index 3 is out of bounds [0..1] dmd 2.071.2-b2 Intended but on its way out. 2.072.0-b1 tells you it's deprecated.