Re: std.file: read, readText and UTF-8 decoding
OK. Thanks for response. I wish that there it was some API to handle it "out of the box". Do I need to write some issue or something in order to not forget about this?
Re: std.file: read, readText and UTF-8 decoding
Addition: Current solution to this problemme that I was found is: So I just check for BOM manually. Get length of bom.sequence and remove that count of items from beginning. But I dont' think that it's convenient solution, because `who knows` how much else issues with UTF could happend. And I don't think that it's correct to handle them on the side of users of standart D library... I think that should be solution "out of the box". It could be not much effective, but it should at least "just work" without extra movements... string[] getGroupsFromFile(string groupFilePath) { writeln(`Parse file` ~ groupFilePath); string[] groupNames = []; char[] rawContent = cast(char[]) read(groupFilePath); auto bom = getBOM(cast(ubyte[]) rawContent); string content = cast(string) rawContent[bom.sequence.length..$]; writeln(`Content:\n` ~ content); //... work with XML return groupNames; }
std.file: read, readText and UTF-8 decoding
Hello! I have some strange problem. I am trying to parse XML files and extract some information from it. I use library dxml for it by Jonathan M Davis. But I have a probleme that I have multiple XML files made by different people around the world. Some of these files was created with Byte Order Mark, but some of them without BOM. dxml expects no BOM at the start of the string. At first I tried to read file with std.file.readText. Looks like it doesn't decode file at any way and doesn't remove BOM, so dxml failed to parse it then. This looks strange for me, because I expect that "text" function must decode data to UTF-8. Then I read that this behavior is documented at least: """ ...However, no width or endian conversions are performed. So, if the width or endianness of the characters in the given file differ from the width or endianness of the element type of S, then validation will fail. """ So it's OK. But I understood that this function "readText" is not usefull for me. So I tried to use plain "read" that returns "void[]". Problemmme is that I still don't understand which method I should use to convert this to string[] with proper UTF-8 decoding and remove BOM and etc. Could you help me, please to make some clearance. P.S. Function readText looks odd in std.file, because you cannot specify any encoding to decode this file. And logic how it decodes is unclear...
Re: Why Throwable.message is not a property
On Wednesday, 17 March 2021 at 19:38:48 UTC, Adam D. Ruppe wrote: On Wednesday, 17 March 2021 at 19:32:02 UTC, uranuz wrote: Seems that a problem with concatenation is because Throwable.message has const(char)[] type, but not string. This makes some inconvenience ;-) Yes, that's what I thought. The concat operation tends to give the most flexible type of the arguments... and I wish it would then ACTUALLY use that flexibility... but it doesn't. Regardless though since you know you are concating it, which means you get a new string anyway, you can safely cast(string) it. string longMsg = "The: " ~ cast(string) exc.message; that's how i do it. This is what I have done ;-)
Re: Why Throwable.message is not a property
On Wednesday, 17 March 2021 at 17:52:20 UTC, Adam D. Ruppe wrote: On Wednesday, 17 March 2021 at 17:46:27 UTC, uranuz wrote: Also because it is not a property in some contexts when I try to concatenate it with string without parentheses using "~" operator it fails Can you post some sample code that demonstrates this? Seems that a problem with concatenation is because Throwable.message has const(char)[] type, but not string. This makes some inconvenience ;-) There is an example: import std; void main() { auto exc = new Exception("Test"); string longMsg = "The: " ~ exc.message; // Adding parentheses () after "message" actually doesn't change anything. Error is the same writeln(longMsg); } Compile error: onlineapp.d(6): Error: cannot implicitly convert expression "The: " ~ exc.message() of type char[] to string I could add cast(string), but it's not something I want to do. The reason, why I want to use "message" instead of "msg" is that I want to add some extra information to exception as separate typed fields. But I want it to be displayed when converting exception to string. So I shall override "message" and convert this extra info to string...
Why Throwable.message is not a property
The question is why Throwable.message is not a @property?! It looks strange now, because "message" is not a *verb*, but a *noun*. So it's expected to be a property. Also because it is not a property in some contexts when I try to concatenate it with string without parentheses using "~" operator it fails, because (as you could expect) it is a *regular* function, but not a property. I wonder if it was made as *non-property* by some reason or by oversight? Thanks
Re: Difference between range `save` and copy constructor
> Either way, generic code should never be using a range after > it's been copied, and copying is a key part of how > idiomatic, range-based code works in D. OK. Thanks for instructions. I shall give it a try.
Re: Difference between range `save` and copy constructor
On Sunday, 16 February 2020 at 12:38:51 UTC, Jonathan M Davis wrote: On Sunday, February 16, 2020 3:41:31 AM MST uranuz via Digitalmars-d-learn wrote: I have reread presentation: http://dconf.org/2015/talks/davis.pdf We declare that `pure` input range cannot be `unpoped` and we can't return to the previous position of it later at the time. So logically there is no sence of copying input range at all. So every Phobos algorithm that declares that it's is working with InputRange must be tested for working with range with disabled A range that can't be copied is basically useless. Not only do almost all range-based algorithms take their argumenst by value (and thus copy them), but foreach copies any range that it's given, meaning that if a range isn't copyable, you can't even use it with foreach. And since many range-based algorithms function by wrapping one range with another, the ability to copy ranges is fundamental to most range-based code. This is working fine with disabled postblit... import std; struct SS { @disable this(this); // Disabled copy bool _empty = false; bool empty() @property { return _empty; } void popFront() { _empty = true; } int front() @property { return 10; } } void main() { foreach( it; SS() ) { writeln(it); } } Am I missing something?
Re: Difference between range `save` and copy constructor
In general for value-semantics and ref-semantics the different code is actually needed. But generic algorithm try to pretend that the logic is the same. But it's not true. But in wide subset of trivial algorithm it's true. So it's incorrectly interpolated that it's true for every case. The very bad thing if range is passed by value it still can have value or reference semantic. And algorithm cannot say which is it actually. There is not such problemme for classes. So as I already said when passing ranges by ref in algorithms they behave predictible. And if I want algrorithm to operate on copy of algorithm then I can just create this copy before passing it to this algorithm. And again intention is more clear. But Phobos algorithms don't work like that. It's why I can't use them in some cases, because they are looking unpredictable for me.
Re: Difference between range `save` and copy constructor
It's very bad. Because there seem that when I use range based algorithm I need to take two things into account. The first is how algrorithm is implemented. If it creates copies of range inside or pass it by reference. And the second is how the range is implemented if it has value or reference semantics. So every time I need to look into implementation and I can't rely on API description in most of the cases. In a lot of cases Phobos uses value semantics. But there are cases where I want the range actually be consumed, but it's not. And the other problemme is when algorithm expects range to have value semantics, but it's not. So it's a buggy mess that it's hard to think about. In trivial cases this is working although. But in more complex cases it's simplier to implement some algorithms by own hands so that it would work as I expect it myself rather that thinking about all these value-ref-range mess. But still can't say that I implement it correctly, because range specification actually sucks as yo say. It's just horrible
Re: Difference between range `save` and copy constructor
I have reread presentation: http://dconf.org/2015/talks/davis.pdf We declare that `pure` input range cannot be `unpoped` and we can't return to the previous position of it later at the time. So logically there is no sence of copying input range at all. So every Phobos algorithm that declares that it's is working with InputRange must be tested for working with range with disabled copy constructor and postblit. And if it is not it means that this algroithm actually requires a forward range and there we missing `save` calls? Because as it was written in this presentation a range copy is undefined (without call to save). So it's illegal to create copy of range in Phobos algorithms without `save`? So we need a test for every algorithm that it is working with range with disabled copy constructor and postblit if we declare that we only use `save` for range copy?
Re: Difference between range `save` and copy constructor
Also I see the problemme that someone can think that it creates an input range, because he doesn't provide `save` method, but actually it creates forward range unexpectedly, because it is copyable. And it makes what is actually happening in code more difficult. Some algrorithm can take ranges by value, but others take them by reference. So result can be completely different. In first case range is being consumed, but in another in is not. Personally I prefer to take range by reference in all of my algrorithms except cases where I is always a class (because it's a reference already). But I still don't know what is the right way. There are no official guidelines about it. So every time it's a problemme. Although it looks like that range is a simple concept, but it's actually not.
Re: Difference between range `save` and copy constructor
Actually, as I understand it, the main reason that save was introduced was so that classes could be forward ranges I have use of ranges as a classes in my code that rely on classes and polymorthism, but it's usually an InputRange that implements Phobos interface: https://dlang.org/phobos/std_range_interfaces.html#.InputRange I have virtual opSlice operator that returns InputRange. And sometimes implementation of range is very different. So it's difficult to write one range as a struct. I have a pattern in my code that looks like the following: interface IContainer { InputRange opSlice(); } class MyContainer1: IContainer { class Range1: InputRange { //... one implementation } override InputRange opSlice() { return new Range1(this); } } class MyContainer2: IContainer { class Range2: InputRange { //... another implementation } override InputRange opSlice() { return new Range2(this); } } In this example I need a range to be a class, but not a struct. Another problemme is that `copy contructor` is defined only for structs, but not classes. For the class that uses another class instance of the `same` type to initialize from it would be a regular constructor with parameter. A copy constructor in struct semantics requires that the source would be actually `the same` type. But for classes source could be instance of another class that is inherited from current class. And we cannot prove statically that it's actually the same type. And also if we talk about range interface constructor cannot be a part of it. So we cannot add `copy contructor` (if we would have it for class) to interface and check for it's presence in generic code. So here we have this workaround with `save` method... I don't like that primitive concept has two ways to do the same thing. And it's unclear what is the primary way of doing this (copy constructor or save). It introduce the situation when half of the code would require range being copyable, but another part would require it to to have a save method. Not the situation is that there are a lot of algorothms in Phobos that are not working with ranges that have disabled postblit, but have `save` method that could be used to make a copy. Still I want to be able to create ranges as classes...
Difference between range `save` and copy constructor
I am interested in current circumstances when we have new copy constructor feature what is the purpose of having range `save` primitive? For me they look like doing basicaly the same thing. And when looking in some source code of `range` module the most common thing that `save` does is that it use constructor typeof(this) to create a new instance and use `save` on the source range: https://github.com/dlang/phobos/blob/v2.090.1/std/range/package.d So what is conceptual difference between `save` and copy contructor of range?
Re: D create many thread
Is it also possible to set some custom thread name for GC threads in order to be distinguishable from other threads in utilities like `htop`? It would be handy...
Re: Question about alias and getOverloads
OK. Thanks. Created two reports related to these questions: https://issues.dlang.org/show_bug.cgi?id=20553 https://issues.dlang.org/show_bug.cgi?id=20555
Re: Question about alias and getOverloads
I apologise that I need to revive this discussion again. But still I got answer to only one of my questions. I know that it is a common practice in programmers society that when someone asks more than 1 question. Then people who answer them usually choose only one of these questions that is the most easiest to answer. But the rest of the questions are just ignored. But the topic is still considered resolved. Person who answered `increased his carma`. All are happy. Except for the man who asked the question, but only got answer that is trivial, easy-to-answer or easy-to-find by himself. And actually got the answer to only one of the questions. And it is the less important. At my job in this case I usually ask questions only one by one. It gives to person that shall try to answer no options and to answer only to this question. So only when I got answer that satisfies me I start to ask the next question. I didn't want to use this technique there, because I believe that D community is better... Sorry for this disgression, but I still don't understand several main points: 1. Why API for __traits(getOverloads) is so strange. Why I need to find parent for symbol myself and pass actual symbol name as string, but not actually pass a symbol itself? It is very strange to me... 2. Where in the documentation is mentioned that when I create alias to name that is a function or method that has overloads then this alias is actually an alias not only for the first or second or randomly selected overload in overload set, but an alias for all of overloads in set at the same time? Thanks. Have a good day!
Re: Question about alias and getOverloads
I have read it two or three times just before writing my question: https://dlang.org/spec/declaration.html#alias And also a have read all the dlang docs several time few years ago... ;) But I don't see what do you you mean by writing that it was menioned here. I don't se any words or any examples that describe how `alias` works with function overload sets. Is it a blind assumption that it was written here? The only example that someone can mix up and consider as answer to my question if actually didn't read it with attention. It is example bellow: ``` alias myint = int; void foo(int x) { ... } void foo(myint m) { ... } // error, multiply defined function foo ``` But the only thing that this example illustrates is that `myint` and `int` is actualy the same type. So this overload set is just incorrect. I don't ask you to consider the case where overload set is incorrect. So this didn't answered my question in any way. Looks like this is some kind of nasty details that language developers don't "proud of" and don't like to discover details about how it's working. Or just lazy enough to do so ;) Still I figured answer myself using your example. The answer is not full, but yet enough for me for practical usage. But the lack of description about it makes me think that I am not the last man who will have his curiosity not fully satisfied about this aspect of language. And also __traits(parent, Func) seems like not universal for all cases with functions, because it fails on lambda-functions. For instance: // import std; template Bar(alias Func) { alias Bar = __traits(getOverloads, __traits(parent, Func), __traits(identifier, Func)); } void main() { alias Test = Bar!(() { return `test`; }); } // Output: onlineapp.d(4): Error: no property __lambda1 for type void onlineapp.d(4): Error: main().__lambda1 cannot be resolved onlineapp.d(9): Error: template instance onlineapp.Bar!(function () pure nothrow @nogc @safe => "test") error instantiating // Seems that it fails to get parent for lambda. I don't know why? What parent should be for labmda? Thanks for attention!
Re: Question about alias and getOverloads
Thanks for advice ;) This looks like some `standard trick` that is yet not learnt or forgoten by me personally. The key was in using `parent` trait. This is what I failed to think of. This is working as expected: //- import std; import core.thread; import std.meta: AliasSeq; void foo(string param1) {} void foo(string param1, int param2, bool param3) {} template Bar(alias Func) { alias Bar = __traits(getOverloads, __traits(parent, Func), __traits(identifier, Func)); } void main() { import std.traits: fullyQualifiedName, Parameters; import std.conv: text; static foreach( It; Bar!foo ) { pragma(msg, fullyQualifiedName!It ~ "/" ~ (Parameters!It).length.text); } } //- Output: onlineapp.foo/1 onlineapp.foo/3 //- So as far as I understand alias template parameter gives access to all of items of overload set as I was expecting. The only problem is that I didn't found something about it in specification about templates: https://dlang.org/spec/template.html
Question about alias and getOverloads
Hello! I have a question about `alias` template parameter and getOverloads. For instance I have some code like this: // - import std; import core.thread; void foo(string param1) {} void foo(string param1, int param2) {} template Bar(alias Func) { // Next line is not valid now. This is my understanding of how I wish it would work... pragma(msg, __traits(getOverloads, Func)); } void main() { Bar!foo; } //--- By the spec: https://dlang.org/spec/traits.html#getOverloads The signature of `getOverloads` trait requires me to pass a symbol where my function is contained (it could be class, struct or module). And a name of function that I want to get overloads for. Let's imagine that `foo` overloads and Bar template are in different modules. And `Bar` template doesn't have no direct access to module where `foo` is contained. And `Bar` is instantiated outside module where `Bar` is declared. I have two questions: 1. Whether `Bar` instantiation would get first, second or both overloads of function? Or maybe I would get two instantiations of template by the number of overloads? I don't understand well how this mechanic is working. Is it documented somewhere? Does actually one alias parameter represents only one symbol from overload set or all of them? 2. If alias parameter represents multiple symbols from overload set. Then I wish I could access to list of overloads having alias parameter. I wish to get count of overloads in my real case in order to issue an error that overloaded are not supported by my code.
Re: Some code that compiles but shouldn't
On Monday, 30 December 2019 at 19:09:13 UTC, MoonlightSentinel wrote: On Monday, 30 December 2019 at 18:18:49 UTC, uranuz wrote: So as you see I have added a lot of enforce to test if all variables are not null. But nothing was null and the reason of segfault were unclear. What about moduleName, mod and the return value of mod.toStdJSON()? And whats the return type of ctx.response.write? (Returning a void expression is allowed and avoids some special casing in generic code) OK. This example compiles... void bar() {} void main() { return bar(); }
Re: Some code that compiles but shouldn't
On Monday, 30 December 2019 at 19:09:13 UTC, MoonlightSentinel wrote: On Monday, 30 December 2019 at 18:18:49 UTC, uranuz wrote: So as you see I have added a lot of enforce to test if all variables are not null. But nothing was null and the reason of segfault were unclear. What about moduleName, mod and the return value of mod.toStdJSON()? And whats the return type of ctx.response.write? (Returning a void expression is allowed and avoids some special casing in generic code) I have reviewed this code and ctx.response.write(...) returns void too.. ;-) So I don't even know if this is correct or no? Could I use `return void;`?
Some code that compiles but shouldn't
I have created library/ framework to handle JSON-RPC requests using D methods. I use some *template magic* to translate JSON-RPC parameters and return values from/ and to JSON. And I have encountered funny bug that at first was hard to find. My programme just segfaulted when call to this method occured: void getCompiledTemplate(HTTPContext ctx) { import std.exception: enforce; enforce(ctx, `ctx is null`); enforce(ctx.request, `ctx.request is null`); enforce(ctx.request.form, `ctx.request is null`); enforce(ivyEngine !is null, `ivyEngine is null`); string moduleName = ctx.request.form[`moduleName`]; auto mod = ivyEngine.getByModuleName(moduleName); return ctx.response.write(mod.toStdJSON().toString()); } So as you see I have added a lot of enforce to test if all variables are not null. But nothing was null and the reason of segfault were unclear. Today I just went home. Opened a bottle of beer. And have noticed that function is marked as returning `void`, but in fact it doesn't. When I fixed this segfault have gone. But why this even compiled?! Interesting...
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 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.
Re: How to make rsplit (like in Python) in D
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
Re: How to make rsplit (like in Python) in D
On Saturday, 1 October 2016 at 17:23:16 UTC, Uranuz wrote: On Saturday, 1 October 2016 at 16:45:11 UTC, Uranuz wrote: How to make rsplit (like in Python) in D without need for extra allocation using standard library? And why there is no algorithms (or parameter in existing algorithms) to process range from the back. Is `back` and `popBack` somehow worse than `front` and `popFront`. I've tried to write somethig that would work without allocation, but failed. I have searching in forum. Found this thread: https://forum.dlang.org/post/bug-1030...@http.d.puremagic.com%2Fissues%2F I tried to use `findSplitBefore` with `retro`, but it doesn't compile: import std.stdio; import std.algorithm; import std.range; import std.string; void main() { string str = "Human.Engineer.Programmer.DProgrammer"; writeln( findSplitBefore(retro(str), ".")[0].retro ); } Compilation output: /d153/f534.d(10): Error: template std.range.retro cannot deduce function from argument types !()(Result), candidates are: /opt/compilers/dmd2/include/std/range/package.d(198): std.range.retro(Range)(Range r) if (isBidirectionalRange!(Unqual!Range)) Why I have to write such strange things to do enough wide-spread operation. I using Python at the job and there is very much cases when I use rsplit. So it's very strange to me that D library has a lot of `advanced` algorithms that are not very commonly used, but there is no rsplit. Maybe I missing something, so please give me some advice) Sorry for noise. It was easy enough: import std.stdio; import std.algorithm; import std.range; import std.string; void main() { string str = "Human.Engineer.Programmer.DProgrammer"; writeln( splitter(str, '.').back ); } But I still interested why the above not compiles and how to do `rfind` or indexOf from the right in D. I think even if we do not have exactly algorithms with these names we could provide some examples how to *emulate* behaviour of standard functions from other popular languages) But these example fails. Oops. Looks like a bug( import std.stdio; import std.algorithm; import std.range; import std.string; void main() { string str = ""; writeln( splitter(str, '.').back ); } core.exception.AssertError@std/algorithm/iteration.d(3132): Assertion failure ??:? _d_assert [0x43dd1f] ??:? void std.algorithm.iteration.__assert(int) [0x4432b0] ??:? pure @property @safe immutable(char)[] std.algorithm.iteration.splitter!("a == b", immutable(char)[], char).splitter(immutable(char)[], char).Result.back() [0x43b8d6] ??:? _Dmain [0x43ae41] ??:? _D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ6runAllMFZ9__lambda1MFZv [0x43e33e] ??:? void rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).tryExec(scope void delegate()) [0x43e288] ??:? void rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).runAll() [0x43e2fa] ??:? void rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).tryExec(scope void delegate()) [0x43e288] ??:? _d_run_main [0x43e1f9] ??:? main [0x43d049]
Re: How to make rsplit (like in Python) in D
On Saturday, 1 October 2016 at 16:45:11 UTC, Uranuz wrote: How to make rsplit (like in Python) in D without need for extra allocation using standard library? And why there is no algorithms (or parameter in existing algorithms) to process range from the back. Is `back` and `popBack` somehow worse than `front` and `popFront`. I've tried to write somethig that would work without allocation, but failed. I have searching in forum. Found this thread: https://forum.dlang.org/post/bug-1030...@http.d.puremagic.com%2Fissues%2F I tried to use `findSplitBefore` with `retro`, but it doesn't compile: import std.stdio; import std.algorithm; import std.range; import std.string; void main() { string str = "Human.Engineer.Programmer.DProgrammer"; writeln( findSplitBefore(retro(str), ".")[0].retro ); } Compilation output: /d153/f534.d(10): Error: template std.range.retro cannot deduce function from argument types !()(Result), candidates are: /opt/compilers/dmd2/include/std/range/package.d(198): std.range.retro(Range)(Range r) if (isBidirectionalRange!(Unqual!Range)) Why I have to write such strange things to do enough wide-spread operation. I using Python at the job and there is very much cases when I use rsplit. So it's very strange to me that D library has a lot of `advanced` algorithms that are not very commonly used, but there is no rsplit. Maybe I missing something, so please give me some advice) Sorry for noise. It was easy enough: import std.stdio; import std.algorithm; import std.range; import std.string; void main() { string str = "Human.Engineer.Programmer.DProgrammer"; writeln( splitter(str, '.').back ); } But I still interested why the above not compiles and how to do `rfind` or indexOf from the right in D. I think even if we do not have exactly algorithms with these names we could provide some examples how to *emulate* behaviour of standard functions from other popular languages)
How to make rsplit (like in Python) in D
How to make rsplit (like in Python) in D without need for extra allocation using standard library? And why there is no algorithms (or parameter in existing algorithms) to process range from the back. Is `back` and `popBack` somehow worse than `front` and `popFront`. I've tried to write somethig that would work without allocation, but failed. I have searching in forum. Found this thread: https://forum.dlang.org/post/bug-1030...@http.d.puremagic.com%2Fissues%2F I tried to use `findSplitBefore` with `retro`, but it doesn't compile: import std.stdio; import std.algorithm; import std.range; import std.string; void main() { string str = "Human.Engineer.Programmer.DProgrammer"; writeln( findSplitBefore(retro(str), ".")[0].retro ); } Compilation output: /d153/f534.d(10): Error: template std.range.retro cannot deduce function from argument types !()(Result), candidates are: /opt/compilers/dmd2/include/std/range/package.d(198): std.range.retro(Range)(Range r) if (isBidirectionalRange!(Unqual!Range)) Why I have to write such strange things to do enough wide-spread operation. I using Python at the job and there is very much cases when I use rsplit. So it's very strange to me that D library has a lot of `advanced` algorithms that are not very commonly used, but there is no rsplit. Maybe I missing something, so please give me some advice)
Re: How to check member function for being @disable?
On Tuesday, 13 September 2016 at 15:32:57 UTC, Jonathan M Davis wrote: On Tuesday, September 13, 2016 08:28:10 Jonathan M Davis via Digitalmars-d- learn wrote: On Tuesday, September 13, 2016 04:58:38 Uranuz via Digitalmars-d-learn wrote: > In my code I iterate in CT over class methods marked as > @property and I have a probleme that one of methods is > @disable. So I just want to skip @disable members. I found > possible solution, but it's interesting to we if we have > more clear and obvious way to test for @disable without > using __traits( compile ) for it? @disable "looks" like > attribute but seems that I cant't get it through __traits( > getAttributes ) or __traits( getFunctionAttributes ). Maybe > we could add something to test for @disable if it's not > already exists? I really don't think that it's going to scale properly to check whether something is marked with @disable. The problem is that it propagates. For instance, if a struct has a member variable that has default initialization disabled via @disable this(); then that struct effectively has @disable this(); too even though it doesn't have it explicitly. So, ultimately what needs to be tested for is the behavior and not the presence of @disable, and that means testing with __traits(compiles, ...). And I would point out that most traits test via __traits(compiles, ...) or is(typeof(...)) rather than checking for something like an attribute. So, if don't like using __traits(compiles, ...) in metaprogramming, your going to get frustrated quickly. A large portion of the time, it's exactly the solution to the problem. What would make sense would be creating a trait to test for the @disabled functionality in queston - e.g. there could be an eponymous template named something like hasDefaultInitializer (though that name is a bit long) which indicated whether a type had @disabled this(); or not. Then you can use that trait in your code rather than using __traits(compiles, ...) all over the place. - Jonthan M Davis OK. Seems that there is nothing that I could do more about my example code.. So the best way to be sure if something is assignable property is to try assign to it and test whether it compiles. The question was because utill this moment I somehow was living without __traits(compiles..). Seems that my use cases just was not enough complicated... Thanks for the answers. It could be good idea to have __traits( isDisable ... ) or something for it. I admit that not only '@disabled this();' regular methods could me marked @disable too..
How to check member function for being @disable?
In my code I iterate in CT over class methods marked as @property and I have a probleme that one of methods is @disable. So I just want to skip @disable members. I found possible solution, but it's interesting to we if we have more clear and obvious way to test for @disable without using __traits( compile ) for it? @disable "looks" like attribute but seems that I cant't get it through __traits( getAttributes ) or __traits( getFunctionAttributes ). Maybe we could add something to test for @disable if it's not already exists? void fillProperties(Ctrl)(Ctrl ctrl, IDirectiveStatement statement, Interpreter interp) { import std.meta: Alias, AliasSeq; import std.traits; import std.conv; TDataNode[string] attrDict = getNamedAttributesValues(statement, interp); foreach( memberName; AliasSeq!( __traits( allMembers, Ctrl ) ) ) { static if( __traits( compiles, __traits(getOverloads, Ctrl.init, memberName) ) ) { alias Overloads = AliasSeq!(__traits( getOverloads, Ctrl.init, memberName )); foreach( overload; Overloads ) { static if( (functionAttributes!(overload) & FunctionAttribute.property) ) { alias params = Parameters!(overload); static if( params.length == 1 ) { alias propType = params[0]; static if( __traits(compiles, mixin("{ ctrl."~memberName~" = propType.init; }") ) ) { pragma( msg, memberName, ": ", typeof() ); TDataNode attrValue = attrDict.get( memberName, TDataNode(null) ); if( !attrValue.empty ) { mixin( "ctrl." ~ memberName ~ " = nodeToDValue!(propType)(attrValue);" ); } } } } } } } }
Re: static immutable and lambdas inside struct or class. Is that bug or not?
On Sunday, 14 August 2016 at 15:53:21 UTC, ag0aep6g wrote: On 08/14/2016 04:27 PM, Uranuz wrote: [...] Looks like a compiler bug, since it works without the struct: import std.algorithm: map; import std.array: array; import std.typecons: tuple; immutable aaa = [ tuple("1", "one"), tuple("2", "two"), tuple("3", "three") ]; immutable bbb = aaa.map!( a => a[0] ).array; And that's essentially the same thing. It has already been filed: https://issues.dlang.org/show_bug.cgi?id=15908 For a workaround, it works when you explicitly state the type of the parameter: struct A { import std.algorithm: map; import std.array: array; import std.typecons: tuple, Tuple; static immutable aaa = [ tuple("1", "one"), tuple("2", "two"), tuple("3", "three") ]; alias Tup = Tuple!(string, string); static immutable bbb = aaa.map!( (Tup a) => a[0] ).array; } OK. I just declared alias for predicate outside struct to workaround. Maybe compiler trying to get context when attemting to infer arguments for some reason, but fails. Or something else...
static immutable and lambdas inside struct or class. Is that bug or not?
Greatings! I need help with these lines bellow. I don't understand why it doesn't compile. Is it bug somewhere in Phobos or compiler? Or just I wrote smth wrong? //- struct A { import std.algorithm: map; import std.array: array; import std.typecons: tuple; static immutable aaa = [ tuple("1", "one"), tuple("2", "two"), tuple("3", "three") ]; static immutable bbb = aaa.map!( a => a[0] ).array; } void main() { A a = A(); } //- Compilation output: /opt/compilers/dmd2/include/std/algorithm/iteration.d(455): Error: this.__lambda6 has no value You could test it here: https://dpaste.dzfl.pl/67a8cda8f2a8
Problem with circular imports of modules with static ctors an immutable variables
In my program I have error with circular imports of modules with static ctors. So I decided to move ctors in separate file and import it only from the 1st file. But problem is that in the first file I have immutables that should be initialized in shared static ctor. However doing it from another module's ctor gives compilation error: "Error: cannot modify immutable expression". 1. Is it a bug? 2. Could I solve this problem another way? Example code: module mod; import mod_init; static immutable string[string] aa; ... -- module mod_init; import mod; shared static this { aa = [ "a": "b", "c": "d" ]; //This gives compilation error } ...
Re: Stupid question about AA. The following code works but I don't undrstand why?!
On Saturday, 9 April 2016 at 21:16:08 UTC, ag0aep6g wrote: On Saturday, 9 April 2016 at 19:31:31 UTC, Uranuz wrote: I think that we need to add warning about such case in documentation section: https://dlang.org/spec/hash-map.html#construction_and_ref_semantic in order to prevent this kind of mistakes in code. Isn't that exactly what the section you linked does? Yes certainly. But maybe we should give just a little more example there.
Re: Stupid question about AA. The following code works but I don't undrstand why?!
On Saturday, 9 April 2016 at 19:25:32 UTC, Uranuz wrote: On Saturday, 9 April 2016 at 18:27:11 UTC, ag0aep6g wrote: [...] Another observation is illustrated with the foloving code: http://dpaste.dzfl.pl/8d68fd5922b7 Because AA and arrays are not created before they were assigned some value it leads to inconsistency in behavior. And will produce unexpected and hidden bugs that is not good. It's not very good side of D's array and AA. But classes could be also affected by this *feature* (or bug, as you wish). So we must always construct reference semantics types before passing them to functions that will modify it. For classes it's obvious but for AA and dynamic arrays is not. Another solution is to pass reference types by *ref*. So you will not have such bugs in implementation I think that we need to add warning about such case in documentation section: https://dlang.org/spec/hash-map.html#construction_and_ref_semantic in order to prevent this kind of mistakes in code.
Re: Stupid question about AA. The following code works but I don't undrstand why?!
On Saturday, 9 April 2016 at 18:27:11 UTC, ag0aep6g wrote: On Saturday, 9 April 2016 at 18:06:52 UTC, Uranuz wrote: Thanks. It's clear now. AA holds not `array struct` itself inside, but pointer to it. How the array is stored in the AA doesn't matter, as far as I can see. The point is that you obtain a pointer to the array struct in the AA, not a copy. If you had tried it like the following, mapElem would be a copy of the array struct in the AA, and the append would not affect mapka["item"]: string[] mapElem = "item" in mapka ? mapka["item"] : (mapka["item"] = []); mapElem ~= ["dog", "cat", "horse", "penguin", "fish", "frog"]; So reallocation affects ptr to allocated memory but not pointer to `array struct`. I think that's it. Correct. Another observation is illustrated with the foloving code: http://dpaste.dzfl.pl/8d68fd5922b7 Because AA and arrays are not created before they were assigned some value it leads to inconsistency in behavior. And will produce unexpected and hidden bugs that is not good. It's not very good side of D's array and AA. But classes could be also affected by this *feature* (or bug, as you wish). So we must always construct reference semantics types before passing them to functions that will modify it. For classes it's obvious but for AA and dynamic arrays is not. Another solution is to pass reference types by *ref*. So you will not have such bugs in implementation
Re: Stupid question about AA. The following code works but I don't undrstand why?!
On Saturday, 9 April 2016 at 16:44:06 UTC, ag0aep6g wrote: On 09.04.2016 18:13, Uranuz wrote: http://dpaste.dzfl.pl/523781df67ab For reference, the code: import std.stdio; void main() { string[][string] mapka; string[]* mapElem = "item" in mapka; //Checking if I have item if( !mapElem ) mapElem = &( mapka["item"] = [] ); //Creating empty element inside map writeln( (*mapElem).capacity ); //Appending should reallocate, so pointer to array should change *mapElem ~= ["dog", "cat", "horse", "penguin", "fish", "frog"]; //But AA still somehow knows the right pointer writeln(mapka); //It works, but I dont understand why? } mapElem is not a pointer to the elements of the array. It's a pointer to the dynamic array structure which holds the pointer to the data and the length. That means, the reallocation doesn't change mapElem. It changes (*mapElem).ptr. Thanks. It's clear now. AA holds not `array struct` itself inside, but pointer to it. So reallocation affects ptr to allocated memory but not pointer to `array struct`. I think that's it.
Stupid question about AA. The following code works but I don't undrstand why?!
I am stupid today :) So I have a question. The piece of code given: http://dpaste.dzfl.pl/523781df67ab It looks good, but I don't understand why it works?
Need some help about error that I don't understand
In my custom multithreaded web-server (non vibe-based) I got error that is strange for me. I've was looking for a reason running app under GDB, but I don't understand how to interpret what I've got. It's interesting that it fails (without any error or segfault message) in the case when null reference to class object passed into static method of class. When it's not null all goes well. So there is backtrace: //--- (gdb) thread apply all bt Thread 4 (Thread 0x71cb1700 (LWP 30869)): #0 sem_wait () at ../nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S:85 #1 0x0084747f in core.thread.suspend() () #2 0x00839467 in thread_suspendAll () #3 0x0082bd88 in gc.gc.Gcx.fullcollect() () #4 0x0082a43d in gc.gc.Gcx.bigAlloc() () #5 0x00827ca5 in gc.gc.GC.malloc() () #6 0x007f36cc in gc_malloc () #7 0x007f09f0 in core.memory.GC.malloc() () #8 0x008321cf in std.array.__T14arrayAllocImplVbi0TAhTmZ.arrayAllocImpl() () #9 0x008321a1 in std.array.__T18uninitializedArrayTAhTymZ.uninitializedArray() () #10 0x00806724 in std.file.readImpl() () #11 0x00780b49 in std.file.__T4readTAyaZ.read() () #12 0x0073357c in mkk_site.utils.getPageTemplate() () #13 0x00733243 in mkk_site.utils.getGeneralTemplate() () #14 0x0072ed8f in mkk_site.uri_page_router.MKK_Site_URIPageRouter.renderMessageBody() () #15 0x0072ecba in mkk_site.uri_page_router.MKK_Site_URIPageRouter.customProcessRequest() () #16 0x0079fa03 in webtank.net.http.handler.EventBasedHTTPHandler.processRequest() () #17 0x0079fc43 in webtank.net.http.handler.HTTPRouter.customProcessRequest() () #18 0x0079fa03 in webtank.net.http.handler.EventBasedHTTPHandler.processRequest() () #19 0x00755692 in webtank.net.web_server.WorkingThread._work() () #20 0x008257de in core.thread.Thread.run() () #21 0x00825422 in thread_entryPoint () #22 0x775ba182 in start_thread (arg=0x71cb1700) at pthread_create.c:312 #23 0x770df47d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:111 Thread 3 (Thread 0x724b2700 (LWP 30860)): #0 __lll_lock_wait () at ../nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:135 #1 0x775bc672 in _L_lock_953 () from /lib/x86_64-linux-gnu/libpthread.so.0 #2 0x775bc4da in __GI___pthread_mutex_lock (mutex=0xac58a0) at ../nptl/pthread_mutex_lock.c:114 #3 0x007f33b1 in core.sync.mutex.Mutex.lock_nothrow() () #4 0x00827445 in gc.gc.GCMutex.lock() () #5 0x00827c52 in gc.gc.GC.malloc() () #6 0x007f36cc in gc_malloc () #7 0x007f09f0 in core.memory.GC.malloc() () #8 0x0075985c in std.array.__T14arrayAllocImplVbi0TAaTmZ.arrayAllocImpl() () #9 0x00759839 in std.array.__T18uninitializedArrayTAaTmZ.uninitializedArray() () #10 0x0075981d in std.array.__T5arrayTS3std4conv47__T7toCharsVii10TaVE3std5ascii10LetterCasei1TmZ7toCharsFNaNbNiNfmZ6ResultZ.array() () #11 0x0075978b in std.array.__T5arrayTS3std4conv47__T7toCharsVii10TaVE3std5ascii10LetterCasei1TmZ7toCharsFNaNbNiNfmZ6ResultZ.array() () #12 0x00719122 in std.conv.__T6toImplTAyaTmZ.toImpl() () #13 0x007190b3 in std.conv.__T6toImplTAyaTmZ.toImpl() () #14 0x00719099 in std.conv.__T2toTAyaZ.__T2toTmZ.to() () #15 0x007d1f04 in webtank.common.logger.FileLogger.writeEvent() () #16 0x007d2183 in webtank.common.logger.ThreadedLogger._run() () #17 0x007d4141 in std.concurrency.Message.__T3mapTDFS7webtank6common6logger8LogEventZvZ.map() () #18 0x007d3a79 in std.concurrency.MessageBox.__T3getTDFS7webtank6common6logger8LogEventZvTDFNaNbNiNfS7webtank6common6logger14ThreadedLogger10LogStopMsgZvTDFC3std11concurrency15OwnerTerminatedZvZ.get() () #19 0x007d3e79 in std.concurrency.MessageBox.__T3getTDFS7webtank6common6logger8LogEventZvTDFNaNbNiNfS7webtank6common6logger14ThreadedLogger10LogStopMsgZvTDFC3std11concurrency15OwnerTerminatedZvZ.get() () #20 0x007d39a6 in std.concurrency.MessageBox.__T3getTDFS7webtank6common6logger8LogEventZvTDFNaNbNiNfS7webtank6common6logger14ThreadedLogger10LogStopMsgZvTDFC3std11concurrency15OwnerTerminatedZvZ.get() () #21 0x007d380b in std.concurrency.__T7receiveTDFS7webtank6common6logger8LogEventZvTDFNaNbNiNfS7webtank6common6logger14ThreadedLogger10LogStopMsgZvTDFC3std11concurrency15OwnerTerminatedZvZ.receive() () #22 0x007d215b in webtank.common.logger.ThreadedLogger._run() () #23 0x007d237d in std.concurrency.__T6_spawnTPFS3std11concurrency3TidOC7webtank6common6logger6LoggerZvTS3std11concurrency3TidTOC7webtank6common6logger6LoggerZ._spawn() () ---Type to continue, or q to quit--- #24 0x008257de in core.thread.Thread.run() () #25 0x00825422 in thread_entryPoint () #26 0x775ba182 in start_thread
Re: Need some help about error that I don't understand
On Friday, 5 February 2016 at 17:39:55 UTC, Uranuz wrote: In my custom multithreaded web-server (non vibe-based) I got error that is strange for me. I've was looking for a reason running app under GDB, but I don't understand how to interpret what I've got. It's interesting that it fails (without any error or segfault message) in the case when null reference to class object passed into static method of class. When it's not null all goes well. So there is backtrace: //--- (gdb) thread apply all bt Thread 4 (Thread 0x71cb1700 (LWP 30869)): #0 sem_wait () at ../nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S:85 #1 0x0084747f in core.thread.suspend() () #2 0x00839467 in thread_suspendAll () #3 0x0082bd88 in gc.gc.Gcx.fullcollect() () #4 0x0082a43d in gc.gc.Gcx.bigAlloc() () #5 0x00827ca5 in gc.gc.GC.malloc() () #6 0x007f36cc in gc_malloc () #7 0x007f09f0 in core.memory.GC.malloc() () #8 0x008321cf in std.array.__T14arrayAllocImplVbi0TAhTmZ.arrayAllocImpl() () #9 0x008321a1 in std.array.__T18uninitializedArrayTAhTymZ.uninitializedArray() () #10 0x00806724 in std.file.readImpl() () #11 0x00780b49 in std.file.__T4readTAyaZ.read() () #12 0x0073357c in mkk_site.utils.getPageTemplate() () #13 0x00733243 in mkk_site.utils.getGeneralTemplate() () #14 0x0072ed8f in mkk_site.uri_page_router.MKK_Site_URIPageRouter.renderMessageBody() () #15 0x0072ecba in mkk_site.uri_page_router.MKK_Site_URIPageRouter.customProcessRequest() () #16 0x0079fa03 in webtank.net.http.handler.EventBasedHTTPHandler.processRequest() () #17 0x0079fc43 in webtank.net.http.handler.HTTPRouter.customProcessRequest() () #18 0x0079fa03 in webtank.net.http.handler.EventBasedHTTPHandler.processRequest() () #19 0x00755692 in webtank.net.web_server.WorkingThread._work() () #20 0x008257de in core.thread.Thread.run() () #21 0x00825422 in thread_entryPoint () #22 0x775ba182 in start_thread (arg=0x71cb1700) at pthread_create.c:312 #23 0x770df47d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:111 Thread 3 (Thread 0x724b2700 (LWP 30860)): #0 __lll_lock_wait () at ../nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:135 #1 0x775bc672 in _L_lock_953 () from /lib/x86_64-linux-gnu/libpthread.so.0 #2 0x775bc4da in __GI___pthread_mutex_lock (mutex=0xac58a0) at ../nptl/pthread_mutex_lock.c:114 #3 0x007f33b1 in core.sync.mutex.Mutex.lock_nothrow() () #4 0x00827445 in gc.gc.GCMutex.lock() () #5 0x00827c52 in gc.gc.GC.malloc() () #6 0x007f36cc in gc_malloc () #7 0x007f09f0 in core.memory.GC.malloc() () #8 0x0075985c in std.array.__T14arrayAllocImplVbi0TAaTmZ.arrayAllocImpl() () #9 0x00759839 in std.array.__T18uninitializedArrayTAaTmZ.uninitializedArray() () #10 0x0075981d in std.array.__T5arrayTS3std4conv47__T7toCharsVii10TaVE3std5ascii10LetterCasei1TmZ7toCharsFNaNbNiNfmZ6ResultZ.array() () #11 0x0075978b in std.array.__T5arrayTS3std4conv47__T7toCharsVii10TaVE3std5ascii10LetterCasei1TmZ7toCharsFNaNbNiNfmZ6ResultZ.array() () #12 0x00719122 in std.conv.__T6toImplTAyaTmZ.toImpl() () #13 0x007190b3 in std.conv.__T6toImplTAyaTmZ.toImpl() () #14 0x00719099 in std.conv.__T2toTAyaZ.__T2toTmZ.to() () #15 0x007d1f04 in webtank.common.logger.FileLogger.writeEvent() () #16 0x007d2183 in webtank.common.logger.ThreadedLogger._run() () #17 0x007d4141 in std.concurrency.Message.__T3mapTDFS7webtank6common6logger8LogEventZvZ.map() () #18 0x007d3a79 in std.concurrency.MessageBox.__T3getTDFS7webtank6common6logger8LogEventZvTDFNaNbNiNfS7webtank6common6logger14ThreadedLogger10LogStopMsgZvTDFC3std11concurrency15OwnerTerminatedZvZ.get() () #19 0x007d3e79 in std.concurrency.MessageBox.__T3getTDFS7webtank6common6logger8LogEventZvTDFNaNbNiNfS7webtank6common6logger14ThreadedLogger10LogStopMsgZvTDFC3std11concurrency15OwnerTerminatedZvZ.get() () #20 0x007d39a6 in std.concurrency.MessageBox.__T3getTDFS7webtank6common6logger8LogEventZvTDFNaNbNiNfS7webtank6common6logger14ThreadedLogger10LogStopMsgZvTDFC3std11concurrency15OwnerTerminatedZvZ.get() () #21 0x007d380b in std.concurrency.__T7receiveTDFS7webtank6common6logger8LogEventZvTDFNaNbNiNfS7webtank6common6logger14ThreadedLogger10LogStopMsgZvTDFC3std11concurrency15OwnerTerminatedZvZ.receive() () #22 0x007d215b in webtank.common.logger.ThreadedLogger._run() () #23 0x007d237d in std.concurrency.__T6_spawnTPFS3std11concurrency3TidOC7webtank6common6logger6LoggerZvTS3std11concurrency3TidTOC7webtank6common6logger6LoggerZ._spawn() () ---Type to continue, or q to quit--- #24 0x008257de in core.thread.Thread.run() () #25 0x00825422 in
Question about OutputRange and std.range: put
Hello to forum readers! I have a question about using OutputRange and std.range: put. I have the following code snippet to illustrate my question: import std.range, std.stdio, std.string; void main() { string greating = "Hello, " ; string username = "Bob"; put(greating, username); put(greating, "!"); writeln(greating); } It doesn't compile. It says following: Compilation output: /opt/compilers/dmd2/include/std/range/primitives.d(335): Error: static assert "Cannot put a string into a string." /d52/f530.d(8):instantiated from here: put!(string, string) Documentation about std.range.put says that one of code snippets, where *put* applies is when second argument is array of elements (If I understand it correctly with my knowledge of English). Especially the following line is there in doc for usage scenario: r.doPut([ e ]); R specifically accepts an E[]. Can I put range or array f elements as second argument of put or it works only at per element basis? I think writing multiple items at a time should be more effective but maybe it's not supported for OutputRange? Could someone explain?
Re: Question about OutputRange and std.range: put
On Saturday, 16 January 2016 at 16:14:56 UTC, Jonathan M Davis wrote: On Saturday, January 16, 2016 12:11:11 Uranuz via Digitalmars-d-learn wrote: [...] There are a few problems here. First off, when put is used with an array, it fills the array. It doesn't append to it. So, you can't use a string as an output range, since its elements are immutable. Here's an example with int[]: [...] Thanks for your response. After looking for some time in Phobos documentation I already found that it would be better to use Appender for this purpose. As far as I understand it allocates less often and I can reserve some memory from the start. I'll take this possibility into account when I'll do further small optimisations. Thanks again.
Re: Problem with using struct ranges with @disabled this(this) with some range functions
On Wednesday, 2 September 2015 at 07:34:15 UTC, Mike Parker wrote: On Wednesday, 2 September 2015 at 06:28:52 UTC, Uranuz wrote: As far as I understand to save current cursor of forward range I should always use *save* property. But sometimes range struct is just copied using postblit without using save (it happens even in Phobos). Is it correct behaviour to *pass ownership* for range structs via just copying of range or not. As I think for at least *forward* ranges that are structs we must always use save methot to store new cursor. But for *input* ranges it is not possible, so there maybe plain copying could be allowed. I thing that we should work out some descision on this problem, provide some unittests for different types of ranges with and without postblit for standard Phobos functions and fix them accordingly. I have problem with std.range.take function and forward range with disabled postblit and I don't understand is it my or library bug? My understanding is that one underlying assumption in Phobos about ranges is that they are lightweight and single-minded -- they should carry no state other than what is necessary to fulfill the range interface they provide. This follows from the idea that, given a container, you do not slap a range interface on the container type and pass container instances to range-based functions, but instead implement a range type separate from the container that knows where the elements of the container begin and end and nothing else. They do not carry the elements of the container around with them. Looking at ranges from that angle, the need to disable postblit on a range type would be a special case. That raises the question, for what reason have you disabled postblit on your range type? Is it not possible for you to create a lightweight range from your data? I want to understand if we have *save* method in Forward Range then why or in which cases we should use plain struct copying instead. Should we assume that these two ways are equal or not? Also as far as I understand behaviour for Input Ranges vs Forward Ranges would be different, because you could not store cursor on object like network data stream, because as soon as you read from it you cannot save some range that will point on previous bytes in network stream, because they are gone if you read them. So for Input Range copy will always point on current state, but not previois state, that was saved before in another range pointing to the same source. For Forward Range we have ability to save cursor position and return to it later. In this case would copying via postblit would be equal to *save* method or would be similar as for Input Range.
Problem with using struct ranges with @disabled this(this) with some range functions
As far as I understand to save current cursor of forward range I should always use *save* property. But sometimes range struct is just copied using postblit without using save (it happens even in Phobos). Is it correct behaviour to *pass ownership* for range structs via just copying of range or not. As I think for at least *forward* ranges that are structs we must always use save methot to store new cursor. But for *input* ranges it is not possible, so there maybe plain copying could be allowed. I thing that we should work out some descision on this problem, provide some unittests for different types of ranges with and without postblit for standard Phobos functions and fix them accordingly. I have problem with std.range.take function and forward range with disabled postblit and I don't understand is it my or library bug?
Re: Passing reference data to class and incapsulation
On Friday, 28 November 2014 at 08:31:26 UTC, bearophile wrote: Uranuz: Same situation happens when I assign reference data to properties. Someone has suggested to solve this problem with an attribute, like owned, that forbids to return mutable reference data owned by a class/struct instance. Bye, bearophuile Yes. Problem is even if you have property that controls correct assignment. If you have getter that returns mutable reference type and you try to access some fields of it or apply index operator (for arrays or AA) *host* cannot control corectness of these assignments or cannot react to these changes (in order to do some changes in model). The way I see is to create my own type of Array for this that can notify *host object* about changes so it could refresh the model or do some checks. Another way is to write interfaces in a way so we cant't escape uncontrolled references to mutable data. What do you think of it? Is there any patterns that could help to solve such problems? I think that writing your own type every time when you need to enforce consistency and safety is not very good))
Passing reference data to class and incapsulation
In D we a several data types which are passed by reference: dynamic arrays, associative arrays. And sometimes we need to pass these reference data to class instance to store it inside. One of the principles of object-oriented programming is incapsulation. So all class data should be only modyfiable via class methods and properties. But I we pass reference data to class (for example as parameter in constructor) we still can change these data from initial code and break some internal logic of class for modifying these data. Example: class Foo { this(int[] b) { bar = b; } private int[] bar; //Some methods } void main() { int[] bar = [1,2,3,4,5]; Foo foo = new Foo(bar); //There I could do some logic with class bar[2] = 6; //I modify class without some checks from class //And there I might pass *bar* somewhere outside and break incapsulation } Same situation happens when I assign reference data to properties. I can check or do something with data at the moment of assignment, but I can't control that someone will modify using initial reference from outside. So do you copy reference data in constructors or properties? Should it be? Or call site should be responsible for not escaping reference somewhere outside and not modifying these data badly? There also possible some situations when these data should be shared between different pieces of code (for example different class instance could reference the same memory area). But I think this is not very good and safe approach and should be avoided if possible. But I think storing reference to class inside another class could be good approach because there could be different type of relations between classes. For plain data types we often have types of relations: *ownership* or *aggregation*. But classes can usualy have more types of relations: *usage* or when one class subscribes for events of another. Is there some good links to read for these questions that you could advice. After several hours of googling I haven't found good topics about these problems. And I have not enough time for reading big book.
Question about eponymous template trick
I have an example of code like this: template Node(String) { struct Node {} struct Name {} struct Attr {} } void main() { alias MyNode = Node!(string).Node; alias MyName = Node!(string).Name; alias MyAttr = Node!(string).Attr; } This code fails during compilation with message: Compilation output: /d228/f410.d(12): Error: no property 'Node' for type 'Node!string' /d228/f410.d(12): Error: no property 'Node' for type 'Node!string' /d228/f410.d(13): Error: no property 'Name' for type 'Node!string' /d228/f410.d(13): Error: no property 'Name' for type 'Node!string' /d228/f410.d(14): Error: no property 'Attr' for type 'Node!string' /d228/f410.d(14): Error: no property 'Attr' for type 'Node!string' So question is: is this intended behaviour and I'm missing something about eponymous templates? Or is it a bug in compiler?
Re: Question about eponymous template trick
Looks like compiler looks for Node, Name and Attr in Node struct, because of eponymous thing. I understand it but I want to know if it is documented behaviour or not. Could anybody clear what happens with eponymous stuff and why I can't get acces to *other* declarations inside eponymous template? I guess that it is not intended behaviour.
Re: Question about eponymous template trick
I think it's the intended behavior. I think documentation is outdated. Ali Thanks. So I will modify my programme to workaround this.
Re: Question about eponymous template trick
Also I failed to find any documentation about eponymous stuff in language reference. As far as I remember it was here but now looks like it is missing.
Representing parse tree node
Now I'm working on implementation of Jinja template engine for web development on D language. http://jinja.pocoo.org I like it's explicit but still rather short syntax inherited from Python. I find it good for writing templates for web pages and other stuff such as configs or maybe CSS files. But I have a problem in my head about better way of representing parse tree node in D. So I want to ask an advice from people who have some experience in working with grammars, parsing, creating compilers, etc. Currently my lexer algorithm is implemented with small amount of allocations using plain structs everywhere. So one of my considerations is that it would be good to implement parser with as less allocations as possible or at least consolidate it in one place. In this case it could be possible to switch allocation policy easily. Now about parse tree nodes. Tree node has set of field of *Node* type, and also can be list of Nodes (Node[]) or can contain plain values (string. bool. int). One way is to implement node as struct like std.json does it. enum NodeType { /+...+/} struct Node { NodeType type; Node[string] fileds; Node[] list; //Could store plain values int integer; bool boolean; string str; float floating; Lexeme lex; //Stores info about corresponding lexeme } Some of these fields can be merged into *union* to make it more memory efficient. So there is two data types that will reallocate when I'll be operating on them: array and associative array. Another way is using of base class/interface for Node and have separate class for each node type. For example class Node { //... } class Statement: Node { //... } class Expr: Node { //... } class If : Statement { Expr test; Node body_; Node else_; } class Literal: Node { } class List: Literal { Node[] list; } class Integer: Literal { int value; } So as I see there I'll have more allocation taking class allocations into account. And what is the benefit of it if I using parse tree node as just data storing structure without methods? What is a standard apprach implementing parse tree node?
Re: How to check i
This is
Re: How to match string by word
I haven't touched any key on a keyboard and haven't pressed *Send* but message was posted somehow. Thanks. Checking for UTF-8 continuation bytes is good idea. Also I agree that UTF-16 is more difficult. I will keep it for future release when implementation will start to work properly on UTF-8 and UTF-32
How to check i
I have some string *str* of unicode characters. The question is how to check if I have valid unicode code point starting at code unit *index*? I need it because I try to write parser that operates on string by *code unit*. If more precisely I trying to write function *matchWord* that should exctract whole words (that could consist not only English letters) from text. This word then compared with word from parameter. I want to not decode if it is not necessary. But looks like I can't do it without decoding, because I need to know if current character is letter of alphabet and not punctuation or whitespace for example. There is how I think this look like. In real code I have template algorithm that operates on differrent types of strings: string, wstring, dstring. struct Lexer { string str; size_t index; bool matchWord(string word) { size_t i = index; while( !str[i..$].empty ) { if( !str.isValidChar(i) ) { i++; continue; } uint len = str.graphemeStride(i); if( !isAlpha(str[i..i+len]) ) { break; } i++; } return word == str[index..i]; } } It is just a draft of idea. Maybe it is complicated. What I want to get as a result is logical flag (matched or not) and position should be set after word if it is matched. And it should match whole words of course. How do I implement it correctly without overhead and additional UTF decodings if possible? And also how could I validate single char of string starting at code unit index? Also I don't like that graphemeStride can throw Exception if I point to wrong possition. Is there some nothrow version? I don't want to have extra allocations for exceptions.
Re: How to detect start of Unicode symbol and count amount of graphemes
Have a look here [1]. For example, if you have a byte that is between U+0080 and U+07FF you know that you need two bytes to get that whole code point. [1] http://en.wikipedia.org/wiki/UTF-8#Description Thanks. I solved it myself already for UTF-8 encoding. There choosed approach with using bitbask. Maybe it is not best with eficiency but it works) ( str[index] 0b1000 ) == 0 || ( str[index] 0b1110 ) == 0b1100 || ( str[index] 0b ) == 0b1110 || ( str[index] 0b1000 ) == 0b If it is true it means that first byte of sequence found and I can count them. Am I right that it equals to number of graphemes, or are there some exceptions from this rule? For UTF-32 number of codeUnits is just equal to number of graphemes. And what about UTF-16? Is it possible to detect first codeUnit of encoding sequence?
How to detect start of Unicode symbol and count amount of graphemes
I have struct StringStream that I use to go through and parse input string. String could be of string, wstring or dstring type. I implement function popChar that reads codeUnit from Stream. I want to have *debug* mode of parser (via CT switch), where I could get information about lineIndex, codeUnitIndex, graphemeIndex. So I don't want to use *front* primitive because it autodecodes everywhere, but I want to get info abot index of *user perceived character* in debug mode (so decoding is needed here). Question is how to detect that I go from one Unicode grapheme to another when iterating on string, wstring, dstring by code unit? Is it simple or is it attempt to reimplement a big piece of existing std library code? As a result I should just increment internal graphemeIndex. There short version of implementation that I want follows struct StringStream(String) { String str; size_t index; size_t graphemeIndex; auto popChar() { index++; if( ??? ) //How to detect new grapheme? { graphemeIndex++; } return str[index]; } } Sorry for very simple question. I just have a mess in my head about Unicode and D strings
Re: How to detect start of Unicode symbol and count amount of graphemes
You can use std.uni.byGrapheme to iterate by graphemes: http://dlang.org/phobos/std_uni.html#.byGrapheme AFAIK, graphemes are not self synchronizing, but codepoints are. You can pop code units until you reach the beginning of a new codepoint. From there, you can iterate by graphemes, though your first grapheme might be off. Maybe there is some idea how to just detect first code unit of grapheme without overhead for using Grapheme struct? I just tried to check if ch 128 (for UTF-8). But this dont work. How to check if byte is continuation of code for single code point or if new sequence started?
Re: sdlang-d can not link after updating to dmd 2.066
On Thursday, 28 August 2014 at 10:16:15 UTC, Puming wrote: I updated dub to 0.9.22 and still got the same error... THis is the output of `dub build --force`: --- output --- ## Warning for package sdlang-d ## The following compiler flags have been specified in the package description file. They are handled by DUB and direct use in packages is discouraged. Alternatively, you can set the DFLAGS environment variable to pass custom flags to the compiler, or use one of the suggestions below: -wi: Use the buildRequirements field to control warning behavior ## Warning for package sdlang-d, configuration unittest ## The following compiler flags have been specified in the package description file. They are handled by DUB and direct use in packages is discouraged. Alternatively, you can set the DFLAGS environment variable to pass custom flags to the compiler, or use one of the suggestions below: -debug: Call dub with --build=debug -unittest: Call dub with --build=unittest ## Warning for package sdlang-d ## The following compiler flags have been specified in the package description file. They are handled by DUB and direct use in packages is discouraged. Alternatively, you can set the DFLAGS environment variable to pass custom flags to the compiler, or use one of the suggestions below: -wi: Use the buildRequirements field to control warning behavior ## Warning for package sdlang-d, configuration unittest ## The following compiler flags have been specified in the package description file. They are handled by DUB and direct use in packages is discouraged. Alternatively, you can set the DFLAGS environment variable to pass custom flags to the compiler, or use one of the suggestions below: -debug: Call dub with --build=debug -unittest: Call dub with --build=unittest Building sdlang-d 0.8.4 configuration library, build type debug. Running dmd... Building haha ~master configuration application, build type debug. Compiling using dmd... Linking... Undefined symbols for architecture x86_64: _D7sdlang_3ast3Tag103__T11MemberRangeTC7sdlang_3ast3TagVAyaa7_616c6c54616773VAyaa11_746167496e646963696573VAyaa5_5f74616773Z11MemberRange11__invariantMxFZv, referenced from: _D7sdlang_3ast3Tag103__T11MemberRangeTC7sdlang_3ast3TagVAyaa7_616c6c54616773VAyaa11_746167496e646963696573VAyaa5_5f74616773Z11MemberRange30__T13opBinaryRightVAyaa2_696eZ13opBinaryRightMFAyaZb in haha.o ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation) --- errorlevel 1 FAIL .dub/build/application-debug-posix.osx-x86_64-dmd-561BEB9B9938BB39E9AD2177AB127CD0/ haha executable Error executing command build: dmd failed with exit code 1. -- end --- On Wednesday, 27 August 2014 at 16:35:18 UTC, Israel wrote: It looks fine here, OSX 10.9.4 sdlang-d: =0.8.4 Im using DUB RC2 though I get strange link errors when using scoped imports sometimes. It's often in the case when scoped import placed at the same nesting level as ising some symbol from imported module. I don't know exactly what happens here, but most of cases that I faced is about it. Other possibility is connected with calling abstract methods in classes.
Re: Question about operations on class/struct properties
I have another similar example illustrating this problem at semantic level. import std.stdio, std.typecons; struct Test { //ref Nullable!int prop() @property { return _value; } private Nullable!int _value = 10; } void main() { auto test = Test(); //This looks like I want to modify property with *nullify*, //but instead it creates variable that will never be used and modify it test.prop.nullify(); assert( test.prop.isNull ); //This fails } So when using with value types I should always look if property is *ref* or not and it's not very good. I have another question. How could I implement in this example if I uncomment it to call some function after modifying property? Do I need some sort of class wrapper for property or is there some other ideas? What I expect: void main() { auto test = Test(); test.prop.nullify(); //Callback called after this operation test.prop = 15; //Callback called after this operation too } Callback is simple method of Test like: void callback(Nullable!int value) { if( value.isNull ) //Do smth else if( value = 0 ) //Do smth else else //Just assign to internal field _value = value; } So I think it is possible to do this with some class wrapper around Nullable!int that should implement al of it's methods or for example dispatching calls to them via opDispacth. But this approach looks slightly complicated. What if I have complicated interface (for example std.datetime.Date as such property) so I need to reimplement or dispatch a lot of methods. Could you advise another more simple approach to this problem?
Question about operations on class/struct properties
I think there is something that I don't understand about concept of *properties*. I thing that property is sort of object attribute that belongs to it. Currently property considered as two functions: *get* and/or *set*. So we can do two sort of operations on concept that called *property*: *assign to it* and *read it*. If property doesn't return reference value all other manipulations are forbidden. A will illustrate it with example: import std.datetime, std.stdio; void main() { auto date = Date(1991, 5, 7); //date.day += 5; //Not working //date.day++; //Not working date.day = date.day + 1; } Because day property is of ubyte (not reference) type, we can only read it into some other variable or assign to it, but other other operations couldn't be done. It is a common case when I want to increment, decrement or using some other 'op=' - operation, but it is not working and I get compile-time error. I always was thinking that date.day++; date.day -= 5; Should be treated as: date.day = date.day + 1; date.day = date.day - 5; if the were not oveloaded. So if we have get and set property methods I see that it could be calculated and this should working. Of course I can define return value of get property as *ref* but in this case I don't understand how I should use it with *setter* method. It's interesting to see any thinkings about it.
Re: Question about operations on class/struct properties
On Monday, 18 August 2014 at 18:07:09 UTC, Phil Lavoie wrote: All you said makes sense. If there is a direct connection between getter, setter and member than yes, returning it by reference is usually more convenient: private T _member; @property ref inout(T) member() inout {return _member;} However, sometimes, there is no direct connection between field and mutators. Sometimes, it is calculated on the fly. Yes. As you said often it calculated on the fly. And sometimes when setting some value you need to trigger some *event handler*. This is one of use cases that properties were designed in different languages. Another case is to check value and throw exception or something else. So using getter that returns reference is very close to just exposing class/ struct field and allowing to modify it directly. I think that *setter* should shadow *ref getter* in opAssign and opOpAssign expressions. And opOpAssign should rewrite into *read - execute operation - write* sequence. Also I have another interesting question. For example I have some struct (value object) that has method, that modifies it's state. Then I declare some class/ struct that has property of value type. Problem is that logically I could expect that this method should modify property of class, but instead some value return from property method returned (by value) and then it is was modified. I'll give short illustration. struct PropType { }
Re: Question about operations on class/struct properties
I posted it suddenly. I don't know why. I'll give short illustration. struct PropType { void append(int value) { //implementation } } class Test { PropType myProp() @property { return _propValue; } private PropType _propValue; } void main() { Test test = new Test; //This line looks like I want to append value //to field of *test* object. But it cant't modify //it and just doing useless job. test.myProp.append(10); } I don't know intentions of language designers in part of properties. But in this code I see some logical contradiction. What I see and thinking of this line of code it is not what it really does. I don't know much about properties behaviour in different languages but there is something that confuses me. I believe that this problem deserves more attention. There are 5 DIP's in dlang wiki. So I think it's important
Re: Help with porting grammar from PEGjs to D for dustjs project!
What I was thinking about is possibility to change ParseTree struct with user-defined version of it. And I was thinking about setting tree type as template parameter to grammar: grammar!(MyParseTree)( Arithmetic: ... ); Or somethink like this. I think changing source code of library in order to change tree type is not good and should be set as parameter. If it's already implemented please let me knoe because I couldn't find it. And also some minimal interface is needed to be described in documentation for ParseTree (may be ability to set it as class is good in order to have polymorthic nodes with different methods and properties). Of course I can transform PEGGED syntactic tree into another form of tree specified by usage domain. But if it doesn't significantly differs from PEGGED tree (for example node have a pair of additional properties) it only causes into additional memory consumption and CPU to transform tree. But if domain specific tree differs a lot of course we need some useful way to transform trees.
Re: Help with porting grammar from PEGjs to D for dustjs project!
Different formats and also different languages. I don't see how you can compare a parse tree that's a D object and another tree made by dustjs: you never see the AST produced by dust, you only see the resulting JS code. Yes. That's a point. Thanks for all the explanations. I'll try to make something useful of it.
Re: Help with porting grammar from PEGjs to D for dustjs project!
On Tuesday, 5 August 2014 at 08:13:25 UTC, Uranuz wrote: Different formats and also different languages. I don't see how you can compare a parse tree that's a D object and another tree made by dustjs: you never see the AST produced by dust, you only see the resulting JS code. Yes. That's a point. Thanks for all the explanations. I'll try to make something useful of it. Is there multiline comments available inside PEGGED template? As far as I understand inline comments are set via # sign.
Help with porting grammar from PEGjs to D for dustjs project!
I want to try to implement web template engine dustjs: http://akdubya.github.io/dustjs/ At the first step implementing parser for it's grammar is needed. As far as code for parsing grammar was generated via PEGjs grammar generator the resulting code is enough long (about 4200 lines of code). I though that it is productive way to make porting manually. It's long and something could change in the source JavaScript code. And it will be not so easy to maintain. So I remembered about PEGGED project for D. As I see formats for writing grammar differs for these two systems and I have no experience with using grammar generators. So I need some help with rewriting grammar from PEGjs into PEGGED. Also I don't understand in PEGGED (I have not tried to use it yet) how to generate some logic from AST. Where should I describe it or should I walk around all nodes for somehow and generate code for them. Goal of this is to use dust template system as template engine at server side. I also considered handlebars.js, but I can't evaluate what is more suitable for my purposes. The choice is just very subjective.
Re: Help with porting grammar from PEGjs to D for dustjs project!
I am real noob about grammar description languages so I need some explanation about it. As far as I understand expressions in curly bracers are used to modify syntax tree just in process of parsing instead of modifying it after? How I could use PEGGED to map some code to these parsed expressions to generate code that will perform operations defined by this grammar? Should I walk around all the syntax tree and just append code to some string and mix it in then or are there some features for code generation? Something that I was thinking about is comparision of resulting syntax tree to check if it was correctly implemented. It would be great if different gramar parsers will output result in common format (JSON or XML for example) and it will be possiple to compare them for equality. But different parsers have different internal format of tree so maybe creating some transformation is possible. With this feature it could be possible to say if parser is working correctly.
Re: How to say to compiler that I want to inherit final template bethod of base interface into derived class
On Sunday, 20 July 2014 at 12:48:09 UTC, anonymous wrote: import std.stdio; interface IBase { template getStr(string fieldName) { final string getStr() { return George; } } string getStr(string fieldName); } class Derived: IBase { alias getStr = IBase.getStr; /* order matters, see below */ override string getStr(string fieldName) { return Sam; } /* alias getStr = IBase.getStr; /* doesn't work here, I guess that's a compiler bug */ } void main() { auto obj = new Derived; assert( obj.getStr!(aaa)() == George ); assert( obj.getStr(aaa) == Sam ); } Sorry, but this example doesn't work too.
Re: How to say to compiler that I want to inherit final template bethod of base interface into derived class
On Sunday, 20 July 2014 at 16:12:20 UTC, anonymous wrote: On Sunday, 20 July 2014 at 15:48:19 UTC, Uranuz wrote: Sorry, but this example doesn't work too. Ugh, 2.065 doesn't like it, but it works for me with git head (v2.066-devel-82b031c). Where did you get it? Or you compiled it yourself? Because I tried beta4 and it doesn't work there too.
Re: Question about iteger literals
On Monday, 23 June 2014 at 18:32:38 UTC, Steven Schveighoffer wrote: On Sun, 22 Jun 2014 08:23:45 -0400, Uranuz neura...@gmail.com wrote: If these rules are not so clear and have some exceptions (but I don't understand why they are needed) then some documentation needed about this. See integer promotion rules: http://dlang.org/type.html#Integer%20Promotions And the section below it. -Steve I see these rules but when I compile following code and it fails with error it looks VERY stupid. import std.stdio; void main() { ubyte a = 15; ubyte b = 10; ubyte c = a + b; //What is happening there?! ARGH! Are you joking?! } Compilation output: /d837/f382.d(9): Error: cannot implicitly convert expression (cast(int)a + cast(int)b) of type int to ubyte I'm just crazy about it! How could it happen?!
Re: Question about iteger literals
In C/C++/D if you sum a types that are smaller than int, you obtain an int. D has copied C for backwards compatibility with C code. Bye, bearophile Is there any reasoning why this should remain unchainged? How could it break interface between languages? And also this code succesfully compiles and runs in C++. #include iostream using namespace std; int main() { unsigned short a = 15; unsigned short b = 10; unsigned short c = a + b; //There is no problem cout c endl; return 0; } As D compiler doesn't need to compile C programme and have compatible operations with types. Why we still should keep this garbage?! I don't know the right solution but I believe that previous example illustrates some contradiction in integer types system design or implementation. Why we dont promote *ulong* and *long* to int? Let's also promote string into array of ints?! Can't believe it!
Re: Question about iteger literals
I see these rules but when I compile following code and it fails with error it looks VERY stupid. import std.stdio; void main() { ubyte a = 15; ubyte b = 10; ubyte c = a + b; //What is happening there?! ARGH! Are you joking?! } Compilation output: /d837/f382.d(9): Error: cannot implicitly convert expression (cast(int)a + cast(int)b) of type int to ubyte I'm just crazy about it! How could it happen?! I just should forget about all integer type except *int*, because it make my head just explode!!!
How to say to compiler that I want to inherit final template bethod of base interface into derived class
The question is in the header: How to say to compiler that I want to inherit final template bethod of base interface into derived class? I have the following example. I know that it is maybe overcomplicated but still I need this feature in my code. import std.stdio; interface IBase { template getStr(string fieldName) { final string getStr() { return George; } } string getStr(string fieldName); } class Derived: IBase { override string getStr(string fieldName) { return Sam; } } void main() { auto obj = new Derived; writeln( obj.getStr!(aaa)() ); } Compilation output: /d907/f266.d(33): Error: obj.getStr isn't a template When I have all of these methods having the same name compiler shadows template method from the base interface. So the question is how to inherit template method without reimplementing it in derived class?
Re: How to test templates for equality?
template isMyInstanceOf(alias Templ, alias Inst) { alias Args = ???; //I don't have idea how to get it enum bool isMyInstanceOf = __traits(isSame, Templ!(Args), Inst); } Do you have any idea how to solve this? May be standad library could be improved with such type of test for template instance? Is new compiler trait is needed for solving this like alias Args = __traits(getTemplateArgumentList, Inst); or it could be solved with existing tools?
Re: How to test templates for equality?
I have another question about testing if given symbol is instance of the given template and geting it's template arguments. I'm talking about raw template symbols, but not struct or class templates. For case with struct or class template std.traits.isInstanceOf is working well. But using *raw* template is not possible for it. There is an example. import std.stdio, std.traits; template WrapperTemplate(T) {} void main() { writeln( isInstanceOf!(WrapperTemplate, WrapperTemplate!(int)) ); } Because isInstanceOf implemented as *is* expression it expects type arguments, but template is not type at all. So this is not working. As we have __traits(isSame, ...) we could make such a test, but I need to have tuple of template arguments. But I don't understand how to get them template isMyInstanceOf(alias Templ, alias Inst) { }
Re: How to test templates for equality?
Suddenly posted. I don't know why it's happened)) template isMyInstanceOf(alias Templ, alias Inst) { alias Args = ???; //I don't have idea how to get it enum bool isMyInstanceOf = __traits(isSame, Templ!(Args), Inst); } Do you have any idea how to solve this? May be standad library could be improved with such type of test for template instance?
Re: How to test templates for equality?
On Tuesday, 1 July 2014 at 05:51:17 UTC, Peter Alexander wrote: template Foo(T...) {} template Bar(T...) {} template isFoo(alias F) { enum isFoo = __traits(isSame, F, Foo); } pragma(msg, isFoo!Foo); // true pragma(msg, isFoo!Bar); // false Thanks for quick response. I really forget to look into language __traits statement.
How to test templates for equality?
I have a question. How could I know if some alias or template parameter is some template symbol. I want to not that I want to know that symbol is template symbol itself but not instance of template (std.traits.isInstanceOf give answer for that question). I'll give some example template Foo(T...) { } template isFoo(alias F) { }
Re: How to test templates for equality?
I suddenly posted it for somehow. But I hope idea is clear. How could I test if symbol is equal to some concrete template. I tried these examples: template isFoo(alias F) { enum bool isFoo = is( F == Foo ); } template isFoo(alias F) { enum bool isFoo = F == Foo; } Could you advise something to solve this?
Conflict between function and template with the same name
I have a question about this example code; import std.stdio; string getByName(string name) { return smth; } template getByName(string name) { enum //string getByName = getByName(name); } void main() { writeln(getByName!(name)); } This produces compilation output: /d967/f983.d(13): Error: forward reference of variable getByName /d967/f983.d(19): Error: template instance f983.getByName!name error instantiating Uncommenting line *//string* changes message to: Compilation output: /d976/f558.d(13): Error: recursive evaluation of getByName(name) /d976/f558.d(19): Error: template instance f558.getByName!name error instantiating Is there any reason why function and template conflict. They using different syntax to *call*. For template we have *!* but for function we don't have it. So why compiler is not able to see the difference?
Re: Conflict between function and template with the same name
import std.stdio; string getByName(string name) { return smth; } template getByName(string name) { enum getByName = .getByName(name); } void main() { writeln(getByName!(name)); } Thanks a lot! Very interesting. Do you see any reasoning why this happens?
Enum type deduction inside templates is not working
Compiler can't deduce type for template struct Pair when using it with enum argument. There is an example import std.stdio; enum Category { first, second, third }; struct Pair(F, S) { F first; S second; this(F f, S s) { first = f; second = s; } } void main() { auto p = Pair(Category.first, first); //It fails writeln(p); } Is it not working for some reason or I'm doing something wrong or is it just lack of implementation? How I could make this working without explicit specifying of types?
Re: Enum type deduction inside templates is not working
On Friday, 27 June 2014 at 06:14:48 UTC, pgtkda wrote: On Friday, 27 June 2014 at 06:12:57 UTC, pgtkda wrote: How I could make this working without explicit specifying of types? sorry, i should read better Ok. Maybe it was discussed already somewhere, but I am not god in searching in English. Is there any directions about it? How could I work around it? Should I mail some proposal or bug report for it?
Re: Enum type deduction inside templates is not working
I think, D is a typesafe language, therefore you can't use variables with no type declaration. One thing you can search for, are templates but even there you have to define a type: import std.stdio; enum Category : string { first = first} template Pair(T) { T t; T cat; } void main() { alias Pair!(string) a; a.cat = Category.first; a.t = first; writeln(a.cat, . , a.t); } Ok. I know that D is typesafe language, but I'm not going to do some implicit type casts in there, because type of Category.first is Category itself but not string or something. In this example `a.cat = Category.first;` tries to make implicit cast (I don't remember is it allowed or not)
Re: Enum type deduction inside templates is not working
Seems that I found answer myself. As far as I understand type inference is working only for template functions but not struct or class templates. This is why this not working and enum is not responsible for that. I don't know why I use D enough long but I did not remember this fact.
Re: Enum type deduction inside templates is not working
There is proposal exists for this topic http://wiki.dlang.org/DIP40
Re: Using attributes inside template instantiation
But if I write @(hello) struct Hello {} so all of the variables that have type Hello will have attribute @(hello) like come type qualifier because attribute is a part of declaration of Hello. Do I understand correctly?
Using attributes inside template instantiation
I'm trying to declare format for database record in compile time. I consider to use attributes fo this. Can I do something similar to this code? struct RecordFormat(T) {} alias Format = RecordFormat!( @(cool) int ); pragma( msg, Format ); void main() { } Or I want something strange that is not supported by language? For now I don't understand whether UDA are a part of types or they are a part of variable instance definition or something different (3rd dimension)). For example 'const int' is a type but what @attribute int is? Can it be considered as separate type or it could be binded to definition of variable only? @attribute int number; I failed to alias type alias coolInt = @(cool) int; But I can alias const int alias constInt = const int; I think I understood something wrong about attributes.
Question about iteger literals
I have the following programme import std.stdio; bool isDigit(char c) nothrow { return c = '0' c = '9'; } ushort hexValue(char c) nothrow { if( isDigit(c) ) return c - '0'; else if (c = 'a' c = 'f') return c - 'a' + 10; else if (c = 'A' c = 'F') return c - 'A' + 10; else return ushort.max; } void main() { writeln(hexValue('A')); } This example is compiling successfully in DMD 2.064 but in DMD 2.065 a got the following error: /d544/f547.d(12): Error: cannot implicitly convert expression (cast(int)c - 48) of type int to ushort /d544/f547.d(14): Error: cannot implicitly convert expression (cast(int)c - 97 + 10) of type int to ushort /d544/f547.d(16): Error: cannot implicitly convert expression (cast(int)c - 65 + 10) of type int to ushort So I have a question why these expressions are casted to int? I was thinking that result should be of char type. And it could be implicitly converted to ushort (because there is enough place to store result). Is it a bug in compiler or I should insert explicit casts?
Re: Question about iteger literals
ushort hexValue(in char c) pure nothrow @safe @nogc else return ushort.max; I understand what pure, nothrow and @safe mean there. But what @nogc changes in there so I should use this modifier? Is it logical specifier that this function can be used without garbage collector or what?
Re: Question about iteger literals
In expression return c - 'a' + 10; I could think that 10 has type int and resulting value promoted to the largest type. But I don't understand why in expression where both of arguments have type char: return c - '0'; I have resulting type int. It's very strange for me and looks very buggy)
Re: Question about iteger literals
In D operations among chars return a int. The same happens in C/C++. If you subtract a char from a char in general you can have a negative result, that can't fit in a char. So what's buggy is your thinking. Ok. Thank you! I never thought about it that way
Re: Question about iteger literals
Another stupid question. Using this logic substraction for two uint values should return int too, because it can produce negative result. Am I right or not?
Re: Question about iteger literals
On Sunday, 22 June 2014 at 11:57:48 UTC, Uranuz wrote: Another stupid question. Using this logic substraction for two uint values should return int too, because it can produce negative result. Am I right or not? Now this code import std.stdio; void main() { uint a = 50; uint b = 60; auto c = a - b; writeln(typeid(c)); } produce output uint. It's some breakage in my logic. I am thinking that all integer-like types should behave similar way. I perceive char type as ubyte, that should be printed as symbol when using functions like writeln(). But the folowing example import std.stdio; void main() { ubyte a = 50; ubyte b = 60; auto c = a - b; writeln(typeid(c)); } produces output int like you said. Why there are so complicated rules in the *new* language. It's hard to understand the logic.
Re: Question about iteger literals
If these rules are not so clear and have some exceptions (but I don't understand why they are needed) then some documentation needed about this. But I would prefer to have result of uint substraction like uint, and char substraction like char. If we will changing all the types it will be kind of mess. Using this logic we should have some bigger type for int multiplication operator to fit in result of multiplication of int.max*int.max. I know that some assembler operations do this and multiplication of two registers with byte size results in placing product into two result register. But in context of higher level programming language it's better to have better type consistensy. Or we will nead a bigger type to store product for ulong.max*ulong.max result. Is it good or not?
Re: Dub. Mercurial (bitbucket.org). Projects deployment
Thanks for all the answers) 8. I have another more simple question about rdmd utility. It takes one *.d file and searches for all dependencies. What if I need to pass independent *.d file or *.ddoc file directly to dmd compiler? How could I do that using dmd? I have no idea how I could include *.ddoc file with set of DDOC macroses. I have tried to use string mixin. mixin(import(mysettings.ddoc)); But I haven't succeed. My be compiler strips all the comments before mixing in or I doing something wrong. Another way is to use dmd.conf but I don't like this, because it's brutal way of doing so and as I think it's not compiler independent.
Dub. Mercurial (bitbucket.org). Projects deployment
I have web-application project in D language hosted on bitbucket.org. So I using Mercurial repository. I exactly have two *logical* projects but currently they are in one repo. The first is my library that includes not only D code, but also some resources like HTML-page templates (not compiled vibe's diet templates), CSS and also some JavaScript code. The second project is website itself. It also has D sources, images, CSS's, js's, etc. 1. My goal is to separate this REPO into two: library and website that depends on library. Bitbucket has option for having several private repos for user, that are visible only to users from the list of invited users. I want to publish the library under some free license. But I don't want to publish web-site repository. It's offtopic question, but can you give some advice how I could handle this? May be someone read some pages in bitbucket doc and has link :) 2. For some time I used rdmd and some small shell script for building my web-site. And also I haven't built any ddoc coments but I faced with it's necessity now. rdmd takes only one input file and then search for all import directives recursively to find all other files to compile. Problem is that I want to pass some *.ddoc file with some DDOC macro to dmd but I don't' whether it's possible, because I can pass only 1 file to rdmd. How it could be solved? 3. Then I was thinking about using dub as long as it can automatically manage dependencies and it's higher level tool. And I can maybe pass *.ddoc file with general macro with *sourceFiles* (I'm not sure about this). But I think that dub doesn't support Mercurial and working with private repos. I can download project manually from Bitbucket. But it would be good to automate this. Not all programmers working with github and even git)) May be it should be solved somehow. I could participate in it but haven't contributed anything to D yet((. And also I don't know Mercurial and Bitbucket's API. 4. Another question about dub is how project structure looks like when I use some subprojects or libraries in my project. Examples in dub repository are very very simple and don't show advantages of dub over plain using of dmd or rdmd. So for now I don't understand the idea of this tool. Maybe some examples of *big and complicated* project would help. It would be better if it uses different sources for dependencies. I would like to see source from bitbucket.org, github.org, using binary libraries, local sources - all in one dub project)) This will show that this system is useful and tasty)) 5. Also I would like to use dub for deployment some small projects: copy come files, create some folder structure, make some symbolic links, run *.css, *.js processing and minification tools, run some service daemon apps, etc. May be it can be handled with *preBuildCommands*, *postBuildCommands* directives for now and using some shell scripts or running deployment application on D)) P.S. It would be a plesure to see answers for all the items if possible, not only discussion around))
Re: Dub. Mercurial (bitbucket.org). Projects deployment
Also I have additional question to this post. 6. If I would convert my repo to git, but use anather hosting that github.org for example my own local server or bitbucket.org. How could I specify source for loading dependencies? This is unclear from dub documentation. Is it a tool for working with concrete web-repository? 7. Also I have a question about structure of folders that dub creates. I tried to implement example from vibed.org and created test web-server using dub. As I see dub is loading dependencies into ~/.dub (on Linux). In my application I have some resources that used by application at runtime. These are static data like *.html, *.css, images, *.js and other files that included in library tha I want to use in my application. What is a good approach? Create a separate working folder where I will copy all resource files or create symbolic links to folders or write paths to this library inside ~/.dup. This is all about general organization of project that is not considered very well in articles. And I don't know how it can be solved for projects on D language.