On Fri, Dec 25, 2020 at 5:07 PM David Foster <davidfstr@gmail.com> wrote:
On 12/23/20 12:48 PM, Eric Traut wrote:
 > David said:
 >> it's possible to trivially implement safe_cast()...
 >
 > Yes, but I'll point out that you would need to reverse the parameters
because the expression that is being narrowed (in your example, the
`value` parameter) must be the first param of the type guard function.

(The example of safe_cast() I provided doesn't actually use TypeGuard so
I'm assuming you meant cast(), whose definition is already fixed by the
existing API to have a typing form as the first parameter.)

Ah yes. It would be necessary to use explicit syntax in TypeGuard to
declare which (non-first) parameter was involved. Here's a corrected
definition of cast() that uses TypeGuard:

```
def cast(form: TypeForm[T], value: object) -> TypeGuard[value=T]:
     return value
```

Um, that's not a valid type guard according to Eric's PEP. The type guard function must return a bool. Or is this part of an alternate proposal where that's not the case? Maybe you could add some more context?
 
[snip]
On 12/23/20 4:48 PM, Sebastian Kreft wrote:
 >     I don't think that multiple arguments is the problem here. I've come
 >     across a couple of cases in real code where I wouldn't have been
 >     able to use the TypeGuard mechanism if it was limited to just one
 >     argument, so I'm reluctant to place that limitation on it.
 >
 > Note that it'd be just a deferral until we get more insights on how
 > typeguards are used in Python. Then we could extend TypeGuard to accept
 > an optional second argument specifying which argument is the one being
 > guarded, something like TypeGuard[T, 'second'].

I'll still advocate for a future syntax more like `TypeGuard[second=T]`
if the ability to explicitly label the applicable parameter appears
later. :)

To stress an earlier point, I do *not* think it's necessary to add that
kind of parameter-labeling syntax in the initial PEP, especially given
that for most uses of TypeGuard (ignoring combinations with TypeForm)
it's always the *first* parameter of the function that's being narrowed,
which doesn't require the labeling syntax. (If keyword arguments inside
[] were already available, I'd have a different opinion.)

I agree that with PEP 637 syntax this would look nicer. However it wouldn't work in Python versions before 3.10, so maybe we could offer Sebastian's suggestion as a backwards compatible syntax option (like for variadics we're leaning towards `*Ts` in 3.10 with `Expand[Ts]` for earlier versions).

--
--Guido van Rossum (python.org/~guido)