Personally I think it's an awful idea to use meta-programming without an exceptionally good reason in production code. Like excessive use of function pointers in C. Just because you can doesn't mean you should. Programming in this style causes more code complexity and will accelerate the rate at a which a codebase becomes a mess, not to mention it's really slow.
I think the real problem is dynamic metaprogramming. Things like method_missing and the like can be very hard to reason about. However, static metaprogramming (ie code generation), can dramatically reduce maintenance costs and yield a fantastic regression testing mechanism for free: Just check-in the generated code!
New developers (less than 10 years professional experience) seem to become fascinated by "cool" language features that let them do unintuitive things and then approach problem solving with a mindset of "What cool tricks can I do to solve this?"
Instead, the experienced developer will always approach a problem with "What is the simplest way to solve this problem?"
A sensible compromise to me is that runtime meta-programming should be used to accomplish something sufficiently generic that it can be confined to a library.
Said library can then document (and test) the interface and implementation sufficiently to add a minimal amount of complexity to the application code.
The big red flag is using this stuff in application code to hack around bad design decisions or save on a small amount of typing (there's also no barrier to its expanding and engulfing the entire codebase).
Personally I think it's an awful idea to use meta-programming without an exceptionally good reason in production code
One of the less well known rules of thumb from extreme programming was to have just 5 to 7 "things you have to know" to write good code for a system. Only up to two of those things should be notably abstruse or automagically implicit. Preferably, it should be zero, and any fancy tricks should be transparent for most coding.
Really, this just follows from optimizing code for reading.
Wow, major hate on the metaprogramming in this post today. Note to self: I'm not working for any of you. K? k.
Anyway. The need for metaprogramming is like a lesser version of the need object-oriented programming. You never strictly need OOP. And you can totally go overboard with the Abstract Factory Factory, and make your code insanely obnoxious to follow.
But it can help, and it can specifically help in the situations when it simplifies more than it complicates -- in the situations where it's so simple you barely notice it. (Describing object attributes for your favorite ORM is a case that comes to mind.) If you're set in your ways and you've already made up your mind to eschew it always, then sooner or later you're going to end up with something more complicated than it should be instead of simpler, and it's just an empty piety. :P
I've never heard anyone describe function pointers as meta-programming before.
Functions are data, just like other kinds of data. I use them in C whenever what I want to parameterize is behavior, and not, say, an integer or a string.
I believe that if you explicitly avoid function pointers, and instead use a less appropriate construct, that would become a mess, instead. If you replace the function pointer with an enum, you've tightly coupled the type definition of the parameter with all users. You've added a switch statement on the enum, rather than a function pointer call. It would be both messier and probably slower than the function pointer.
With all the many languages I've used in my life, ObjC is actually my favorite to work with, especially with the modern runtime and features. I first used it in the 90's with NeXT WebObjects and was pleased to see it become popular again.
They're similar enough that MacRuby http://macruby.org/ is actually built on top of the Objective-C runtime (I'm surprised that the article doesn't mention that).
Yes, ruby has a strong smalltalk foundation (messages & runtime). Thus it makes sense to compare the roots of both langs in the way they interact with messages & the runtime.
I know that may not seem like a big deal but many major applications people care about seem to have first appeared on Mac OS / Mac OS X (yes, these are two very different things).
BTW: namespaces?! Not exactly my go to checklist feature for languages.
And MacOS applications. You know, the second bigger desktop platform.
But it's not like "where it's used" matters. That's mostly just a historical accident. If Microsoft had adopted it instead of C++ for example (which is not that outlandish), it would have been used a lot more. There was also NeXT that adopted ObjectiveC (it was developed before it), and OpenStep which also involed Sun and other players etc.
And compared to "being used for iOS apps" (e.g 1 million apps in the most lucrative mobile market", Lisp and Smalltalk are not used even 1/100 that. And Haskell even less (some "success story" here and there, eg an obscure bank, and that's mostly it). Does that make them bad languages?
And the fact that it doesn't have namespaces. Yeah, so like C. So that's important, because?
>Nope, that's exactly what I think it is.
Well, doesn't seem like you do. Or have any extended experience with the language. It's just empty snark to convey "oh, so obsolete".
How do namespaces come to be the feature to specifically call out? Is there something deeper to namespaces than a lexical (i.e. surface) convention around identifiers?
Yep. And the fact that Apple did absolutely nothing to evolve the language into something better shows that they just don't give a fuck about tools and most importantly about their developers! Maybe it's better than C++ or other alternative, maybe XCode is quite good, but this just show that since the days of NeXT (the 80s!), they just don't give a fuck!
...hate to say it, but nowadays the only big company that seems to care about developers and actually gives them cool tools and languages is Microsoft! C# with all its extensions, F# and the cool research they do in the languages area shows one thing: they care about us!
Please use this stuff sparingly though, especially things like resolveClassMethod: as it makes for some incredibly difficult to follow code that can segfault with some very strange error messages. Your future team members thank you.
i enjoyed this b/c i recently made the jump from ruby to obj-C and, though scary at first, i now feel incredibly comfortable working in obj-C and think i even prefer it. so, that's cool.
i do see at the bottom that this post is one of those "inbound marketing for job candidates" things. that's cool, too... but, i gotta say, as soon as i read the sign off, "If you want to work somewhere where..." i thought to myself, "not in a million f'ing years - that company is run by jerks!"...now, maybe the founders are actually good people but their public personae is just so off-putting that it totally undermines an otherwise well-done marketing blog post. i'm curious if that's just me or if they generally have trouble recruiting.
When I first started toying around with Objective-C and got past the syntactic differences with Ruby, I was struck by how similar Ruby and Objective-C are, and concluded that they were clearly inspired by a common source (Smalltalk) or by one another or both. Although this kind of thing is no doubt mentioned in the Wikipedia articles, it was interesting to observe the commonalities firsthand and in context.
On "concise syntax" - this works well when your vocabulary is large. But when you have to search for an English word that's sorta-like what you want to do, and then contort the definition to fit the algorithm, readability suffers. For example, JavaScript's Array.join() and SQL's JOIN are radically different concepts and the definitions are not interchangeable, only tangentially related in the respect that all the information being 'join'ed ends up in one [maybe larger] pile.
With respect to the article, concision looks like an artifact of standard practices by the languages users rather than any part of the language specification. One can be just as concise in ObjC (or C or Java), but the tradeoff is still readability.
I've never really thought about it before but PHP has some very similar metaprogramming features.
For starters, the incredibly dangerous runkit extension (like importing Objective-C's runtime).
There's also the Reflection API, which provides introspection and is quite widely used.
PHP also has magic methods, such as __call(), which give the ability to handle calling a method that doesn't exist.
As others have mentioned about Objective-C, these are all nice tools to know about and understand, however using them is often a code smell and can lead to unmaintainable code.
PHP doesn't have anything like categories, which is a shame because they look really useful in cases (as long as you don't mind violating the SRP a little). PHP has traits, which are more similar to mixins in ruby than categories in Objective-C.
These features are extremely difficult to use when C types are involved. @encode() mitigates this to some extent, but there are some C types that you can't fully express using @encode(), and it can't properly handle all types (namely out-pointers).
Yes. Using objc_msgSend and NSSelectorFromString, you can call functions, dynamically by name in Objective C.
Yes, it's dangerous. Clever, and not quite as easy as your favorite dynamic scripting language, but Obj-C supports it.
My favorite personal use case so far is an Objective-C state machine, where state names are strings, and state callback functions can be added to the code & called without declaration. It's not really saving much technically, but it eases just a tiny bit of mental & manual friction to be able to modify the code without having to update header files.
I like ObjC. It's true that what people generally use it for are the Cocoa features, but it could be a really good server language too (particularly with additions of blocks, GCD, and ARC). There are a lot of nice functional features that would make server development fun. It's pretty clear why Apple doesn't push it this way, but I think it could be a good server platform.
[+] [-] soup10|12 years ago|reply
[+] [-] brandonbloom|12 years ago|reply
[+] [-] ebbv|12 years ago|reply
New developers (less than 10 years professional experience) seem to become fascinated by "cool" language features that let them do unintuitive things and then approach problem solving with a mindset of "What cool tricks can I do to solve this?"
Instead, the experienced developer will always approach a problem with "What is the simplest way to solve this problem?"
[+] [-] chrisdevereux|12 years ago|reply
Said library can then document (and test) the interface and implementation sufficiently to add a minimal amount of complexity to the application code.
The big red flag is using this stuff in application code to hack around bad design decisions or save on a small amount of typing (there's also no barrier to its expanding and engulfing the entire codebase).
[+] [-] pornel|12 years ago|reply
https://www.mikeash.com/pyblog/friday-qa-2009-01-23.html
[+] [-] stcredzero|12 years ago|reply
One of the less well known rules of thumb from extreme programming was to have just 5 to 7 "things you have to know" to write good code for a system. Only up to two of those things should be notably abstruse or automagically implicit. Preferably, it should be zero, and any fancy tricks should be transparent for most coding.
Really, this just follows from optimizing code for reading.
[+] [-] fennecfoxen|12 years ago|reply
Anyway. The need for metaprogramming is like a lesser version of the need object-oriented programming. You never strictly need OOP. And you can totally go overboard with the Abstract Factory Factory, and make your code insanely obnoxious to follow.
But it can help, and it can specifically help in the situations when it simplifies more than it complicates -- in the situations where it's so simple you barely notice it. (Describing object attributes for your favorite ORM is a case that comes to mind.) If you're set in your ways and you've already made up your mind to eschew it always, then sooner or later you're going to end up with something more complicated than it should be instead of simpler, and it's just an empty piety. :P
[+] [-] Peaker|12 years ago|reply
Functions are data, just like other kinds of data. I use them in C whenever what I want to parameterize is behavior, and not, say, an integer or a string.
I believe that if you explicitly avoid function pointers, and instead use a less appropriate construct, that would become a mess, instead. If you replace the function pointer with an enum, you've tightly coupled the type definition of the parameter with all users. You've added a switch statement on the enum, rather than a function pointer call. It would be both messier and probably slower than the function pointer.
[+] [-] unknown|12 years ago|reply
[deleted]
[+] [-] coldcode|12 years ago|reply
[+] [-] nbevans|12 years ago|reply
[+] [-] pornel|12 years ago|reply
[+] [-] MrGando|12 years ago|reply
[+] [-] jimbokun|12 years ago|reply
http://www.rubymotion.com/
[+] [-] Touche|12 years ago|reply
A language without namespaces, that's used almost exclusively for iOS apps and nothing else. Nope, that's exactly what I think it is.
[+] [-] Tloewald|12 years ago|reply
I know that may not seem like a big deal but many major applications people care about seem to have first appeared on Mac OS / Mac OS X (yes, these are two very different things).
BTW: namespaces?! Not exactly my go to checklist feature for languages.
[+] [-] coldtea|12 years ago|reply
But it's not like "where it's used" matters. That's mostly just a historical accident. If Microsoft had adopted it instead of C++ for example (which is not that outlandish), it would have been used a lot more. There was also NeXT that adopted ObjectiveC (it was developed before it), and OpenStep which also involed Sun and other players etc.
And compared to "being used for iOS apps" (e.g 1 million apps in the most lucrative mobile market", Lisp and Smalltalk are not used even 1/100 that. And Haskell even less (some "success story" here and there, eg an obscure bank, and that's mostly it). Does that make them bad languages?
And the fact that it doesn't have namespaces. Yeah, so like C. So that's important, because?
>Nope, that's exactly what I think it is.
Well, doesn't seem like you do. Or have any extended experience with the language. It's just empty snark to convey "oh, so obsolete".
[+] [-] bennyg|12 years ago|reply
Instead of this Foundation::Array we get NSArray. Way easier to type out, and looks a million times cleaner to me.
[+] [-] luikore|12 years ago|reply
[+] [-] benched|12 years ago|reply
[+] [-] nnq|12 years ago|reply
...hate to say it, but nowadays the only big company that seems to care about developers and actually gives them cool tools and languages is Microsoft! C# with all its extensions, F# and the cool research they do in the languages area shows one thing: they care about us!
[+] [-] RyanZAG|12 years ago|reply
[+] [-] tempodox|12 years ago|reply
[+] [-] localhost3000|12 years ago|reply
i do see at the bottom that this post is one of those "inbound marketing for job candidates" things. that's cool, too... but, i gotta say, as soon as i read the sign off, "If you want to work somewhere where..." i thought to myself, "not in a million f'ing years - that company is run by jerks!"...now, maybe the founders are actually good people but their public personae is just so off-putting that it totally undermines an otherwise well-done marketing blog post. i'm curious if that's just me or if they generally have trouble recruiting.
[+] [-] babesh|12 years ago|reply
[+] [-] allochthon|12 years ago|reply
[+] [-] delinka|12 years ago|reply
With respect to the article, concision looks like an artifact of standard practices by the languages users rather than any part of the language specification. One can be just as concise in ObjC (or C or Java), but the tradeoff is still readability.
[+] [-] MrGando|12 years ago|reply
> Ruby and Objective-C look like opposites: one is dynamic, the other's static;
EDIT: Just read that the author basically denies those claims in the next paragraph.
[+] [-] swift|12 years ago|reply
[+] [-] pikachu_is_cool|12 years ago|reply
[+] [-] dave1010uk|12 years ago|reply
For starters, the incredibly dangerous runkit extension (like importing Objective-C's runtime).
There's also the Reflection API, which provides introspection and is quite widely used.
PHP also has magic methods, such as __call(), which give the ability to handle calling a method that doesn't exist.
As others have mentioned about Objective-C, these are all nice tools to know about and understand, however using them is often a code smell and can lead to unmaintainable code.
PHP doesn't have anything like categories, which is a shame because they look really useful in cases (as long as you don't mind violating the SRP a little). PHP has traits, which are more similar to mixins in ruby than categories in Objective-C.
Oh, PHP also has eval().
[+] [-] sdegutis|12 years ago|reply
[+] [-] dahart|12 years ago|reply
Yes, it's dangerous. Clever, and not quite as easy as your favorite dynamic scripting language, but Obj-C supports it.
My favorite personal use case so far is an Objective-C state machine, where state names are strings, and state callback functions can be added to the code & called without declaration. It's not really saving much technically, but it eases just a tiny bit of mental & manual friction to be able to modify the code without having to update header files.
[+] [-] cmollis|12 years ago|reply
[+] [-] tambourine_man|12 years ago|reply
[+] [-] pjmlp|12 years ago|reply
[+] [-] tbarbugli|12 years ago|reply
[+] [-] jwheeler79|12 years ago|reply
[+] [-] jokoon|12 years ago|reply
[+] [-] callesgg|12 years ago|reply