www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - D versus Objective C Comparison

reply Chris R Miller <lordsauronthegreat gmail.com> writes:
In my hiatus from D, I decided to take the plunge and teach myself 
Objective-C.  This gave me some interesting insights into both 
languages.  It's so fun, whenever I find another programmer, one of the 
first twenty things I say is "have you ever tried Digital Mars D?  It 
will change your whole life, I swear to you!"

Anyways, I decided to write up a comparison of the two languages from a 
less technical, more deployment oriented standpoint.  IOW, examining how 
well they perform for the last mile of development: deploying software.

As is my general stance, I refuse to downright pick a side - they're 
both good languages.  But I thought that those of you who put so much 
(god-damn heroic) effort into D might appreciate a little critique for a 
small bit of perspective.

http://www.fsdev.net/~cmiller/a/20090123_dvobjc.html

Also, I do honor the right of reply.  If there's something I have 
written that is now incorrect or inaccurate I will of course change my 
page to reflect that.  Heck, all the comparisons in the world are 
worthless if they aren't accurate!

Have a great day, and keep up the good work!  I personally can't wait 
until D gets to the point that a (total bonehead) like me can install it 
on OS X!  Alas, right now it seemeth to require more brain cells than I 
have at my disposal.
Jan 31 2009
next sibling parent reply Walter Bright <newshound1 digitalmars.com> writes:
Chris R Miller wrote:
 Also, I do honor the right of reply.  If there's something I have 
 written that is now incorrect or inaccurate I will of course change my 
 page to reflect that.  Heck, all the comparisons in the world are 
 worthless if they aren't accurate!

Thanks for doing this, it's a nice comparison. But one error is that there is a dmd for Linux, and it's as fully supported and capable as the windows one. I use it all the time on Ubuntu.
Jan 31 2009
parent reply Chris R Miller <lordsauronthegreat gmail.com> writes:
Walter Bright wrote:
 Chris R Miller wrote:
 Also, I do honor the right of reply.  If there's something I have 
 written that is now incorrect or inaccurate I will of course change my 
 page to reflect that.  Heck, all the comparisons in the world are 
 worthless if they aren't accurate!

Thanks for doing this, it's a nice comparison. But one error is that there is a dmd for Linux, and it's as fully supported and capable as the windows one. I use it all the time on Ubuntu.

Hmm, I didn't think that I was implying that it wasn't supported, but I have never gotten it to work satisfactorily on Linux with my usual entourage of libraries, so I just try and ignore it as me "not doing it right" again. I have clarified that part though, as after re-reading it I see how it could be taken the wrong way.
Jan 31 2009
parent reply Walter Bright <newshound1 digitalmars.com> writes:
Chris R Miller wrote:
 Walter Bright wrote:
 Chris R Miller wrote:
 Also, I do honor the right of reply.  If there's something I have 
 written that is now incorrect or inaccurate I will of course change 
 my page to reflect that.  Heck, all the comparisons in the world are 
 worthless if they aren't accurate!

Thanks for doing this, it's a nice comparison. But one error is that there is a dmd for Linux, and it's as fully supported and capable as the windows one. I use it all the time on Ubuntu.

Hmm, I didn't think that I was implying that it wasn't supported, but I have never gotten it to work satisfactorily on Linux with my usual entourage of libraries, so I just try and ignore it as me "not doing it right" again. I have clarified that part though, as after re-reading it I see how it could be taken the wrong way.

Thanks. But what is the issue you're running into with the Linux dmd?
Jan 31 2009
parent reply Chris R Miller <lordsauronthegreat gmail.com> writes:
Walter Bright wrote:
 Chris R Miller wrote:
 Walter Bright wrote:
 Chris R Miller wrote:
 Also, I do honor the right of reply.  If there's something I have 
 written that is now incorrect or inaccurate I will of course change 
 my page to reflect that.  Heck, all the comparisons in the world are 
 worthless if they aren't accurate!

Thanks for doing this, it's a nice comparison. But one error is that there is a dmd for Linux, and it's as fully supported and capable as the windows one. I use it all the time on Ubuntu.

Hmm, I didn't think that I was implying that it wasn't supported, but I have never gotten it to work satisfactorily on Linux with my usual entourage of libraries, so I just try and ignore it as me "not doing it right" again. I have clarified that part though, as after re-reading it I see how it could be taken the wrong way.

Thanks. But what is the issue you're running into with the Linux dmd?

Primarily that it's difficult (for me) to figure out how to get Tango and DSSS working with it. The compiler is only part of the story - in your defense, I got the //compiler// working just fine. It was my aforementioned entourage of libraries that stopped the party. If I remember correctly the showstopper was DWT. It was Linux 64, and DWT (at least at that point in time) wasn't yet 64-bit compatible. So it didn't work.
Jan 31 2009
parent Piotrek <starpit tlen.pl> writes:
Chris R Miller pisze:

 Primarily that it's difficult (for me) to figure out how to get Tango 
 and DSSS working with it.
 

If you like Debian/Ubuntu you can try: http://www.dsource.org/projects/tango/wiki/Debian But I also got working dmd on linux many times with manual installation (Tango/DWT). Of course I had to change some initial configuration entries.
 The compiler is only part of the story - in your defense, I got the 
 //compiler// working just fine.  It was my aforementioned entourage of 
 libraries that stopped the party.  If I remember correctly the 
 showstopper was DWT.  It was Linux 64, and DWT (at least at that point 
 in time) wasn't yet 64-bit compatible.  So it didn't work.

You can be right about 64-bit environment, I haven't tried it. But as long it does the job at the same time or even slower than 32-bit, I don't care (see http://shootout.alioth.debian.org/u32/benchmark.php?test=all&lang=gpp&lang2=gpp and http://shootout.alioth.debian.org/u64/benchmark.php?test=all& ang=gpp&lang2=gpp). But the works are in progress to have 64-bit in the future. Cheers Piotrek
Feb 01 2009
prev sibling next sibling parent reply Michel Fortin <michel.fortin michelf.com> writes:
On 2009-01-31 15:39:17 -0500, Chris R Miller 
<lordsauronthegreat gmail.com> said:

 Anyways, I decided to write up a comparison of the two languages from a 
 less technical, more deployment oriented standpoint.  IOW, examining 
 how well they perform for the last mile of development: deploying 
 software.

You talk about IDEs in there, and praise Xcode. Do you know about D for Xcode? <http://michelf.com/projects/d-for-xcode/> And since have you taken a look at my D/Objective-C bridge? <http://michelf.com/projects/d-objc/> Unfortunately, these two projects aren't getting much attention these days, mostly because I can't do much with the current state of the one D compiler that runs on my PowerPC iBook. One area I think Objective-C to be very great and that you haven't touched is for creating stable APIs. In Objective-C, contrary to D and C++, you don't have to recompile every dependency when reordering, adding and removing member functions in a class. In 64-bit Objective-C 2.0, you can even add variables to a class without care about recompiling derived classes. Compare that to D, where exposing a class as a public API will either force you to not change much that class, or force your users to recompile every time you make such a change.
 Also, I do honor the right of reply.  If there's something I have 
 written that is now incorrect or inaccurate I will of course change my 
 page to reflect that.  Heck, all the comparisons in the world are 
 worthless if they aren't accurate!

Well there's one error: "If you ignore Cocoa, then there is the GNUStep [gnustep.org] project, which is an Open-Source implementation of the old Carbon standard from NeXT Step." No. Carbon was created to ease port of classic Mac OS applications to Mac OS X. It's a revamped version of the Mac OS Toolbox, which got some additions as Mac OS X evolved. It has nothing to do with NeXT. <http://en.wikipedia.org/wiki/Carbon_(API)> -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Jan 31 2009
next sibling parent reply Chris R Miller <lordsauronthegreat gmail.com> writes:
Michel Fortin wrote:
 On 2009-01-31 15:39:17 -0500, Chris R Miller 
 <lordsauronthegreat gmail.com> said:
 
 Anyways, I decided to write up a comparison of the two languages from 
 a less technical, more deployment oriented standpoint.  IOW, examining 
 how well they perform for the last mile of development: deploying 
 software.

You talk about IDEs in there, and praise Xcode. Do you know about D for Xcode? <http://michelf.com/projects/d-for-xcode/>

I never got that working with Xcode 3.0, so I decided to ignore it.
 And since have you taken a look at my D/Objective-C bridge?
 <http://michelf.com/projects/d-objc/>

Unfortunately not. I don't have any compilable D code to bridge to Objective-C.
 Unfortunately, these two projects aren't getting much attention these 
 days, mostly because I can't do much with the current state of the one D 
 compiler that runs on my PowerPC iBook.

Hm, that'd certainly be an impediment to continuing work with D.
 One area I think Objective-C to be very great and that you haven't 
 touched is for creating stable APIs. In Objective-C, contrary to D and 
 C++, you don't have to recompile every dependency when reordering, 
 adding and removing member functions in a class. In 64-bit Objective-C 
 2.0, you can even add variables to a class without care about 
 recompiling derived classes. Compare that to D, where exposing a class 
 as a public API will either force you to not change much that class, or 
 force your users to recompile every time you make such a change.

Hm, I didn't know that. I'm not sure it is exactly pertinent to the main focus, which is towards quickly building software which can then be deployed to a user base relatively quickly and easily. I just glossed over some language features to give a small peek at the language's killer features according to me. D's most cool trick is the ability to implement the functionality of many data structures through use of its array syntax, and Objective-C is cool 'cause it's C with objects, sans all the crazy complexity that you run into with C++.
 Also, I do honor the right of reply.  If there's something I have 
 written that is now incorrect or inaccurate I will of course change my 
 page to reflect that.  Heck, all the comparisons in the world are 
 worthless if they aren't accurate!

Well there's one error: "If you ignore Cocoa, then there is the GNUStep [gnustep.org] project, which is an Open-Source implementation of the old Carbon standard from NeXT Step." No. Carbon was created to ease port of classic Mac OS applications to Mac OS X. It's a revamped version of the Mac OS Toolbox, which got some additions as Mac OS X evolved. It has nothing to do with NeXT. <http://en.wikipedia.org/wiki/Carbon_(API)>

Yikes, I'm just full of hot air today, aren't I? Fixed. :-)
Jan 31 2009
next sibling parent reply Michel Fortin <michel.fortin michelf.com> writes:
On 2009-01-31 17:03:10 -0500, Chris R Miller 
<lordsauronthegreat gmail.com> said:

 Michel Fortin wrote:
 On 2009-01-31 15:39:17 -0500, Chris R Miller 
 <lordsauronthegreat gmail.com> said:
 
 Anyways, I decided to write up a comparison of the two languages from a 
 less technical, more deployment oriented standpoint.  IOW, examining 
 how well they perform for the last mile of development: deploying 
 software.

You talk about IDEs in there, and praise Xcode. Do you know about D for Xcode? <http://michelf.com/projects/d-for-xcode/>

I never got that working with Xcode 3.0, so I decided to ignore it.

That's sad. There was a time where it didn't work with Xcode 3, but I've fixed that. If you still wish it to work, please test with the latest verision and send me be a bug report if you still have problems. I'm still fixing bugs when I know it c
 Unfortunately, these two projects aren't getting much attention these 
 days, mostly because I can't do much with the current state of the one 
 D compiler that runs on my PowerPC iBook.

Hm, that'd certainly be an impediment to continuing work with D.

Indeed.
 One area I think Objective-C to be very great and that you haven't 
 touched is for creating stable APIs. In Objective-C, contrary to D and 
 C++, you don't have to recompile every dependency when reordering, 
 adding and removing member functions in a class. In 64-bit Objective-C 
 2.0, you can even add variables to a class without care about 
 recompiling derived classes. Compare that to D, where exposing a class 
 as a public API will either force you to not change much that class, or 
 force your users to recompile every time you make such a change.

Hm, I didn't know that. I'm not sure it is exactly pertinent to the main focus, which is towards quickly building software which can then be deployed to a user base relatively quickly and easily. I just glossed over some language features to give a small peek at the language's killer features according to me. D's most cool trick is the ability to implement the functionality of many data structures through use of its array syntax, and Objective-C is cool 'cause it's C with objects, sans all the crazy complexity that you run into with C++.

