Re: [PHP-DEV] [VOTE] Named arguments

This is only part of a thread. view whole thread
  110919
July 10, 2020 14:18 kontakt@beberlei.de (Benjamin Eberlei)
On Fri, Jul 10, 2020 at 11:21 AM Marco Pivetta <ocramius@gmail.com> wrote:

> Hi Nikita, > > I kept my "NO" stance here, as per discussion in > https://externals.io/message/110004#110005, where I provided (in my > opinion) good/safe alternatives to arrays as input parameters. >
> The BC implications on this RFC still largely outweigh any advantages that > it brings, from my perspective. >
Are there alternatives to named parameters? Of course. Are they as simple? Not really. 1. You can use an array, but array values cannot be typed, so you completly loose typing of the language. 2. You can use an object with builder pattern, but that requires a lot of code to write, and increases the mental capacity of understanding something for developers. 3. your example of an api to convert named params to a sequence is not discoverable, you don't know looking or using method A() that it comes with an additional NamedParamsA() helper. I see PHP as a language to get up and running quickly. So builder pattern is really more an advanced approach, should be used by not many use-cases. We have seen arrays of $options and $params to no end in framework and library APIs, with all their problems. So named params are a real improvement that feels like supporting "the php way(tm)". Lastly we need to consider internal APIs, which are usually about adding more parameters (htmlentities, json_decode, ...). These APIs are going to stay and benefit hugely from named params. Then the question becomes, do we rename parameters a lot? I doubt it's a large problem, and even then the variadics support makes it very easy to handle in a backwards compatible way. In addition libraries are always open to declare they don't consider named parameters as part of their API.
> Greets, > > Marco Pivetta > > http://twitter.com/Ocramius > > http://ocramius.github.com/ > > > On Fri, Jul 10, 2020 at 10:42 AM Nikita Popov ppv@gmail.com> > wrote: > > > Hi internals, > > > > I have opened voting on the named arguments RFC: > > https://wiki.php.net/rfc/named_params > > > > Voting will close on 2020-07-24. > > > > Regards, > > Nikita > > >
  110930
July 10, 2020 22:34 cja987@gmail.com (Chuck Adams)
> Then the question becomes, do we rename parameters a lot? I doubt it's a > large problem, and even then the variadics support makes it very easy to > handle in a backwards compatible way. In addition libraries are always open > to declare they don't consider named parameters as part of their API.
Python supports the notion of "keyword-only arguments". If that was supported, and the renamed argument had a default, an API could rename parameters in a backward-compatible manner by introducing a kw-only arg with the same name. One could also consider an aliasing syntax such that more than one keyword could correspond to a named argument. Perhaps using an annotation? --c
  110962
July 12, 2020 10:24 php@manuelcanga.dev (Manuel Canga)
Hi,


 ---- En vie, 10 jul 2020 16:18:40 +0200 Benjamin Eberlei <kontakt@beberlei..de> escribió ----
 > On Fri, Jul 10, 2020 at 11:21 AM Marco Pivetta <ocramius@gmail.com> wrote:
 > 
 > > Hi Nikita,
 > >
 > > I kept my "NO" stance here, as per discussion in
 > > https://externals.io/message/110004#110005, where I provided (in my
 > > opinion) good/safe alternatives to arrays as input parameters.
 > >
 > 
 > > The BC implications on this RFC still largely outweigh any advantages that
 > > it brings, from my perspective.
 > >
 > 
 > Are there alternatives to named parameters? Of course. Are they as simple?
 > Not really.
 > 
 > 1. You can use an array, but array values cannot be typed, so you completly
 > loose typing of the language.
 > 2. You can use an object with builder pattern, but that requires a lot of
 > code to write, and increases the mental capacity of understanding something
 > for developers.
 > 3. your example of an api to convert named params to a sequence is not
 > discoverable, you don't know looking or using method A() that it comes with
 > an additional NamedParamsA() helper.
 > 


4. Other option is creating a  new function( not yet available in PHP ) like:

```
 array_check_scheme( array $array, array $scheme,  bool $forced = false  ): bool
```

