I'm not sure how well this works, but Nimbus (iOS framework) lets you embed itself in your own static library with a custom prefix via preprocessor macros. It would helpful if more libraries provide this feature.
The framework is divided into modules. For each module you include in your static lib (even the ones that gets added indirectly), you need to add its namespace header file. The file you linked to is the namespace header for the Core module. There are more.
Perhaps this could be avoided by just replacing all class names with macros (e.g. _N(NILinkedList)), though that might hinder code completion.
If you are building your own static library and would like to distribute Nimbus with it, this feature allows you to add a prefix to all Nimbus classes without having you to manually rename them. This lets users of your static lib free to include Nimbus with their project without triggering a name conflict with the one included with your lib.
In a vm you can do dynamic loading and bytecode manipulation tricks that are much harder to do in native code. Look at all the crazy AOP stuff people have done on the JVM.
At first glance yes, but as always with Java when you dig under the hood you see tight coupling to bad ideas from the early 90s. Given the OO/Java mantra of decoupling I'm not sure why the namespace is a consequence of the filepath they seem far too tightly integrated.
Agreed - C# fixed this, though (by default it maps to the directory structure, but you can change this). Scala encourages Java-style packages but lets you put them wherever you want.
I find that an irritating pain with scala, actually. I move a file from one directory to another, then spend ten minutes trying to figure out why lift still can't find the class, before the facepalm moment where I realise I didn't change the package declaration in the file.
I agree that it's actually sort of stupid to allow it--I used the word choice I did intentionally, because C# 'fixed' it (its strong IDE support makes having files in different places pretty much impossible unless you want it to happen), but Scala isn't so lucky. At least I get it when I use IntelliJ, which doesn't even tell me before updating the package declaration. :)
I use Play or a home-rolled solution based on vertx, though. so I don't have to worry so much about finding them.
Haskell's hierarchical modules extension is also very, very good. Amongst other things, it fixes Python's issue of lacking independent "namespaces" (mapping namespaces to packages or modules directly means you can't have two packages living in the same namespace easily)
Still has one failure though: the default import is both qualified and unqualified, I think it should have been qualified only.
This situation is most commonly encountered on iOS, with ad networks and SBJson.
As the developer behind one of the ad network SDKs included in countless iOS apps, I struggled finding a good solution to this problem. Spoiler: there isn't one.
The good news is, while there were often collisions on SBJson; pretty much all versions of the version are compatible. For a while, we would compile our static library without the SBJson objects, and ship the library and SBJson separately.
Recently we decided to create our own fork of SBJson, and switch to using our own prefix, which allowed us to embed it in our library, and not worry about what other libraries were doing.
Note: another tricky gotcha with static libraries for iOS: There is a bug in the linker, in that it will not import Objective-C categories from `.o` files unless there is another another symbol that is recognized, such as a class of C function. This has caused crashers and much headache.
Yes, but that's a flag that our library's users would have to figure out how to add to their project. And if they forget to, it would create crashes at runtime. That's not a can of worm we were willing to open.
Namespaces don't really solve that problem, do they?. Your options are to either fork SBJson and give it its own namespace/prefix, or require SBJson as an external dependency and lets your users provide their own version of the framework.
I prefer if SBJSON is an external dependency, since there's less chance that I need to modify external projects my own projects make use of. The downside of course is that not all external projects might use the same version of SBJSON, so method names could have changed, could be missing, etc... So it falls to the developer to provide patches to external libraries if they use an outdated version of a library like SBJSON.
I've never used namespaces in C++, and they aren't supported in C. And yet the only collisions I've seen between libraries are from un-prefixed identifiers. There's a whole pile of them in the Win32 headers of course. I ended up with a variable called "compress" once, in a function that was calling zlib. And Bink has a U32 or u32 typedef that conflicted with the same one in the code I was working on at the time.
Aside from that, no problems noted - of course, I cannot claim to have seen every program ever, and it is straightforward to engineer problems cases. But if a namespace collision is somehow news, you may assume that they are rarer in practice than you might imagine.
>Funny how Apple still relies on language without any form of namespace support for their system.
Yeah, very funny, especially since they don't have any other pragmatic reasons to use it, ie. it being a more dynamic OO C than C++ while retaining full C power, them having huge API libraries for it over 25 years of NeXT/OS X development, etc etc.
>Prefixes are not a solution as they have no ways to avoid collisions.
It's not like you use lots of third party libs (if any at all) in OS X.
>So much for supporting large scale development with Objective-C.
Yeah, I mean they have just those tiny projects in it, like iPhoto, Final Cut Pro, Pages, Numbers, the whole Cocoa and Cocoa Touch stack, etc.
But we need more support for large scale development, because there are many many teams of 100s of programmers that also want to write 20 million lines Objective-C programs.
And C is even worse, you just have small projects like the Linux kernel written in it, due to the severe issue of lack of namespaces.
> It's not like you use lots of third party libs (if any at all) in OS X.
Yeah, that only works if you don't use any third party stuff.
> Yeah, I mean they have just those tiny projects in it, like iPhoto, Final Cut Pro, Pages, Numbers, the whole Cocoa and Cocoa Touch stack, etc.
There are all internal Apple projects, as such the company can decide which prefixes to use. If they happen to clash with some third party small company, bad luck for the external company.
> But we need more support for large scale development, because there are many many teams of 100s of programmers that also want to write 20 million lines Objective-C programs.
Well, most projects I work on professionally, are the typical enterprise projects with 100+ developers, scattered across the globe.
> And C is even worse, you just have small projects like the Linux kernel written in it, due to the severe issue of lack of namespaces.
While you're being sarcastic here, let me tell you that Linux kernel works, because everyone that wants to add code to the kernel is obliged to follow certain conventions.
You cannot have that with third party code that you don't control.
Specially if it is delivered as commercial closed source libraries, which is quite common in the enterprise world.
A month ago, Kyle Sluder proposed a namespacing system for Objective-C[1]. There has been a lively discussion both in the comments and on the objc-language mailing list[2].
This is interesting, but doing it all at the compiler and language level seems like overkill. ObjC is a dynamic language, so the important thing is to have namespacing support in the runtime. If the user of a framework or bundle can specify a (reified) namespace to load a bundle's classes/protocols/etc and the runtime and language support A.B.C style class and protocol names, that might be enough to solve name collision problems. The framework/bundle author need not then bother to find a suitable globally unique name. This would certainly be enough to solve the original poster's problem.
I'm not sure I've thought through all issues with the above approach, but the whole @namespace thing seems gross overkill to me.
Despite the accepted answer saying to use bundle unloading, please don't. It may be supported in theory but in practice unloading a bundle leaves all kinds of opportunities for stale pointers and crashing.
35 comments
[ 4.6 ms ] story [ 54.3 ms ] threadhttp://wiki.nimbuskit.info/Nimbus-Namespacing
Perhaps this could be avoided by just replacing all class names with macros (e.g. _N(NILinkedList)), though that might hinder code completion.
Now that I think about it, I see that I don't have any idea how 'dylib's work... I should look them up.
On the other hand, with a carefully chosen three letter prefix these kinds of collisions should be pretty rare in practice.
Namespace mangling and more importantly a lack of standard for it are not required to implement namespaces.
In Obj-C it really wouldn't be that difficult to make an @namespace directive that just prepended the namespace to the class.
Could be semantically equivalent toI wouldn't mind seeing explicit namespace support in Obj-C although I can't say I've run into any namespace clashes in my own code yet.
Why so? Since the late 70's every language that supports modules has already solved this problem, and many of them have native code compilers.
That is how you do cool demoscene stuff in 4096K or less, with lots of self rewriting code.
It has nothing to do with the VM and everything to do with the implementation of namespaces/calling conventions being 'undefined'
It's insane.
I use Play or a home-rolled solution based on vertx, though. so I don't have to worry so much about finding them.
Still has one failure though: the default import is both qualified and unqualified, I think it should have been qualified only.
Only C and Objective-C don't, and force everyone to come up with prefixes.
And when collisions do happen, you have to resort to preprocessor tricks to work around it.
As the developer behind one of the ad network SDKs included in countless iOS apps, I struggled finding a good solution to this problem. Spoiler: there isn't one.
The good news is, while there were often collisions on SBJson; pretty much all versions of the version are compatible. For a while, we would compile our static library without the SBJson objects, and ship the library and SBJson separately.
Recently we decided to create our own fork of SBJson, and switch to using our own prefix, which allowed us to embed it in our library, and not worry about what other libraries were doing.
Note: another tricky gotcha with static libraries for iOS: There is a bug in the linker, in that it will not import Objective-C categories from `.o` files unless there is another another symbol that is recognized, such as a class of C function. This has caused crashers and much headache.
c.f. the "Important" box in http://developer.apple.com/library/mac/#qa/qa1490/_index.htm...
Still, this is for me the preferred approach.
Prefixes are not a solution as they have no ways to avoid collisions.
So much for supporting large scale development with Objective-C.
I've never used namespaces in C++, and they aren't supported in C. And yet the only collisions I've seen between libraries are from un-prefixed identifiers. There's a whole pile of them in the Win32 headers of course. I ended up with a variable called "compress" once, in a function that was calling zlib. And Bink has a U32 or u32 typedef that conflicted with the same one in the code I was working on at the time.
Aside from that, no problems noted - of course, I cannot claim to have seen every program ever, and it is straightforward to engineer problems cases. But if a namespace collision is somehow news, you may assume that they are rarer in practice than you might imagine.
Yeah, very funny, especially since they don't have any other pragmatic reasons to use it, ie. it being a more dynamic OO C than C++ while retaining full C power, them having huge API libraries for it over 25 years of NeXT/OS X development, etc etc.
>Prefixes are not a solution as they have no ways to avoid collisions.
It's not like you use lots of third party libs (if any at all) in OS X.
>So much for supporting large scale development with Objective-C.
Yeah, I mean they have just those tiny projects in it, like iPhoto, Final Cut Pro, Pages, Numbers, the whole Cocoa and Cocoa Touch stack, etc.
But we need more support for large scale development, because there are many many teams of 100s of programmers that also want to write 20 million lines Objective-C programs.
And C is even worse, you just have small projects like the Linux kernel written in it, due to the severe issue of lack of namespaces.
/s
Yeah, that only works if you don't use any third party stuff.
> Yeah, I mean they have just those tiny projects in it, like iPhoto, Final Cut Pro, Pages, Numbers, the whole Cocoa and Cocoa Touch stack, etc.
There are all internal Apple projects, as such the company can decide which prefixes to use. If they happen to clash with some third party small company, bad luck for the external company.
> But we need more support for large scale development, because there are many many teams of 100s of programmers that also want to write 20 million lines Objective-C programs.
Well, most projects I work on professionally, are the typical enterprise projects with 100+ developers, scattered across the globe.
> And C is even worse, you just have small projects like the Linux kernel written in it, due to the severe issue of lack of namespaces.
While you're being sarcastic here, let me tell you that Linux kernel works, because everyone that wants to add code to the kernel is obliged to follow certain conventions.
You cannot have that with third party code that you don't control.
Specially if it is delivered as commercial closed source libraries, which is quite common in the enterprise world.
1: http://www.optshiftk.com/2012/04/draft-proposal-for-namespac...
2: http://lists.apple.com/archives/objc-language/2012/Apr/msg00...
I'm not sure I've thought through all issues with the above approach, but the whole @namespace thing seems gross overkill to me.