Start with C or C++ to get to ObjC/Cocoa?

2

Comments

  • Reply 21 of 47
    lundylundy Posts: 4,466member
    You can't skip procedural altogether - even a "pure" Objective-C app will still have if-then-else, do-while, and sequencing. If someone learns that all you do is send messages to objects, they wouldn't understand flow control. You'd have people coding (choosing random Objective-C statement here)



    NSBundle *myBundle = [NSBundle mainbundle];



    In a dead-code spot which would never get executed.



    If you mean not learning the "procedural" syntax of say, Carbon calls, like



    (NSBundle *) myBundle = NSBundle (@"mainBundle";);



    That might be useful, as procedural calls are read left to right, and Objective-C calls are read right to left, similar to reverse Polish.
  • Reply 22 of 47
    kickahakickaha Posts: 8,760member
    Quote:
    Originally Posted by Mike Eggleston


    The problem with learning both is that, as a beginner, you will tend to start getting the two confused. I started with Procedural Oriented Programming, and it made life really difficult to understand and use Objects. From a procedural standpoint, the idea that a data element could have a function is just bizarre, until you make the distinction that an Object is just like a structure, and the structure can have a or multiple functions.



    Weird. I never saw the problem. Basically the day I was introduced to OO, it felt natural - more so than the years of procedural experience prior to that, to be honest. Perhaps it was my physics background, where the concepts of states and forces are explicit. To me, an object isn't data, an object *contains* data, as state. A pure OO system (unlike C++) enforces this concept by eliminating POD types. (Now yes, you get the situation where state data is objects as well, but really, those are made of state, which are objects, but those are made of state, which are objects... but really, it works out in the denotational semantics in the end. )



    I would suggest that it is precisely the hybrid languages that confuse new programmers, by merging the syntaxes and concepts in a horrible mishmash of procedural and OO. Something like Obj-C would, I believe, be a cleaner teaching tool, because it makes the distinction clear. Of course, learning solid OO concepts via an even cleaner language such as Smalltalk or Eiffel is best yet.



    Quote:

    If the OP is going to be doing some serious Cocoa programming, then the best advice is to skip Procedural Oriented Programming almost altogether. Cocoa and Obj-C are both Object Oriented.



    almost I agree with - to a point. They'll find themselves to be much better Cocoa developers if they understand what's going on at the raw C level for when they need it... because they will, from time to time. If for nothing else, accessing Core* functionality when there's a gap in the Cocoa API.



    Quote:

    I know that C was the latecomer. I knew that Pascal and BASIC came out before then. However they did not get the ability to do lower level calls until C came abut. And that is why I give C all the credit it deserves.



    'Low level calls'. Alright, you're going to have to explain what you mean by that. Pointer access perhaps?



    You might be able to say "The success of C showed that low-level access to memory, etc, was a useful tool, and it positively influenced the later development of earlier languages such as BASIC and Pascal", and I'd agree with you. But they certainly would have existed without C, since they preceded it.



    Quote:

    Listen, the main point about this is that you will find developers (myself included) who think that [insert language here] is the best language ever, and all the others are crap.



    Yes, and they're shooting themselves in the foot by not recognizing that every language is a tradeoff, and no language is perfect. The right tool for the right job is paramount.



    As an educator, I've always tried to give my students a practical theory view of programming languages - not teach them theory for theory's sake, but so that they can pick up a new language quickly. My goal is that a student I've taught should be able to pick up a new language in each of the main language families (procedural, OO, functional, logical, etc) in less than two or three days, enough time to adapt to the syntax and major quirks. This lets you shift from language to language quickly and easily, as the task requires... because you'll need them, eventually.



    Quote:

    Personally, I think Java doesn't get enough recognition it deserves, but that isn't the point of this thread.



    Nope, but it's an interesting tangent. I like Java, the language, for the most part. I think it's starting to suffer from featuritis, unfortunately, when some cleaner decisions long ago would have made them unnecessary. The libraries are... cumbersome, IMO, but serviceable. The JVM, however... ick. Whoever made the decision to go with stripped bytecodes should be shot. It was appropriate when Java was still the Oak project, but they've held back the language ever since.



    Quote:

    brent1a, you will need a little bit of C knowledge. I would also spend a little bit of time with C++ or Java to get a handle on how Objects interact with each other. Then, I would get into Cocoa. Cocoa and Obj-C are really powerful tools, as long as you can get your mind wrapped around the idea of Objects, and how they deal with each other.



    Agreed... but I'd avoid C++ and Java, they're really pretty horrible OO examples. Just dive in to Obj-C, and learn the OO model there. You'll have plenty of opportunity to learn how objects interact, without having to mess with a much less clean language.
  • Reply 23 of 47
    Quote:
    Originally Posted by Kickaha


    Weird. I never saw the problem. Basically the day I was introduced to OO, it felt natural - more so than the years of procedural experience prior to that, to be honest. Perhaps it was my physics background, where the concepts of states and forces are explicit. To me, an object isn't data, an object *contains* data, as state. A pure OO system (unlike C++) enforces this concept by eliminating POD types. (Now yes, you get the situation where state data is objects as well, but really, those are made of state, which are objects, but those are made of state, which are objects... but really, it works out in the denotational semantics in the end. )



    I found it hard because I have been programming since I was 8, so that probably has a lot to do with it. I guess what I am trying to say (however not nearly as eloquent as you have been doing) is that Procedural Oriented Programers have a lot of baggage that gets accumulated: workarounds, global function libraries, etc. (For the record, I too have a global function library) The problem with all of those, especially the more you collect, it makes the transition to go from Procedural to Object much more difficult. Also, for a blank slate, understanding what an object is does seem more natural than writing n number of functions that only pertain to a small part. Geeze, again, I am not nearly being as eloquent as I'd like...



    Quote:
    Originally Posted by Kickaha


    I would suggest that it is precisely the hybrid languages that confuse new programmers, by merging the syntaxes and concepts in a horrible mishmash of procedural and OO. Something like Obj-C would, I believe, be a cleaner teaching tool, because it makes the distinction clear. Of course, learning solid OO concepts via an even cleaner language such as Smalltalk or Eiffel is best yet.



    Point taken, and agreed. I ONLY mention C++ because it is very similar to C, and it has some OOP built into it. As a stepping stone, it can be very useful.



    Quote:
    Originally Posted by Kickaha


    'Low level calls'. Alright, you're going to have to explain what you mean by that. Pointer access perhaps?



    You might be able to say "The success of C showed that low-level access to memory, etc, was a useful tool, and it positively influenced the later development of earlier languages such as BASIC and Pascal", and I'd agree with you. But they certainly would have existed without C, since they preceded it.



    Again, my eloquentness failed me again. That is one area that I was addressing. Pascal, for example, didn't get pointer access/math until C proved that it was a good way of handling things.



    Quote:
    Originally Posted by Kickaha


    Yes, and they're shooting themselves in the foot by not recognizing that every language is a tradeoff, and no language is perfect. The right tool for the right job is paramount.



    Exactly. I can't say that enough. Too many times have I heard the [insert language here] is so much better because of [insert correct but foolish reason here]. My only complaint is that there is no easy way of merging languages. PHP comes close (especially in comparison of other languages) in that you can have PHP and HTML in the same file. However, that is not what I am talking about.



    Quote:
    Originally Posted by Kickaha


    As an educator, I've always tried to give my students a practical theory view of programming languages - not teach them theory for theory's sake, but so that they can pick up a new language quickly. My goal is that a student I've taught should be able to pick up a new language in each of the main language families (procedural, OO, functional, logical, etc) in less than two or three days, enough time to adapt to the syntax and major quirks. This lets you shift from language to language quickly and easily, as the task requires... because you'll need them, eventually.



    Where were you when I was going to school??
  • Reply 24 of 47
    MarvinMarvin Posts: 15,324moderator
    Quote:
    Originally Posted by Kickaha


    That's the beauty of Objective-C: it separates the two models used internally, procedural and OO, into two distinct syntaxes. This lets each be easily identified, easily used in the proper way, and easily optimized by the compiler. Languages such as C++ that try and unify the systems end up creating a hybrid that doesn't offer the cleanliness for either style, trying instead to pretend that they are singular.



    I never really thought of it that way. I'm not sure about the compiler optimization because the compiler would have to know the syntax differences in any language in order to be able to raise errors. Plus, Objective-C is probably one of the slowest C-based languages based on numerous benchmarks.



    But I guess conceptually it might help the programmer separate the two models and so write better programs.



    As for syntax, what do people regard to be their favourite? My vote personally goes with Python even though using tabs for scope annoys people. Second would be C.



    Also, what do people think about Apple's Objective-C documentation? I think it sucks. I tried to make a save panel as a sheet and I kept getting errors about not being able to use nil for contextInfo. Every example I found set contextInfo to nil:



    NSSavePanel *panel=[NSSavePanel savePanel];

    [panel setRequiredFileType:@"pdf"];

    [panel beginSheetForDirectory:nil file: nil modalForWindow [NSApp mainWindow] modalDelegate:self didEndSelector: @selector (PDF:returnCode:contextInfo: ) contextInfo:nil];



    And yet mine just wouldn't compile. I ended up using a modal save panel. To me, that code above is horrendous. I would have no problem if it was something like this:



    panel = NSSavePanel.savePanel()

    panel.setRequiredFileType("pdf")

    panel.beginSheetForDirectory(nil, nil, mainWindow, returnFunction(PDF, returnCode, contextInfo), nil)



    pointers can still be used in Python but you can avoid them the majority of the time.
  • Reply 25 of 47
    kickahakickaha Posts: 8,760member
    Your version does only two things. Replaces brackets with parentheses, and wipes out any readability of the method call. The former is just a syntax issue, which should be trivial. The latter is the real problem. You have no idea what the arguments in your call to beginSheetForDirectory do, or what they represent. I shouldn't have to go document-diving to just read a function call.



    And the compiler optimizations come about because the compiler can treat the two methodologies as distinct, just as the developer does, and make a number of assumptions that say, a C++ compiler cannot easily. POD code can be optimized for *JUST* that style, while object code can be treated purely. A small bridge takes care of the point between.



    In C++, any piece of data, assuming RTTI has been turned on, has to be considered as object code. This includes POD data - that's inefficient. And when RTTI has been turned off, the object code loses a lot of powerful behaviour. You have to choose between efficiency for the procedural code, *OR* a strong OO model.



    Objective-C lets the compiler treat the two separately, so that the POD code is optimized just as straight C is, (it's no different), but the OO code gets the power that it needs.



    I'd like to see the benchmarks you're thinking of, because the ones I've seen (which I'll try and track down) show Obj-C's messaging system to be *slightly* slower for method calls compared to C++, but depending on the code being compiled, it can actually be faster due to the improved algorithmic possibilities. (More maintainable too, since the code is frequently simpler.)
  • Reply 26 of 47
    Quote:
    Originally Posted by Marvin


    NSSavePanel *panel=[NSSavePanel savePanel];

    [panel setRequiredFileType:@"pdf"];

    [panel beginSheetForDirectory:nil file: nil modalForWindow [NSApp mainWindow] modalDelegate:self didEndSelector: @selector (PDF:returnCode:contextInfo: ) contextInfo:nil];



    pointers can still be used in Python but you can avoid them the majority of the time.



    Ok, here is the reason why Obj-C is just blasted cool.



    Take your basic function: exponent.



    Code:




    function exponent(base, exp) {

    start = 1;

    act = 'MULT';

    if (exp < 0) { exp = exp * (-1); act = 'DIV'; }

    for (x = 1; x <= exp; x++) {

    if (act == 'MULT') { start *= base; } else { start /= base; }

    }

    return start;

    }







    Ok, this is a very simple function. However, in C, C++, PHP, BASIC, Pascal, Python, etc. it has to always be in the order of the base, then the exponent. Here is the beauty of Obj-C (to me atleast):



    Code:




    tmp = [exponent base:2 exp:3]; // tmp = 8

    tmp2 = [exponent exp:3 base:2]; // tmp2 = 8

    // tmp == tmp2









    Function/Method order is no longer an issue. A developer just needs to know which variables there are, and that is it. A good developer will always document what the function call does, what each element is, and how it is used.
  • Reply 27 of 47
    hirohiro Posts: 2,663member
    Kick, take a caffeine break, you're reading too much into what I'm saying. I'm not saying you are wrong, but you aren't going to convince me I'm wrong either. Your posts actually allude to the many of the reasons I feel the way I do, you just see them differently. There are too many differing criteria involved and the issue can devolve into a ridiculous holy war just because. I'd rather join in a holy war of "Obj-C is cool, but pick the best tool for the job at hand whether it's cool or not."



    Marvin, Obj-C messaging is slower (compared to a normal C/C++ function call) the first time a particular message is invoked, after that it is for all intents and purposes that message call is as fast as a normal C/C++ function call due to object-message caching. And the object-message caching actually makes Obj-C faster than C++ on dynamically linked code. 15 years ago that wasn't the case because object-message caching didn't exist, but it does now.
  • Reply 28 of 47
    carniphagecarniphage Posts: 1,984member
    The C++ Vs Objective C holy war is a bit of a silly one. Largely speaking we do not have much of a choice. If you are working on the PC or in Games Development you don't have the option of Objective C. If you are programming for the Mac, you can work in both, but Objective C will be your main weapon of choice.



    Yes it might be nice if Objective C broke out of the Mac ghetto - but that would require a seismic shift in the userbase.
  • Reply 29 of 47
    MarvinMarvin Posts: 15,324moderator
    Quote:
    Originally Posted by Kickaha


    You have no idea what the arguments in your call to beginSheetForDirectory do, or what they represent. I shouldn't have to go document-diving to just read a function call.



    That helps when debugging but it means much more work when writing code and there you still have to look it up for built-in functions. Python has this sort of thing too in the form of a dictionary so all I'd need to do is pass a dictionary as a function argument. That gives people the choice to name arguments. I think it can be advantageous though because I use Python dictionaries a lot for this reason.



    Quote:
    Originally Posted by Kickaha


    I'd like to see the benchmarks you're thinking of, because the ones I've seen (which I'll try and track down) show Obj-C's messaging system to be *slightly* slower for method calls compared to C++, but depending on the code being compiled, it can actually be faster due to the improved algorithmic possibilities. (More maintainable too, since the code is frequently simpler.)



    Yeah that's mainly the same as I found but I also found that Obj-C++ is worse than pure Obj-C and in most cases, Obj-C++ will be necessary. I don't think many people can write a pure Obj-C program because there is so much C++ code around.



    If Objective-C is so powerful then why don't more companies use it? I hadn't even heard of it before Apple started using it. From what I read, it seems like C++ has lots of problems and is a bunch of ugly hacks whereas Obj-C is pure. To me, that should encourage a major shift in the interests of future development.



    Quote:
    Originally Posted by Carniphage


    Yes it might be nice if Objective C broke out of the Mac ghetto - but that would require a seismic shift in the userbase.



    This is why I think it needs to change. A lot of good programmers say the syntax is trivial but for people who have only used certain syntax and programming conventions, it's incredibly difficult to pick up.
  • Reply 30 of 47
    kickahakickaha Posts: 8,760member
    Quote:
    Originally Posted by Marvin


    That helps when debugging but it means much more work when writing code



    Not really - most developers I know make frequent use of auto-complete in their IDEs anyway.



    And also... consider that the cost of writing 1.0 code is just 15% of the total cost of a project's lifetime, on average in industry. Anything that helps with debugging (ie, maintenance) is a huge win. It's the dirty little secret of software production.



    Quote:

    and there you still have to look it up for built-in functions. Python has this sort of thing too in the form of a dictionary so all I'd need to do is pass a dictionary as a function argument. That gives people the choice to name arguments. I think it can be advantageous though because I use Python dictionaries a lot for this reason.



    Python's dicts are the one feature I miss the most in other languages.



    Quote:

    Yeah that's mainly the same as I found but I also found that Obj-C++ is worse than pure Obj-C and in most cases, Obj-C++ will be necessary. I don't think many people can write a pure Obj-C program because there is so much C++ code around.



    True, but it is usually pretty easy to sandbox the Obj-C++ code into just a few files, and use Obj-C in the rest. The decision of Obj-C/Obj-C++ is done at the file level, nothing larger. Think of it as really easy bridge code between two environments.



    Quote:

    If Objective-C is so powerful then why don't more companies use it?



    If MacOS X is so good, then why don't more companies use it? \



    Good doesn't ever mean popular.



    Quote:

    I hadn't even heard of it before Apple started using it. From what I read, it seems like C++ has lots of problems and is a bunch of ugly hacks whereas Obj-C is pure. To me, that should encourage a major shift in the interests of future development.



    For a time, NeXT utterly dominated the market for custom apps at Fortune 500 companies. Folks who needed rapid development in-house bought them up like mad. Then... meh.



    Quote:

    This is why I think it needs to change. A lot of good programmers say the syntax is trivial but for people who have only used certain syntax and programming conventions, it's incredibly difficult to pick up.



    Well, I said it *should* be trivial. Yeah, the first time you run across a new syntax it can be a bit painful, which is why I think getting exposed to a number of syntaxes early on is a good thing. Once you can wrap your head around a syntax, moving to/from it later is pretty easy. The C++ -> Obj-C filter is just:



    [A B: c D: e] -> A.B(c, e)



    Some people merge the descriptors into one method name to keep the describability:



    [A B: c D: e] -> A.B_D(c, e)



    That's really pretty much it, other than '@' starting Obj-C keywords. It's only when the brackets start getting deeply nested from call chaining that things look messy. In those cases, the dot selector notation has a distinct advantage for readability.
  • Reply 31 of 47
    Quote:
    Originally Posted by Mike Eggleston


    Ok, here is the reason why Obj-C is just blasted cool.



    Take your basic function: exponent. . . .



    Is what you think is so cool is the idea that the objC/smalltalk compiler will rearrange function arguments? I guess that's fine, but I'd hammer objC here if it didn't have full C compatibility. Removing order from function arguments removes the ability to elegantly work with arbitrary length arguments (see printf). But I will agree that by being more descriptive with function calls, objC/smalltalk is doing us all a favor. Typing and code length are not problems anymore, and having descriptive code syntax just makes it easier to write comments. This is probably the big reason why I like Ada.



    And dude, the way to invert is negative = (not postive) + 1. In all seriousness, this becomes important if you're doing things in parallel, which is becoming the status quo.
  • Reply 32 of 47
    kickahakickaha Posts: 8,760member
    Quote:
    Originally Posted by Splinemodel


    Is what you think is so cool is the idea that the objC/smalltalk compiler will rearrange function arguments? I guess that's fine, but I'd hammer objC here if it didn't have full C compatibility.



    100% agreed - that's the beauty of it. Need to optimize away some of those method calls? Realize you *can* get away with raw functions in speedy speedy C? Do it. Being able to drop back to C at a moment's notice is a godsend.



    Otherwise it's just Smalltalk.
  • Reply 33 of 47
    lundylundy Posts: 4,466member
    The main hassle I have with Objective-C is the following: getting the actual scalar value of an object to do a simple compare or loop or printing or loading into an NSTextField:



    Example: I want to get the length of an NSString to see if it is too long or too short:



    Code:




    NSMutableString *JumbleWord1 = [NSMutableString new];

    unsigned int jwLen;

    ...

    ...

    // Check entered string for proper length

    jwLen = [[JumbleWord1 stringValue] length];

    if ((jwLen >= MINWORDLEN) && (jwLen <= MAXWORDLEN))

    ....

    ....









    So I either have to use an Objective-C compare, or extract the object's value as above so I can test it in C.



    Which would you do?
  • Reply 34 of 47
    Quote:
    Originally Posted by lundy


    The main hassle I have with Objective-C is the following: getting the actual scalar value of an object to do a simple compare or loop or printing or loading into an NSTextField:



    Example: I want to get the length of an NSString to see if it is too long or too short:



    Code:




    NSMutableString *JumbleWord1 = [NSMutableString new];

    unsigned int jwLen;

    ...

    ...

    // Check entered string for proper length

    jwLen = [[JumbleWord1 stringValue] length];

    if ((jwLen >= MINWORDLEN) && (jwLen <= MAXWORDLEN))

    ....

    ....









    So I either have to use an Objective-C compare, or extract the object's value as above so I can test it in C.



    Which would you do?



    I would add a method to my NSString category.



    That way, the code would be rewritten as:



    Code:




    NSMutableString *jumbleWord = getFromSomewhere();



    if ([jumbleWord isLengthBetweenMinimum: minimumWordLength andMaximum: maximumWordLength])

    ....









    and then in the category file



    Code:




    - (BOOL) isLengthBetweenMinimum: (int) min andMaximum: (int max) {

    unsigned length = [self length];

    if ((length >= min) && (length <= max))

    return YES;

    else

    return NO;

    }









    That way you have a nice reusable method, and it keeps your calling code really clean.



    (Also, why are you calling stringValue on a string? That's just silly.)



    (Also also: why doesn't stupid [code] handle whitespaces?)
  • Reply 35 of 47
    Quote:
    Originally Posted by lundy


    So I either have to use an Objective-C compare, or extract the object's value as above so I can test it in C.



    Which would you do?



    I'd use the C method, and dump it into a macro. No reason to dirty-up your cache with extra addressing.



    Yes, most of the compiled programming I do is for embedded ARMs.
  • Reply 36 of 47
    kickahakickaha Posts: 8,760member
    Quote:
    Originally Posted by lundy


    The main hassle I have with Objective-C is the following:



    Engage picking of nits:



    I'd say that's more of an issue with the NS libraries than Objective-C the language... but given that the only serious use of Obj-C at the moment is with those libraries... meh.
  • Reply 37 of 47
    lundylundy Posts: 4,466member
    Quote:
    Originally Posted by gregmightdothat


    (Also, why are you calling stringValue on a string? That's just silly.)



    Eh - I was mistaken - it's really defined as an IBOutlet and I couldn't cast it as an NSMutableString



    from JumbleController.h :



    Code:




    @interface JumbleController : NSObject

    {

    IBOutlet id JumbleWord1;

    IBOutlet id SolutionWord1;

    IBOutlet id elapsedTime;



    NSDictionary * jumbleDictionary;



    }









    I remember that I also had to use setObjectValue: to change the string, since it was really an NSTextField. Still haven't figured that one out.
  • Reply 38 of 47
    Quote:
    Originally Posted by lundy


    Eh - I was mistaken - it's really defined as an IBOutlet and I couldn't cast it as an NSMutableString



    from JumbleController.h :



    Code:




    @interface JumbleController : NSObject

    {

    IBOutlet id JumbleWord1;

    IBOutlet id SolutionWord1;

    IBOutlet id elapsedTime;



    NSDictionary * jumbleDictionary;



    }









    I remember that I also had to use setObjectValue: to change the string, since it was really an NSTextField. Still haven't figured that one out.



    NSTextField inherits from NSControl which has the following methods:



    ? doubleValue

    ? setDoubleValue:

    ? floatValue

    ? setFloatValue:

    ? intValue

    ? setIntValue:

    ? objectValue

    ? setObjectValue:

    ? stringValue

    ? setStringValue:

    ? attributedStringValue

    ? setAttributedStringValue:
  • Reply 39 of 47
    Quote:
    Originally Posted by Splinemodel


    I'd use the C method, and dump it into a macro. No reason to dirty-up your cache with extra addressing.



    Yes, most of the compiled programming I do is for embedded ARMs.



    Unless the method is called regularly, from multiple places, in which case you're filling up your cache with duplicate code.



    There's a reason why compiler writers decided to start ignoring the "inline" keyword
  • Reply 40 of 47
    lundylundy Posts: 4,466member
    Quote:
    Originally Posted by Mr Beardsley


    NSTextField inherits from NSControl which has the following methods:



    Right. What I couldn't figure out was how to change that NSTextField (which comes in as type IBOutlet; internally it is type NSTextField) to an NSMutableString so that I could do string methods like "length" on it directly. I suppose I could just do a



    NSMutableString *myString = [JumbleWord1 stringValue];



    to cast it, and use myString from then on. I don't know if that is the preferred way of doing it though.
Sign In or Register to comment.