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

Michael Kay mike at saxonica.com
Mon Sep 8 17:04:24 PDT 2008


> I'm working on a conforming XQuery implementation for the 
> .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.

> An example of such 
> mapping would be:
> 
>  declare namespace sys = "clr-namespace:System;assembly=mscorlib";
>  declare function local:foo(s as sys:String) {
>    sys:String.ToLower(s)
>  };

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)
};

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.
> 
> This seems to work fine and look nice, but problems begin 
> when generic types are brought into the picture. 

Agreed, there's no easy answer to this. I think my preferred solution is to
not bring them into the picture. Mappings to external type systems are never
going to be perfect. Alternatively, I would be inclined to use "declare
option" to declare a local name for an external type:

declare option saxon:type-alias "my:listOfString =
System.Collections.List<System.String>";

declare function local:foo(s as my:listOfString) {
  ...
}

or perhaps even to define some kind of mapping language that contains these
type mappings in an external file, which can then be imported. XSD 1.1
allows user-defined primitive types, so that could provide the basis of a
mechanism.

> I considered a language extension, something along these lines:
> 
>  (: The corresponding .NET type is System.Func<System.String, 
> System.Int32> :)  declare function local:foo(fun as 
> generic-instance(sys:Func, sys:String, sys:Int32)) { ... };

There seems to be an attitude among XQuery implementors that extending the
syntax is OK. Personally I regard it as very undesirable. It's not possible
for Saxon in any case, because I am implementing XSLT as well as XQuery, and
private syntax in XSLT is both banned by the spec, and considered
unacceptable by the user community. 
> 
> The problem is that there is nothing in XQuery spec to 
> guarantee that this won't clash with any future language 
> developments. 

Which is one reason why XSLT bans it...
> 

Michael Kay
http://www.saxonica.com/



More information about the talk mailing list