[xquery-talk] Type system extensions: best syntax for foreigngeneric types

Pavel Minaev int19h at gmail.com
Tue Sep 9 23:15:39 PDT 2008


On Mon, Sep 8, 2008 at 7:04 PM, Michael Kay <mike at saxonica.com> wrote:
>> .NET platform. Naturally, to be useful, it would require
>> first-class interop with .NET libraries, both stock and
>> third-party. I've seen the way Saxon does it, but I'd rather
>> have the entire .NET type system available for use in XQuery
>> - so that you could not just call a .NET method, but declare
>> an XQuery function that takes a reference to a .NET object,
>> and so on.
>
> Saxon can in fact do this. But it doesn't yet handle generics.

Actually, it is half-way there. This works on Saxon 9.1 for .NET:

 declare namespace nul = "clitype:System.Nullable`1[System.Int32]";
 let $x := nul:new(123)
 return nul:HasValue($x)

though there is still no way to use generic type name on its own in a
declaration or a cast.

> For method calling, Saxon maps an XML namespace to each .NET class, not to
> each external package or namespace. And for the name of the type, it uses a
> single namespace http://saxon.sf.net/clitype. So this would be (without
> generics)
>
> declare namespace dotnet="http://saxon.sf.net/clitype";
> declare namespace System.String = "clitype:System.String?asm=mscorlib";
> declare function local:foo(s as dotnet:System.String) {
>   System.String:ToLower(s)
> };

Ah, I do apologize; I was aware of the function/method mapping from my
past experience with Saxon XSLT (it proved to be very handy back
then), but I was not aware about the types, probably because they
aren't really all that useful on their own.

> This can potentially lead to a lot of namespaces; but it that's the case,
> then I think you are over-using the facility for calling extension functions
> and should reexamine your application design.

Well, let me explain why I want the feature in the first place, and
why it is an important one for the scenarios considered. I'm not
merely trying to write yet another XQuery implementation in .NET; what
I want is to come up with an implementation that is an (almost)
first-class .NET citizen, with XQuery modules being statically
compiled to .NET assemblies with straightforward mapping, XDM types
mapped to .NET types where possible, and so on. The intended use case
is to refactor complex XML processing into XQuery modules, which are
compiled to .NET classes that are immediately usable from C#/VB/... -
so you could write this:

 module namespace foo = "clr-namespace:Acme.Foo";
 import schema namespace mytypes = "mytypes.xsd";
 declare function foo:Bar($customer as
schema-element(mytypes:customer)) as xs:int { ... };

and then use it like this:

 using Acme.Foo;
 XmlDocument doc = new XmlDocument();
 doc.Load("customer.xml");
 doc.Schemas.Add(null, "mytypes.xsd");
 doc.Validate();
 Module foo = new Module();
 int bar = foo.Bar(doc.DocumentElement);

With this approach, it's much more common for foreign code to call
into XQuery code than vice versa. However, it would be a typical
scenario to have XQuery functions that would take raw or typed XML
nodes, parse or otherwise process them, and build object graphs from
the data, e.g.:

 declare namespace acme = "clr-namespace:Acme";
 declare function parse-customer($cust as element(Customer)) as
acme:Customer? { ... };

and this requires an expressive way to use arbitrary .NET types in
function signatures.

> There seems to be an attitude among XQuery implementors that extending the
> syntax is OK. Personally I regard it as very undesirable.

That was the main reasoning behind my post. No matter what, I consider
compliance to the spec first priority; therefore, while I would like
an easy way out, I'm not going to take one that is not permissible
within the boundaries of the spec. I was just wondering whether I
indeed correctly understood their restrictiveness.

By the way, it seems rather strange to me that there are explicit
extensibility points for some elements of the language - "declare
option" for global stuff, and expression-scope pragmas - but no
similar mechanisms to decorate type references, or function
declarations. Is it a deliberate design decision, or just something
that was not considered because of the (then) seeming lack of need of
such a thing?


More information about the talk mailing list