Let's revisit the basics. Is it possible to take Clean Code too far?

246 views
Skip to first unread message

Terence McGhee

unread,
Dec 19, 2013, 2:02:37 PM12/19/13
to clean-code...@googlegroups.com
Intro

For I'll explain what I perceive as the problem. Then I'll explain what I did to address the problem. Then I'd like you all to let me know if you think I took things too far.


The Problem

I'm well on my way to building my first iPhone application. All is going well, but I really don't like the syntax of Objective-C.

I think the syntax of the language is inherently not clean. One of the many things that bother me is that, they continually violate the concept of monads, dyads, and triads. For Example, it's very common to see code like the following:

UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil message:nil delegate:self cancelButtonTitle:nil otherButtonTitles: nil]


Not only is this method call (rather sending of a message... to use proper nomenclature) a very common message that you will send often on the platform, but it takes 5 parameters. Admittedly, after the first parameter, all of the rest of them are labeled (which helps) but it's still a monster line of code. 

To make matters worse (in my opinion), the first message being sent in that line of code is to the UIAlertView class itself asking to to initialize an instance of the class [UIAlertView alloc]. Then that instance is asked to initialize itself with the arguments provided.

This is an awful lot of work for a single line of code, but I digress.

The Solution

So the main goal that I'm trying to achieve is readability. I realize that, if a coder understands the language of Objective-C, s/he'll be able to read that just fine. But it doesn't read like well written prose. This is what I'm after, well written prose.

Since I'm really a C programmer down in my soul and Objective-C is a superset of C, I decided to take advantage of one of my favorite C constructs... the preprocessor.

I created a header file called prose.h. And within it, created a few #defines. Using these macros allowed me to use a more fluent-like calling syntax and turn the previous line of code into these two:

UIAlertView *alert = new(UIAlertView);

alert = tell(alert)__to(initWithTitle:nil)_with(message:nil)_with(delegate:self)_with(cancelButtonTitle:nil)_andWith(otherButtonTitles: nil);


In my opinion, my updated version reads more like well written prose. But before I get too attached to this idea, I'm curious if I've taken things too far. In effect, I've used the preprocessor to avoid the syntax of the language. This might be a bad idea.

Also, I should point out that I'm working alone on this so there aren't any other team members to consider.

Thoughts?

Caio Fernando Bertoldi Paes de Andrade

unread,
Dec 19, 2013, 2:44:19 PM12/19/13
to clean-code...@googlegroups.com
Terence,

I ran into the same problem when I wrote my first iPhone app, and I have to agree with you: Objective-C’s syntax is horrible.

Although there are things you can do to make your code more readable, I think that creating a pre-processor is too far indeed. Besides, you didn’t make that code cleaner, did you? It still takes 5 arguments, and the names are pretty much the same. An experienced Objective-C program wouldn’t benefit much from that.

Notice that those calls bloated with arguments are made to iOS’s frameworks. Protect yourself by isolating the iOS part of your application the same way you isolate the Web, it’s just a delivery mechanism. Make the objects that call those monster methods very very humble. ;)

Hope this helps,
Caio

--
The only way to go fast is to go well.
---
You received this message because you are subscribed to the Google Groups "Clean Code Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to clean-code-discu...@googlegroups.com.
To post to this group, send email to clean-code...@googlegroups.com.
Visit this group at http://groups.google.com/group/clean-code-discussion.

Terence McGhee

unread,
Dec 19, 2013, 10:28:43 PM12/19/13
to clean-code...@googlegroups.com
@Caio that's a pretty good idea to isolate the monolithic parts of the framework away from "my" code. I like that. I like that a lot. I'm actually going to begin working on a system for that tonight!! 

But as far as readability goes, yes I do think the preprocessor macros make the code easier to read. I'm not sure I would call it cleaner, but I would definitely say that

ask(self)_for(addressBook) ;

is just easier for me to read than 

[self addressBook];

The intent is clearer (in my opinion). But I don't know if the improvement is worth the price I have to pay for it. Well, rather, I'm not sure if the idea of writing code in Objective-C that looks nothing like Objective-C is really the way to go here (or ever).

I do appreciate your input and you have definitely help me solve one part of the overall un-cleanliness of Objective-C.

Bennie Copeland

unread,
Dec 20, 2013, 6:14:50 AM12/20/13
to clean-code...@googlegroups.com
In my opinion, my updated version reads more like well written prose. But before I get too attached to this idea, I'm curious if I've taken things too far. In effect, I've used the preprocessor to avoid the syntax of the language. This might be a bad idea.
 