No indeed. I was just mentionning something I admire very much about Objective-C which makes it very good to build stable yet evolving APIs. Something which neither C++ nor D has. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Jan 31 2009
parent Chris R Miller <lordsauronthegreat gmail.com> writes:
Michel Fortin wrote:
 On 2009-01-31 17:03:10 -0500, Chris R Miller 
 <lordsauronthegreat gmail.com> said:
 
 Michel Fortin wrote:
 On 2009-01-31 15:39:17 -0500, Chris R Miller 
 <lordsauronthegreat gmail.com> said:

 Anyways, I decided to write up a comparison of the two languages 
 from a less technical, more deployment oriented standpoint.  IOW, 
 examining how well they perform for the last mile of development: 
 deploying software.

You talk about IDEs in there, and praise Xcode. Do you know about D for Xcode? <http://michelf.com/projects/d-for-xcode/>

I never got that working with Xcode 3.0, so I decided to ignore it.

That's sad. There was a time where it didn't work with Xcode 3, but I've fixed that. If you still wish it to work, please test with the latest verision and send me be a bug report if you still have problems. I'm still fixing bugs when I know it c

I'll put it on the accumulator, though my magic 8-ball says "don't count on it." I've got school again... and this crazy teacher that has me print out all this stuff... killing trees left and right this guy is. Luckily we just got this fancy new printer with duplex, so that's a big relief (plus ADF Duplex scanning - FTW!)
 One area I think Objective-C to be very great and that you haven't 
 touched is for creating stable APIs. In Objective-C, contrary to D 
 and C++, you don't have to recompile every dependency when 
 reordering, adding and removing member functions in a class. In 
 64-bit Objective-C 2.0, you can even add variables to a class without 
 care about recompiling derived classes. Compare that to D, where 
 exposing a class as a public API will either force you to not change 
 much that class, or force your users to recompile every time you make 
 such a change.

Hm, I didn't know that. I'm not sure it is exactly pertinent to the main focus, which is towards quickly building software which can then be deployed to a user base relatively quickly and easily. I just glossed over some language features to give a small peek at the language's killer features according to me. D's most cool trick is the ability to implement the functionality of many data structures through use of its array syntax, and Objective-C is cool 'cause it's C with objects, sans all the crazy complexity that you run into with C++.

No indeed. I was just mentionning something I admire very much about Objective-C which makes it very good to build stable yet evolving APIs. Something which neither C++ nor D has.

Yup, someday someone will take the absolute best parts of all languages and make one big super-language. Until then... D is the closest I've seen to the one language to rule them all.
Jan 31 2009
prev sibling parent =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
Chris R Miller wrote:
 Michel Fortin wrote:

 Well there's one error:

 "If you ignore Cocoa, then there is the GNUStep [gnustep.org] project, 
 which is an Open-Source implementation of the old Carbon standard from 
 NeXT Step."

 No. Carbon was created to ease port of classic Mac OS applications to 
 Mac OS X. It's a revamped version of the Mac OS Toolbox, which got 
 some additions as Mac OS X evolved. It has nothing to do with NeXT.
 <http://en.wikipedia.org/wiki/Carbon_(API)>

Yikes, I'm just full of hot air today, aren't I? Fixed. :-)

If it matters, the name of the old standard was "OpenStep" and it was released by NeXT with Sun Microsystems in 1994. http://en.wikipedia.org/wiki/Openstep --anders
Feb 01 2009
prev sibling parent reply Walter Bright <newshound1 digitalmars.com> writes:
Michel Fortin wrote:
 One area I think Objective-C to be very great and that you haven't 
 touched is for creating stable APIs. In Objective-C, contrary to D and 
 C++, you don't have to recompile every dependency when reordering, 
 adding and removing member functions in a class. In 64-bit Objective-C 
 2.0, you can even add variables to a class without care about 
 recompiling derived classes. Compare that to D, where exposing a class 
 as a public API will either force you to not change much that class, or 
 force your users to recompile every time you make such a change.

If you use interfaces, you can add member fields without needing to recompile clients.
Jan 31 2009
parent reply Michel Fortin <michel.fortin michelf.com> writes:
On 2009-01-31 18:50:52 -0500, Walter Bright <newshound1 digitalmars.com> said:

 Michel Fortin wrote:
 One area I think Objective-C to be very great and that you haven't 
 touched is for creating stable APIs. In Objective-C, contrary to D and 
 C++, you don't have to recompile every dependency when reordering, 
 adding and removing member functions in a class. In 64-bit Objective-C 
 2.0, you can even add variables to a class without care about 
 recompiling derived classes. Compare that to D, where exposing a class 
 as a public API will either force you to not change much that class, or 
 force your users to recompile every time you make such a change.

If you use interfaces, you can add member fields without needing to recompile clients.

Yeah, indeed. I hadn't thought about that. That's a pretty interesting thing about interfaces now that you make me think about it. But exposing only interfaces makes the API harder to use. In Cocoa, classes gain new methods at each new version of the framework (read each version of Mac OS X) and it doesn't hinder programs compiled with earlier versions of the framework. If you had a smart enough dynamic linker and the signature of each function in the virtual table, you could do that in D too by creating virtual tables and updating offsets in the code accordingly while linking. (Objective-C doesn't work like that, but it has the same effect.) Alternativly, it could be done in some static initialisation phase. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Jan 31 2009
next sibling parent Daniel Keep <daniel.keep.lists gmail.com> writes:
Michel Fortin wrote:
 On 2009-01-31 18:50:52 -0500, Walter Bright <newshound1 digitalmars.com>
 said:
 
 Michel Fortin wrote:
 One area I think Objective-C to be very great and that you haven't
 touched is for creating stable APIs. In Objective-C, contrary to D
 and C++, you don't have to recompile every dependency when
 reordering, adding and removing member functions in a class. In
 64-bit Objective-C 2.0, you can even add variables to a class without
 care about recompiling derived classes. Compare that to D, where
 exposing a class as a public API will either force you to not change
 much that class, or force your users to recompile every time you make
 such a change.

If you use interfaces, you can add member fields without needing to recompile clients.

Yeah, indeed. I hadn't thought about that. That's a pretty interesting thing about interfaces now that you make me think about it. But exposing only interfaces makes the API harder to use. In Cocoa, classes gain new methods at each new version of the framework (read each version of Mac OS X) and it doesn't hinder programs compiled with earlier versions of the framework. If you had a smart enough dynamic linker and the signature of each function in the virtual table, you could do that in D too by creating virtual tables and updating offsets in the code accordingly while linking. (Objective-C doesn't work like that, but it has the same effect.) Alternativly, it could be done in some static initialisation phase.

Visual Basic (not this .NET malarkey) solved this problem by having a little checkbox in the project options labelled something like "Enable Binary Compatibility." Basically, when you compiled, it looked at the previous version of your library, and made sure that any new methods you'd added didn't stomp all over the old ones. -- Daniel
Jan 31 2009
prev sibling next sibling parent reply Chris R Miller <lordsauronthegreat gmail.com> writes:
Michel Fortin wrote:
 On 2009-01-31 18:50:52 -0500, Walter Bright <newshound1 digitalmars.com> 
 said:
 
 Michel Fortin wrote:
 One area I think Objective-C to be very great and that you haven't 
 touched is for creating stable APIs. In Objective-C, contrary to D 
 and C++, you don't have to recompile every dependency when 
 reordering, adding and removing member functions in a class. In 
 64-bit Objective-C 2.0, you can even add variables to a class without 
 care about recompiling derived classes. Compare that to D, where 
 exposing a class as a public API will either force you to not change 
 much that class, or force your users to recompile every time you make 
 such a change.

If you use interfaces, you can add member fields without needing to recompile clients.

Yeah, indeed. I hadn't thought about that. That's a pretty interesting thing about interfaces now that you make me think about it. But exposing only interfaces makes the API harder to use. In Cocoa, classes gain new methods at each new version of the framework (read each version of Mac OS X) and it doesn't hinder programs compiled with earlier versions of the framework. If you had a smart enough dynamic linker and the signature of each function in the virtual table, you could do that in D too by creating virtual tables and updating offsets in the code accordingly while linking. (Objective-C doesn't work like that, but it has the same effect.) Alternativly, it could be done in some static initialisation phase.

An increasingly interesting toy to study (I would think) would be Categories - the ability to take an existing class and just randomly tack on additional receivers. Perhaps this is exclusive to Objective-C's message-receiver architecture, but it's a curious little technology nonetheless.
Jan 31 2009
parent reply Michel Fortin <michel.fortin michelf.com> writes:
On 2009-01-31 20:51:57 -0500, Chris R Miller 
<lordsauronthegreat gmail.com> said:

 If you had a smart enough dynamic linker and the signature of each 
 function in the virtual table, you could do that in D too by creating 
 virtual tables and updating offsets in the code accordingly while 
 linking. (Objective-C doesn't work like that, but it has the same 
 effect.) Alternativly, it could be done in some static initialisation 
 phase.

An increasingly interesting toy to study (I would think) would be Categories - the ability to take an existing class and just randomly tack on additional receivers. Perhaps this is exclusive to Objective-C's message-receiver architecture, but it's a curious little technology nonetheless.

I'm sure we could add something like categories with what I'm proposing above. In fact, many people on this list have requested a way to write extensions to classes: more methods you can invoke using the dot syntax. Perhaps virtual tables built at runtime could allow people to write class extensions and still be able to override extension methods in subclasses. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Jan 31 2009
parent reply Jacob Carlborg <doob me.com> writes:
Michel Fortin wrote:
 On 2009-01-31 20:51:57 -0500, Chris R Miller 
 <lordsauronthegreat gmail.com> said:
 
 If you had a smart enough dynamic linker and the signature of each 
 function in the virtual table, you could do that in D too by creating 
 virtual tables and updating offsets in the code accordingly while 
 linking. (Objective-C doesn't work like that, but it has the same 
 effect.) Alternativly, it could be done in some static initialisation 
 phase.

An increasingly interesting toy to study (I would think) would be Categories - the ability to take an existing class and just randomly tack on additional receivers. Perhaps this is exclusive to Objective-C's message-receiver architecture, but it's a curious little technology nonetheless.

I'm sure we could add something like categories with what I'm proposing above. In fact, many people on this list have requested a way to write extensions to classes: more methods you can invoke using the dot syntax. Perhaps virtual tables built at runtime could allow people to write class extensions and still be able to override extension methods in subclasses.

It would be great if D could have categories/open classes and you could do something like this: class A { void foo () {} } class A { void bar () {} } void main () { auto a = new A; a.foo; a.bar; } And it should of course work on classes you don't have access to the source code.
Feb 01 2009
next sibling parent reply Walter Bright <newshound1 digitalmars.com> writes:
Jacob Carlborg wrote:
 It would be great if D could have categories/open classes and you could 
 do something like this:
 
 class A
 {
     void foo () {}
 }
 
 class A
 {
     void bar () {}
 }
 
 void main ()
 {
     auto a = new A;
     a.foo;
     a.bar;
 }
 
 And it should of course work on classes you don't have access to the 
 source code.

Setting aside the technical issues for the moment, isn't that exactly what inheritance is supposed to be good for?
Feb 01 2009
next sibling parent reply Jacob Carlborg <doob me.com> writes:
Walter Bright wrote:
 Jacob Carlborg wrote:
 It would be great if D could have categories/open classes and you 
 could do something like this:

 class A
 {
     void foo () {}
 }

 class A
 {
     void bar () {}
 }

 void main ()
 {
     auto a = new A;
     a.foo;
     a.bar;
 }

 And it should of course work on classes you don't have access to the 
 source code.

Setting aside the technical issues for the moment, isn't that exactly what inheritance is supposed to be good for?

A few times I've had the need for this, I've always been able to solve the problem but it would have been easier with support for this. But to be honest I don't remember these problems right now, so perhaps it's not that important.
Feb 02 2009
parent reply Chris R Miller <lordsauronthegreat gmail.com> writes:
Jacob Carlborg wrote:
 Walter Bright wrote:
 Setting aside the technical issues for the moment, isn't that exactly 
 what inheritance is supposed to be good for?

A few times I've had the need for this, I've always been able to solve the problem but it would have been easier with support for this. But to be honest I don't remember these problems right now, so perhaps it's not that important.

