Re: Is there a more elegant way to do this?
On Sunday, 12 March 2017 at 05:13:41 UTC, bauss wrote: I was wondering if there's a more elegant way to do something like this? template BitSize(T) { enum BitSize = T.sizeof * 8; } struct Data(ParentType,ChildType) { @property { ChildType low() { return cast(ChildType)value; } void low(ChildType lowValue) { value = ((high << (BitSize!ParentType / 2)) | lowValue); } ChildType high() { return cast(ChildType)(value >> (BitSize!ParentType / 2)); } void high(ChildType highValue) { value = ((highValue << 16 | low)); } } ParentType value; alias value this; } Example usage: void main() { Data!(uint,ushort) data; data = 14065735; writefln("low: %s high: %s", data.low, data.high); data.low = 41031 ; data.high = 214; writefln("value: %s", data.value); } Basically to explain what it is: You give it a parent-type and a corresponding child-type. Ex. if the parent-type is uint, the child-type would be ushort. if the parent-type is long, the child-type would be int. etc. What it allows you to is to either manipulate the data as the parent-type or as two values of the child type. I was just wondering if there's a more elegant or performant way to do this, perhaps something in Phobos exist already? template HalfSize(T) { static if (T==long) alias HalfSize == int; // repeat for all combos } struct Data(T) { union { T value; struct { version(LittleEndian) { HalfSize!T low; HalfSize!T high; } version(BigEndian) { HalfSize!T low; HalfSize!T high; } } } alias value this; }
Re: Is there a more elegant way to do this?
On Sunday, 12 March 2017 at 05:13:41 UTC, bauss wrote: I was wondering if there's a more elegant way to do something like this? [...] I saw one improvement to it which would be BitSize!ChildType instead of taking parent type's bit size divided by two. Also value = ((highValue << 16 | low)); Is supposed to be value = ((highValue << BitSize!ChildType | low));
Is there a more elegant way to do this?
I was wondering if there's a more elegant way to do something like this? template BitSize(T) { enum BitSize = T.sizeof * 8; } struct Data(ParentType,ChildType) { @property { ChildType low() { return cast(ChildType)value; } void low(ChildType lowValue) { value = ((high << (BitSize!ParentType / 2)) | lowValue); } ChildType high() { return cast(ChildType)(value >> (BitSize!ParentType / 2)); } void high(ChildType highValue) { value = ((highValue << 16 | low)); } } ParentType value; alias value this; } Example usage: void main() { Data!(uint,ushort) data; data = 14065735; writefln("low: %s high: %s", data.low, data.high); data.low = 41031 ; data.high = 214; writefln("value: %s", data.value); } Basically to explain what it is: You give it a parent-type and a corresponding child-type. Ex. if the parent-type is uint, the child-type would be ushort. if the parent-type is long, the child-type would be int. etc. What it allows you to is to either manipulate the data as the parent-type or as two values of the child type. I was just wondering if there's a more elegant or performant way to do this, perhaps something in Phobos exist already?
[Issue 16210] std.utf.byUTF can be made into a bidirectional range
https://issues.dlang.org/show_bug.cgi?id=16210 --- Comment #2 from Jack Stouffer--- (In reply to Jakub Łabaj from comment #1) > Assuming "ö" == [0xC3, 0xB6], which one version would be correct: > a) behaviour of std.utf.byCodeUnit, just go by code units backward: > "ö".byUTF!char().back == 0xB6 > > b) decode the character and return its first code unit: > "ö".byUTF!char().back == 0xC3 > > Personally I thought the b) version is desired (docs says that byUTF encodes > input), but at the moment it passes some inputs to byCodeUnit - it means for > some ranges byUTF is bidirectional already and version a) applies. Well damn. IMO B is more intuitive in all situations, so byUTF returning by byCodeUnit isn't want we really want. But because we can't break code, we would have to have B be the behavior only when some encoding has to be done inside of byUTF and clearly document this odd behavior. --
Re: C interface provides a pointer and a length... wrap without copying?
On Sunday, March 12, 2017 02:47:19 cy via Digitalmars-d-learn wrote: > On Saturday, 11 March 2017 at 23:43:54 UTC, Nicholas Wilson wrote: > > A string *is* a pointer length pair, an immutable(char)[]. > > Yes, but surely there's some silly requirement, like that the > pointer must only ever point to garbage collected memory, or > something? No. A dynamic array is just a struct with a pointer and a length. Aside from avoiding accessing memory that is no longer valid or avoiding allocations, it doesn't matter one whit what memory it points to. char[5] a; char[] b = a; is perfectly valid as is slicing memory that comes from malloc or some other crazy place. Most dynamic array operations don't even need to care about what memory they refer to. If you access an element, it does the math and dereferences it like you'd get with naked pointer arithmetic. The difference is that it also does bounds checking for you, because it knows the length. If you slice the array, then you just get an array with an adjusted pointer and/or length. The only times that the GC gets involved are when doing anything involving appending. If you call capacity, reserve, or ~=, then the GC gets involved. In those cases, the GC looks at the pointer to determine whether it can append. If it finds that it's GC-allocated memory, then it will look to see what room there is in the GC-allocated block after the array. If you're calling capacity, it will just return how large the array can grow to without being reallocated. If you're calling reserve or ~= it checks to see whether the capacity is great enough to grow into that space. If not, it will allocate a new block of memory, copy the array's elements into that, and set the array to point to it. In the case of ~=, it will also grow the array into that memory and put the new elements in it, whereas in the case of reserve, it just does the reallocation. If there was enough space, then ~= will just expand the array into that space without reallocating, and reserve will do nothing. If you have a dynamic array that was not allocated by the GC (be it a slice of a static array or malloc-ed memory or whatever), then its capacity will be 0. So, capacity will tell you 0, and ~= and reserve will always result in the array being reallocated. I would suggest that you read this excellent article: http://dlang.org/d-array-article.html though I would point out that it uses the wrong terminology in that it refers to the GC-allocated buffer as the dynamic array rather than T[], and it refers to T[] as a slice, whereas the official terminology is that T[] is the dynamic array and that buffer doesn't have an official name, and while T[] _is_ a slice of memory (assuming that it's not null), slice refers to a lot of other stuff in D (e.g. slicing a container gives you range over that container, so it's a slice of the container, but it's not T[]). And your use case here is a perfect example of why T[] is the dynamic array and not the GC-allocated buffer. Dynamic arrays simply don't care about the memory that they refer to, because they don't manage their own memory. ~=, reserve, and capacity do care about what memory a dynamic array refers to, but they work exactly the same way regardless of what the dynamic array refers to. It's just a question of when reallocations do or do not occur. The big concern with slicing static arrays or malloc-ed memory to get a dynamic array is that it's then up to you to ensure that that dynamic array does not outlive the memory that it refers to. So, there is some danger there, but that's no different from operating on raw pointers, and operating on dynamic arrays gives better safety thanks to bounds-checking, and it also works with appending, though that will cause the dynamic array to then refer to GC-allocated memory instead of the original memory. - Jonathan M Davis
ranges of characters and the overabundance of traits that go with them
Okay, I'm sorry, but this is a wall of text, and I don't know how to actually make it short. If you really want the TLDR version, look for the =='s at the bottom which mark off the conclusion, but you're not going to understand the reasoning if you skip the wall of text. Now, to the post... Recently, there was a PR submitted for Phobos which tried to add isStringLike to std.traits. There was some debate about what the name should be, but ultimately, Walter pointed out that we really needed to step back and examine all of the various traits that we have for strings and related types in Phobos before we add anything like this, regardless of the name. So, I've been mulling over this and looking at the current situation and thought I should post about it. The PR in question: https://github.com/dlang/phobos/pull/5137 First off, I think that the concept of anything "string-like" should be tabled for now. String-like implies that it acts like a string and is therefore at least attempting to be a drop-in replacement. Nothing in Phobos currently tries to do that, and I think that discussions on that sort of thing are better left for when we look at adding something like Andrei's RCString to druntime or Phobos. What we're concerned with at the moment is how strings, things that convert to strings, and ranges of characters are dealt with in templated code. The first thing to notice when when looking at strings and traits in Phobos is that we have too many traits that are very similiar but not quite the same. Each of them was added over time to solve a particular problem that the existing traits didn't solve well enough or simply because it was a concept that the submitter thought was one that we'd need to reuse. The result is a mish-mash of traits with varying - and often confusing uses. We have isSomeString, isNarrowString, isAutodecodableString, and isConvertibleToString. And of course, related to those, we have isSomeChar, ElementType, ElementEncodingType, isDynamicArray, isInputRange, isForwardRange, isBidirectionalRange, isRandomAccessRange, hasSlicing, isDynamicArray, isAggregateType, isStaticArray, is(T == enum), is(T : const char[]), etc. all of which can be used in combination with or instead of the main string traits. Exactly which combination of all of those traits get used depends on what the function in question is trying to do, and they're often used inconsistently. But I think that the main concern is the various is*String traits. So, isSomeString: True for any dynamic array of any character type as well as any enum type whose base type is a dynamic array of any character type. isNarrowString: The same as isSomeString except that arrays of dchar and enum types with a base type that's a dynamic array of dchar do not qualify as narrow strings. isAutodecodableString: The same as isNarrowString except that it also accepts user-defined types which implicitly convert to a dynamic array of char or wchar. isConvertibleToString: Any type that is _not_ a dynamic array of characters but implicitly converts to a dynamic array of characters - so enums with that as their base type, user-defined types which implicitly convert to such dynamic arrays, and static arrays which implicitly convert to such dynamic arrays. Note that these are all similar but subtly different. Of particular note is how this affects implicit conversions. Implicit conversions in generic code are _bad_. It's trivial for a type to pass a template constraint due to an implicit conversion and then not actually compile with the template - or worse, to compile but have subtly wrong behavior. So, pretty much any time that an implicit conversion is allowed with a template constraint, that conversion needs to be forced. Once it's converted, then it can function as the targetted type, because it _is_ the targetted type. Honestly, I'm inclined to think that in most cases that conversion should be done explicitly by the programmer rather than happening automatically, because that's far less error-prone (e.g. this is what we do when we require that you slice a static array to pass it to a range-based function rather than having the range-based function do it for you). Unfortunately, that's not always an option - e.g. when templatizing a function that previously accepted string, if you don't want to break code, then you have to accept anything that implicitly converts to string. So, the first mistake here is that isSomeString accepts enums. Annoyingly, that was actually my fault (Kenji actually fixed isSomeString years ago, and at the time, I argued that it should accept enums, which in hindsight, was dumb of me). :( In some cases, having a templated function accept both strings and enums _can_ work, but in most cases, it's going to be wrong. You can examine an enum with a base type of string, but you can't mutate it or assign it without risking either not compiling or ending up with a variable of an enum type with an invalid value, and enums
Re: C interface provides a pointer and a length... wrap without copying?
cy wrote: On Saturday, 11 March 2017 at 23:43:54 UTC, Nicholas Wilson wrote: A string *is* a pointer length pair, an immutable(char)[]. Yes, but surely there's some silly requirement, like that the pointer must only ever point to garbage collected memory, or something? why should it? a slice can point anywhere, and GC is smart enough to know what memory it owns and what it isn't. if you'll try to append something to non-GC-owned slice, GC will make a copy first. so the only requirement is: "don't use `~=` on it if you don't want to have a memory leak".
Re: C interface provides a pointer and a length... wrap without copying?
On Saturday, 11 March 2017 at 23:43:54 UTC, Nicholas Wilson wrote: A string *is* a pointer length pair, an immutable(char)[]. Yes, but surely there's some silly requirement, like that the pointer must only ever point to garbage collected memory, or something? ubyte[] arr; // or byte/char whatever is the pointed to type returned by giveMeTheMemory arr = giveMeTheMemory()[0 .. getMeTheLength()]; ...guess not! :D
Re: I think is a bug?
On Sunday, 12 March 2017 at 01:55:20 UTC, ketmar wrote: Random D user wrote: How come string* suddenly has a .length property? due to automatic pointer dereferencing that `.` does. no, not a bug. Ah... right. Silly me. Of course, since string is actually immutable(char)[]. That's bit of a nasty corner case where -> == . isn't that nice. Fortunately, it's rare. Thanks. This happened to me, when I was packing stuff into SoA layout and didn't want to duplicate the length in the struct (implicitly by using []). Of course, I forgot to update one place to use the shared length. That is: length ptr ptr ptr instead of ptr length ptr length ptr length Perhaps I should do a SoA layout template that somehow disables .length on individual arrays.
Re: I think is a bug?
Random D user wrote: How come string* suddenly has a .length property? due to automatic pointer dereferencing that `.` does. no, not a bug.
I think is a bug?
int*[] foo; foo.length = 5; import std.c.string; int* baz = cast(string*)malloc(50); import std.c.stdio; printf("%d %d", foo.length, baz.length ); prints: Error: no property 'length' for type 'int*' BUT: string*[] foo; foo.length = 5; import std.c.string; string* baz = cast(string*)malloc(50); import std.c.stdio; printf("%d %d", foo.length, baz.length ); compiles and prints: 5 -842150451 How come string* suddenly has a .length property? Anyway the result is garbage, so I think this must be a bug. DMD32 D Compiler v2.073.2
Re: DMD win32.mak error
On Saturday, 11 March 2017 at 18:02:00 UTC, Stefan Koch wrote: On Saturday, 11 March 2017 at 02:25:15 UTC, Paul D Anderson wrote: On Saturday, 11 March 2017 at 00:34:03 UTC, Paul D Anderson wrote: On Friday, 10 March 2017 at 22:04:23 UTC, Paul D Anderson wrote: [...] I see John Colvin has already filed a bug report (issue 17165) addressing this. Apparently the missing file is available on GitHub. I copied the missing file John referenced to my src/dmd file but this did not have any effect. I've created a bug report (17253) addressing this problem. Paul verstring is created automatically I think the problem is a failure in the process of creating verstring. The missing file is "dmd/res/default_ddoc_theme/ddoc"
Re: C interface provides a pointer and a length... wrap without copying?
On Saturday, 11 March 2017 at 22:39:02 UTC, cy wrote: So a lovely C library does its own opaque allocation, and provides access to the malloc'd memory, and that memory's length. Instead of copying the results into garbage collected memory (which would probably be smart) I was thinking about creating a structure like: struct WrappedString { byte* ptr; size_t length; } And then implementing opIndex for it, and opEquals for all the different string types, and conversions to those types, and then it occurred to me that this sounds like a lot of work. Has anybody done this already? Made a pointer/length pair, that acts like a string? A string *is* a pointer length pair, an immutable(char)[]. Your `WrappedString` is effectively a byte[]. All you need to do is: ubyte[] arr; // or byte/char whatever is the pointed to type returned by giveMeTheMemory arr = giveMeTheMemory()[0 .. getMeTheLength()]; No need to reimplement anything.
Re: Better ddoc defaults?
On Saturday, 11 March 2017 at 09:54:25 UTC, Yuxuan Shui wrote: On Friday, 10 March 2017 at 07:58:36 UTC, Petar Kirov [ZombineDev] wrote: On Thursday, 9 March 2017 at 21:08:17 UTC, Yuxuan Shui wrote: [...] My favorite one is: https://github.com/MartinNowak/scod. BTW, the default ddox (the one that comes with dub) is getting an upgrade soon: https://github.com/rejectedsoftware/ddox/pull/149 https://github.com/rejectedsoftware/ddox/pull/150. I tried ddox, and it worked pretty well. Only problem is that, ddox uses the json output of dmd, which is different from dmd -D result. dmd -D will include the then-branch of static-ifs and version blocks that's been compiled in, but the json output doesn't. Is this by design? Or can we make the json output consistent with the ddoc output? I opened a PR for this: https://github.com/dlang/dmd/pull/6621
Dub and bindings
Are there any general tips or best practices for bindings in dub packages? For example, I love the d2sqlite3 package. It just works out of the box. No linker configuration or anything. However, that is probably a testament to sqlite's lack of dependencies. That cannot work for libraries, which rely on other libraries. Should the C code be included in the Github repo? Are submodules fine? Should the C build be invoked by dub via "preBuildCommands"? What about system libraries? Can that be made cross-platform? Should lflags be specified in the dub config or should they be passed via environment variable? There should be a general guide for this. Maybe there already is one?
Re: C interface provides a pointer and a length... wrap without copying?
cy wrote: So a lovely C library does its own opaque allocation, and provides access to the malloc'd memory, and that memory's length. Instead of copying the results into garbage collected memory (which would probably be smart) I was thinking about creating a structure like: struct WrappedString { byte* ptr; size_t length; } And then implementing opIndex for it, and opEquals for all the different string types, and conversions to those types, and then it occurred to me that this sounds like a lot of work. Has anybody done this already? Made a pointer/length pair, that acts like a string? yep, it was done before. int* a = cast(int*)malloc(1024); auto b = a[0..1024]; // yay, b is just an ordinary slice now!
C interface provides a pointer and a length... wrap without copying?
So a lovely C library does its own opaque allocation, and provides access to the malloc'd memory, and that memory's length. Instead of copying the results into garbage collected memory (which would probably be smart) I was thinking about creating a structure like: struct WrappedString { byte* ptr; size_t length; } And then implementing opIndex for it, and opEquals for all the different string types, and conversions to those types, and then it occurred to me that this sounds like a lot of work. Has anybody done this already? Made a pointer/length pair, that acts like a string?
Re: Zcoin implementation bug enabled attacker to create 548, 000 Zcoins
On 11.03.2017 20:39, H. S. Teoh via Digitalmars-d wrote: On Sat, Mar 11, 2017 at 01:46:31PM +0100, Timon Gehr via Digitalmars-d wrote: On 10.03.2017 23:41, H. S. Teoh via Digitalmars-d wrote: Basically, operator syntax is just too specific to the arithmetical meanings of the operators that overloading them to mean something else seems like just asking for trouble. OTOH, restricting how operators can be overloaded means they cannot be used for symbolic mathematics, which is annoying. I think you misunderstand my intent. I'm not disagreeing with your point, I'm just adding that the language should not necessarily attempt to enforce it. By "arithmetical meanings" I meant any meanings to which mathematics may assign to said operators, so using "x + y" for vector addition, for example, is fair game. And perhaps even field addition for general fields. But using "x + y" for division is abusive, for example, and so is using "+" for appending to a file. But in any case, this isn't something that's enforceable. Deciding whether an implementation of an overload of "+" is "addition-like" is probably undecidable. It's the same with "<=", and the current approach has false negatives. It's just bad practice to use "+" for something that someone reading the code wouldn't expect. The bottom line is really readability and maintainability than anything else. T This is not really specific to operators at all though. The general point is that functions should be named reasonably.
[Issue 16210] std.utf.byUTF can be made into a bidirectional range
https://issues.dlang.org/show_bug.cgi?id=16210 Jakub Łabajchanged: What|Removed |Added CC||uaaabbj...@gmail.com --- Comment #1 from Jakub Łabaj --- Assuming "ö" == [0xC3, 0xB6], which one version would be correct: a) behaviour of std.utf.byCodeUnit, just go by code units backward: "ö".byUTF!char().back == 0xB6 b) decode the character and return its first code unit: "ö".byUTF!char().back == 0xC3 Personally I thought the b) version is desired (docs says that byUTF encodes input), but at the moment it passes some inputs to byCodeUnit - it means for some ranges byUTF is bidirectional already and version a) applies. --
Re: How to debug D programs
On Monday, 8 August 2016 at 10:36:39 UTC, eugene wrote: Hello, everyone, question to you: how do you debug D programs on gnu/linux? and what ides are you using for debugging? I'm using emacs, it has great integration with gdb.
Re: Zcoin implementation bug enabled attacker to create 548, 000 Zcoins
On Friday, 10 March 2017 at 22:41:43 UTC, H. S. Teoh wrote: The problem is that "<<" was designed to be a bit-shift operator, and as such it has a specific precedence level in the hierarchy of operators. Fair point. IIRC Algol68 allowed custom precedence levels. Found this: http://www.kestrel.edu/home/people/meertens/publications/papers/Operator-Priority_Grammar_for_ALGOL_68+.pdf At the other end of the spectrum Pony requires explicit parens for operators outside the most familiar ones ("+", "-", "*"...).
Re: Can you fix this code to avoid using pointers?
On Saturday, 11 March 2017 at 19:15:59 UTC, H. S. Teoh wrote: What about just: foreach (const ref p; [in1, in2, in3, in4]) I would think there will be already one copy from the local parameter variables to the in situ array. Then from that one into the for each element it's ref'd all right. But I'm afk and can't test. Like the other copy I missed and Adam spotted when passing the arguments with missing ref qualifiers.. I realized that the code that sparked the question made no sense and should be done in a different way... As is always the case when these questions come up. But I still like the version with pointers ;)
[Issue 13619] std.container.array capacity not updated when length increases
https://issues.dlang.org/show_bug.cgi?id=13619 github-bugzi...@puremagic.com changed: What|Removed |Added Status|NEW |RESOLVED Resolution|--- |FIXED --
[Issue 13619] std.container.array capacity not updated when length increases
https://issues.dlang.org/show_bug.cgi?id=13619 --- Comment #5 from github-bugzi...@puremagic.com --- Commits pushed to master at https://github.com/dlang/phobos https://github.com/dlang/phobos/commit/8ba7ce59ba4bbeb1e7f45fb34ecff2a02930aad9 Fix issue 13619 - array capacity not updated when changing length https://github.com/dlang/phobos/commit/9872247505c8a62e87bb97010084406c051eed2f Merge pull request #5267 from byebye/issue_13619 Fix issue 13619 - array capacity not updated when changing length merged-on-behalf-of: Jack Stouffer--
Re: CTFE Status 2
On Sat, Mar 11, 2017 at 02:39:54PM +, Stefan Koch via Digitalmars-d wrote: [...] > Contrary to the old interpreter no copies are made. > newCTFE slices reference memory just as runtime slices do. [...] Awesome! This alone ought to greatly expand the scope of what's feasible in CTFE. Now I really can't wait to see this merged into master. :-) T -- English has the lovely word "defenestrate", meaning "to execute by throwing someone out a window", or more recently "to remove Windows from a computer and replace it with something useful". :-) -- John Cowan
Re: Zcoin implementation bug enabled attacker to create 548, 000 Zcoins
On Sat, Mar 11, 2017 at 01:46:31PM +0100, Timon Gehr via Digitalmars-d wrote: > On 10.03.2017 23:41, H. S. Teoh via Digitalmars-d wrote: > > > > Basically, operator syntax is just too specific to the arithmetical > > meanings of the operators that overloading them to mean something > > else seems like just asking for trouble. > > OTOH, restricting how operators can be overloaded means they cannot be > used for symbolic mathematics, which is annoying. I think you misunderstand my intent. By "arithmetical meanings" I meant any meanings to which mathematics may assign to said operators, so using "x + y" for vector addition, for example, is fair game. And perhaps even field addition for general fields. But using "x + y" for division is abusive, for example, and so is using "+" for appending to a file. But in any case, this isn't something that's enforceable. Deciding whether an implementation of an overload of "+" is "addition-like" is probably undecidable. It's just bad practice to use "+" for something that someone reading the code wouldn't expect. The bottom line is really readability and maintainability than anything else. T -- My program has no bugs! Only unintentional features...
Re: Zcoin implementation bug enabled attacker to create 548, 000 Zcoins
On Sat, Mar 11, 2017 at 03:03:30PM +, Nick Treleaven via Digitalmars-d wrote: > On Friday, 10 March 2017 at 19:02:06 UTC, H. S. Teoh wrote: > > A long-standing item on my todo list is to implement compile-time > > writefln format strings using this technique. > > Yes, the actual checking seems straightforward - here I implemented CT > format as an overload: > > import std.format : format; > > auto format(string fmt, A...)(A args) > { > static assert(__traits(compiles, {enum s = .format(fmt, A.init);}), > "Arguments do not match format string: '" ~ fmt ~ "' with " ~ > A.stringof); > return .format(fmt, args); > } > > unittest > { > auto s = format!"%s is %s"(5, "five"); > static assert(!__traits(compiles, {s = format!"%d"("four");})); > } Yes, that's the general idea of it. But I want to go further: to eliminate unnecessary dependencies of format() based on the contents of the format string. More specifically, currently calling format() will instantiate a whole bunch of stuff for typesetting *all* possible format strings, like floating-point, array expansion, etc.. That means a simple format("%s",s) will pull in a whole bunch of code into your executable that may not actually be used. (And not even LTO can get rid of it, because the code is inside if- or switch-statements, and technically is "referenced" by the caller; the linker has no way to know it won't actually get called.) Not to mention, "%s" itself pulls in a whole bunch of code for dealing with things like field width, max width, padding, etc. (i.e., to handle things like "%10s", "%10.5s", and so on), all of which isn't actually needed to implement plain ole "%s". So the idea is to analyse the format string at compile-time to determine exactly what functionality is actually used, and instantiate only that. Think of it as a format-string mini-compiler: given a format string and a list of argument types, compile it into the equivalent minimal D code. E.g.: format("abc%sdef", s) should get compiled into: "abc" ~ s ~ "def" // N.B.: no floating-point code, no // width handling, etc. and so on. T -- What doesn't kill me makes me stranger.
Re: Can you fix this code to avoid using pointers?
On Sat, Mar 11, 2017 at 12:45:10PM +, XavierAP via Digitalmars-d-learn wrote: > On Saturday, 11 March 2017 at 12:35:42 UTC, XavierAP wrote: > > I do not really think it's a bad solution, to check several scalar > > arguments that must obey the same condition; just wondering if you > > have better ideas. Try to avoid modifying the function's signature > > and defining custom types, unless you have a really terrific idea. > > > > void calc(double in1, double in2, double in3, double in4) > > in { > >foreach(const p; [, , , ]) > > enforce(*p > 0); > > } > > body { /* ... */ } > > Please imagine double is a type that I wanted to avoid copying, just > check by ref. Same question :p What about just: foreach (const ref p; [in1, in2, in3, in4]) ... ? T -- Stop staring at me like that! It's offens... no, you'll hurt your eyes!
Re: Any news on DIP88?
On Saturday, March 11, 2017 15:25:14 bauss via Digitalmars-d wrote: > Are there any news on DIP88? Will it be implemented?, when?, is > there an implementation currently in development or? > > https://wiki.dlang.org/DIP88 It has never been approved. and as mentioned on the main DIPs page on the wiki, there is a new DIP process (which attempts to solve the problem of DIPs being proposed and then going nowhere). So, for DIP 88 to be approved (or any other of the DIPs on the wiki that hasn't been approved), it would have to go through the new DIP process, and DIP 88 has not been submitted for review with the new DIP process. https://github.com/dlang/DIPs That being said, there have been multiple threads in this newsgroup about ways to have named arguments via templates in the language right now without making any language changes, and adding them to the language was already pretty controversial. So, I would expect that any DIP for it would be rejected on the grounds that it can already been done via a library solution without language changes, and it might also be rejected on the grounds that it would be undesirable to have it be built into the language (last I heard, Walter was against it; I don't know remember if I ever heard Andrei's opinion on the matter, but he favors library solutions over language ones regardless). So, if someone cares enough, they can propose a new DIP for named arguments, but I doubt that it would be accepted, and no one has made the attempt regardless, so it definitely hasn't been accepted as of now. - Jonathan M Davis
Re: Problem building DMD
On Saturday, 11 March 2017 at 17:54:55 UTC, ag0aep6g wrote: On 03/11/2017 06:41 PM, Eric wrote: I'm trying to build the master branch of DMD on redhat 7. I get the following errors: ddmd/root/newdelete.c:26:8: error: expected identifier or ‘(’ before string constant extern "C" ^ ddmd/root/newdelete.c:31:17: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘new’ void * operator new(size_t m_size) ^ ddmd/root/newdelete.c:36:15: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘delete’ void operator delete(void *p) Does anyone know what I am doing wrong? Looks like a C compiler is used instead of a C++ compiler. Despite the extension, dmd's *.c files are C++ code. Yes - I needed to install gcc-c++, not g++. That fixed everything.
Re: Problem building DMD
On Saturday, 11 March 2017 at 17:54:55 UTC, ag0aep6g wrote: Looks like a C compiler is used instead of a C++ compiler. Despite the extension, dmd's *.c files are C++ code. Yes, that's what I thought - redhat has gcc, but not g++. There must be a needed compile option...
Re: DMD win32.mak error
On Saturday, 11 March 2017 at 02:25:15 UTC, Paul D Anderson wrote: On Saturday, 11 March 2017 at 00:34:03 UTC, Paul D Anderson wrote: On Friday, 10 March 2017 at 22:04:23 UTC, Paul D Anderson wrote: While building DMD -- "make -fwin32.mak release" -- I received the following error message: echo "2.073.2" > verstr.h Error: don't know how to make '../res/default_ddoc_theme/ddoc' --- error level 1 I'm guessing it might be a build configuration problem on my end, but what is the problem? Paul I see John Colvin has already filed a bug report (issue 17165) addressing this. Apparently the missing file is available on GitHub. I copied the missing file John referenced to my src/dmd file but this did not have any effect. I've created a bug report (17253) addressing this problem. Paul verstring is created automatically
Re: Problem building DMD
On 03/11/2017 06:41 PM, Eric wrote: I'm trying to build the master branch of DMD on redhat 7. I get the following errors: ddmd/root/newdelete.c:26:8: error: expected identifier or ‘(’ before string constant extern "C" ^ ddmd/root/newdelete.c:31:17: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘new’ void * operator new(size_t m_size) ^ ddmd/root/newdelete.c:36:15: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘delete’ void operator delete(void *p) Does anyone know what I am doing wrong? Looks like a C compiler is used instead of a C++ compiler. Despite the extension, dmd's *.c files are C++ code.
Re: CTFE Status 2
On Saturday, 11 March 2017 at 17:38:04 UTC, Nordlöw wrote: On Saturday, 11 March 2017 at 14:39:54 UTC, Stefan Koch wrote: Basic Slicing support is in; The following code will now compile with the newCTFE_slicing branch: I guess this should greatly benefit compile-time parsing, right? As soon as the UTF8 stuff works properly, yes. Slicing is really just syntactic sugar :)
Problem building DMD
I'm trying to build the master branch of DMD on redhat 7. I get the following errors: ddmd/root/newdelete.c:26:8: error: expected identifier or ‘(’ before string constant extern "C" ^ ddmd/root/newdelete.c:31:17: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘new’ void * operator new(size_t m_size) ^ ddmd/root/newdelete.c:36:15: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘delete’ void operator delete(void *p) Does anyone know what I am doing wrong?
Re: CTFE Status 2
On Saturday, 11 March 2017 at 14:39:54 UTC, Stefan Koch wrote: Basic Slicing support is in; The following code will now compile with the newCTFE_slicing branch: I guess this should greatly benefit compile-time parsing, right?
Re: Rename 'D' to 'D++'
D•• :D
Any news on DIP88?
Are there any news on DIP88? Will it be implemented?, when?, is there an implementation currently in development or? https://wiki.dlang.org/DIP88
Re: Zcoin implementation bug enabled attacker to create 548, 000 Zcoins
On Friday, 10 March 2017 at 19:02:06 UTC, H. S. Teoh wrote: A long-standing item on my todo list is to implement compile-time writefln format strings using this technique. Yes, the actual checking seems straightforward - here I implemented CT format as an overload: import std.format : format; auto format(string fmt, A...)(A args) { static assert(__traits(compiles, {enum s = .format(fmt, A.init);}), "Arguments do not match format string: '" ~ fmt ~ "' with " ~ A.stringof); return .format(fmt, args); } unittest { auto s = format!"%s is %s"(5, "five"); static assert(!__traits(compiles, {s = format!"%d"("four");})); }
Re: Can you fix this code to avoid using pointers?
On Saturday, 11 March 2017 at 14:49:42 UTC, XavierAP wrote: But also I don't want to modify the function signature, certainly in this way. It is already copied by the time you get in to the function though because of the signature (unless they are constructed in-place at the call site). But you can also do an unrolled loop with AliasSeq http://dpldocs.info/experimental-docs/std.meta.AliasSeq.html import std.meta; import std.exception; void calc(double in1, double in2, double in3, double in4) in { foreach(ref item; AliasSeq!(in1, in2, in3, in4)) enforce(item > 0); } body { /* ... */ } Note that if the loop body is large, this could bloat the code slightly since a foreach over AliasSeq is always an unrolled loop. But that's probably irrelevant to you.
Re: Can you fix this code to avoid using pointers?
On Saturday, 11 March 2017 at 13:44:30 UTC, Satoshi wrote: void calc(in double[] array...) { foreach (x; array) { } } To do what I want it should be foreach(ref x; array) -- or const ref. But also I don't want to modify the function signature, certainly in this way. In another situation yes, but the arguments are very different magnitudes, for example temperatures, conductivity, heat power, etc. They should be separate arguments with self-documenting names. And it's not worth the bother to define a struct type for them as a set. Specially since this is an internal implementation "problem" that shouldn't affect the outer interface. I know there's something in std.algorithm for this, but afaik it would be relatively bloated compared to this pointer solution. In C++ I would use a instead of a *pointer, but I actually think C++ references are redundant with pointers, not much safer, and plain confusing. I guess it's a not a common case because if a type is non trivial to copy it should probably be a class, which is already assigned by reference so I wouldn't need the pointer/ref.
Re: CTFE Status 2
On Thursday, 16 February 2017 at 21:05:51 UTC, Stefan Koch wrote: [ ... ] Basic Slicing support is in; The following code will now compile with the newCTFE_slicing branch: static immutable uint[] OneToTen = [1,2,3,4,5,6,7,8,9,10]; const(uint[]) SliceOf1to10(uint lwr, uint upr) { return OneToTen[lwr .. upr]; } static assert(SliceOf1to10(2,8) == [3u, 4u, 5u, 6u, 7u, 8u]); Contrary to the old interpreter no copies are made. newCTFE slices reference memory just as runtime slices do. Cheers, Stefan;
Re: Can you fix this code to avoid using pointers?
On Saturday, 11 March 2017 at 12:35:42 UTC, XavierAP wrote: I do not really think it's a bad solution, to check several scalar arguments that must obey the same condition; just wondering if you have better ideas. Try to avoid modifying the function's signature and defining custom types, unless you have a really terrific idea. void calc(double in1, double in2, double in3, double in4) in { foreach(const p; [, , , ]) enforce(*p > 0); } body { /* ... */ } void calc(in double[] array...) { foreach (x; array) { } }
Re: Zcoin implementation bug enabled attacker to create 548, 000 Zcoins
On 11.03.2017 13:46, Timon Gehr wrote: On 10.03.2017 23:41, H. S. Teoh via Digitalmars-d wrote: Basically, operator syntax is just too specific to the arithmetical meanings of the operators that overloading them to mean something else seems like just asking for trouble. OTOH, restricting how operators can be overloaded means they cannot be used for symbolic mathematics, which is annoying. Example: https://scala-lms.github.io/
Re: Rename 'D' to 'D++'
On Saturday, 11 March 2017 at 10:32:02 UTC, meppl wrote: On Friday, 10 March 2017 at 11:25:11 UTC, Traktor TOni wrote: I think the name is just misleading, the D developers should at least be honest with themselves. look here: https://en.wikipedia.org/wiki/C_(programming_language)#History so, once upon a day there was _A_ssembler. then a language of the name "B" was created. later a successor language was created - called "C". it happened that someone was not satisfied with "C", but didnt really want to abandon "C". thats why he created a superset of "C" and called it "C++". a "C" with more capabilities. (thats probably not 100% true, but still pretty much the meaning of the name). another person was not satisfied and created another successor. "D" was born. "D" abandoned compatibility with "C" - more than "C++" did. also, "D" is ment to be a successor of C/C++. but "D" is not a (C++)++ or C+2, also not a C++, because its not a superset, since it breaks compatibility to the predecessors in that context, i think the name is _not misleading_: A B C C++ _D_ Yeah, we could say that D is an alias of ++C. i.e. the result of the increment. As C++ is the operation of incrementing but returning the old value. The day they will have achieved their incrementation they will realise that they now have reached where D is already ;-) Don't take that too seriously, these dick wagging posts are generally not very productive and indeed can paint people in a unpleasant way.
Re: Zcoin implementation bug enabled attacker to create 548, 000 Zcoins
On 10.03.2017 23:41, H. S. Teoh via Digitalmars-d wrote: Basically, operator syntax is just too specific to the arithmetical meanings of the operators that overloading them to mean something else seems like just asking for trouble. OTOH, restricting how operators can be overloaded means they cannot be used for symbolic mathematics, which is annoying.
Re: Can you fix this code to avoid using pointers?
On Saturday, 11 March 2017 at 12:35:42 UTC, XavierAP wrote: I do not really think it's a bad solution, to check several scalar arguments that must obey the same condition; just wondering if you have better ideas. Try to avoid modifying the function's signature and defining custom types, unless you have a really terrific idea. void calc(double in1, double in2, double in3, double in4) in { foreach(const p; [, , , ]) enforce(*p > 0); } body { /* ... */ } Please imagine double is a type that I wanted to avoid copying, just check by ref. Same question :p
Re: Can you fix this code to avoid using pointers?
Oh... please forget it What a terrible example :p I forgot why I was using pointers at all... I must have had a reason to write this in the past ???
Can you fix this code to avoid using pointers?
I do not really think it's a bad solution, to check several scalar arguments that must obey the same condition; just wondering if you have better ideas. Try to avoid modifying the function's signature and defining custom types, unless you have a really terrific idea. void calc(double in1, double in2, double in3, double in4) in { foreach(const p; [, , , ]) enforce(*p > 0); } body { /* ... */ }
Re: Let's kill the ddoc _name feature.
On Monday, 6 March 2017 at 03:58:11 UTC, Adam D. Ruppe wrote: I propose that we kill it in a three step process: +1 yes please
Recently added ndslice API
11 ndslice and ndField constructors was added since ndslice API had been reworked. All of them do not perform any memory allocations. mir.ndslice.slice: - slicedNdField - Creates full featured n-dimensional ndslice over an ndField. ndField is a simple user-defined multidimensional view that may have only `auto ref opIndex(size_t[N] indexes...)` primitive. mir.ndslice.topology: - cartesian - Multidimensional Cartesian product - kronecker - Multidimensional Kronecker product - bitwise - Bitwise slice over an unsigned integral slice. (used in tamediadigital/lincount) - bitpack - Bitpack slice over an unsigned integral slice. (used in tamediadigital/hll-d) - indexed - Multidimensional std.range.indexed analog for ndslice. It works like map, e.g. indexes may have any type that can be accepted by source's `opIndex` API. - linspace - Multidimensional evenly spaced numbers over specified intervals. It is numpy and matlab analog. linspace does not have floating-point related std.range.iota bug (Issue 6531). mir.ndslice.concatenation (new): - concatenation, Creates a concatenated view of multiple slices. - pad, Pads with a constant value. - padEdge, Pads with the edge values of slice. - padSymmetric, Pads with the reflection of the slice mirrored along the edge of the slice. - padWrap - Pads with the wrap of the slice along the axis. The first values are used to pad the end and the end values are used to pad the beginning. Github: https://github.com/libmir/mir-algorithm API: http://docs.algorithm.dlang.io/ Know bugs: - `mir.ndslice.topology.map` may not work with LDC because it has deprecated DMD FE. Best regards, Ilya
Re: Rename 'D' to 'D++'
On Friday, 10 March 2017 at 11:25:11 UTC, Traktor TOni wrote: I think the name is just misleading, the D developers should at least be honest with themselves. look here: https://en.wikipedia.org/wiki/C_(programming_language)#History so, once upon a day there was _A_ssembler. then a language of the name "B" was created. later a successor language was created - called "C". it happened that someone was not satisfied with "C", but didnt really want to abandon "C". thats why he created a superset of "C" and called it "C++". a "C" with more capabilities. (thats probably not 100% true, but still pretty much the meaning of the name). another person was not satisfied and created another successor. "D" was born. "D" abandoned compatibility with "C" - more than "C++" did. also, "D" is ment to be a successor of C/C++. but "D" is not a (C++)++ or C+2, also not a C++, because its not a superset, since it breaks compatibility to the predecessors in that context, i think the name is _not misleading_: A B C C++ _D_
Re: Better ddoc defaults?
On Friday, 10 March 2017 at 07:58:36 UTC, Petar Kirov [ZombineDev] wrote: On Thursday, 9 March 2017 at 21:08:17 UTC, Yuxuan Shui wrote: I'm using ddoc for the first time. I was naively expecting something resembles dlang.org, and the results is a bit disappointing. So I looked at dlang.org and realized lots and lots of ddoc templates are required to achieve that. As the developer of a tiny package that nobody cares, I want to have a nice looking documents page, but I don't want put too much (or any!) time into it. And I don't care whether my documents have any "personality". I guess a lot people would agree. So why don't we make the defaults more beautiful? Or make the dlang.org templates easier to adopt for average users? My favorite one is: https://github.com/MartinNowak/scod. BTW, the default ddox (the one that comes with dub) is getting an upgrade soon: https://github.com/rejectedsoftware/ddox/pull/149 https://github.com/rejectedsoftware/ddox/pull/150. I tried ddox, and it worked pretty well. Only problem is that, ddox uses the json output of dmd, which is different from dmd -D result. dmd -D will include the then-branch of static-ifs and version blocks that's been compiled in, but the json output doesn't. Is this by design? Or can we make the json output consistent with the ddoc output?