Re: Printing a C "string" with write(f)ln
On Tuesday, 9 February 2016 at 12:46:59 UTC, Whirlpool wrote: Hello, When you are using a C function (from an external library) that returns a pointer on char which is the beginning of a string (I know that C does not have a string type, that they are just arrays of chars ended by '\0'), is there a simple way to print that string with D's write(f)ln, should I use C's printf, or something else ? What is the best way ? Because if I do writefln("... %s", *pString); it only displays the first character of the string, the value that pString points to Thanks writefln et al sensibly does *not* assume that a pointer to char is a C string, for memory safety purposes. Print the result of std.string.fromStringz[1] instead: writeln(fromStringz(pString)); writefln("%s", fromStringz(pString)); [1] http://dlang.org/phobos/std_string#fromStringz
Re: Printing a C "string" with write(f)ln
On Tuesday, 9 February 2016 at 16:52:09 UTC, Gary Willoughby wrote: On Tuesday, 9 February 2016 at 12:50:27 UTC, Jakob Ovrum wrote: writefln et al sensibly does *not* assume that a pointer to char is a C string, for memory safety purposes. Print the result of std.string.fromStringz[1] instead: writeln(fromStringz(pString)); writefln("%s", fromStringz(pString)); [1] http://dlang.org/phobos/std_string#fromStringz Or use `to` like this: import std.conv; writefln("%s", pString.to!(string)); to!string behaving like that was a poor design choice[1]. Please use fromStringz. [1] https://github.com/D-Programming-Language/phobos/pull/1607
Re: How do you pass in a static array by reference?
On Monday, 8 February 2016 at 05:59:43 UTC, Enjoys Math wrote: I have several class members: Arc[4] arcs; Arc[4] arcs_2; and Id like to initialize them with the same function, so how do I "pass them in" by reference? void foo(ref Arc[4] arr) { … } The dimension can of course be templatized: void foo(size_t n)(ref Arc[n] arr) { … }
Re: How do you pass in a static array by reference?
On Monday, 8 February 2016 at 06:01:24 UTC, Jakob Ovrum wrote: On Monday, 8 February 2016 at 05:59:43 UTC, Enjoys Math wrote: I have several class members: Arc[4] arcs; Arc[4] arcs_2; and Id like to initialize them with the same function, so how do I "pass them in" by reference? void foo(ref Arc[4] arr) { … } The dimension can of course be templatized: void foo(size_t n)(ref Arc[n] arr) { … } Alternatively you can take a slice of the fixed-length array: void foo(Arc[] arr) { … } foo(arcs[]); foo(arcs_2[]);
Re: What's going to replace std.stream?
On Saturday, 6 February 2016 at 06:29:56 UTC, cy wrote: Let's say I have a socket, and a file, and I want to send the contents of that file to the socket. What's the best way to do that? Yes I'm aware that in Linux, you can use a combination of a pipe and splice(2) to keep all buffers kernel side for that, but I was thinking more generally. The traditional C way is to read() into a buffer, then write() it out, until the input is exhausted. But apparantly in D we're not supposed to do that? It's just that I tried to use std.stream, and found that the whole module had been marked as deprecated some time last year. What exactly is going to replace it? Some sort of lazy file contents accessor, that can take advantage of zero copy things like splice() when hooked together? A source/sink paradigm maybe? I don't see anything analagous to what std.stream does in phobos... has it just not been made public yet? There are some third party libraries that implement streams [1], but your example can be done like: foreach(chunk; File("path/to/file").byChunk(16 * 1024)) socket.write(chunk); [1] e.g. http://code.dlang.org/packages/io
Re: Types as keys
On Tuesday, 26 January 2016 at 15:54:14 UTC, Voitech wrote: How to handle this correctly? Make BaseParser the value type of the AA. Parser!Foo and Parser!Bar are subtypes of BaseParser. Unlike Java, just `Parser` is not a type but a template. It must be instantiated to create a type. Java implements generics differently from templates, with its own set of disadvantages and advantages.
Re: Ranges: How to take N last of elements of range
On Saturday, 26 December 2015 at 05:31:59 UTC, Ur@nuz wrote: On Friday, 25 December 2015 at 20:06:04 UTC, drug wrote: 25.12.2015 17:13, Ur@nuz пишет: [...] You can do following http://dpaste.dzfl.pl/41c57f89a5a0 The reason of compile error is your using a range as a separator, change it to single symbol and it works. Also I used 'array' after 'take' to make range bidirectional to let next 'retro' works. And 'join' joins result to string with '.' as a separator. Thanks for reply. This is useful https://github.com/D-Programming-Language/phobos/pull/3855
Re: Most performant way of converting int to string
On Tuesday, 22 December 2015 at 17:23:11 UTC, Andrew Chapman wrote: On Tuesday, 22 December 2015 at 17:18:16 UTC, cym13 wrote: On Tuesday, 22 December 2015 at 17:15:27 UTC, Andrew Chapman wrote: Sorry if this is a silly question but is the to! method from the conv library the most efficient way of converting an integer value to a string? e.g. string s = to!string(100); I'm seeing a pretty dramatic slow down in my code when I use a conversion like this (when looped over 10 million iterations for benchmarking). Cheers! Out of curiosity a slow down compared to what? No conversion at all? Yeah, if I include a simple conversion in my loop: for({int i; i = 0;} i < num; i++) { //string s = to!string(i); Customer c = Customer(i, "Customer", "", i * 2); string result = objS.serialize(c); } If I uncomment the "string s" line I'm seeing a 20% increase in running time, which given what's going on the rest of the code is quite surprising. I've tried compiling with both dmd and ldc2 - it's the same under both. Cheers. Dynamic memory allocation is expensive. If the string is short-lived, allocate it on the stack: enum maxDigits = to!string(ulong.max).length; foreach(i; 0 .. num) { char[maxDigits] buffer = void; auto c = Customer(sformat(buffer[], "%s", i)); string result = objS.serialize(c); } Note that this is unsafe if the string (sformat's return value) outlives the loop iteration, as this is `buffer`'s scope.
Re: Most performant way of converting int to string
On Wednesday, 23 December 2015 at 11:21:32 UTC, Jakob Ovrum wrote: Dynamic memory allocation is expensive. If the string is short-lived, allocate it on the stack: See also std.conv.toChars[1] for stringifying lazily/on-demand. http://dlang.org/phobos/std_conv#toChars
Re: Multiple selective imports on one line
On Wednesday, 23 December 2015 at 10:51:52 UTC, earthfront wrote: I'm using hackerpilot's excellent textadept plugin + DCD, Dfmt, and Dscanner. Upon saving files, it produces suggestions, much like warnings from the compiler. One suggestion is to use selective imports in local scopes. OK, I'll do that. Now I'm left with a smattering of lines which are just selective imports from a single module: void foo() { import std.exception:enforce; import std.algorithm:array; import std.algorithm.iteration:filter; import std.functional:memoize; //..Work.. } What is the proper way to combine these into one line? There's no `array` in std.algorithm, and I don't see more than one import per module in your example, but I'm guessing what you want is: import mod : a, b, c; // import a, b and c from mod
Re: C string to D without memory allocation?
On Monday, 21 December 2015 at 08:35:22 UTC, Jonathan M Davis wrote: There's also fromStringz that Jakob suggests using elsewhere in this thread, but that really just boils down to return cString ? cString[0 .. strlen(cString)] : null; So, using that over simply slicing is primarily for documentation purposes, though it does make it so that you don't have to call strlen directly or check for null before calling it. To add to this, the main motivation behind `fromStringz` is that `cString` is often a non-trivial expression, such as a function call. With `fromStringz`, this expression can always be put in the argument list and it will only be evaluated once. Otherwise a variable has to be added: auto cString = foo(); return cString[0 .. strlen(cString)];
Re: C string to D without memory allocation?
On Monday, 21 December 2015 at 06:00:45 UTC, Shriramana Sharma wrote: I suppose what you mean is, the onus of guaranteeing that const(char)* refers to a null-terminated string is upon the person calling the to! function? Yes I understand, and Phobos documentation does say that using a pointer for input makes this "@system". Wouldn't it be better to just reject pointer as input and force people to use fromStringz? It could also simply have done the same as format("%p", p). The problem isn't that to!string is too accepting, but that it makes an unsafe assumption with an inconspicuous, generic interface. I see that "%s".format(str) where str is a const(char)* just prints the pointer value in hex. So perhaps one should say that std.format just treats it like any other pointer (and not specifically that it treats it as a pointer to a single char)? Indeed.
Re: C string to D without memory allocation?
On Monday, 21 December 2015 at 05:41:31 UTC, Shriramana Sharma wrote: Rikki Cattermole wrote: string myCString = cast(string)ptr[0 .. strLen]; Thanks but does this require that one doesn't attempt to append to the returned string using ~= or such? In which case it is not safe, right? Growing operations like ~= will copy the array to a GC-allocated, druntime-managed array if it isn't one already.
Re: C string to D without memory allocation?
On Monday, 21 December 2015 at 05:34:07 UTC, Shriramana Sharma wrote: Hello. I have the following code: import std.stdio, std.conv; extern(C) const(char) * textAttrN(const (char) * specString, size_t n); string textAttr(const(char)[] specString) { const(char) * ptr = textAttrN(specString.ptr, specString.length); writeln(ptr); return to!string(ptr); } void main() { auto s = textAttr("w /g"); writeln(s.ptr); } Now I'm getting different pointer values printed, like: 7F532A85A440 7F532A954000 Is it possible to get D to create a D string from a C string but not allocate memory? I thought perhaps the allocation is because C does not guarantee immutability but a D string has to. So I tried changing the return type of textAttr to const(char)[] but I find it is still allocating for the return value. Is this because a slice can potentially be appended to but it may overflow a C buffer? Finally, I just want to return a safe D type encapsulating a C string but avoid allocation – is it possible or not? Thanks! Use std.string.fromStringz. to!string assumes that pointers to characters are null-terminated strings which is not safe or general (unlike std.format, which safely assumes they are pointers to single characters); it is a poor design. fromStringz is explicit about this assumption. That said, to!string shouldn't allocate when given immutable(char)*.
Re: function without "this" cannot be const?
On Monday, 21 December 2015 at 02:03:14 UTC, Shriramana Sharma wrote: I'm trying to interface to a C function: extern(C) const char * textAttrN(const char * specString, size_t n); and getting the error: Error: function .textAttrN without 'this' cannot be const Please advise as to what I'm doing wrong?! :-( Change it to: extern(C) const(char)* textAttrN(const char * specString, size_t n); ^^
Re: C string to D without memory allocation?
On Monday, 21 December 2015 at 05:39:32 UTC, Rikki Cattermole wrote: size_t strLen = ...; char* ptr = ...; string myCString = cast(string)ptr[0 .. strLen]; I can't remember if it will include the null terminator or not, but if it does just decrease strLen by 1. Strings from C libraries shouldn't be casted to immutable. If the characters of the C string are truly immutable, mark it as immutable(char)* in the binding (and needless to say, use fromStringz instead of explicit counting when the length isn't known).
Re: C string to D without memory allocation?
On Monday, 21 December 2015 at 05:43:04 UTC, Rikki Cattermole wrote: On 21/12/15 6:41 PM, Shriramana Sharma wrote: Rikki Cattermole wrote: string myCString = cast(string)ptr[0 .. strLen]; Thanks but does this require that one doesn't attempt to append to the returned string using ~= or such? In which case it is not safe, right? Correct, ~= should only be used by GC controlled memory. Which this is not. This is just plain wrong. No idea where you got this from.
Re: exit(1)?
On Thursday, 17 December 2015 at 07:33:36 UTC, Jacob Carlborg wrote: I agree with that, but why don't the runtime register a function with "atexit" that cleans up everything? I think it might be possible, but it doesn't sound trivial. In particular, all threads and fibers managed by druntime need to have their stacks rewinded.
Re: No documentation for core.sys?
On Thursday, 17 December 2015 at 03:40:02 UTC, Shriramana Sharma wrote: In my recent search for D's equivalent of isatty, I found out that there is a core.sys.posix module only by rgrepping under /usr/include/dmd. Why isn't there a documentation page http://dlang.org/phobos/core_sys.html whereas lots of other core.* modules are documented? core.sys contains packages with system-specific D interface files (ports of header files). As with core.stdc, refer to the documentation for the equivalent C header.
Re: Using a struct as a wrapper for an extern(C) opaque type, no default constructor, what do?
On Thursday, 17 December 2015 at 04:05:30 UTC, Jeremy DeHaan wrote: http://dpaste.com/3FH3W13 Also, I would be wary of lazy initialization. We have bad experiences with it for AAs and standard containers. A typical example would be: void foo(Wrapper w) { ... w.doTheThing(); ... } void main() { Wrapper w; foo(); w.inspect(); // `w` is still a null reference here }
Re: Using a struct as a wrapper for an extern(C) opaque type, no default constructor, what do?
On Thursday, 17 December 2015 at 04:05:30 UTC, Jeremy DeHaan wrote: Thanks. I guess what bugs me is that I always try to hide the fact that the API is a wrapper around C stuff, ie, I want to make people feel as though they're using idiomatic D. Doing something like this makes it feel like less idiomatic D and more like a wrapper. I think I have a solution that I like in my own case though. Right now I'm considering something like this: http://dpaste.com/3FH3W13 I completely understand your sentiment, but I don't see how default construction factors into it. D libraries that *aren't* wrappers around C libraries have the same restriction and have to make the same interface choices. Or did you mean something else? Your code looks good, but make sure you either disable postblit or implement the postblit operator appropriately. The Rule of Three applies well to D.
Re: Using a struct as a wrapper for an extern(C) opaque type, no default constructor, what do?
On Thursday, 17 December 2015 at 06:04:14 UTC, Jeremy DeHaan wrote: And I guess what I was talking about before is that using a factory method feels klunky to me. If the things I am wrapping had been written in D they could use default initialization, so it feels wrong to do otherwise. I also just don't really like factory methods. They feel like a workaround that the end user has to deal with. But that's just me. If the type you're wrapping would still be accessed through a reference type, then that reference type would have exactly the same situation. But yeah, it would allow you to make it a value type.
Re: No documentation for core.sys?
On Thursday, 17 December 2015 at 04:23:30 UTC, Shriramana Sharma wrote: Jakob Ovrum wrote: As with core.stdc, refer to the documentation for the equivalent C header. I only know of even core.stdc's existence since I've been poking into the Phobos sources. At least the Phobos documentation should mention that such modules exist. Maybe. The thing is, the bindings in core.sys have been built on an as-needed (by druntime or Phobos) basis, so some of them are incomplete and some headers are probably missing. That said, I'm not very familiar with it, so maybe the current status is different. I know for one thing that core.sys.windows recently had a major overhaul. [sigh] This is why D's API version is still 0, as in 2.0.69.2 (at least my interpretation of the weird zero-prefixed numbering being used). Uh, hyperbole much? https://github.com/D-Programming-Language/druntime/pull/1402
Re: Testing if a file is connected to a terminal
On Thursday, 17 December 2015 at 04:05:57 UTC, Adam D. Ruppe wrote: On Thursday, 17 December 2015 at 03:59:27 UTC, Jakob Ovrum wrote: There are some terminal libraries on Github (like consoled) but I have to say I think they're uninspiring in terms of quality and presentation. Can you be any more specific about that? Where's the reference documentation?
Re: exit(1)?
On Thursday, 17 December 2015 at 05:02:50 UTC, Shriramana Sharma wrote: http://dlang.org/phobos/std_getopt.html has a line in an example saying exit(1); Surely this works only if core.stdc.stdlib is imported? Should the example be modified to show the import? And is exit() the canonical way to exit the current process even in D? Ouch, that's not good. `exit` is not a good way to terminate a D program. It doesn't call destructors, including module destructors. The example should be restructured to `return 1;` from `main`.
Re: Using a struct as a wrapper for an extern(C) opaque type, no default constructor, what do?
On Thursday, 17 December 2015 at 03:31:37 UTC, Jeremy DeHaan wrote: Hi all. I'm interfacing to some C code which include an opaque type and some C functions that create and work with a pointer to that type. I want to wrap up everything in a struct, and the only thing that seems to bug me is initialization. Since it is C code, I obviously can't read the function that creates the opaque type. Not only that, I can't define a default constructor. What are my options here? This is for an API that is intended to be used by people other than myself, so I'd like to use something that doesn't look ugly or isn't a hack. I really don't like the idea of using a factory method or overriding opCall. Am I basically out of luck and need to resort to one of these methods? Using a factory function alongside @disable this(); is the canonical way to do this. Although, if your struct is a reference type, you can simply allow default construction and have it mean a null reference. Using static opCall here is just a factory function with special syntax, but I think it does more harm than good.
Re: isBidirectionalRange fails for unknown reasons
On Wednesday, 16 December 2015 at 20:43:02 UTC, Jack Stouffer wrote: ... You can also use return type covariance: class ReferenceBidirectionalRange(T) : ReferenceForwardRange!T { this(Range)(Range r) if (isInputRange!Range) { super(r); } final override @property typeof(this) save() { return new typeof(this)(_payload); } final @property ref T back(){ return _payload.back; } final void popBack(){ _payload.popBack(); } } ReferenceBidirectionalRange!T is a subtype of ReferenceForwardRange!T, so the override is legal.
Re: Testing if a file is connected to a terminal
On Thursday, 17 December 2015 at 03:38:31 UTC, Shriramana Sharma wrote: Is there a canonical way to test in D whether stdout/stderr (or in general, a std.stdio.File) refers to a terminal or not? https://www.google.co.in/search?q=terminal=dlang.org/phobos turns out nothing. I knew of C's (or rather POSIX's) isatty, and after some digging I found isatty defined under core.sys.posix.unistd, and I suppose I can just pass to it the output of std.stdio.File.getFP. Is there any other way to do the desired test? Or is this the recommended way? We don't have any terminal functionality in Phobos at this time, so using isatty directly is the way to go. There are some terminal libraries on Github (like consoled) but I have to say I think they're uninspiring in terms of quality and presentation.
Re: Binary search
On Tuesday, 15 December 2015 at 00:22:37 UTC, tsbockman wrote: I also found `SortedRange.equalRange`, but that sounds like it has an unreasonable amount of (admittedly O(1)) overhead for the (extremely common) case in which I am looking for only a single element, not a range. If your array doesn't contain duplicates, the overhead is just one extra comparison. For cheap comparisons, this overhead will be completely dwarfed by the actual search (assuming your array is big enough to justify binary search over linear search). If your array contains duplicates but you are only interested in getting any one of them, or your comparison is non-trivial, then I agree this could potentially be a problem. For sorted arrays you won't find any other standard facility for doing binary search, but the containers RedBlackTree and BinaryHeap provide something related.
Balanced match with std.regex
Is there a way to do balanced match with std.regex? Example (from [1]): test -> funcPow((3),2) * (9+1) I want to match the funcPow((3),2) bit, regardless of the depth of the expression in funcPow(*). https://stackoverflow.com/questions/7898310/using-regex-to-balance-match-parenthesis [1]
Re: Binary search
On Tuesday, 15 December 2015 at 00:31:45 UTC, Jakob Ovrum wrote: For sorted arrays you won't find any other standard facility for doing binary search, but the containers RedBlackTree and BinaryHeap provide something related. You could also get the upper bound (SortedRange.upperBound) and calculate the index from its length. If I'm thinking straight, this might result in fewer comparisons for some patterns.
Re: Balanced match with std.regex
On Tuesday, 15 December 2015 at 01:07:32 UTC, Chris Wright wrote: I don't think so. std.regex looks like it implements only a deterministic finite automaton, whereas what you are looking for requires a push-down automaton. It just so happens that a few popular regex libraries implement PDAs rather than DFAs (and have associated changes to their regex syntax to make it work, albeit inelegantly). Thanks, that makes sense. String manipulation in D without regex is pretty nice anyway, so it's not a big loss.
Re: Reset all Members of a Aggregate Instance
On Saturday, 5 December 2015 at 16:28:18 UTC, Chris Wright wrote: The default constructor doesn't set default field values, though, which is why my solution involved copying ClassInfo.init. Thanks, this is a handy factoid. Reminds me of the whole __dtor vs __xdtor debacle.
Re: Reset all Members of a Aggregate Instance
On Thursday, 3 December 2015 at 21:04:00 UTC, Nordlöw wrote: Given class C { // lots of members } and a function f(C c) { } is there a generic way, perhaps through reflection, to reset (inside f) all members of `c` to their default values? Something along foreach(ref member; __traits(allMembers, c)) { member = typeof(member).init; } import std.traits; foreach(i, member; FieldNameTuple!C) { alias FieldType = Fields!C[i]; static if(isMutable!FieldType) __traits(getMember, c, member) = FieldType.init; } However, it doesn't work in the presence of private fields. A better alternative is probably to `destroy` the instance then `emplace` to default-construct a new instance over it.
Re: std.range.only with different range types
On Sunday, 8 November 2015 at 19:57:34 UTC, Freddy wrote: --- import std.algorithm; import std.range; import std.stdio; void main(){ only(iota(0,4),[1,4,5]).writeln; } --- How can I call std.range.only with different range types? `only` is for creating a range from a list of values. iota(0, 4) and [1, 4, 5] are already ranges. Maybe you want to use std.range.chain? assert(iota(1, 3).chain([3, 4]).equal([1, 2, 3, 4]));
Re: Is it possible to filter variadics?
On Wednesday, 4 November 2015 at 09:48:40 UTC, maik klein wrote: Thanks, that is exactly what I wanted to achieve. What is the performance implication of 'only' in this context? Will it copy all arguments? Yes, it will, but just from the stack to a different location on stack.
Re: Bidirectional Filter
On Tuesday, 3 November 2015 at 08:41:11 UTC, Nordlöw wrote: Is there a reason why std.algorithm.iteration.filter() doesn't propagate bidirectional access? http://dlang.org/phobos/std_algorithm_iteration.html#filterBidirectional
Re: Is it possible to filter variadics?
On Tuesday, 3 November 2015 at 23:41:10 UTC, maik klein wrote: Is it possible to filter variadics for example if I would call void printSumIntFloats(Ts...)(Ts ts){...} printSumIntFloats(1,1.0f,2,2.0f); I want to print the sum of all integers and the sum of all floats. //Pseudo code void printSumIntFloats(Ts...)(Ts ts){ auto sumOfInts = ts .filter!(isInteger) .reduce(a => a + b); writeln(sumOfInts); ... } Is something like this possible? import std.algorithm.iteration : sum; import std.meta : allSatisfy, Filter; import std.traits; import std.typecons : tuple; import std.range : only; // These two are necessary since the ones in std.traits // don't accept non-types enum isIntegral(alias i) = std.traits.isIntegral!(typeof(i)); enum isFloatingPoint(alias f) = std.traits.isFloatingPoint!(typeof(f)); auto separateSum(T...)(T args) if(allSatisfy!(isNumeric, T)) { return tuple(only(Filter!(isIntegral, args)).sum(), only(Filter!(isFloatingPoint, args)).sum()); } pure nothrow @safe unittest { assert(separateSum(2, 2.0) == tuple(2, 2.0)); assert(separateSum(3, 2.0, 5, 1.0, 1.0) == tuple(8, 4.0)); }
Re: Unionize range types
On Tuesday, 3 November 2015 at 01:55:27 UTC, Freddy wrote: Is there any way I can Unionize range Types? --- auto primeFactors(T)(T t, T div = 2) { if (t % div == 0) { return t.only.chain(primeFactors(t / div, div)); } if (div > t) { return []; } else { return primeFactors(t, div + 1); } } --- http://dlang.org/phobos/std_range#choose
Re: LuaD: creating a flexible data filter system
On Friday, 16 October 2015 at 09:01:57 UTC, yawniek wrote: hi, i'm reading in a stream of data that is deserialized into individual frames. a frame is either of: a) a specific D datastructure ( struct with a few ulong,string,string[string] etc members), known at compile time b) json (preferably stdx.data.json) i now want to implement something where i can dynamically add lua filters that then get data out of these frames, create a new lua object send it back to D code where its either sent to another lua filter or at last being serialized again to json und then being processed further. ideally i would not like to copy all the data into a lua object but directly access it from lua. is there an elegant approach to do this and support both a and b cases? so far i did some benchmarks, mainly with string comparisons and it turned out that luaD is about 10x faster than mruby and python D bridges. The class support in LuaD supports the kind of indirection you want, but it's probably not finished enough for your use case. Once closer to completion, it will be possible to use it with structs as well.
Re: LuaD: creating a flexible data filter system
On Friday, 16 October 2015 at 10:45:52 UTC, Chris wrote: Later you call the function with the Lua C API like "lua_pcall(L, 0, 1, 0);". It's a bit tricky to move things around on the Lua stack, but you'll get there! ;) Or you could use LuaD which doesn't require you to mess around with the relatively unproductive, bug-prone C API :)
Re: Why can't function expecting immutable arg take mutable input?
On Saturday, 17 October 2015 at 02:03:01 UTC, Shriramana Sharma wrote: Ali Çehreli wrote: http://ddili.org/ders/d.en/const_and_immutable.html#ix_const_and_immutable.parameter, %20const%20vs.%20immutable Hi Ali – I take this chance to personally thank you sincerely for your book which provides much-needed hand-holding in my baby D-steps. I did read that chapter already and IMO you have given clear instructions as to when to use const and when immutable. My question was however to the root of the issue, as to *why* the compiler cannot consider mutable as immutable just like in C/C++ any non-const can be taken as const. It would seem that the answer is one related to optimization. Obviously, labeling an argument as immutable can be done only if we are sure that we will have to process only immutable input, thereby paving the opportunity for the compiler to optimize some memory access or allocation or such – I'm not much clear beyond that but that's enough for me now... It appears that the linked chapter doesn't explain *why* you would want to receive immutable arguments. In my experience, the most common motivation is a desire to escape a reference to the argument. We want to read the data later, but when we do, we want it to be unchanged from when we received it: --- struct S { immutable(int)[] numbers; this(immutable(int)[] numbers) { this.numbers = numbers; } void printNumbers() { import std.stdio; writeln(numbers); } } immutable numbers = [1, 2, 3]; auto s = S(numbers); /* ... */ s.printNumers(); // [1, 2, 3] --- In the above code, *no matter what code is run between construction and `printNumbers`*, it will always print the same numbers it received at construction, as the numbers are immutable. Because of this guarantee, S.numbers can simply alias the constructor argument as seen in the constructor body, instead of say, copying the numbers into a new heap-allocated copy of the array. If we used const instead of immutable, there would be no such guarantee, as const can refer to mutable data: the numbers could have been overwritten between construction and the call to `printNumbers`. Another common use of immutable is to share data between multiple threads. As immutable data never changes after initialization, it can be passed between threads and read freely without worrying about data races. const in D simply exists to bridge mutable and immutable data. It is different from C++'s const, despite sharing the same name.
Re: Why do abstract class functions require definitions?
On Friday, 18 September 2015 at 13:18:23 UTC, Jacob Carlborg wrote: On 2015-09-16 12:36, Marc Schütz wrote: Wouldn't the following behaviour be more useful as a default? abstract class Foo { void bar1() { } // non-abstract, obviously void bar2();// abstract, because it's in an abstract class // (different from now) extern void bar3(); // non-abstract, but defined externally } Currently "extern" has the meaning, at least on Windows, that the symbol will be visible outside a dynamic library. That's `export`.
Re: Calling D from C, C++, Python…
On Thursday, 10 September 2015 at 18:01:10 UTC, Russel Winder wrote: Is there an easy way of knowing when you do not have to initialize the D runtime system to call D code from, in this case, Python via a C adapter? I naïvely transformed some C++ to D, without consideration of D runtime systems, compiled it and it all worked. Which is good, but… Surely the reasonable choice is to always initialize the runtime in a sensible location? What do you gain from not initializing it, and is it really worth the effort? core.runtime has Runtime.initialize and Runtime.terminate. In a Windows DLL, it's sensible to use DllMain to call these. core.sys.windows.dll.SimpleDllMain is a mixin template that makes it easy: version(Windows) { import core.sys.windows.dll; mixin SimpleDllMain; } On Linux and other ELF-using platforms, initialization and deinitialization functions could be placed in the .init and .deinit special sections, but I don't know if druntime has any convenient provisions for this. With GDC and LDC you can probably use a pragma to put functions in these sections, but I don't know if DMD has such a pragma. I don't know what the equivalent is for Apple's Mach-O shared libraries.
Re: Calling D from C, C++, Python…
On Sunday, 13 September 2015 at 10:10:32 UTC, Jakob Ovrum wrote: On Thursday, 10 September 2015 at 18:01:10 UTC, Russel Winder wrote: Is there an easy way of knowing when you do not have to initialize the D runtime system to call D code from, in this case, Python via a C adapter? I naïvely transformed some C++ to D, without consideration of D runtime systems, compiled it and it all worked. Which is good, but… Surely the reasonable choice is to always initialize the runtime in a sensible location? What do you gain from not initializing it, and is it really worth the effort? core.runtime has Runtime.initialize and Runtime.terminate. In a Windows DLL, it's sensible to use DllMain to call these. core.sys.windows.dll.SimpleDllMain is a mixin template that makes it easy: version(Windows) { import core.sys.windows.dll; mixin SimpleDllMain; } On Linux and other ELF-using platforms, initialization and deinitialization functions could be placed in the .init and .deinit special sections, but I don't know if druntime has any convenient provisions for this. With GDC and LDC you can probably use a pragma to put functions in these sections, but I don't know if DMD has such a pragma. I don't know what the equivalent is for Apple's Mach-O shared libraries. Note that if the host program can call into the D shared library from multiple threads, it's necessary to register those threads with the runtime as well. The DllMain solution handles this automatically, but for other systems additional handling is necessary.
Re: best way to memoize a range?
On Friday, 11 September 2015 at 13:09:33 UTC, Laeeth Isharc wrote: obviously it's trivial to do with a little aa cache. and I know I can memoize a function, and turn the memoized version into an infinite range. but suppose I have a lazy function that returns a finite range, and its expensive to calculate. can I use Phobos to produce a memoized range? So it will calculate on access to an element if it needs to, but will return the cached value if it has been calculated before. Is your range random access? If not, `cache` should do the trick. [1] http://dlang.org/phobos/std_algorithm_iteration.html#cache
Re: Better Return Value for findSplit*()
On Saturday, 16 May 2015 at 09:36:30 UTC, Per Nordlöw wrote: After having written a lot of text pattern matching functions using Phobos' findSplit, findSplitBefore, findSplitAfter, and some more I've written myself I've come to the conclusion that I would like to enhance these functions to instead return a struct instead of tuples. This struct would typically look like struct FindSplit(T) { T[3] data; T first() { return data[0]; } T separator() { return data[1]; } T second() { return data[2]; } T opIndex(size_t i) return { return data[i]; } cast(T : bool)() { return !separator.empty; } } This would enable the following useful syntax: if (const split = line.findSplit(`-`)) { // do something with split } instead of current const split = line.findSplit(`-`) if (!split[1].empty) { } which is a constantly reoccurring pattern in D code processing text. The cons I can think of is that split[N] (N being a CT-constant) will occurr in run-time instead of compile-time and of course that people relying on that return-type of findSplit() being a tuple will cause code-breakage. What do you guys think; - Add extra template-param that returns struct instead and make the current behaviour deprecated? - Will happen for D3? :) - Will never happen? Destroy! It can be implemented in a backwards-compatible way as a subtype of a Tuple. struct FindSplit(R) { Tuple!(R, pre, R, separator, R, post) asTuple; bool opCast(T : bool)() { return !asTuple.separator.empty; } alias asTuple this; } Tuple!(R, pre, R, separator, R, post) is a subtype of Tuple!(R, R, R), which should be the current return type.
Re: Better Return Value for findSplit*()
On Saturday, 16 May 2015 at 10:28:11 UTC, Per Nordlöw wrote: Nice! Should I make a PR? I think that would be very welcome.
Re: Run-time Indexing of a Compile-Time Tuple
On Tuesday, 12 May 2015 at 13:30:22 UTC, Idan Arye wrote: A little hacky, but how about casting it to a static array? http://dpaste.dzfl.pl/d0059e6e6c09 This PR[1] achieves this without making a copy. [1] https://github.com/D-Programming-Language/phobos/pull/3198
Re: Parameter storage class 'in' transitive like 'const'?
On Sunday, 3 May 2015 at 05:20:34 UTC, Ali Çehreli wrote: We know that 'in' is equivalent to const scope: http://dlang.org/function.html#parameters So, the constness of 'in' is transitive as well, right? Ali Of course, there's no concept of non-transitive const in D: struct S { char[] str; } void foo(in S s) { pragma(msg, typeof(s.str)); // const(char[]) }
Re: Fuzzy Levenshtein variant of std.conv.to
On Wednesday, 29 April 2015 at 14:46:04 UTC, Per Nordlöw wrote: On Tuesday, 28 April 2015 at 23:09:27 UTC, Per Nordlöw wrote: On Tuesday, 28 April 2015 at 16:20:24 UTC, Per Nordlöw wrote: I update my Github repo. I had forgotten to push my latest changes. I solved it. I started working on this yesterday before you solved it, and ended up finishing a solution. It was a fun excercise, thanks. https://gist.github.com/JakobOvrum/515737710619a9d97273 It uses a loop instead of a range composition because of the early return when the Levenshtein distance is 0; that would be clumsy to express with ranges.
std.net.curl.get failing to resolve google.com
test.d --- void main() { import std.net.curl; import std.stdio; writeln(get(http://google.com;)); } --- rdmd -g test.d --- std.net.curl.CurlException@std\net\curl.d(3691): couldn't resolve host name on handle 26B4878 0x0040572A in pure @safe void std.exception.bailOut!(std.net.curl.CurlException).bailOut(immutable(char)[], uint, const(char[])) at d:\Programming\D\dmd.2.067.0.windows\dmd2\windows\bin\..\..\src\phobos\std\exception.d(400) 0x004056D2 in pure @safe bool std.exception.enforce!(std.net.curl.CurlException, bool).enforce(bool, lazy const(char)[], immutable(char)[], uint) at d:\Programming\D\dmd.2.067.0.windows\dmd2\windows\bin\..\..\src\phobos\std\exception.d(352) 0x00431356 in void std.net.curl.Curl._check(int) 0x004064F6 in char[] std.net.curl.get!(std.net.curl.HTTP, char).get(const(char)[], std.net.curl.HTTP) at d:\Programming\D\dmd.2.067.0.windows\dmd2\windows\bin\..\..\src\phobos\std\net\curl.d(405) 0x004020A4 in char[] std.net.curl.get!(std.net.curl.AutoProtocol, char).get(const(char)[], std.net.curl.AutoProtocol) at d:\Programming\D\dmd.2.067.0.windows\dmd2\windows\bin\..\..\src\phobos\std\net\curl.d(419) 0x0040202A in _Dmain 0x00423C0A in D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ6runAllMFZ9__lambda1MFZv 0x00423BDF in void rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).runAll() 0x00423AF7 in _d_run_main 0x004237A0 in main 0x0046E025 in mainCRTStartup 0x76D0338A in BaseThreadInitThunk 0x77269F72 in RtlInitializeExceptionChain 0x77269F45 in RtlInitializeExceptionChain --- Using DMD32 D Compiler v2.067.0 (release version) on Windows. google.com resolves fine when using ping or a browser, so what could be causing this? It happens with every other host name I've tried, too.
std.datetime.parseRFC822DateTime
std.datetime contains parseRFC822DateTime to convert from an RFC822/RFC5322 formatted string (ala Sat, 6 Jan 1990 12:14:19 -0800) to a SysTime. Does it contain anything for the converse - converting from a SysTime to Sat, 6 Jan 1990 12:14:19 -0800? If not, should it?
Re: std.datetime.parseRFC822DateTime
On Tuesday, 21 April 2015 at 10:28:32 UTC, Jonathan M Davis wrote: On Tuesday, April 21, 2015 08:14:10 Jakob Ovrum via Digitalmars-d-learn wrote: std.datetime contains parseRFC822DateTime to convert from an RFC822/RFC5322 formatted string (ala Sat, 6 Jan 1990 12:14:19 -0800) to a SysTime. Does it contain anything for the converse - converting from a SysTime to Sat, 6 Jan 1990 12:14:19 -0800? If not, should it? No, it does not contain the reverse. It was added specifically for the installer. If it weren't for that, std.datetime wouldn't support it at all. It's a horrible format that should just die. The only reason to use it is because the e-mail spec (and thus specs like HTTP) unfortunately uses it. However, anyone that's going to need to generate the format for anything like that is going to need a lot more than that that Phobos doesn't provide anyway, so I really don't think that it's much of a loss. Regardless, I'm strongly of the opinion that anything dealing with that format should be restricted to a library for e-mail or HTTP, and if it weren't for the fact that the installer needed to be able to read it (I forget why), I would have argued strongly against adding parseRFC822DateTime to Phobos. - Jonathan M Davis I needed it for the If-Modified-Since HTTP header, through std.net.curl.HTTP.addRequestHeader. Phobos has HTTP support and this is the preferred date format according to spec. Phobos should support it.
Re: Why is indexed foreach restricted to build in array ?
On Saturday, 11 April 2015 at 10:50:17 UTC, matovitch wrote: Hello, The question is in the title. It should be possible for a finite random access ranges to perform an indexed foreach no ? I mean like : foreach(size_t i = 0, auto ref x; R) { /*...*/ } Why are other foreach statements overloadable but this one ? Thanks in advance. As of 2.067, you can use std.range.enumerate[1]. See the PR that added it[2] and the enhancement request that proposed it[3] for more information about why it's a library function. [1] http://dlang.org/phobos/std_range#enumerate [2] https://github.com/D-Programming-Language/phobos/pull/1866 [3] https://issues.dlang.org/show_bug.cgi?id=5550
Re: Why is indexed foreach restricted to build in array ?
On Saturday, 11 April 2015 at 12:04:06 UTC, matovitch wrote: well ldc doesn't compile : kmeans.d(40): Error: no property 'enumerate' for type 'Range' With -O -release -inline I get around 2s with foreach and 0.5s with a simple for. LDC does not yet support the 2.067 front-end version in which `enumerate` was made available. You could get the `enumerate` implementation from the DMD release and it should work with older FE versions (within reason - it may or may not depend on relatively new language features). Performance with range-based code requires a sophisticated optimizer, the kind that is used to optimize idiomatic C++ code. In particular, inlining is important as there are a lot of tiny generic functions involved. Unfortunately, DMD's optimizer is not up to this task.
Re: using vibe.d to parse json
On Thursday, 26 March 2015 at 00:41:50 UTC, Laeeth Isharc wrote: Yeah, it is not very intuitive. But it works. Thanks. Next question - how can I correctly deal with inconsiderately chosen JSON field names like 'private' (which conflict in a struct declaration with D language keywords). A hack is to do a search and replace on the JSON before presenting it to vibe.d, but I wondered if there was a better way. Incidentally, vibe doesn't seem to like my replacing private with private_ - whereas privateX works. Laeeth. Use the @name attribute: http://vibed.org/api/vibe.data.serialization/name
Re: What is the Correct way to Malloc in @nogc section?
On Thursday, 12 February 2015 at 23:27:51 UTC, Kitt wrote: The Exception obviously uses the GC, and would need to be replaced with a printf or something; however, emplace doesn't have a @nogc replacement that I know of. What I'd like to know, from people much more knowledgeable about the ins and outs of D, is what the Best or Correct way to allocate and deallocate within @nogc sections? This issue, as well as PS: Tangentially related, what hashing algorithm does D use? I've seen people suggest using typeid(object).toHash(object); however, toHash isn't @nogc, so I need to write my own Hashing function. For the sake of consistency and peace of mind, I'd really like to match mine as closely to Ds internal one as possible. this one, are related to the loss of guarantee attributes when using TypeInfo methods, most recently discussed in this thread[1]. It is essentially a bug, and a work in progress. The correct way to handle OOM in D is to call core.exception.onOutOfMemoryError: --- if (auto p = malloc(...)) /* use p */ else onOutOfMemoryError(); // Throws OutOfMemoryError without allocating memory --- [1] http://forum.dlang.org/post/krccldftrbbczahas...@forum.dlang.org
Re: Intended to be able to RefCount an interface?
On Tuesday, 10 February 2015 at 06:26:39 UTC, weaselcat wrote: Is there currently an enhancement request open for this on the bug tracker? I cannot find anything. I couldn't find it either, so I filed it: https://issues.dlang.org/show_bug.cgi?id=14168
Re: Intended to be able to RefCount an interface?
On Tuesday, 10 February 2015 at 04:44:55 UTC, weaselcat wrote: Thread title. interface Itest{ } class testclass : Itest{ } void main() { import std.typecons; auto test = RefCounted!Itest(new testclass()); } If you change the refcounted to type testclass it doesn't compile because refcounted doesn't support classes. Is this a bug, or intended? I think this is a bug, and that the current RefCounted needs to reject interfaces. AFAIK, it is intended that RefCounted!SomeClass is supposed to reference-count the actual class instance, not its reference, which is what RefCounted!SomeInterface currently does.
Re: how can I get a reference of array?
On Thursday, 5 February 2015 at 06:58:09 UTC, Ali Çehreli wrote: On 02/04/2015 10:42 PM, zhmt wrote: Here is a simple code snippet: With this approach, the allocation of `arr` itself is often clumsy and error-prone. In this case it is important to note that `arr` is allocated on the stack and thus has scoped lifetime. Consider using std.container.array.Array instead.
Re: pop popFront combined
On Saturday, 1 November 2014 at 11:43:28 UTC, Nordlöw wrote: On Saturday, 20 September 2014 at 19:23:46 UTC, Jakob Ovrum wrote: If you want move semantics, use `moveFront`. But x.moveFront doesn't modify x. It does modify `x` as it leaves `front` in a destroyed and default-initialized state, as required by move semantics. What I want is to transform my uses of std.range from if (!x.empty) { x.front.doStuff; x.popFront; } into if (!x.empty) if (auto front = x.stealFront) { front.doStuff; } This is more functional/atomic, that is it reduces the risk of accidentally forgetting to call popFront at the end. Destroy! The other half of my post explained why such a `stealFront` is problematic.
Re: pop popFront combined
On Saturday, 20 September 2014 at 18:59:03 UTC, Nordlöw wrote: Is there a reason why popFront doesn't automatically return what front does? If so I'm still missing a combined variant of pop and popFront in std.range. Why isn't such a common operation in Phobos already? Sometimes after popping, the previous `front` is no longer valid, such as in the case of a buffer being reused. We should be careful about promoting using a previously read `front` after `popFront` until we figure out what we want to do about these transient ranges. If you want move semantics, use `moveFront`.
Re: findSplit
On Friday, 25 July 2014 at 18:56:44 UTC, Gecko wrote: findSplit accepts a predicate but it doesnt compile for me if i use an other function than ((a,b) = a == b). Not at the moment. I've been working on a patch that makes the `findSplit*` family of algorithms as powerful as `find`, including support for your use case.
Re: How to define and use a custom comparison function
On Tuesday, 17 June 2014 at 04:32:20 UTC, Jakob Ovrum wrote: On Monday, 16 June 2014 at 20:49:29 UTC, monarch_dodra wrote: MyCompare cmp(SortOrder.ASC, 10); This syntax is not valid D. It should be: auto cmp = MyCompare(SortOrder,ASC, 10); Sorry, that first comma is a typo and should be a dot. auto cmp = MyCompare(SortOrder.ASC, 10);
Re: How to define and use a custom comparison function
On Monday, 16 June 2014 at 20:49:29 UTC, monarch_dodra wrote: MyCompare cmp(SortOrder.ASC, 10); This syntax is not valid D. It should be: auto cmp = MyCompare(SortOrder,ASC, 10);