I've always wondered how the dependencies are managed from a programming language to its libraries. Take for example C#. When I was beginning to learn about computing, I would assume (wrongly as it turns out) that the language itself is designed independently of the class libraries that would eventually become available for it. That is, the set of language keywords (such as for, class or throw) plus the syntax and semantics are defined first, and libraries that can be used from the language are developed separately. The specific classes in those libraries, I used to think, should not have any impact on the design of the language.
But that doesn't work, or not all the time. Consider throw. The C# compiler makes sure that the expression following throw resolves to an exception type. Exception is a class in a library, and as such it should not be special at all. It would be a class as any other, except that the C# compiler assigns it that special semantics. That is very good, but my conclusion is that the design of the language does depend on the existence and behaviour of specific elements in the class libraries.
Additionally, I wonder how this dependency is managed. If I were to design a new programming language, what techniques would I use to map the semantics of throw to the very particular class that is Exception?
So my questions are two:
Am I correct in thinking that language design is tightly coupled to that of its base class libraries?
How are these dependencies managed from within the compiler and run-time? What techniques are used?
Thank you.
EDIT. Thanks to those who pointed out that my second question is very vague. I agree. What I am trying to learn is what kind of references the compiler stores about the types it needs. For example, does it find the types by some kind of unique id? What happens when a new version of the compiler or the class libraries is released? I am aware that this is still pretty vague, and I don't expect a precise, single-paragraph answer; rather, pointers to literature or blog posts are most welcome.
What I am trying to learn is what kind of references the compiler stores about the types it needs. For example, does it find the types by some kind of unique id?
Obviously the C# compiler maintains an internal database of all the types available to it in both source code and metadata; this is why a compiler is called a "compiler" -- it compiles a collection of data about the sources and libraries.
When the C# compiler needs to, say, check whether an expression that is thrown is derived from or identical to System.Exception it pretends to do a global namespace lookup on System, and then it does a lookup on Exception, finds the class, and then compares the resulting class information to the type that was deduced for the expression.
The compiler team uses this technique because that way it works no matter whether we are compiling your source code and System.Exception is in metadata, or if we are compiling mscorlib itself and System.Exception is in source.
Of course as a performance optimization the compiler actually has a list of "known types" and populates that list early so that it does not have to undergo the expense of doing the lookup every time. As you can imagine, the number of times you'd have to look up the built-in types is extremely large. Once the list is populated then the type information for System.Exception can be just read out of the list without having to do the lookup.
What happens when a new version of the compiler or the class libraries is released?
What happens is: a whole bunch of developers, testers, managers, designers, writers and educators get together and spend a few million man-hours making sure that the compiler and the class libraries all work before they're released.
This question is, again, impossibly vague. What has to happen to make a new compiler release? A lot of work, that's what has to happen.
I am aware that this is still pretty vague, and I don't expect a precise, single-paragraph answer; rather, pointers to literature or blog posts are most welcome.
I write a blog about, among other things, the design of the C# language and its compiler. It's at http://ericlippert.com.
I would assume (perhaps wrongly) that the language itself is designed independently of the class libraries that would eventually become available for it.
Your assumption is, in the case of C#, completely wrong. C# 1.0, the CLR 1.0 and the .NET Framework 1.0 were all designed together. As the language, runtime and framework evolved, the designers of each worked very closely together to ensure that the right resources were allocated so that each could ship new features on time.
I do not understand where your completely false assumption comes from; that sounds like a highly inefficient way to write a high-level language and a great way to miss your deadlines.
I can see writing a language like C, which is basically a more pleasant syntax for assembler, without a library. But how would you possibly write, say, async-await without having the guy designing Task<T> in the room with you? It seems like an exercise in frustration.
Am I correct in thinking that language design is tightly coupled to that of its base class libraries?
In the case of C#, yes, absolutely. There are dozens of types that the C# language assumes are available and as-documented in order to work correctly.
I once spent a very frustrating hour with a developer who was having some completely crazy problem with a foreach loop before I discovered that he had written his own IEnumerable<T> that had slightly different methods than the real IEnumerable<T>. The solution to his problem: don't do that.
How are these dependencies managed from within the compiler and run-time?
I don't know how to even begin to answer this impossibly vague question.
All (practical) programming languages have a minimum number of required functions. For modern "OO" languages, this also includes a minimum number of required types.
If the type is required in the Language Specification, then it is required - regardless of how it is packaged.
Conversely, not all of the BCL is required to have a valid C# implementation. This is because not all of the BCL types are required by the Language Specification. For instance, System.Exception (see #16.2) and NullReferenceException are required, but FileNotFoundException is not required to implement the C# Language.
Note that even though the specification provides minimal definitions for base types (e.g System.String), it does not define the commonly-accepted methods (e.g. String.Replace). That is, almost all of the BCL is outside the scope of the Language Specification1.
.. but my conclusion is that the design of the language does depend on the existence and behaviour of specific elements in the class libraries.
I agree entirely and have included examples (and limits of such definitions) above.
.. If I were to design a new programming language, what techniques would I use to map the semantics of "throw" to the very particular class that is "Exception"?
I would not look primarily at the C# specification, but rather I would look at the Common Language Infrastructure specification. This new language should, for practically reasons, be designed to interoperate with existing CLI/CLR languages, but does not necessarily need to "be C#".
1 The CLI (and associated references) do define the requirements of a minimal BCL. So if it is taken that a valid C# implementation must conform to (or may assume) the CLI then there are many other types to consider that are not mentioned in the C# specification itself.
Unfortunately, I do not have sufficient knowledge of the 2nd (and more interesting) question.
my impression is that
in languages like C# and Ada
application source code is portable
standard library source code is not portable
accross compilers/implementations
Related
C# is, unlike C++, a language that hides technical stuff from the developer. No pointers (except in unsafe code) and garbage collection are examples of this. As I understand, C# wants the developer to focus only on the concepts and not the underlying architecture, memory handling etc..
But then, why does the developer have to decide where an object is to be stored? For class it is always on the heap, for struct it is either on the stack (if local variable) or inline (if member of an object).
Isn't that something the compiler could figure out either based on the class definition (it could estimate needed memory space and decide heuristically based on that) or based on the context a given instance is in (is it a local variable in a function, then stack; is it more global, then heap; is it member of an object, then base decision on its estimated memory space)?
PS: I know class and struct have more differences than that, namely reference equality versus value equality, but this is not point of my question. (And for those aspects, other solutions could be found to unlink these properties from the decision class/struct.)
Your question is not valid (I mean in a logical way) because it depends on a false premise:
The developper cannot really decide where an object is to be stored, because this is an implementation detail.
See this answer discussing struct on heap or stack,
or this question: C# structs/classes stack/heap control?
The first links to Eric Lippert's blog. Here is an extract:
Almost every article I see that describes the difference between value
types and reference types explains in (frequently incorrect) detail
about what “the stack” is and how the major difference between value
types and reference types is that value types go on the stack. I’m
sure you can find dozens of examples by searching the web.
I find this characterization of a value type based on its
implementation details rather than its observable characteristics to
be both confusing and unfortunate. Surely the most relevant fact about
value types is not the implementation detail of how they are
allocated, but rather the by-design semantic meaning of “value type”,
namely that they are always copied “by value” . If the relevant thing
was their allocation details then we’d have called them “heap types”
and “stack types”. But that’s not relevant most of the time. Most of
the time the relevant thing is their copying and identity semantics.
I regret that the documentation does not focus on what is most
relevant; by focusing on a largely irrelevant implementation detail,
we enlarge the importance of that implementation detail and obscure
the importance of what makes a value type semantically useful. I
dearly wish that all those articles explaining what “the stack” is
would instead spend time explaining what exactly “copied by value”
means and how misunderstanding or misusing “copy by value” can cause
bugs.
C# is, unlike C++, a language that hides technical stuff from the developer
I do not think this is a fair characterization of c#. There is plenty of technical details a c# developer has to be aware of, and there are plenty of languages work on a much higher abstraction level. I think it would be more fair to say that C# aims to make it easy to write good, working code. Sometimes called "The pit of success" by Eric Lippert. See also C++ and the pit of despair.
Ideally you would just write code that describes the problem, and let the compiler sort out anything that has to do with performance. But writing compilers is hard, especially when you have a hard time constraint since you are compiling just in time. While language is theoretically unrelated to performance, practice show that higher level languages tend to be more difficult to optimize.
While there are important semantic differences between a struct and a class, the main reason to chose one or the other usually comes down to performance, and the performance is directly related to how they are stored and passed around. You would typically avoid many small objects, or passing around huge structs.
As a comparison, Java is very similar to C#, and did just fine without value types for many years. It seems however like they have or will introduce one to reduce the overhead of creating objects.
why does the developer have to decide where an object is to be stored?
The simple answer seem to be that determining the optimal storage location is difficult for the compiler to do. Letting the developer hint how the type is used helps improve performance for some situations and allow C# to be used in in situations where it would otherwise be unsuitable for. At the cost of making the language more complex and more difficult to learn.
the page at http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html says that double-checked locking is flawed in java. I'm just wondering does it also apply to other languages (C#, Vb, C++, etc)
I've read Double checked locking pattern: Broken or not?, Is this broken double checked locking?, How to solve the "Double-Checked Locking is Broken" Declaration in Java? to be truthful i don't know what the common consensus is. some say yes its broken others say no.
Anyway, my question is does it also apply to other languages (C#, Vb, C++, etc)
Double checked locking is safe in Java, PROVIDED THAT:
the instance variable is declared as volatile, AND
the JVM correctly implements the JSR-133 specification; i.e. it is compliant with Java 5 and later.
My source is the JSR-133 (Java Memory Model) FAQ - Jeremy Manson and Brian Goetz, February 2004. This is confirmed by Goetz in a number of other places.
However, as Goetz says, this is an idiom whose time has passed. Uncontended synchronization in Java is now fast, so he recommends that you just declare the getInstance() method as synchronized if you need to do lazy initialization. (And I imagine that this applies to other languages too ...)
Besides, all things being equal, it is a bad idea to write code that works in Java 5 but is unreliable in older JVMs.
OK, so what about the other languages? Well, it depends on how the idiom is implemented, and often on the platform.
C# - according to https://stackoverflow.com/a/1964832/139985, it is platform dependent whether the instance variable needs to be volatile. However, Wikipedia says that if you do use volatile or explicit memory barriers, the idiom can be implemented safely.
VB - according to Wikipedia the idiom can be implemented safely using explicit memory barriers.
C++ - according to Wikipedia the idiom can be implemented safely using volatile in Visual C++ 2005. But other sources say that in general the C++ language specification doesn't provide sufficient guarantees for volatile to be sure. However double-checked locking can be implemented in the context of the C++ 2011 language revision - https://stackoverflow.com/a/6099828/139985.
(Note: I'm just summarizing some sources I found which seem to me to be recent ... and sound. I'm not C++, C# or VB expert. Please read the linked pages and make your own judgements.)
This wikipedia article covers java, c++ and .net (c#/vb) http://en.wikipedia.org/wiki/Double-checked_locking
This is a tricky question, with a mine-field of contradictory information out there.
A part of the problem is that there are a few variants of double-checked locking:
The field checked on the fast path may be volatile or not.
There is a one-field variant and a two-field variant of double-checked locking.
And not only that, different authors have a different definition for what it means that the pattern is "correct".
Definition #1: A widely accepted specification of the programming language (e.g. ECMA for C#) guarantees that the pattern is correct.
Definition #2: The pattern works in practice on a particular architecture (typically x86).
As disagreeable as it might seem, a lot of code out there depends on Definition #2.
Let's take C# as an example. In C#, the double-checked pattern (as typically implemented) is correct according to Definition #1 if and only if the field is volatile. But if we consider Definition #2, pretty much all variants are correct on X86 (i.e., happen to work), even if the field is non-volatile. On Itanium, the one-field variant happens to work if the field is non-volatile, but not the two-field variant.
The unfortunate consequence is that you'll find articles making clearly contradictory statements on the correctness of this pattern.
As others have said, this idiom has had its time. FWIW, for lazy initialization, .Net now provides a built-in class: System.Lazy<T> (msdn). Don't know if something similar is available in java though.
It was flawed in Java, it was fixed in Java 5. The fact that is was broken was more of an implementation issue coupled with a misunderstanding than a technically "bad idea".
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 9 years ago.
I've been working with C# and more generally the .Net framework for a couple of years now. I often heard about the similarity between C# & the Java language and would like to learn more about the second one.
Have you got any specific advice to learn Java when coming from C# ?
Any common errors a C# programmer would do when starting Java ?
Any documentation showing the habits you can keep and the ones you must change (still in a C# to Java optic, so something a bit more specific then a C# vs Java comparison) ?
Well, while C# and Java are superficially alike there are a number of small differences that might bite you. Generally I think the opposite direction—going from Java to C#—is less problematic. This is mainly due to C# being a more complex language so you might find many simplifications from common Java patterns but the other way around might be a little painful.
Things to look out for (partial list, not guaranteed to be exhaustive):
Different ...
Naming conventions. In Java only type names start with a capital letter (i. e. PascalCase), everything else uses camelCase. Not very hard to adhere to, though.
Also interfaces generally don't start with I. On the other hand you have to implement them with a different keyword. Doesn't really help in the middle of the code, though.
Class library :-)
While obvious, this has been the thing I spent most time on when learning a language. When dealing with a known paradigm the syntax differences are quickly sorted out, but getting to know the standard library / class library / framework takes some time in some cases :-)
Patterns. Well, not quite, it's still the same stuff. But C# supports some patterns at the language level, while you still have to implement them yourself in Java. No events, but the Observer pattern (very prevalent in Swing—whenever you see a Listener, you know what to do :-))
Exception handling. Java has so-called checked exceptions which means that an exception must either be caught or declared upwards. Usually this means that you have
catch (SomeException ex) {
ex.printStackTrace();
}
pretty often in your code1 :-)
Types. While .NET has normal objects and value types, they both are objects and support methods, properties, &c. Java has a dichotomy of primitive types, such as int, float, char, &c. and classes such as String. Doesn't matter much since they implemented auto-boxing, but sometimes it's still annoying to wrap int in Integer.
Polymorphism: All Java methods are virtual by default whereas c# methods are not.
Minor syntactic differences.
foreach (a in b) → for (a : b)
Different access keywords. Things like internal and protected internal don't exist. But unqualified members are visible to other classes in the same package (sort of internal, but then again not quite).
String comparison isn't done with == in Java. You have to use .equals(). While in C# == on strings is value equality, in Java == is always reference equality.
No ...
Properties. In Java this is generally done with the Foo getFoo()/void setFoo(Foo foo) pattern which C# generates silently behind your back when using properties but you have to do it explicitly in Java. Generally, to keep the language itself simpler many things in Java are just conventions. Still, most of the time you're better off adhering to them :-)
Operator overloading. Deemed a hazard to the righteous programmer they weren't implemented for fear of abuse. Don't need them too often anyway, not even in C#, but sometimes they are nice and then you're missing something.
Indexers. You always have to access list items through myList.get(5) instead of the array-like syntax myList[5]. Just a mild inconvenience, though.
LINQ (though there exist implementations2 but it's not as nicely integrated), or lambda functions3 (no delegates anyway, but anonymous classes), extension methods, or partial classes (yes, that's a painful one when dealing with Swing, unless you're very disciplined), and a few more things.
Multidimensional arrays. You can use jagged arrays (arrays of arrays), buttrue multidimensionality isn't there.
Generics are compile-time only, at runtime only Objects remain. Also wildcards in generics can be hard to resolve sometimes when the compiler complains about all of the four ? in your generics having different types. (Though to be fair: That was a case where I would have needed type information at runtime anyway so I reverted back to Objects).
General advice: Grab a friend with Java experience and let him glance over your code. While he probably can't tell you everything you should take care of when you directly ask him that question, he can spot strange things in code just fine and notify you of that. This has greatly helped me learning Java (although I learned Java first and then C#, so it might be different).
1 Yes, I know many catch blocks look different, but still, this is probably the archetypical one and not even that rare.
2 Quaere, JaQue, JaQu, Querydsl
3 There's lambdaj, though. Thanks for pointing that out, Esko.
I honestly think the biggest hurdle for many C# developers trying to learn Java is learning a new IDE. Visual Studio is great, and when you're coding in C# for a long period of time, you get used to it. When having to move over to Eclipse or Netbeans, you suddenly feel lost. How do I set a breakpoint? Where's the immediate window? How do I create a windows app? etc etc... I know this sounds crazy, but I'm telling you, people get very attached to their IDE's and have a tough time getting used to new ones...
Languages themselves are pretty similar, sans few keywords and Java lacking some features C# programmers got used to (properties, using, reified (non-type-erased) generics).
The main problem here is knowledge of frameworks, of which there are thousands for Java.
The main language is fine. Getting to know the libraries will be one thing which takes time. If you're doing web-applications, there is a LOT to learn... equivalent technologies to WCF and ASP.net.
You don't say what kind of area you work in... desktop, server, or web-server?
Biggest difference between C# and Java : In Java, all methods are virtual. Hence the reason why tools such as NUnit and such came from the Java world.
To be honest, if you're a competent C# programmer I don't believe there's much you do need to know apart from packaging and deployment of applications.
Here's a good link http://en.wikipedia.org/wiki/Comparison_of_Java_and_C_Sharp
The biggest thing you need to learn is how to Greenspun C#'s functional style features in Java. For example, you can expect to make a lot of interfaces with only one method to get around Java's lack of lambda functions and delegates.
I honestly recommend Java in a Nutshell. Most Java/any_other_lang introduction books are for totally novice readers explaining the concept of a loop for pages and recursion for a chapter... You can start writing Java programs within two days with this book. Of course it will take you a long time to understand what is going on under the hood and how to use all the available framework. But once the language itself is mastered, it is easy to get along even with google only resources.
Although, this is the other way around, I found the following link to be quite useful for comparing Java and C#.
C# From a Java Developer's Perspective
I made a transition from Java to C# and back to Java again. I think syntactically they are very similar and most of the trouble I had was learning the .NET APIs and learning how to use them effectively. Many times I was using 'syntactic sugar', writing my code as if it was in Java and then translating it to C#. I spent a lot of time on Microsoft's website reading and learning about the APIs which was a huge help.
I am currently developing an application where you can create "programs" with it without writing source code, just click&play if you like.
Now the question is how do I generate an executable program from my data model. There are many possibilities but I am not sure which one is the best for me. I need to generate assemblies with classes and namespace and everything which can be part of the application.
CodeDOM class: I heard of lots of limitations and bugs of this class. I need to create attributes on method parameters and return values. Is this supported?
Create C# source code programmatically and then call CompileAssemblyFromFile on it: This would work since I can generate any code I want and C# supports most CLR features. But wouldn't this be slow?
Use the reflection ILGenerator class: I think with this I can generate every possible .NET code. But I think this is much more complicated and error prone than the other approaches?
Are there other possible solutions?
EDIT:
The tool is general for developing applications, it is not restricted to a specific domain. I don't know if it can be considered a visual programming language. The user can create classes, methods, method calls, all kinds of expressions. It won't be very limitating because you should be able to do most things which are allowed in real programming languages.
At the moment lots of things must still be written by the user as text, but the goal at the end is, that nearly everything can be clicked together.
You my find it is rewarding to look at the Dynamic Language Runtime which is more or less designed for creating high-level languages based on .NET.
It's perhaps also worth looking at some of the previous Stack Overflow threads on Domain Specific Languages which contain some useful links to tools for working with DSLs, which sounds a little like what you are planning although I'm still not absolutely clear from the question what exactly your aim is.
Most things "click and play" should be simple enough just to stick some pre-defined building-block objects together (probably using interfaces on the boundaries). Meaning: you might not need to do dynamic code generation - just "fake it". For example, using property-bag objects (like DataTable etc, although that isn't my first choice) for values, etc.
Another option for dynamic evaluation is the Expression class; especially in .NET 4.0, this is hugely versatile, and allows compilation to a delegate.
Do the C# source generation and don't care about speed until it matters. The C# compiler is quite quick.
When I wrote a dynamic code generator, I relied heavily on System.Reflection.Emit.
Basically, you programatically create dynamic assemblies and add new types to them. These types are constructed using the Emit constructs (properties, events, fields, etc..). When it comes to implementing methods, you'll have to use an ILGenerator to pump out MSIL op-codes into your method. That sounds super scary, but you can use a couple of tools to help:
A pre-built sample implementation
ILDasm to inspect the op-codes of the sample implementation.
It depends on your requirements, CodeDOM would certainly be the best fit for a "program" stored it in a "data model".
However its unlikely that using option 2 will be in any way measurably slower in comparision with any other approach.
I would echo others in that 1) the compiler is quick, and 2) "Click and Play" things should be simple enough so that no single widget added to a pile of widgets can make it an illegal pile.
Good luck. I'm skeptical that you can achieve point (2) for anything but really toy-level programs.
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
I've recently purchased a Mac and use it primarily for C# development under VMWare Fusion. With all the nice Mac applications around I've started thinking about Xcode lurking just an install click away, and learning Objective-C.
The syntax between the two languages looks very different, presumably because Objective-C has its origins in C and C# has its origins in Java/C++. But different syntaxes can be learnt so that should be OK.
My main concern is working with the language and if it will help to produce well-structured, readable and elegant code. I really enjoy features such as LINQ and var in C# and wonder if there are equivalents or better/different features in Objective-C.
What language features will I miss developing with Objective-C? What features will I gain?
Edit: The framework comparisons are useful and interesting but a language comparison are what this question is really asking (partly my fault for originally tagging with .net). Presumably both Cocoa and .NET are very rich frameworks in their own right and both have their purpose, one targeting Mac OS X and the other Windows.
Thank you for the well thought out and reasonably balanced viewpoints so far!
No language is perfect for all tasks, and Objective-C is no exception, but there are some very specific niceties. Like using LINQ and var (for which I'm not aware of a direct replacement), some of these are strictly language-related, and others are framework-related.
(NOTE: Just as C# is tightly coupled with .NET, Objective-C is tightly coupled with Cocoa. Hence, some of my points may seem unrelated to Objective-C, but Objective-C without Cocoa is akin to C# without .NET / WPF / LINQ, running under Mono, etc. It's just not the way things are usually done.)
I won't pretend to fully elaborate the differences, pros, and cons, but here are some that jump to mind.
One of the best parts of Objective-C is the dynamic nature — rather than calling methods, you send messages, which the runtime routes dynamically. Combined (judiciously) with dynamic typing, this can make a lot of powerful patterns simpler or even trivial to implement.
As a strict superset of C, Objective-C trusts that you know what you're doing. Unlike the managed and/or typesafe approach of languages like C# and Java, Objective-C lets you do what you want and experience the consequences. Obviously this can be dangerous at times, but the fact that the language doesn't actively prevent you from doing most things is quite powerful. (EDIT: I should clarify that C# also has "unsafe" features and functionality, but they default behavior is managed code, which you have to explicitly opt out of. By comparison, Java only allows for typesafe code, and never exposes raw pointers in the way that C and others do.)
Categories (adding/modifying methods on a class without subclassing or having access to source) is an awesome double-edged sword. It can vastly simplify inheritance hierarchies and eliminate code, but if you do something strange, the results can sometimes be baffling.
Cocoa makes creating GUI apps much simpler in many ways, but you do have to wrap your head around the paradigm. MVC design is pervasive in Cocoa, and patterns such as delegates, notifications, and multi-threaded GUI apps are well-suited to Objective-C.
Cocoa bindings and key-value observing can eliminate tons of glue code, and the Cocoa frameworks leverage this extensively. Objective-C's dynamic dispatch works hand-in-hand with this, so the type of the object doesn't matter as long as it's key-value compliant.
You will likely miss generics and namespaces, and they have their benefits, but in the Objective-C mindset and paradigm, they would be niceties rather than necessities. (Generics are all about type safety and avoiding casting, but dynamic typing in Objective-C makes this essentially a non-issue. Namespaces would be nice if done well, but it's simple enough to avoid conflicts that the cost arguably outweighs the benefits, especially for legacy code.)
For concurrency, Blocks (a new language feature in Snow Leopard, and implemented in scores of Cocoa APIs) are extremely useful. A few lines (frequently coupled with Grand Central Dispatch, which is part of libsystem on 10.6) can eliminates significant boilerplate of callback functions, context, etc. (Blocks can also be used in C and C++, and could certainly be added to C#, which would be awesome.) NSOperationQueue is also a very convenient way to add concurrency to your own code, by dispatching either custom NSOperation subclasses or anonymous blocks which GCD automatically executes on one or more different threads for you.
I've been programming in C, C++ and C# now for over 20 years, first started in 1990. I have just decided to have a look at the iPhone development and Xcode and Objective-C. Oh my goodness... all the complaints about Microsoft I take back, I realise now how bad things code have been. Objective-C is over complex compared to what C# does. I have been spoilt with C# and now I appreciate all the hard work Microsoft have put in. Just reading Objective-C with method invokes is difficult to read. C# is elegant in this. That is just my opinion, I hoped that the Apple development language was a good as the Apple products, but dear me, they have a lot to learn from Microsoft. There is no question C#.NET application I can get an application up and running many times faster than XCode Objective-C. Apple should certainly take a leaf out of Microsoft's book here and then we'd have the perfect environment. :-)
No technical review here, but I just find Objective-C much less readable.
Given the example Cinder6 gave you:
C#
List<string> strings = new List<string>();
strings.Add("xyzzy"); // takes only strings
strings.Add(15); // compiler error
string x = strings[0]; // guaranteed to be a string
strings.RemoveAt(0); // or non-existant (yielding an exception)
Objective-C
NSMutableArray *strings = [NSMutableArray array];
[strings addObject:#"xyzzy"];
[strings addObject:#15];
NSString *x = strings[0];
[strings removeObjectAtIndex:0];
It looks awful. I even tried reading 2 books on it, they lost me early on,
and normally I don't get that with programming books / languages.
I'm glad we have Mono for Mac OS, because if I'd had to rely on Apple
to give me a good development environment...
Manual memory management is something beginners to Objective-C seems to have most problem with, mostly because they think it is more complex than it is.
Objective-C and Cocoa by extension relies on conventions over enforcement; know and follow a very small set of rules and you get a lot for free by the dynamic run-time in return.
The not 100% true rule, but good enough for everyday is:
Every call to alloc should be matched with a release at the end of the current scope.
If the return value for your method has been obtained by alloc then it should be returned by return [value autorelease]; instead of being matched by a release.
Use properties, and there is no rule three.
The longer explanation follows.
Memory management is based on ownership; only the owner of an object instance should ever release the object, everybody else should always do nothing. This mean that in 95% of all code you treat Objective-C as if it was garbage collected.
So what about the other 5%? You have three methods to look out for, any object instance received from these method are owned by the current method scope:
alloc
Any method beginning with the word new, such as new or newService.
Any method containing the word copy, such as copy and mutableCopy.
The method have three possible options as of what to do with it's owned object instances before it exits:
Release it using release if it is no longer needed.
Give ownership to the a field (instance variable), or a global variable by simply assigning it.
Relinquish ownership but give someone else a chance to take ownership before the instance goes away by calling autorelease.
So when should you pro-actively take ownership by calling retain? Two cases:
When assigning fields in your initializers.
When manually implementing setter method.
Sure, if everything you saw in your life is Objective C, then its syntax looks like the only possible. We could call you a "programming virgin".
But since lots of code is written in C, C++, Java, JavaScript, Pascal and other languages, you'll see that ObjectiveC is different from all of them, but not in a good way. Did they have a reason for this? Let's see other popular languages:
C++ added a lot extras to C, but it changed the original syntax only as much as needed.
C# added a lot extras compared to C++ but it changed only things that were ugly in C++ (like removing the "::" from the interface).
Java changed a lot of things, but it kept the familiar syntax except in parts where the change was needed.
JavaScript is a completely dynamic language that can do many things ObjectiveC can't. Still, its creators didn't invent a new way of calling methods and passing parameters just to be different from the rest of the world.
Visual Basic can pass parameters out of order, just like ObjectiveC. You can name the parameters, but you can also pass them the regular way. Whatever you use, it's normal comma-delimited way that everyone understands. Comma is the usual delimiter, not just in programming languages, but in books, newspapers, and written language in general.
Object Pascal has a different syntax than C, but its syntax is actually EASIER to read for the programmer (maybe not to the computer, but who cares what computer thinks). So maybe they digressed, but at least their result is better.
Python has a different syntax, which is even easier to read (for humans) than Pascal. So when they changed it, making it different, at least they made it better for us programmers.
And then we have ObjectiveC. Adding some improvements to C, but inventing its own interface syntax, method calling, parameter passing and what not. I wonder why didn't they swap + and - so that plus subtracts two numbers. It would have been even cooler.
Steve Jobs screwed up by supporting ObjectiveC. Of course he can't support C#, which is better, but belongs to his worst competitor. So this is a political decision, not a practical one. Technology always suffers when tech decisions are made for political reasons. He should lead the company, which he does good, and leave programming matters to real experts.
I'm sure there would be even more apps for iPhone if he decided to write iOS and support libraries in any other language than ObjectiveC. To everyone except die-hard fans, virgin programmers and Steve Jobs, ObjectiveC looks ridiculous, ugly and repulsive.
One thing I love about objective-c is that the object system is based on messages, it lets you do really nice things you couldn't do in C# (at least not until they support the dynamic keyword!).
Another great thing about writing cocoa apps is Interface Builder, it's a lot nicer than the forms designer in Visual Studio.
The things about obj-c that annoy me (as a C# developer) are the fact that you have to manage your own memory (there's garbage collection, but that doesn't work on the iPhone) and that it can be very verbose because of the selector syntax and all the [ ].
As a programmer just getting started with Objective-C for iPhone, coming from C# 4.0, I'm missing lambda expressions, and in particular, Linq-to-XML. The lambda expressions are C#-specific, while the Linq-to-XML is really more of a .NET vs. Cocoa contrast. In a sample app I was writing, I had some XML in a string. I wanted to parse the elements of that XML into a collection of objects.
To accomplish this in Objective-C/Cocoa, I had to use the NSXmlParser class. This class relies on another object which implements the NSXMLParserDelegate protocol with methods that are called (read: messages sent) when an element open tag is read, when some data is read (usually inside the element), and when some element end tag is read. You have to keep track of the parsing status and state. And I honestly have no idea what happens if the XML is invalid. It's great for getting down to the details and optimize performance, but oh man, that's a whole lot of code.
By contrast, here's the code in C#:
using System.Linq.Xml;
XDocument doc = XDocument.Load(xmlString);
IEnumerable<MyCustomObject> objects = doc.Descendants().Select(
d => new MyCustomObject{ Name = d.Value});
And that's it, you've got a collection of custom objects drawn from XML. If you wanted to filter those elements by value, or only to those that contain a specific attribute, or if you just wanted the first 5, or to skip the first 1 and get the next 3, or just find out if any elements were returned... BAM, all right there in the same line of code.
There are many open-source classes that make this processing a lot easier in Objective-C, so that does much of the heavy lifting. It's just not this built in.
*NOTE: I didn't actually compile the code above, it's just meant as an example to illustrate the relative lack of verbosity required by C#.
Probably most important difference is memory management. With C# you get garbage collection, by virtue of it being a CLR based language. With Objective-C you need to manage memory yourself.
If you're coming from a C# background (or any modern language for that matter), moving to a language without automatic memory management will be really painful, as you will spend a lot of your coding time on properly managing memory (and debugging as well).
Here's a pretty good article comparing the two languages:
http://www.coderetard.com/2008/03/16/c-vs-objective-c/
Other than the paradigm difference between the 2 languages, there's not a lot of difference. As much as I hate to say it, you can do the same kind of things (probably not as easily) with .NET and C# as you can with Objective-C and Cocoa. As of Leopard, Objective-C 2.0 has garbage collection, so you don't have to manage memory yourself unless you want to (code compatibility with older Macs and iPhone apps are 2 reasons to want to).
As far as structured, readable code is concerned, much of the burden there lies with the programmer, as with any other language. However, I find that the message passing paradigm lends itself well to readable code provided you name your functions/methods appropriately (again, just like any other language).
I'll be the first to admit that I'm not very familiar with C# or .NET. But the reasons Quinn listed above are quite a few reasons that I don't care to become so.
The method calls used in obj-c make for easily read code, in my opinion much more elegant than c# and obj-c is built on top of c so all c code should work fine in obj-c. The big seller for me though is that obj-c is an open standard so you can find compilers for any system.