Re: GtkD 2.3.0 released, GTK+ with D.
On Monday, 7 October 2013 at 20:47:52 UTC, Mike Wey wrote: GtkD 2.3.0 is now available on gtkd.org: http://gtkd.org/download.html Good work as always!
Re: dunit 0.7.0 released
On Sunday, 29 September 2013 at 21:06:16 UTC, linkrope wrote: https://github.com/linkrope/dunit/tree/v0.7.0 The xUnit testing framework for D is used in production for one year now. Guys, we have at least 5 (!) different unit test projects! Can you cooperate your efforts to create one, but wonderful?
Re: dunit 0.7.0 released
On Monday, 21 October 2013 at 11:09:25 UTC, ilya-stromberg wrote: Guys, we have at least 5 (!) different unit test projects! Can you cooperate your efforts to create one, but wonderful? ...and add it to Phobos review queue ;)
Re: dunit 0.7.0 released
On Monday, 21 October 2013 at 11:58:14 UTC, Jonathan M Davis wrote: On Monday, October 21, 2013 13:48:16 Dicebot wrote: On Monday, 21 October 2013 at 11:09:25 UTC, ilya-stromberg wrote: Guys, we have at least 5 (!) different unit test projects! Can you cooperate your efforts to create one, but wonderful? ...and add it to Phobos review queue ;) I confess that I don't understand why anyone is creating any unit test projects for D, and I'd likely vote against any attempt to add such a thing to Phobos. D has built in unit testing functionality, and it works great. Maybe some additional assert-like functions could be useful (similar to assertThrown or assertNotThrown), but we really don't need much beyond what the language provides. - Jonathan m Davis Yes, you are right if we talk about SIMPLE unit tests. For more complex cases like integration tests you have A LOT of problems. It isn't only my opinion - for example, look at the Higgs, an Experimental JIT Compiler written in D Slides from last dconf (page 57): http://dconf.org/2013/talks/chevalier_boisvert.html
Re: dunit 0.7.0 released
On Monday, October 21, 2013 14:10:13 Dicebot wrote: On Monday, 21 October 2013 at 11:58:14 UTC, Jonathan M Davis wrote: I confess that I don't understand why anyone is creating any unit test projects for D, and I'd likely vote against any attempt to add such a thing to Phobos. D has built in unit testing functionality, and it works great. Maybe some additional assert-like functions could be useful (similar to assertThrown or assertNotThrown), but we really don't need much beyond what the language provides. Sorry but it feels like you didn't really investigate the topic. D built-in unit-test facilities are a basic and extendable framework. Many notable unittest libraries work on top of it (using custom assert helpers and/or __traits(getUnittests)) being at the same time perfectly compatible with raw `dmd -unittest -main -run file.d`. At the very same time built-in reporting facilities are very limited and almost any bigger project will want some extension. Assuming full compatibility with built-in ones and zero external dependencies I don't see why this can't go to Phobos. I know that you can extend the built-in facilities by overriding how assert works and the like. I also see no reason to do so. IIRC, such facilities were even removed at one point, because no one was using them. They were readded after someone complained about wanting them, but every time I see anyone talking about doing anything with those, it seems like overkill to me. And since it's frequently for nonsense like making it so that the tests continue after an assertion fails (which is outright bad practice IMHO), I have a very low opinion of attempts to override the built-in assert for unit tests. If someone wants to present something to the review queue that's related to unit tests, that's fine. But I really don't see any problem with the built-in unit tests facilities and would expect to be against any such submission, particularly since every time I've delved into any discussions on them, what folks are doing with them has seemed like a really bad idea to me. But I guess that we'll just have to wait and see what gets submitted for review, if anything. - Jonathan M Davis
Re: dunit 0.7.0 released
On Mon, 2013-10-21 at 04:58 -0700, Jonathan M Davis wrote: […] I confess that I don't understand why anyone is creating any unit test projects for D, and I'd likely vote against any attempt to add such a thing to Phobos. D has built in unit testing functionality, and it works great. Maybe some additional assert-like functions could be useful (similar to assertThrown or assertNotThrown), but we really don't need much beyond what the language provides. The focus on unit testing is a problem for me, unit testing is but ⅓ of the testing needed. There is integration testing and system testing to consider as well. Not to mention the different features needed of BDD rather than TDD. I appreciate that many people on this list think of anything to do with the JVM beneath contempt ;-) but the JUnit → TestNG → Spock and Cucumber journey is worth considering as a lesson in why not to get too focused on programmer generation of units. Python has the same lessons with the way unittest (aka PyUnit) and py.test are used. It is all about a testing framework supporting unit test, integration test, and system test usage. See Catch for the current C++ front-runner. https://github.com/philsquared/Catch -- Russel. = Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.win...@ekiga.net 41 Buckmaster Roadm: +44 7770 465 077 xmpp: rus...@winder.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder
Re: dunit 0.7.0 released
On Monday, 21 October 2013 at 12:24:18 UTC, Jonathan M Davis wrote: I know that you can extend the built-in facilities by overriding how assert works and the like. Overriding assert is dangerous because changes behavior of program itself and lacks context data. Own test runner implemented using __traits(getUnittests) is perfectly safe. And since it's frequently for nonsense like making it so that the tests continue after an assertion fails (which is outright bad practice IMHO), It is absolutely necessary feature in any big project of you want to keep reasonable edit-build cycle times. Tests are always hierarchical naturally, there is no reason to stop the world if completely unrelated ones fail. I have a very low opinion of attempts to override the built-in assert for unit tests. You are right here but it is not needed anymore. But I really don't see any problem with the built-in unit tests facilities and would expect to be against any such submission, There is nothing wrong with built-in ones, just some higher-level tools on top of them are lacking. But I guess that we'll just have to wait and see what gets submitted for review, if anything. Exactly, lets argue in time ;)
Re: dunit 0.7.0 released
On Mon, 2013-10-21 at 16:22 +0200, qznc wrote: […] Somewhat off topic, but out of curiosity: How do you distinguish between integration and system testing? Integration testing is when you test part or all of the system but not in a full deployment context (so possibly still using mocks for the database, network, user interface, etc.) whilst system testing is testing the whole system in a real, albeit test, context. The descriptions I found usually sound like system testing is a special case of integration testing, where you simply integrate all components. No, the difference is mostly in the context of execution of the system. Integration testing is about the interworking of the components and so you can mock out bits as needed to speed things up and drive things more deterministically. System testing allows no use of mocks and must occur in a full deployment setting, with the only compromise being that the deployment is in a sandbox isolated from the rest of the world. -- Russel. = Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.win...@ekiga.net 41 Buckmaster Roadm: +44 7770 465 077 xmpp: rus...@winder.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder
Re: dunit 0.7.0 released
On Monday, 21 October 2013 at 14:22:31 UTC, qznc wrote: The descriptions I found usually sound like system testing is a special case of integration testing, where you simply integrate all components. There is a certain terminology issue here as system testing may apply to both certain program on its own (and thus come before integration one) and software platform as a whole (being essentially final integration test of all components). I personally favor hierarchical separation into unit - functional - integration.
Re: dunit 0.7.0 released
On Monday, 21 October 2013 at 11:58:14 UTC, Jonathan M Davis wrote: On Monday, October 21, 2013 13:48:16 Dicebot wrote: On Monday, 21 October 2013 at 11:09:25 UTC, ilya-stromberg wrote: Guys, we have at least 5 (!) different unit test projects! Can you cooperate your efforts to create one, but wonderful? ...and add it to Phobos review queue ;) I confess that I don't understand why anyone is creating any unit test projects for D, and I'd likely vote against any attempt to add such a thing to Phobos. D has built in unit testing functionality, and it works great. Maybe some additional assert-like functions could be useful (similar to assertThrown or assertNotThrown), but we really don't need much beyond what the language provides. - Jonathan m Davis 640K ought to be enough for anybody Seriously though, unit testing is a major tool that all languages should have access to. The built-in stuff is adequate for very simple testing on simple types such as asserting something is true, etc. But when you're writing tests for a class that need dependencies then the built-in stuff won't cut it. The framework i'm currently working allows for mocking of dependencies which in itself is a big deal. Replacing dependencies with 'fake' stubs is something which makes unit tests a lot clearer and less complicated. It also means i can override the return value of any method at runtime to pretend returned data is real there too. I've also extended the assert mechanism in the D runtime to create better errors. Instead of just getting: core.exception.AssertError@file(57): Assertion failure You now get: +-- | Failed asserting equal +-- | File: file.d | Line: 57 +-- | ✓ Expected value: (int[]) [1, 2, 3, 4, 5] | ✗ Actual value: (int[]) [1, 2, 4, 5] This is way more clear exactly what and where failed. This is essential when unit testing using structs, arrays, classes, etc.. as you need this information to truly narrow down exactly what failed. Extending stuff like this also helps with overall project reporting, writing to a file or drawing pretty graphs etc..
Re: dunit 0.7.0 released
On Monday, 21 October 2013 at 19:02:45 UTC, Gary Willoughby wrote: On Monday, 21 October 2013 at 11:58:14 UTC, Jonathan M Davis wrote: On Monday, October 21, 2013 13:48:16 Dicebot wrote: On Monday, 21 October 2013 at 11:09:25 UTC, ilya-stromberg wrote: Guys, we have at least 5 (!) different unit test projects! Can you cooperate your efforts to create one, but wonderful? ...and add it to Phobos review queue ;) I confess that I don't understand why anyone is creating any unit test projects for D, and I'd likely vote against any attempt to add such a thing to Phobos. D has built in unit testing functionality, and it works great. Maybe some additional assert-like functions could be useful (similar to assertThrown or assertNotThrown), but we really don't need much beyond what the language provides. - Jonathan m Davis Seriously though, unit testing is a major tool that all languages should have access to. The built-in stuff is adequate for very simple testing on simple types such as asserting something is true, etc. But when you're writing tests for a class that need dependencies then the built-in stuff won't cut it. The framework i'm currently working allows for mocking of dependencies which in itself is a big deal. Replacing dependencies with 'fake' stubs is something which makes unit tests a lot clearer and less complicated. It also means i can override the return value of any method at runtime to pretend returned data is real there too. I've also extended the assert mechanism in the D runtime to create better errors. Instead of just getting: core.exception.AssertError@file(57): Assertion failure You now get: +-- | Failed asserting equal +-- | File: file.d | Line: 57 +-- | ✓ Expected value: (int[]) [1, 2, 3, 4, 5] | ✗ Actual value: (int[]) [1, 2, 4, 5] This is way more clear exactly what and where failed. This is essential when unit testing using structs, arrays, classes, etc.. as you need this information to truly narrow down exactly what failed. Extending stuff like this also helps with overall project reporting, writing to a file or drawing pretty graphs etc.. +1
Re: Pragmatic D Tutorial
On Thu, 10 Oct 2013 00:24:16 +0200, qznc wrote: On Wednesday, 9 October 2013 at 20:22:39 UTC, Dejan Lekic wrote: It is a very nice web-site, but the main column should be wider. Sometimes the source code floats over to the second column... Hm, not here. I suspect a weird font selection for the code. I plan to redesign it at some point anyways. This is the agogo standard theme of Sphinx, which is the only standard theme, where the width is not 100%. Look at this thread and see how many people complain about it... :)
Re: Early review of std.logger
On Thursday, 17 October 2013 at 07:34:28 UTC, qznc wrote: On Thursday, 17 October 2013 at 02:13:12 UTC, Eric Anderton wrote: The strength of this is that it would allow us to freely integrate D libraries that use std.logger, yet filter their log output from *outside* the library through the std.logger API. This is one of the most important aspects in my opinion. Std.logger should be easy to use, so library writers are encouraged to use it. Compare this with the unittest keyword, which makes it easy to write some simple tests. Of course, flexibility to use complex machinery for using the messages/tests is necessary. Just like we can hook up more advanced unit testing frameworks, we should be able to hook up more advanced logging machinery. The advanced stuff is not for Phobos though. Advanced stuff for unittests is for example, parallel execution and graphical reports. Advanced stuff for logging is for example log rotation and networking. There is no contradiction. Complex log libraries become (relatively) complex when one wants to use their advanced features, but are as simple as the others when one wants to use them simply. That's why in the Java world nearly everyone uses Log4j instead of the official JEE API. In practive, you really want a powerful logging facility. Another feature I used once in a project, was to log to RAM. We decided to log TRACE logs in production in order to catch a rare bug, but of course, it would output too many logs. So we decided to log everything in RAM and keep the last 1000 logs. Whenever there would be an exception or a CRITICAL log, the whole 1000 logs would be dumped on disk. That feature proved very useful.
Re: Early review of std.logger
On Monday, 21 October 2013 at 06:27:39 UTC, SomeDude wrote: On Thursday, 17 October 2013 at 07:34:28 UTC, qznc wrote: On Thursday, 17 October 2013 at 02:13:12 UTC, Eric Anderton wrote: The strength of this is that it would allow us to freely integrate D libraries that use std.logger, yet filter their log output from *outside* the library through the std.logger API. This is one of the most important aspects in my opinion. Std.logger should be easy to use, so library writers are encouraged to use it. Compare this with the unittest keyword, which makes it easy to write some simple tests. Of course, flexibility to use complex machinery for using the messages/tests is necessary. Just like we can hook up more advanced unit testing frameworks, we should be able to hook up more advanced logging machinery. The advanced stuff is not for Phobos though. Advanced stuff for unittests is for example, parallel execution and graphical reports. Advanced stuff for logging is for example log rotation and networking. There is no contradiction. Complex log libraries become (relatively) complex when one wants to use their advanced features, but are as simple as the others when one wants to use them simply. That's why in the Java world nearly everyone uses Log4j instead of the official JEE API. In practive, you really want a powerful logging facility. Another feature I used once in a project, was to log to RAM. We decided to log TRACE logs in production in order to catch a rare bug, but of course, it would output too many logs. So we decided to log everything in RAM and keep the last 1000 logs. Whenever there would be an exception or a CRITICAL log, the whole 1000 logs would be dumped on disk. That feature proved very useful. +1 Also, it would be useful to use buffered asynchronous logger (mentioned above). It will help to trace and save all logs, but should be fast for production usage.
Re: Should we distribute a Dutmite binary in the zipped package?
On Sunday, 20 October 2013 at 12:16:14 UTC, Andrej Mitrovic wrote: ...it's strange how many people don't even know it exists... No it isn't. Look a this page: http://dlang.org/download.html Now, look at all the pages under Compilers Tools here: http://wiki.dlang.org/The_D_Programming_Language How do you expect people to find out about tools if they're not even so much as mentioned in the places you'd go to find tools? People don't know about things that aren't documented. Full stop. -Wyatt
Re: Should we distribute a Dutmite binary in the zipped package?
On 10/21/13, Wyatt wyatt@gmail.com wrote: On Sunday, 20 October 2013 at 12:16:14 UTC, Andrej Mitrovic wrote: ...it's strange how many people don't even know it exists... No it isn't. What isn't? I'm just reporting on user experience here. Look a this page: http://dlang.org/download.html Right, it would have to be added there as well. Now, look at all the pages under Compilers Tools here: http://wiki.dlang.org/The_D_Programming_Language It's listed here: http://wiki.dlang.org/Community:Open_Source_Projects People don't know about things that aren't documented. Full stop. Not really a full stop, Dustmite has been incorporated into our tools repository (https://github.com/D-Programming-Language/tools), which is also the home of RDMD. Adding it to the zip, linking it on the website, and mentioning it in the changelog could give a boost to its usage, and it really is a super-useful tool for reducing regressions. There were over 97 regressions fixed in the latest release.
Re: core.bitop.bt semantics
On 10/20/13 21:23, David Nadlinger wrote: The documentation [1] for core.bitop.bt just says Tests the bit. With the function returning an int, the question is whether the return value is guaranteed to be 0 or 1, as ensured by the current implementation, or whether it can be any non-zero integer if the bit is set (as documented for the related bts function). The std.bitmanip.BitArray formatting functions in 2.064 assume the former, and are thus currently broken with LDC. LDC will probably end up switching to simply using the D implementation anyway as LLVM recognizes the pattern just fine, but I'd like to know what to fix first. David [1] http://dlang.org/phobos/core_bitop.html bt, bts, btr, btc all have the same return value. They only differ in what happens with the tested bit. The fact that they return int amplifies the zero / non-zero pattern. I think BitArray should get fixed to support that definition. But you might want to keep bt on LDC the same as on DMD, just to prevent similar bugs in user's code. L.
Re: Early review of std.logger
On 10/21/2013 06:19 AM, SomeDude wrote: On Tuesday, 15 October 2013 at 08:47:00 UTC, Robert Schadek wrote: On 10/15/2013 09:32 AM, Sönke Ludwig wrote: Am 15.10.2013 09:08, schrieb Jacob Carlborg: On 2013-10-14 23:22, Dicebot wrote: If we need to care about that, D module system is a failure. But I don't think it is a valid concern. People already complain about conflict function names in Phobos. And I'd agree with them. At least inside of a library, care IMO should be taken to minimize overlap (of course functionally equivalent ones in different overload sets are fine, though). But in case of logXXX this seems to be very unlikely, much in contrast to log (std.math.log). yes and no. Of course does logXXX create less conflict, but I like to simply write log and don't care about the LogLevel. So again pros and cons I for once have never seen any log API with log.level = INFO; Logger.log(Here be dragons); And this I believe for a good reason: in 99% of production code I've seen, several log levels are mixed, i.e INFO, CRITICAL and DEBUG for instance, so the case where a single log level is used, even in the same method, just never happens. The proposed solution looks extremely inconvenient to me as it will almost always necessit two lines of code instead of one. How good than, that you can pass the LogLevel as first argument to the log function. I am with Sönke on this one, as well as the need for multi logger output. That's the absolute minimum requirement. If this doesn't exist, what will happen is, someone will make something better. I added a MultiLogger five days ago...
Re: Missing compiler warning?
On Sunday, 20 October 2013 at 01:15:12 UTC, Jonathan M Davis wrote: On Saturday, October 19, 2013 18:50:16 Chris wrote: A warning would be enough. The thing is I didn't want to give it the same name. It was meant to be the class variable but the auto was a leftover from a test. A warning would have been nice, à la do you really want this?. I would have seen it immediately. Warnings are pretty much always a bad idea IMHO. If you're being a responsible programmer, you fix all warnings, so they're ultimately not really any different from an error except that you can leave them alone temporarily while developing. It's far better to make something an error not have the compiler complain about it at all. lint-like tools can do additional analysis based on additional stuff that a programmer decides they want to look for in their code, but the compiler shouldn't be pointing out stuff that might be wrong, because you'll have to fix it whether it's wrong or not just to get the compiler to shut up about it. And Walter agrees with me on this. Pretty much the only reason that warnings even exist in dmd is because he got pestered into adding them, and even then, we don't have very many. Most of them end up being warnings about stuff that will become errors later (rather than just making them an error immediately and break code). - Jonathan M Davis I can see your point. However, in this case a warning would really make sense, in my opinion, because it is potentially harmful and very likely not what the programmer intended, except in a case like this (string a) { this.a = a; } which could be ignored by the compiler. Usually same-name variables are only used in the constructor. Using them in other places in the class is not recommendable, and I don't mind useful warnings like Listen, there is a variable shadowing the class variable, do you really really want this? To spam the command line with compiler warnings is not very helpful, I agree, but is it a good solution to categorically rule out warnings?
Re: Early review of std.logger
On Monday, 21 October 2013 at 08:37:43 UTC, Robert Schadek wrote: I for once have never seen any log API with log.level = INFO; Logger.log(Here be dragons); And this I believe for a good reason: in 99% of production code I've seen, several log levels are mixed, i.e INFO, CRITICAL and DEBUG for instance, so the case where a single log level is used, even in the same method, just never happens. The proposed solution looks extremely inconvenient to me as it will almost always necessit two lines of code instead of one. How good than, that you can pass the LogLevel as first argument to the log function. We repeat many times: you can add Logger.logInfo(Here be dragons); syntax. It's much better than Logger.log(LogLevel.Info, Here be dragons);
Re: Early review of std.logger
On 10/21/2013 08:27 AM, SomeDude wrote: In practive, you really want a powerful logging facility. Another feature I used once in a project, was to log to RAM. We decided to log TRACE logs in production in order to catch a rare bug, but of course, it would output too many logs. So we decided to log everything in RAM and keep the last 1000 logs. Whenever there would be an exception or a CRITICAL log, the whole 1000 logs would be dumped on disk. That feature proved very useful. That was a feature you added or was it part of the logging library?
Re: Should we distribute a Dutmite binary in the zipped package?
On Monday, 21 October 2013 at 08:17:49 UTC, Andrej Mitrovic wrote: On 10/21/13, Wyatt wyatt@gmail.com wrote: On Sunday, 20 October 2013 at 12:16:14 UTC, Andrej Mitrovic wrote: ...it's strange how many people don't even know it exists... No it isn't. What isn't? I'm just reporting on user experience here. I think he meant it isn't strange.
Re: Missing compiler warning?
On Monday, October 21, 2013 10:37:57 Chris wrote: Usually same-name variables are only used in the constructor. Using them in other places in the class is not recommendable Well, that's up to the programmer, and plenty of folks use them in places like setters as well. but is it a good solution to categorically rule out warnings? Honestly? Yes, I think that it is. I am of the opinion that the _only_ warnings that the compiler should have are things that will become errors later but aren't immediately in order to give programmers the chance to change their code before it breaks. For instance, override is now required on virtual functions which override a base class function, whereas before it wasn't - we used a warning to ease the transition, and that makes sense. But ultimately, it became an error. Because it is not good practice to ever leave warnings in your code, I am firmly of the belief that something should be an error or completely legal and nothing in between. Otherwise, you're needlessly forced to change your code just because it _might_ have a problem. Additional lint-like tools can be written and used to check for anything which might be wrong, and the compiler can be left to report only stuff that is definitively wrong. And once we have a D lexer and parser in Phobos (and we're getting close to having a lexer), writing such tools will become much easier, and then such tools can warn programmers about what _they_ want to be warned about but which isn't necessarily wrong. - Jonathan M Davisbut is
Re: Missing compiler warning?
On Monday, 21 October 2013 at 09:05:58 UTC, Jonathan M Davis wrote: On Monday, October 21, 2013 10:37:57 Chris wrote: Usually same-name variables are only used in the constructor. Using them in other places in the class is not recommendable Well, that's up to the programmer, and plenty of folks use them in places like setters as well. but is it a good solution to categorically rule out warnings? Honestly? Yes, I think that it is. I am of the opinion that the _only_ warnings that the compiler should have are things that will become errors later but aren't immediately in order to give programmers the chance to change their code before it breaks. For instance, override is now required on virtual functions which override a base class function, whereas before it wasn't - we used a warning to ease the transition, and that makes sense. But ultimately, it became an error. Because it is not good practice to ever leave warnings in your code, I am firmly of the belief that something should be an error or completely legal and nothing in between. Otherwise, you're needlessly forced to change your code just because it _might_ have a problem. Additional lint-like tools can be written and used to check for anything which might be wrong, and the compiler can be left to report only stuff that is definitively wrong. And once we have a D lexer and parser in Phobos (and we're getting close to having a lexer), writing such tools will become much easier, and then such tools can warn programmers about what _they_ want to be warned about but which isn't necessarily wrong. - Jonathan M Davisbut is That would be a good solution, so ideally programmers could have a list of bad practice and check against that too. I only wonder which other use cases there are for same name variables other than constructors and setters. void setValue(string input) { this.input = input; } But there you have this. But a function (in the same class) like void processInput() { auto input = // ... // 20 lines later input = std.string.format(Hello %s!, someString); } Why would one want to write code like this? Why should a short-lived local variable assume the name of a class variable? This is a source of confusion and I don't consider this good practice. Maybe it's just personal taste.
Re: Should we distribute a Dutmite binary in the zipped package?
On 10/21/13, John Colvin john.loughran.col...@gmail.com wrote: I think he meant it isn't strange. Ah. Well maybe the more proper word is unfortunate. :)
Re: Missing compiler warning?
On Monday, October 21, 2013 11:24:06 Chris wrote: But there you have this. But a function (in the same class) like void processInput() { auto input = // ... // 20 lines later input = std.string.format(Hello %s!, someString); } Why would one want to write code like this? Why should a short-lived local variable assume the name of a class variable? This is a source of confusion and I don't consider this good practice. Maybe it's just personal taste. That may very well be bad practice (I certainly wouldn't advise writing code like that), but it's also not definitively wrong. Unless it's definitely a bug, I think that the compiler should keep quiet about it, because anything that it yells about has to be treated as a bug, and we shouldn't be forcing people to change their code just because there _might_ be a bug in it. - Jonathan M Davis
Re: Empty VS null array?
On Fri, 18 Oct 2013 17:36:28 +0100, Dicebot pub...@dicebot.lv wrote: On Friday, 18 October 2013 at 15:42:56 UTC, Andrei Alexandrescu wrote: That's bad API design, pure and simple. The function should e.g. return the string including the line terminator, and only return an empty (or null) string upon EOF. I'd say it should throw upon EOF as it is pretty high-level convenience function. I disagree. Exceptions should never be used for flow control so the rule is to throw on exceptional occurrences ONLY not on something that you will ALWAYS eventually happen. R -- Using Opera's revolutionary email client: http://www.opera.com/mail/
D programming language feature?
What are the Language Features can be found on D programming language?
Re: D programming language feature?
Am 21.10.2013 12:00, schrieb Vincent: What are the Language Features can be found on D programming language? http://dlang.org/comparison.html
Re: More on C++ stack arrays
On 21 October 2013 11:48, Walter Bright newshou...@digitalmars.com wrote: On 10/20/2013 5:59 PM, Jonathan M Davis wrote: If that paradigm is frequent enough, it might be worth wrapping it in a struct. Then, you'd probably get something like StaticArray!(int, 10) tmp(n); int[] a = tmp[]; which used T[10] if n was 10 or less and allocated T[] otherwise. The destructor could then deal with freeing the memory. Sounds like a good idea - and it should fit in with Andrei's nascent allocator design. I use this pattern all over the place. I don't love it though. It doesn't feel elegant at all and it wastes stack space, but it's acceptable, and I'd really like to see this pattern throughout phobos, especially where strings and paths are concerned. System interface functions that pass zero-terminated strings through to the OS are the primary offender, needless garbage, those should be on the stack. I like to use alloca too where it's appropriate. I'd definitely like if D had a variable-sized static array syntax for pretty-ing alloca. I thought about something similar using alloca via a mixin template, but that feels really hackey!
Re: Empty VS null array?
On Sat, 19 Oct 2013 10:56:02 +0100, Kagamin s...@here.lot wrote: On Friday, 18 October 2013 at 10:44:11 UTC, Regan Heath wrote: This comes up time and again. The use of, and ability to distinguish empty from null is very useful. Yes, you run the risk of things like null pointer exceptions etc, but we have that risk now without the reward of being able to distinguish these cases. In C# code null strings are a plague. I code in C# every day for work and I never have any problems with null strings. The conflated empty/null cases are the real nightmare for me (more below). null strings are no different to null class references, they're not a special case. People seem to have this odd idea that null is somehow an invalid state for a string /reference/ (c# strings are reference types), it's not. People also seem to elevate empty strings to some sort of special status, that's like saying 0 has some special status for int - it doesn't it's just one of a number of possible values. In fact, int having no null like state is a problem causing solutions like boxing to elevate the value type to a reference in order to allow a null state for int. Yet, in D we've decided to inconsistently remove that functionality from string for no gain. If string could not actually be null then we'd gain something from the limitation, instead we lose functionality and gain nothing - you still have to check your strings for null in D. We ought to go one way or the other, this middle ground is worse than either of the other options. In my code I don't have to check for or treat empty strings any differently to other values. I simply have to check for null. Remembering to check for null on reference types is automatic for me, strings are not special in this regard. Most of the time you don't need them Sure, and if I don't have access to null (like when using a value type like int), I can code around that lack, but it's never as straight forward a solution. but still must check for them just in order to not get an exception. Sure, you must check for the possible states of a reference type. Also business logic makes no difference between null and empty This is simply not true. Example at the end. both of them are just no data, so you end up typing if(string.IsNullOrEmpty(mystr)) every time everywhere. I only have to code like this when I use 3rd party code which has conflated empty and null. In my code when it's null it means not specified, and empty is just one type of value - for which I do no special handling. And, yeah, only one small feature in this big mess ever needs to differentiate between null and empty. Untrue, null allows many alternate and IMO more direct/obvious designs. I found this one case trivially implementable, but nulls still plague all remaining code. Which one case? The readline() one below? Take this simple design: string readline(); This function would like to be able to: - return null for EOF - return [] for a blank line but it cannot, because as soon as you write: foo(readline()) the null/[] case merges. This is a horrible design. You better throw an exception on eof instead of null: No, no, no. You should only throw in exceptional circumstances or you risk using exceptions for flow control, and that is just plain horrid. this null will break the caller anyway possibly in a contrived way. Never a contrived way, always a blatantly obvious one and only if you're not doing your job properly. If you want a contrived, unpredictable and difficult to debug breakage look no further than heap or stack corruption. Null is never a difficult bug to find and fix, and is no different to forgetting to handle one of the integer return values of a function. I use this all the time: http://msdn.microsoft.com/en-us/library/system.io.streamreader.readline.aspx It has never caused me any issues. It explicitly states that null is a possible output, and so I check for it - doing anything less is simply bad programming. It works if you read one line per loop cycle, but if you read several lines and assume they're not null (some multiline data format), There is your problem, never assume - the documentation is very clear on the issue. you're screwed or your code becomes littered with null checks, but who accounts for all alternative scenarios from the start? Me, and IMO any competent programmer. It is misguided to think you can ignore valid states, null is a valid state in C, C++, C#, and D.. You should be thinking about and handling it. You don't have to check for it on every access to the variable, but you do need to check for it once where the variable is assigned, or passed (in private functions you can skip this). From that point onward you can assume non-null, valid, job done. There are plenty of other such design/cases that can be imagined, and
Valgrind and GC
There seems to be some serious issue with the GC, yet almost no attention is paid to that. (See e.g. this thread: http://forum.dlang.org/thread/anhitkodvlstehwxa...@forum.dlang.org) I did a simple test: `void main { new ubyte[65536]; }`. This doesn't pass memcheck! Valgrind tells about using uninitialized values in core.thread.callWithStackShell called by gc.gcx.Gcx.mark. Can anybody look into that? ==3595== Conditional jump or move depends on uninitialised value(s) ==3595==at 0x41E605: _D2gc3gcx3Gcx4markMFPvPviZv (in /home/lomereiter/test) ==3595==by 0x41E5B7: _D2gc3gcx3Gcx4markMFPvPvZv (in /home/lomereiter/test) ==3595==by 0x425520: _D4core6thread14thread_scanAllUMDFPvPvZvZv45__T10__lambda69TE4core6thread8ScanTypeTPvTPvZ10__lambda69MFE4core6thread8ScanTypePvPvZv (in /home/lomereiter/test) ==3595==by 0x4291DA: _D4core6thread15scanAllTypeImplFMDFE4core6thread8ScanTypePvPvZvPvZv (in /home/lomereiter/test) ==3595==by 0x429140: _D4core6thread18thread_scanAllTypeUMDFE4core6thread8ScanTypePvPvZvZv19__T10__lambda62TPvZ10__lambda62MFPvZv (in /home/lomereiter/test) ==3595==by 0x42900F: _D4core6thread18callWithStackShellFMDFPvZvZv (in /home/lomereiter/test) ==3595==by 0x429118: thread_scanAllType (in /home/lomereiter/test) ==3595==by 0x4254F8: thread_scanAll (in /home/lomereiter/test) ==3595==by 0x41EAA5: _D2gc3gcx3Gcx11fullcollectMFZm (in /home/lomereiter/test) ==3595==by 0x41E05C: _D2gc3gcx3Gcx8bigAllocMFmPPS2gc3gcx4PoolPmZPv (in /home/lomereiter/test) ==3595==by 0x41B983: _D2gc3gcx2GC12mallocNoSyncMFmkPmZPv (in /home/lomereiter/test) ==3595==by 0x41B7B6: _D2gc3gcx2GC6mallocMFmkPmZPv (in /home/lomereiter/test) ==3595== Uninitialised value was created by a stack allocation ==3595==at 0x428FE0: _D4core6thread18callWithStackShellFMDFPvZvZv (in /home/lomereiter/test)
Re: Empty VS null array?
On Fri, 18 Oct 2013 16:43:23 +0100, Andrei Alexandrescu seewebsiteforem...@erdani.org wrote: On 10/18/13 3:44 AM, Regan Heath wrote: On Fri, 18 Oct 2013 00:32:46 +0100, H. S. Teoh hst...@quickfur.ath.cx wrote: On Fri, Oct 18, 2013 at 01:27:33AM +0200, Adam D. Ruppe wrote: On Thursday, 17 October 2013 at 23:12:03 UTC, ProgrammingGhost wrote: is null still treats [] as null. blah, you're right. It will at least distinguish it from an empty slice though (like arr[$..$]). I don't think there's any way to tell [] from null except typeof(null) at all. At runtime they're both the same: no contents, so null pointer and zero length. I think it's a mistake to rely on the distinction between null and non-null but empty arrays in D. They should be regarded as implementation details that user code shouldn't depend on. If you need to distinguish between arrays that are empty and arrays that are null, consider using Nullable!(T[]) instead. This comes up time and again. The use of, and ability to distinguish empty from null is very useful. I disagree. Because.. the risk of a null pointer exception is not worth the gain? If so, why not go the whole hog and prevent string from ever being null? Then, at least we'd gain something from the loss of the null/empty distinction/limitation. D strings ought to decide whether they're reference types or value types, if the former then I want consistent null back, if the latter then I want to be rid of null for good. This middle ground sucks. Yes, you run the risk of things like null pointer exceptions etc, but we have that risk now without the reward of being able to distinguish these cases. Take this simple design: string readline(); This function would like to be able to: - return null for EOF - return [] for a blank line That's bad API design, pure and simple. The function should e.g. return the string including the line terminator, and only return an empty (or null) string upon EOF. It's the C# ReadLine() design and I've never once had a bug because of it. R -- Using Opera's revolutionary email client: http://www.opera.com/mail/
Re: Empty VS null array?
On Fri, 18 Oct 2013 17:55:46 +0100, Andrei Alexandrescu seewebsiteforem...@erdani.org wrote: On 10/18/13 9:26 AM, Max Samukha wrote: *That's* bad API design. readln should be symmetrical to writeln, not write. And about preserving the exact representation of new lines, readln/writeln shouldn't preserve that, pure and simple. Fair point. I just gave one possible alternative out of many. Thing is, relying on client code to distinguish subtleties between empty and null strings is fraught with dangers. My code does not need to distinguish between empty and null. null is checked for, and empty is just a normal value for a string. The problem you're referring to is /casused/ by conflating null and empty, by making empty strings special in the same way someone might make 0 a special value for an int (meaning not specified - for example). If you stop using empty string as a special case of null, then empty does not need special handling - it's just a normal string value handled like any other - you can read it, write it, append it, etc etc etc. null is the /only/ case which needs special handling - just like any other reference type. R -- Using Opera's revolutionary email client: http://www.opera.com/mail/
Re: Missing compiler warning?
On Monday, 21 October 2013 at 09:36:48 UTC, Jonathan M Davis wrote: On Monday, October 21, 2013 11:24:06 Chris wrote: But there you have this. But a function (in the same class) like void processInput() { auto input = // ... // 20 lines later input = std.string.format(Hello %s!, someString); } Why would one want to write code like this? Why should a short-lived local variable assume the name of a class variable? This is a source of confusion and I don't consider this good practice. Maybe it's just personal taste. That may very well be bad practice (I certainly wouldn't advise writing code like that), but it's also not definitively wrong. Unless it's definitely a bug, I think that the compiler should keep quiet about it, because anything that it yells about has to be treated as a bug, and we shouldn't be forcing people to change their code just because there _might_ be a bug in it. - Jonathan M Davis So the solution would be an additional layer that can be turned on / off. Warnings like unused variable or shadowing class declaration are quite useful. I don't see any other cases where a warning would be nice (at the moment).
Re: Valgrind and GC
On Monday, 21 October 2013 at 10:36:21 UTC, Artem Tarasov wrote: There seems to be some serious issue with the GC, yet almost no attention is paid to that. (See e.g. this thread: http://forum.dlang.org/thread/anhitkodvlstehwxa...@forum.dlang.org) I did a simple test: `void main { new ubyte[65536]; }`. This doesn't pass memcheck! Valgrind tells about using uninitialized values in core.thread.callWithStackShell called by gc.gcx.Gcx.mark. A conservative garbage collector is never correct according to Valgrind [0]. You need to configure Valgrind to ignore the GC. Here is an example for the Boehm GC: https://github.com/UU-ComputerScience/uhc/tree/master/EHC/misc/valgrind [0] http://www.hpl.hp.com/hosted/linux/mail-archives/gc/2004-November/000629.html
Re: Empty VS null array?
On Fri, 18 Oct 2013 18:38:12 +0100, H. S. Teoh hst...@quickfur.ath.cx wrote: On Fri, Oct 18, 2013 at 01:32:58PM -0400, Jonathan M Davis wrote: On Friday, October 18, 2013 09:55:46 Andrei Alexandrescu wrote: On 10/18/13 9:26 AM, Max Samukha wrote: *That's* bad API design. readln should be symmetrical to writeln, not write. And about preserving the exact representation of new lines, readln/writeln shouldn't preserve that, pure and simple. Fair point. I just gave one possible alternative out of many. Thing is, relying on client code to distinguish subtleties between empty and null strings is fraught with dangers. Yeah, but the primary reason that it's bad design is the fact that D tries to conflate null and empty instead of keeping them distinct (which is essentially the complaint that was made). Whether that's ultimately good or bad is up for debate, but the side effect is that relying on the difference between null and empty ends up being very bug-prone, whereas in other languages which don't conflate the two, it isn't problematic in the same way, and it's much more reasonable to have the API treat them differently. [...] Conceptually speaking, an array is a sequence of values of non-negative length. An array with non-zero length contains at least one element, and is therefore non-empty, whereas an array with zero length is empty. Same thing goes with a slice. A slice is a view into zero or more array elements. A slice with zero length is empty, and a slice with non-zero length contains at least one element. This describes the empty/not empty distinction. There's nowhere in this conceptual scheme for such a thing as a null array that's distinct from an empty array. And this is the problem/complaint. You cannot represent specified/not specified, you can only represent empty/not empty. I agree you cannot logically have an existing array that is somehow a null array and distinct/different from an empty array, but that's not what I want/am asking for. I want to use an array 'reference' to represent that the array is non existent, has not been set, has not been defined, etc. This is what null is for. This distinction only crops up in implementation, and IMO leads to code smells because code should be operating based on the conceptual behaviour of arrays rather than on the implementation details. It is not an implementation detail, it's a conceptual difference. A reference type has the power to represent specified/not specified in addition to referring to an array which is empty/not empty. A value type, like int, cannot do the same thing without either boxing (into a reference type, whose reference can be null) or by giving up one of it's values (i.e. 0) and pretending it's something special. This is what D's string has done with empty, it is pretending that it is special and means not specified, and because it converts null into empty, that means we cannot rely on empty really being empty (as in the user wants the value set to empty), as it might also be a value the user did not specify. It's actually a fairly simple distinction I want to be able to make. If you get input from a user a field called foo may be: - not specified - specified and if specified, may be: - empty - not empty null allows us the specified/not specified distinction. Regan -- Using Opera's revolutionary email client: http://www.opera.com/mail/
Re: Empty VS null array?
On Fri, 18 Oct 2013 20:58:07 +0100, H. S. Teoh hst...@quickfur.ath.cx wrote: On Fri, Oct 18, 2013 at 02:04:41PM -0400, Jonathan M Davis wrote: On Friday, October 18, 2013 10:38:12 H. S. Teoh wrote: [...] IMO, distinguishing between null and empty arrays is bad abstraction. I agree with D's conflation of null with empty, actually. Conceptually speaking, an array is a sequence of values of non-negative length. An array with non-zero length contains at least one element, and is therefore non-empty, whereas an array with zero length is empty. Same thing goes with a slice. A slice is a view into zero or more array elements. A slice with zero length is empty, and a slice with non-zero length contains at least one element. There's nowhere in this conceptual scheme for such a thing as a null array that's distinct from an empty array. This distinction only crops up in implementation, and IMO leads to code smells because code should be operating based on the conceptual behaviour of arrays rather than on the implementation details. In most languages, an array is a reference type, so there's the question of whether it's even _there_. There's a clear distinction between having null reference to an array and having a reference to an empty array. This is particularly clear in C++ where an array is just a pointer, but it's try in plenty of other languages that don't treat as arrays as pointers (e.g. Java). To me, these are just implementation details. Conceptually speaking, D arrays are actually slices, so that gives them reference semantics. Being slices, they refer to zero or more elements, so either their length is zero, or not. There is no concept of nullity here. That only comes because we chose to implement slices as pointer + length, so implementation-wise we can distinguish between a null .ptr and a non-null .ptr. But from the conceptual POV, if we consider slices as a whole, they are just a sequence of zero or more elements. Null has no meaning here. Put another way, slices themselves are value types, but they refer to their elements by reference. It's a subtle but important difference. The problem is that D put the length on the stack alongside the pointer, making it so that D arrays are sort of reference types and sort of not. The pointer is a reference type, but the length is a value type, making the dynamic array half and half. If it were fully a reference type, then there would be no problem with distinguishing between null and empty arrays. A null array is simply a null reference to an array. But since D arrays aren't quite reference types, that doesn't work. [...] I think the issue comes from the preconceived notion acquired from other languages that arrays are some kind of object floating somewhere out there on the heap, for which we have a handle here. Thus we have the notion of null, being the case when we have a handle here but there's actually nothing out there. But we consider the slice as being a thing right *here* and now, referencing some sequence of elements out there, then we arrive at D's notion of null and empty being the same thing, because while there may be no elements out there being referenced, the handle (i.e. slice) is always *here*. In that sense, there's no distinction between an empty slice and a null slice: either there are elements out there that we're referring to, or there are none. There is no third null case. There's no reason why we should adopt the previous notion if this one works just as well, if not better. I argue that the second notion is conceptually cleaner, because it eliminates an unnecessary distinction between an empty sequence and a non-existent sequence (which then leads to similar issues one encounters with null pointers). If what you say is true then slices would and could never be null... If that were the case I would stop complaining and simply box them with Nullable when I wanted a reference type. But, D's strings/slices are some kind of mutant half reference half value type, and that's the underlying problem here. Regan -- Using Opera's revolutionary email client: http://www.opera.com/mail/
Re: Empty VS null array?
On Fri, 18 Oct 2013 21:09:35 +0100, Blake Anderton rbander...@gmail.com wrote: I agree a null value and empty array are separate concepts, but from my very anecdotal/non rigorous point of view I really appreciate D's ability to treat them as equivalent. My day job mostly involves C# and array code almost always follows the pattern if(arr == null || arr.Length == 0) ... Interesting. My day job is C# and I almost never do that. I check for null and treat empty as any other string value. The /only/ time I have to check for empty is when I have interfaced with 3rd party code which has decided to conflate empty and null to mean the same thing. Regan -- Using Opera's revolutionary email client: http://www.opera.com/mail/
Re: More on C++ stack arrays
21.10.2013 14:30, Manu пишет: System interface functions that pass zero-terminated strings through to the OS are the primary offender, needless garbage, those should be on the stack. I like to use alloca too where it's appropriate. I'd definitely like if D had a variable-sized static array syntax for pretty-ing alloca. I thought about something similar using alloca via a mixin template, but that feels really hackey! No hacks needed. See `unstd.c.string` module from previous post: http://forum.dlang.org/thread/lqdktyndevxfcewgt...@forum.dlang.org?page=2#post-l42evp:241ok7:241:40digitalmars.com -- Денис В. Шеломовский Denis V. Shelomovskij
Re: Empty VS null array?
On Mon, 21 Oct 2013 11:58:07 +0100, Regan Heath re...@netmail.co.nz wrote: On Fri, 18 Oct 2013 20:58:07 +0100, H. S. Teoh hst...@quickfur.ath.cx wrote: On Fri, Oct 18, 2013 at 02:04:41PM -0400, Jonathan M Davis wrote: On Friday, October 18, 2013 10:38:12 H. S. Teoh wrote: [...] IMO, distinguishing between null and empty arrays is bad abstraction. I agree with D's conflation of null with empty, actually. Conceptually speaking, an array is a sequence of values of non-negative length. An array with non-zero length contains at least one element, and is therefore non-empty, whereas an array with zero length is empty. Same thing goes with a slice. A slice is a view into zero or more array elements. A slice with zero length is empty, and a slice with non-zero length contains at least one element. There's nowhere in this conceptual scheme for such a thing as a null array that's distinct from an empty array. This distinction only crops up in implementation, and IMO leads to code smells because code should be operating based on the conceptual behaviour of arrays rather than on the implementation details. In most languages, an array is a reference type, so there's the question of whether it's even _there_. There's a clear distinction between having null reference to an array and having a reference to an empty array. This is particularly clear in C++ where an array is just a pointer, but it's try in plenty of other languages that don't treat as arrays as pointers (e.g. Java). To me, these are just implementation details. Conceptually speaking, D arrays are actually slices, so that gives them reference semantics. Being slices, they refer to zero or more elements, so either their length is zero, or not. There is no concept of nullity here. That only comes because we chose to implement slices as pointer + length, so implementation-wise we can distinguish between a null .ptr and a non-null .ptr. But from the conceptual POV, if we consider slices as a whole, they are just a sequence of zero or more elements. Null has no meaning here. Put another way, slices themselves are value types, but they refer to their elements by reference. It's a subtle but important difference. The problem is that D put the length on the stack alongside the pointer, making it so that D arrays are sort of reference types and sort of not. The pointer is a reference type, but the length is a value type, making the dynamic array half and half. If it were fully a reference type, then there would be no problem with distinguishing between null and empty arrays. A null array is simply a null reference to an array. But since D arrays aren't quite reference types, that doesn't work. [...] I think the issue comes from the preconceived notion acquired from other languages that arrays are some kind of object floating somewhere out there on the heap, for which we have a handle here. Thus we have the notion of null, being the case when we have a handle here but there's actually nothing out there. But we consider the slice as being a thing right *here* and now, referencing some sequence of elements out there, then we arrive at D's notion of null and empty being the same thing, because while there may be no elements out there being referenced, the handle (i.e. slice) is always *here*. In that sense, there's no distinction between an empty slice and a null slice: either there are elements out there that we're referring to, or there are none. There is no third null case. There's no reason why we should adopt the previous notion if this one works just as well, if not better. I argue that the second notion is conceptually cleaner, because it eliminates an unnecessary distinction between an empty sequence and a non-existent sequence (which then leads to similar issues one encounters with null pointers). If what you say is true then slices would and could never be null... Aargh, my apologies I misread your post. Ignore my first reply. I agree that slices never being null are like a pre-null checked array, which is a good thing. The issue I have had in the past is with strings (not slices) mutating from null to empty and/or vice-versa. Also, it's not at all clear when you're dealing with a pre-check not-null slice and when you're dealing with a possibly null array, for example.. import std.stdio; void foo(string arr) { if (arr is null) writefln(null); else writefln(not null); if (arr.length == 0) writefln(empty); else writefln(not empty); } void main() { string arr; foo(arr); foo(arr[0..$]); arr = ; foo(arr); foo(arr[0..$]); } Output: null empty null empty not null empty not null empty Which of those are strings/arrays and which are slices? Why are the ones formed by actually slicing coming up as is null? (This last, not directed at you, just venting..) I can understand arguing against null from a safety point of view. I can
Re: More on C++ stack arrays
On Monday, 21 October 2013 at 00:59:38 UTC, Jonathan M Davis wrote: On Sunday, October 20, 2013 09:33:36 Walter Bright wrote: On 10/20/2013 7:25 AM, bearophile wrote: More discussions about variable-sized stack-allocated arrays in C++, it seems there is no yet a consensus: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3810.pdf I'd like variable-sized stack-allocated arrays in D. They're far more trouble than they're worth. Just use: auto a = new T[n]; Stack allocated arrays are far more trouble than they're worth. But what about efficiency? Here's what I often do something along the lines of: T[10] tmp; T[] a; if (n = 10) a = tmp[0..n]; else a = new T[n]; scope (exit) if (a != tmp) delete a; The size of the static array is selected so the dynamic allocation is almost never necessary. If that paradigm is frequent enough, it might be worth wrapping it in a struct. Then, you'd probably get something like StaticArray!(int, 10) tmp(n); int[] a = tmp[]; which used T[10] if n was 10 or less and allocated T[] otherwise. The destructor could then deal with freeing the memory. - Jonathan M Davis Well that's the approach taken by std::array (C++11), if I am not mistaken. -- Paulo
Re: Missing compiler warning?
On Monday, October 21, 2013 12:50:44 Chris wrote: So the solution would be an additional layer that can be turned on / off. Warnings like unused variable or shadowing class declaration are quite useful. I don't see any other cases where a warning would be nice (at the moment). Perhaps, but Walter is against adding much in the way of switches to dmd, and he has pretty much the same position on warnings that I do. Also, with a 3rd party tool, it'll be a lot easier to get warnings on exactly what you want, whereas with the compiler, you have to convince Walter that it should be a warning. Having a configurable tool for additional checks is just more flexible and avoids all of the arguments over what should and should be a warning. Also, because of -w (which makes a warning an error), it would actually be _very_ bad for something like unused variable to be a warning, because then it would be an error, which would result in a _lot_ of traits failing to compile, because it's _very_ common for those to have unused variables. It also would cause problems with RAII. Ideally, -w wouldn't even exist, since it essentially changes what is and isn't legal in the language, but the fact that it does exist makes it that much more precarious to add warnings to the compiler. - Jonathan M Davis
Re: Empty VS null array?
On Monday, October 21, 2013 11:58:07 Regan Heath wrote: If what you say is true then slices would and could never be null... If that were the case I would stop complaining and simply box them with Nullable when I wanted a reference type. But, D's strings/slices are some kind of mutant half reference half value type, and that's the underlying problem here. Yeah, dynamic arrays in D are just plain weird. They're halfway between reference types and value types, and it definitely causes confusion, and it totally screws with null (which definitely sucks). But they mostly work really well the way that they are, and in general, the way that slices work works really well. So, I don't know if what we have is ultimately the right design or not. I definitely don't like how null works for arrays though. Given how they work, we probably would have been better off if they couldn't be null. The ptr obviously could be null, but the array itself arguably shouldn't be able to be null. If we did that, then it would be clear that null wouldn't work with arrays, and no one would try. It would still kind of suck, since you wouldn't have null, but then at least it would be clear that null wouldn't work with arrays instead of having a situation where it kind of does and kind of doesn't. - Jonathan M Davis
Re: Empty VS null array?
On Monday, 21 October 2013 at 09:40:13 UTC, Regan Heath wrote: I disagree. Exceptions should never be used for flow control so the rule is to throw on exceptional occurrences ONLY not on something that you will ALWAYS eventually happen. For such function it is exceptional situation. For precise reading different API is required anyway (==different function).
Re: Missing compiler warning?
On Monday, 21 October 2013 at 10:50:45 UTC, Chris wrote: So the solution would be an additional layer that can be turned on / off. Warnings like unused variable or shadowing class declaration are quite useful. I don't see any other cases where a warning would be nice (at the moment). And this additional layer is called static analysis tool, should be configurable and does not belong to compiler. Warnings must die.
Re: Valgrind and GC
Valgrind in its current state is unfortunately almost unusable with D as it does not support some instructions at least DMD emits.
Re: Valgrind and GC
On 21/10/13 14:04, Dicebot wrote: Valgrind in its current state is unfortunately almost unusable with D as it does not support some instructions at least DMD emits. Don't know about DMD as I never use it for production apart from when I'm working on Phobos, but I've found some of the valgrind family quite useful in profiling D code (which I compile either with GDC or LDC). Memcheck seems useful only in checking the overall number of allocs, though.
Re: Should we distribute a Dutmite binary in the zipped package?
On Monday, 21 October 2013 at 08:17:49 UTC, Andrej Mitrovic wrote: On 10/21/13, Wyatt wyatt@gmail.com wrote: On Sunday, 20 October 2013 at 12:16:14 UTC, Andrej Mitrovic wrote: ...it's strange how many people don't even know it exists... No it isn't. What isn't? I'm just reporting on user experience here. John Colvin got it, but I'll confirm: It's not at all strange or unusual that an undocumented tool isn't well-known. It doesn't matter that it's in the tools repository or tucked away on some non-obvious page of the wiki. If people don't see it in the first two places we expect them to look, then it may as well not exist to a lot of them. I agree it should be added to the release tarball, but even that won't necessarily improve its visibility. How often do you look for new things with strange names added to /usr/bin alongside the binaries you're actually using? So I'll go a little further: not only should it be on the tooling-related pages, it should also be mentioned and linked in any place where we talk about reporting bugs, including the homepage of the bug tracker. -Wyatt
Re: More on C++ stack arrays
On 21 October 2013 21:24, Denis Shelomovskij verylonglogin@gmail.comwrote: 21.10.2013 14:30, Manu пишет: System interface functions that pass zero-terminated strings through to the OS are the primary offender, needless garbage, those should be on the stack. I like to use alloca too where it's appropriate. I'd definitely like if D had a variable-sized static array syntax for pretty-ing alloca. I thought about something similar using alloca via a mixin template, but that feels really hackey! No hacks needed. See `unstd.c.string` module from previous post: http://forum.dlang.org/thread/**lqdktyndevxfcewgthcj@forum.** dlang.org?page=2#post-l42evp:**241ok7:241:40digitalmars.comhttp://forum.dlang.org/thread/lqdktyndevxfcewgt...@forum.dlang.org?page=2#post-l42evp:241ok7:241:40digitalmars.com Super awesome! Phobos devs should be encouraged to use these in non-recursive functions (particularly OS pass-through's).
Re: Empty VS null array?
On Mon, Oct 21, 2013 at 11:53:44AM +0100, Regan Heath wrote: On Fri, 18 Oct 2013 18:38:12 +0100, H. S. Teoh hst...@quickfur.ath.cx wrote: [...] Conceptually speaking, an array is a sequence of values of non-negative length. An array with non-zero length contains at least one element, and is therefore non-empty, whereas an array with zero length is empty. Same thing goes with a slice. A slice is a view into zero or more array elements. A slice with zero length is empty, and a slice with non-zero length contains at least one element. This describes the empty/not empty distinction. There's nowhere in this conceptual scheme for such a thing as a null array that's distinct from an empty array. And this is the problem/complaint. You cannot represent specified/not specified, you can only represent empty/not empty. I agree you cannot logically have an existing array that is somehow a null array and distinct/different from an empty array, but that's not what I want/am asking for. I want to use an array 'reference' to represent that the array is non existent, has not been set, has not been defined, etc. This is what null is for. The thing is, D slices are value types even though the elements they point to are pointed to by reference. If you treat slices (slices themselves, that is, not the elements they refer to) as value types, then the problem goes away. If you want to have a *reference* to a slice, then you simply write T[]* and then it becomes nullable as expected. I do agree that the current situation is confusing, though, mainly because you can write `if (arr is null)`, which then makes you think of it as a reference type. I think that should be prohibited, and slices should be treated as pure value types, and all comparisons should be checked with .length (or .empty if you import std.range). T -- Кто везде - тот нигде.
Re: Empty VS null array?
On Mon, Oct 21, 2013 at 10:40:14AM +0100, Regan Heath wrote: On Fri, 18 Oct 2013 17:36:28 +0100, Dicebot pub...@dicebot.lv wrote: On Friday, 18 October 2013 at 15:42:56 UTC, Andrei Alexandrescu wrote: That's bad API design, pure and simple. The function should e.g. return the string including the line terminator, and only return an empty (or null) string upon EOF. I'd say it should throw upon EOF as it is pretty high-level convenience function. I disagree. Exceptions should never be used for flow control so the rule is to throw on exceptional occurrences ONLY not on something that you will ALWAYS eventually happen. [...] while (!file.eof) { auto line = file.readln(); // never throws ... } T -- There are two ways to write error-free programs; only the third one works.
Re: More on C++ stack arrays
Am 21.10.2013 15:04, schrieb Manu: On 21 October 2013 21:24, Denis Shelomovskij verylonglogin@gmail.comwrote: 21.10.2013 14:30, Manu пОÑеÑ: System interface functions that pass zero-terminated strings through to the OS are the primary offender, needless garbage, those should be on the stack. I like to use alloca too where it's appropriate. I'd definitely like if D had a variable-sized static array syntax for pretty-ing alloca. I thought about something similar using alloca via a mixin template, but that feels really hackey! No hacks needed. See `unstd.c.string` module from previous post: http://forum.dlang.org/thread/**lqdktyndevxfcewgthcj@forum.** dlang.org?page=2#post-l42evp:**241ok7:241:40digitalmars.comhttp://forum.dlang.org/thread/lqdktyndevxfcewgt...@forum.dlang.org?page=2#post-l42evp:241ok7:241:40digitalmars.com Super awesome! Phobos devs should be encouraged to use these in non-recursive functions (particularly OS pass-through's). looks like Walters solution - but cleaner ...Implementation note: For small strings tempCString will use stack allocated buffer, for large strings (approximately 1000 characters and more) it will allocate temporary one from unstd.memory.allocation.threadHeap... does that mean that tempCString reserves minimum 1000 bytes on stack else using heap? if so i would prefer a template based version where i can put in the size
endsWith: wrong function call, no error
The following code compiles: import std.stdio; void main() { auto text = Hello world!; if (!std.algorithm.endsWith(text, ! .)) { writeln(No punctuation!); } else { writeln(Has punctuation); } } The bug is in line 6 a missing comma between ! and .: !std.algorithm.endsWith(text, ! .) If you insert the comma, it will behave as expected. Is this ok or a bug?
Re: endsWith: wrong function call, no error
On Monday, 21 October 2013 at 15:12:36 UTC, Chris wrote: The following code compiles: import std.stdio; void main() { auto text = Hello world!; if (!std.algorithm.endsWith(text, ! .)) { writeln(No punctuation!); } else { writeln(Has punctuation); } } The bug is in line 6 a missing comma between ! and .: !std.algorithm.endsWith(text, ! .) If you insert the comma, it will behave as expected. Is this ok or a bug? It's a feature.
Re: endsWith: wrong function call, no error
On Monday, 21 October 2013 at 15:12:36 UTC, Chris wrote: The following code compiles: import std.stdio; void main() { auto text = Hello world!; if (!std.algorithm.endsWith(text, ! .)) { writeln(No punctuation!); } else { writeln(Has punctuation); } } The bug is in line 6 a missing comma between ! and .: !std.algorithm.endsWith(text, ! .) If you insert the comma, it will behave as expected. Is this ok or a bug? It C-compatible behavior, two string literal separated with only spaces are concatenated into one. So your code was essentially `endsWith(text, !.)`
Re: endsWith: wrong function call, no error
Chris: Is this ok or a bug? In my opinion it's a design bug inherited from C/C++ languages. Please vote for this issue: http://d.puremagic.com/issues/show_bug.cgi?id=3827 Walter once agreed to remove this anti-feature. Bye, bearophile
Re: endsWith: wrong function call, no error
On Monday, 21 October 2013 at 15:21:21 UTC, bearophile wrote: Chris: Is this ok or a bug? In my opinion it's a design bug inherited from C/C++ languages. Please vote for this issue: http://d.puremagic.com/issues/show_bug.cgi?id=3827 Walter once agreed to remove this anti-feature. Bye, bearophile Hm. It took me a few minutes to find the bug in my program. I don't know yet what to think of it. If I wanted !. I would possibly type this. Is there any real world scenario where this behavior could be useful?
Re: endsWith: wrong function call, no error
On Monday, 21 October 2013 at 15:26:17 UTC, Chris wrote: Hm. It took me a few minutes to find the bug in my program. I don't know yet what to think of it. If I wanted !. I would possibly type this. Is there any real world scenario where this behavior could be useful? It was necessary in C because it does not have built-in string concatenation. So only way to define pre-formatted string was something like this: `Error in __FILENAME__ , run for your lives!` It does not seem that needed in D. I was using it out of habit but bearophile has convinced me it is a bad idea.
Re: More on C++ stack arrays
21.10.2013 18:04, dennis luehring пишет: ...Implementation note: For small strings tempCString will use stack allocated buffer, for large strings (approximately 1000 characters and more) it will allocate temporary one from unstd.memory.allocation.threadHeap... does that mean that tempCString reserves minimum 1000 bytes on stack else using heap? if so i would prefer a template based version where i can put in the size Yes, `tempCString` allocates `1024 * To.sizeof` bytes on the stack. Note that it doesn't initialize the data so it is O(1) operation which will just do ~1 KiB move of stack pointer. As function stack frame can easily eat 50-100 bytes it is like 10-20 function calls. IIRC typical stack size is ~1 MiB and `tempCString` isn't expected to be used in some deep recursion or be ~1000 times used in one function. So I'd prefer to change default stack allocation size if needed and not confuse user with manual choice. -- Денис В. Шеломовский Denis V. Shelomovskij
Re: endsWith: wrong function call, no error
On Monday, 21 October 2013 at 15:18:18 UTC, monarch_dodra wrote: It's a feature. I actually like that feature. It's me compose long strings in an easily viewable way without having to use concatenation and therefore additional allocation. Or, even to just comment on indvidual lines string command = /usr/bin/rm -rf / // Don't worry, it'll be fine... /dev/null 2/dev/null // This way nobody will know about it.
Re: Empty VS null array?
On Mon, 21 Oct 2013 15:01:04 +0100, H. S. Teoh hst...@quickfur.ath.cx wrote: On Mon, Oct 21, 2013 at 11:53:44AM +0100, Regan Heath wrote: On Fri, 18 Oct 2013 18:38:12 +0100, H. S. Teoh hst...@quickfur.ath.cx wrote: [...] Conceptually speaking, an array is a sequence of values of non-negative length. An array with non-zero length contains at least one element, and is therefore non-empty, whereas an array with zero length is empty. Same thing goes with a slice. A slice is a view into zero or more array elements. A slice with zero length is empty, and a slice with non-zero length contains at least one element. This describes the empty/not empty distinction. There's nowhere in this conceptual scheme for such a thing as a null array that's distinct from an empty array. And this is the problem/complaint. You cannot represent specified/not specified, you can only represent empty/not empty. I agree you cannot logically have an existing array that is somehow a null array and distinct/different from an empty array, but that's not what I want/am asking for. I want to use an array 'reference' to represent that the array is non existent, has not been set, has not been defined, etc. This is what null is for. The thing is, D slices are value types even though the elements they point to are pointed to by reference. If you treat slices (slices themselves, that is, not the elements they refer to) as value types, then the problem goes away. If you want to have a *reference* to a slice, then you simply write T[]* and then it becomes nullable as expected. True, and that's a pointer, and I am comfortable using pointers.. however I worry this will limit the compilers ability to optimise somehow.. and doesn't it make the code immediately unsafe? I do agree that the current situation is confusing, though, mainly because you can write `if (arr is null)`, which then makes you think of it as a reference type. I think that should be prohibited, and slices should be treated as pure value types, and all comparisons should be checked with .length (or .empty if you import std.range). IMO, this would be preferable to the current situation even thought I would rather go the other way and have a reference type. I can see the argument that it would be safer and easier for most users, even though I do not believe I am in that category. R -- Using Opera's revolutionary email client: http://www.opera.com/mail/
Re: Empty VS null array?
On Mon, 21 Oct 2013 12:54:56 +0100, Jonathan M Davis jmdavisp...@gmx.com wrote: On Monday, October 21, 2013 11:58:07 Regan Heath wrote: If what you say is true then slices would and could never be null... If that were the case I would stop complaining and simply box them with Nullable when I wanted a reference type. But, D's strings/slices are some kind of mutant half reference half value type, and that's the underlying problem here. Yeah, dynamic arrays in D are just plain weird. They're halfway between reference types and value types, and it definitely causes confusion, and it totally screws with null (which definitely sucks). But they mostly work really well the way that they are, and in general, the way that slices work works really well. So, I don't know if what we have is ultimately the right design or not. I definitely don't like how null works for arrays though. Given how they work, we probably would have been better off if they couldn't be null. The ptr obviously could be null, but the array itself arguably shouldn't be able to be null. If we did that, then it would be clear that null wouldn't work with arrays, and no one would try. It would still kind of suck, since you wouldn't have null, but then at least it would be clear that null wouldn't work with arrays instead of having a situation where it kind of does and kind of doesn't. Agreed. This is preferable to the current situation, even if it's not my personal preferred solution. R -- Using Opera's revolutionary email client: http://www.opera.com/mail/
Re: Empty VS null array?
On Mon, 21 Oct 2013 15:02:35 +0100, H. S. Teoh hst...@quickfur.ath.cx wrote: On Mon, Oct 21, 2013 at 10:40:14AM +0100, Regan Heath wrote: On Fri, 18 Oct 2013 17:36:28 +0100, Dicebot pub...@dicebot.lv wrote: On Friday, 18 October 2013 at 15:42:56 UTC, Andrei Alexandrescu wrote: That's bad API design, pure and simple. The function should e.g. return the string including the line terminator, and only return an empty (or null) string upon EOF. I'd say it should throw upon EOF as it is pretty high-level convenience function. I disagree. Exceptions should never be used for flow control so the rule is to throw on exceptional occurrences ONLY not on something that you will ALWAYS eventually happen. [...] while (!file.eof) { auto line = file.readln(); // never throws ... } For a file this is implementable (without a buffer) but not for a socket or similar source/stream where a read MUST be performed to detect EOF. So, if you're implementing a line reader over multiple sources, you would need to buffer. Not the end of the world, but definitely more complicated than just returning a null, no? R -- Using Opera's revolutionary email client: http://www.opera.com/mail/
Re: Slices in D vs Go
On 10/18/13 9:52 PM, Jesse Phillips wrote: Do to the recent slices discussion I did some investigation on what is different in Go. Thus, created this http://he-the-great.livejournal.com/48672.html http://www.reddit.com/r/programming/comments/1owpmp/slices_in_d_vs_go/ Andrei
Re: endsWith: wrong function call, no error
On Monday, 21 October 2013 at 15:38:47 UTC, David Eagen wrote: I actually like that feature. It's me compose long strings in an easily viewable way without having to use concatenation and therefore additional allocation. Concatenation of string literals doesn't need to allocate, as discussed here: http://d.puremagic.com/issues/show_bug.cgi?id=3827. It's trivial to handle the cases where you would've written string1 string2 instead of string1 ~ string2. Once overloaded operators come into play, it's a bit trickier, but if this case really occurred in your program, you could always add a pair of parens to fix it. See also this post by Walter: http://forum.dlang.org/post/ibi742$gi2$1...@digitalmars.com David
Re: endsWith: wrong function call, no error
On Monday, 21 October 2013 at 15:38:47 UTC, David Eagen wrote: On Monday, 21 October 2013 at 15:18:18 UTC, monarch_dodra wrote: It's a feature. I actually like that feature. It's me compose long strings in an easily viewable way without having to use concatenation and therefore additional allocation. Or, even to just comment on indvidual lines string command = /usr/bin/rm -rf / // Don't worry, it'll be fine... /dev/null 2/dev/null // This way nobody will know about it. Well, in my program it was a bug that could comfortably hide for quite a while. It didn't really matter until now, because the program worked in spite of the bug. Only recent changes (today) brought it to light. If it does more harm than good, than it should be removed. It's too easy to forget a comma in an array or in a function like endsWith. What is more, this type of bug might only become apparent after a long long time. If you have auto list = [Joseph, Mary, Peter, Ustinov, Django Pope]; and Django and Pope are the least likely go be selected, it can take a while until you realize that there's a bug. For my part, I've lived happily without this feature.
[OT] Stack safety in Rust
Since I know several people here have been following the development of Rust concerning object lifetime and memory safety vs. (segmented) stacks, I figured this might be interesting: http://cmr.github.io/blog/2013/10/21/on-stack-safety/ It's a new blog post by Corey Richardson, discussing how to mitigate memory corruption due to stack overflows. David
Re: More on C++ stack arrays
On 20 October 2013 20:15, David Nadlinger c...@klickverbot.at wrote: On Sunday, 20 October 2013 at 18:42:06 UTC, Walter Bright wrote: If your optimizing compiler is that good, it can optimize new T[n] to be on the stack as well. Just a side note: LDC actually does this if it can prove statically that the size is bounded. Unfortunately, the range detection is rather conservative (unless your allocation size turns out to be a constant due to inlining, LLVM is unlikely to get it). One idea that might be interesting to think about is to insert a run-time check for the size if an allocation is known not to be escaped, but the size is not yet determined. As a GC allocation is very expensive anyway, this probably wouldn't even be much of a pessimization in the general case. David, can you check the code generation of: http://dpaste.dzfl.pl/3e333df6 PS: Walter, looks the above causes an ICE in DMD? -- Iain Buclaw *(p e ? p++ : p) = (c 0x0f) + '0';
Re: More on C++ stack arrays
On Monday, 21 October 2013 at 15:26:33 UTC, Denis Shelomovskij wrote: So I'd prefer to change default stack allocation size if needed and not confuse user with manual choice. Wouldn't it work to make it optional then? Something like this, I think: auto tempCString(To = char, From, Length = 1024)(in From[] str) if (isSomeChar!To isSomeChar!From); Choosing a sane default but allowing specialist users an easy way to fine-tune it for their needs while keeping the basic usage simple is something I'd advocate for. (Personally, I think 1K sounds quite high; I'd probably make it 256 (one less than the max length of filenames on a whole bunch of filesystems)). -Wyatt
Re: endsWith: wrong function call, no error
On Monday, 21 October 2013 at 15:57:14 UTC, David Nadlinger wrote: Concatenation of string literals doesn't need to allocate, as discussed here: http://d.puremagic.com/issues/show_bug.cgi?id=3827. It's trivial to handle the cases where you would've written string1 string2 instead of string1 ~ string2. Once overloaded operators come into play, it's a bit trickier, but if this case really occurred in your program, you could always add a pair of parens to fix it. See also this post by Walter: http://forum.dlang.org/post/ibi742$gi2$1...@digitalmars.com Thanks for pointing that out. I've changed my stance then. It's causing difficult to find bugs and serves no useful purpose so it should go. But since the thread you linked to is three years old it is apparently already decided and merely waiting implementation.
Re: Empty VS null array?
On Mon, Oct 21, 2013 at 04:41:23PM +0100, Regan Heath wrote: On Mon, 21 Oct 2013 15:01:04 +0100, H. S. Teoh hst...@quickfur.ath.cx wrote: On Mon, Oct 21, 2013 at 11:53:44AM +0100, Regan Heath wrote: [...] I agree you cannot logically have an existing array that is somehow a null array and distinct/different from an empty array, but that's not what I want/am asking for. I want to use an array 'reference' to represent that the array is non existent, has not been set, has not been defined, etc. This is what null is for. The thing is, D slices are value types even though the elements they point to are pointed to by reference. If you treat slices (slices themselves, that is, not the elements they refer to) as value types, then the problem goes away. If you want to have a *reference* to a slice, then you simply write T[]* and then it becomes nullable as expected. True, and that's a pointer, and I am comfortable using pointers.. however I worry this will limit the compilers ability to optimise somehow.. and doesn't it make the code immediately unsafe? No, pointers are allowed in @safe. What is not allowed is pointer *arithmetic* and casting pointers into pointers of different types. I do agree that the current situation is confusing, though, mainly because you can write `if (arr is null)`, which then makes you think of it as a reference type. I think that should be prohibited, and slices should be treated as pure value types, and all comparisons should be checked with .length (or .empty if you import std.range). IMO, this would be preferable to the current situation even thought I would rather go the other way and have a reference type. I can see the argument that it would be safer and easier for most users, even though I do not believe I am in that category. [...] Well, either way would work, though I do prefer treating slices as value types. It's just cleaner conceptually, IMO. But I suppose this is one of those things in which reasonable people may disagree. T -- Sometimes the best solution to morale problems is just to fire all of the unhappy people. -- despair.com
Re: Empty VS null array?
On Mon, Oct 21, 2013 at 04:47:05PM +0100, Regan Heath wrote: On Mon, 21 Oct 2013 15:02:35 +0100, H. S. Teoh hst...@quickfur.ath.cx wrote: On Mon, Oct 21, 2013 at 10:40:14AM +0100, Regan Heath wrote: On Fri, 18 Oct 2013 17:36:28 +0100, Dicebot pub...@dicebot.lv wrote: On Friday, 18 October 2013 at 15:42:56 UTC, Andrei Alexandrescu wrote: That's bad API design, pure and simple. The function should e.g. return the string including the line terminator, and only return an empty (or null) string upon EOF. I'd say it should throw upon EOF as it is pretty high-level convenience function. I disagree. Exceptions should never be used for flow control so the rule is to throw on exceptional occurrences ONLY not on something that you will ALWAYS eventually happen. [...] while (!file.eof) { auto line = file.readln(); // never throws ... } For a file this is implementable (without a buffer) but not for a socket or similar source/stream where a read MUST be performed to detect EOF. So, if you're implementing a line reader over multiple sources, you would need to buffer. Not the end of the world, but definitely more complicated than just returning a null, no? [...] This is actually a very interesting issue to me, and one which I've thought about a lot in the past. There are two incompatible (albeit with much overlap) approaches here. One is the Unix approach where EOF is unknown until you try to read past the end of a file (socket, etc.), and the other is where EOF is known *before* you perform a read. Personally, I prefer the second approach as being conceptually cleaner: an input stream should know when it doesn't have any more data, so that its EOF state can be queried at any time. Conceptually speaking one shouldn't need to (try to) read from it before realizing there's nothing left. However, I understand that the Unix approach is easier to implement, in the sense that if you have a network socket, it may be the case that when you attempt to read from it, it is still connected, but before any further data is received, the remote end disconnects. In this case, the OS can't reasonably predict when there will be more incoming data, so you do have to read the socket before finding out that the remote end is going to disconnect without sending anything more. In terms of API design, though, I still lean towards the approach where EOF is always query-able, because it leads to cleaner code. This can be implemented on Posix by having .eof read a single byte (or whatever unit is expected) and buffering it, and the subsequent readln() takes this buffering into account. This slight complication in implementation is worth achieving the nicer user-facing API, IMO. T -- I've been around long enough to have seen an endless parade of magic new techniques du jour, most of which purport to remove the necessity of thought about your programming problem. In the end they wind up contributing one or two pieces to the collective wisdom, and fade away in the rearview mirror. -- Walter Bright
Re: Should we distribute a Dutmite binary in the zipped package?
On Sunday, 20 October 2013 at 12:16:14 UTC, Andrej Mitrovic wrote: It's a pretty useful tool after all (and it's strange how many people don't even know it exists, judging from IRC conversations). It's already in the tools repo. The issue is filed as: http://d.puremagic.com/issues/show_bug.cgi?id=10332 I'm using D for many years, and this is the first time I'm hearing about this tool.
Re: Valgrind and GC
While I haven't re-examined this issue in years, the collector hasn't changed and this property continues to hold... it's a natural artifact of the stack scan process in the gc. Not every byte of the stack is initialized from valgrind's point of view (or in reality), yet the stack scan can't know that and takes every slot into account regardless. IE, it's a standard part of conservative gc engines. The right 'solution' is to suppress that stacktrace in valgrind. On 10/21/13 3:36 AM, Artem Tarasov wrote: There seems to be some serious issue with the GC, yet almost no attention is paid to that. (See e.g. this thread: http://forum.dlang.org/thread/anhitkodvlstehwxa...@forum.dlang.org) I did a simple test: `void main { new ubyte[65536]; }`. This doesn't pass memcheck! Valgrind tells about using uninitialized values in core.thread.callWithStackShell called by gc.gcx.Gcx.mark. Can anybody look into that? ==3595== Conditional jump or move depends on uninitialised value(s) ==3595==at 0x41E605: _D2gc3gcx3Gcx4markMFPvPviZv (in /home/lomereiter/test) ==3595==by 0x41E5B7: _D2gc3gcx3Gcx4markMFPvPvZv (in /home/lomereiter/test) ==3595==by 0x425520: _D4core6thread14thread_scanAllUMDFPvPvZvZv45__T10__lambda69TE4core6thread8ScanTypeTPvTPvZ10__lambda69MFE4core6thread8ScanTypePvPvZv (in /home/lomereiter/test) ==3595==by 0x4291DA: _D4core6thread15scanAllTypeImplFMDFE4core6thread8ScanTypePvPvZvPvZv (in /home/lomereiter/test) ==3595==by 0x429140: _D4core6thread18thread_scanAllTypeUMDFE4core6thread8ScanTypePvPvZvZv19__T10__lambda62TPvZ10__lambda62MFPvZv (in /home/lomereiter/test) ==3595==by 0x42900F: _D4core6thread18callWithStackShellFMDFPvZvZv (in /home/lomereiter/test) ==3595==by 0x429118: thread_scanAllType (in /home/lomereiter/test) ==3595==by 0x4254F8: thread_scanAll (in /home/lomereiter/test) ==3595==by 0x41EAA5: _D2gc3gcx3Gcx11fullcollectMFZm (in /home/lomereiter/test) ==3595==by 0x41E05C: _D2gc3gcx3Gcx8bigAllocMFmPPS2gc3gcx4PoolPmZPv (in /home/lomereiter/test) ==3595==by 0x41B983: _D2gc3gcx2GC12mallocNoSyncMFmkPmZPv (in /home/lomereiter/test) ==3595==by 0x41B7B6: _D2gc3gcx2GC6mallocMFmkPmZPv (in /home/lomereiter/test) ==3595== Uninitialised value was created by a stack allocation ==3595==at 0x428FE0: _D4core6thread18callWithStackShellFMDFPvZvZv (in /home/lomereiter/test)
Re: Valgrind and GC
On 10/21/13 5:04 AM, Dicebot wrote: Valgrind in its current state is unfortunately almost unusable with D as it does not support some instructions at least DMD emits. Are those issues in bugzilla (for either dmd or valgrind)?
Re: Valgrind and GC
On Monday, 21 October 2013 at 17:01:51 UTC, Brad Roberts wrote: On 10/21/13 5:04 AM, Dicebot wrote: Valgrind in its current state is unfortunately almost unusable with D as it does not support some instructions at least DMD emits. Are those issues in bugzilla (for either dmd or valgrind)? http://d.puremagic.com/issues/show_bug.cgi?id=10054 for example. It is valgrind issue but I don't know if it was ever reported there.
Re: Valgrind and GC
On Mon, Oct 21, 2013 at 9:00 PM, Brad Roberts bra...@puremagic.com wrote: While I haven't re-examined this issue in years, the collector hasn't changed and this property continues to hold... it's a natural artifact of the stack scan process in the gc. Not every byte of the stack is initialized from valgrind's point of view (or in reality), yet the stack scan can't know that and takes every slot into account regardless. IE, it's a standard part of conservative gc engines. The right 'solution' is to suppress that stacktrace in valgrind. Makes sense. Thanks for the explanation, Brad.
Re: More on C++ stack arrays
On 10/21/2013 9:24 AM, Iain Buclaw wrote: http://dpaste.dzfl.pl/3e333df6 PS: Walter, looks the above causes an ICE in DMD? All ICE's should be filed in bugzilla: http://d.puremagic.com/issues/show_bug.cgi?id=11315
Re: More on C++ stack arrays
On 21 October 2013 18:42, Walter Bright newshou...@digitalmars.com wrote: On 10/21/2013 9:24 AM, Iain Buclaw wrote: http://dpaste.dzfl.pl/3e333df6 PS: Walter, looks the above causes an ICE in DMD? All ICE's should be filed in bugzilla: http://d.puremagic.com/issues/show_bug.cgi?id=11315 I've told enough people to raise bugs in GDC to know this. My intention wasn't to find a bug in DMD though when I pasted that link. ;-) I was more curious what LDC does if it stack allocates array literals assigned to static arrays in that program. My guess is that the dynamic array will get the address of the stack allocated array literal, and it's values will be lost after calling fill(); If so, this is another bug that needs to be filled and fixed. -- Iain Buclaw *(p e ? p++ : p) = (c 0x0f) + '0';
An interesting way to teach someone a library
http://nodeschool.io/ Some of the phrases are taken from learnyouahaskell.com - but it is still a good idea for a teaching tool. By the way, how's dtutor coming along? Haven't seen much activity in a while... Regards Iain.
Re: What is the status of dlls on windows?
On Monday, 21 October 2013 at 00:05:28 UTC, TheFlyingFiddle wrote: 2. Throw exceptions over dll boundary\ 2. Last time I tried it, exceptions were not thrown over dll boundary. But it works fine on Linux for shared object files.
Re: What is the status of dlls on windows?
Am 21.10.2013 02:05, schrieb TheFlyingFiddle: How complete is dll support on windows (32/64)? I'm specifically interested in D-to-D dlls. Can i: 1. Load phobos as a DLL 2. Throw exceptions over dll boundary 3. Use multiple threads with thread local storage in loaded dll. D-to-D dlls are pretty much not useable because the export protection level is implemented in a way which makes it over complicated to use (you always need both .d and .di files) and even fails to export some important symbols. If you want to export simple functions it will work. Exporting anything else (classes, structs, etc.) will just be overly complicated or not work at all. See: http://d.puremagic.com/issues/show_bug.cgi?id=9816 and: http://wiki.dlang.org/DIP45 I tried to push DIP 45 for quite some time. The only response I got from Walter numerous times was that he didn't have time to take a look at it. The newsgroup discussion on the topic also only had 3 contributors. There doesn't seem to be much general interest in this topic because most people seem to be using D on linux. I'm planning to push this topic again to get some offical approval because I will never again put work into something D-related without getting it approved first. Kind Regards Benjamin Thaut
Re: Early review of std.logger
On Mon, 14 Oct 2013 13:39:51 +0200, Dicebot wrote: As `std.logger` is still marked as work in progress this thread is less formal that typical pre-voting review. Goal is to provide as much input about desirable `std.logger` functionality and current state and let module author to use this information for preparing proposal for actual review / voting. Lets unleash the forces of constructive destruction. = Meta = Code: https://github.com/D-Programming-Language/phobos/pull/1500/files Docs: http://burner.github.io/phobos/phobos-prerelease/std_logger.html First announcement / discussion thread : http://forum.dlang.org/post/mailman.313.1377180809.1719.digitalmars- d...@puremagic.com std.logger is a good start, but I must admit I do not like the way it is architectured. I use Java's Logging and Log4J for years so naturally I compare std.logger with these two frameworks (that are heavily used in production). std.logger is a bad name, IMHO - it should be std.logging as there will be many Logger implementations there I presume...
Re: More on C++ stack arrays
On Sunday, 20 October 2013 at 14:25:37 UTC, bearophile wrote: More discussions about variable-sized stack-allocated arrays in C++, it seems there is no yet a consensus: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3810.pdf I'd like variable-sized stack-allocated arrays in D. Bye, bearophile I think that is a job for the optimizer. Consider cases like : auto foo() { return new Foo(); } void bar() { auto f = foo(); f.someMethod(); } This is an incredibly common pattern, and it won't be possible to optimize it via added language design without dramatic increase in language complexity. However, once the inliner is passed, you'll end up with something like : auto foo() { return new Foo(); } void bar() { auto f = new Foo(); f.someMethod(); } And if the optimizer is aware of GC calls (LDC is already aware of them, even if only capable of limited optimizations, it is already a good start and show the feasibility of the idea). Obviously Foo is a struct or an class here, but that is the exact same problem as for arrays.
Re: More on C++ stack arrays
On 10/21/2013 07:53 PM, Iain Buclaw wrote: On 21 October 2013 18:42, Walter Bright newshou...@digitalmars.com wrote: On 10/21/2013 9:24 AM, Iain Buclaw wrote: http://dpaste.dzfl.pl/3e333df6 PS: Walter, looks the above causes an ICE in DMD? All ICE's should be filed in bugzilla: http://d.puremagic.com/issues/show_bug.cgi?id=11315 I've told enough people to raise bugs in GDC to know this. My intention wasn't to find a bug in DMD though when I pasted that link. ;-) I was more curious what LDC does if it stack allocates array literals assigned to static arrays in that program. My guess is that the dynamic array will get the address of the stack allocated array literal, and it's values will be lost after calling fill(); If so, this is another bug that needs to be filled and fixed. Why? AFAICS it is the expected behaviour in any case.
Re: More on C++ stack arrays
On 21 October 2013 21:24, Timon Gehr timon.g...@gmx.ch wrote: On 10/21/2013 07:53 PM, Iain Buclaw wrote: On 21 October 2013 18:42, Walter Bright newshou...@digitalmars.com wrote: On 10/21/2013 9:24 AM, Iain Buclaw wrote: http://dpaste.dzfl.pl/3e333df6 PS: Walter, looks the above causes an ICE in DMD? All ICE's should be filed in bugzilla: http://d.puremagic.com/issues/show_bug.cgi?id=11315 I've told enough people to raise bugs in GDC to know this. My intention wasn't to find a bug in DMD though when I pasted that link. ;-) I was more curious what LDC does if it stack allocates array literals assigned to static arrays in that program. My guess is that the dynamic array will get the address of the stack allocated array literal, and it's values will be lost after calling fill(); If so, this is another bug that needs to be filled and fixed. Why? AFAICS it is the expected behaviour in any case. It's an assignment to a dynamic array, so it should invoke the GC and do a _d_arraycopy. -- Iain Buclaw *(p e ? p++ : p) = (c 0x0f) + '0';
Re: More on C++ stack arrays
On 10/21/2013 10:32 PM, Iain Buclaw wrote: On 21 October 2013 21:24, Timon Gehr timon.g...@gmx.ch wrote: On 10/21/2013 07:53 PM, Iain Buclaw wrote: On 21 October 2013 18:42, Walter Bright newshou...@digitalmars.com wrote: On 10/21/2013 9:24 AM, Iain Buclaw wrote: http://dpaste.dzfl.pl/3e333df6 PS: Walter, looks the above causes an ICE in DMD? All ICE's should be filed in bugzilla: http://d.puremagic.com/issues/show_bug.cgi?id=11315 I've told enough people to raise bugs in GDC to know this. My intention wasn't to find a bug in DMD though when I pasted that link. ;-) I was more curious what LDC does if it stack allocates array literals assigned to static arrays in that program. My guess is that the dynamic array will get the address of the stack allocated array literal, and it's values will be lost after calling fill(); If so, this is another bug that needs to be filled and fixed. Why? AFAICS it is the expected behaviour in any case. It's an assignment to a dynamic array, so it should invoke the GC and do a _d_arraycopy. This code: int[] x; int[3] y; x = y = [1,2,3]; Is equivalent to this code: int[] x; int[3] y; y = [1,2,3]; x = y; // -- here Are you saying the line marked with here should perform an implicit allocation and copy the contents of y to the heap?
Re: Early review of std.logger
On 10/21/2013 10:19 PM, Dejan Lekic wrote: On Mon, 14 Oct 2013 13:39:51 +0200, Dicebot wrote: As `std.logger` is still marked as work in progress this thread is less formal that typical pre-voting review. Goal is to provide as much input about desirable `std.logger` functionality and current state and let module author to use this information for preparing proposal for actual review / voting. Lets unleash the forces of constructive destruction. = Meta = Code: https://github.com/D-Programming-Language/phobos/pull/1500/files Docs: http://burner.github.io/phobos/phobos-prerelease/std_logger.html First announcement / discussion thread : http://forum.dlang.org/post/mailman.313.1377180809.1719.digitalmars- d...@puremagic.com std.logger is a good start, but I must admit I do not like the way it is architectured. I use Java's Logging and Log4J for years so naturally I compare std.logger with these two frameworks (that are heavily used in production). unfamiliar or bad (details please).
No memory model
As far as I google, D has not specified a memory model. However, I assume it should basically be the same as the C++ memory model: Sequential consistency for data-race-free programs.
Re: More on C++ stack arrays
On 21 October 2013 21:41, Timon Gehr timon.g...@gmx.ch wrote: On 10/21/2013 10:32 PM, Iain Buclaw wrote: On 21 October 2013 21:24, Timon Gehr timon.g...@gmx.ch wrote: On 10/21/2013 07:53 PM, Iain Buclaw wrote: On 21 October 2013 18:42, Walter Bright newshou...@digitalmars.com wrote: On 10/21/2013 9:24 AM, Iain Buclaw wrote: http://dpaste.dzfl.pl/3e333df6 PS: Walter, looks the above causes an ICE in DMD? All ICE's should be filed in bugzilla: http://d.puremagic.com/issues/show_bug.cgi?id=11315 I've told enough people to raise bugs in GDC to know this. My intention wasn't to find a bug in DMD though when I pasted that link. ;-) I was more curious what LDC does if it stack allocates array literals assigned to static arrays in that program. My guess is that the dynamic array will get the address of the stack allocated array literal, and it's values will be lost after calling fill(); If so, this is another bug that needs to be filled and fixed. Why? AFAICS it is the expected behaviour in any case. It's an assignment to a dynamic array, so it should invoke the GC and do a _d_arraycopy. This code: int[] x; int[3] y; x = y = [1,2,3]; Is equivalent to this code: int[] x; int[3] y; y = [1,2,3]; x = y; // -- here Are you saying the line marked with here should perform an implicit allocation and copy the contents of y to the heap? In GDC, the allocation currently is: y = [1,2,3]; // --- here So it is a safe to not copy. But yes. I think a GC memcopy should be occuring, as dynamic arrays aren't passed by value, so are expected to last the lifetime of the reference to the address. -- Iain Buclaw *(p e ? p++ : p) = (c 0x0f) + '0';
Re: More on C++ stack arrays
On Monday, 21 October 2013 at 21:07:46 UTC, Iain Buclaw wrote: But yes. I think a GC memcopy should be occuring, as dynamic arrays aren't passed by value, so are expected to last the lifetime of the reference to the address. This doesn't produce a heap copy (neither according to the spec nor to actual DMD/LDC behaviour): --- void foo() { int[3] a; int[] b = a; } --- Thus, your example will not copy any data either, as due to associativity, it is equivalent to an assignment to y followed by an assignment of y to x. x simply is a slice of the stack-allocated static array. David
Re: Valgrind and GC
On Monday, 21 October 2013 at 12:04:10 UTC, Dicebot wrote: Valgrind in its current state is unfortunately almost unusable with D as it does not support some instructions at least DMD emits. This is widely wrong. Valgrind can catch many, many bugs, including wrong code, memory errors etc. It just reports warnings on some GC code (it seems that what makes valgrind suspicios is inline asm which initializes some stack data in gc) and sometimes it cannot recognize code instructions (in my experience somtimes means 2 cases of IR bugs for 2 years of debugging buggy code from bugzilla). Taking into account incomplete status of compiler it brings much value. Better description is not almost unusable but failing in extreme cases due to IR bugs and giving some false pasitive conditional jump ... messages about GC code.
Re: More on C++ stack arrays
On 21 October 2013 22:24, David Nadlinger c...@klickverbot.at wrote: On Monday, 21 October 2013 at 21:07:46 UTC, Iain Buclaw wrote: But yes. I think a GC memcopy should be occuring, as dynamic arrays aren't passed by value, so are expected to last the lifetime of the reference to the address. This doesn't produce a heap copy (neither according to the spec nor to actual DMD/LDC behaviour): --- void foo() { int[3] a; int[] b = a; } --- Thus, your example will not copy any data either, as due to associativity, it is equivalent to an assignment to y followed by an assignment of y to x. x simply is a slice of the stack-allocated static array. I know this, but it does deter me against changing gdc over to stack allocating array literals. :-) I'll mull on it over night. -- Iain Buclaw *(p e ? p++ : p) = (c 0x0f) + '0';
Re: Valgrind and GC
On Monday, 21 October 2013 at 21:26:14 UTC, Maxim Fomin wrote: On Monday, 21 October 2013 at 12:04:10 UTC, Dicebot wrote: Valgrind in its current state is unfortunately almost unusable with D as it does not support some instructions at least DMD emits. This is widely wrong. It is in fact true. I couldn't use it on x86_64 Linux to analyse/profile pretty much any non-trivial D application due to some floating point instructions DMD emits not being recognised. There wasn't even any esoteric code involved, just some floating point formatting or similar. Maybe it works fine for test cases from Bugzilla (but wouldn't you typically rather use it on DMD itself for those anyway?), but it's virtually unusable for real D applications. And I say that as a Valgrind fan, having also made some smaller contributions to KCachegrind, a cachegrind/callgrind result viewer for KDE. GDC/LDC-produced executables work just fine, though. David
Re: More on C++ stack arrays
On Monday, 21 October 2013 at 21:41:24 UTC, Iain Buclaw wrote: I know this, but it does deter me against changing gdc over to stack allocating array literals. :-) I'll mull on it over night. There is no change in behaviour due to stack-allocating the literal in the static array assignment (or just not emitting it at all), at least if GDC correctly implements slice - sarray assignment. The dynamic array never sees the literal at all, as shown by Timon. In the general case (i.e. when assigned to dynamic arrays), you obviously can't stack-allocate literals, but I don't think we disagree here. David
Re: More on C++ stack arrays
On 21 October 2013 22:48, David Nadlinger c...@klickverbot.at wrote: On Monday, 21 October 2013 at 21:41:24 UTC, Iain Buclaw wrote: I know this, but it does deter me against changing gdc over to stack allocating array literals. :-) I'll mull on it over night. There is no change in behaviour due to stack-allocating the literal in the static array assignment (or just not emitting it at all), at least if GDC correctly implements slice - sarray assignment. The dynamic array never sees the literal at all, as shown by Timon. In the general case (i.e. when assigned to dynamic arrays), you obviously can't stack-allocate literals, but I don't think we disagree here. That we do not. :o) -- Iain Buclaw *(p e ? p++ : p) = (c 0x0f) + '0';
Re: More on C++ stack arrays
On Monday, 21 October 2013 at 01:48:56 UTC, Walter Bright wrote: On 10/20/2013 5:59 PM, Jonathan M Davis wrote: If that paradigm is frequent enough, it might be worth wrapping it in a struct. Then, you'd probably get something like StaticArray!(int, 10) tmp(n); int[] a = tmp[]; which used T[10] if n was 10 or less and allocated T[] otherwise. The destructor could then deal with freeing the memory. Sounds like a good idea - and it should fit in with Andrei's nascent allocator design. Hmmm, it gave me a weird idea... void smalloc(T)(ushort n, void function(T[]) statement) { if(n = 256) { if(n = 16) { T[16] buf = void; statement(buf[0..n]); } else { T[256] buf = void; statement(buf[0..n]); } } else { if(n = 4096) { T[4096] buf = void; statement(buf[0..n]); } else { T[65536] buf = void; statement(buf[0..n]); } } } smalloc(256, (int[] buf) { });
ARM bare-metal programming in D
Hello, This is my first post here, but I've been warching D for the past year and a half. I currently build small bare-metal (no OS) ARM Cortex-M1/4 embedded system. These targets typically have less than 1MB of program memory, less than 512KB of embedded RAM, and run at less than 200MHz. I currently use C, C++, and assembly, but would very much like to add D to this mix, hopefully removing the Cs completely. Language Questions: 1. Is D or WiLL D be a suitable language for these targets? 2. Is the D runtime required for bare metal programming? In other words, if the D runtime has not yet been ported to these targets, how far can one get using just D the language? Compiler Questions: 1. What is the status of LDC GDC for these bare-metal targets? Is DMD even in this game? 2. If not ARM Cortex, can any of the D compilers target Intel's Quark processor? Finally, if D is not yet ready for these targets, but would like to be, what work remains to be done to get it there. Looking forward to your thoughtful answers. Mike
Re: No memory model
On Monday, 21 October 2013 at 20:50:28 UTC, qznc wrote: As far as I google, D has not specified a memory model. However, I assume it should basically be the same as the C++ memory model: Sequential consistency for data-race-free programs. shared = sequential consistency. immutable = immutable. TL = do whatever you want to make my program faster.