Introducing the "for" loop

Terry Reedy tjreedy at udel.edu
Sat Oct 7 12:58:03 EDT 2017


On 10/7/2017 5:09 AM, Steve D'Aprano wrote:
> On Fri, 6 Oct 2017 11:44 pm, ROGER GRAYDON CHRISTMAN wrote:
> 
>> Despite the documentation, I would still be tempted to say that range is a
>> function.
>> Taking duck-typing to the meta-level, every time I use range, I use its name
>> followed
>> by a pair of parentheses enclosing one to three parameters, and I get back
>> an
>> immutable sequence object.   It sure looks like a function to me.
> 
> I agree -- range() is a function in the (almost) mathematical sense, something
> which takes arguments and returns a value. It's also a type (class), in the
> OOP sense:
> 
> 
> py> type(range)
> <class 'type'>
> 
> 
> The term "function" is ambiguous but normally clear from context. Often, the
> differences make no difference, but when they are important, we can discuss
> them:
> 
> - range is a callable (a callable object);
> 
> - it is also a type/class, and calling it returns an instance;
> 
> - it looks like, and behaves like, a function;
> 
> - and is, conceptually, a function;
> 
> - but it is *not* an instance of FunctionType:
> 
> 
> py> from types import FunctionType
> py> def function():
> ...     pass
> ...
> py> isinstance(function, FunctionType)
> True
> py> isinstance(range, FunctionType)
> False

No built-in function is an instance of FunctionType
 >>> isinstance(compile, FunctionType)
False
 >>> isinstance(print, FunctionType)
False
 >>> type(compile)
<class 'builtin_function_or_method'>
 >>> type(int.bit_length)
<class 'method_descriptor'>


FunctionType == function defined by def statement or lambda expression.
These are a subset of functions defined by Python code.

> It is this last sense (an instance of FunctionType) which people are thinking
> of when they state that range is not a function.

Unless one means 'function defined by def or class', excluding all 
functions defined in the interpreter implementation language, which can 
change as modules are recoded one way or the other, and some functions 
defined in Python, FunctionType is too narrow.  The predecate would have 
to be at least

BuiltinFunction = type(compile)
MethonDescriptor = type(int.bit_length)
isinstance(x, (FunctionType, BuiltinFunction, MethodDescriptor))

but that still excludes bound methods and partial functions.

I have the impression that classes being functions is somewhat peculiar 
to Python but I have not been exposed to enough OOP languages to know.

The other sense in which 'range is not a function' makes some sense is 
when it means 'range is not *just* a function'.  This is akin to when 
'people are not animals' means 'people are not (or should not be) *just* 
animals'.  Do people speaking other than English say subcategory Y of 
category X is special by saying 'Ys are not Xs'?

-- 
Terry Jan Reedy




More information about the Python-list mailing list