I think it has less to do with how often its needed and more to do with how much more elegant the solution will be. Just because I want to supply one example of where it's even appropriate to use a category-pattern to extend a class' function table without extending the class into a new type, I'll just spit out something I just wrote in Objective-C. ===== Short Story ===== I needed to search through a String (NSString) specifically to know whether a character at a specific index is any one of a given set of characters. Rather than subclass NSString, I decided to make a category: == NSString.h == #import <Cocoa/Cocoa.h> interface NSString (ACSExtensions) - (bool)characterAtIndex:(int)idx isOneOf:(NSString*)characters; end == NSString.m == #import "NSString.h" implementation NSString (ACSExtensions) - (bool)characterAtIndex:(int)idx isOneOf:(NSString*)characters { unichar *arr = malloc([characters length]*sizeof(unichar)); [characters getCharacters:arr]; char ch = [self characterAtIndex:idx]; int lp=([characters length]-1)/10,rm=[characters length]%10; switch(rm){ case 0: do { if(ch==arr[lp*10+9]) return YES; case 9: if(ch==arr[lp*10+8]) return YES; case 8: if(ch==arr[lp*10+7]) return YES; case 7: if(ch==arr[lp*10+6]) return YES; case 6: if(ch==arr[lp*10+5]) return YES; case 5: if(ch==arr[lp*10+4]) return YES; case 4: if(ch==arr[lp*10+3]) return YES; case 3: if(ch==arr[lp*10+2]) return YES; case 2: if(ch==arr[lp*10+1]) return YES; case 1: if(ch==arr[lp*10 ]) return YES; } while(0<--lp); break; } return NO; } end == end of file == As you can see, I added important functionality to the class NSString without going through all the trouble to make a new class and type cast between NSString and MyDerivedString all over the place. It's more transparent, and it's far better than a global function, or placing this kind of code into an unrelated class, or worse yet, a "kitchen-sink" class. ===== Special Extended Explanation ===== Since some of you may be in a hurry, this part is kind of secondary. The purpose for adding functionality to NSString is because I'm trying my hand at writing my own programming language (interpreted, but a language nonetheless). It's very rudimentary in syntax and capability, and it's only designed to script the effects of cards in a card game called Arcomage. I later extended some of its capabilities to make it suitable for AI scripting as well. Mind you I haven't implemented the language yet. I just wrote a specification that I'm now focusing on implementing. If you want to have a laugh or maybe see how badly I've been spoiled by D, you can read through the specsheet here: http://www.fsdev.net/~cmiller/pdf/acs_spec.pdf And I talk a bit on how I plan to implement such a system over here: http://www.fsdev.net/~cmiller/a/20090126_acsadv.html Anyways, the specific and immediate purpose for writing such functionality into NSString was so that I could - as I was parsing through the source script - quickly and easily check to see if characters are certain control characters. For instance, when searching for an integer, the first task is to read to the first numeric character. Two options: read to the first numeric character, or (more resistant to malformed code) read through all the whitespace characters and then if the next character isn't numeric, you have problems. What whitespace characters are there? \t \r \n (space) Unfortunately, they aren't in sequential order in the ASCII table, so it's not as simple as determining if char c is numeric: if ( c > '0' && c < '9' ) // c is numeric Therefore, it's useful for searching quickly, without getting into the potential mess that could be a regular expression search. Well, I'm sure for a lot of people it'd be shorter and more concise, but my relative ineptitude with regular expressions would make it far more bothersome for me. Am I here to write a language, or to teach myself regular expressions? Anyways, I'm really happy with the ensuing discussion about this - this is the entire reason why I decided to compare the two languages: in hopes of bringing up potentially useful features and getting people to think about them.
Feb 03 2009
next sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
Chris R Miller:
 As you can see, I added important functionality to the class NSString 
 without going through all the trouble to make a new class and type cast 
 between NSString and MyDerivedString all over the place.  It's more 
 transparent, and it's far better than a global function, or placing this 
 kind of code into an unrelated class, or worse yet, a "kitchen-sink" class.

Instead of using a "kitchen-sink" class, in D you can put such functionality into a module, like the string module of Phobos or similar libs. I don't know Object-C, what you have done looks like the "monkey patching" done sometimes in Ruby. Is this the same thing? "monkey patching" as done in Ruby has several disadvantages and dangers. Time ago I have read that there's a simple enough way to remove most of the dangers from monkey patching: make it scoped. So the changes to the classes can be seen just inside a scope (and its subscopes) and not outside it. Bye, bearophile
Feb 04 2009
parent reply Michel Fortin <michel.fortin michelf.com> writes:
On 2009-02-04 04:13:38 -0500, bearophile <bearophileHUGS lycos.com> said:

 Instead of using a "kitchen-sink" class, in D you can put such 
 functionality into a module, like the string module of Phobos or 
 similar libs.
 
 I don't know Object-C, what you have done looks like the "monkey 
 patching" done sometimes in Ruby. Is this the same thing?
 "monkey patching" as done in Ruby has several disadvantages and 
 dangers. Time ago I have read that there's a simple enough way to 
 remove most of the dangers from monkey patching: make it scoped. So the 
 changes to the classes can be seen just inside a scope (and its 
 subscopes) and not outside it.

From Wikipedia <http://en.wikipedia.org/wiki/Monkey_patching>: "In Ruby, the term monkey patch means any dynamic modification to a class and is often used as a synonym for dynamically modifying any class at runtime." Categories are indeed monkey patching according to this definition. Indeed, the way categories work in Objective-C, there is some risk that NSString could gain a function of the same name in a future version of the Foundation framework, and in that case the category-defined method will override the "official" one, so unless you give it a name like MF_myMethod (sort of namespacing it with your own prefix), there is a risk of clash. That said, with the extension syntax I proposed for class extensions in D, you wouldn't have that problem (if implemented correctly) because the compiler would always know from where the function is comming and could therfore generate code so that the right function is called even if a function of the same name is added to the underlying library. Hum, perhaps this needs more explaination. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Feb 04 2009
parent bearophile <bearophileHUGS lycos.com> writes:
Michel Fortin:
 with the extension syntax I proposed for class extensions in 
 D, you wouldn't have that problem (if implemented correctly) because 
 the compiler would always know from where the function is comming and 
 could therfore generate code so that the right function is called even 
 if a function of the same name is added to the underlying library. Hum, 
 perhaps this needs more explaination.

It sounds like the "scoped monkey patching" I was talking about :-) Bye, bearophile
Feb 04 2009
prev sibling next sibling parent reply Michel Fortin <michel.fortin michelf.com> writes:
On 2009-02-04 01:36:59 -0500, Chris R Miller 
<lordsauronthegreat gmail.com> said:

 Unfortunately, they aren't in sequential order in the ASCII table, so 
 it's not as simple as determining if char c is numeric:
 
 if ( c > '0' && c < '9' ) // c is numeric
 
 Therefore, it's useful for searching quickly, without getting into the 
 potential mess that could be a regular expression search.  Well, I'm 
 sure for a lot of people it'd be shorter and more concise, but my 
 relative ineptitude with regular expressions would make it far more 
 bothersome for me.  Am I here to write a language, or to teach myself 
 regular expressions?

Perhaps it's offtopic in a D forum, but you should use the class NSCharacterSet for that if you want to be efficient. There's a couple of methods in NSString accepting NSCharacterSet too which you may be interested in if you're writing a parser. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Feb 04 2009
parent "Nick Sabalausky" <a a.a> writes:
"Michel Fortin" <michel.fortin michelf.com> wrote in message 
news:gmbt40$18pb$2 digitalmars.com...
 Perhaps it's offtopic in a D forum, but you should use the class 
 NSCharacterSet for that if you want to be efficient. There's a couple of 
 methods in NSString accepting NSCharacterSet too which you may be 
 interested in if you're writing a parser.

Nick Sabalausky is curious what the "NS" stands for in "NSString" and "NSCharacterSet"...?
Feb 04 2009
prev sibling parent reply Sean Kelly <sean invisibleduck.org> writes:
Chris R Miller wrote:
 Jacob Carlborg wrote:
 Walter Bright wrote:
 Setting aside the technical issues for the moment, isn't that exactly 
 what inheritance is supposed to be good for?

A few times I've had the need for this, I've always been able to solve the problem but it would have been easier with support for this. But to be honest I don't remember these problems right now, so perhaps it's not that important.

I think it has less to do with how often its needed and more to do with how much more elegant the solution will be. Just because I want to supply one example of where it's even appropriate to use a category-pattern to extend a class' function table without extending the class into a new type, I'll just spit out something I just wrote in Objective-C. ===== Short Story ===== I needed to search through a String (NSString) specifically to know whether a character at a specific index is any one of a given set of characters. Rather than subclass NSString, I decided to make a category: [snip]

Won't all of this be solved by the planned D2 feature of making these operations synonymous for all types? void fn(T val); T t; fn(t); t.fn(); Or are you saying that these added functions can actually access private data in the class? Sean
Feb 04 2009
parent Chris R Miller <lordsauronthegreat gmail.com> writes:
Sean Kelly wrote:
 Chris R Miller wrote:
 ===== Short Story =====

 I needed to search through a String (NSString) specifically to know 
 whether a character at a specific index is any one of a given set of 
 characters.  Rather than subclass NSString, I decided to make a category:

Won't all of this be solved by the planned D2 feature of making these operations synonymous for all types? void fn(T val); T t; fn(t); t.fn(); Or are you saying that these added functions can actually access private data in the class?

Yes, they can access private data. I see how this could be both a feature and a potential hazard. Then again, do you not need to be careful when subclassing things in Java-style OO languages? Otherwise you can very easily mire yourself in a world of objects that end up hindering more than helping. And just to prove D's potency, the very algorithm I used was stolen from something I wrote in D not long ago: ====== DuffsDevice.d ====== module duffsdevice; import tango.io.Stdout; /// tells if anything in the contents of arr1 are present in arr2 /// uses type implicit opCmp for comparison bool hasAnyOf(T)(T[] arr1,T[] arr2){ T[] small,large; if(arr1.length>arr2.length){ large=arr1;small=arr2; }else{ large=arr2;small=arr1; } int lp,rm=large.length%10; foreach(T t;small){ lp=(large.length-1)/10; switch(rm){ case 0: do{ if(t==large[lp*10+9]) return true; case 9: if(t==large[lp*10+8]) return true; case 8: if(t==large[lp*10+7]) return true; case 7: if(t==large[lp*10+6]) return true; case 6: if(t==large[lp*10+5]) return true; case 5: if(t==large[lp*10+4]) return true; case 4: if(t==large[lp*10+3]) return true; case 3: if(t==large[lp*10+2]) return true; case 2: if(t==large[lp*10+1]) return true; case 1: if(t==large[lp*10 ]) return true; }while(0<--lp); break; } } return false; } void main(char[][] argc) { if(argc.length>2) { Stdout("argc[0]=={}",argc[1]).newline; Stdout("argc[1]=={}",argc[2]).newline; Stdout("hasAnyOf!(char[])(argc[0],argc[1])=={}", hasAnyOf!(char)(argc[1],argc[2])).newline; } } ====== EOF ====== Personally I prefer the D to the Objective-C implementation.
Feb 04 2009
prev sibling next sibling parent reply grauzone <none example.net> writes:
Walter Bright wrote:
 Jacob Carlborg wrote:
 It would be great if D could have categories/open classes and you 
 could do something like this:

 class A
 {
     void foo () {}
 }

 class A
 {
     void bar () {}
 }

 void main ()
 {
     auto a = new A;
     a.foo;
     a.bar;
 }

 And it should of course work on classes you don't have access to the 
 source code.

Setting aside the technical issues for the moment, isn't that exactly what inheritance is supposed to be good for?

Consider the above example is written as
 class A { int foo; }
 class B : A { int bar; }