It reads like well written prose to you. Which if you are the only developer, it might make it worth it. However, if you run into some issue where you need to reach out for help, you'll have to de-define all your code before you can provide snippits. You're avoiding the language itself and trying to turn it into something different. Its like writing C# with macros to make it read more like visual basic instead of embracing the syntax of the language. Coming from a primarly C/C++/C# language background, I found the Obj-C syntax difficult at first. But then I found that while the syntax is verbose, it is also informative; the method name describes the parameters. I don't have to go looking in headers to see what parameters I need to provide, there is no function overloading to think about. And, I don't know how well Xcode does with auto completion for defines, but this could reduce productivity. Having Xcode auto complete the method name and allowing me to tab between the parameters beats having to type out each character and possibly making a typo. Another option is to do this:
UIAlertView *alert = [UIAlertView new];
[alert setTitle: @"My Title"];
[alert setMessage: @"My message"];
 
Or you could wrap the call up in a facade to reduce the number of parameters needed.
 

Rusi Filipov

unread,
Dec 22, 2013, 12:31:33 PM12/22/13
to clean-code...@googlegroups.com
My first touch to Objective-C also made me feel dizy due to the strange syntax, which is influenced by Smalltalk. But besides its weird syntax, Objective-C has good language concepts integrated - blocks, protocols, dynamic polymorphism. This is actually quite good for such an old language.

Now even that the syntax is not the best, I would discourage inventing custom language constructs and idioms. This might seem nice at first, but it will not conform to the principle of least surprise, and will likely confuse experienced Objective-C programmers. 

Instead, it might be better to stick with the language as it is and use it in its native idiomatic way. Btw, it might help if you combine XCode with AppCode from JetBrains, which makes working with the language a little less painful. 

Terence McGhee

unread,
Dec 24, 2013, 6:23:17 AM12/24/13
to clean-code...@googlegroups.com
I agree that as a language, Objective-C has some very sexy features, but it inherently makes the readability principles of clean code kinda difficult. And for me, readability is vital, especially when you're first immersed in a language and learning it.

However, Objective-C is fairly robust when it comes to adhering to SOLID principles though. There's no doubt about that. And working with AppCode is wonderful! Definitely a great investment.

However, I didn't really intend for this topic to become a mini language-war and that feels like what it's turning into. I've decided that the macros are taking things a bit too far. The idea of using features of the language to alter the language's syntax to avoid the language's syntax is a bit too much. 

But I might change my mind back again later. Hehe.

Terence McGhee

unread,
Dec 24, 2013, 6:34:07 AM12/24/13
to clean-code...@googlegroups.com
Thanks for that tip! I did not know that you could bypass the more verbose messages and set the values individually. That has been extremely helpful to me. Thank you so much!


--
The only way to go fast is to go well.
---
You received this message because you are subscribed to a topic in the Google Groups "Clean Code Discussion" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/clean-code-discussion/d96RXE-QYTs/unsubscribe.
To unsubscribe from this group and all its topics, send an email to clean-code-discu...@googlegroups.com.

To post to this group, send email to clean-code...@googlegroups.com.
Visit this group at http://groups.google.com/group/clean-code-discussion.



--
Terence

Paul Stringer

unread,
Dec 24, 2013, 7:13:57 AM12/24/13
to clean-code...@googlegroups.com
Cocoa's (and we need a point of order here because it's not Objective-C that we're really discussing it's Cocoa Framework APIs) style is more verbose by design because of it's named parameter syntax (as mentioned inspired by SmallTalk). I don't believe in general you'll find so many usages of methods taking this many arguments  (in UIAlertViews defence it's a view object that you present and forget about, and it really does require every single one of those parameters in general usage). In fact this style it can be argued is a very good example of good practices for writing your own clean code - every method reads like a sentence and every parameter is named. Also the intent is extremely clear, put that in front of anyone without prior knowledge and they've probably got a reasonable idea about what that is going to do, especially followed by an [alertView present] call.

Go with Cocoa and over time even though it looks wordy you begin to appreciate it's self documenting nature. Long and short following the conventions/style of Cocoa's will be a better long term course than trying to shoehorn it to something else. It's also definitely worth a reading of some of the documentation regarding the idioms of Cocoa.  https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/CodingGuidelines/CodingGuidelines.html

For fun here's one of the more famous longest method names with 11 arguments http://oleb.net/blog/2010/12/method-names-in-objective-c/

Uncle Bob

unread,
Dec 29, 2013, 11:45:39 AM12/29/13
to clean-code...@googlegroups.com
Using the preprocessor is always a last resort, and something to be undertaken with an extreme amount of caution.  It is remarkably difficult to write good preprocessor macros that work like elements of language syntax.  They can be a source of bugs that are very difficult to diagnose.

I much prefer the ideas that others have suggested of isolating the framework behind a more friendly API, and using setters as opposed to constructors with lots of arguments.

In my book, I advise against functions that take more than three arguments.  However, in languages like ObjC, that have keyword arguments, I relax that rule a bit.  In such languages is much harder to get confused with the order of arguments.
Reply all
Reply to author
Forward
0 new messages