Re: Announcing bottom-up-build - a build system for C/C++/D
Am Thu, 27 Jun 2013 10:26:01 +0200 schrieb eles e...@eles.com: On Thursday, 27 June 2013 at 07:32:32 UTC, eles wrote: CTRL-Z works for me. I think it expects input. Ignore it. It just suspends it. You might want to check how many programs you thought to have killed like this so far in your running session. It might eat up your RAM. -- Marco
Re: Announcing bottom-up-build - a build system for C/C++/D
On Thursday, 27 June 2013 at 23:03:40 UTC, Graham St Jack wrote: This isn't a build tool for everyone, but it really does make a big difference on big projects. Well I'm noticing some interesting concepts, such as being able to associate an include or import file with the library to link in, so that it gets done automatically simply by using the include/import file, great idea assuming I understood that correctly. One thing you may want to consider, or maybe this is already possible, is add the ability to optionally specify something like *.d so that all .d files get included from a folder, rather than have to always individually specify them manually. Also more concise documentation with clearer examples would be invaluable. I'm currently unsure if I need to restructure my existing project folders to fit bub or if bub can be configured to fit my existing projects. --rt
Re: Announcing bottom-up-build - a build system for C/C++/D
How does this build tool handle projects with multiple executables ? For example the util-linux package contains dozens of utilities or a project might have a CLI and a GUI version. Or there might be slight alterations like setting a version or debug flag: -debug=threading -version=demo -- Marco
Re: Announcing bottom-up-build - a build system for C/C++/D
On Fri, 28 Jun 2013 08:05:08 +0200, Rob T wrote: On Thursday, 27 June 2013 at 23:03:40 UTC, Graham St Jack wrote: This isn't a build tool for everyone, but it really does make a big difference on big projects. Well I'm noticing some interesting concepts, such as being able to associate an include or import file with the library to link in, so that it gets done automatically simply by using the include/import file, great idea assuming I understood that correctly. That is correct. A side effect of assigning headers to libraries is that bub can then enforce the visibility rules and give understandable error messages almost instantaneously when you transgress them. Another consequence is that the compiler only needs to be given a few -I directives because you aren't using them to control visibility. One thing you may want to consider, or maybe this is already possible, is add the ability to optionally specify something like *.d so that all .d files get included from a folder, rather than have to always individually specify them manually. A useful idea. I will add it to the list. Also more concise documentation with clearer examples would be invaluable. I'm currently unsure if I need to restructure my existing project folders to fit bub or if bub can be configured to fit my existing projects. Documentation is always tough to pitch at the right level. I will see what I can do. Whether you need to restructure your project depends on whether you have already thought about dependencies and arranged things accordingly. My suggestion is to extend the example a bit and get a feel for how it works, then think about what that means for your project.
Re: Announcing bottom-up-build - a build system for C/C++/D
On Fri, 28 Jun 2013 08:28:03 +0200, Marco Leise wrote: How does this build tool handle projects with multiple executables ? For example the util-linux package contains dozens of utilities or a project might have a CLI and a GUI version. Or there might be slight alterations like setting a version or debug flag: -debug=threading -version=demo A central theme in bottom-up-build is to produce any number of build artifacts: libraries, executables, tests, etc. Different versions are catered for with: bub-config --mode=whatever build-dir The mode is described in your configuration file, and results in a build directory set up specifically for that mode. If you want multiple modes, use multiple build directories. Take a look in example/bub.cfg.
Re: Announcing bottom-up-build - a build system for C/C++/D
Am Fri, 28 Jun 2013 07:03:27 + (UTC) schrieb Graham St Jack graham.stj...@internode.on.net: On Fri, 28 Jun 2013 08:28:03 +0200, Marco Leise wrote: How does this build tool handle projects with multiple executables ? For example the util-linux package contains dozens of utilities or a project might have a CLI and a GUI version. Or there might be slight alterations like setting a version or debug flag: -debug=threading -version=demo A central theme in bottom-up-build is to produce any number of build artifacts: libraries, executables, tests, etc. Different versions are catered for with: bub-config --mode=whatever build-dir The mode is described in your configuration file, and results in a build directory set up specifically for that mode. If you want multiple modes, use multiple build directories. Take a look in example/bub.cfg. Sounds good! -- Marco
Re: Announcing bottom-up-build - a build system for C/C++/D
On 27/06/13 09:40, Graham St Jack wrote: Bottom-up-build (bub) is a build system written in D which supports building of large C/C++/D projects. I've worked with Graham in the past and can attest to bub's coolness. My pet project 'terminol' is about a month away from an initial release, but given that is uses the bub build system, and that Graham has made his announcement, it could be interest now to anyone wishing to see a small project that uses bub: https://github.com/bagnose/terminol Briefly: terminol is a lightweight terminal emulator for Linux, essentially aimed at being a rxvt-unicode refresh. It should checkout, build fine with bub, but so far I'm the only one who ever has. I'm sorry, it's not written in D (it's written in C++11) but I am a huge fan of D. Having worked with GNU Make, Jam and autotools (and looked closely at several others) I find bub very pleasant to use indeed. I won't repeat the benefits that Graham already espoused. I think the focus with bub thus far has been to develop its core approaches: unifying C/C++/D, bottom-up-build, library inference, circularity detection, etc. As such, it is a little unfurnished at the edges. For example, bub does not have a defined scheme for determining things like: what libraries does the user have available and what are their peculiarities (versions, location, etc). At the moment the user may need to do a bit of bub.cfg customisation of their own to make things work. Those things are the next hurdle and will be interesting to discuss. However I think bub already demonstrates the promise of greatness and is worth taking a good look at. David Bryant
Re: dlibgit updated to libgit2 v0.19.0
On Friday, 28 June 2013 at 16:00:57 UTC, Andrej Mitrovic wrote: Deimos is an overhead which provides no benefits. It was supposed to be used to make discovery easy, but discovery can be done through a wiki, or dlang.org, or an automated process (dub). I suspect with time Deimos will be completely superseeded by dub or whatever tool becomes standard package manager for D. However, it should not be simply discarded because: 1) right now dub is not an official dlang.org project, but Deimos is 2) it is a certain brand name which gives promises about aggregated bindings - all Deimos bindings are thin 1-to-1 reflections of their C origin. In that sense, I would have expected Deimos become part of dub registry at some point, preferrably as a separate package category. But they should not loose identity of Deimos project.
Re: dlibgit updated to libgit2 v0.19.0
On 6/28/13, Sönke Ludwig slud...@outerproduct.org wrote: It's a CI server that heavily relies on GIT and DUB to provide an almost configuration free experience. It's still WIP and just planned for internal use for now, though. Btw, do you have any opinion on whether the API should be struct-based or class-based? I'm thinking I'll probably have to worry about memory management, so either refcounted structs or final classes could be used one way or another (similar to CairoD). Btw, if you have any suggestions about the overall API design, or what you need in the D API that the C API doesn't support, do let me know.
Re: Announcing bottom-up-build - a build system for C/C++/D
On Thursday, 27 June 2013 at 00:10:37 UTC, Graham St Jack wrote: Having side-by-side comparisons of D against bash scripts and C++ modules had the effect of turning almost all the other team members into D advocates. Any chance we could know what team this is? (Sorry if this is common knowledge)
Programming in D book is about 88% translated
I have continued with the translation of the book. There are 82 of the 718 pages still to be translated. (However, I still need to write the UDA chapter.) In addition to many corrections and additions throughout the book, there are the following chapters translated: * Bit Operations * Conditional Compilation * is Expression * Function Pointers, Delegates, and Lambdas * foreach with Structs and Classes * Unions * Labels and goto As a reminder, the book is available as PDF, downloadable from the header of each chapter: http://ddili.org/ders/d.en/index.html No Kindle or Lulu versions yet. Ali
Re: Programming in D book is about 88% translated
On 06/28/2013 07:15 PM, MattCoder wrote: I'm really thinking about translate to portuguese That sounds great! :) Somebody else had started a translation last year to Brazilian Portuguese. I have just emailed the author to see how much they have advanced. I was about to email you know about any legal terms etc. Thinking that it is free enough, I had chosen this: http://creativecommons.org/licenses/by-nc-sa/3.0/us/ Just let me know if it is limiting in any way. Ali
Re: Automatic typing
On Friday, 28 June 2013 at 00:48:23 UTC, Steven Schveighoffer wrote: On Thu, 27 Jun 2013 20:34:53 -0400, JS js.m...@gmail.com wrote: Would it be possible for a language(specifically d) to have the ability to automatically type a variable by looking at its use cases without adding too much complexity? It seems to me that most compilers already can infer type mismatchs which would allow them to handle stuff like: main() { auto x; auto y; x = 3; // x is an int, same as auto x = 3; y = f(); // y is the same type as what f() returns x = 3.9; // x is really a float, no mismatch with previous type(int) } in this case x and y's type is inferred from future use. The compiler essentially just lazily infers the variable type. Obviously ambiguity will generate an error. There are very good reasons not to do this, even if possible. Especially if the type can change. Consider this case: void foo(int); void foo(double); void main() { auto x; x = 5; foo(x); // way later down in main x = 6.0; } What version of foo should be called? By your logic, it should be the double version, but looking at the code, I can't reason about it. I have to read the whole function, and look at every usage of x. auto then becomes a liability, and not a benefit. says who? No one is forcing you to use it with an immediate inference. If you get easily confused then simply declare x as a double in the first place! Most of the time a variable's type is well know by the programmer. That is, the programmer has some idea of the type a variable is to take on. Having the compiler infer the type is tantamount to figuring out what the programmer had in mind, in most cases this is rather easy to do... in any ambiguous case an error can be thrown. Coupling the type of a variable with sparse usages is going to be extremely confusing and problematic. You are better off declaring the variable as a variant. If you are confused by the usage then don't use it. Just because for some programmers in some cases it is bad does not mean that it can't be useful to some programmers in some cases. Some programmers what to dumb down the compiler because they themselves want to limit all potential risk... What's amazing is that many times the features they are against does not have to be used in the first place. If you devise an extremely convoluted example then simply use a unit test or define the type explicitly. I don't think limiting the compiler feature set for the lowest common denominator is a way to develop a powerful language. You say using a variant type is better off, how? What is the difference besides performance? An auto type without immediate type inference offers all the benefits of static typing with some of those from a variant type... Since it seems you are not against variant then why would you be against a static version, since it actually offers more safety? In fact, my suggestion could simply be seen as an optimization of a variant type. e.g., variant x; x = 3; the compiler realizes that x can be reduced to an int type and sees the code as int x; x = 3; Hence, unless you are against variants and think they are evil(which contradicts your suggestion to use it), your argument fails.
Re: Automatic typing
On Friday, June 28, 2013 02:34:53 JS wrote: Would it be possible for a language(specifically d) to have the ability to automatically type a variable by looking at its use cases without adding too much complexity? It seems to me that most compilers already can infer type mismatchs which would allow them to handle stuff like: main() { auto x; auto y; x = 3; // x is an int, same as auto x = 3; y = f(); // y is the same type as what f() returns x = 3.9; // x is really a float, no mismatch with previous type(int) } in this case x and y's type is inferred from future use. The compiler essentially just lazily infers the variable type. Obviously ambiguity will generate an error. Regardless of whether such a feature would be of value (and honestly, I'm inclined to believe that it would do more harm than good), Walter would never go for it, because it would require code flow analysis, and he pretty much refuses to have that in the compiler or to have any feature which would require it in the language. So, while it may be technically feasible, it'll never happen. - Jonathan M Davis
Re: why allocators are not discussed here
Am Thu, 27 Jun 2013 01:59:00 +0200 schrieb Adam D. Ruppe destructiona...@gmail.com: void fillBuffer(lent char[] buffer) {} would be disallowed and that is something I would definitely want. Isn't that what scope is for? -- Marco
Re: Using alloca?
Am Fri, 28 Jun 2013 06:42:31 +0200 schrieb Maxime Chevalier-Boisvert maximechevali...@gmail.com: I'd like to stack-allocate an array that will be dynamically sized. Is alloca somewhere in the standard D library? If so, what should I import to have access to it? As a side note, in Mono-D you can just type alloca, then press Ctrl+Alt+Space and the correct import magically appears at the top of the source file. -- Marco
Re: Notes from C++ static analysis
On 6/27/2013 8:22 PM, Peter Williams wrote: Yes, but voting is very seldom the best way so decide a technical issue. You want the best technical solution not the one supported by the best lobbyists. A sound technical argument can trump votes. There are enough cases of votes overriding technical arguments to everyone's later regret, like exported templates in C++ :-)
Re: Notes from C++ static analysis
On Friday, June 28, 2013 00:48:20 Walter Bright wrote: On 6/27/2013 8:22 PM, Peter Williams wrote: Yes, but voting is very seldom the best way so decide a technical issue. You want the best technical solution not the one supported by the best lobbyists. A sound technical argument can trump votes. There are enough cases of votes overriding technical arguments to everyone's later regret, like exported templates in C++ :-) Agreed. I just disagree with the idea that what the majority thinks is irrelevant. It _is_ relevant, but it's just one of the things to consider. The place where it's likely to matter most is when you have multiple choices which are all more or less equal. Where it's likely to matter the least is when you have strong technical arguments against the majority opinion, and the majority opinion does not have similarly strong arguments in its favor. - Jonathan M Davis
Suggesting new changelog format
Turn on the sound ;) http://starlogs.net/#D-Programming-Language/dmd /Jonas
Re: Suggesting new changelog format
On Friday, 28 June 2013 at 08:11:04 UTC, Jonas Drewsen wrote: Turn on the sound ;) http://starlogs.net/#D-Programming-Language/dmd /Jonas http://forum.dlang.org/post/xbadgetphtoqaodkl...@forum.dlang.org
Re: Suggesting new changelog format
On Friday, 28 June 2013 at 08:14:21 UTC, Mr. Anonymous wrote: On Friday, 28 June 2013 at 08:11:04 UTC, Jonas Drewsen wrote: Turn on the sound ;) http://starlogs.net/#D-Programming-Language/dmd /Jonas http://forum.dlang.org/post/xbadgetphtoqaodkl...@forum.dlang.org Ahh missed that one /Jonas
Re: why allocators are not discussed here
On Friday, 28 June 2013 at 07:07:39 UTC, Marco Leise wrote: Am Thu, 27 Jun 2013 01:59:00 +0200 schrieb Adam D. Ruppe destructiona...@gmail.com: void fillBuffer(lent char[] buffer) {} would be disallowed and that is something I would definitely want. Isn't that what scope is for? Reading dlang.org makes you guess so but official position is that 'scope' does not exist, so it is hard to say what it is really for.
Re: why allocators are not discussed here
On Thursday, 27 June 2013 at 22:50:47 UTC, John Colvin wrote: Old but perhaps relevant? http://www.linkedin.com/news?viewArticle=articleID=-1gid=86782type=memberitem=253295471articleURL=http%3A%2F%2Fwww%2Eallendowney%2Ecom%2Fss08%2Fhandouts%2Fberger02reconsidering%2Epdfurlhash=96TJgoback=%2Egmr_86782%2Egde_86782_member_253295471 (It's an academic article about memory allocation from 2002) Interesting paper. Still concurrency isn't really addressed, which is a problem to be future proof.
Re: why allocators are not discussed here
On Friday, 28 June 2013 at 07:07:39 UTC, Marco Leise wrote: Isn't that what scope is for? I don't really know. In practice, it does something else (usually nothing, but suppresses heap closure allocation on delegates). The DIPs relating to it all talk about returning refs from functions and I'm not sure if they relate to the built ins or not- I don't think it would quite work for what I have in mind.
Re: why allocators are not discussed here
On Friday, 28 June 2013 at 11:55:46 UTC, Adam D. Ruppe wrote: On Friday, 28 June 2013 at 07:07:39 UTC, Marco Leise wrote: Isn't that what scope is for? I don't really know. In practice, it does something else (usually nothing, but suppresses heap closure allocation on delegates). The DIPs relating to it all talk about returning refs from functions and I'm not sure if they relate to the built ins or not- I don't think it would quite work for what I have in mind. It is no-op keyword in current implementation for everything but delegates. DIP speculation was based on http://dlang.org/attribute.html#scope and Parameter Storage Classes in http://dlang.org/function.html but that info is obviously outdated.
Re: Folding similar templates into one
Am Thu, 27 Jun 2013 23:24:48 +0200 schrieb Meta jared...@gmail.com: I'm not an expert on how DMD works, but could this possibly be done after the native code is generated I've thought of that as well, but you have to merge templates at an earlier stage. In case of a compiler such as GCC, the native code is not even generated in the compiler, but an external assembler. That said, DMD does not create duplicate template instances for the same parameters. I'd assume this includes string lambdas. And I'm not sure what you really want to improve for assertNotThrown. It is a unit testing function and the most important thing at the moment seems to keep DMD's memory consumption low, which more compile-time parameters can only increase. Another point is that today's best compilers are good at detecting compile-time constants already and could inline a function with runtime parameters that are statically known. I've once let DMD create a switch-case with 81 cases for me and used a 100% templated function specialized for all these cases. The result was a major slow-down from all the compile-time arguments. Run-time arguments are just better! -- Marco
Re: Folding similar templates into one
On Friday, 28 June 2013 at 12:45:22 UTC, Marco Leise wrote: Am Thu, 27 Jun 2013 23:24:48 +0200 schrieb Meta jared...@gmail.com: I'm not an expert on how DMD works, but could this possibly be done after the native code is generated I've thought of that as well, but you have to merge templates at an earlier stage. In case of a compiler such as GCC, the native code is not even generated in the compiler, but an external assembler. That said, DMD does not create duplicate template instances for the same parameters. I'd assume this includes string lambdas. That's good to know. I wasn't sure if there were some cases when template were ellided or not, even with the same arguments. By string lambdas, I mean lambdas of the form sort!a = b that are heavily used in std.algorithm. And I'm not sure what you really want to improve for assertNotThrown. It is a unit testing function and the most important thing at the moment seems to keep DMD's memory consumption low, which more compile-time parameters can only increase. I was only using assertNotThrown as an example of a template function where parameters that could be compile-time arguments become run-time arguments to minimize template bloat. Another point is that today's best compilers are good at detecting compile-time constants already and could inline a function with runtime parameters that are statically known. I've once let DMD create a switch-case with 81 cases for me and used a 100% templated function specialized for all these cases. The result was a major slow-down from all the compile-time arguments. Run-time arguments are just better! That is certainly a corner case. Perhaps finding a way to fold templates in some cases would still provide benefits in more normal cases.
Re: Folding similar templates into one
On Friday, 28 June 2013 at 12:45:22 UTC, Marco Leise wrote: Am Thu, 27 Jun 2013 23:24:48 +0200 schrieb Meta jared...@gmail.com: I'm not an expert on how DMD works, but could this possibly be done after the native code is generated I've thought of that as well, but you have to merge templates at an earlier stage. In case of a compiler such as GCC, the native code is not even generated in the compiler, but an external assembler. That said, DMD does not create duplicate template instances for the same parameters. I'd assume this includes string lambdas. What is a string lambda ? Do you mean a string alias latter parsed as an expression, or an actual lambda function. There were talks about this recently in learn: If you *type* the same lambda function twice, it *will* generate two different templates. http://forum.dlang.org/thread/rufkccowcdogctvck...@forum.dlang.org For example: struct S(alias pred){} void main() { auto a = S!(() = 1)(); auto b = S!(() = 1)(); a = b; } DMD v2.064 DEBUG main.d(7): Error: cannot implicitly convert expression (b) of type S!(function int() { return 1; } ) to S!(function int() { return 1; } ) However, enum PRED = () = 1; struct S(alias pred){} void main() { auto a = S!PRED(); auto b = S!PRED(); a = b; } This is fine. From testing, *string* preds don't have this feature/bug (?), even if you compile time build them, the compiler will see that it is the same string (probably true for integrals and whatnot). But for lambdas, only their *name* counts (eg __lambda1__). So if you plan to re-use a lambda, it *must* be stored in a way the compiler can see its unicity, and not typed more than once. Furthermore, I'm think this is the correct behavior.
Re: Folding similar templates into one
On Thursday, 27 June 2013 at 02:03:52 UTC, Meta wrote: I'd like to ask, however, why should this be? The arguments line and file will only ever be strings and ints. They don't vary in type, only value, and changing those values will not affect how the function works. You could easily substitute out exception.d with stdio.d, and the functionality will be unchanged. Just because the arguments are known 99% of the time at compile time, doesn't mean they should be parameters. Parameters shouldn't be used to just mean compile time anyways, but *specifically* to create different versions of a function or code, which in this case, is not the case at all. Besides, there are scenarios where you could pass these as runtime parameters from higher functions, if you want the exception to look like it came from a higher level call. Making these parameters would mean that *any* function that handles lines or filenames would have to be parameterized on that.
Re: why allocators are not discussed here
On Friday, 28 June 2013 at 10:57:45 UTC, deadalnix wrote: On Thursday, 27 June 2013 at 22:50:47 UTC, John Colvin wrote: Old but perhaps relevant? http://www.linkedin.com/news?viewArticle=articleID=-1gid=86782type=memberitem=253295471articleURL=http%3A%2F%2Fwww%2Eallendowney%2Ecom%2Fss08%2Fhandouts%2Fberger02reconsidering%2Epdfurlhash=96TJgoback=%2Egmr_86782%2Egde_86782_member_253295471 (It's an academic article about memory allocation from 2002) Interesting paper. Still concurrency isn't really addressed, which is a problem to be future proof. http://en.wikipedia.org/wiki/Hoard_memory_allocator
Re: Automatic typing
On Friday, 28 June 2013 at 00:34:54 UTC, JS wrote: Would it be possible for a language(specifically d) to have the ability to automatically type a variable by looking at its use cases without adding too much complexity? Well ocaml has it (https://en.wikipedia.org/wiki/Hindley%E2%80%93Milner) and well it's not all that positive, at least in that language. Combined with parametric polymorphism it's nice and sound, except it has the potential to hide a simple typo a lot further from where it is (think mixing up integer operators and FP operators). As it break overloading on leaves, it is the reason ocaml has print_string and print_int which is quite frankly ugly. Once you have type inference, the first thing you do to make your code readable is to add back type annotations.
Re: Automatic typing
On Friday, 28 June 2013 at 07:04:12 UTC, Jonathan M Davis wrote: On Friday, June 28, 2013 02:34:53 JS wrote: Would it be possible for a language(specifically d) to have the ability to automatically type a variable by looking at its use cases without adding too much complexity? It seems to me that most compilers already can infer type mismatchs which would allow them to handle stuff like: main() { auto x; auto y; x = 3; // x is an int, same as auto x = 3; y = f(); // y is the same type as what f() returns x = 3.9; // x is really a float, no mismatch with previous type(int) } in this case x and y's type is inferred from future use. The compiler essentially just lazily infers the variable type. Obviously ambiguity will generate an error. Regardless of whether such a feature would be of value (and honestly, I'm inclined to believe that it would do more harm than good), Walter would never go for it, because it would require code flow analysis, and he pretty much refuses to have that in the compiler or to have any feature which would require it in the language. So, while it may be technically feasible, it'll never happen. code flow analysis is require for @disable this. And this is the very reason why @disable this is full of holes right now.
Re: Automatic typing
ponce: Well ocaml has it (https://en.wikipedia.org/wiki/Hindley%E2%80%93Milner) and well it's not all that positive, at least in that language. I think a H-M global type inferencer is not needed for what the OP is asking for, that is limited _inside_ functions, so it's not global. See the flow-typing link I have shown above (the links I add to threads aren't just for show). Bye, bearophile
Re: Folding similar templates into one
Meta jared...@gmail.com wrote in message news:ovlbbsdtyejzpsllf...@forum.dlang.org... I'm not an expert on how DMD works, but could this possibly be done after the native code is generated, but before optimizations are performed? Just throwing out ideas. The obvious place to do this is at link time - then you get to fold all functions from all compilation units. It becomes something similar to string constant pooling - you fold sections/data based on content, not labels.
Re: Automatic typing
On Fri, 28 Jun 2013 02:51:39 -0400, JS js.m...@gmail.com wrote: On Friday, 28 June 2013 at 00:48:23 UTC, Steven Schveighoffer wrote: On Thu, 27 Jun 2013 20:34:53 -0400, JS js.m...@gmail.com wrote: Would it be possible for a language(specifically d) to have the ability to automatically type a variable by looking at its use cases without adding too much complexity? It seems to me that most compilers already can infer type mismatchs which would allow them to handle stuff like: main() { auto x; auto y; x = 3; // x is an int, same as auto x = 3; y = f(); // y is the same type as what f() returns x = 3.9; // x is really a float, no mismatch with previous type(int) } in this case x and y's type is inferred from future use. The compiler essentially just lazily infers the variable type. Obviously ambiguity will generate an error. There are very good reasons not to do this, even if possible. Especially if the type can change. Consider this case: void foo(int); void foo(double); void main() { auto x; x = 5; foo(x); // way later down in main x = 6.0; } What version of foo should be called? By your logic, it should be the double version, but looking at the code, I can't reason about it. I have to read the whole function, and look at every usage of x. auto then becomes a liability, and not a benefit. says who? No one is forcing you to use it with an immediate inference. If you get easily confused then simply declare x as a double in the first place! This is already defined: auto x = 5; To change the meaning of that, would be unnecessarily confusing. Most of the time a variable's type is well know by the programmer. That is, the programmer has some idea of the type a variable is to take on. Having the compiler infer the type is tantamount to figuring out what the programmer had in mind, in most cases this is rather easy to do... in any ambiguous case an error can be thrown. It's not the programmer I'm worried about. It's the maintainer/reviewer. Coupling the type of a variable with sparse usages is going to be extremely confusing and problematic. You are better off declaring the variable as a variant. If you are confused by the usage then don't use it. Just because for some programmers in some cases it is bad does not mean that it can't be useful to some programmers in some cases. But I use auto all the time, and I don't want its meaning to change. Some programmers what to dumb down the compiler because they themselves want to limit all potential risk... What's amazing is that many times the features they are against does not have to be used in the first place. As you have the compiler infer more and more, you lose it's ability to statically detect errors. This is the point of having a statically typed language. If you want loosey goosey semantics, you can use php. If you devise an extremely convoluted example then simply use a unit test or define the type explicitly. I don't think limiting the compiler feature set for the lowest common denominator is a way to develop a powerful language. simply is an inaccurate description. Maintain any large project for some time in php and you will know what I mean. You say using a variant type is better off, how? What is the difference besides performance? An auto type without immediate type inference offers all the benefits of static typing with some of those from a variant type... It declares up front this can change type mid-function. I don't have to read the whole function to guess it's type, it's a variant. Since it seems you are not against variant then why would you be against a static version, since it actually offers more safety? Variant is reasonable. It allows you to specify that you don't care about the type. And anything that takes variant can do the same. But in your scheme, the type is NOT I don't care, but basically defined by the compiler. Good luck discovering what it is. I see a lot of pragma(msg, typeof(x)) going to be put in that code. In fact, my suggestion could simply be seen as an optimization of a variant type. e.g., variant x; x = 3; the compiler realizes that x can be reduced to an int type and sees the code as int x; x = 3; Hence, unless you are against variants and think they are evil(which contradicts your suggestion to use it), your argument fails. My argument is that auto should be left the way it is. I don't want it to change. And variant already does what you want with less confusing semantics, no reason to add another feature. -Steve
Re: Automatic typing
On 06/28/2013 03:44 PM, ponce wrote: On Friday, 28 June 2013 at 00:34:54 UTC, JS wrote: Would it be possible for a language(specifically d) to have the ability to automatically type a variable by looking at its use cases without adding too much complexity? Well ocaml has it (https://en.wikipedia.org/wiki/Hindley%E2%80%93Milner) and well it's not all that positive, at least in that language. Combined with parametric polymorphism it's nice and sound, except it has the potential to hide a simple typo a lot further from where it is (think mixing up integer operators and FP operators). As it break overloading on leaves, it is the reason ocaml has print_string and print_int which is quite frankly ugly. The type system might be too primitive in that regard. Haskell has 'print'. Once you have type inference, the first thing you do to make your code readable is to add back type annotations. ... at a few places.
Re: Using alloca?
On Friday, 28 June 2013 at 05:27:54 UTC, Andrei Alexandrescu wrote: On 6/27/13 9:42 PM, Maxime Chevalier-Boisvert wrote: I'd like to stack-allocate an array that will be dynamically sized. Is alloca somewhere in the standard D library? If so, what should I import to have access to it? Yah, import core.stdc.stdlib. Andrei Thank you good sir :)
Re: Automatic typing
On Friday, 28 June 2013 at 13:44:19 UTC, ponce wrote: On Friday, 28 June 2013 at 00:34:54 UTC, JS wrote: Would it be possible for a language(specifically d) to have the ability to automatically type a variable by looking at its use cases without adding too much complexity? Well ocaml has it (https://en.wikipedia.org/wiki/Hindley%E2%80%93Milner) and well it's not all that positive, at least in that language. No, OCaml doesn't quite do what the OP is asking for. In particular, the part where x is assigned an int and subsequently assigned a float can not be modeled directly. Even the separate 'auto x' and subsequent use of x is different from how OCaml's let polymorphism works. To model that, you could declare everything as 'a option refs and assign them later, like let main () = let x = ref None in let y = ref None in begin x := Some 1; y := Some (f()); end but if you want to use x as another type later you'll have to shadow the declaration in a new scope. Combined with parametric polymorphism it's nice and sound, except it has the potential to hide a simple typo a lot further from where it is (think mixing up integer operators and FP operators). As it break overloading on leaves, it is the reason ocaml has print_string and print_int which is quite frankly ugly. Yes, and the +., -., *., /. operators are ugly too, as is the requirement that record field labels in the same scope be distinct. Overloading can be dangerous, but no overloading is a PITA. Combining type inference and overloading is problematic. Once you have type inference, the first thing you do to make your code readable is to add back type annotations. There should always be a .mli file with exported decls. I wish OCaml had some ability to have separate type decls from the value, like Haskell. Type inference is most useful inside a function, IMO. I think that even if the feature being requested were feasible, it would be awful for D. -- Brian
Re: Automatic typing
Brian Rogoff: No, OCaml doesn't quite do what the OP is asking for. In particular, the part where x is assigned an int and subsequently assigned a float can not be modeled directly. I see, then this is not related to the flow typing I have linked to, sorry. Bye, bearophile
Re: why allocators are not discussed here
On Friday, June 28, 2013 13:55:45 Adam D. Ruppe wrote: On Friday, 28 June 2013 at 07:07:39 UTC, Marco Leise wrote: Isn't that what scope is for? I don't really know. In practice, it does something else (usually nothing, but suppresses heap closure allocation on delegates). The DIPs relating to it all talk about returning refs from functions and I'm not sure if they relate to the built ins or not- I don't think it would quite work for what I have in mind. Per the spec, all scope is supposed to do is prevent references in a parameter to be escaped. To be specific, it says --- references in the parameter cannot be escaped (e.g. assigned to a global variable) --- So, in theory, if you had something like auto foo(scope int[] i) {...} it would prevent i or anything refering to it from being returned or assigned to any variable which will outlive the function call. However, scope currently does _nothing_ for anything other than delegates - which is why I think that using the in attribute is such an incredibly bad idea. Using either in or scope on anything other than delegates could result in all kinds of code breakage if/when scope is ever implemented for types other than delegates. For delegates, it has the advantage of telling the compiler that it doesn't need to allocate a closure (since the delegate won't be used passed the point when it's calling scope will exist as could occur if the delegate escaped the function it was passed to), but I'm not sure that even that works 100% correctly right now. We really should sort out exactly what we're going to do with scope one of these days soon. But the stuff that some of the DIPS do with scope (e.g. returning with scope - which is completely against the spec at this point) are suggestions and not at all how it currently works. - Jonathan M Davis
Re: Using alloca?
Am 28.06.2013 06:42, schrieb Maxime Chevalier-Boisvert: I'd like to stack-allocate an array that will be dynamically sized. Is alloca somewhere in the standard D library? If so, what should I import to have access to it? The last time I checked alloca did not work well together with execptions. Whenever a exception whas thrown thourgh a stack frame which used alloca the app would crash. (on dmd Windows 64 bit, which uses the same exception mechanism as the linux versions of dmd) -- Kind Regards Benjamin Thaut
Re: why allocators are not discussed here
On Friday, 28 June 2013 at 17:43:21 UTC, Jonathan M Davis wrote: it would prevent i or anything refering to it from being returned or assigned to any variable which will outlive the function call. However, That's fairly close to what I'd want. But there's two cases I'm not sure it would cover: 1: struct Unique(T) { scope T borrow(); } If the unique pointer decides to let its reference slip, it wouldn't want it going somewhere else and escaping, since that breaks the unique need. This is important for a few cases. Here's one: int* foo; { Unique!(int*) bar; foo = bar.borrow; int* ok = bar.borrow; // this should be ok, because this never exists outside the same scope as the Unique } // foo now talks to a freed *bar, so that shouldn't be allowed Similarly, if bar were reassigned, this could cause trouble, but what we might do is just disallow such reassignments, but maybe it could work if it always goes down in scope. I'd have to think about that. (I'm thinking my borrowed thing might have to be a type constructor rather than a storage class. Otherwise, you could get around it by: int* bar(scope int* foo) { int* b = foo; return b; } Unless the compiler is very smart about following where it goes.) But if scope works on the return value too, it might be ok. maybe 2: void bar(scope int* foo, int** bar) { *bar = foo; } Actually, I'm reasonably clear the spec's scope words would work for this one. But we'd need to be sure - this is one case where pure wouldn't help (pure generally would help, since it disallows assignments to the outside world, but there's enough holes that you could leak a reference). To be memory safe, these would all have to be guaranteed.
Re: Using alloca?
Benjamin Thaut: The last time I checked alloca did not work well together with execptions. Whenever a exception whas thrown thourgh a stack frame which used alloca the app would crash. (on dmd Windows 64 bit, which uses the same exception mechanism as the linux versions of dmd) Is this in Bugzilla? Bye, bearophile
Re: why allocators are not discussed here
On Friday, June 28, 2013 19:56:44 Adam D. Ruppe wrote: struct Unique(T) { scope T borrow(); } Per the current spec, this would not be a valid use of scope, as scope is specifically a parameter storage class and can only be used on function parameters (just like in, out, ref, and lazy). scope seems to be specifically intended for guaranteeing that an argument passed to a function does not escape that function. - Jonathan M Davis
Re: Using alloca?
Am 28.06.2013 20:01, schrieb bearophile: Benjamin Thaut: The last time I checked alloca did not work well together with execptions. Whenever a exception whas thrown thourgh a stack frame which used alloca the app would crash. (on dmd Windows 64 bit, which uses the same exception mechanism as the linux versions of dmd) Is this in Bugzilla? Bye, bearophile Yes, its a pretty old bug too: http://d.puremagic.com/issues/show_bug.cgi?id=3753 -- Kind Regards Benjamin Thaut
Re: stack trace on linux amd64 ?
On Jun 24, 2013, at 11:34 AM, Martin Nowak c...@dawg.eu wrote: On 06/24/2013 04:54 PM, deadalnix wrote: Haaa, passing -export-dynamic to the linker did the trick. Exporting symbols from the executable is an ugly solution to get stacktraces. It would be much better if we used the debug information instead. They also provides richer information like line numbers. If I remember correctly, the issue there was that the runtime would need to open the executable or map file and parse it, and it seemed a lot more straightforward to simply make an API call. But if you're inclined to submit a pull request...
[SOLVED]Linking 2 c++ libraries with D
On Friday, 28 June 2013 at 04:21:19 UTC, Milvakili wrote: On Friday, 28 June 2013 at 02:34:01 UTC, Juan Manuel Cabo wrote: On 06/27/2013 10:12 PM, Milvakili wrote: I have successfully link c++ with D. Have ever when I create a dependency: cpp2-cpp1-d when compile with dmd dmd cpp1.a cpp2.a file.d -L-lstdc++ I tried it and it works _perfectly_ for me, but instead of .a I compiled the C++ files to .o g++ -c cpp1.cpp g++ -c cpp2.cpp dmd cpp1.o cpp2.o file.d -L-lstdc++ (I had to comment the printf in cpp1.cpp) Running the program prints this output: Testing callinf C++ main from D cbin2 c++ library called from:cbin.cpp I'm on Kubuntu 12.04 64bits, using DMD v2.063.2 I have the following libstdc++ packages installed As shown by dpkg -l libstd*|grep ^ii libstdc++6 4.6.3-1ubuntu5 libstdc++6-4.4-dev 4.4.7-1ubuntu2 libstdc++6-4.6-dev 4.6.3-1ubuntu5 G++ version is: g++ (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3 ldd on the executable shows that it's using these libraries: linux-vdso.so.1 = (0x7fff989ff000) libstdc++.so.6 = /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x7f9c0cbb7000) libpthread.so.0 = /lib/x86_64-linux-gnu/libpthread.so.0 (0x7f9c0c99a000) librt.so.1 = /lib/x86_64-linux-gnu/librt.so.1 (0x7f9c0c791000) libgcc_s.so.1 = /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x7f9c0c57b000) libc.so.6 = /lib/x86_64-linux-gnu/libc.so.6 (0x7f9c0c1bc000) /lib64/ld-linux-x86-64.so.2 (0x7f9c0cedb000) libm.so.6 = /lib/x86_64-linux-gnu/libm.so.6 (0x7f9c0bebf000) Hope that any of this was useful to you! --jm Thanks for the answer, I had the same ldd output. The interesting thing is the code is working with same libraries when we have one dependency. The problem is I manually build some the libraries and link them. I fix the problem by using the os standard libraries.
Re: stack trace on linux amd64 ?
Am Fri, 28 Jun 2013 11:12:25 -0700 schrieb Sean Kelly s...@invisibleduck.org: If I remember correctly, the issue there was that the runtime would need to open the executable or map file and parse it, and it seemed a lot more straightforward to simply make an API call. But if you're inclined to submit a pull request... In the meantime the GCC guys have developed libbacktrace [1] for GCC 4.8 which does exactly that: map the executable, parse it and use the dwarf debug info and all that without malloc. We're currently integrating this into GDC [2]. Unfortunately it's not as easy to integrate into dmd: It uses libgcc, the libbacktrace library is not installed in the target system (it's only available at gcc build time, we then just link it statically into druntime) and you need a more advanced build system to check for BACKTRACE_SUPPORTED in C headers. [1] https://github.com/mirrors/gcc/tree/master/libbacktrace [2] https://github.com/D-Programming-GDC/GDC/pull/65
Assigning to non-ref foreach loop variable
This is deprecated according to dmd 64-bit linux, but no error message for Mac or Windows, and exhibits different runtime behavior on Windows to those other platforms, as I found out from my students using it in a current CS2 class. Is there some reason why assigning to a non-ref foreach variable is permitted at all? Naively, it's a value from the loop's range, but not a variable, and so the compiler could treat it as such and forbid assignment.
Re: Assigning to non-ref foreach loop variable
Carl Sturtivant: Is there some reason why assigning to a non-ref foreach variable is permitted at all? Naively, it's a value from the loop's range, but not a variable, and so the compiler could treat it as such and forbid assignment. I opened a discussion on this, and later an enhancement request, that the very good Kenji has done some improvements. Currently this code compiles and runs: void main() { import std.stdio; foreach (i; 0 .. 10) { i.writeln; i++; } writeln; foreach (ref i; 0 .. 10) { i.writeln; i++; } } That prints: 0 1 2 3 4 5 6 7 8 9 0 2 4 6 8 I think both are not so good. Also in D this is a common bug: struct S { int x; } void main() { import std.stdio; auto data = [1.S, 2.S, 3.S]; foreach (item; data) item.x++; data.writeln; } That prints: [S(1), S(2), S(3)] See some threads: http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.Darticle_id=155816 And some issues: http://d.puremagic.com/issues/show_bug.cgi?id=5306 http://d.puremagic.com/issues/show_bug.cgi?id=6214 http://d.puremagic.com/issues/show_bug.cgi?id=6652 Thanks to Kenji the situation is improved compared to the past, but I think the current situation is not yet good enough... Bye, bearophile
Re: Automatic typing
On Friday, 28 June 2013 at 14:02:07 UTC, Steven Schveighoffer wrote: On Fri, 28 Jun 2013 02:51:39 -0400, JS js.m...@gmail.com My argument is that auto should be left the way it is. I don't want it to change. And variant already does what you want with less confusing semantics, no reason to add another feature. -Steve Using the auto keyword was just an example. My argument does not depend the specific keyword used. My idea is simply generalizing auto to use forward inferencing. variant is NOT what I am talking about. It is not a performant time but a union of types. I am talking about the compiler finding the best choice for the type by looking ahead of the definition of the time. I think variant would be a good choice as my suggestion is a sort of optimization of variant. i.e., attempt to find the appropriate type at compile time, if not use a variant(or throw an error).
Re: Automatic typing
On 6/27/2013 5:34 PM, JS wrote: Would it be possible for a language(specifically d) to have the ability to automatically type a variable by looking at its use cases without adding too much complexity? It seems to me that most compilers already can infer type mismatchs which would allow them to handle stuff like: main() { auto x; auto y; x = 3; // x is an int, same as auto x = 3; y = f(); // y is the same type as what f() returns x = 3.9; // x is really a float, no mismatch with previous type(int) } in this case x and y's type is inferred from future use. The compiler essentially just lazily infers the variable type. Obviously ambiguity will generate an error. I don't see a compelling use case for this proposal, or even any use case. There'd have to be some serious advantage to it to justify its complexity.
Re: Folding similar templates into one
On Friday, 28 June 2013 at 13:20:47 UTC, monarch_dodra wrote: What is a string lambda ? Do you mean a string alias latter parsed as an expression, or an actual lambda function. The former. I didn't think it was *that* obscure of a term (https://www.google.com/search?q=%22string+lambda%22+site:forum.dlang.org). There were talks about this recently in learn: If you *type* the same lambda function twice, it *will* generate two different templates. http://forum.dlang.org/thread/rufkccowcdogctvck...@forum.dlang.org I'm not sure if that's due to this bug or not: http://forum.dlang.org/thread/jdbhas$2ftb$1...@digitalmars.com?page=2#post-jdcn98:241mg9:244:40digitalmars.com However, enum PRED = () = 1; struct S(alias pred){} void main() { auto a = S!PRED(); auto b = S!PRED(); a = b; } This is fine. If that's all it takes to avoid copies, then maybe it's not so big of a problem for lambdas. From testing, *string* preds don't have this feature/bug (?), even if you compile time build them, the compiler will see that it is the same string (probably true for integrals and whatnot). But for lambdas, only their *name* counts (eg __lambda1__). So if you plan to re-use a lambda, it *must* be stored in a way the compiler can see its unicity, and not typed more than once. Ditto.
Re: Automatic typing
On Friday, 28 June 2013 at 22:29:21 UTC, Walter Bright wrote: On 6/27/2013 5:34 PM, JS wrote: Would it be possible for a language(specifically d) to have the ability to automatically type a variable by looking at its use cases without adding too much complexity? It seems to me that most compilers already can infer type mismatchs which would allow them to handle stuff like: main() { auto x; auto y; x = 3; // x is an int, same as auto x = 3; y = f(); // y is the same type as what f() returns x = 3.9; // x is really a float, no mismatch with previous type(int) } in this case x and y's type is inferred from future use. The compiler essentially just lazily infers the variable type. Obviously ambiguity will generate an error. I don't see a compelling use case for this proposal, or even any use case. There'd have to be some serious advantage to it to justify its complexity. My thoughts too. It's a lot of work for a very minor (and perhaps rather unwise) convenience.
Re: Folding similar templates into one
On Friday, 28 June 2013 at 13:25:54 UTC, monarch_dodra wrote: Just because the arguments are known 99% of the time at compile time, doesn't mean they should be parameters. Parameters shouldn't be used to just mean compile time anyways, but *specifically* to create different versions of a function or code, which in this case, is not the case at all. That was probably the idea when templates were conceived of for C++, but I think their usage has evolved far beyond that now, especially in D. With the advent of CTFE, there's an enormous amount that we can do at compile-time, a lot of which isn't strictly related to characterizing a function/struct/class/etc. on a type. Though I suppose it could be argued that with CTFE, doing compile-time template stuff isn't as important. Besides, there are scenarios where you could pass these as runtime parameters from higher functions, if you want the exception to look like it came from a higher level call. I was just using assertNotThrown as an example to illustrate my point. Making these parameters would mean that *any* function that handles lines or filenames would have to be parameterized on that. I don't think there's anything stopping you from passing __FILE__ and __LINE__ as template parameters to some functions, and as function parameters to other functions.
Re: Folding similar templates into one
On Friday, 28 June 2013 at 22:40:14 UTC, Meta wrote: With the advent of CTFE, there's an enormous amount that we can do at compile-time, a lot of which isn't strictly related to characterizing a function/struct/class/etc. on a type. s/characterizing/parameterizing
Problem with Variant
void main() { struct Vector { float length(); } import std.variant; Variant v = Vector(); } Currently this does not work, as it seems Variant thinks length() is a property restricted to arrays. cannot implicitly convert expression ((*zis).length()) of type float to int C:\D\dmd2\src\phobos\std\variant.d 488 I quickly changed that line in variant.do to static if (is(typeof(zis.length)) is(ReturnType!(zis.length) == size_t)) and my code compiles. Currently its a hack, but should it be more developed and would it not interfere with something else?
Re: Automatic typing
On 06/29/2013 12:29 AM, Walter Bright wrote: On 6/27/2013 5:34 PM, JS wrote: Would it be possible for a language(specifically d) to have the ability to automatically type a variable by looking at its use cases without adding too much complexity? It seems to me that most compilers already can infer type mismatchs which would allow them to handle stuff like: main() { auto x; auto y; x = 3; // x is an int, same as auto x = 3; y = f(); // y is the same type as what f() returns x = 3.9; // x is really a float, no mismatch with previous type(int) } in this case x and y's type is inferred from future use. The compiler essentially just lazily infers the variable type. Obviously ambiguity will generate an error. I don't see a compelling use case for this proposal, or even any use case. There'd have to be some serious advantage to it to justify its complexity. Eg: auto a; if(x in cache) a=cache[x]; else cache[x]=a=new AnnoyingToSpellOutBeforeTheIf!!(); Using the type of the lexically first assignment would often be good enough, where reading the variable is disallowed prior to this first assignment. A little better (and still decidable) would be using the common type of all branches' first assignments not preceded by a read.
Re: Automatic typing
On Friday, 28 June 2013 at 22:29:21 UTC, Walter Bright wrote: On 6/27/2013 5:34 PM, JS wrote: Would it be possible for a language(specifically d) to have the ability to automatically type a variable by looking at its use cases without adding too much complexity? It seems to me that most compilers already can infer type mismatchs which would allow them to handle stuff like: main() { auto x; auto y; x = 3; // x is an int, same as auto x = 3; y = f(); // y is the same type as what f() returns x = 3.9; // x is really a float, no mismatch with previous type(int) } in this case x and y's type is inferred from future use. The compiler essentially just lazily infers the variable type. Obviously ambiguity will generate an error. I don't see a compelling use case for this proposal, or even any use case. There'd have to be some serious advantage to it to justify its complexity. Is variant useful? If not then you have a point. I'm not proposing anything that variant can't already do except add compile time performance. I do not think the complexity is much more than what is already done. D already checks for time mismatch. With such a variant or auto the check simply is more intelligent. e.g., auto x; // x's type is undefined or possibly variant. x = 3; // x's type is set temporarily to an int ... x = 3.0; // at we have several possibilities. 1. Throw an error, this makes auto more useful and avoids many pitfalls. 2. Set x's type to a variant. [possibly goto 3 if castable to new type] 3. Set x's type to a double. Both 2 and 3 require an extra pass to convert the code because it uses forward inference. auto looks only at the immediate assignment expression to determine the type. I am talking about generalizing it to look in the scope with possible fallback to a variant type with optional warning, an error, or type enlargement.
Re: Problem with Variant
On 6/28/13 4:27 PM, develop32 wrote: void main() { struct Vector { float length(); } import std.variant; Variant v = Vector(); } Currently this does not work, as it seems Variant thinks length() is a property restricted to arrays. cannot implicitly convert expression ((*zis).length()) of type float to int C:\D\dmd2\src\phobos\std\variant.d 488 I quickly changed that line in variant.do to static if (is(typeof(zis.length)) is(ReturnType!(zis.length) == size_t)) and my code compiles. Currently its a hack, but should it be more developed and would it not interfere with something else? Could you please paste your note into a bug report? In a perfect world you may want to also submit a pull request! Thanks, Andrei
Re: why allocators are not discussed here
On Wednesday, 26 June 2013 at 13:16:25 UTC, Jason House wrote: Bloomberg released an STL alternative called BSL which contains an alternate allocator model. In a nutshell object supporting custom allocators can optionally take an allocator pointer as an argument. Containers will save the pointer and use it for all their allocations. It seems simple enough and does not embed the allocator in the type. https://github.com/bloomberg/bsl/wiki/BDE-Allocator-model There is also EASTL's (Electronic Arts version of STL for gamedev) take on allocators. http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2271.html#eastl_allocator
Re: Automatic typing
On 6/28/2013 5:00 PM, JS wrote: Is variant useful? If not then you have a point. I'm not proposing anything that variant can't already do except add compile time performance. I do not think the complexity is much more than what is already done. D already checks for time mismatch. With such a variant or auto the check simply is more intelligent. e.g., auto x; // x's type is undefined or possibly variant. x = 3; // x's type is set temporarily to an int ... x = 3.0; // at we have several possibilities. 1. Throw an error, this makes auto more useful and avoids many pitfalls. 2. Set x's type to a variant. [possibly goto 3 if castable to new type] 3. Set x's type to a double. Both 2 and 3 require an extra pass to convert the code because it uses forward inference. auto looks only at the immediate assignment expression to determine the type. I am talking about generalizing it to look in the scope with possible fallback to a variant type with optional warning, an error, or type enlargement. Again, I need a compelling use case. It's not enough to say it's the same as variant, and it's not enough to say it can be implemented. A compelling use case would be a pattern that is commonplace, and for which the workarounds are ugly, unsafe, error prone, unportable, etc.
Re: Automatic typing
On 6/28/2013 4:42 PM, Timon Gehr wrote: On 06/29/2013 12:29 AM, Walter Bright wrote: I don't see a compelling use case for this proposal, or even any use case. There'd have to be some serious advantage to it to justify its complexity. Eg: auto a; typeof(cache[x]) a; // (1) if(x in cache) a=cache[x]; else cache[x]=a=new AnnoyingToSpellOutBeforeTheIf!!(); Or: auto a = (x in cache) ? cache[x] : (cache[x]=new AnnoyingToSpellOutBeforeTheIf!!()); // (2) Using the type of the lexically first assignment would often be good enough, where reading the variable is disallowed prior to this first assignment. So far, the use case is not compelling. A little better (and still decidable) would be using the common type of all branches' first assignments not preceded by a read. (1) handles that. Not every workaround needs a language feature.
Re: Automatic typing
On Saturday, 29 June 2013 at 01:49:01 UTC, JS wrote: On Saturday, 29 June 2013 at 01:31:13 UTC, Walter Bright wrote: On 6/28/2013 5:00 PM, JS wrote: Is variant useful? If not then you have a point. I'm not proposing anything that variant can't already do except add compile time performance. I do not think the complexity is much more than what is already done. D already checks for time mismatch. With such a variant or auto the check simply is more intelligent. e.g., auto x; // x's type is undefined or possibly variant. x = 3; // x's type is set temporarily to an int ... x = 3.0; // at we have several possibilities. 1. Throw an error, this makes auto more useful and avoids many pitfalls. 2. Set x's type to a variant. [possibly goto 3 if castable to new type] 3. Set x's type to a double. Both 2 and 3 require an extra pass to convert the code because it uses forward inference. auto looks only at the immediate assignment expression to determine the type. I am talking about generalizing it to look in the scope with possible fallback to a variant type with optional warning, an error, or type enlargement. Again, I need a compelling use case. It's not enough to say it's the same as variant, and it's not enough to say it can be implemented. A compelling use case would be a pattern that is commonplace, and for which the workarounds are ugly, unsafe, error prone, unportable, etc. What was the use case for auto that got in into the language? A quick look at any heavily templated c++ (pre c++11) is all you need to justify it. auto cuts code clutter by huge amounts all over the place.
Re: Automatic typing
On 6/28/2013 6:48 PM, JS wrote: What was the use case for auto that got in into the language? In code where the type of the initializer would change, and if the type of the variable was fixed, then there would be an unintended implicit conversion. The other use case was voldemort types. Such patterns are commonplace, and a source of error and inconvenience without auto. auto appears in various forms in other languages, and is almost universally lauded as worthwhile. These cases don't apply to this proposal, nor do I know of its successful adoption in another language. It's not a matter of finding reasons not to implement it. It's finding reasons TO implement it. Language features do not have zero cost - some benefit has to offset it.
Re: DMD under 64-bit Windows 7 HOWTO
I followed all the instructions to a tea, but I'm getting this one error when compiling: == Can't run 'C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\bin\amd64\link.exe', check PATH Exit code -1 Build complete -- 1 error, 0 warnings == The linked DOES exist in the below file and I can directly execute it from cmd: C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\bin\amd64\link.exe My sc.ini: [Version] version=7.51 Build 020 [Environment] LIB=%DEV_DIR_WINSDK%\Lib\x64;%DEV_DIR_MSVC%\lib\amd64;%@P%\..\lib DFLAGS=-m64 -L/NOLOGO -I%@P%\..\..\src\phobos -I%@P%\..\..\src\druntime\import LINKCMD=%@P%\link.exe LINKCMD64=%DEV_DIR_MSVC%\bin\amd64\link.exe == Also, these directories also exist and have the proper libs: %DEV_DIR_WINSDK%\Lib\x64;%DEV_DIR_MSVC%\lib\amd64 Help?
Re: Automatic typing
On Saturday, 29 June 2013 at 02:05:35 UTC, Walter Bright wrote: On 6/28/2013 6:48 PM, JS wrote: What was the use case for auto that got in into the language? In code where the type of the initializer would change, and if the type of the variable was fixed, then there would be an unintended implicit conversion. The other use case was voldemort types. Such patterns are commonplace, and a source of error and inconvenience without auto. auto appears in various forms in other languages, and is almost universally lauded as worthwhile. These cases don't apply to this proposal, nor do I know of its successful adoption in another language. It's not a matter of finding reasons not to implement it. It's finding reasons TO implement it. Language features do not have zero cost - some benefit has to offset it. I don't disagree with you and I'm not saying auto is not useful. IMO though, auto is almost all convenience and very little to do with solving errors. A very simple use case is: auto x = 0; ... x = complex(1, 1) + x; which obviously is an error. By having auto use forward inferencing we can avoid such errors. It's obvious that x was intended to be a complex variable. Having auto look forward(or using a different keyword) reduces code refactoring and improves on the power of auto. for example suppose we use instead auto x = pow(2, 10); where pow returns a real. In this case x is still the wrong type. So we always have to know the final supertype anyways... I'm just proposing we let the compiler figure it out for us if we want. But because some types are supertypes of others it is entirely logical that they be extended when it is obvious the are being used as such. To see why this is even more useful, suppose we had such code above but now want to refactor to use quaternions. In this case, the line x = complex(1,1) + x is becomes invalid too and requires fixing(or the auto x line has to be fixed). If we allowed auto x; to easily see that it is suppose to be a quaternion then that line does not have to be fixed and everything would work as expected. So the real question is, is it error prone to allow the compiler to deduce what supertype a variable really is? I do not think it is a problem because ambiguity results in an error and warnings could be given when a variable type was upgraded to a super type. At some point, if flow analysis is ever added, auto would be a natural bridge to it. another useless case is auto someflag; static if (__cpu == 3) someflag = amdx64 else someflag = false; which allows a sort of static variant type. (which could be gotten around if a static if conditional expression, e.g., static auto someflag = (__cpu == 3) ?? amdx64 : false; ) The above may make it easier in some cases for configuration code. The biggest benefit I can immediately see comes from using mixins. In this case we can always have a variable select the appropriate type. e.g., mixin template Foo() { ((...) ?? int : float) func() { } } // func is of type int or float depending on the condition ... class Bar { auto x; // possibly auto x = default(typeof(func)); but possibly error prone due to refactoring if line order matters mixin Foo; static Bar() { x = default(typeof(func)); } } note that x's type is deduced at compile time to be the appropriate type corresponding to the mixin used. Because x's type does not have to be immediately known we can specify it implicitly later on without ever having to know the return types of the mixins. In this case Bar acts like a templated class but isn't(or is a sort of statically templated class so to speak) Such classes would be useful for versioning where the user of the class is oblivious to the types used in the class and does not need to specify a type parameter. e.g., The Bar class above could use int for a more performant version of the program and float for a more precise version. The use of auto would completely or near completely eliminate having to deal with which one is being used. In any case I can't specify any super duper use case because I don't know any.
Re: Automatic typing
On Fri, 28 Jun 2013 18:00:54 -0400, JS js.m...@gmail.com wrote: On Friday, 28 June 2013 at 14:02:07 UTC, Steven Schveighoffer wrote: On Fri, 28 Jun 2013 02:51:39 -0400, JS js.m...@gmail.com My argument is that auto should be left the way it is. I don't want it to change. And variant already does what you want with less confusing semantics, no reason to add another feature. -Steve Using the auto keyword was just an example. My argument does not depend the specific keyword used. My idea is simply generalizing auto to use forward inferencing. variant is NOT what I am talking about. It is not a performant time but a union of types. I am talking about the compiler finding the best choice for the type by looking ahead of the definition of the time. There is a possible way to solve this -- auto return types. If you can fit your initialization of the variable into a function (even an inner function) that returns auto, then the compiler should be able to figure out the best type. Example: import std.stdio; void main(string[] args) { auto foo() { if(args.length 1 args[1] == 1) return 1; else return 2.5; } auto x = foo(); writeln(typeof(x).stringof); } this outputs double. Granted, it doesn't solve the general case, where you want to use x before it's initialized a second time, but I think that really is just a programming error -- use a different variable. -Steve
Re: Problem with Variant
On Friday, June 28, 2013 17:14:22 Andrei Alexandrescu wrote: Could you please paste your note into a bug report? In a perfect world you may want to also submit a pull request! Well, he can do that in an _imperfect_ world too... ;) - Jonathan M Davis
Re: DMD under 64-bit Windows 7 HOWTO
bat file that sets environment for D and related stuff. - @ECHO OFF SET MS_VC_PATH=C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC SET MS_SDK_PATH=C:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A SET DE=%CD%\Environment SET DEC=%DE%\Compiler SET DER=%DE%\Runtime SET DET=%DE%\Tool SET DEC_D=%DEC%\Dmd SET DEC_MINGW=%DEC%\MinGW SET DE_PATH=%DET%;%DEC_D%\windows\bin;%DEC_MINGW%\bin SET DE_LIB=%DEC_D%\windows\lib;%DEC_MINGW%\lib SET DFLAGS=-I%DEC_D%\src\phobos -I%DEC_D%\src\druntime\import SET PATH=%PATH%;%MS_VC_PATH%\bin;%DE_PATH% SET LIB=%LIB%;%DE_LIB% START D Environment cmd /E:ON /U /D - sc.ini - [Version] version=7.51 Build 020 [Environment] VCINSTALLDIR=%MS_VC_PATH%\ WindowsSdkDir=%MS_SDK_PATH%\ LINKCMD=%@P%\link.exe LINKCMD64=%VCINSTALLDIR%\bin\x86_amd64\link.exe - In general check your paths to: 1. ..\bin\x86_amd64\link.exe 2. mspdb120.dll (it's for VS 2013, mspdb110.dll for VS 2012) 3. add path of mspdb*.dll to PATH variable
Re: stack trace on linux amd64 ?
On Friday, 28 June 2013 at 20:00:52 UTC, Johannes Pfau wrote: Am Fri, 28 Jun 2013 11:12:25 -0700 schrieb Sean Kelly s...@invisibleduck.org: If I remember correctly, the issue there was that the runtime would need to open the executable or map file and parse it, and it seemed a lot more straightforward to simply make an API call. But if you're inclined to submit a pull request... In the meantime the GCC guys have developed libbacktrace [1] for GCC 4.8 which does exactly that: map the executable, parse it and use the dwarf debug info and all that without malloc. We're currently integrating this into GDC [2]. Unfortunately it's not as easy to integrate into dmd: It uses libgcc, the libbacktrace library is not installed in the target system (it's only available at gcc build time, we then just link it statically into druntime) and you need a more advanced build system to check for BACKTRACE_SUPPORTED in C headers. [1] https://github.com/mirrors/gcc/tree/master/libbacktrace [2] https://github.com/D-Programming-GDC/GDC/pull/65 https://github.com/bombela/backward-cpp That may be relevant.
Re: Scope of temporaries as function arguments
On Fri, 28 Jun 2013 07:11:05 +0200 Maxim Fomin ma...@maxim-fomin.ru wrote: On Friday, 28 June 2013 at 04:54:56 UTC, Nick Sabalausky wrote: Probably a silly question, but I wanted to double-check... If you have this: struct Foo {...} bar(Foo()); Then regardless of optimizations (aside from any optimizer bugs, of course) the Foo temporary can't go out of scope or have its dtor called until bar finishes executing, right? Struct dtor is always called in the end of the caller (bar in example). This will be OK, but in general case no. Currently object is copied in caller side but destroyed in callee side, and if one of the arguments next to struct is passed by invoking function which throws, callee and respectively dtor will never be called. Interesting. BTW, for anyone else reading, I just searched bugzilla and it looks like the relevant issue is #9704. Kinda ugly as it means refcounted RAII structs can leek under this condition: func(refCountedStruct, thisThrows()); Ouch. Or I guess more accurately, is there any guarantee that the assert in func() below should always pass?: class Foo { int i = 1; //...etc... } struct Bar { Foo foo; ~this() { foo.i = 2; } //...etc... } void func(Bar bar) { //...anything here that *doesn't* change bar.foo.i... assert(bar.foo.i == 1); // Guaranteed to pass? } void main() { Foo f = new Foo(); func(Bar(f)); } Here yes, but in general case if there are other arguments, and one if them passed by lambda invocation which touches f and modifies, then no. Cool, thanks.
Re: Scope of temporaries as function arguments
On Friday, 28 June 2013 at 06:15:26 UTC, Nick Sabalausky wrote: On Fri, 28 Jun 2013 07:11:05 +0200 Maxim Fomin ma...@maxim-fomin.ru wrote: On Friday, 28 June 2013 at 04:54:56 UTC, Nick Sabalausky wrote: Probably a silly question, but I wanted to double-check... If you have this: struct Foo {...} bar(Foo()); Then regardless of optimizations (aside from any optimizer bugs, of course) the Foo temporary can't go out of scope or have its dtor called until bar finishes executing, right? Struct dtor is always called in the end of the caller (bar in example). This will be OK, but in general case no. Currently object is copied in caller side but destroyed in callee side, and if one of the arguments next to struct is passed by invoking function which throws, callee and respectively dtor will never be called. Interesting. BTW, for anyone else reading, I just searched bugzilla and it looks like the relevant issue is #9704. Kinda ugly as it means refcounted RAII structs can leek under this condition: func(refCountedStruct, thisThrows()); Ouch. Just in case it wasn't clear from the original explanation, this is a bug, it *should* be perfectly safe to pass as many temps as you want, and expect the right amount of destructor called in case of a throw.
Re: Opaque structs
On Friday, 28 June 2013 at 02:17:06 UTC, Brad Anderson wrote: On Friday, 28 June 2013 at 01:40:44 UTC, Andrej Mitrovic wrote: Note that if we implement Issue 8728[1], we could even create a better error message via: - struct S { @disable(S is an opaque C type and must only be used as a pointer) this(); @disable(S is an opaque C type and must only be used as a pointer) this(this); } void main() { S* s1; // ok S s2; // user error } - [1] : http://d.puremagic.com/issues/show_bug.cgi?id=8728 +1. Anything that makes error messages clearer is a win in my book and there is precedents for it in @deprecate(msg) which was a clear win. +1 also. I was going to say deprecated does it that way, so should disable, but that's already in the ticket ^^
Get body of a function as string
Is there any way of getting the body of a function as a string? (Obviously only when the source code is available to the compiler)
Re: Scope of temporaries as function arguments
Am Fri, 28 Jun 2013 02:15:19 -0400 schrieb Nick Sabalausky seewebsitetocontac...@semitwist.com: BTW, for anyone else reading, I just searched bugzilla and it looks like the relevant issue is #9704. Reminds me of an issue I reported later: http://d.puremagic.com/issues/show_bug.cgi?id=10409 -- Marco
zip vs. lockstep -- problem when setting values
Consider the following equivalent code using zip and lockstep respectively to iterate over the entries in an array and set their values: auto arr1 = new double[10]; foreach(i, ref x; zip(iota(10), arr1)) { x = i; } writeln(arr1); auto arr2 = new double[10]; foreach(i, ref x; lockstep(iota(10), arr2)) { x = i; } writeln(arr2); The first array will still be full of nan's when it is output, while the second will have values set correctly. Can anyone offer a reasonable explanation why this should be so? It looks like a bug to me, or at best an unreasonable difference in functionality. :-(
Re: Get body of a function as string
John Colvin: Is there any way of getting the body of a function as a string? (Obviously only when the source code is available to the compiler) I think that currently there isn't a simple way to do it. What is your use case? Bye, bearophile
Re: Get body of a function as string
On Friday, 28 June 2013 at 13:18:39 UTC, bearophile wrote: John Colvin: Is there any way of getting the body of a function as a string? (Obviously only when the source code is available to the compiler) I think that currently there isn't a simple way to do it. What is your use case? Bye, bearophile I want to create a function with an identical body but different parameters: e.g. given a function int foo(int a){ return a+1; } automatically create a new function int foo(int a)(){ return a+1; } I'm trying to implement a sort of automatic compile-time currying.
Re: Get body of a function as string
And why don't you call the function from your clone function? Maybe this could help you: http://dpaste.1azy.net/fork/597affd2 I used it to generate my own rvalue functions because of the lack of rvalue references.
sort error
Hello there, Ive got the following code http://dpaste.dzfl.pl/e391a268 This code throws me a Range Exception in Algorithm.d. If I use a lower number of random vectors, like 100, the code terminates. Also, if I delete the template instruction like this : sort(individuals); I also don't get an exception. Does anybody know, why this is the case?
Re: Scope of temporaries as function arguments
On Friday, 28 June 2013 at 08:08:17 UTC, monarch_dodra wrote: Just in case it wasn't clear from the original explanation, this is a bug, it *should* be perfectly safe to pass as many temps as you want, and expect the right amount of destructor called in case of a throw. Original explanation lacks the word bug deliberately because this is not a bug (in a sense that dmd generates wrong code), but a language design problem. How could you do this: struct S { int i = 1; } void foo(S s) { s.i = 2; } void main() { S s; foo(s); } Currently there are two dtors, one which gets S(2) at the end of foo and second at the end of main, which gets S(1). If you move dtor from callee to caller, it would get S(1) object (struct is passed by value), but it doesn't make sense to destruct S(1) where you have S(2). One possible solution is to pass by pointer in low level, which would probably increase magnitude of problems.
Re: Scope of temporaries as function arguments
On Friday, 28 June 2013 at 14:26:04 UTC, Maxim Fomin wrote: On Friday, 28 June 2013 at 08:08:17 UTC, monarch_dodra wrote: Just in case it wasn't clear from the original explanation, this is a bug, it *should* be perfectly safe to pass as many temps as you want, and expect the right amount of destructor called in case of a throw. Original explanation lacks the word bug deliberately because this is not a bug (in a sense that dmd generates wrong code), but a language design problem. How could you do this: struct S { int i = 1; } void foo(S s) { s.i = 2; } void main() { S s; foo(s); } Currently there are two dtors, one which gets S(2) at the end of foo and second at the end of main, which gets S(1). If you move dtor from callee to caller, it would get S(1) object (struct is passed by value), but it doesn't make sense to destruct S(1) where you have S(2). One possible solution is to pass by pointer in low level, which would probably increase magnitude of problems. I don't understand the problem... There *should* be two destroyers... main.s is postblitted into foo.s, and then foo destroys foo.s at the end of its scope... Where is the problem here?
Re: sort error
snow: http://dpaste.dzfl.pl/e391a268 This code throws me a Range Exception in Algorithm.d. If I use a lower number of random vectors, like 100, the code terminates. Also, if I delete the template instruction like this : sort(individuals); I also don't get an exception. Does anybody know, why this is the case? If I replace your vector with a tuple (that defines automatically a lexicographic opCmp) the problem seems to disappear: import std.stdio, std.random, std.array, std.algorithm, std.range, std.typecons; alias Vector3D = Tuple!(double,x, double,y, double,z); alias Individual = Vector3D[]; Vector3D getFitness(in ref Individual individual) pure nothrow { return individual[0]; } bool myComp(in Individual x, in Individual y) { return x.getFitness y.getFitness; } Vector3D[] initializeRandomVectors(in uint count) { Vector3D[] result; foreach (immutable i; 0 .. count) result ~= Vector3D(uniform(0.0, 11.0), uniform(0.0, 11.0), uniform(0.0, 11.0)); return result; } Individual[] initializeRandomIndividuals() { return 1000.iota.map!(_ = 10.initializeRandomVectors).array; } void main() { auto individuals = initializeRandomIndividuals; individuals.sort!(myComp, SwapStrategy.stable); finished.writeln; } Bye, bearophile
Re: Scope of temporaries as function arguments
On Friday, 28 June 2013 at 15:17:12 UTC, monarch_dodra wrote: Should I have expected a different behavior? import std.stdio; int callme() { throw new Exception(); } struct S { int i = 0; this(int i){this.i = i; writeln(constructing: , i);} this(this){writeln(postbliting: , i);} ~this(){writeln(destroying: , i);} } void foo(S s, int i) { s.i = 2; } void main() { S s = S(1); foo(s, callme()); } Destructor for copied object is not called because it is placed in foo(). Before calling foo(), dmd makes a copy of main.s, calls postblit, then puts code to invoke callme() and code to invoke foo(). Since callme() throws, foo() is not called and destructor placed in foo() is also not called. A struct copy escapes destructor. Now, if you try fix this by putting dtor for copy not in foo(), but in main immediately after foo() invocation, you will have a problem because destructor would get S(1) object while it should destroy S(2). Any modification made in foo() is lost. This can be possible fixed by passing copy by reference which would probably create new ABI problems.
counting words
I'm currently making a few tests with std.algorithm, std.range, etc I have a arry of words. Is it possible to count how often each word is contained in the array and then sort the array by the count of the individual words by chaining ranges? (e.g. without using a foreach loop + hashmap)? -- Kind Regards Benjamin Thaut
Re: Scope of temporaries as function arguments
On Friday, 28 June 2013 at 15:33:40 UTC, Maxim Fomin wrote: On Friday, 28 June 2013 at 15:17:12 UTC, monarch_dodra wrote: Should I have expected a different behavior? import std.stdio; int callme() { throw new Exception(); } struct S { int i = 0; this(int i){this.i = i; writeln(constructing: , i);} this(this){writeln(postbliting: , i);} ~this(){writeln(destroying: , i);} } void foo(S s, int i) { s.i = 2; } void main() { S s = S(1); foo(s, callme()); } Destructor for copied object is not called because it is placed in foo(). Before calling foo(), dmd makes a copy of main.s, calls postblit, then puts code to invoke callme() and code to invoke foo(). Since callme() throws, foo() is not called and destructor placed in foo() is also not called. A struct copy escapes destructor. Now, if you try fix this by putting dtor for copy not in foo(), but in main immediately after foo() invocation, you will have a problem because destructor would get S(1) object while it should destroy S(2). Any modification made in foo() is lost. This can be possible fixed by passing copy by reference which would probably create new ABI problems. I thought that was where you were getting to. Couldn't this simply be solved by having the *caller*, destroy the object that was postblitted into foo? Since foo ends up not being called (because of the exception), then I see no problem having the caller destroy the to-be-passed-but-ends-up-not object? Basically, it would mean creating a argument scope into which each arg is constructed. If something throws, then the up to now built args are deconstruted just like with standard scope. If you reach the end of the scope, then call is made, but passing the resposability of destruction to foo. EG, pseudo code: memcpy_all_args; try { foreach arg in args: arg.postblit; exit(failure) arg.destroy; } call_foo; Isn't that how C++ does it? In terms of passing args by value, I see no difference between CC and postblit... And I'm 99% sure C++ doesn't have this problem...
Re: counting words
On Friday, 28 June 2013 at 16:04:35 UTC, Benjamin Thaut wrote: I'm currently making a few tests with std.algorithm, std.range, etc I have a arry of words. Is it possible to count how often each word is contained in the array and then sort the array by the count of the individual words by chaining ranges? (e.g. without using a foreach loop + hashmap)? If you don't mind sorting twice: words.sort() .group() .array() .sort!((a, b)= a[1] b[1]) .map!(a = a[0]) .copy(words); You could also do it with a hashmap to keep the count.
Re: counting words
On Friday, 28 June 2013 at 16:25:25 UTC, Brad Anderson wrote: On Friday, 28 June 2013 at 16:04:35 UTC, Benjamin Thaut wrote: I'm currently making a few tests with std.algorithm, std.range, etc I have a arry of words. Is it possible to count how often each word is contained in the array and then sort the array by the count of the individual words by chaining ranges? (e.g. without using a foreach loop + hashmap)? If you don't mind sorting twice: words.sort() .group() .array() .sort!((a, b)= a[1] b[1]) .map!(a = a[0]) .copy(words); You could also do it with a hashmap to keep the count. Like so: size_t[string] dic; words.map!((w) { ++dic[w.idup]; return w; }) .array // eager (so dic is filled first), sortable .sort!((a, b) { bool less = dic[a] dic[b]; return less || less a b; }) .uniq .copy(words); It's a bit ugly and abuses side effects with the hash map. The order will differ from the other program when words have identical counts.
Re: Scope of temporaries as function arguments
On 06/28/2013 09:01 AM, monarch_dodra wrote: And I'm 99% sure C++ doesn't have this problem... +1%. :) I just finished checking. No, C++ does not have this problem. But there is the following related issue, which every real C++ programmer should know. ;) http://www.boost.org/doc/libs/1_53_0/libs/smart_ptr/shared_ptr.htm#BestPractices Ali P.S. The C++ program that I have just used for testing: #include iostream #include stdexcept using namespace std; int callme() { throw runtime_error(); return 0; } struct S { int i_; S(int i) : i_(i) { cout constructing: i_ at this '\n'; } S(const S that) { cout copying: that.i_ to this '\n'; i_ = that.i_; } ~S() { cout destroying: i_ at this '\n'; } }; void foo(int i, S s) { s.i_ = 2; } int main() { S s = S(1); try { foo(callme(), s); } catch (...) { cout caught\n; } }
Re: counting words
Am 28.06.2013 18:42, schrieb Brad Anderson: On Friday, 28 June 2013 at 16:25:25 UTC, Brad Anderson wrote: On Friday, 28 June 2013 at 16:04:35 UTC, Benjamin Thaut wrote: I'm currently making a few tests with std.algorithm, std.range, etc I have a arry of words. Is it possible to count how often each word is contained in the array and then sort the array by the count of the individual words by chaining ranges? (e.g. without using a foreach loop + hashmap)? If you don't mind sorting twice: words.sort() .group() .array() .sort!((a, b)= a[1] b[1]) .map!(a = a[0]) .copy(words); You could also do it with a hashmap to keep the count. Like so: size_t[string] dic; words.map!((w) { ++dic[w.idup]; return w; }) .array // eager (so dic is filled first), sortable .sort!((a, b) { bool less = dic[a] dic[b]; return less || less a b; }) .uniq .copy(words); It's a bit ugly and abuses side effects with the hash map. The order will differ from the other program when words have identical counts. I figured something like this by now too. Thank you. But I don't quite understand what the copy is for at the end? -- Kind Regards Benjamin Thaut
Re: counting words
On Friday, 28 June 2013 at 16:25:25 UTC, Brad Anderson wrote: On Friday, 28 June 2013 at 16:04:35 UTC, Benjamin Thaut wrote: I'm currently making a few tests with std.algorithm, std.range, etc I have a arry of words. Is it possible to count how often each word is contained in the array and then sort the array by the count of the individual words by chaining ranges? (e.g. without using a foreach loop + hashmap)? If you don't mind sorting twice: words.sort() .group() .array() .sort!((a, b)= a[1] b[1]) .map!(a = a[0]) .copy(words); You could also do it with a hashmap to keep the count. It's just missing the construction scheme for words. I had this: text .splitter(); .reduce!((words, w)=++words[w], words)(int[string]); But alas... reduce's signature is not ctfe-able :( Well, I've had a PR open for this for about 8 months now...
Re: Scope of temporaries as function arguments
On Friday, 28 June 2013 at 16:50:07 UTC, Maxim Fomin wrote: On Friday, 28 June 2013 at 16:01:05 UTC, monarch_dodra wrote: I thought that was where you were getting to. Couldn't this simply be solved by having the *caller*, destroy the object that was postblitted into foo? Since foo ends up not being called (because of the exception), then I see no problem having the caller destroy the to-be-passed-but-ends-up-not object? In case when there is no exception, struct argument is passed and is modified in callee, destructor in caller would have unchanged version (because structs are passed by value). I'm saying the callee destroys whatever is passed to it, all the time, but that means callee needs to actually be called. If caller constructs objects, but then fails to actually call callee, then caller *has* to be responsible for destroying the objects it has built, but not passed to anyone. But this is only if an exception is thrown: No exception: Caller constructs objects into foo. foo is called, foo becomes owner of objects. foo finishes. foo destroys object. Exception: Caller starts construction. Exception is thrown. Caller destroys objects as exception is propagating. All objects are destroyed, exception goes up.
Re: counting words
On Friday, 28 June 2013 at 16:48:08 UTC, Benjamin Thaut wrote: Am 28.06.2013 18:42, schrieb Brad Anderson: On Friday, 28 June 2013 at 16:25:25 UTC, Brad Anderson wrote: On Friday, 28 June 2013 at 16:04:35 UTC, Benjamin Thaut wrote: I'm currently making a few tests with std.algorithm, std.range, etc I have a arry of words. Is it possible to count how often each word is contained in the array and then sort the array by the count of the individual words by chaining ranges? (e.g. without using a foreach loop + hashmap)? If you don't mind sorting twice: words.sort() .group() .array() .sort!((a, b)= a[1] b[1]) .map!(a = a[0]) .copy(words); You could also do it with a hashmap to keep the count. Like so: size_t[string] dic; words.map!((w) { ++dic[w.idup]; return w; }) .array // eager (so dic is filled first), sortable .sort!((a, b) { bool less = dic[a] dic[b]; return less || less a b; }) .uniq .copy(words); It's a bit ugly and abuses side effects with the hash map. The order will differ from the other program when words have identical counts. I figured something like this by now too. Thank you. But I don't quite understand what the copy is for at the end? Just replacing your original word list with the sorted list (which I just realized is wrong because it will leave a bunch of words on the end, oops). You could .array it instead to get a new array or just store the range with auto and consume that where needed with no extra array allocation.
Re: Scope of temporaries as function arguments
On Friday, 28 June 2013 at 16:01:05 UTC, monarch_dodra wrote: I thought that was where you were getting to. Couldn't this simply be solved by having the *caller*, destroy the object that was postblitted into foo? Since foo ends up not being called (because of the exception), then I see no problem having the caller destroy the to-be-passed-but-ends-up-not object? In case when there is no exception, struct argument is passed and is modified in callee, destructor in caller would have unchanged version (because structs are passed by value). Basically, it would mean creating a argument scope into which each arg is constructed. If something throws, then the up to now built args are deconstruted just like with standard scope. If you reach the end of the scope, then call is made, but passing the resposability of destruction to foo. This is another option but suffers from the same problem (in posted examples exception is always thrown, but in reality it need not to).
Re: sort error
On 06/28/2013 07:00 AM, snow wrote: Hello there, Ive got the following code http://dpaste.dzfl.pl/e391a268 This code throws me a Range Exception in Algorithm.d. If I use a lower number of random vectors, like 100, the code terminates. Also, if I delete the template instruction like this : sort(individuals); I also don't get an exception. Yes, what is thrown is an Error. (Error and Exception are different hierarchies under Throwable.) Does anybody know, why this is the case? Your opCmp does not provide a complete ordering of objects: int opCmp(ref const Vector3D vec) { if (this.x vec.x this.y vec.y this.z vec.z) return 1; if (this.x vec.x this.y vec.y this.z vec.z) return -1; return 0; } According to that function, the following two values are neither less than nor greater than the other: // passes: assert(!(Vector3D(1, 2, 3) Vector3D(2, 1, 3)) !(Vector3D(1, 2, 3) Vector3D(2, 1, 3))); Ali
Re: Scope of temporaries as function arguments
On Fri, 28 Jun 2013 12:44:02 -0400, Ali Çehreli acehr...@yahoo.com wrote: I just finished checking. No, C++ does not have this problem. But there is the following related issue, which every real C++ programmer should know. ;) http://www.boost.org/doc/libs/1_53_0/libs/smart_ptr/shared_ptr.htm#BestPractices Thank you, I didn't know this. I can consider myself a real C++ programmer now :) -Steve
Re: Scope of temporaries as function arguments
On Friday, 28 June 2013 at 16:44:03 UTC, Ali Çehreli wrote: Ali P.S. The C++ program that I have just used for testing: Are you sure that the code is exact translation of demonstrated D problem? I see difference in argument passing order and your version uses try-catch block. This code #include iostream #include stdexcept using namespace std; int callme() { throw runtime_error(); return 0; } struct S { int i_; S(int i) : i_(i) { cout constructing: i_ at this '\n'; } S(const S that) { cout copying: that.i_ to this '\n'; i_ = that.i_; } ~S() { cout destroying: i_ at this '\n'; } }; void foo(S s, int i) { s.i_ = 2; } int main() { S s = S(1); foo(s, callme()); } prints for me: constructing: 1 at 0x7fffb93078d0 terminate called after throwing an instance of 'std::runtime_error' what(): Aborted
Re: counting words
Am 28.06.2013 19:01, schrieb Brad Anderson: On Friday, 28 June 2013 at 16:48:08 UTC, Benjamin Thaut wrote: Am 28.06.2013 18:42, schrieb Brad Anderson: On Friday, 28 June 2013 at 16:25:25 UTC, Brad Anderson wrote: On Friday, 28 June 2013 at 16:04:35 UTC, Benjamin Thaut wrote: I'm currently making a few tests with std.algorithm, std.range, etc I have a arry of words. Is it possible to count how often each word is contained in the array and then sort the array by the count of the individual words by chaining ranges? (e.g. without using a foreach loop + hashmap)? If you don't mind sorting twice: words.sort() .group() .array() .sort!((a, b)= a[1] b[1]) .map!(a = a[0]) .copy(words); You could also do it with a hashmap to keep the count. Like so: size_t[string] dic; words.map!((w) { ++dic[w.idup]; return w; }) .array // eager (so dic is filled first), sortable .sort!((a, b) { bool less = dic[a] dic[b]; return less || less a b; }) .uniq .copy(words); It's a bit ugly and abuses side effects with the hash map. The order will differ from the other program when words have identical counts. I figured something like this by now too. Thank you. But I don't quite understand what the copy is for at the end? Just replacing your original word list with the sorted list (which I just realized is wrong because it will leave a bunch of words on the end, oops). You could .array it instead to get a new array or just store the range with auto and consume that where needed with no extra array allocation. Ok, thank you very much -- Kind Regards Benjamin Thaut
Re: Scope of temporaries as function arguments
On 06/28/2013 10:11 AM, Steven Schveighoffer wrote: On Fri, 28 Jun 2013 12:44:02 -0400, Ali Çehreli acehr...@yahoo.com wrote: http://www.boost.org/doc/libs/1_53_0/libs/smart_ptr/shared_ptr.htm#BestPractices Thank you, I didn't know this. Even though this issue is covered in Herb Sutter's Exceptional C++ book, which I had read with great interest, I re-learned it last year when a colleague showed that link to me. I have always considered C++ a language where mere-mortals like myself must read lots and lots of books to advance (or to write any decent code). This thread makes me think that D is following in C++'s steps. I am too normal to figure out these corner cases myself. :-/ Ali