Re: How should I return multiple const values from a function?
On 1/2/23 17:56, Paul Backus via Digitalmars-d-learn wrote: return Tuple!(const(Key), const(Value))(k, v); Great! OK, now the code is: auto findFirst () { if (root is null) { Key k = Key.init; Val v = Val.init; return Tuple!(const(Key), const(Val))(k, v); } Node n = root; while (n.lft !is null) n = n.lft; auto k = cast(const)(n.key); auto v = cast(const)(n.val); return Tuple!(const(Key), const(Val))(k, v); } //nd bool findFirst (out Key k, out Val v) I couldn't show that previously because the various things I was trying were too different. -- Javascript is what you use to allow third part programs you don't know anything about and doing you know not what to run on your computer.
Re: How should I return multiple const values from a function?
On 1/2/23 15:14, Paul Backus via Digitalmars-d-learn wrote: On Monday, 2 January 2023 at 22:53:13 UTC, Charles Hixson wrote: I want to return values of the template parameter type, so there doesn't seem to be any way to dup or idup them. It's hard to say where exactly you're going wrong if you only post the error message, without the code that produced it. If you post your code (or a simplified version with the same problem), I'm sure someone will be able to help you. O. Key and Val are template parameters, and Key has a less method defined. -- Javascript is what you use to allow third part programs you don't know anything about and doing you know not what to run on your computer.
Re: How should I return multiple const values from a function?
On 1/2/23 15:14, Paul Backus via Digitalmars-d-learn wrote: On Monday, 2 January 2023 at 22:53:13 UTC, Charles Hixson wrote: I want to return values of the template parameter type, so there doesn't seem to be any way to dup or idup them. It's hard to say where exactly you're going wrong if you only post the error message, without the code that produced it. If you post your code (or a simplified version with the same problem), I'm sure someone will be able to help you. I don't really know where to start. dup doesn't reliably work on template parameters. Assignment returns things that may have internal pointers. The code is 5-6 lines of testing this approach or that, and every single one of them has failed. Some approaches will work with strings, but not with ints, some with ints but not with strings, some may return pointers to internal data. What I'm trying to do is return data that will be const or immutable from a function. They syntax I wanted was something like: bool func (const out Key k, const out Val v) { k = this.key.dup; v = this.val.dup; return true; } but that fails six or seven different ways. -- Javascript is what you use to allow third part programs you don't know anything about and doing you know not what to run on your computer.
How should I return multiple const values from a function?
I want to return values of the template parameter type, so there doesn't seem to be any way to dup or idup them. I don't want the returned values to be able to be used to modify the values held in the table. const out is an illegal parameter type. dup doesn't work on ints. So I tried to return a tuple, but cast(const) doesn't work on strings. (Error: cannot implicitly convert expression `tuple(k, v)` of type `Tuple!(string, string)` to `Tuple!(const(string), const(string))` Sometimes it remembers that I've done the cast, and sometimes it doesn't. The code was: return tuple (cast(const)(Key.init), cast(const)(Val.init)); I've no idea why it was talking about type `Tuple!(string, string)`, since in the test the types were (string, uint). I feel like I'm overlooking something obvious, but I've no idea what. I really just wanted to return dups, but those don't work if one of the types might be an int. (Though I should have been trying to return idups. O, well.) -- Javascript is what you use to allow third part programs you don't know anything about and doing you know not what to run on your computer.
Re: Unexpected path of execution
Thank you. That seems to have solved the problem (bar additional testing). And also thanks for your recommendation to add to the index rather than casting the length. It wasn't as "nice" to my eyes at first, but it's a cleaner answer. On 10/19/21 9:38 AM, Adam D Ruppe via Digitalmars-d-learn wrote: On Tuesday, 19 October 2021 at 16:20:39 UTC, Charles Hixson wrote: given this code fragment: if (i < (line.length - 3) ) in c4: i = 0, line.length = 2 line.length is an unsigned value. Arithmetic on an unsigned thing is still unsigned. So UNSIGNED 2 - 3 is not -1, but instead it is size_t.max since it rolls over. Then the comparison also becomes unsigned. So 0 < size_t.max is true, meaning it goes in there. you should be able to fix it if you do if(i < (cast(int) line.length) - 3) to force it to become signed. But this isn't great either. You probably want to change the code to avoid going negative in the first place. Maybe test `i + 3 < line.length` instead. Or maybe `if(!(i > ... wahtever that is)`. You get the idea im brain farting. I personally hate that array.length is unsigned. And I hate that the signed/unsigned mixing prefers unsigned instead of just about anything else. What a pain in the butt. But that's how it is. -- Javascript is what you use to allow third part programs you don't know anything about and doing you know not what to run on your computer.
Unexpected path of execution
given this code fragment: if (i < (line.length - 3) ) { writeln ("in c4: i = ", i, ", line.length = ", line.length); add2 (c4, line [i..i+4]); I get this result: in c4: i = 0, line.length = 2 core.exception.RangeError@source/freqs.d(32): Range violation ??:? _d_arrayboundsp [0x56041325a70d] ??:? _Dmain [0x560413233beb] Why did this get executed? The if test was supposed to prevent this. DMD64 D Compiler v2.097.2 -- Javascript is what you use to allow third part programs you don't know anything about and doing you know not what to run on your computer.
Re: template parameters :: fix
change: { rl.remove(i); to: { rl = rl.remove(i); -- Javascript is what you use to allow third party programs you don't know anything about and doing you know not what to run on your computer.
Re: template parameters
Thanks. See below for what I did. On 8/29/21 5:05 PM, Ali Çehreli via Digitalmars-d-learn wrote: On 8/29/21 3:31 PM, Charles Hixson wrote: > Thanks. I going to have to study: > > enum supportsCall = isIntegral!(typeof(T.init.%s())); > > > for awhile to make any sense of that, but it looks like just what I was > looking for. Trying to explain with comments: // This is an eponymous template because it contains // a symbol that's the same as the name of this template. // And that symbol is 'supportsCall'. So, this template // will be whatever that symbol is. (In this case, it // will be a compile-time know entity: 'enum bool'.) template supportsCall(T, string func) { import std.format : format; import std.traits : isIntegral; // This is a string expression we will mix-in below. enum expr = format!q{ enum supportsCall = isIntegral!(typeof(T.init.%s())); }(func); // The above expression will be the following e.g. // for 'int' and for "ndx": // // enum supportsCall = isIntegral!(typeof(int.init.ndx())); // // So, it's determining whether the typeof the expression // int.init.ndx() is an integral. // // 'supportsCall' is a bool, which I could have made explicit: // // enum bool supportsCall = [...] // // You can prove it for yourself by "printing" the expression // at compile time: pragma(msg, expr); // Here is where we mix-in the expression into this template's // definition. mixin (expr); } Then the whole template can be used as a compile-time bool value. Ali I'm going to need to save that for the future. I ran into errors in other sections. I suspect that a general form would require static if tests in numerous routines. Anyway, if you're interested this is what I ended up with. (I think it's error free, but not all paths have been tested.) import std.algorithm : remove; import std.exception; import std.stdio; import std.traits : isIntegral; import utils; // this is for my randomized integer code based on time: rndT /** An Associative Array with some Randomization and Linear features. * Note: This is done in a simplified and not too generalized fashion so that I don't need to * figure out template parameters at the moment. It should be redone later, when my mastery * is better. The current version should work for classes and structs that have a function * int T.ndx() that returns a unique id. That id (called the key) is used as an AA index * to find the instance, with duplicates not being allowed. */ class AARL2 (T) { /** The associative array of cells, with the index as the key. */ T[int] aa; /** A linear array of cell key values. This is ordered by the order in which they were * inserted rather than by value. */ int[] rl; /** Create an AARL from an array of cells. The array must have no entries with duplicate * key values (i.e. cell.ndx). Currently this throws an exception. Consider how it could * be handled more gracefully. */ this (T[] inp) { foreach (T c; inp) { int key = c.ndx; enforce (key !in aa, "Attempt to insert a key already present."); aa[key] = c; rl ~= key; } } this () {} /** Access members by serial position of key. (Not the value of the key!) */ T at (int i) in { assert (i >= 0 && i < rl.length, "Index outside bounds"); } body { int key = rl[i]; return aa[key]; } /** This is a read-only count of number of entries. */ long length() { return aa.length; } bool opBinaryRight(string op)(int key) const if (op == "in") { return cast (bool)(key in aa); } bool opBinaryRight(string op)(T c) const if (op == "in") { return cast (bool)(c.ndx in aa); } /** Allow the [] operator to retrieve instances by key value. */ T opIndex(int key) { if (key in aa) return aa[key]; return null; } /** "append" an instance of T. */ void opOpAssign (string op)(T c) // if (op == "~=" && isIntegral!(typeof(T.init.ndx()) if (op == "~") { append (c); } /** "append" an instance of T. * Note: I need a better response to an attempt to add duplicates. */ void append (T c) { if (c is null) { stderr.writeln ("Attempt to add a null T to the AARL rejected."); return; } int key = c.ndx; if (key in aa) { aa[key] = c; } else { aa[key] = c; rl ~= key;
Re: template parameters
Thanks. I going to have to study: enum supportsCall = isIntegral!(typeof(T.init.%s())); for awhile to make any sense of that, but it looks like just what I was looking for. On 8/29/21 2:41 PM, Ali Çehreli via Digitalmars-d-learn wrote: On 8/29/21 11:32 AM, Charles H. wrote: I've set up a class template (so far untested) thus: class AARL (T, ndx = "ndx") if (isIntegral(T.init.ndx) ) If I'm correct, this should work for ndx an integer variable of T, but I'd really like T to be able to be anything which can be stored both in an array and in an associative array. But I can't figure out how to specify ndx. After all, T might be a float, so it wouldn't have any appropriate attributes. And I'd also like ndx to be able to be a function either a member of the class/struct T or a stand alone function. So how should I set up this template? I came up with the following: template supportsCall(T, string func) { import std.format : format; import std.traits : isIntegral; enum expr = format!q{ enum supportsCall = isIntegral!(typeof(T.init.%s())); }(func); mixin (expr); } class AARL (T, string func = "ndx") if (supportsCall!(T, func)) { } int ndx(int i) { return 42; } struct S { long ndx() { return 100; } } void main() { auto a = new AARL!int(); auto b = new AARL!S(); } Ali -- Javascript is what you use to allow third part programs you don't know anything about and doing you know not what to run on your computer.
template parameters
I've set up a class template (so far untested) thus: class AARL (T, ndx = "ndx") if (isIntegral(T.init.ndx) ) If I'm correct, this should work for ndx an integer variable of T, but I'd really like T to be able to be anything which can be stored both in an array and in an associative array. But I can't figure out how to specify ndx. After all, T might be a float, so it wouldn't have any appropriate attributes. And I'd also like ndx to be able to be a function either a member of the class/struct T or a stand alone function. So how should I set up this template? -- Javascript is what you use to allow third part programs you don't know anything about and doing you know not what to run on your computer.
Re: auto: useful, annoying or bad practice?
auto has its uses, but it's wildly overused, especially in library code and documentation, and really, really, *really* much so in documentation examples. On 05/01/2018 06:09 AM, Craig Dillabaugh via Digitalmars-d wrote: On Monday, 30 April 2018 at 21:11:07 UTC, Gerald wrote: I'll freely admit I haven't put a ton of thought into this post (never a good start), however I'm genuinely curious what people's feeling are with regards to the auto keyword. Speaking for myself, I dislike the auto keyword. Some of this is because I have a preference for static languages and I find auto adds ambiguity with little benefit. Additionally, I find it annoying that the phobos documentation relies heavily on auto obscuring return types and making it a bit more difficult to follow what is happening which gives me a bad taste for it. clip So I'm curious, what's the consensus on auto? As some have pointed out, it certainly has value. For example, in functions returning ranges, etc. where you wouldn't want to have to write out the whole type. However, as an infrequent D user I admit I prefer to see the actual type where it is feasible, as I find 'auto' is a barrier to understanding to someone who isn't familiar with a particular piece of code. I would never use auto in place of a basic type.
Re: shared arrray problem
On 11/20/2016 12:41 PM, ag0aep6g via Digitalmars-d-learn wrote: On 11/20/2016 09:09 PM, Charles Hixson via Digitalmars-d-learn wrote: Thinking it over a bit more, the item returned would need to be a struct, but the struct wouldn't contain the array, it would just contain a reference to the array and a start and end offset. The array would need to live somewhere else, in the class (or struct...but class is better as you don't want the array evaporating by accident) that created the returned value. This means you are dealing with multiple levels of indirection, so it's costly compared to array access, but cheap compared to lots of large copies. So the returned value would be something like: struct { private: /** this is a reference to the data that lives elsewhere. It should be a pointer, but I don't like the syntax*/ ubyte[] data; intstart, end;///first and last valid indicies into data public: this (ubyte[] data, int start, int end) {this.data = data; this.start = start; this.end = end;} ... // various routines to access the data, but to limit the access to the spec'd range, and // nothing to change the bounds } Instead of extra 'start' and 'end' fields you can slice the array. A dynamic array already is just a reference coupled with a length, i.e. a pointer with restricted indexing. So you can slice the original array with your offsets and create the struct with that slice. I feel like there is a misunderstanding somewhere, but I'm not sure on whose side. As far as I can tell, your understanding of dynamic arrays may be lacking, or maybe I don't understand what you're getting at. While you are definitely correct about slices, I really feel more comfortable with the start and end fields. I keep being afraid some smart optimizer is going to decide I don't really need the entire array. This is probably unjustified, but I find start and end fields easier to think about. I don't think either of us misunderstands what's going on, we just feel differently about methods that are approximately equivalent. Slices would probably be marginally more efficient (well, certainly so as you'd need two less fields), so if this were a public library there would be an excellent argument for doing it your way. I keep trying to think of a reason that start and end fields are better, and failing. All I've got is that I feel more comfortable with them. Which is really the answer you already posted, but just a bit more detail on the construct, and what it meant. (Yeah, I could allow types other than ubyte as the base case, but I don't want to. I'm thinking of this mainly as a means of sharing a buffer between applications where different parts have exclusive access to different parts of the buffer, and where the buffer will be written to a file with a single fwrite, or since the underlying storage will be an array, it could even be rawwrite). I don't want to specify any more than I must about how the methods calling this will format the storage, and this means that those with access to different parts may well use different collections of types, but all types eventually map down to ubytes (or bytes), so ubytes is the common ground. Perhaps I'll need to write inbuffer,outbuffer methods/wrappings, but that's far in the future. Sure, go with a specialized type instead of a template, if that makes more sense for your use case. As far as I see, the concept is independent of the element type, so it seemed natural to make it a template, but a special type is perfectly fine and probably has less pitfalls. P.S.: The traits that I mentioned previously were those given by: static assert(!__traits(compiles, cla.length = 3)); static assert(!__traits(compiles, cla ~= 6)); in your main routine. I assumed that they were validity tests. I don't understand why they were static. I've never happened to use static asserts, but I would assume that when they ran cla wouldn't be defined. Those are tests to ensure that cla's length cannot be set and that it cannot be appended to. The asserts check that the code does not compile, i.e. that you cannot do those things. They're static simply because they can be. The code inside is not executed at run-time.
Re: shared arrray problem
On 11/20/2016 03:42 AM, ag0aep6g via Digitalmars-d-learn wrote: On 11/20/2016 04:34 AM, Charles Hixson via Digitalmars-d-learn wrote: Whether you would call the change "break things for your code" might be dubious. It would be effectively broken, even if technically my code was doing the correct thing. But my code wouldn't be storing the data that needed storing, so effectively it would be broken. I don't see how it's dubious. It's an error by the user. When users are given a dynamic array (and not by reference), they cannot expect that your code sees changes to length. That's just not how arrays work. When a user has that wrong expectation, and writes wrong code because of it, then it's arguably their own fault. However, if you want you can hold their hand a bit and make the mistake less likely. "Write something for yourself" is what I'd like to do, given that the language doesn't have that built-in support, but I can't see how to do it. Wrap the array in a struct that has indexing, but doesn't allow setting the length or appending. Here's a quick prototype: struct ConstLengthArray(E) { private E[] data; this(E[] arr) { this.data = arr; } ref inout(E) opIndex(size_t i) inout { return data[i]; } @property size_t length() const { return data.length; } } void main() { auto cla = ConstLengthArray!ubyte([1, 2, 3, 4, 5]); /* Mutating elements is allowed: */ cla[0] = 10; assert(cla[0] == 10); /* No setting length, no appending: */ static assert(!__traits(compiles, cla.length = 3)); static assert(!__traits(compiles, cla ~= 6)); } You might want to add support for slicing, concatenation, etc. Maybe allow implicit conversion to const(E[]), though that would also allow conversion to const(E)[] and that has a settable length again Thinking it over a bit more, the item returned would need to be a struct, but the struct wouldn't contain the array, it would just contain a reference to the array and a start and end offset. The array would need to live somewhere else, in the class (or struct...but class is better as you don't want the array evaporating by accident) that created the returned value. This means you are dealing with multiple levels of indirection, so it's costly compared to array access, but cheap compared to lots of large copies. So the returned value would be something like: struct { private: /** this is a reference to the data that lives elsewhere. It should be a pointer, but I don't like the syntax*/ ubyte[] data; intstart, end;///first and last valid indicies into data public: this (ubyte[] data, int start, int end) {this.data = data; this.start = start; this.end = end;} ... // various routines to access the data, but to limit the access to the spec'd range, and // nothing to change the bounds } Which is really the answer you already posted, but just a bit more detail on the construct, and what it meant. (Yeah, I could allow types other than ubyte as the base case, but I don't want to. I'm thinking of this mainly as a means of sharing a buffer between applications where different parts have exclusive access to different parts of the buffer, and where the buffer will be written to a file with a single fwrite, or since the underlying storage will be an array, it could even be rawwrite). I don't want to specify any more than I must about how the methods calling this will format the storage, and this means that those with access to different parts may well use different collections of types, but all types eventually map down to ubytes (or bytes), so ubytes is the common ground. Perhaps I'll need to write inbuffer,outbuffer methods/wrappings, but that's far in the future. P.S.: The traits that I mentioned previously were those given by: static assert(!__traits(compiles, cla.length = 3)); static assert(!__traits(compiles, cla ~= 6)); in your main routine. I assumed that they were validity tests. I don't understand why they were static. I've never happened to use static asserts, but I would assume that when they ran cla wouldn't be defined. N.B.: Even this much is just thinking about design, not something I'll actually do at the moment. But this is a problem I keep coming up against, so a bit of thought now seemed a good idea.
Re: shared arrray problem
On 11/20/2016 03:42 AM, ag0aep6g via Digitalmars-d-learn wrote: On 11/20/2016 04:34 AM, Charles Hixson via Digitalmars-d-learn wrote: Whether you would call the change "break things for your code" might be dubious. It would be effectively broken, even if technically my code was doing the correct thing. But my code wouldn't be storing the data that needed storing, so effectively it would be broken. I don't see how it's dubious. It's an error by the user. When users are given a dynamic array (and not by reference), they cannot expect that your code sees changes to length. That's just not how arrays work. When a user has that wrong expectation, and writes wrong code because of it, then it's arguably their own fault. However, if you want you can hold their hand a bit and make the mistake less likely. "Write something for yourself" is what I'd like to do, given that the language doesn't have that built-in support, but I can't see how to do it. Wrap the array in a struct that has indexing, but doesn't allow setting the length or appending. Here's a quick prototype: struct ConstLengthArray(E) { private E[] data; this(E[] arr) { this.data = arr; } ref inout(E) opIndex(size_t i) inout { return data[i]; } @property size_t length() const { return data.length; } } void main() { auto cla = ConstLengthArray!ubyte([1, 2, 3, 4, 5]); /* Mutating elements is allowed: */ cla[0] = 10; assert(cla[0] == 10); /* No setting length, no appending: */ static assert(!__traits(compiles, cla.length = 3)); static assert(!__traits(compiles, cla ~= 6)); } You might want to add support for slicing, concatenation, etc. Maybe allow implicit conversion to const(E[]), though that would also allow conversion to const(E)[] and that has a settable length again. Well, that precise approach wouldn't work. (The traits aren't a part of the sturct, e.g.), but returning a struct (or perhaps a class) rather than an actual array has promise. It could even allow separate callers to have separate views of the data based on some sort of registered key, which they could share on an as-needed basis. That's too much overhead work for this project, but has promise for the more general problem.
Re: shared arrray problem
On 11/19/2016 05:52 PM, ag0aep6g via Digitalmars-d-learn wrote: On 11/20/2016 01:33 AM, Charles Hixson via Digitalmars-d-learn wrote: Yes. I was hoping someone would pop up with some syntax making the array, but not its contents, const or immutable, which I couldn't figure out how to do, and which is what I really hoped would be the answer, but it appears that this isn't part of the syntax. Yup, head const is not part of the language. You'd have to find a library solution or write something yourself. I really *can't* allow the length to be changed, Your emphasis suggests that user could break things for your code. They can't. Any changes to the length will only affect the slice on the user's end. They can only fool themselves. That may be bad enough to warrant a more restricted return type, but for your code it's safe to return a plain dynamic array. Whether you would call the change "break things for your code" might be dubious. It would be effectively broken, even if technically my code was doing the correct thing. But my code wouldn't be storing the data that needed storing, so effectively it would be broken. "Write something for yourself" is what I'd like to do, given that the language doesn't have that built-in support, but I can't see how to do it. I want to end up with a continuous array of ubytes of a given length with certain parts reserved to only be directly accessible to the defining class, and other parts accessible to the calling class(es). And the length of the array isn't known until run time. So I guess the only safe solution is to do an extra copy...which isn't a problem in this particular application as I only need to do it twice per file opening (once on opening, once on closing), but for other applications would be a real drag.
Re: shared arrray problem
On 11/19/2016 01:50 PM, ag0aep6g via Digitalmars-d-learn wrote: On 11/19/2016 10:26 PM, Charles Hixson via Digitalmars-d-learn wrote: It's worse than that, if they modify the length the array may be reallocated in RAM so that the pointers held by the containing class do not point to the changed values. (Read the header comments...it's not nice at all.) Arguably, any D programmer must be aware that appending to a dynamic array potentially means making a copy of the data, and that changes to length are not visible to other views of the data. But it's an opportunity to mess up, for sure. You could return a wrapper around the array that supports editing the data but not changing the length or appending. Looks like std.experimental.typecons.Final [1] is supposed to be that wrapper. But in a little test I can still set the length. Not sure if that's a bug, or if Final has slightly different goals. [1] https://dlang.org/phobos/std_experimental_typecons.html#.Final Yes. I was hoping someone would pop up with some syntax making the array, but not its contents, const or immutable, which I couldn't figure out how to do, and which is what I really hoped would be the answer, but it appears that this isn't part of the syntax. If the array is constant, so is it's contents. I really *can't* allow the length to be changed, and if the array is reallocated, it won't get saved. But the contents of the array are intended to be changed by the calling routines. Again, for this particular problem the kludge of copying the values into the array works fine (and is what I've decided to do), but that's not a good general solution to this kind of problem.
Re: shared arrray problem
On 11/19/2016 11:10 AM, Nicolas Gurrola via Digitalmars-d-learn wrote: On Saturday, 19 November 2016 at 18:51:05 UTC, Charles Hixson wrote: ubyte[]header()@property {return fHead[4..$];} This method should do what you want. You are only returning a slice of the fHead array, so if the caller modifies the length it will only affect of the return value, and not the length of fHead itself. It's worse than that, if they modify the length the array may be reallocated in RAM so that the pointers held by the containing class do not point to the changed values. (Read the header comments...it's not nice at all.) More, the class explicitly requires the array to be a particular length as it needs to fit into a spot in a binary file, so I really want to forbid any replacement of the array for any reason. The first four bytes are managed by the class and returned via alternate routines which do not allow the original values to be altered, and this is necessary. I could make them immutable, but actually what I do is return, e.g., an int of 256 * fHead[0] + fHead[1], which is the length of the header. It's an int to allow negative values to be returned in case of error. So what I'll probably eventually decide on is some variation of saveToHead, e.g.: boolsaveToHeader(ubyte[] rec) { if(rec.length + 4 > dheader)returnfalse; fHead[4..recLen + 4] = rec[0..$]; returntrue; } unless I can think of something better. Actually for this particular case that's not a bad approach, but for the larger problem it's a lousy kludge.
Re: fPIC Error
On 11/18/2016 10:35 PM, deadalnix via Digitalmars-d-learn wrote: On Thursday, 3 November 2016 at 06:11:48 UTC, rikki cattermole wrote: [Environment32] DFLAGS=-I/usr/include/dmd/phobos -I/usr/include/dmd/druntime/import -L-L/usr/lib/i386-linux-gnu -L--export-dynamic -fPIC -defaultlib=libphobos2.so [Environment64] DFLAGS=-I/usr/include/dmd/phobos -I/usr/include/dmd/druntime/import -L-L/usr/lib/x86_64-linux-gnu -L--export-dynamic -fPIC -defaultlib=libphobos2.so I'm sorry bit that's horseshit. I'm not compiling everything with fPIC because DMD can't get it's act straight. IIRC, LDC didn't have that problem. I don't remember testing gdc. But, yes, it is quite annoying.
shared arrray problem
I have a piece of code that looks thus: /**Returns an editable file header missing the header length and data * length portions. Those cannot be edited by a routine outside this class. * Access to them is available via the lenHead and lenRec functions. * Warning: Do NOT change the size of the header. If you do the size * will be reset to the current value before it is saved, and results are * unpredictable. Also do not replace it. This class maintains it's own * pointer to the header, and your replacement will be ignored. */ ubyte[]header()@property{return fHead[4..$];} I want other classes to be able to modify the tail of the array, but not to resize it. Eventually it should be written to a file. This way works (well, should work) but looks radically unsafe for the reasons indicated in the comments. I'm sure there must be a better way, but can't think of what it would be. The only alternative I've been able to think of is, approx: boolsaveToHeader (ubyte[] rec){ ... buf[4..$] = rec[0..$]; ... } but that would be guaranteed to have an extra copying step, and it's bool because if the length of the passed parameter isn't correct saveToHeader would fail. It may still be better since in this case the copying would be rather minimal, but the general problem bothers me because I don't see a good solution.
Re: Is it possible to store different generic types in ex. an
On 11/09/2016 07:46 AM, Is it possible to store different generic types? via Digitalmars-d-learn wrote: On Wednesday, 9 November 2016 at 15:44:59 UTC, Is it possible to store different generic types? wrote: Is it possible to store different generic types in ex. somekind of container such as an array, hashtable etc. Let's say we got class Foo(T) { ... } Would it be possible to store something like Foo[] foos; // Where Foo of course should allow any generic version of Foo Ex. Foo!int and Foo!string should both be able to be stored inside the array. If so how would one construct an array like that or is there some other container that may be able to do it? I'm aware that I could have Foo inherit a base class and then use casting, but I would like to avoid casting if possible. You don't necessarily have to do casting if all of the objects that you are going to store use the same methods for the purposes that you are going to use them. Just craft an interface that they all implement and inherit from that. But if they don't all implement all the methods you are going to need, you can't avoid casting unless you do something like: 1) create a dummy class (I don't *think* an abstract class would work) that implements all the methods you are going to need with dummy methods. 2) inherit all the classes you are going to use from that class 3) be sure to use override on the methods that are actually implemented. Even then I'm not sure this would work. Since you are doing something like: Dummy[Key] stuff; when you retrieve an item from stuff, what you retrieve will be the actual item, but the system will probably think it's a Dummy unless you properly cast it. So go with the interface approach, even if that means implementing dummy methods for some of the classes. (OTOH, I haven't actually *tried* that inherit from a common class...it might work. I'd just bet against it without casting.) The basic idea here is that all the objects that you store have to implement all the methods that you are going to use on any of them, but the implementations can be something like: void method1(){assert (false, "You should never come here"); }
Re: problem with isnan
On 11/11/2016 01:34 PM, John C via Digitalmars-d-learn wrote: On Friday, 11 November 2016 at 20:55:52 UTC, Charles Hixson wrote: Thank you. Unfortunately: importstd.math; ... assert(isNan (c.curActivation), "cell has unexpected curActivation: %s".format(c.curActivation)); yields: cell.d(292): Error: undefined identifier 'isNan', did you mean overloadset 'isnan'? It should be isNaN. Ok, now it seems the same as std.math.isnan, (i.e., it works properly). On looking over the error messages more closely (just now) I noticed that the line number had now changed. Whoops! It just *LOOKED* like the error hadn't been fixed, where it had actually moved onto the next one. The hint should have been that it was printing an integer value...I mean besides the changed line number.
Re: problem with isnan
On 11/11/2016 10:31 AM, pineapple via Digitalmars-d-learn wrote: On Thursday, 10 November 2016 at 16:47:30 UTC, Adam D. Ruppe wrote: On Thursday, 10 November 2016 at 16:41:56 UTC, Charles Hixson wrote: It's *supposed* to be nan, and the assert message reports that it is, but it should pass the assert test, not throw an assertion. What am I doing wrong? How did you set it? There are like billions of different NaNs. I'm not sure if isnan checks for all of them. (I'm also not sure that it doesn't, the docs don't specify.) you might try using std.math.isNaN instead and see what it does. Incidentally, I just recently submitted a PR to fix this. What probably happened is that you're referring to a limited `isnan` method defined as a unittest utility method in object.d that should have been private but wasn't. You want to use `isNan` instead. Thank you. Unfortunately: importstd.math; ... assert(isNan (c.curActivation), "cell has unexpected curActivation: %s".format(c.curActivation)); yields: cell.d(292): Error: undefined identifier 'isNan', did you mean overloadset 'isnan'? while: importstd.math; ... assert(std.math.isnan (c.curActivation), "cell has unexpected curActivation: %s".format(c.curActivation)); yields: core.exception.AssertError@cell.d(310): cell has unexpected idno: 636144943519357244 That is, indeed, an unexpected value, unless it's some representation of Nan, in which case it should have passed the assert. I notice that it doesn't appear to be a float, which puzzles me.
Re: problem with isnan
On 11/10/2016 08:47 AM, Adam D. Ruppe via Digitalmars-d-learn wrote: On Thursday, 10 November 2016 at 16:41:56 UTC, Charles Hixson wrote: It's *supposed* to be nan, and the assert message reports that it is, but it should pass the assert test, not throw an assertion. What am I doing wrong? How did you set it? There are like billions of different NaNs. I'm not sure if isnan checks for all of them. (I'm also not sure that it doesn't, the docs don't specify.) you might try using std.math.isNaN instead and see what it does. It was default initialized by the class instance: classCell ... floatcurActivation; ... The this method doesn't have any mention of a few variables that are supposed to be default initialized, or which curActivation is one. I suppose I could set it to be -2.0 or something, but that doesn't really tell me what's going on.
problem with isnan
The line: assert(isnan (c.curActivation), "cell has unexpected curActivation: %s".format(c.curActivation)); throws the exception: core.exception.AssertError@cell.d(285): cell has unexpected curActivation: nan and I've looked at it backwards and forwards and don't understand why. It's *supposed* to be nan, and the assert message reports that it is, but it should pass the assert test, not throw an assertion. What am I doing wrong?
Re: Sockets and using them...
On 11/05/2016 11:02 PM, Era Scarecrow via Digitalmars-d-learn wrote: So I've got a project where I want to create basically a decentralized chat program where every program is a host and a client. When you connect all connections can go through to route the chat to everyone else. So to make this work I've looked over the sockets package and I don't quite follow how you'd make it so it works a lot like a web browser, aka when you get a connection you redirect to a different port so you have 1 listening port for new connections so it can act as a server. What settings or configuration would I need to be able to do that? That sounds more like a job for udp than tcp sockets. You'd need to implement an ack/nak protocol because udp doesn't guarantee delivery, but unless you want a central server I don't see how you could use tcp. The central server wouldn't need to do much, and could delegate most of the processing, but it wouldn't be decentralized. I was looking into using tcp (actually zmq) for something similar awhile back and tcp just didn't seem to support actually decentralized communication. Udp did...which meant I couldn't use zmq. That was a real pity because zmq is basically a very nice package, and easy to wrap.
Re: strange -fPIC compilation error
On 11/01/2016 10:34 AM, bachmeier via Digitalmars-d-learn wrote: On Tuesday, 1 November 2016 at 17:23:54 UTC, Charles Hixson wrote: On 11/01/2016 12:52 AM, Nordlöw via Digitalmars-d-learn wrote: On Tuesday, 1 November 2016 at 07:15:19 UTC, Mike Parker wrote: but dmd -defaultlib=libphobos2.so -fPIC test.d works. It shouldn't be required (as in the default /etc/dmd.conf should handle it correctly, but I can deal with it now. Can this be fed as parameters to the DMD call (programmatically) instead of manual editing of dmd.conf? I did feed it into the dmd call programmatically. Thus: dmd -defaultlib=libphobos2.so -fPIC test.d I'm reluctant to edit the dmd.conf file as I don't really understand the syntax...and I have to be root to do the editing. https://dlang.org/dmd-linux.html#dmd-conf You can copy dmd.conf to the current working directory and try out changes there. That will only affect the current program. Then you can move it to your home directory. I'll probably do that eventually...but for now I'm just pasting a comment at the start of each file that tells how to compile it, e.g.: //ldc2 -Dddocs -c msg.d<<--no documentation generated //dmd -Dddocs -c msg.d //rdmd -main -Dddocs -unittest -defaultlib=libphobos2.so -fPIC msg.d
Re: strange -fPIC compilation error
On 11/01/2016 12:52 AM, Nordlöw via Digitalmars-d-learn wrote: On Tuesday, 1 November 2016 at 07:15:19 UTC, Mike Parker wrote: but dmd -defaultlib=libphobos2.so -fPIC test.d works. It shouldn't be required (as in the default /etc/dmd.conf should handle it correctly, but I can deal with it now. Can this be fed as parameters to the DMD call (programmatically) instead of manual editing of dmd.conf? I did feed it into the dmd call programmatically. Thus: dmd -defaultlib=libphobos2.so -fPIC test.d I'm reluctant to edit the dmd.conf file as I don't really understand the syntax...and I have to be root to do the editing.
Re: strange -fPIC compilation error
On 10/31/2016 12:31 PM, Daniel Kozak via Digitalmars-d-learn wrote: Dne 31.10.2016 v 20:20 Charles Hixson via Digitalmars-d-learn napsal(a): ... but dmd -defaultlib=libphobos2.so -fPIC test.d works. It shouldn't be required (as in the default /etc/dmd.conf should handle it correctly, but I can deal with it now. It should work, it is possible that you have some another dmd.conf somewhere? I did have a couple lying around, but they worked fine in the past, and renaming them didn't fix, or even just change, anything. I've still got some others on my backup partition, but I can't imagine that they would be in use. One of them was there because I had a few macros that were specified in an external ddoc file that was used by one project, e.g.
Re: strange -fPIC compilation error
On 10/31/2016 11:23 AM, Daniel Kozak via Digitalmars-d-learn wrote: Dne 31.10.2016 v 18:06 Charles Hixson via Digitalmars-d-learn napsal(a): On 10/31/2016 09:26 AM, Charles Hixson via Digitalmars-d-learn wrote: On 10/30/2016 11:34 PM, Daniel Kozak via Digitalmars-d-learn wrote: Dne 31.10.2016 v 02:30 Charles Hixson via Digitalmars-d-learn napsal(a): Well, that certainly changed the error messages. With dmd -defaultlib=/usr/lib/x86_64-linux-gnu/libphobos2.so test.d I get: /usr/include/dmd/druntime/import/core/stdc/stdio.d(1121): Error: found 'nothrow' when expecting '{' /usr/include/dmd/druntime/import/core/stdc/stdio.d(1123): Error: mismatched number of curly brackets /usr/include/dmd/druntime/import/core/stdc/stdio.d(1124): Error: mismatched number of curly brackets /usr/include/dmd/druntime/import/core/stdc/stdio.d(1125): Error: mismatched number of curly brackets /usr/include/dmd/druntime/import/core/stdc/stdio.d(1126): Error: mismatched number of curly brackets /usr/include/dmd/druntime/import/core/stdc/stdio.d(1127): Error: mismatched number of curly brackets /usr/include/dmd/druntime/import/core/stdc/stdio.d(1128): Error: mismatched number of curly brackets /usr/include/dmd/druntime/import/core/stdc/stdio.d(1129): Error: mismatched number of curly brackets /usr/include/dmd/druntime/import/core/stdc/stdio.d(1133): Error: asm statements must end in ';' /usr/include/dmd/druntime/import/core/stdc/stdio.d(1136): Error: found 'private' instead of statement /usr/include/dmd/druntime/import/core/stdc/stdio.d(1146): Error: no identifier for declarator add /usr/include/dmd/druntime/import/core/stdc/stdio.d(1149): Error: no identifier for declarator usDone /usr/include/dmd/druntime/import/core/stdc/stdio.d(1149): Error: Declaration expected, not ':' /usr/include/dmd/druntime/import/core/stdc/stdio.d(1157): Error: Declaration expected, not '(' /usr/include/dmd/druntime/import/core/stdc/stdio.d(1159): Error: Declaration expected, not 'foreach' /usr/include/dmd/druntime/import/core/stdc/stdio.d(1159): Error: Declaration expected, not '0' /usr/include/dmd/druntime/import/core/stdc/stdio.d(1164): Error: no identifier for declarator __fhnd_info[fd] /usr/include/dmd/druntime/import/core/stdc/stdio.d(1164): Error: Declaration expected, not '=' /usr/include/dmd/druntime/import/core/stdc/stdio.d(1165): Error: Declaration expected, not 'return' /usr/include/dmd/druntime/import/core/stdc/stdio.d(1167): Error: unrecognized declaration /usr/include/dmd/phobos/std/typecons.d(1124): Error: semicolon expected following function declaration This seems to be problem with your installation, you probably have diferen version of dmd compiler and phobos library. So you should uninstall all your dmd packages and make sure there is no /usr/include/dmd left in your system. And instal dmd only from one source (d-apt idealy). I've done that 2 or 3 times. If that's the problem, then there are different versions stored in the repository. Since I'm on debian testing I'd been assuming that there'd been some system change since I'd last used the compiler, and the debs weren't yet up to date. The only updates to my system prior to the compiler breaking HAD been via apt-get. Since then I've used dpkg remove and install a couple of times to try other versions of dmd with no benefit. Currently dmd-bin version 2.071.2-0 libphobos2.071.2-0 libphobos2.071.2-0 so they're LISTED as being the same version. And dmd.conf was installed by the deb, and is (eliminating the comments): [Environment32] DFLAGS=-I/usr/include/dmd/phobos -I/usr/include/dmd/druntime/import -L-L/usr/lib/i386-linux-gnu -L--export-dynamic [Environment64] DFLAGS=-I/usr/include/dmd/phobos -I/usr/include/dmd/druntime/import -L-L/usr/lib/x86_64-linux-gnu -L--export-dynamic But somewhere during the process (which included the nightly system update) the error messages changed, and now: dmd test.d yields: /usr/include/dmd/druntime/import/core/stdc/stdio.d(1121): Error: found 'nothrow' when expecting '{' /usr/include/dmd/druntime/import/core/stdc/stdio.d(1123): Error: mismatched number of curly brackets ... /usr/include/dmd/druntime/import/core/stdc/stdio.d(1167): Error: unrecognized declaration /usr/include/dmd/phobos/std/typecons.d(1124): Error: semicolon expected following function declaration FWIW starting at /usr/include/dmd/druntime/import/core/stdc/stdio.d(1121):: asm nothrow @nogc { mov EDX, num; lock; inc _iSemLockCtrs[EDX * 2]; so nothrow isn't being seen as appropriate at the beginning of an asm block. After that I think it gets confused as 1123 doesn't HAVE a brace (i.e. curly bracket) in it. when you type dmd --version what it prints? THAT WAS THE CLUE! (that which follows is how I proceeded to the answer after that clue.) dmd -version Error: unrecognized switch '-version' and dmd --version Error
Re: strange -fPIC compilation error
On 10/31/2016 09:26 AM, Charles Hixson via Digitalmars-d-learn wrote: On 10/30/2016 11:34 PM, Daniel Kozak via Digitalmars-d-learn wrote: Dne 31.10.2016 v 02:30 Charles Hixson via Digitalmars-d-learn napsal(a): Well, that certainly changed the error messages. With dmd -defaultlib=/usr/lib/x86_64-linux-gnu/libphobos2.so test.d I get: /usr/include/dmd/druntime/import/core/stdc/stdio.d(1121): Error: found 'nothrow' when expecting '{' /usr/include/dmd/druntime/import/core/stdc/stdio.d(1123): Error: mismatched number of curly brackets /usr/include/dmd/druntime/import/core/stdc/stdio.d(1124): Error: mismatched number of curly brackets /usr/include/dmd/druntime/import/core/stdc/stdio.d(1125): Error: mismatched number of curly brackets /usr/include/dmd/druntime/import/core/stdc/stdio.d(1126): Error: mismatched number of curly brackets /usr/include/dmd/druntime/import/core/stdc/stdio.d(1127): Error: mismatched number of curly brackets /usr/include/dmd/druntime/import/core/stdc/stdio.d(1128): Error: mismatched number of curly brackets /usr/include/dmd/druntime/import/core/stdc/stdio.d(1129): Error: mismatched number of curly brackets /usr/include/dmd/druntime/import/core/stdc/stdio.d(1133): Error: asm statements must end in ';' /usr/include/dmd/druntime/import/core/stdc/stdio.d(1136): Error: found 'private' instead of statement /usr/include/dmd/druntime/import/core/stdc/stdio.d(1146): Error: no identifier for declarator add /usr/include/dmd/druntime/import/core/stdc/stdio.d(1149): Error: no identifier for declarator usDone /usr/include/dmd/druntime/import/core/stdc/stdio.d(1149): Error: Declaration expected, not ':' /usr/include/dmd/druntime/import/core/stdc/stdio.d(1157): Error: Declaration expected, not '(' /usr/include/dmd/druntime/import/core/stdc/stdio.d(1159): Error: Declaration expected, not 'foreach' /usr/include/dmd/druntime/import/core/stdc/stdio.d(1159): Error: Declaration expected, not '0' /usr/include/dmd/druntime/import/core/stdc/stdio.d(1164): Error: no identifier for declarator __fhnd_info[fd] /usr/include/dmd/druntime/import/core/stdc/stdio.d(1164): Error: Declaration expected, not '=' /usr/include/dmd/druntime/import/core/stdc/stdio.d(1165): Error: Declaration expected, not 'return' /usr/include/dmd/druntime/import/core/stdc/stdio.d(1167): Error: unrecognized declaration /usr/include/dmd/phobos/std/typecons.d(1124): Error: semicolon expected following function declaration This seems to be problem with your installation, you probably have diferen version of dmd compiler and phobos library. So you should uninstall all your dmd packages and make sure there is no /usr/include/dmd left in your system. And instal dmd only from one source (d-apt idealy). I've done that 2 or 3 times. If that's the problem, then there are different versions stored in the repository. Since I'm on debian testing I'd been assuming that there'd been some system change since I'd last used the compiler, and the debs weren't yet up to date. The only updates to my system prior to the compiler breaking HAD been via apt-get. Since then I've used dpkg remove and install a couple of times to try other versions of dmd with no benefit. Currently dmd-bin version 2.071.2-0 libphobos2.071.2-0 libphobos2.071.2-0 so they're LISTED as being the same version. And dmd.conf was installed by the deb, and is (eliminating the comments): [Environment32] DFLAGS=-I/usr/include/dmd/phobos -I/usr/include/dmd/druntime/import -L-L/usr/lib/i386-linux-gnu -L--export-dynamic [Environment64] DFLAGS=-I/usr/include/dmd/phobos -I/usr/include/dmd/druntime/import -L-L/usr/lib/x86_64-linux-gnu -L--export-dynamic But somewhere during the process (which included the nightly system update) the error messages changed, and now: dmd test.d yields: /usr/include/dmd/druntime/import/core/stdc/stdio.d(1121): Error: found 'nothrow' when expecting '{' /usr/include/dmd/druntime/import/core/stdc/stdio.d(1123): Error: mismatched number of curly brackets ... /usr/include/dmd/druntime/import/core/stdc/stdio.d(1167): Error: unrecognized declaration /usr/include/dmd/phobos/std/typecons.d(1124): Error: semicolon expected following function declaration FWIW starting at /usr/include/dmd/druntime/import/core/stdc/stdio.d(1121):: asm nothrow @nogc { mov EDX, num; lock; inc _iSemLockCtrs[EDX * 2]; so nothrow isn't being seen as appropriate at the beginning of an asm block. After that I think it gets confused as 1123 doesn't HAVE a brace (i.e. curly bracket) in it.
Re: strange -fPIC compilation error
On 10/30/2016 11:34 PM, Daniel Kozak via Digitalmars-d-learn wrote: Dne 31.10.2016 v 02:30 Charles Hixson via Digitalmars-d-learn napsal(a): Well, that certainly changed the error messages. With dmd -defaultlib=/usr/lib/x86_64-linux-gnu/libphobos2.so test.d I get: /usr/include/dmd/druntime/import/core/stdc/stdio.d(1121): Error: found 'nothrow' when expecting '{' /usr/include/dmd/druntime/import/core/stdc/stdio.d(1123): Error: mismatched number of curly brackets /usr/include/dmd/druntime/import/core/stdc/stdio.d(1124): Error: mismatched number of curly brackets /usr/include/dmd/druntime/import/core/stdc/stdio.d(1125): Error: mismatched number of curly brackets /usr/include/dmd/druntime/import/core/stdc/stdio.d(1126): Error: mismatched number of curly brackets /usr/include/dmd/druntime/import/core/stdc/stdio.d(1127): Error: mismatched number of curly brackets /usr/include/dmd/druntime/import/core/stdc/stdio.d(1128): Error: mismatched number of curly brackets /usr/include/dmd/druntime/import/core/stdc/stdio.d(1129): Error: mismatched number of curly brackets /usr/include/dmd/druntime/import/core/stdc/stdio.d(1133): Error: asm statements must end in ';' /usr/include/dmd/druntime/import/core/stdc/stdio.d(1136): Error: found 'private' instead of statement /usr/include/dmd/druntime/import/core/stdc/stdio.d(1146): Error: no identifier for declarator add /usr/include/dmd/druntime/import/core/stdc/stdio.d(1149): Error: no identifier for declarator usDone /usr/include/dmd/druntime/import/core/stdc/stdio.d(1149): Error: Declaration expected, not ':' /usr/include/dmd/druntime/import/core/stdc/stdio.d(1157): Error: Declaration expected, not '(' /usr/include/dmd/druntime/import/core/stdc/stdio.d(1159): Error: Declaration expected, not 'foreach' /usr/include/dmd/druntime/import/core/stdc/stdio.d(1159): Error: Declaration expected, not '0' /usr/include/dmd/druntime/import/core/stdc/stdio.d(1164): Error: no identifier for declarator __fhnd_info[fd] /usr/include/dmd/druntime/import/core/stdc/stdio.d(1164): Error: Declaration expected, not '=' /usr/include/dmd/druntime/import/core/stdc/stdio.d(1165): Error: Declaration expected, not 'return' /usr/include/dmd/druntime/import/core/stdc/stdio.d(1167): Error: unrecognized declaration /usr/include/dmd/phobos/std/typecons.d(1124): Error: semicolon expected following function declaration This seems to be problem with your installation, you probably have diferen version of dmd compiler and phobos library. So you should uninstall all your dmd packages and make sure there is no /usr/include/dmd left in your system. And instal dmd only from one source (d-apt idealy). I've done that 2 or 3 times. If that's the problem, then there are different versions stored in the repository. Since I'm on debian testing I'd been assuming that there'd been some system change since I'd last used the compiler, and the debs weren't yet up to date. The only updates to my system prior to the compiler breaking HAD been via apt-get. Since then I've used dpkg remove and install a couple of times to try other versions of dmd with no benefit. Currently dmd-bin version 2.071.2-0 libphobos2.071.2-0 libphobos2.071.2-0 so they're LISTED as being the same version. And dmd.conf was installed by the deb, and is (eliminating the comments): [Environment32] DFLAGS=-I/usr/include/dmd/phobos -I/usr/include/dmd/druntime/import -L-L/usr/lib/i386-linux-gnu -L--export-dynamic [Environment64] DFLAGS=-I/usr/include/dmd/phobos -I/usr/include/dmd/druntime/import -L-L/usr/lib/x86_64-linux-gnu -L--export-dynamic But somewhere during the process (which included the nightly system update) the error messages changed, and now: dmd test.d yields: /usr/include/dmd/druntime/import/core/stdc/stdio.d(1121): Error: found 'nothrow' when expecting '{' /usr/include/dmd/druntime/import/core/stdc/stdio.d(1123): Error: mismatched number of curly brackets ... /usr/include/dmd/druntime/import/core/stdc/stdio.d(1167): Error: unrecognized declaration /usr/include/dmd/phobos/std/typecons.d(1124): Error: semicolon expected following function declaration
Re: strange -fPIC compilation error
On 10/30/2016 05:14 PM, Lodovico Giaretta via Digitalmars-d-learn wrote: On Monday, 31 October 2016 at 00:08:59 UTC, Charles Hixson wrote: So now I removed the repository version of dmd and dub, downloaded DMD64 D Compiler v2.072.0-b2, used dkpg to install it, and appear to get the same errors. (Well, actually I removed the commenting out of the code, but it compiles and runs properly with ldc2.) I don't think it's a problem of DMD. This is due to your gcc installation being hardened, that is, configured to produce PIE by default. To produce PIE, the linker needs to be fed PIC, which DMD does not produce by default. The -fPIC flags makes DMD produce PIC out of your sources. The problem is, libphobos2.a (the static version of Phobos) is not compiled with -fPIC, so even if your code is PIC, gcc will complain. The workaround is to use -defaultlib=libphobos2.so to dynamically link with the shared version of Phobos. Being it a shared object, it does not give any problem with PIE. Looking on internet, I didn't find any clue about Debian shipping an hardened gcc, but this is the only cause I can think of for the behaviour you are experiencing. Well, that certainly changed the error messages. With dmd -defaultlib=/usr/lib/x86_64-linux-gnu/libphobos2.so test.d I get: /usr/include/dmd/druntime/import/core/stdc/stdio.d(1121): Error: found 'nothrow' when expecting '{' /usr/include/dmd/druntime/import/core/stdc/stdio.d(1123): Error: mismatched number of curly brackets /usr/include/dmd/druntime/import/core/stdc/stdio.d(1124): Error: mismatched number of curly brackets /usr/include/dmd/druntime/import/core/stdc/stdio.d(1125): Error: mismatched number of curly brackets /usr/include/dmd/druntime/import/core/stdc/stdio.d(1126): Error: mismatched number of curly brackets /usr/include/dmd/druntime/import/core/stdc/stdio.d(1127): Error: mismatched number of curly brackets /usr/include/dmd/druntime/import/core/stdc/stdio.d(1128): Error: mismatched number of curly brackets /usr/include/dmd/druntime/import/core/stdc/stdio.d(1129): Error: mismatched number of curly brackets /usr/include/dmd/druntime/import/core/stdc/stdio.d(1133): Error: asm statements must end in ';' /usr/include/dmd/druntime/import/core/stdc/stdio.d(1136): Error: found 'private' instead of statement /usr/include/dmd/druntime/import/core/stdc/stdio.d(1146): Error: no identifier for declarator add /usr/include/dmd/druntime/import/core/stdc/stdio.d(1149): Error: no identifier for declarator usDone /usr/include/dmd/druntime/import/core/stdc/stdio.d(1149): Error: Declaration expected, not ':' /usr/include/dmd/druntime/import/core/stdc/stdio.d(1157): Error: Declaration expected, not '(' /usr/include/dmd/druntime/import/core/stdc/stdio.d(1159): Error: Declaration expected, not 'foreach' /usr/include/dmd/druntime/import/core/stdc/stdio.d(1159): Error: Declaration expected, not '0' /usr/include/dmd/druntime/import/core/stdc/stdio.d(1164): Error: no identifier for declarator __fhnd_info[fd] /usr/include/dmd/druntime/import/core/stdc/stdio.d(1164): Error: Declaration expected, not '=' /usr/include/dmd/druntime/import/core/stdc/stdio.d(1165): Error: Declaration expected, not 'return' /usr/include/dmd/druntime/import/core/stdc/stdio.d(1167): Error: unrecognized declaration /usr/include/dmd/phobos/std/typecons.d(1124): Error: semicolon expected following function declaration
Re: strange -fPIC compilation error
So now I removed the repository version of dmd and dub, downloaded DMD64 D Compiler v2.072.0-b2, used dkpg to install it, and appear to get the same errors. (Well, actually I removed the commenting out of the code, but it compiles and runs properly with ldc2.) On 10/30/2016 11:02 AM, Charles Hixson via Digitalmars-d-learn wrote: dmd --version DMD64 D Compiler v2.071.2 Copyright (c) 1999-2015 by Digital Mars written by Walter Bright on debian testing. dub is installed via apt-get. Should I revert to an earlier version? Or what? The program: importstd.stdio; voidmain() {//int[]t1; //t1~=1; //t1~=2; //writeln ("t1 = ", t1); } fails with the 442 lines of error: /usr/bin/ld: test.o: relocation R_X86_64_32 against symbol `__dmd_personality_v0' can not be used when making a shared object; recompile with -fPIC /usr/bin/ld: /usr/lib/x86_64-linux-gnu/libphobos2.a(exception_224_3b4.o): relocation R_X86_64_32 against symbol `__dmd_personality_v0' can not be used when making a shared object; recompile with -fPIC /usr/bin/ld: /usr/lib/x86_64-linux-gnu/libphobos2.a(exception_227_4a2.o): relocation R_X86_64_32 against symbol `__dmd_personality_v0' can not be used when making a shared object; recompile with -fPIC /usr/bin/ld: /usr/lib/x86_64-linux-gnu/libphobos2.a(exception_229_5cc.o): relocation R_X86_64_32 against symbol `__dmd_personality_v0' can not be used when making a shared object; recompile with -fPIC /usr/bin/ld: /usr/lib/x86_64-linux-gnu/libphobos2.a(dmain2_626_47b.o): relocation R_X86_64_32 against symbol `_D6object9Throwable7__ClassZ' can not be used when making a shared object; recompile with -fPIC /usr/bin/ld: /usr/lib/x86_64-linux-gnu/libphobos2.a(dmain2_628_776.o): relocation R_X86_64_32 against symbol `__dmd_personality_v0' can not be used when making a shared object; recompile with -fPIC /usr/bin/ld: /usr/lib/x86_64-linux-gnu/libphobos2.a(dwarfeh_62b_6b9.o): relocation R_X86_64_32 against symbol `__dmd_personality_v0' can not be used when making a shared object; recompile with -fPIC ... /usr/bin/ld: /usr/lib/x86_64-linux-gnu/libphobos2.a(aaA_51a_53e.o): relocation R_X86_64_32 against symbol `__dmd_personality_v0' can not be used when making a shared object; recompile with -fPIC /usr/bin/ld: final link failed: Nonrepresentable section on output collect2: error: ld returned 1 exit status --- errorlevel 1
Re: strange -fPIC compilation error
Just as a test I tried it with ldc, and, as expected, there wasn't any problem. On 10/30/2016 11:02 AM, Charles Hixson via Digitalmars-d-learn wrote: dmd --version DMD64 D Compiler v2.071.2 Copyright (c) 1999-2015 by Digital Mars written by Walter Bright on debian testing. dub is installed via apt-get. Should I revert to an earlier version? Or what? The program: importstd.stdio; voidmain() {//int[]t1; //t1~=1; //t1~=2; //writeln ("t1 = ", t1); } fails with the 442 lines of error: /usr/bin/ld: test.o: relocation R_X86_64_32 against symbol `__dmd_personality_v0' can not be used when making a shared object; recompile with -fPIC /usr/bin/ld: /usr/lib/x86_64-linux-gnu/libphobos2.a(exception_224_3b4.o): relocation R_X86_64_32 against symbol `__dmd_personality_v0' can not be used when making a shared object; recompile with -fPIC /usr/bin/ld: /usr/lib/x86_64-linux-gnu/libphobos2.a(exception_227_4a2.o): relocation R_X86_64_32 against symbol `__dmd_personality_v0' can not be used when making a shared object; recompile with -fPIC /usr/bin/ld: /usr/lib/x86_64-linux-gnu/libphobos2.a(exception_229_5cc.o): relocation R_X86_64_32 against symbol `__dmd_personality_v0' can not be used when making a shared object; recompile with -fPIC /usr/bin/ld: /usr/lib/x86_64-linux-gnu/libphobos2.a(dmain2_626_47b.o): relocation R_X86_64_32 against symbol `_D6object9Throwable7__ClassZ' can not be used when making a shared object; recompile with -fPIC /usr/bin/ld: /usr/lib/x86_64-linux-gnu/libphobos2.a(dmain2_628_776.o): relocation R_X86_64_32 against symbol `__dmd_personality_v0' can not be used when making a shared object; recompile with -fPIC /usr/bin/ld: /usr/lib/x86_64-linux-gnu/libphobos2.a(dwarfeh_62b_6b9.o): relocation R_X86_64_32 against symbol `__dmd_personality_v0' can not be used when making a shared object; recompile with -fPIC ... /usr/bin/ld: /usr/lib/x86_64-linux-gnu/libphobos2.a(aaA_51a_53e.o): relocation R_X86_64_32 against symbol `__dmd_personality_v0' can not be used when making a shared object; recompile with -fPIC /usr/bin/ld: final link failed: Nonrepresentable section on output collect2: error: ld returned 1 exit status --- errorlevel 1
Re: strange -fPIC compilation error
On 10/30/2016 04:03 PM, Lodovico Giaretta via Digitalmars-d-learn wrote: On Sunday, 30 October 2016 at 18:02:28 UTC, Charles Hixson wrote: dmd --version DMD64 D Compiler v2.071.2 Copyright (c) 1999-2015 by Digital Mars written by Walter Bright on debian testing. dub is installed via apt-get. Should I revert to an earlier version? Or what? The program: importstd.stdio; voidmain() {//int[]t1; //t1~=1; //t1~=2; //writeln ("t1 = ", t1); } fails with the 442 lines of error: /usr/bin/ld: test.o: relocation R_X86_64_32 against symbol `__dmd_personality_v0' can not be used when making a shared object; recompile with -fPIC /usr/bin/ld: /usr/lib/x86_64-linux-gnu/libphobos2.a(exception_224_3b4.o): relocation R_X86_64_32 against symbol `__dmd_personality_v0' can not be used when making a shared object; recompile with -fPIC /usr/bin/ld: /usr/lib/x86_64-linux-gnu/libphobos2.a(exception_227_4a2.o): relocation R_X86_64_32 against symbol `__dmd_personality_v0' can not be used when making a shared object; recompile with -fPIC /usr/bin/ld: /usr/lib/x86_64-linux-gnu/libphobos2.a(exception_229_5cc.o): relocation R_X86_64_32 against symbol `__dmd_personality_v0' can not be used when making a shared object; recompile with -fPIC /usr/bin/ld: /usr/lib/x86_64-linux-gnu/libphobos2.a(dmain2_626_47b.o): relocation R_X86_64_32 against symbol `_D6object9Throwable7__ClassZ' can not be used when making a shared object; recompile with -fPIC /usr/bin/ld: /usr/lib/x86_64-linux-gnu/libphobos2.a(dmain2_628_776.o): relocation R_X86_64_32 against symbol `__dmd_personality_v0' can not be used when making a shared object; recompile with -fPIC /usr/bin/ld: /usr/lib/x86_64-linux-gnu/libphobos2.a(dwarfeh_62b_6b9.o): relocation R_X86_64_32 against symbol `__dmd_personality_v0' can not be used when making a shared object; recompile with -fPIC ... /usr/bin/ld: /usr/lib/x86_64-linux-gnu/libphobos2.a(aaA_51a_53e.o): relocation R_X86_64_32 against symbol `__dmd_personality_v0' can not be used when making a shared object; recompile with -fPIC /usr/bin/ld: final link failed: Nonrepresentable section on output collect2: error: ld returned 1 exit status --- errorlevel 1 Are you on Ubuntu 16.10, or some other system with an hardened toolchain? If that's the case, you should compile with `-fPIC -defaultlib=libphobos2.so`. You can put those options in your dmd.conf configuration file, so that you don't have to type them every time. Well, I'm using debian, but I've never had to do anything of that nature before. OTOH, it's been a couple of months if this is a new change.
strange -fPIC compilation error
dmd --version DMD64 D Compiler v2.071.2 Copyright (c) 1999-2015 by Digital Mars written by Walter Bright on debian testing. dub is installed via apt-get. Should I revert to an earlier version? Or what? The program: importstd.stdio; voidmain() {//int[]t1; //t1~=1; //t1~=2; //writeln ("t1 = ", t1); } fails with the 442 lines of error: /usr/bin/ld: test.o: relocation R_X86_64_32 against symbol `__dmd_personality_v0' can not be used when making a shared object; recompile with -fPIC /usr/bin/ld: /usr/lib/x86_64-linux-gnu/libphobos2.a(exception_224_3b4.o): relocation R_X86_64_32 against symbol `__dmd_personality_v0' can not be used when making a shared object; recompile with -fPIC /usr/bin/ld: /usr/lib/x86_64-linux-gnu/libphobos2.a(exception_227_4a2.o): relocation R_X86_64_32 against symbol `__dmd_personality_v0' can not be used when making a shared object; recompile with -fPIC /usr/bin/ld: /usr/lib/x86_64-linux-gnu/libphobos2.a(exception_229_5cc.o): relocation R_X86_64_32 against symbol `__dmd_personality_v0' can not be used when making a shared object; recompile with -fPIC /usr/bin/ld: /usr/lib/x86_64-linux-gnu/libphobos2.a(dmain2_626_47b.o): relocation R_X86_64_32 against symbol `_D6object9Throwable7__ClassZ' can not be used when making a shared object; recompile with -fPIC /usr/bin/ld: /usr/lib/x86_64-linux-gnu/libphobos2.a(dmain2_628_776.o): relocation R_X86_64_32 against symbol `__dmd_personality_v0' can not be used when making a shared object; recompile with -fPIC /usr/bin/ld: /usr/lib/x86_64-linux-gnu/libphobos2.a(dwarfeh_62b_6b9.o): relocation R_X86_64_32 against symbol `__dmd_personality_v0' can not be used when making a shared object; recompile with -fPIC ... /usr/bin/ld: /usr/lib/x86_64-linux-gnu/libphobos2.a(aaA_51a_53e.o): relocation R_X86_64_32 against symbol `__dmd_personality_v0' can not be used when making a shared object; recompile with -fPIC /usr/bin/ld: final link failed: Nonrepresentable section on output collect2: error: ld returned 1 exit status --- errorlevel 1
Re: Why 16Mib static array size limit?
On 08/16/2016 01:49 PM, Steven Schveighoffer via Digitalmars-d wrote: On 8/16/16 4:11 PM, Yuxuan Shui wrote: On Tuesday, 16 August 2016 at 17:51:13 UTC, Johan Engelen wrote: On Tuesday, 16 August 2016 at 01:28:05 UTC, Ali Çehreli wrote: With ldc2, the best option is to go with a dynamic array ONLY IF you access the elements through the .ptr property. As seen in the last result, using the [] operator on the array is about 4 times slower than that. As Yuxuan Shui mentioned the difference is in vectorization. The non-POINTER version is not vectorized because the semantics of the code is not the same as the POINTER version. Indexing `arr`, and writing to that address could change `arr.ptr`, and so the loop would do something different when "caching" `arr.ptr` in `p` (POINTER version) versus the case without caching (non-POINTER version). Evil code demonstrating the problem: ``` ubyte evil; ubyte[] arr; void doEvil() { // TODO: use this in the obfuscated-D contest arr = ()[0..50]; } ``` The compiler somehow has to prove that `arr[i]` will never point to `arr.ptr` (it's called Alias Analysis in LLVM). Perhaps it is UB in D to have `arr[i]` ever point into `arr` itself, I don't know. If so, the code is vectorizable and we can try to make it so. -Johan Wait, doesn't D have strict aliasing rules? ubyte* () should not be allowed to alias with ubyte** (). Even if it did, I believe the wildcard is ubyte*. Just like in C, char* can point at anything, ubyte is D's equivalent. -Steve I think what you say is true (look at the code of std.outbuffer), but IIRC the documentation says that's supposed to be the job of void*.
Re: Multi-Thread message passing approach
On 08/16/2016 07:21 AM, Kagamin via Digitalmars-d-learn wrote: On Monday, 15 August 2016 at 01:53:33 UTC, Charles Hixson wrote: If I modify the code to attempt to pass a Tid[] as a member of struct Start I get: /usr/include/dmd/phobos/std/concurrency.d(603): Error: static assert "Aliases to mutable thread-local data not allowed." test.d(47):instantiated from here: send!(Start) and this seems to imply that the casting away of shared might also be an unsafe access which just doesn't happen to be detected by the library. Currently not all types, that are supposed to be thread-safe, support shared, e.g. Semaphore, so it doesn't necessarily mean that sharing them is incorrect. Thanks. But "not all types" is a bit worrisome. Fortunately it's just as easy to pass a fixed length array of Tids through send, and that even yields simpler code. The problems I was running into turned out to be because there was a "local reference", i.e. the dynamic array. I just wasn't understanding the error message. So now I don't need to use the "shared data" that I was worrying about. I am a bit surprised, however, as Tids include a private class reference, and it seems as if that should raise the same error flag, but it doesn't. Of course, the real problem is that just because concurrent software seems to be working right when you test it doesn't say anything about how it will perform under load...so I want to avoid anything even questionable.
Re: Multi-Thread message passing approach
I misunderstood the problem. The problem was that a dynamically sized array cannot be sent as a message. So this works: import std.concurrency; import std.stdio; import core.thread; enum tidMax = 10; struct Start { int tidCnt = 0; Tid[tidMax] tids; } struct Msg { int orig; int dest; } struct Done { int dummy = 0; } void worker (int ndx) { writeln ("worker ", ndx, " spawned"); Start start = receiveOnly!(Start)(); Tid[] tids; foreach (i; 0 .. start.tidCnt) { tids ~= start.tids[i]; } writeln ("worker ", ndx, " got tidList"); for (int i = 0; i < 3; i++) { if (i != ndx) { Msg msg = Msg(ndx, i); send (tids[i], msg); } } writeln ("worker ", ndx, " sent messages"); bool done = false; while (!done) { receive ( (Msg msg) { writeln ("msg from: ", msg.orig, ", to: ", msg.dest); }, (Done d) { done = true; } ); } writeln ("worker ", ndx, " is done"); } void main() { Start start; Done done; for (int i = 0; i < 3; i++) { auto tid = spawn (, i); start.tids[start.tidCnt++] = tid; } foreach (i; 0 .. start.tidCnt) { send (start.tids[i], start); } Thread.sleep (1000.msecs); foreach (i; 0 .. start.tidCnt) { send (start.tids[i], done); } Thread.sleep (1000.msecs); writeln ("main is done"); }
Re: Multi-Thread message passing approach
Looking at the std.concurrency code, it appears that Tid is just a handle to a class, so multiple assignments should all refer to the same underlying class, and it looks like that underlying class (MessageBox) uses mutexes to ensure safe handling of multiple access. So this shared access to tids should be safe. But in that case why can't Tids be passed as function parameters to spawn, which would have avoided the requirement for a fixed length shared array? So I don't trust my reasoning here. If I modify the code to attempt to pass a Tid[] as a member of struct Start I get: /usr/include/dmd/phobos/std/concurrency.d(603): Error: static assert "Aliases to mutable thread-local data not allowed." test.d(47):instantiated from here: send!(Start) and this seems to imply that the casting away of shared might also be an unsafe access which just doesn't happen to be detected by the library. On 08/14/2016 07:44 AM, Charles Hixson via Digitalmars-d-learn wrote: This is an approach to n x n thread message passing. The idea is that each thread should be able to pass messages to any other thread. The only alternative I've come up with involves the main thread handling each message. Is that a better approach? Is there a better way to pass lists of Tids? importstd.concurrency; importstd.stdio; importcore.thread; sharedTid[3]tidList; structStart{intdummy=0;} structMsg{intorig;intdest;} structDone{intdummy=0;} voidworker (int ndx) { writeln("worker ", ndx, " spawned"); { automsg=receiveOnly!(Start)(); writeln("worker ", ndx, " started"); } Tid[]tids; foreach(t; tidList){tids~=cast(Tid)t;} for(int i = 0;i < 3;i++) { if(i != ndx) { Msg msg=Msg(ndx, i); send (tids[i], msg); } } writeln("worker ", ndx, " got tidList"); booldone=false; while(!done) { receive ( (Msg msg){writeln ("msg from: ", msg.orig, ", to: ", msg.dest);}, (Done d){done = true;} ); } writeln ("worker ", ndx, " is done"); } voidmain() { Startstart; Donedone; for(int i = 0;i < 3;i++) { auto tid=spawn (, i); tidList[i]=cast(shared Tid)tid; } foreach (i; 0 .. 3){send (cast(Tid)tidList[i], start);} Thread.sleep (1000.msecs); foreach (i; 0 .. 3){send (cast(Tid)tidList[i], done);} Thread.sleep (1000.msecs); writeln ("main is done"); }
Re: Multi-Thread message passing approach
On 08/14/2016 07:44 AM, Charles Hixson via Digitalmars-d-learn wrote: This is an approach to n x n thread message passing. The idea is that each thread should be able to pass messages to any other thread. The only alternative I've come up with involves the main thread handling each message. Is that a better approach? Is there a better way to pass lists of Tids? An attempt using the main thread as a relay follows. I have fewer doubts about it working, as Tids aren't accessed by multiple threads, but the logic is more convoluted, and harder to get right. import std.concurrency; import std.stdio; import core.thread; struct Start { int dummy = 0; } struct Msg { int orig; int dest; } struct Done { int dummy = 0; } enum threadCnt = 3; void worker (int ndx) { writeln ("worker ", ndx, " spawned"); { auto msg = receiveOnly!(Start)(); writeln ("worker ", ndx, " started"); } Tid owner = ownerTid; for (int i = 0; i < threadCnt; i++) { if (i != ndx) { Msg msg = Msg(ndx, i); send (owner, msg); } } writeln ("worker ", ndx, " sent msgs"); bool done = false; while (!done) { receive ( (Msg msg) { writeln ("msg from: ", msg.orig, ", to: ", msg.dest); }, (Done d) { done = true; writeln ("thread ", ndx, " is done."); } ); } send (owner, Done(ndx)); writeln ("worker ", ndx, " is done"); } void main() { Tid[] tidList; Start start; Done done; for (int i = 0; i < threadCnt; i++) { tidList ~=spawn (, i); } yield; foreach (i; 0 .. threadCnt) { send (tidList[i], start); } int tidLength = cast(int)tidList.length; Thread.sleep (500.msecs); foreach (i; 0 .. threadCnt) { send (tidList[i], done); } while (tidLength > 0) { receive ( (Msg msg) { send (tidList[msg.dest], msg); }, (Done d) { writeln ("tid ", d.dummy, " is done..", --tidLength, " remaining."); } ); } writeln ("main is done"); }
Re: Is this the best way to share Tids between threads?
Sorry this ended up here rather than at learn. I followed up there with something more explicit. See "Multi-Thread message passing approach" in learn. The problem here is that the threads will be doing the same thing, sort of, modulus an integer. And the number of them should be set at run time by checking the number of available CPUs. Which is handled in today's code example (see learn), but I'm not really sure I'm doing things the best way, or even that it's safe. (I'm using a shared Tid[].) There will be a couple of specialized threads, for which that looks like a good approach, though I could easily just special case those. It's the more general case that I'm concerned about. If the approach of using "shared Tid[]" is safe, then it's probably the best approach, but since I have to cast away the "shared" to use it, I worry about it's safety. If it's unsafe, then I probably need to set up an relay in the main thread. I suppose I could register "th1", "th2", ... "thn" and then only spawn a limited number of threads, and then use that to get the Tid[] as a local variable, or some other work around, but that seems quite clumsy, besides, if "shared Tid[]" is unsafe, then probably so is using Tids retrieved by locate in multiple independent threads. On 08/14/2016 01:55 AM, angel via Digitalmars-d wrote: Let each thread have a name related to its task. It is like having a shared Tid array, but already implemented. Reference: http://dlang.org/phobos/std_concurrency.html#.register
Multi-Thread message passing approach
This is an approach to n x n thread message passing. The idea is that each thread should be able to pass messages to any other thread. The only alternative I've come up with involves the main thread handling each message. Is that a better approach? Is there a better way to pass lists of Tids? importstd.concurrency; importstd.stdio; importcore.thread; sharedTid[3]tidList; structStart{intdummy=0;} structMsg{intorig;intdest;} structDone{intdummy=0;} voidworker (int ndx) { writeln("worker ", ndx, " spawned"); { automsg=receiveOnly!(Start)(); writeln("worker ", ndx, " started"); } Tid[]tids; foreach(t; tidList){tids~=cast(Tid)t;} for(int i = 0;i < 3;i++) { if(i != ndx) { Msg msg=Msg(ndx, i); send (tids[i], msg); } } writeln("worker ", ndx, " got tidList"); booldone=false; while(!done) { receive ( (Msg msg){writeln ("msg from: ", msg.orig, ", to: ", msg.dest);}, (Done d){done = true;} ); } writeln ("worker ", ndx, " is done"); } voidmain() { Startstart; Donedone; for(int i = 0;i < 3;i++) { auto tid=spawn (, i); tidList[i]=cast(shared Tid)tid; } foreach (i; 0 .. 3){send (cast(Tid)tidList[i], start);} Thread.sleep (1000.msecs); foreach (i; 0 .. 3){send (cast(Tid)tidList[i], done);} Thread.sleep (1000.msecs); writeln ("main is done"); }
Is this the best way to share Tids between threads?
I'm trying to figure out the best way to have multiple threads that can each send messages to the other threads. I've come up with two basic approaches, one uses the main thread as a relay, and the other uses a shared array of Tid...thus: importstd.concurrency; importstd.stdio; importcore.thread; sharedTid[8]tidList; voidworker (int ndx) { Thread.sleep (5.msecs); writeln ("worker is done"); } voidmain() { auto tid=spawn (, 0); tidList[0]=cast(shared Tid)tid; Thread.sleep (40.msecs); writeln ("main is done"); } Is there a reasonable way to decide which way is best? Is there a better way that I just haven't thought of? Are there problems with sending messages via shared Tids that I just haven't thought of yet?
Re: how to declare an immutable class?
Thank you both. On 08/12/2016 01:35 AM, Jonathan M Davis via Digitalmars-d-learn wrote: On Friday, August 12, 2016 05:25:45 Mike Parker via Digitalmars-d-learn wrote: immutable class Foo { ... } is the same as declaring every member of Foo as immutable, just as final class Foo { ... } makes every method final. I'm not sure that that's quite the same thing, because there is such a thing as a final class, because making the class final makes it illegal to derive another class from it rather than just affecting the class' functions. So, final does affect the class itself, whereas immutable does not. It's the same with most of attributes though - @safe, pure, nothrow, etc. They affect the members but not the class itself. Putting them on the class is the same as doing attribute { class C { ... } } or the same as attribute: class C { ... } if there's nothing after the class in the file (since the label syntax affects everything after it in the file, whereas the braces only affect what's in the braces). - Jonathan M Davis
Re: how to declare an immutable class?
On 08/11/2016 06:33 PM, Mike Parker via Digitalmars-d-learn wrote: On Friday, 12 August 2016 at 00:44:31 UTC, Charles Hixson wrote: A way around this, which may be the same as the approach used by string was: alias immutable(Msg_)Msg; classMsg_ { ... This is exactly what Jonathan suggested in the post above. And yes, it's how string is handled: alias string = immutable(char)[]; This so far appears to do what I want. The only problem is that it introduces an extraneous symbol, which I would prefer to avoid. What problem do you want to avoid? This is a common D idiom. Alias names are very short-lived. Yes, it's another symbol in the namespace, but it will never make it to the object file. It won't even make it to error messages -- you'll see Msg_ there instead. Yes, I saw his answer after I'd posted my resolution. It works, it's just not the syntax that I'd prefer. And it leaves me wondering exactly what immutable class Msg {...} was declaring.
Re: how to declare an immutable class?
A way around this, which may be the same as the approach used by string was: alias immutable(Msg_)Msg; classMsg_ { ... This so far appears to do what I want. The only problem is that it introduces an extraneous symbol, which I would prefer to avoid. OTOH, I did fix a few problems before this solution On 08/11/2016 10:56 AM, Charles Hixson via Digitalmars-d-learn wrote: I want to declare a class all instances of which will be immutable, and all references to which will be inherently immutable (so that I don't need to slip a huge number of "immutable" statements in my code). This is surely possible, because string acts just that way, but I can't figure out how to do this. immutable classMsg {this(...) immutable{...} ... } doesn't work that way, as when I do Msg m = new Msg (...); I get: Error: incompatible types for ((this.m) - (m)): 'immutable(Msg)' and 'cellram.Msg' and Error: immutable method cellram.Msg.this is not callable using a mutable object Does anyone know the correct approach?
how to declare an immutable class?
I want to declare a class all instances of which will be immutable, and all references to which will be inherently immutable (so that I don't need to slip a huge number of "immutable" statements in my code). This is surely possible, because string acts just that way, but I can't figure out how to do this. immutable classMsg {this(...) immutable{...} ... } doesn't work that way, as when I do Msg m = new Msg (...); I get: Error: incompatible types for ((this.m) - (m)): 'immutable(Msg)' and 'cellram.Msg' and Error: immutable method cellram.Msg.this is not callable using a mutable object Does anyone know the correct approach?
arrays, mmu, addressing choices
I have a rather large array that I intend to build. but much of it will only occasionally be used. Will the unused sections automatically be paged out? If it matters my system is Debian Linux. This array will be indexed by a ulong. Is there any reasonable maximum size? I've considered segmented addressing anyway, in case that's needed to allow paging, and it will definitely be needed when I get around to concurrent processing, with different sections resident in different threads. But if appropriate I could do that from the start. The questions above are really for a normal array, but I'd also be interested in how using an associative array would affect them. I expect to eventually be using more memory than I have RAM in my system, so designing for paging is going to be important. (Before then I'll be adding more RAM and a larger disk drive, but if I complete the full design even a large disk is going to be small.)
Re: Why D is not popular enough?
On 08/01/2016 09:37 AM, eugene via Digitalmars-d wrote: On Monday, 1 August 2016 at 15:31:35 UTC, Emre Temelkuran wrote: For years, i was travelling along Golang, Rust, Perl, Ruby, Python, PHP, JScript, JVM Languages. Lastly Crystal Lang and Nimrod, Julia, Haskell, Swift and many more that i can't remember. I'm 24 years old, my first lang was PHP and VBasic then C,C++ and i first heard about D after 2005 when i was 14-15 years old. I always ignored D, i prejudiced that D failed, because nobody were talking about it. I decided to check it yesterday, it has excellent documentation, i almost covered all aspects. I think D is much better than the most of the other popular langs. It's clear as JScript, Swift, Julia and PHP, also it's capable enough as C,C++. I think D deserves a bigger community. Why people need NodeJS, Typescript etc, when there is already better looking lang? Everyone talking about how ugly is Golang. So why people are going on it? Performance concerns? Why languages that are not backed up by huge companies are looking like they failed? maybe another reason is that people who tried to use D still think it is unstable I have never experienced D as being unstable. I have, however, experienced problems using various libraries with D. Whenever you need to use a foreign library you invite problems, but D wrappers around libraries have a habit of showing up and then not being maintained. THAT has caused me problems...enough problems that if I don't need the performance I'll pick Python. As for D1 being a failure...that depends on what you wanted to do with it. Until it started being influenced by Tango I was quite pleased, and even Tango wasn't all bad. It had a few good unicode tools that haven't yet been incorporated into D2. D2 I'm less satisfied with, though that may just be a rosy-glasses memory of D1. Most of my needs aren't fancy compile time techniques but rather run-time techniques. (I did mention Python as the alternate rather than C++.) But what the best language is depends a lot on what you are doing. To talk in terms of other languages, Objective C is a better language for my needs than C++. It isn't really because of the commitment to 16-bit unicode, but outside of that... So in either version of D I have mixed uses of 8-bit unicode and 32-bit unicode. D seems to handle this better than any other language. And it's got lots of other nice features. I love garbage collection, as I hate memory management. I'm less attracted to ranges as implemented by D, though I like them in Ruby and Python. A lot of this has to do with what gets done at compile time and what gets done at run time, though, so for me that just means that I'd rather avoid needing to use ranges when I need speed. For my purposes the template language is overblown, and I'd be satisfied with a much simpler form with some run-time supplementation...but different people would like different simplifications even among those who want it to be simpler. Traits, e.g., I find indispensable (especially isPOD) and I need to be able to test THAT at compile time, but most people who talk about templates don't even mention traits. Many languages become significant when there is an popular application or library that depends on them. Others grow slowly. There *is*, however, a network effect, so that popular languages tend to become more popular, and this is often driven by a "niche" application (a place where there is no competition, so everyone who wants to work in that niche must use that language). An example of this, if you go back to before it was popular, is JavaScript.
Re: Make D language as Apache foundation project
On 08/01/2016 08:56 AM, Emre Temelkuran via Digitalmars-d wrote: On Wednesday, 27 July 2016 at 13:28:04 UTC, Adam D. Ruppe wrote: On Wednesday, 27 July 2016 at 13:08:17 UTC, eugene wrote: Hello everyone, why not to make a D language as a project of Apache foundation as it happened to groovy? My impression of Apache foundation stuff is it is a graveyard of other people's abandoned stuff not the message I'd want to send. I know what you tried to say. You're right and wrong. :D. Yes, ASF got lots of trash but 1/2 of that list is alive and useful. http://www.apache.org/index.html#projects-list - Some projects are definitely killer. Linux Foundation is another option. The Linux Foundation is less appropriate for what it intended to be a cross-platform application. And the FSF wants it's projects to be GPL. Of the major ... repositories isn't the right word, but what is? ... Apache seems the most appropriate choice. GitHub, e.g., doesn't seem to be quite the same category of thing.
Re: Overflows in Phobos
On 07/26/2016 07:36 AM, ketmar via Digitalmars-d wrote: On Tuesday, 26 July 2016 at 14:28:48 UTC, Timon Gehr wrote: "The expression assert(0) is a special case; it signifies that it is unreachable code. [...] The optimization and code generation phases of compilation may assume that it is unreachable code." so specs should be fixed. i bet everyone is using `assert(0);` to mark some "immediate error exit" cases. FWIW, in that case I always use assert (false, "..."); I try to never use integers for booleans. But this may well be a common usage.
Re: randomIO, std.file, core.stdc.stdio
On 07/27/2016 06:46 AM, Rene Zwanenburg via Digitalmars-d-learn wrote: On Wednesday, 27 July 2016 at 02:20:57 UTC, Charles Hixson wrote: O, dear. It was sounding like such an excellent approach until this last paragraph, but growing the file is going to be one of the common operations. (Certainly at first.) (...) So I'm probably better off sticking to using a seek based i/o system. Not necessarily. The usual approach is to over-allocate your file so you don't need to grow it that often. This is the exact same strategy used by D's dynamic arrays and grow-able array-backed lists in other languages - the difference between list length and capacity. There is no built-in support for this in std.mmfile afaik. But it's not hard to do yourself. Well, that would mean I didn't need to reopen the file so often, but that sure wouldn't mean I wouldn't need to re-open the file. And it would add considerable complexity. Possibly that would be an optimal approach once the data was mainly collected, but I won't want to re-write this bit at that point.
Re: randomIO, std.file, core.stdc.stdio
On 07/26/2016 12:53 PM, Adam D. Ruppe via Digitalmars-d-learn wrote: On Tuesday, 26 July 2016 at 19:30:35 UTC, Charles Hixson wrote: It looks as if the entire file is stored in memory, which is not at all what I want, but I also can't really believe that's what's going on. It is just mapped to virtual memory without actually being loaded into physical memory, so when you access the array it returns, the kernel loads a page of the file into memory, but it doesn't do that until it actually has to. Think of it as being like this: struct MagicFile { ubyte[] opIndex(size_t idx) { auto buffer = new ubyte[](some_block_length); fseek(fp, idx, SEEK_SET); fread(buffer.ptr, buffer.length, 1); return buffer; } } And something analogous for writing, but instead of being done with overloaded operators in D, it is done with the MMU hardware by the kernel (and the kernel also does smarter buffering than this little example). A part of the problem is that I don't want this to be a process with an arbitrarily high memory use. The kernel will automatically handle physical memory usage too, similarly to a page file. If you haven't read a portion of the file recently, it will discard that page, since it can always read it again off disk if needed, but if you do have memory to spare, it will keep the data in memory for faster access later. So basically the operating system handles a lot of the details which makes it efficient. Growing a memory mapped file is a bit tricky though, you need to unmap and remap. Since it is an OS concept, you can always look for C or C++ examples too, like herE: http://stackoverflow.com/questions/4460507/appending-to-a-memory-mapped-file/4461462#4461462 O, dear. It was sounding like such an excellent approach until this last paragraph, but growing the file is going to be one of the common operations. (Certainly at first.) It sounds as if that means the file needs to be closed and re-opened for extensions. And I quote from https://www.gnu.org/software/libc/manual/html_node/Memory_002dmapped-I_002fO.html: Function: /void */ *mremap* /(void *address, size_t length, size_t new_length, int flag)/ Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts <https://www.gnu.org/software/libc/manual/html_node/POSIX-Safety-Concepts.html#POSIX-Safety-Concepts>. This function can be used to change the size of an existing memory area. address and length must cover a region entirely mapped in the same |mmap| statement. A new mapping with the same characteristics will be returned with the length new_length. ... This function is only available on a few systems. Except for performing optional optimizations one should not rely on this function. END So I'm probably better off sticking to using a seek based i/o system.
Re: randomIO, std.file, core.stdc.stdio
On 07/26/2016 11:31 AM, Steven Schveighoffer via Digitalmars-d-learn wrote: On 7/26/16 1:57 PM, Charles Hixson via Digitalmars-d-learn wrote: Thanks. Since there isn't any excess overhead I guess I'll use stdio. Buffering, however, isn't going to help at all since I'm doing randomIO. I know that most of the data the system reads from disk is going to end up getting thrown away, since my records will generally be smaller than 8K, but there's no help for that. Even for doing random I/O buffering is helpful. It depends on the size of your items. Essentially, to read 10 bytes from a file probably costs the same as reading 100,000 bytes from a file. So may as well buffer that in case you need it. Now, C i/o's buffering may not suit your exact needs. So I don't know how it will perform. You may want to consider mmap which tells the kernel to link pages of memory directly to disk access. Then the kernel is doing all the buffering for you. Phobos has support for it, but it's pretty minimal from what I can see: http://dlang.org/phobos/std_mmfile.html -Steve I've considered mmapfile often, but when I read the documentation I end up realizing that I don't understand it. So I look up memory mapped files in other places, and I still don't understand it. It looks as if the entire file is stored in memory, which is not at all what I want, but I also can't really believe that's what's going on. I know that there was an early form of this in a version of BASIC (the version that RISS was written in, but I don't remember which version that was) and in *that* version array elements were read in as needed. (It wasn't spectacularly efficient.) But memory mapped files don't seem to work that way, because people keep talking about how efficient they are. Do you know a good introductory tutorial? I'm guessing that "window size" might refer to the number of bytes available, but what if you need to append to the file? Etc. A part of the problem is that I don't want this to be a process with an arbitrarily high memory use. Buffering would be fine, if I could use it, but for my purposes sequential access is likely to be rare, and the working layout of the data in RAM doesn't (can't reasonably) match the layout on disk. IIUC (this is a few decades old) the system buffer size is about 8K. I expect to never need to read that large a chunk, but I'm going to try to keep the chunks in multiples of 1024 bytes, and if it's reasonable to exactly 1024 bytes. So I should never need two reads or writes for a chunk. I guess to be sure of this I'd better make sure the file header is also 1024 bytes. (I'm guessing that the seek to position results in the appropriate buffer being read into the system buffer, so if my header were 512 bytes I might occasionally need to do double reads or writes.) I'm guessing that memory mapped files trade off memory use against speed of access, and for my purposes that's probably a bad trade, even though databases are doing that more and more. I'm likely to need all the memory I can lay my hands on, and even then thrashing wouldn't surprise me. So a fixed buffer size seems a huge advantage.
Re: randomIO, std.file, core.stdc.stdio
On 07/26/2016 10:18 AM, Steven Schveighoffer via Digitalmars-d-learn wrote: On 7/26/16 12:58 PM, Charles Hixson via Digitalmars-d-learn wrote: Ranges aren't free, are they? If so then I should probably use stdfile, because that is probably less likely to change than core.stdc.stdio. Do you mean slices? When I see "f.rawRead([0 .. 1])" it looks to me as if unneeded code is being generated explictly to be thrown away. (I don't like using pointer/length either, but it's actually easier to understand than this kind of thing, and this LOOKS like it's generating extra code.) This is probably a misunderstanding on your part. is accessing the item as a pointer. Since the compiler already has it as a reference, this is a noop -- just an expression to change the type. [0 .. 1] is constructing a slice out of a pointer. It's done all inline by the compiler (there is no special _d_constructSlice function), so that is very very quick. There is no bounds checking, because pointers do not have bounds checks. So there is pretty much zero overhead for this. Just push the pointer and length onto the stack (or registers, not sure of ABI), and call rawRead. That said, perhaps I should use stdio anyway. When doing I/O it's the disk speed that's the really slow part, and that so dominates things that worrying about trivialities is foolish. And since it's going to be wrapped anyway, the ugly will be confined to a very small routine. Having written a very templated io library (https://github.com/schveiguy/iopipe), I can tell you that in my experience, the slowdown comes from 2 things: 1) spending time calling the kernel, and 2) not being able to inline. This of course assumes that proper buffering is done. Buffering should mitigate most of the slowdown from the disk. It is expensive, but you amortize the expense by buffering. C's i/o is pretty much as good as it gets for an opaque non-inlinable system, as long as your requirements are simple enough. The std.stdio code should basically inline into the calls you should be making, and it handles a bunch of stuff that optimizes the calls (such as locking the file handle for one complex operation). -Steve Thanks. Since there isn't any excess overhead I guess I'll use stdio. Buffering, however, isn't going to help at all since I'm doing randomIO. I know that most of the data the system reads from disk is going to end up getting thrown away, since my records will generally be smaller than 8K, but there's no help for that.
Re: randomIO, std.file, core.stdc.stdio
On 07/26/2016 05:31 AM, Steven Schveighoffer via Digitalmars-d-learn wrote: On 7/25/16 9:19 PM, Charles Hixson via Digitalmars-d-learn wrote: On 07/25/2016 05:18 PM, ketmar via Digitalmars-d-learn wrote: On Monday, 25 July 2016 at 18:54:27 UTC, Charles Hixson wrote: Are there reasons why one would use rawRead and rawWrite rather than fread and fwrite when doiing binary random io? What are the advantages? In particular, if one is reading and writing structs rather than arrays or ranges, are there any advantages? yes: keeping API consistent. ;-) for example, my stream i/o modules works with anything that has `rawRead`/`rawWrite` methods, but don't bother to check for any other. besides, `rawRead` is just looks cleaner, even with all `()[0..1])` noise. so, a question of style. OK. If it's just a question of "looking cleaner" and "style", then I will prefer the core.stdc.stdio approach. I find it's appearance extremely much cleaner...except that that's understating things. I'll probably wrap those routines in a struct to ensure things like files being properly closed, and not have explicit pointers persisting over large areas of code. It's more than just that. Having a bounded array is safer than a pointer/length separated parameters. Literally, rawRead and rawWrite are inferred @safe, whereas fread and fwrite are not. But D is so nice with UFCS, you don't have to live with APIs you don't like. Allow me to suggest adding a helper function to your code: rawReadItem(T)(File f, ref T item) @trusted { f.rawRead([0 .. 1]); } -Steve That *does* make the syntax a lot nicer, and I understand the safety advantage of not using pointer/length separated parameters. But I'm going to be wrapping the I/O anyway, and the external interface is going to be more like: struct RF (T, long magic) { void read (size_t recNo, ref T val){...} size_t read (ref T val){...} ... } where a sequential read returns the record number, or you specify the record number and get an indexedIO read. So the length with be T.sizeof, and will be specified at the time the file is opened. To me this seems to eliminate the advantage of stdfile, and stdfile seems to add a level of indirection. Ranges aren't free, are they? If so then I should probably use stdfile, because that is probably less likely to change than core.stdc.stdio. When I see "f.rawRead([0 .. 1])" it looks to me as if unneeded code is being generated explictly to be thrown away. (I don't like using pointer/length either, but it's actually easier to understand than this kind of thing, and this LOOKS like it's generating extra code.) That said, perhaps I should use stdio anyway. When doing I/O it's the disk speed that's the really slow part, and that so dominates things that worrying about trivialities is foolish. And since it's going to be wrapped anyway, the ugly will be confined to a very small routine.
Re: randomIO, std.file, core.stdc.stdio
On 07/25/2016 09:22 PM, ketmar via Digitalmars-d-learn wrote: On Tuesday, 26 July 2016 at 04:05:22 UTC, Charles Hixson wrote: Yes, but I really despise the syntax they came up with. It's probably good if most of your I/O is ranges, but mine hasn't yet ever been. (Combining ranges with random I/O?) that's why i wrote iv.stream, and then iv.vfs, with convenient things like `readNum!T`, for example. you absolutely don't need to reimplement the whole std.stdio.File if all you need it better API. thanks to UFCS, you can write your new API as free functions accepting std.stdio.File as first arg. or even generic stream, like i did in iv.stream: enum isReadableStream(T) = is(typeof((inout int=0) { auto t = T.init; ubyte[1] b; auto v = cast(void[])b; t.rawRead(v); })); enum isWriteableStream(T) = is(typeof((inout int=0) { auto t = T.init; ubyte[1] b; t.rawWrite(cast(void[])b); })); T readInt(T : ulong, ST) (auto ref ST st) if (isReadableStream!ST) { T res; ubyte* b = cast(ubyte*) foreach (immutable idx; 0..T.sizeof) { if (st.rawRead(b[idx..idx+1]).length != 1) throw new Exception("read error"); } return res; } and then: auto fl = File("myfile"); auto i = fl.readInt!uint; something like that. That's sort of what I have in mind, but I want to do what in Fortran would be (would have been?) called record I/O, except that I want a file header that specifies a few things like magic number, records allocated, head of free list, etc. In practice I don't see any need for record size not known at compile time...except that if there are different versions of the program, they might include different things, so, e.g., the size of the file header might need to be variable. This is a design problem I'm still trying to wrap my head around. Efficiency seems to say "you need to know the size at compile time", but flexibility says "you can't depend on the size at compile time". The only compromise position seems to compromise safety (by depending on void * and record size parameters that aren't guaranteed safe). I'll probably eventually decide in favor of "size fixed at compile time", but I'm still dithering. But clearly efficiency dictates that the read size not be a basic type. I'm currently thinking of a struct that's about 1 KB in size. As far as the I/O routines are concerned this will probably all be uninterpreted bytes, unless I throw in some sequencing for error recovery...but that's probably making things too complex, and should be left for a higher level. Clearly this is a bit of a specialized case, so I wouldn't be considering implementing all of stdio, only the relevant bits, and those wrapped with an interpretation based around record number. The thing is, I'd probably be writing this wrapper anyway, what I was wondering originally is whether there was any reason to use std.file as the underlying library rather than going directly to core.stdc.stdio.
Re: randomIO, std.file, core.stdc.stdio
On 07/25/2016 07:11 PM, ketmar via Digitalmars-d-learn wrote: On Tuesday, 26 July 2016 at 01:19:49 UTC, Charles Hixson wrote: then I will prefer the core.stdc.stdio approach. I find it's appearance extremely much cleaner... only if you are really used to write C code. when you see pointer, or explicit type size argument in D, it is a sign of C disease. I'll probably wrap those routines in a struct to ensure things like files being properly closed, and not have explicit pointers persisting over large areas of code. exactly what std.stdio.File did! ;-) Yes, but I really despise the syntax they came up with. It's probably good if most of your I/O is ranges, but mine hasn't yet ever been. (Combining ranges with random I/O?)
Re: randomIO, std.file, core.stdc.stdio
On 07/25/2016 05:18 PM, ketmar via Digitalmars-d-learn wrote: On Monday, 25 July 2016 at 18:54:27 UTC, Charles Hixson wrote: Are there reasons why one would use rawRead and rawWrite rather than fread and fwrite when doiing binary random io? What are the advantages? In particular, if one is reading and writing structs rather than arrays or ranges, are there any advantages? yes: keeping API consistent. ;-) for example, my stream i/o modules works with anything that has `rawRead`/`rawWrite` methods, but don't bother to check for any other. besides, `rawRead` is just looks cleaner, even with all `()[0..1])` noise. so, a question of style. OK. If it's just a question of "looking cleaner" and "style", then I will prefer the core.stdc.stdio approach. I find it's appearance extremely much cleaner...except that that's understating things. I'll probably wrap those routines in a struct to ensure things like files being properly closed, and not have explicit pointers persisting over large areas of code. (I said a lot more, but it was just a rant about how ugly I find rawRead/rawWrite syntax, so I deleted it.)
randomIO, std.file, core.stdc.stdio
Are there reasons why one would use rawRead and rawWrite rather than fread and fwrite when doiing binary random io? What are the advantages? In particular, if one is reading and writing structs rather than arrays or ranges, are there any advantages?
Re: Our docs should be more beautiful
I think the Python docs looks better and are more useful...but the older Python docs were even better. Sometimes fancier HTML just makes things less useful. That said, I think that when feasible docs should be auto-generated from code included within the code files. More like ddoc or javadoc then Sphinx or such. But this shouldn't necessarily apply to the basic frameworks. The basic D documentation is extremely good, it's when we get to the libraries that things become a bit iffy. (Then again, I don't like the template syntax. I thought the D1 docs were better than the D2 docs, but this might be because when they were rewritten they assumed things that give me trouble. I prefer the way that Python handles ranges to the way the D does. Etc. These impact the understanding of the documentation of many Phobos files.) On 07/18/2016 06:41 PM, Andrei Alexandrescu via Digitalmars-d wrote: On 07/18/2016 09:28 PM, Carl Vogel wrote: Racket's docs have actually been designed by a professional typographer, so might be a good reference point. Example: https://docs.racket-lang.org/reference/flonums.html They do look nice! -- Andrei
Re: How to open file with exclusive lock?
On 07/12/2016 03:54 PM, H. S. Teoh via Digitalmars-d-learn wrote: On Tue, Jul 12, 2016 at 03:40:36PM -0700, Charles Hixson via Digitalmars-d-learn wrote: [...] OK. It's not possible without OS support. Agreed. And I don't want to get into C calls, but rather to use the mechanisms that D provides. And this *probably* won't cause any problems. But how should I tell D that that's the way I want to access to work? It's not clear to me that locking beyond the current EOF is valid, or whether it will decide that it needs to reserve the space before I use it (in which case locking from 0->ulong.max bytes is a bad idea, and would totally fill my hard disk). Here's another approach. Since it's almost a given that we're talking about cooperating processes sharing an advisory lock here (since a global mandatory file lock seems to have poor support, at least on Posix), we don't *have* to lock the actual bytes we're writing to. We can simply reserve a couple of bytes (perhaps even just one byte) at the beginning of the file, and agree among all processes that we will always try to acquire lock on that byte before writing to (the rest of) the file. Essentially it would serve as a file equivalent of a mutex. Then wrap all your file primitives in a little wrapper that acquires this mutex before performing file I/O, have your program only do I/O through this wrapper, and you're all set. (IIRC, this is how the SQLite3 library implements database read/write locks. Each sqlite3 database file has a few bytes, IIRC 6 bytes, at a known file offset, that it uses to control various levels of access to the database. Depending on which level of locking was needed, it would acquire a lock on one or more of these bytes, before accessing the rest of the file. It doesn't actually acquire a lock on the bytes being read / modified.) T That's probably the most viable approach. It does mean there's a lag between file open and file lock (unless I was to mess around with concurrency locks), but it's quite unlikely that anyone else will access the file while I have it open. (Well, possibly baloo or nepomuk or some such, but that's probably harmless.)
Re: How to open file with exclusive lock?
On 07/12/2016 12:05 PM, H. S. Teoh via Digitalmars-d-learn wrote: On Tue, Jul 12, 2016 at 11:54:18AM -0700, Charles Hixson via Digitalmars-d-learn wrote: I want to open a file with an exclusive lock. It would be important that no other thread be able to access the file in write mode, and desirable that no other thread be able to access the file in read mode. (Ditto for other processes.) stdio.file.lock (or is it stdio.file.File.lock?) seems to demand a range of chunks to lock, but the file is not fixed in length. Is it appropriate to just specify the maximum possible number of bytes (i.e. ulong.max)? Whether this is even possible depends on your OS. I don't know of any cross-platform way of file-locking that is guaranteed to work everywhere. In Posix there's fcntl(F_RDLCK / F_WRLCK), which I believe is the underlying OS call for File.lock. However, this is only an *advisory* lock, i.e., any other processes accessing the file must also call flock(), otherwise none of its protections apply. It only works between cooperating processes. Linux does have a mandatory locking feature, but it requires the kernel to be specially configured for it, and the filesystem must also support it (and must be mounted with the correct options). Unfortunately it's Linux-specific and probably won't work for any other OS. Windows may have some file-locking mechanism that does what you want, but I'm not familiar with the intricacies of how it works. T OK. It's not possible without OS support. Agreed. And I don't want to get into C calls, but rather to use the mechanisms that D provides. And this *probably* won't cause any problems. But how should I tell D that that's the way I want to access to work? It's not clear to me that locking beyond the current EOF is valid, or whether it will decide that it needs to reserve the space before I use it (in which case locking from 0->ulong.max bytes is a bad idea, and would totally fill my hard disk).
How to open file with exclusive lock?
I want to open a file with an exclusive lock. It would be important that no other thread be able to access the file in write mode, and desirable that no other thread be able to access the file in read mode. (Ditto for other processes.) stdio.file.lock (or is it stdio.file.File.lock?) seems to demand a range of chunks to lock, but the file is not fixed in length. Is it appropriate to just specify the maximum possible number of bytes (i.e. ulong.max)?
Re: D is crap
Garbage collection allows many syntax "liberalizations" that lack of garbage collection renders either impossible or highly dangerous. (In this definition of "garbage collection" I'm including variations like reference counting.) For an example of this consider the dynamic array type. You MUST have garbage collection to use that safely...unless you require the freeing of memory with every change in size. C++ does that with the STL, but if you want the dynamic types built into the language, then you need garbage collection built into the language. (This is different from saying it needs to be active everywhere, but once you've got it, good places to use it keep showing up.) One of the many advantages of the dynamic array type being built into the language is that arrays of different sizes are reasonably comparable by methods built into the language. This is used all over the place. In D I almost never need to use "unchecked conversion". On 07/11/2016 02:30 AM, Chris via Digitalmars-d wrote: On Sunday, 10 July 2016 at 03:25:16 UTC, Ola Fosheim Grøstad wrote: Just like there is no C++ book that does not rant about how great RAII is... What do you expect from a language evangelic? The first Java implementation Hotspot inherited its technology from StrongTalk, a Smalltalk successor. It was not a Java phenomenon, and FWIW both Lisp, Simula and Algol68 were garbage collected. Please stop intentionally missing the point. I don't care if Leonardo Da Vinci already had invented GC - which wouldn't surprise me - but this is not the point. My point is that GC became a big thing in the late 90ies early 2000s which is in part owed to Java having become the religion of the day (not Lisp or SmallTalk)[1]. D couldn't have afforded not to have GC when it first came out. It was expected of a (new) language to provide GC by then - and GC had become a selling point for new languages. [1] And of course computers had become more powerful and could handle the overhead of GC better than in the 80ies. What was "new" with Java was compile-once-run-everywhere. Although, that wasn't new either, but it was at least marketable as new. Java was the main catalyst for GC - or at least for people demanding it. Practically everybody who had gone through IT courses, college etc. with Java (and there were loads) wanted GC. It was a given for many people. Well, yes, of course Java being used in universities created a demand for Java and similar languages. But GC languages were extensively used in universities before Java. Yes, it didn't last long. But the fact that they bothered to introduce it, shows you how big GC was/is. No, it shows how demanding manual reference counting was in Objective-C on regular programmers. GC is the first go to solution for easy memory management, and has been so since the 60s. Most high level languages use garbage collection. It wasn't demanding. I wrote a lot of code in Objective-C and it was perfectly doable. You even have features like `autorelease` for return values. The thing is that Apple had become an increasingly popular platform and more and more programmers were writing code for OS X. So they thought, they'd make it easier and reduce potential memory leaks (introduced by not so experienced Objective-C coders) by adding GC, especially because a lot of programmers expected GC "in this day and age".
Re: Should we add another SmallArray to DMD?
On 07/07/2016 03:51 AM, Guillaume Chatelet via Digitalmars-d wrote: On Thursday, 7 July 2016 at 07:56:44 UTC, Stefan Koch wrote: On Thursday, 7 July 2016 at 06:39:19 UTC, Guillaume Chatelet wrote: On Tuesday, 5 July 2016 at 19:41:18 UTC, Guillaume Chatelet wrote: DMD currently provides the Array type: https://github.com/dlang/dmd/blob/master/src/root/array.d [...] Walter, Daniel, Thoughts? I guess a few number of the perf difference this can make would be helpful. It's not so much about performance gain (although it wouldn't hurt). It's more about codebase sanity: idiomatic D, documentation, tests. I think it's currently hard to contribute to DMD. Sure it improved a lot with the migration to D but it still bears the marks of the past. If it's just for code sanity, why wouldn't an alias suffice? I often alias types to create a "type" for a specialized purpose. Of course, if you want a real type you could wrap it in a struct...which I do with classes when it's *IMPORTANT* that the finalizer be called.
Re: How to get current time as long or ulong?
On 07/06/2016 10:32 AM, H. S. Teoh via Digitalmars-d-learn wrote: On Wed, Jul 06, 2016 at 10:19:19AM -0700, Charles Hixson via Digitalmars-d-learn wrote: [...] The same time needs to be used for two different purposes (or I have to keep two separate times). One time is used during a particular run of the program to compare when two different things happened. This needs fine discrimination...millisecond level. The other needs to be used to order events happening over a period of time. This needs to be at the hour level, and the minute level is better. But it needs to work over years. That's why I originally said UnixTime...and UnixTime would work fine, but problems might happen if it were in use in 2029(?*). Since D supports a 64 bit time, not using it would seem to be unreasonable. I looked into scaling it, but either I use more than 32 bits, or I need to keep two times. So the long version of SysTime seems to be what I want. That will even let me compare things against books published in the Classical Greek period, and doesn't threaten to roll over. It's more precise than I need, but there's no one time of lesser precision that will do everything I want. The problem with this is that the system clock may change. Would your program continue to function correctly if, during execution, the user changes the system clock? Or if the OS in the background syncs with a remote NTP server and loses/gains a few seconds/minutes during which events are happening that record timestamps? I.e., some events might have their timestamps out-of-order with the actual sequence of events if you use system time. T It would err in a trivial way, which might require reloading something from disk. So an occasional mistake of that nature isn't a problem.
Re: How to get current time as long or ulong?
On 07/05/2016 05:23 PM, Jonathan M Davis via Digitalmars-d-learn wrote: On Tuesday, July 05, 2016 12:51:54 Charles Hixson via Digitalmars-d-learn wrote: On 07/05/2016 11:43 AM, Jonathan M Davis via Digitalmars-d-learn wrote: On Tuesday, July 05, 2016 11:16:31 Charles Hixson via Digitalmars-d-learn wrote: What I'm looking for is the opposite of the "FromUnixTime" function. SysTime has toUnixTime, which is right above fromUnixTime in the documentation. But if what you want is a time_t, and you don't want to deal with SysTime, there's no point in using std.datetime. Just use core.time to call C's time function. - Jonathan M Davis That's what I want, but I'm worried by the documentation saying: " This has no relation to the wall clock time, as the wall clock time can be adjusted (e.g. by NTP), whereas the monotonic clock always moves forward." What I want is the system clock time, which *is* adjusted by NTP. I know it's not guaranteed monotonic, but different computers should have the same time (or be able to be synchronized to the same NTP time). And it's "approximately monotonic". time_t is fine, as 32 bit hardware is becoming scarce, and the application I'm working on will probably never encounter any. (More than 32 bits of precision is required as I don't want it to roll over every 42.5 days.) I understand why some purposes would really want a monotonic time, but that's not a strong constraint for me. But I do want it to be a long or ulong. (I don't really care where 0 is. What I'm using now is: aliaslongClockT; ClockTnow(){returnMonoTime.currTime();} And it's working fine during testing, but the documentation about the setting of MonoTime bothers me. The Monotonic clock has nothing to do with the wall clock. It's giving the number of system clock ticks which have occurred since some arbitrary time that the system clock decided was 0, and the number of ticks per second is completely system dependent. You wouldn't even want to share that number between programs, let alone between runs of the same programe or between computers. It's used for timing, not for knowing what time it is. e.g. auto before = MonoTime.currTime; // ... do a bunch of stuff auto after = Monotime.currTime; // The amount of time that that stuff took auto diff = after - before; It's the difference that becomes meaningful. The actual values of before and after would be meaningless outside of this exact run of the program. What makes the monotonic clock work for timing unlike the wall clock is that it always moves forward by a fixed number of ticks per second. It's all about timing and not at all about determing what time of day it is. The wall clock time, on the other hand, is all about the time of day. It's this particular hour, minute, second, etc. on this particular day of this particular month of this particular year. And because the system's wall clock time can be changed (be it because of NTP or someone manually changing the time - or even because of a change in time zone if you're dealing with the local time), it is not guaranteed to always move forward at a fixed rate. It could change radically, which is why it does not work for timing. It's all about knowing what time of day that something happened. There really should never be a question of whether the monotonic time or the wall clock time is appropriate. If you're ever asking that question, then you almost certainly don't understand what they are. If what you want is to time stuff (e.g. this happened x minutes into the run of this program or this operation took y seconds), then you want the monotonic time. If what you want is to know when something happens - i.e. the time of day and/or date - then what you want is the wall clock time. What you're using it for should make it obvious which you need. But I would have to know more about what you're trying to do to have any clue what you should be using. And I don't know why you would be so interested in having the time as an integral value. That's usually a bad idea. It's almost always better to use a time type that actually involves units and context rather than a naked integral value. - Jonathan M Davis The same time needs to be used for two different purposes (or I have to keep two separate times). One time is used during a particular run of the program to compare when two different things happened. This needs fine discrimination...millisecond level. The other needs to be used to order events happening over a period of time. This needs to be at the hour level, and the minute level is better. But it needs to work over years. That's why I originally said UnixTime...and UnixTime would work fine, but problems might happen if it were in use in 2029(?*). Since D supports a 64 bit time, not using it would seem to be unreasonable. I looked into scaling it, but either I use more than 32 bits, or I need to keep two times. So the
Re: How to get current time as long or ulong?
Thank you for confirming the change. It hasn't made any difference during the tests so far, but it sounds like it soon would have. I don't really want a long...but an int rolls over too quickly, and there's no 48 bit time. The time is basically for use over smaller intervals, but occasionally I may need to compare across multiple months, or even years. So the reason is because I want one time unit to have multiple uses. It's going to end up being stored on disk, but order of access is going to frequently be important, and occasionally the relative age of quite different entities is going to be important. For the second use I could use a much lower precision timer, but that would mean using two separate times for each item. On 07/05/2016 05:10 PM, Jonathan M Davis via Digitalmars-d-learn wrote: On Tuesday, July 05, 2016 16:18:19 Charles Hixson via Digitalmars-d-learn wrote: I guess I was expressing myself poorly, probably due to muddled thinking about the representation of time. Based on various hints from you and others my current guess is that I should use: longnow() { returnClock.currTime().stdTime;} IIUC this should return the current system clock time offset to start at the start of 1 C.E. (with a standard systematic error that common across all machines allowing for drift since the last time their clocks were updated by NTP). And that this is the supported way to get this time. (Which is probably about the same as MonoTime.currTime(), but *is* updated when NTP updates the system clock.) And which is standardly a 64 bit number. MonoTime and stdTime have _nothing_ to do with each other. stdTime is the number of hecto-nanoseconds since midnight, January 1st, 1 A.D. MonoTime contains a timestamp in system ticks, and how many of those there are per second as well as how long ago 0 was are completely system-dependent. The monotonic time is used for timing things not for anything related to the wall clock. If what you care about is the wall clock, then use SysTime. If what you care about is timing stuff, then use MonoTime. I don't know why you'd want a long for the system time. There's nothing standard about stdTime (which is why it's a horrible name, but unfortunately, there really isn't a good name for it like there is with unix time). SysTime exposes stdTime for the rare code that actually needs it, but in general, code should either be using SysTime or converting SysTime to the ISO or ISO extended formats, because those are standard. But you certainly can store the stdTime somewhere if you want to. - Jonathan M Davis
Re: How to get current time as long or ulong?
I guess I was expressing myself poorly, probably due to muddled thinking about the representation of time. Based on various hints from you and others my current guess is that I should use: longnow() { returnClock.currTime().stdTime;} IIUC this should return the current system clock time offset to start at the start of 1 C.E. (with a standard systematic error that common across all machines allowing for drift since the last time their clocks were updated by NTP). And that this is the supported way to get this time. (Which is probably about the same as MonoTime.currTime(), but *is* updated when NTP updates the system clock.) And which is standardly a 64 bit number. On 07/05/2016 11:53 AM, Jonathan M Davis via Digitalmars-d-learn wrote: On Tuesday, July 05, 2016 11:43:32 Jonathan M Davis via Digitalmars-d-learn wrote: But if what you want is a time_t, and you don't want to deal with SysTime, there's no point in using std.datetime. Just use core.time to call C's time function. Actually, I should qualify this. I keep forgetting that time_t is not guaranteed to be unix time on non-POSIX systems. If what you want is time_t, then use C's time function via core.time, but if what you want is actual unix time, then just do Clock.currTime.toUnixTime, since that's the simplest way to do it. If you're using Microsoft's runtime, then time_t is indeed unix time, but it's not for the Digital Mars runtime (and the standard - unfortunately - doesn't require it to be). Digital Mars uses someting that's _close_ to time_t but isn't actually time_t. :( - Jonathan M Davis
Re: How to get current time as long or ulong?
On 07/05/2016 11:43 AM, Jonathan M Davis via Digitalmars-d-learn wrote: On Tuesday, July 05, 2016 11:16:31 Charles Hixson via Digitalmars-d-learn wrote: What I'm looking for is the opposite of the "FromUnixTime" function. SysTime has toUnixTime, which is right above fromUnixTime in the documentation. But if what you want is a time_t, and you don't want to deal with SysTime, there's no point in using std.datetime. Just use core.time to call C's time function. - Jonathan M Davis That's what I want, but I'm worried by the documentation saying: " This has no relation to the wall clock time, as the wall clock time can be adjusted (e.g. by NTP), whereas the monotonic clock always moves forward." What I want is the system clock time, which *is* adjusted by NTP. I know it's not guaranteed monotonic, but different computers should have the same time (or be able to be synchronized to the same NTP time). And it's "approximately monotonic". time_t is fine, as 32 bit hardware is becoming scarce, and the application I'm working on will probably never encounter any. (More than 32 bits of precision is required as I don't want it to roll over every 42.5 days.) I understand why some purposes would really want a monotonic time, but that's not a strong constraint for me. But I do want it to be a long or ulong. (I don't really care where 0 is. What I'm using now is: aliaslongClockT; ClockTnow(){returnMonoTime.currTime();} And it's working fine during testing, but the documentation about the setting of MonoTime bothers me.
How to get current time as long or ulong?
I've been reading std.datetime documentation backwards and forwards, but if the information is there, I've been missing it. How do I get the current time as a long? Clock.currTime() returns a SysTime, and while currently I can convert that to a long, this is because I looked into the code. What's the supported way? All the documentation seems to be based around auto, which is great if you don't need to store it in memory with a defined number of bits allocated...but lousy if you do. (E.g., I don't want to store a time zone, just the UTC time. What I'm looking for is the opposite of the "FromUnixTime" function.
Re: D is almost the exact language I need...
On 07/03/2016 01:31 AM, Walter Bright via Digitalmars-d wrote: On 7/3/2016 12:21 AM, Charles Hixson via Digitalmars-d wrote: I do wish that phobos included a D wrapper around SQLite, There was one recently announced. Thanks. I missed the announcement. I'd also like to be able to depend on class finalizers being called. Sometimes I wrap a class in a struct just so I can depend on the finalizer. That's the way to do it. It works, but it's a bit of added friction when I'm coding. Especially if I need access to the internals of the class...then I need to manually mangle the names. (I'm not implying I need to match the compiler's version of the name.) The last time I checked DDoc stopped working after encountering an extern "C" block in a file. I'm not aware of this. Is there a bug report filed? I wasn't sure it was a bug. And it may not still be present. Since I figured out the cause I've just put the C externals in a separate file. DDoc could use considerable work in formatting. I'd like to be able to globally control the font attributes of classes, structs, aliases, enums. DDoc relies on having a user-supplied xxx.ddoc file to provide the formatting, css, etc. I wasn't able to figure out how to highlight classes differently from structs, etc. I have built small .ddoc files to make custom changes, but that was for defining macros. I'd like to be able to document private routines or not depending on a (compiler) switch. I'm not sure what the point of that would be. Private functions shouldn't be called by anything outside of the file, and you already have the file open in the editor when working on it. But you can always submit an enhancement request for it on bugzilla. That's not for export. The documentation is written for me to use a month or more later. Most of my needs are for run time flexibility rather than for more compile time flexibility. E.g., I'd like to be able to declare a statically sized array from a parameter. You can do it more or less with alloca(). I know C99 has this feature, and some people swear by it, but I just don't think it pulls its weight. Yes, I could manually allocate them. But that adds a lot of resistance. If they are too much effort, well, OK, but that's an example of the kind of thing that I want that D doesn't address. No language does everything, and D is one of the two or three languages I consider best. Python is another, but slow. Vala shows promise, but it's not portable, and the development is glacial. Also it's poorly documented. It's advantage is it's fast AND has a lot of wrapped libraries. (But last I checked it seemed FAR from 1.0.) I feel sort of guilty for "complaining" this way when I've been devoting all my efforts to my own projects, but you did, essentially, invite comments. If something good can come from it, it's good. My chances of getting any usable result from my work are *very* low. OTOH, if I do the social payoff will be huge. So I persevere. Except when I get discouraged.
Re: D is almost the exact language I need...
FWIW, I feel that the elaboration of the template language doesn't serve me well. That's my use case, so I try to ignore it as much as possible, but phobos has been re-written to be much less intelligible to me. I'm sure that many people find the inclusion of ranges into everything useful, but it rarely helps me. I really like the way D handles unicode. D and Vala are the two languages that seem to handle it well, and Vala isn't portable. And I really like having garbage collection, and especially the syntax that it enables. I was just considering a hash table (associative array) in C++, and realized that I had to either allocate on the heap, or I couldn't easily do an increment of a struct variable. (Well, I'm thinking about QHash, because walking the files of a directory path in standard C++ is unpleasant, and Qt makes both that and unicode tests [the ones I need to do] pretty simple.) But if I allocate structs on the heap I have to make sure that everything gets released when I'm through, so I need to use an enhanced pointer construct, so It's a lot simpler in D. I do wish that phobos included a D wrapper around SQLite, something object oriented. I'd also like to be able to depend on class finalizers being called. Sometimes I wrap a class in a struct just so I can depend on the finalizer. The last time I checked DDoc stopped working after encountering an extern "C" block in a file. This is not desirable, even though one can work around it by moving all the extern routines to another file. DDoc could use considerable work in formatting. I'd like to be able to globally control the font attributes of classes, structs, aliases, enums. I'd like to be able to document private routines or not depending on a (compiler) switch. I frequently end up declaring things to be protected rather than private just so I can generate documentation. Most of my needs are for run time flexibility rather than for more compile time flexibility. E.g., I'd like to be able to declare a statically sized array from a parameter. I do appreciate D's speed, but complex templates aren't something I ever use. (Truth is, I was pretty well satisfied with D1, though perhaps I'm forgetting some limitations, but even then I'm pretty much sure that I felt the main limitation was a lack of well interfaced libraries.) Too many of D's libraries seem to try to re-invent the wheel. When a library is working well and has been debugged, the best think if to create a wrapper around it. The wrapper *does* need to adapt the library to the syntax of the language, but that's not a huge problem. A major part of Python's success is "batteries included". I feel sort of guilty for "complaining" this way when I've been devoting all my efforts to my own projects, but you did, essentially, invite comments. On 07/02/2016 11:23 PM, Walter Bright via Digitalmars-d wrote: Thanks for taking the time to write this. Let me see if I can help. On 7/2/2016 9:37 PM, D is crap wrote: 1. The language is not completely well defined. While the language itself contains many nice features and what makes D appealing, too many features are cobbled together and don't completely work 100% properly. This creates very subtle bugs or problem areas that can stop one in their tracks. One can see how these things are cobbled together by observing the forms and the discussions about how to proceed in certain areas. This is true. I'm interested in which of these have caused you problems. Naturally, people in the forum are going to debate the edge cases, as they do in every language. It isn't necessary to use those edge cases to write very successful code, however. 2. The compilation process is riddled with meaningless error messages and a simple missing ';' can launch one off to the moon to figure out it is missing. The error messages can cascade. Fix the ';' and 20 messages disappear. I agree this is true for the syntax checker, but also I'm not aware of any compiler that has successfully dealt with this problem other than simply stopping after the first message. The semantic pass is much better at having one and only one error message per actual error. Usually each message is 100 characters+ when it involves templates. Again, you are right, but this is a consequence of templates being complex. The compiler tries to emit all the relevant context to enable the user to figure out the right fix. Rather than just telling you what is grammatically missing, like any normal modern compiler does, you have to hunt and peck and fill your head with meaningless information. Most of the error messages out of the syntax checker are of the form "xxx expected", so if you could present an example of a bad error message I'd appreciate it so it can be improved. 3. The compilers are designed as if they come straight out of the 70's. The setup is obscure, relies on assumptions that are not
Re: UTF-8 Everywhere
On 06/19/2016 11:44 PM, Walter Bright via Digitalmars-d wrote: On 6/19/2016 11:36 PM, Charles Hixson via Digitalmars-d wrote: To me it seems that a lot of the time processing is more efficient with UCS-4 (what I call utf-32). Storage is clearly more efficient with utf-8, but access is more direct with UCS-4. I agree that utf-8 is generally to be preferred where it can be efficiently used, but that's not everywhere. The problem is efficient bi-directional conversion...which D appears to handle fairly well already with text() and dtext(). (I don't see any utility for utf-16. To me that seems like a first attempt that should have been deprecated.) That seemed to me to be true, too, until I wrote a text processing program using UCS-4. It was rather slow. Turns out, 4x memory consumption has a huge performance cost. The approach I took (which worked well for my purposes) was to process the text a line at a time, and for that the overhead of memory was trivial. ... If I'd needed to go back and forth this wouldn't have been desirable, but there was one dtext conversion, processing, and then several text conversions (of small portions), and it was quite efficient. Clearly this can't be the approach taken in all circumstances, but for this purpose it was significantly more efficient than any other approach I've tried. It's also true that most of the text I handled was actually ASCII, which would have made the most common conversion processes simpler. To me it appears that both cases need to be handled. The problem is documenting the tradeoffs in efficiency. D seems to already work quite well with arrays of dchars, so there may well not be any need for development in that area. Direct indexing of utf-8 arrays, however, is a much more complicated thing, which I doubt can ever be as efficient. Memory allocation, however, is a separate, though not independent, complexity. If you can work in small chunks then it becomes less important.
Re: UTF-8 Everywhere
To me it seems that a lot of the time processing is more efficient with UCS-4 (what I call utf-32). Storage is clearly more efficient with utf-8, but access is more direct with UCS-4. I agree that utf-8 is generally to be preferred where it can be efficiently used, but that's not everywhere. The problem is efficient bi-directional conversion...which D appears to handle fairly well already with text() and dtext(). (I don't see any utility for utf-16. To me that seems like a first attempt that should have been deprecated.) On 06/19/2016 05:49 PM, Walter Bright via Digitalmars-d wrote: http://utf8everywhere.org/ It has a good explanation of the issues and problems, and how these things came to be. This is pretty much in line with my current (!) opinion on Unicode. What it means for us is I don't think it is that important anymore for algorithms to support strings of UTF-16 or UCS-4.
Re: Andrei's list of barriers to D adoption
On 06/05/2016 09:17 PM, Adam D. Ruppe via Digitalmars-d wrote: On Monday, 6 June 2016 at 02:30:55 UTC, Pie? wrote: Duh! The claim is made that D can work without the GC... but that's a red herring... If you take about the GC what do you have? Like 90% of the language, still generally nicer than most the competition. Though, I wish D would just own its decision instead of bowing to Reddit pressure. GC is a proven success in the real world with a long and impressive track record. Yes, there are times when you need to optimize your code, but even then you aren't really worse off with it than without it. Usually correct, but there are times when you want to suspend the garbage collection. The problem is this should always be a scoped decision, because it's easy to accidentally leave it turned off, and then it's MUCH worse than not having it.
stdout.flush
Using: dmd --version DMD64 D Compiler v2.071.0 on debian Linux, and importing: importstd.stdio; the line: flush(); causes: nt.d(29): Error: undefined identifier 'flush', did you mean function 'fflush'? This appears solved by doing stdout.flush; (compiles, but I'm still writing the code) but as write, writef, etc. don't require explicitly mentioning stdout, I think that the documentation for flush should mention that the file must be specified. Currently it seems to imply that all files will be flushed.
Re: More binary I/O problems
On 04/08/2016 07:42 PM, Basile B. via Digitalmars-d-learn wrote: On Friday, 8 April 2016 at 20:58:06 UTC, Charles Hixson wrote: [...] And that worked, but suddenly (after a compiler upgrade, did that matter? I'd also changed the program, though in ways that shouldn't have affected this.) it stopped working with the message: let4a.d(138): Error: no [] operator overload for type Chnk [...] you can cast too (void*) struct Chnk { char[20] wrd; ubyte length; ulong id; this (ulong id, string wrd) {} uint hCode () {return 0;} string toString () { return "";} string wrdStr() {return "";} } void main() { import std.file: read, write; Chnk c; write("a.txt", (cast(void*))[0..Chnk.sizeof]); auto buff = read("a.txt", Chnk.sizeof); (cast(void*))[0..Chnk.sizeof] = buff[0..Chnk.sizeof]; } Thanks. That syntax looks like it would work, but gee! The syntax is getting worse and worse. OTOH, I notice that you're using a file name rather than a File. Perhaps that's my problem, but if so how do I specify that I want a binary read/write rather than a text one. (I notice that you named the file "a.txt", and I explicitly do not want to do a text conversion. That would result in different numbers taking up different numbers of bytes, and so random addressing wouldn't work.) Also read indicates that it tries to read in the entire file, so perhaps it's not intended for this purpose, and I should use rawRead/rawWrite which should work with that hideous cast & copy to/from ubyte[] step. I suppose I could code the I/O in C...that way I might need to use foreign calling conventions, but the I/O would be straightforwards. And since everything is fixed length it should be an easy transition... I want to use D because the garbage collection is useful and the handling of unicode strings/chars is hard to beat. It would also mean I didn't need to use ZMQ when I got around to parallel execution. But this code was working, and now it suddenly isn't. I know you pointed out that I could get around this by copying it to a buffer, and writing out the buffer, and then reading in the buffer, and then copying the buffer to the object, with lots of casting. And I admit that it's doable, but I'm having trouble believing how ugly it is. Not to mention that this is needed because code that used to be working stopped working. Fortunately I was still developing this area, or it might have broken totally and I wouldn't have known until I tried to put the pieces together.
More binary I/O problems
On 03/25/2016 11:32 AM, Adam D. Ruppe via Digitalmars-d-learn wrote: On Friday, 25 March 2016 at 18:25:28 UTC, Charles Hixson wrote: But when I try to cast a Chnk to a ubyte[], I get an error, and rawWrite takes a generic array of anything... you should be able to rawWrite((_object)[0 .. 1]) Thanks, that compiled. It's running a test now...and I'm leaving it for a few hours. And that worked, but suddenly (after a compiler upgrade, did that matter? I'd also changed the program, though in ways that shouldn't have affected this.) it stopped working with the message: let4a.d(138): Error: no [] operator overload for type Chnk Well, there isn't, Chnk is just a struct. The offending line was: f.rawWrite (&(val)[0..1]); which I already though was unreasonably convoluted. I just wanted something like: f.write(, val.sizeof); which used to work, but the corresponding read doesn't seem to exist anymore, so I can't test it. It's documented, but when I try to use it: f.read(, c.sizeof); results in: let4a.d(172): Error: template std.file.read cannot deduce function from argument types !()(File, Chnk*, ulong), candidates are: /usr/include/dmd/phobos/std/file.d(222):std.file.read(R)(R name, size_t upTo = size_t.max) if (isInputRange!R && isSomeChar!(ElementEncodingType!R) && !isConvertibleToString!R) /usr/include/dmd/phobos/std/file.d(248): std.file.read(R)(auto ref R name, size_t upTo = size_t.max) if (isConvertibleToString!R) And I'm trying to do a binary read, not a string read. (I also tried it with f.read(c, c.sizeof); and got equivalent error messages. And the struct was (abbreviated as noted): structChnk { char[20]wrd; ubytelength; ulongid; this(ulong id,string wrd) { ... } uinthCode (){returnhash(wrdStr) % fcnt;} stringtoString (){ ... } stringwrdStr(){ ... } }//structChnk There are no indirections. It's just a simple struct that I want to read and write to a randomly accessible file. This used to be easy, but now I keep running into problems. FWIW, it's stored in a ChnkTbl, thus: constushortfcnt=128; aliasChnk[string]ChnkTbl; ChnkTbl[fcnt]chnks; with the idea that each ChnkTbl would be stored in a separate file. But it's the binary read/write I keep having problems with.
Re: Decompressing bzip2
On 04/05/2016 03:33 PM, Mike Parker via Digitalmars-d-learn wrote: On Tuesday, 5 April 2016 at 19:27:20 UTC, Charles Hixson wrote: ... Are you asserting that scope is soon to be officially deprecated? I'm finding "shouldn't really be used at all anymore" a bit of a worrying statement, as I much prefer the syntax used by scope. Why shouldn't it "be used at all anymore"? http://dlang.org/deprecate.html#scope%20for%20allocating%20classes%20on%20the%20stack Thanks. It is the "for other features" that I normally use scope. Mainly, admittedly, for timing the running of the destructor (or analogs thereto, like File.close), but the syntax is not the one being deprecated.
Re: Decompressing bzip2
On 04/04/2016 04:38 PM, Mike Parker via Digitalmars-d-learn wrote: On Monday, 4 April 2016 at 21:32:10 UTC, stunaep wrote: Can you please explain what the scope keyword does and if there scope was originally intended to be used primarily with classes in order to get deterministic destruction. It ensures the destructor of a class is called when the scope exits, just as with a struct. It's not needed here and shouldn't really be used at all anymore. It has been superseded by std.typecons.scoped [1]. It's not needed here at all, though. bz_stream is a struct, so there's no need to allocate an instance of it: ... Are you asserting that scope is soon to be officially deprecated? I'm finding "shouldn't really be used at all anymore" a bit of a worrying statement, as I much prefer the syntax used by scope. Why shouldn't it "be used at all anymore"?
Re: unicode confusion--An answer
I was writing my output to two different files. Only one of them was set to utf-8, the other must have been some other encoding, because when I set the encoding to utf-8 everything cleared up. On 04/04/2016 04:04 PM, Charles Hixson via Digitalmars-d-learn wrote: Well, at least I think that it's unicode confusion. When a store values into a string (in an array of structs) and then compare it against itself, it compares fine, and if I write it out at that point it writes out fine. And validate says it's good unicode. But later... valid = true, len = 17, wrd = true , cnt = 2, txt = Gesammtabentheuer valid = true, len = 27, wrd = true , cnt = 1, txt = νεÏεληγεÏá½³ÏÎ·Ï valid = true, len = 17, wrd = true , cnt = 1, txt = ζηÏοῦÏιν valid = true, len = 36, wrd = true , cnt = 1, txt = αἱμοÏÏοÏδοκαύÏÏÎ·Ï valid = true, len = 18, wrd = true , cnt = 2, txt = Î´Ï Î½Î·Î¸Ïμεν valid = true, len = 20, wrd = true , cnt = 1, txt = ÏÏοÏκÏοÏÏÏ valid = true, len = 20, wrd = true , cnt = 1, txt = ÏκοÏÏμÎνην valid = true, len = 18, wrd = true , cnt = 1, txt = á¼Î³Î±ÏηÏοί valid = true, len = 28, wrd = true , cnt = 1, txt = ×Ö½Ö·×Ö°×Ö´×ָּתָ×Ö¼ valid = true, len = 19, wrd = true , cnt = 1, txt = Î¤Ï ÏÏηνικά valid = true, len = 17, wrd = true , cnt = 2, txt = IODOHYDRARGYRATIS valid = true, len = 21, wrd = true , cnt = 1, txt = ÏοινικίÏιν valid = true, len = 17, wrd = true , cnt = 1, txt = Spectrophotometer valid = true, len = 26, wrd = true , cnt = 1, txt = αἰνιÏÏόμενοι valid = true, len = 70, wrd = true , cnt = 1, txt = ÎÎΣΠÎÎÎΡÎÎÎΣΧÎÎÎÎÎΡÎÎΣÎÎÎÎ¥ÎÎ ÎΤÎΣÎÎÎ valid = true, len = 18, wrd = true , cnt = 1, txt = μικÏÏÏαÏα valid = true, len = 23, wrd = true , cnt = 1, txt = á¼ÏοÏá½±ÏηÏίν valid = true, len = 18, wrd = true , cnt = 1, txt = ××ֹקְש×Öµ× valid = true, len = 17, wrd = true , cnt = 1, txt = διαμένÏν . . . (etc. for 39599 lines) (And it looks worse than that, actually, because control characters aren't coming through). I think the originals were usually greek letters due to an earlier test (why there should be so many greek words I don't know...but if they're there I want them to be handled properly), but the corrupted text is such a small part of the original file that I can't be certain. Valid = true means that it passed string validates right before being printed. wrd = true means that the only characters in it should be isAlpha, hyphen, apostrophe, or underscore. cnt = n means that it was detected n times in the dataset (of 8013 text files). And the string in each struct is only written once in the execution of the program. I was scanning the dataset looking to see what long words were valid...I didn't expect THIS at all. And as you can see from, e.g., "Spectrophotometer", ASCII values don't seem to be damaged at all. FWIW, I was expecting to encounter an occasional Greek, French, or Chinese word...but nothing like this. I'd think it was the conversion from string to dchar[] and back that was the problem, but when I test immediately after I know I've written to the string everything looks right. So I'm guessing it's something about how unicode is handled.
unicode confusion
Well, at least I think that it's unicode confusion. When a store values into a string (in an array of structs) and then compare it against itself, it compares fine, and if I write it out at that point it writes out fine. And validate says it's good unicode. But later... valid = true, len = 17, wrd = true , cnt = 2, txt = Gesammtabentheuer valid = true, len = 27, wrd = true , cnt = 1, txt = νεÏεληγεÏá½³ÏÎ·Ï valid = true, len = 17, wrd = true , cnt = 1, txt = ζηÏοῦÏιν valid = true, len = 36, wrd = true , cnt = 1, txt = αἱμοÏÏοÏδοκαύÏÏÎ·Ï valid = true, len = 18, wrd = true , cnt = 2, txt = Î´Ï Î½Î·Î¸Ïμεν valid = true, len = 20, wrd = true , cnt = 1, txt = ÏÏοÏκÏοÏÏÏ valid = true, len = 20, wrd = true , cnt = 1, txt = ÏκοÏÏμÎνην valid = true, len = 18, wrd = true , cnt = 1, txt = á¼Î³Î±ÏηÏοί valid = true, len = 28, wrd = true , cnt = 1, txt = ×Ö½Ö·×Ö°×Ö´×ָּתָ×Ö¼ valid = true, len = 19, wrd = true , cnt = 1, txt = Î¤Ï ÏÏηνικά valid = true, len = 17, wrd = true , cnt = 2, txt = IODOHYDRARGYRATIS valid = true, len = 21, wrd = true , cnt = 1, txt = ÏοινικίÏιν valid = true, len = 17, wrd = true , cnt = 1, txt = Spectrophotometer valid = true, len = 26, wrd = true , cnt = 1, txt = αἰνιÏÏόμενοι valid = true, len = 70, wrd = true , cnt = 1, txt = ÎÎΣΠÎÎÎΡÎÎÎΣΧÎÎÎÎÎΡÎÎΣÎÎÎÎ¥ÎÎ ÎΤÎΣÎÎÎ valid = true, len = 18, wrd = true , cnt = 1, txt = μικÏÏÏαÏα valid = true, len = 23, wrd = true , cnt = 1, txt = á¼ÏοÏá½±ÏηÏίν valid = true, len = 18, wrd = true , cnt = 1, txt = ××ֹקְש×Öµ× valid = true, len = 17, wrd = true , cnt = 1, txt = διαμένÏν . . . (etc. for 39599 lines) (And it looks worse than that, actually, because control characters aren't coming through). I think the originals were usually greek letters due to an earlier test (why there should be so many greek words I don't know...but if they're there I want them to be handled properly), but the corrupted text is such a small part of the original file that I can't be certain. Valid = true means that it passed string validates right before being printed. wrd = true means that the only characters in it should be isAlpha, hyphen, apostrophe, or underscore. cnt = n means that it was detected n times in the dataset (of 8013 text files). And the string in each struct is only written once in the execution of the program. I was scanning the dataset looking to see what long words were valid...I didn't expect THIS at all. And as you can see from, e.g., "Spectrophotometer", ASCII values don't seem to be damaged at all. FWIW, I was expecting to encounter an occasional Greek, French, or Chinese word...but nothing like this. I'd think it was the conversion from string to dchar[] and back that was the problem, but when I test immediately after I know I've written to the string everything looks right. So I'm guessing it's something about how unicode is handled.
Re: rawWrite of a struct suggestions
OK, after removing a few bugs, preliminary checks say that this works perfectly. Thanks again, as I never would have even considered that approach. On 03/25/2016 12:24 PM, Charles Hixson via Digitalmars-d-learn wrote: On 03/25/2016 11:32 AM, Adam D. Ruppe via Digitalmars-d-learn wrote: On Friday, 25 March 2016 at 18:25:28 UTC, Charles Hixson wrote: But when I try to cast a Chnk to a ubyte[], I get an error, and rawWrite takes a generic array of anything... you should be able to rawWrite((_object)[0 .. 1]) Thanks, that compiled. It's running a test now...and I'm leaving it for a few hours.
Re: rawWrite of a struct suggestions
On 03/25/2016 11:32 AM, Adam D. Ruppe via Digitalmars-d-learn wrote: On Friday, 25 March 2016 at 18:25:28 UTC, Charles Hixson wrote: But when I try to cast a Chnk to a ubyte[], I get an error, and rawWrite takes a generic array of anything... you should be able to rawWrite((_object)[0 .. 1]) Thanks, that compiled. It's running a test now...and I'm leaving it for a few hours.
rawWrite of a struct suggestions
I've got a simple struct: structChnk { ulongid; char[20]wrd; ubytelength; ...<--various utility functions and constructors } That I'm trying to write to a file. I want to use an unformatted read/write because I want this to be a random access file. But when I try to cast a Chnk to a ubyte[], I get an error, and when I try to to!ubyte[] it I get a slightly different error:: Error: template instance isRawStaticArray!() does not match template declaration isRawStaticArray(T, A...) I don't want to copy it twice each time I read or write it, as I would if, e.g., I used OutBuffer. How should I approach this? Do I need to use fread/fwrite? I'm sure I used to be able to pass a pointer and length, but I can't find that option anymore.
is increment on shared ulong atomic operation?
If I define a shared ulong variable, is increment an atomic operation? E.g. shared ulong t; ... t++; It seems as if it ought to be, but it could be split into read, increment, store. I started off defining a shared struct, but that seems silly, as if the operations defined within a shared struct are synced, then the operation on a shared variable should be synced, but "+=" is clearly stated not to be synchronized, so I'm uncertain.
Re: is increment on shared ulong atomic operation?
Thanks, that's what I needed to know. I'm still going to do it as a class, but now only the inc routine needs to be handled specially. (The class is so that other places where the value is used don't even need to know that it's special. And so that instances are easy to share between threads.) On 02/07/2016 11:43 AM, rsw0x via Digitalmars-d-learn wrote: On Sunday, 7 February 2016 at 19:39:27 UTC, rsw0x wrote: On Sunday, 7 February 2016 at 19:27:19 UTC, Charles Hixson wrote: If I define a shared ulong variable, is increment an atomic operation? E.g. shared ulong t; ... t++; It seems as if it ought to be, but it could be split into read, increment, store. I started off defining a shared struct, but that seems silly, as if the operations defined within a shared struct are synced, then the operation on a shared variable should be synced, but "+=" is clearly stated not to be synchronized, so I'm uncertain. https://dlang.org/phobos/core_atomic.html#.atomicOp Just noticed that there's no example. It's used like shared(ulong) a; atomicOp!"+="(a, 1);
Re: Proposal: Database Engine for D
FWIW, were I proposing a "Database Engine for D" I'd be proposing a B+Tree that was restricted to storing explicit data (no pointers or other indirection...including strings, you'd need to specify fixed size arrays of char, wchar, or dchar). There would be one "type"/file, and the "type" would be given by a struct that contained no pointers either obvious or hidden (i.e., dynamic arrays, strings, etc.). This would be for simplicity of implementation and basic functionality. Later I would consider implementing secondary keys which would be implemented as databases storing only the key value and the record number. Since records are of fixed size, sorting them would be trivial, but only the secondary keys would provide this option because you want the record number of the main file to be reliable and invariant. SQL seems like a poor fit to D. At some point one might consider a fancier front end to the database that would allow indirections, but that's a whole can of worms, with threats of multiple copies that have different values for items that started out pointing to the same variable. On 01/04/2016 12:39 PM, Andrei Alexandrescu via Digitalmars-d wrote: On 01/04/2016 01:28 PM, Russel Winder via Digitalmars-d wrote: Rusts macros show it can be done well. Do you have a few examples handy? Thanks. -- Andrei
Re: Wishlist for D
On 12/14/2015 01:27 PM, tsbockman via Digitalmars-d wrote: On Sunday, 13 December 2015 at 11:25:37 UTC, Ola Fosheim Grøstad wrote: On Sunday, 13 December 2015 at 11:18:31 UTC, Robert burner Schadek wrote: On Saturday, 12 December 2015 at 22:57:55 UTC, Ola Fosheim Grøstad wrote: 2. Debug-mode testing of integer overflow. https://github.com/D-Programming-Language/phobos/pull/3389 I know, but that does not help when one are debugging code that doesn't use it. I have spent a lot of time trying to design the best checked integer type possible for Phobos, and I intend to finish the job (hopefully soon). Nevertheless, I fully agree with Ola: compiler support (similar to how array bounds checking is handled already) would be much better than any library solution could be. Doing it right would also be a fundamental breaking change, though, so this will have to wait for a hypothetical D3. It wouldn't need to be a breaking change if checked integer were a separate type series, as the unsigned series is. The types could be called "cint" etc. I expect that they would incur significant overhead, as I don't think there is hardware support for checked integers, and as such the current types would need to be maintained.
Re: Wishlist for D
A "batteries included" extension to phobos modeled after the Python modules. Esp. I'd like a standard linkage to Sqlite via D rather than C, but I'm sure that other have other most desired libraries. Additionally, I'd like fewer language changes. D is a great language now, and changes, while interesting, are (for my purposes) of at best dubious value. (Bug fixes, of course, is a different matter.) OTOH, I am usually not interested in compile time enhancement, but only in execution time enhancements. E.g., I generally find that using ranges is both less intelligible and less flexible than using indexed access. (I originally hoped that foreach would be to allow parallel execution, as that was the only use I could see for it. Now I'll occasionally use it, but I so often need to iterate over multiple arrays that I use indexing much more often.) On 12/01/2015 08:43 AM, Ozan via Digitalmars-d wrote: Hi We all have experience with several programming languages and the great ideas implemented there. It is close to Xmas and I think the right time for wishes about future functions in D. Where is right place to put these inspirations on? Shall we send them directly to the D Foundation presidents? The Secretary? A central mailbox? Regards, Ozan
Re: Wishlist for D
On 12/12/2015 03:47 PM, Jack Stouffer via Digitalmars-d wrote: On Saturday, 12 December 2015 at 19:55:27 UTC, Charles Hixson wrote: Now I'll occasionally use it, but I so often need to iterate over multiple arrays that I use indexing much more often Why not use foreach(ref a, ref b, ref c; lockstep(array1, array2, array3)) ? Because indexing is easier, more intelligible, and less error prone.
Re: error detected at """ ch in unicode.C """ Library error?
On 10/23/2015 04:33 AM, rumbu via Digitalmars-d-learn wrote: My opinion is to use the Tango's unicodedata.d module to obtain the unicode category, std.uni does not provide such functionality. This module does not have any dependency, therefore you can just use it directly: https://github.com/SiegeLord/Tango-D2/blob/d2port/tango/text/UnicodeData.d#L169 Thank you for confirming that std.uni doesn't implement that functionality, and for pointing to a Tango source. That's probably the one I was originally remembering, but is Tango even still being maintained? (OK, this very module was last updated 3 days ago.) FWIW, in the past I've had a lot of trouble syncing Tango and D, to the point that I just dropped Tango, but as you say, this module doesn't seem to have any external dependencies, and it would be a faster solution to the problem, and perhaps it would work on the various control chars. Still, I don't use this for heavy processing, so maintaining this external dependency would likely be more effort than it is worth...as long as I don't need to handle exotic chars in the control range. If speed were my main consideration, I'd certainly give that solution a try. The benefit of the solution that I proposed is that it's easy to understand given the phobos library. And if I actually needed to handle exotic control chars, then it would be the only option I've seen. However the text I'm handling is *almost* all ASCII, so ... (occasional German, occasional footnotes in Greek, and occasional and usually isolated single ideograms in Chinese or some Japanese script, etc. I don't think I've run across any Sanskrit yet. etc.) As such the solution I proposed is probably good enough, though if there were a Phobos level solution I'd prefer that.
Re: error detected at """ ch in unicode.C """ Library error?
On 10/21/2015 06:21 PM, Charles Hixson via Digitalmars-d-learn wrote: To me this looks like a library error, but I'm not sure. Any suggestions importstd.uni; chargcCat1(dchar ch) { if(ch in unicode.L)return'L';// Letter if(ch in unicode.M)return'M';// Mask if(ch in unicode.C)return'C';// Control <<== error here! if(ch in unicode.N)return'N';// Numeric if(ch in unicode.P)return'P';// Punctuation if(ch in unicode.S)return'S';// Symbol if(ch in unicode.Z)return'Z';// Separator return'?'; } $ rdmd --main -unittest test2.d /usr/include/dmd/phobos/std/uni.d(6220): Error: slice [0..2] exceeds array bounds [0..1] /usr/include/dmd/phobos/std/uni.d(6220):called from here: comparePropertyName(name[0..2], "In") /usr/include/dmd/phobos/std/uni.d(6119):called from here: findAny("C") /usr/include/dmd/phobos/std/uni.d(6122): Error: static assert "No unicode set by name C was found." test2.d(7):instantiated from here: opDispatch!"C" Failed: ["dmd", "-unittest", "-v", "-o-", "test2.d", "-I."] $ dmd DMD64 D Compiler v2.068.2 Copyright (c) 1999-2015 by Digital Mars written by Walter Bright Documentation: http://dlang.org/ Config file: /etc/dmd.conf ... Here is a routine for general character category that works except for control characters, which appear to be mishandled by the library. (If there's another explanation, I'd like to hear it.) Note: The unittests are excessively verbose, but the way to silence them is pretty obvious, except in the cases that fail. This is NOT a comprehensive unittest, so there may be errors not currently detected. Also, if there's a better way to do this, I'd like to hear it. import std.uni; /** Return a character approximately equivalent to the first character *of the Unicode General Category Classification. * Warning: This method has been specialized for English and related * languages. (That's what category Q is about. It has also been * adapted to consider the characters often used in SSI#s, phone #s, * dates, and times as embeddable.) * Returns: L, Z, C, Q, P, or ?. Q is for embeddable chars. Numeric has *been combined with Alpha, and ? is not otherwise classifiable. */ char charCat (dchar ch) { if (isAlpha (ch) ) return 'L'; if (isNumber (ch) )return 'L'; // I don't want to distinguish between letters and numbers if (isWhite (ch) ) return 'Z'; if (isControl (ch) ) return 'C'; // if ("'-+.,@/’‘:/".indexOf (ch) >= 0) return 'Q'; // Not a unicode grouping if (isPunctuation (ch) ) return 'P'; else return '?'; // Includes not a character } char gcCat1 (dchar ch) { if (ch in unicode.L)return 'L'; // Letter if (ch in unicode.M)return 'M'; // Mask // if (ch in unicode.C)return 'C'; // Control if (isControl(ch) ) return 'C'; // Control if (ch in unicode.N)return 'N'; // Numeric if (ch in unicode.P)return 'P'; // Punctuation if (ch in unicode.S)return 'S'; // Symbol if (ch in unicode.Z)return 'Z'; // Separator return '?'; } /** Get the two letter general character category. */ string gcCat2 (dchar ch) { char kind = gcCat1(ch); switch (kind) { case 'C': // C Other //CcControl if (ch in unicode.Cc) return "Cc"; // CfFormat if (ch in unicode.Cf) return "Cf"; // CnUnassigned if (ch in unicode.Cn) return "Cn"; // CoPrivate_Use if (ch in unicode.Co) return "Co"; // CsSurrogate if (ch in unicode.Cs) return "Cs"; // Unexpected value return "C?"; case 'L': // L Letter // LlLowercase_Letter if (ch in unicode.Ll) return "Ll"; // LmModifier_Letter if (ch in unicode.Lm) return "Lm"; // LoOther_Letter if (ch in unicode.Lo) return "Lo"; // LtTitlecase_Letter if (ch in unicode.Lt) return "Lt"; // LuUppercase_Letter if (ch in unicode.Lu) return "Lu"; // Unexpected Letter return "L?"; case 'M': // M Mark // McSpacing_Mark if (ch in unicode.Mc) return "Mc"; // MeEnclo
Re: std.uni general character category
On 10/20/2015 10:38 AM, Charles Hixson via Digitalmars-d-learn wrote: In std.uni (D Lib 2.068.2) I can no longer see how to get the general category code for a character. Does anyone know what the currently supported way to do that is? I thought I remembered that I used to be able to directly get the general character category, but as a crutch this is what I'm using (and checking back to 2012 I apparently couldn't do better then): charcharCat (dchar ch) { if(isAlpha (ch) )return'L'; if(isNumber (ch) )return'N'; if(isWhite (ch) )return'Z'; if(isControl (ch) ) return'C'; if(isPunctuation (ch) ) return'P'; else return'?';// Includes not a character } This suffices for my current needs, but it clearly a lot less information than the two letter code would be, and sometimes that's what I need.
error detected at """ ch in unicode.C """ Library error?
To me this looks like a library error, but I'm not sure. Any suggestions importstd.uni; chargcCat1(dchar ch) { if(ch in unicode.L)return'L';//Letter if(ch in unicode.M)return'M';//Mask if(ch in unicode.C)return'C';// Control <<== error here! if(ch in unicode.N)return'N';// Numeric if(ch in unicode.P)return'P';// Punctuation if(ch in unicode.S)return'S';// Symbol if(ch in unicode.Z)return'Z';// Separator return'?'; } $ rdmd --main -unittest test2.d /usr/include/dmd/phobos/std/uni.d(6220): Error: slice [0..2] exceeds array bounds [0..1] /usr/include/dmd/phobos/std/uni.d(6220):called from here: comparePropertyName(name[0..2], "In") /usr/include/dmd/phobos/std/uni.d(6119):called from here: findAny("C") /usr/include/dmd/phobos/std/uni.d(6122): Error: static assert "No unicode set by name C was found." test2.d(7):instantiated from here: opDispatch!"C" Failed: ["dmd", "-unittest", "-v", "-o-", "test2.d", "-I."] $ dmd DMD64 D Compiler v2.068.2 Copyright (c) 1999-2015 by Digital Mars written by Walter Bright Documentation: http://dlang.org/ Config file: /etc/dmd.conf ...
std.uni general character category
In std.uni (D Lib 2.068.2) I can no longer see how to get the general category code for a character. Does anyone know what the currently supported way to do that is?
Re: Replacement of std.stream
On Monday, 29 June 2015 at 12:00:14 UTC, Jonathan M Davis wrote: On Sunday, June 28, 2015 11:14:57 Baz via Digitalmars-d-learn wrote: On Sunday, 28 June 2015 at 05:04:48 UTC, DlangLearner wrote: I will convert a Java program into D. The original Java code is based on the class RandomeAccessFile which essentially defines a set of methods for read/write Int/Long/Float/String etc. The module std.stream seems to be a good fit for this job, but in its documentation, it is marked deprecated. So I'd like to know what is the replacement for this module. If I don't use this module, what is the other apporach I should use. Thanks for help. You can use std.stream. There is no candidate to replace it. Even if tomorrow someone comes with one, it has to be reviewed, accepted in std.experimental and after a while it would totally replace the old one. I think it's safe to say that std.stream will exist for at least 2 years in its current shape. No. It was decided at dconf that it was going to be deprecated and then removed within a relatively short period of time. In fact, it would have been deprecated with the next release, but there was a problem with the deprecation and the ddoc build, so the deprecation was temporarily reverted. But once that's sorted out, it's going to be deprecated, and it won't be around much longer at all. We decided that it was worse to leave it in saying that it was going to be replaced without having come up with anything for years than to leave it in. And given that std.stream rarely even comes up in discussions and that no one has proposed a replacement, Andrei thinks that it's a sign that there really isn't much demand for it anyway. For the most part, simply using std.stdio.File or std.mmfile.MmFile with ranges does what streams need to do just fine. Maybe someone will come up with a replacement for std.stream eventually, but there really doesn't seem to be much call for it. Regardless, until someone comes up with a replacement, we're simply not going have a stream-based I/O (though ranges are close - which is part of why no one has felt the need to replace std.stream strongly enough to actually do it). - Jonathan M Davis The documentation of std.mmfile.MmFile makes it an unacceptable replacement for std.stream. I can't even tell if it's features are missing, or just unintelligible. It rather looks as if you need to have enough RAM to hold the entire file in memory at once, but I'm not even sure of that. Perhaps this is just a documentation problem. Perhaps. But it's certainly a real problem. std.stdio.File is a much more reasonable substitute, but the documentation needs to be improved...probably lifted into a major heading, perhaps std.stdFile or some such. And examples. As it is it's buried where it gets overlooked...of course, that would tend to break any code that depended on using it is where it is now, so this should be done quickly, or this will end up being a continuing problem. (Even as it is, much of my code will stop compiling when this change is finalized, as I have used std.stream most of the time for years, not knowing of any alternative.)