HeadUnshared in core.atomic
Hello, I was recently exposed to this template in core.atomic: private { template HeadUnshared(T) { static if( is( T U : shared(U*) ) ) alias shared(U)* HeadUnshared; else alias T HeadUnshared; } } Could someone please explain/elaborate on what this is doing, and why it's necessary and used so often in core.atomic? Thanks, Mike
Re: Multiple alias this failed workaround...obscure error message
On Wed, 11 Jun 2014 23:01:31 + matovitch via Digitalmars-d-learn wrote: > About alias working with identifier but not with (runtime) > expression. Alias should work with compile time expression like > map!(x=>2*x) right ? So a static cast should work isn't it ? > (though static_cast doesn't exist in D :/) alias is for _symbols_, not expressions. http://dlang.org/declaration.html#alias I really don't think that what you're trying to do is going to work. - Jonathan M Davis
Re: Working on a library: request for code review
On Wednesday, 11 June 2014 at 18:29:27 UTC, Mike wrote: Hello. Here's the link to the repo: http://bit.ly/1mIuGhv Hi, sorry didn't read through your code yet, but while ago I wrote some encoders/decoders for jpeg and png (https://github.com/callumenator/imaged, haven't compiled it in a while). Might it be worth stitching things together into a proper image processing package? Cheers, cal
Re: Basics of calling C from D
On Wednesday, 11 June 2014 at 14:45:22 UTC, simendsjo wrote: I must say I really like your writing-style as well as the down-to-earth and precise and concise presentation of the material. So kudos to you! thanks, don't forget to tell that to amazon review readers too :P Really looking forward to reading some of the more advanced material as well as seeing your dconf presentation. Based on the pace of dconf posting, it'll probably be early July before it is online :(
Re: Multiple alias this failed workaround...obscure error message
If I quote de documentation : "Any casting of a class reference to a derived class reference is done with a runtime check to make sure it really is a downcast. null is the result if it isn't. Note: This is equivalent to the behavior of the dynamic_cast operator in C++." I explicitly kept track of the derived type as template parameter so that the cast could be performed statically (this is absurd :P).
Re: Multiple alias this failed workaround...obscure error message
On Wednesday, 11 June 2014 at 20:53:21 UTC, Jonathan M Davis via Digitalmars-d-learn wrote: I don't believe that it's legal to use a cast in an alias declaration, and that's certainly what the error seems to be indicating. Also, using ref in a cast is definitely illegal regardless of where the cast is. ref is not part of a type. The only places that you can use it are function parameters, return types, and foreach variables. If you want to do anything like you seem to be trying to do, you're going to have to alias a function which does the cast for you rather than try and alias the variable itself. I also don't see anything here that would work as any kind of multiple alias this. - Jonathan M Davis Thank you, I was assuming D worked as C++ but ref not being part of type is so much better ! (According to Marc Schütz your solution isn't doing so well.) About alias working with identifier but not with (runtime) expression. Alias should work with compile time expression like map!(x=>2*x) right ? So a static cast should work isn't it ? (though static_cast doesn't exist in D :/)
Re: modulo Strangeness?
modulo of a negative number can give some surprising results. A negative index in that array would cause it to throw a range error, so my guess is that's what you're getting. If you do %array.length though it becomes an unsigned math and thus will never be negative, explaining the different result. Remember btw that when foreaching over an array, the value you get is the number in the array, not the index.
Re: modulo Strangeness?
On Wednesday, 11 June 2014 at 22:32:45 UTC, Taylor Hillegeist wrote: I have a simpleish bit of code here that always seems to give me an error, and i can't figure out quite why. modulo takes the sign of the dividend: http://en.wikipedia.org/wiki/Modulo_operation#Common_pitfalls It works with length because you introduce a signed -> unsigned conversion.
Re: modulo Strangeness?
On Wednesday, 11 June 2014 at 22:38:02 UTC, Taylor Hillegeist wrote: On Wednesday, 11 June 2014 at 22:35:39 UTC, Taylor Hillegeist wrote: On Wednesday, 11 June 2014 at 22:32:45 UTC, Taylor Hillegeist wrote: I have a simpleish bit of code here that always seems to give me an error, and i can't figure out quite why. If I have a constant 43 in the modulo if breaks. however if i use points.length it seems to be ok? import std.stdio; void main(){ int points[43] = [0, 1153, 1905, 1996, 1392, 305, -888,-1773,-2041,-1600, -603, 603, 1600,2041, 1773, 888, -305,-1392,-1996,-1905,-1153, -0,1153, 1905, 1996, 1392,305, -888,-1773,-2041,-1600, -603, 603, 1600, 2041, 1773, 888, -305,-1392,-1996,-1905,-1153,0]; foreach(int x; points){ writeln("List Value: ",points[(x%43)],"\t"); } } Perhaps i am stupid 0..points.length lol? i've been looking at this too long. foreach(uint x; points){ writeln("List Value: ",points[(x%43)],"\t"); } this must work because its a different type than an element in points[] Negative indexes are possible with modulo... that is why i am getting breaking... sorry all.
Re: modulo Strangeness?
On Wednesday, 11 June 2014 at 22:35:39 UTC, Taylor Hillegeist wrote: On Wednesday, 11 June 2014 at 22:32:45 UTC, Taylor Hillegeist wrote: I have a simpleish bit of code here that always seems to give me an error, and i can't figure out quite why. If I have a constant 43 in the modulo if breaks. however if i use points.length it seems to be ok? import std.stdio; void main(){ int points[43] = [0, 1153, 1905, 1996, 1392, 305, -888,-1773,-2041,-1600, -603, 603, 1600,2041, 1773, 888, -305,-1392,-1996,-1905,-1153, -0,1153, 1905, 1996, 1392,305, -888,-1773,-2041,-1600, -603, 603, 1600, 2041, 1773, 888, -305,-1392,-1996,-1905,-1153,0]; foreach(int x; points){ writeln("List Value: ",points[(x%43)],"\t"); } } Perhaps i am stupid 0..points.length lol? i've been looking at this too long. foreach(uint x; points){ writeln("List Value: ",points[(x%43)],"\t"); } this must work because its a different type than an element in points[]
Re: modulo Strangeness?
On Wednesday, 11 June 2014 at 22:32:45 UTC, Taylor Hillegeist wrote: I have a simpleish bit of code here that always seems to give me an error, and i can't figure out quite why. If I have a constant 43 in the modulo if breaks. however if i use points.length it seems to be ok? import std.stdio; void main(){ int points[43] = [0, 1153, 1905, 1996, 1392, 305, -888,-1773,-2041,-1600, -603, 603, 1600,2041, 1773, 888, -305,-1392,-1996,-1905,-1153, -0,1153, 1905, 1996, 1392,305, -888,-1773,-2041,-1600, -603, 603, 1600, 2041, 1773, 888, -305,-1392,-1996,-1905,-1153,0]; foreach(int x; points){ writeln("List Value: ",points[(x%43)],"\t"); } } Perhaps i am stupid 0..points.length lol? i've been looking at this too long.
modulo Strangeness?
I have a simpleish bit of code here that always seems to give me an error, and i can't figure out quite why. If I have a constant 43 in the modulo if breaks. however if i use points.length it seems to be ok? import std.stdio; void main(){ int points[43] = [0, 1153, 1905, 1996, 1392, 305, -888,-1773,-2041,-1600, -603, 603, 1600,2041, 1773, 888, -305,-1392,-1996,-1905,-1153, -0,1153, 1905, 1996, 1392,305, -888,-1773,-2041,-1600, -603, 603, 1600, 2041, 1773, 888, -305,-1392,-1996,-1905,-1153,0]; foreach(int x; points){ writeln("List Value: ",points[(x%43)],"\t"); } }
Re: Basics of calling C from D
On 11/06/14 16:22, Adam D. Ruppe via Digitalmars-d-learn wrote: On Wednesday, 11 June 2014 at 14:11:04 UTC, simendsjo wrote: I believe the correct answer should be "Buy my book!". ah, of course! I should just make a .sig file lol http://www.packtpub.com/discover-advantages-of-programming-in-d-cookbook/book chapter 4 talks about this kind of thing :P My copy arrived today. Life is clearly going to be more fun. :-)
Re: Cannot understand deprecation message recently added to Phobos
https://github.com/D-Programming-Language/druntime/pull/825 I updated https://github.com/nordlow/justd/blob/master/pprint.d with two versions of shortDurationString(). DMD picks the right one using static if (__VERSION__ >= 2066L) // new else // old I hope I it right this time.
Re: Cannot understand deprecation message recently added to Phobos
You can safely change your code to use total!"weeks" instead. Ok. Thx
Re: Cannot understand deprecation message recently added to Phobos
On Wednesday, 11 June 2014 at 21:06:42 UTC, Kapps wrote: On Wednesday, 11 June 2014 at 20:59:25 UTC, Nordlöw wrote: Can somebody explain the meaning of split in the error message Deprecation: function core.time.Duration.weeks is deprecated - Please use split instead. weeks was too frequently confused for total!"weeks". given by function shortDurationString() at https://github.com/nordlow/justd/blob/master/pprint.d https://github.com/D-Programming-Language/druntime/pull/825 Ok, I replaced immutable weeks = dur.weeks(); with immutable weeks = dur.split!"weeks"; but my code using it if (weeks) { if (weeks < 52) fails as pprint.d(39,9): Error: expression weeks of type immutable(SplitUnits) does not have a boolean value pprint.d(41,13): Error: incompatible types for ((weeks) < (52)): 'immutable(SplitUnits)' and 'int' Sorry but I don't understand what to do with the struct SplitUnits.
Re: Cannot understand deprecation message recently added to Phobos
On Wed, 11 Jun 2014 16:59:24 -0400, Nordlöw wrote: Can somebody explain the meaning of split in the error message Deprecation: function core.time.Duration.weeks is deprecated - Please use split instead. weeks was too frequently confused for total!"weeks". given by function shortDurationString() at https://github.com/nordlow/justd/blob/master/pprint.d Actually, that may not be a valid deprecation message. All the other unit functions do not get the total number of units, but there are not larger units supported by Duration. In fact, dur.weeks was the equivalent of dur.total!"weeks". You can safely change your code to use total!"weeks" instead. Jonathan, can we update this deprecation message? The function is going away because of the confusion with smaller units. For example, dur.seconds could be confused as "the number of seconds in this duration", but it's really "the number of seconds that do not make up a whole minute in this duration". Basically, it's the mod remainder for the seconds. -Steve
Re: Multiple alias this failed workaround...obscure error message
On Wednesday, 11 June 2014 at 18:07:44 UTC, matovitch wrote: source/app.d(5): Error: basic type expected, not cast source/app.d(5): Error: no identifier for declarator int source/app.d(5): Error: semicolon expected to close alias declaration source/app.d(5): Error: Declaration expected, not 'cast' Error: DMD compile run failed with exit code 1 This particular error stems from the fact that you can only define `alias this` to a symbol, but you are using a cast, which is an expression. For this, a helper function is required: class A(Derived) { auto castHelper() { return (cast(Derived) this).x; } } (Note that you also need to remove the `ref` inside the cast, because classes are already reference types, and the `ref` would mean a reference to a reference.) But this still doesn't work, as then the compiler crashes while it tries to do the cast, iff the alias this is there. This works: import std.stdio; class A(Derived) { auto castHelper() { return (cast(Derived) this).x; } //alias castHelper this; } class B : A!B { float x; } class C : A!C { int x; } void main() { auto b = new B; b.x = 0.5; auto c = new C; c.x = 42; float f = b.castHelper; writeln("b = ", f); int i = c.castHelper; writeln("c = ", i); } But if you enable the `alias this` line, it segfaults. You don't even need to reduce the calls to `castHelper` in the main function, it evidently doesn't get that far.
Re: Cannot understand deprecation message recently added to Phobos
On Wednesday, 11 June 2014 at 20:59:25 UTC, Nordlöw wrote: Can somebody explain the meaning of split in the error message Deprecation: function core.time.Duration.weeks is deprecated - Please use split instead. weeks was too frequently confused for total!"weeks". given by function shortDurationString() at https://github.com/nordlow/justd/blob/master/pprint.d https://github.com/D-Programming-Language/druntime/pull/825
Cannot understand deprecation message recently added to Phobos
Can somebody explain the meaning of split in the error message Deprecation: function core.time.Duration.weeks is deprecated - Please use split instead. weeks was too frequently confused for total!"weeks". given by function shortDurationString() at https://github.com/nordlow/justd/blob/master/pprint.d
Re: Source File and Position of User Defined Type
I don't believe this is possible. Perhaps you would be able to How about adding __traits(sourceFile, T) __traits(sourceLine, T) __traits(sourceColumn, T) to DMD? T of course must be a user-defined type.
Re: Multiple alias this failed workaround...obscure error message
> Sent: Wednesday, June 11, 2014 at 8:07 PM > From: "matovitch via Digitalmars-d-learn" > To: digitalmars-d-learn@puremagic.com > Subject: Multiple alias this failed workaround...obscure error message > > I was looking for a workaround to multiple alias this (or > opImplicitCast) the following trick doesn't work (why shouldn't > it ?). The error message is quite obscure to me. > > > import std.stdio; > > class A(Derived) > { > alias cast(ref Derived)(this).x this; > } > > class B : A!B > { > float x; > } > > class C : A!C > { > int x; > } > > void main() > { > B b; > b.x = 0.5; > > float f; > f = b; > } > > > output : > > source/app.d(5): Error: basic type expected, not cast > source/app.d(5): Error: no identifier for declarator int > source/app.d(5): Error: semicolon expected to close alias > declaration > source/app.d(5): Error: Declaration expected, not 'cast' > Error: DMD compile run failed with exit code 1 I don't believe that it's legal to use a cast in an alias declaration, and that's certainly what the error seems to be indicating. Also, using ref in a cast is definitely illegal regardless of where the cast is. ref is not part of a type. The only places that you can use it are function parameters, return types, and foreach variables. If you want to do anything like you seem to be trying to do, you're going to have to alias a function which does the cast for you rather than try and alias the variable itself. I also don't see anything here that would work as any kind of multiple alias this. - Jonathan M Davis
Re: Source File and Position of User Defined Type
On Tuesday, 10 June 2014 at 20:58:41 UTC, Nordlöw wrote: Is there a way to, programatically (trait), lookup the source file and position of a user defined type either dynamically or, even better, statically? I don't believe this is possible. Perhaps you would be able to generate the .json file and use that at runtime, but I don't know if even that will handle situations like using mixins.
Working on a library: request for code review
Hello. I am new to D and I must admit I really like the language. In my opinion it takes the best from C++ and, say, Python and combines it really elegantly. Great work! I am currently working on my first library in D - related to TARGA image format. Here's the link to the repo: http://bit.ly/1mIuGhv It's a work-in-progress case: at the moment the library does what I need for my other projects, but there is a couple of things that I want to add/fix soon. Perhaps someone could have a look at the code and point out some obvious traps that I fell into etc. Any feedback would be great! Best regards, Mike
Re: Splitting Ranges using Lambda Predicates
On 06/11/14 16:05, monarch_dodra via Digitalmars-d-learn wrote: > Well, (IMO) it's a problem with no real solution. But for what it's worth, > most (if not all) of the algorithms in the standard lib know how to handle > strings efficiently and correctly (split, find, etc...). Things only start > getting funny once you start mixing indexing and element counts. If the recommended approach for writing a really trivial string transformation is to copy and modify ~60 lines of std lib code then something is very wrong. The consequence is that such code will often end up being eager, as it's much easier to write it that way... That is why, after seeing your solution, I wrote the most compact lazy version I could think of - let's not scare people away from using ranges. AFAIUI the OP basically wanted a version of splitter that does not eat the separators and a predicate that keeps around previous state. The latter can already be achieved via a lambda, so the missing bit is an optional splitter template parameter (eg consume=false). So at least in this case the problem could be easily handled. artur
escape string into a C style string litteral (pasteable in C code)
Is there an existing way to do it or do I have to roll my own? unittest{ assert(escapeC(`a"bc\ndef`~"\n") == `"a\"bc\\ndef\n"`); } Likewise with escapeD (pastable in D code), which would return something like: `r"..."` for more readability
Multiple alias this failed workaround...obscure error message
I was looking for a workaround to multiple alias this (or opImplicitCast) the following trick doesn't work (why shouldn't it ?). The error message is quite obscure to me. import std.stdio; class A(Derived) { alias cast(ref Derived)(this).x this; } class B : A!B { float x; } class C : A!C { int x; } void main() { B b; b.x = 0.5; float f; f = b; } output : source/app.d(5): Error: basic type expected, not cast source/app.d(5): Error: no identifier for declarator int source/app.d(5): Error: semicolon expected to close alias declaration source/app.d(5): Error: Declaration expected, not 'cast' Error: DMD compile run failed with exit code 1
Re: crt1.o: could not read symbols: Bad value
On Wednesday, 11 June 2014 at 17:11:51 UTC, Tim wrote: On Wednesday, 11 June 2014 at 10:09:50 UTC, FreeSlave wrote: I conclude that because I have similar errors when trying to build 64-bit library on 32-bit system. /usr/bin/ld: /usr/lib/x86_64-linux-gnu/libphobos2.a(format_712_5b3.o): relocation R_X86_64_32 against `.rodata' can not be used when making a shared object; recompile with -fPIC /usr/lib/x86_64-linux-gnu/libphobos2.a: error adding symbols: Bad value collect2: error: ld returned 1 exit status --- errorlevel 1 But paths in your error log look like you're on x64, so it's probably not the case. Yes, I'm using a x64 system (CentOS 6.5), but I also use dmd64. It seems that -defaultlib=libphobos2.so solved the problem. When I use the following compile command: dmd test.d -shared -defaultlib=libphobos2.so I don't get any error. I hope the shared object works as expect...
Re: crt1.o: could not read symbols: Bad value
On Wednesday, 11 June 2014 at 10:09:50 UTC, FreeSlave wrote: I conclude that because I have similar errors when trying to build 64-bit library on 32-bit system. /usr/bin/ld: /usr/lib/x86_64-linux-gnu/libphobos2.a(format_712_5b3.o): relocation R_X86_64_32 against `.rodata' can not be used when making a shared object; recompile with -fPIC /usr/lib/x86_64-linux-gnu/libphobos2.a: error adding symbols: Bad value collect2: error: ld returned 1 exit status --- errorlevel 1 But paths in your error log look like you're on x64, so it's probably not the case. Yes, I'm using a x64 system (CentOS 6.5), but I also use dmd64.
Re: Decimal type documentation
On Tuesday, 10 June 2014 at 15:52:29 UTC, Poyeyo wrote: Hello, has anyone used this https://github.com/andersonpd/decimal implementation? I'm learning D and want to know where to start for the decimal (or bigfloat) stuff. The goal is to be able to read and write some data from a SQL DB with a decimal(10,2) field. I recently tried this implementation without any success. I always got conflicts. I had the same problem. I had to read a decimal(32,8) value from my database. I figured out that the best solution for my case is to simply use the phobos implementation for BigInt. I'm simply converting the decimal-value to an integer (using multiplication) and use this instead of solving all the conflicts of the library above.
Node.js async/threads and shared in D
I have a Node.js module written in D and exposed through C++ interface. I'd like to implement a proper async API which is pretty straightforward using libuv in the C++ glue part. On the D side I have a data structure that's build once and then queried from Node (possibly torn down and rebuild later). Since it will be queried asynchronously, it will be called from multiple threads. It is build using and stores inside a bunch of helper classes. Am I correct to assume that for this data structure to be available across threads it and every class it touches have to be marked shared? What about types that I have no control of, like arrays? Are they inherently shared? I did read "Lock-Free Coding with shared classes" from TDPL, but it has a rather short example and the structure there is both read and written from multiple threads. Thanks for any pointers.
Re: Basic dynamic array question. Use of new versus no new.
On Tue, 10 Jun 2014 23:28:16 -0400, Kapps wrote: On Wednesday, 11 June 2014 at 02:30:01 UTC, WhatMeWorry wrote: In Mr. Cehreli's book it says Additionally, the length of dynamic arrays can be changed by assigning a value to this property: int[] array; // initially empty array.length = 5; // now has 5 elements while in Mr. Alexandrescu's book, it says To create a dynamic array, use a new expression (§ 2.3.6.1 on page 51) as follows: int[] array = new int[20]; // Create an array of 20 integers Could someone please compare and contrast the two syntaxes. I presume the "new" command places the 2nd array in heap memory. They both do the same, create an array of n integers on the heap and set the length to n. You can also use .capacity instead of .length to allocate n but not adjust length. This is slightly incorrect. Here is the difference as I see it: 1. Setting length goes through the extra steps of checking the current length, looking up the existing block (obviously with initial value of null, there isn't one), and allocating if necessary. A lot more code is executed. 2. The 'new' call will ALWAYS allocate a new block, even if array previously had data in it. 3. The block size allocated is not always n, it could be more. 4. You meant 'reserve', not 'capacity'. capacity checks how many elements the block can support. Which way is easier/better? If you know you are starting with a blank array, then new is the way to go. This avoids any unnecessary extra checks for existing data. The second way is required if you may already have some data in the array (i.e. prior to setting the length, arr.length != 0). Also, I would recommend to use: auto array = new int[20] To avoid repeating the type. -Steve
Re: Basics of calling C from D
On Wednesday, 11 June 2014 at 14:28:49 UTC, belkin wrote: On Wednesday, 11 June 2014 at 14:02:08 UTC, John Colvin wrote: On Wednesday, 11 June 2014 at 13:52:09 UTC, belkin wrote: Example: I have this C function that is compiled into a library //File: factorial.h int factorial(int n); //File: factorial.c #include "factorial.h" int factorial(int n) { if(n!=1) return n*factorial(n-1); } Question: How do I use it from D? //File: blah.d extern(C) int factorial(int n); //coincidentally identical to the C declaration. void main() { assert(factorial(3) == 6); } $ gcc -c factorial.c -ofactorial.o $ dmd blah.d factorial.o $ ./blah or $ gcc -c factorial.c -ofactorial.o $ ar rcs libfactorial.a factorial.o $ dmd blah.d -L-lfactorial $ ./blah Basically, you just translate the header files from C to D, then link to the C implementation. See http://code.dlang.org/packages/dstep for automatic translation of headers. This is great. How practical (reliable ) is it to translate a large and complex header file like oci.h ( the interface for Oracle's database API ) to D? By hand it's just laborious, but it's very simple. Using dstep: It doesn't handle any pre-processor stuff, so a lot of complicated headers are out of the question. One approach is to run the pre-processor in gcc over the file, use dstep on the output, then reconstruct the conditional compilation stuff manually.
Re: Basics of calling C from D
On Wednesday, 11 June 2014 at 15:14:19 UTC, Colin wrote: On Wednesday, 11 June 2014 at 14:28:49 UTC, belkin wrote: On Wednesday, 11 June 2014 at 14:02:08 UTC, John Colvin wrote: On Wednesday, 11 June 2014 at 13:52:09 UTC, belkin wrote: Example: I have this C function that is compiled into a library //File: factorial.h int factorial(int n); //File: factorial.c #include "factorial.h" int factorial(int n) { if(n!=1) return n*factorial(n-1); } Question: How do I use it from D? //File: blah.d extern(C) int factorial(int n); //coincidentally identical to the C declaration. void main() { assert(factorial(3) == 6); } $ gcc -c factorial.c -ofactorial.o $ dmd blah.d factorial.o $ ./blah or $ gcc -c factorial.c -ofactorial.o $ ar rcs libfactorial.a factorial.o $ dmd blah.d -L-lfactorial $ ./blah Basically, you just translate the header files from C to D, then link to the C implementation. See http://code.dlang.org/packages/dstep for automatic translation of headers. This is great. How practical (reliable ) is it to translate a large and complex header file like oci.h ( the interface for Oracle's database API ) to D? You can do a lot of it by simply doing a find and replace in the file. For example, all C definitions of: unsigned char x become: ubyte x So a find an replace will do that for you quite easily. Other things like structs and typedefs are a bit more difficult to do with a find & replace. All the info you need is here anyway: wiki.dlang.org/Bind_D_to_C And here: http://dlang.org/interfaceToC.html
Re: Basics of calling C from D
On Wednesday, 11 June 2014 at 14:28:49 UTC, belkin wrote: On Wednesday, 11 June 2014 at 14:02:08 UTC, John Colvin wrote: On Wednesday, 11 June 2014 at 13:52:09 UTC, belkin wrote: Example: I have this C function that is compiled into a library //File: factorial.h int factorial(int n); //File: factorial.c #include "factorial.h" int factorial(int n) { if(n!=1) return n*factorial(n-1); } Question: How do I use it from D? //File: blah.d extern(C) int factorial(int n); //coincidentally identical to the C declaration. void main() { assert(factorial(3) == 6); } $ gcc -c factorial.c -ofactorial.o $ dmd blah.d factorial.o $ ./blah or $ gcc -c factorial.c -ofactorial.o $ ar rcs libfactorial.a factorial.o $ dmd blah.d -L-lfactorial $ ./blah Basically, you just translate the header files from C to D, then link to the C implementation. See http://code.dlang.org/packages/dstep for automatic translation of headers. This is great. How practical (reliable ) is it to translate a large and complex header file like oci.h ( the interface for Oracle's database API ) to D? You can do a lot of it by simply doing a find and replace in the file. For example, all C definitions of: unsigned char x become: ubyte x So a find an replace will do that for you quite easily. Other things like structs and typedefs are a bit more difficult to do with a find & replace. All the info you need is here anyway: wiki.dlang.org/Bind_D_to_C
Re: Basics of calling C from D
On 06/11/2014 04:22 PM, Adam D. Ruppe wrote: > On Wednesday, 11 June 2014 at 14:11:04 UTC, simendsjo wrote: >> I believe the correct answer should be "Buy my book!". > > ah, of course! I should just make a .sig file lol > > http://www.packtpub.com/discover-advantages-of-programming-in-d-cookbook/book > > > chapter 4 talks about this kind of thing :P Yeah, I was skimming through that chapter just minutes before I saw this post :) I must say I really like your writing-style as well as the down-to-earth and precise and concise presentation of the material. So kudos to you! Really looking forward to reading some of the more advanced material as well as seeing your dconf presentation.
Re: Basics of calling C from D
On Wednesday, 11 June 2014 at 14:22:51 UTC, Adam D. Ruppe wrote: On Wednesday, 11 June 2014 at 14:11:04 UTC, simendsjo wrote: I believe the correct answer should be "Buy my book!". ah, of course! I should just make a .sig file lol http://www.packtpub.com/discover-advantages-of-programming-in-d-cookbook/book chapter 4 talks about this kind of thing :P Thanks. This book is on my "To Buy" list.
Re: Basics of calling C from D
On Wednesday, 11 June 2014 at 14:11:04 UTC, simendsjo wrote: I believe the correct answer should be "Buy my book!". ah, of course! I should just make a .sig file lol http://www.packtpub.com/discover-advantages-of-programming-in-d-cookbook/book chapter 4 talks about this kind of thing :P
Re: passing predicates to lowerBound, or alternatively, how lazy is map?
So I was hoping for a learning experience, and I got it. With a little playing around, looking at phobos, and TDPL, I think I've figured out how lowerBound gets its predicate. It learns it from assumeSorted. So I can do this: order.assumeSorted!((a, b) => number[a] < number[b]) .lowerBound(order[4]) and I'll retrieve the indices of the 4 smallest numbers. Not useful for my current purposes, but is getting me closer to figuring out how higher level functions and ranges work. Thanks Andrew
Re: Basics of calling C from D
On Wednesday, 11 June 2014 at 14:02:08 UTC, John Colvin wrote: On Wednesday, 11 June 2014 at 13:52:09 UTC, belkin wrote: Example: I have this C function that is compiled into a library //File: factorial.h int factorial(int n); //File: factorial.c #include "factorial.h" int factorial(int n) { if(n!=1) return n*factorial(n-1); } Question: How do I use it from D? //File: blah.d extern(C) int factorial(int n); //coincidentally identical to the C declaration. void main() { assert(factorial(3) == 6); } $ gcc -c factorial.c -ofactorial.o $ dmd blah.d factorial.o $ ./blah or $ gcc -c factorial.c -ofactorial.o $ ar rcs libfactorial.a factorial.o $ dmd blah.d -L-lfactorial $ ./blah Basically, you just translate the header files from C to D, then link to the C implementation. See http://code.dlang.org/packages/dstep for automatic translation of headers. This is great. How practical (reliable ) is it to translate a large and complex header file like oci.h ( the interface for Oracle's database API ) to D?
Re: Basics of calling C from D
On 06/11/2014 03:54 PM, Adam D. Ruppe wrote: > On Wednesday, 11 June 2014 at 13:52:09 UTC, belkin wrote: >> Question: How do I use it from D? > > Write the prototype in your D file with extern(C): > extern(C) int factorial(int n); > > then just call the function normally in D. Make sure you include all the > C object files when you compile the D program too so it all links together. I believe the correct answer should be "Buy my book!".
Re: Splitting Ranges using Lambda Predicates
On Wednesday, 11 June 2014 at 13:44:25 UTC, Artur Skawina via Digitalmars-d-learn wrote: There is a reason why I never use D's std lib. artur Well, (IMO) it's a problem with no real solution. But for what it's worth, most (if not all) of the algorithms in the standard lib know how to handle strings efficiently and correctly (split, find, etc...). Things only start getting funny once you start mixing indexing and element counts.
Re: Splitting Ranges using Lambda Predicates
On 06/11/14 15:44, Artur Skawina wrote: > If, instead, you create a string-specific 'countUntil' that returns > a type that holds both the byte and code-point counts and implicitly > converts to the latter, then you can have a 'takeExactly' overload > that uses the extra info to avoid the unnecessary decoding and is able > to directly return slices. The overhead is minimal; one extra integer > that's passed around, and often completely eliminated by function inlining. > But now you don't need to write a string-specific version of every > algorithm. (Of course this description is slightly oversimplified) Well, for safety, you'd most likely want to pass around the range too (ie string slice, or just the pointer as the min-length is implied); so it's two size_ts, not one. Still, the overhead is tiny and the advantage of not having to special-case for strings everywhere is worth it. artur
Re: Basics of calling C from D
On Wednesday, 11 June 2014 at 13:52:09 UTC, belkin wrote: Question: How do I use it from D? Write the prototype in your D file with extern(C): extern(C) int factorial(int n); then just call the function normally in D. Make sure you include all the C object files when you compile the D program too so it all links together.
Re: Basics of calling C from D
On Wednesday, 11 June 2014 at 13:52:09 UTC, belkin wrote: Example: I have this C function that is compiled into a library //File: factorial.h int factorial(int n); //File: factorial.c #include "factorial.h" int factorial(int n) { if(n!=1) return n*factorial(n-1); } Question: How do I use it from D? //File: blah.d extern(C) int factorial(int n); //coincidentally identical to the C declaration. void main() { assert(factorial(3) == 6); } $ gcc -c factorial.c -ofactorial.o $ dmd blah.d factorial.o $ ./blah or $ gcc -c factorial.c -ofactorial.o $ ar rcs libfactorial.a factorial.o $ dmd blah.d -L-lfactorial $ ./blah Basically, you just translate the header files from C to D, then link to the C implementation. See http://code.dlang.org/packages/dstep for automatic translation of headers.
Basics of calling C from D
Example: I have this C function that is compiled into a library //File: factorial.h int factorial(int n); //File: factorial.c #include "factorial.h" int factorial(int n) { if(n!=1) return n*factorial(n-1); } Question: How do I use it from D?
Re: Splitting Ranges using Lambda Predicates
On 06/11/14 14:40, monarch_dodra via Digitalmars-d-learn wrote: > For example, you should avoid "countUntil" and "takeExactly" when dealing > with strings, since these are not O(1) operations, and don't actually return > string slices. EG: > string s = "someGGGreatVariableName".slicer().front; > Error: cannot implicitly convert expression > (slicer("someGGGreatVariableName").front()) of type Result to string That's a problem with D's string handling. For both examples and rarely called code, i always prefer correctness over performance. Of course if that code ends up being perf significant it could be further optimized by adding a specialization for D strings... > That's why the splitter code uses the more verbose "r.length - r.find!pred". ... but that's the wrong approach. You end up writing a string-specific (or -aware) special version for practically every algorithm... If, instead, you create a string-specific 'countUntil' that returns a type that holds both the byte and code-point counts and implicitly converts to the latter, then you can have a 'takeExactly' overload that uses the extra info to avoid the unnecessary decoding and is able to directly return slices. The overhead is minimal; one extra integer that's passed around, and often completely eliminated by function inlining. But now you don't need to write a string-specific version of every algorithm. (Of course this description is slightly oversimplified) There is a reason why I never use D's std lib. artur
Re: passing predicates to lowerBound, or alternatively, how lazy is map?
On Wednesday, 11 June 2014 at 13:25:03 UTC, John Colvin wrote: On Wednesday, 11 June 2014 at 13:20:37 UTC, Andrew Brown wrote: You are correct. assumeSorted and lowerBound will provide better time complexity than countUntil I'm sorry, one final question because I think I'm close to understanding. Map produces a forward range (lazily) but not a random access range? Therefore, lowerBound will move along this range until the pred is not true? This means it would be better to do: numbers.indexed(order).assumeSorted.lowerBound than: map(a => numbers[a])(order).assumeSorted.lowerBound as the lowerBound will be faster on a random access range as produced by indexed? map preserves the random access capabilities of it's source. An array is random access, therefore map applied to an array is also random access. There isn't any practical difference between indices.map!((i) => src[i])() and src.indexed(indices) that I know of. That's great, thank you very much for taking the time to answer.
Re: passing predicates to lowerBound, or alternatively, how lazy is map?
On Wednesday, 11 June 2014 at 13:20:37 UTC, Andrew Brown wrote: You are correct. assumeSorted and lowerBound will provide better time complexity than countUntil I'm sorry, one final question because I think I'm close to understanding. Map produces a forward range (lazily) but not a random access range? Therefore, lowerBound will move along this range until the pred is not true? This means it would be better to do: numbers.indexed(order).assumeSorted.lowerBound than: map(a => numbers[a])(order).assumeSorted.lowerBound as the lowerBound will be faster on a random access range as produced by indexed? map preserves the random access capabilities of it's source. An array is random access, therefore map applied to an array is also random access. There isn't any practical difference between indices.map!((i) => src[i])() and src.indexed(indices) that I know of.
Re: passing predicates to lowerBound, or alternatively, how lazy is map?
You are correct. assumeSorted and lowerBound will provide better time complexity than countUntil I'm sorry, one final question because I think I'm close to understanding. Map produces a forward range (lazily) but not a random access range? Therefore, lowerBound will move along this range until the pred is not true? This means it would be better to do: numbers.indexed(order).assumeSorted.lowerBound than: map(a => numbers[a])(order).assumeSorted.lowerBound as the lowerBound will be faster on a random access range as produced by indexed?
Re: problem with Access Violation, and I'm not sure where
On 6/11/2014 2:14 PM, Matt wrote: window = SDL_CreateWindow (cfg["window"]["caption"].str.ptr, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, width, height, SDL_WINDOW_SHOWN); I'm curious -- does cfg[""][""].str ensure that the string is null terminated? Because if it doesn't, you've got a potential problem here (aside from the fact that you aren't checking the return value).
Re: passing predicates to lowerBound, or alternatively, how lazy is map?
On Wednesday, 11 June 2014 at 11:50:36 UTC, Andrew Brown wrote: map is fully lazy. However, if you've already got the sorted indices in `order`, I would do this: auto numLessThanN = numbers.indexed(order).countUntil!((x) => x >= N)(); That indexed command is perfect though, does the trick, thank you very much. For future reference: map applies its predicate in `front`, meaning that a) It is completely lazy, you only pay for elements you actually access. b) Unless the optimiser is smart and caches the result for you, you pay every time you call `front`, even if you haven't called `popFront` in between.
Re: passing predicates to lowerBound, or alternatively, how lazy is map?
On Wednesday, 11 June 2014 at 11:38:07 UTC, Andrew Brown wrote: My question about this is how lazy is map? Will it work on every value of order and then pass it to lowerBound, or could it work to evaluate only those values asked by lowerBound? I guess probably not, but could a function be composed that worked in this way? Thank you very much Andrew map is fully lazy. However, if you've already got the sorted indices in `order`, I would do this: auto numLessThanN = numbers.indexed(order).countUntil!((x) => x >= N)(); Thanks for the reply, I'm going to have a lot of numbers though. I guess compared to the time it will take me to sort them, it makes no difference, but is it right that countUntil will take linear time? If I can figure out lowerBound, then I have my answer in log(n) time? Best Andrew You are correct. assumeSorted and lowerBound will provide better time complexity than countUntil
Re: Splitting Ranges using Lambda Predicates
On Wednesday, 11 June 2014 at 11:42:42 UTC, Artur Skawina via Digitalmars-d-learn wrote: On 06/11/14 00:31, "Nordlöw" via Digitalmars-d-learn wrote: Either way, it shouldn't be too hard to implement. Base it off "splitter!pred", which is actually quite trivial. AFAIK, your What do you mean by basing it off splitter!pred - should I start with some existing splitter algorithm in Phobos or start from scratch? Starting from scratch is actually not a bad idea, at least for this kind of trivial functionality. A working version can be written in less time than copying, analyzing and modifying another implementation... ... artur I don't know about "starting from scratch" entirely. Maybe not copy paste, but it always helps to have a reference implementation. For example, you should avoid "countUntil" and "takeExactly" when dealing with strings, since these are not O(1) operations, and don't actually return string slices. EG: string s = "someGGGreatVariableName".slicer().front; Error: cannot implicitly convert expression (slicer("someGGGreatVariableName").front()) of type Result to string That's why the splitter code uses the more verbose "r.length - r.find!pred".
Re: passing predicates to lowerBound, or alternatively, how lazy is map?
map is fully lazy. However, if you've already got the sorted indices in `order`, I would do this: auto numLessThanN = numbers.indexed(order).countUntil!((x) => x >= N)(); That indexed command is perfect though, does the trick, thank you very much.
Re: Splitting Ranges using Lambda Predicates
On 06/11/14 00:31, "Nordlöw" via Digitalmars-d-learn wrote: >> Either way, it shouldn't be too hard to implement. Base it off >> "splitter!pred", which is actually quite trivial. AFAIK, your > > What do you mean by basing it off splitter!pred - should I start with some > existing splitter algorithm in Phobos or start from scratch? Starting from scratch is actually not a bad idea, at least for this kind of trivial functionality. A working version can be written in less time than copying, analyzing and modifying another implementation... For example (using monarch_dodra's test inputs): auto slicer(alias PRED, R)(R r) { import std.algorithm, std.array, std.range; struct Slicer { R r; size_t c; bool empty() @property const { return r.empty; } auto front() @property { c = r.dropExactly(1).countUntil!PRED()+1; if (c==0) c = r.length; return r.takeExactly(c); } void popFront() { r.popFrontN(c); } } return Slicer(r); } auto slicer(R)(R r) { import std.uni; return slicer!(a=>isUpper(a))(r); } void main() { import std.stdio, std.range; "SomeGreatVariableName" .slicer().writeln(); "someGGGreatVariableName".slicer().join(" ").writeln(); "".slicer().writeln(); "a".slicer().writeln(); "A".slicer().writeln(); } artur
Re: passing predicates to lowerBound, or alternatively, how lazy is map?
My question about this is how lazy is map? Will it work on every value of order and then pass it to lowerBound, or could it work to evaluate only those values asked by lowerBound? I guess probably not, but could a function be composed that worked in this way? Thank you very much Andrew map is fully lazy. However, if you've already got the sorted indices in `order`, I would do this: auto numLessThanN = numbers.indexed(order).countUntil!((x) => x >= N)(); Thanks for the reply, I'm going to have a lot of numbers though. I guess compared to the time it will take me to sort them, it makes no difference, but is it right that countUntil will take linear time? If I can figure out lowerBound, then I have my answer in log(n) time? Best Andrew
Re: passing predicates to lowerBound, or alternatively, how lazy is map?
On Wednesday, 11 June 2014 at 11:22:08 UTC, Andrew Brown wrote: Hi there, The problem this question is about is now solved, by writing my own binary search algorithm, but I'd like to ask it anyway as I think I could learn a lot from the answers. The problem was, given an array of numbers, double[] numbers, and an ordering from makeIndex size_t[] order, I want to count how many numbers are less than a number N. The obvious way would be to use lowerBound from std.range, but I can't work out how to pass it a predicate like "numbers[a] < b". Could someone explain the template: (SearchPolicy sp = SearchPolicy.binarySearch, V)(V value) if (isTwoWayCompatible!(predFun, ElementType!Range, V)); The alternative way I thought to do it was to combine map with lowerBound, i.e.: map!(a => numbers[a])(order).assumeSorted .lowerBound(N) .length My question about this is how lazy is map? Will it work on every value of order and then pass it to lowerBound, or could it work to evaluate only those values asked by lowerBound? I guess probably not, but could a function be composed that worked in this way? Thank you very much Andrew map is fully lazy. However, if you've already got the sorted indices in `order`, I would do this: auto numLessThanN = numbers.indexed(order).countUntil!((x) => x >= N)();
passing predicates to lowerBound, or alternatively, how lazy is map?
Hi there, The problem this question is about is now solved, by writing my own binary search algorithm, but I'd like to ask it anyway as I think I could learn a lot from the answers. The problem was, given an array of numbers, double[] numbers, and an ordering from makeIndex size_t[] order, I want to count how many numbers are less than a number N. The obvious way would be to use lowerBound from std.range, but I can't work out how to pass it a predicate like "numbers[a] < b". Could someone explain the template: (SearchPolicy sp = SearchPolicy.binarySearch, V)(V value) if (isTwoWayCompatible!(predFun, ElementType!Range, V)); The alternative way I thought to do it was to combine map with lowerBound, i.e.: map!(a => numbers[a])(order).assumeSorted .lowerBound(N) .length My question about this is how lazy is map? Will it work on every value of order and then pass it to lowerBound, or could it work to evaluate only those values asked by lowerBound? I guess probably not, but could a function be composed that worked in this way? Thank you very much Andrew
Re: Basic dynamic array question. Use of new versus no new.
On Wed, 11 Jun 2014 02:30:00 + WhatMeWorry via Digitalmars-d-learn wrote: > In Mr. Cehreli's book it says > > Additionally, the length of dynamic arrays can be changed by > assigning a value to this property: > > int[] array; // initially empty > array.length = 5; // now has 5 elements > > while in Mr. Alexandrescu's book, it says > > To create a dynamic array, use a new expression (§ 2.3.6.1 on > page 51) as follows: > > int[] array = new int[20]; // Create an array of 20 integers > > > Could someone please compare and contrast the two syntaxes. I > presume the "new" command places the 2nd array in heap memory. They do essentially the same thing but, the first one does it in two steps instead of one. To better understand arrays in D, I'd advise reading this article: http://dlang.org/d-array-article.html - Jonathan M Davis
Re: crt1.o: could not read symbols: Bad value
I conclude that because I have similar errors when trying to build 64-bit library on 32-bit system. /usr/bin/ld: /usr/lib/x86_64-linux-gnu/libphobos2.a(format_712_5b3.o): relocation R_X86_64_32 against `.rodata' can not be used when making a shared object; recompile with -fPIC /usr/lib/x86_64-linux-gnu/libphobos2.a: error adding symbols: Bad value collect2: error: ld returned 1 exit status --- errorlevel 1 But paths in your error log look like you're on x64, so it's probably not the case.
Re: crt1.o: could not read symbols: Bad value
It seems like you're trying to compile 64-bit code when you are on 32-bit system and you have 32-bit libphobos.
Re: Source File and Position of User Defined Type
On Tuesday, 10 June 2014 at 20:58:41 UTC, Nordlöw wrote: Is there a way to, programatically (trait), lookup the source file and position of a user defined type either dynamically or, even better, statically? I don't know about the source file, per se, but std.traits has the fullQualifiedName!() template, which you could go on to parse for the package and module of a type. Or just use the packageName and moduleName templates instead.
Re: Version() for unittest OR debug?
On Tuesday, 10 June 2014 at 14:06:58 UTC, bearophile wrote: Juanjo Alvarez: Probably I pretty simple question, how could I mark some code to be compiled when in debug OR unittest mode? (or both, ||) At first I tough I could do: version(unittest, debug) {} You can define a enum boolean value in the version unittest block, and another inside the debug {} else {}. And then you can use "if (b1 || b2) { ... }". Bye, bearophile Not pretty, but works. Thanks!
Re: Basic dynamic array question. Use of new versus no new.
On Wednesday, 11 June 2014 at 05:46:07 UTC, Ali Çehreli wrote: On 06/10/2014 08:06 PM, Matt wrote: > On Wednesday, 11 June 2014 at 02:30:01 UTC, WhatMeWorry wrote: >> int[] array; // initially empty >> array.length = 5; // now has 5 elements >> >> while in Mr. Alexandrescu's book, it says >> >> To create a dynamic array, use a new expression (§ 2.3.6.1 on page 51) >> as follows: >> >> int[] array = new int[20]; // Create an array of 20 integers > I would have read the second as creating a static array of 20 ints in > heap memory, then assigning a dynamic array to point to it. Correct but it is not different from the first one, other than doing it in one step. Wait, what? That's not correct. "new int[20]" is simply "one of two" syntaxes to allocate an array of 20 ints, the other being "new int[](20)". It does NOT allocate a static array, and then slice it. Proof is that there is APPENDABLE data present, which should not happen if you had actually simply allocated a single element of type int[20] (APPENDABLE data is only present for array-style allocation). AFAIK, there is no "natural" way to allocate either a static array or a slice itslef, using new syntax. It can be done via the "wrapper struct" hack though: // //Used to allocate a slice "int[]". //Or a static array "int[20]" on the heap. struct NewWrapper(T) { T data; } void main() { int[] arr1 = new int[20]; int[] arr2 = (new NewWrapper!(int[20])).data[]; writeln(arr1.length); //20, as expected writeln(arr1.capacity); //31 on my machine writeln(arr2.length); //20 writeln(arr2.capacity); //0 } // Too bad the ambiguous syntax has us resolve to these tricks. It also prevents value constructing an array of elements. A syntax where the array sizes came *before* the type could have solved these issue: int size = 20; new size int[5]([1, 2, 3, 4, 5]); Allocate "20" (runtime) elements of type "int[5]", each initialized to the value ([1, 2, 3, 4, 5]). But, well, that ship has set sail long ago :(
Re: Splitting Ranges using Lambda Predicates
On Tuesday, 10 June 2014 at 22:31:37 UTC, Nordlöw wrote: Either way, it shouldn't be too hard to implement. Base it off "splitter!pred", which is actually quite trivial. AFAIK, your What do you mean by basing it off splitter!pred - should I start with some existing splitter algorithm in Phobos or start from scratch? Thx. I meant mostly copy pasting it, and modifying it to your needs. For example, I adapted it into this. For simplicity, I stripped infinite and forward only range support. The only functions I actually modified were "findTerminator", to actually find according to what I want, and popFront. // auto slicer(alias isTerminator, Range)(Range input) if (((isRandomAccessRange!Range && hasSlicing!Range) || isSomeString!Range) && is(typeof(unaryFun!isTerminator(input.front { return SlicerResult!(unaryFun!isTerminator, Range)(input); } private struct SlicerResult(alias isTerminator, Range) { alias notTerminator = not!isTerminator; private Range _input; private size_t _end = 0; private void findTerminator() { auto r = _input.save.find!(not!isTerminator).find!isTerminator(); _end = _input.length - r.length; } this(Range input) { _input = input; if (!_input.empty) findTerminator(); else _end = size_t.max; } static if (isInfinite!Range) enum bool empty = false; // Propagate infiniteness. else @property bool empty() { return _end == size_t.max; } @property auto front() { return _input[0 .. _end]; } void popFront() { _input = _input[_end .. _input.length]; if (_input.empty) { _end = size_t.max; return; } findTerminator(); } @property typeof(this) save() { auto ret = this; ret._input = _input.save; return ret; } } // This will split on before the first element where pred is true, provided there are previous elements where pred is false: // void main() { "SomeGreatVariableName" .slicer!isUpper.writeln(); "someGGGreatVariableName".slicer!isUpper.writeln(); "".slicer!isUpper.writeln(); "a".slicer!isUpper.writeln(); "A".slicer!isUpper.writeln(); } // ["Some", "Great", "Variable", "Name"] ["some", "GGGreat", "Variable", "Name"] [] ["a"] ["A"] // This may or may not be what you wanted, depending on how you want to split "GGGreat". If you wanted it to simply split *ON* the left of every capital letter, then you can modify the the find terminator into: private void findTerminator() { auto r = _input.save.dropOne.find!isTerminator; _end = _input.length - r.length; } And you'd get: ["some", "G", "G", "Great", "Variable", "Name"] *** *** *** In any case, yeah, it shouldn't be too hard to shape it into what you want. A more involved solution to this problem could be to simply pass a "searchFun" predicate, in which case you'd be able to split not just according to any "unitary predicate", but according to an entire "range search strategy: // auto slicer(alias searchFun, Range)(Range input) if (((isRandomAccessRange!Range && hasSlicing!Range) || isSomeString!Range) && is(typeof(searchFun(input { return SlicerResult!(searchFun, Range)(input); } private struct SlicerResult(alias searchFun, Range) { private Range _input; private size_t _end = 0; private void findTerminator() { auto r = searchFun(_input.save); _end = _input.length - r.length; } ... // And then: "SomereatVariableName".slicer!((s)=>s.find!isLower.find!isUpper).writeln(); "someGGGreatVariableName" .slicer!((s)=>s.dropOne.find!isUpper).writeln(); ["Some", "reat", "Variable", "Name"] ["some", "G", "G", "Great", "Variable", "Name"] Just ideas.