Re: Appenders and Arrays
On 09/01/2015 02:16 PM, Steven Schveighoffer wrote:> On 9/1/15 3:13 PM, Daniel Kozak via Digitalmars-d-learn wrote: >> >> >> Dne 1.9.2015 v 19:20 Steven Schveighoffer via Digitalmars-d-learn >> napsal(a): >>> On 9/1/15 12:49 PM, default0 wrote: Hello A simple thing I stumbled across: int main() { import std.stdio; import std.range; int[] d; d ~= 10; d ~= 20; d.put(5); writeln(d); return 0; } Appenders work fine as output ranges, but arrays do not. The above code prints "20" (ie the 10 is removed). Is "put" not supposed to mean "append one element"? >>> >>> put into an slice does not append, it fills in the front. This is >>> because the "target" of a slice is the data it points at. >>> >>> Think of it as a buffer that you want to fill: >>> >>> int[20] buf; >>> int[] outputRange = buf[]; >>> outputRange.put(10); >>> outputRange.put(20); >>> >>> assert(buf[0..2] == [10,20]); >> So it is something like this?: >> >> int main() >> { >> import std.stdio; >> import std.range; >> >> int[] d; >> d ~= [10]; >> d ~= [20]; >> d.front = 5; >> d.popFront(); >> writeln(d); >> >> return 0; >> } >> > > I'm not following your code. What is the question? > > -Steve I think Daniel is asking whether .put() on a slice is the equivalent of assigning to front() and then popFront(). The answer is yes. http://dlang.org/phobos/std_range_primitives.html#.put http://ddili.org/ders/d.en/ranges.html#ix_ranges.slice,%20as%20OutputRange Ali
Re: Problem with using struct ranges with @disabled this(this) with some range functions
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?
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.
Re: Why ElementType!(char[3]) == dchar instead of char?
On 02.09.2015 11:30, FreeSlave wrote: I see, thanks. So I should always treat char[] as UTF in D itself, but because I need to pass char[], wchar[] or dchar[] to a C library I should treat it as not UTF but ubytes sequence or ushort or uint sequence - just to pass it correctly, right? You should just keep in mind that strings returned by Phobos are UTF encoded. Does your C library have UTF support? Is it relevant at all? Maybe it just treats char array as binary data. But if it does some non-trivial string and character manipulations or talks to file system, then it surely should expect strings in some specific encoding, and if it's not UTF, you should re-encode data before passing from D to this library. Also C does not have wchar and dchar, but has wchar_t which size is not fixed and depends on particular platform. Well, I think it's not simple question. The C library I used is hdf5 lib and it stores data without processing. In general. In particular I need to evalutate a situation concretely, I guess. Thanks all for anwers.
Re: Why ElementType!(char[3]) == dchar instead of char?
On Wednesday, 2 September 2015 at 05:00:42 UTC, drug wrote: 02.09.2015 00:08, Jonathan M Davis via Digitalmars-d-learn пишет: On Tuesday, September 01, 2015 20:05:18 drug via Digitalmars-d-learn wrote: My case is I don't know what type user will be using, because I write a library. What's the best way to process char[..] in this case? char[] should never be anything other than UTF-8. Similarly, wchar[] is UTF-16, and dchar[] is UTF-32. So, if you're getting something other than UTF-8, it should not be char[]. It should be something more like ubyte[]. If you want to operate on it as char[], you should convert it to UTF-8. std.encoding may or may not help with that. But pretty much everything in D - certainly in the standard library - assumes that char, wchar, and dchar are UTF-encoded, and the language spec basically defines them that way. Technically, you _can_ put other encodings in them, but it's just asking for trouble. - Jonathan M Davis I see, thanks. So I should always treat char[] as UTF in D itself, but because I need to pass char[], wchar[] or dchar[] to a C library I should treat it as not UTF but ubytes sequence or ushort or uint sequence - just to pass it correctly, right? You should just keep in mind that strings returned by Phobos are UTF encoded. Does your C library have UTF support? Is it relevant at all? Maybe it just treats char array as binary data. But if it does some non-trivial string and character manipulations or talks to file system, then it surely should expect strings in some specific encoding, and if it's not UTF, you should re-encode data before passing from D to this library. Also C does not have wchar and dchar, but has wchar_t which size is not fixed and depends on particular platform.
Re: std.experimental.logger instantiation fails in 2.067
On Wednesday, 2 September 2015 at 06:57:12 UTC, drug wrote: Before 2.067 I used std.experimental.logger in form of a dub package. Because it included in 2.067 I stop using the dub package but now I get the error: Error: safe function 'std.experimental.logger.core.Logger.memLogFunctions!cast(LogLevel)cast(ubyte)32u.logImplf!(383, [snip]).logImplf' cannot call system function 'std.format.formattedWrite!(MsgRange, char, InitiatingPTrack).formattedWrite' What is the way to avoid it? (I guess it's known issue) P.S. using dmd 2.067 with the dub package it compiles, without the dub package it fails, but ldc 0.16 fails both without and with the dub package - there is some inconsistence. https://issues.dlang.org/show_bug.cgi?id=14940
Re: new static array
On 09/01/2015 09:47 AM, anonymous wrote:> Hello, > > I tried to send a string[4] with std.concurrency: > > import std.concurrency; > import std.stdio; > void fun() { > receive((string[4] data) { writeln(data);}); > } > > void main() { > string[4] data; > auto tid = spawn(); > send(tid, data); > } > > I got (dmd 2.068) > /usr/include/dmd/phobos/std/variant.d(633): Error: new can only create > structs, dynamic arrays or class objects, not string[4]'s > [...] > > with int[4] it compiles and runs. int[][4] fails. Is this a bug? I think so. > Simple workaround: send a slice. Another one: Wrap the array in a struct: struct Data { string[4] s; } Ali
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?
std.experimental.logger instantiation fails in 2.067
Before 2.067 I used std.experimental.logger in form of a dub package. Because it included in 2.067 I stop using the dub package but now I get the error: Error: safe function 'std.experimental.logger.core.Logger.memLogFunctions!cast(LogLevel)cast(ubyte)32u.logImplf!(383, [snip]).logImplf' cannot call system function 'std.format.formattedWrite!(MsgRange, char, InitiatingPTrack).formattedWrite' What is the way to avoid it? (I guess it's known issue) P.S. using dmd 2.067 with the dub package it compiles, without the dub package it fails, but ldc 0.16 fails both without and with the dub package - there is some inconsistence.
Re: 2.068.0 std.process.executeShell how to set the shell?
On Wednesday, 2 September 2015 at 01:46:18 UTC, Jonathan M Davis wrote: On Wednesday, 2 September 2015 at 01:26:23 UTC, Jonathan M Davis wrote: [snip] https://issues.dlang.org/show_bug.cgi?id=15000 - Jonathan M Davis Thank you for your reply and for the bug report. Looking at your suggestions I do not fully understand/agree. executeShell has been one of the easiest ways for us to interact with the shell, all other functions require more work to implement. Being able to define the shell to be used is something that makes sense across all functions in std.process. Honestly being able to set a different variable name instead of SHELL would make more sense. It would not take the default shell from the user thus using /bin/sh and would allow us to change it if desired with a different value. The change would be minimal across code and documentation. But that's just my suggestion, I'm not a library developer. I understand that all variants may have their own issues, but taking away from the developer the power to make decisions also doesn't seem a good option. Anyway I would like to ask if you can help to understand why this simple example using execute fails? auto outputDiff = execute ( ["bash","echo"] ); writeln (outputDiff.output); Output: /bin/echo: /bin/echo: cannot execute binary file At the moment some of the uses I had are not working and I'm not able to implement any workaround. Obrigado
Re: reading file byLine
On Wednesday, 2 September 2015 at 15:04:10 UTC, cym13 wrote: On Wednesday, 2 September 2015 at 13:46:54 UTC, Namal wrote: Thx, cym. I have a question about a D strings though. In c++ I would just reuse the string buffer with the "=" how can I clear the string after i store a line in the buffer and do something with it. I also tried to append a line to an array of strings but it failed because the line is a char? In D you can do as in C++: buffer = ""; // or a brand new string You can also reset a variable to its initial state (what you would hav had if you hadn't initialized it) using: buffer.init(); When reading files the default type you get is dchar[]. There are different kind of strings in D, you way want to check http://dlang.org/arrays.html#strings . If you want to append to an array of strings, simply convert your line to type string: import std.conv; import std.stdio; void main() { string[] buffer; foreach (line ; File("test.txt").byLine) buffer ~= line.to!string; // <- Here is the magic writeln(buffer); } Actually, even if converting works, what qznc did is better in the case of file reading. And even better would be to use .byLineCopy which basically does the same thing as qznc's solution but more efficiently: import std.stdio; void main() { string[] buffer; foreach (line ; File("test.txt").byLineCopy) buffer ~= line; writeln(buffer); }
Re: Access Violation while trying to use OpenGL
On Wednesday, 2 September 2015 at 01:07:01 UTC, Mike Parker wrote: On Tuesday, 1 September 2015 at 20:35:43 UTC, spec00 wrote: On Tuesday, 1 September 2015 at 20:15:28 UTC, spec00 wrote: [...] The problem was in me using the 64bit version of the GLFW dll. DMD doesn't support compiling to x64? I tried using the DUB flag --arch=x86_x64 but i then got an error saying: Can't run '\bin\link.exe', check PATH What would be the correct way to compile to x64? Thanks, To compile 64-bit programs on Windows, DMD requires the Microsoft toolchain. The easiest thing to do is to install the Community Edition of Visual Studio 2013 (DMD isn't yet compatible with VS 2015). Also, you aren't using OpenGL in this example, but GLFW :) Thanks Mike!
interprocess communication and sharing memory
This is my first attempt at a project in D, so pardon me if I'm overlooking something obvious: I'm using libasync to create an eventloop, to set up something like a server/daemon process. This part works very well. We'll call this Server A. Now I'd like to write another process (running on the same computer), we'll call Client B, and pass signals in to Server A. I want to be able to create the process independently from Server A, I don't want to have to spawn the process from the server. I'd also like to avoid creating a pipe process just to pass information from/to Server A and Client B. What would be a good way to have Client B identify and pass signals and information to Server A (and back)? I would prefer to choose the fastest solution, as I hope to expand this to relatively large data sets. After I get simple signal passing working, I'd like to attempt passing shared memory of c-style arrays with Plain Old Data types. I've read many posts about shared memory and interprocess communication in D, but I didn't see any conclusive information about whether this type of interprocess memory sharing will be convenient or practical in D. If it doesn't work out, I have some prototype already working in c++ with boost interprocess, but I'd prefer to use a native D solution if possible.
Re: 2.068.0 std.process.executeShell how to set the shell?
On Wednesday, September 02, 2015 15:28:35 albatroz via Digitalmars-d-learn wrote: > On Wednesday, 2 September 2015 at 01:46:18 UTC, Jonathan M Davis > wrote: > > On Wednesday, 2 September 2015 at 01:26:23 UTC, Jonathan M > > Davis wrote: > > [snip] > > > > https://issues.dlang.org/show_bug.cgi?id=15000 > > > > - Jonathan M Davis > > Thank you for your reply and for the bug report. > > Looking at your suggestions I do not fully understand/agree. > > executeShell has been one of the easiest ways for us to interact > with the shell, all other functions require more work to > implement. Being able to define the shell to be used is something > that makes sense across all functions in std.process. > > Honestly being able to set a different variable name instead of > SHELL would make more sense. It would not take the default shell > from the user thus using /bin/sh and would allow us to change it > if desired with a different value. The change would be minimal > across code and documentation. > > But that's just my suggestion, I'm not a library developer. I > understand that all variants may have their own issues, but > taking away from the developer the power to make decisions also > doesn't seem a good option. Oh, it would be nice to be able to specify the shell (and feel free to add a comment on that to the bug report). It's just that spawnShell and executeShell already have a lot of parameters, and it would kind of ugly to add another. Not to mention, it would probably have to go on the end after several parameters with default arguments, forcing you to list all of the default arguments explicitly just so that you can list the shell. So, while in principle, listing the shell, would be nice. In practice, I'm not sure how to add it cleanly to the current API, and it _is_ possible to use execute or spawnProcess to run a specific shell. > Anyway I would like to ask if you can help to understand why this > simple example using execute fails? > >auto outputDiff = execute ( ["bash","echo"] ); >writeln (outputDiff.output); > > Output: > /bin/echo: /bin/echo: cannot execute binary file > > At the moment some of the uses I had are not working and I'm not > able to implement any workaround. That's because you're doing the equivalent of bash echo on the command line, and if you try that, you'll notice that you get the same error there. What you need to do instead, per the bash man page, is to run bash with the -c flag, where -c takes the command you want to run. So, you can do something like auto result = execute(["bash", "-c", "echo world"]); though what gets printed doesn't seem to appear on the command line any more than if you echoed with executeShell. If you want that, you'd have to use spawnShell or spawnProcess, e.g. auto result = wait(spawnProcess(["bash", "-c", "echo world"])); But if you don't care about the commands appearing on the command line, then execute works just fine. In either case, the key thing that you're missing is -c. - Jonathan M Davis
Re: Casting away immutability
On Wednesday, September 02, 2015 14:00:07 Sergei Degtiarev via Digitalmars-d-learn wrote: > On Wednesday, 2 September 2015 at 04:19:24 UTC, lobo wrote: > > No, I think your design is unsafe because you're throwing away > > type information and returning void[], then telling the > > compiler not to worry about it. > It is unsafe, but this not my design but std.mmfile module in > phobos. This is what I'm trying to improve. And there was no type > information initially, this is raw allocated memory returned to > user. Well, that's how mmap works. You're just getting raw bytes as void*, and the D code converts that to void[], which is slightly safer. It doesn't inherently have a type, and often, the data referred to by mmap never did have a type. It's just bytes in a file. So, if you want to use it as a type, you have to tell the compiler what it's type is - and get it right - via a cast. And yes, you can cast to immutable as part of that, because casts let you shoot yourself in the foot, because you're telling the compiler that you know better than it does, but you shouldn't be casting anything you get from C to immutable, because it's not going to be immutable. Most code shouldn't be casting to immutable any more than it should be casting away immutable. immutable data is treated by the compiler as immutable - it will _never_ change over the course of the program - so if it does change, you're going to have fun bugs, and if it really refers to mutable data (as would be the case with an mmapped file), then it could change. Additionally, immutable is treated as implicitly shared, so the compiler could do different optimizations based on that (though that probably won't affect anything if you only ever have it one a single thread), and if it's not really immutable, you could have fun bugs caused by that. Don't cast to or from immutable unless you know what you're doing, and in most of those cases, there's a decent chance that that's not the best way to do what you're trying to do anyway. But at the end of the day, the cast operator is a blunt instrument which inloves you telling the compiler that you know better than it does, so you had better know better, or you're going to shoot yourself in the foot. - Jonathan M Davis
Re: Why ElementType!(char[3]) == dchar instead of char?
On Wednesday, September 02, 2015 11:47:11 drug via Digitalmars-d-learn wrote: > On 02.09.2015 11:30, FreeSlave wrote: > >> I see, thanks. So I should always treat char[] as UTF in D itself, but > >> because I need to pass char[], wchar[] or dchar[] to a C library I > >> should treat it as not UTF but ubytes sequence or ushort or uint > >> sequence - just to pass it correctly, right? > > > > You should just keep in mind that strings returned by Phobos are UTF > > encoded. Does your C library have UTF support? Is it relevant at all? > > Maybe it just treats char array as binary data. But if it does some > > non-trivial string and character manipulations or talks to file system, > > then it surely should expect strings in some specific encoding, and if > > it's not UTF, you should re-encode data before passing from D to this > > library. > > > > Also C does not have wchar and dchar, but has wchar_t which size is not > > fixed and depends on particular platform. > Well, I think it's not simple question. The C library I used is hdf5 lib > and it stores data without processing. In general. In particular I need > to evalutate a situation concretely, I guess. > Thanks all for anwers. Yeah. char in C is often used for what D uses ubyte, so just because C uses a char doesn't mean that it even has anything to do with strings, let alone UTF. The correct way to deal with a C function depends on the C function, and that requires that you understand enough about what it's doing to know whether you're really dealing with a string or just bytes. Fortunately, most of the time - in *nix-land anyway - when char* is treated as string data, it's either ASCII or UTF-8. However, in Windows, it's not, and the situation gets far less pleasant (though if you're dealing with strings a Windows API, you should almost always be using UTF-16 and avoid that whole issue altogether). In any case, you have to be familiar with what the C function is doing and whether it's operating on string data or not rather than just blindly seeing char* and thinking that it's a zero-terminated string. - Jonathan M Davis
Re: Problem with using struct ranges with @disabled this(this) with some range functions
On Wednesday 02 September 2015 09:52, Uranuz wrote: > 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? No, don't assume that they're the same. > 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. A copy of an input range may reflect the original, but it may also become invalid when the original is touched. Any operation on the original (especially popFront) may leave the copy in an invalid state, and vice versa. That means, when you make a copy of an input range, you should not use the original anymore. > 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. Can go either way. Copying a forward range may work like a call to `save`, but it's not guaranteed/required to. When you need the behavior of `save`, call `save`. Do not assume that copying works like `save`. Do also not assume that a copy and the original of a range update each other correctly. When you pass an input range to some function and you want the operation to affect the original, use std.range.refRange to pass a reference.
Re: interprocess communication and sharing memory
On Thursday, 3 September 2015 at 02:52:00 UTC, Laeeth Isharc wrote: On Thursday, 3 September 2015 at 01:27:15 UTC, j55 wrote: [...] It's probably a stupid idea, but until someone with experience answers: what happens if you declare the memory as shared or __gshared and send a pointer to it via message passing or a pipe? I can give it a try tomorrow, for "message passing", which d library would you consider? I wasn't sure a simple pointer would work, I'd have to experiment. Though I'd like to try any safer higher level libraries for this, if they exist...
Re: interprocess communication and sharing memory
On Thursday, 3 September 2015 at 01:27:15 UTC, j55 wrote: This is my first attempt at a project in D, so pardon me if I'm overlooking something obvious: I'm using libasync to create an eventloop, to set up something like a server/daemon process. This part works very well. We'll call this Server A. Now I'd like to write another process (running on the same computer), we'll call Client B, and pass signals in to Server A. I want to be able to create the process independently from Server A, I don't want to have to spawn the process from the server. I'd also like to avoid creating a pipe process just to pass information from/to Server A and Client B. What would be a good way to have Client B identify and pass signals and information to Server A (and back)? I would prefer to choose the fastest solution, as I hope to expand this to relatively large data sets. After I get simple signal passing working, I'd like to attempt passing shared memory of c-style arrays with Plain Old Data types. I've read many posts about shared memory and interprocess communication in D, but I didn't see any conclusive information about whether this type of interprocess memory sharing will be convenient or practical in D. If it doesn't work out, I have some prototype already working in c++ with boost interprocess, but I'd prefer to use a native D solution if possible. It's probably a stupid idea, but until someone with experience answers: what happens if you declare the memory as shared or __gshared and send a pointer to it via message passing or a pipe?
Re: new static array
On Wednesday, 2 September 2015 at 06:04:40 UTC, Ali Çehreli wrote: > with int[4] it compiles and runs. int[][4] fails. Is this a bug? I think so. https://issues.dlang.org/show_bug.cgi?id=15004 may related to https://issues.dlang.org/show_bug.cgi?id=10740
Re: reading file byLine
On Wednesday, 2 September 2015 at 15:04:10 UTC, cym13 wrote: You can also reset a variable to its initial state (what you would hav had if you hadn't initialized it) using: buffer.init(); Huh? That doesn't work... Instead, use: buffer = buffer.init;
Re: reading file byLine
Thx guys, this helped alot. The next thing I want to do is read the file line by line and split the stream into words. I found this example of code that seems to do sort of something like it. How can I modyfy it so I can store the words in an array of strings? Is a => a.length the iterator range? import std.algorithm, std.stdio, std.string; // Count words in a file using ranges. void main() { auto file = File("file.txt"); // Open for reading const wordCount = file.byLine()// Read lines .map!split // Split into words .map!(a => a.length) // Count words per line .sum(); // Total word count writeln(wordCount); }
Re: reading file byLine
On Wednesday, 2 September 2015 at 21:53:20 UTC, Namal wrote: Thx guys, this helped alot. The next thing I want to do is read the file line by line and split the stream into words. I found this example of code that seems to do sort of something like it. How can I modyfy it so I can store the words in an array of strings? Is a => a.length the iterator range? import std.algorithm, std.stdio, std.string; // Count words in a file using ranges. void main() { auto file = File("file.txt"); // Open for reading const wordCount = file.byLine()// Read lines .map!split // Split into words .map!(a => a.length) // Count words per line .sum(); // Total word count writeln(wordCount); } I would do what you want like this auto file = File("file.txt"); auto words = file.byLine() // you've all lines in range .map!(a => a.split); // read each line, splitting it into words // now you've a range, where each element is an array of words The map!(a => a.split) line simply maps each element to the return value of a.split - this is the predicate. The a => a.split syntax is a lambda expression that tells map what to do on each element.
Re: Prefer Signed or Unsigned in D?
On Wednesday, 2 September 2015 at 11:03:00 UTC, ponce wrote: On Tuesday, 1 September 2015 at 23:06:50 UTC, John Carter wrote: C/C++ discussion here http://blog.robertelder.org/signed-or-unsigned-part-2/ D rules here... http://dlang.org/type.html#integer-promotions Everything Bjarne said still applies equally to D code, since integer promotion is identical with C from what I understand. Hmm. What Robert Elder says also applies still. And in my world his argument about undefined behavior carries weight. Bugs that emerge from different optimizations / different versions of the compiler / on different CPU's are nightmares in my domain. Here is a bug that existed in the JDK for 9 years (and probably in many other places) http://googleresearch.blogspot.co.nz/2006/06/extra-extra-read-all-about-it-nearly.html So given the advice on mixing unsigned and signed, and the complexity of Dominikus's code to get signed and unsigned code to compare sanely Maybe if his code becomes standard in D... Yup, mixing signed and unsigned is A Bad Thing, and you best go with whatever your base libraries give you. The whole problem http://www.di.unipi.it/~ruggieri/Papers/semisum.pdf ...makes me feel vaguely ill and long for a Numerical Tower. I really must get around to benchmarking BigInt
Re: Prefer Signed or Unsigned in D?
On Wednesday, 2 September 2015 at 21:22:59 UTC, John Carter wrote: On Wednesday, 2 September 2015 at 11:03:00 UTC, ponce wrote: Everything Bjarne said still applies equally to D code, since integer promotion is identical with C from what I understand. Hmm. What Robert Elder says also applies still. And in my world his argument about undefined behavior carries weight. I'd like to point out that while Robert Elder has remarkably documented articles, his conclusions are still contrary to most C++ experts (Bjarne, Meyers, Andrei...). Additionally, I was said weeks ago on this NG that and signed overflow in D is not actually Undefined Behaviour.
Re: Prefer Signed or Unsigned in D?
On Wednesday, 2 September 2015 at 09:47:16 UTC, BBasile wrote: On Tuesday, 1 September 2015 at 23:06:50 UTC, John Carter wrote: C/C++ discussion here http://blog.robertelder.org/signed-or-unsigned-part-2/ D rules here... http://dlang.org/type.html#integer-promotions It depends on the context. You should take care of blending signed and unsigned: comparison error, a is > b but... --- uint a = 1; int b = -1; assert(a < b); // does not throw --- You should take care to the index type in a loop: loop that doesn't run at all because of an infered unsigned index... --- auto array = new int[](8); for (auto i = array.length - 1; i > -1; i--) array[i] = 8; assert(array[0] == 0); // does not throw --- I wish the following would be the standard D behaviour (for T == U or if floats are involved neither C nor D have a problem)): int opCmp(T, U)(const(T) a, const(U) b) pure @safe @nogc nothrow if(isIntegral!T && isIntegral!U && !is(Unqual!T == Unqual!U)) { alias C = CommonType!(T, U); static if(isSigned!T && isUnsigned!U && T.sizeof <= U.sizeof) return (a < 0) ? -1 : opCmp(cast(U)a, b); else static if(isUnsigned!T && isSigned!U && T.sizeof >= U.sizeof) return (b < 0) ? 1 : opCmp(a, cast(T)b); else return opCmp(cast(C)a, cast(C)b); } this is really almost equally fast, but always correct.
Re: Casting away immutability
On Wednesday, 2 September 2015 at 04:19:24 UTC, lobo wrote: No, I think your design is unsafe because you're throwing away type information and returning void[], then telling the compiler not to worry about it. It is unsafe, but this not my design but std.mmfile module in phobos. This is what I'm trying to improve. And there was no type information initially, this is raw allocated memory returned to user.
Re: reading file byLine
On Wednesday, 2 September 2015 at 13:12:39 UTC, cym13 wrote: On Wednesday, 2 September 2015 at 13:01:31 UTC, Namal wrote: Hello, I want to read a file line by line and store each line in a string. I found this example with byLine and ranges. First of all, do I need the range lib at all to do this and if so what is the range of the end of the file? You don't need the range lib at all, std.range provides advanced functions to work with ranges but ranges are a general concept. You need std.stdio though as this is doing file operations. A way to do it is: void main() { auto f = File("myfile"); string buffer; foreach (line ; f.byLine) { buffer ~= line; } f.close(); writeln(buffer); } Note that by default byLine doesn't keep the line terminator. See http://dlang.org/phobos/std_stdio.html#.File.byLine for more informations. Thx, cym. I have a question about a D strings though. In c++ I would just reuse the string buffer with the "=" how can I clear the string after i store a line in the buffer and do something with it. I also tried to append a line to an array of strings but it failed because the line is a char?
Re: Prefer Signed or Unsigned in D?
On Tuesday, 1 September 2015 at 23:06:50 UTC, John Carter wrote: C/C++ discussion here http://blog.robertelder.org/signed-or-unsigned-part-2/ D rules here... http://dlang.org/type.html#integer-promotions It depends on the context. You should take care of blending signed and unsigned: comparison error, a is > b but... --- uint a = 1; int b = -1; assert(a < b); // does not throw --- You should take care to the index type in a loop: loop that doesn't run at all because of an infered unsigned index... --- auto array = new int[](8); for (auto i = array.length - 1; i > -1; i--) array[i] = 8; assert(array[0] == 0); // does not throw ---
Re: std.experimental.logger instantiation fails in 2.067
my guess is that InitiatingPTrack.toString is not @safe
Re: std.experimental.logger instantiation fails in 2.067
On 02.09.2015 11:36, Robert burner Schadek wrote: On Wednesday, 2 September 2015 at 06:57:12 UTC, drug wrote: Before 2.067 I used std.experimental.logger in form of a dub package. Because it included in 2.067 I stop using the dub package but now I get the error: Error: safe function 'std.experimental.logger.core.Logger.memLogFunctions!cast(LogLevel)cast(ubyte)32u.logImplf!(383, [snip]).logImplf' cannot call system function 'std.format.formattedWrite!(MsgRange, char, InitiatingPTrack).formattedWrite' What is the way to avoid it? (I guess it's known issue) P.S. using dmd 2.067 with the dub package it compiles, without the dub package it fails, but ldc 0.16 fails both without and with the dub package - there is some inconsistence. https://issues.dlang.org/show_bug.cgi?id=14940 Thank you! Unfortunately it doesn't solved my case, because I use std.string.format that is unsafe :( Am I right it is the problem of absent @safe qualifier?
Re: Prefer Signed or Unsigned in D?
On Tuesday, 1 September 2015 at 23:06:50 UTC, John Carter wrote: C/C++ discussion here http://blog.robertelder.org/signed-or-unsigned-part-2/ D rules here... http://dlang.org/type.html#integer-promotions Everything Bjarne said still applies equally to D code, since integer promotion is identical with C from what I understand.
Re: Digger 2.3 & verstr.h problem
On 2015-08-23 17:01:07 +, Vladimir Panteleev said: Can't reproduce this on Windows, Linux or OS X 10.10.3. Can you include more of the build log (specifically, the entire failing command line)? It should have a -J. in it. I still try to get digger running on my OSX again. I fiddled around a bit and think I'm a bit closer to the problem, but still don't have an idea how to fix it. 1. I replaced the used DMD version with 2.068, no effect same problem. 2. If I avoid the import("verstr.h") code and replace it with a fixed string, it works. 3. If I add the src/ directory explicitly to the command line it works too. Looks like this then: Volumes/Daten/Windows/d/develop/d-language/Digger/dl/dmd-2.067.1/dmd2/osx/bin/dmd -v -ofdmd -m64 -vtls -J. -J/Volumes/Daten/Windows/d/develop/d-language/Digger/repo/dmd/src -d -L-lstdc++ access.d aggregate.d aliasthis.d apply.d argtypes.d arrayop.d arraytypes.d attrib.d backend.d builtin.d canthrow.d clone.d complex.d cond.d constfold.d cppmangle.d ctfeexpr.d dcast.d dclass.d declaration.d delegatize.d denum.d dimport.d dinifile.d dinterpret.d dmacro.d dmangle.d dmodule.d doc.d dscope.d dstruct.d dsymbol.d dtemplate.d dunittest.d dversion.d entity.d errors.d escape.d expression.d func.d globals.d hdrgen.d id.d identifier.d impcnvtab.d imphint.d init.d inline.d intrange.d json.d lexer.d lib.d link.d mars.d mtype.d nogc.d nspace.d opover.d optimize.d parse.d sapply.d sideeffect.d statement.d staticassert.d target.d tokens.d traits.d utf.d visitor.d typinf.d irstate.d objc.d libmach.d scanmach.d root/aav.d root/array.d root/file.d root/filename.d root/longdouble.d root/man.d root/outbuffer.d root/port.d root/response.d root/rmem.d root/rootobject.d root/speller.d root/stringtable.d newdelete.o glue.a backend.a Note the second -J So, somehow the file look-up with -J. seems not to work on my OSX. But I don't have a clue what the problem could be. Maybe some strange environment settings on my side? Any help welcome... -- Robert M. Münch http://www.saphirion.com smarter | better | faster
reading file byLine
Hello, I want to read a file line by line and store each line in a string. I found this example with byLine and ranges. First of all, do I need the range lib at all to do this and if so what is the range of the end of the file?
Re: Digger 2.3 & verstr.h problem
Some more tests with a simple example: import std.stdio; void main() { writeln("hello world!" ~ import("signature.h")); } mac-pro:d-language robby$ dmd -v -J. hello.d binarydmd version v2.068.0 config/usr/local/bin/dmd.conf parse hello importall hello importobject(/Library/D/dmd/src/druntime/import/object.d) importstd.stdio (/Library/D/dmd/src/phobos/std/stdio.d) importcore.stdc.stdio (/Library/D/dmd/src/druntime/import/core/stdc/stdio.d) importcore.stdc.config (/Library/D/dmd/src/druntime/import/core/stdc/config.d) importcore.stdc.stdarg (/Library/D/dmd/src/druntime/import/core/stdc/stdarg.d) importcore.stdc.stdlib (/Library/D/dmd/src/druntime/import/core/stdc/stdlib.d) importcore.stdc.stddef (/Library/D/dmd/src/druntime/import/core/stdc/stddef.d) importcore.stdc.stdint (/Library/D/dmd/src/druntime/import/core/stdc/stdint.d) importcore.stdc.signal (/Library/D/dmd/src/druntime/import/core/stdc/signal.d) importcore.stdc.wchar_ (/Library/D/dmd/src/druntime/import/core/stdc/wchar_.d) importcore.stdc.time (/Library/D/dmd/src/druntime/import/core/stdc/time.d) importcore.sys.posix.sys.types (/Library/D/dmd/src/druntime/import/core/sys/posix/sys/types.d) importcore.sys.posix.config (/Library/D/dmd/src/druntime/import/core/sys/posix/config.d) importstd.typecons (/Library/D/dmd/src/phobos/std/typecons.d) importstd.traits(/Library/D/dmd/src/phobos/std/traits.d) importstd.typetuple (/Library/D/dmd/src/phobos/std/typetuple.d) importstd.meta (/Library/D/dmd/src/phobos/std/meta.d) importstd.stdiobase (/Library/D/dmd/src/phobos/std/stdiobase.d) importstd.range.primitives (/Library/D/dmd/src/phobos/std/range/primitives.d) semantic hello importcore.stdc.errno (/Library/D/dmd/src/druntime/import/core/stdc/errno.d) entry main hello.d semantic2 hello semantic3 hello hello.d(4): Error: file "signature.h" cannot be found or not in a path specified with -J And now adding the explicit path: mac-pro:d-language robby$ pwd /Volumes/Daten/Windows/d/develop/d-language mac-pro:d-language robby$ dmd -v -J/Volumes/Daten/Windows/d/develop/d-language hello.d binarydmd version v2.068.0 config/usr/local/bin/dmd.conf parse hello importall hello importobject(/Library/D/dmd/src/druntime/import/object.d) importstd.stdio (/Library/D/dmd/src/phobos/std/stdio.d) importcore.stdc.stdio (/Library/D/dmd/src/druntime/import/core/stdc/stdio.d) importcore.stdc.config (/Library/D/dmd/src/druntime/import/core/stdc/config.d) importcore.stdc.stdarg (/Library/D/dmd/src/druntime/import/core/stdc/stdarg.d) importcore.stdc.stdlib (/Library/D/dmd/src/druntime/import/core/stdc/stdlib.d) importcore.stdc.stddef (/Library/D/dmd/src/druntime/import/core/stdc/stddef.d) importcore.stdc.stdint (/Library/D/dmd/src/druntime/import/core/stdc/stdint.d) importcore.stdc.signal (/Library/D/dmd/src/druntime/import/core/stdc/signal.d) importcore.stdc.wchar_ (/Library/D/dmd/src/druntime/import/core/stdc/wchar_.d) importcore.stdc.time (/Library/D/dmd/src/druntime/import/core/stdc/time.d) importcore.sys.posix.sys.types (/Library/D/dmd/src/druntime/import/core/sys/posix/sys/types.d) importcore.sys.posix.config (/Library/D/dmd/src/druntime/import/core/sys/posix/config.d) importstd.typecons (/Library/D/dmd/src/phobos/std/typecons.d) importstd.traits(/Library/D/dmd/src/phobos/std/traits.d) importstd.typetuple (/Library/D/dmd/src/phobos/std/typetuple.d) importstd.meta (/Library/D/dmd/src/phobos/std/meta.d) importstd.stdiobase (/Library/D/dmd/src/phobos/std/stdiobase.d) importstd.range.primitives (/Library/D/dmd/src/phobos/std/range/primitives.d) semantic hello importcore.stdc.errno (/Library/D/dmd/src/druntime/import/core/stdc/errno.d) entry main hello.d semantic2 hello semantic3 hello file signature.h (/Volumes/Daten/windows/d/develop/d-language/signature.h) ... It works. This made me suspicous what's goind on. The /Volumes/Daten/... device is not the boot device nor the one where my ~home directory is located. So, tried it there: mac-pro:tmp robby$ pwd /Users/robby/tmp mac-pro:tmp robby$ dmd -v -J. hello.d binarydmd version v2.068.0 config/usr/local/bin/dmd.conf parse hello importall hello importobject(/Library/D/dmd/src/druntime/import/object.d) importstd.stdio (/Library/D/dmd/src/phobos/std/stdio.d) importcore.stdc.stdio (/Library/D/dmd/src/druntime/import/core/stdc/stdio.d) importcore.stdc.config (/Library/D/dmd/src/druntime/import/core/stdc/config.d) importcore.stdc.stdarg (/Library/D/dmd/src/druntime/import/core/stdc/stdarg.d) importcore.stdc.stdlib (/Library/D/dmd/src/druntime/import/core/stdc/stdlib.d) importcore.stdc.stddef (/Library/D/dmd/src/druntime/import/core/stdc/stddef.d) import
Re: reading file byLine
On Wednesday, 2 September 2015 at 13:01:31 UTC, Namal wrote: Hello, I want to read a file line by line and store each line in a string. I found this example with byLine and ranges. First of all, do I need the range lib at all to do this and if so what is the range of the end of the file? You don't need the range lib at all, std.range provides advanced functions to work with ranges but ranges are a general concept. You need std.stdio though as this is doing file operations. A way to do it is: void main() { auto f = File("myfile"); string buffer; foreach (line ; f.byLine) { buffer ~= line; } f.close(); writeln(buffer); } Note that by default byLine doesn't keep the line terminator. See http://dlang.org/phobos/std_stdio.html#.File.byLine for more informations.
Re: reading file byLine
On Wednesday, 2 September 2015 at 13:46:54 UTC, Namal wrote: On Wednesday, 2 September 2015 at 13:12:39 UTC, cym13 wrote: On Wednesday, 2 September 2015 at 13:01:31 UTC, Namal wrote: Hello, I want to read a file line by line and store each line in a string. I found this example with byLine and ranges. First of all, do I need the range lib at all to do this and if so what is the range of the end of the file? You don't need the range lib at all, std.range provides advanced functions to work with ranges but ranges are a general concept. You need std.stdio though as this is doing file operations. A way to do it is: void main() { auto f = File("myfile"); string buffer; foreach (line ; f.byLine) { buffer ~= line; } f.close(); writeln(buffer); } Note that by default byLine doesn't keep the line terminator. See http://dlang.org/phobos/std_stdio.html#.File.byLine for more informations. Thx, cym. I have a question about a D strings though. In c++ I would just reuse the string buffer with the "=" how can I clear the string after i store a line in the buffer and do something with it. Just like in C++: buffer = line; However, you can just use "line" instead of "buffer" then. The byLine does buffer internally, so it overwrites "line" on the next iteration of foreach. If you want to keep the line string, then make a copy "line.idup". I also tried to append a line to an array of strings but it failed because the line is a char? Here is how to get an array of lines: import std.stdio; void main() { auto f = File("myfile"); string buffer[]; foreach (line ; f.byLine) { buffer ~= line.idup; } f.close(); writeln(buffer); }
Re: reading file byLine
On Wednesday, 2 September 2015 at 13:46:54 UTC, Namal wrote: Thx, cym. I have a question about a D strings though. In c++ I would just reuse the string buffer with the "=" how can I clear the string after i store a line in the buffer and do something with it. I also tried to append a line to an array of strings but it failed because the line is a char? In D you can do as in C++: buffer = ""; // or a brand new string You can also reset a variable to its initial state (what you would hav had if you hadn't initialized it) using: buffer.init(); When reading files the default type you get is dchar[]. There are different kind of strings in D, you way want to check http://dlang.org/arrays.html#strings . If you want to append to an array of strings, simply convert your line to type string: import std.conv; import std.stdio; void main() { string[] buffer; foreach (line ; File("test.txt").byLine) buffer ~= line.to!string; // <- Here is the magic writeln(buffer); }