Re: Why typeof(template) is void?
On Wednesday, 20 July 2016 at 01:50:37 UTC, Adam D. Ruppe wrote: On Wednesday, 20 July 2016 at 01:14:05 UTC, mogu wrote: Why S's type isn't something like `S: (T) -> S`? Because S isn't a type... think of a template as being like a function that returns a type. int foo(int) { return 0; } There, you wouldn't expect typeof(foo) to be int, no, typeof(foo) is a function that returns an int. The template is the same thing - it isn't a type, it is a template that returns a type. So it's a higher kinded type aka type class in Haskell. But D's reflection cannot get enough information about template's kind. Only a `void` given. It may be inconvenient in distinction between an alias of template and void. The only solution AFAIK is by string of the type property .stringof.
Re: How to search for an enum by values and why enum items aren't unique
On Wednesday, July 20, 2016 04:03:23 stunaep via Digitalmars-d-learn wrote: > How can I search for an enum by its values? For example I have > > >struct TestTraits { > > > > int value1; > > string value2; > > > >} > > > >enum Test : TestTraits { > > > > TEST = TestTraits(1, "test1"), > > TESTING = TestTraits(5, "test5") > > > >} > > and I have the int 5 and need to find TESTING with it. > > In java I would create a SearchableEnum interface, make all > searchable enums implement it and use this method to find them. > > >public static T find(T[] vals, int > >id) { > > > > for (T val : vals) { > > > > if (id == val.getId()) { > > > > return val; > > > > } > > > > } > > return null; > > > >} > > But the way enums work in D doesn't seem to permit this. If you want the list of members in an enum, then use std.traits.EnumMembers and you'll get a compile-time list of them. It can be made into a runtime list by being put into an array literal. For instance, if we take std.datetime.Month, we can look for the enum with the value 10 in it like so. auto found = [EnumMembers!Month].find(10); assert(found = [Month.oct, Month.nov, Month.dec]); So, if you had your TestTraits struct as the type for an enum, you could do something like auto found = [EnumMembers!TestTraits].find!(a => a.value1 == 5)(); if(found.empty) { // there is no TestTraits which matches } else { // found.front is the match } > And why on earth are different enum items with the same values > equal to each other? Say I have an enum called DrawableShape Because they have the same value. The fact that they're enums doesn't change how they're compared. That's determined by what type they are. All you're really getting with an enum is a list of named constants that are grouped together which implicitly convert to their base type but which are not converted to implicitly from their base type. The only stuff that's going to treat an enum member differently from any other value of that type is something that specifically operates on enums - e.g. by taking the enum type explicitly, or because it has is(T == enum) and does something different for enums (quite a few traits do that in std.traits), or because it uses a final switch. Most code is just going to treat them like any other value of the enum's base type. They aren't magically treated as unique in some way just because they're in an enum. - Jonathan M Davis
Re: Dynamic code generation
On 07/20/2016 06:36 AM, Rufus Smith wrote: Does D offer any solutions to generate code dynamically? I don't think so. I would like to order based on optimal strategies. This requires effectively hard coding the execution path. A simple example, if (x == true) foo(); else bar(); can be recoded to be foo() or bar() while x is fixed, in my case x is fixed for long periods and therefor the check is unnecessary. I also know when x changes in all cases. This is just a simple example, of course. I would not want to resort to assembly programming to accomplish this. Just an idea: void main() { setX(true); f(); /* calls foo */ setX(false); f(); /* calls bar */ } void function() f; void setX(bool x) { if (x) f = &impl!true; else f = &impl!false; } void impl(bool x)() { static if (x) foo(); else bar(); } void foo() { import std.stdio; writeln("foo"); } void bar() { import std.stdio; writeln("bar"); } Of course, if this is for optimization purposes, measure first if hard-coded is actually faster than the branch.
Dynamic code generation
Does D offer any solutions to generate code dynamically? I would like to order based on optimal strategies. This requires effectively hard coding the execution path. A simple example, if (x == true) foo(); else bar(); can be recoded to be foo() or bar() while x is fixed, in my case x is fixed for long periods and therefor the check is unnecessary. I also know when x changes in all cases. This is just a simple example, of course. I would not want to resort to assembly programming to accomplish this.
How to search for an enum by values and why enum items aren't unique
How can I search for an enum by its values? For example I have struct TestTraits { int value1; string value2; } enum Test : TestTraits { TEST = TestTraits(1, "test1"), TESTING = TestTraits(5, "test5") } and I have the int 5 and need to find TESTING with it. In java I would create a SearchableEnum interface, make all searchable enums implement it and use this method to find them. public static T find(T[] vals, int id) { for (T val : vals) { if (id == val.getId()) { return val; } } return null; } But the way enums work in D doesn't seem to permit this. And why on earth are different enum items with the same values equal to each other? Say I have an enum called DrawableShape struct DrawableShapeTraits { bool useAlpha; int sideCount; } enum DrawableShape : DrawableShapeTraits { RECTANGLE = DrawableShapeTraits(true, 4), DIAMOND = DrawableShapeTraits(true, 4), } Now say I have some code that does this if(shape == DrawableShape.DIAMOND) ... render a diamond else if(shape == DrawableShape.RECTANGLE) ... render a rectangle Now even if shape is a DrawableShape.RECTANGLE it's going to render a DrawableShape.DIAMOND unless I add a dummy value to differentiate them.
Re: Template arguments produce unidentified identifier
On Wednesday, 20 July 2016 at 01:48:31 UTC, Adam D. Ruppe wrote: Take a read of this: http://stackoverflow.com/a/32621854/1457000 The short of it is don't mixin stringof. Instead, mixin the actual template itself. The functionLinkage might need to be string, but the types should remain literal. So try this: mixin("alias Func = extern("~functionLinkage!Q~") (ReturnType!Q) function (Erase!(Parameters!Q));"); or something like that - don't concatenate strings of those, just make the string itself still say ReturnType!Q etc when you mix in. Then the scope will be correct. Thanks, it did work with some modification: mixin("alias Func = extern("~functionLinkage!Q~") ReturnType!Q function(Erase!(Parameters!Q));"); No parenthesis around ReturnType or strange errors happen.
Re: Why typeof(template) is void?
On Wednesday, 20 July 2016 at 01:14:05 UTC, mogu wrote: Why S's type isn't something like `S: (T) -> S`? Because S isn't a type... think of a template as being like a function that returns a type. int foo(int) { return 0; } There, you wouldn't expect typeof(foo) to be int, no, typeof(foo) is a function that returns an int. The template is the same thing - it isn't a type, it is a template that returns a type.
Re: Template arguments produce unidentified identifier
Take a read of this: http://stackoverflow.com/a/32621854/1457000 The short of it is don't mixin stringof. Instead, mixin the actual template itself. The functionLinkage might need to be string, but the types should remain literal. So try this: mixin("alias Func = extern("~functionLinkage!Q~") (ReturnType!Q) function (Erase!(Parameters!Q));"); or something like that - don't concatenate strings of those, just make the string itself still say ReturnType!Q etc when you mix in. Then the scope will be correct.
Re: Template arguments produce unidentified identifier
If it's not clear, I have to import the proper identifiers but every use of the template would require the user to add their import. Obviously not the way to go.
Template arguments produce unidentified identifier
I have complex template that uses a mixin to solve some problems. The mixin produces the error. I thought template's were added in to the scope of the call? I guess the mixin is inserted before this happens. That isn't good ;/ Here is one place the error happens mixin("alias Func = extern("~functionLinkage!Q~") "~(ReturnType!Q).stringof~" function"~(Erase!(Parameters!Q)).stringof~";"); The mixin is required to get the proper linkage, as no other method has been found to do that. Everything works with built in types. I saw somewhere that vibe.d had some way around this but the links are dead.
Why typeof(template) is void?
``` struct S(T) {} static assert(is (typeof(S) == void)); ``` Why S's type isn't something like `S: (T) -> S`?
Re: Is there a way to "see" source code generated by templates after a compile?
On Sunday, 17 July 2016 at 05:57:52 UTC, WhatMeWorry wrote: I don't suppose there's a way to "see" source code generated by templates after a compile but before execution? Or does the compiler generate it to a lower level on the fly; thus losing the source code? I'm assuming no because if there were a way, I'd of come across it by now :) I've just stumbled across this on dmd documentation. Haven't had time to play with it yet. -allinst generate code for all template instantiations
Re: Allowing "fall through" of attributes
On Tuesday, 19 July 2016 at 17:10:35 UTC, Lodovico Giaretta wrote: On Tuesday, 19 July 2016 at 17:05:55 UTC, Rufus Smith wrote: On Tuesday, 19 July 2016 at 16:59:48 UTC, Lodovico Giaretta wrote: On Tuesday, 19 July 2016 at 16:50:56 UTC, Rufus Smith wrote: On Tuesday, 19 July 2016 at 16:09:38 UTC, Lodovico Giaretta wrote: [...] But this doesn't create a function with all the attributes of the original? Just one that has the same return type and parameters. What if Fun is pure or extern(C) or some other attributes? I'd like to create a function that is exactly the same in all regards as the original. Sorry, I misunderstood your question. With the method I showed you, if the function is @safe, pure, @nogc or nothrow, foo will infer those attributes. But only if the operations you do in foo (apart from calling bar) are themselves @safe, pure, @nogc or nothrow. For other things, like extern(C), I don't think there's a simple solution; but I'm not an expert, so I hope someone else will give you a better answer. What is strange is I cannot even pass an extern(C) function to foo. void foo(R, A...)(R function(A) bar); extern(C) void bar(); foo(&bar) fails. Remove extern and it passes. I have not figured out how to allow for extern(C) functions to be passed. That's because an extern function must be called with a different code. So it cannot be cast to a non-extern(C) function pointer, which is what your foo accepts. If you follow my advice, and make the entire function type a parameter of foo, then foo will at least accept your extern(C) function, but it will not be extern(C) itself. I don't want it to be cast to a non-extern function. What I want to do is create the exact same type of function that is passed to the template except modify the arguments. If I use a general parameter for the function, it accepts extern(C), but I can't construct a function with it. mixin("alias F = extern("~functionLinkage!Q~") "~(ReturnType!Q).stringof~" function"~(Parameters!Q).stringof~";"); gives me a type that looks to be what I want but I can't really use it unless I want to declare the function that does the work inside foo as mixin string. One can't do extern(functionLinkage!Q) void baz() to create baz with the proper linkage ;/ It looks like I might have to go the mixin way ;/ Going to be messy ;/
Re: How to get the "this" ptr of a lambda inside the lambda?
On 7/19/16 1:03 PM, Rufus Smith wrote: On Tuesday, 19 July 2016 at 16:58:12 UTC, Steven Schveighoffer wrote: On 7/19/16 12:52 PM, Rufus Smith wrote: On Tuesday, 19 July 2016 at 15:58:49 UTC, Steven Schveighoffer wrote: [...] Yes, but then this = null. I matters not for my use case. 'this' is not null in either case. There is no 'this'. Please stop saying that: https://en.wikipedia.org/wiki/This_(computer_programming) this is more general than you think. The compiler knows about the context pointer, your delegate has no name for it. And in a lambda that does not need one, there is no context pointer, it's not a pointer that's set to null. I fully understand what you're looking for. In D, 'this' means the object/struct that a method is being called with. If you don't have an object delegate, then you don't have a 'this' reference (and by that I mean a named parameter to the member function called 'this' or any other name). -Steve
Re: Allowing "fall through" of attributes
On Tuesday, 19 July 2016 at 17:05:55 UTC, Rufus Smith wrote: On Tuesday, 19 July 2016 at 16:59:48 UTC, Lodovico Giaretta wrote: On Tuesday, 19 July 2016 at 16:50:56 UTC, Rufus Smith wrote: On Tuesday, 19 July 2016 at 16:09:38 UTC, Lodovico Giaretta wrote: [...] But this doesn't create a function with all the attributes of the original? Just one that has the same return type and parameters. What if Fun is pure or extern(C) or some other attributes? I'd like to create a function that is exactly the same in all regards as the original. Sorry, I misunderstood your question. With the method I showed you, if the function is @safe, pure, @nogc or nothrow, foo will infer those attributes. But only if the operations you do in foo (apart from calling bar) are themselves @safe, pure, @nogc or nothrow. For other things, like extern(C), I don't think there's a simple solution; but I'm not an expert, so I hope someone else will give you a better answer. What is strange is I cannot even pass an extern(C) function to foo. void foo(R, A...)(R function(A) bar); extern(C) void bar(); foo(&bar) fails. Remove extern and it passes. I have not figured out how to allow for extern(C) functions to be passed. That's because an extern function must be called with a different code. So it cannot be cast to a non-extern(C) function pointer, which is what your foo accepts. If you follow my advice, and make the entire function type a parameter of foo, then foo will at least accept your extern(C) function, but it will not be extern(C) itself.
Re: Passing a single tuple or multiple values
On Tuesday, 19 July 2016 at 15:40:20 UTC, Lodovico Giaretta wrote: You can find this out from the error, which says that you can't expand an object of type `(Tuple!(int, int))`. Note the surrounding parenthesis: they tell you that what you have is not a Tuple, but an AliasSeq whose only member is a Tuple. If you do `[0]` on it, you obtain the correct type, i.e. `Tuple!(int, int)`, without the parenthesis. Ah.
Re: Allowing "fall through" of attributes
On Tuesday, 19 July 2016 at 16:59:48 UTC, Lodovico Giaretta wrote: On Tuesday, 19 July 2016 at 16:50:56 UTC, Rufus Smith wrote: On Tuesday, 19 July 2016 at 16:09:38 UTC, Lodovico Giaretta wrote: [...] But this doesn't create a function with all the attributes of the original? Just one that has the same return type and parameters. What if Fun is pure or extern(C) or some other attributes? I'd like to create a function that is exactly the same in all regards as the original. Sorry, I misunderstood your question. With the method I showed you, if the function is @safe, pure, @nogc or nothrow, foo will infer those attributes. But only if the operations you do in foo (apart from calling bar) are themselves @safe, pure, @nogc or nothrow. For other things, like extern(C), I don't think there's a simple solution; but I'm not an expert, so I hope someone else will give you a better answer. What is strange is I cannot even pass an extern(C) function to foo. void foo(R, A...)(R function(A) bar); extern(C) void bar(); foo(&bar) fails. Remove extern and it passes. I have not figured out how to allow for extern(C) functions to be passed.
Re: How to get the "this" ptr of a lambda inside the lambda?
On Tuesday, 19 July 2016 at 16:58:12 UTC, Steven Schveighoffer wrote: On 7/19/16 12:52 PM, Rufus Smith wrote: On Tuesday, 19 July 2016 at 15:58:49 UTC, Steven Schveighoffer wrote: [...] Yes, but then this = null. I matters not for my use case. 'this' is not null in either case. There is no 'this'. Please stop saying that: https://en.wikipedia.org/wiki/This_(computer_programming) this is more general than you think.
Re: Allowing "fall through" of attributes
On Tuesday, 19 July 2016 at 16:50:56 UTC, Rufus Smith wrote: On Tuesday, 19 July 2016 at 16:09:38 UTC, Lodovico Giaretta wrote: On Tuesday, 19 July 2016 at 15:55:02 UTC, Rufus Smith wrote: I have some functions that take other functions. I would like the attributes to be able to "fall" through so I get overload like behavior. I only care that I am passing a function, not if it is shared, extern(C), pure, @nogc, etc. void foo(R, A...)(R function(A) bar) { alias type = typeof(bar); pragma(msg, type); // does magic with bar } foo never uses the attributes of bar explicitly. It uses type to instantiate other functions like bar. I have to create a foo for each attribute combination, which is not worth while. The code seems to break only for extern, the best I can tell, most attributes do pass through. But type does not contain these attributes. You shall do something like this (please note that I didn't check the docs while writing this; you shall definitely have a look at std.traits and consider the following as pseudo-code and not actual D): void foo(Fun)(Fun bar) if (isSomeFunction!Fun) // your constraint that bar is a function { // how to get your R and A types, if you need them: alias R = ReturnType!bar; alias A = Parameters!bar; alias type = Fun; pragma(msg, type); // do some magic } But this doesn't create a function with all the attributes of the original? Just one that has the same return type and parameters. What if Fun is pure or extern(C) or some other attributes? I'd like to create a function that is exactly the same in all regards as the original. Sorry, I misunderstood your question. With the method I showed you, if the function is @safe, pure, @nogc or nothrow, foo will infer those attributes. But only if the operations you do in foo (apart from calling bar) are themselves @safe, pure, @nogc or nothrow. For other things, like extern(C), I don't think there's a simple solution; but I'm not an expert, so I hope someone else will give you a better answer.
Re: How to get the "this" ptr of a lambda inside the lambda?
On 7/19/16 12:52 PM, Rufus Smith wrote: On Tuesday, 19 July 2016 at 15:58:49 UTC, Steven Schveighoffer wrote: On 7/19/16 11:25 AM, Rufus Smith wrote: [...] I think what Mike may be alluding to is that there is no name for the stack frame pointer you can use. There is no 'this' pointer that you can get at (even though it can be passed). Also note that lambdas are not necessarily delegates, they could be straight function pointers if they don't need a context: void main() { int a; pragma(msg, typeof((int b) => b * 2)); // int function(int b) pure nothrow @nogc @safe pragma(msg, typeof(() => a * 2)); // int delegate() pure nothrow @nogc @safe } Yes, but then this = null. I matters not for my use case. 'this' is not null in either case. There is no 'this'. There is probably a way to get the stack pointer. Take a look at the code in std.functional.toDelegate. http://dlang.org/phobos/std_functional.html#toDelegate -Steve
Re: How to get the "this" ptr of a lambda inside the lambda?
On Tuesday, 19 July 2016 at 15:58:49 UTC, Steven Schveighoffer wrote: On 7/19/16 11:25 AM, Rufus Smith wrote: [...] I think what Mike may be alluding to is that there is no name for the stack frame pointer you can use. There is no 'this' pointer that you can get at (even though it can be passed). Also note that lambdas are not necessarily delegates, they could be straight function pointers if they don't need a context: void main() { int a; pragma(msg, typeof((int b) => b * 2)); // int function(int b) pure nothrow @nogc @safe pragma(msg, typeof(() => a * 2)); // int delegate() pure nothrow @nogc @safe } Yes, but then this = null. I matters not for my use case. A question to ask is, why do you need it? Magic my friend! Magic!!!
Re: Allowing "fall through" of attributes
On Tuesday, 19 July 2016 at 16:09:38 UTC, Lodovico Giaretta wrote: On Tuesday, 19 July 2016 at 15:55:02 UTC, Rufus Smith wrote: I have some functions that take other functions. I would like the attributes to be able to "fall" through so I get overload like behavior. I only care that I am passing a function, not if it is shared, extern(C), pure, @nogc, etc. void foo(R, A...)(R function(A) bar) { alias type = typeof(bar); pragma(msg, type); // does magic with bar } foo never uses the attributes of bar explicitly. It uses type to instantiate other functions like bar. I have to create a foo for each attribute combination, which is not worth while. The code seems to break only for extern, the best I can tell, most attributes do pass through. But type does not contain these attributes. You shall do something like this (please note that I didn't check the docs while writing this; you shall definitely have a look at std.traits and consider the following as pseudo-code and not actual D): void foo(Fun)(Fun bar) if (isSomeFunction!Fun) // your constraint that bar is a function { // how to get your R and A types, if you need them: alias R = ReturnType!bar; alias A = Parameters!bar; alias type = Fun; pragma(msg, type); // do some magic } But this doesn't create a function with all the attributes of the original? Just one that has the same return type and parameters. What if Fun is pure or extern(C) or some other attributes? I'd like to create a function that is exactly the same in all regards as the original.
Re: Allowing "fall through" of attributes
On Tuesday, 19 July 2016 at 15:55:02 UTC, Rufus Smith wrote: I have some functions that take other functions. I would like the attributes to be able to "fall" through so I get overload like behavior. I only care that I am passing a function, not if it is shared, extern(C), pure, @nogc, etc. void foo(R, A...)(R function(A) bar) { alias type = typeof(bar); pragma(msg, type); // does magic with bar } foo never uses the attributes of bar explicitly. It uses type to instantiate other functions like bar. I have to create a foo for each attribute combination, which is not worth while. The code seems to break only for extern, the best I can tell, most attributes do pass through. But type does not contain these attributes. You shall do something like this (please note that I didn't check the docs while writing this; you shall definitely have a look at std.traits and consider the following as pseudo-code and not actual D): void foo(Fun)(Fun bar) if (isSomeFunction!Fun) // your constraint that bar is a function { // how to get your R and A types, if you need them: alias R = ReturnType!bar; alias A = Parameters!bar; alias type = Fun; pragma(msg, type); // do some magic }
Re: strange bug: (not) calling module ctors; help with "master" needed
On Tuesday, 19 July 2016 at 15:18:20 UTC, Steven Schveighoffer wrote: Please add what you can to the report. ok, i found why it doesn't work with static libs. not sure what to do next, though... added the info to bugzilla.
Re: How to get the "this" ptr of a lambda inside the lambda?
On 7/19/16 11:25 AM, Rufus Smith wrote: On Tuesday, 19 July 2016 at 06:46:44 UTC, Mike Parker wrote: On Tuesday, 19 July 2016 at 06:32:32 UTC, Rufus Smith wrote: Error: 'this' is only defined in non-static member functions, not __lambda2 Lambda's are delegates and delegates have a "this" type of pointer. I would like to get at it inside the lambda to check for some things. I'm doing some funky stuff. I'm not concerned about the scope or what this actually pointers to or anything like that, just need it's value for debugging. No, delegates do not have a "this" type of pointer. "this" is an implicit function parameter in a class or struct member function. Delegates have no such thing. The only generic way I know of to get at a delegate's function pointer inside the implementation is to explicitly add the pointer type to the parameter list as part of the declaration and pass it as an argument when you call the delegate. Delegates do have a this, they have a context pointer that is implicitly passed and used to access the outside context. It is no different than methods. Just because the explicit implementation details are different does not change the underlying meaning. I think what Mike may be alluding to is that there is no name for the stack frame pointer you can use. There is no 'this' pointer that you can get at (even though it can be passed). Also note that lambdas are not necessarily delegates, they could be straight function pointers if they don't need a context: void main() { int a; pragma(msg, typeof((int b) => b * 2)); // int function(int b) pure nothrow @nogc @safe pragma(msg, typeof(() => a * 2)); // int delegate() pure nothrow @nogc @safe } A question to ask is, why do you need it? -Steve
Allowing "fall through" of attributes
I have some functions that take other functions. I would like the attributes to be able to "fall" through so I get overload like behavior. I only care that I am passing a function, not if it is shared, extern(C), pure, @nogc, etc. void foo(R, A...)(R function(A) bar) { alias type = typeof(bar); pragma(msg, type); // does magic with bar } foo never uses the attributes of bar explicitly. It uses type to instantiate other functions like bar. I have to create a foo for each attribute combination, which is not worth while. The code seems to break only for extern, the best I can tell, most attributes do pass through. But type does not contain these attributes.
Re: Passing a single tuple or multiple values
On Tuesday, 19 July 2016 at 15:36:42 UTC, Lodovico Giaretta wrote: As you have to do `isTuple!(T[0])`, you also have to do `x[0].expand`. That's because T... works "as if" it was an array of types, and x, being of type T, it works "as if" it was an array of values. So you have to use an index in both cases. You can find this out from the error, which says that you can't expand an object of type `(Tuple!(int, int))`. Note the surrounding parenthesis: they tell you that what you have is not a Tuple, but an AliasSeq whose only member is a Tuple. If you do `[0]` on it, you obtain the correct type, i.e. `Tuple!(int, int)`, without the parenthesis.
Re: Passing a single tuple or multiple values
On Tuesday, 19 July 2016 at 13:33:41 UTC, jmh530 wrote: On Tuesday, 19 July 2016 at 07:23:52 UTC, John wrote: auto bar(T...)(T x) { static if (T.length == 1 && isTuple!(T[0])) return foo(x.expand); else return foo(x); } Hmm, this actually doesn't seem to be resolving my issue. I'm still getting the error about not being able to expand x. I tried it like below and got the same error. auto bar(T...)(T x) { static if (T.length > 1) { return foo(x); } else static if (T.length == 1 && isTuple!(T)) { return foo(x.expand); } } As you have to do `isTuple!(T[0])`, you also have to do `x[0].expand`. That's because T... works "as if" it was an array of types, and x, being of type T, it works "as if" it was an array of values. So you have to use an index in both cases.
Re: strange bug: (not) calling module ctors; help with "master" needed
On Tuesday, 19 July 2016 at 15:18:20 UTC, Steven Schveighoffer wrote: It's affecting phobos devs too, we are aware of the issue: https://issues.dlang.org/show_bug.cgi?id=16291 i see, thank you. my searching foo failed to find that issue. i guess i have to use digger to find the commit that broke that... oh...
Re: How to get the "this" ptr of a lambda inside the lambda?
On Tuesday, 19 July 2016 at 06:46:44 UTC, Mike Parker wrote: On Tuesday, 19 July 2016 at 06:32:32 UTC, Rufus Smith wrote: Error: 'this' is only defined in non-static member functions, not __lambda2 Lambda's are delegates and delegates have a "this" type of pointer. I would like to get at it inside the lambda to check for some things. I'm doing some funky stuff. I'm not concerned about the scope or what this actually pointers to or anything like that, just need it's value for debugging. No, delegates do not have a "this" type of pointer. "this" is an implicit function parameter in a class or struct member function. Delegates have no such thing. The only generic way I know of to get at a delegate's function pointer inside the implementation is to explicitly add the pointer type to the parameter list as part of the declaration and pass it as an argument when you call the delegate. Delegates do have a this, they have a context pointer that is implicitly passed and used to access the outside context. It is no different than methods. Just because the explicit implementation details are different does not change the underlying meaning.
Re: strange bug: (not) calling module ctors; help with "master" needed
On 7/19/16 11:08 AM, ketmar wrote: i'm using git master (updated daily), and recently found very strange thing. when i'm linking my programs with libphobos2.a, module ctor from "std.internal.phobosinit" is not called, but when i'm linking with .so, everything is ok. it is easy to check: `EncodingScheme.create("utf-8")` will fail if ctor is not called (as all that ctor does currently is registering codecs from std.encoding). i guess that not many people is using that, so it may slip unnoticed for some time. that, or something is very wrong with my local system (which is possible too, of course). so please, if somebody can build dmd master and check it to confirm (i hope ;-) the results, i'd be very grateful. my system is 32-bit GNU/Linux, with gold linker. switching between libs is done in dmd.conf, with: DFLAGS=-defaultlib=libphobos2.a or DFLAGS=-defaultlib=libphobos2.so It's affecting phobos devs too, we are aware of the issue: https://issues.dlang.org/show_bug.cgi?id=16291 Please add what you can to the report. -Steve
strange bug: (not) calling module ctors; help with "master" needed
i'm using git master (updated daily), and recently found very strange thing. when i'm linking my programs with libphobos2.a, module ctor from "std.internal.phobosinit" is not called, but when i'm linking with .so, everything is ok. it is easy to check: `EncodingScheme.create("utf-8")` will fail if ctor is not called (as all that ctor does currently is registering codecs from std.encoding). i guess that not many people is using that, so it may slip unnoticed for some time. that, or something is very wrong with my local system (which is possible too, of course). so please, if somebody can build dmd master and check it to confirm (i hope ;-) the results, i'd be very grateful. my system is 32-bit GNU/Linux, with gold linker. switching between libs is done in dmd.conf, with: DFLAGS=-defaultlib=libphobos2.a or DFLAGS=-defaultlib=libphobos2.so
Re: returning constant references from class methods
On Tuesday, 19 July 2016 at 12:33:53 UTC, ag0aep6g wrote: final const(ulong[char]) nucleotide_counts () const { return cached_counts; } OMG! I'm so blind. Never thought of trying the obvious way. Thank you
Re: counting characters
Thank you! That clarified a lot of things for me.
Re: LDC with ARM backend
On Friday, 15 July 2016 at 15:24:36 UTC, Kai Nacke wrote: There is a reason why we do not distribute a binary version of LDC with all LLVM targets enabled. LDC still uses the real format of the host. This is different on ARM (80bit on Linux/x86 vs. 64bit on Linux/ARM). Do not expect that applications using real type work correctly. (The Windows version of LDC uses 64bit reals. The binary build has the ARM target enabled.) Regards, Kai Hello Kai, Thanks for your answer. From the link https://wiki.dlang.org/Build_LDC_for_Android , I did exactly the same steps described in section "Compile LLVM" (patch applied). At section "Build ldc for Android/ARM", I did it quite the same. I applied the patch ldc_1.0.0_android_arm, but changed runtime/CMakeList.txt, instead of using Android specific stuff, I did: Line 15: set(D_FLAGS -w;-mtriple=arm-none-linux-gnueabi CACHE STRING "Runtime build flags, separated by ;") Line 505: # # Set up build targets. # set(RT_CFLAGS "-g") set(CMAKE_SYSTEM_NAME Linux) set(CMAKE_C_COMPILER /opt/arm-2009q1/bin/arm-none-linux-gnueabi-gcc) set(CMAKE_CXX_COMPILER /opt/arm-2009q1/bin/arm-none-linux-gnueabi-c++) On the command line, I aliased DMD to /usr/bin/dmd and runt cmake as described... Afterwards, I ran make for ldc2, phobos2-ldc an druntime-ldc, but I did not apply the patches on phobos and runtime. It looked like the path introduced some static compilation towards Android, so I thought it would not apply to my needs. So here' what I get if I do a "ldc2 -version": LDC - the LLVM D compiler (1.0.0): based on DMD v2.070.2 and LLVM 3.8.1 built with DMD64 D Compiler v2.071.1 Default target: x86_64-unknown-linux-gnu Host CPU: westmere http://dlang.org - http://wiki.dlang.org/LDC Registered Targets: arm - ARM armeb - ARM (big endian) thumb - Thumb thumbeb - Thumb (big endian) I can strictly compile a "hello world" program: ./bin/ldc2 -mtriple=arm-none-linux-gnueabi test.d I get the expected "test.o" But I don't know how to link it. I don't have "clang". I tried to link it with the gcc from the gnu ARM toolchain with libdruntime-ldc.a, libldc.a and libphobos2-ldc.a, but it fails miserably: many undefined symbols (pthread, and some other os related stuff).
Re: counting characters
On Tuesday, July 19, 2016 12:23:11 celavek via Digitalmars-d-learn wrote: > On Tuesday, 19 July 2016 at 09:57:27 UTC, Lodovico Giaretta wrote: > > On Tuesday, 19 July 2016 at 09:42:40 UTC, celavek wrote: > > > > Works for me: > > > > size_t[char] counts; > > const string dna_chain = > > "AGCCATTCTGACTGCAACGGGCAATATGTCTCTGTGTGGATTAAAGAGTGTCTGATAGCAGC"; > > counts['A'] = countchars(dna_chain, "A"); > > It was failing for me as I was using "countchars!". I thought > that I should use the "!" in order to instantiate a template in > D. I'm still confused why it is working without the "!". Anyway > the compiler message was not very helpful. ! is required for explicit template instantiation, but with functions, you have use IFTI - Implicit Function Template Instantiation. So, when you have a function like auto foo(T)(T bar) {...} and you call it without a template argument foo(42); the compiler infers the type. You can also explicitly instantiate it if you want to foo!int(42); Many functions in Phobos have a template argument which is expected to be explicit (one which is not the type of any of the function's parameters) whereas all of the ones associated with the function's parameters are inferred. e.g. auto result = map!(a => a % 5)([12, 14, 15]); map takes a template argument for the function that it calls on each of the elements in the range it's given, and it takes a function argument that is the range that's being operated on, and while the type of that range is indeed a template argument, it's inferred by the compiler rather than being explicitly given by the programmer. You _could_ give it explicitly, but there really isn't a reason to, and the code is a lot uglier if you do. In the case of countchars, you attempted to give the function arguments as template arguments size_t countchars(S, S1)(S s, in S1 pattern) @safe pure @nogc if (isSomeString!S && isSomeString!S1) {...} If you do countchars!(dna_chain, 'A') then S and S1 are then the template arguments, and they're used as the types of the function parameters, which doesn't work, since they're not types; they don't pass the template constraint either (since neither of them is a type which is a string - they're an actual string and a character, not types). And to make matters worse, there are then no function arguments. So, countchars is being given bogus types, the template arguments fail the template constraint, and it's not being given the function arguments that it needs. So, the error is definitely telling you what's going wrong (or at least part of it) - that the template arguments don't match the template constraint - but your understanding of D's templates seems to be low enough that I suppose that it's no surprise that the error message is confusing. I expect that the reason that it's specifically the template constraints which are complained about rather than the lack of function arguments or that the template arguments aren't even types when they're then used as types for the function parameters is because when you declare size_t countchars(S, S1)(S s, in S1 pattern) @safe pure @nogc if (isSomeString!S && isSomeString!S1) {...} the compiler lowers it to template countchars(S, S1) if (isSomeString!S && isSomeString!S1) { size_t countchars(S s, in S1 pattern) @safe pure @nogc {...} } and that's going to fail to compile at the template constraint before it even looks at the function, because isSomeString is not true for either dna_chain or 'A' (even if it would be true for the _type_ of dna_chain, it's not true for dna_chain itself). If you haven't already, I would suggest that you read http://ddili.org/ders/d.en/index.html I expect that the section http://ddili.org/ders/d.en/templates.html would be the most relevant to this discussion, but the book a as a whole would be good to read if you're new to D. - Jonathan M Davis
Re: counting characters
On 7/19/16 8:23 AM, celavek wrote: On Tuesday, 19 July 2016 at 09:57:27 UTC, Lodovico Giaretta wrote: On Tuesday, 19 July 2016 at 09:42:40 UTC, celavek wrote: Works for me: size_t[char] counts; const string dna_chain = "AGCCATTCTGACTGCAACGGGCAATATGTCTCTGTGTGGATTAAAGAGTGTCTGATAGCAGC"; counts['A'] = countchars(dna_chain, "A"); It was failing for me as I was using "countchars!". I thought that I should use the "!" in order to instantiate a template in D. I'm still confused why it is working without the "!". Anyway the compiler message was not very helpful. https://dlang.org/spec/template.html#function-templates Check out the section a little bit down that talks about implicitly deduced template parameters. -Steve
Re: Passing a single tuple or multiple values
On Tuesday, 19 July 2016 at 07:23:52 UTC, John wrote: auto bar(T...)(T x) { static if (T.length == 1 && isTuple!(T[0])) return foo(x.expand); else return foo(x); } Hmm, this actually doesn't seem to be resolving my issue. I'm still getting the error about not being able to expand x. I tried it like below and got the same error. auto bar(T...)(T x) { static if (T.length > 1) { return foo(x); } else static if (T.length == 1 && isTuple!(T)) { return foo(x.expand); } }
Re: returning constant references from class methods
On Tuesday, 19 July 2016 at 12:30:49 UTC, celavek wrote: final ulong[char] nucleotide_counts () const { return cached_counts; } BTW you can find enumap useful https://forum.dlang.org/post/hloitwqnisvtgfoug...@forum.dlang.org if you want to have small associative arrays with enum keys.
Re: counting characters
On Tuesday, 19 July 2016 at 12:23:11 UTC, celavek wrote: On Tuesday, 19 July 2016 at 09:57:27 UTC, Lodovico Giaretta wrote: On Tuesday, 19 July 2016 at 09:42:40 UTC, celavek wrote: Works for me: size_t[char] counts; const string dna_chain = "AGCCATTCTGACTGCAACGGGCAATATGTCTCTGTGTGGATTAAAGAGTGTCTGATAGCAGC"; counts['A'] = countchars(dna_chain, "A"); It was failing for me as I was using "countchars!". I thought that I should use the "!" in order to instantiate a template in D. I'm still confused why it is working without the "!". Anyway the compiler message was not very helpful. The declaration is: countchars(S, S1)(S str, S1 pattern) So the most verbose way to instantiate it is: countchars!(string, string)(dna_chain, "A") But as S and S1 are the types of the two arguments, the compiler can easily infer them, so you can write: countchars(dna_chain, "A") And have the compiler infer: countchars!(typeof(dna_chain), typeof("A"))(dna_chain, "A") The error message is technically correct: you cannot instantiate countchars with template parameters `dna_chain` and `"A"`, which is what you were actually doing.
Re: returning constant references from class methods
On 07/19/2016 02:30 PM, celavek wrote: Hi, I'm trying the following code: class counter { public: final ulong[char] nucleotide_counts () const { return cached_counts; } private: ulong[char] cached_counts; } void main() { } I get the following error from the compiler: Error: cannot implicitly convert expression (this.cached_counts) of type const(ulong[char]) to ulong[char] I tried making the class variable constant, I tried the const in the return type but I can't seem to get it right. I would like to return a constant reference to the internal associative array - much like in C++. How would I do that in D? final const(ulong[char]) nucleotide_counts () const { return cached_counts; }
returning constant references from class methods
Hi, I'm trying the following code: class counter { public: final ulong[char] nucleotide_counts () const { return cached_counts; } private: ulong[char] cached_counts; } void main() { } I get the following error from the compiler: Error: cannot implicitly convert expression (this.cached_counts) of type const(ulong[char]) to ulong[char] I tried making the class variable constant, I tried the const in the return type but I can't seem to get it right. I would like to return a constant reference to the internal associative array - much like in C++. How would I do that in D?
Re: counting characters
On Tuesday, 19 July 2016 at 09:57:27 UTC, Lodovico Giaretta wrote: On Tuesday, 19 July 2016 at 09:42:40 UTC, celavek wrote: Works for me: size_t[char] counts; const string dna_chain = "AGCCATTCTGACTGCAACGGGCAATATGTCTCTGTGTGGATTAAAGAGTGTCTGATAGCAGC"; counts['A'] = countchars(dna_chain, "A"); It was failing for me as I was using "countchars!". I thought that I should use the "!" in order to instantiate a template in D. I'm still confused why it is working without the "!". Anyway the compiler message was not very helpful.
Re: counting characters
On Tuesday, 19 July 2016 at 09:55:43 UTC, Jonathan M Davis wrote: On Tuesday, July 19, 2016 09:41:32 John via Digitalmars-d-learn wrote: auto result = count(dna_chain, 'A'); or if you know that the string is always going to just contain ASCII (as seems likely based on the example), then string.representation can be used to convert the string to immutable(ubyte)[] in order to avoid the auto-decoding that occurs with string and range-based functions. e.g. auto result = count(dna_chain.representation, 'A'); That's almost certainly the fastest way to do it with Phobos. - Jonathan M Davis Thank you. I used what you suggested as I have only ASCII characters.
Re: Passing a single tuple or multiple values
On Tuesday, 19 July 2016 at 07:23:52 UTC, John wrote: auto bar(T...)(T x) { static if (T.length == 1 && isTuple!(T[0])) return foo(x.expand); else return foo(x); } void main() { auto x = tuple(1, 2); auto y = bar(x); auto z = bar(x.expand); writeln(y); writeln(z); } I was leaving out the T[0] in the isTuple!
Re: counting characters
On Tuesday, 19 July 2016 at 09:42:40 UTC, celavek wrote: On Tuesday, 19 July 2016 at 09:41:32 UTC, John wrote: On Tuesday, 19 July 2016 at 09:34:11 UTC, celavek wrote: Hi, I am trying to count characters in a string like: const string dna_chain = "AGCCATTCTGACTGCAACGGGCAATATGTCTCTGTGTGGATTAAAGAGTGTCTGATAGCAGC"; counts['A'] = countchars!(dna_chain, 'A'); countchars(dna_chain, "A"); Not working. Same error. Works for me: size_t[char] counts; const string dna_chain = "AGCCATTCTGACTGCAACGGGCAATATGTCTCTGTGTGGATTAAAGAGTGTCTGATAGCAGC"; counts['A'] = countchars(dna_chain, "A");
Re: counting characters
On Tuesday, July 19, 2016 09:41:32 John via Digitalmars-d-learn wrote: > On Tuesday, 19 July 2016 at 09:34:11 UTC, celavek wrote: > > Hi, > > > > I am trying to count characters in a string like: > > > > const string dna_chain = > > "AGCCATTCTGACTGCAACGGGCAATATGTCTCTGTGTGGATTAAAGAGTGTCTGATAGCAGC"; > > counts['A'] = countchars!(dna_chain, 'A'); > > countchars(dna_chain, "A"); That fixes the call to countchars, but given that the OP is only looking to count a specific character and is not really using a "pattern" (which is what countchars looks for), it's bound to be more efficient to just use a function which counts the number of elements in the array which match a certain character rather than seaching for a pattern. std.algorithm.count would be the most idiomatic choice. So, you get something like auto result = count(dna_chain, 'A'); or if you know that the string is always going to just contain ASCII (as seems likely based on the example), then string.representation can be used to convert the string to immutable(ubyte)[] in order to avoid the auto-decoding that occurs with string and range-based functions. e.g. auto result = count(dna_chain.representation, 'A'); That's almost certainly the fastest way to do it with Phobos. - Jonathan M Davis
Re: counting characters
On Tuesday, 19 July 2016 at 09:41:32 UTC, John wrote: On Tuesday, 19 July 2016 at 09:34:11 UTC, celavek wrote: Hi, I am trying to count characters in a string like: const string dna_chain = "AGCCATTCTGACTGCAACGGGCAATATGTCTCTGTGTGGATTAAAGAGTGTCTGATAGCAGC"; counts['A'] = countchars!(dna_chain, 'A'); countchars(dna_chain, "A"); Not working. Same error.
Re: counting characters
On Tuesday, 19 July 2016 at 09:34:11 UTC, celavek wrote: Hi, I am trying to count characters in a string like: const string dna_chain = "AGCCATTCTGACTGCAACGGGCAATATGTCTCTGTGTGGATTAAAGAGTGTCTGATAGCAGC"; counts['A'] = countchars!(dna_chain, 'A'); countchars(dna_chain, "A");
counting characters
Hi, I am trying to count characters in a string like: const string dna_chain = "AGCCATTCTGACTGCAACGGGCAATATGTCTCTGTGTGGATTAAAGAGTGTCTGATAGCAGC"; counts['A'] = countchars!(dna_chain, 'A'); But I get a compilation error: template instance countchars!(dna_chain, "C") does not match template declaration countchars(S, S1)(S s, in S1 pattern) if (isSomeString!S && isSomeString!S1) I cannot figure out why I do get the error. It completely eludes me. The documentation of countchars is minimal and it lacks examples. Could someone enlighten me? dmd version: DMD64 D Compiler v2.071.1 Thanks
Re: Passing a single tuple or multiple values
On Tuesday, 19 July 2016 at 01:22:01 UTC, jmh530 wrote: import std.typecons : isTuple, tuple; import std.stdio : writeln; auto foo(T...)(T x) { T[0] y; foreach (i, e; x) { y += e; } return y; } auto bar(T)(T x) { static if (isTuple!T) { return foo(x.expand); } } auto bar(T...)(T x) { return foo(x); } auto bar(T...)(T x) { static if (T.length == 1 && isTuple!(T[0])) return foo(x.expand); else return foo(x); } void main() { auto x = tuple(1, 2); auto y = bar(x); auto z = bar(x.expand); writeln(y); writeln(z); }