D versus Objective C Comparison

Chris R Miller lordsauronthegreat at gmail.com
Tue Feb 3 22:36:59 PST 2009


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.



More information about the Digitalmars-d mailing list