Delegates: Difference between revisions

From Rosetta Code
Content added Content deleted
No edit summary
(Added FreeBASIC)
 
(16 intermediate revisions by 5 users not shown)
Line 16: Line 16:
=={{header|Ada}}==
=={{header|Ada}}==
All that is needed in order to implement this is a common base type. The delegator holds a pointer to an "untyped" object from the base class. Querying if the target implements the delegate interface is done using run-time type identification.
All that is needed in order to implement this is a common base type. The delegator holds a pointer to an "untyped" object from the base class. Querying if the target implements the delegate interface is done using run-time type identification.
<lang ada>with Ada.Text_IO; use Ada.Text_IO;
<syntaxhighlight lang="ada">with Ada.Text_IO; use Ada.Text_IO;


procedure Delegation is
procedure Delegation is
Line 63: Line 63:
A.Delegate := Has_Thing'Access; -- Set a thing
A.Delegate := Has_Thing'Access; -- Set a thing
Put_Line (A.Operation);
Put_Line (A.Operation);
end Delegation;</lang>
end Delegation;</syntaxhighlight>
Sample output:
Sample output:
<pre>
<pre>
Line 72: Line 72:


=={{header|Aikido}}==
=={{header|Aikido}}==
<lang aikido>
<syntaxhighlight lang="aikido">
class Delegator {
class Delegator {
public generic delegate = none
public generic delegate = none
Line 97: Line 97:
println (d1.operation())
println (d1.operation())


</syntaxhighlight>
</lang>


=={{header|Aime}}==
=={{header|Aime}}==
<lang aime>text
<syntaxhighlight lang="aime">text
thing(void)
thing(void)
{
{
Line 141: Line 141:


return 0;
return 0;
}</lang>
}</syntaxhighlight>


=={{header|ALGOL 68}}==
=={{header|ALGOL 68}}==
As Algol 68 doesn't have classes, we supply a non-OO approximation, similar to the C version.
As Algol 68 doesn't have classes, we supply a non-OO approximation, similar to the C version.
<lang algol68># An Algol 68 approximation of delegates #
<syntaxhighlight lang="algol68"># An Algol 68 approximation of delegates #


# The delegate mode - the delegate is a STRUCT with a single field #
# The delegate mode - the delegate is a STRUCT with a single field #
Line 220: Line 220:


)
)
</syntaxhighlight>
</lang>
{{out}}<pre>
{{out}}<pre>
No delegate : default implementation
No delegate : default implementation
Line 230: Line 230:
=={{header|Atari Basic}}==
=={{header|Atari Basic}}==


The code does not fully implement all requirements from above.
If you find which requirements have not been met that's great.
What is your proposal to solve that in the code?


<syntaxhighlight lang="ataribasic">
10 REM DELEGATION CODE AND EXAMPLE . ATARI BASIC 2020 A.KRE<GERMAN SHARP S>
10 REM DELEGATION CODE AND EXAMPLE . ATARI BASIC 2020 A. KRESS andreas.kress@hood-group.com
14 REM
14 REM
15 GOTO 100:REM MAINLOOP
15 GOTO 100:REM MAINLOOP
Line 243: Line 247:
56 RETURN
56 RETURN
60 REM CALL DELEGATE
60 REM CALL DELEGATE
65 GOSUB 80
65 GOSUB DELEGATOR
66 RETURN
66 RETURN
79 REM
79 REM
Line 253: Line 257:
100 REM MAINLOOP - DELEGATION EXAMPLE
100 REM MAINLOOP - DELEGATION EXAMPLE
101 REM
101 REM
110 DELEGATEEXIST=1:REM NO DELEGATE
110 DELEGATE=0:REM NO DELEGATE
120 GOSUB 20:REM INIT DELEGATOR
120 GOSUB 20:REM INIT DELEGATOR
130 DELEGATE=80:REM DELEGATE IS
130 DELEGATE=80:REM DELEGATE IS
140 GOSUB 20:REM INIT DELEGATOR
140 GOSUB 20:REM INIT DELEGATOR
</syntaxhighlight>
200 END
{{out}}<pre>
RUN
DEFAULT IMPLEMENTATION - DONE BY DELEGATOR
DELEGATE IMPLEMENTATION - DONE BY DELEGATE


Ready
</pre>


=={{header|C}}==
=={{header|C}}==
As best you can do, without support for classes.
As best you can do, without support for classes.
<lang c>#include <stdio.h>
<syntaxhighlight lang="c">#include <stdio.h>
#include <stdlib.h>
#include <stdlib.h>
#include <string.h>
#include <string.h>
Line 347: Line 357:
Delegator_Operation( theDelegator, 3, del2));
Delegator_Operation( theDelegator, 3, del2));
return 0;
return 0;
}</lang>
}</syntaxhighlight>


=={{header|C sharp}}==
=={{header|C sharp|C#}}==
<lang csharp>using System;
<syntaxhighlight lang="csharp">using System;


interface IOperable
interface IOperable
Line 388: Line 398:
}
}
}
}
}</lang>
}</syntaxhighlight>
Output:
Output:
<pre>Default implementation.
<pre>Default implementation.
Line 397: Line 407:
Delegates in the C# or D style are available in C++ through std::tr1::function class template. These delegates don't exactly match this problem statement though, as they only support a single method call (which is operator()), and so don't support querying for support of particular methods.
Delegates in the C# or D style are available in C++ through std::tr1::function class template. These delegates don't exactly match this problem statement though, as they only support a single method call (which is operator()), and so don't support querying for support of particular methods.


<syntaxhighlight lang="cpp">
<lang Cpp>
#include <tr1/memory>
#include <tr1/memory>
#include <string>
#include <string>
Line 477: Line 487:
*/
*/
}
}
</syntaxhighlight>
</lang>


=={{header|Clojure}}==
=={{header|Clojure}}==
<lang clojure>(defprotocol Thing
<syntaxhighlight lang="clojure">(defprotocol Thing
(thing [_]))
(thing [_]))


Line 492: Line 502:
(defrecord Delegate []
(defrecord Delegate []
Thing
Thing
(thing [_] "delegate implementation"))</lang>
(thing [_] "delegate implementation"))</syntaxhighlight>


{{out}}
{{out}}
Line 511: Line 521:
=={{header|CoffeeScript}}==
=={{header|CoffeeScript}}==
{{trans|Python}}
{{trans|Python}}
<lang coffeescript>
<syntaxhighlight lang="coffeescript">
class Delegator
class Delegator
operation: ->
operation: ->
Line 536: Line 546:
testDelegator()
testDelegator()
</syntaxhighlight>
</lang>
output
output
<lang>
<syntaxhighlight lang="text">
> coffee foo.coffee
> coffee foo.coffee
default implementation
default implementation
default implementation
default implementation
Delegate Implementation
Delegate Implementation
</syntaxhighlight>
</lang>


=={{header|Common Lisp}}==
=={{header|Common Lisp}}==
Line 550: Line 560:
In CLOS, methods exist apart from classes, and are specialized based on the types of their arguments. This example defines two classes (delegator and delegate), and a thing generic method which is specialized in three ways: (1) for 'any' argument, providing a default method; (2) for delegators, where thing is recursively applied to the delegator's delegate (if there is one); and (3) for delegates.
In CLOS, methods exist apart from classes, and are specialized based on the types of their arguments. This example defines two classes (delegator and delegate), and a thing generic method which is specialized in three ways: (1) for 'any' argument, providing a default method; (2) for delegators, where thing is recursively applied to the delegator's delegate (if there is one); and (3) for delegates.


<lang lisp>(defgeneric thing (object)
<syntaxhighlight lang="lisp">(defgeneric thing (object)
(:documentation "Thing the object."))
(:documentation "Thing the object."))


Line 578: Line 588:
(assert (string= "no delegate" (thing d1)))
(assert (string= "no delegate" (thing d1)))
(assert (string= "default implementation" (thing d2)))
(assert (string= "default implementation" (thing d2)))
(assert (string= "delegate implementation" (thing d3))))</lang>
(assert (string= "delegate implementation" (thing d3))))</syntaxhighlight>


=={{header|D}}==
=={{header|D}}==
Line 584: Line 594:
''Delegate'' object and pass a real delegate directly to '''Delegator'''.
''Delegate'' object and pass a real delegate directly to '''Delegator'''.


<lang d>class Delegator {
<syntaxhighlight lang="d">class Delegator {
string delegate() hasDelegate;
string delegate() hasDelegate;


Line 607: Line 617:
writeln(dr.operation());
writeln(dr.operation());
writeln(dr.setDg(thing).operation());
writeln(dr.setDg(thing).operation());
}</lang>
}</syntaxhighlight>
{{out}}
{{out}}
<pre>Default implementation
<pre>Default implementation
Line 615: Line 625:
===Version using Tango===
===Version using Tango===
{{libheader|tango}}
{{libheader|tango}}
<lang d>import tango.io.Stdout;
<syntaxhighlight lang="d">import tango.io.Stdout;


class Delegator
class Delegator
Line 643: Line 653:
Stdout ( dr.setDg(thing).operation ).newline;
Stdout ( dr.setDg(thing).operation ).newline;
return 0;
return 0;
}</lang>
}</syntaxhighlight>


=={{header|Dart}}==
=={{header|Dart}}==
I didn't find a way to check for existing methods, so the version with Object doesn't work yet. The code is adapted from the Java version, but using var instead of an Interface
I didn't find a way to check for existing methods, so the version with Object doesn't work yet. The code is adapted from the Java version, but using var instead of an Interface
<lang dart>class Delegator {
<syntaxhighlight lang="dart">class Delegator {
var delegate;
var delegate;
Line 675: Line 685:
a.delegate = d;
a.delegate = d;
Expect.equals("delegate implementation",a.operation());
Expect.equals("delegate implementation",a.operation());
}</lang>
}</syntaxhighlight>


=={{header|Delphi}}==
=={{header|Delphi}}==
Translation of the Java example found at [http://en.wikipedia.org/wiki/Delegation_pattern Wikipedia].
Translation of the Java example found at [http://en.wikipedia.org/wiki/Delegation_pattern Wikipedia].
<lang Delphi>unit Printer;
<syntaxhighlight lang="delphi">unit Printer;


interface
interface
Line 728: Line 738:
end;
end;


end.</lang>
end.</syntaxhighlight>
<lang Delphi>program Delegate;
<syntaxhighlight lang="delphi">program Delegate;


{$APPTYPE CONSOLE}
{$APPTYPE CONSOLE}
Line 747: Line 757:
PrinterObj.Free;
PrinterObj.Free;
end;
end;
end.</lang>
end.</syntaxhighlight>


=={{header|E}}==
=={{header|E}}==


<lang e>def makeDelegator {
<syntaxhighlight lang="e">def makeDelegator {
/** construct without an explicit delegate */
/** construct without an explicit delegate */
to run() {
to run() {
Line 784: Line 794:
> })
> })
> delegator.operation()
> delegator.operation()
# value: "default implementation"</lang>
# value: "default implementation"</syntaxhighlight>


=={{header|Elena}}==
=={{header|Elena}}==
ELENA 5.0 :
ELENA 6.x :


Using multi methods:
Using multi methods:
<lang elena>import extensions;
<syntaxhighlight lang="elena">import extensions;
import system'routines;
import system'routines;
interface IOperable
interface IOperable
{
{
abstract operate() {}
abstract operate();
}
}
Line 829: Line 839:
var delegator := new Delegator();
var delegator := new Delegator();
new object[]{nil, new Object(), new Operable()}.forEach:(o)
new object[]{nil, new Object(), new Operable()}.forEach::(o)
{
{
delegator.Delegate := o;
delegator.Delegate := o;
Line 835: Line 845:
console.printLine(delegator.operate())
console.printLine(delegator.operate())
}
}
}</lang>
}</syntaxhighlight>
Generic solution:
Generic solution:
<lang elena>import extensions;
<syntaxhighlight lang="elena">import extensions;
import system'routines;
import system'routines;


