How to add operator extension as a part of context of the specific class without subclassing? - operator-overloading

I'm trying to utilize operators for Wicket, which is painfully verbose.
My most wanted feature is to use an unary "+" to add() a component.
But it will be needed to work inside context of every MarkupContainer descendants.
Use should be like this:
class SomePage() : WebPage() {
init {
// SomePage{} context
+Label("someLabel","Some label")
// instead of this.add(Label("someLabel","Some label"))
+object : StatelessForm<Unit>("someForm") {
init {
// StatelessForm{} context
+Label("fieldLabel","Field label")
+RequiredTextField("someField")
}
}
}
}
Is it possible to implement this now without subclassing everything? Some imaginary syntax of what i want:
extend org.apache.wicket.MarkupContainer {
operator fun<T: Component> T.unaryPlus():T {
// add() is called as a method of a MarkupContainer instance
add(this) // this#MarkupContainer.add(this#unaryPlus)
return this
}
}
https://kotlinlang.org/docs/reference/extensions.html
https://kotlinlang.org/docs/reference/operator-overloading.html

Using the unaryPlus operator (+Component) is harder in this context since, as the unary implies, it's a single operand operator (single input). There's a sort of hacky solution though:
class ExtOf<out T : MarkupContainer>(val self: T) {
companion object {
private val lastConfiguredContainer = ThreadLocal<ExtOf<MarkupContainer>?>()
fun <T : MarkupContainer> configure(container: T, configurer: ExtOf<T>.() -> Any?): T {
val currentLast = lastConfiguredContainer.get()
try {
val newCurrent = ExtOf(container)
lastConfiguredContainer.set(newCurrent)
newCurrent.configurer()
} finally {
lastConfiguredContainer.set(currentLast)
}
return container
}
}
operator fun <T2 : Component> T2.unaryPlus(): T2 {
val container = lastConfiguredContainer.get()
container!!.self.add(this) //TODO throw a nice exception explaining how ot use the `configure`
return this
}
}
fun <T : MarkupContainer> T.configure(configurer: ExtOf<T>.() -> Any?) = ExtOf.configure(this, configurer)
The above maintains information about last configured MarkupContainer in a ThreadLocal private variable that is used to supply the receiver of add method.
You can then write:
class SomePage() : WebPage() {
init {
configure {
+Label("someLabel", "Some label")
+StatelessForm<Unit>("someForm").configure {
// StatelessForm{} context
+Label("fieldLabel", "Field label")
+RequiredTextField<Long>("someField")
}
}
}
}
As I mentioned above the solution while works is far from being pretty. It can be confusing (as often overloaded operators are) so I'd advice using the regular add like so:
class SomePage() : WebPage() {
init {
add(
Label("someLabel", "Some label"),
StatelessForm<Unit>("someForm").apply {
// StatelessForm{} context
add(
Label("fieldLabel", "Field label"),
RequiredTextField<Long>("someField")
)
}
}
}
}
I guess ideally there would be a library similar to anko but for wicket.

I believe it's not possible
The problem is that unaryPlus operator fun cannot have any params. You want to use unaryPlus inside MarkupContainer class, but you also want to add component (other class, other reference with technicly could be a param)
The only way I see it could work would be with subclassing (Component subclass MarkupContainer) and unaryPlus perator extension to MarkupContainer
class Label(name: String, b: String) : Component() {}
open class MarkupContainer() {
fun add(component: Component) {
println("added" + this)
}
}
open class Component() : MarkupContainer() {}
open class StatelessForm<T>(name: String) : Component()
operator fun Component.unaryPlus() {
add(this)
}
class SomePage() : Component() {
init {
add(Label("someLabel", "Some label"))
+Label("someLabel", "Some label")
+object : StatelessForm<Unit>("someForm") {
init {
// StatelessForm{} context
+Label("fieldLabel", "Field label")
}
}
}
}

Related

Type constraints on contained generic type parameter

