Re: assert(false) in release == splinter in eye
On Sunday 10 October 2010 08:52:28 Christopher Bergqvist wrote: > Hi, > > Time for some Sunday nitpicking. While reading TDPL, one thing that stuck > out to me was the special behavior of assert(false). Consider the following > program compiled with "-release". > > void main() > { > int a = 0; > assert(a); > } > > That program will run without errors. Changing the type of variable a from > "int" to "enum" results in the program segfaulting thanks to the compiler > being able to know the value of the expression "a" at compile time and > inserting a HLT/"halt" instruction. Having the ability to change something > subtle in a more complex expression or series of expressions without > realizing you made a compile time assert(false) which crashes your program > feels ugly. > > I would prefer it if assert() didn't have this special type of behavior, > and that a "halt" keyword or equivalent was introduced. What do you think? > > / Chris I really don't see the problem. Why would you feed an enum to assert as a test? assert is for testing stuff at runtime. If you want to test stuff at compile time, you use static assert. You're not going to accidentally shoot yourself in the foot with this unless you change a variable to an enum and forget to change your assert to a static assert. And since assertions are usually used on function arguments and member variables - _none_ of which would be compile-time constants - I really don't see the problem. - Jonathan M Davis
Re: [challenge] Bounded types
On Sunday 10 October 2010 22:59:44 Yao G. wrote: > On Sun, 10 Oct 2010 21:13:01 -0500, Denis Koroskin <2kor...@gmail.com> > > wrote: > > You shouldn't feel that way. I've read your message, and even took a > > look at your code (very high quality, I must admit). > > It's just IntWrapped isn't quite the same as Bounded, and thus wasn't > > counted as a solution. If you were expecting a review, then please be > > more specific next time! > > I'm sorry. I tried to make a jocular remark. but it seems that I failed. > Maybe I forgot to add a smile or something. Getting tone across in writing can be very difficult. That's one thing that is far easier to do with speech. - Jonathan M Davis
Re: assert(false) in release == splinter in eye
On Mon, 11 Oct 2010 00:22:38 +0300, Tomek Sowiński wrote: BTW, does anybody know the reason for the assert(0) infernal syntax? From http://www.digitalmars.com/d/2.0/expression.html#AssertExpression: "The expression assert(0) is a special case; it signifies that it is unreachable code. Either AssertError is thrown at runtime if it is reachable, or the execution is halted (on the x86 processor, a HLT instruction can be used to halt execution). The optimization and code generation phases of compilation may assume that it is unreachable code." Sometimes it's useful to add an assert(0) at the end of a function which should always return at other points, but the compiler can't know that. -- Best regards, Vladimirmailto:vladi...@thecybershadow.net
Re: [challenge] Bounded types
On Sun, 10 Oct 2010 21:13:01 -0500, Denis Koroskin <2kor...@gmail.com> wrote: You shouldn't feel that way. I've read your message, and even took a look at your code (very high quality, I must admit). It's just IntWrapped isn't quite the same as Bounded, and thus wasn't counted as a solution. If you were expecting a review, then please be more specific next time! I'm sorry. I tried to make a jocular remark. but it seems that I failed. Maybe I forgot to add a smile or something. -- Yao G.
Re: CMake for D2 ready for testers
On Fri, Oct 8, 2010 at 12:41 PM, Jens Mueller wrote: > I also think CMake isn't that shiny. But you can get the job done once > you're familiar with it. My sentiments exactly. Discussing the beauties of a particular build system is all well and good, but what really matters are the warts that emerge only after you're a long way into a big project.
Re: [challenge] Bounded types
On 10/10/10 21:13 CDT, Denis Koroskin wrote: On Mon, 11 Oct 2010 05:55:15 +0400, Yao G. wrote: On Sun, 10 Oct 2010 16:16:05 -0500, Philippe Sigaud wrote: I don't have a bounded type, but a wrapping integer, ported from Boost: http://bitbucket.org/gomez/yao-library/src/tip/src/yao/datetime/core.d#cl-551 I posted this on the Phobos list, but it seems that everybody is ignoring my messages on that list. You shouldn't feel that way. I've read your message, and even took a look at your code (very high quality, I must admit). The ideal submission would be well-motivated, well argued, solidly implemented, and thoroughly documented. I'm not picking on this submission, but it would strain people's time to analyze a variety proposed pieces of code that could be adapted and improved and documented to fit particular needs for Phobos. Andrei
Re: Is D right for me?
On Sunday 10 October 2010 21:26:28 Andrei Alexandrescu wrote: > > A stream solution is in the works (it's discussed periodically on the > > Phobos list), but they haven't sorted out quite what they want to do > > with it yet. The Phobos API in general is in flux, though pieces of it > > are likely to stay more or less unchanged from what they currently are. > > But there's far from any kind of guarantee that much of anything from > > the D1 Phobos is going to survive in the D2 Phobos. They're looking to > > make Phobos as good as they can, and they aren't yet worried about > > keeping its API stable (though they don't make changes unless they think > > that it's actually benificial, so things don't change willy-nilly). I'm > > sure that the time will come, however, when Phobos' API will stabilize, > > and projects will be able to rely on it staying the same. > > > > I think that the reality of the matter is that porting D1 code to D2 code > > is going to be just like, if not exactly like, porting code from one > > library to another rather than an upgrade like you'd get between Qt3 and > > Qt4 (which had plenty of changes). I'm sure that the split between D1 > > and D2 is going to cause a lot of problems for people looking to port > > code from one to the other, but it will be better for newly written > > code, so it's a definite tradeoff. I wouldn't look forward to porting a > > project from D1 to D2 though. > > I think it's a bit hasty to speak on behalf of all of Phobos' > participants. Phobos 2 is indeed different from Phobos 1 but > backward-incompatible changes to Phobos 2 are increasingly rare. Sorry if I overstepped my bounds on that. It's just that from what I've seen, the Phobos devs have been quite willing to make backwards incompatible changes if they thought that they were an improvement, though they aren't done all that frequently. Backwards compatability is considered, but improvements to the API seem to override it. Regardless, the result is that if you wrote your code for dmd 2.040 or something similar and ended up trying to update it to 2.050, you'd likely have a number of changes to make, though porting from Phobos 1 would be far worse. If Phobos were completely stable or at least never made backwards-compatability breaking changes, that wouldn't be the case. I fully expect that as Phobos matures, such breaking changes will become quite rare if not outright nonexistent, but they do still happen. Actually deprecating and replacing the modules that are intended to be deprecated and replace will help a lot with that, but that obviously takes time. - Jonathan M Davis
Re: Is D right for me?
On 10/10/10 20:59 CDT, Jonathan M Davis wrote: On Sunday 10 October 2010 17:27:55 Daniel Gibson wrote: bioinfornatics schrieb: LDC support 64 bit ;) as well as GDC. But both currently lack an up-to-date D2 compiler (but the GDC guys are at least working on it, seems like they're currently at 2.029 - which is great - about 3 months ago they were still at 2.018 and in between was the big 2.020 update that introduced druntime). I agree with walter that 64bit support in DMD is very important, especially for D2: I started a project a few months ago that might have benefited from D2s features (especially ranges), but I decided to use D1 because no 64bit compiler for D2 was in sight. I am btw a bit worried about "upgrading" code from D1 to D2 some day because of the heavy (still ongoing) changes, especially in phobos. I read that for example std.stream is going to be deprecated and replaced by either something with ranges or something like std.stdio (whoever was right about that, maybe even both?). This means that all my (file/network) IO-Code would have to be rewritten sooner or later.. But, currently lacking an alternative to std.stream/std.socketstream for networking, I would have had the same problems even if I had started the project with D2... A stream solution is in the works (it's discussed periodically on the Phobos list), but they haven't sorted out quite what they want to do with it yet. The Phobos API in general is in flux, though pieces of it are likely to stay more or less unchanged from what they currently are. But there's far from any kind of guarantee that much of anything from the D1 Phobos is going to survive in the D2 Phobos. They're looking to make Phobos as good as they can, and they aren't yet worried about keeping its API stable (though they don't make changes unless they think that it's actually benificial, so things don't change willy-nilly). I'm sure that the time will come, however, when Phobos' API will stabilize, and projects will be able to rely on it staying the same. I think that the reality of the matter is that porting D1 code to D2 code is going to be just like, if not exactly like, porting code from one library to another rather than an upgrade like you'd get between Qt3 and Qt4 (which had plenty of changes). I'm sure that the split between D1 and D2 is going to cause a lot of problems for people looking to port code from one to the other, but it will be better for newly written code, so it's a definite tradeoff. I wouldn't look forward to porting a project from D1 to D2 though. I think it's a bit hasty to speak on behalf of all of Phobos' participants. Phobos 2 is indeed different from Phobos 1 but backward-incompatible changes to Phobos 2 are increasingly rare. Andrei
Re: [challenge] Bounded types
On Mon, 11 Oct 2010 05:55:15 +0400, Yao G. wrote: On Sun, 10 Oct 2010 16:16:05 -0500, Philippe Sigaud wrote: I don't have a bounded type, but a wrapping integer, ported from Boost: http://bitbucket.org/gomez/yao-library/src/tip/src/yao/datetime/core.d#cl-551 I posted this on the Phobos list, but it seems that everybody is ignoring my messages on that list. You shouldn't feel that way. I've read your message, and even took a look at your code (very high quality, I must admit). It's just IntWrapped isn't quite the same as Bounded, and thus wasn't counted as a solution. If you were expecting a review, then please be more specific next time! In general if you message was answered, don't take it personal. My message are sometimes being unanswered, too, even though I was asking for a reply (or even referring to specific person). Unanswered message could mean that people didn't understand you, or they have nothing to add, or they could be busy to reply right away (and forgot to do it later). Don't hesitate to bump the topic (or mention it in another discussion) if you feel it was important. I use it in my port of Boost date time library, to convert the overflow from hours, to days. It's a simple, brain dead example, but maybe it can be used as basis or inspiration for something more complex.
Re: [challenge] Bounded types
On Sunday 10 October 2010 18:55:15 Yao G. wrote: > On Sun, 10 Oct 2010 16:16:05 -0500, Philippe Sigaud > wrote: > > I don't have a bounded type, but a wrapping integer, ported from Boost: > > http://bitbucket.org/gomez/yao-library/src/tip/src/yao/datetime/core.d#cl > > -551 > > I posted this on the Phobos list, but it seems that everybody is ignoring > my messages on that list. Ouch! Where did you get that idea? You posted your message on this all of six hours ago, and that list isn't exactly the most active (though the datetime thread has been more active than most). I didn't reply to it, since I'm not going to worry too much about the bounded type issue until it looks like we have an accepted solution. I have enough to worry about with datetime as it is. Regardless of the bound stuff though, your comment on URL shorteners was quite helpful. Do continue to post stuff there. The Phobos list does have rather low activity levels compared to the main D list however. There are probably a number of people who post on this list all the time who should pay attention to the Phobos list but don't, or at least they never post there. - Jonathan M davis
Re: Is D right for me?
On Sunday 10 October 2010 17:27:55 Daniel Gibson wrote: > bioinfornatics schrieb: > > LDC support 64 bit ;) > > as well as GDC. > > But both currently lack an up-to-date D2 compiler (but the GDC guys are > at least working on it, seems like they're currently at 2.029 - which is > great - about 3 months ago they were still at 2.018 and in between was > the big 2.020 update that introduced druntime). > > I agree with walter that 64bit support in DMD is very important, > especially for D2: I started a project a few months ago that might have > benefited from D2s features (especially ranges), but I decided to use D1 > because no 64bit compiler for D2 was in sight. > > I am btw a bit worried about "upgrading" code from D1 to D2 some day > because of the heavy (still ongoing) changes, especially in phobos. > I read that for example std.stream is going to be deprecated and > replaced by either something with ranges or something like std.stdio > (whoever was right about that, maybe even both?). This means that all my > (file/network) IO-Code would have to be rewritten sooner or later.. > But, currently lacking an alternative to std.stream/std.socketstream for > networking, I would have had the same problems even if I had started the > project with D2... A stream solution is in the works (it's discussed periodically on the Phobos list), but they haven't sorted out quite what they want to do with it yet. The Phobos API in general is in flux, though pieces of it are likely to stay more or less unchanged from what they currently are. But there's far from any kind of guarantee that much of anything from the D1 Phobos is going to survive in the D2 Phobos. They're looking to make Phobos as good as they can, and they aren't yet worried about keeping its API stable (though they don't make changes unless they think that it's actually benificial, so things don't change willy-nilly). I'm sure that the time will come, however, when Phobos' API will stabilize, and projects will be able to rely on it staying the same. I think that the reality of the matter is that porting D1 code to D2 code is going to be just like, if not exactly like, porting code from one library to another rather than an upgrade like you'd get between Qt3 and Qt4 (which had plenty of changes). I'm sure that the split between D1 and D2 is going to cause a lot of problems for people looking to port code from one to the other, but it will be better for newly written code, so it's a definite tradeoff. I wouldn't look forward to porting a project from D1 to D2 though. - Jonathan M Davis
Re: [challenge] Bounded types
On Sun, 10 Oct 2010 16:16:05 -0500, Philippe Sigaud wrote: I don't have a bounded type, but a wrapping integer, ported from Boost: http://bitbucket.org/gomez/yao-library/src/tip/src/yao/datetime/core.d#cl-551 I posted this on the Phobos list, but it seems that everybody is ignoring my messages on that list. I use it in my port of Boost date time library, to convert the overflow from hours, to days. It's a simple, brain dead example, but maybe it can be used as basis or inspiration for something more complex. -- Yao G.
Re: assert(false) in release == splinter in eye
On Mon, 11 Oct 2010 03:53:07 +0400, Christopher Bergqvist wrote: Thanks for the support guys. :) Unfortunately "halt" would still need to be a keyword if one wants to keep the full behavior of assert(0), where the compiler knows that it affects the control-flow of the program. Legal: int main() { assert(0); } Illegal (Error: function D main has no return statement, but is expected to return a value of type int): int main() { int a = 0; assert(a); } Just a random thought: class Foo { this(int i) { ... } } class Bar { this(int j) { assert(false); } } Still illegal, but that's a bug I guess.
Re: Call C (or C++) with pointer to static function
I am under the impression that passing a pointer to a static function (ie, passing a pointer to a memory address that contains the starting point of a function) is not the same as defining a method that can be called by name from C code. I am not a C expert though. Can one call fortran libraries from D? Ie, say one wanted to use LAPACK from D? Also, know of any mathematical libraries written in D (like implementations of runge-kutta, linear algebra routines and data structures, optimization or curve-fitting algorithms)? -Mike On Sun, Oct 10, 2010 at 5:10 PM, Simen kjaeraas wrote: > On Sun, 10 Oct 2010 22:03:51 +0200, Michael Stover < > michael.r.sto...@gmail.com> wrote: > > I am wondering if D would be a good choice for our differential equation >> modeling app. What it needs to be able to do is dynamically compile D >> code >> into a static function that can then be used to call C-code that expects a >> pointer to a static function. >> >> Longer description: >> It is a desktop app. The user writes equations. I'd like to be translate >> the equations into D code, compile it, and then call C code that >> represents >> optimizing or solver procedures. These functions expect a pointer to a >> static function that calculates the values of the equations, which would >> be >> the D code just compiled. >> >> Is this feasible with D2? >> > > Absolutely. The dynamic compilation part is not directly supported, but > possible. There are several ways of accomplishing this, from Burton > Radon's (outdated, proof-of-concept only) dynamic compilation[1], to > calling the C functions in the generated D code, and pipe the output > where you need it. > > Interfacing to C is detailed on this page: > http://digitalmars.com/d/2.0/interfaceToC.html > > And can mostly be summarized like this: > > Create a D function that is callable from C: > extern( C ) returnType myFunc( /* args */ ) {} > > Refer to a C function that is callable from D: > extern( C ) returnType myFunc( /* args */ ); > > > [1]: > http://members.shaw.ca/burton-radons/The%20Joy%20and%20Gibbering%20Terror%20of%20Custom-Loading%20Executables.html > > -- > Simen >
Re: Is D right for me?
bioinfornatics schrieb: LDC support 64 bit ;) as well as GDC. But both currently lack an up-to-date D2 compiler (but the GDC guys are at least working on it, seems like they're currently at 2.029 - which is great - about 3 months ago they were still at 2.018 and in between was the big 2.020 update that introduced druntime). I agree with walter that 64bit support in DMD is very important, especially for D2: I started a project a few months ago that might have benefited from D2s features (especially ranges), but I decided to use D1 because no 64bit compiler for D2 was in sight. I am btw a bit worried about "upgrading" code from D1 to D2 some day because of the heavy (still ongoing) changes, especially in phobos. I read that for example std.stream is going to be deprecated and replaced by either something with ranges or something like std.stdio (whoever was right about that, maybe even both?). This means that all my (file/network) IO-Code would have to be rewritten sooner or later.. But, currently lacking an alternative to std.stream/std.socketstream for networking, I would have had the same problems even if I had started the project with D2...
Re: assert(false) in release == splinter in eye
Tomek S.: > BTW, does anybody know the reason for the assert(0) infernal syntax? I think it's a shorcut, to gain a functionality without adopting a specific syntax. An as it very often happens in language design, shortcuts later come back to bite your bum :-) Bye, bearophile
Re: Is D right for me?
LDC support 64 bit ;)
Re: assert(false) in release == splinter in eye
Thanks for the support guys. :) Unfortunately "halt" would still need to be a keyword if one wants to keep the full behavior of assert(0), where the compiler knows that it affects the control-flow of the program. Legal: int main() { assert(0); } Illegal (Error: function D main has no return statement, but is expected to return a value of type int): int main() { int a = 0; assert(a); } 2010/10/10 Tomek Sowiński > Christopher Bergqvist napisał: > > > Hi, > > > > Time for some Sunday nitpicking. While reading TDPL, one thing that stuck > > out to me was the special behavior of assert(false). Consider the > > following program compiled with "-release". > > > > void main() > > { > > int a = 0; > > assert(a); > > } > > > > That program will run without errors. Changing the type of variable a > from > > "int" to "enum" results in the program segfaulting thanks to the compiler > > being able to know the value of the expression "a" at compile time and > > inserting a HLT/"halt" instruction. Having the ability to change > something > > subtle in a more complex expression or series of expressions without > > realizing you made a compile time assert(false) which crashes your > program > > feels ugly. > > > > I would prefer it if assert() didn't have this special type of behavior, > > and that a "halt" keyword or equivalent was introduced. What do you > think? > > I have the same feeling. 'halt' is good, 'fail' is good too. It doesn't > have to be a keyword, a > function in object.d would suffice. > > BTW, does anybody know the reason for the assert(0) infernal syntax? > > -- > Tomek >
Re: [challenge] Bounded types
> I think scope(success) is an overkill here. Yeah. It is in my brain due to writing a lot of database code with it: db.query("START TRANSACTION"); scope(success) db.query("COMMIT"); scope(failure) db.query("ROLLBACK"); > Well done otherwise, looking forward for final version! Thanks. For future direction, I don't think the Type argument is actually needed to the Bounded struct. It could determine it from the bounds. So Bounded!(0, 255) it knows could be a ubyte, but Bounded!('A', 'Z') is a char. Maybe the type param can be moved to the end, as an optional parameter. In most cases, it should be able to figure it out on its own.
Re: [challenge] Bounded types
Denis Koroskin: > Also, one should be able to define CheckedInt type as follows: > > alias Bounded!(int, int.min, int.max) CheckedInt; > > CheckedInt would allow easy integer overflow detection. Smart compiler > would also optimize all the (int.min <= value && value <= int.max) checks > as redundant, and the type would be very slim and efficient. That CheckedInt may be useful in some situations, but it's not able to give you many advantages of overflow detection. Think about having a BoundedArray type in Phobos that implements an array with out-of-bound errors, and have the built-in arrays without bound detection. How much good is this for your code? To spot out-of-bound bugs in your code it's instead very good to have a global switch (-release) that allows you to disable bound tests for all the arrays in your compilation unit (and if you don't use -release all those tests are present). Your code is unchanged, you are able to catch many bugs early in your code, and if you don't need those tests you may disable them with just a flag. And a smarter D compiler may remove some useless bound tests even in nonrelease mode (as the JavaVM recently does in some situations). In exactly the same way, it's good to have a compiler switch, like: Overflows: signed unsigned 1) No switch ==> no no 2) -ov ==>yes yes 3) -ovs ==>yes no That disables signed/unsigned overflows or disables both (enabled on default). It catches integral numerics bugs early. (Plus you need a simple syntax to enable/disable the tests locally, overriding the global compilation switch). One thing you may fear of, is that such tests are going to slow down your code a lot (and increase its size). I have done tests running the C# benchmarks of the Shootout site using integer overflows and not using them, and the difference in performance is usually not so great (such timings are compatible with my precedent experience with Delphi programs, where I have used all the time those runtime tests). Bye, bearophile
Re: [challenge] Bounded types
On Mon, 11 Oct 2010 02:24:55 +0400, Adam D. Ruppe wrote: Your code is wrong in many places. In short, exceptional situation should leave your object in correct state. Yeah, I know, but I wanted to get the overflow flag check working first and worry about transactional integrity later. The way I was thinking of doing it is storing the result in a temporary, which gets the checks, then having scope(success) commit it to the _payload. But I just haven't gotten around to it yet - it's just a starting point, not a finished product. I think scope(success) is an overkill here. Well done otherwise, looking forward for final version!
Re: [challenge] Bounded types
Philippe Sigaud: > there is a long discussion about a date/time module on the Phobos mailing > list, and among other very interesting things, it was suggested to add a > Bounded template to Phobos. I'll extract this as a challenge to the D > community. I think they are also named ranged types, they are quite useful to reduce the bug-count of programs, because when you use them, you are sure they are bounded in the specified interval. They are one of the original built-in features I have asked few years ago for D, but I think Walter answered something like they are a "failed language feature". I have used them and I have appreciated them a lot in Delphi, and I think they are the opposite of a failure. Implementing them as library things instead of built-ins may give a bit worse syntax (and maybe a bit lower performance if assembly is used inside them, that kills inlining), but allows for more experiments and flexibility. But the "alias this" must be implemented really well by the compiler. Their syntax in Pascal and Ada: http://en.wikipedia.org/wiki/Pascal_%28programming_language%29#Subrange_types http://en.wikipedia.org/wiki/Ada_%28programming_language%29#Data_types In SPARK (Ada subset) you may also write (allows you to specify that it's a subtype): subtype String_3_Index is Positive range 1 .. 3; In D there's the ranged foreach syntax: foreach (i; 0 .. 10) If that 0 .. 10 syntax becomes more first class, it may be used to specify a bit better ranges for library-defined ranged types. > Otherwise, I gather it throws an exception. It's a to-be standard numeric overflow exception, I presume. Or just asserts, or otherwise it must have a way to statically disable those bound tests. > PS: clever (or perverse) readers may wonder what happens when Bounded uses a > type that has no obvious ordering. Like: Bounded!(int function(int), ...). In > that case, I suggest passing a ordering template that will test if a given > value is between min and max. The default would be BinaryFun!"a < b". Another > possibility is to restrict Bounded to types defining opCmp. Be careful to avoid over-engineer them :-) In the end bounded types are just a special case of numeric overflow tests (a difference is that your bounded values work with floating point values too), that I think still are very useful in D both for debugging and to create high-reliability D code (I think D may eventually interest people that write code that must be very safe, like code that controls potentially deadly machines). Bye, bearophile
Re: [challenge] Bounded types
> Your code is wrong in many places. In short, exceptional situation should leave your object in correct state. Yeah, I know, but I wanted to get the overflow flag check working first and worry about transactional integrity later. The way I was thinking of doing it is storing the result in a temporary, which gets the checks, then having scope(success) commit it to the _payload. But I just haven't gotten around to it yet - it's just a starting point, not a finished product.
Re: [challenge] Bounded types
On Mon, 11 Oct 2010 01:16:05 +0400, Philippe Sigaud wrote: Hi, there is a long discussion about a date/time module on the Phobos mailing list, and among other very interesting things, it was suggested to add a Bounded template to Phobos. I'll extract this as a challenge to the D community. Bounded takes a type, a min value and a max value and gives back a type that can hold only values between min and max (tested at runtime). Otherwise, I gather it throws an exception. for example: Bounded!(char, 'a','z') can only hold lowercase letters. Bounded!(double, 0.0, 1.0) is a bit like a double, but can only hold doubles between 0.0 and 1.0. As you can see, an "open or closed for both ends" policy could be interesting to add. In the previous example, is 1.0 a correct value? Another policy could be if it internally uses 'alias this' or not, and if opAssign is defined. That is, given alias Bounded!(int, 0, 9) Digit; Digit d; int foo(int i) { return i*i;} can you do: d = 9; or do you have to do: d = Digit(9); And can you call foo with d? As for all type-wrapper templates, this raises issues already seen on typedef threads: subtype, parallel type, totally distinct type? The challenge is: implement Bounded. Philippe PS: clever (or perverse) readers may wonder what happens when Bounded uses a type that has no obvious ordering. Like: Bounded!(int function(int), ...). In that case, I suggest passing a ordering template that will test if a given value is between min and max. The default would be BinaryFun!"a < b". Another possibility is to restrict Bounded to types defining opCmp. Also, one should be able to define CheckedInt type as follows: alias Bounded!(int, int.min, int.max) CheckedInt; CheckedInt would allow easy integer overflow detection. Smart compiler would also optimize all the (int.min <= value && value <= int.max) checks as redundant, and the type would be very slim and efficient.
Re: [challenge] Bounded types
Your code is wrong in many places. In short, exceptional situation should leave your object in correct state. E.g. the following is invalid: _payload += stuff; mixin(runCheckCode()); while the following is correct: T tmp = _payload + stuff; mixin(runCheckCode()); _payload = tmp; There is a great book about Exception Safety by Scott Meyers, I highly recommend reading it. At the very least read this: http://en.wikipedia.org/wiki/Exception_handling#Exception_safety
Re: [challenge] Bounded types
Philippe Sigaud napisał: > As you can see, an "open or closed for both ends" policy could be > interesting to add. In the previous example, is 1.0 a correct value? It can be handled as in std.random: Bounded!(T, min, max, string bounds = "[)"). But with "[]" as default. -- Tomek
Re: Schrödinger's Stride
Andrei Alexandrescu napisał: > On 10/10/10 13:34 CDT, Tomek Sowiński wrote: >> Currently the contents of Stride depend on from which end we look at it: >> >> auto m = [1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4]; // 3 rows, 4 columns >> auto col = stride(m, 4); >> assert(equal(col, [1, 1, 1])); >> assert(equal(retro(col), [4, 4, 4])); >> >> Is the quantum behavior intended? > > Bug! http://d.puremagic.com/issues/show_bug.cgi?id=5035 -- Tomek
Re: [challenge] Bounded types
I saw it on the Phobos list and whipped together a first try. Here's the code: import std.conv; class BoundedOverflowException : Exception { this(string msg) { super(msg); } } struct Bounded(T, T min, T max) { T _payload; static string runCheckCode() { return q{ asm { jo overflow; } if(_payload < min) goto overflow; if(_payload > max) goto overflow; goto ok; overflow: throw new BoundedOverflowException("Overflow at "~file~":"~to!string(line)~" (payload: " ~ to!string(_payload) ~ ")"); ok: ; }; } T opUnary(string op, string file = __FILE__, int line = __LINE__)() { mixin("_payload " ~ op ~ ";"); mixin(runCheckCode()); } T opBinary(string op, string file = __FILE__, int line = __LINE__)(T rhs) { T tmp = void; mixin("tmp = _payload " ~ op ~ "rhs;"); _payload = tmp; mixin(runCheckCode()); return tmp; } T opOpAssign(string op, string file = __FILE__, int line = __LINE__)(T rhs) { T tmp = void; mixin("tmp = _payload " ~ op ~ "rhs;"); _payload = tmp; mixin(runCheckCode()); return _payload; } T opAssign(T rhs, string file = __FILE__, int line = __LINE__) { _payload = rhs; mixin(runCheckCode()); return _payload; } string toString() { return to!string(_payload); } alias _payload this; } import std.stdio; void main() { Bounded!(int, int.min, int.max) a; a = int.max; a += 5; // throws writefln("%s", a); a += 5; writefln("%s", a); a += 5; } === It uses a mixin to do the check, so the jo instruction works so it catches wrapping overflow too. I'm sure it is broken with types other than int right now, but it might be a starting point.
Re: assert(false) in release == splinter in eye
Christopher Bergqvist napisał: > Hi, > > Time for some Sunday nitpicking. While reading TDPL, one thing that stuck > out to me was the special behavior of assert(false). Consider the > following program compiled with "-release". > > void main() > { > int a = 0; > assert(a); > } > > That program will run without errors. Changing the type of variable a from > "int" to "enum" results in the program segfaulting thanks to the compiler > being able to know the value of the expression "a" at compile time and > inserting a HLT/"halt" instruction. Having the ability to change something > subtle in a more complex expression or series of expressions without > realizing you made a compile time assert(false) which crashes your program > feels ugly. > > I would prefer it if assert() didn't have this special type of behavior, > and that a "halt" keyword or equivalent was introduced. What do you think? I have the same feeling. 'halt' is good, 'fail' is good too. It doesn't have to be a keyword, a function in object.d would suffice. BTW, does anybody know the reason for the assert(0) infernal syntax? -- Tomek
[challenge] Bounded types
Hi, there is a long discussion about a date/time module on the Phobos mailing list, and among other very interesting things, it was suggested to add a Bounded template to Phobos. I'll extract this as a challenge to the D community. Bounded takes a type, a min value and a max value and gives back a type that can hold only values between min and max (tested at runtime). Otherwise, I gather it throws an exception. for example: Bounded!(char, 'a','z') can only hold lowercase letters. Bounded!(double, 0.0, 1.0) is a bit like a double, but can only hold doubles between 0.0 and 1.0. As you can see, an "open or closed for both ends" policy could be interesting to add. In the previous example, is 1.0 a correct value? Another policy could be if it internally uses 'alias this' or not, and if opAssign is defined. That is, given alias Bounded!(int, 0, 9) Digit; Digit d; int foo(int i) { return i*i;} can you do: d = 9; or do you have to do: d = Digit(9); And can you call foo with d? As for all type-wrapper templates, this raises issues already seen on typedef threads: subtype, parallel type, totally distinct type? The challenge is: implement Bounded. Philippe PS: clever (or perverse) readers may wonder what happens when Bounded uses a type that has no obvious ordering. Like: Bounded!(int function(int), ...). In that case, I suggest passing a ordering template that will test if a given value is between min and max. The default would be BinaryFun!"a < b". Another possibility is to restrict Bounded to types defining opCmp.
Re: Tuple literal syntax
On Sun, Oct 10, 2010 at 23:05, bearophile wrote: > Philippe Sigaud: > >> may I suggest to have a way to concatenate tuples? > > I have implemented it, see enhancement request 4591 Cool, I'll have a look. *does so* Wow, much more complicated that what I had in mind. I totally forgot about named fields. Philippe
Re: Call C (or C++) with pointer to static function
On Sun, 10 Oct 2010 22:03:51 +0200, Michael Stover wrote: I am wondering if D would be a good choice for our differential equation modeling app. What it needs to be able to do is dynamically compile D code into a static function that can then be used to call C-code that expects a pointer to a static function. Longer description: It is a desktop app. The user writes equations. I'd like to be translate the equations into D code, compile it, and then call C code that represents optimizing or solver procedures. These functions expect a pointer to a static function that calculates the values of the equations, which would be the D code just compiled. Is this feasible with D2? Absolutely. The dynamic compilation part is not directly supported, but possible. There are several ways of accomplishing this, from Burton Radon's (outdated, proof-of-concept only) dynamic compilation[1], to calling the C functions in the generated D code, and pipe the output where you need it. Interfacing to C is detailed on this page: http://digitalmars.com/d/2.0/interfaceToC.html And can mostly be summarized like this: Create a D function that is callable from C: extern( C ) returnType myFunc( /* args */ ) {} Refer to a C function that is callable from D: extern( C ) returnType myFunc( /* args */ ); [1]: http://members.shaw.ca/burton-radons/The%20Joy%20and%20Gibbering%20Terror%20of%20Custom-Loading%20Executables.html -- Simen
Re: assert(false) in release == splinter in eye
Christopher Bergqvist: > I would prefer it if assert() didn't have this special type of behavior, and > that a "halt" keyword or equivalent was introduced. What do you think? A halt() intrinsic from sounds indeed cleaner. But I don't know if Walter is willing to add a keyword just for this purpose. Bye bearophile
Re: Schrödinger's Stride
On 10/10/10 13:34 CDT, Tomek Sowiński wrote: Currently the contents of Stride depend on from which end we look at it: auto m = [1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4]; // 3 rows, 4 columns auto col = stride(m, 4); assert(equal(col, [1, 1, 1])); assert(equal(retro(col), [4, 4, 4])); Is the quantum behavior intended? Bug! Andrei
Re: Tuple literal syntax
Philippe Sigaud: > may I suggest to have a way to concatenate tuples? I have implemented it, see enhancement request 4591 Bye, bearophile
Re: Schrödinger's Stride
On 10/10/10 9:45 PM, Tomek Sowiński wrote: Peter Alexander napisał: On 10/10/10 7:34 PM, Tomek Sowiński wrote: Currently the contents of Stride depend on from which end we look at it: auto m = [1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4]; // 3 rows, 4 columns auto col = stride(m, 4); assert(equal(col, [1, 1, 1])); assert(equal(retro(col), [4, 4, 4])); Is the quantum behavior intended? Hmm, that does seem counter-intuitive, but I can't see any other way for it to work. Consider a doubly-linked list with the same data as above. How could Stride implement back() without first computing the length of the list? I don't know but that wouldn't work now anyway -- popBack() and back() is defined if isBidirectionalRange!(R)&& hasLength!(R), where R is the underlying. You could implement it correctly and efficiently for (non-infinite) random access ranges, but then you'd have inconsistent behavior between random access ranges and non-RA bidirectional ranges. It's not about random access, but length. Having length, it's trivial to calculate how many popBack()s one needs to prime the stride. For ranges without length it doesn't matter because the above. The solution I believe is to make Stride a forward range for directional ranges, and give it the correct semantics for back() when used on a random access range i.e. use ((length-1) - (length-1) % stride) to get the back element index so that the retro traversal is actually the reverse of the forward traversal. For bidirectional ranges, people can always just use stride(retro(r), n) to get a backwards traversing stride. Actually I see in Stride's ctor an attempt to pop slack items off the input's back: this(R input, size_t n) { _input = input; _n = n; static if (hasLength!(R)) { auto slack = _input.length % _n; if (slack) slack--; if (!slack) return; Since retro'ing isn't unittested, I can't tell if it was to address this issue or not. I think it's just a matter of fixing the 'slack' number. Phobos people? Sorry, yeah, you're absolutely right. I don't know why I was fixated on random access ranges.
Re: Schrödinger's Stride
Peter Alexander napisał: > On 10/10/10 7:34 PM, Tomek Sowiński wrote: >> Currently the contents of Stride depend on from which end we look at it: >> >> auto m = [1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4]; // 3 rows, 4 columns >> auto col = stride(m, 4); >> assert(equal(col, [1, 1, 1])); >> assert(equal(retro(col), [4, 4, 4])); >> >> Is the quantum behavior intended? > > Hmm, that does seem counter-intuitive, but I can't see any other way for > it to work. > > Consider a doubly-linked list with the same data as above. How could > Stride implement back() without first computing the length of the list? I don't know but that wouldn't work now anyway -- popBack() and back() is defined if isBidirectionalRange!(R) && hasLength!(R), where R is the underlying. > You could implement it correctly and efficiently for (non-infinite) > random access ranges, but then you'd have inconsistent behavior between > random access ranges and non-RA bidirectional ranges. It's not about random access, but length. Having length, it's trivial to calculate how many popBack()s one needs to prime the stride. For ranges without length it doesn't matter because the above. > The solution I believe is to make Stride a forward range for directional > ranges, and give it the correct semantics for back() when used on a > random access range i.e. use ((length-1) - (length-1) % stride) to get > the back element index so that the retro traversal is actually the > reverse of the forward traversal. > > For bidirectional ranges, people can always just use stride(retro(r), n) > to get a backwards traversing stride. Actually I see in Stride's ctor an attempt to pop slack items off the input's back: this(R input, size_t n) { _input = input; _n = n; static if (hasLength!(R)) { auto slack = _input.length % _n; if (slack) slack--; if (!slack) return; Since retro'ing isn't unittested, I can't tell if it was to address this issue or not. I think it's just a matter of fixing the 'slack' number. Phobos people? -- Tomek
Call C (or C++) with pointer to static function
I am wondering if D would be a good choice for our differential equation modeling app. What it needs to be able to do is dynamically compile D code into a static function that can then be used to call C-code that expects a pointer to a static function. Longer description: It is a desktop app. The user writes equations. I'd like to be translate the equations into D code, compile it, and then call C code that represents optimizing or solver procedures. These functions expect a pointer to a static function that calculates the values of the equations, which would be the D code just compiled. Is this feasible with D2? Thanks, Michael Stover
assert(false) in release == splinter in eye
Hi, Time for some Sunday nitpicking. While reading TDPL, one thing that stuck out to me was the special behavior of assert(false). Consider the following program compiled with "-release". void main() { int a = 0; assert(a); } That program will run without errors. Changing the type of variable a from "int" to "enum" results in the program segfaulting thanks to the compiler being able to know the value of the expression "a" at compile time and inserting a HLT/"halt" instruction. Having the ability to change something subtle in a more complex expression or series of expressions without realizing you made a compile time assert(false) which crashes your program feels ugly. I would prefer it if assert() didn't have this special type of behavior, and that a "halt" keyword or equivalent was introduced. What do you think? / Chris
Re: Tuple literal syntax
Whatever the conclusion on all this is, may I suggest to have a way to concatenate tuples? auto t1 = tuple(1, "a"); // or (|1, "a"|) or {1, "a"} or what have you. auto t2 = tuple((int i, string s) { return i;}); auto result = t1 ~ t2; result is a (int,string, int function(int,string)) tuple. Ideally, you should also be able to add any value before or after a tuple. auto result2 = 3.1415 ~ result; This is easily added to std.typecons.Tuple with opBinary!"~".
Re: ParserCobinator like scala in D
Hi, you can aggregate all submissions on one page: ideone.com/user_login/page - just simply manage them on 'my submissions' panel, good luck! SphereResearch Team $BH~GO5W9T(B Wrote: > Since I want parser to make a Scripting Engine, I wrote ParserCombinator > which is popular in Scala in D. > However, when we devotedly write parser using ParserCombinator, the source > code is very dirty. > Like this > convert!(parseSeq!(parseOption(parseChar!('a')), parseChar!('b')), > funciton(){~}) > > We can easily convert PEG into parser by using ParserCombinator, > so I wrote the parser which parse a PEG and return the string of parser in > CTFE. > Like this > enum peg = q{ > foo = ('0' | '1') >> (char c) { > return c - '0'; > }; > } > mixin(defs(peg).value); > 'defs' is the parser. > I call the parser PEGParser as a matter of convenience. > > Template Library: http://ideone.com/3rKF4 > ParserCombinator: http://ideone.com/YlGP2 > PEGParser: http://ideone.com/vkTyh > Sample(Expression of four arithmetic operations): http://ideone.com/0uc3t > > What do you think about this? > > Since I want parser to make a Scripting Engine, I wrote > ParserCombinator which is popular in Scala in D.However, when we > devotedly write parser using ParserCombinator, the source code is very > dirty. > Like this style="white-space:pre"> > convert!(parseSeq!(parseOption(parseChar!('a')), > parseChar!('b')), style="white-space:pre"> funciton(){~}) > We can easily convert PEG into parser by using > ParserCombinator,so I wrote the parser which parse a PEG and > return the string of parser in CTFE.Like this class="Apple-tab-span" style="white-space:pre"> enum peg = q{ > > foo= ('0' | '1') >> (char c) { class="Apple-tab-span" style="white-space:pre"> return > c - '0'; > > }; > } > mixin(defs(peg).value); > 'defs' is the parser.I call the parser PEGParser as a matter > of convenience.Template Library: href="http://ideone.com/3rKF4";>http://ideone.com/3rKF4ParserCombinator: > http://ideone.com/YlGP2";>http://ideone.com/YlGP2 > PEGParser: href="http://ideone.com/vkTyh";>http://ideone.com/vkTyhSample(Expression > of four arithmetic operations): href="http://ideone.com/0uc3t";>http://ideone.com/0uc3t > What do you think about this? >
Re: Is D right for me?
Jonathan M Davis wrote: Of course, projects like QtD suffer from the same sort of problem as a compiler does in that it's not necessarily very useful until it's complete. Lots of people may be interested in using QtD, but if it's not at least close to done, it's not going to be useable enough to use in any major project, so people won't use, they won't report bugs on it, and the won't give any kind of feedback on the project. So, the poor QtD people then have to get a _lot_ of code done before they see any kind of positive feedback from the community, and when they _do_ start getting feedback, much of it is likely to be negative because feature X hasn't been implemented yet or feature Y is buggy. A lot of people have given up on D for similar reasons. Hopefully enough of the problems that they were having with dmd get fixed soon enough that they're able to actually continue working on the project without getting too frustrated over it. Things sure have changed. Back in the 80's, people were able to get real projects done with absolutely *terrible* compilers. Compilers have steadily gotten better, and so have expectations.
Re: ; not required after pragma
Tomek Sowiński, el 10 de octubre a las 20:13 me escribiste: > Simen kjaeraas napisał: > > > Tomek Sowiński wrote: > > > >> pragma(msg, "blabla") > >> > >> bug or feature? > > > > Feature. http://www.digitalmars.com/d/2.0/pragma.html: > > > > "Pragmas can be used by themselves terminated with a ';', they can > > influence a statement, a block of statements, a declaration, or a block > > of declarations." > > > > E.g. pragma( blah, blablableh ) struct foo {}; might mean something, > > and in this case the pragma would modify foo. > > Heh, should've DAFS, thanks. > It's still baffling a bit - what can pragma(msg) possibly influence? Perhaps > there should be a > division - influencing vs. statement flavor. The compiler could disallow > usage not lying in a > particular pragma's nature. The parser doesn't know about what "msg" means. To do this you'll have to define each pragma as part of the syntax (you can't, since most of the usefulness of pragma is language extension) or have a stmpragma and exppragma to parse differently "statement flavor" and "influencing" pragmas, or something like that. -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- He cometido pecados, he hecho el mal, he sido víctima de la envidia, el egoísmo, la ambición, la mentira y la frivolidad, pero siempre he sido un padre argentino que quiere que su hijo triunfe en la vida. -- Ricardo Vaporeso
Re: Is D right for me?
Gour D. wrote: (64bit dmd, do you hear me?) Don't I know it. 64 bit support is absolutely essential for D's future.
Re: Schrödinger's Stride
On 10/10/10 7:34 PM, Tomek Sowiński wrote: Currently the contents of Stride depend on from which end we look at it: auto m = [1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4]; // 3 rows, 4 columns auto col = stride(m, 4); assert(equal(col, [1, 1, 1])); assert(equal(retro(col), [4, 4, 4])); Is the quantum behavior intended? Hmm, that does seem counter-intuitive, but I can't see any other way for it to work. Consider a doubly-linked list with the same data as above. How could Stride implement back() without first computing the length of the list? You could implement it correctly and efficiently for (non-infinite) random access ranges, but then you'd have inconsistent behavior between random access ranges and non-RA bidirectional ranges. The solution I believe is to make Stride a forward range for directional ranges, and give it the correct semantics for back() when used on a random access range i.e. use ((length-1) - (length-1) % stride) to get the back element index so that the retro traversal is actually the reverse of the forward traversal. For bidirectional ranges, people can always just use stride(retro(r), n) to get a backwards traversing stride.
convenient backward compatible template arguments type deduction
Greetings, Given: a template function foo(T) (T[] a, T[] b) { .. } It is being called using: foo(mutableString,"immutableString"); dmd will fail because it can't deduce the type. So far so expected. Now, there are situations where I don't care in my template whether any part is mutable or not (so I would want use const) and there are situations where certain parameters need to be mutable. One solution I found: foo(T,U=T) (T[] a, U[] b) { .. } Problem is, I still can't say which one should be const, if any. Additionally, the types can be very different and I should add checks for that. The obvious solution foo(T) (const(T)[] a, const(T)[] b) { .. } is not available to me in this case, because I want it to be D1 compatible. I tried to do this: template Constify(T) { version(D_Version2) mixin("alias const(T) Constify;"); else alias T Constify; } foo(T) (Constify!(T)[] a, Constify!(T)[] b) { .. } but this fails at deducing the type from the arguments. I could of course provide either a version for D1 and one for D2 or just mixin the body of the function, but I was hoping someone here knows a better way. --Marenz
Re: [Theory] Halting problem
== Quote from Norbert Nemec (norb...@nemec-online.de)'s article > On 10/10/10 19:36, %u wrote: > > == Quote from Norbert Nemec (norb...@nemec-online.de)'s article > >> In language design, the theoretical halting problem actually is often an > >> argument because the compiler does not know the memory limitation at run > >> time. The finite memory of the machine can therefore not be used to > >> reason about a piece of code. For the purpose of the compiler, the > >> machine has to be assumed to have arbitrarily much (i.e. infinite) memory. > > I don't know people in language design, but I suspect they know their stuff > > and I > > would be surprised to hear that they would think of the theoretical Halting > > problem where the practical halting problem as an argument would suffice. > > Programs > > generally can't index an infinite amount of memory. > > Why would they use an argument which rests on an abstract system where they > > could > > just as easily use an argument based on an actual system. > Basically: because 1GB=infinity for all purposes of logical reasoning. No no no! :D If you'd left out logical it would have been just fine :D I'm not even going to give ridiculous logical proof with this assumption.. no I will not.. .. assume inf is 1GB.. No! .. > > Anyway, I made this thread because in uni I got the Halting problem > > explained in > > totally the wrong context and would like other people not to make the same > > wrong > > first step. > I know that situation very well: having the big Aha-effect after years > of misunderstanding calls for telling people about it. Actually, I find > it quite interesting to discuss this kind of issues once in a while.
Re: [Theory] Halting problem
On 10/10/10 19:36, %u wrote: == Quote from Norbert Nemec (norb...@nemec-online.de)'s article In language design, the theoretical halting problem actually is often an argument because the compiler does not know the memory limitation at run time. The finite memory of the machine can therefore not be used to reason about a piece of code. For the purpose of the compiler, the machine has to be assumed to have arbitrarily much (i.e. infinite) memory. I don't know people in language design, but I suspect they know their stuff and I would be surprised to hear that they would think of the theoretical Halting problem where the practical halting problem as an argument would suffice. Programs generally can't index an infinite amount of memory. Why would they use an argument which rests on an abstract system where they could just as easily use an argument based on an actual system. Basically: because 1GB=infinity for all purposes of logical reasoning. Anyway, I made this thread because in uni I got the Halting problem explained in totally the wrong context and would like other people not to make the same wrong first step. I know that situation very well: having the big Aha-effect after years of misunderstanding calls for telling people about it. Actually, I find it quite interesting to discuss this kind of issues once in a while.
Schrödinger's Stride
Currently the contents of Stride depend on from which end we look at it: auto m = [1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4]; // 3 rows, 4 columns auto col = stride(m, 4); assert(equal(col, [1, 1, 1])); assert(equal(retro(col), [4, 4, 4])); Is the quantum behavior intended? -- Tomek
Re: ; not required after pragma
Simen kjaeraas napisał: > Tomek Sowiński wrote: > >> pragma(msg, "blabla") >> >> bug or feature? > > Feature. http://www.digitalmars.com/d/2.0/pragma.html: > > "Pragmas can be used by themselves terminated with a ';', they can > influence a statement, a block of statements, a declaration, or a block > of declarations." > > E.g. pragma( blah, blablableh ) struct foo {}; might mean something, > and in this case the pragma would modify foo. Heh, should've DAFS, thanks. It's still baffling a bit - what can pragma(msg) possibly influence? Perhaps there should be a division - influencing vs. statement flavor. The compiler could disallow usage not lying in a particular pragma's nature. -- Tomek
Re: [Theory] Halting problem
== Quote from Norbert Nemec (norb...@nemec-online.de)'s article > On 10/10/10 17:06, %u wrote: > > I am not sure where exactly the line lies where people tend to use > > impossible as a > > synonym for a hard problem, but I agree that np might well be around that > > border. > > It depends on "trivial", but I wouldn't call integer factorization > > impossible. > > > > The point I was trying to make was that using "impossible" to denote the > > practical > > halting problem is very confusing as the theoretical Halting problem is > > truly > > impossible. > > Confusing, as the proof at first sight seems to hold on memory limited > > systems as > > well. > I think, the essence here is the "limited memory" issue. A turing > machine has infinite memory available, but a program that finished in > finite time will always have used only a finite amount of memory. The > halting problem is to determine if a program written down as a finite > piece of code will finish in finite time and memory or not. This is correct. > In language design, the theoretical halting problem actually is often an > argument because the compiler does not know the memory limitation at run > time. The finite memory of the machine can therefore not be used to > reason about a piece of code. For the purpose of the compiler, the > machine has to be assumed to have arbitrarily much (i.e. infinite) memory. I don't know people in language design, but I suspect they know their stuff and I would be surprised to hear that they would think of the theoretical Halting problem where the practical halting problem as an argument would suffice. Programs generally can't index an infinite amount of memory. Why would they use an argument which rests on an abstract system where they could just as easily use an argument based on an actual system. Anyway, I made this thread because in uni I got the Halting problem explained in totally the wrong context and would like other people not to make the same wrong first step.
Re: ; not required after pragma
Tomek Sowiński wrote: pragma(msg, "blabla") bug or feature? Feature. http://www.digitalmars.com/d/2.0/pragma.html: "Pragmas can be used by themselves terminated with a ';', they can influence a statement, a block of statements, a declaration, or a block of declarations." E.g. pragma( blah, blablableh ) struct foo {}; might mean something, and in this case the pragma would modify foo. -- Simen
; not required after pragma
pragma(msg, "blabla") bug or feature? -- Tomek
Re: [Theory] Halting problem
On 10/10/10 17:06, %u wrote: I am not sure where exactly the line lies where people tend to use impossible as a synonym for a hard problem, but I agree that np might well be around that border. It depends on "trivial", but I wouldn't call integer factorization impossible. The point I was trying to make was that using "impossible" to denote the practical halting problem is very confusing as the theoretical Halting problem is truly impossible. Confusing, as the proof at first sight seems to hold on memory limited systems as well. I think, the essence here is the "limited memory" issue. A turing machine has infinite memory available, but a program that finished in finite time will always have used only a finite amount of memory. The halting problem is to determine if a program written down as a finite piece of code will finish in finite time and finite memory or not. In language design, the theoretical halting problem actually is often an argument because the compiler does not know the memory limitation at run time. The finite memory of the machine can therefore not be used to reason about a piece of code. For the purpose of the compiler, the machine has to be assumed to have arbitrarily much (i.e. infinite) memory.
Re: Tuple literal syntax
Andrei: > Tuples with named fields are restricted in a number of ways compared to > structs. They are expandable, they have indexed fields, they offer no > encapsulation, etc. Lambda structs would be rather unwieldy. I > personally am fine with tuples. Now the discussion is developing in a slower and more relaxed way. Have Walter and you reached some partial conclusion on this subject? I am not asking for the final words on this topic, because I probably few further discussions will be needed, but other people and I have already expressed several opinions and ideas. I think that multiple return values and a nice clean packing & unpacking syntax for tuples may be useful for D (especially if it can be used for unpacking in foreach and function signatures too). And It's just syntax sugar, yet I think a good syntax sugar for this is able to change the taste of the D language, because if it's good and efficient, it will probably be used very often, in normal Python code it's not hard to find one or more tuples every 3-8 lines of code, a normal Python module may contain a fifty tuple literals (often just as "return x, y"). Bye, bearophile
Re: [Theory] Halting problem
I am not sure where exactly the line lies where people tend to use impossible as a synonym for a hard problem, but I agree that np might well be around that border. It depends on "trivial", but I wouldn't call integer factorization impossible. The point I was trying to make was that using "impossible" to denote the practical halting problem is very confusing as the theoretical Halting problem is truly impossible. Confusing, as the proof at first sight seems to hold on memory limited systems as well. == Quote from Norbert Nemec (norb...@nemec-online.de)'s article > "Impossible to solve" is often used synonymous to "exponentially hard to > solve" meaning, as the problem size (e.g. size of finite memory) grows > as N, the cost for solution grows as exp(N). Of course, the actual cost > of an actual problem always depends on the pre-factor, but experience > shows that exponentially hard problems are typically only solvable for > trivially small problems. > On 09/10/10 21:59, %u wrote: > > == Quote from Simen kjaeraas (simen.kja...@gmail.com)'s article > >> %u wrote: > >>> Just to be clear about this, the halting problem is only unsolvable for > >>> Turing > >>> machines. > >>> That is, a machine with a tape that extends or is indefinitely > >>> extensible to > >>> the right.[wikipedia:Turing machine] > >> > >> Of course. However, for non-trivial programs it is hard enough that we > >> may consider it impossible. > > > > This may be, but too often I see the theoretical(truly impossible) problem > > mentioned when the practical Halting problem is applicable. > > Especially people asking about the Halting problem should not be thrown off > > by > > saying that the theoretical Halting problem is why a problem can't be > > implemented. > > Why, for instance, doesn't Stewart Gordon's proof not apply for finite > > memory > > programs? > > > > > > > > > >
Re: Tuple literal syntax
On 10/10/10 9:00 CDT, Denis Koroskin wrote: On Sun, 10 Oct 2010 17:39:52 +0400, Stephan Soller wrote: On 07.10.2010 17:36, Andrei Alexandrescu wrote: On 10/7/10 10:13 CDT, Kagamin wrote: Andrei Alexandrescu Wrote: struct Coord { int x, y, z; } one iota typesafer than alias Tuple!(int, "x", int, "y", int, "z") Coord; Is there a real need for an alternative way to declare structs? Yes. Andrei I agree but I also don't agree. I like the possibility to return multiple values (quite handy in Ruby, PHP and other languages) and therefore we need language constructs to group multiple values and ungroup them again. However as soon as these fields are named it looks to me like an ordinary structure. So why not just create something like an "anonymous structure literal" that behaves to structures like anonymous functions (or delegates) to functions? This would look a lot more consistent to me than playing around with different kinds of tuples. However I'm not sure about the details (e.g. how would such structures handle type or alias contents). Happy programming Stephan Exactly. To be honest, I see absolutely no reason to have yet another to declare structs, but some people have other preferences. I don't mind having Tuple in a library, as long as I'm not insisted in using it *and* it doesn't affect other language features. I mean, it's not even shorter to write alias Tuple!(int, "x", int, "y", int, "z") Coord; than struct Coord { int x; int y; int z; } Tuples with named fields are restricted in a number of ways compared to structs. They are expandable, they have indexed fields, they offer no encapsulation, etc. Lambda structs would be rather unwieldy. I personally am fine with tuples. Andrei
Re: Tuple literal syntax
bearophile wrote: Simen kjaeraas: Perhaps it would be possible to augment struct static initializers for this purpose? { int a; string b } foo( ) { return { 1, "text" }; } What kind of tuple unpacking syntax do you suggest for this? (I think at the moment the unpacking syntax is more important than the literals one). int a; string b; { a, b } = foo( ); string s = "123456" char c; { c, s... } = s; I guess. -- Simen
Re: Tuple literal syntax
On Sun, 10 Oct 2010 18:33:35 +0400, bearophile wrote: Denis Koroskin: I don't mind having Tuple in a library, as long as I'm not insisted in using it *and* it doesn't affect other language features. More modern module-based languages as D are not like C. If they want some success they develop a community of programmers that share modules. You don't program in a vacuum any more. This means that if Tuple is appreciated and used by the community, then you will often use modules (including frequently stuff from Phobos2) written by other people that expect tuples as input values or that return tuples as outputs and so on. So if tuples have success, you will probably need to use them in your code too, they become an idiom of the language almost as they are built-ins, this is also why it's better to give them a good syntax. Multiple return values have the disadvantage that sometimes your don't exactly remember what each value is, but they are handy, and overall they are an improvement over C-style single return values. In a recent post I've shown why they may also help avoid some bugs compared to "out" arguments. Bye, bearophile I was referring *only* to Tuple!(int, "foo", float, "bar") syntax. I'd love having proper tuples (Python-style or similar) support in D, and use it to the maximum. But Tuple!? Meh.
Re: Tuple literal syntax
Simen kjaeraas: > Perhaps it would be possible to augment struct static initializers for > this purpose? > > { int a; string b } foo( ) { > return { 1, "text" }; > } What kind of tuple unpacking syntax do you suggest for this? (I think at the moment the unpacking syntax is more important than the literals one). Bye, bearophile
Re: Tuple literal syntax
Denis Koroskin: > I don't mind having Tuple in a library, as long as I'm not insisted in > using it *and* it doesn't affect other language features. More modern module-based languages as D are not like C. If they want some success they develop a community of programmers that share modules. You don't program in a vacuum any more. This means that if Tuple is appreciated and used by the community, then you will often use modules (including frequently stuff from Phobos2) written by other people that expect tuples as input values or that return tuples as outputs and so on. So if tuples have success, you will probably need to use them in your code too, they become an idiom of the language almost as they are built-ins, this is also why it's better to give them a good syntax. Multiple return values have the disadvantage that sometimes your don't exactly remember what each value is, but they are handy, and overall they are an improvement over C-style single return values. In a recent post I've shown why they may also help avoid some bugs compared to "out" arguments. Bye, bearophile
Re: Tuple literal syntax
Stephan Soller wrote: However as soon as these fields are named it looks to me like an ordinary structure. So why not just create something like an "anonymous structure literal" that behaves to structures like anonymous functions (or delegates) to functions? Perhaps it would be possible to augment struct static initializers for this purpose? { int a; string b } foo( ) { return { 1, "text" }; } I'm not sure if there are problems with this syntax (it sorta looks like a delegate, for one), so elucidation would be welcome. -- Simen
Re: Tuple literal syntax
On Sun, 10 Oct 2010 17:39:52 +0400, Stephan Soller wrote: On 07.10.2010 17:36, Andrei Alexandrescu wrote: On 10/7/10 10:13 CDT, Kagamin wrote: Andrei Alexandrescu Wrote: struct Coord { int x, y, z; } one iota typesafer than alias Tuple!(int, "x", int, "y", int, "z") Coord; Is there a real need for an alternative way to declare structs? Yes. Andrei I agree but I also don't agree. I like the possibility to return multiple values (quite handy in Ruby, PHP and other languages) and therefore we need language constructs to group multiple values and ungroup them again. However as soon as these fields are named it looks to me like an ordinary structure. So why not just create something like an "anonymous structure literal" that behaves to structures like anonymous functions (or delegates) to functions? This would look a lot more consistent to me than playing around with different kinds of tuples. However I'm not sure about the details (e.g. how would such structures handle type or alias contents). Happy programming Stephan Exactly. To be honest, I see absolutely no reason to have yet another to declare structs, but some people have other preferences. I don't mind having Tuple in a library, as long as I'm not insisted in using it *and* it doesn't affect other language features. I mean, it's not even shorter to write alias Tuple!(int, "x", int, "y", int, "z") Coord; than struct Coord { int x; int y; int z; }
Re: Tuple literal syntax
On 07.10.2010 17:36, Andrei Alexandrescu wrote: On 10/7/10 10:13 CDT, Kagamin wrote: Andrei Alexandrescu Wrote: struct Coord { int x, y, z; } one iota typesafer than alias Tuple!(int, "x", int, "y", int, "z") Coord; Is there a real need for an alternative way to declare structs? Yes. Andrei I agree but I also don't agree. I like the possibility to return multiple values (quite handy in Ruby, PHP and other languages) and therefore we need language constructs to group multiple values and ungroup them again. However as soon as these fields are named it looks to me like an ordinary structure. So why not just create something like an "anonymous structure literal" that behaves to structures like anonymous functions (or delegates) to functions? This would look a lot more consistent to me than playing around with different kinds of tuples. However I'm not sure about the details (e.g. how would such structures handle type or alias contents). Happy programming Stephan
[theory] What is a type?
Specifically I have a problem in trying to implement a functional language translator in D. My target language has a rather non-conventional type system, in which, superficially at least, types can be described as being Cartesian in nature. That is, types in this system have two orthogonal dimensions: (1) classical data-type (e.g. boolean, number, string, object) and (2) Kleene cardinality (occurrences) with respect to (1). The axial origin of this Cartesian type-system correlates well with the concept of the "top" type (AKA "Unit" in Scala) and as the rather adhoc "void" type in many Algol-derived languages such as C/C++/Java/D. So along axis 1 we might broadly describe the classical data types as item, boolean, number, string, object where item is effectively either a superclass or variant of the other mentioned types. Along axis 2 we describe Kleene occurrences of 1 as may be passed contractually to a receiving function. These occurrences may be enumerated six-fold as: zeroOrMore zeroOrOne oneOrMore exactlyZero exactlyOne none Readers may see that, for example, zeroOrOne is a special case (perhaps a subclass?) of zeroOrMore. exactlyOne is a special case of both zeroOrOne and oneOrMore (sounds like multiple inheritance?). OTOH, exactlyZero is a special case of zeroOrOne, which, in turn, is a special case of zeroOrmore. none is a special case of all of the above and reflects the cardinality facet of the return type of a function that never returns (say as by throwing an exception). To make this type system even more enigmatic lets add a third dimension, taking the 2-D Cartesian type system model to a 3-D Spatial model, by imagining a further degree of freedom with respect to laziness of evaluation (AKA closure of arguments). Now having hopefully described that a type is something that might well have multiple orthogonal aspects to its identity, how would one go about implementing a dynamic language with such a complex type system in D? I realize that this is a complex topic and that it might require better articulation than so far I have given. Nevertheless, thanks for all replies, Justin Johansson
Re: ParserCobinator like scala in D
> Template Library: http://ideone.com/3rKF4 > ParserCombinator: http://ideone.com/YlGP2 > PEGParser: http://ideone.com/vkTyh > Sample(Expression of four arithmetic operations): http://ideone.com/0uc3t > > What do you think about this? The code looks clean enough. I suggest to use 4 spaces as indent (or a single tab). You may rewrite tuple.field[1] as tuple[1] An alias char[] str; may shorten some signatures a bit. See also Pymeta, an implementation of OMeta: http://washort.twistedmatrix.com/ Bye, bearophile
Re: Minor site suggestion regarding NG and bugs
On 10/10/2010 12:32 PM, Nick Sabalausky wrote: On whatever page(s) on digitalmars.com or d-programming-language.com refer to the newsgroups, there should probably be a note (with a link) indicating that bug reports should be posted to bug tracker rather than the NG. And also that "digitalmars.D.bugs" is just a mirror for the issues on the tracker and that posts shouldn't be made dirctly there. We're confusing a lot of people because of that. Yes, confirm I am confused also.
Re: [Theory] Halting problem
On 10/10/2010 8:07 PM, Norbert Nemec wrote: "Impossible to solve" is often used synonymous to "exponentially hard to solve" meaning, as the problem size (e.g. size of finite memory) grows as N, the cost for solution grows as exp(N). Of course, the actual cost of an actual problem always depends on the pre-factor, but experience shows that exponentially hard problems are typically only solvable for trivially small problems. That's a fair observation. Cheers Justin Johansson
Re: Why all the D hate?
On 10/10/2010 5:24 PM, Juanjo Alvarez wrote: On Sun, 10 Oct 2010 13:04:57 +0900, Jordi wrote: Sorry, shameful mistake with my shell script skills. It is 50K lines :| Mine is 4000 lines, having started to learn D from Andrei's book three weeks ago. D is not perfect but for me is perfect enough and will no doubt be my favorite general purpose language once we have and stable version. Hang in there guys; I am hopeful too despite the fact that I often post as Devil's Advocate for the negative. Cheers Justin Johansson
Re: [Theory] Halting problem
"Impossible to solve" is often used synonymous to "exponentially hard to solve" meaning, as the problem size (e.g. size of finite memory) grows as N, the cost for solution grows as exp(N). Of course, the actual cost of an actual problem always depends on the pre-factor, but experience shows that exponentially hard problems are typically only solvable for trivially small problems. On 09/10/10 21:59, %u wrote: == Quote from Simen kjaeraas (simen.kja...@gmail.com)'s article %u wrote: Just to be clear about this, the halting problem is only unsolvable for Turing machines. That is, a machine with a tape that extends or is indefinitely extensible to the right.[wikipedia:Turing machine] Of course. However, for non-trivial programs it is hard enough that we may consider it impossible. This may be, but too often I see the theoretical(truly impossible) problem mentioned when the practical Halting problem is applicable. Especially people asking about the Halting problem should not be thrown off by saying that the theoretical Halting problem is why a problem can't be implemented. Why, for instance, doesn't Stewart Gordon's proof not apply for finite memory programs?
Re: CMake for D2 ready for testers
On Sat, 9 Oct 2010 16:48:15 +0200 >> "Gour" == "Gour D." wrote: Gour> Rationale? I forgot to add: x) deps are determined by hash and not by timestamps Sincerely, Gour -- Gour | Hlapicina, Croatia | GPG key: CDBF17CA signature.asc Description: PGP signature
Re: Is D right for me?
On Sun, 10 Oct 2010 00:46:47 -0700 >> "Jonathan" == Jonathan M Davis wrote: Jonathan> Yes, a lack of positive feedback can be frustrating even if Jonathan> you have the best code ever. And as much as the developers of Jonathan> QtD likely want to use it for their own stuff, it's likely Jonathan> not worth doing it just for themselves. It's just too much Jonathan> work. Well, I tried to do my little 'homework'...wrote to the QtD devs explaining them that their project is essential to adopting D for our project. Moreover, informed them that only for the sake of trying QtD I've created 32bit chroot on my machine(64bit dmd, do you hear me?) and got some help on #qtd in order to build "hello world" (instructions at http://www.dsource.org/projects/qtd/wiki/BuildLinux are now up-to-date). Lastly, I told devs that despite of current status of QtD, we have decided to 'gamble' and will use D/QtD for our project. The next step is to order Andrei's book, start learning the language, experiment with non-GUI stuff and try to help (in any way) to push QtD further. Jonathan> QtD is a huge service to the D community. Indeed! Coming from Haskell community where all the GUI libs (bindings) are in hands of just few devs, I sincerely hope that users of D will recognize importance of QtD for the success of language itself and help the project to become complete and fully usable asap. Sincerely, Gour -- Gour | Hlapicina, Croatia | GPG key: CDBF17CA signature.asc Description: PGP signature
Re: Is D right for me?
On Saturday 09 October 2010 12:44:37 Walter Bright wrote: > Gour D. wrote: > > Walter> Few things work better than customers letting a company know > > Walter> they are interested in such-and-such a product. > > Even a non-paying customer in the open-source world? > > At least it shows interest. No emails tells the open source developer > "nobody cares, so I'll just abandon it". Yes, a lack of positive feedback can be frustrating even if you have the best code ever. And as much as the developers of QtD likely want to use it for their own stuff, it's likely not worth doing it just for themselves. It's just too much work. Of course, projects like QtD suffer from the same sort of problem as a compiler does in that it's not necessarily very useful until it's complete. Lots of people may be interested in using QtD, but if it's not at least close to done, it's not going to be useable enough to use in any major project, so people won't use, they won't report bugs on it, and the won't give any kind of feedback on the project. So, the poor QtD people then have to get a _lot_ of code done before they see any kind of positive feedback from the community, and when they _do_ start getting feedback, much of it is likely to be negative because feature X hasn't been implemented yet or feature Y is buggy. A lot of people have given up on D for similar reasons. Hopefully enough of the problems that they were having with dmd get fixed soon enough that they're able to actually continue working on the project without getting too frustrated over it. QtD is a huge service to the D community. - Jonathan M Davis
Re: Uniform Function Call syntax for properties
On Sun, 10 Oct 2010 00:58:39 -0400, Denis Koroskin <2kor...@gmail.com> wrote: On Sun, 10 Oct 2010 08:44:59 +0400, Robert Jacques wrote: On Sat, 09 Oct 2010 22:03:56 -0400, Denis Koroskin <2kor...@gmail.com> wrote: On Sun, 10 Oct 2010 05:58:00 +0400, Robert Jacques wrote: On Sat, 09 Oct 2010 16:28:32 -0400, Denis Koroskin <2kor...@gmail.com> wrote: On Sun, 10 Oct 2010 00:09:23 +0400, Sean Kelly wrote: Andrei Alexandrescu wrote: On 10/8/10 7:55 CDT, Steven Schveighoffer wrote: Someone was asking about UFC syntax for properties on d.learn, and I realized, we have a huge ambiguity here. Given a function: @property int foo(int x) Is this a global setter or a getter on an int? Good question. Setter. Consider "a = b = c". I think you missed the point. Which of the two is it: int x = 42; auto y = x.foo(); // transformed into "auto y = foo(x);", getter or foo = 42; // transformed into "foo(42);", setter Both match. I agree that there is ambiguity here, but does it why does foo have to be only a getter or only a setter? Why can't it behave like either, depending on its implementation and use? Because you may want to have both, but you can't because their syntax overlap. Okay I'm confused. How do their syntax overlap? And which syntaxes do you think are overlapping? All the following 'lowerings' look fine/unambiguous to me: foo = 42; => foo(42); y = x.foo; => y = x.foo(); => y = foo(x); foo = foo = x.foo; => foo = foo = x.foo(); => foo = foo = foo(x); => foo = foo(foo(x)); => foo(foo(foo(x))); I wasn't talking about ambiguity. I told that you can't assign different behavior to foo = 42; and y = x.foo; Both are resolving to the same symbol. E.g. I'd like to write a setter, "foo = 42;": private int _foo; int foo(int x) { debug writeln("foo = ", x); _foo = x; return x; } But the following code also triggers the setter above: y = 42.foo(); // prints "foo = 42;", sets private variable _foo to 42, and returns that value That's completely unexpected. Actually, that's completely expected, in my humble opinion. Yes, it will be a bit confusing to people new to D, perhaps even to those familiar with C#'s extension methods. But once one understands the power and freedom of UFC, that behavior is perfectly natural. Imagine yourself writing class Foo with method bar, and a user who highjacks a hole in the language, creates class bar, and invokes method Foo on it. That's what it looks like at this moment. Well, hijacking won't be possible since D's got really good function hijacking detection. Also, how can Foo be both a method and a class?