OOP Untangled Part 3: Other Languages Worth Mentioning
Image source: https://www.flickr.com/photos/toomore/23066277453
In the previous articles, we used some well-known languages that were known for the OOP to achieve object orientation according to Alan Kay’s definition. In fact, there are other few some of them are not known for OOP, but we can still achieve object orientation with, which is what we’re discovering in this article.
This is the 3rd part of a series of articles, to check the other parts:
OOP Untanged Part 1: Object-Orientation and Dynamic Languages
OOP Untangled Part 2: Object-Orientation and Statically Typed Languages
The First Language
There’s a couple of statically typed languages that has interesting features that might ease the OOP. Take a look at this code:
class Record
def save
puts "saved!"
end
end
class XeroIntegration
def save_record(r)
r.save
end
end
class QuickbooksIntegration
def save_record(r)
r.save
end
end
def somehow_get_integration_by_id(integration_id)
case integration_id
when "xero"
XeroIntegration.new
when "quickbooks"
QuickbooksIntegration.new
else
raise "Unknown Integration" # To avoid nil
end
end
r = Record.new
integration = somehow_get_integration_by_id("xero")
integration.save_record(r)
What do you think? What language is this? Well, if you say, Ruby, you’re very close, it’s actually a valid Ruby code. But this is Crystal language. It’s heavily inspired by Ruby (that’s why I like it) with static typing that can be inferred. Also, you can do duck typing!
The Second Language
Another interesting type system you can find in Go language—even though it’s not known for being a “full” object-oriented language. One of my favorite features in Go is that the interfaces are implicitly implemented if the struct has that method. Not clean what it means right? Let’s see some code!
type Record struct{}
func (self *Record) Save() {
println("saved!")
}
type XeroIntegration struct{
name string
}
func (self *XeroIntegration) SaveRecord(record interface{ Save() }) error {
// Some logic here
record.Save()
return nil
}
type QuickbooksIntegration struct{
name string
}
func (self *QuickbooksIntegration) SaveRecord(record interface{ Save() }) error {
// Some logic here
record.Save()
return nil
}
// Another file
type Integration interface {
SaveRecord(record interface{ Save() }) error
}
func SomehowGetIntegrationById(id string) (error, Integration) {
switch id {
case "xero":
return nil, &XeroIntegration{}
case "quickbooks":
return nil, &QuickbooksIntegration{}
default:
return errors.New("Unknown Integration"), nil
}
}
// Where it actually get used
func main() {
// Returns something that support SaveRecord message
err, integration := SomehowGetIntegrationById("xero")
if err == nil {
r := &Record{}
integration.SaveRecord(r)
}
}
Let’s ignore the part where it needs & and *. The implicit interface is a nice feature, as long as it supports those specific messages, it is accepted. No need to wrap the external integration or the one written by a teammate. Also, no need to extract the interface into its own package.
There’s one thing I didn’t like, the interfaces only work with method—which makes perfect sense. However, in contrast to Crystal (or Ruby) structs in Go exposes some fields—like the name above—that are not “methods”. To work around this, you might need to write a reader method for each field you have and keep the field private (starts with lowercase). Like the example below:
func (self *XeroIntegration) Name() string {
return self.name
}
func (self *Quickbooks) Name() string {
return self.name
}
Keep in mind, there might be other statically typed languages that I don’t know about their existence, that support features that are even more suited for OOP. I only mentioned the ones I follow and am aware of.
Conclusion
In this article, we discovered a different yet interesting set of languages that you can still achieve Alan Kay’s object orientation with, if I found more, I will surely add them, one I am thinking of is Clojure, but I don’t know the language yet, but I would love to implement OOP with it.
Hope you enjoyed the reading, see you in future articles!