The point is, that your code might need to associate additional data to class A. You could inherit from that class, and simply add the fields you need (in this case "bar"). (It's almost the same for virtual methods, just that virtual methods are like additional fields in the class' vtable, or something like this.) Here's my arguments why inheritance isn't a general or elegant enough solution: 1. If you want to extend a class with inheritance, you need to have control about how the class is instantiated, so that you can insert your "new B();". That's trivial in Jacob's example code. But if the "new A();" line is hidden somewhere inside the foreign code, you obviously can't extend the class; the foreign code will give you only not-extended class instances. You can't cast them to B. 2. If A (or any other classes) has methods or properties, which have A as return type, you'll probably end up having to cast from A to B each time you want to use your extensions. 3. Inheritance works only once. There can't be two independent modules, which both extend the class A. At least not if these two modules want to use the same object instances. (Although the modules are independent, they both depend and use the module which provides class A, and might indirectly exchange object references through it. If both modules need to "extend" them, it won't work.) The closest to achieve something that doesn't have the above mentioned problems, is to use a map with the object as key. For example:
 int[A] bar;

So whenever you need "bar" as additional field for A, you do an AA lookup with the object reference as key. But this approach has performance and garbage collection problems, and it looks a bit ugly. The question is, is there a solution, which is both aesthetically and technically better?
Feb 02 2009
next sibling parent grauzone <none example.net> writes:
 The question is, is there a solution, which is both 
 aesthetically and technically better?

PS: in dynamic languages, this capability is built-in. If you want an object to have an additional field, you can add that field dynamically.
Feb 02 2009
prev sibling parent reply "Nick Sabalausky" <a a.a> writes:
"grauzone" <none example.net> wrote in message 
news:gm7pa1$2tjg$1 digitalmars.com...
 Walter Bright wrote:
 Jacob Carlborg wrote:
 It would be great if D could have categories/open classes and you could 
 do something like this:

 class A
 {
     void foo () {}
 }

 class A
 {
     void bar () {}
 }

 void main ()
 {
     auto a = new A;
     a.foo;
     a.bar;
 }

 And it should of course work on classes you don't have access to the 
 source code.

Setting aside the technical issues for the moment, isn't that exactly what inheritance is supposed to be good for?

Consider the above example is written as
 class A { int foo; }
 class B : A { int bar; }

The point is, that your code might need to associate additional data to class A. You could inherit from that class, and simply add the fields you need (in this case "bar"). (It's almost the same for virtual methods, just that virtual methods are like additional fields in the class' vtable, or something like this.) Here's my arguments why inheritance isn't a general or elegant enough solution: 1. If you want to extend a class with inheritance, you need to have control about how the class is instantiated, so that you can insert your "new B();". That's trivial in Jacob's example code. But if the "new A();" line is hidden somewhere inside the foreign code, you obviously can't extend the class; the foreign code will give you only not-extended class instances. You can't cast them to B. 2. If A (or any other classes) has methods or properties, which have A as return type, you'll probably end up having to cast from A to B each time you want to use your extensions. 3. Inheritance works only once. There can't be two independent modules, which both extend the class A. At least not if these two modules want to use the same object instances. (Although the modules are independent, they both depend and use the module which provides class A, and might indirectly exchange object references through it. If both modules need to "extend" them, it won't work.) The closest to achieve something that doesn't have the above mentioned problems, is to use a map with the object as key. For example:
 int[A] bar;

So whenever you need "bar" as additional field for A, you do an AA lookup with the object reference as key. But this approach has performance and garbage collection problems, and it looks a bit ugly. The question is, is there a solution, which is both aesthetically and technically better?

Umm, go into class A and add whatever you need?
Feb 02 2009
parent reply grauzone <none example.net> writes:
Nick Sabalausky wrote:
 "grauzone" <none example.net> wrote in message 
 news:gm7pa1$2tjg$1 digitalmars.com...
 Walter Bright wrote:
 Jacob Carlborg wrote:
 It would be great if D could have categories/open classes and you could 
 do something like this:

 class A
 {
     void foo () {}
 }

 class A
 {
     void bar () {}
 }

 void main ()
 {
     auto a = new A;
     a.foo;
     a.bar;
 }

 And it should of course work on classes you don't have access to the 
 source code.

what inheritance is supposed to be good for?

 class A { int foo; }
 class B : A { int bar; }

class A. You could inherit from that class, and simply add the fields you need (in this case "bar"). (It's almost the same for virtual methods, just that virtual methods are like additional fields in the class' vtable, or something like this.) Here's my arguments why inheritance isn't a general or elegant enough solution: 1. If you want to extend a class with inheritance, you need to have control about how the class is instantiated, so that you can insert your "new B();". That's trivial in Jacob's example code. But if the "new A();" line is hidden somewhere inside the foreign code, you obviously can't extend the class; the foreign code will give you only not-extended class instances. You can't cast them to B. 2. If A (or any other classes) has methods or properties, which have A as return type, you'll probably end up having to cast from A to B each time you want to use your extensions. 3. Inheritance works only once. There can't be two independent modules, which both extend the class A. At least not if these two modules want to use the same object instances. (Although the modules are independent, they both depend and use the module which provides class A, and might indirectly exchange object references through it. If both modules need to "extend" them, it won't work.) The closest to achieve something that doesn't have the above mentioned problems, is to use a map with the object as key. For example:
 int[A] bar;

with the object reference as key. But this approach has performance and garbage collection problems, and it looks a bit ugly. The question is, is there a solution, which is both aesthetically and technically better?

Umm, go into class A and add whatever you need?

Maybe I can't, because it's foreign code. Changing it might increase maintenance overhead, require recompilation of libraries, might introduce additional module dependencies, which in the worst case lead to cyclic dependencies or dependencies from a library into the application, and so on. You also might want to separate different pieces of code that work on the same object. Sometimes, that code might need to dispatch a function depending on the object type (aka virtual methods), or even need to associate its own data to an object.
Feb 02 2009
parent reply Daniel Keep <daniel.keep.lists gmail.com> writes:
grauzone wrote:
 Nick Sabalausky wrote:
 [snip]

 Umm, go into class A and add whatever you need? 

Maybe I can't, because it's foreign code. Changing it might increase maintenance overhead, require recompilation of libraries, might introduce additional module dependencies, which in the worst case lead to cyclic dependencies or dependencies from a library into the application, and so on.

I've heard this argument before, and it's always confused me. How are you going to expand a class that you don't have (or have, but don't want to change) the source of? Your foreign library will create instances at a certain size, with a certain vtable, etc. The only way I can see that you could change the instantiated objects would be to subvert it's object creation code. But how are you going to do that when the library has already been compiled? You could put all the ctors into a shared module somewhere, but at that point you no longer need partial classes, since you can simply replace the class with an entirely different one like, say, a subclass. And if your library doesn't create instances, then you can just use inheritance straight up. There's the argument that it lets you add functionality to a class you use but don't manage yourself, but generalised function syntax (a(b,...) -> b.a(...)) takes care of that for everything. The only argument I've ever seen that held water was to separate the implementation of a class among multiple files. But we have template mixins to do that. I'm not saying it wouldn't be useful, I just can't see any legitimate reason for it that is either technically possible, or that you can't already fulfil some other way. -- Daniel
Feb 02 2009
parent grauzone <none example.net> writes:
Daniel Keep wrote:
 grauzone wrote:
 Nick Sabalausky wrote:
 [snip]

 Umm, go into class A and add whatever you need? 

maintenance overhead, require recompilation of libraries, might introduce additional module dependencies, which in the worst case lead to cyclic dependencies or dependencies from a library into the application, and so on.

I've heard this argument before, and it's always confused me. How are you going to expand a class that you don't have (or have, but don't want to change) the source of?

You say that as if this was impossible. In the most primitive way, you'd do something like ClassInfo.init.length += 1 to extend a class by one byte and use the old length as offset to your own data. Of course, in reality, it's not that simple. By the way, AspectJ can do this at link time, and all dynamic languages at runtime.
 Your foreign library will create instances at a certain size, with a
 certain vtable, etc.  The only way I can see that you could change the
 instantiated objects would be to subvert it's object creation code.  But
 how are you going to do that when the library has already been compiled?

The object creation code could call a library routine, which checks the other modules linked to the program? Again, it's not that hard to come up with a naive approach.
 You could put all the ctors into a shared module somewhere, but at that
 point you no longer need partial classes, since you can simply replace
 the class with an entirely different one like, say, a subclass.
 
 And if your library doesn't create instances, then you can just use
 inheritance straight up.

The point of this approach is to avoid all this.
 There's the argument that it lets you add functionality to a class you
 use but don't manage yourself, but generalised function syntax (a(b,...)
 -> b.a(...)) takes care of that for everything.

Lacks virtual methods.
 The only argument I've ever seen that held water was to separate the
 implementation of a class among multiple files.  But we have template
 mixins to do that.

