What is a Functor in Python?
Question:
I am new to Python. Can someone explain where the functor value is coming from. Functor = msg.functor, but there is no explanation for the word functor, I’ve tried googling it and came up with nothing. Also the .val keyword isn’t explained anywhere, I’m probably being dim but i cannot find any examples.
def process_action(self, msg, sender):
assert msg.get_type() == pedroclient.PObject.structtype
functor = msg.functor
assert functor.get_type() == pedroclient.PObject.atomtype
cmd_type = functor.val
cmd = msg.args[0]
if cmd_type == 'stop_':
assert cmd.get_type() == pedroclient.PObject.structtype
cmd_functor = cmd.functor.val
#if cmd_functor in ['pickup', 'putdown']:
self.stop_arm(cmd.args[0].val)
#else:
# self.stop_arm(cmd.args[0].val)
elif cmd_type in ['start_', 'mod_']:
self.start_animate()
assert cmd.get_type() == pedroclient.PObject.structtype
cmd_functor = cmd.functor.val
if cmd_functor == 'pickup':
self.pickup(cmd.args[0].val, cmd.args[1].val, sender)
elif cmd_functor == 'putdown':
if cmd.args[1].get_type() == pedroclient.PObject.inttype:
self.putdown_on_block(cmd.args[0].val, cmd.args[1].val,
sender)
else:
self.putdown_on_table(cmd.args[0].val, cmd.args[1].val,
sender)
elif cmd_functor == 'go_home':
self.go_home(cmd.args[0].val)
Edit: Sorry there is a lot more code, I have skimmed it as much as i could.
def process_msg(self, term):
msg = term.args[2]
sender_process = term.args[1].args[0].args[1].val
robotID = int(sender_process[-1])-1
#print msg
if str(msg) == "initialise_":
robotID = int(sender_process[-1])-1
def data_cb(self, event):
self.env.process_msg(event.notification)
The best I can understand it is that the functor is an attribute of msg, which in turn is the argument of system input, where system input is a event notification. Am i correct or completely going of in the wrong direction.
Answers:
functor
is an attribute of the msg
object; without seeing the definition of that object we can’t tell you anything more. Similarly, val
is in turn an attribute of msg
.
Searching via Google I have found documentation, which shall probably explain part of your :
The Pedro 1.6 Reference Manual
Regarding the functor
I did not find a not about that (but did not spend much time on it). It is likely, Pedro is used as messaging system for sending commands to some (real or virtual) robot. The robot is controlled by messages, which have some structure, including functor, being probably identification of what type of action shall be performed, and values, which are are defining parameters of that action.
Since Python allows passing functions as values a Functor is basically an object which is a function. Note that on the code that you post you are comparing many times which function is this.
On the line cmd_type = functor.val
you actually attributed to cmd_type the function itself and later on you compare it to know which function it is exactly.
if cmd_type == 'stop_':
is the function stop()?
elif cmd_type in ['start_', 'mod_']:
is one of these functions, start(), mod()?
And so on… Further reading here
Edit: I found this topic to be very related to understand the concept of functors, though it doesn’t quotes python but python has a lot of Functional programming features.
Basic stuff – msg & functor might be in these places:
- Defined in this file
- In a local module that is imported by the import statements at the top of this file, this would be a .py file in the directory structure of the app
- In an installed package from someone else
.val – this is most likely an attribute containing data. It is not a Python keyword of any kind that I can find. I’m sure you thought that it is probably short for “value”. It is either defined in the objects it is a part of (functor, cmd.args[]) or in some superior object that they import and thus inherit val from.
A functor (also known as a "function object"), is something other than a function which behaves like a function; a functor is like a function, but with more extra code added, which is a good thing sometimes.
Normally, we have classes like this:
class HoundDog:
"""
The `Dog` class is a dog-making machine.
It makes dogs.
Each dog has a name.
"""
def __init__(this_dog, name:str):
this_dog._name = str(name)
We have a problem: Dogs made from the class shown above does not like parentheses.
copper = HoundDog()
balto = HoundDog()
chief = HoundDog()
result = copper()
# error!,
# ERROR!!,
# ERROR!!!
# parentheses, such as `()`, are not allowed to the right of a dog, such as
# copper, balto, chief, or other good dogs from themovie "Fox and the Hound" (1981)
We have to define a method named __call__
in order to create a class object which behaves like a function.
class HoundDog:
"""
The `Dog` class is a dog-making machine.
It makes dogs.
Each dog has a name.
"""
def __init__(this_dog, name:str):
this_dog._name = str(name)
Below is another example of a functor (a function object):
# inky_the_inkrementor is a functor.
inky_the_inkrementor = Inkrementor(1)
# running total is 1
inky_the_inkrementor(10)
# running total is 11
inky_the_inkrementor(100)
# running total is 111
inky_the_inkrementor(1000)
# running total is 1111
inky_the_inkrementor(10000)
# running total is 11111
inky_the_inkrementor(100000)
# running total is 111111
inky_the_inkrementor(9)(1)(10)(100) #
# running total is 111111
inky_the_inkrementor(500000, 50000, 5000)
# the running total is
inky_the_inkrementor(9*10**9)(8*10**8, 7*10**7)
print(int(inky_the_inkrementor))
# prints 9871555111
In the mess of code below, is might be best to focus on the fact that there is a method named __call__
:
class Inkrementor:
# also known as...
# ... an "ACCUMULATOR"
# ... a running total
def __init__(this, *args):
this._num = 0
this(*args)
def __call__(this, *args):
# convert args[0] into a decimal number, such as 53.91982
dn = float(args[0])
# assign the decimal number to a variable named `left`
left = float(dn)
# add the left-overs altogether recursively
leftovers = this(*args[1:])
this._num += left
this._num += leftovers
this._num = sum(float(arg) for arg in args)
def __float__(this):
return this._num
What makes functors useful is that you can store so-called state variables inside of a function-like-thing which has inputs and outputs.
I am new to Python. Can someone explain where the functor value is coming from. Functor = msg.functor, but there is no explanation for the word functor, I’ve tried googling it and came up with nothing. Also the .val keyword isn’t explained anywhere, I’m probably being dim but i cannot find any examples.
def process_action(self, msg, sender):
assert msg.get_type() == pedroclient.PObject.structtype
functor = msg.functor
assert functor.get_type() == pedroclient.PObject.atomtype
cmd_type = functor.val
cmd = msg.args[0]
if cmd_type == 'stop_':
assert cmd.get_type() == pedroclient.PObject.structtype
cmd_functor = cmd.functor.val
#if cmd_functor in ['pickup', 'putdown']:
self.stop_arm(cmd.args[0].val)
#else:
# self.stop_arm(cmd.args[0].val)
elif cmd_type in ['start_', 'mod_']:
self.start_animate()
assert cmd.get_type() == pedroclient.PObject.structtype
cmd_functor = cmd.functor.val
if cmd_functor == 'pickup':
self.pickup(cmd.args[0].val, cmd.args[1].val, sender)
elif cmd_functor == 'putdown':
if cmd.args[1].get_type() == pedroclient.PObject.inttype:
self.putdown_on_block(cmd.args[0].val, cmd.args[1].val,
sender)
else:
self.putdown_on_table(cmd.args[0].val, cmd.args[1].val,
sender)
elif cmd_functor == 'go_home':
self.go_home(cmd.args[0].val)
Edit: Sorry there is a lot more code, I have skimmed it as much as i could.
def process_msg(self, term):
msg = term.args[2]
sender_process = term.args[1].args[0].args[1].val
robotID = int(sender_process[-1])-1
#print msg
if str(msg) == "initialise_":
robotID = int(sender_process[-1])-1
def data_cb(self, event):
self.env.process_msg(event.notification)
The best I can understand it is that the functor is an attribute of msg, which in turn is the argument of system input, where system input is a event notification. Am i correct or completely going of in the wrong direction.
functor
is an attribute of the msg
object; without seeing the definition of that object we can’t tell you anything more. Similarly, val
is in turn an attribute of msg
.
Searching via Google I have found documentation, which shall probably explain part of your :
The Pedro 1.6 Reference Manual
Regarding the functor
I did not find a not about that (but did not spend much time on it). It is likely, Pedro is used as messaging system for sending commands to some (real or virtual) robot. The robot is controlled by messages, which have some structure, including functor, being probably identification of what type of action shall be performed, and values, which are are defining parameters of that action.
Since Python allows passing functions as values a Functor is basically an object which is a function. Note that on the code that you post you are comparing many times which function is this.
On the line cmd_type = functor.val
you actually attributed to cmd_type the function itself and later on you compare it to know which function it is exactly.
if cmd_type == 'stop_':
is the function stop()?
elif cmd_type in ['start_', 'mod_']:
is one of these functions, start(), mod()?
And so on… Further reading here
Edit: I found this topic to be very related to understand the concept of functors, though it doesn’t quotes python but python has a lot of Functional programming features.
Basic stuff – msg & functor might be in these places:
- Defined in this file
- In a local module that is imported by the import statements at the top of this file, this would be a .py file in the directory structure of the app
- In an installed package from someone else
.val – this is most likely an attribute containing data. It is not a Python keyword of any kind that I can find. I’m sure you thought that it is probably short for “value”. It is either defined in the objects it is a part of (functor, cmd.args[]) or in some superior object that they import and thus inherit val from.
A functor (also known as a "function object"), is something other than a function which behaves like a function; a functor is like a function, but with more extra code added, which is a good thing sometimes.
Normally, we have classes like this:
class HoundDog:
"""
The `Dog` class is a dog-making machine.
It makes dogs.
Each dog has a name.
"""
def __init__(this_dog, name:str):
this_dog._name = str(name)
We have a problem: Dogs made from the class shown above does not like parentheses.
copper = HoundDog()
balto = HoundDog()
chief = HoundDog()
result = copper()
# error!,
# ERROR!!,
# ERROR!!!
# parentheses, such as `()`, are not allowed to the right of a dog, such as
# copper, balto, chief, or other good dogs from themovie "Fox and the Hound" (1981)
We have to define a method named __call__
in order to create a class object which behaves like a function.
class HoundDog:
"""
The `Dog` class is a dog-making machine.
It makes dogs.
Each dog has a name.
"""
def __init__(this_dog, name:str):
this_dog._name = str(name)
Below is another example of a functor (a function object):
# inky_the_inkrementor is a functor.
inky_the_inkrementor = Inkrementor(1)
# running total is 1
inky_the_inkrementor(10)
# running total is 11
inky_the_inkrementor(100)
# running total is 111
inky_the_inkrementor(1000)
# running total is 1111
inky_the_inkrementor(10000)
# running total is 11111
inky_the_inkrementor(100000)
# running total is 111111
inky_the_inkrementor(9)(1)(10)(100) #
# running total is 111111
inky_the_inkrementor(500000, 50000, 5000)
# the running total is
inky_the_inkrementor(9*10**9)(8*10**8, 7*10**7)
print(int(inky_the_inkrementor))
# prints 9871555111
In the mess of code below, is might be best to focus on the fact that there is a method named __call__
:
class Inkrementor:
# also known as...
# ... an "ACCUMULATOR"
# ... a running total
def __init__(this, *args):
this._num = 0
this(*args)
def __call__(this, *args):
# convert args[0] into a decimal number, such as 53.91982
dn = float(args[0])
# assign the decimal number to a variable named `left`
left = float(dn)
# add the left-overs altogether recursively
leftovers = this(*args[1:])
this._num += left
this._num += leftovers
this._num = sum(float(arg) for arg in args)
def __float__(this):
return this._num
What makes functors useful is that you can store so-called state variables inside of a function-like-thing which has inputs and outputs.