Re: Parse .eml files
On Monday, 9 April 2018 at 19:17:20 UTC, Adam D. Ruppe wrote: [...] I had a chance to try this out and it worked without a problem. I did have to download color.d in addition to the other dependencies you listed. In the event that Google brings someone here, this is a complete working program: import std.file, std.stdio, std.string; import arsd.email; void main(string[] args) { string[] f = std.file.readText(args[1]).splitLines(); auto em = new IncomingEmailMessage(f); writeln("From: ", em.from); writeln("To: ", em.to); writeln("Subject: ", em.subject); writeln(em.textMessageBody); } Compile with dmd *.d -ofreademail And run ./reademail 'email message.eml'
Re: Strange Thread Causing Duplicating `writeln`
On 4/9/18 6:56 PM, Jonathan wrote: On Monday, 9 April 2018 at 22:53:31 UTC, Jonathan wrote: On Monday, 9 April 2018 at 22:49:07 UTC, Cym13 wrote: I don't know, but I can't reproduce either with dmd or ldc. What was your compilation line? dmd -run file.d I am on Window 10 btw. It's a windows 32-bit issue (specifically, DMC's FILE *, upon which std.stdio.File is based, is thread unsafe). Try -m64. https://issues.dlang.org/show_bug.cgi?id=18483 http://bugzilla.digitalmars.com/issues/show_bug.cgi?id=327 -Steve
Re: Should "a is b" compile if a and b have unrelated classes?
On 4/10/18 5:52 PM, Michael Coulombe wrote: I had a bug in my code that was messing me up for a while, and it boiled down to an identity check between two Object references with unrelated static types, like below: class A {} class B {} void main() { A a = new A; B b = new B; if (a is b) {} // compiles } I was surprised that the type system failed me here. It's true that A and B could be upcast to Object and then comparisons would make sense type-wise, but the comparison should never pass (and the compiler should know it won't since they are in separate inheritance subtrees) unless the programmer is intentionally breaking the type system. Is there reasoning for this? If not, should it be a warning or error, as it is for example when comparing two pointers to structs of different types? Probably the reason is laziness. Sure it could be outlawed. But `is` has a special connotation of "identity", meaning it's EXACTLY the same. Let's look at what does compile: https://run.dlang.io/is/KHcHCc So there is at least some type checking for `is`, when it comes to pointers. There's definitely a precedent for this. The question is, should it just fold to "false", or should it fail to compile? If we change it to an error, there may be some unintentional code breakage out there. -Steve
Re: Range length property
On 4/10/18 6:07 PM, Cym13 wrote: On Tuesday, 10 April 2018 at 20:08:14 UTC, Jonathan M Davis wrote: On Tuesday, April 10, 2018 19:47:10 Nordlöw via Digitalmars-d-learn wrote: On Tuesday, 10 April 2018 at 14:34:40 UTC, Adam D. Ruppe wrote: > On Tuesday, 10 April 2018 at 14:25:52 UTC, Nordlöw wrote: >> Should ranges always provide a length property? > > No. > >> If so, in which cases is a length property an advantage or >> a requirement? > > Just provide it whenever it is cheap to do so. If you need > to do complex calculations or especially loop over contents > to figure out the length, do NOT provide it. > > But if it is as simple as returning some value, provide it > and algorithms can take advantage of it for optimizations > etc. as needed. I'm thinking of my own container Hashmap having its range ByKeyValue requiring one extra word of memory to store the iteration count which, in turn, can be used to calculate the length of the remaining range. Is this motivated? That would depend entirely on what you're trying to do, but in general, if a range has length, then some algorithms will be more efficient, and some algorithms do require length. So, if you can provide length, then the range will be more useful, just like a bidirectional range can be more useful than a forward range or a random-access range can be more useful than either. However, if you're not doing anything that ever benefits from it having length, then it doesn't buy you anything. So, it ultimately depends on what you're doing. In a general purpose library, I'd say that it should have length if it can do so in O(1), but if it's just for you, then it may or may not be worth it. The other thing to consider is what happens when the container is mutated. I don't think that ranges necessarily behave all that well when an underlying container is mutated, but it is something that has to be considered when dealing with a range over a container. Even if mutating the underlying container doesn't necessarily invalidate a range, maintaining the length in the manner that you're suggesting probably makes it so that it would be invalidated in more cases, since if any elements are added or removed in the portion that was already popped off the range, then the iteration count couldn't be used to calculate the length in the same way anymore. Now, with a hash map, the range is probably fully invalidated when anything gets added or removed anyway, since that probably screws with the order of the elements in the range, but how the range is going to behave when the underlying container is mutated and how having the length property does or doesn't affect that is something that you'll need to consider. - Jonathan M Davis I find that discussion very interesting as I had never considered that because of design by introspection having a costly length method would lead to unexpected calls by generic algorithms making it a disadventage if present. On the other hand I don't think the end user should have to scratch his head to find the length of a range, especially if it's not trivial to get (say, O(log n) kind of case). Therefore exposing a method in any case seems the best from an API perspective. O(lg n) is fine for .length, it doesn't need to be O(1). It just can't be O(n). I think we established that "fast" operations are O(lg n) or better. That being said, I don't know of a use case where you can get the length in O(lg n). It's usually O(1) or O(n). But to avoid the performance issues mentionned earlier it means it should bear a different name (get/setLength comes to mind). I believe this is the same kind of issue that lead to having "in" for associative arrays but not regular ones. However this also leads to less coherent APIs in contradiction with the principle of least surprise. It's definitely a tradeoff. It pushes some implementation details to the user, but it also makes the runtime complexity more predictable. In retrospect since only "unexpected" calls to such methods cause the issue I wonder if it wouldn't be best to have an UDA saying "Hey, please, this method is costly, if you're a generic template performing introspection you should probably not call me". And writing that Andrei's work on complexity annotations comes to mind. Anyway, I don't think the user should use different names just to alleviate an issue on the library side but the alternative would be costly to put in place... Potentially, but remember at the time length and walkLength were conceived, UDA's didn't exist! Using UDAs would also have the unfortunate side effect of eliminating self-documentation. When you see walkLength right now, you know it's "slow", when you see length, you know "fast". If you have to look at UDAs to figure that out, then reading the code is that much harder. -Steve
Re: Range length property
On Tue, Apr 10, 2018 at 10:07:40PM +, Cym13 via Digitalmars-d-learn wrote: [...] > On the other hand I don't think the end user should have to scratch > his head to find the length of a range, especially if it's not trivial > to get (say, O(log n) kind of case). Therefore exposing a method in > any case seems the best from an API perspective. > > But to avoid the performance issues mentionned earlier it means it > should bear a different name (get/setLength comes to mind). I believe > this is the same kind of issue that lead to having "in" for > associative arrays but not regular ones. However this also leads to > less coherent APIs in contradiction with the principle of least > surprise. [...] I've run into this in my own code, and I've been using `walkLength` as the name of the method, just for consistency with Phobos' walkLength. I'm not 100% sure this is a good idea, since overloading Phobos names can sometimes lead to annoying symbol conflict situations. But the one good thing is that you won't forget what it's called because it's so familiar. T -- An elephant: A mouse built to government specifications. -- Robert Heinlein
Re: Should "a is b" compile if a and b have unrelated classes?
On Tuesday, April 10, 2018 21:52:22 Michael Coulombe via Digitalmars-d-learn wrote: > I had a bug in my code that was messing me up for a while, and it > boiled down to an identity check between two Object references > with unrelated static types, like below: > > class A {} > class B {} > void main() { > A a = new A; > B b = new B; > if (a is b) {} // compiles > } > > I was surprised that the type system failed me here. It's true > that A and B could be upcast to Object and then comparisons would > make sense type-wise, but the comparison should never pass (and > the compiler should know it won't since they are in separate > inheritance subtrees) unless the programmer is intentionally > breaking the type system. > > Is there reasoning for this? If not, should it be a warning or > error, as it is for example when comparing two pointers to > structs of different types? Well, the compiler can't simply say that they're different classes and refuse to compare their references. It could look at the class hierarchy and determine that there's no way that the two are the same reference, because neither A nor B is a subclass of the other and thus treat it as an error - which I gather is what you're suggesting it should do. However, because doing that is more complicated, I suspect that it just doesn't bother. With struct pointers, it can at least see at a glance that one can't be the other, whereas it has to do a lot more examination of the type if it's class references. It's probably a reasonable enhancement request, though I'm not sure that it really matters much. One potential issue is that since opEquals is unfortunately part of Object, it's perfectly legal to do if(a == b) even though a and b can never be equal, so if is were disallowed in this case, then we'd get a situation where a == b compiles but a is b doesn't which would be a bit weird - though presumably, if we do end up going with some form of Andrei's ProtoObject proposal where we get a new root class beneath Object, then we'd definitely have classes that could be compared with is but not ==. So, that may not be all that big a deal as weird as it may be. My bigger concern would be how it would interact with generic code. It's not uncommon that stuff that at first glance seems like it should be disallowed would actually cause a fair but of grief in generic code (e.g. that's at least part of why it's usually the case that function attributes that don't apply are just ignored rather than treated as errors). If it definitely wasn't going to cause problems for generic code, then such a change would probably be reasonable, but I have no idea how likely it would be to cause problems in generic code. So, maybe? You can certainly open an enhancement request about it. - Jonathan M Davis
Re: Range length property
On Tuesday, April 10, 2018 22:07:40 Cym13 via Digitalmars-d-learn wrote: > On Tuesday, 10 April 2018 at 20:08:14 UTC, Jonathan M Davis wrote: > > On Tuesday, April 10, 2018 19:47:10 Nordlöw via > > > > Digitalmars-d-learn wrote: > >> On Tuesday, 10 April 2018 at 14:34:40 UTC, Adam D. Ruppe wrote: > >> > On Tuesday, 10 April 2018 at 14:25:52 UTC, Nordlöw wrote: > >> >> Should ranges always provide a length property? > >> > > >> > No. > >> > > >> >> If so, in which cases is a length property an advantage or > >> >> a requirement? > >> > > >> > Just provide it whenever it is cheap to do so. If you need > >> > to do complex calculations or especially loop over contents > >> > to figure out the length, do NOT provide it. > >> > > >> > But if it is as simple as returning some value, provide it > >> > and algorithms can take advantage of it for optimizations > >> > etc. as needed. > >> > >> I'm thinking of my own container Hashmap having its range > >> ByKeyValue requiring one extra word of memory to store the > >> iteration count which, in turn, can be used to calculate the > >> length of the remaining range. Is this motivated? > > > > That would depend entirely on what you're trying to do, but in > > general, if a range has length, then some algorithms will be > > more efficient, and some algorithms do require length. So, if > > you can provide length, then the range will be more useful, > > just like a bidirectional range can be more useful than a > > forward range or a random-access range can be more useful than > > either. However, if you're not doing anything that ever > > benefits from it having length, then it doesn't buy you > > anything. So, it ultimately depends on what you're doing. In a > > general purpose library, I'd say that it should have length if > > it can do so in O(1), but if it's just for you, then it may or > > may not be worth it. > > > > The other thing to consider is what happens when the container > > is mutated. I don't think that ranges necessarily behave all > > that well when an underlying container is mutated, but it is > > something that has to be considered when dealing with a range > > over a container. Even if mutating the underlying container > > doesn't necessarily invalidate a range, maintaining the length > > in the manner that you're suggesting probably makes it so that > > it would be invalidated in more cases, since if any elements > > are added or removed in the portion that was already popped off > > the range, then the iteration count couldn't be used to > > calculate the length in the same way anymore. Now, with a hash > > map, the range is probably fully invalidated when anything gets > > added or removed anyway, since that probably screws with the > > order of the elements in the range, but how the range is going > > to behave when the underlying container is mutated and how > > having the length property does or doesn't affect that is > > something that you'll need to consider. > > > > - Jonathan M Davis > > I find that discussion very interesting as I had never considered > that because of design by introspection having a costly length > method would lead to unexpected calls by generic algorithms > making it a disadventage if present. > > On the other hand I don't think the end user should have to > scratch his head to find the length of a range, especially if > it's not trivial to get (say, O(log n) kind of case). Therefore > exposing a method in any case seems the best from an API > perspective. > > But to avoid the performance issues mentionned earlier it means > it should bear a different name (get/setLength comes to mind). I > believe this is the same kind of issue that lead to having "in" > for associative arrays but not regular ones. However this also > leads to less coherent APIs in contradiction with the principle > of least surprise. > > In retrospect since only "unexpected" calls to such methods cause > the issue I wonder if it wouldn't be best to have an UDA saying > "Hey, please, this method is costly, if you're a generic template > performing introspection you should probably not call me". And > writing that Andrei's work on complexity annotations comes to > mind. Anyway, I don't think the user should use different names > just to alleviate an issue on the library side but the > alternative would be costly to put in place... > > Any thoughts? In general, if you care about efficient code, it becomes critical that anything that's going to be used in generic code has well-known Big-O complexity, which is why C++ cares about that sort of thing with its containers and why Andrei specifically put the Big-O complexity of all of the generic container operations in std.container. And that extends to ranges. If ranges are implemented without any care about the algorithmic complexity of the operations, then performance is ultimately going to tank. And in the case of ranges, it's really not all that hard to understand the algorithmic complexity, because prett
Re: Range length property
On Tuesday, 10 April 2018 at 20:08:14 UTC, Jonathan M Davis wrote: On Tuesday, April 10, 2018 19:47:10 Nordlöw via Digitalmars-d-learn wrote: On Tuesday, 10 April 2018 at 14:34:40 UTC, Adam D. Ruppe wrote: > On Tuesday, 10 April 2018 at 14:25:52 UTC, Nordlöw wrote: >> Should ranges always provide a length property? > > No. > >> If so, in which cases is a length property an advantage or >> a requirement? > > Just provide it whenever it is cheap to do so. If you need > to do complex calculations or especially loop over contents > to figure out the length, do NOT provide it. > > But if it is as simple as returning some value, provide it > and algorithms can take advantage of it for optimizations > etc. as needed. I'm thinking of my own container Hashmap having its range ByKeyValue requiring one extra word of memory to store the iteration count which, in turn, can be used to calculate the length of the remaining range. Is this motivated? That would depend entirely on what you're trying to do, but in general, if a range has length, then some algorithms will be more efficient, and some algorithms do require length. So, if you can provide length, then the range will be more useful, just like a bidirectional range can be more useful than a forward range or a random-access range can be more useful than either. However, if you're not doing anything that ever benefits from it having length, then it doesn't buy you anything. So, it ultimately depends on what you're doing. In a general purpose library, I'd say that it should have length if it can do so in O(1), but if it's just for you, then it may or may not be worth it. The other thing to consider is what happens when the container is mutated. I don't think that ranges necessarily behave all that well when an underlying container is mutated, but it is something that has to be considered when dealing with a range over a container. Even if mutating the underlying container doesn't necessarily invalidate a range, maintaining the length in the manner that you're suggesting probably makes it so that it would be invalidated in more cases, since if any elements are added or removed in the portion that was already popped off the range, then the iteration count couldn't be used to calculate the length in the same way anymore. Now, with a hash map, the range is probably fully invalidated when anything gets added or removed anyway, since that probably screws with the order of the elements in the range, but how the range is going to behave when the underlying container is mutated and how having the length property does or doesn't affect that is something that you'll need to consider. - Jonathan M Davis I find that discussion very interesting as I had never considered that because of design by introspection having a costly length method would lead to unexpected calls by generic algorithms making it a disadventage if present. On the other hand I don't think the end user should have to scratch his head to find the length of a range, especially if it's not trivial to get (say, O(log n) kind of case). Therefore exposing a method in any case seems the best from an API perspective. But to avoid the performance issues mentionned earlier it means it should bear a different name (get/setLength comes to mind). I believe this is the same kind of issue that lead to having "in" for associative arrays but not regular ones. However this also leads to less coherent APIs in contradiction with the principle of least surprise. In retrospect since only "unexpected" calls to such methods cause the issue I wonder if it wouldn't be best to have an UDA saying "Hey, please, this method is costly, if you're a generic template performing introspection you should probably not call me". And writing that Andrei's work on complexity annotations comes to mind. Anyway, I don't think the user should use different names just to alleviate an issue on the library side but the alternative would be costly to put in place... Any thoughts?
Should "a is b" compile if a and b have unrelated classes?
I had a bug in my code that was messing me up for a while, and it boiled down to an identity check between two Object references with unrelated static types, like below: class A {} class B {} void main() { A a = new A; B b = new B; if (a is b) {} // compiles } I was surprised that the type system failed me here. It's true that A and B could be upcast to Object and then comparisons would make sense type-wise, but the comparison should never pass (and the compiler should know it won't since they are in separate inheritance subtrees) unless the programmer is intentionally breaking the type system. Is there reasoning for this? If not, should it be a warning or error, as it is for example when comparing two pointers to structs of different types?
Re: Range length property
On Tuesday, 10 April 2018 at 20:16:18 UTC, Steven Schveighoffer wrote: e.g. std.array.array is going to pre-allocate an array of the correct length and fill it in, vs. appending each element as it gets them from the range. Personally, I would store the length because typically a container range is short-lived. It also jives with the container itself which likely has O(1) length. Thanks, that's what I thought too.
Re: Range length property
On 4/10/18 4:08 PM, Jonathan M Davis wrote: On Tuesday, April 10, 2018 19:47:10 Nordlöw via Digitalmars-d-learn wrote: I'm thinking of my own container Hashmap having its range ByKeyValue requiring one extra word of memory to store the iteration count which, in turn, can be used to calculate the length of the remaining range. Is this motivated? That would depend entirely on what you're trying to do, but in general, if a range has length, then some algorithms will be more efficient, and some algorithms do require length. e.g. std.array.array is going to pre-allocate an array of the correct length and fill it in, vs. appending each element as it gets them from the range. Personally, I would store the length because typically a container range is short-lived. It also jives with the container itself which likely has O(1) length. -Steve
Re: Range length property
On Tuesday, April 10, 2018 19:47:10 Nordlöw via Digitalmars-d-learn wrote: > On Tuesday, 10 April 2018 at 14:34:40 UTC, Adam D. Ruppe wrote: > > On Tuesday, 10 April 2018 at 14:25:52 UTC, Nordlöw wrote: > >> Should ranges always provide a length property? > > > > No. > > > >> If so, in which cases is a length property an advantage or a > >> requirement? > > > > Just provide it whenever it is cheap to do so. If you need to > > do complex calculations or especially loop over contents to > > figure out the length, do NOT provide it. > > > > But if it is as simple as returning some value, provide it and > > algorithms can take advantage of it for optimizations etc. as > > needed. > > I'm thinking of my own container Hashmap having its range > ByKeyValue requiring one extra word of memory to store the > iteration count which, in turn, can be used to calculate the > length of the remaining range. Is this motivated? That would depend entirely on what you're trying to do, but in general, if a range has length, then some algorithms will be more efficient, and some algorithms do require length. So, if you can provide length, then the range will be more useful, just like a bidirectional range can be more useful than a forward range or a random-access range can be more useful than either. However, if you're not doing anything that ever benefits from it having length, then it doesn't buy you anything. So, it ultimately depends on what you're doing. In a general purpose library, I'd say that it should have length if it can do so in O(1), but if it's just for you, then it may or may not be worth it. The other thing to consider is what happens when the container is mutated. I don't think that ranges necessarily behave all that well when an underlying container is mutated, but it is something that has to be considered when dealing with a range over a container. Even if mutating the underlying container doesn't necessarily invalidate a range, maintaining the length in the manner that you're suggesting probably makes it so that it would be invalidated in more cases, since if any elements are added or removed in the portion that was already popped off the range, then the iteration count couldn't be used to calculate the length in the same way anymore. Now, with a hash map, the range is probably fully invalidated when anything gets added or removed anyway, since that probably screws with the order of the elements in the range, but how the range is going to behave when the underlying container is mutated and how having the length property does or doesn't affect that is something that you'll need to consider. - Jonathan M Davis
Re: Range length property
On Tuesday, 10 April 2018 at 14:34:40 UTC, Adam D. Ruppe wrote: On Tuesday, 10 April 2018 at 14:25:52 UTC, Nordlöw wrote: Should ranges always provide a length property? No. If so, in which cases is a length property an advantage or a requirement? Just provide it whenever it is cheap to do so. If you need to do complex calculations or especially loop over contents to figure out the length, do NOT provide it. But if it is as simple as returning some value, provide it and algorithms can take advantage of it for optimizations etc. as needed. I'm thinking of my own container Hashmap having its range ByKeyValue requiring one extra word of memory to store the iteration count which, in turn, can be used to calculate the length of the remaining range. Is this motivated?
Re: Destructor call
On 4/10/18 3:24 PM, Jonathan M Davis wrote: On Tuesday, April 10, 2018 18:52:19 kinke via Digitalmars-d-learn wrote: On Tuesday, 10 April 2018 at 18:34:54 UTC, n0fun wrote: Why the destructor is called in the second case and why not in the first? The first case is RAII, where destruction isn't done for not fully constructed instances. Yeah, which is arguably a bug: https://issues.dlang.org/show_bug.cgi?id=14246 The second case is GC finalization at program shutdown and looks like a bug, as the GC should probably immediately reclaim the allocated heap memory if construction wasn't successful. Maybe it should reclaim the memory immediately, but I don't see how it could be argued to be a bug. When memory is freed by the GC is an implementation detail, and it's never guaranteed that a finalizer will actually ever run. Actually, it is a bug, because the destructor is going to run the finalizer on a collection cycle, and the object may be partially created. This is due to the way it's created using new: 1. a memory block is allocated 2. The typeinfo is stored in the block 3. The runtime returns the pointer to the block. 4. the compiler calls the constructor on the block. Because the typeinfo is unconditionally stored, the finalizer will run, even if it shouldn't. The issue is that the compiler is much better at calling the constructor of the struct. This means we need 2 hooks for the construction -- 1. the memory allocation, and 2. a "post construction" call. I'd hate to pass the constructor parameters to a template function rather than the compiler handle all of these messy details. -Steve
Re: Destructor call
On Tuesday, April 10, 2018 18:52:19 kinke via Digitalmars-d-learn wrote: > On Tuesday, 10 April 2018 at 18:34:54 UTC, n0fun wrote: > > Why the destructor is called in the second case and why not in > > the first? > > The first case is RAII, where destruction isn't done for not > fully constructed instances. Yeah, which is arguably a bug: https://issues.dlang.org/show_bug.cgi?id=14246 > The second case is GC finalization at program shutdown and looks > like a bug, as the GC should probably immediately reclaim the > allocated heap memory if construction wasn't successful. Maybe it should reclaim the memory immediately, but I don't see how it could be argued to be a bug. When memory is freed by the GC is an implementation detail, and it's never guaranteed that a finalizer will actually ever run. - Jonathan M Davis
Re: Destructor call
On Tuesday, 10 April 2018 at 18:34:54 UTC, n0fun wrote: Why the destructor is called in the second case and why not in the first? The first case is RAII, where destruction isn't done for not fully constructed instances. The second case is GC finalization at program shutdown and looks like a bug, as the GC should probably immediately reclaim the allocated heap memory if construction wasn't successful.
Destructor call
import std.stdio; struct S(alias n) { this(int) { throw new Exception("Exception"); } ~this() { writeln("destructor " ~ n); } } void main() { writeln("--- 1 ---"); try { auto s = S!"1"(0); } catch (Exception) {} writeln("--- 2 ---"); try { auto s = new S!"2"(0); } catch (Exception) {} } Output: --- 1 --- --- 2 --- destructor 2 Why the destructor is called in the second case and why not in the first? How to design structs with such different behavior?
Re: Is std.variant.visit not @nogc?
On 4/10/18 12:59 PM, Paul Backus wrote: On Tuesday, 10 April 2018 at 12:34:07 UTC, aliak wrote: Awesome! this is a neat trick: union { AliasSeq!(T0, T1) values; } Is that usage documented somewhere, or is it somewhere in phobos maybe? Also, can Algebraic be fully replaced with this version then or is there some functionality that would stop it going through? It's called "type sequence instantiation", and it's documented in the "Compile-time Sequences" article [1] on dlang.org. I discovered it reading the source of the 'tagged_union' dub package [2]. It's not mentioned anywhere in the language spec, as far as I can tell. Ooh! that's really cool. I've put AliasSeq of types into a struct, but never considered putting it into a union. This has a lot of potential when you want to auto-generate unions. Nice trick! -Steve
Re: Range length property
On Tuesday, April 10, 2018 14:25:52 Nordlöw via Digitalmars-d-learn wrote: > Should ranges always provide a length property? > > If so, in which cases is a length property an advantage or a > requirement? Whether a range has a length property or not is primarily dependent on how efficient it is to implement length. https://dlang.org/phobos/std_container.html lists the Big-O complexity of the various functions and properties that are expected for containers, and in the case of length, that also applies to ranges. It lists O(log n) as the Big-O complexity of length, so length should only be implemented if its Big-O complexity is no worse than O(log n). In most cases, that means implementing it only if it's O(1) (I think that it's O(log n) rather than O(1) because of binary trees), and length should certainly never be implemented if it's O(n). Basically, if you can just return the length without calculating it, then it makes sense to implement it, but if you have to calculate it, then in most cases, it shouldn't be there. Range-based functions are going to expect length to be very cheap to call if it is present, and any function that needs to ascertain the length of a range even if it doesn't have length will call walkLength (which returns length if present and iterates the entire range to count it if it's not). As iterating the entire range to count it, is O(n), most algorithms won't do that are more likely to require length if they need to know how many elements there are in the range, but that depends on what they're doing. A function that requires a length property or which has a path optimized for ranges that have a length property checks for that with std.range.primitives.hasLength. Random access ranges are required to either be infinite or provide length, but for other range types, it's optional and must be checked for if an algorithm is going to use it. And actually, a large percentage of ranges are lazy, in which case, it's pretty rare that they can have a length property, because you usually have no way of knowing how long they're going to be without actually iterating through the range. So, while it's not uncommon for a range to define length, it's very common that they don't. - Jonathan M Davis
Re: Is std.variant.visit not @nogc?
On Tuesday, 10 April 2018 at 12:34:07 UTC, aliak wrote: Awesome! this is a neat trick: union { AliasSeq!(T0, T1) values; } Is that usage documented somewhere, or is it somewhere in phobos maybe? Also, can Algebraic be fully replaced with this version then or is there some functionality that would stop it going through? It's called "type sequence instantiation", and it's documented in the "Compile-time Sequences" article [1] on dlang.org. I discovered it reading the source of the 'tagged_union' dub package [2]. It's not mentioned anywhere in the language spec, as far as I can tell. SumType should be capable of doing anything that Algebraic can do (if it's not, please open an issue on Github!), but it's not a drop-in replacement, and it's still a work in progress. Documentation for the current version (more or less) is available at http://sumtype.dpldocs.info/index.html. If there are any particular features you'd like to see, let me know, and I'll do my best to add them. [1] https://dlang.org/articles/ctarguments.html#type-seq-instantiation [2] https://github.com/Superstar64/tagged_union/blob/master/source/tagged_union.d
Re: stirling numbers and multidimensional arrays
On Sunday, 8 April 2018 at 16:51:14 UTC, ag0aep6g wrote: On 04/08/2018 06:15 PM, popgen wrote: [...] [...] [...] [...] [...] Should it be `q <= k` here? You're using q as an index into an array of length k + 1. If you go up to i, you'll exceed that and go out of bounds. That you're seeing a segfault instead of a range error indicates that you're compiling with -release. Better not do that when debugging. Thank you for your help! And I learned two things, the error in the code and not to use -release while debugging.
trouble building dlang.org
I'm trying to update the language spec. I have the standard dmd installed on my Mac in `~/dlang/dmd` using the install script from the website "curl -fsS https://dlang.org/install.sh | bash -s dmd". Okay, good, done. Now, according to: dlang.org/CONTRIBUTING.md: "git clone https://github.com/dlang/dlang.org cd dlang.org" Okay, done. Now: "make -f posix.mak html" This first errored out with "No package file found in /Users/zach/dlang/dmd/, expected one of dub.json/dub.sdl/package.json make: *** [.generated/ddoc_preprocessor] Error 2" I didn't know why the dub.sdl wasn't already installed, so I manually copied it from github. But now the error for "make -f posix.mak html" is: ".generated/stable_dmd-2.078.2/dmd2/osx/bin/dub build --compiler=.generated/stable_dmd-2.078.2/dmd2/osx/bin/dmd --root=ddoc && \ mv ddoc/ddoc_preprocessor .generated/ddoc_preprocessor Invalid source/import path: /Users/zach/dlang/dmd/src/dmd Invalid source/import path: /Users/zach/dlang/dmd/generated/dub" So I'm here wondering wuzzup? The basic instructions in CONTRIBUTING.md aren't working. Anyone?
Re: SMTP Mail
On Tuesday, 10 April 2018 at 15:10:44 UTC, Vino wrote: The variable "to" is of type string[] but we need it as Array!string The variable "Subject" but we need it as Array!string. You'll have to convert them yourself if that is a must, but why would you need that?
Re: SMTP Mail
On Tuesday, 10 April 2018 at 13:51:02 UTC, Adam D. Ruppe wrote: On Tuesday, 10 April 2018 at 11:09:56 UTC, Vino wrote: Now the program works, but the attachment does not work as expected, message.addAttachment("text/plain", "C:\\Temp\\Test\Test1.txt", "Test"); What did you expect that "Test" argument to do if it was going to read the file as the content? I guess I should change the documents on this. The way it works is the filename argument is just what is seen in the email as a suggestion name for the user to download the attachment, and the content argument is what is what's inside that attachment. Since the attachment name just suggests a name, and the user decides where to put it, it should NOT have a path name. So try this instead: addAttachment("text/plain", "Test1.txt", std.file.read("C:\Temp\Test\Test1.txt")); so the name argument is JUST the name to suggest to the user, then the content argument gives the content of your file to attach - which here is read from the file on disk via the phobos std.file read function. Hi Adam, Thank you very much, the program now works, but i need to make some adjustment, if possible can you please help me on this. The variable "to" is of type string[] but we need it as Array!string The variable "Subject" but we need it as Array!string. From, Vino.B
Re: Range length property
On Tuesday, 10 April 2018 at 14:25:52 UTC, Nordlöw wrote: Should ranges always provide a length property? No. If so, in which cases is a length property an advantage or a requirement? Just provide it whenever it is cheap to do so. If you need to do complex calculations or especially loop over contents to figure out the length, do NOT provide it. But if it is as simple as returning some value, provide it and algorithms can take advantage of it for optimizations etc. as needed.
Range length property
Should ranges always provide a length property? If so, in which cases is a length property an advantage or a requirement?
Re: How to destruct class instances allocated by a Region-allocator over a single GC block
On 11/04/2018 1:56 AM, Eduard Staniloiu wrote: On Monday, 9 April 2018 at 14:51:24 UTC, Per Nordlöw wrote: On Monday, 9 April 2018 at 13:51:47 UTC, Steven Schveighoffer wrote: Well, you know the type, because make returned it no? The contract is, you call obj = make!X(args), then you have to call dispose(obj), where obj is of the type X. That's how it knows. If you are thinking you want to destroy the whole block at once (typed as void[]), that's not how it works. stdx.allocator is not going to help you with GC collection, it's not geared towards that purpose. Ok, thanks! If you are using a custom allocator to allocate memory then you also have to manually dispose of the memory when it is no longer needed. You can't have a custom allocator to supply you with the memory and then have the GC track and dispose of it. I get the feeling that this is what you were looking for? As long as you can use libc's free, sure you can :)
Re: How to destruct class instances allocated by a Region-allocator over a single GC block
On Monday, 9 April 2018 at 14:51:24 UTC, Per Nordlöw wrote: On Monday, 9 April 2018 at 13:51:47 UTC, Steven Schveighoffer wrote: Well, you know the type, because make returned it no? The contract is, you call obj = make!X(args), then you have to call dispose(obj), where obj is of the type X. That's how it knows. If you are thinking you want to destroy the whole block at once (typed as void[]), that's not how it works. stdx.allocator is not going to help you with GC collection, it's not geared towards that purpose. Ok, thanks! If you are using a custom allocator to allocate memory then you also have to manually dispose of the memory when it is no longer needed. You can't have a custom allocator to supply you with the memory and then have the GC track and dispose of it. I get the feeling that this is what you were looking for?
Re: SMTP Mail
On Tuesday, 10 April 2018 at 11:09:56 UTC, Vino wrote: Now the program works, but the attachment does not work as expected, message.addAttachment("text/plain", "C:\\Temp\\Test\Test1.txt", "Test"); What did you expect that "Test" argument to do if it was going to read the file as the content? I guess I should change the documents on this. The way it works is the filename argument is just what is seen in the email as a suggestion name for the user to download the attachment, and the content argument is what is what's inside that attachment. Since the attachment name just suggests a name, and the user decides where to put it, it should NOT have a path name. So try this instead: addAttachment("text/plain", "Test1.txt", std.file.read("C:\Temp\Test\Test1.txt")); so the name argument is JUST the name to suggest to the user, then the content argument gives the content of your file to attach - which here is read from the file on disk via the phobos std.file read function.
Re: Is std.variant.visit not @nogc?
On Tuesday, 10 April 2018 at 03:48:25 UTC, Paul Backus wrote: Nope! It's just a tagged union, almost exactly the same as what you'd write by hand in C. You can take a look at the source yourself, if you're curious---it's actually pretty simple: https://github.com/pbackus/sumtype/blob/master/src/sumtype.d#L27 Awesome! this is a neat trick: union { AliasSeq!(T0, T1) values; } Is that usage documented somewhere, or is it somewhere in phobos maybe? Also, can Algebraic be fully replaced with this version then or is there some functionality that would stop it going through?
Re: SMTP Mail
On Monday, 9 April 2018 at 19:19:53 UTC, Adam D. Ruppe wrote: On Monday, 9 April 2018 at 15:38:55 UTC, Vino.B wrote: Thank you very much, I copied your folder arsd under the phobes folder in c:\D\... and the program was placed on my desktop and tried to execute it from the desktop via rdmd. I don't think rdmd is seeing the dependency on htmltotext.d. Try importing it explicitly from your main: import arsd.email; import arsd.htmltotext; /* the rest of your code */ Just that way rdmd will find it easier. Hi Adam, Now the program works, but the attachment does not work as expected, message.addAttachment("text/plain", "C:\\Temp\\Test\Test1.txt", "Test"); It takes the full path as file name eg: If the attachment file resides on the path C:\Temp\Test\Test1.txt" the attachment name file name that we receive is as "CTempTestTest1.txt" and also it does not attached the real file, instead the content of the file is "Test" We Tried the below message.addAttachment("text/plain", "Test1.txt", "C:\\Temp\\Test\Test1.txt"); After the above change the attachment file name is "Test1.txt" with the content "C:\Temp\Test\Test1.txt" The orignal content of the file is "Hi This is Test Attachment". From, Vino.B