Template mixins are a horrible thing to do this. Even using mixin(import("include.inc")) causes less problems. (By the way, maybe D should abandon the module principle and compile several D source files at once to an "assembly". Then distributing a class implementation over several source files would be as simple as in C#. Maybe this also would fix all of the circular module dependency bugs by not allowing circular dependencies as compilation units.)
 I'm not saying it wouldn't be useful, I just can't see any legitimate
 reason for it that is either technically possible, or that you can't
 already fulfil some other way.
 
   -- Daniel

Feb 04 2009
prev sibling parent reply Michel Fortin <michel.fortin michelf.com> writes:
On 2009-02-01 14:45:58 -0500, Walter Bright <newshound1 digitalmars.com> said:

 Setting aside the technical issues for the moment, isn't that exactly 
 what inheritance is supposed to be good for?

I'll attempt a better example of something useful with class extensions. Say you have these classes: class Node { string path(); string name(); } class File : Node { ... } class Directory : Node { Node[] children(); ... } And a couple of functions returning directories and files: File getConfigFile(); Directory getResourceDirectory(); Directory getDataDirectory(); Now, you may not have control over these functions, if you subclass File or Directory to do what you want, it won't cause these functions to magically create instances of your class. Say you want to implement a backup function traversing the filesystem tree. In Objective-C, I'd simply create a category adding a new method. If you had something like it in D, it could look like this: extension NodeBackup : Node { void backup(string backupPath) { } } Where I'm extending Node with an extension named NodeBackup, allowing me to call the backup function as if it was a member of Node. From there, I create another extension for File, overriding the backup function provided by NodeBackup: extension FileBackup : NodeBackup, File { override void backup(string backupPath) { copy(this.path, backupPath ~ "/" ~ this.name); } } And so on for Directory. extension DirectoryBackup : NodeBackup, Directory { override void backup(string backupPath) { foreach(child; children) child.backup(backupPath ~ "/" ~ this.name); } } All this you can do with the visitor pattern if you need to. But the visitor pattern is a lot more clumbersome to implement, and much less natural to use... getDataDirectory.backup("/backup_disk"); vs. something like this: getDataDirectory.accept(new BackupVisitor("/backup_disk")); -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Feb 02 2009
parent reply Daniel Keep <daniel.keep.lists gmail.com> writes:
Michel Fortin wrote:
 [stuff]

Wouldn't this be just as well served with Walter's "universal function syntax"; ie: void backup(File this, string backupPath) { copy(this.path, backupPath ~ "/" ~ this.name); } File someFile; someFile.backup(backupPath); I know Walter was planning on adding this (it already works on arrays) but hasn't mentioned it in a while. -- Daniel
Feb 02 2009
parent reply Michel Fortin <michel.fortin michelf.com> writes:
On 2009-02-02 21:19:52 -0500, Daniel Keep <daniel.keep.lists gmail.com> said:

 
 
 Michel Fortin wrote:
 [stuff]

Wouldn't this be just as well served with Walter's "universal function syntax"; ie: void backup(File this, string backupPath) { copy(this.path, backupPath ~ "/" ~ this.name); } File someFile; someFile.backup(backupPath);

It would work in your example, but not in mine. Note the difference: foreach(child; children) child.backup(backupPath ~ "/" ~ this.name); Statically, child is a Node here. If at runtime child is a File, the backup function is overriden by the FileBackup extension of File, so it'd call the backup function from FileBackup, not NodeBackup. If at runtime child is a Directory, it'll call DirectoryBackup's backup function. At least, that's what it would do in Objective-C using categories. And that's why you don't need the visitor pattern in Objective-C. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Feb 02 2009
next sibling parent Daniel Keep <daniel.keep.lists gmail.com> writes:
Michel Fortin wrote:
 On 2009-02-02 21:19:52 -0500, Daniel Keep <daniel.keep.lists gmail.com>
 said:
 
 Michel Fortin wrote:
 [stuff]

Wouldn't this be just as well served with Walter's "universal function syntax"; ie: void backup(File this, string backupPath) { copy(this.path, backupPath ~ "/" ~ this.name); } File someFile; someFile.backup(backupPath);

It would work in your example, but not in mine. Note the difference: foreach(child; children) child.backup(backupPath ~ "/" ~ this.name); Statically, child is a Node here. If at runtime child is a File, the backup function is overriden by the FileBackup extension of File, so it'd call the backup function from FileBackup, not NodeBackup. If at runtime child is a Directory, it'll call DirectoryBackup's backup function. At least, that's what it would do in Objective-C using categories. And that's why you don't need the visitor pattern in Objective-C.

Aaah, yes. -- Daniel
Feb 02 2009
prev sibling parent reply "Nick Sabalausky" <a a.a> writes:
"Michel Fortin" <michel.fortin michelf.com> wrote in message 
news:gm8dhq$sj7$1 digitalmars.com...
 On 2009-02-02 21:19:52 -0500, Daniel Keep <daniel.keep.lists gmail.com> 
 said:

 Michel Fortin wrote:
 [stuff]

Wouldn't this be just as well served with Walter's "universal function syntax"; ie: void backup(File this, string backupPath) { copy(this.path, backupPath ~ "/" ~ this.name); } File someFile; someFile.backup(backupPath);

It would work in your example, but not in mine. Note the difference: foreach(child; children) child.backup(backupPath ~ "/" ~ this.name); Statically, child is a Node here. If at runtime child is a File, the backup function is overriden by the FileBackup extension of File, so it'd call the backup function from FileBackup, not NodeBackup. If at runtime child is a Directory, it'll call DirectoryBackup's backup function. At least, that's what it would do in Objective-C using categories. And that's why you don't need the visitor pattern in Objective-C. -- Michel Fortin michel.fortin michelf.com http://michelf.com/

I had been slowly coming around to the idea of having that universal function syntax instead of C#-style explicit extension methods, but maybe this need for dynamic dispatch is a good reason to prefer explicit extension methods: // As in C#, the "this" means backup() is an extension method void backup(this Node obj, string backupPath) { // base impl } void backup(this File obj, string backupPath) { copy(obj.path, backupPath ~ "/" ~ obj.name); } void backup(this Directory obj, string backupPath) { foreach(child; children) child.backup(backupPath ~ "/" ~ obj.name); } I'm not exactly sure what C# does in this case, but what I'm proposing here is that this could (somehow) cause dynamic dispatch to be used. Maybe by adding "backup" to appropriate vtables or automatically generating something like this that gets swapped in wherever "backup" is called: void _backup(this Object obj, string backupPath) { if(cast(File)obj) backup(cast(File)obj, backupPath); else if(cast(Directory)obj) backup(cast(Directory)obj, backupPath); else if(cast(Object)obj) backup(cast(Object)obj, backupPath); else if(obj is null) throw new NullPointerException(); else { /* shouldn't happen unless compiler's static type checking messed up */ } } Or something else to that general effect.
Feb 02 2009
next sibling parent reply "Nick Sabalausky" <a a.a> writes:
"Nick Sabalausky" <a a.a> wrote in message 
news:gm8pul$1eei$1 digitalmars.com...
 "Michel Fortin" <michel.fortin michelf.com> wrote in message 
 news:gm8dhq$sj7$1 digitalmars.com...
 On 2009-02-02 21:19:52 -0500, Daniel Keep <daniel.keep.lists gmail.com> 
 said:

 Michel Fortin wrote:
 [stuff]

Wouldn't this be just as well served with Walter's "universal function syntax"; ie: void backup(File this, string backupPath) { copy(this.path, backupPath ~ "/" ~ this.name); } File someFile; someFile.backup(backupPath);

It would work in your example, but not in mine. Note the difference: foreach(child; children) child.backup(backupPath ~ "/" ~ this.name); Statically, child is a Node here. If at runtime child is a File, the backup function is overriden by the FileBackup extension of File, so it'd call the backup function from FileBackup, not NodeBackup. If at runtime child is a Directory, it'll call DirectoryBackup's backup function. At least, that's what it would do in Objective-C using categories. And that's why you don't need the visitor pattern in Objective-C. -- Michel Fortin michel.fortin michelf.com http://michelf.com/

I had been slowly coming around to the idea of having that universal function syntax instead of C#-style explicit extension methods, but maybe this need for dynamic dispatch is a good reason to prefer explicit extension methods: // As in C#, the "this" means backup() is an extension method void backup(this Node obj, string backupPath) { // base impl } void backup(this File obj, string backupPath) { copy(obj.path, backupPath ~ "/" ~ obj.name); } void backup(this Directory obj, string backupPath) { foreach(child; children) child.backup(backupPath ~ "/" ~ obj.name); } I'm not exactly sure what C# does in this case, but what I'm proposing here is that this could (somehow) cause dynamic dispatch to be used.

Out of curiosity, I just did a little test on this in C#. Apperently it doesn't do any dynamic dispatch on this, it just calls the extension method overload for whatever the static type is. public class Base { } public class Sub : Base { } public static class ExtensionMethods { public static void foo(this Base obj) { System.Console.WriteLine("foo(Base)"); } public static void foo(this Sub obj) { System.Console.WriteLine("foo(Sub)"); } } class Program { static void Main(string[] args) { Base obj = new Sub(); obj.foo(); // Output: foo(Base) } }
Feb 02 2009
parent Michel Fortin <michel.fortin michelf.com> writes:
On 2009-02-03 02:15:16 -0500, "Nick Sabalausky" <a a.a> said:

 "Nick Sabalausky" <a a.a> wrote in message
 news:gm8pul$1eei$1 digitalmars.com...
 I had been slowly coming around to the idea of having that universal
 function syntax instead of C#-style explicit extension methods, but maybe
 this need for dynamic dispatch is a good reason to prefer explicit
 extension methods:
 
 // As in C#, the "this" means backup() is an extension method
 void backup(this Node obj, string backupPath)
 {
 // base impl
 }
 void backup(this File obj, string backupPath)
 {
 copy(obj.path, backupPath ~ "/" ~ obj.name);
 }
 void backup(this Directory obj, string backupPath)
 {
 foreach(child; children)
 child.backup(backupPath ~ "/" ~ obj.name);
 }
 
 I'm not exactly sure what C# does in this case, but what I'm proposing
 here is that this could (somehow) cause dynamic dispatch to be used.

Out of curiosity, I just did a little test on this in C#. Apperently it doesn't do any dynamic dispatch on this, it just calls the extension method overload for whatever the static type is.

Great. :-) An area where we could surpass C# by just making things work the way they should. Although I'm somewhat doubtful we'll see Walter going away from the simple C++-like vtable design needed for implementing this. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Feb 03 2009
prev sibling parent Don <nospam nospam.com> writes:
Nick Sabalausky wrote:
 "Michel Fortin" <michel.fortin michelf.com> wrote in message 
 news:gm8dhq$sj7$1 digitalmars.com...
 On 2009-02-02 21:19:52 -0500, Daniel Keep <daniel.keep.lists gmail.com> 
 said:

 Michel Fortin wrote:
 [stuff]

syntax"; ie: void backup(File this, string backupPath) { copy(this.path, backupPath ~ "/" ~ this.name); } File someFile; someFile.backup(backupPath);

foreach(child; children) child.backup(backupPath ~ "/" ~ this.name); Statically, child is a Node here. If at runtime child is a File, the backup function is overriden by the FileBackup extension of File, so it'd call the backup function from FileBackup, not NodeBackup. If at runtime child is a Directory, it'll call DirectoryBackup's backup function. At least, that's what it would do in Objective-C using categories. And that's why you don't need the visitor pattern in Objective-C. -- Michel Fortin michel.fortin michelf.com http://michelf.com/

I had been slowly coming around to the idea of having that universal function syntax instead of C#-style explicit extension methods, but maybe this need for dynamic dispatch is a good reason to prefer explicit extension methods:

I think that allowing interfaces to be declared AFTER the objects which satify them, would be a more general solution. Create a vtable, fill it with all the entries from the object's vtable, and add any extra functions you want. Then you could allow structs to support interfaces, for example.
Feb 03 2009
prev sibling parent "Nick Sabalausky" <a a.a> writes:
"Jacob Carlborg" <doob me.com> wrote in message 
news:gm4fsm$kds$1 digitalmars.com...
 Michel Fortin wrote:
 On 2009-01-31 20:51:57 -0500, Chris R Miller 
 <lordsauronthegreat gmail.com> said:

 If you had a smart enough dynamic linker and the signature of each 
 function in the virtual table, you could do that in D too by creating 
 virtual tables and updating offsets in the code accordingly while 
 linking. (Objective-C doesn't work like that, but it has the same 
 effect.) Alternativly, it could be done in some static initialisation 
 phase.

An increasingly interesting toy to study (I would think) would be Categories - the ability to take an existing class and just randomly tack on additional receivers. Perhaps this is exclusive to Objective-C's message-receiver architecture, but it's a curious little technology nonetheless.

I'm sure we could add something like categories with what I'm proposing above. In fact, many people on this list have requested a way to write extensions to classes: more methods you can invoke using the dot syntax. Perhaps virtual tables built at runtime could allow people to write class extensions and still be able to override extension methods in subclasses.

It would be great if D could have categories/open classes and you could do something like this: class A { void foo () {} } class A { void bar () {} } void main () { auto a = new A; a.foo; a.bar; } And it should of course work on classes you don't have access to the source code.

That's similar to C#'s partial classes: // Error class A { void foo () {} } class A { void bar () {} } // Ok partial class B { void foo () {} } partial class B { void bar () {} }
Feb 01 2009
prev sibling parent reply Bill Baxter <wbaxter gmail.com> writes:
On Thu, Feb 5, 2009 at 3:55 AM, Nick Sabalausky <a a.a> wrote:
 "Michel Fortin" <michel.fortin michelf.com> wrote in message
 news:gmbt40$18pb$2 digitalmars.com...
 Perhaps it's offtopic in a D forum, but you should use the class
 NSCharacterSet for that if you want to be efficient. There's a couple of
 methods in NSString accepting NSCharacterSet too which you may be
 interested in if you're writing a parser.

Nick Sabalausky is curious what the "NS" stands for in "NSString" and "NSCharacterSet"...?

I believe it is for "NextStep". --bb
Feb 04 2009
parent reply John Reimer <terminal.node gmail.com> writes:
Hello Bill,

 On Thu, Feb 5, 2009 at 3:55 AM, Nick Sabalausky <a a.a> wrote:
 
 "Michel Fortin" <michel.fortin michelf.com> wrote in message
 news:gmbt40$18pb$2 digitalmars.com...
 
 Perhaps it's offtopic in a D forum, but you should use the class
 NSCharacterSet for that if you want to be efficient. There's a
 couple of methods in NSString accepting NSCharacterSet too which you
 may be interested in if you're writing a parser.
 

"NSCharacterSet"...?

--bb

I'm pretty sure that is the case. That's one element, though, that I find annoying about the language libraries. I think the notation looks ugly. Sorry Nick, it doesn't stand for "Nick Sabalausky". ;D -JJR
Feb 04 2009
parent "Nick Sabalausky" <a a.a> writes:
"John Reimer" <terminal.node gmail.com> wrote in message 
news:28b70f8c139c58cb5508b9b1b790 news.digitalmars.com...
 Hello Bill,

 On Thu, Feb 5, 2009 at 3:55 AM, Nick Sabalausky <a a.a> wrote:

 "Michel Fortin" <michel.fortin michelf.com> wrote in message
 news:gmbt40$18pb$2 digitalmars.com...

 Perhaps it's offtopic in a D forum, but you should use the class
 NSCharacterSet for that if you want to be efficient. There's a
 couple of methods in NSString accepting NSCharacterSet too which you
 may be interested in if you're writing a parser.

"NSCharacterSet"...?


I'm pretty sure that is the case. That's one element, though, that I find annoying about the language libraries. I think the notation looks ugly. Sorry Nick, it doesn't stand for "Nick Sabalausky". ;D

Dang, and here I was so sure I had created Cocoa and just forgot about it ;) But seriously though, I would find that sooo distracting/confusing if I ever wrote anything in Cocoa, not just because of having the same extra couple letters prepended to everything, but because any time I see "NS" anywhere, my mind automatically parses that as "me". "What? I don't remember writing this...Oh, right."
Feb 04 2009
prev sibling next sibling parent reply Christopher Wright <dhasenan gmail.com> writes:
It seems that your only significant complaint about Descent is that it 
is not integrated with DSSS. I believe you can set up DSSS as an 
external task in Eclipse:
http://dsource.org/projects/descent/wiki/CompilingPrograms

