Posts filed under ‘oop’
Here’s what I realized: it seems that every language under the sun is being evangelized as an excellent functional programming language simply because it supports a few paradigms from FP.
Or, restated: Anonymous functions do not a functional language make.
The most egregious example of a pundit claiming a language is functional when it’s clearly not is Eric Kidd’s well-known Why Ruby is an acceptable Lisp. Kidd tells us explicitly that Ruby is a denser functional language than Lisp – and I’ll be the first one to admit that if I were to debate the “denser” part of that sentence, I wouldn’t know what I was talking about.
But Ruby is not functional – Wikipedia calls it a reflective, object-oriented programming language, and I agree with them. Yes, you can have block arguments to methods, continuations, generators, reflection, and metaprogramming – but it isn’t functional, for two reasons.
1. It’s hard to carry around functions as objects.
I really don’t know why Ruby hates parentheses so much – it’s probably part of its Perl heritage. In Ruby, you can call methods without sticking superfluous parentheses in there – take a look at this Python code:
" I'll write about Cocoa soon; disaster struck the app I was writing ".strip().lower().split()
Now take a look at the equivalent Ruby code:
" Apple's releasing a tool
with XCode 3
which completely supersedes my Cocoa app - so I'm very depressed right now ".strip.downcase.split
Though you could put parentheses in front of
split, Ruby will work just fine without them. Now, this feature makes for far fewer parentheses, thereby making code significantly more readable. But what if I want a previously-declared function as an argument? If I type in the name, Ruby will just evaluate the function. Sure, I could use the kludge that is Symbol.to_proc, but that’s ugly – and it wraps the function inside a Proc object, which has to be called with the
call(*args) method. And that’s just ugly. In Python, all you need to do is type the function’s name to use it as an object, and append a pair of parentheses if you need to call it.
2. Variables are.
A purely functional language only has immutable variables. Ruby doesn’t. (Yes, I know LISP isn’t purely functional. But it adheres to so many other FP paradigms that we can overlook that.)
But I’m getting distracted, so I’ll cut the above point short.
Anyway, what I wanted to say was this – just because your pet language has support for anonymous functions/closures doesn’t make it a functional language. Sure, Python has
In conclusion, don’t say your language is a functional one just because you borrowed a few ideas from Lisp. If you want a real functional language, try OCaml, Haskell, ML, or Scheme. Calling imperative/OOP languages functional just makes the term meaningless.
(Update: as usual, Scott Stevenson totally kicked my ass:
+ (EPFoobarMO *)foobarWithDefaultContext
return [NSEntityDescription insertNewObjectForEntityForName:@"Foobar" inManagedObjectContext: [[NSApp delegate] managedObjectContext];
I often forget that I’m a cretin preaching to a crowd of really smart people.)
I kid you not: NSManagedObject and Core Data are becoming some of my favorite coding structures/paradigms ever. (I suppose I have Wolf Rentzsch to thank; by the way, mogenerator v1.1 is out. Check it out.) It’s just so awesome – so nice not to have to futz around with NSUndoManager, NSCoding, and all the other minutiae that some brave souls worked with in years past.
I got rejected – not just deferred, rejected – from the University of Chicago. :( As such, I don’t really have time to write a very lengthy entry; therefore, I’ll just leave you with this little question/guide.
The official way of instantiating an instance/subclass of NSManagedObject is (I think) to use the NSManagedObject class method
initWithEntity:insertIntoManagedObjectContext:, like so: (we are assuming that there’s an NSManagedObjectModel and NSManagedObjectContext named
NSEntityDescription *e = [[model entitiesByName] objectForKey: @"Foobar"];
EPFoobarMO *foo = [[EPFoobarMO alloc] initWithEntity: e insertIntoManagedObjectContext: context];
Since they’re nice people, Apple gave us a convenience method:
EPFoobarMO *foo = [NSEntityDescription insertNewObjectForEntityForName: @"Foobar" inManagedObjectContext: context];
But if we’re sticking to the MVC paradigm (which we are, aren’t we?), one wants to put the initialization code for the EPFoobarMO object inside the EPFoobarMO .m/.h file.
+ (EPFoobarMO *)foobarWithContext:(NSManagedObjectContext *)context
// According to the docs the object returned is autoreleased
return [NSEntityDescription insertNewObjectForEntityForName:@"Foobar"
But it’s ugly to have to pass the NSManagedObjectContext to the initializer every time. We could stick it inside the app’s controller:
- (EPFoobarMO *) foobar
But that’s a flagrant violation of the MVC rules. (Of course, if you’re ignoring them, then this is an ideal solution. But down that way lies Nyarlathotep.)
Or we could resort to the insanity that is the C preprocessor. (I would give a code sample, but I don’t want to hate myself.)
Anyway, what do you think? Leave comments with your opinions or to alert me of any blatant inaccuracies.
Python has undergone a fair share of criticism for its lack of support for information hiding. Despite its being a solidly object-oriented language, Python has historically refused to support this facet of object-orientation. Other programming languages have implemented encapsulation in a variety of ways:
- All variables in Smalltalk, the canonical OO language, are private; in order to access them, the programmer must write explicit accessor and mutator methods for each variable.
- C++, Java, and C# rely on the
protectedkeywords in order to implement variable scoping and encapsulation.
- Cocoa’s Objective-C code strongly encourages the programmer to use key-value coding for encapsulatory purposes.
- Ruby does ultra-sexy encapsulation through the
However, Pythonistas like myself often assert that “we’re all consenting adults here.” While this attitude is refreshing in this day of slavish devotion to OOP principles, the Python community has realized that in order to avoid alienating newcomers, Python should perform some sort of encapsulatory behavior. This article intends to show the various ways in which Python supports encapsulation and/or information hiding.