Re: get element index when using each!(x)
On Thursday, 17 September 2020 at 03:16:42 UTC, Paul Backus wrote: On Thursday, 17 September 2020 at 03:14:08 UTC, JG wrote: Perhaps there are other ways, but you can use enumerate. For example --- import std.algorithm; import std.range; import std.stdio; void main() { string s = "hello"; s.enumerate.each!(x=>writeln(x[0],":",x[1])); } Worth knowing that the tuples you get from enumerate actually have named members, so you can write: s.enumerate.each!(x => writeln(x.index, ":", x.value)); Documentation: http://dpldocs.info/experimental-docs/std.range.enumerate.html thanks you! and thanks to JG. - binghoo
Re: What kind of mangling has the LDC2 -X JsonFile "deco" field?
On Thursday, 17 September 2020 at 03:06:45 UTC, realhet wrote: Anyone can help me telling how to decode these please? so here's a cool trick to get hte other demanglers to help. Just prepend _D4name to the string. so like: $ ./ddemangle _D4nameFAyaZE3het8keywords10KeywordCat het.keywords.KeywordCat name(immutable(char)[]) so then the demangler will recognize it and use your placeholder name while spitting out the rest. of course you can change that 4name to whatever you want.
Re: get element index when using each!(x)
On Thursday, 17 September 2020 at 03:14:08 UTC, JG wrote: Perhaps there are other ways, but you can use enumerate. For example --- import std.algorithm; import std.range; import std.stdio; void main() { string s = "hello"; s.enumerate.each!(x=>writeln(x[0],":",x[1])); } Worth knowing that the tuples you get from enumerate actually have named members, so you can write: s.enumerate.each!(x => writeln(x.index, ":", x.value)); Documentation: http://dpldocs.info/experimental-docs/std.range.enumerate.html
Re: What kind of mangling has the LDC2 -X JsonFile "deco" field?
On Thursday, 17 September 2020 at 03:06:45 UTC, realhet wrote: I'm trying to get information from the JsonFile produced by LDC2, but having no clue how to decode this: For example: header: KeywordCat kwCatOf(int k) "deco" : "FAyaZE3het8keywords10KeywordCat", That's a D mangle but just of one individual variable, without an attached name. std.demangle looks for the _D prefix and the name so it prolly can't read it. https://dlang.org/spec/abi.html#name_mangling But from eyeball it is a extern(D) function taking a string argument and returning a KeywordCat enum.. The "F" means extern(D). After this are the argument list. "Aya" you'll get to recognize as "string", but formally it means "Array (A) of immutable (y) chars (a)". Then "Z" means non-variadic function and this ends the argument list, so the next thing is the return type. "E" means enum, then the name comes with a count of chars in this name piece, then the chars.
Re: get element index when using each!(x)
On Thursday, 17 September 2020 at 00:51:54 UTC, dangbinghoo wrote: hi, is there any way to get the index for an element when iteration using each!(x)? I know I can do this using foreach statement, but I prefer using the each template. --- string s = "hello"; foreach(i, c; s) { } -- how can I get to ? Thanks! binghoo dang Perhaps there are other ways, but you can use enumerate. For example --- import std.algorithm; import std.range; import std.stdio; void main() { string s = "hello"; s.enumerate.each!(x=>writeln(x[0],":",x[1])); } --- Produces --- 0:h 1:e 2:l 3:l 4:o ---
What kind of mangling has the LDC2 -X JsonFile "deco" field?
Hello, I'm trying to get information from the JsonFile produced by LDC2, but having no clue how to decode this: For example: header: KeywordCat kwCatOf(int k) "deco" : "FAyaZE3het8keywords10KeywordCat", The "deco" field contains the full name of the return type het.keywords.KeywordCat, but in front of that I don't know how to decode that "FAyaZE". Also this is how a string return type is encoded: "FiZAya" I tried std.demangle and and online GCC demangler, but no luck. Anyone can help me telling how to decode these please? Thank you in advance!
Re: enum and const or immutable ‘variable’ whose value is known at compile time
On Thursday, 17 September 2020 at 00:32:40 UTC, Cecil Ward So can the result of declaring certain things with enum ever have an _address_ then? (According to legit D code that is, never mind the underlying implementation details, which may not be observable) No. Think of it as a named literal. Given enum x = 10, then int num = x is the same as if you had typed int num = 10. Thats’s why you have be careful with array enums if you care about allocations. I actually really hate the way enum was bent out of shape and twisted from its original purpose so that finally we end up with a way of defining only one value, not the whole range of permissible values for a type as in the beginning. I wish there were just a keyword ‘constant’ or something (yes, I know, you could just call that something ‘enum’, or ‘const’) enum foo is essentially a shortcut for enum { foo }. It’s neither bent out of shape nor twisted. Consider that C++ added the new keyword constexpr for the same thing. Why pollute the namespace with a new keyword when you already have one that fits?
get element index when using each!(x)
hi, is there any way to get the index for an element when iteration using each!(x)? I know I can do this using foreach statement, but I prefer using the each template. --- string s = "hello"; foreach(i, c; s) { } -- how can I get to ? Thanks! binghoo dang
Re: enum and const or immutable ‘variable’ whose value is known at compile time
On Wednesday, 16 September 2020 at 17:19:13 UTC, Adam D. Ruppe wrote: On Wednesday, 16 September 2020 at 17:12:47 UTC, Cecil Ward wrote: then is there any downside to just using enum all the time? For a non-string array, enum may give runtime allocations that static immutable won't. Generally think of enum as being replaced with the literal representation and array literals actually make a new array. This may or may not matter to you. So can the result of declaring certain things with enum ever have an _address_ then? (According to legit D code that is, never mind the underlying implementation details, which may not be observable) I actually really hate the way enum was bent out of shape and twisted from its original purpose so that finally we end up with a way of defining only one value, not the whole range of permissible values for a type as in the beginning. I wish there were just a keyword ‘constant’ or something (yes, I know, you could just call that something ‘enum’, or ‘const’)
Re: Neater "not version (...)" ?
On Wednesday, 16 September 2020 at 19:04:24 UTC, Vladimirs Nordholm wrote: Ah, I guess it boils down to this then. Doesn't really make it "neater", but thank you for the tip! IMO, just keep it as `version(Windows) {} else { ... }` if you HAVE to instead of one of the workarounds people suggest. I do wonder what kind of code runs on the "not Windows" operating system though, do you mean `version(Posix)` perhaps?
Re: Neater "not version (...)" ?
On Wednesday, 16 September 2020 at 19:04:24 UTC, Vladimirs Nordholm wrote: On Wednesday, 16 September 2020 at 18:54:45 UTC, Jacob Carlborg wrote: version (Windows) enum windows = true; else enum windows = false; static if (!windows) { // ... my code } Ah, I guess it boils down to this then. Doesn't really make it "neater", but thank you for the tip! I wrote this helper a little while back: struct Version { template opDispatch(string name) { mixin("version ("~name~") enum opDispatch = true; else enum opDispatch = false;"); } } static if (Version.Windows) pragma(msg, "Windows machine"); static if (Version.linux) pragma(msg, "Linux machine"); Note that it only works for global versions, and those defined in the same module as Version. -- Simen
Re: Neater "not version (...)" ?
On Wednesday, 16 September 2020 at 18:54:45 UTC, Jacob Carlborg wrote: On 2020-09-16 19:53, Vladimirs Nordholm wrote: Hello. I wonder if there is a better way to compile something if the current operating system is _not_ a specific platform. For example, I only want some code to compile if the operating system is not Windows. Currently I do this: version (Windows) { } else { // ... my code } Is there a neater version of this, like `!version (Windows) { /+ ... my code +/ }` ? The workaround for that is to define booleans for all versions and then use `static if`: version (Windows) enum windows = true; else enum windows = false; static if (!windows) { // ... my code } Ah, I guess it boils down to this then. Doesn't really make it "neater", but thank you for the tip!
Re: Neater "not version (...)" ?
On Wednesday, 16 September 2020 at 18:07:25 UTC, Ferhat Kurtulmuş wrote: On Wednesday, 16 September 2020 at 17:53:31 UTC, Vladimirs Nordholm wrote: Hello. I wonder if there is a better way to compile something if the current operating system is _not_ a specific platform. For example, I only want some code to compile if the operating system is not Windows. Currently I do this: version (Windows) { } else { // ... my code } Is there a neater version of this, like `!version (Windows) { /+ ... my code +/ }` ? Not what you may want, but a dub solution is available. "excludeSourceFiles-windows" : ["source/someunixcode.d"] Unfortunately for my use case this does not work here. Thanks for the tip though!
Re: Neater "not version (...)" ?
On 2020-09-16 19:53, Vladimirs Nordholm wrote: Hello. I wonder if there is a better way to compile something if the current operating system is _not_ a specific platform. For example, I only want some code to compile if the operating system is not Windows. Currently I do this: version (Windows) { } else { // ... my code } Is there a neater version of this, like `!version (Windows) { /+ ... my code +/ }` ? The workaround for that is to define booleans for all versions and then use `static if`: version (Windows) enum windows = true; else enum windows = false; static if (!windows) { // ... my code } -- /Jacob Carlborg
Re: Building LDC runtime for a microcontroller
On Wednesday, 16 September 2020 at 17:59:41 UTC, Remi wrote: I tried to modify the hello.d example from your blog post. It works without changes but when I tried to do a string concatenation Yeah, concatenation is one of the features that uses druntime, and specifically, it is done through TypeInfo. I would actually personally skip it if you are doing a minimal custom thing. If you skip it, you can implement your own type instead of using the built-in array concat. You can make a struct with an operator overload to look basically the same, and it can give a slice to pass to other functions. This is much easier here - no druntime code needed and the user code will be clearer that they might have to manage the memory. Typical code with normal append tends to just assume there's no stomping, that the GC takes care of it, etc. I'm hitting linker errors related to TypeInfo: But if you do implement it, as of right now, you have to define TypeInfo. Which suckss because it is super tedious. There's a WIP pull request up there with dmd to templatize this which would help a lot. But right now it means implementing at least some of it. You'd need the base class TypeInfo, then TypeInfo_a (a == "char"), TypeInfo_Array, TypeInfo_Aa (which means "array of char"), then finally, TypeInfo_Aya, which is "array of immutable char", aka, string. Once you get enough of that up - and the compiler is picky about those right now - then the append operation is `_d_arrayappendcTX`, which takes TypeInfo as a param. Search these names in the druntime source to see their official implementations... it is a bit of a beast, which is why I recommend actually skipping them if you can. It quickly explodes in size and by the time you follow it to its final conclusion, you've reimplemented 3/4 of full druntime anyway and might as well have just done a port.
Re: Neater "not version (...)" ?
On Wednesday, 16 September 2020 at 17:53:31 UTC, Vladimirs Nordholm wrote: Hello. I wonder if there is a better way to compile something if the current operating system is _not_ a specific platform. For example, I only want some code to compile if the operating system is not Windows. Currently I do this: version (Windows) { } else { // ... my code } Is there a neater version of this, like `!version (Windows) { /+ ... my code +/ }` ? Not what you may want, but a dub solution is available. "excludeSourceFiles-windows" : ["source/someunixcode.d"]
Re: Building LDC runtime for a microcontroller
On Monday, 7 September 2020 at 22:13:20 UTC, Adam D. Ruppe wrote: On Monday, 7 September 2020 at 20:55:54 UTC, IGotD- wrote: I guess this was written before betterC existed. Well, -betterC existed even then, but it was *completely* useless. It didn't become useful until 2016 or 2017. But around that same time, going minimal runtime got even easier, so I never really got on the betterC train anyway. On my tetris webassembly thing last month, I went with a minimal druntime http://dpldocs.info/this-week-in-d/Blog.Posted_2020_08_10.html#druntime And it has some class support too in not a lot of code: https://github.com/adamdruppe/webassembly/blob/master/arsd-webassembly/object.d (and if you aren't doing classes and built-in arrays, you can cut a bunch of that out too). To be honest I like this approach better as it opens up for gradually adding functionality. Yes, indeed. betterC is nice that it gives a library community a shared target to rally around, but for your own custom application it is probably better to do your own thing (though betterC might work for you too, worth considering at least). I tried to modify the hello.d example from your blog post. It works without changes but when I tried to do a string concatenation, I'm hitting linker errors related to TypeInfo: lld: error: server/omg.o: undefined symbol: _D12TypeInfo_Aya6__initZ Using this in hello.d string tmp = "hello"; tmp ~= " world !"; writeln(tmp); I've hit this when trying to make a minimal runtime like yours but I couldn't figure out from the LDC source how that happens. Would you be able to help me understand how to solve this __init symbol issue? Thanks. - Remi.
Neater "not version (...)" ?
Hello. I wonder if there is a better way to compile something if the current operating system is _not_ a specific platform. For example, I only want some code to compile if the operating system is not Windows. Currently I do this: version (Windows) { } else { // ... my code } Is there a neater version of this, like `!version (Windows) { /+ ... my code +/ }` ?
Re: enum and const or immutable ‘variable’ whose value is known at compile time
On Wednesday, 16 September 2020 at 17:12:47 UTC, Cecil Ward wrote: then is there any downside to just using enum all the time? For a non-string array, enum may give runtime allocations that static immutable won't. Generally think of enum as being replaced with the literal representation and array literals actually make a new array. This may or may not matter to you.
enum and const or immutable ‘variable’ whose value is known at compile time
A really stupid question, I fear. If I have some kind of declaration of some ‘variable’ whose value is strictly known at compile time and I do one of the following (rough syntax) either enum foo = bar; or const foo = bar; or immutable foo = bar; then is there any downside to just using enum all the time? - I don’t need to take the address of foo, in fact want to discourage , (as I said, given that I can do so) Is there any upside either to using enum? I’m a bit nervous about using immutable having had bad allergic reactions when passing immutable ‘variables’ to functions and so just tend to use const or enum.
Re: Why is BOM required to use unicode in tokens?
On Tuesday, 15 September 2020 at 01:49:13 UTC, James Blachly wrote: I wish to write a function including ∂x and ∂y (these are trivial to type with appropriate keyboard shortcuts - alt+d on Mac), but without a unicode byte order mark at the beginning of the file, the lexer rejects the tokens. It is not apparently easy to insert such marks (AFAICT no common tool does this specifically), while other languages work fine (i.e., accept unicode in their source) without it. Is there a downside to at least presuming UTF-8? As you probably already know BOM means byte order mark so it is only relevant for multi byte encodings (UTF-16, UTF-32). A BOM for UTF-8 isn't required an in fact it's discouraged. Your editor should automatically insert a BOM if appropriate when you save your file. Probably you need to select the appropriate encoding for your file. Typically this is available in the 'Save as..' dialog, or the settings.
Re: importing a symbol without specifying a subpackage name
On Wednesday, 16 September 2020 at 13:36:22 UTC, 60rntogo wrote: except that I tried doing this in foo.d and then the compiler yelled at me. Yeah, this is the one case where the compiler is picky about the directory structure and filename. It *must* be package.d. (blargh.)
Re: importing a symbol without specifying a subpackage name
On Wednesday, 16 September 2020 at 13:33:34 UTC, Adam D. Ruppe wrote: They define an additional file std/package.d Thanks for a quick answer. I suspected it must have been something like that, except that I tried doing this in foo.d and then the compiler yelled at me.
Re: importing a symbol without specifying a subpackage name
On Wednesday, 16 September 2020 at 13:30:57 UTC, 60rntogo wrote: then saying "import foo : Bar;" yields an error "module foo is in file 'foo.d' which cannot be read". I'm curious, how is this behavior achieved in the standard library? To expand on Adam's reply: https://dlang.org/spec/module.html#package-module
importing a symbol without specifying a subpackage name
I have noticed that if I want to import std.algorithm.searching.find, each of the following will work: --- import std.algorithm.searching : find; import std.algorithm : find; import std : find; --- (Although, the last one is probably not the greatest idea.) However, if I write my own module: --- module foo.bar; struct Bar {} --- then saying "import foo : Bar;" yields an error "module foo is in file 'foo.d' which cannot be read". I'm curious, how is this behavior achieved in the standard library?
Re: importing a symbol without specifying a subpackage name
On Wednesday, 16 September 2020 at 13:30:57 UTC, 60rntogo wrote: I'm curious, how is this behavior achieved in the standard library? They define an additional file std/package.d (and std/algorithm/package.d btw) that lists off module std; public import std.algorithm; public import std.everything; public import std.else; you get the idea. So then teh compiler sees import std and finds that package.d, then follows its public imports the rest of the way down.
Re: Why is BOM required to use unicode in tokens?
On Wednesday, 16 September 2020 at 07:38:26 UTC, Dominikus Dittes Scherkl wrote: We only need to define which properties a character need to be allowed in an identifier. I think the following change in the grammar would be sufficient: Identifier: IdentifierStart IdentifierStart IdentifierChars IdentifierChars: IdentifierChar IdentifierChar IdentifierChars IdentifierStart: _ Any Unicode codepoint with general category Lu, Ll, Lt, Lo, Nl or No IdentifierChar: IdentifierStart Any Unicode codepoint with general category Lm, Mn, Me, Mc or Nd
Re: Why does compose from std.functional return a templated function
On Wednesday, 16 September 2020 at 09:59:59 UTC, Jan Hönig wrote: I have toyed with the compose template in std.functional and ran into some problems. rikki_cattermole on discord helped me a lot to solve my problem. However, what still remains (for me) to understand is why. Source code for `compose`: https://github.com/dlang/phobos/blob/master/std/functional.d#L1161 `compose` pipes together given functions. And returns a TEMPLATED function. Why does it return a templated function? At compile-time, compose definitly knows, what kinds of function it composes together. So with std.traits, it could put there a definitve type, depending on the given function(s). I somewhat see, that inside compose itself, this probably solves some issues with casting (maybe). However, the last composition, i.e. the one which is returned, does not need to be templated, since it is known, what parameter has the last function. In my case, I failed to understand, that it returns a non-initialized template function, which lead into compile problems. In general I can imagine that this leads to weird compile errors, which are hard to understand. (types, casting, etc.) My main question is why? Is there something, which I am missing, that explains, why it is beneficial to return a templated function? (maybe, because I might want to compose together templated non-initialized functions?) It's perfectly possible to compose templated functions without wanting to specify the template parameters, and not allowing this would significantly hamper compose's usability. The other complication is overloads. Here's a version of compose that generates the correct overloads: template getOverloads(alias fn) { static if (__traits(compiles, __traits(getOverloads, __traits(parent, fn), __traits(identifier, fn), true))) { alias getOverloads = __traits(getOverloads, __traits(parent, fn), __traits(identifier, fn), true); } else { alias getOverloads = fn; } } template compose(funs...) if (funs.length > 0) { static foreach (overload; getOverloads!(funs[$-1])) { static if (__traits(isTemplate, overload)) { auto compose(Args...)(Args args) { static if (funs.length == 1) { return overload(args); } else { return funs[0](.compose!(funs[1..$])(args)); } } } else { import std.traits : Parameters; auto compose(Parameters!overload args) { static if (funs.length == 1) { return overload(args); } else { return funs[0](.compose!(funs[1..$])(args)); } } } } } As you can see, this is *a lot* more complex than the version in std.functional. The benefit is you can take the address of it easily. Here's how you can do the same with std.functional.compose: import std.functional : compose; import std.meta : Instantiate; unittest { auto sun = !(compose!(fun, gun), int); sun(3); } void fun(T)(T t) { } int gun(int t) { return t; } I will argue the latter is an acceptable cost of avoiding the dense, bug-prone monstrosity of the former. -- Simen
Re: Why does compose from std.functional return a templated function
On Wed, Sep 16, 2020 at 12:50 PM Daniel Kozak wrote: > > > On Wed, Sep 16, 2020 at 12:00 PM Jan Hönig via Digitalmars-d-learn < > digitalmars-d-learn@puremagic.com> wrote: > >> ... >> >> My main question is why? Is there something, which I am missing, >> that explains, why it is beneficial to return a templated >> function? >> >> (maybe, because I might want to compose together templated >> non-initialized functions?) > > (maybe, because I might want to compose together templated non-initialized functions?) Yes
Re: Why does compose from std.functional return a templated function
On Wednesday, 16 September 2020 at 10:50:06 UTC, Daniel Kozak wrote: On Wed, Sep 16, 2020 at 12:00 PM Jan Hönig via Digitalmars-d-learn < digitalmars-d-learn@puremagic.com> wrote: ... My main question is why? Is there something, which I am missing, that explains, why it is beneficial to return a templated function? (maybe, because I might want to compose together templated non-initialized functions?) It has to be templated because than you can alias it and use it many times something like import std.stdio; import std.functional : compose; import std.algorithm.comparison : equal; import std.algorithm.iteration : map; import std.array : split, array; import std.conv : to; alias StrArrToIntArr = compose!(array,map!(to!int), split); void main() { auto str1 = "2 4 8 9"; int[] intArr = StrArrToIntArr(str1); } If compose would not be template it would need to store functions addresses so it would need to have some array of functions, this would be ineffective and need to use GC Right, if i give it non-initialized templated functions, it makes a lot of sense to return a template function as well. But for functions without templates? Probably not a frequent usecase I guess.
Re: Why does compose from std.functional return a templated function
On Wed, Sep 16, 2020 at 12:00 PM Jan Hönig via Digitalmars-d-learn < digitalmars-d-learn@puremagic.com> wrote: > ... > > My main question is why? Is there something, which I am missing, > that explains, why it is beneficial to return a templated > function? > > (maybe, because I might want to compose together templated > non-initialized functions?) > It has to be templated because than you can alias it and use it many times something like import std.stdio; import std.functional : compose; import std.algorithm.comparison : equal; import std.algorithm.iteration : map; import std.array : split, array; import std.conv : to; alias StrArrToIntArr = compose!(array,map!(to!int), split); void main() { auto str1 = "2 4 8 9"; int[] intArr = StrArrToIntArr(str1); } If compose would not be template it would need to store functions addresses so it would need to have some array of functions, this would be ineffective and need to use GC
Why does compose from std.functional return a templated function
I have toyed with the compose template in std.functional and ran into some problems. rikki_cattermole on discord helped me a lot to solve my problem. However, what still remains (for me) to understand is why. Source code for `compose`: https://github.com/dlang/phobos/blob/master/std/functional.d#L1161 `compose` pipes together given functions. And returns a TEMPLATED function. Why does it return a templated function? At compile-time, compose definitly knows, what kinds of function it composes together. So with std.traits, it could put there a definitve type, depending on the given function(s). I somewhat see, that inside compose itself, this probably solves some issues with casting (maybe). However, the last composition, i.e. the one which is returned, does not need to be templated, since it is known, what parameter has the last function. In my case, I failed to understand, that it returns a non-initialized template function, which lead into compile problems. In general I can imagine that this leads to weird compile errors, which are hard to understand. (types, casting, etc.) My main question is why? Is there something, which I am missing, that explains, why it is beneficial to return a templated function? (maybe, because I might want to compose together templated non-initialized functions?)
Re: Why is BOM required to use unicode in tokens?
On Wednesday, 16 September 2020 at 00:22:15 UTC, Steven Schveighoffer wrote: Someone should verify that the character you want to use for a symbol name is actually considered a letter or not. Using phobos to prove this is kind of self-defeating, as I'm pretty sure it would be in league with DMD if there is a bug. UnicodeData.txt (a data file provided by the unicode organization itself since version 1) contains exactly the necessary properties (in an easy parsable format), so we don't need to hard-code the list of allowed identifier characters, but can instead use the latest version provided by unicode (changing every year!). We only need to define which properties a character need to be allowed in an identifier.