I believe this will call dsss (or whatever program you specify) on the 
current file, however.
Jan 31 2009
parent reply Chris R Miller <lordsauronthegreat gmail.com> writes:
Christopher Wright wrote:
 It seems that your only significant complaint about Descent is that it 
 is not integrated with DSSS. I believe you can set up DSSS as an 
 external task in Eclipse:
 http://dsource.org/projects/descent/wiki/CompilingPrograms
 
 I believe this will call dsss (or whatever program you specify) on the 
 current file, however.

Yes, I looked into that before... I never was able to make it work. I've used Eclipse for a long, long, long time, and if I and my heavy Java/Eclipse background and experience can't make it work... a comparative newbie looking to build something quick and show the world isn't going to get that to work, either. Then again, regression towards the mean would suggest that I could be very, very mistaken...
Jan 31 2009
parent Piotrek <starpit tlen.pl> writes:
Chris R Miller linux:
 Christopher Wright wrote:
 It seems that your only significant complaint about Descent is that it 
 is not integrated with DSSS. I believe you can set up DSSS as an 
 external task in Eclipse:
 http://dsource.org/projects/descent/wiki/CompilingPrograms

 I believe this will call dsss (or whatever program you specify) on the 
 current file, however.

Yes, I looked into that before... I never was able to make it work.

Probably this is only a matter of configuration (you didn't mention if it was a linking problem or what). For me it works flawlessly. On Linux I have to pass the -L-ldl switch in the arguments textfield in addition to the configuration site description. Cheers Piotrek
Feb 01 2009
prev sibling next sibling parent reply =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
Chris R Miller wrote:

 Have a great day, and keep up the good work!  I personally can't wait 
 until D gets to the point that a (total bonehead) like me can install it 
 on OS X!  Alas, right now it seemeth to require more brain cells than I 
 have at my disposal.

You can find Mac OS X installer packages on http://gdcmac.sf.net/ If you *require* Leopard / Xcode 3.0 support or Tango / DSSS etc. look at http://www.dsource.org/projects/tango/wiki/MacOSXInstall LDC packages are available for 0.9, but it has some bugs still... --anders
Feb 01 2009
parent reply Chris R Miller <lordsauronthegreat gmail.com> writes:
Anders F Björklund wrote:
 Chris R Miller wrote:
 
 Have a great day, and keep up the good work!  I personally can't wait 
 until D gets to the point that a (total bonehead) like me can install 
 it on OS X!  Alas, right now it seemeth to require more brain cells 
 than I have at my disposal.

You can find Mac OS X installer packages on http://gdcmac.sf.net/ If you *require* Leopard / Xcode 3.0 support or Tango / DSSS etc. look at http://www.dsource.org/projects/tango/wiki/MacOSXInstall

Well, I don't have Tiger lying around for me to use, so Leopard is non-negotiable. I tried those packages several times, but each time it complained that the checksum didn't validate. I tried re-downloading several times, using wget and curl as well (sometimes they're more robust), but it didn't work.
 LDC packages are available for 0.9, but it has some bugs still...

Personally I can't wait to try LDC! AFAICT LDC and LLVM are some of the newest things happening to compilers in a long time. But I am keeping myself busy with Objective-C right now (I think there's a better chance that I'll find a paying job with Objective-C) so I can't say that I'll be investing time into checking it out as soon as I'd like. He who has not a working compiler on hand should keep a low profile. Which is why I've not been terribly active 'round these parts lately. But fear not, I am inactive, not gone! Or that could be reason to fear... depends on your viewpoint I suppose.
Feb 01 2009
parent reply =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
Chris R Miller wrote:

 If you *require* Leopard / Xcode 3.0 support or Tango / DSSS etc.
 look at http://www.dsource.org/projects/tango/wiki/MacOSXInstall

Well, I don't have Tiger lying around for me to use, so Leopard is non-negotiable.

But it's possible to run Xcode 2.5 on Leopard, just as you can run the 32-bit version of the compiler on a 64-bit host. Not optimal, but works. But the latest packages there (r229) should work with both Leopard and Tango, unlike the GDC 0.24 release that had some problems with those...
 I tried those packages several times, but each time it complained that 
 the checksum didn't validate.  I tried re-downloading several times, 
 using wget and curl as well (sometimes they're more robust), but it 
 didn't work.

That's weird, first time I heard of checksum problems with those PKG. >> LDC packages are available for 0.9, but it has some bugs still...
 
 Personally I can't wait to try LDC!

It's available as a tarball, "ldc-0.9-mac.tar.bz2", including Tango. --anders
Feb 01 2009
parent reply Marianne Gagnon <auria.mg gmail.com> writes:
   >> LDC packages are available for 0.9, but it has some bugs still...
 
 Personally I can't wait to try LDC!

It's available as a tarball, "ldc-0.9-mac.tar.bz2", including Tango.

Where is this file available? I've been browsing the LDC website without finding anything beyond the source tarball. -- Auria
Feb 01 2009
parent =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
Marianne Gagnon wrote:

   >> LDC packages are available for 0.9, but it has some bugs still...
 Personally I can't wait to try LDC!


Where is this file available? I've been browsing the LDC website without finding anything beyond the source tarball.

I could make it available somewhere, apparently it can't be posted to the LDC dsource site until some more bugs have been worked out ? AFAIK the current download for 0.9 isn't on the LDC website either, but was just posted on the developer's blog and home page instead. So far I'm only hosting the GDC packages (i.e. over on SourceForge), the DMD and LDC packages (there's RPMS too) were more for my own use. --anders
Feb 01 2009
prev sibling parent reply John Reimer <terminal.node gmail.com> writes:
Hello Chris,


 http://www.fsdev.net/~cmiller/a/20090123_dvobjc.html
 
 Also, I do honor the right of reply.  If there's something I have
 written that is now incorrect or inaccurate I will of course change my
 page to reflect that.  Heck, all the comparisons in the world are
 worthless if they aren't accurate!
 
 Have a great day, and keep up the good work!  I personally can't wait
 until D gets to the point that a (total bonehead) like me can install
 it on OS X!  Alas, right now it seemeth to require more brain cells
 than I have at my disposal.
 

Here's a couple comments: (1) I'm surprised that, in your Objective C introduction, you don't indicate that the langauge is a direct decendant of Smalltalk. Interestingly you mention Smalltalk in the D introduction instead, even though the only similarity between the two is that they both implement a form of OO programming. Objective C is practically C with embedded Smalltalk. A major purpose for the creation of Objective C was to bring the benefits and explicit OO style of SmallTalk to C language developers. A few sources: http://developer.apple.com/documentation/Cocoa/Conceptual/ObjectiveC/Introduction/chapter_1_section_1.html http://faqs.cs.uu.nl/na-dir/Objective-C/answers.html And of course, wikipedia (to which you did provide a link): http://en.wikipedia.org/wiki/Objective-C (2) The DWT port doesn't support 64-bit platforms (so far as I know), so I don't understand why this is called a bug. The two ports of SWT that are currently supported are dwt-win and dwt-linux, both 32-bit versions and dependent on a 32-compiler (dmd for x86). dwt-mac is still in development by Jacob Carlborg: this version is compiled with gdc for Mac and is also 32-bit, so far as I know. Finally, I agree most with what you say here: "I stand by my original statement that they're different languages and different tools for different purposes." My take on it is this: Some of Objective C's features are very useful (dynamic OO extensions and runtime binding); however, I think that Objective-C is really meant to be a sort of domain specific solution for which the Cocoa development experience is optimized: the language is purposely simple, which makes it significantly useful for its intended task. I know Apple recently updated the language to Objective C 2.0 that added a few more convenience features, but I don't think they even argue that it's directly competitive with C++ (however, I cannot verify this). In fact, for those that might need to use other libraries or use more powerful features only available in C++, there's the option of developing in Objective C++. Finally, I don't think Objective-C was intended to be a general-purpose programming language in the manner of D or C++, so the comparison will fall somewhat flat there. It's superb for the task for which it was designed (as Smalltalk was), but then how does one say it is "better "than or even equivalent to D? If you are a Mac programmer... it's just better because it meets the requirements of the Mac environment (which has been partially designed around the language) and includes the tools and API's to improve the experience on that platform only. It would seem difficult for any language to compete with that. -JJR
Feb 01 2009
parent reply Chris R Miller <lordsauronthegreat gmail.com> writes:
John Reimer wrote:
 Hello Chris,
 
 
 http://www.fsdev.net/~cmiller/a/20090123_dvobjc.html

 Also, I do honor the right of reply.  If there's something I have
 written that is now incorrect or inaccurate I will of course change my
 page to reflect that.  Heck, all the comparisons in the world are
 worthless if they aren't accurate!

 Have a great day, and keep up the good work!  I personally can't wait
 until D gets to the point that a (total bonehead) like me can install
 it on OS X!  Alas, right now it seemeth to require more brain cells
 than I have at my disposal.

Here's a couple comments: (1) I'm surprised that, in your Objective C introduction, you don't indicate that the langauge is a direct decendant of Smalltalk. Interestingly you mention Smalltalk in the D introduction instead, even though the only similarity between the two is that they both implement a form of OO programming. Objective C is practically C with embedded Smalltalk. A major purpose for the creation of Objective C was to bring the benefits and explicit OO style of SmallTalk to C language developers.

To me it seems that every language borrows from SmallTalk. So I prefer to just ignore it as the father or all modern language design patterns. I link to stuff so that people can do more reading if they want. :) And again, I'm not there to really give a history lesson, more to analyze the situation of "you want to build an app which does foo, which is better for that purpose?" (the answer is that it depends: who do you want to support? Windows and Linux, or OS X?)
 (2)  The DWT port doesn't support 64-bit platforms (so far as I know), 
 so I don't understand why this is called a bug.  The two ports of SWT 
 that are currently supported are dwt-win and dwt-linux, both 32-bit 
 versions and dependent on a 32-compiler (dmd for x86).  dwt-mac is still 
 in development by Jacob Carlborg: this version is compiled with gdc for 
 Mac and is also 32-bit, so far as I know.

Yes, the 32-bit-ness of DWT has distressed me for some time. When I had DMD working on Ubuntu a while back I tried to make DWT work... the code is 64-bit compatible AFACT, but it needs some work with the libraries it links to - they're not 64-bit compatible. I wasn't up to re-writing the library linkage (or the prospect of maybe finding that the code itself isn't 64-bit compatible!) so I just left it unfixed in hopes that someone else would fix it someday.
 Finally, I agree most with what you say here:
 
 
 "I stand by my original statement that they're different languages and 
 different tools for different purposes."
 
 
 My take on it is this:
 
 
 Some of Objective C's features are very useful (dynamic OO extensions 
 and runtime binding); however, I think that Objective-C is really meant 
 to be a sort of domain specific solution for which the Cocoa development 
 experience is optimized: the language is purposely simple, which makes 
 it significantly useful for its intended task.  I know Apple recently 
 updated the language to Objective C 2.0 that added a few more 
 convenience features, but I don't think they even argue that it's 
 directly competitive with C++ (however, I cannot verify this).  In fact, 
 for those that might need to use other libraries or use more powerful 
 features only available in C++, there's the option of developing in 
 Objective C++.
 
 
 Finally, I don't think Objective-C was intended to be a general-purpose 
 programming language in the manner of D or C++, so the comparison will 

I would argue the opposite. Objective-C retains the ability to compile and run *any* code that C can. C is a general-purpose language. Therefore Objective-C is a SmallTalk-ish extension of a general-purpose language. To me, it's the lack of really strong multiplatform support that keeps Objective-C from being more of a multiplatform general-purpose language, but it's still a general-purpose language to me.
Feb 01 2009
parent reply John Reimer <terminal.node gmail.com> writes:
Hello Chris,

 John Reimer wrote:
 
 Hello Chris,
 
 http://www.fsdev.net/~cmiller/a/20090123_dvobjc.html
 
 Also, I do honor the right of reply.  If there's something I have
 written that is now incorrect or inaccurate I will of course change
 my page to reflect that.  Heck, all the comparisons in the world are
 worthless if they aren't accurate!
 
 Have a great day, and keep up the good work!  I personally can't
 wait until D gets to the point that a (total bonehead) like me can
 install it on OS X!  Alas, right now it seemeth to require more
 brain cells than I have at my disposal.
 

(1) I'm surprised that, in your Objective C introduction, you don't indicate that the langauge is a direct decendant of Smalltalk. Interestingly you mention Smalltalk in the D introduction instead, even though the only similarity between the two is that they both implement a form of OO programming. Objective C is practically C with embedded Smalltalk. A major purpose for the creation of Objective C was to bring the benefits and explicit OO style of SmallTalk to C language developers.

prefer to just ignore it as the father or all modern language design patterns. I link to stuff so that people can do more reading if they want. :) And again, I'm not there to really give a history lesson, more to analyze the situation of "you want to build an app which does foo, which is better for that purpose?" (the answer is that it depends: who do you want to support? Windows and Linux, or OS X?)

As you wish, but I still think you left out a fairly distinct part of Objective C introduction: it's what makes it Objective C. I say this because your mention of it is more appropriate on that side of the Objective-C introduction than the D one. Not all OOP languages are alike.
 (2)  The DWT port doesn't support 64-bit platforms (so far as I
 know), so I don't understand why this is called a bug.  The two ports
 of SWT that are currently supported are dwt-win and dwt-linux, both
 32-bit versions and dependent on a 32-compiler (dmd for x86).
 dwt-mac is still in development by Jacob Carlborg: this version is
 compiled with gdc for Mac and is also 32-bit, so far as I know.
 

had DMD working on Ubuntu a while back I tried to make DWT work... the code is 64-bit compatible AFACT, but it needs some work with the libraries it links to - they're not 64-bit compatible. I wasn't up to re-writing the library linkage (or the prospect of maybe finding that the code itself isn't 64-bit compatible!) so I just left it unfixed in hopes that someone else would fix it someday.

There are a lot of d applications and libraries that will need to become 64-bit someday. I'm afraid, though, that those of us contributing to dwt can only handle so much for now.
 Finally, I agree most with what you say here:
 
 "I stand by my original statement that they're different languages
 and different tools for different purposes."
 
 My take on it is this:
 
 Some of Objective C's features are very useful (dynamic OO extensions
 and runtime binding); however, I think that Objective-C is really
 meant to be a sort of domain specific solution for which the Cocoa
 development experience is optimized: the language is purposely
 simple, which makes it significantly useful for its intended task.  I
 know Apple recently updated the language to Objective C 2.0 that
 added a few more convenience features, but I don't think they even
 argue that it's directly competitive with C++ (however, I cannot
 verify this).  In fact, for those that might need to use other
 libraries or use more powerful features only available in C++,
 there's the option of developing in Objective C++.
 
 Finally, I don't think Objective-C was intended to be a
 general-purpose programming language in the manner of D or C++, so
 the comparison will
 

