All Articles

Fluid methods: a new approach to generic and oblique methods in OOP

Jekyll

I have a dream …

Imagine being able to define a generic method outside of a class

Imagine that the method can be called as a normal method

Imagine that the method is automatically available to all instantiated objects …

Imagine that the method is oblique and works over different data types

Sci-fi? Well, this is what I call a fluid method!

Where am I coming from?

I am currently working on the development of GrabQL, a SQL-like query language for Web-scraping. And I decided to base it on a core of a more generic language named K+ (key plus). Ambitious project, I admit!

K+ introduces the concept of fluid method, that is, a method that is defined outside of a class but that is applied right-side to a value/variable of different data types (obliquity), and that it’s responsible of validating the value/variable and decide which kind of result to produce.

Concept

The concept is simple:

  • I want to define it outside of a class (generic)
  • I want it to work as a normal method
  • I want it to work not only on the object, but also on the object properties themselves
  • I want it to work on data types (obliquely)
  • I want the business logic encapsulated in the fluid method itself

How should it work, therefore?

In practice …

In pseudo-code, imagine to define a simple class that stores the basic data of an employee:

define class Employee
    public name
    public surname
    public salary

    public constructor(name, surname, salary)
        this.name = name
        this.surname = surname
        this.salary = salary
    end

    public method fullname()
        return this.name + " " + this.surname
    end
end

and a class that defines the employer:

define class Employer
    public name
    public address

    public constructor(name, address)
        this.name = name
        this.address = address
    end

    public method fullname()
        return this.name + ", " + this.address
    end
end

The Employee and Employer classes are of a completely different data type, and the same occurs with their properties once instantiated with the following code.

var jim = new Employee("Jim", "Smith", 40000)
var agency = new Employer("Agency Ltd", {"number": "1", "street": "Waterloo Road", "city": "London"})

I want to be fluid

Now I want to create a generic fluid method named json, that I can apply to whatever object or object property (this is what I call being oblique) and that should return the JSON-encoded version of that object/property.

define fluid_method json(obj)
    if is_object(obj)
        return json.encode(obj.methods())
    else
        return json.encode(obj)
    end
end

And the following pseudo-code should work …

write jim.json()                    # ==> {"name": "Jim", "surname": "Smith", "salary": 40000}
write jim.name.json()               # ==> "Jim"
write jim.surname.json()            # ==> "Smith"
write jim.surname.salary.json()     # ==> 40000

write agency.json()                 # ==> {"name": "Agency Ltd", "address": {"number": "1", "street": "Waterloo Road", "city": "London"}}
write agency.name.json()            # ==> "Agency Ltd"
write agency.address.json()         # ==> {"number": "1", "street": "Waterloo Road", "city": "London"}

Being more fluid …

I should be able to define a new fluid method at run time, that is applied to objects already instantiated:

write jim.length()
# ==> this will trigger an error, because no fluid method length() is available

define fluid_method length(obj)
    if is_string(obj)
        return strlen(obj)
    elseif is_array(obj)
        return count(obj)
    elseif is_object(obj)
        return count(obj.methods())
    else
        return 0
    end
end

write jim.length()                  # ==> 3, the number of properties
write jim.name.length()             # ==> 3, the string length
write jim.address.length()          # ==> 3, the array length

Potentiality

Imagine the potential of a fluid method: a traversable method that is made available to all objects, that I can create at run time and that makes OOP development more fun!

Obviously, it’s not trivial to implement fluid methods in current programming languages. I have experimented how to do it in PHP, one of the languages I often use, and you can have a look to “Fluidity” library on GitHub that shows how the fluid method concept may work.