> 3. Can we consider a cleaner compromise? I call this the XOR proposal (or the "have our cake and eat it too" proposal):
>
> ```
> callable_syntax :=
>    | shorthand_syntax
>    | def_style_syntax
> ```

> I want a solution that can capture all types you can specify using `def` (excepting `@overload`).

Guido: Yes, the xor syntax was designed to do exactly that. Did you have thoughts on using the xor syntax instead of the hybrid syntax?

Given how rarely the additional features will be used, it seems better to have a straightforward def-style way to specify them instead of having several additional rules for allowing (x: str=...) -> int, (str=...) -> int, (**int) -> int, etc.

Overall, shorthand is compatible with both xor and hybrid, so adding the additional syntax later should be relatively easy if needed. I'd prefer just shorthand over either hybrid or xor. 

Likewise, xor syntax is compatible with the hybrid syntax (the latter accepts any instance of the former). So, if we discover that we do want the extra features from hybrid, we could easily add them in the future. So, if just shorthand is not acceptable, I'd prefer xor over hybrid. Going for hybrid right away seems like we are prematurely adding complexity for rare cases.

> There would be several additional rules:
>
> - if a parameter specifies the `NAME '='` part, all following parameters must too
> - a '/' is inserted before the first parameter that has the `NAME '='` part
> - a '*' or '**' prefix is allowed, using all the usual constraints

> (a) should it be **int or **kwargs: int?
> (b) is `(int, str=...) -> bool` valid or do we have to use (int, x: str=...) -> bool?
> (c) should we allow `(int, x: str, bool) -> str`?
>
> In my version, (a) both, (b) both, (c) no.

Thanks for specifying hybrid some more.

> Similarly, is `(foo, bar) -> int` shorthand or def-style syntax? If we prepend `def f`, it is valid.

Good point. We would restrict `def_style_syntax` to fully-typed signatures. So, `(foo, bar) -> int` would be parsed as the shorthand syntax.

On Tue, Sep 28, 2021 at 10:47 AM Kevin Millikin via Typing-sig <typing-sig@python.org> wrote:
That seems undesirable. A programmer who has a value annotated with static type (x: int = 0) -> None who wants to pass 0 might assume it's safe to call it without the argument. But if that value might be a function of type (x: int = 42) -> None then that program should not type check. 

On Tue, 28 Sept 2021, 16:16 Eric Traut, <eric@traut.com> wrote:
> I'm curious about the semantics of default values in a callable type

The value of a default doesn't affect the type of the callable, but the presence of a default does.

From a type perspective:

`(x: int = 42) -> None` is equivalent to both `(x: int = 0) -> None` and `(x: int = ...) -> None`.

and

`(x: int = ...) -> None` is compatible with both `(x: int) -> None` and `() -> None`.

 -Eric

--
Eric Traut
Contributor to pyright & pylance
Microsoft Corp.
_______________________________________________
Typing-sig mailing list -- typing-sig@python.org
To unsubscribe send an email to typing-sig-leave@python.org
https://mail.python.org/mailman3/lists/typing-sig.python.org/
Member address: kmillikin@google.com
_______________________________________________
Typing-sig mailing list -- typing-sig@python.org
To unsubscribe send an email to typing-sig-leave@python.org
https://mail.python.org/mailman3/lists/typing-sig.python.org/
Member address: gohanpra@gmail.com


--
S Pradeep Kumar