Line 850: Line 860:
class Delegator
class Delegator
{
{
prop object Delegate;
object Delegate : prop;
constructor()
constructor()
Line 859: Line 869:
operate()
operate()
{
{
// if the object does not support "get&operable" message - returns nil
// if the object does not support "Operable" message - returns nil
var operable := Delegate.Operable \ back:nil;
var operable := Delegate.Operable \ back(nil);
if (nil == operable)
if (nil == operable)
Line 877: Line 887:
var delegator := new Delegator();
var delegator := new Delegator();
new object[]{nil, new Object(), new Operable()}.forEach:(o)
new object[]{nil, new Object(), new Operable()}.forEach::(o)
{
{
delegator.Delegate := o;
delegator.Delegate := o;
Line 883: Line 893:
console.printLine(delegator.operate())
console.printLine(delegator.operate())
}
}
}</lang>
}</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 890: Line 900:
delegate implementation
delegate implementation
</pre>
</pre>

=={{header|FreeBASIC}}==
{{trans|Phix}}
FreeBASIC does not directly support objects or delegation functions. However, you can achieve similar functionality using user-defined types and function pointers.
<syntaxhighlight lang="vbnet">
Type Objeto
operation As Function() As String
other As String
End Type

Function xthing() As String
Return "default implementation"
End Function

Function newX() As Objeto
Dim As Objeto o
o.operation = @xthing
Return o
End Function

Function newY() As Objeto
Dim As Objeto o = newX()
o.other = "something else"
o.operation = 0 ' remove delegate
Return o
End Function

Function zthing() As String
Return "delegate implementation"
End Function

Function newZ() As Objeto
Dim As Objeto o = newX()
o.operation = @zthing ' replace delegate
Return o
End Function

Function operation(o As Objeto) As String
Return Iif(o.operation <> 0, o.operation(), "no implementation")
End Function

Dim As Objeto x = newX()
Dim As Objeto y = newY()
Dim As Objeto z = newZ()

Print operation(x)
Print operation(y)
Print operation(z)

Sleep</syntaxhighlight>
{{out}}
<pre>Similar as Phix entry.</pre>


=={{header|F_Sharp|F#}}==
=={{header|F_Sharp|F#}}==
<lang fsharp>type Delegator() =
<syntaxhighlight lang="fsharp">type Delegator() =
let defaultOperation() = "default implementation"
let defaultOperation() = "default implementation"
let mutable del = null
let mutable del = null
Line 917: Line 979:


d.Delegate <- new Delegate()
d.Delegate <- new Delegate()
assert (d.operation() = "delegate implementation")</lang>
assert (d.operation() = "delegate implementation")</syntaxhighlight>


=={{header|Forth}}==
=={{header|Forth}}==
Line 925: Line 987:
Needs the FMS-SI (single inheritance) library code located here:
Needs the FMS-SI (single inheritance) library code located here:
http://soton.mpeforth.com/flag/fms/index.html
http://soton.mpeforth.com/flag/fms/index.html
<lang forth>include FMS-SI.f
<syntaxhighlight lang="forth">include FMS-SI.f


:class delegate
:class delegate
Line 959: Line 1,021:
slave master !:
slave master !:
master operation \ => delegate implementation
master operation \ => delegate implementation
</syntaxhighlight>
</lang>


=={{header|Go}}==
=={{header|Go}}==


<lang go>package main
<syntaxhighlight lang="go">package main
import "fmt"
import "fmt"


Line 1,001: Line 1,063:
a.delegate = d
a.delegate = d
fmt.Println(a.operation()) // prints "delegate implementation"
fmt.Println(a.operation()) // prints "delegate implementation"
}</lang>
}</syntaxhighlight>


=={{header|Io}}==
=={{header|Io}}==
{{trans|Python}}
{{trans|Python}}
<lang Io>Delegator := Object clone do(
<syntaxhighlight lang="io">Delegator := Object clone do(
delegate ::= nil
delegate ::= nil
operation := method(
operation := method(
Line 1,026: Line 1,088:


a setDelegate(Delegate clone)
a setDelegate(Delegate clone)
a operation println</lang>
a operation println</syntaxhighlight>
{{out}}
{{out}}
<pre>default implementation
<pre>default implementation
Line 1,036: Line 1,098:
Life becomes slightly cleaner if we delegate to ourselves in the absence of some other delegate.
Life becomes slightly cleaner if we delegate to ourselves in the absence of some other delegate.


<lang J>coclass 'delegator'
<syntaxhighlight lang="j">coclass 'delegator'
operation=:3 :'thing__delegate ::thing y'
operation=:3 :'thing__delegate ::thing y'
thing=: 'default implementation'"_
thing=: 'default implementation'"_
Line 1,048: Line 1,110:


NB. set context in case this script was used interactively, instead of being loaded
NB. set context in case this script was used interactively, instead of being loaded
cocurrent 'base'</lang>
cocurrent 'base'</syntaxhighlight>


Example use:
Example use:


<lang J> obj=:conew'delegator'
<syntaxhighlight lang="j"> obj=:conew'delegator'
operation__obj''
operation__obj''
default implementation
default implementation
Line 1,066: Line 1,128:
└─┘
└─┘
operation__obj''
operation__obj''
delegate implementation</lang>
delegate implementation</syntaxhighlight>


=={{header|Java}}==
=={{header|Java}}==
This implementation uses an interface called Thingable to specify the type of delegates that respond to thing(). The downside is that any delegate you want to use has to explicitly declare to implement the interface. The upside is that the type system guarantees that when the delegate is non-null, it must implement the "thing" method.
This implementation uses an interface called Thingable to specify the type of delegates that respond to thing(). The downside is that any delegate you want to use has to explicitly declare to implement the interface. The upside is that the type system guarantees that when the delegate is non-null, it must implement the "thing" method.


<lang java>interface Thingable {
<syntaxhighlight lang="java">interface Thingable {
String thing();
String thing();
}
}
Line 1,113: Line 1,175:
assert a.operation().equals("anonymous delegate implementation");
assert a.operation().equals("anonymous delegate implementation");
}
}
}</lang>
}</syntaxhighlight>


{{works with|Java|8+}}
{{works with|Java|8+}}
<lang java>package delegate;
<syntaxhighlight lang="java">package delegate;


@FunctionalInterface
@FunctionalInterface
public interface Thingable {
public interface Thingable {
public String thing();
public String thing();
}</lang>
}</syntaxhighlight>


<lang java>package delegate;
<syntaxhighlight lang="java">package delegate;


import java.util.Optional;
import java.util.Optional;
Line 1,141: Line 1,203:
;
;
}
}
}</lang>
}</syntaxhighlight>


<lang java>package delegate;
<syntaxhighlight lang="java">package delegate;


@FunctionalInterface
@FunctionalInterface
Line 1,159: Line 1,221:
return () -> thingable;
return () -> thingable;
}
}
}</lang>
}</syntaxhighlight>


<lang java>package delegate;
<syntaxhighlight lang="java">package delegate;


public final class Delegate implements Thingable {
public final class Delegate implements Thingable {
Line 1,168: Line 1,230:
return "delegate implementation";
return "delegate implementation";
}
}
}</lang>
}</syntaxhighlight>


<lang java>package delegate;
<syntaxhighlight lang="java">package delegate;


// Example usage
// Example usage
Line 1,205: Line 1,267:
assert d5.operation().equals("lambda expression implementation");
assert d5.operation().equals("lambda expression implementation");
}
}
}</lang>
}</syntaxhighlight>


=={{header|JavaScript}}==
=={{header|JavaScript}}==
{{trans|Python}}
{{trans|Python}}
<lang javascript>function Delegator() {
<syntaxhighlight lang="javascript">function Delegator() {
this.delegate = null ;
this.delegate = null ;
this.operation = function(){
this.operation = function(){
Line 1,233: Line 1,295:
a.delegate = new Delegate() ;
a.delegate = new Delegate() ;
document.write(a.operation() + "\n") ;
document.write(a.operation() + "\n") ;
}</lang>
}</syntaxhighlight>


=={{header|Julia}}==
=={{header|Julia}}==
'''Module''':
'''Module''':
<lang julia>module Delegates
<syntaxhighlight lang="julia">module Delegates


export Delegator, Delegate
export Delegator, Delegate
Line 1,251: Line 1,313:
thing(::Delegate) = "delegate implementation"
thing(::Delegate) = "delegate implementation"


end # module Delegates</lang>
end # module Delegates</syntaxhighlight>


'''Main''':
'''Main''':
<lang julia>using .Delegates
<syntaxhighlight lang="julia">using .Delegates


a = Delegator(nothing)
a = Delegator(nothing)
Line 1,264: Line 1,326:
@show Delegates.operation(a)
@show Delegates.operation(a)
@show Delegates.operation(b)
@show Delegates.operation(b)
@show Delegates.operation(c)</lang>
@show Delegates.operation(c)</syntaxhighlight>


{{out}}
{{out}}
Line 1,275: Line 1,337:


The first two scenarios are not therefore strictly possible though the second can be simulated by passing a 'responds' parameter to the delegate class constructor.
The first two scenarios are not therefore strictly possible though the second can be simulated by passing a 'responds' parameter to the delegate class constructor.
<lang scala>// version 1.1.51
<syntaxhighlight lang="scala">// version 1.1.51


interface Thingable {
interface Thingable {
Line 1,299: Line 1,361:
val dd2 = Delegator(d2)
val dd2 = Delegator(d2)
println(dd2.operation())
println(dd2.operation())
}</lang>
}</syntaxhighlight>


{{out}}
{{out}}
Line 1,310: Line 1,372:


{{trans|Python}}
{{trans|Python}}
<lang latitude>Delegator ::= Object clone tap {
<syntaxhighlight lang="latitude">Delegator ::= Object clone tap {
self delegate := Nil.
self delegate := Nil.
self clone := {
self clone := {
Line 1,341: Line 1,403:
;; Delegate which implements `thing`
;; Delegate which implements `thing`
foo delegate := Delegate.
foo delegate := Delegate.
println: foo operation. ;; "delegate implementation"</lang>
println: foo operation. ;; "delegate implementation"</syntaxhighlight>


=={{header|Logtalk}}==
=={{header|Logtalk}}==
We use prototypes instead of classes for simplicity.
We use prototypes instead of classes for simplicity.
<lang logtalk>% define a category for holding the interface
<syntaxhighlight lang="logtalk">% define a category for holding the interface
% and implementation for delegator objects
% and implementation for delegator objects


Line 1,420: Line 1,482:
a_delegator::operation(String3),
a_delegator::operation(String3),
String3 == 'delegate implementation'
String3 == 'delegate implementation'
)).</lang>
)).</syntaxhighlight>


=={{header|Lua}}==
=={{header|Lua}}==
<lang lua>local function Delegator()
<syntaxhighlight lang="lua">local function Delegator()
return {
return {
operation = function(self)
operation = function(self)
Line 1,468: Line 1,530:
assert(d:operation() == "delegate implementation")
assert(d:operation() == "delegate implementation")


print("pass")</lang>
print("pass")</syntaxhighlight>


=={{header|M2000 Interpreter}}==
=={{header|M2000 Interpreter}}==
<syntaxhighlight lang="m2000 interpreter">
<lang M2000 Interpreter>
Module Checkit {
Module Checkit {
\\ there are some kinds of objects in M2000, one of them is the Group, the user object
\\ there are some kinds of objects in M2000, one of them is the Group, the user object
Line 1,579: Line 1,641:
Checkit
Checkit


</syntaxhighlight>
</lang>
{{out}}
{{out}}
<pre>
<pre>
Line 1,610: Line 1,672:


=={{header|Mathematica}} / {{header|Wolfram Language}}==
=={{header|Mathematica}} / {{header|Wolfram Language}}==
<lang Mathematica>delegator[del_]@operate :=
<syntaxhighlight lang="mathematica">delegator[del_]@operate :=
If[StringQ[del@operate], del@operate, "default implementation"];
If[StringQ[del@operate], del@operate, "default implementation"];
del1 = Null;
del1 = Null;
del2@banana = "phone";
del2@banana = "phone";
del3@operate = "delegate implementation";
del3@operate = "delegate implementation";
Print[delegator[#]@operate] & /@ {del1, del2, del3};</lang>
Print[delegator[#]@operate] & /@ {del1, del2, del3};</syntaxhighlight>
{{out}}
{{out}}
<pre>default implementation
<pre>default implementation
Line 1,622: Line 1,684:


=={{header|NGS}}==
=={{header|NGS}}==
<syntaxhighlight lang="ngs">{
<lang NGS>{
type Delegator
type Delegator


Line 1,661: Line 1,723:
echo(a.operation())
echo(a.operation())
}</lang>
}</syntaxhighlight>
{{out}}
{{out}}
<pre>default implementation
<pre>default implementation
Line 1,668: Line 1,730:


=={{header|Nim}}==
=={{header|Nim}}==
<lang Nim>####################################################################################################
<syntaxhighlight lang="nim">####################################################################################################
# Base delegate.
# Base delegate.


Line 1,715: Line 1,777:


let d2 = initDelegator(Delegate2())
let d2 = initDelegator(Delegate2())
echo "With a delegate which provided the “thing” method: ", d2.operation()</lang>
echo "With a delegate which provided the “thing” method: ", d2.operation()</syntaxhighlight>


{{out}}
{{out}}
Line 1,724: Line 1,786:
=={{header|Objeck}}==
=={{header|Objeck}}==
{{trans|Java}}
{{trans|Java}}
<lang objeck>interface Thingable {
<syntaxhighlight lang="objeck">interface Thingable {
method : virtual : public : Thing() ~ String;
method : virtual : public : Thing() ~ String;
}
}
Line 1,778: Line 1,840:
}
}
}
}
</syntaxhighlight>
</lang>


=={{header|Objective-C}}==
=={{header|Objective-C}}==
Line 1,784: Line 1,846:
{{works with|Cocoa}}
{{works with|Cocoa}}
{{works with|GNUstep}}
{{works with|GNUstep}}
<lang objc>#import <Foundation/Foundation.h>
<syntaxhighlight lang="objc">#import <Foundation/Foundation.h>


@interface Delegator : NSObject {
@interface Delegator : NSObject {
Line 1,859: Line 1,921:


return 0;
return 0;
}</lang>
}</syntaxhighlight>


Objective-C 2.0, modern runtime, Automatic Reference Counting, Autosynthesize (LLVM 4.0+)
Objective-C 2.0, modern runtime, Automatic Reference Counting, Autosynthesize (LLVM 4.0+)
{{works with|Cocoa}}
{{works with|Cocoa}}


<lang objc>#import <Foundation/Foundation.h>
<syntaxhighlight lang="objc">#import <Foundation/Foundation.h>


// Formal protocol for the delegate
// Formal protocol for the delegate
Line 1,908: Line 1,970:
}
}
return 0;
return 0;
}</lang>
}</syntaxhighlight>


=={{header|Oforth}}==
=={{header|Oforth}}==
<lang Oforth>Object Class new: Delegate1
<syntaxhighlight lang="oforth">Object Class new: Delegate1
Object Class new: Delegate2
Object Class new: Delegate2
Line 1,921: Line 1,983:
Delegator method: operation
Delegator method: operation
@delegate respondTo(#thing) ifTrue: [ @delegate thing return ]
@delegate respondTo(#thing) ifTrue: [ @delegate thing return ]
"Default implementation" println ;</lang>
"Default implementation" println ;</syntaxhighlight>
Usage :
Usage :


<lang Oforth>Delegator new(null) operation
<syntaxhighlight lang="oforth">Delegator new(null) operation
Default implementation
Default implementation


Line 1,931: Line 1,993:


Delegator new(Delegate2 new) operation
Delegator new(Delegate2 new) operation
Delegate implementation</lang>
Delegate implementation</syntaxhighlight>


=={{header|ooRexx}}==
=={{header|ooRexx}}==
<syntaxhighlight lang="oorexx">
<lang ooRexx>
delegator = .delegator~new -- no delegate
delegator = .delegator~new -- no delegate
say delegator~operation
say delegator~operation
Line 1,975: Line 2,037:
nomethod:
nomethod:
return "default implementation"
return "default implementation"
</syntaxhighlight>
</lang>


=={{header|OxygenBasic}}==
=={{header|OxygenBasic}}==
<lang oxygenbasic>
<syntaxhighlight lang="oxygenbasic">
class DelegateA 'not implmenting thing()
class DelegateA 'not implmenting thing()
'==============
'==============
Line 2,023: Line 2,085:
print dgr.thing 'result "not using Delegate"
print dgr.thing 'result "not using Delegate"
print dg.thing 'result "Delegate Implementation"
print dg.thing 'result "Delegate Implementation"
</syntaxhighlight>
</lang>


=={{header|Oz}}==
=={{header|Oz}}==
{{trans|Python}}
{{trans|Python}}
<lang oz>declare
<syntaxhighlight lang="oz">declare
class Delegator from BaseObject
class Delegator from BaseObject
attr
attr
Line 2,069: Line 2,131:


{A set({New Delegate noop})}
{A set({New Delegate noop})}
{System.showInfo {A operation($)}}</lang>
{System.showInfo {A operation($)}}</syntaxhighlight>


=={{header|Pascal}}==
=={{header|Pascal}}==
Line 2,076: Line 2,138:
=={{header|Perl}}==
=={{header|Perl}}==
{{trans|Python}}
{{trans|Python}}
<lang perl>use strict;
<syntaxhighlight lang="perl">use strict;


package Delegator;
package Delegator;
Line 2,114: Line 2,176:
$a->{delegate} = Delegate->new;
$a->{delegate} = Delegate->new;
$a->operation eq 'delegate implementation' or die;
$a->operation eq 'delegate implementation' or die;
</syntaxhighlight>
</lang>


Using Moose.
Using Moose.


<lang perl>
<syntaxhighlight lang="perl">
use 5.010_000;
use 5.010_000;


Line 2,174: Line 2,236:
$delegator->operation eq 'delegate implementation' or die;
$delegator->operation eq 'delegate implementation' or die;


</syntaxhighlight>
</lang>


=={{header|Phix}}==
=={{header|Phix}}==
Line 2,180: Line 2,242:
I will admit that the whole concept of "no delegate/with one that does not implement" makes no sense whatsoever to me.<br>
I will admit that the whole concept of "no delegate/with one that does not implement" makes no sense whatsoever to me.<br>
While I've shown this using a single rid, you could of course hold an entire sequence of them or even better a dictionary and use named lookups for rids in that.
While I've shown this using a single rid, you could of course hold an entire sequence of them or even better a dictionary and use named lookups for rids in that.
<lang Phix>enum OTHER, OPERATION
<syntaxhighlight lang="phix">enum OTHER, OPERATION


function operation(object o)
function operation(object o)
Line 2,223: Line 2,285:
?operation(x)
?operation(x)
?operation(y)
?operation(y)
?operation(z)</lang>
?operation(z)</syntaxhighlight>


{{out}}
{{out}}
Line 2,232: Line 2,294:
</pre>
</pre>
Obviously, you can explictly test for rid=NULL as shown, or remove that test and catch exceptions, ie:
Obviously, you can explictly test for rid=NULL as shown, or remove that test and catch exceptions, ie:
<lang Phix>?operation(x)
<syntaxhighlight lang="phix">?operation(x)
try -- (since rid=NULL check commented out)
try -- (since rid=NULL check commented out)
?operation(y)
?operation(y)
Line 2,238: Line 2,300:
?"oops, no implementation"
?"oops, no implementation"
end try
end try
?operation(z)</lang>
?operation(z)</syntaxhighlight>


=={{header|PHP}}==
=={{header|PHP}}==
{{trans|Python}}
{{trans|Python}}
<lang php>class Delegator {
<syntaxhighlight lang="php">class Delegator {
function __construct() {
function __construct() {
$this->delegate = NULL ;
$this->delegate = NULL ;
Line 2,266: Line 2,328:


$a->delegate = new Delegate() ;
$a->delegate = new Delegate() ;
print "{$a->operation()}\n" ;</lang>
print "{$a->operation()}\n" ;</syntaxhighlight>


=={{header|PicoLisp}}==
=={{header|PicoLisp}}==
<lang PicoLisp>(class +Delegator)
<syntaxhighlight lang="picolisp">(class +Delegator)
# delegate
# delegate


Line 2,298: Line 2,360:
# With delegate that implements 'thing>'
# With delegate that implements 'thing>'
(put A 'delegate (new '(+Delegate) "delegate implementation"))
(put A 'delegate (new '(+Delegate) "delegate implementation"))
(println (operation> A)) )</lang>
(println (operation> A)) )</syntaxhighlight>
Output:
Output:
<pre>"default implementation"
<pre>"default implementation"
Line 2,305: Line 2,367:


=={{header|Pop11}}==
=={{header|Pop11}}==
<lang pop11>uses objectclass;
<syntaxhighlight lang="pop11">uses objectclass;
define :class Delegator;
define :class Delegator;
slot delegate = false;
slot delegate = false;
Line 2,336: Line 2,398:
;;; delegating to a freshly created Delegate
;;; delegating to a freshly created Delegate
newDelegate() -> delegate(a);
newDelegate() -> delegate(a);
operation(a) =></lang>
operation(a) =></syntaxhighlight>


=={{header|Python}}==
=={{header|Python}}==
<lang python>class Delegator:
<syntaxhighlight lang="python">class Delegator:
def __init__(self):
def __init__(self):
self.delegate = None
self.delegate = None
Line 2,363: Line 2,425:
# With delegate that implements "thing"
# With delegate that implements "thing"
a.delegate = Delegate()
a.delegate = Delegate()
assert a.operation() == 'delegate implementation'</lang>
assert a.operation() == 'delegate implementation'</syntaxhighlight>


=={{header|Racket}}==
=={{header|Racket}}==
Line 2,375: Line 2,437:
follows the requirement of the task better.
follows the requirement of the task better.


<lang racket>#lang racket
<syntaxhighlight lang="racket">#lang racket
;; Delegates. Tim Brown 2014-10-16
;; Delegates. Tim Brown 2014-10-16


Line 2,409: Line 2,471:
(send delegator-2 operation) => "delegate implementation"
(send delegator-2 operation) => "delegate implementation"
(send (new delegator% [delegate thinging-delegate]) operation) => "delegate implementation"))
(send (new delegator% [delegate thinging-delegate]) operation) => "delegate implementation"))
</syntaxhighlight>
</lang>


