Page 1 of 1

Extension methods

PostPosted: Sun Apr 06, 2008 9:03 pm
by Charles
This feature is available in development.

You can now add methods to existing types, even ones from DLLs that you don't have the source for. This feature is similar to Smalltalk and Objective-C categories, and C# and VB's extension methods. Unlike C# and VB, you can use this feature even in .NET 2.0.

Here is an example taken from CobraLang.cobra which now enhances lists to have a "swap" convenience method:
extend System.Collections.IList

def swap(i as int, j as int)
temp = this[i]
this[i] = this[j]
this[j] = temp

So now you can say "someList.swap(i, j)". You can also extend classes and structs.

In addition to "enhancing" library classes, another use would be to organize your code. For example, you could add UI oriented methods to domain objects, but put them in extensions in a separate file. Then if you implement another form of UI (say WUI vs. GUI), you can easily exclude the old UI methods. I used that approach quite a bit when I was an Objective-C developer.

Note that the compiler will only "see" extension methods that are in your current namespace or brought in via "use" directives (as in "use Some.Name.Space").

The test cases for the extensions are found in <Workspace>/Tests/420-extensions

As with ordinary methods and classes, you can have "test" sections and contracts.

There are some limitations that will be addressed in the future:
-- Cannot effectively extend primitive types such as "int" and "bool".
-- Cannot extend generic types.
-- Cannot overload against a method in the extended type (but you can overload within the extension you are writing).
-- Cannot read extension methods found in .NET 3.5 standard libraries.

I would appreciate it if some of you would take this feature for a test drive and give feedback. Thanks.

Re: Extension methods

PostPosted: Mon Apr 07, 2008 10:26 am
by khjklujn
Linux, Mono 1.2.6, Cobra svn-post-0.7.4 rev 1450

Don't remember if I've already said this, but before moving on to my typically dry report of what doesn't seem to be working, I'd like to say that overall I'm quite pleased with what I'm finding in Cobra. I've been working on a non-trivial (200+ classes) exercise, and the ease with which I've been able to perform refactorings has just been astounding. There have been a couple of wholesale reorganizations of the codebase that would have taken a week in Python (and wouldn't have even been considered as an option in C++) that have taken less than an hour to accomplish using Cobra.

Anyway...

First difficulty: the comp script complained about the 'extend' in CobraLang.cobra. I built the compiler from the command line using:

cobra -compile -color -debug -timeit -files:files-to-compile.text

Next: is the following code supposed to work?
class Bob
def init
pass

extend Bob
var _i as int

def getI as int
return _i

def setI(i as int)
_i = i

test
a = Bob()
b = Bob()

a.setI(1)
assert a.getI == 1

b.setI(2)
assert b.getI == 2

assert a.getI == 1

The final assert fails. I would expect _i to be treated as an instance variable, but its behavior is static.

Also, the error messages associated with using properties or init in a extension are perhaps a little ambiguous.

Re: Extension methods

PostPosted: Mon Apr 07, 2008 10:46 am
by Charles
I'm glad that you're doing well with Cobra. It's refreshing to hear because bug reports and feature gaps are the most common things people take the time to report. :-)

Regarding your first problem, I updated the <Workspace>/Source/Snapshot/* files 9 hours ago so that should be "extend" aware. I ran the whole test suite before and after the snapshot. Do you recall if you were updated and if you had this problem before or after the snapshot? I've tested a fresh workspace and it's working for me... So let me know if you're still having problems.

Regarding extensions, only methods are supported. I'll improve the error checking.

There is also a feature in C# called partial classes which Cobra will eventually have. For a partial class, you must have the entire source to the class, but then you add anything you want (vars, properties, methods, etc.).

Re: Extension methods

PostPosted: Mon Apr 07, 2008 2:21 pm
by khjklujn
I think what happened with the initial build failure was that the version of cobra in my Snapshot didn't support extend. I bootstrapped my way around the problem by building cobra by itself first, but I have gone ahead and reinstalled from a fresh checkout to be on the safe side--didn't encounter any problems with the completely new tree from svn.

Re: Extension methods

PostPosted: Mon Apr 07, 2008 4:45 pm
by Charles
I wasn't using "extend" in the compiler source code itself so Snapshot didn't need it.

Maybe what you're saying is that you're using Snapshot/ as the latest Cobra. Actually, I only produce a new Snapshot once in awhile and not normally after a major feature since there will usually be some kinks to work out and that can be distracting while working on the compiler itself.

So by "latest out of source" I mean:
Code: Select all
cd CobraWorkspace
svn up
cd Source
comp
cobra hello
cobra -bsl

The "cobra hello" is just a quickie test.

-bsl is for "build standard library". It makes the Cobra.Lang.dll for when you say "cobra -ert:no ...".

And if you're not doing development, you might prefer "comp -turbo" which makes a smaller, faster .exe.

HTH