Re: How to Add CSS and JS to vibe.d templates
On 1/19/23 11:44 PM, seany wrote: Hi Howcan one add CSS and JS to vibe.d templates? Here is my setup (vibe.d project initiated with dub using dub init myproject vibe.d): ./public: main.css main.js ./source: app.d ./views: auth2fa.dt fail.dt login.dt pair.dt passfail.dt userfail.dt I am trying to add a css file using `link(rel="stylesheet", type="text/css", href="main.css")` in the diet templates, but it has no effect. I took the files from here: https://codepen.io/ricardoolivaalonso/pen/YzyaRPN Keep in mind, this literally translates to a `link` tag in the HTML. So here is what happens: 1. your vibe project is running, and passes out the compiled template to the browser. 2. The browser sees the link tag, and attempts to ask the server for the file "main.css" 3. The vibe project tries to match that to its routes, and cannot find it, and so returns an error. So this takes 2 steps to remedy: 1. Register a `serveStaticFiles` route with the glob `public/*`. See the docs here: https://vibed.org/api/vibe.http.fileserver/serveStaticFiles 2. Change your link to refer to `public/main.css`, instead of just `main.css`. This is how it looks in my code: ```d router.get("/public/*", serveStaticFiles("")); ``` And the links look like: ```pug link(rel="stylesheet",href="/public/css/flatpickr.min.css") ``` as an example. Note that I put my css files into a css subdirectory under public, and my javascript files under a js subdirectory. It all depends on how you want to set it up. -Steve
Re: What is the 'Result' type even for?
On 1/19/23 19:11, Ruby The Roobster wrote: > typeof(c).stringof.writeln; > The program prints: > > ["a", "b", "c", "d", "e"] > Result > > What is the purpose of this 'Result' type? Just to make sure, 'Result' is what the programmer of a Phobos algorithm chose to name a struct type. It could be anything. I will try to demonstrate it by naming my struct 'MyResult' below. The following range algorithm alternates between the two values it is called with. The pragma(msg) inside 'main' prints MyResult. auto alternate(T)(T a, T b) { // This function will return an object // of the following nested struct. // (Note: This is for demonsration // purposes only. Yes, this can be // be more optimal.) struct MyResult { bool useB = false; enum empty = false; // Infinite T front() { return useB ? b : a; } void popFront() { // Flip the selector useB = !useB; } } // Here, an object of the struct is // returned. It has single member (useB) // that it uses as a selector. // The values 'a' and 'b' are the actual // function arguments. return MyResult(); } import std; void main() { auto myRange = alternate(42, 7); // This prints 'MyResult' at compile time pragma(msg, typeof(myRange)); const expected = [ 42, 7, 42, 7, 42 ]; assert(myRange.take(5).equal(expected)); } > even when the type > has the same inherent function: Different instantiations of templates are distinct types. For example, if I called 'alternate' with two 'long' values, both alternate!int (as instantiated by the code above) and alternate!long would have different MyResult struct types. Although they would have the same functionality, they would be compiled potentially with very different CPU instructions and would not be assignable. Ali
How to Add CSS and JS to vibe.d templates
Hi Howcan one add CSS and JS to vibe.d templates? Here is my setup (vibe.d project initiated with dub using dub init myproject vibe.d): ./public: main.css main.js ./source: app.d ./views: auth2fa.dt fail.dt login.dt pair.dt passfail.dt userfail.dt I am trying to add a css file using `link(rel="stylesheet", type="text/css", href="main.css")` in the diet templates, but it has no effect. I took the files from here: https://codepen.io/ricardoolivaalonso/pen/YzyaRPN Note that (as discussed in my previous post by Steven Schveighoffer) , there are some errors in the jade/pug template file. But even if we correct them, and then I try to use the setup, I do not get the styles. (Of course, i can't point my browser to www.my.server/main.css or so, because those endpoints are not defined. However, as I understood, all non-defined endpoints should anyway be redirected to public) Thank you.
Re: What is the 'Result' type even for?
On Friday, 20 January 2023 at 03:11:33 UTC, Ruby The Roobster wrote: What is the purpose of this 'Result' type? To serve as a generic range? Because, it seems to only cause problems... No. When I first started learning this language, I thought the same thing. However, such a designm consisting of structs was preferred because it is necessary for the ranges to be used as a whole (connected end-to-Znd like a pipe). qWalter has a very old [article](https://www.drdobbs.com/cpp/voldemort-types-in-d/232901591) about Voldemort which is the basis of D, pllease read it. D's ranges are very strong for those who know how to use it. SDB@79
Re: What is the 'Result' type even for?
On Friday, 20 January 2023 at 03:11:33 UTC, Ruby The Roobster wrote: Take this example: [...] What is the purpose of this 'Result' type? To serve as a generic range? Yes this is a lazy input range. Use `.array` to yield directly as a concrete value, then you can append using `~=`. Note that there are special functions to keep the laziness, e.g `chain` to happen an input range to another element-compatible input range ``` import std; void main() { auto c = "a|b|c|d|e".splitter("|").chain(["f"]); string[] e = ["a", "b", "c", "d", "e", "f"]; assert(c.equal(e)); } ```
Re: What is the 'Result' type even for?
On 1/19/23 10:34 PM, Ruby The Roobster wrote: On Friday, 20 January 2023 at 03:30:56 UTC, Steven Schveighoffer wrote: On 1/19/23 10:11 PM, Ruby The Roobster wrote: ... The point is to be a range over the original input, evaluated lazily. Using this building block, you can create an array, or use some other algorithm, or whatever you want. All without allocating more space to hold an array. I get the point that it is supposed to be lazy. But why are these basic cases not implemented? I shouldn't have to go write a wrapper for something as simple as casting this type to the original type. This is one of the things that one expects the standard library to do for you. A range simply does not provide the API you are seeking. It provides 3 methods: front popFront empty That's it. It does not provide appending. If you want appending or random access, use an array: ```d auto c = "a|b|c|d|e".split('|'); static assert(is(typeof(c) == string[])); // or: auto c2 = "a|b|c|d|e".splitter('|').array; // convert range to an array ``` -Steve
Re: What is the 'Result' type even for?
On Fri, Jan 20, 2023 at 03:34:43AM +, Ruby The Roobster via Digitalmars-d-learn wrote: > On Friday, 20 January 2023 at 03:30:56 UTC, Steven Schveighoffer wrote: > > On 1/19/23 10:11 PM, Ruby The Roobster wrote: > > ... > > > > The point is to be a range over the original input, evaluated > > lazily. Using this building block, you can create an array, or use > > some other algorithm, or whatever you want. All without allocating > > more space to hold an array. [...] > I get the point that it is supposed to be lazy. But why are these > basic cases not implemented? I shouldn't have to go write a wrapper > for something as simple as casting this type to the original type. > This is one of the things that one expects the standard library to do > for you. There's no need to write any wrappers. Just tack `.array` to the end of your pipeline, and you're good to go. T -- My father told me I wasn't at all afraid of hard work. I could lie down right next to it and go to sleep. -- Walter Bright
Re: What is the 'Result' type even for?
On Friday, 20 January 2023 at 03:30:56 UTC, Steven Schveighoffer wrote: On 1/19/23 10:11 PM, Ruby The Roobster wrote: ... The point is to be a range over the original input, evaluated lazily. Using this building block, you can create an array, or use some other algorithm, or whatever you want. All without allocating more space to hold an array. -Steve I get the point that it is supposed to be lazy. But why are these basic cases not implemented? I shouldn't have to go write a wrapper for something as simple as casting this type to the original type. This is one of the things that one expects the standard library to do for you.
Re: What is the 'Result' type even for?
On Fri, Jan 20, 2023 at 03:11:33AM +, Ruby The Roobster via Digitalmars-d-learn wrote: > Take this example: > > ```d > import std; > void main() > { > auto c = "a|b|c|d|e".splitter('|'); > c.writeln; > string[] e = ["a", "b", "c", "d", "e"]; > assert(c.equal(e)); > typeof(c).stringof.writeln; > } > ``` > > The program prints: > > ["a", "b", "c", "d", "e"] > Result > > What is the purpose of this 'Result' type? To serve as a generic > range? It's a Voldemort type, representing a range that iterates over its elements lazily. > Because, it seems to only cause problems. For example, you cannot > assign or cast the result type into a range, even when the type has > the same inherent function: > > ```d > string[] c = "a|b|c|d|e".splitter('|'); // fails > string[] d = cast(string[])"a|b|c|d|e".splitter('|'); // also fails > ``` You're confusing arrays and ranges. A "range" isn't any specific type, it refers to *any* type that behaves a certain way (behaves like a range). Each `Result` you get back has its own unique type (arguably, it's a compiler bug to display it as merely `Result` without distinguishing it from other identically-named but distinct Voldemort types), so you cannot just assign it back to an array. You can either create an array from it using std.array.array, use a function that eagerly creates its results instead of a lazy result (in the above instance, use std.string.split instead of .splitter), or use std.algorithm.copy to copy the contents of the lazy range into an array: // Option 1 string[] c = "a|b|c|d|e".splitter('|').dup; // Option 2 string[] c = "a|b|c|d|e".split('|'); // Option 3 // Caveat: .copy expects you to have prepared the buffer // beforehand to be large enough to hold the contents; it does // not reallocate the result array for you. string[] result = new string[5]; "a|b|c|d|e".splitter('|').copy(result); [...] > Then what is the point of this type, if not to just make things > difficult? It cannot be casted, and vector operations cannot be > performed, and it seems to just serve as an unnecessary > generalization. It serves to chain further range operations into a pipeline: string[] c = "a|b|c|d|e".splitter('|') .filter!(c => c >= 'b' && c <= 'd') .map!(c => c+1) .array; Because ranges are lazily iterated, the .array line only allocates the 3 elements that got through the .filter. Whereas if you created the intermediate result array eagerly, you'd have to allocate space for 5 elements only to discard 2 of them afterwards. One way to think about this is that the intermediate Result ranges are like the middle part of a long pipe; you cannot get stuff from the middle of the pipe without breaking it, you need to terminate the pipe with a sink (like .array, .copy, etc.) first. T -- I am Pentium of Borg. Division is futile; you will be approximated.
Re: What is the 'Result' type even for?
On 1/19/23 10:11 PM, Ruby The Roobster wrote: Take this example: ```d import std; void main() { auto c = "a|b|c|d|e".splitter('|'); c.writeln; string[] e = ["a", "b", "c", "d", "e"]; assert(c.equal(e)); typeof(c).stringof.writeln; } ``` The program prints: ["a", "b", "c", "d", "e"] Result What is the purpose of this 'Result' type? To serve as a generic range? Because, it seems to only cause problems. For example, you cannot assign or cast the result type into a range, even when the type has the same inherent function: ```d string[] c = "a|b|c|d|e".splitter('|'); // fails string[] d = cast(string[])"a|b|c|d|e".splitter('|'); // also fails ``` The `Result` type is an internal type that provides a lazily-evaluated range of the original string. That is, no array is allocated, and the actual searching of the `|` character isn't done until you start fetching each element. It returns windows into the *original* string, and builds each window one element at a time (via slicing). So when you say "cast to a range", you are incorrectly stating the type `string[]` as a "range", when you are trying to cast to an array of strings. The `Result` type *is* a range, it's a range of strings. But it is not an array. If you want an array, you can use the `split` function, which allocates an array to hold all the slices. And if you need to perform a set operation? ```d c[] ~= "lolno"; // fails, as [] isn't defined for Result. ``` Right, because a `Result` is not an array. Appending is an array operation, not a range operation. Then what is the point of this type, if not to just make things difficult? It cannot be casted, and vector operations cannot be performed, and it seems to just serve as an unnecessary generalization. The point is to be a range over the original input, evaluated lazily. Using this building block, you can create an array, or use some other algorithm, or whatever you want. All without allocating more space to hold an array. -Steve
Re: What is the 'Result' type even for?
On Friday, 20 January 2023 at 03:11:33 UTC, Ruby The Roobster wrote: Take this example: ```d import std; void main() { auto c = "a|b|c|d|e".splitter('|'); c.writeln; string[] e = ["a", "b", "c", "d", "e"]; assert(c.equal(e)); typeof(c).stringof.writeln; } ``` The program prints: ["a", "b", "c", "d", "e"] Result What is the purpose of this 'Result' type? To serve as a generic range? Because, it seems to only cause problems. For example, you cannot assign or cast the result type into a range, even when the type has the same inherent function: ```d string[] c = "a|b|c|d|e".splitter('|'); // fails string[] d = cast(string[])"a|b|c|d|e".splitter('|'); // also fails ``` And if you need to perform a set operation? ```d c[] ~= "lolno"; // fails, as [] isn't defined for Result. ``` Then what is the point of this type, if not to just make things difficult? It cannot be casted, and vector operations cannot be performed, and it seems to just serve as an unnecessary generalization. Furthermore, it can also be confirmed that each member of c is a string, further solidifying my opinion of 'Result' as just being a generic range template, that cannot be casted to an array of the original type.
What is the 'Result' type even for?
Take this example: ```d import std; void main() { auto c = "a|b|c|d|e".splitter('|'); c.writeln; string[] e = ["a", "b", "c", "d", "e"]; assert(c.equal(e)); typeof(c).stringof.writeln; } ``` The program prints: ["a", "b", "c", "d", "e"] Result What is the purpose of this 'Result' type? To serve as a generic range? Because, it seems to only cause problems. For example, you cannot assign or cast the result type into a range, even when the type has the same inherent function: ```d string[] c = "a|b|c|d|e".splitter('|'); // fails string[] d = cast(string[])"a|b|c|d|e".splitter('|'); // also fails ``` And if you need to perform a set operation? ```d c[] ~= "lolno"; // fails, as [] isn't defined for Result. ``` Then what is the point of this type, if not to just make things difficult? It cannot be casted, and vector operations cannot be performed, and it seems to just serve as an unnecessary generalization.
Re: Pyd examples or resources for Python 3.x
On Friday, 20 January 2023 at 00:39:47 UTC, Seamus wrote: Howdy folks I am new around these parts and looking forward to getting stuck into some D development. Really liking it so far, just one some questions though... I am working on a project that did not sit well with me when I tried it in Python. I need static typing (above and beyond MyPy, as nice as that is) and the extra speed from D is a bonus. However, there are some nice libraries in Python I would still like to use (Spacy for example) and I have played around with Pyd to see if I can get it working with Python 3.x. Unfortunately the documentation and examples in the Pyd repo presume more knowledge than I have. I have looked around this forum and there are tantalising snippets of conversation that suggest Pyd will work with some C based extensions of Python... I just cannot get it to work myself. So does anyone have any sample code, pointers or tips on using Pyd with something like Spacy? Is this possible, or even desirable? I have a fallback position for now in that I can wrap my Python scripts in something like Fire (https://google.github.io/python-fire/guide/) and create an external process from D, but that seems a bit less efficient. Either that or REST services/ZeroMQ middleware, but they all add complexity. Idle speculation and suggestions welcome! Cheers Seamus Have you tried this? https://github.com/symmetryinvestments/autowrap
Re: Vibe.d Diet Templatesand Forms
On Friday, 20 January 2023 at 01:32:04 UTC, Steven Schveighoffer wrote: On 1/19/23 6:24 PM, seany wrote: [...] Did you mean to include straight HTML here? I don't think that is supported. [...] You are indeed right. The Link was a problem, and removing the link actually have sorted the issue. Thank you.
Re: Vibe.d Diet Templatesand Forms
On 1/19/23 6:24 PM, seany wrote: Hello Please consider this diet template: doctype html html(lang="es", dir="ltr") head meta(name="viewport", content="width=device-width, user-scalable=no, initial-scale=1.0") meta(charset="utf-8") link(rel="stylesheet", type="text/css", href="main.css") href="https://fonts.googleapis.com/css2?family=Montserrat:wght@400;700;800=swap; rel="stylesheet"> Did you mean to include straight HTML here? I don't think that is supported. Please notice the line `form(id= ...`. This line is causing the following error: login.dt(29,45): Error: found `method` when expecting `;` following `return` statement login.dt(29,51): Error: found `=` instead of statement login.dt(28,12): Error: missing closing `)` after `if ("form"` login.dt(28,21): Error: found `)` when expecting `;` following statement login.dt(28,36): Error: found `method` when expecting `)` login.dt(28,42): Error: found `=` when expecting `)` login.dt(28,43): Error: found `""` when expecting `)` login.dt(28,45): Error: found `)` instead of statement /root/.dub/packages/diet-ng-1.8.1/diet-ng/source/diet/html.d(246,8): Error: template instance `diet.html.compileHTMLDietFileString!("login.dt", contents, DefaultDietFilters).exec!(StreamOutputRange!(InterfaceProxy!(OutputStream), 1024LU))` error instantiating /root/.dub/packages/vibe-d-0.9.5/vibe-d/http/vibe/http/server.d(351,66): instantiated from here: `compileHTMLDietFileString!(StreamOutputRange!(InterfaceProxy!(OutputStream), 1024LU))` source/app.d(41,5): instantiated from here: `render!"login.dt"` What is the problem? How can I resolve it? Thank you. The easiest way to see what the diet compiler is producing is to uncomment the line that outputs the compiled file to the console during compilation. That is located here: https://github.com/rejectedsoftware/diet-ng/blob/856bf6d75127955565b3b5edd9b1f4418b8ec7c3/source/diet/html.d#L234 With that being said, how diet works is to convert the diet template directly into D code. It relies on the translation to produce valid D code (no specialized parsing or semantic-aware processing is done, it's just a direct translation from diet AST to D). What is happening here is the diet compiler is not producing valid D code. This can happen when there are bugs, but usually only when there are D "escapes", which don't correctly set up the syntax (like if you include a curly brace, which isn't expected) However, in your code, I don't see any "escapes", so I'm not sure what could cause it there. I will note that most of the time, when I get diet errors like that the error is not on that specific line, but on something that happened before to confuse the D compiler. That html `link` node might be the issue, but again, I'm not sure what is intended there. -Steve
Re: Pyd examples or resources for Python 3.x
On Friday, 20 January 2023 at 00:39:47 UTC, Seamus wrote: Howdy folks Honestly in my opinion PyD looks kinda abounded. I don’t know how much effort you need to spend to run spaCy. Just to be sure that you’ve seen this documentation https://pyd.readthedocs.io/en/latest/index.html Also probably if you will find C API (as it is written in Cython) it will be possible to make bindings for them using dstep, ctod or ImportC tools. Or maybe it is possible to prepare D bindings like someone did for other C-like languages: https://github.com/d99kris/spacy-cpp https://github.com/AMArostegui/SpacyDotNet
Pyd examples or resources for Python 3.x
Howdy folks I am new around these parts and looking forward to getting stuck into some D development. Really liking it so far, just one some questions though... I am working on a project that did not sit well with me when I tried it in Python. I need static typing (above and beyond MyPy, as nice as that is) and the extra speed from D is a bonus. However, there are some nice libraries in Python I would still like to use (Spacy for example) and I have played around with Pyd to see if I can get it working with Python 3.x. Unfortunately the documentation and examples in the Pyd repo presume more knowledge than I have. I have looked around this forum and there are tantalising snippets of conversation that suggest Pyd will work with some C based extensions of Python... I just cannot get it to work myself. So does anyone have any sample code, pointers or tips on using Pyd with something like Spacy? Is this possible, or even desirable? I have a fallback position for now in that I can wrap my Python scripts in something like Fire (https://google.github.io/python-fire/guide/) and create an external process from D, but that seems a bit less efficient. Either that or REST services/ZeroMQ middleware, but they all add complexity. Idle speculation and suggestions welcome! Cheers Seamus
Vibe.d Diet Templatesand Forms
Hello Please consider this diet template: doctype html html(lang="es", dir="ltr") head meta(name="viewport", content="width=device-width, user-scalable=no, initial-scale=1.0") meta(charset="utf-8") link(rel="stylesheet", type="text/css", href="main.css") href="https://fonts.googleapis.com/css2?family=Montserrat:wght@400;700;800=swap; rel="stylesheet"> body div.main div.container.a-container#a-container form(id="loginfrm", class="frm", method="post", action="/login_attempt") h2.form_title.title Create Account span.form__span or use email for registration input.form__input(type="text", placeholder="Name" ) input.form__input(type="text", placeholder="Email") input.form__input(type="password", placeholder="Password") button().form__button.button.submit SIGN UP Please notice the line `form(id= ...`. This line is causing the following error: login.dt(29,45): Error: found `method` when expecting `;` following `return` statement login.dt(29,51): Error: found `=` instead of statement login.dt(28,12): Error: missing closing `)` after `if ("form"` login.dt(28,21): Error: found `)` when expecting `;` following statement login.dt(28,36): Error: found `method` when expecting `)` login.dt(28,42): Error: found `=` when expecting `)` login.dt(28,43): Error: found `""` when expecting `)` login.dt(28,45): Error: found `)` instead of statement /root/.dub/packages/diet-ng-1.8.1/diet-ng/source/diet/html.d(246,8): Error: template instance `diet.html.compileHTMLDietFileString!("login.dt", contents, DefaultDietFilters).exec!(StreamOutputRange!(InterfaceProxy!(OutputStream), 1024LU))` error instantiating /root/.dub/packages/vibe-d-0.9.5/vibe-d/http/vibe/http/server.d(351,66):instantiated from here: `compileHTMLDietFileString!(StreamOutputRange!(InterfaceProxy!(OutputStream), 1024LU))` source/app.d(41,5):instantiated from here: `render!"login.dt"` What is the problem? How can I resolve it? Thank you.
Re: Are there more up-to-date D template tutorials?
roduct/learning-d/9781783552481?_ga=2.241359490.1811075590.1674153096-1605518740.1674153096 or Adam's book https://www.packtpub.com/product/d-cookbook/9781783287215?_ga=2.198287279.1811075590.1674153096-1605518740.1674153096 They're older than 2019, but I don't think much of the material they've covered is in any sense obsolete. Mike's one is more of a learning one. I'll check out Adam's as it seems to be more geared toward learning the advanced stuff of the language, thanks!
Re: Are there more up-to-date D template tutorials?
On Thursday, 19 January 2023 at 04:22:21 UTC, thebluepandabear wrote: Help would be appreciated. Regards, thebluepandabear A bit off topic/ranty but I did find the book by Ali on D extremely useful, but it was good as an 'introduction'. I feel like when it comes to more advanced features (such as templates, mixins, ranges, concurrency, etc) there are no resources out there, but I guess that's the 'cost' of picking a lesser-known language. Hopefully in the future there will be more books written on this language, if there was a book on the advanced features of D I'd happily purchase it :) Have you checked Mike's book https://www.packtpub.com/product/learning-d/9781783552481?_ga=2.241359490.1811075590.1674153096-1605518740.1674153096 or Adam's book https://www.packtpub.com/product/d-cookbook/9781783287215?_ga=2.198287279.1811075590.1674153096-1605518740.1674153096 They're older than 2019, but I don't think much of the material they've covered is in any sense obsolete.
Re: Covariance for []
On Thursday, 19 January 2023 at 12:54:39 UTC, davemo wrote: Hello, I was wondering why the following code does not compile. ```d import std; [...] It looks like the following change works fine. ```d Range!A as() { return wrap(_bs.map!((b) { return cast(A) b; })); } ```
Re: Are there more up-to-date D template tutorials?
On Thursday, 19 January 2023 at 04:22:21 UTC, thebluepandabear wrote: ... I also wrote this article[1] recently exploring how one of my D libraries make use of templates and metaprogramming. Unfortuantely the LinkedIn editor is complete trash and I got to the point any change at all would produce an error; so sadly the article itself is in a very raw and unfinished state. However, there's still plenty of information there to have a look at. [1] https://www.linkedin.com/pulse/d-language-without-compromise-bradley-chatha/?trackingId=ucVY1PBrTNesGvBA6CXp7w%3D%3D
Re: Are there more up-to-date D template tutorials?
On Thursday, 19 January 2023 at 04:22:21 UTC, thebluepandabear wrote: ... I presented a talk[1] at Dconf online 2021, which may or may not be what you're looking for. I know my mic audio is pretty bad, but honestly the slides themselves have all the information you need, so you can just read through if you don't want to watch the video itself. [1] https://www.youtube.com/watch?v=0lo-FOeWecA
Re: Why not allow elementwise operations on tuples?
On Wednesday, 18 January 2023 at 16:42:00 UTC, JG wrote: I guess such a method wouldn't be particularly generic since a tuple does not need to consist of types that have the same operations e.g. Tuple!(int,string) etc That's where `areCompatibleTuples` function comes in!
Covariance for []
Hello, I was wondering why the following code does not compile. ```d import std; abstract class Range(T) { abstract T back(); abstract bool empty(); abstract T front(); abstract void popBack(); abstract void popFront(); } class RangeWrapper(TRange) : Range!(ForeachType!(TRange)) { alias TValue = ForeachType!(TRange); private TRange _range; this(TRange range) { _range = range; } override TValue back() { return _range.back(); } override bool empty() { return _range.empty(); } override TValue front() { return _range.front(); } override void popBack() { return _range.popBack(); } override void popFront() { return _range.popFront(); } } auto wrap(TRange)(TRange range) { return new RangeWrapper!TRange(range); } class A { } class B : A { } class C : A { private B[] _bs; this() { _bs = [new B(), new B()]; } Range!A as() { return wrap(_bs); } } void main() { } ``` I receive the following error. ```d onlineapp.d(73): Error: cannot implicitly convert expression `wrap(this._bs)` of type `onlineapp.RangeWrapper!(B[])` to `onlineapp.Range!(A)` ``` Anyone have any idea how I can achieve [covariance](https://en.wikipedia.org/wiki/Covariance_and_contravariance_(computer_science)#Formal_definition) for `[]`?