A well-shaven Jim Miller gave a talk at Brown today on introducing dynamic languages into the CLR. I went because (a) they were giving away a free camera (which I didn’t get), and (b) the talk seemed actually interesting. Much more interesting than my last Microsoft talk, which was some interminably boring thing about webservices.
The talk was essentially an overview of the CLR, of the form, “Do you think this is cool? Work for us!” The focus was on IronPython‘s genesis and growth. Those kids love their Python.
I tried to ask him the following question: “You’ve talked a lot about getting basic interoperability between programs written in different languages — object-oriented, procedural, functional — but you’ve said nothing about heterogeneity of styles. How does the CLR cope with that?” I asked because he said that an interface of an object included a way to create it, modify its insides, and so on — not necessarily how I define my datatypes. But then he turned it around, and asked me for an example — the best I could come up with was Erlang’s processes and single-assignment (a red herring) or Haskell’s purity (an academic joke).
Not what I was looking for. The mismatch is more serious, but I couldn’t adequately get at it on the spot. I asked him a follow-up, about GUI programming style. Would a GUI in IronPython need to be written in some bogus Windows Forms style, all callbacks? I didn’t want to compare the callback-GUI system to Flapjax‘s, since that’d be a bit wankerish of me. I didn’t handle it well at all.
So: what did I mean to ask? On the one hand, my problem is this: the mismatch between the CLR and some paradigms is pretty clear. If I wanted to work with Windows Forms in, say, F#, I would have to write in an all-ref style. In other words, the CLR lets me program C# in the language of my choice.
On the other hand, how else would I write a GUI? Flapjax is the most viable FRP implementation I’ve seen, but it’s still extremely nascent. When interfacing with the user, what is better than direct, mutative style? Python uses callback-based Tkinter and WxPython; DrScheme uses the MrEd callback-based framework. So what gives?
I may be more comfortable in the FP world, and happier programming Scheme in Scheme, rather than C# in Scheme, or even worse, Scheme in C# — but it’s becoming increasingly clear to me that my preference may be more related to my own experience than actual advantages.
Your question sounded vague to me – as you said, Miller opened by saying something along the lines of they prioritized features based on general style: object oriented (a must), procedural (fuzzy water), functional (what is necessary). It is unclear what you meant by style; your Python example is a problem with Python, not the CLR. For Erlang, as one person that doesn’t use it to another, I think we see another view of style: does the CLR support optimizations resultant from certain mantras, eg, light weight processes with no shared memory. The answer there would be: OO (fast method look ups and static vs instance fields), procedural (mutation? jmp instructions? I have no idea what this means), and functional (1st class / HOFs with TCO I presume) styles.
After the talk, I did do the wankerish thing and asked about data binding support in the CLR. He gave the exact answer you would expect: it is unneccessary, because it can be otherwise easily encoded with little overhead, so they didn’t bother. Several MS products have constraint based or dynamic properties, so this was an explicit decision with performance honestly factored in. The same exact approach taken by Macromedia in their data binding implementation.
I agree the question was vague, and I think you’re right. The problem with Python was Python; data-binding support should be built on top, and so forth.
Taking the CLR as a high-level machine, it has TCO and typing (that is, if you give types at a call node, you don’t have to worry about run-time checking). It’s more than sufficient as a compilation target for functional and other weird languages. The question I’d now ask — a question for us, not for Jim Miller — is: why do we want that free ride? While the CLR already gives so many guarantees (and optimizations), do they also need to write the hard parts of our compilers for us? A good Erlang implementation does its own optimizations to make lightweight processes work…why can’t we, on the CLR?
The link to Flapjax is broken; it’s missing a ‘j’
I am not sure if this is what you meant, but as I read this I thought about the “Ruby way” and the “Python way” of doing things. Yes, they are both dynamic, powerful languages with meta programming options, but some things that are clearly kosher in Ruby, aren’t in Python. I thought you might be trying to get at something similar with C# and Python. There are lots of things that you would do in C# that you wouldn’t in Python, and vice versa. The map function is a good example. I wouldn’t use the equivalent of map w/ lambda in C#, but I might in Python.
This comes down to the language effecting the way you think. The Sapir-Whorf theory (not sure if this is the correct spelling) hypothesizes that the language you speak effects what ideas you are capable of expressing. Nowhere is this more evident than in programming languages. I specific example would be something like the use of “and-or” constructs as a ternary operator in Python (test and success or failure vs. test ? success : failure). Because “and” and “or” return the values of their sub-expressions instead of returning a boolean value their might be a mismatch between Python and C#. That’s the best example I can come up with off the top of my head. It does seem as though there is something out there bothering me, but I can’t put my finger on it.
Differences in low-level expressivity between languages — e.g. block expressions in Ruby don’t exist in Python, hygenic macros in Scheme — are important, you’re right. I’m not sure how big of a difference there is between Python and C#. In any case, I wrote about discovering (about myself) after Jim Miller’s talk that these features are valuable to me, but are in general relegated to corner cases. I realized that I was underestimating the homogeneity of big APIs, particularly GUI libraries. And if this is the case, we’ve been ‘forced’ to use them for a long time — since before C#, before even Java.
While you might miss and/or or not use apply/map/fold/unfold in C#, that may have more to do with idiom than Sapir-Whorf expressibility. There’s a simple translation in either direction from and/or/if chains to ?: chains. (In fact, in your example the two have the same number of tokens!) C#’s delegate system supports map fully and cleanly, e.g. this generalized implementation. Granted, there’s some ugliness, but it’s all local management. Outside of the function, you just have map.
I felt as you seem to: there was “something out there bothering me”, but I wasn’t sure what. After a few days of introspection, what bothered me was that I couldn’t come up with a real example of an important style difference. It was discomforting for me to discover that my opinions. based on ‘principles’ and ‘theory’, are really just that — my opinions.