I expected the following code to print "extension" in both cases. But the type constraint on the extension does not take effect on the contained generic type. I see the same behavior when constraining on protocols too.
class Generic1<T1> {
func doSomething() {
print("base")
}
}
extension Generic1 where T1 == String {
func doSomething() {
print("extension")
}
}
class Generic2<T2> {
private let generic1 = Generic1<T2>()
func doSomething() {
generic1.doSomething()
}
}
Generic1<String>().doSomething() // prints extension
Generic2<String>().doSomething() // prints base
The only workaround I currently have is to constrain the outer generic as well like so:
extension Generic2 where T2 == String {
func doSomething() {
generic1.doSomething()
}
}
Why does this happen? Are there better solutions?
Edit: Just for completeness, the workaround that suited my case was the following:
class Generic1<T1> {
func doSomething() {
print("base")
}
}
class StringGeneric1: Generic1<String> {
override func doSomething() {
print("extension")
}
}
class Generic2<T2> {
private let generic1: Generic1<T2>
init (_ generic1: Generic1<T2>) {
self.generic1 = generic1
}
func doSomething() {
generic1.doSomething()
}
}
Generic1<String>().doSomething() // prints "base"
Generic2<String>(StringGeneric1()).doSomething() // prints "extension"
The problem is that methods defined in extensions are statically dispatched. So when you have:
class Generic2<T2> {
private let generic1 = Generic1<T2>()
func doSomething() {
generic1.doSomething()
}
}
The compiler cannot know here whether T2 is going to be a String or not, so it generates a call to the method in the base class. When you explicitly specify that T2 is String, then with that information, the compiler can generate a call to the extension's method here. Otherwise, though, the type of T2 isn't known until runtime, so you can't reach the extension method via static dispatch.
This may be solved when conditional conformances are added with Swift 4.2

How to test a swift generic type another one?

I have some generic type class but no instance of object to test. What I would like to do is to alter the behavior of the function according to the runtime type.
class MyGenericUtility<SomeGenericClass> {
func myFunction() {
// so far I have tested "is", "==" and "==="
if SomeGenericClass is SomeRealClass {
println("some special stuff there")
}
println("some generic stuff as the name tells")
}
}
You can compare the class type, using SomeGenericClass.self == SomeRealClass.self as,
class MyGenericUtility<SomeGenericClass> {
func myFunction() {
if SomeGenericClass.self == SomeRealClass.self {
print("SomeRealClass stuffs")
} else if SomeGenericClass.self == String.self {
print("String stuffs")
}
}
}
let someRealUtility = MyGenericUtility<SomeRealClass>()
someRealUtility.myFunction()
let stringUtility = MyGenericUtility<String>()
stringUtility.myFunction()
Rather than testing at runtime, you should generally handle this at compile time with constrained extensions (this assumes Swift 2). Doing it this way avoids any need to do unsafe as! casting when you need to access type-specific parts of the instance.
class MyGenericUtility<SomeGenericClass> {
}
// Special handling for `SomeRealClass`
extension MyGenericUtility where SomeGenericClass: SomeRealClass {
func myFunction() {
print("SomeRealClass stuffs")
}
}
// Default handling for any unspecified class
extension MyGenericUtility {
func myFunction() {
print("Other stuffs")
}
}
let someRealUtility = MyGenericUtility<SomeRealClass>()
someRealUtility.myFunction()
let stringUtility = MyGenericUtility<String>()
stringUtility.myFunction()
Note that this is based on inheritance, not equality, so any subclass of SomeRealClass would get the SomeRealClass behavior.
You can't use the generic type directly, you need to use a property of that type when comparing with "is".
class MyGenericUtility<T> {
var a: T
func myFunction() {
if a is Int {
println("some special stuff there")
}
println("some generic stuff as the name tells")
}
init(value: T) {
a = value
}
}
let test = MyGenericUtility(value: 5)
test.myFunction()
// Output: some special stuff there
// some generic stuff as the name tells
let test2 = MyGenericUtility(value: "foo")
test2.myFunction()
// Output: some generic stuff as the name tells

