-1

I was reading abount type hinting and function annotations on this link: https://peps.python.org/pep-3107/#return-values

I don't understand the difference between both of them, but other than that I don't understand this grammar for function definition. Can someone explain this to me?

Here is the grammar from PEP 3107:

decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE 
decorators: decorator+
funcdef: [decorators] 'def' NAME parameters ['->' test] ':' suite
parameters: '(' [typedargslist] ')'
typedargslist: ((tfpdef ['=' test] ',')*
            ('*' [tname] (',' tname ['=' test])* [',' '**' tname]
             | '**' tname)
            | tfpdef ['=' test] (',' tfpdef ['=' test])* [','])
tname: NAME [':' test]
tfpdef: tname | '(' tfplist ')'
tfplist: tfpdef (',' tfpdef)* [',']
Donald Duck
  • 8,409
  • 22
  • 75
  • 99
Ryu10
  • 21
  • 3
  • 3
    Don't just look at grammar, especially not without specific examples. Almost nobody learns any language based on the grammar. – luk2302 Jan 04 '23 at 22:15
  • 2
    could you be more specific about which part you don't understand? – Barmar Jan 04 '23 at 22:16
  • i'm not looking only at the grammar to learn the language, i just want to understand what i am reading. i'm learning the language by books and practice – Ryu10 Jan 04 '23 at 22:17
  • 1
    "i don't understand the difference between both of them" both of what? type hinting vs function annotations? – Alex Hall Jan 04 '23 at 22:17
  • 1
    Formal grammars are useful when designing the language, writing implementations and answering language-lawyer questions. Few working programmers ever look at them, that's not how we learn languages. You nearn from descriptions and examples in textbooks and tutorials. – Barmar Jan 04 '23 at 22:21

3 Answers3

1

Ok, so the central part is the funcdef line:

funcdef: [decorators] 'def' NAME parameters ['->' test] ':' suite

This is saying, "look for an instance of 'def', followed by a NAME, followed by some parameters, an optional '->' test marker (to express the expected return datatype most likely - see here), a literal : and something called suite.

The grammatical definition of NAME is not included in the section you've copied - but it would be some legal string, perhaps not starting with an integer and not overlapping with some additional collection of reserved keywords. I'll leave you to look into that one.

parameters is defined here, as being some repeating collection of typedargslist's, surrounded by literal brackets to the left and right.

There's some variation here on how parameters are expressed that seems to include * and ** forms of parameter unpacking - that's an interesting aspect of python you can read about here:

The rest is fairly straightforward, but these components described are a minimal definition for how to constitute a function header.

I'd imagine suite is either a collection of statements that make up a function, or some optional function-header extra that I'm not aware of. You'd have to investigate that. It may be the case that there's some definition function that's made up of a funcdef header, followed by some collection of statements with an optional return element, terminated by some kind of out-dent.

It's difficult to parse only a section of a grammar, so this is the best I can do with what you've provided.

From what I know about how decorators are applied, it looks like out-denting is already catered for here - so my guess is that suite in this context describes the function contents as some collection of valid statement phrases.

A comprehensive document that contains hotlinks for each grammar component can be found here which should be able to fill in some of the gaps.

To answer your point about type hinting and return values. Type hinting tells you what you expect your function to return at run-time. If you want to, you can use this information to run compile-time tests and debugging scripts that will identify if/when you're using a function in some unintended way - to be honest, you're unlikely to come across a serious use except in some commercial dev-houses, and they'll have their preferred house-style to inform you how they expect you to use this feature.

Python does not enforce type-hinting at runtime, so the actual return data types for a given function are entirely independent. Type hinting is a late addition to python and to not break anything, was intended to be little more than a useful piece of documentation. Good coding practice would be to use it, but it's little more than a documentary convention.

Thomas Kimber
  • 10,601
  • 3
  • 25
  • 42
  • thank you for the reply. how can i write some compile-time tests and debugging scripts to use it? just as reference, i want to understand better – Ryu10 Jan 04 '23 at 23:58
  • Here's a guide on the subject: https://realpython.com/python-type-checking/ I've not followed it specifically, but it makes reference to PyCharm (a python IDE) and something called MyPy - both of which make use of this kind of type setting syntax. I'm sure other options are available. – Thomas Kimber Jan 05 '23 at 00:13
1

TLDR

Annotations are expressions that can be made to parameters and the return type of functions. Type hints give semantics to annotations. A type hint is an annotation (expression) that evaluates to a type. Which the annotated parameter is expected to have.

Explanation

The PEP you refer is from 2006. So not all the things are still the same as of now in Python 2.11. When looking to the current version of the grammar, things might become more clear.

Here the definition of a function is (I omit all of the framing definitions)

function_def_raw:
    | 'def' NAME '(' [params] ')' ['->' expression ] ':' [func_type_comment] block

Or more practically spoken, the return annptation of the function which folows the -> is an expression.

And for parameters:

param: NAME annotation? 
...
annotation: ':' expression

Also here, an annotation is just a usual expression.

So from point of view of language definition the annotations are just expressions. This means it is something the python interpreter can interprete anyhow. E.g., it can be some string value or int value or 42+36 or a function call. But it has no direct meaning and is not executed.

In PEP 484, the python team decided to give some meaning to the annotations by interpreting them as type hints (without restrictions to other usages - as explicitly stated in the PEP). So this means that, when the expression is just a type, the type is considered as the type of the param or the returned value. And can be used by checking tools to verify your implementation or documentation tools, etc..

A more general usage could be that the type is calculated from the given expression, but that would lead to some other (more theoretic) problems.

sim
  • 1,148
  • 2
  • 9
  • 18
  • thank you for the patience. what is a framing definitions? i read the pep 484 but i don't understand most of it, neither i do understand the difference between annotations and type hints – Ryu10 Jan 04 '23 at 23:45
  • 1
    @Ryu10 Maybe it is more clear for you know. – sim Jan 05 '23 at 10:31
0

Function annotations were added to the language in Python 3.0. They come in two varieties:

  1. Expression preceding the : in the def statement, following a ->
  2. Expressions separated from a parameter name by a :

No semantics were assigned to these annotations, though they were typically used to provide informal, documentary type hints for the parameters and the return value, respectively. There is no difference between function annotations and type hints to speak of: type hints are an application of function annotations.

Starting with PEP 484, the syntax for these type hints was standardized. PEP 563 explicitly deprecates the use of annotations for anything except type hints.

The two optional parts in the grammar you quote that specify function annotations are

  1. In funcdef, [ '->' test ] for return values
  2. In name, [':' test] for parameter types.
chepner
  • 497,756
  • 71
  • 530
  • 681