Re: [IronPython] Writing cross-language libraries that appear native

2011-04-05 Thread Markus Schaber
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 
IEnumerableFoo, 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 IEnumerableFoo.
  * 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 IListFoo or ICollectionFoo 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 IDictionaryobject,object make_dict(object val) {
 if (val as IDictionaryobject,object != null) {
 return ((IDictionaryobject,object)val);
 } else
 throw new System.ArgumentException(object is not a
 dictionary);
 }
 
 public static IListobject make_list(object val) {
 if (val as IListobject != null) {
 return ((IListobject)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


Re: [IronPython] Writing cross-language libraries that appear native

2011-04-05 Thread Doug Blank
On Tue, Apr 5, 2011 at 3:05 AM, Markus Schaber
m.scha...@3s-software.com wrote:
 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.

It is true that each language has conventions, and also true that some
languages have multiple conventions (for example, there are CamelCase
and underscore Python programmers). But there are some options that
just aren't possible. For example, it was not even possible to access
a lowercased class name from IronRuby (at least when I tried a while
back). My goal was to document that kind of issue. Also, the naming
convention isn't so important (to us) as is a natural way of passing
parameters and getting back results.

 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.

Well, not all .NET languages are implemented by Microsoft, and many
follow their own conventions. I'm trying to come up with some
guidelines for writing good libraries that work across a wide spectrum
(from Boo to F#).

 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 IEnumerableFoo, python will create an auto-casting enumerator, and 
 will throw when the sequence contains elements not compatible to Foo.

Yes, the Iron* languages are excellent in this regard. I'm hoping that
more languages will adopt that autocasting code, if not more of the
DLR.

 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 IEnumerableFoo.
  * 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 IListFoo or ICollectionFoo 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.)

If you could give an example guideline url, that would be useful...
maybe I'm using bad search terms.

 - 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.

Yes, I'm writing examples in all of the .NET languages and libraries
that we [1] support [2].

 (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.)

IronRuby does some cleaver things such as renaming CamelCase items to
camel_case. But most languages don't.

I'll eventually document all this on a website (can I use your
suggestions?) This may be beyond the scope of the IronPython website,
though.

-Doug

[1] http://pyjamaproject.org/
[2] http://svn.cs.brynmawr.edu/viewvc/Pyjama/trunk/examples/

 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

[IronPython] Writing cross-language libraries that appear native

2011-04-04 Thread Doug Blank
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 IDictionaryobject,object make_dict(object val) {
if (val as IDictionaryobject,object != null) {
return ((IDictionaryobject,object)val);
} else
throw new System.ArgumentException(object is not a dictionary);
}

public static IListobject make_list(object val) {
if (val as IListobject != null) {
return ((IListobject)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


Re: [IronPython] Writing cross-language libraries that appear native

2011-04-04 Thread Tomas Matousek
Re: 1.

MutableString is convertible to String, so why would you need an object 
parameter?

Tomas

-Original Message-
From: users-boun...@lists.ironpython.com 
[mailto:users-boun...@lists.ironpython.com] On Behalf Of Doug Blank
Sent: Monday, April 04, 2011 8:25 AM
To: Discussion of IronPython
Subject: [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 IDictionaryobject,object make_dict(object val) {
if (val as IDictionaryobject,object != null) {
return ((IDictionaryobject,object)val);
} else
throw new System.ArgumentException(object is not a dictionary);
}

public static IListobject make_list(object val) {
if (val as IListobject != null) {
return ((IListobject)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


Re: [IronPython] Writing cross-language libraries that appear native

2011-04-04 Thread Doug Blank
On Mon, Apr 4, 2011 at 11:52 AM, Tomas Matousek
tomas.matou...@microsoft.com wrote:
 Re: 1.

 MutableString is convertible to String, so why would you need an object 
 parameter?

Do you mean that one could write:

    public static string expects_string(MutableString val) {
        return (val as String);
    }

I wrote:

    public static string expects_string(object val) {
        return val.ToString();
    }

because that would work for all languages, and you could pass in an
IronPython or F# string it it would work just as well. Or did you mean
something else?

-Doug

 Tomas

 -Original Message-
 From: users-boun...@lists.ironpython.com 
 [mailto:users-boun...@lists.ironpython.com] On Behalf Of Doug Blank
 Sent: Monday, April 04, 2011 8:25 AM
 To: Discussion of IronPython
 Subject: [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 IDictionaryobject,object make_dict(object val) {
        if (val as IDictionaryobject,object != null) {
            return ((IDictionaryobject,object)val);
        } else
            throw new System.ArgumentException(object is not a dictionary);
    }

    public static IListobject make_list(object val) {
        if (val as IListobject != null) {
            return ((IListobject)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

___
Users mailing list
Users@lists.ironpython.com
http://lists.ironpython.com/listinfo.cgi/users-ironpython.com


Re: [IronPython] Writing cross-language libraries that appear native

2011-04-04 Thread Jimmy Schementi
Tomas means you can write this:

 public static string ExpectsString(string val) {
return val;
 }


And call it from Ruby with a Ruby string:

expects_string Foo

~Jimmy


On Apr 4, 2011, at 12:21 PM, Doug Blank doug.bl...@gmail.com wrote:

 On Mon, Apr 4, 2011 at 11:52 AM, Tomas Matousek
 tomas.matou...@microsoft.com wrote:
 Re: 1.
 
 MutableString is convertible to String, so why would you need an object 
 parameter?
 
 Do you mean that one could write:
 
public static string expects_string(MutableString val) {
return (val as String);
}
 
 I wrote:
 
public static string expects_string(object val) {
return val.ToString();
}
 
 because that would work for all languages, and you could pass in an
 IronPython or F# string it it would work just as well. Or did you mean
 something else?
 
 -Doug
 
 Tomas
 
 -Original Message-
 From: users-boun...@lists.ironpython.com 
 [mailto:users-boun...@lists.ironpython.com] On Behalf Of Doug Blank
 Sent: Monday, April 04, 2011 8:25 AM
 To: Discussion of IronPython
 Subject: [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 IDictionaryobject,object make_dict(object val) {
if (val as IDictionaryobject,object != null) {
return ((IDictionaryobject,object)val);
} else
throw new System.ArgumentException(object is not a dictionary);
}
 
public static IListobject make_list(object val) {
if (val as IListobject != null) {
return ((IListobject)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
 
 ___
 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


Re: [IronPython] Writing cross-language libraries that appear native

2011-04-04 Thread Doug Blank
On Mon, Apr 4, 2011 at 12:54 PM, Jimmy Schementi jscheme...@gmail.com wrote:
 Tomas means you can write this:

 public static string ExpectsString(string val) {
        return val;
 }


 And call it from Ruby with a Ruby string:

 expects_string Foo

Yes, indeed, that works fine. Thanks! So, the DLR languages all behave
properly with all types, even with nullable and default values ---if
you name your classes correctly. Another point I discovered was that I
had to name my outer class with upper case letters, or else IronRuby
couldn't access it.

Any other gotchas or time savers for non-DLR languages? (I wish the
DLR group could help the F# group... they don't even have an eval,
except for running the entire fsi.exe in a subprocess... wouldn't that
be nice if they used a DLR environment...)

-Doug

 ~Jimmy


 On Apr 4, 2011, at 12:21 PM, Doug Blank doug.bl...@gmail.com wrote:

 On Mon, Apr 4, 2011 at 11:52 AM, Tomas Matousek
 tomas.matou...@microsoft.com wrote:
 Re: 1.

 MutableString is convertible to String, so why would you need an object 
 parameter?

 Do you mean that one could write:

    public static string expects_string(MutableString val) {
        return (val as String);
    }

 I wrote:

    public static string expects_string(object val) {
        return val.ToString();
    }

 because that would work for all languages, and you could pass in an
 IronPython or F# string it it would work just as well. Or did you mean
 something else?

 -Doug

 Tomas

 -Original Message-
 From: users-boun...@lists.ironpython.com 
 [mailto:users-boun...@lists.ironpython.com] On Behalf Of Doug Blank
 Sent: Monday, April 04, 2011 8:25 AM
 To: Discussion of IronPython
 Subject: [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 IDictionaryobject,object make_dict(object val) {
        if (val as IDictionaryobject,object != null) {
            return ((IDictionaryobject,object)val);
        } else
            throw new System.ArgumentException(object is not a dictionary);
    }

    public static IListobject make_list(object val) {
        if (val as IListobject != null) {
            return ((IListobject)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

 ___
 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

___
Users mailing list
Users@lists.ironpython.com
http://lists.ironpython.com/listinfo.cgi/users-ironpython.com


Re: [IronPython] Writing cross-language libraries that appear native

2011-04-04 Thread Jimmy Schementi
For #3, you can avoid using an object argument and casting by typing the 
argument as the the non-generic IList and IDictionary.

I think you're correct with #2 as F# doesn't support NullableT syntactically, 
but it doesn't mean F# can't consume code using Nullable.

~Jimmy


On Apr 4, 2011, at 11:24 AM, Doug Blank doug.bl...@gmail.com wrote:

 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 IDictionaryobject,object make_dict(object val) {
if (val as IDictionaryobject,object != null) {
return ((IDictionaryobject,object)val);
} else
throw new System.ArgumentException(object is not a dictionary);
}
 
public static IListobject make_list(object val) {
if (val as IListobject != null) {
return ((IListobject)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