All the tests pass. Believe me.
All the tests pass. Believe me.
Line 2,415: Line 2,477:
=={{header|Raku}}==
=={{header|Raku}}==
(formerly Perl 6)
(formerly Perl 6)
<lang perl6>class Non-Delegate { }
<syntaxhighlight lang="raku" line>class Non-Delegate { }


class Delegate {
class Delegate {
Line 2,442: Line 2,504:
$d.delegate = Delegate.new;
$d.delegate = Delegate.new;


say "Delegate: "~$d.operation;</lang>
say "Delegate: "~$d.operation;</syntaxhighlight>


=={{header|Ruby}}==
=={{header|Ruby}}==
{{trans|Python}}
{{trans|Python}}
<lang ruby>class Delegator
<syntaxhighlight lang="ruby">class Delegator
attr_accessor :delegate
attr_accessor :delegate
def operation
def operation
Line 2,476: Line 2,538:
a.delegate = Delegate.new
a.delegate = Delegate.new
puts a.operation # prints "delegate implementation"
puts a.operation # prints "delegate implementation"
end</lang>
end</syntaxhighlight>


Using Forwardable lib
Using Forwardable lib


<lang ruby>require 'forwardable'
<syntaxhighlight lang="ruby">require 'forwardable'


class Delegator; extend Forwardable
class Delegator; extend Forwardable
Line 2,499: Line 2,561:
a = Delegator.new
a = Delegator.new
puts a.delegated # prints "Delegate"
puts a.delegated # prints "Delegate"
</syntaxhighlight>
</lang>


=={{header|Rust}}==
=={{header|Rust}}==
Requiring delegates to implement Thingable:
Requiring delegates to implement Thingable:
<lang Rust>trait Thingable {
<syntaxhighlight lang="rust">trait Thingable {
fn thing(&self) -> &str;
fn thing(&self) -> &str;
}
}
Line 2,529: Line 2,591:
let d: Delegator<Delegate> = Delegator(Some(Delegate {}));
let d: Delegator<Delegate> = Delegator(Some(Delegate {}));
println!("{}", d.thing());
println!("{}", d.thing());
}</lang>
}</syntaxhighlight>
{{Out}}
{{Out}}
<pre>Default implmementation
<pre>Default implmementation
Line 2,535: Line 2,597:


Using nightly-only specialization feature:
Using nightly-only specialization feature:
<lang Rust>#![feature(specialization)]
<syntaxhighlight lang="rust">#![feature(specialization)]


trait Thingable {
trait Thingable {
Line 2,575: Line 2,637:
let d: Delegator<Delegate> = Delegator(Some(Delegate {}));
let d: Delegator<Delegate> = Delegator(Some(Delegate {}));
println!("{}", d.thing());
println!("{}", d.thing());
}</lang>
}</syntaxhighlight>
{{Out}}
{{Out}}
<pre>Default implementation
<pre>Default implementation
Line 2,584: Line 2,646:
=={{header|Scala}}==
=={{header|Scala}}==
{{Out}}Best seen running in your browser either by [https://scalafiddle.io/sf/cCYD9tQ/0 ScalaFiddle (ES aka JavaScript, non JVM)] or [https://scastie.scala-lang.org/2TWYJifpTuOVhrAfWP51oA Scastie (remote JVM)].
{{Out}}Best seen running in your browser either by [https://scalafiddle.io/sf/cCYD9tQ/0 ScalaFiddle (ES aka JavaScript, non JVM)] or [https://scastie.scala-lang.org/2TWYJifpTuOVhrAfWP51oA Scastie (remote JVM)].
<lang Scala>trait Thingable {
<syntaxhighlight lang="scala">trait Thingable {
def thing: String
def thing: String
}
}
Line 2,615: Line 2,677:
assert(a.operation == "anonymous delegate implementation")
assert(a.operation == "anonymous delegate implementation")


}</lang>
}</syntaxhighlight>


=={{header|Sidef}}==
=={{header|Sidef}}==
<lang ruby>class NonDelegate { }
<syntaxhighlight lang="ruby">class NonDelegate { }


