A non-OO interface system

I got a question recently from a person i used to mentor some years ago. He had trouble with a program he was developing, where he needed to have access to an generic “object” that he could pass around, but he needed this entitity to correpsond to different subtypes, with different implementation specifics, but this was to be unknown to the user of the entity.

He was basically asking for a pattern to create a plugin system, with a central process that will consume, load and call anonymous instances of “modules”. Now, this is an excellent example of programming to a contract, where sublclasses and/or interfaces would save the day.

Problem in this case: he was to use C. On an old compiler. So, question became, how to do “polymorphism in C”?

My answer to him was that yes, it can be done, sort of. Not in the parent-/child-type kind of way, perhaps, but in the interface way. There are some well used patterns existing for this. However, a method i have used exstensively myself is the one i will describe here. It is a method, whereby you hide the implementation of a function, and just use a pointer to it to call it, much like what Java or C++ will do behind the scenes. This pointer you make part of your “interface”, being a struct. Now this type becomes your contract, that you can use to pass multiple types of modules, but using them through the same interface. This also requires a “factory”-like construct, that can create custom types, that will be of the contract type (conforming to the iface).

Some noteable places where patterns like this ARE used are in the source code of Quake2 (renderer plugins) and in the source code of Nexus Filemanager (different tree-viewports loaded dynamically) as well as many early plugin-based software.

For an interesting comparison, i will also show a simplified example written in Go, for the same pattern. Go is also a non-OO language, but the difference ia that Go has many nice things that C does not, for instance it has a native notion of an “interface”, making the same pattern more readable. It also has a native garbage collection despite being a complied language, which helps a bit in larger implementations (as the C variant would need code to clean up and free the pointed to functions, if no type is left using it).

Our example today, will be simple. I will use the age old OO example of animals of different types, making sounds (common in every OO-langauge textbook known to man). We will however not have the classes Animal->Dog etc. The only entity the base system will know of is the general contract Animal. It will then call the makeSound() function on each animal, and through some fake polymorphism it will act different, despite the call being the same. Conclusion being that you do not need to make your animal-base aware of the existance of dogs, cows etc. by using specific types. Instead it is only aware of the base type Animal, the actual animal is built by the “factory”. The contract is thus the same, make_sound() is the only call the base needs to make, no matter what animal we have.

We have now, by doing this, created out of a struct, something that resembles a basic “object”. Meaning that due to the function pointer, it not only holds data, it holds “methods”. If you add in self-reference (send a pointer to the instance holding the function pointer in the call) you can even replicate the true OO paradigm of “data and methods to work on that data”.

So how do we do this in C?

First, let us review the concept of the “function pointer”. In a C program, a function is merely an entry-point in memory. Thus, this can be pointed to by a pointer, and passed around as such. This is what enables us to do things like we are about to do now. For instance you can pass a pointer to a function and use it to call said function from a different place in code (like a callback function).

It is written on the following form:

int (*func_ptr)(int,int);

meaning it is a pointer to a function returning an int, that takes two int parameters as input. The pointer is called func_ptr. To pint it to a function, any function fulfilling this pattern will do. So we can do this:

func_ptr = &some_function;

where some_function is the name of a function in your program.

Now, on to the actual code.

First we write the header file, to define our type:


//animal.h
 
//Sound "iface"
typedef void (*animal_sound)(void);


//A "polymorphic" Animal struct 
typedef struct {
	int type; 

	//Custom "method" for sound
	animal_sound make_sound;

} Animal;

//Factory to create an animal, based on input 
Animal* ConstructAnimal(int type);


//Different sound functions for animals, conforms to contract of FP 
void Bark(); 
void Moo(); 
void Meow();

Note the use of the factory to create “animals”. Also, we need to specify the functions that we will bind to the various types of animals. As opposed to OO, here we can not contain them in their object, we will declare them freely, in our interface code, and instead point to them.

On to the implementations:

#include "animal.h"
#include <stdio.h>

//Implementation of the animal factory 
Animal* ConstructAnimal(int type) {
	Animal* an = malloc(sizeof(Animal));
	switch (type) {
	case 1:
		//Dog
		an->type = 1; 
		
		//Hook up the pointer to the internal func to use 
		an->make_sound = Bark;

		break;

	case 2:
		//Cow
		an->type = 2;

		//Hook up the pointer to the internal func to use 
		an->make_sound = Moo;

		break; 

	case 3:
		//Cat
		an->type = 3;

		//Hook up the pointer to the internal func to use, pass self ref
		an->make_sound = Meow;

		break;

	default:

		//Dog
		an->type = 1;

		//Hook up the pointer to the internal func to use 
		an->make_sound = Bark;
	}
}


//Different sound functions for animals, caller does not need to know which is used, this is set up by the factory
void Bark() {
	printf("I am an animal of type Dog and i bark, bark bark!\n\n");
}
void Moo() {
	printf("I am an animal of type Cow and i moo, moo moo!\n\n");
}
void Meow() {
	printf("I am an animal of type Cat and i meow, meow meow!\n\n");
}

As you can see, the factory is responsible for creating an animal of the requested type. Now, this is a simple example. In real life you would probably have a lot of logic to determine which functions to point to (what type of animal, plugin, renderer etc.), and you would likely have self-reference in the functions pointed to, to access the base data of the struct.

Now for some testing:

#include <stdio.h>
#include "animal.h"

int main() {

	//Spawn an animal by the factory method, we could use more complex input here
	Animal* animal_one = ConstructAnimal(1);
	Animal* animal_two = ConstructAnimal(2);
	Animal* animal_three = ConstructAnimal(3);
	Animal* animal_four = ConstructAnimal(4);

	//Note that this code does not need to know anything about the target animal, only that there is a func for sound. This is a "polymorphic" tendency, albeit not fully 
	//We can now allow for modules to load in like plugins and such
	
	//Note the use of the same call, albeit these are different "types" of animals, returned by the factory 
	animal_one->make_sound();
	animal_two->make_sound();
	animal_three->make_sound();
	animal_four->make_sound();

	//Wait 
	getch();
	
	//Deallocate 
	free(animal_one);
	free(animal_two);
	free(animal_three);
	free(animal_four);

	return 0;
}

Note the use of the same contract make_sound()… despite different functions actually being called. We have now built a polymorphic animal-interface.

This idea can be expanded to a larger plugin structure, where you would have a factory responsible for determining if you have 3D sound or not in your machine, and returning a Sound-interface for instance, that would be tailored to call the right functions, but the caller would only need to know one function call, like in polymorphic OO.

An interesting new development in languages is Go. Go is a C-equivalent, in that it is non-OO and compiled, and it has a C-like syntax. However Go was designed to add some features to development in such a paradigm. It adds native thread support for instance, as well as support for inter-process-messaging, as part of standard syntax. It also has garbage collection of pointers (cleaning up for you). In light of our example above however, it is more interesting that it also supports the notion of an interface, much like Java or C#. This makes code like the above, much easier to grasp and read, as it actually defines a contract type as such.

For reference i implemented the above example in Go, to give you an idea of its structure.

So how to do it in Go, what is the difference?

First we have the Animal-package:

//Animal.go
package Animals

import "fmt"

//Animal iface, for polymorphic behaviour
type Animal interface {
	MakeSound()
}

//Types, these could be declared elsewhere, however these are now implicitly animals
type Dog struct {
	id int
}

type Cow struct {
	id int
}

type Cat struct {
	id int
}

//Spawning factory, can return pointer to local, will auto-move to heap
func CreateAnimal(animaltype string) (ani Animal) {
	switch animaltype {
	case "Dog":
		return &Dog{10}

	case "Cow":
		return &Cow{20}

	case "Cat":
		return &Cat{30}

	default:
		return &Dog{10}
	}
}