compile and run *any* code that C can. C is a general-purpose language. Therefore Objective-C is a SmallTalk-ish extension of a general-purpose language.

Yes, I made an assumption in my statement there (concerning the C language). If you still consider the C component a competitive general-purpose language, then this is indeed true. I don't think C (plus the OO extension) is nearly as competitive in functionality as D or C++ as general-purpose languages go. What we're discussing here anyway is really just the Objective extension, since C is available everywhere anyway. But I do feel the Objective C extension serves the niche that it's in very well; in fact, it becomes the best option for that platform specifically because of the rich runtime and API immediately at its disposal. But this could be the case with many languages that manage to be neatly and nearly built around an operating system... even D would excel a manifold times more if things like garbage collection, language specific linking and dynamics, interfaces, etc were integrated into and understood by the OS (or a type of abstraction layer that implements the functionality). What better than to have singular consistancy where everything is oriented to D in a system such the compilers and systems can make easy assumptions. I emphasize this fact because the dynanism that Objective C achieves is primarly a result of its runtime. Here's a quote from /Objective-C 2.0 Runtime Programming Guide/ (Introduction, Page 7): "The Objective-C language defers as much as it can from compile time and link time to runtime. Whenever possible, it does things dynamically. This means that the language requires not just a compiler, but also a runtime system to execute the compiled code. The runtime system acts as a kind of operating system for the Objective-C language; it's what makes the language work." This is actually kind of interesting because it would seem to make Objective-C slightly comparable to the C# language in that it's more than just a language (as is Java). It's a platform (and the beauty of the platform is really only extensively demonstrated by the OS runtime functionality that supports it ... and Cocoa).
 To me, it's the lack of really strong multiplatform support that keeps
 Objective-C from being more of a multiplatform general-purpose
 language, but it's still a general-purpose language to me.
 

Yes, this is also true. But I think Objective C will likely never break out of this mold because all the impressive functionality is to remain bound to it's runtime + API functionality on a single platform. On the other hand, if Apple ever takes over the computer industry, I suppose we'll see Objective C everywhere, and then there will be no argument. :) With all that said, I certainly wouldn't mind seeing D demonstrate OS level integration of some sort or another such that threading, gc, exception handling, linking were completely D technology. Niche or not, this would be amazing, and it would solve a multitude of weaknesses in the current D toolset. I could see myself spending a fair bit of time using such a system. :) -JJR
Feb 01 2009
next sibling parent reply Chris R Miller <lordsauronthegreat gmail.com> writes:
John Reimer wrote:
 I link to stuff so that people can do more reading if they want. :)

 And again, I'm not there to really give a history lesson, more to
 analyze the situation of "you want to build an app which does foo,
 which is better for that purpose?"  (the answer is that it depends:
 who do you want to support?  Windows and Linux, or OS X?)

As you wish, but I still think you left out a fairly distinct part of Objective C introduction: it's what makes it Objective C. I say this because your mention of it is more appropriate on that side of the Objective-C introduction than the D one. Not all OOP languages are alike.

Well, I've come to the general conclusion that I am the least experienced person around here, so I'll defer to your judgement there. I've added a small note that acknowledges Objective-C's SmallTalk design underpinnings.
 Yes, the 32-bit-ness of DWT has distressed me for some time.  When I
 had DMD working on Ubuntu a while back I tried to make DWT work... the
 code is 64-bit compatible AFACT, but it needs some work with the
 libraries it links to - they're not 64-bit compatible.  I wasn't up to
 re-writing the library linkage (or the prospect of maybe finding that
 the code itself isn't 64-bit compatible!) so I just left it unfixed in
 hopes that someone else would fix it someday.

There are a lot of d applications and libraries that will need to become 64-bit someday. I'm afraid, though, that those of us contributing to dwt can only handle so much for now.

I'm still amazed that so few people were able to create DWT.
 I would argue the opposite.  Objective-C retains the ability to
 compile and run *any* code that C can.  C is a general-purpose
 language. Therefore Objective-C is a SmallTalk-ish extension of a
 general-purpose language.

Yes, I made an assumption in my statement there (concerning the C language). If you still consider the C component a competitive general-purpose language, then this is indeed true. I don't think C (plus the OO extension) is nearly as competitive in functionality as D or C++ as general-purpose languages go. What we're discussing here anyway is really just the Objective extension, since C is available everywhere anyway.

There is still a whole lot of stuff being written in C, both commercially and Open-Source. I believe that's because it's such a good, general-purpose language and because it's ubiquitous. Nearly every platform has a C compiler.
 But I do feel the Objective C extension serves the niche that it's in 
 very well; in fact, it becomes the best option for that platform 
 specifically because of the rich runtime and API immediately at its 
 disposal.  But this could be the case with many languages that manage to 
 be neatly and nearly built around an operating system... even D would 
 excel a manifold times more if things like garbage collection, language 
 specific linking and dynamics, interfaces, etc were integrated into and 
 understood by the OS (or a type of abstraction layer that implements the 
 functionality).   What better than to have singular consistancy where 
 everything is oriented to D in a system such the compilers and systems 
 can make easy assumptions.
 
 
 I emphasize this fact because the dynanism that Objective C achieves is 
 primarly a result of its runtime.  Here's a quote from /Objective-C 2.0 
 Runtime Programming Guide/ (Introduction, Page 7):
 
 
 "The Objective-C language defers as much as it can from compile time and 
 link time to runtime.  Whenever possible, it does things dynamically.  
 This means that the language requires not just a compiler, but also a 
 runtime system to execute the compiled code.  The runtime system acts as 
 a kind of operating system for the Objective-C language; it's what makes 
 the language work."
 
 
 This is actually kind of interesting because it would seem to make 
 Objective-C slightly comparable to the C# language in that it's more 
 than just a language (as is Java).  It's a platform (and the beauty of 
 the platform is really only extensively demonstrated by the OS runtime 
 functionality that supports it ... and Cocoa). 

Well, I suppose it's largely how much you build into the runtime. C and C++ have runtimes, after all, but compared to things like D and C# they don't do much at all. D, C#, and Objective-C perform many more functions via their runtimes than do C and C++.
 To me, it's the lack of really strong multiplatform support that keeps
 Objective-C from being more of a multiplatform general-purpose
 language, but it's still a general-purpose language to me.

Yes, this is also true. But I think Objective C will likely never break out of this mold because all the impressive functionality is to remain bound to it's runtime + API functionality on a single platform. On the other hand, if Apple ever takes over the computer industry, I suppose we'll see Objective C everywhere, and then there will be no argument. :)

Objective-C's runtime is bundled with it just like C++'s (or as far as I can tell). I wholly agree that the one killer feature of Objective-C - the Cocoa library - is stuck on OS X, but if you for some reason fell in love with Objective-C as a *language* you could run it on any platform. Because it can access C libraries and, through Objective-C++, C++ libraries, you could probably use Objective-C with great success on other platforms. I'm just not willing to leave the nice cushy "it just works" Xcode environment though. :-) Which is why I rate Objective-C's cross-platform ability so low. Heck, you could write a brainfuck interpreter for any platform, but without the ability to load external libraries and interface with the system in truly meaningful ways I'd call brainfuck's cross-platform support horrible as well.
 With all that said, I certainly wouldn't mind seeing D demonstrate OS 
 level integration of some sort or another such that threading, gc, 
 exception handling, linking were completely D technology.  Niche or not, 
 this would be amazing, and it would solve a multitude of weaknesses in 
 the current D toolset.  I could see myself spending a fair bit of time 
 using such a system. :)

Making an OS around D would be a grossly fascinating project. As it is I don't think you could make the kernel in D - the D runtime relies too heavily on kernel-supplied routines for memory allocation, etc. You'd have to take D and remove the runtime, which is largely what the Linux kernel does with C - they took C, and removed the runtime in order to make the kernel. Which makes Linux kernel hacking very confusing! Use zmalloc() instead of kmalloc() in kernel code, etc. and stuff like that... Perhaps taking a Linux/BSD kernel and building a software system up from there? How would one go about doing such a thing? I suppose you could use a QEMU interpreter to virtualize the system in the earliest stages until you get such tools as a command shell working.
Feb 02 2009
next sibling parent John Reimer <terminal.node gmail.com> writes:
Hello Chris,

 John Reimer wrote:
 
 I link to stuff so that people can do more reading if they want. :)
 
 And again, I'm not there to really give a history lesson, more to
 analyze the situation of "you want to build an app which does foo,
 which is better for that purpose?"  (the answer is that it depends:
 who do you want to support?  Windows and Linux, or OS X?)
 

Objective C introduction: it's what makes it Objective C. I say this because your mention of it is more appropriate on that side of the Objective-C introduction than the D one. Not all OOP languages are alike.

experienced person around here, so I'll defer to your judgement there. I've added a small note that acknowledges Objective-C's SmallTalk design underpinnings.

