Hi, Doug,

I it won't be possible to make it "feel naturally" with every language, simply 
because the languages have very different naming conventions (C# mandates 
CamelCase, Python prefers words_with_underscores, ...) and programming 
paradigms.

But on the other hand, you should keep in mind that .NET was designed as a 
multi-paradigm environment, and that all those Languages were implemented with 
this in mind.

Most of the dynamic languages have very clever parameter resolution and 
automatic casting mechanisms implemented, as they offer easy access to the 
whole .NET standard library - this will automatically apply to your interface, 
too. E. G. any python list and tuple can be passed to a function taking a 
IEnumerable<Foo>, python will create an auto-casting enumerator, and will throw 
when the sequence contains elements not compatible to Foo.

Nevertheless, my concrete points of advice are:

- I think the most important thing is that you make a simple, clearly 
structured API. 

- Be generous but exact in what you accept. For example if you need a sequence 
of Foo as parameter, accept IEnumerable<Foo>.
  * No need to use IEnumerable and cast yourself - more Code to type, the 
dynamic language binding will auto-cast for you, and the statically typed 
languages like C# and F# profit from the stricter declaration. 
  * Accepting IList<Foo> or ICollection<Foo> is too strict for the main method, 
but if your algorithm can profit from indexing or knowing the size, you may 
provide them as optimized overloads.

- Adhere to the coding standards / naming conventions in the language you use 
to implement.

- Take care that all your functionality is exposed in CLS conformant ways. 
(IMHO, it is okay to provide optimized non-CLS conformant alternative ways of 
access. One example is that you should provide access methods for all 
overloaded operators. Browse the Web and MSDN for CLS conformance, you'll find 
lots of guidelines.)

- After drafting your interface (or implementing the first alpha), ask users of 
the target languages for their advice, or implement a test application in all 
of the languages.

(I personally don't have any experience with IronRuby, and simply assumed that 
they use similar mechanisms like IronPython, so take my advice with a grain of 
salt.)
Regards,
Markus


> -----Ursprüngliche Nachricht-----
> Von: users-boun...@lists.ironpython.com [mailto:users-
> boun...@lists.ironpython.com] Im Auftrag von Doug Blank
> Gesendet: Montag, 4. April 2011 17:25
> An: Discussion of IronPython
> Betreff: [IronPython] Writing cross-language libraries that appear native
> 
> I'm working on writing C# libraries which can be imported by a variety of
> .NET languages, DLR and otherwise, which appear native to the language
> importing them.
> 
> For example, writing a C# function that can be used naturally in
> IronPython as if it were written in Python, IronRuby as if it were written
> in Ruby, and F# as if it were written in F#, etc.
> 
> I've encountered some gotchas that I thought I'd share, and looking for
> any other points of advice in writing cross-language libraries.
> 
> 1. IronRuby strings aren't really strings, so you need to pass them in as
> an object, and call .ToString().
> 
>     public static string expects_string(object val) {
>         return val.ToString();
>     }
> 
> 2. F# 2.0 doesn't seem to automatically convert a type to the associated
> nullable type, so avoid nullable types as parameters.
> 
>     // AVOID:
>     public static double? expects_nullable(double? var1=null) {
>         return var1;
>     }
> 
>     // BETTER:
>     public static double? expects_nullable() {
>         return null;
>     }
>     public static double expects_nullable(double var1) {
>         return var1;
>     }
> 
> 3. IronPython and IronRuby lists and dictionaries implement IList and
> IDictionary, so no problem with those.
> 
>     public static IDictionary<object,object> make_dict(object val) {
>         if (val as IDictionary<object,object> != null) {
>             return ((IDictionary<object,object>)val);
>         } else
>             throw new System.ArgumentException("object is not a
> dictionary");
>     }
> 
>     public static IList<object> make_list(object val) {
>         if (val as IList<object> != null) {
>             return ((IList<object>)val);
>         } else
>             throw new System.ArgumentException("object is not a list");
>     }
> 
> Any other suggestions?
> 
> -Doug
> _______________________________________________
> Users mailing list
> Users@lists.ironpython.com
> http://lists.ironpython.com/listinfo.cgi/users-ironpython.com
_______________________________________________
Users mailing list
Users@lists.ironpython.com
http://lists.ironpython.com/listinfo.cgi/users-ironpython.com

Reply via email to