Open
Description
Hi,
I recently though of a way to facilitate argument parsing by letting JS doing most of the job.
Frankly, I do not know if this would be faster, but the code should be cleaner.
By declaring the function prototype as:
function foo(_pos_a, _pos_b = 3, locals = {a = _pos_a, b = _pos_b, c, d = 4} = _b_.KW) {
_b_.KW = {};
// do stuff
}
We can simply call with :
function call_without_kw(fct, ...args) {
// verif usage
// ...
fct(...args);
}
function call_with_kw(fct, ...args) {
_b_.KW = args[--args.length];
// verif usage
// ....
fct(...args);
}
call_with_kw( fct, 1, {c=4} );
This would also offer more possibilities when calling Python functions from JS code (e.g. in Brython internals).
To verify the proper usage, we need to ensure:
- compare the number of arguments given with the required min/max positional arguments (both precomputed) ;
- for each positional parameters without defaults, that wasn't given as a positional argument (so from number of arguments to a precomputed start_of_pos_defaults), verify if it was given as a kw args ;
- for each positional parameters that was given as a positional argument, verify it wasn't given as a kw args ;
- for each kwonly parameters without defaults (precomputed list), verify if it was given as a kw args ;
- if there isn't a
**kwargs
, verify the kw args keys.
For steps 2-5 there might be a simple algorithm, for example :
const array = new Array(...); // preallocated
const name2id = { // precomputed
"a" : 0,
"b" : 1
}
array.fill(false);
for(let key in KW) {
const idx = name2id[key];
if( idx === undefined)
; // either continue or throw depending if **kwargs parameter
if( idx === -1 ) // kwonly with default
; // continue
if( idx < nb_pos_given) // duplicate pos/kw argument
; // raise error
array[idx] = true;
}
for(let i = nb_pos_given; i < end; ++i)
if( array[i] === false ) // missing argument
; // raise error.
Another way (I'm a little surprise we don't need to do more) :
const required_args = ["a", "b"]; // precomputed
const args_with_defaults =["c"]; // precomputed if no **kwargs
for(let i = nb_pos_given; i < end; ++i)
if( ! (args[i] in KW) )
; // throw missing args
if( ! hasKWARGS ) {
let count = Object.keys(KW).length - required_args + nb_posonly;
for(let i = 0; i < args_with_defaults.length; ++i)
if( args_with_defaults[i] in KW )
--count;
if( count > 0 ) ; // throw unknown args or dupl. args
}
// note: we could also do :
const keys = Object.keys(KW);
keys.includes(key)
// in some cases this might be slightly faster than key in KW (?)
Duplicate keys could be handled at two levels:
- at the level of
a=2, a=3
. - in
call_with_kw(fct, 1, 2, _b_.merge({a:2}, {a:3}) )
.
Metadata
Metadata
Assignees
Labels
No labels