//Funcs

//This will implicitly implement the iface, because func exist, attach the func to "objects" of types
func (dog Dog) MakeSound() {
	fmt.Println("I am a dog, woof, woof")
}

func (cow Cow) MakeSound() {
	fmt.Println("I am a cow, moo, moo")

}

func (cat Cat) MakeSound() {
	fmt.Println("I am a cat, meow, meow")
}

The interesting thing here is that we have different ACTUAL animal types, but they are all of interface Animal. You see, in Go, you may tie a function to a specific type. Now as you can see at the end this allows for the functions to be tied implicitly to these types. However, Go specfies that as soon as a function is tied to a type with the name and signature of an interface type, it also IS such an interface contract. There is no implicit definition of this like in Java:

 
class SomeClass implements iface_x {...}

We can now therefore refer to our animals as Animal instead of the actual type:

//Base.go
package main

import "tests/goifaces/animals"

//Printer function, to demonstrate the use of generic iface Animal, note, this method works on the generic Animal iface
//so it does not need to know the type
func PrintAnimalSound(ani Animals.Animal) {
	ani.MakeSound()
}

func main() {
	//Main

	//Get a pointer to an animal, generic interface type
	var ani_one Animals.Animal
	var ani_two Animals.Animal
	var ani_three Animals.Animal

	ani_one = Animals.CreateAnimal("Dog")
	ani_two = Animals.CreateAnimal("Cow")
	ani_three = Animals.CreateAnimal("Cat")

	//Call Printer, note it does not need to know the type of the animal
	PrintAnimalSound(ani_one)
	PrintAnimalSound(ani_two)
	PrintAnimalSound(ani_three)

}

Note here that we declare variables of the type Animal. That way, when we call the print function, we can pass it as is, despite it actually being a dog, cow, cat etc. The caller does not need to know, as it will assume it is of the interface type Animal and thus has the MakeSound() function tied to itself.

Both of these cases can be expanded to fully featured plugin systems based on contracts.

This shows that partial OO-like constructs can and should be used in non-OO languages, when there is a need for it. You just have to work a bit harder to implement it. On the other hand, the Go example shows that Go is really well suited to this kind of development, despite being non-OO, due to some choices made in its design.

The idea of the hybrid cloud

I recently saw a note from Oracle Tech saying you should consolidate your cloud effort and tooling towards a single vendor, to allow for better support.

I would like to strongly refute this idea and instead i would defend the “hybrid cloud”. One of the reasons of doing cloud, for me, is breaking vendor lock-in and allowing for technology advances at a rapid rate. To me, consolidating your cloud effort to a single vendor is blocking this. You should instead be open to change and to applying different solutions depending on the nature of the current problem.

One of the selling points of cloud / off-site hosting and services, is in my view, the ability to mix and match them and use pay-as-you-go models to build less monolithic constructs. This has benefits in nearly all fields of computing, from analytics to integration. Therefore i say:

Opt-in to all the major cloud providers. Keep accounts with them. Utilize pay-as-you-go to scale up/down and do testing. Use what you need, when you need it.

Today, we are truly reaching the point where we can pick and choose everything from database to network infrastructure at a click, and pay only for what we use. We should use that oppurtunity.

However, this requires companies to hire good, forward thinking innovators, and have skilled engineers thinking up solutions, with an open mindset. This, as opposed to buying the all-in-one package from giant supplier X, will give you the truly advantageous solutions. The additional cost of adding this staffing, letting them use the environments freely, and also keep policies for several vendors WILL be justified by the results.

Monolithic monsters that you sign over your entire stack of apps to, is a thing of the past. Let’s build and innovate, with the toolboxes we can now access easily, and take control.

Therefore i say, go hybrid, build your solutions loosely coupled and as micro-services. As long as the endpoints is standardized, they will work together, regardless of the underlying service structure.

When will internet of things take off?