( name of function can be better )

in order to check types in arrays. Then you could:

/**
  * @param array $args{name: string, surname: string, ?age: int}
 */
function my_function(  array $args ) {
   $scheme = ['name' => 'string', 'surname' => 'string', '?age' => 'int');
   $is_valid =  array_check_scheme( $args, $scheme );
}


my_function( ['name' = 'Nikita', 'surname' => 'Popov' ] );  //is_vaild = true
my_function( ['name' = 'Nikita'] );  //is_vaild = false
my_function( ['name' = 'Nikita'],  'age' => 10 );  //is_vaild = false

A function like this could be useful in other contexts as well.

Regards
--
Manuel Canga
  110963
July 12, 2020 12:19 rowan.collins@gmail.com (Rowan Tommins)
On 12 July 2020 11:24:50 BST, Manuel Canga <php@manuelcanga.dev> wrote:
>4. Other option is creating a new function( not yet available in PHP ) >like: > >``` >array_check_scheme( array $array, array $scheme, bool $forced = false >): bool >```
The problem with this, whether built in or not, is that you have to express everything with strings rather than keywords. That means, for instance, that invalid values in the definitions themselves will only error at run-time. The definitions also tend to get verbose pretty quickly. To make it concise and checked at compile-time, you need it to be a construct that pairs identifiers to types without first representing them as strings, e.g. to write `?string $foo = 'hello'` rather than `'foo' => ['type'=>'string', 'nullable'=>true, 'default'=>'hello']`. It turns out we already have a construct for doing that: function signatures. If the input is an actual array or object coming from "outside", you're probably going to want a more extensible validation system anyway. Those are really hard to design, and probably best left to userland where people can choose the tradeoffs they prefer. Regards, -- Rowan Tommins [IMSoP]
  110965
July 12, 2020 14:05 php@manuelcanga.dev (Manuel Canga)
Hi, Rowan,


 ---- En dom, 12 jul 2020 14:19:08 +0200 Rowan Tommins collins@gmail..com> escribió ----

 > The problem with this, whether built in or not, is that you have to express everything with strings rather than keywords. That means, for instance, that invalid values in the definitions themselves will only error at run-time. The definitions also tend to get verbose pretty quickly.
 > 
 > To make it concise and checked at compile-time, you need it to be a construct that pairs identifiers to types without first representing them as strings, e.g. to write `?string $foo = 'hello'` rather than `'foo' => ['type'=>'string', 'nullable'=>true, 'default'=>'hello']`. It turns out we already have a construct for doing that: function signatures.
 > 
 > If the input is an actual array or object coming from "outside", you're probably going to want a more extensible validation system anyway. Those are really hard to design, and probably best left to userland where people can choose the tradeoffs they prefer.
 > 
 > Regards,
 > 

I see. 

However, with named arguments you also have to implement changes in parser in order to can recognize named arguments. You also have to change behavior about default parameters. I don't know if this change affect to performance, maybe do. 

By the other hand, editor like PHPStorm has "Inlay Hints": 
https://www.jetbrains.com/help/rider/Inline_Parameter_Name_Hints.html

With a function which checks scheme, you also could use in other contexts, like  forms:

```
$scheme = ['name' => 'string', 'surname' => 'string', '?age' => 'int');
$is_valid = array_check_scheme( $_POST, $scheme ); 
```

You can use it even with JSON:

```
$request = json_decode( $request_json, true );
$scheme = ['name' => 'string', 'surname' => 'string', '?age' => 'int');
$is_valid = array_check_scheme( $request, $scheme ); 
```

 > e.g. to write `?string $foo = 'hello'` rather than `'foo' => ['type'=>'string', 'nullable'=>true, 'default'=>'hello']`

Maybe you don't need checked at compile-time. is it  slow?, securely, but you don't use in everywhere.

> you're probably going to want a more extensible validation system anyway.
Maybe, in that case, userland libraries have a starting point. With XML parsing is the same. PHP provides basic functionality and userland provide advanced. Regards -- Manuel Canga