Swift: how to support "template method" design pattern (since Swift doesn't have protected)?

Traditionally in the "template method" pattern, a base class implements some algorithms and defers to derived classes for specific behavior. This works well in languages like C++/C#/Java because you can use "protected" on those methods to hide them from the callers but keep it visible for derived classes. For example, in the GoF book, you have something like:
class Application
{
void CreateDocument() { ..., this->DoCreateDocument() }
protected void DoCreateDocument() { } // override for custom behavior
}
This keeps the public interface for Application clean. In Swift, because you cannot use protected, the public interface is not clean. I do not want users of Application to see DoCreateDocument.
So I'm trying another method, which instead of using methods for DoCreateDocument, I'm trying to define a closure and use "functor" patterns.
class Application
{
typealias ActionFunc = () -> ()
private let doCreateDocument : ActionFunc
init(a : ActionFunc) { self.doCreateDocument = a }
func CreateDocument() {
self.doCreateDocument()
}
}
So this class looks good - the public interface is clean. However, it's impossible to actually use this.
The obvious approach is using a derived class:
class DoApplication : Application
{
init() {
super.init(
a : {
// This would work, but you cannot use self here!
self. // anything with self. is an error
})
}
}
The problem with this approach is that in the initializer, you cannot pass a closure to super.init that uses self. I get the error self used before super.init.
That basically makes it useless because you cannot access any state variables.
However, if you don't initialize doCreateDocument in the init, you need to expose a setter of some sorts - again, the lack of protected means that the setter is on the public API. Yuck.
So is there any way to cleanly implement the template pattern that keeps the interface clean?
I know this is an ugly hack, but it works.
class DoApplication: Application {
init() {
var doCreateDocument: (Application.ActionFunc)!
super.init(a: { doCreateDocument() })
doCreateDocument = { [unowned self] in
self.foo()
}
}
func foo() {
println("DoApplication.foo");
}
}
Alternatively, you can pass self to doCreateDocument:
class Application {
typealias ActionFunc = (Application) -> ()
private let doCreateDocument : ActionFunc
init(a : ActionFunc) { self.doCreateDocument = a }
func CreateDocument() {
self.doCreateDocument(self)
}
}
class DoApplication : Application {
init() {
super.init(a : { _self in
let _self = _self as! DoApplication
_self.foo()
})
}
func foo() {
println("DoApplication.foo");
}
}

How do I make a referential type comparison in Swift using 'is'?

I can't figure out how to make a type comparison in Swift using the is operator, if the right side is a reference and not a hard-coded type.
For example,
class GmBuilding { }
class GmOffice: GmBuilding { }
class GmFactory: GmBuilding { }
class GmStreet {
var buildings: [GmBuilding] = []
func findAllBuildingsOfType(buildingType: GmBuilding.Type) -> [GmBuilding] {
var result: [GmBuilding] = []
for building in self.buildings {
if building is buildingType { // complains that buildingType is not a type
result.append(building)
}
}
return result
}
}
let myStreet = GmStreet()
var buildingList: [GmBuilding] = myStreet.findAllBuildingsOfType(GmOffice.self)
It complains that 'buildingType is not a type'. How can it be made to work?
A generic method may do what you want:
func findAllBuildingsOfType<T: GmBuilding>(buildingType: T.Type) -> [GmBuilding] {
// you can use `filter` instead of var/for/append
return buildings.filter { $0 is T }
}
This will work so long as you really do only want to determine the type at compile time:
let myStreet = GmStreet()
let buildingList = myStreet.findAllBuildingsOfType(GmOffice.self)
// T is set at compile time to GmOffice --------^
However, often when this question comes up, the follow-up question is, how do I store GmOffice.self in a variable and then have the type be determined at runtime? And that will not work with this technique. But if statically fixed types at compile time are enough for you, this should do it.
If AirSpeed Velocity's answer doesn't work for you, you can also accomplish this by bridging to Objective-C.
Make GmBuilding inherit from NSObject:
class GmBuilding: NSObject { }
And use isKindOfClass(_:) to check the type:
for building in self.buildings {
if building.isKindOfClass(buildingType) {
result.append(building)
}
}
Not as Swifty, but it works.
I'm sure there must be a better way than this, but it doesn't require inheritance from NSObject and it works at runtime - according to my playground
class GmBuilding { }
class GmOffice: GmBuilding { }
class GmFactory: GmBuilding { }
func thingIs(thing: GmBuilding, #sameTypeAs: GmBuilding) -> Bool
{
return thing.dynamicType === sameTypeAs.dynamicType
}
var foo: GmOffice = GmOffice()
thingIs(foo, sameTypeAs: GmOffice()) // true
thingIs(foo, sameTypeAs: GmFactory()) // false
The main reason I instantiate an object (you can use a singleton instead) is because I can't figure out how to declare a parameter to be a metatype.
It also doesn't work for
thingIs(foo, sameTypeAs: GmBuilding()) // false :=(
As a final resort, using Obj-C reflect function:
import ObjectiveC
func isinstance(instance: AnyObject, cls: AnyClass) -> Bool {
var c: AnyClass? = instance.dynamicType
do {
if c === cls {
return true
}
c = class_getSuperclass(c)
} while c != nil
return false
}
class GmBuilding { }
class GmOffice: GmBuilding { }
class GmFactory: GmBuilding { }
isinstance(GmOffice(), GmOffice.self) // -> true
isinstance(GmOffice(), GmFactory.self) // -> false
isinstance(GmOffice(), GmBuilding.self) // -> true

Can I simulate traits/mixins in Swift?

Does Swift have a way of mixing in traits, a la Scala? The section of the Swift book on using extensions to add protocols to existing classes comes tantalizingly close. However, since protocols can't contain an implementation, this can't be used to mix code into a class. Is there another way?
As of Swift 2.0, yes!
Providing Default Implementations
You can use protocol extensions to provide a default implementation
to any method or property requirement of that protocol. If a
conforming type provides its own implementation of a required method
or property, that implementation will be used instead of the one
provided by the extension.
One way to simulate mixing is use generic function to provide implementation
For example with these protocols
protocol Named {
func GetName() -> String
}
protocol NamedExtension {
func GetLowercaseName() -> String
func GetUppercaseName() -> String
}
I want some class to implement GetName() and use mixing so they also get GetLowercaseName() and GetUppercaseName() without implement them
This is the implementation of NamedExtension as in free function
func GetLowercaseNameImpl<T:Named>(obj:T) -> String {
return obj.GetName().lowercaseString
}
func GetUppercaseNameImpl<T:Named>(obj:T) -> String {
return obj.GetName().uppercaseString
}
and extensions on Int
extension Int : Named {
func GetName() -> String {
return "Int"
}
}
extension Int : NamedExtension {
// use provided implementation
func GetLowercaseName() -> String {
return GetLowercaseNameImpl(self)
}
func GetUppercaseName() -> String {
return GetUppercaseNameImpl(self)
}
}
and I can use
1.GetName() // result Int
1.GetUppercaseName() // result "INT"
1.GetLowercaseName() // result "int"
I don't know Scala, but from what you're telling me it is possible to simultaneously create a protocol and an extension that extends a type to add "pseudo-trait" behavior.
For example:
protocol IsGreaterThan
{
func isGreaterThan(other:Int) -> Bool
func isNotGreaterThan(other:Int) -> Bool
}
extension Int : IsGreaterThan
{
func isGreaterThan(other:Int) -> Bool
{
return self > other
}
func isNotGreaterThan(other:Int) -> Bool
{
return !isGreaterThan(other)
}
}
The real hamstring is how generics are somewhat limited for now. I think they will improve a lot in the coming revisions of Swift.
Similar to Bryan Chen's answer:
import Foundation
protocol Named {
var name : String { get }
}
protocol NamedExtension : Named { // NB extends Named
var lowercaseName : String { get }
var uppercaseName : String { get }
}
struct NamedExtensionDefault { // Put defaults inside a struct to keep name spaces seperate
static func lowercaseName(named : NamedExtension) -> String {
return (named.name as NSString).lowercaseString
}
static func uppercaseName(named : NamedExtension) -> String {
return (named.name as NSString).uppercaseString
}
}
extension Int : NamedExtension {
var name : String {
return "Int"
}
// Use default implementation
var lowercaseName : String {
return NamedExtensionDefault.lowercaseName(self)
}
var uppercaseName : String {
return NamedExtensionDefault.uppercaseName(self)
}
}
1.name // result Int
1.uppercaseName // result "INT"
1.lowercaseName // result "int"
The main difference from Bryan's answer is that I didn't use generics because I made NamedExtension extends Named, so that the default implementations can access name.
Here's my (not yet widely tested) way of doing what I think are Scala traits in Swift 2.1.1, Playgrounds-ready, two versions:
Less flexible:
protocol BigBadProtocol {
func madFunc() -> String;
// func otherFunc();
// Maybe a couple more functions here.
}
protocol BlueMadFuncUser: BigBadProtocol {}
extension BlueMadFuncUser {
func madFunc() -> String {
return "Blue"
}
}
protocol RedMadFuncUser: BigBadProtocol {}
extension RedMadFuncUser {
func madFunc() -> String {
return "Red"
}
}
class ClearClass: BigBadProtocol {
func madFunc() -> String {
return "Clear"
}
}
class BlueClass: BlueMadFuncUser {}
class RedClass: RedMadFuncUser {}
More flexible:
protocol BigBadProtocol {
func madFunc() -> String;
// func otherFunc();
// Maybe a couple more functions here.
}
protocol BlueMadFuncUser {}
extension BigBadProtocol where Self: BlueMadFuncUser {
func madFunc() -> String {
return "Blue"
}
}
protocol RedMadFuncUser {}
extension BigBadProtocol where Self: RedMadFuncUser {
func madFunc() -> String {
return "Red"
}
}
class ClearClass: BigBadProtocol {
func madFunc() -> String {
return "Clear"
}
}
class BlueClass: BigBadProtocol, BlueMadFuncUser {}
class RedClass: BigBadProtocol, RedMadFuncUser {}
Sanity check:
var classes: [BigBadProtocol] = [ClearClass(), BlueClass(), RedClass()]
// Prints "Clear, Blue, Red\n"
print((classes.map { $0.madFunc() }).joinWithSeparator(", "))
// Print another way for Playgrounds, which appears to bug out on the lines above
var s = ""
for klass in classes {
s += klass.madFunc() + " "
}
print(s)
BlueMadFuncUser and RedMadFuncUser are two versions of a trait. My terminology might be off, but then you can independently create a second trait like that and mix and match in your classes as you please.
Would be much more challenging or boiler-plate-y to reuse logic like that with an inheritance-based approach.
I ended up wanting this pattern after finding it very useful in Hack for PHP, where from what I can tell traits are very similar to Scala's: https://docs.hhvm.com/hack/other-features/trait-and-interface-requirements)