class Delegate {
class Delegate {
Line 2,642: Line 2,704:
say "NonDelegate: #{d.operation}"
say "NonDelegate: #{d.operation}"
d.delegate = Delegate()
d.delegate = Delegate()
say "Delegate: #{d.operation}"</lang>
say "Delegate: #{d.operation}"</syntaxhighlight>
{{out}}
{{out}}
empty: default implementation
empty: default implementation
Line 2,651: Line 2,713:
{{works with|Smalltalk/X}}
{{works with|Smalltalk/X}}
Definition of the thingy:
Definition of the thingy:
<lang smalltalk>Object
<syntaxhighlight lang="smalltalk">Object
subclass:#Thingy
subclass:#Thingy
instanceVariableNames:''
instanceVariableNames:''


thing
thing
^ 'thingy implementation'</lang>
^ 'thingy implementation'</syntaxhighlight>
Definition of the delegator:
Definition of the delegator:
<lang smalltalk>Object
<syntaxhighlight lang="smalltalk">Object
subclass:#Delegator
subclass:#Delegator
instanceVariableNames:'delegate'
instanceVariableNames:'delegate'
Line 2,667: Line 2,729:
operation
operation
^ delegate
^ delegate
perform:#thing ifNotUnderstood:'default implementation'.</lang>
perform:#thing ifNotUnderstood:'default implementation'.</syntaxhighlight>
Sample use:
Sample use:
<lang smalltalk>|d|
<syntaxhighlight lang="smalltalk">|d|
d := Delegator new.
d := Delegator new.
d operation.
d operation.
Line 2,676: Line 2,738:
d delegate:(Thingy new).
d delegate:(Thingy new).
d operation.
d operation.
-> 'thingy implementation'</lang>
-> 'thingy implementation'</syntaxhighlight>


=={{header|Swift}}==
=={{header|Swift}}==
Allowing the delegate to be any type and taking advantage of dynamism of method lookup:
Allowing the delegate to be any type and taking advantage of dynamism of method lookup:
<lang swift>import Foundation
<syntaxhighlight lang="swift">import Foundation


protocol Thingable { // prior to Swift 1.2, needs to be declared @objc
protocol Thingable { // prior to Swift 1.2, needs to be declared @objc
Line 2,712: Line 2,774:
let d = Delegate()
let d = Delegate()
a.delegate = d
a.delegate = d
println(a.operation()) // prints "delegate implementation"</lang>
println(a.operation()) // prints "delegate implementation"</syntaxhighlight>




Alternately, requiring the delegate to conform to a given protocol:
Alternately, requiring the delegate to conform to a given protocol:
<lang swift>protocol Thingable : class {
<syntaxhighlight lang="swift">protocol Thingable : class {
func thing() -> String
func thing() -> String
}
}
Line 2,742: Line 2,804:
let d = Delegate()
let d = Delegate()
a.delegate = d
a.delegate = d
println(a.operation()) // prints "delegate implementation"</lang>
println(a.operation()) // prints "delegate implementation"</syntaxhighlight>


=={{header|Tcl}}==
=={{header|Tcl}}==
{{works with|Tcl|8.6}} or {{libheader|TclOO}}
{{works with|Tcl|8.6}} or {{libheader|TclOO}}
Uses [[Assertions#Tcl]]
Uses [[Assertions#Tcl]]
<lang tcl>package require TclOO
<syntaxhighlight lang="tcl">package require TclOO


oo::class create Delegate {
oo::class create Delegate {
Line 2,799: Line 2,861:
assert {[a operation] ne "default implementation"}
assert {[a operation] ne "default implementation"}


puts "all assertions passed"</lang>
puts "all assertions passed"</syntaxhighlight>


To code the <code>operation</code> method without relying on catching an exception, but strictly by using introspection:
To code the <code>operation</code> method without relying on catching an exception, but strictly by using introspection:
<lang tcl>method operation {} {
<syntaxhighlight lang="tcl">method operation {} {
if { [info exists delegate] &&
if { [info exists delegate] &&
[info object isa object $delegate] &&
[info object isa object $delegate] &&
Line 2,811: Line 2,873:
set result "default implementation"
set result "default implementation"
}
}
}</lang>
}</syntaxhighlight>

=={{header|TXR}}==

<syntaxhighlight lang="txrlisp">;; TXR Lisp's :delegate implementation is hard delegation: the indicated
;; delegate object must exist and take the method call. To do soft
;; delegation, we develop a macro (delegate-or-fallback x y z)
;; which chooses x if x is an object which supports a z method,
;; or else chooses y.

(defun delegate-or-fallback-impl (del-inst fb-inst required-meth)
(let (del-type)
(if (and (structp del-inst)
(set del-type (struct-type del-inst))
(static-slot-p del-type required-meth)
(functionp (static-slot del-type required-meth)))
del-inst
fb-inst)))

(defmacro delegate-or-fallback (delegate-expr fallback-obj : required-meth)
^(delegate-or-fallback-impl ,delegate-expr ,fallback-obj ',required-meth))

;; With the above, we can use the defstruct delegate clause syntax:
;;
;; (:delegate source-method (obj) target-obj target-method)
;;
;; which writes a delegate method called source-method, that delegates
;; to target-method on target-obj. We calculate target-obj using
;; our macro and ensure that the delegator itself imlpements target-method.

(defstruct delegator ()
delegate
(:delegate operation (me) (delegate-or-fallback me.delegate me thing) thing)

(:method thing (me)
"default implementation"))

(defstruct delegate ()
(:method thing (me)
"delegate implementation"))

;; Tests:

;; no delegate
(prinl (new delegator).(operation))

;; struct delegate, but not with thing method
(prinl (new delegator delegate (new time)).(operation))

;; delegate with thing method
(prinl (new delegator delegate (new delegate)).(operation))</syntaxhighlight>

{{out}}

<pre>"default implementation"
"default implementation"
"delegate implementation"</pre>


=={{header|Vorpal}}==
=={{header|Vorpal}}==
Delegate objects can be an array of delegates or as a single delegate.
Delegate objects can be an array of delegates or as a single delegate.
<lang vorpal>a = new()
<syntaxhighlight lang="vorpal">a = new()
a.f = method(){
a.f = method(){
.x.print()
.x.print()
Line 2,838: Line 2,956:
d.delegate = a
d.delegate = a
d.x = 7
d.x = 7
d.f()</lang>
d.f()</syntaxhighlight>


The resulting output:
The resulting output:
Line 2,845: Line 2,963:
4
4
7
7
</pre>

=={{header|Wren}}==
Wren is dynamically typed so we can plug any kind of delegate into the Delegator.
<syntaxhighlight lang="wren">class Thingable {
thing { }
}

// Delegate that doesn't implement Thingable
class Delegate {
construct new() { }
}

// Delegate that implements Thingable
class Delegate2 is Thingable {
construct new() { }

thing { "delegate implementation" }
}

class Delegator {
construct new() {
_delegate = null
}

delegate { _delegate }
delegate=(d) { _delegate = d }

operation {
if (!_delegate || !(_delegate is Thingable)) return "default implementation"
return _delegate.thing
}
}

// without a delegate
var d = Delegator.new()
System.print(d.operation)

// with a delegate that doesn't implement Thingable
d.delegate = Delegate.new()
System.print(d.operation)

// with a delegate that does implement Thingable
d.delegate = Delegate2.new()
System.print(d.operation)</syntaxhighlight>

{{out}}
<pre>
default implementation
default implementation
delegate implementation
</pre>
</pre>


=={{header|zkl}}==
=={{header|zkl}}==
{{trans|Scala}}
{{trans|Scala}}
<lang zkl>class Thingable{ var thing; }
<syntaxhighlight lang="zkl">class Thingable{ var thing; }
class Delegator{
class Delegator{
Line 2,859: Line 3,028:
}
}
class Delegate(Thingable){ thing = "delegate implementation" }</lang>
class Delegate(Thingable){ thing = "delegate implementation" }</syntaxhighlight>
<lang zkl> // Without a delegate:
<syntaxhighlight lang="zkl"> // Without a delegate:
a:= Delegator();
a:= Delegator();
a.operation().println(); //--> "default implementation"
a.operation().println(); //--> "default implementation"
Line 2,867: Line 3,036:
// With a delegate:
// With a delegate:
a.delegate = Delegate();
a.delegate = Delegate();
a.operation().println(); //-->"delegate implementation"</lang>
a.operation().println(); //-->"delegate implementation"</syntaxhighlight>
A second example
A second example
<lang zkl>class [static] Logger{ // Only one logging resource
<syntaxhighlight lang="zkl">class [static] Logger{ // Only one logging resource
var [mixin=File] dst; // File like semantics, eg Data, Pipe
var [mixin=File] dst; // File like semantics, eg Data, Pipe
dst = File.DevNull;
dst = File.DevNull;
// initially, the logger does nothing
// initially, the logger does nothing
fcn log(msg){dst.writeln(vm.pasteArgs())}
fcn log(msg){dst.writeln(vm.pasteArgs())}
}</lang>
}</syntaxhighlight>


<lang zkl>Logger.log("this is a test"); //-->nada
<syntaxhighlight lang="zkl">Logger.log("this is a test"); //-->nada
Logger.dst=Console;
Logger.dst=Console;
Logger.log("this is a test 2"); //-->writes to Console
Logger.log("this is a test 2"); //-->writes to Console


class B(Logger){ log("Hello from ",self,"'s constructor"); }
class B(Logger){ log("Hello from ",self,"'s constructor"); }
B(); //-->Hello from Class(B)'s constructor</lang>
B(); //-->Hello from Class(B)'s constructor</syntaxhighlight>


The base class B was constructed at startup,
The base class B was constructed at startup,

Latest revision as of 22:09, 29 March 2024

Task
Delegates
You are encouraged to solve this task according to the task description, using any language you may know.

A delegate is a helper object used by another object. The delegator may send the delegate certain messages, and provide a default implementation when there is no delegate or the delegate does not respond to a message. This pattern is heavily used in Cocoa framework on Mac OS X. See also wp:Delegation pattern.

Objects responsibilities:

Delegator:

  • Keep an optional delegate instance.
  • Implement "operation" method, returning the delegate "thing" if the delegate respond to "thing", or the string "default implementation".

Delegate:

  • Implement "thing" and return the string "delegate implementation"

Show how objects are created and used. First, without a delegate, then with a delegate that does not implement "thing", and last with a delegate that implements "thing".

Ada

All that is needed in order to implement this is a common base type. The delegator holds a pointer to an "untyped" object from the base class. Querying if the target implements the delegate interface is done using run-time type identification.

with Ada.Text_IO;  use Ada.Text_IO;

procedure Delegation is
   package Things is
      -- We need a common root for our stuff
      type Object is tagged null record;
      type Object_Ptr is access all Object'Class;
      
      -- Objects that have operation thing
      type Substantial is new Object with null record;
      function Thing (X : Substantial) return String;
      
      -- Delegator objects
      type Delegator is new Object with record
         Delegate : Object_Ptr;
      end record;
      function Operation (X : Delegator) return String;
      
      No_Thing  : aliased Object;      -- Does not have thing
      Has_Thing : aliased Substantial; -- Has one
   end Things;
      
   package body Things is
      function Thing (X : Substantial) return String is
      begin
         return "delegate implementation";
      end Thing;
   
      function Operation (X : Delegator) return String is
      begin
         if X.Delegate /= null and then X.Delegate.all in Substantial'Class then
            return Thing (Substantial'Class (X.Delegate.all));
         else
            return "default implementation";
         end if;
      end Operation;
   end Things;

   use Things;

   A : Delegator; -- Without a delegate
begin
   Put_Line (A.Operation);
   A.Delegate := No_Thing'Access; -- Set no thing
   Put_Line (A.Operation);
   A.Delegate := Has_Thing'Access; -- Set a thing
   Put_Line (A.Operation);
end Delegation;

Sample output:

default implementation
default implementation
delegate implementation

Aikido

class Delegator {
    public generic delegate = none

    public function operation {
        if (typeof(delegate) == "none") {
            return "default implementation"
        }
        return delegate()
    }
}

function thing {
    return "delegate implementation"
}

// default, no delegate
var d = new Delegator()
println (d.operation())

// delegate
var d1 = new Delegator()
d1.delegate = thing
println (d1.operation())

Aime

text
thing(void)
{
    return "delegate implementation";
}

text
operation(record delegator)
{
    text s;

    if (r_key(delegator, "delegate")) {
        if (r_key(delegator["delegate"], "thing")) {
            s = call(r_query(delegator["delegate"], "thing"));
        } else {
            s = "default implementation";
        }
    } else {
        s = "default implementation";
    }

    return s;
}

integer
main(void)
{
    record delegate, delegator;

    o_text(operation(delegator));
    o_byte('\n');

    r_link(delegator, "delegate", delegate);
    o_text(operation(delegator));
    o_byte('\n');

    r_put(delegate, "thing", thing);
    o_text(operation(delegator));
    o_byte('\n');

    return 0;
}

ALGOL 68

As Algol 68 doesn't have classes, we supply a non-OO approximation, similar to the C version.

# An Algol 68 approximation of delegates                                #

# The delegate mode - the delegate is a STRUCT with a single field      #
# that is a REF PROC STRING. If this is NIL, it doesn't implement       #
# thing                                                                 #
MODE DELEGATE  = STRUCT( REF PROC STRING thing );


# A delegator mode that will invoke the delegate's thing method         #
# - if there is a delegate and the delegate has a thing method          #
MODE DELEGATOR = STRUCT( REF DELEGATE delegate
                       , PROC( REF DELEGATE )STRING thing
                       );

# constructs a new DELEGATE with the specified PROC as its thing        #
# Algol 68 HEAP is like "new" in e.g. Java, but it can't take           #
# parameters, so this PROC does the equivalent                          #
PROC new delegate = ( REF PROC STRING thing )REF DELEGATE:
    BEGIN
        REF DELEGATE result = HEAP DELEGATE;
        thing OF result := thing;

        result
    END # new delegate #
;

# constructs a new DELEGATOR with the specified DELEGATE                #
PROC new delegator = ( REF DELEGATE delegate )REF DELEGATOR:
    HEAP DELEGATOR := ( delegate
                      , # anonymous PROC to invoke the delegate's thing #
                        ( REF DELEGATE delegate )STRING:
                            IF delegate IS REF DELEGATE(NIL)
                            THEN
                                # we have no delegate #
                                "default implementation"

                            ELIF thing OF delegate IS REF PROC STRING(NIL)
                            THEN
                                # the delegate doesn't have an implementation #
                                "default implementation"

                            ELSE
                                # the delegate can thing #
                                thing OF delegate

                            FI
                      )
;


# invokes the delegate's thing via the delagator                        #
# Because the PROCs of a STRUCT don't have an equivalent of e.g. Java's #
# "this", we have to explicitly pass the delegate as a parameter        #
PROC invoke thing = ( REF DELEGATOR delegator )STRING:
    # the following is Algol 68 for what would be written in Java as    #
    #                           "delegator.thing( delegator.delegate )" #
    ( thing OF delegator )( delegate OF delegator )
;

main:
(

    print( ( "No delegate           : "
           , invoke thing( new delegator( NIL ) )
           , newline
           , "Delegate with no thing: "
           , invoke thing( new delegator( new delegate( NIL ) ) )
           , newline
           , "Delegate with a thing : "
           , invoke thing( new delegator( new delegate( HEAP PROC STRING := STRING: ( "delegate implementation" ) ) ) )
           , newline
           )
         )

)
Output:

No delegate  : default implementation Delegate with no thing: default implementation Delegate with a thing : delegate implementation


Atari Basic

The code does not fully implement all requirements from above. If you find which requirements have not been met that's great. What is your proposal to solve that in the code?

10 REM DELEGATION CODE AND EXAMPLE . ATARI BASIC 2020 A. KRESS andreas.kress@hood-group.com
14 REM 
15 GOTO 100:REM MAINLOOP
16 REM 
20 REM DELEGATOR OBJECT
21 REM 
30 IF DELEGATE THEN GOSUB DELEGATE:GOTO 56
35 REM 
50 REM DELEGATOR HAS TO DO THE JOB
55 PRINT "DEFAULT IMPLEMENTATION - DONE BY DELEGATOR"
56 RETURN 
60 REM CALL DELEGATE
65 GOSUB DELEGATOR
66 RETURN 
79 REM 
80 REM DELEGATE OBJECT
81 REM 
90 PRINT "DELEGATE IMPLEMENTATION - DONE BY DELEGATE"
91 RETURN 
99 REM 
100 REM MAINLOOP - DELEGATION EXAMPLE
101 REM 
110 DELEGATE=0:REM NO DELEGATE
120 GOSUB 20:REM INIT DELEGATOR
130 DELEGATE=80:REM DELEGATE IS
140 GOSUB 20:REM INIT DELEGATOR
Output:

RUN DEFAULT IMPLEMENTATION - DONE BY DELEGATOR DELEGATE IMPLEMENTATION - DONE BY DELEGATE

Ready

C

As best you can do, without support for classes.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef const char * (*Responder)( int p1);

typedef struct sDelegate {
    Responder operation;
} *Delegate;

/* Delegate class constructor */
Delegate NewDelegate( Responder rspndr )
{
    Delegate dl = malloc(sizeof(struct sDelegate));
    dl->operation = rspndr;
    return dl;
}

/* Thing method of Delegate */
const char *DelegateThing(Delegate dl, int p1)
{
    return  (dl->operation)? (*dl->operation)(p1) : NULL;
}

/** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
typedef struct sDelegator {
    int     param;
    char    *phrase;
    Delegate delegate;
} *Delegator;

const char * defaultResponse( int p1)
{
    return "default implementation";
}

static struct sDelegate defaultDel = { &defaultResponse };

/* Delegator class constructor */
Delegator NewDelegator( int p, char *phrase)
{
    Delegator d  = malloc(sizeof(struct sDelegator));
    d->param = p;
    d->phrase = phrase;
    d->delegate = &defaultDel;	/* default delegate */
    return d;
}

/* Operation method of Delegator */
const char *Delegator_Operation( Delegator theDelegator, int p1, Delegate delroy)
{
    const char *rtn;
    if (delroy) {
        rtn = DelegateThing(delroy, p1);
        if (!rtn) {			/* delegate didn't handle 'thing' */
            rtn = DelegateThing(theDelegator->delegate, p1);
        }
    }
    else 		/* no delegate */
        rtn = DelegateThing(theDelegator->delegate, p1);

    printf("%s\n", theDelegator->phrase );
    return rtn;
}

/** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
const char *thing1( int p1)
{
    printf("We're in thing1 with value %d\n" , p1);
    return "delegate implementation";
}

int main()
{
    Delegate del1 = NewDelegate(&thing1);
    Delegate del2 = NewDelegate(NULL);
    Delegator theDelegator = NewDelegator( 14, "A stellar vista, Baby.");

    printf("Delegator returns %s\n\n", 
            Delegator_Operation( theDelegator, 3, NULL));
    printf("Delegator returns %s\n\n", 
            Delegator_Operation( theDelegator, 3, del1));
    printf("Delegator returns %s\n\n",
            Delegator_Operation( theDelegator, 3, del2));
    return 0;
}

C#

using System;

interface IOperable
{
    string Operate();
}

class Inoperable
{
}

class Operable : IOperable
{
    public string Operate()
    {
        return "Delegate implementation.";
    }
}

class Delegator : IOperable
{
    object Delegate;

    public string Operate()
    {
        var operable = Delegate as IOperable;
        return operable != null ? operable.Operate() : "Default implementation.";
    }

    static void Main()
    {
        var delegator = new Delegator();
        foreach (var @delegate in new object[] { null, new Inoperable(), new Operable() })
        {
            delegator.Delegate = @delegate;
            Console.WriteLine(delegator.Operate());
        }
    }
}

Output:

Default implementation.
Default implementation.
Delegate implementation.

C++

Delegates in the C# or D style are available in C++ through std::tr1::function class template. These delegates don't exactly match this problem statement though, as they only support a single method call (which is operator()), and so don't support querying for support of particular methods.

#include <tr1/memory>
#include <string>
#include <iostream>
#include <tr1/functional>

using namespace std;
using namespace std::tr1;
using std::tr1::function;

// interface for all delegates
class IDelegate
{
public:
    virtual ~IDelegate() {}
};

//interface for delegates supporting thing 
class IThing
{
public:
    virtual ~IThing() {}
    virtual std::string Thing() = 0;
};

// Does not handle Thing
class DelegateA : virtual public IDelegate
{
};
 
// Handles Thing
class DelegateB : public IThing, public IDelegate
{
    std::string Thing()
    {
        return "delegate implementation";
    }
};
 
class Delegator
{
public:
    std::string Operation()
    {
        if(Delegate) //have delegate
           if (IThing * pThing = dynamic_cast<IThing*>(Delegate.get()))
            //delegate provides IThing interface
            return pThing->Thing();
        
        return "default implementation";
    }
 
    shared_ptr<IDelegate> Delegate;
};
 
int main()
{
    shared_ptr<DelegateA> delegateA(new DelegateA());
    shared_ptr<DelegateB> delegateB(new DelegateB());
    Delegator delegator;
 
    // No delegate
    std::cout << delegator.Operation() << std::endl;
 
    // Delegate doesn't handle "Thing"
    delegator.Delegate = delegateA;
    std::cout << delegator.Operation() << std::endl;
 
    // Delegate handles "Thing"
    delegator.Delegate = delegateB;
    std::cout << delegator.Operation() << std::endl;

/*
Prints:

  default implementation
  default implementation
  delegate implementation
 */
}

Clojure

(defprotocol Thing
  (thing [_]))

(defprotocol Operation
  (operation [_]))

(defrecord Delegator [delegate]
  Operation
  (operation [_] (try (thing delegate) (catch IllegalArgumentException e "default implementation"))))

(defrecord Delegate []
  Thing
  (thing [_] "delegate implementation"))
Output:
; without a delegate
=> (operation (Delegator. nil))
"default implementation"

; with a delegate that does not implement "thing"
=> (operation (Delegator. (Object.)))
"default implementation"

; with a delegate that implements "thing"
=> (operation (Delegator. (Delegate.)))
"delegate implementation"

CoffeeScript

Translation of: Python
class Delegator
  operation: ->
    if @delegate and typeof (@delegate.thing) is "function"
      return @delegate.thing() 
    "default implementation"
    
class Delegate
  thing: ->
    "Delegate Implementation"

testDelegator = ->
  # Delegator with no delegate.
  a = new Delegator()
  console.log a.operation()
  
  # Delegator with delegate not implementing "thing"
  a.delegate = "A delegate may be any object"
  console.log a.operation()
  
  # Delegator with delegate that does implement "thing"
  a.delegate = new Delegate()
  console.log a.operation()
  
testDelegator()

output

 > coffee foo.coffee 
default implementation
default implementation
Delegate Implementation

Common Lisp

Translation of: Python

In CLOS, methods exist apart from classes, and are specialized based on the types of their arguments. This example defines two classes (delegator and delegate), and a thing generic method which is specialized in three ways: (1) for 'any' argument, providing a default method; (2) for delegators, where thing is recursively applied to the delegator's delegate (if there is one); and (3) for delegates.

(defgeneric thing (object)
  (:documentation "Thing the object."))

(defmethod thing (object)
  "default implementation")

(defclass delegator ()
  ((delegate
    :initarg :delegate
    :reader delegator-delegate)))

(defmethod thing ((delegator delegator))
  "If delegator has a delegate, invoke thing on the delegate,
otherwise return \"no delegate\"."
  (if (slot-boundp delegator 'delegate)
    (thing (delegator-delegate delegator))
    "no delegate"))

(defclass delegate () ())

(defmethod thing ((delegate delegate))
  "delegate implementation")

(let ((d1 (make-instance 'delegator))
      (d2 (make-instance 'delegator :delegate nil))
      (d3 (make-instance 'delegator :delegate (make-instance 'delegate))))
  (assert (string= "no delegate" (thing d1)))
  (assert (string= "default implementation" (thing d2)))
  (assert (string= "delegate implementation" (thing d3))))

D

D has built-in delegates, so we can skip creating an additional Delegate object and pass a real delegate directly to Delegator.

class Delegator {
    string delegate() hasDelegate;

    string operation() {
        if (hasDelegate is null)
            return "Default implementation";
        return hasDelegate();
    }

    typeof(this) setDg(string delegate() dg) {
        hasDelegate = dg;
        return this;
    }
}

void main() {
    import std.stdio;
    auto dr = new Delegator;
    string delegate() thing = () => "Delegate implementation";

    writeln(dr.operation());
    writeln(dr.operation());
    writeln(dr.setDg(thing).operation());
}
Output:
Default implementation
Default implementation
Delegate implementation

Version using Tango

Library: tango
import tango.io.Stdout;

class Delegator
{
    private char[] delegate() hasDelegate;
public:
    char[] operation() {
        if (hasDelegate is null)
            return "default implementation";
        return hasDelegate();
    }

    typeof(this) setDg(char[] delegate() dg)
    {
        hasDelegate = dg;
        return this;
    }
}

int main(char[][] args)
{
    auto dr = new Delegator();
    auto thing = delegate char[]() { return "delegate implementation"; };

    Stdout ( dr.operation ).newline;
    Stdout ( dr.operation ).newline;
    Stdout ( dr.setDg(thing).operation ).newline;
    return 0;
}

Dart

I didn't find a way to check for existing methods, so the version with Object doesn't work yet. The code is adapted from the Java version, but using var instead of an Interface

class Delegator {
  var delegate;
 
  String operation() {
    if (delegate == null)
      return "default implementation";
    else
      return delegate.thing();
  }
}

class Delegate {
  String thing() => "delegate implementation";
}

main() {
  // Without a delegate:
  Delegator a = new Delegator();
  Expect.equals("default implementation",a.operation());

  // any object doesn't work unless we can check for existing methods
  // a.delegate=new Object();
  // Expect.equals("default implementation",a.operation());

  // With a delegate:
  Delegate d = new Delegate();
  a.delegate = d;
  Expect.equals("delegate implementation",a.operation());
}

Delphi

Translation of the Java example found at Wikipedia.

unit Printer;

interface

type
  // the "delegate"
  TRealPrinter = class
  public
    procedure Print;
  end;

  // the "delegator"
  TPrinter = class
  private
    FPrinter: TRealPrinter;
  public
    constructor Create;
    destructor Destroy; override;
    procedure Print;
  end;

implementation

{ TRealPrinter }

procedure TRealPrinter.Print;
begin
   Writeln('Something...');
end;

{ TPrinter }

constructor TPrinter.Create;
begin
  inherited Create;
  FPrinter:= TRealPrinter.Create;
end;

destructor TPrinter.Destroy;
begin
  FPrinter.Free;
  inherited;
end;

procedure TPrinter.Print;
begin
  FPrinter.Print;
end;

end.
program Delegate;

{$APPTYPE CONSOLE}

uses
  SysUtils,
  Printer in 'Printer.pas';

var
  PrinterObj: TPrinter;
begin
  PrinterObj:= TPrinter.Create;
  try
    PrinterObj.Print;
    Readln;
  finally
    PrinterObj.Free;
  end;
end.

E

def makeDelegator {
    /** construct without an explicit delegate */
    to run() {
        return makeDelegator(null)
    }

    /** construct with a delegate */
    to run(delegateO) { # suffix because "delegate" is a reserved keyword
        def delegator {
            to operation() {
                return if (delegateO.__respondsTo("thing", 0)) {
                           delegateO.thing()
                       } else {
                           "default implementation"
                       }
            }
        }
        return delegator
    }
}

? def delegator := makeDelegator()
> delegator.operation()
# value: "default implementation"

? def delegator := makeDelegator(def doesNotImplement {})
> delegator.operation()
# value: "default implementation"

? def delegator := makeDelegator(def doesImplement {
>     to thing() { return "delegate implementation" }
> })
> delegator.operation()
# value: "default implementation"

Elena

ELENA 6.x :

Using multi methods:

import extensions;
import system'routines;
 
interface IOperable
{
    abstract operate();
}
 
class Operable : IOperable
{
    constructor() {}
 
    operate()
        = "delegate implementation";
}
 
class Delegator
{
    object theDelegate;
 
    set Delegate(object)
    {
        theDelegate := object
    }
 
    internal operate(operable)
        = "default implementation";
 
    internal operate(IOperable operable)
        = operable.operate();
 
    operate()
        <= operate(theDelegate);
}
 
public program()
{
    var delegator := new Delegator();
 
    new object[]{nil, new Object(), new Operable()}.forEach::(o)
    {
       delegator.Delegate := o;
 
       console.printLine(delegator.operate())
    }
}

Generic solution:

import extensions;
import system'routines;

class Operable
{
    Operable = self;
    
    operate()
        = "delegate implementation";
}
 
class Delegator
{
    object Delegate : prop;
 
    constructor()
    {
        Delegate := nil
    }
 
    operate()
    {
        // if the object does not support "Operable" message - returns nil
        var operable := Delegate.Operable \ back(nil);
        
        if (nil == operable)
        {
            ^ "default implementation"
        }
        else
        {
            ^ operable.operate()
        }
    }
}
 
public program()
{
    var delegator := new Delegator();
 
    new object[]{nil, new Object(), new Operable()}.forEach::(o)
    {
       delegator.Delegate := o;
 
       console.printLine(delegator.operate())
    }
}
Output:
default implementation
default implementation
delegate implementation

FreeBASIC

Translation of: Phix

FreeBASIC does not directly support objects or delegation functions. However, you can achieve similar functionality using user-defined types and function pointers.

Type Objeto
    operation As Function() As String
    other As String
End Type

Function xthing() As String
    Return "default implementation"
End Function

Function newX() As Objeto
    Dim As Objeto o
    o.operation = @xthing
    Return o
End Function

Function newY() As Objeto
    Dim As Objeto o = newX()
    o.other = "something else"
    o.operation = 0 ' remove delegate
    Return o
End Function

Function zthing() As String
    Return "delegate implementation"
End Function

Function newZ() As Objeto
    Dim As Objeto o = newX()
    o.operation = @zthing ' replace delegate
    Return o
End Function

Function operation(o As Objeto) As String
    Return Iif(o.operation <> 0, o.operation(), "no implementation")
End Function

Dim As Objeto x = newX()
Dim As Objeto y = newY()
Dim As Objeto z = newZ()

Print operation(x)
Print operation(y)
Print operation(z)

Sleep
Output:
Similar as Phix entry.

F#

type Delegator() =
  let defaultOperation() = "default implementation"
  let mutable del = null

  // write-only property "Delegate"
  member x.Delegate with set(d:obj) = del <- d
  
  member x.operation() =
    if del = null then
      defaultOperation()
    else
      match del.GetType().GetMethod("thing", [||]) with
      | null -> defaultOperation()
      | thing -> thing.Invoke(del, [||]) :?> string 
      
type Delegate() =
  member x.thing() = "delegate implementation"

let d = new Delegator()
assert (d.operation() = "default implementation")

d.Delegate <- "A delegate may be any object"
assert (d.operation() = "default implementation")

d.Delegate <- new Delegate()
assert (d.operation() = "delegate implementation")

Forth

Works with: Forth

Works with any ANS Forth

Needs the FMS-SI (single inheritance) library code located here: http://soton.mpeforth.com/flag/fms/index.html

include FMS-SI.f

:class delegate
  :m thing ." delegate implementation" ;m
;class

delegate slave

:class delegator
  ivar del  \ object container
  :m !: ( n -- ) del ! ;m
  :m init: 0 del ! ;m
  :m default ." default implementation" ;m
  :m operation 
     del @ 0= if self default exit then
     del @ has-meth thing
     if del @ thing
     else self default
     then ;m
;class

delegator master 
 
\ First, without a delegate
master operation \ => default implementation

\ then with a delegate that does not implement "thing"
object o  
o master !:
master operation \ => default implementation

\ and last with a delegate that implements "thing"
slave master !:
master operation \ => delegate implementation

Go

package main
import "fmt"

type Delegator struct {
    delegate interface{} // the delegate may be any type
}

// interface that represents anything that supports thing()
type Thingable interface {
    thing() string
}

func (self Delegator) operation() string {
    if v, ok := self.delegate.(Thingable); ok {
        return v.thing()
    }
    return "default implementation"
}

type Delegate int // any dummy type

func (Delegate) thing() string {
    return "delegate implementation"
}

func main() {
    // Without a delegate:
    a := Delegator{}
    fmt.Println(a.operation()) // prints "default implementation"

    // With a delegate that does not implement "thing"
    a.delegate = "A delegate may be any object"
    fmt.Println(a.operation()) // prints "default implementation"

    // With a delegate:
    var d Delegate
    a.delegate = d
    fmt.Println(a.operation()) // prints "delegate implementation"
}

Io

Translation of: Python
Delegator := Object clone do(
    delegate ::= nil
    operation := method(
        if((delegate != nil) and (delegate hasSlot("thing")),
            delegate thing,
            "default implementation"
        )
    )
)

Delegate := Object clone do(
    thing := method("delegate implementation")
)

a := clone Delegator
a operation println

a setDelegate("A delegate may be any object")
a operation println

a setDelegate(Delegate clone)
a operation println
Output:
default implementation
default implementation
delegate implementation

J

Life becomes slightly cleaner if we delegate to ourselves in the absence of some other delegate.

coclass 'delegator'
  operation=:3 :'thing__delegate ::thing y'
  thing=: 'default implementation'"_
  setDelegate=:3 :'delegate=:y'  NB. result is the reference to our new delegate
  delegate=:<'delegator'

coclass 'delegatee1'

coclass 'delegatee2'
  thing=: 'delegate implementation'"_

NB. set context in case this script was used interactively, instead of being loaded
cocurrent 'base'

Example use:

   obj=:conew'delegator'
   operation__obj''
default implementation
   setDelegate__obj conew'delegatee1'
┌─┐
4
└─┘
   operation__obj''
default implementation
   setDelegate__obj conew'delegatee2'
┌─┐
5
└─┘
   operation__obj''
delegate implementation

Java

This implementation uses an interface called Thingable to specify the type of delegates that respond to thing(). The downside is that any delegate you want to use has to explicitly declare to implement the interface. The upside is that the type system guarantees that when the delegate is non-null, it must implement the "thing" method.

interface Thingable {
    String thing();
}

class Delegator {
    public Thingable delegate;

    public String operation() {
        if (delegate == null)
            return "default implementation";
        else
            return delegate.thing();
    }
}

class Delegate implements Thingable {
    public String thing() {
        return "delegate implementation";
    }
}

// Example usage
// Memory management ignored for simplification
public class DelegateExample {
    public static void main(String[] args) {
        // Without a delegate:
        Delegator a = new Delegator();
        assert a.operation().equals("default implementation");

        // With a delegate:
        Delegate d = new Delegate();
        a.delegate = d;
        assert a.operation().equals("delegate implementation");

        // Same as the above, but with an anonymous class:
        a.delegate = new Thingable() {
                public String thing() {
                    return "anonymous delegate implementation";
                }
            };
        assert a.operation().equals("anonymous delegate implementation");
    }
}
Works with: Java version 8+
package delegate;

@FunctionalInterface
public interface Thingable {
  public String thing();
}
package delegate;

import java.util.Optional;

public interface Delegator {
  public Thingable delegate();
  public Delegator delegate(Thingable thingable);

  public static Delegator new_() {
    return $Delegator.new_();
  }
 
  public default String operation() {
    return Optional.ofNullable(delegate())
      .map(Thingable::thing)
      .orElse("default implementation")
    ;
  }
}
package delegate;

@FunctionalInterface
/* package */ interface $Delegator extends Delegator {
  @Override
  public default Delegator delegate(Thingable thingable) {
    return new_(thingable);
  }

  public static $Delegator new_() {
    return new_(() -> null);
  }

  public static $Delegator new_(Thingable thingable) {
    return () -> thingable;
  }
}
package delegate;

public final class Delegate implements Thingable {
  @Override
  public String thing() {
    return "delegate implementation";
  }
}
package delegate;

// Example usage
// Memory management ignored for simplification
public interface DelegateTest {
  public static String thingable() {
    return "method reference implementation";
  }

  public static void main(String... arguments) {
    // Without a delegate:
    Delegator d1 = Delegator.new_();
    assert d1.operation().equals("default implementation");

    // With a delegate:
    Delegator d2 = d1.delegate(new Delegate());
    assert d2.operation().equals("delegate implementation");

    // Same as the above, but with an anonymous class:
    Delegator d3 = d2.delegate(new Thingable() {
      @Override
      public String thing() {
        return "anonymous delegate implementation";
      }
    });
    assert d3.operation().equals("anonymous delegate implementation");

    // Same as the above, but with a method reference:
    Delegator d4 = d3.delegate(DelegateTest::thingable);
    assert d4.operation().equals("method reference implementation");

    // Same as the above, but with a lambda expression:
    Delegator d5 = d4.delegate(() -> "lambda expression implementation");
    assert d5.operation().equals("lambda expression implementation");
  }
}

JavaScript

Translation of: Python
function Delegator() {
  this.delegate = null ;
  this.operation = function(){
    if(this.delegate && typeof(this.delegate.thing) == 'function')
      return this.delegate.thing() ;
    return 'default implementation' ;
  }
}

function Delegate() {
  this.thing = function(){
    return 'Delegate Implementation' ;
  }
}

function testDelegator(){
  var a = new Delegator() ;
  document.write(a.operation() + "\n") ;
  
  a.delegate = 'A delegate may be any object' ; 
  document.write(a.operation() + "\n") ;
  
  a.delegate = new Delegate() ;
  document.write(a.operation() + "\n") ;
}

Julia

Module:

module Delegates

export Delegator, Delegate

struct Delegator{T}
    delegate::T
end

struct Delegate end

operation(x::Delegator) = thing(x.delegate)
thing(::Any) = "default implementation"
thing(::Delegate) = "delegate implementation"

end  # module Delegates

Main:

using .Delegates

a = Delegator(nothing)
b = Delegator("string")

d = Delegate()
c = Delegator(d)

@show Delegates.operation(a)
@show Delegates.operation(b)
@show Delegates.operation(c)
Output:
Delegates.operation(a) = "default implementation"
Delegates.operation(b) = "default implementation"
Delegates.operation(c) = "delegate implementation"

Kotlin

Whilst Kotlin supports class delegation 'out of the box', the delegate and delegator both have to implement a particular interface and the delegate cannot be optional or null.

The first two scenarios are not therefore strictly possible though the second can be simulated by passing a 'responds' parameter to the delegate class constructor.

// version 1.1.51

interface Thingable {
    fun thing(): String?
}

class Delegate(val responds: Boolean) : Thingable {
    override fun thing() = if (responds) "delegate implementation" else null
}

class Delegator(d: Delegate) : Thingable by d {
    fun operation() = thing() ?: "default implementation"
}

fun main(args: Array<String>) {
    // delegate doesn't respond to 'thing'
    val d = Delegate(false)
    val dd = Delegator(d)
    println(dd.operation())

    // delegate responds to 'thing'
    val d2 = Delegate(true)
    val dd2 = Delegator(d2)
    println(dd2.operation())
}
Output:
default implementation
delegate implementation

Latitude

Translation of: Python
Delegator ::= Object clone tap {
  self delegate := Nil.
  self clone := {
    Parents above (parent self, 'clone) call tap {
      self delegate := #'(self delegate).
    }.
  }.
  self operation := {
    localize.
    if { this delegate slot? 'thing. } then {
      this delegate thing.
    } else {
      "default implementation".
    }.
  }.
}.

Delegate ::= Object clone tap {
  self thing := "delegate implementation".
}.

;; No delegate
foo := Delegator clone.
println: foo operation. ;; "default implementation"

;; Delegate which lacks `thing`
foo delegate := Object.
println: foo operation. ;; "default implementation"

;; Delegate which implements `thing`
foo delegate := Delegate.
println: foo operation. ;; "delegate implementation"

Logtalk

We use prototypes instead of classes for simplicity.

% define a category for holding the interface
% and implementation for delegator objects

:- category(delegator).

    :- public(delegate/1).
    :- public(set_delegate/1).

    :- private(delegate_/1).
    :- dynamic(delegate_/1).

    delegate(Delegate) :-
        ::delegate_(Delegate).

    set_delegate(Delegate) :-
        ::retractall(delegate_(Delegate)),
        ::assertz(delegate_(Delegate)).

:- end_category.

% define a simpler delegator object, with a
% method, operation/1, for testing delegation

:- object(a_delegator,
    imports(delegator)).

    :- public(operation/1).

    operation(String) :-
        (   ::delegate(Delegate), Delegate::current_predicate(thing/1) ->
            % a delegate is defined that understands the method thing/1
            Delegate::thing(String)
        ;   % otherwise just use the default implementation
            String = 'default implementation'
        ).

:- end_object.

% define an interface for delegate objects 

:- protocol(delegate).

    :- public(thing/1).

:- end_protocol.

% define a simple delegate

:- object(a_delegate,
    implements(delegate)).

    thing('delegate implementation').

:- end_object.

% define a simple object that doesn't implement the "delegate" interface

:- object(an_object).

:- end_object.

% test the delegation solution when this file is compiled and loaded

:- initialization((
    % without a delegate:
    a_delegator::operation(String1),
    String1 == 'default implementation',
    % with a delegate that does not implement thing/1:
    a_delegator::set_delegate(an_object),
    a_delegator::operation(String2),
    String2 == 'default implementation',
    % with a delegate that implements thing/1:
    a_delegator::set_delegate(a_delegate),
    a_delegator::operation(String3),
    String3 == 'delegate implementation'
)).

Lua

local function Delegator()
  return {
    operation = function(self)
      if (type(self.delegate)=="table") and (type(self.delegate.thing)=="function") then
        return self.delegate:thing()
      else
        return "default implementation"
      end
    end
  }
end

local function Delegate()
  return {
    thing = function(self)
      return "delegate implementation"
    end
  }
end

local function NonDelegate(which)
  if (which == 1) then return true -- boolean
  elseif (which == 2) then return 12345 -- number
  elseif (which == 3) then return "Hello" -- string
  elseif (which == 4) then return function() end -- function
  elseif (which == 5) then return { nothing = function() end } -- table (without "thing")
  elseif (which == 6) then return coroutine.create(function() end) -- thread
  elseif (which == 7) then return io.open("delegates.lua","r") -- userdata (if exists, or nil)
  end
end

-- WITH NO (NIL) DELEGATE
local d = Delegator()
assert(d:operation() == "default implementation")

-- WITH A NON-DELEGATE
for i = 1, 7 do
  d.delegate = NonDelegate(i)
  assert(d:operation() == "default implementation")
end

-- WITH A PROPER DELEGATE
d.delegate = Delegate()
assert(d:operation() == "delegate implementation")

print("pass")

M2000 Interpreter

Module Checkit {
	\\ there are some kinds of objects in M2000, one of them is the Group, the user object
	\\ the delegate is a pointer to group
	\\ 1. We pass parameters to function operations$(), $ means that this function return string value
	\\ 2. We see how this can be done with pointers to group
	global doc$  \\ first define a global (for this module) to log output
	document doc$="Output:"+{
	}
	class Delegator {
	private:
		group delegate
		group null
	public:
		function operation$ {
			if not .delegate is .null then
				try ok {
					ret$="Delegate implementation:"+.delegate=>operation$(![])
					\\ [] is the stack of values (leave empty stack), ! used to place this to callee stack
				}
				if not ok or error then ret$="No implementation"
			else
				ret$= "Default implementation"
			end if
			\\ a global  variable and all group members except arrays use <= not =. Simple = used for declaring local variables
			doc$<=ret$+{
			}
			=ret$
		}	
	class:
		Module Delegator {
				class none {}
				.null->none()
				If match("G") then .delegate->(group) else .delegate<=.null
		}
	}
	 
	Class Thing {
		function operation$(a,b) {
			=str$(a*b)
		}	
	}
	Module CallbyReference (&z as group) {
		Print Z.operation$(5,30)
	}
	Module CallbyValue (z as group) {
		Print Z.operation$(2,30)
	}
	Module CallbyReference2 (&z as pointer) {
		Print Z=>operation$(5,30)
	}
	Module CallbyValue2 (z as pointer) {
		Print Z=>operation$(2,30)
	}
	\\ Normal Group  ' no logging to doc$
	N=Thing()
	Print N.operation$(10,20)
	CallbyReference &N
	CallbyValue N
	N1->N    ' N1 is a pointer to a named group
	Print N1=>operation$(10,20)
	CallbyReference2 &N1
	CallbyValue2 N1
	N1->(N)  ' N1 now is a pointer to a float group (a copy of N)
 	Print N1=>operation$(10,20)
	CallbyReference2 &N1
	CallbyValue2 N1
	\\ using named groups (A is a group, erased when this module exit)
	A=Delegator()
	B=Delegator(Thing())
	Print A.operation$(10,20)
	Print B.operation$(10,20)
	A=B
	CallbyReference &A
	CallbyValue A
	\\ M2000 has two kinds of pointers to groups
	\\ one is a pointer to a no named group (a float group)
	\\ a float group leave until no pointer refer to it
	\\ using pointers to groups (A1 is a pointer to Group)
	A1->Delegator()
	B1->Delegator(Thing())
	Print A1=>operation$(10,20)
	Print B1=>operation$(10,20)
	A1=B1
	CallbyReference2 &A1
	CallbyValue2 A1
	\\ Second type is a pointer to a named group
	\\ the pointer hold a weak reference to named group
	\\ so a returned pointer of thid kind can be invalid if actual reference not exist
	A=Delegator() ' copy a float group to A
	A1->A
	B1->B
	Print A1=>operation$(10,20)
	Print B1=>operation$(10,20)
	A1=B1
	CallbyReference2 &A1
	CallbyValue2 A1
	Group Something {		
	}
	B=Delegator(Something)
	Print B.operation$(10,20)
	CallbyReference &B
	CallbyValue B
	Report Doc$
	Clipboard Doc$
}
Checkit
Output:
 200
 150
 60
 200
 150
 60
 200
 150
 60
Output:
Default implementation
Delegate implementation: 200
Delegate implementation: 150
Delegate implementation: 60
Default implementation
Delegate implementation: 200
Delegate implementation: 150
Delegate implementation: 60
Default implementation
Delegate implementation: 200
Delegate implementation: 150
Delegate implementation: 60
No implementation
No implementation
No implementation

Mathematica / Wolfram Language

delegator[del_]@operate := 
  If[StringQ[del@operate], del@operate, "default implementation"];
del1 = Null;
del2@banana = "phone";
del3@operate = "delegate implementation";
Print[delegator[#]@operate] & /@ {del1, del2, del3};
Output:
default implementation
default implementation
delegate implementation

NGS

{
	type Delegator

	F init(d:Delegator) d.delegate = null

	F default_impl(d:Delegator) 'default implementation'

	F operation(d:Delegator) default_impl(d)

	F operation(d:Delegator) {
		guard defined thing
		guard thing is Fun
		try {
			d.delegate.thing()
		}
		catch(e:ImplNotFound) {
			# Might be unrelated exception, so check and optionally rethrow
			e.callable !== thing throws e
			default_impl(d)
		}
	}

	F operation(d:Delegator) {
		guard d.delegate is Null
		default_impl(d)
	}


	a = Delegator()
	echo(a.operation())

	# There is no method thing(s:Str)
	a.delegate = "abc"
	echo(a.operation())

	# ... now there is method thing(s:Str)
	F thing(s:Str) 'delegate implementation'
	echo(a.operation())
	
}
Output:
default implementation
default implementation
delegate implementation

Nim

####################################################################################################
# Base delegate.

type Delegate = ref object of RootObj
  nil

method thing(d: Delegate): string {.base.} =
  ## Default implementation of "thing".
  ## Using a method rather than a proc allows dynamic dispatch.
  "default implementation"


####################################################################################################
# Delegator.

type Delegator = object
  delegate: Delegate

proc initDelegator(d: Delegate = nil): Delegator =
  ## Create a delegator with given delegate or nil.
  if d.isNil:
    Delegator(delegate: Delegate())     # Will use a default delegate instance.
  else:
    Delegator(delegate: d)              # Use the provided delegate instance.

proc operation(d: Delegator): string =
  ## Calls the delegate.
  d.delegate.thing()


####################################################################################################
# Usage.

let d = initDelegator()
echo "Without any delegate: ", d.operation()

type Delegate1 = ref object of Delegate

let d1 = initDelegator(Delegate1())
echo "With a delegate which desn’t provide the “thing” method: ", d1.operation()

type Delegate2 = ref object of Delegate

method thing(d: Delegate2): string =
  "delegate implementation"

let d2 = initDelegator(Delegate2())
echo "With a delegate which provided the “thing” method: ", d2.operation()
Output:
Without any delegate: default implementation
With a delegate which desn’t provide the “thing” method: default implementation
With a delegate which provided the “thing” method: delegate implementation

Objeck

Translation of: Java
interface Thingable {
  method : virtual : public : Thing() ~ String;
}
 
class Delegator {
  @delegate : Thingable;

  New() {
  }   

  method : public : SetDelegate(delegate : Thingable) ~ Nil {
    @delegate := delegate;
  }

  method : public : Operation() ~ String {
    if(@delegate = Nil) {
      return "default implementation";
    }
    else {
      return @delegate->Thing();
    };
  }
}

class Delegate implements Thingable {
  New() {
  }   

  method : public : Thing() ~ String {
    return "delegate implementation";
  }
}

class Example {
  function : Main(args : String[]) ~ Nil {
    # Without a delegate:
    a := Delegator->New();
    Runtime->Assert(a->Operation()->Equals("default implementation"));
 
    # With a delegate:
    d := Delegate->New();
    a->SetDelegate(d);
    Runtime->Assert(a->Operation()->Equals("delegate implementation"));

    # Same as the above, but with an anonymous class:
    a->SetDelegate(Base->New() implements Thingable {
      method : public : Thing() ~ String {
        return "anonymous delegate implementation";
      }
    });

    Runtime->Assert(a->Operation()->Equals("anonymous delegate implementation"));
  }
}

Objective-C

Classic Objective-C

Works with: Cocoa
Works with: GNUstep
#import <Foundation/Foundation.h>

@interface Delegator : NSObject {

    id delegate;
}

- (id)delegate;
- (void)setDelegate:(id)obj;
- (NSString *)operation;

@end

@implementation Delegator

- (id)delegate {

    return delegate;
}

- (void)setDelegate:(id)obj {

    delegate = obj; // Weak reference
}

- (NSString *)operation {

    if ([delegate respondsToSelector:@selector(thing)])
        return [delegate thing];

    return @"default implementation";
}

@end

// Any object may implement these
@interface NSObject (DelegatorDelegating)

- (NSString *)thing;

@end

@interface Delegate : NSObject

// Don't need to declare -thing because any NSObject has this method

@end

@implementation Delegate

- (NSString *)thing {

    return @"delegate implementation";
}

@end

// Example usage
// Memory management ignored for simplification
int main() {

    // Without a delegate:
    Delegator *a = [[Delegator alloc] init];
    NSLog(@"%d\n", [[a operation] isEqualToString:@"default implementation"]);

    // With a delegate that does not implement thing:
    [a setDelegate:@"A delegate may be any object"];
    NSLog(@"%d\n", [[a operation] isEqualToString:@"delegate implementation"]);

    // With a delegate that implements "thing":
    Delegate *d = [[Delegate alloc] init];
    [a setDelegate:d];
    NSLog(@"%d\n", [[a operation] isEqualToString:@"delegate implementation"]);

    return 0;
}

Objective-C 2.0, modern runtime, Automatic Reference Counting, Autosynthesize (LLVM 4.0+)

Works with: Cocoa
#import <Foundation/Foundation.h>

// Formal protocol for the delegate
@protocol DelegatorDelegatingProtocol
    - (NSString *)thing;
@end

@interface Delegator : NSObject
    @property (weak) id delegate;
    - (NSString *)operation;
@end
@implementation Delegator
    - (NSString *)operation {
        if ([self.delegate respondsToSelector: @selector(thing)])
            return [self.delegate thing];

        return @"default implementation";
    }
@end

@interface Delegate : NSObject
    <DelegatorDelegatingProtocol>
@end
@implementation Delegate
    - (NSString *)thing { return @"delegate implementation"; }
@end

// Example usage with Automatic Reference Counting
int main() {
    @autoreleasepool {
        // Without a delegate:
        Delegator *a = [Delegator new];
        NSLog(@"%@", [a operation]);    // prints "default implementation"

        // With a delegate that does not implement thing:
        a.delegate = @"A delegate may be any object";
        NSLog(@"%@", [a operation]);    // prints "default implementation"

        // With a delegate that implements "thing":
        Delegate *d = [Delegate new];
        a.delegate = d;
        NSLog(@"%@", [a operation]);    // prints "delegate implementation"
    }
    return 0;
}

Oforth

Object Class new: Delegate1
 
Object Class new: Delegate2
Delegate2 method: thing  "Delegate implementation" println ;
 
Object Class new: Delegator(delegate)
Delegator method: initialize  := delegate ;
 
Delegator method: operation
   @delegate respondTo(#thing) ifTrue: [ @delegate thing return ]
   "Default implementation" println ;

Usage :

Delegator new(null) operation
Default implementation

Delegator new(Delegate1 new) operation
Default implementation

Delegator new(Delegate2 new) operation
Delegate implementation

ooRexx

delegator = .delegator~new   -- no delegate
say delegator~operation
-- an invalid delegate type
delegator~delegate = "Some string"
say delegator~operation
-- a good delegate
delegator~delegate = .thing~new
say delegator~operation
-- a directory object with a thing entry defined
d = .directory~new
d~thing = "delegate implementation"
delegator~delegate = d
say delegator~operation

-- a class we can use as a delegate
::class thing
::method thing
  return "delegate implementation"

::class delegator
::method init
  expose delegate
  use strict arg delegate = .nil

::attribute delegate

::method operation
  expose delegate
  if delegate == .nil then return "default implementation"

  -- Note:  We could use delegate~hasMethod("THING") to check
  -- for a THING method, but this will fail of the object relies
  -- on an UNKNOWN method to handle the method.  By trapping
  -- NOMETHOD conditions, we can allow those calls to go
  -- through
  signal on nomethod
  return delegate~thing

nomethod:
  return "default implementation"

OxygenBasic

class DelegateA 'not implmenting thing()
'==============
'
string message

end class

class DelegateB 'implementing thing()
'==============
'
string message

method thing() as string
return message
end method
'
end class


Class Delegator
'==============
'
has DelegateA dgA
has DelegateB dgB
'
method operation() as DelegateB
dgB.message="Delegate Implementation"
return @dgB
end method

method thing() as string
return "not using Delegate"
end method
'
end class

'====
'TEST
'====

Delegator dgr
let dg=dgr.operation
print dgr.thing 'result "not using Delegate"
print dg.thing  'result "Delegate Implementation"

Oz

Translation of: Python
declare
  class Delegator from BaseObject
     attr
	delegate:unit

     meth set(DG)
	{Object.is DG} = true %% assert: DG must be an object
	delegate := DG
     end

     meth operation($)
	if @delegate == unit then
	   {self default($)}
	else
	   try
	      {@delegate thing($)}
	   catch error(object(lookup ...) ...) then
	      %% the delegate did not understand the message
	      {self default($)}
	   end
	end
     end

     meth default($)
	"default implementation"
     end
  end
 
  class Delegate from BaseObject
     meth thing($)
	"delegate Implementation"
     end
  end
 
  A = {New Delegator noop}  
in
  {System.showInfo {A operation($)}}

  {A set({New BaseObject noop})}
  {System.showInfo {A operation($)}}

  {A set({New Delegate noop})}  
  {System.showInfo {A operation($)}}

Pascal

See Delphi

Perl

Translation of: Python
use strict;

package Delegator;
sub new {
   bless {}
}
sub operation {
   my ($self) = @_;
   if (defined $self->{delegate} && $self->{delegate}->can('thing')) {
      $self->{delegate}->thing;
   } else {
      'default implementation';
   }
}
1;

package Delegate;
sub new {
   bless {};
}
sub thing {
   'delegate implementation'
}
1;


package main;
# No delegate
my $a = Delegator->new;
$a->operation eq 'default implementation' or die;

# With a delegate that does not implement "thing"
$a->{delegate} = 'A delegate may be any object';
$a->operation eq 'default implementation' or die;

# With delegate that implements "thing"
$a->{delegate} = Delegate->new;
$a->operation eq 'delegate implementation' or die;

Using Moose.

use 5.010_000;

package Delegate::Protocol
use Moose::Role;
# All methods in the Protocol is optional
#optional  'thing';
# If we wanted to have a required method, we would state:
# requires 'required_method';
#

package Delegate::NoThing;
use Moose;
with 'Delegate::Protocol';

package Delegate;
use Moose;

#  The we confirm to Delegate::Protocol
with 'Delegate::Protocol';
sub thing { 'delegate implementation' };

package Delegator;
use Moose;

has delegate => (
     is      => 'rw',
    does => 'Delegate::Protocol', # Moose insures that the delegate confirms to the protocol.
   predicate => 'hasDelegate'
);

sub operation {
   
    my ($self) = @_;
    if( $self->hasDelegate  && $self->delegate->can('thing') ){
        return $self->delegate->thing() . $postfix; # we are know that delegate has thing.
    } else {
        return 'default implementation';
   }
};

package main;
use strict;

# No delegate
my $delegator = Delegator->new();
$delegator->operation eq 'default implementation' or die;

# With a delegate that does not implement "thing"
$delegator->delegate(  Delegate::NoThing->new );
$delegator->operation eq 'default implementation' or die;

# With delegate that implements "thing"
$delegator->delegate(  Delegate->new );
$delegator->operation eq 'delegate implementation' or die;

Phix

Phix is not object orientated, instead I would just use a routine_id for this sort of thing.
I will admit that the whole concept of "no delegate/with one that does not implement" makes no sense whatsoever to me.
While I've shown this using a single rid, you could of course hold an entire sequence of them or even better a dictionary and use named lookups for rids in that.

enum OTHER, OPERATION

function operation(object o)
    integer rid = o[OPERATION]
    if rid!=NULL then
        return call_func(rid,{})
    end if
    return "no implementation"
end function

function xthing()
    return "default implementation"
end function

function newX()
    return {1,routine_id("xthing"),2}
end function

function newY()
    object res = newX()
    res[OTHER] = "something else"
    -- remove delegate:
    res[OPERATION] = NULL
    return res
end function

function zthing()
    return "delegate implementation"
end function

function newZ()
    object res = newX()
    -- replace delegate:
    res[OPERATION] = routine_id("zthing")
    return res
end function

object x = newX(),
       y = newY(),
       z = newZ()

?operation(x)
?operation(y)
?operation(z)
Output:
"default implementation"
"no implementation"
"delegate implementation"

Obviously, you can explictly test for rid=NULL as shown, or remove that test and catch exceptions, ie:

?operation(x)
try -- (since rid=NULL check commented out)
    ?operation(y)
catch e
    ?"oops, no implementation"
end try
?operation(z)

PHP

Translation of: Python
class Delegator {
  function __construct() {
    $this->delegate = NULL ;
  }
  function operation() {
    if(method_exists($this->delegate, "thing"))
      return $this->delegate->thing() ;
    return 'default implementation' ;
  }
}

class Delegate {
  function thing() {
    return 'Delegate Implementation' ;
  }
}

$a = new Delegator() ;
print "{$a->operation()}\n" ;

$a->delegate = 'A delegate may be any object' ;
print "{$a->operation()}\n" ;

$a->delegate = new Delegate() ;
print "{$a->operation()}\n" ;

PicoLisp

(class +Delegator)
# delegate

(dm operation> ()
   (if (: delegate)
      (thing> @)
      "default implementation" ) )


(class +Delegate)
# thing

(dm T (Msg)
   (=: thing Msg) )

(dm thing> ()
   (: thing) )


(let A (new '(+Delegator))
   # Without a delegate
   (println (operation> A))

   # With delegate that does not implement 'thing>'
   (put A 'delegate (new '(+Delegate)))
   (println (operation> A))

   # With delegate that implements 'thing>'
   (put A 'delegate (new '(+Delegate) "delegate implementation"))
   (println (operation> A)) )

Output:

"default implementation"
NIL
"delegate implementation"

Pop11

uses objectclass;
define :class Delegator;
    slot delegate = false;
enddefine;

define :class Delegate;
enddefine;

define :method thing(x : Delegate);
   'delegate implementation'
enddefine;

define :method operation(x : Delegator);
if delegate(x) and fail_safe(delegate(x), thing) then
   ;;; Return value is on the stack
else
   'default implementation'
endif;
enddefine;

;;; Default, without a delegate
lvars a = newDelegator();
operation(a) =>

;;; a delegating to itself (works because Delegator does not
;;; implement thing)
a -> delegate(a);
operation(a) =>

;;; delegating to a freshly created Delegate
newDelegate() -> delegate(a);
operation(a) =>

Python

class Delegator:
   def __init__(self):
      self.delegate = None
   def operation(self):
       if hasattr(self.delegate, 'thing') and callable(self.delegate.thing):
          return self.delegate.thing()
       return 'default implementation'

class Delegate:
   def thing(self):
      return 'delegate implementation'

if __name__ == '__main__':

   # No delegate
   a = Delegator()
   assert a.operation() == 'default implementation'

   # With a delegate that does not implement "thing"
   a.delegate = 'A delegate may be any object'
   assert a.operation() == 'default implementation'

   # With delegate that implements "thing"
   a.delegate = Delegate()
   assert a.operation() == 'delegate implementation'

Racket

[object-method-arity-includes?] tests for the existence of the method in an object. [is-a?] can be used to test for a class instance or interface implementor; and is probably more likely to be used in anger. But object-method-arity-includes? can be used generally; and actually follows the requirement of the task better.

#lang racket
;; Delegates. Tim Brown 2014-10-16

(define delegator%
  (class object%
    (init-field [delegate #f])
    (define/public (operation)
      (cond [(and (object? delegate) (object-method-arity-includes? delegate 'thing 0))
             (send delegate thing)]
            [else "default implementation"]))
    (super-new)))

(define non-thinging-delegate% (class object% (super-new)))

(define thinging-delegate%
  (class object%
    (define/public (thing) "delegate implementation")
    (super-new)))

(module+ test
  (require tests/eli-tester)
  (define delegator-1 (new delegator%))
  (define delegator-2 (new delegator%))
  (define non-thinging-delegate (new non-thinging-delegate%))
  (define thinging-delegate     (new thinging-delegate%))
  
  (test
   (send delegator-1 operation) => "default implementation"
   (send delegator-2 operation) => "default implementation"
   (set-field! delegate delegator-1 non-thinging-delegate) => (void)
   (set-field! delegate delegator-2 thinging-delegate)     => (void)
   (send delegator-1 operation) => "default implementation"
   (send delegator-2 operation) => "delegate implementation"
   (send (new delegator% [delegate thinging-delegate]) operation) => "delegate implementation"))

All the tests pass. Believe me.

Raku

(formerly Perl 6)

class Non-Delegate  { }

class Delegate {
	method thing {
		return "delegate implementation"
	}
}

class Delegator {
	has $.delegate is rw;

	method operation {
		$.delegate.^can( 'thing' ) ?? $.delegate.thing
		!! "default implementation"
	}
}

my Delegator $d .= new;

say "empty: "~$d.operation;

$d.delegate = Non-Delegate.new;

say "Non-Delegate: "~$d.operation;

$d.delegate = Delegate.new;

say "Delegate: "~$d.operation;

Ruby

Translation of: Python
class Delegator
   attr_accessor :delegate
   def operation
      if @delegate.respond_to?(:thing)
         @delegate.thing
      else
         'default implementation'
      end
   end
end

class Delegate
   def thing
      'delegate implementation'
   end
end

if __FILE__ == $PROGRAM_NAME

   # No delegate
   a = Delegator.new
   puts a.operation # prints "default implementation"

   # With a delegate that does not implement "thing"
   a.delegate = 'A delegate may be any object'
   puts a.operation # prints "default implementation"

   # With delegate that implements "thing"
   a.delegate = Delegate.new
   puts a.operation # prints "delegate implementation"
end

Using Forwardable lib

require 'forwardable'

class Delegator; extend Forwardable
  attr_accessor :delegate
  def_delegator :@delegate, :thing, :delegated

  def initialize
    @delegate = Delegate.new()
  end
end

class Delegate
  def thing
    'Delegate'
  end
end

a = Delegator.new
puts a.delegated # prints "Delegate"

Rust

Requiring delegates to implement Thingable:

trait Thingable {
    fn thing(&self) -> &str;
}

struct Delegator<T>(Option<T>);

struct Delegate {}

impl Thingable for Delegate {
    fn thing(&self) -> &'static str {
        "Delegate implementation"
    }
}

impl<T: Thingable> Thingable for Delegator<T> {
    fn thing(&self) -> &str {
        self.0.as_ref().map(|d| d.thing()).unwrap_or("Default implmementation")
    }
}

fn main() {
    let d: Delegator<Delegate> = Delegator(None);
    println!("{}", d.thing());
    
    let d: Delegator<Delegate> = Delegator(Some(Delegate {}));
    println!("{}", d.thing());
}
Output:
Default implmementation
Delegate implementation

Using nightly-only specialization feature:

#![feature(specialization)]

trait Thingable {
    fn thing(&self) -> &str;
}

struct Delegator<T>(Option<T>);

struct Delegate {}

impl Thingable for Delegate {
    fn thing(&self) -> &'static str {
        "Delegate implementation"
    }
}

impl<T> Thingable for Delegator<T> {
    default fn thing(&self) -> &str {
        "Default implementation"
    }
}

impl<T: Thingable> Thingable for Delegator<T> {
    fn thing(&self) -> &str {
        self.0.as_ref().map(|d| d.thing()).unwrap_or("Default implmementation")
    }
}

fn main() {
    let d: Delegator<i32> = Delegator(None);
    println!("{}", d.thing());
    
    let d: Delegator<i32> = Delegator(Some(42));
    println!("{}", d.thing());
    
    let d: Delegator<Delegate> = Delegator(None);
    println!("{}", d.thing());
    
    let d: Delegator<Delegate> = Delegator(Some(Delegate {}));
    println!("{}", d.thing());
}
Output:
Default implementation
Default implementation
Default implmementation
Delegate implementation

Scala

Output:

Best seen running in your browser either by ScalaFiddle (ES aka JavaScript, non JVM) or Scastie (remote JVM).

trait Thingable {
  def thing: String
}

class Delegator {
  var delegate: Thingable = _

  def operation: String = if (delegate == null) "default implementation"
  else delegate.thing
}

class Delegate extends Thingable {
  override def thing = "delegate implementation"
}

// Example usage
// Memory management ignored for simplification
object DelegateExample extends App {

  val a = new Delegator
  assert(a.operation == "default implementation")
  // With a delegate:
  val d = new Delegate
  a.delegate = d
  assert(a.operation == "delegate implementation")
  // Same as the above, but with an anonymous class:
  a.delegate = new Thingable() {
    override def thing = "anonymous delegate implementation"
  }
  assert(a.operation == "anonymous delegate implementation")

}

Sidef

class NonDelegate { }

class Delegate {
    method thing {
        return "delegate implementation"
    }
}

class Delegator (delegate = null) {
    method operation {

        if (delegate.respond_to(:thing)) {
            return delegate.thing
        }

        return "default implementation"
    }
}

var d = Delegator()
say "empty: #{d.operation}"
d.delegate = NonDelegate()
say "NonDelegate: #{d.operation}"
d.delegate = Delegate()
say "Delegate: #{d.operation}"
Output:
empty: default implementation
NonDelegate: default implementation
Delegate: delegate implementation

Smalltalk

Works with: Smalltalk/X

Definition of the thingy:

Object 
 subclass:#Thingy
 instanceVariableNames:''

thing
    ^ 'thingy implementation'

Definition of the delegator:

Object 
 subclass:#Delegator
 instanceVariableNames:'delegate'

delegate:something
    delegate := something

operation
    ^ delegate 
        perform:#thing ifNotUnderstood:'default implementation'.

Sample use:

|d|
d := Delegator new.
d operation.
-> 'default implementation'

d delegate:(Thingy new).
d operation.
-> 'thingy implementation'

Swift

Allowing the delegate to be any type and taking advantage of dynamism of method lookup:

import Foundation

protocol Thingable { // prior to Swift 1.2, needs to be declared @objc
  func thing() -> String
}

class Delegator {
  weak var delegate: AnyObject?
  func operation() -> String {
    if let f = self.delegate?.thing {
      return f()
    } else {
      return "default implementation"
    }
  }
}

class Delegate {
  dynamic func thing() -> String { return "delegate implementation" }
}

// Without a delegate:
let a = Delegator()
println(a.operation())    // prints "default implementation"

// With a delegate that does not implement thing:
a.delegate = "A delegate may be any object"
println(a.operation())    // prints "default implementation"

// With a delegate that implements "thing":
let d = Delegate()
a.delegate = d
println(a.operation())    // prints "delegate implementation"


Alternately, requiring the delegate to conform to a given protocol:

protocol Thingable : class {
  func thing() -> String
}

class Delegator {
  weak var delegate: Thingable?
  func operation() -> String {
    if let d = self.delegate {
      return d.thing()
    } else {
      return "default implementation"
    }
  }
}

class Delegate : Thingable {
  func thing() -> String { return "delegate implementation" }
}

// Without a delegate:
let a = Delegator()
println(a.operation())    // prints "default implementation"

// With a delegate:
let d = Delegate()
a.delegate = d
println(a.operation())    // prints "delegate implementation"

Tcl

Works with: Tcl version 8.6

or

Library: TclOO

Uses Assertions#Tcl

package require TclOO

oo::class create Delegate {
    method thing {} {
        return "delegate impl."
    }
    export thing
}

oo::class create Delegator {
    variable delegate
    constructor args {
        my delegate {*}$args
    }
    
    method delegate args {
        if {[llength $args] == 0} {
            if {[info exists delegate]} {
                return $delegate
            }
        } elseif {[llength $args] == 1} {
            set delegate [lindex $args 0]
        } else {
            return -code error "wrong # args: should be \"[self] delegate ?target?\""
        }
    }
    
    method operation {} {
        try {
            set result [$delegate thing]
        } on error e {
            set result "default implementation"
        }
        return $result
    }
}

# to instantiate a named object, use: class create objname; objname aMethod
# to have the class name the object:  set obj [class new]; $obj aMethod

Delegator create a
set b [Delegator new "not a delegate object"]
set c [Delegator new [Delegate new]]

assert {[a operation] eq "default implementation"}   ;# a "named" object, hence "a ..."
assert {[$b operation] eq "default implementation"}  ;# an "anonymous" object, hence "$b ..."
assert {[$c operation] ne "default implementation"}

# now, set a delegate for object a
a delegate [$c delegate]
assert {[a operation] ne "default implementation"}

puts "all assertions passed"

To code the operation method without relying on catching an exception, but strictly by using introspection:

method operation {} {
    if { [info exists delegate] &&
         [info object isa object $delegate] &&
         "thing" in [info object methods $delegate -all]
    } then {
        set result [$delegate thing]
    } else {
        set result "default implementation"
    }
}

TXR

;; TXR Lisp's :delegate implementation is hard delegation: the indicated
;; delegate object must exist and take the method call. To do soft
;; delegation, we develop a macro (delegate-or-fallback x y z)
;; which chooses x if x is an object which supports a z method,
;; or else chooses y.

(defun delegate-or-fallback-impl (del-inst fb-inst required-meth)
  (let (del-type)
    (if (and (structp del-inst)
             (set del-type (struct-type del-inst))
             (static-slot-p del-type required-meth)
             (functionp (static-slot del-type required-meth)))
      del-inst
      fb-inst)))

(defmacro delegate-or-fallback (delegate-expr fallback-obj : required-meth)
  ^(delegate-or-fallback-impl ,delegate-expr ,fallback-obj ',required-meth))

;; With the above, we can use the defstruct delegate clause syntax:
;; 
;;  (:delegate source-method (obj) target-obj target-method)
;;
;; which writes a delegate method called source-method, that delegates
;; to target-method on target-obj. We calculate target-obj using
;; our macro and ensure that the delegator itself imlpements target-method.

(defstruct delegator ()
  delegate
  (:delegate operation (me) (delegate-or-fallback me.delegate me thing) thing)

  (:method thing (me)
    "default implementation"))

(defstruct delegate ()
  (:method thing (me)
    "delegate implementation"))

;; Tests:

;; no delegate
(prinl (new delegator).(operation))

;; struct delegate, but not with thing method
(prinl (new delegator delegate (new time)).(operation))

;; delegate with thing method
(prinl (new delegator delegate (new delegate)).(operation))
Output:
"default implementation"
"default implementation"
"delegate implementation"

Vorpal

Delegate objects can be an array of delegates or as a single delegate.

a = new()
a.f = method(){
        .x.print()
}

c = new()
c.g = method(){
        (.x + 1).print()
}

# array of delegates
b = new()
b.delegate = new()
b.delegate[0] = a
b.delegate[1] = c
b.x = 3
b.f()
b.g()

# single delegate
d = new()
d.delegate = a
d.x = 7
d.f()

The resulting output:

3
4
7

Wren

Wren is dynamically typed so we can plug any kind of delegate into the Delegator.

class Thingable {
    thing { }
}

// Delegate that doesn't implement Thingable
class Delegate {
    construct new() { }
}

// Delegate that implements Thingable
class Delegate2 is Thingable {
    construct new() { }

    thing { "delegate implementation" }
}

class Delegator {
    construct new() {
        _delegate = null
    }

    delegate     { _delegate }
    delegate=(d) { _delegate = d }

    operation {
        if (!_delegate || !(_delegate is Thingable)) return "default implementation"
        return _delegate.thing
    }
}

// without a delegate
var d = Delegator.new()
System.print(d.operation)

// with a delegate that doesn't implement Thingable
d.delegate = Delegate.new()
System.print(d.operation)

// with a delegate that does implement Thingable
d.delegate = Delegate2.new()
System.print(d.operation)
Output:
default implementation
default implementation
delegate implementation

zkl

Translation of: Scala
class Thingable{ var thing; }
 
class Delegator{
   var delegate;
   fcn operation{
      if (delegate) delegate.thing;
      else "default implementation"
   }
}
 
class Delegate(Thingable){ thing = "delegate implementation" }
    // Without a delegate:
a:= Delegator();
a.operation().println(); //--> "default implementation"

    // With a delegate:
a.delegate = Delegate();
a.operation().println(); //-->"delegate implementation"

A second example

class [static] Logger{ // Only one logging resource
   var [mixin=File] dst; // File like semantics, eg Data, Pipe
   dst = File.DevNull;
   // initially, the logger does nothing
   fcn log(msg){dst.writeln(vm.pasteArgs())}
}
Logger.log("this is a test"); //-->nada
Logger.dst=Console;
Logger.log("this is a test 2"); //-->writes to Console

class B(Logger){ log("Hello from ",self,"'s constructor"); }
B(); //-->Hello from Class(B)'s constructor

The base class B was constructed at startup, so the first Hello went to DevNull as all base classes are created before code runs (base classes are used to create class instances, eg B()).