digitalmars.D - D as a prototyping language (for C/C++ projects)
- Craig Dillabaugh (21/21) Feb 26 2013 I am a novice D programmer and use C++ in my work. One thing I
- dennis luehring (5/10) Feb 26 2013 i don't get it
- Namespace (8/19) Feb 26 2013 I do it as well.
- monarch_dodra (16/27) Feb 26 2013 It's not about using special features. As a matter of fact, I'd
- Craig Dillabaugh (19/30) Feb 26 2013 I should qualify that a bit. I don't avoid D features altogether,
- bearophile (11/17) Feb 26 2013 I often write the code in D (sometimes I start from Python and
- Craig Dillabaugh (19/36) Feb 26 2013 One of the reasons I like D for this kind of work is that as a
- renoX (5/11) Feb 26 2013 I'm curious: is this process still useful with C++11?
- Craig Dillabaugh (4/15) Feb 26 2013 Again since my work is heavily array based probably, I would
- monarch_dodra (7/35) Feb 26 2013 Have you tried it?
- MattCodr (4/5) Feb 26 2013 I usually do this, but in a little different way. I wrote my code
- Andrei Alexandrescu (4/9) Feb 26 2013 These are great data points. We should figure how to improve D to lessen...
- bearophile (6/8) Feb 26 2013 Regarding the D => C conversions I write, time ago I have
- Jacob Carlborg (9/11) Feb 26 2013 It helps by having convenient functions in the standard library. It also...
- H. S. Teoh (6/18) Feb 26 2013 [...]
- Jacob Carlborg (40/41) Feb 26 2013 Return the date from two days ago:
- Ary Borenszweig (4/17) Feb 26 2013 And also having to import std.algorithm. In Ruby you can do map, sort
- simendsjo (8/33) Feb 26 2013 I often find myself importing std.algorithm, std.array and
- Jacob Carlborg (4/7) Feb 27 2013 Often you need std.range and std.array as well.
- Andrei Alexandrescu (3/10) Feb 26 2013 The last two return the time right now, how come?
- Jacob Carlborg (5/6) Feb 27 2013 They're supposed to. I just accidentally put them below "Return the date...
- Jacob Carlborg (7/8) Feb 26 2013 Some more:
- Paulo Pinto (2/12) Feb 27 2013 REPL?
- Andrei Alexandrescu (4/18) Feb 27 2013 Good idea. Should be in bugzilla as an enh, although it'll take a while
- Zach the Mystic (4/27) Feb 27 2013 D would be one step closer to actually passing the "BOTCH" test!
- Jacob Carlborg (5/7) Feb 27 2013 I wonder how good the implementation will be if one just pass the line
- timotheecour (10/16) Feb 27 2013 I'm assuming you're talking about REPL. That won't cut it, as one
- Andrei Alexandrescu (4/9) Feb 27 2013 Try it, rdmd has --eval and --loop. It's useful but not as good as a
- Jacob Carlborg (4/6) Feb 27 2013 I'll give that a try, thanks.
- Joseph Rushton Wakeling (12/17) Feb 26 2013 I have to say that these days (also as someone who programs for scientif...
- H. S. Teoh (45/101) Feb 26 2013 I find the Phobos version more readable, actually. Writing "2.days.ago"
- Walter Bright (2/10) Feb 26 2013 This is a subtle but very important point.
- Jacob Carlborg (6/7) Feb 27 2013 It's not about adding the inverse of an already existing function. It's
- Jacob Carlborg (19/52) Feb 27 2013 I don't agree. BTW, the whole point of having programming languages is
- H. S. Teoh (29/90) Feb 27 2013 OK, then let's agree to disagree. I see that there's no point in arguing
- Jacob Carlborg (31/47) Feb 27 2013 That's the problem. Then we will have a language with a slightly
- H. S. Teoh (29/85) Feb 27 2013 Well, given that we have UFCS now, maybe we *do* want to standardize on
- Jacob Carlborg (15/32) Feb 27 2013 Allow structs to be passed as well. Although they need to be passed by
- Ary Borenszweig (10/32) Feb 27 2013 Tap is nice when you want to print-debug something and you have a chain
- Andrei Alexandrescu (3/12) Feb 27 2013 I like Tap (including the name). It is similar to Unix's "tee" utility.
- Jacob Carlborg (4/5) Feb 28 2013 Cool, is this something that could be included in Phobos? If yes, where?
- Andrei Alexandrescu (10/13) Feb 28 2013 I think it belongs to std.range.
- Jacob Carlborg (9/17) Feb 28 2013 That is not my idea of "tap". This is my idea of "tap":
- Andrei Alexandrescu (3/20) Feb 28 2013 I know. I think my tap is better than your tap.
- Andrei Alexandrescu (5/27) Feb 28 2013 ... and closer in intent to Ruby's tap as I understand it from reading
- David Nadlinger (6/19) Feb 28 2013 Ruby's tap just applies the passed block to the object it is
- Andrei Alexandrescu (28/48) Feb 28 2013 Oh, I misunderstood the example at
- Jacob Carlborg (4/8) Feb 28 2013 What about a function allowing both?
- Timon Gehr (4/11) Mar 02 2013 I'm not sure who would.
- Rob T (10/18) Feb 27 2013 I agree.
- Jacob Carlborg (13/19) Feb 27 2013 As I said to H.S. Teoh, the question is not about adding the inverse of
- Ary Borenszweig (4/10) Feb 27 2013 Then why not remove the binary "-" from D. You can always do:
- Daniel Murphy (3/6) Mar 01 2013 Compatibility with C.
- Rob T (12/17) Feb 27 2013 On Wednesday, 27 February 2013 at 13:02:02 UTC, Jacob Carlborg
- H. S. Teoh (16/34) Feb 27 2013 This is interesting. I have also been collecting a bunch of stuff that I
- Jacob Carlborg (8/15) Feb 27 2013 That's a good idea. This is my library:
- Rob T (14/17) Feb 27 2013 I had a look at your isBlank function. Why not check if length
- Jacob Carlborg (6/17) Feb 28 2013 Sure, I could do that. But I thought checking for "empty" would be more
- deadalnix (3/24) Feb 28 2013 It is easy to ensure via UFCS.
- Jonathan M Davis (9/32) Feb 28 2013 All ranges are guaranteed to have empty, so any range with length will
- Rob T (9/16) Feb 27 2013 I also found that my D version of my std.me lib is a lot smaller
- Rob T (5/11) Feb 27 2013 Once we get ability to add user comments to Phobos documentation,
- Jacob Carlborg (4/20) Feb 27 2013 Ok, then my apologize.
- Rob T (12/38) Feb 26 2013 I can understand why you are doing this. C++ code tends to be
- monarch_dodra (8/12) Feb 27 2013 Funny story, I'm doing it the other way around.
- Rob T (10/23) Feb 27 2013 I understand why your are doing this, but it must be a ton of
- simendsjo (9/15) Feb 27 2013 (...)
- Namespace (5/11) Feb 27 2013 As we said: D isn't mature enough.
I am a novice D programmer and use C++ in my work. One thing I find myself doing when I need to implement some non-trivial algorithm is that I will originally code it in D and perform testing from there to make sure I have the logic right. Once I have everything working in D I simply port it over to C++. In my experience this porting is very trivial (it probably helps there that I write D like a C++ programmer). While I don't have hard evidence I think that the 'porting' effort to C++ is more than offset by the productivity gains I achieve fighting with C++ syntax while trying to get the logic right. Most of the porting effort is simply copying and pasting the D code into my C++ source files and adding headers, replacing imports with includes, etc. Usually significant portions of the code compile without any changes. I was curious to know if anyone else uses D like this. If so this might be a good way to try and get D into some C++ shops. The nice thing about D in my opinion is that even for people without D experience, if they have C++ experience they can likely 'read' D code without much trouble (of course some features might not map over so well - but the languages are syntactically very close).
Feb 26 2013
Am 26.02.2013 16:26, schrieb Craig Dillabaugh:I am a novice D programmer and use C++ in my work. One thing I find myself doing when I need to implement some non-trivial algorithm is that I will originally code it in D and perform testing from there to make sure I have the logic right. Once I have everything working in D I simply port it over to C++.i don't get it you are an novice D programmer and your programs are easy to convert back to C++ so you'r not using too much D specials whats the point of doing it like this?
Feb 26 2013
On Tuesday, 26 February 2013 at 15:43:42 UTC, dennis luehring wrote:Am 26.02.2013 16:26, schrieb Craig Dillabaugh:I do it as well. In D you can write code (mostly) much faster. However, I would not attempt to implement larger projects (more) in D, because D is simply not mature enough and lacks too much. So after writing and testing in D, I port my program/code then in C++ and complete it.I am a novice D programmer and use C++ in my work. One thing I find myself doing when I need to implement some non-trivial algorithm is that I will originally code it in D and perform testing from there to make sure I have the logic right. Once I have everything working in D I simply port it over to C++.i don't get it you are an novice D programmer and your programs are easy to convert back to C++ so you'r not using too much D specials whats the point of doing it like this?
Feb 26 2013
On Tuesday, 26 February 2013 at 15:43:42 UTC, dennis luehring wrote:Am 26.02.2013 16:26, schrieb Craig Dillabaugh:It's not about using special features. As a matter of fact, I'd think he'd purposefully stay away from special features. The point is that he *develop* the program in D in half the time it would have taken him in C++. Given this productivity gain, he can mess and improve his program much faster and with more quality than he could have in C++. Once his D program is stable and the outline/flow is clearer to him, and he knows what he wants to do, he only has to convert to C++, which can be done very fast. I do this too. It is *very* helpful when you don't know *where* you are going when you start. I'd stick to D all the way, but as namespace said, D may not be mature enough, or stable enough, or just allowed as a final language in the workplace :/I am a novice D programmer and use C++ in my work. One thing I find myself doing when I need to implement some non-trivial algorithm is that I will originally code it in D and perform testing from there to make sure I have the logic right. Once I have everything working in D I simply port it over to C++.i don't get it you are an novice D programmer and your programs are easy to convert back to C++ so you'r not using too much D specials whats the point of doing it like this?
Feb 26 2013
On Tuesday, 26 February 2013 at 15:43:42 UTC, dennis luehring wrote:Am 26.02.2013 16:26, schrieb Craig Dillabaugh:I should qualify that a bit. I don't avoid D features altogether, but I don't necessarily use many of the advanced features (eg. mixins) that might have no equivalent in C++. I work in scientific computing so I do much of my work with arrays. Working with D arrays is much, much nicer than in C++. So I save lots of time getting my algorithm working/tested. Then the porting is pretty simple, because while slices for example are not supported in C++ you can handle the same logic in C++ without too much trouble. However, the C++ code is uglier and not having to deal with that ugliness lets me focus my mental effort on the details of my algorithm. This lets me implement it correctly more quickly. Using D associative arrays vs C++ std.map is another example. Now, I would never suggest using D to prototype a full application or anything like that, but at least for the type of work I tend to do I find that using D lets me focus on my 'algorithm' without fight with awkward syntax.I am a novice D programmer and use C++ in my work. One thing I find myself doing when I need to implement some non-trivial algorithm is that I will originally code it in D and perform testing from there to make sure I have the logic right. Once I have everything working in D I simply port it over to C++.i don't get it you are an novice D programmer and your programs are easy to convert back to C++ so you'r not using too much D specials whats the point of doing it like this?
Feb 26 2013
Craig Dillabaugh:I am a novice D programmer and use C++ in my work. One thing I find myself doing when I need to implement some non-trivial algorithm is that I will originally code it in D and perform testing from there to make sure I have the logic right. Once I have everything working in D I simply port it over to C++.I often write the code in D (sometimes I start from Python and then I convert it to D), get it right, write down more tests, then I slowly lower the level of the D code keeping it correct with help of the tests, and then convert it to C. When the code is quite complex, if I do this I waste some time, but it's a known amount of time, while if I follow a more direct route, writing the C code directly, I can't tell how much debugging time I will need. Bye, bearophile
Feb 26 2013
On Tuesday, 26 February 2013 at 16:15:49 UTC, bearophile wrote:Craig Dillabaugh:One of the reasons I like D for this kind of work is that as a multi-paradigm language it lets you do stuff in a style closer what your final C++ code will look like. My research is in satellite image processing, so most of my work involves reading in imagery into 2D arrays and performing processing over all/or part of an image. I find being able to write code like: for(int i =0; i < rows; i++) { for(int j = 0; j < cols; j++) { } } Sometimes is the easiest way to perform certain tasks. D lets you do this and the syntax is exactly the same a C/C++ - Python? I don't know - but I imagine it would be tricker to port to C++! I have found, at least in this particular problem domain, that the C++/D style syntax is about as good as it gets.I am a novice D programmer and use C++ in my work. One thing I find myself doing when I need to implement some non-trivial algorithm is that I will originally code it in D and perform testing from there to make sure I have the logic right. Once I have everything working in D I simply port it over to C++.I often write the code in D (sometimes I start from Python and then I convert it to D), get it right, write down more tests, then I slowly lower the level of the D code keeping it correct with help of the tests, and then convert it to C. When the code is quite complex, if I do this I waste some time, but it's a known amount of time, while if I follow a more direct route, writing the C code directly, I can't tell how much debugging time I will need. Bye, bearophile
Feb 26 2013
On Tuesday, 26 February 2013 at 15:26:17 UTC, Craig Dillabaugh wrote:I am a novice D programmer and use C++ in my work. One thing I find myself doing when I need to implement some non-trivial algorithm is that I will originally code it in D and perform testing from there to make sure I have the logic right. Once I have everything working in D I simply port it over to C++.I'm curious: is this process still useful with C++11? BR, renoX
Feb 26 2013
On Tuesday, 26 February 2013 at 16:34:01 UTC, renoX wrote:On Tuesday, 26 February 2013 at 15:26:17 UTC, Craig Dillabaugh wrote:Again since my work is heavily array based probably, I would guess so, but perhaps not quite so much. How long though until C++11 is broadly available?I am a novice D programmer and use C++ in my work. One thing I find myself doing when I need to implement some non-trivial algorithm is that I will originally code it in D and perform testing from there to make sure I have the logic right. Once I have everything working in D I simply port it over to C++.I'm curious: is this process still useful with C++11? BR, renoX
Feb 26 2013
On Tuesday, 26 February 2013 at 16:34:01 UTC, renoX wrote:On Tuesday, 26 February 2013 at 15:26:17 UTC, Craig Dillabaugh wrote:Have you tried it? C++11 can prototype faster than C++, but it ain't D. On Tuesday, 26 February 2013 at 16:55:50 UTC, Craig Dillabaugh wrote:I am a novice D programmer and use C++ in my work. One thing I find myself doing when I need to implement some non-trivial algorithm is that I will originally code it in D and perform testing from there to make sure I have the logic right. Once I have everything working in D I simply port it over to C++.I'm curious: is this process still useful with C++11? BR, renoXOn Tuesday, 26 February 2013 at 16:34:01 UTC, renoX wrote:AFAIK, it's already mostly available from both GCC and VS. *Some* functionality is still missing, but nothing major.On Tuesday, 26 February 2013 at 15:26:17 UTC, Craig Dillabaugh wrote:Again since my work is heavily array based probably, I would guess so, but perhaps not quite so much. How long though until C++11 is broadly available?I am a novice D programmer and use C++ in my work. One thing I find myself doing when I need to implement some non-trivial algorithm is that I will originally code it in D and perform testing from there to make sure I have the logic right. Once I have everything working in D I simply port it over to C++.I'm curious: is this process still useful with C++11? BR, renoX
Feb 26 2013
On Tuesday, 26 February 2013 at 15:26:17 UTC, Craig Dillabaugh wrote:I was curious to know if anyone else uses D like this.I usually do this, but in a little different way. I wrote my code in a interpreted language, and then I port to D or C languages.
Feb 26 2013
On 2/26/13 11:46 AM, MattCodr wrote:On Tuesday, 26 February 2013 at 15:26:17 UTC, Craig Dillabaugh wrote:These are great data points. We should figure how to improve D to lessen the barriers in both directions. AndreiI was curious to know if anyone else uses D like this.I usually do this, but in a little different way. I wrote my code in a interpreted language, and then I port to D or C languages.
Feb 26 2013
Andrei Alexandrescu:We should figure how to improve D to lessen the barriers in both directions.Regarding the D => C conversions I write, time ago I have suggested a "-cstyle" compiler switch: http://d.puremagic.com/issues/show_bug.cgi?id=4580 Bye, bearophile
Feb 26 2013
On 2013-02-26 18:45, Andrei Alexandrescu wrote:These are great data points. We should figure how to improve D to lessen the barriers in both directions.It helps by having convenient functions in the standard library. It also helps with not having to import a lot of modules just to get something simple done. I don't know if it's that I'm not so used to Phobos but it doesn't feel as intuitive to work with in comparison with say Ruby. In particular with Rails which adds a lot of convenient functions. -- /Jacob Carlborg
Feb 26 2013
On Tue, Feb 26, 2013 at 08:49:12PM +0100, Jacob Carlborg wrote:On 2013-02-26 18:45, Andrei Alexandrescu wrote:[...] Do you have any specific examples? T -- Study gravitation, it's a field with a lot of potential.These are great data points. We should figure how to improve D to lessen the barriers in both directions.It helps by having convenient functions in the standard library. It also helps with not having to import a lot of modules just to get something simple done. I don't know if it's that I'm not so used to Phobos but it doesn't feel as intuitive to work with in comparison with say Ruby. In particular with Rails which adds a lot of convenient functions.
Feb 26 2013
On 2013-02-26 20:52, H. S. Teoh wrote:Do you have any specific examples?Return the date from two days ago: Ruby on Rails: 2.days.ago Date.today Time.now D: Clock.currTime - 2.days // Not sure how to do the other two in D This is not that bad but it's a bit less intuitive. Here we also have shortening of "current" which just saves three characters, for no reason. I think it's mostly std.algorithm that is the problem. * reduce - The "reduce" function is really weird. It can't be used as a property. The signature is: reduce!(fun)(seed, range) When it should be: reduce!(seed, fun)(range) And: reduce!(fun)(range, seed) * No algorithm functions for associative arrays. * tap - Ruby has a really nice function, "tap". In D it would look like: T (func, T) (T t) { func(t); return t; } You can do things like: Foo foo () { return (new Foo).tap!((f) { f.x = 3; f.y = 3; }); } This becomes a bit tricky because we want structs to be passed by ref, but preferably we don't want to be able to change the parameter in the delegate. In Ruby it's no problem since all types are reference types. I probably can come up with more later. -- /Jacob Carlborg
Feb 26 2013
On 2/26/13 6:01 PM, Jacob Carlborg wrote:On 2013-02-26 20:52, H. S. Teoh wrote:And also having to import std.algorithm. In Ruby you can do map, sort and whatever without using an import. You use it so often that an import is annoying.Do you have any specific examples?Return the date from two days ago: Ruby on Rails: 2.days.ago Date.today Time.now D: Clock.currTime - 2.days // Not sure how to do the other two in D This is not that bad but it's a bit less intuitive. Here we also have shortening of "current" which just saves three characters, for no reason. I think it's mostly std.algorithm that is the problem.
Feb 26 2013
On Tuesday, 26 February 2013 at 21:10:30 UTC, Ary Borenszweig wrote:On 2/26/13 6:01 PM, Jacob Carlborg wrote:I often find myself importing std.algorithm, std.array and std.range even for the simplest things. std.string, std.ascii, std.conv, std.stdio is also quite common at the top of my files.. And *then* I import modules more specific for the problem I'm going to solve :) I sometimes wish I was using an editor that automatically added the imports for me.On 2013-02-26 20:52, H. S. Teoh wrote:And also having to import std.algorithm. In Ruby you can do map, sort and whatever without using an import. You use it so often that an import is annoying.Do you have any specific examples?Return the date from two days ago: Ruby on Rails: 2.days.ago Date.today Time.now D: Clock.currTime - 2.days // Not sure how to do the other two in D This is not that bad but it's a bit less intuitive. Here we also have shortening of "current" which just saves three characters, for no reason. I think it's mostly std.algorithm that is the problem.
Feb 26 2013
On 2013-02-26 22:10, Ary Borenszweig wrote:And also having to import std.algorithm. In Ruby you can do map, sort and whatever without using an import. You use it so often that an import is annoying.Often you need std.range and std.array as well. -- /Jacob Carlborg
Feb 27 2013
On 2/26/13 4:01 PM, Jacob Carlborg wrote:On 2013-02-26 20:52, H. S. Teoh wrote:The last two return the time right now, how come? AndreiDo you have any specific examples?Return the date from two days ago: Ruby on Rails: 2.days.ago Date.today Time.now
Feb 26 2013
On 2013-02-27 00:39, Andrei Alexandrescu wrote:The last two return the time right now, how come?They're supposed to. I just accidentally put them below "Return the date from two days ago". -- /Jacob Carlborg
Feb 27 2013
On 2013-02-26 20:52, H. S. Teoh wrote:Do you have any specific examples?Some more: isBlank and the opposite isPresent. These exists in Ruby on Rails, this is my D version: https://github.com/jacob-carlborg/mambo/blob/master/mambo/core/core.d -- /Jacob Carlborg
Feb 26 2013
On 26.02.2013 18:45, Andrei Alexandrescu wrote:On 2/26/13 11:46 AM, MattCodr wrote:REPL?On Tuesday, 26 February 2013 at 15:26:17 UTC, Craig Dillabaugh wrote:These are great data points. We should figure how to improve D to lessen the barriers in both directions. AndreiI was curious to know if anyone else uses D like this.I usually do this, but in a little different way. I wrote my code in a interpreted language, and then I port to D or C languages.
Feb 27 2013
On 2/27/13 3:29 AM, Paulo Pinto wrote:On 26.02.2013 18:45, Andrei Alexandrescu wrote:Good idea. Should be in bugzilla as an enh, although it'll take a while to get to that. AndreiOn 2/26/13 11:46 AM, MattCodr wrote:REPL?On Tuesday, 26 February 2013 at 15:26:17 UTC, Craig Dillabaugh wrote:These are great data points. We should figure how to improve D to lessen the barriers in both directions. AndreiI was curious to know if anyone else uses D like this.I usually do this, but in a little different way. I wrote my code in a interpreted language, and then I port to D or C languages.
Feb 27 2013
On Wednesday, 27 February 2013 at 10:07:43 UTC, Andrei Alexandrescu wrote:On 2/27/13 3:29 AM, Paulo Pinto wrote:D would be one step closer to actually passing the "BOTCH" test! http://mathprogrammer.com/blog/?p=12On 26.02.2013 18:45, Andrei Alexandrescu wrote:Good idea. Should be in bugzilla as an enh, although it'll take a while to get to that. AndreiOn 2/26/13 11:46 AM, MattCodr wrote:REPL?On Tuesday, 26 February 2013 at 15:26:17 UTC, Craig Dillabaugh wrote:These are great data points. We should figure how to improve D to lessen the barriers in both directions. AndreiI was curious to know if anyone else uses D like this.I usually do this, but in a little different way. I wrote my code in a interpreted language, and then I port to D or C languages.
Feb 27 2013
On 2013-02-27 11:07, Andrei Alexandrescu wrote:Good idea. Should be in bugzilla as an enh, although it'll take a while to get to that.I wonder how good the implementation will be if one just pass the line to rdmd and prints the result. -- /Jacob Carlborg
Feb 27 2013
On Wednesday, 27 February 2013 at 19:55:41 UTC, Jacob Carlborg wrote:On 2013-02-27 11:07, Andrei Alexandrescu wrote:I'm assuming you're talking about REPL. That won't cut it, as one wants to keep maintain a notion of state (variables in memory etc) and not reparse lines entered everytime (which could have IO side effects etc). I've played a bit with Oskar Linde's library for that and ported it to latest DMD release and it works quite well already, something solid to build upon (see post http://forum.dlang.org/thread/fpmpa6$2muq$1 digitalmars.com).Good idea. Should be in bugzilla as an enh, although it'll take a while to get to that.I wonder how good the implementation will be if one just pass the line to rdmd and prints the result.
Feb 27 2013
On 2/27/13 2:55 PM, Jacob Carlborg wrote:On 2013-02-27 11:07, Andrei Alexandrescu wrote:Try it, rdmd has --eval and --loop. It's useful but not as good as a real REPL. AndreiGood idea. Should be in bugzilla as an enh, although it'll take a while to get to that.I wonder how good the implementation will be if one just pass the line to rdmd and prints the result.
Feb 27 2013
On 2013-02-27 22:54, Andrei Alexandrescu wrote:Try it, rdmd has --eval and --loop. It's useful but not as good as a real REPL.I'll give that a try, thanks. -- /Jacob Carlborg
Feb 27 2013
On 02/26/2013 04:26 PM, Craig Dillabaugh wrote:I am a novice D programmer and use C++ in my work. One thing I find myself doing when I need to implement some non-trivial algorithm is that I will originally code it in D and perform testing from there to make sure I have the logic right. Once I have everything working in D I simply port it over to C++.I have to say that these days (also as someone who programs for scientific research purposes) I find that I can both write _and_ use D effectively -- the range of functionality that I need to rely on is pretty solid in D. Depending on exactly what it is you need to use, your sense of the "maturity" of D may be paranoid (but of course I appreciate paranoia as a virtue where scientific software is concerned:-). Now, that said, I can see myself doing exactly what you describe in a case where I really felt the need to use C/C++. The major reason to do so would probably be ease of access to C or C++ libraries, or collaborative requirements (most of my colleagues are C++ users for serious number crunching, although at least one typically uses FORTRAN).
Feb 26 2013
On Tue, Feb 26, 2013 at 10:01:59PM +0100, Jacob Carlborg wrote: [.[..]Return the date from two days ago: Ruby on Rails: 2.days.ago Date.today Time.now D: Clock.currTime - 2.days // Not sure how to do the other two in D This is not that bad but it's a bit less intuitive. Here we also have shortening of "current" which just saves three characters, for no reason.I find the Phobos version more readable, actually. Writing "2.days.ago" is all neat and clever and everything, but the logician in me protests at what all those '.'s are referring to, and they do. Code is not English, and when it pretends to be English, it makes me suspicious that something is subtle going on that I'm not aware of. And when I'm coding, that's something I don't like -- I need to have the assurance I know exactly what's going on. And yes I can learn to parse "2.days.ago" eventually, but it's just additional mental load for only superficial convenience. But YMMV.I think it's mostly std.algorithm that is the problem. * reduce - The "reduce" function is really weird. It can't be used as a property. The signature is: reduce!(fun)(seed, range) When it should be: reduce!(seed, fun)(range) And: reduce!(fun)(range, seed)IMHO this is just bikeshedding. I actually find Phobos' order more intuitive (to me anyway), because the function you're reducing on, ideally, should be inlined, so it makes sense to pass it as a compile-time parameter, and the seed value is what you start with, so it makes sense to have it appear as the first parameter. But I can see where UFCS will fail to kick in here, which makes it a bit annoying, I suppose. But reduce was designed before UFCS made it into DMD.* No algorithm functions for associative arrays.Yeah that area needs some work.* tap - Ruby has a really nice function, "tap". In D it would look like: T (func, T) (T t) { func(t); return t; } You can do things like: Foo foo () { return (new Foo).tap!((f) { f.x = 3; f.y = 3; }); }[...] Couldn't you use map for this purpose? On Tue, Feb 26, 2013 at 10:04:50PM +0100, Jacob Carlborg wrote:On 2013-02-26 20:52, H. S. Teoh wrote:[...] Unfortunately, on this point I have to disagree. I find !isBlank much better. Generally, I prefer a more minimal API, but I suppose people coming from Ruby might expect a more "rich" kind of API design (caveat: I don't know Ruby). Having too many ways of stating the same thing makes me wonder if there's some subtle bug lurking somewhere. What if isPresent is not 100% equivalent to !isBlank? And I don't mean just hypothetically; I've seen cases of libraries where bugs cause two supposedly-opposite functions to be not exactly opposite, and then code starts to depend on the buggy behaviour, causing hidden bugs later when the code gets fixed, etc.. A lot of unnecessary problems when you could have just written !isBlank in the first place. Now, I used to be a Perl fanatic, so I totally understand TIMTOWTDI and all that, but I think having a separate function just to encode !isBlank is a bit too extreme. The language has boolean operators for a reason, after all. T -- If you look at a thing nine hundred and ninety-nine times, you are perfectly safe; if you look at it the thousandth time, you are in frightful danger of seeing it for the first time. -- G. K. ChestertonDo you have any specific examples?Some more: isBlank and the opposite isPresent. These exists in Ruby on Rails, this is my D version: https://github.com/jacob-carlborg/mambo/blob/master/mambo/core/core.d
Feb 26 2013
On 2/26/2013 1:26 PM, H. S. Teoh wrote:Having too many ways of stating the same thing makes me wonder if there's some subtle bug lurking somewhere. What if isPresent is not 100% equivalent to !isBlank? And I don't mean just hypothetically; I've seen cases of libraries where bugs cause two supposedly-opposite functions to be not exactly opposite, and then code starts to depend on the buggy behaviour, causing hidden bugs later when the code gets fixed, etc.. A lot of unnecessary problems when you could have just written !isBlank in the first place.This is a subtle but very important point.
Feb 26 2013
On 2013-02-27 03:52, Walter Bright wrote:This is a subtle but very important point.It's not about adding the inverse of an already existing function. It's about adding a function that doesn't exist at all. Don't you read the post and the code at all? Or do I express myself so badly? -- /Jacob Carlborg
Feb 27 2013
On 2013-02-26 22:26, H. S. Teoh wrote:I find the Phobos version more readable, actually. Writing "2.days.ago" is all neat and clever and everything, but the logician in me protests at what all those '.'s are referring to, and they do. Code is not English, and when it pretends to be English, it makes me suspicious that something is subtle going on that I'm not aware of. And when I'm coding, that's something I don't like -- I need to have the assurance I know exactly what's going on. And yes I can learn to parse "2.days.ago" eventually, but it's just additional mental load for only superficial convenience.I don't agree. BTW, the whole point of having programming languages is for programmers to read and write it. Therefore they are similar to English (or some other language). For the computer the language is just in the way. It just wants to execute machine code.IMHO this is just bikeshedding. I actually find Phobos' order more intuitive (to me anyway), because the function you're reducing on, ideally, should be inlined, so it makes sense to pass it as a compile-time parameter, and the seed value is what you start with, so it makes sense to have it appear as the first parameter.I never said it shouldn't be passed as a compile time parameter. Look at the example. I added the seed to the compile time parameter list.But I can see where UFCS will fail to kick in here, which makes it a bit annoying, I suppose. But reduce was designed before UFCS made it into DMD.Then it should be changed. Oh, wait. We can't break any code, every I don't know why I keep bothering. You (not as in "you" personally) never want to improve anything.Couldn't you use map for this purpose?No, not as far as I know. "map" expects a range and returns a new range. "tap" expects an object and returns the same object. You can use "tap" to tap into chains of method calls and change an object.Unfortunately, on this point I have to disagree. I find !isBlank much better. Generally, I prefer a more minimal API, but I suppose people coming from Ruby might expect a more "rich" kind of API design (caveat: I don't know Ruby). Having too many ways of stating the same thing makes me wonder if there's some subtle bug lurking somewhere. What if isPresent is not 100% equivalent to !isBlank? And I don't mean just hypothetically; I've seen cases of libraries where bugs cause two supposedly-opposite functions to be not exactly opposite, and then code starts to depend on the buggy behaviour, causing hidden bugs later when the code gets fixed, etc.. A lot of unnecessary problems when you could have just written !isBlank in the first place.This is not about adding "isPresent" to an already existing "isBlank" this is about adding "isBlank" or "isPresent" which don't exist.Now, I used to be a Perl fanatic, so I totally understand TIMTOWTDI and all that, but I think having a separate function just to encode !isBlank is a bit too extreme. The language has boolean operators for a reason, after all.isBlank does way more than checking if a value is false or not. Do you read the code at all? -- /Jacob Carlborg
Feb 27 2013
On Wed, Feb 27, 2013 at 02:02:01PM +0100, Jacob Carlborg wrote:On 2013-02-26 22:26, H. S. Teoh wrote:OK, then let's agree to disagree. I see that there's no point in arguing about this, since it ultimately comes down to preference, which can never be reconciled.I find the Phobos version more readable, actually. Writing "2.days.ago" is all neat and clever and everything, but the logician in me protests at what all those '.'s are referring to, and they do. Code is not English, and when it pretends to be English, it makes me suspicious that something is subtle going on that I'm not aware of. And when I'm coding, that's something I don't like -- I need to have the assurance I know exactly what's going on. And yes I can learn to parse "2.days.ago" eventually, but it's just additional mental load for only superficial convenience.I don't agree. BTW, the whole point of having programming languages is for programmers to read and write it. Therefore they are similar to English (or some other language). For the computer the language is just in the way. It just wants to execute machine code.Yes, I was just talking about the order of parameters.IMHO this is just bikeshedding. I actually find Phobos' order more intuitive (to me anyway), because the function you're reducing on, ideally, should be inlined, so it makes sense to pass it as a compile-time parameter, and the seed value is what you start with, so it makes sense to have it appear as the first parameter.I never said it shouldn't be passed as a compile time parameter. Look at the example. I added the seed to the compile time parameter list.Not sure who you're referring to here, but the reason reduce probably will not change is because a lot of code relies on the current order of parameters, and deliberately breaking that just for aesthetic (rather than functional) reasons is not a good idea. It would be a different story if the current order of parameters somehow makes it impossible to implement some particular functionality. I agree that perhaps the current situation is not perfect, but at least it's not a complete road blocker.But I can see where UFCS will fail to kick in here, which makes it a bit annoying, I suppose. But reduce was designed before UFCS made it into DMD.Then it should be changed. Oh, wait. We can't break any code, every I don't know why I keep bothering. You (not as in "you" personally) never want to improve anything.Isn't that the same as: map!((obj x) { doSomething(x); return x; })(range) ? I know it's not as pretty, but at least it's possible.Couldn't you use map for this purpose?No, not as far as I know. "map" expects a range and returns a new range. "tap" expects an object and returns the same object. You can use "tap" to tap into chains of method calls and change an object.My point was that you only need one of them, not both. I don't see what's the advantage of adding both isBlank and isPresent, when adding just one will already give you the functionality of the other. I didn't mean to say that it's a bad idea to add *either* one.Unfortunately, on this point I have to disagree. I find !isBlank much better. Generally, I prefer a more minimal API, but I suppose people coming from Ruby might expect a more "rich" kind of API design (caveat: I don't know Ruby). Having too many ways of stating the same thing makes me wonder if there's some subtle bug lurking somewhere. What if isPresent is not 100% equivalent to !isBlank? And I don't mean just hypothetically; I've seen cases of libraries where bugs cause two supposedly-opposite functions to be not exactly opposite, and then code starts to depend on the buggy behaviour, causing hidden bugs later when the code gets fixed, etc.. A lot of unnecessary problems when you could have just written !isBlank in the first place.This is not about adding "isPresent" to an already existing "isBlank" this is about adding "isBlank" or "isPresent" which don't exist.[...] Again, my point was not that it's a bad idea to have isBlank. My point was that if you add isBlank, then isPresent is redundant, and I would argue even harmful. The best APIs are minimal ones, that provide all *necessary* primitives with minimal overlap between them. T -- Who told you to swim in Crocodile Lake without life insurance??Now, I used to be a Perl fanatic, so I totally understand TIMTOWTDI and all that, but I think having a separate function just to encode !isBlank is a bit too extreme. The language has boolean operators for a reason, after all.isBlank does way more than checking if a value is false or not. Do you read the code at all?
Feb 27 2013
On 2013-02-27 18:35, H. S. Teoh wrote:Not sure who you're referring to here, but the reason reduce probably will not change is because a lot of code relies on the current order of parameters, and deliberately breaking that just for aesthetic (rather than functional) reasons is not a good idea. It would be a different story if the current order of parameters somehow makes it impossible to implement some particular functionality. I agree that perhaps the current situation is not perfect, but at least it's not a complete road blocker.That's the problem. Then we will have a language with a slightly inconsistent and inconvenient standard library.Isn't that the same as: map!((obj x) { doSomething(x); return x; })(range) ? I know it's not as pretty, but at least it's possible.No it's not the same thing. "map" expects a range and returns a new range. "map" will pass each element from the range to the delegate and then return a new range of all elements returned for each call to the delegate. "tap" on the other hand expects an object or value. It will then pass the object to the delegate and then return the object. Note that it doesn't return whats returned from the delegate. It will always return the object passed to "tap". The most basic, non-templated implementation of "tap" would look like this: Object tap (alias func) (Object o) { func(o); return o; } class Point { int x; int y; } Point createPoint () { return (new Point).tap!((p) { p.x = 3; p.y = 4 }); }Again, my point was not that it's a bad idea to have isBlank. My point was that if you add isBlank, then isPresent is redundant, and I would argue even harmful. The best APIs are minimal ones, that provide all *necessary* primitives with minimal overlap between them.OK, then it was a misunderstanding, my bad. But with this philosophy it will not be as easy create quick scripts compared to scripting languages. This the original question, how to improve that in D. -- /Jacob Carlborg
Feb 27 2013
On Wed, Feb 27, 2013 at 08:54:21PM +0100, Jacob Carlborg wrote:On 2013-02-27 18:35, H. S. Teoh wrote:Well, given that we have UFCS now, maybe we *do* want to standardize on the range always being the first argument, so that UFCS chaining always works. I'm OK to have reduce change the order of arguments... but given the amount of code it will break, I doubt it will get in. One way is to introduce the new version under a different name and deprecate "reduce". I'm not the person you have to convince, though; it's Jonathan or Andrei who will decide whether to accept this change.Not sure who you're referring to here, but the reason reduce probably will not change is because a lot of code relies on the current order of parameters, and deliberately breaking that just for aesthetic (rather than functional) reasons is not a good idea. It would be a different story if the current order of parameters somehow makes it impossible to implement some particular functionality. I agree that perhaps the current situation is not perfect, but at least it's not a complete road blocker.That's the problem. Then we will have a language with a slightly inconsistent and inconvenient standard library.Oh I get it now. So basically it's a wrapper around functions to make UFCS chaining possible?Isn't that the same as: map!((obj x) { doSomething(x); return x; })(range) ? I know it's not as pretty, but at least it's possible.No it's not the same thing. "map" expects a range and returns a new range. "map" will pass each element from the range to the delegate and then return a new range of all elements returned for each call to the delegate. "tap" on the other hand expects an object or value. It will then pass the object to the delegate and then return the object. Note that it doesn't return whats returned from the delegate. It will always return the object passed to "tap".The most basic, non-templated implementation of "tap" would look like this: Object tap (alias func) (Object o) { func(o); return o; }What would a templated version add to this functionality?class Point { int x; int y; } Point createPoint () { return (new Point).tap!((p) { p.x = 3; p.y = 4 }); }I guess I'm skeptical about the value of using tap in this context, since you could just call the function on the object, then set its values, then return it. So this is just syntactic sugar. But I guess I can see some use cases where you're chaining a bunch of stuff inside nested function calls, then tap might become convenient: return map!myFunc(zip(r1, [ new X().tap!myFunc2(), new X().tap!myFunc2() ])); Which can be unpacked into linear code, but you would would need a bunch of temporary variables to hold the intermediate results.[...] I disagree with this point. Writing !isBlank is just as easy as writing isPresent (in fact, a few characters less). I don't see how this helps with writing scripts faster. T -- Answer: Because it breaks the logical sequence of discussion. / Question: Why is top posting bad?Again, my point was not that it's a bad idea to have isBlank. My point was that if you add isBlank, then isPresent is redundant, and I would argue even harmful. The best APIs are minimal ones, that provide all *necessary* primitives with minimal overlap between them.OK, then it was a misunderstanding, my bad. But with this philosophy it will not be as easy create quick scripts compared to scripting languages. This the original question, how to improve that in D.
Feb 27 2013
On 2013-02-27 21:12, H. S. Teoh wrote:Oh I get it now. So basically it's a wrapper around functions to make UFCS chaining possible?Yes, something like that.What would a templated version add to this functionality?Allow structs to be passed as well. Although they need to be passed by ref. But then you would be able to do this: auto s = Struct(); s.tap!((ref e) { e = Struct(); }); Which should be avoidable if possible.I guess I'm skeptical about the value of using tap in this context, since you could just call the function on the object, then set its values, then return it. So this is just syntactic sugar. But I guess I can see some use cases where you're chaining a bunch of stuff inside nested function calls, then tap might become convenient: return map!myFunc(zip(r1, [ new X().tap!myFunc2(), new X().tap!myFunc2() ])); Which can be unpacked into linear code, but you would would need a bunch of temporary variables to hold the intermediate results.This is about the little things that makes it convenient to write code. I'm not saying that you cannot do anything without these things. But the question was, what can we do to make D more usable as a scripting language.I disagree with this point. Writing !isBlank is just as easy as writing isPresent (in fact, a few characters less). I don't see how this helps with writing scripts faster.No, I was more thinking of "The best APIs are minimal ones". If you only have the minimal building blocks you would need to create wrappers and similar to create convenient functions. -- /Jacob Carlborg
Feb 27 2013
On 2/27/13 5:12 PM, H. S. Teoh wrote:Tap is nice when you want to print-debug something and you have a chain of calls: auto foo = x.map!(...).reduce!(...).nWayUnion!(...); Now something is not working correctly and you want to see what's after the "reduce!" step: auto foo = x.map!(...).reduce!(...).tap!(r) { writefln(r); }).nWayUnion!(...); Otherwise you'd have to break it in many lines and then put them back together.The most basic, non-templated implementation of "tap" would look like this: Object tap (alias func) (Object o) { func(o); return o; }What would a templated version add to this functionality?class Point { int x; int y; } Point createPoint () { return (new Point).tap!((p) { p.x = 3; p.y = 4 }); }I guess I'm skeptical about the value of using tap in this context, since you could just call the function on the object, then set its values, then return it. So this is just syntactic sugar.
Feb 27 2013
On 2/27/13 3:53 PM, Ary Borenszweig wrote:Tap is nice when you want to print-debug something and you have a chain of calls: auto foo = x.map!(...).reduce!(...).nWayUnion!(...); Now something is not working correctly and you want to see what's after the "reduce!" step: auto foo = x.map!(...).reduce!(...).tap!(r) { writefln(r); }).nWayUnion!(...); Otherwise you'd have to break it in many lines and then put them back together.I like Tap (including the name). It is similar to Unix's "tee" utility. Andrei
Feb 27 2013
On 2013-02-27 22:59, Andrei Alexandrescu wrote:I like Tap (including the name). It is similar to Unix's "tee" utility.Cool, is this something that could be included in Phobos? If yes, where? -- /Jacob Carlborg
Feb 28 2013
On 2/28/13 3:03 AM, Jacob Carlborg wrote:On 2013-02-27 22:59, Andrei Alexandrescu wrote:I think it belongs to std.range. 1. tap!fun(r) returns a new range (of a new type R1 distinct from typeof(r)). Upon the first call to .front without an intervening popFront, fun(r.front) is called. 2. tap!(fun1, fun2)(r) also returns a new range, calls fun1 as described above, and fun2 whenever popFront() gets called without the front() being looked at. So fun1 tracks the looked-at data and fun2 tracks the ignored data. AndreiI like Tap (including the name). It is similar to Unix's "tee" utility.Cool, is this something that could be included in Phobos? If yes, where?
Feb 28 2013
On 2013-02-28 16:18, Andrei Alexandrescu wrote:I think it belongs to std.range. 1. tap!fun(r) returns a new range (of a new type R1 distinct from typeof(r)). Upon the first call to .front without an intervening popFront, fun(r.front) is called. 2. tap!(fun1, fun2)(r) also returns a new range, calls fun1 as described above, and fun2 whenever popFront() gets called without the front() being looked at. So fun1 tracks the looked-at data and fun2 tracks the ignored data.That is not my idea of "tap". This is my idea of "tap": Object (func) (Object o) { func(o); return o; } -- /Jacob Carlborg
Feb 28 2013
On 2/28/13 10:24 AM, Jacob Carlborg wrote:On 2013-02-28 16:18, Andrei Alexandrescu wrote:I know. I think my tap is better than your tap. AndreiI think it belongs to std.range. 1. tap!fun(r) returns a new range (of a new type R1 distinct from typeof(r)). Upon the first call to .front without an intervening popFront, fun(r.front) is called. 2. tap!(fun1, fun2)(r) also returns a new range, calls fun1 as described above, and fun2 whenever popFront() gets called without the front() being looked at. So fun1 tracks the looked-at data and fun2 tracks the ignored data.That is not my idea of "tap". This is my idea of "tap": Object (func) (Object o) { func(o); return o; }
Feb 28 2013
On 2/28/13 10:49 AM, Andrei Alexandrescu wrote:On 2/28/13 10:24 AM, Jacob Carlborg wrote:... and closer in intent to Ruby's tap as I understand it from reading http://ruby-doc.org/core-2.0/Object.html#method-i-tap No? AndreiOn 2013-02-28 16:18, Andrei Alexandrescu wrote:I know. I think my tap is better than your tap.I think it belongs to std.range. 1. tap!fun(r) returns a new range (of a new type R1 distinct from typeof(r)). Upon the first call to .front without an intervening popFront, fun(r.front) is called. 2. tap!(fun1, fun2)(r) also returns a new range, calls fun1 as described above, and fun2 whenever popFront() gets called without the front() being looked at. So fun1 tracks the looked-at data and fun2 tracks the ignored data.That is not my idea of "tap". This is my idea of "tap": Object (func) (Object o) { func(o); return o; }
Feb 28 2013
On Thursday, 28 February 2013 at 15:51:02 UTC, Andrei Alexandrescu wrote:On 2/28/13 10:49 AM, Andrei Alexandrescu wrote:Ruby's tap just applies the passed block to the object it is called on. I am not quite sure how your range idea comes into play here? DavidOn 2/28/13 10:24 AM, Jacob Carlborg wrote:... and closer in intent to Ruby's tap as I understand it from reading http://ruby-doc.org/core-2.0/Object.html#method-i-tapThat is not my idea of "tap". This is my idea of "tap": Object (func) (Object o) { func(o); return o; }I know. I think my tap is better than your tap.
Feb 28 2013
On 2/28/13 11:36 AM, David Nadlinger wrote:On Thursday, 28 February 2013 at 15:51:02 UTC, Andrei Alexandrescu wrote:Oh, I misunderstood the example at http://ruby-doc.org/core-2.0/Object.html#method-i-tap: It eagerly prints the entire range, then eagerly prints the entire array, then eagerly the entire filtered range, then eagerly the entire map result. I thought it works lazily, and I think in D it should (otherwise it would be e.g. useless with an input range). So the D translation would be: iota(1, 10) .tap!(a => writeln("original: ", a)) .filter!(a => a % 2 == 0) .tap!(a => writeln("filtered: ", a)) .map!(a => a * a) .tap!(a => writeln("squared: ", a)); This will produce output interleaved, so it's semantically different. I've used something similar to "tap" in a streaming-based library for machine learning I worked on as a grad student. It's been instrumental for data analysis and debugging. This conversation reminded me of it. So my thought on the subject - I don't care much for T tap(alias func)(T x) { func(x); return x; } It's the kind of chaff that doesn't do any real work and only dilutes the value of a library, but I do think a tap tapping into a range does real work and would be a valuable addition. AndreiOn 2/28/13 10:49 AM, Andrei Alexandrescu wrote:Ruby's tap just applies the passed block to the object it is called on. I am not quite sure how your range idea comes into play here? DavidOn 2/28/13 10:24 AM, Jacob Carlborg wrote:... and closer in intent to Ruby's tap as I understand it from reading http://ruby-doc.org/core-2.0/Object.html#method-i-tapThat is not my idea of "tap". This is my idea of "tap": Object (func) (Object o) { func(o); return o; }I know. I think my tap is better than your tap.
Feb 28 2013
On 2013-02-28 18:08, Andrei Alexandrescu wrote:T tap(alias func)(T x) { func(x); return x; } It's the kind of chaff that doesn't do any real work and only dilutes the value of a library, but I do think a tap tapping into a range does real work and would be a valuable addition.What about a function allowing both? -- /Jacob Carlborg
Feb 28 2013
On 02/28/2013 06:08 PM, Andrei Alexandrescu wrote:... So my thought on the subject - I don't care much for T tap(alias func)(T x) { func(x); return x; }I'm not sure who would. template tap(alias func){ T tap(T)(T x){ func(x); return x; } }It's the kind of chaff that doesn't do any real work and only dilutes the value of a library, but I do think a tap tapping into a range does real work and would be a valuable addition. ...map!(tap!func)
Mar 02 2013
On Wednesday, 27 February 2013 at 17:37:34 UTC, H. S. Teoh wrote: [...]Again, my point was not that it's a bad idea to have isBlank. My point was that if you add isBlank, then isPresent is redundant, and I would argue even harmful. The best APIs are minimal ones, that provide all *necessary* primitives with minimal overlap between them. TI agree. I can only see a need for "isPresent" (or the opposite) only if it was made clear that isPresent does something different than !isBlank. If you continue to use isPresent, then I suggest that it is implemented as a convenience wrapper around !isBlank to make sure that changes to isBlank automatically propagate back to isPresent. --rt
Feb 27 2013
On 2013-02-27 21:01, Rob T wrote:I agree. I can only see a need for "isPresent" (or the opposite) only if it was made clear that isPresent does something different than !isBlank. If you continue to use isPresent, then I suggest that it is implemented as a convenience wrapper around !isBlank to make sure that changes to isBlank automatically propagate back to isPresent.As I said to H.S. Teoh, the question is not about adding the inverse of an already existing function. It's about adding functionality that doesn't exist. It doesn't matter if isPresent or isBlank would be added. If you had looked at the code you would see the the implementation of isPresent looks like this: property bool isPresent (T) (T t) { return !isBlank(t); } Which is _exactly_ the inverse of isBlank. -- /Jacob Carlborg
Feb 27 2013
On 2/27/13 2:35 PM, H. S. Teoh wrote:Then why not remove the binary "-" from D. You can always do: a + -b I believe this makes the language simpler.This is not about adding "isPresent" to an already existing "isBlank" this is about adding "isBlank" or "isPresent" which don't exist.My point was that you only need one of them, not both. I don't see what's the advantage of adding both isBlank and isPresent, when adding just one will already give you the functionality of the other. I didn't mean to say that it's a bad idea to add *either* one.
Feb 27 2013
"Ary Borenszweig" <ary esperanto.org.ar> wrote in message news:512E717B.7090808 esperanto.org.ar...Then why not remove the binary "-" from D. You can always do: a + -b I believe this makes the language simpler.Compatibility with C.
Mar 01 2013
On Wednesday, 27 February 2013 at 13:02:02 UTC, Jacob Carlborg wrote: [...]This is not about adding "isPresent" to an already existing "isBlank" this is about adding "isBlank" or "isPresent" which don't exist.[...]isBlank does way more than checking if a value is false or not. Do you read the code at all?This thread got busted up into separate threads over the web interface, so maybe some people (like me) did not read everything you suggested. OK I see you wanted to add only one or the other, not both. I like the idea of having this function in the std.lib. I added it to my own "standard.me" library. --rt PS: The web interface thread splitting is very annoying!
Feb 27 2013
On Wed, Feb 27, 2013 at 09:07:15PM +0100, Rob T wrote:On Wednesday, 27 February 2013 at 13:02:02 UTC, Jacob Carlborg wrote: [...]This is interesting. I have also been collecting a bunch of stuff that I constantly reuse in my own code. I wonder if we should do a survey of people's "standard.me" libraries to see what are the functionalities most commonly missing from Phobos? That might give us some interesting insights into what would be most profitable to add to Phobos. Having said that, though, I found that my D personal library is much smaller than my C/C++ one, mostly because Phobos already covered a large part of that functionality! So Phobos is doing *something* right, in spite of all its current flaws. [...]This is not about adding "isPresent" to an already existing "isBlank" this is about adding "isBlank" or "isPresent" which don't exist.[...]isBlank does way more than checking if a value is false or not. Do you read the code at all?This thread got busted up into separate threads over the web interface, so maybe some people (like me) did not read everything you suggested. OK I see you wanted to add only one or the other, not both. I like the idea of having this function in the std.lib. I added it to my own "standard.me" library.PS: The web interface thread splitting is very annoying!We *really* need to look into fixing the mailman gateway, which is largely the cause of this problem. If I had the power to do it, I would. T -- Microsoft is to operating systems & security ... what McDonalds is to gourmet cooking.
Feb 27 2013
On 2013-02-27 21:16, H. S. Teoh wrote:This is interesting. I have also been collecting a bunch of stuff that I constantly reuse in my own code. I wonder if we should do a survey of people's "standard.me" libraries to see what are the functionalities most commonly missing from Phobos? That might give us some interesting insights into what would be most profitable to add to Phobos.That's a good idea. This is my library: https://github.com/jacob-carlborg/mambo It's a bit outdated. It started around 2007 with D1 and Tango.We *really* need to look into fixing the mailman gateway, which is largely the cause of this problem. If I had the power to do it, I would.I agree. I apologize that I got frustrated in the confusing of threads that were split. -- /Jacob Carlborg
Feb 27 2013
On Wednesday, 27 February 2013 at 20:43:47 UTC, Jacob Carlborg wrote:That's a good idea. This is my library: https://github.com/jacob-carlborg/mambo It's a bit outdated. It started around 2007 with D1 and Tango.I had a look at your isBlank function. Why not check if length exists and run it as follows? property bool isBlank (T) (T t) { static if (__traits(compiles, t.length)) { if (t.length == 0) return true; } ... That would be more generic I think. --rt
Feb 27 2013
On 2013-02-28 04:35, Rob T wrote:I had a look at your isBlank function. Why not check if length exists and run it as follows? property bool isBlank (T) (T t) { static if (__traits(compiles, t.length)) { if (t.length == 0) return true; } ... That would be more generic I think.Sure, I could do that. But I thought checking for "empty" would be more generic. I would expect every type having "length" would/should also have "empty" but perhaps that's a wrong assumption. -- /Jacob Carlborg
Feb 28 2013
On Thursday, 28 February 2013 at 08:05:20 UTC, Jacob Carlborg wrote:On 2013-02-28 04:35, Rob T wrote:It is easy to ensure via UFCS.I had a look at your isBlank function. Why not check if length exists and run it as follows? property bool isBlank (T) (T t) { static if (__traits(compiles, t.length)) { if (t.length == 0) return true; } ... That would be more generic I think.Sure, I could do that. But I thought checking for "empty" would be more generic. I would expect every type having "length" would/should also have "empty" but perhaps that's a wrong assumption.
Feb 28 2013
On Thursday, February 28, 2013 09:05:19 Jacob Carlborg wrote:On 2013-02-28 04:35, Rob T wrote:All ranges are guaranteed to have empty, so any range with length will obviously have empty. Regardless, in general, it's better to check for empty than length, since it's possible for empty to be more efficient, and it's unlikely the empty will ever be less efficient than checking that length == 0. If you're not talking about ranges, then all bets are off as to what it does and doesn't have, because that would depend on what APIs it adheres to and what they're like. - Jonathan M DavisI had a look at your isBlank function. Why not check if length exists and run it as follows? property bool isBlank (T) (T t) { static if (__traits(compiles, t.length)) { if (t.length == 0) return true; } ... That would be more generic I think.Sure, I could do that. But I thought checking for "empty" would be more generic. I would expect every type having "length" would/should also have "empty" but perhaps that's a wrong assumption.
Feb 28 2013
On Wednesday, 27 February 2013 at 20:18:29 UTC, H. S. Teoh wrote: [...]Having said that, though, I found that my D personal library is much smaller than my C/C++ one, mostly because Phobos already covered a large part of that functionality! So Phobos is doing *something* right, in spite of all its current flaws.I also found that my D version of my std.me lib is a lot smaller than the C++ version, so Phobos seems to do a lot more than the C++ std lib does, and what I've used so far seems to be well done. I've only managed to scratch the surface though. I think with C++ you have to use boost to get the same as what you get with Phobos, but I never liked working with boost. --rt
Feb 27 2013
On Wednesday, 27 February 2013 at 20:18:29 UTC, H. S. Teoh wrote:I wonder if we should do a survey of people's "standard.me" libraries to see what are the functionalities most commonly missing from Phobos? That might give us some interesting insights into what would be most profitable to add to Phobos.Once we get ability to add user comments to Phobos documentation, then maybe that will help determine what is working and what is not, and also what is missing that perhaps should be there. --rt
Feb 27 2013
On 2013-02-27 21:07, Rob T wrote:On Wednesday, 27 February 2013 at 13:02:02 UTC, Jacob Carlborg wrote: [...]Ok, then my apologize. -- /Jacob CarlborgThis is not about adding "isPresent" to an already existing "isBlank" this is about adding "isBlank" or "isPresent" which don't exist.[...]isBlank does way more than checking if a value is false or not. Do you read the code at all?This thread got busted up into separate threads over the web interface, so maybe some people (like me) did not read everything you suggested. OK I see you wanted to add only one or the other, not both. I like the idea of having this function in the std.lib. I added it to my own "standard.me" library. --rt PS: The web interface thread splitting is very annoying!
Feb 27 2013
On Tuesday, 26 February 2013 at 15:26:17 UTC, Craig Dillabaugh wrote:I am a novice D programmer and use C++ in my work. One thing I find myself doing when I need to implement some non-trivial algorithm is that I will originally code it in D and perform testing from there to make sure I have the logic right. Once I have everything working in D I simply port it over to C++. In my experience this porting is very trivial (it probably helps there that I write D like a C++ programmer). While I don't have hard evidence I think that the 'porting' effort to C++ is more than offset by the productivity gains I achieve fighting with C++ syntax while trying to get the logic right. Most of the porting effort is simply copying and pasting the D code into my C++ source files and adding headers, replacing imports with includes, etc. Usually significant portions of the code compile without any changes. I was curious to know if anyone else uses D like this. If so this might be a good way to try and get D into some C++ shops. The nice thing about D in my opinion is that even for people without D experience, if they have C++ experience they can likely 'read' D code without much trouble (of course some features might not map over so well - but the languages are syntactically very close).I can understand why you are doing this. C++ code tends to be about 3x the volume of well written D code, so a lot of effort is wasted when coding in C++, so if you can get it right through using D, then translate to C++, you'll save a lot of time, but of course we're better off using D directly, but first the language and tool set has to be made production use ready. Once full shared library support comes about, we'll be able to integrate D libs directly into existing C/C++ code. This allows for a safe migration path away from legacy C/C++ to D. --rt
Feb 26 2013
On Tuesday, 26 February 2013 at 23:46:52 UTC, Rob T wrote:Once full shared library support comes about, we'll be able to integrate D libs directly into existing C/C++ code. This allows for a safe migration path away from legacy C/C++ to D. --rtFunny story, I'm doing it the other way around. I got my program fully working in D, and am porting it to C. The basic idea is that I'm going to port it "chunk by chunk" to C, while keeping my main in D. This allows me to "package" the finished parts in C, but still work on the rest in D. It also means the porting doesn't have to be done in its totality in a single pass.
Feb 27 2013
On Wednesday, 27 February 2013 at 08:30:18 UTC, monarch_dodra wrote:On Tuesday, 26 February 2013 at 23:46:52 UTC, Rob T wrote:I understand why your are doing this, but it must be a ton of work, and has a lot of potential for introducing bugs that do not exist in the D code base. Someone proposed that we compile D to JVM bytecode, but maybe we should have D compile to C or C++ source code instead, at least that can work fully unlike with JVM bytecode, and it would save you guys a lot of work --rtOnce full shared library support comes about, we'll be able to integrate D libs directly into existing C/C++ code. This allows for a safe migration path away from legacy C/C++ to D. --rtFunny story, I'm doing it the other way around. I got my program fully working in D, and am porting it to C. The basic idea is that I'm going to port it "chunk by chunk" to C, while keeping my main in D. This allows me to "package" the finished parts in C, but still work on the rest in D. It also means the porting doesn't have to be done in its totality in a single pass.
Feb 27 2013
On Tuesday, 26 February 2013 at 15:26:17 UTC, Craig Dillabaugh wrote:I am a novice D programmer and use C++ in my work. One thing I find myself doing when I need to implement some non-trivial algorithm is that I will originally code it in D and perform testing from there to make sure I have the logic right. Once I have everything working in D I simply port it over to C++.(...) I'm surprised to see many people doing this. But I'm wondering.. If you already got the code working in D, why not let it stay there and write a C interface? Company policy? Missing dynamic loading? Some build issues? If the code could stay in D, it would seem like a good way to slowly integrate D into a company.
Feb 27 2013
I'm surprised to see many people doing this. But I'm wondering.. If you already got the code working in D, why not let it stay there and write a C interface? Company policy? Missing dynamic loading? Some build issues? If the code could stay in D, it would seem like a good way to slowly integrate D into a company.As we said: D isn't mature enough. As long as your code base isn't too complex, D is very nice but at some point you get many stumbling blocks, bugs or missing features which is very annoying. I like D, but it is far away from using it instead of C++.
Feb 27 2013