Re: Function which returns a sorted array without duplicates
On Sunday, 22 January 2023 at 23:26:45 UTC, dan wrote: So what i was missing was std.array. Of course you can use the uniq from Phobos. But since we already use array, you should also try the 3rd classic version: ```d import std.algorithm; import std.array; // qef. version: private S[] sortArray ( S )( S[] x ) { auto y = x.dup; return y.sort.uniq.array; } // no dup. version: private S[] sortArrayy ( S )( S[] x ) { S[] w; foreach ( v ; x ) w ~= v; return w.sort.uniq.array; } // classic version: private S[] sortArrayyy ( S )( S[] x ) { S[] w = x.dup; w.sort; size_t diff; for (size_t j, i = 1; i < w.length; ++i) { if (w[j] != w[i]) { w[++j] = w[i]; } else { ++diff; } } return w[0 .. $ - diff]; } void main() { uint[] nums = [1, 3, 2, 5, 1, 4, 2, 8]; auto sorted = nums.sortArray; assert(sorted.equal(nums.sortArrayy)); assert(sorted.equal(nums.sortArrayyy)); import std.stdio; writeln( "Input: ", nums ); writeln( "Output: ", sorted ); } ``` In fine, we have implemented 3 ways to sort an array and return it without repetition. I guess, there is no alternative to this basic algorithm... SDB@79
Re: Non-ugly ways to implement a 'static' class or namespace?
On Monday, 23 January 2023 at 00:36:36 UTC, thebluepandabear wrote: I haven't been programming for a long time, but most of the other languages I used had such a namespace feature. Kotlin has something called an `object` which is essentially a namespace and it is great. The benefits of adding a namespace-like feature outweigh its costs, imo. If you really want to, you can mostly force a namespace use like this: ``` // mylib/package.d module mylib; public static import mylib.impl.funcs; // mylib/impl/funcs.d module mylib.impl.funcs; void foo() { } ``` Now when users import mylib, the public static import means hey call mylib.foo. Just don't bother documenting the impl subpackage and only those who look at the source will even know it exists. I went through this same process when I first came to D years ago. D's modules *are* namespaces, and I wanted a way to force them. Eventually, I got over it. There's no reason to force a namespace. Namespaces are intended to disambiguate conflicting symbols. So let the users use them that way. There's no need to force them to type out the namespace all the time. It's certainly not an OOP vs. procedural issue, as namespaces have nothing to do with OOP.
Re: Non-ugly ways to implement a 'static' class or namespace?
On Monday, 23 January 2023 at 00:11:17 UTC, thebluepandabear wrote: Sorry don't like that solution specifically. That's because it is a procedural implementation, not an OOP-style one. I don't know how much of the D community writes procedurally but I'm personally an OOP-type of guy. A class full of static methods is not OOP either.
Re: vibe.d community/forum/whatever ?
On Monday, 30 August 2021 at 02:39:06 UTC, someone wrote: https://forum.rejectedsoftware.com/groups/rejectedsoftware.vibed/ I've been reading vibe.d tour and some documentation today to get some first impressions. https://vibed.org/community pointed to the link above ... but it seems it is full of crap. Hi, I just uploaded to Github a second edition of the tutorial I wrote last year: https://github.com/reyvaleza/vibed/blob/main/Build%20Web%20Apps%20in%20Vibed%20second%20edition.pdf Hope this helps.
Re: Non-ugly ways to implement a 'static' class or namespace?
On 1/22/23 16:21, thebluepandabear wrote: > Again, stuffing it into a module is not the same thing as a namespace. That is correct but it is also one answer of D's to namespaces. There are others. For example, structs and classes provide namespacing as well. > The user can just bypass this by writing `drawLine`, there's nothing in > the language currently that would 'force' the user to write in a > namespace-like/static-class-like fashion, and that's the biggest problem. I agree with Adam here. The language should provide solutions and the programmer should pick appropriate ones. Later you added that you were talking about library design. There is no problem in the library providing an awesome and very usable API but the programmers still picking some other method that works better for them.[1] I would like to add to your C++ examples: Keyboard::Key.A// Fine Key.A // Fine foo// Fine That last line can exactly be the same as the previous two in C++. OOP is always a solution where it makes sense. I've been very happy with writing free-standing functions and dumb data types that the functions operate on... until... some invariant matters. Then I make the function a member, etc. Perhaps because I don't buy into the "everything is a class" anymore, I am very happy with D's approach. Mostly structs and functions for me. But I use classes as well when they make sense. Having said all that, I realize that your asking specifically for static classes made me think of a solution around classes. However, doesn't D has the equivalent in structs? Isn't the following what you are looking for? struct Algo { static void drawLine(Canvas c, Pos from, Pos to) { .. }; } Now the user is forced to use it like this: Algo.drawLine(new Canvas(), new Pos(5, 3), new Pos(7, 9)); or this: Algo().drawLine(/* ... */); but that can be @disabled. Ali [1] It is interesting that limiting the programmer in some way seems to help with language marketing. And D is deficient in that marketing move because it does the opposite: Gives the programmer choices. I tried to show this point on this slide: https://youtu.be/0JL9uT_XGZE?t=701 The point "not taking anything away from the programmer" can be seen as a marketing issue.
Re: Non-ugly ways to implement a 'static' class or namespace?
On Monday, 23 January 2023 at 00:27:29 UTC, Adam D Ruppe wrote: On Monday, 23 January 2023 at 00:21:12 UTC, thebluepandabear wrote: there's nothing in the language currently that would 'force' the user Why do you hate freedom? It's not a freedom issue, it's a library-design issue. Some libraries want to incorporate a namespace-like design to force the user to be more 'explicit' with what they want. SFML has a `Keyboard` namespace which has a `Key` enum. The user is 'forced' (although I am not sure if this is the case since it's C++) to use the `Keyboard.` declaration before using the `Key` enum. Looking at code block 1 and 2, which makes more sense? ```C++ Keyboard::Key.A ``` ```C++ Key.A ``` The first one does, because looking at the second one, the person who will read the code might be confused what 'Key' means, is it a car key, a set of keys for unlocking something, etc? Now, the user doesn't have to use the library if they don't want to. There will be plenty of libraries out there that don't have namespaces. I haven't been programming for a long time, but most of the other languages I used had such a namespace feature. Kotlin has something called an `object` which is essentially a namespace and it is great. The benefits of adding a namespace-like feature outweigh its costs, imo.
Re: Non-ugly ways to implement a 'static' class or namespace?
On Monday, 23 January 2023 at 00:21:12 UTC, thebluepandabear wrote: there's nothing in the language currently that would 'force' the user Why do you hate freedom?
Re: Non-ugly ways to implement a 'static' class or namespace?
That way of naming a global function is essentially a poor man's^W^Wexcuse me, I mean, C's way of working around the lack of a proper namespacing / module system. In D, we do have a proper module system, so you could just call the function `drawLine` and put it in a file named Algo.d, then you can just use D's symbol resolution rules to disambiguate between Algo.drawLine and PersonalSpace.drawLine, for example. :-P T Again, stuffing it into a module is not the same thing as a namespace. The user can just bypass this by writing `drawLine`, there's nothing in the language currently that would 'force' the user to write in a namespace-like/static-class-like fashion, and that's the biggest problem.
Re: Non-ugly ways to implement a 'static' class or namespace?
Something interesting. I know that D has C++ SFML bindings, although they are unmaintained. I was interested to see how they would 'implement' the C++ namespaces of SFML, and - boy was I surprised. Reading through `DSFML`, I see `final abstract class` getting used to implement SFML's `Keyboard` namespace: `final abstract class Keyboard` at https://github.com/Jebbs/DSFML/blob/master/src/dsfml/window/keyboard.d It seems like using `final abstract` is the best solution.
Re: Non-ugly ways to implement a 'static' class or namespace?
// app.d import API = api; void main() { API.draw(); } ``` Another thing that I don't like about that solution, is that it doesn't 'force' the user to write in a namespace-like style. C++ `namespaces` force you to (I believe), and so does `static class` from Java/C#. D is both an object oriented and procedural language, I would honestly love to see some sort of `namespace` or `static class` feature come into the language. I know that it's controversial here, but I would honestly think it would help develop the language in a good way. But that's just my opinion.
Re: Non-ugly ways to implement a 'static' class or namespace?
On Sunday, 22 January 2023 at 18:30:59 UTC, ryuukk_ wrote: On Friday, 20 January 2023 at 11:28:23 UTC, thebluepandabear wrote: D is not java/C#, it's better than that! ```D // api.d void draw(){} // app.d import API = api; void main() { API.draw(); } ``` Sorry don't like that solution specifically. That's because it is a procedural implementation, not an OOP-style one. I don't know how much of the D community writes procedurally but I'm personally an OOP-type of guy.
Re: Function which returns a sorted array without duplicates
On Sunday, 22 January 2023 at 07:33:01 UTC, evilrat wrote: On Sunday, 22 January 2023 at 04:42:09 UTC, dan wrote: I would like to write a function which takes an array as input, and returns a sorted array without duplicates. ```d private S[] _sort_array( S )( S[] x ) { import std.algorithm; auto y = x.dup; y.sort; auto z = y.uniq; // Cannot just return z; this gives: // Error: cannot implicitly convert expression `z` of type // `UniqResult!(binaryFun, uint[])` to `uint[]` uniq and other algorithms often returns a lazy range, you can build an array by using `std.array.array()` https://dlang.org/phobos/std_array.html#array try something like this or just `return array(y.uniq);` ```d private S[] _sort_array( S )( S[] x ) { import std.algorithm; import std.array; return x.dup .sort .uniq .array(); } ``` And IIRC you probably don't need `dup` as sort produces a lazy range. Thanks evilrat, this works perfectly, and is just the right style too (imvho). So what i was missing was std.array. Thanks also Ali for your subsequent clarifying remarks. (Probably what i need to do is read a good book on the std library for d.) dan Thanks also Ali for your subsequent remarks
Re: Function which returns a sorted array without duplicates
On 1/21/23 23:33, evilrat wrote: > And IIRC you probably don't need `dup` Unfortunately, no. Skipping .dup is only possible if we are allowed to sort the original array. > as sort produces a lazy range. sort() returns a SortedRange but it can't be lazy. Even if it were, the first call to .front would have to sort anyway. However... There is an optimization possible for such requirements if not all elements but just a number of them are needed. For example, if only the first 10 elements are needed, then a binary heap may be faster: https://dlang.org/phobos/std_container_binaryheap.html The usage would be similar to the following for "the first 10 unique elements": heapify(arr).uniq.take(10) (Not tested.) Ali
Re: Non-ugly ways to implement a 'static' class or namespace?
On Friday, 20 January 2023 at 11:28:23 UTC, thebluepandabear wrote: D is not java/C#, it's better than that! ```D // api.d void draw(){} // app.d import API = api; void main() { API.draw(); } ```
Re: Hipreme's #8 Tip of the day - Using custom runtime with dub projects
On Sunday, 22 January 2023 at 18:16:35 UTC, Hipreme wrote: Nope. Those DFLAGS environment variable is used to affect projects such as my dependencies. For example, my dependency needs to be built using my own runtime. The dflags defined in the dub.json only affect the current project, not its dependencies Ah ok, got it, the compiler will fetch them for a whole session no matter what is currently being built. Though this approach will make it harder to anyone who might want to use your project/library if this requirement remains for a user's project.
Re: Hipreme's #8 Tip of the day - Using custom runtime with dub projects
On Sunday, 22 January 2023 at 17:06:13 UTC, evilrat wrote: On Sunday, 22 January 2023 at 16:57:56 UTC, Hipreme wrote: The way to use dub's packages is by using the DFLAGS. With DFLAGS, I can set the import path to my own DRuntime and own std. That way I can make the dependencies behave more or less the same, this is an example of what is being done now: Keep in mind that you'll probably need to setup some env variables such as mine done for making your script a little more portable to other developer's PCs. I would really like if there was a way to define global dflags on dub though. Can't you just use env variable[1] and put into dub dflags like this? https://github.com/Superbelko/ohmygentool/blob/cc75d915a8df8bdc2bba628df305d421151994a1/dub.json#L11 _(note that some of the listed predefines doesn't work in some sections though, a bug maybe?)_ [1] https://dub.pm/package-format-json.html#environment-variables Nope. Those DFLAGS environment variable is used to affect projects such as my dependencies. For example, my dependency needs to be built using my own runtime. The dflags defined in the dub.json only affect the current project, not its dependencies
Re: Hipreme's #8 Tip of the day - Using custom runtime with dub projects
On Sunday, 22 January 2023 at 16:57:56 UTC, Hipreme wrote: The way to use dub's packages is by using the DFLAGS. With DFLAGS, I can set the import path to my own DRuntime and own std. That way I can make the dependencies behave more or less the same, this is an example of what is being done now: Keep in mind that you'll probably need to setup some env variables such as mine done for making your script a little more portable to other developer's PCs. I would really like if there was a way to define global dflags on dub though. Can't you just use env variable[1] and put into dub dflags like this? https://github.com/Superbelko/ohmygentool/blob/cc75d915a8df8bdc2bba628df305d421151994a1/dub.json#L11 _(note that some of the listed predefines doesn't work in some sections though, a bug maybe?)_ [1] https://dub.pm/package-format-json.html#environment-variables
Hipreme's #8 Tip of the day - Using custom runtime with dub projects
I have been working with WebAssembly for at least 1 entire month into getting my entire Game Engine and DRuntime ported to it. As I'm almost reaching the point of the new announcement, I come here to show how I've done DUB's dependency compatibility with a custom runtime. The way to use dub's packages is by using the DFLAGS. With DFLAGS, I can set the import path to my own DRuntime and own std. That way I can make the dependencies behave more or less the same, this is an example of what is being done now: ``` set DFLAGS=-I=%HIPREME_ENGINE%/modules/d_std/source ^ -I=%HIPREME_ENGINE%/build/wasm/runtime/webassembly/arsd-webassembly ^ -preview=shortenedMethods ^ -L-allow-undefined ^ -fvisibility=hidden ^ -d-version=CarelessAlocation dub build --build=debug -c wasm --arch=wasm32-unknown-unknown-wasm ``` So, when dub tried to build their dependencies, your custom runtime overrides D's default ones. In that case I'm overriding both D std and D core/** and object.d Keep in mind that you'll probably need to setup some env variables such as mine done for making your script a little more portable to other developer's PCs. I would really like if there was a way to define global dflags on dub though.
Re: Is there a way to get a template’s parameters and constraints?
On Friday, 20 January 2023 at 17:15:31 UTC, Quirin Schroll wrote: Is there a trait (or a combination of traits) that gives me the constraints of a template? Apologies, I missed the key part of your question. But I think the above can be adapted if you were so inclined.
Re: Is there a way to get a template’s parameters and constraints?
There is a way but it's horrible. You can take the `.stringof` and parse the result. I knocked this up for something but it's not well tested and there are probably templates that it handles incorrectly. I'm not claiming this is any good, I just happened to have it. ```d enum TemplateParameterType { valueType, aliasType, typeType, thisType, sequenceType } public struct TemplateParameter { TemplateParameterType type; string name; string defaultValue; } public auto templateParameters(alias T)() { static assert(__traits(isTemplate, T)); import std.algorithm : startsWith; import std.array : appender; import std.string : strip; auto results = appender!(TemplateParameter[]); auto isMissing = false; const templateSignature = T.stringof; const allParametersStart = findExpectedSource(templateSignature, '(', isMissing) + 1; const allParametersEnd = allParametersStart + findExpectedSource(templateSignature[allParametersStart .. $], ')', isMissing); if (isMissing) throw new Exception("{Expected `(` and `)` in template signature: `" ~ templateSignature ~ "`."); auto parametersText = templateSignature[allParametersStart .. allParametersEnd]; auto parameterIndex = -1; mainParameterLoop: while (parametersText.length > 0) { parameterIndex++; auto parameterEnd = findExpectedSource(parametersText, ',', isMissing); if (isMissing) parameterEnd = parametersText.length; auto parameterRemainingText = parametersText[0 .. parameterEnd]; if (parameterEnd < parametersText.length) parametersText = parametersText[parameterEnd + 1 .. $]; else parametersText = ""; auto token = parameterRemainingText.consumeToken; if (parameterRemainingText.startsWith("...")) { results.put(TemplateParameter(TemplateParameterType.sequenceType, token, "")); continue mainParameterLoop; } auto nextToken = parameterRemainingText.consumeToken; if (nextToken == "") { results.put(TemplateParameter(TemplateParameterType.typeType, token, "")); continue mainParameterLoop; } TemplateParameterType type; if (token == "this") type = TemplateParameterType.thisType; else if (token == "alias") type = TemplateParameterType.aliasType; else if (nextToken == ":" || nextToken == "=") type = TemplateParameterType.typeType; else type = TemplateParameterType.valueType; if (type != TemplateParameterType.typeType) { token = nextToken; nextToken = parameterRemainingText.consumeToken; } while (true) { if (nextToken == "") { results.put(TemplateParameter(type, token, "")); continue mainParameterLoop; } if (nextToken == ":") { const identifierName = token; while (true) { token = parameterRemainingText.consumeToken; if (token.length == 0) { results.put(TemplateParameter(type, identifierName, "")); continue mainParameterLoop; } else if (token == "=") { results.put(TemplateParameter(type, identifierName, parameterRemainingText.strip)); continue mainParameterLoop; } } results.put(TemplateParameter(type, identifierName, parameterRemainingText.strip)); continue mainParameterLoop; } if (nextToken == "=") { const identifierName = token; results.put(TemplateParameter(type, identifierName, parameterRemainingText.strip)); continue mainParameterLoop; } token = nextToken; import std.conv : to; if (token.length == 0) throw new Exception("Cannot parse parameter " ~ parameterIndex.to!string ~ " in template `" ~ templateSignature ~ "`."); nextToken = parameterRemainingText.consumeToken; } } return results[]; } private auto findExpectedCharacter(string source, char character, out bool isMissing) { foreach (offset; 0 .. source.length) if (source[offset] == character) return offset; isMissing = true; return 0; } private auto findExpectedText(string source, string text, out bool isMissing) { import std.algorithm : startsWith; foreach (offset; 0 .. source.length) if (source[offset .. $].startsWith(text)) return