#2463 Extension Methods

go4 Sun 13 Sep 2015

The Swift extensions method is impressive.

extension Double {
    var km: Double { return self * 1_000.0 }
    var m : Double { return self }
    var cm: Double { return self / 100.0 }
    var mm: Double { return self / 1_000.0 }
    var ft: Double { return self / 3.28084 }
}
let oneInch = 25.4.mm
print("One inch is \(oneInch) meters")

It's a pretty literal.

Another side, extensions method can break the circular dependency. For example, Str.toRegex refer to Regex. If extensions method:

class Regex {
  @Extension
  static Regex Str.toRegex(Str self) {
     return fromStr(self)
  }
}

Now, the Str don't know Regex class.

Another case using extension method:

`http://xxx.com`.getStr.println   //do http request and print

SlimerDude Mon 14 Sep 2015

Extension methods have briefly been talked about in what's the equivalent of extension method in fantom and, as Go4 pointed out, allows you to write some very expressive code.

Expressions are really just syntactic sugar for chaining methods together. For instance, instead of writing:

class MyRegex {
  ...

  static MyRegex toMyRegex(Str str) {
     return MyRegex(str)
  }
}

str     := "Hello!"
myRegex := MyRegex.toMyRegex(str)

You could write:

str     := "Hello!"
myRegex := str.toMyRegex()

Syntactically, as Go4 pointed out, all that would be needed is a new @Extension facet:

class MyRegex {
  ...
  @Extension
  static MyRegex toMyRegex(Str str) {
     return MyRegex(str)
  }
}

Similar to other core system facets, the compiler would enforce a single parameter (in our case Str) which determines what Type the extension applies to.

I imagine the biggest piece of compiler work would be scanning all the imported classes from the using statements to create a list of usable extension methods.

A quick win I mentioned in the other post would be to add a simple map() method to Obj:

Obj? map(|Obj item->Obj?| c) { 
  return c.call(this) 
}

This would let you chain expressions together using it-block statements:

str     := "Hello!"
myRegex := str.map { MyRegex.toMyRegex(it) }

Simple... but ugly. And without generics, its usefulness is hindered because it returns Obj which would often need to be cast.

So, back to extensions... I'm not sure where or when I would use them personally, but I do think they would be a good addition to Fantom's feature list.

go4 Tue 15 Sep 2015

IMO, nothing with chaining style. It's OO style and less noise.

StringUtil.replaceIgnoreCase(str) vs str.replaceIgnoreCase

A bit like Java's static imports but more expressive. As I know, Object-C heavy build on it.

Login or Signup to reply.