Re: Find a char among string (string.findAmong.char)
On Monday, 5 July 2021 at 19:34:14 UTC, BoQsc wrote: But I really don't like how it looks less readable and makes less sense on first look. `if (([letter].findAmong(alphabet)).length)` I'd like to use some method on the `letter` instead of [] And `.length` does not make a lot of sense when reading like an english sentence. I suggest canFind, like in my earlier example. findAmong is like "consume this range until you find one of these things, and then return the remainder of the range". It doesn't really fit your use.
Re: Find a char among string (string.findAmong.char)
On Monday, 5 July 2021 at 19:25:23 UTC, jfondren wrote: On Monday, 5 July 2021 at 19:19:19 UTC, BoQsc wrote: If I use `[letter].findAmong(alphabet)` in my code, it considers a dot (.) punctuation character as a letter. You can see it here: https://run.dlang.io/is/YWmaXU It returns a zero-length array that, because it's not null, is true. That's why I used .length in my example. ``` $ rdmd --eval 'writeln("str"[$..$].length); writeln("str"[$..$] ? true : false)' 0 true $ rdmd --eval 'writeln([].length); writeln([] ? true : false)' 0 false ``` Oh alright I think I fixed it with your guidance. ``` import std; void main() { alias alphabet = letters; char[26] letters = ['a','b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']; string wordExample = "Book."; foreach (letter; wordExample){ if (([letter].findAmong(alphabet)).length){ write(letter); write(" letter is found among the alphabet."); writeln; } } } ``` But I really don't like how it looks less readable and makes less sense on first look. `if (([letter].findAmong(alphabet)).length)` I'd like to use some method on the `letter` instead of [] And `.length` does not make a lot of sense when reading like an english sentence.
Re: Find a char among string (string.findAmong.char)
On Monday, 5 July 2021 at 19:19:19 UTC, BoQsc wrote: If I use `[letter].findAmong(alphabet)` in my code, it considers a dot (.) punctuation character as a letter. You can see it here: https://run.dlang.io/is/YWmaXU It returns a zero-length array that, because it's not null, is true. That's why I used .length in my example. ``` $ rdmd --eval 'writeln("str"[$..$].length); writeln("str"[$..$] ? true : false)' 0 true $ rdmd --eval 'writeln([].length); writeln([] ? true : false)' 0 false ```
Re: Find a char among string (string.findAmong.char)
On Monday, 5 July 2021 at 18:59:09 UTC, jfondren wrote: On Monday, 5 July 2021 at 18:53:27 UTC, jfondren wrote: If you replace the findAmong call with `[letter].findAmong(alphabet)`, this works. Consider: ```d import std; void main() { import std.ascii : alphabet = letters; string wordExample = "Book."; foreach (letter; wordExample) { writefln!"%c is %sa letter"(letter, [letter].findAmong(alphabet).length ? "" : "not "); writefln!"%c is %sa letter"(letter, alphabet.canFind(letter) ? "" : "not "); } writeln("___>>___finally some letters".findAmong(alphabet)); } ``` If I use `[letter].findAmong(alphabet)` in my code, it considers a dot (.) punctuation character as a letter. You can see it here: https://run.dlang.io/is/YWmaXU
Re: Find a char among string (string.findAmong.char)
On Monday, 5 July 2021 at 18:53:27 UTC, jfondren wrote: If you replace the findAmong call with `[letter].findAmong(alphabet)`, this works. Consider: ```d import std; void main() { import std.ascii : alphabet = letters; string wordExample = "Book."; foreach (letter; wordExample) { writefln!"%c is %sa letter"(letter, [letter].findAmong(alphabet).length ? "" : "not "); writefln!"%c is %sa letter"(letter, alphabet.canFind(letter) ? "" : "not "); } writeln("___>>___finally some letters".findAmong(alphabet)); } ```
Re: Find a char among string (string.findAmong.char)
On Monday, 5 July 2021 at 18:45:10 UTC, BoQsc wrote: I get an error when I try to find that letter is among alphabet. onlineapp.d(13): Error: template `std.algorithm.searching.findAmong` cannot deduce function from argument types `!()(immutable(char), immutable(string))`, candidates are: /dlang/dmd/linux/bin64/../../src/phobos/std/algorithm/searching.d(2694): `findAmong(alias pred = "a == b", InputRange, ForwardRange)(InputRange seq, ForwardRange choices)` with `pred = "a == b", InputRange = immutable(char), ForwardRange = string` must satisfy the following constraint: ` isInputRange!InputRange` This is the code: You can run it at: https://run.dlang.io/is/5cvuUZ import std; void main() { alias alphabet = letters; char[26] letters = ['a','b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']; string wordExample = "Book."; foreach (letter; wordExample){ if (letter.findAmong(alphabet)){ write("found"); } write(letter); } } If you replace the findAmong call with `[letter].findAmong(alphabet)`, this works. Both arguments to findAmong need to be ranges; you're calling it here against an immutable(char). As it says in the error: ``` from argument types `!()(immutable(char), immutable(string))` ``` immutable(char) looks a lot like immutable(char)[], but the latter is a string and the former is just a singular char.
Find a char among string (string.findAmong.char)
I get an error when I try to find that letter is among alphabet. onlineapp.d(13): Error: template `std.algorithm.searching.findAmong` cannot deduce function from argument types `!()(immutable(char), immutable(string))`, candidates are: /dlang/dmd/linux/bin64/../../src/phobos/std/algorithm/searching.d(2694): `findAmong(alias pred = "a == b", InputRange, ForwardRange)(InputRange seq, ForwardRange choices)` with `pred = "a == b", InputRange = immutable(char), ForwardRange = string` must satisfy the following constraint: ` isInputRange!InputRange` This is the code: You can run it at: https://run.dlang.io/is/5cvuUZ import std; void main() { alias alphabet = letters; char[26] letters = ['a','b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']; string wordExample = "Book."; foreach (letter; wordExample){ if (letter.findAmong(alphabet)){ write("found"); } write(letter); } }
Re: github copilot and dlang
On Monday, 5 July 2021 at 15:56:38 UTC, Antonio wrote: Has someone tried github copilot (https://copilot.github.com/) with dlang? Access to the preview could be requested and, I think, main dlang team members could bypass the waitlist easily. I suspect that the "low" volume of dlang code (used to train OpenAI) compared to other languages could impact in the support (if there is any). Anyway, it could be really interesting to see how Copilot faces templates, traits, ... I was wondering the same, but I haven't gotten the chance to try it - still on wait list since last week. On the topic of GH waitlists, I'm still waiting for access to their Codespaces feature since December of last year. I'd love to build a codespace template for D, along the lines of the setup-dlang GH action.
Re: Remove array element within function
On 7/5/21 8:14 AM, Rekel wrote: > On Monday, 5 July 2021 at 14:22:24 UTC, jfondren wrote: >> What use of long? >> >> remove returns the same type of range as it gets: > > My apology, I meant to say countUntil instead of remove in that context. countUntil says it returns ptrdiff_t, which is the signed version of size_t: https://dlang.org/spec/type.html#ptrdiff_t size_t is an alias of 'long' on 64-bit systems (it would be 'int' on 32-bit systems). So, you needen't guess the type of count; it is ptrdiff_t :) ptrdiff_t index = countUntil(a, element); However, its common to use 'auto' for return types of most algorithms as they may not be mentionable (although, not in this case; see Voldemort types): auto index = countUntil(a, element); And I always think of 'const' first to prevent silly mistakes: const index = countUntil(a, element); Some other people think of 'immutable' first in the same way: immutable index = countUntil(a, element); All should work in this case but 'const' and 'immutable' will have a "turtles all the way down" behavior which may be cumbersome in some case e.g. when the type has indirections. Ali
github copilot and dlang
Has someone tried github copilot (https://copilot.github.com/) with dlang? Access to the preview could be requested and, I think, main dlang team members could bypass the waitlist easily. I suspect that the "low" volume of dlang code (used to train OpenAI) compared to other languages could impact in the support (if there is any). Anyway, it could be really interesting to see how Copilot faces templates, traits, ...
Re: Remove array element within function
Oh my, thank you both, that mostly cleared up my confusion, I had no clue this was struct related. I'll be reading the references you gave me & probably submitting an issue
Re: Remove array element within function
On Monday, 5 July 2021 at 14:22:24 UTC, jfondren wrote: What use of long? remove returns the same type of range as it gets: My apology, I meant to say countUntil instead of remove in that context.
Re: Download a file into array (using std.net.curl.download)
On Monday, 5 July 2021 at 14:57:20 UTC, BoQsc wrote: Let's say I can't store information into files. Is it possible to download a file into an array. Yes, use [`get`](https://dlang.org/phobos/std_net_curl.html#.get): ```d import std.net.curl; void main() { char[] content = get("https://gist.githubusercontent.com/deekayen/4148741/raw/98d35708fa344717d8eee15d11987de6c8e26d7d/1-1000.txt;); } ```
Download a file into array (using std.net.curl.download)
Let's say I can't store information into files. Is it possible to download a file into an array. This is what I have now. It saves a download into a file named: file.txt import std; import std.net.curl; void main() { writeln("Hello D"); download("https://gist.githubusercontent.com/deekayen/4148741/raw/98d35708fa344717d8eee15d11987de6c8e26d7d/1-1000.txt;, "file.txt"); } Also run.dlang.io seems to be blocking and not letting me to run curl requests. I'm feeling sad right now. https://run.dlang.io/?compiler=dmd=import%20std;%0Aimport%20std.net.curl;%0A%0A%0Avoid%20main()%0A%7B%0A%20%20%20%20writeln(%22Hello%20D%22);%0A%20%20%20%20download(%22https:%2F%2Fgist.githubusercontent.com%2Fdeekayen%2F4148741%2Fraw%2F98d35708fa344717d8eee15d11987de6c8e26d7d%2F1-1000.txt%22,%20%22.%22);%0A%7D
Re: Remove array element within function
On Monday, 5 July 2021 at 14:30:11 UTC, Mike Parker wrote: You never copy the contents of a dynamic array/slice. That only comes into play with static arrays: I should rephrase that. You aren't going to copy the contents of an array/slice just by passing it to a function.
Re: Remove array element within function
On Monday, 5 July 2021 at 13:34:50 UTC, Rekel wrote: Ah, ref, thanks, I didn't know if that would work as I was confused since arrays themselves are kind of already pointers. Except they're not :-) Think of them as struct instances with length and pointer fields. That's actually what they are. I believe for setting length it was both when I wanted to initialize the array to a certain length (instead of having that inline with the declaration) ```d int[] arr; arr = new int[](100); ``` & when I want to clear the array of all data. Though I also found threads in which people mentioned changing the length manually after calling remove. You shouldn't need to adjust the length after remove as long as you assign the return value to the original array. And actually, I didn't pay close enough attention to your original function. You didn't do that. It should be: ```d void removeItem(ref int[] a){ ... a = a.remove(index); } ``` Or this: ```d int[] removeElement(int[] a) { ... return a.remove(index); } // Later elems = removeElement(elems); ``` The copies were mostly at play in scenarios such as this one, but also when I'm appending lists to lists, in a `list.addAll(list2);` scenario. Though I guess I'm just not used to reassigning on the list variable after doing things with it. You never copy the contents of a dynamic array/slice. That only comes into play with static arrays: ```d void someFunc1(int[3] a) {} void someFunc2(int[] a); int[3] a = [1, 2, 3]; someFunc1(a);// This copies all the elements someFunc2(a);// This implicitly slices the array ``` Here are some resources that may help: https://ddili.org/ders/d.en/arrays.html https://ddili.org/ders/d.en/slices.html https://dlang.org/articles/d-array-article.html https://dlang.org/blog/2017/03/20/dont-fear-the-reaper/ Pay particular attention to the append operator + reserve. That plus the ability to slice without copying is where the real power of D's arrays lies. Then look into `std.array.Appender` when you have lots of items to append: https://dlang.org/phobos/std_array.html#Appender Also, is my use of long correct? The documentation wasn't very clear on the return type of remove, just calling it a 'number'. If you look in the function signature, it returns `ptrdiff_t`: https://dlang.org/phobos/std_algorithm_searching.html#countUntil Which is defined in `object.d`: https://github.com/dlang/druntime/blob/master/src/object.d#L61 It's `long` on 64-bit systems and `int` on 32-bit. So you can use `ptrdiff_t` or just `auto`: ```d auto index = countUntil(...); ``` Again thanks for your help That's why we're here :-)
Re: Remove array element within function
On Monday, 5 July 2021 at 13:41:59 UTC, Rekel wrote: I'm not sure if this is the place to talk about it, but on the same topic it's a little strange to me neither the Dlang Tour nor the arrays spec page mention removing elements. Even though basically everyone is going to use it sooner or later (most likely sooner). Is that because it's part of the library? That's the only reason I could think of, while in a way I could make that argument for appending in the case it hadn't been given the `~` and `~=` operators. I had no involvement in creating the Tour, so I could only guess why it isn't covered. But if you think it should be, you can always submit an issue: https://github.com/dlang-tour/core/issues
Re: Remove array element within function
On Monday, 5 July 2021 at 13:10:55 UTC, Rekel wrote: Am I the only one slightly unamused by how arrays/ranges work? They keep backfiring on me, or require weird additions other languages wouldn't require such as manually changing .length, or worrying about what operation returns a copy etc. (Kind of jealous of java's ease here) It's easy to start to learn about D's dynamic arrays and ranges and then welcome them as false friends. They're genuinely great, but they're not quite the same thing as what you recognized them as, and as long as this confusion persists, frustration will occur. You were probably expecting dynamic arrays to work like a class: ```d import std.array, std.algorithm; class Array { int[] data; this(int[] xs) { data = xs; } } void removeEvens(Array a) { a.data = a.data.filter!"a%2".array; } unittest { auto h = new Array([1, 2, 4, 5]); h.removeEvens; assert(h.data == [1, 5]); } ``` removeEvens gets a reference to a thing, it mutates it, job done. An int[] parameter though is a copy of a slice. It's more like like this struct: ```d import std.array, std.algorithm; struct Array { int* data; size_t length; this(int[] xs) { data = xs.ptr; length = xs.length; } } void removeEvens(Array a) { for (size_t i = 0; i < a.length; ++i) { if (a.data[i] % 2 == 0) { a.data[0 .. a.length].remove!(SwapStrategy.stable)(i); a.length--; i--; // ! } } } unittest { auto h = Array([1, 2, 4, 5]); h.removeEvens; assert(h.data[0 .. h.length] == [1, 5, 5, 5]); } ``` before removeEvens exits, its copy of a has become the intended 2-length array with only odd elements, but that copy is thrown away and the original 4-length array just sees its memory changed to have a 2-array prefix of its old odd elements, and then it has a suffix of garbage. Of ranges, they look like visual pipelines of functions that directly alter data that flows through them, but their actual result is *the pipeline* and not the data. Range functions take shorter bits of pipeline as an argument and produce longer bits of pipeline as a result, and their errors are all pipeline related: "I only connect to sorted ranges", "I only connect to randomly-accessible ranges", etc. On Monday, 5 July 2021 at 13:34:50 UTC, Rekel wrote: Also, is my use of long correct? The documentation wasn't very clear on the return type of remove, just calling it a 'number'. What use of long? remove returns the same type of range as it gets: ``` Range remove(SwapStrategy s = SwapStrategy.stable, Range, Offset...)(Range range, Offset offset) ^ ^ ^ ``` The first Range is the return type, the second Range is a template type parameter, and the third Range is the argument type. When you remove from an int[] you're calling a specialized function that returns an int[]
Re: Remove array element within function
I'm not sure if this is the place to talk about it, but on the same topic it's a little strange to me neither the Dlang Tour nor the arrays spec page mention removing elements. Even though basically everyone is going to use it sooner or later (most likely sooner). Is that because it's part of the library? That's the only reason I could think of, while in a way I could make that argument for appending in the case it hadn't been given the `~` and `~=` operators.
Re: Remove array element within function
Ah, ref, thanks, I didn't know if that would work as I was confused since arrays themselves are kind of already pointers. On Monday, 5 July 2021 at 13:18:55 UTC, Mike Parker wrote: In what situations do you need to manually change the length? Where do you worry about copies? It's possible there's something you're overlooking. I believe for setting length it was both when I wanted to initialize the array to a certain length (instead of having that inline with the declaration) & when I want to clear the array of all data. Though I also found threads in which people mentioned changing the length manually after calling remove. The copies were mostly at play in scenarios such as this one, but also when I'm appending lists to lists, in a `list.addAll(list2);` scenario. Though I guess I'm just not used to reassigning on the list variable after doing things with it. Also, is my use of long correct? The documentation wasn't very clear on the return type of remove, just calling it a 'number'. Again thanks for your help
Re: Remove array element within function
On Monday, 5 July 2021 at 13:10:55 UTC, Rekel wrote: Am I the only one slightly unamused by how arrays/ranges work? They keep backfiring on me, or require weird additions other languages wouldn't require such as manually changing .length, or worrying about what operation returns a copy etc. (Kind of jealous of java's ease here) D's arrays are friggin' awesome. I don't think they're any more difficult than in Java. In what situations do you need to manually change the length? Where do you worry about copies? It's possible there's something you're overlooking.
Re: Remove array element within function
On Monday, 5 July 2021 at 13:10:55 UTC, Rekel wrote: But what do you do when you have?: ```d void function(int[] a){ . . . long index = countUntil(a, element); a.remove(index); } ``` ```d void function(ref int[] a) { ... } ``` An array is effectively a length/pointer pair that you are passing by value. If you want to do anything that affects either property, you need to pass by ref.
Remove array element within function
Is there an easy way to remove elements from an array passed in as a parameter? Every example I find does something along the lines of: ```d int[] a = ... long index = countUntil(a, element); a = a.remove(index); But what do you do when you have?: ```d void function(int[] a){ . . . long index = countUntil(a, element); a.remove(index); } ``` I assume I can't use a=a.remove(index), as I'm guessing this will only change the array inside the function itself, not the array that's actually used to call the function. Am I the only one slightly unamused by how arrays/ranges work? They keep backfiring on me, or require weird additions other languages wouldn't require such as manually changing .length, or worrying about what operation returns a copy etc. (Kind of jealous of java's ease here)