Re: Keyword arguments and fn:serialize [was fn:slice]

Hi,

this also started as a way to simplify calling the serialize function 
with its parameters.

Do we want a 23-arity serialize function?

fn:serialize($arg as item()*, $allow-duplicate-names as ..., 
$byte-order-mark as ..., $cdata-section-elements as ..., $doctype-public 
as ..., $doctype-system as ..., $encoding as ..., $escape-uri-attributes 
as ..., $html-version as ..., $include-content-type as ..., $indent as 
..., $item-separator as ..., $json-node-output-method as ..., 
$media-type as ..., $method as ..., $normalization-form as ..., 
$omit-xml-declaration as ..., $standalone as ..., $suppress-indentation 
as ..., $undeclare-prefixes as ..., $use-character-maps as ..., $version 
as ...)



Although what really matters is the method. Perhaps it could be pulled 
out to create 4 functions:


|fn:serializ||e-xml|(|$arg|| as ||item()*|, |$params|| as 
||item()?|)| as ||xs:string|
|fn:serialize||-html|(|$arg|| as ||item()*|, |$params|| as 
||item()?|)| as ||xs:string|
|fn:serialize||-xhtml|(|$arg|| as ||item()*|, |$params|| as 
||item()?|)| as ||xs:string|
||
|fn:serialize||-json|(|$arg|| as ||item()*|, |$params|| as 
||item()?|)| as ||xs:string|||||




Or perhaps look at the map constructor again.

When you write map { ... something .. } it is like passing the data 
between {} to "map". Map kind of behaves like a function turning the 
data into an actual map.

That could be allowed for all functions. So you could write serialize { 
"method": "xml", ... }

Not sure how that should get its $arg. Perhaps $arg => serialize { 
"method": "xml", ... }

Cheers,
Benito
On 05.12.20 22:01, Dimitre Novatchev wrote:
> What about something as simple as this:
>
> myFunction($arg1 as item()*, $arg2 as xs:integer default: 15, $arg3 as 
> xs:string default: "Hi")
>
> This isn't breaking the syntax and semantics of previous versions of 
> XPath. The arity is 3, not two or one.
>
> It can be called in these ways:
>
> myFunction(/*/name)  (: will use the defaults for $arg2 and $arg3 :)
>
> myFunction(/*/name, 12) (: $arg2 is entered as a positional argument 
> (which is OK), will use the default for $arg3 :)
>
> myFunction(/*/name, 12, "Yes")  (: Both $arg2 and $arg3 are entered as 
> positional arguments, this is OK :)
>
> myFunction(/*/name, $arg3: "Yes")   (: the default will be used for 
> $arg2 :)
>
> myFunction(/*/name, $arg2: 12) (: the default will be used for $arg3 :)
>
> myFunction(/*/name, $arg3: "Yes", $arg2: 12)  (: when an argument is 
> provided with name and value, order doesn't matter :)
>
> and even:
>
>  myFunction($arg1: /*/name)  (: we can provide a positional argument 
> using its parameter name :)
>
>  myFunction($arg3: "Yes", $arg2: 12, $arg1: /*/name)  (: when an 
> argument is provided with name and value, order doesn't matter, even 
> if this is a required, positional parameter :)
>
> I think this is more or less the ways for calling a method in C# 
> (https://docs.microsoft.com/en-us/dotnet/csharp/methods 
> <https://docs.microsoft.com/en-us/dotnet/csharp/methods>).
> To quote the same document 
> (https://docs.microsoft.com/en-us/dotnet/csharp/methods#method-invocation 
> <https://docs.microsoft.com/en-us/dotnet/csharp/methods#method-invocation>)
>
> "/You can also use named arguments instead of positional arguments 
> when invoking a method. When using named arguments, you specify the 
> parameter name followed by a colon (":") and the argument. Arguments 
> to the method can appear in any order, as long as all required 
> arguments are present. /"
>
> Thanks,
> Dimitre
>
> On Sat, Dec 5, 2020 at 1:16 AM Michael Kay <mike@saxonica.com 
> <mailto:mike@saxonica.com>> wrote:
>
>>
>>     So Mike's example is exactly what i was suggesting before in this
>>     regard, except i want the keywords to map to named arguments so there
>>     can be useful static type checking. We would need to allow optional
>>     arguments for transform() at least, though, and refer to it e.g. as
>>     fn:transform#*
>>
>
>     My only problem with this proposal is whether it can be made
>     backwards-compatible. I guess that in a strict sense, if a
>     parameter has to be declared optional before it can be used in
>     this way, then existing code that doesn't use optional parameters
>     won't be affected. But at a usability level, if different
>     functions follow different conventions, then it could make life
>     difficult for users.
>
>     In the case of system-supplied functions, we've been very careful
>     in the design to ensure, for example, that format-date#2 and
>     format-date#5 have consistent syntax and semantics, so we could
>     simply make the last three parameters optional and turn it into a
>     single function, and a call with any number of supplied arguments
>     could bind to format-date#5 without difficulty. For compatibility,
>     dynamic references to format-date#2 and format-date#5 would still
>     need to work, and for strict compatibility,
>     function-arity(format-date#2) would still have to return 2, while
>     function-arity(format-date#5) returns 5, so they would still be
>     different functions.
>
>     For user-written functions, it's possible that users haven't
>     followed the same conventions, and my:ftingle#2 might do something
>     completely different from my#ftingle#5, so that my:ftingle#2 isn't
>     equivalent to my:ftingle#5 with optional parameters. This means
>     that calls on user-defined functions wouldn't be able to use the
>     new mechanism unless the function definition is changed;. Some
>     function libraries such as the EXPath file and binary libraries
>     are unlikely to change in a hurry; and until they do, users would
>     have to be aware that the new calling mechanism is available for
>     some function libraries and not for others.
>
>     By contrast, the mechanism I have been proposing of assembling
>     keyword arguments into a map requires no change to existing
>     function signatures or implementations.
>
>     Another difference is that my proposal allows the set of accepted
>     keywords to be dynamic and/or extensible. It's possible with a
>     Record type definition in the signature to restrict the available
>     keywords, but you don't have to. The specification of a function
>     can make it extensible if it chooses (so an implementations might
>     accept vendor-defined keywords, as in fn:serialize()) and it's
>     also possible to design functions where the set of keywords is
>     completely open-ended, for example one could design a function
>     where the call
>
>     new-element('p') => with-attributes(class: "note", role:
>     "footnote", date: current-date())
>
>     accepts any set of names for the attributes of a new element.
>
>     Michael Kay
>     Saxonica
>
>
>
> -- 
> Cheers,
> Dimitre Novatchev
> ---------------------------------------
> Truly great madness cannot be achieved without significant intelligence.
> ---------------------------------------
> To invent, you need a good imagination and a pile of junk
> -------------------------------------
> Never fight an inanimate object
> -------------------------------------
> To avoid situations in which you might make mistakes may be the
> biggest mistake of all
> ------------------------------------
> Quality means doing it right when no one is looking.
> -------------------------------------
> You've achieved success in your field when you don't know whether what 
> you're doing is work or play
> -------------------------------------
> To achieve the impossible dream, try going to sleep.
> -------------------------------------
> Facts do not cease to exist because they are ignored.
> -------------------------------------
> Typing monkeys will write all Shakespeare's works in 200yrs.Will they 
> write all patents, too? :)
> -------------------------------------
> Sanity is madness put to good use.
> -------------------------------------
> I finally figured out the only reason to be alive is to enjoy it.

Received on Sunday, 6 December 2020 18:41:24 UTC