Well, now I'm feeling a little silly about being pushy about it. But thank-you for listening nonetheless. For many things I'm in the least experienced category too around here... Anyway, it just happened that I knew a little about Objective-C history, and that point bothered me. :)
 Yes, the 32-bit-ness of DWT has distressed me for some time.  When I
 had DMD working on Ubuntu a while back I tried to make DWT work...
 the code is 64-bit compatible AFACT, but it needs some work with the
 libraries it links to - they're not 64-bit compatible.  I wasn't up
 to re-writing the library linkage (or the prospect of maybe finding
 that the code itself isn't 64-bit compatible!) so I just left it
 unfixed in hopes that someone else would fix it someday.
 

become 64-bit someday. I'm afraid, though, that those of us contributing to dwt can only handle so much for now.


Yeah, it's even better than that. Frank did the most of two ports (dwt-win, dwt-linux). I did some of the DWT underpinnings on both, along with the Browser/XPCOM port, and website. And now Jacob Carlborg is doing the same for DWT-mac. It's pretty amazing.
 Well, I suppose it's largely how much you build into the runtime.  C
 and C++ have runtimes, after all, but compared to things like D and C#
 they don't do much at all.  D, C#, and Objective-C perform many more
 functions via their runtimes than do C and C++.
 

I think what Objective-C does critically in it's runtime is dynamic binding. For some reason, other languages haven't felt the need to do this. I'd have to read more about it to know what's going on, though.
 To me, it's the lack of really strong multiplatform support that
 keeps Objective-C from being more of a multiplatform general-purpose
 language, but it's still a general-purpose language to me.
 

break out of this mold because all the impressive functionality is to remain bound to it's runtime + API functionality on a single platform. On the other hand, if Apple ever takes over the computer industry, I suppose we'll see Objective C everywhere, and then there will be no argument. :)

I can tell). I wholly agree that the one killer feature of Objective-C - the Cocoa library - is stuck on OS X, but if you for some reason fell in love with Objective-C as a *language* you could run it on any platform. Because it can access C libraries and, through Objective-C++, C++ libraries, you could probably use Objective-C with great success on other platforms. I'm just not willing to leave the nice cushy "it just works" Xcode environment though. :-) Which is why I rate Objective-C's cross-platform ability so low. Heck, you could write a brainfuck interpreter for any platform, but without the ability to load external libraries and interface with the system in truly meaningful ways I'd call brainfuck's cross-platform support horrible as well.
 With all that said, I certainly wouldn't mind seeing D demonstrate OS
 level integration of some sort or another such that threading, gc,
 exception handling, linking were completely D technology.  Niche or
 not, this would be amazing, and it would solve a multitude of
 weaknesses in the current D toolset.  I could see myself spending a
 fair bit of time using such a system. :)
 

is I don't think you could make the kernel in D - the D runtime relies too heavily on kernel-supplied routines for memory allocation, etc. You'd have to take D and remove the runtime, which is largely what the Linux kernel does with C - they took C, and removed the runtime in order to make the kernel. Which makes Linux kernel hacking very confusing! Use zmalloc() instead of kmalloc() in kernel code, etc. and stuff like that...

It's possible and has been done... D is at least flexible enough to swap in the parts necessary. Tango is organized to help make such a project easier,for example.
 Perhaps taking a Linux/BSD kernel and building a software system up
 from there?  How would one go about doing such a thing?  I suppose you
 could use a QEMU interpreter to virtualize the system in the earliest
 stages until you get such tools as a command shell working.
 

There a few projects (some dead) that are implementing a D Operating System. I think Jarett was contributing to one of them. -JJR
Feb 02 2009
prev sibling next sibling parent reply Jarrett Billingsley <jarrett.billingsley gmail.com> writes:
On Mon, Feb 2, 2009 at 9:41 AM, John Reimer <terminal.node gmail.com> wrote:
 Perhaps taking a Linux/BSD kernel and building a software system up
 from there?  How would one go about doing such a thing?  I suppose you
 could use a QEMU interpreter to virtualize the system in the earliest
 stages until you get such tools as a command shell working.

There a few projects (some dead) that are implementing a D Operating System. I think Jarett was contributing to one of them.

Actually, I'm the one contributing. That Jarett douchebag keeps taking all my credit. And don't get me started on Jarret! http://xomb.org/
Feb 02 2009
parent reply John Reimer <terminal.node gmail.com> writes:
Hello Jarrett,

 On Mon, Feb 2, 2009 at 9:41 AM, John Reimer <terminal.node gmail.com>
 wrote:
 
 Perhaps taking a Linux/BSD kernel and building a software system up
 from there?  How would one go about doing such a thing?  I suppose
 you could use a QEMU interpreter to virtualize the system in the
 earliest stages until you get such tools as a command shell working.
 

System. I think Jarett was contributing to one of them.

taking all my credit. And don't get me started on Jarret! http://xomb.org/

Oops! A Jarett without an 'r' is just not a Jarrett! :D -JJR
Feb 02 2009
parent reply "Nick Sabalausky" <a a.a> writes:
"John Reimer" <terminal.node gmail.com> wrote in message 
news:28b70f8c137be8cb5379a03492d0 news.digitalmars.com...
 Hello Jarrett,

 On Mon, Feb 2, 2009 at 9:41 AM, John Reimer <terminal.node gmail.com>
 wrote:

 Perhaps taking a Linux/BSD kernel and building a software system up
 from there?  How would one go about doing such a thing?  I suppose
 you could use a QEMU interpreter to virtualize the system in the
 earliest stages until you get such tools as a command shell working.

System. I think Jarett was contributing to one of them.

taking all my credit. And don't get me started on Jarret! http://xomb.org/

Oops! A Jarett without an 'r' is just not a Jarrett! :D

A Jarett without an 'r' is a Jaett. (Pardon the unnecessary technicality ;) )
Feb 02 2009
parent John Reimer <terminal.node gmail.com> writes:
Hello Nick,

 "John Reimer" <terminal.node gmail.com> wrote in message
 news:28b70f8c137be8cb5379a03492d0 news.digitalmars.com...
 
 Hello Jarrett,
 
 On Mon, Feb 2, 2009 at 9:41 AM, John Reimer
 <terminal.node gmail.com> wrote:
 
 Perhaps taking a Linux/BSD kernel and building a software system
 up from there?  How would one go about doing such a thing?  I
 suppose you could use a QEMU interpreter to virtualize the system
 in the earliest stages until you get such tools as a command shell
 working.
 

Operating System. I think Jarett was contributing to one of them.

taking all my credit. And don't get me started on Jarret! http://xomb.org/


technicality ;) )

No problem. I deserve it. :) -JJR
Feb 03 2009
prev sibling parent "Denis Koroskin" <2korden gmail.com> writes:
On Mon, 02 Feb 2009 19:17:17 +0300, Jarrett Billingsley
<jarrett.billingsley gmail.com> wrote:

 On Mon, Feb 2, 2009 at 9:41 AM, John Reimer <terminal.node gmail.com>  
 wrote:
 Perhaps taking a Linux/BSD kernel and building a software system up
 from there?  How would one go about doing such a thing?  I suppose you
 could use a QEMU interpreter to virtualize the system in the earliest
 stages until you get such tools as a command shell working.

There a few projects (some dead) that are implementing a D Operating System. I think Jarett was contributing to one of them.

Actually, I'm the one contributing. That Jarett douchebag keeps taking all my credit. And don't get me started on Jarret! http://xomb.org/

*LOL*
Feb 02 2009
prev sibling next sibling parent reply Michel Fortin <michel.fortin michelf.com> writes:
On 2009-02-02 01:39:40 -0500, John Reimer <terminal.node gmail.com> said:

 "The Objective-C language defers as much as it can from compile time 
 and link time to runtime.  Whenever possible, it does things 
 dynamically.  This means that the language requires not just a 
 compiler, but also a runtime system to execute the compiled code.  The 
 runtime system acts as a kind of operating system for the Objective-C 
 language; it's what makes the language work."
 
 This is actually kind of interesting because it would seem to make 
 Objective-C slightly comparable to the C# language in that it's more 
 than just a language (as is Java).  It's a platform (and the beauty of 
 the platform is really only extensively demonstrated by the OS runtime 
 functionality that supports it ... and Cocoa).

Yeah, but the Objective-C runtime is pretty microscopic compared to Java or the C# runtime. There is no such thing as a virtual machine. What the Objecitve-C runtime does is this, and only this: 1. It manages a list of registered classes, and their associated methods. 2. It provides a method dispatch mechanism, and manages a list of registered selectors. 3. It provides various support routines for the compiler (exception handling, synchronization). For comparison, the D runtime does half of 1, and whole of 3, and a lot more. If you start counting parts of the Foundation framework in the runtime, then you'd have a base object class, an exception class, a thread class... But technically, Foundation is not part of the runtime, even if it's pretty necessary to do anything. I'd say that the Objective-C runtime is smaller than druntime since it does less (no TypeInfo, no array concat, no associative array, no thread support, etc.), although I haven't measured anything. On the other hand, the "standard library" (the Foundation framework) is probably bigger than both Phobos and Tango together. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Feb 02 2009
next sibling parent John Reimer <terminal.node gmail.com> writes:
Hello Michel,

 On 2009-02-02 01:39:40 -0500, John Reimer <terminal.node gmail.com>
 said:
 
 "The Objective-C language defers as much as it can from compile time
 and link time to runtime.  Whenever possible, it does things
 dynamically.  This means that the language requires not just a
 compiler, but also a runtime system to execute the compiled code.
 The runtime system acts as a kind of operating system for the
 Objective-C language; it's what makes the language work."
 
 This is actually kind of interesting because it would seem to make
 Objective-C slightly comparable to the C# language in that it's more
 than just a language (as is Java).  It's a platform (and the beauty
 of the platform is really only extensively demonstrated by the OS
 runtime functionality that supports it ... and Cocoa).
 

Java or the C# runtime. There is no such thing as a virtual machine. What the Objecitve-C runtime does is this, and only this: 1. It manages a list of registered classes, and their associated methods. 2. It provides a method dispatch mechanism, and manages a list of registered selectors. 3. It provides various support routines for the compiler (exception handling, synchronization). For comparison, the D runtime does half of 1, and whole of 3, and a lot more. If you start counting parts of the Foundation framework in the runtime, then you'd have a base object class, an exception class, a thread class... But technically, Foundation is not part of the runtime, even if it's pretty necessary to do anything.

I see... But the dynamic binding part is part of one, I assume? That's a pretty big (in terms of importance) feature that seems lacking in other runtimes? I don't know if C# provides anything like it.
 I'd say that the Objective-C runtime is smaller than druntime since it
 does less (no TypeInfo, no array concat, no associative array, no
 thread support, etc.), although I haven't measured anything. On the
 other hand, the "standard library" (the Foundation framework) is
 probably bigger than both Phobos and Tango together.
 

Ok, thanks for the info. I think with Objective C, it's more about what it achieves than how much. The Objective C people seem to make a fairly big deal about how dynamic binding makes the language so much more flexible than other languages (which probably is true) in this one regard. -JJR
Feb 02 2009
prev sibling parent bearophile <bearophileHUGS lycos.com> writes:
Michel Fortin:
 1. It manages a list of registered classes, and their associated methods.
 2. It provides a method dispatch mechanism, and manages a list of 
 registered selectors.
 3. It provides various support routines for the compiler (exception 
 handling, synchronization).
 
 For comparison, the D runtime does half of 1, and whole of 3, and a lot 
 more.

Note that if you add that 2 to the D runtime, you can do a significant percentage of the things the new "dynamic typing" feature of C#4 does :-) (It's less transparent still and only for classes). Bye, bearophile
Feb 02 2009
prev sibling parent reply Christopher Wright <dhasenan gmail.com> writes:
John Reimer wrote:
 This is actually kind of interesting because it would seem to make 
 Objective-C slightly comparable to the C# language in that it's more 
 than just a language (as is Java).  It's a platform (and the beauty of 
 the platform is really only extensively demonstrated by the OS runtime 
 functionality that supports it ... and Cocoa). 

In C#, it's impossible or very difficult to modify classes at runtime to add methods to them. It involves using libraries that normal programmers will never use. My impression of Objective-C is that it is a lot more dynamic -- for instance, member functions are accessed via global hashtables, so it's easy to open those hashtables up and add or redirect methods.
Feb 02 2009
parent Michel Fortin <michel.fortin michelf.com> writes:
On 2009-02-02 19:12:33 -0500, Christopher Wright <dhasenan gmail.com> said:

 My impression of Objective-C is that it is a lot more dynamic -- for 
 instance, member functions are accessed via global hashtables, so it's 
 easy to open those hashtables up and add or redirect methods.

Indeed. <http://www.cocoadev.com/index.pl?MethodSwizzling> -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Feb 02 2009