Lots of talk these days on the internet of things. Or for the less buzzword-centric, sensors connected to the internet. This talking has been going on for a while now, and there is a lot of hype surrounding iot. But still, it has failed to take off on a larger scale, meaning, average Joe adapting and finding needs for connected utilities.

Basically it seems to be a rather hard sell. Now why is that? Well, frankly, the products are not mature yet. For instance, these newfangled gadgets that let me dim a lightbulb with my cellphone is all fine, but on the other hand, why is that really useful enough to warrant the rather steep pricetag and inconvenience? And if i still opt for it, it will only work with that particular suppliers devices. Iot in the home lacks a killer app. Something that will make the idea of connected utilities in the household become a “must” rather than “overpriced gimmick”.

Now, there ARE possbilities for this. Imagine ways to track your kids whereabouts (wearable gps) for instance. That is a safety measure many parents would like to have, a lot more than the ability to open the garage door with the phone when at work.

Or imagine that you could use several interconnected devices, no matter the manufacturer, and program them independently to react to events. Now that is something tangible and useful for third party consultancy to work on.

Which brings me to another key point: Standardization.

For instance, there is a need for an open standard regarding events created by connected devices. A message format, on which to build intercommunication between your connected home devices.

My suggestion on it is to adapt a known container such as json and then create a standard for describing either a sensor reading or a notification.

So, why is that not happening? I really want to connect my car to my garage door in an open standard communication way, so i can make events from a trigger responses on b (like opening the door when i remote start the car).

Then we may start to see things happen in the field of iot for the home.

Prolog is still alive

Recently i have been dusting off my old Prolog skillset again, to try and find a modern use for it. In the past you saw Prolog in quite a few expert systems used by major companies. Is there still a use for Prolog’s rule based programming logic today?

As i started thinking about a good use for it in 2016, i identified some areas where the type of database integration and rule based development Prolog offers is still a good choice. One is in AI, where state is often based on a combination of compound rules. Another is in financial and business analysis where you can set up complex sets of facts and rules to then do data analysis.

There is also the fact that Prolog is an excellent introduction to logic student language, as evidenced by it still being referred to in the latest printing of Gersting’s seminal CS course-book “Mathematical structures for computer science”, as well as other works in the field of logic and analytics.

I would really like to try Prolog on students to see the reaction to the kind of programming it offers.

But my current project in the area was decided based on the insight about uses in the enterprise world. I have started building a Prolog framework to automatically answer questions on investments, given base data about the desired outcomes. The idea is to feed the rules engine with input data, then ask it questions to determine the best strategic descisions. So it is a data driven expert system.

To do this, i figured i had to consume raw data, to use as basis for the rules database. So i wrote a C routine to recieve events regarding financial data. These would be structured as [purchase|sale|transfer][item][buyer][seller][date][deliverydate]

I would use the C code to structure this into information for the rules database. I build it based on this input, so the rules database contains Prolog rules such as:

discount(X,Y) :-
seller(X),
commonbuyer(Y),
priorelation(X,Z)

 

and so on, meaning i can ask it questions such as:

? – discount(brake_pad,summer,purchaser1, X)
Response: Yes –
X = inhouse_supply_canada
X = external_supply_bromhouse

as in according to observed rules (based on past data), there is two valid matches for X, that satisfies X being a supplier that will give a discount for brake pads, in the summer period, if purchased by purchaser1.

An interesting small hobby project, but now i am more or less done. What it will become? I don’t know. Probably nothing but a small test.

I am however still interested in taking my concept and try to merge Prolog with business intelligence AI. If it’s doable? I don’t know. But i would like to attempt it, given time to do it.

The morale of this rant is that you should try Prolog, as it is still useful, if not only for academic reasons. And if you are a teacher in CS fields, maybe think about having an intro course on Prolog, as it is still a good way of getting hands on with practical logic and expert systems.

Material and links:

Learn Prolog

SWI