Function Zoo

Function Zoo: Part 2 — Function as a sent message

Dmitry Yakimov
BeadList
Published in
5 min readOct 25, 2018

--

Part 1 — Part 2 — Part 3

Today we are going to look at functions as a way of sending messages from one object to another. And in this article we are going to focus more on the expected outcomes of the function execution.

You can look at functions from the perspective of sending messages between the objects. It’s very similar to messages exchange via email, or messenger apps. Basically you have an address of a recipient, and you have some text you are sending. In case of function your object and its method name would be the recipient address, and its arguments would be the message text.

Then with this in mind, we can have 3 types of messages we can send to objects:

  1. Messages without answer expected;
  2. Messages with immediate answer;
  3. Messages with delayed answer.

And based of these types of messages we can have according function types. On that we’ll continue our exploration of the function zoo. The numeration follows the previous article

4. Procedure

”Fish,” said the frog, “could you make a cup of fine tea please?”
“On my way,” answered the fish.

Procedure is a function which does not return a value. It’s called in order to execute something. It’s not a pure function, it is there to get useful side-effects: print a document, notify with a message, give an order to you robot, make a screenshot. In terms of messages it is the message without answer.

How useful the procedures are? Well they can be very useful indeed. Let’s say you have a smart home, then you can tell it to turn off the light. And normally you don’t want any answers from it, you would just want it to do it. And it might have some API going on, and then you could call it via JS like this: SmartHome.turnOffTheLight() .

That’s pretty good. But actually you can write the whole application using just procedures. If they just know where to send answers they can function like a fully functional functions(pun intended). The code would not be nice then, but it would work. Let’s see in example.

const Zoo = {
// Procedure definition
getAnimal(type, color, destination) {
const animals = {
Frog: {
'Infra Red': 'ir_frog.jpg',
'Caribbean Green': 'cr_frog.jpg',
},
Fish: {
'Infra Red': 'ir_fish.jpg',
'Caribbean Green': 'cr_fish.jpg',
},
};
destination.receiveAnimal(animals[type][color]);
},
};
const Receiver = {
animals: [],
execute() {
// Procedure execution
Zoo.getAnimal('Frog', 'Caribbean Green', this);
Zoo.getAnimal('Fish', 'Infra Red', this);
},
receiveAnimal(animal) {
this.animals.push(animal);
},
};
Receiver.execute();
console.log(Receiver.animals);
// => [ 'cr_frog.jpg', 'ir_fish.jpg' ]

As you can see, you can still do pretty powerful things with procedures. Actually this code reminds Visitor Pattern a lot. Also in this code, you could be calling destination.receiveAnimal several times. These way it is very similar to real messengers conversation. And from this example you can have a feel of seeing functions as messages between the objects.

Basic function

”Fish,” said the frog, “what is your favorite painting?”
“Composition VIII, by Kandinsky,” answered the fish.

Here we come back to the basic function. Since it was already discussed in a previous article let’s say where it stands in terms of return value.

function getAnimal(type, color) {
const animals = {
Frog: {
'Infra Red': 'ir_frog.jpg',
'Caribbean Green': 'cr_frog.jpg',
},
Fish: {
'Infra Red': 'ir_fish.jpg',
'Caribbean Green': 'cr_fish.jpg',
},
};
return animals[type][color];
}
console.log(getAnimal('Frog', 'Caribbean Green'));
// => 'cr_frog.jpg'

As you can see it could be a message with immediate answer, since it returns the value immediately. They are very handy and good for any fast computations.

5. Async function

”Fish,” said the frog, “what is your favorite composer?”
“My favorite composer is Ludovico Einaudi,” said the fish, after a few minutes of thought.

As you’ve already guessed async function is the next in our list. It is the message with delayed answer. Once asked, you don’t wait for an answer. And an answer can come back any time. It’s like sending an email. May be the answer won’t even come. Although that is not really expected in the code.

function later(value) {
return new Promise((resolve, reject) =>
setTimeout(() => resolve(value), 1000),
);
}
async function getAnimal(type, color) {
const animals = {
Frog: {
'Infra Red': 'ir_frog.jpg',
'Caribbean Green': 'cr_frog.jpg',
},
Fish: {
'Infra Red': 'ir_fish.jpg',
'Caribbean Green': 'cr_fish.jpg',
},
};
return await later(animals[type][color]);
}
async function receiveAnimal() {
console.log(await getAnimal('Frog', 'Caribbean Green'));
// => 'cr_frog.jpg' (after 1s)
console.log(await getAnimal('Fish', 'Infra Red'));
// => 'ir_fish.jpg' (after 1s)
}
receiveAnimal();

The interesting thing about async/await is that — no matter how it is called the return value always come back to the same place in the code. It’s like sending a mail with a correct return address, from the place where it was actually sent.

Although this property is limiting, it’s also very comfortable and leads to cleaner nicer looking code.

6. Function with callback

”Fish,” said the frog, “what is your favorite film?”
“Oldboy.” said the fish, “No wait! It’s a Revolver. It’s definitely Revolver,” repeated the fish.

So where the function with callback stands in our list. Well interestingly it’s a special beast. It is normally expected to return a value in a delayed manner, but also it can return a value immediately.

And compared to async function it doesn’t have to return a value back to the code where it was called it can send it to a totally new place, as long as it has an address for it. It’s like a mail sent with a different return address or an email which faked the sender.

Just have a look at this example to proof these two points:

import { otherReceiver } from './otherZoo';function later(value, cb) {
setTimeout(() => cb(value), 1000);
}
function getAnimal(type, color, cb) {
const animals = {
Frog: {
'Infra Red': 'ir_frog.jpg',
'Caribbean Green': 'cr_frog.jpg',
},
Fish: {
'Infra Red': 'ir_fish.jpg',
'Caribbean Green': 'cr_fish.jpg',
},
};
later(animals[type][color], cb);
return 'immediate return value';
}
// Use return value in the same place
console.log(
getAnimal(
'Frog',
'Caribbean Green',
value => console.log(value)
)
);
// => 'immediate return value'
// => 'cr_frog.jpg' (after 1s)
// send return value to another place
getAnimal('Frog', 'Caribbean Green', otherReceiver);

Also functions with callbacks can call them several times, which can be useful in some cases. And it can bizarre in others.

As you can see functions with callbacks are very powerful indeed. But it’s also easy to get them wrong. That’s why it’s recommended to use them less often.

Here you go. Now we have discussed more function types over here. I hope you could see functions from a new angle. And I hope that it helped you to understand functions more deeply.

I wish you some beautiful coding sessions! █

--

--

Dmitry Yakimov
BeadList

Web-consultant, Tech-enthusiast. Working on BeadList App: beadlist.com