Groovy's "optional return" semantics - groovy

In Groovy, the return statement is optional, allowing you to write methods like:
def add(a, b) {
a + b
}
...which adds a and b and returns the result to the caller.
However, I'm wondering what the semantics are when the method has multiple return "statements". For example, in Java you might have:
String append(String a, String b) {
if (a == null) {
return b;
}
return a + b;
}
This could (hypothetically) be translated to Groovy like:
def append(a, b) {
if (! a) {
b
}
a + b
}
However, in this case, how does Groovy know that b inside of the if statement should be returned? Or does it not? I assume that Groovy cannot simply treat any statement whose result is unused as a return, correct? Are there any clearly defined semantics for how the "optional return" feature behaves in this case?

The page you linked (rather tersely) describes the exact semantics:
Notice that the return statement is optional at the end of methods.
So the b in that if block would never be returned unless you explicitly returned it. In practice this means that the return value will be the result of the last statement evaluated, so if your example were
def append(a, b) {
if (!a) { b }
else { a + b }
}
Then the result would be b if !a is true and a + b otherwise.
The result of a call to a void function is null, so if the example were
def append(a,b) {
if (!a) { b }
else { a + b }
println "debug: $a $b"
}
Then append would always return null.
My own rule of thumb for this is to always use an explicit return statement if the method or closure contains more than one statement. I think relying on the implicit return statement in more complex methods is dangerous since if anyone adds a line to the end of the method they will change the return value even though they most likely didn't intend to.

Related

Eager interpolation with just a closure behaves like a lazy one?

As part of learning Groovy, I'm trying to explore all intricate possibilities provided by string interpolation.
One of my little experiments gave results that don't make sense to me, and now I'm wondering whether I've completely misunderstood the basic concepts of lazy and eager interpolation in Groovy.
Here's the code I ran:
def myVar1 = 3
// An eager interpolation containing just a closure.
def myStr = "${{->myVar1}}"
print ("Just after the creation of myStr\n")
print (myStr as String)
myVar1 += 1 // Bump up myVar1.
print ("\nJust after incrementing myVar1\n")
print (myStr as String)
Here's the output I got:
Just after the creation of myStr
3
Just after incrementing myVar1
4
Clearly, the closure has been invoked a second time. And the only way the closure could have been re-executed is by the containing interpolation getting re-evaluated. But then, the containing interpolation is, by itself, not a closure, though it contains a closure. So then, why is it getting re-evaluated?
This is how GString.toString() method is implemented. If you take a look at the source code of GString class, you will find something like this:
public String toString() {
StringWriter buffer = new StringWriter();
try {
writeTo(buffer);
}
catch (IOException e) {
throw new StringWriterIOException(e);
}
return buffer.toString();
}
public Writer writeTo(Writer out) throws IOException {
String[] s = getStrings();
int numberOfValues = values.length;
for (int i = 0, size = s.length; i < size; i++) {
out.write(s[i]);
if (i < numberOfValues) {
final Object value = values[i];
if (value instanceof Closure) {
final Closure c = (Closure) value;
if (c.getMaximumNumberOfParameters() == 0) {
InvokerHelper.write(out, c.call());
} else if (c.getMaximumNumberOfParameters() == 1) {
c.call(out);
} else {
throw new GroovyRuntimeException("Trying to evaluate a GString containing a Closure taking "
+ c.getMaximumNumberOfParameters() + " parameters");
}
} else {
InvokerHelper.write(out, value);
}
}
}
return out;
}
Notice that writeTo method examines what the values passed for interpolation are, and in case of closure, it invokes it. This is the way GString handles lazy-evaluation of interpolated values.
Now let's take a look at a few examples. Let's assume we want to print a GString and interpolate a value returned by some method call. This method will also print something to the console, so we can see if the method call was triggered eagerly or lazily.
Ex.1: Eager evaluation
class GStringLazyEvaluation {
static void main(String[] args) {
def var = 1
def str = "${loadValue(var++)}"
println "Starting the loop..."
5.times {
println str
}
println "Loop ended..."
}
static Integer loadValue(int val) {
println "This method returns value $val"
return val
}
}
The output:
This method returns value 1
Starting the loop...
1
1
1
1
1
Loop ended...
The default eager behavior. The method loadValue() was invoked before we have printed out str to the console.
Ex.2: Lazy evaluation
class GStringLazyEvaluation {
static void main(String[] args) {
def var = 1
def str = "${ -> loadValue(var++)}"
println "Starting the loop..."
5.times {
println str
}
println "Loop ended..."
}
static Integer loadValue(int val) {
println "This method returns value $val"
return val
}
}
The output:
Starting the loop...
This method returns value 1
1
This method returns value 2
2
This method returns value 3
3
This method returns value 4
4
This method returns value 5
5
Loop ended...
In the second example, we take advantage of lazy evaluation. We define str with a closure that invokes loadValue() method and this invocation is executed when we explicitly print the str to the console (to be more specific - when the GString.toString() method gets executed).
Ex.3: Lazy evaluation and closure memoization
class GStringLazyEvaluation {
static void main(String[] args) {
def var = 1
def closure = { -> loadValue(var++)}
def str = "${closure.memoize()}"
println "Starting the loop..."
5.times {
println str
}
println "Loop ended..."
}
static Integer loadValue(int val) {
println "This method returns value $val"
return val
}
}
The output:
Starting the loop...
This method returns value 1
1
1
1
1
1
Loop ended...
And here is the example you most probably look for. In this example, we still take advantage of lazy evaluation thanks to the closure parameter. However, in this case, we use closure's memoization feature. The evaluation of the string is postponed to the first GString.toString() invocation and closure's result gets memorized, so the next time it gets called it returns the result instead of re-evaluating the closure.
What is the difference between ${{->myVar1}} and ${->myVar1}?
As it was mentioned earlier, GString.toString() method uses GString.writeTo(out) that checks if the given placeholder stores a closure for a lazy evaluation. Every GString instance store placeholder values in the GString.values array and it gets initialized during GString initialization. Let's consider the following example:
def str = "${myVar1} ... ${-> myVar1} ... ${{-> myVar1}}"
Now let's follow GString.values array initialization:
${myVar1} --> evaluates `myVar1` expression and copies its return value to the values array
${-> myVar1} --> it sees this is closure expression so it copies the closure to values array
${{-> myVar1}} --> evaluates `{-> myVar1}` which is closure definition expression in this case and copies its return value (a closure) to the values array
As you can see, in the 1st and 3rd example it did exactly the same - it evaluated the expression and stored it in the GString.values array of type Object[]. And here is the crucial part: the expression like {->something} is not a closure invocation expression. The expression that evaluates the closure is
{->myVar1}()
or
{->myVar1}.call()
It can be illustrated with the following example:
def str = "${println 'B'; 2 * 4} ${{ -> println 'C'; 2 * 5}} ${{ -> println 'A'; 2 * 6}.call()}"
println str
Values initialization is as follows:
${println 'B'; 2 * 4} ---> evaluates the expression which prints 'B' and returns 8 - this value is stored in values array.
${{ -> println 'C'; 2 * 5}} ---> evaluates the expression which is nothing else than creation of a closure. This closure is stored in the values array.
${{ -> println 'A'; 2 * 6}.call()}" ---> evaluates the expression which creates a closure and then calls it explicitely. It prints 'A' and returns 12 which is stored in the values array at the last index.
That is why after GString object initialization we end up with values array like:
[8, script$_main_closure1, 12]
Now, the creation of this GString caused a side effect - the following characters shown on the console:
B
A
This is because the 1st and the 3rd values evaluation invoked println method call.
Now, when we finally call println str which invokes GString.toString() method, all values get processed. When the interpolation process starts it does the following:
value[0] --> 8 --> writes "8"
value[1] --> script$_main_closure1 --> invoke script$_main_closure1.call() --> prints 'C' --> returns 10 --> 10 --> writes "10"
value[2] --> 12 --> writes "12"
That is why the final console output looks like this:
B
A
C
8 10 12
This is why in practice expressions like ${->myVar1} and ${{->myVar1}} are similar. In the first case GString initialization does not evaluate the closure expression and puts it directly to the values array, in the second example placeholder gets evaluated and the expression it evalutes creates and returns the closure which then gets stored in the values array.
Note on Groovy 3.x
If you try to execute the expression ${{->myVar1}} in Groovy 3.x you will end up with the following compiler error:
org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
General error during conversion: java.lang.NullPointerException
java.lang.NullPointerException
at org.apache.groovy.parser.antlr4.AstBuilder.lambda$visitGstring$28(AstBuilder.java:3579)
at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1382)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499)
at org.apache.groovy.parser.antlr4.AstBuilder.visitGstring(AstBuilder.java:3591)
at org.apache.groovy.parser.antlr4.AstBuilder.visitGstring(AstBuilder.java:356)
at org.apache.groovy.parser.antlr4.GroovyParser$GstringContext.accept(GroovyParser.java:4182)
at groovyjarjarantlr4.v4.runtime.tree.AbstractParseTreeVisitor.visit(AbstractParseTreeVisitor.java:20)
at org.apache.groovy.parser.antlr4.AstBuilder.visit(AstBuilder.java:4287)
.....
at org.codehaus.groovy.control.CompilationUnit.compile(CompilationUnit.java:565)
at org.codehaus.groovy.tools.FileSystemCompiler.compile(FileSystemCompiler.java:72)
at org.codehaus.groovy.tools.FileSystemCompiler.doCompilation(FileSystemCompiler.java:240)
at org.codehaus.groovy.tools.FileSystemCompiler.commandLineCompile(FileSystemCompiler.java:163)
at org.codehaus.groovy.tools.FileSystemCompiler.commandLineCompileWithErrorHandling(FileSystemCompiler.java:203)
at org.codehaus.groovy.tools.FileSystemCompiler.main(FileSystemCompiler.java:187)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.codehaus.groovy.tools.GroovyStarter.rootLoader(GroovyStarter.java:114)
at org.codehaus.groovy.tools.GroovyStarter.main(GroovyStarter.java:136)
1 error

How can I distinguish tail recursive calls/non-tail recursive calls?

int gcd(int a,int b){
if(a == b) return a;
else if (a>b) return gcd(a-b,b);
else return gcd(a,b);
}
For example, i think this is tail-recursive because you don't call another function.
int gcd(int a,int b){
int x;
if(a == b) x=a;
else if (a>b) x= gcd(a-b,b);
else x= gcd(a,b);
return x;
}
And this is non-tail recursive because it calls function gcd.
Am I right? Or is there any easier method to distinguish tail/non-tail recursive call?
First of all, for the purpose of g++ TCO (tail-call optimization) it doesn't matter if you are doing a recursive call or calling a different function altogether - function call will be replaced with unconditional jump.
Second of all, a tail call is happening when there is nothing happening between the call to other function and return. It can be last line before return, not last line before return or return itself.
For example,
} else {
x = gcd(a,b);
return x;
}
is a tail-call, because the value of x is returned unmodified (nothing is happening).
On the other hand,
} else {
x = gcd(a,b);
return x + 1;
}
This is not eligible for TCO, since return value is modified - something is happening.
But the fun just begins! Let's talk C++ and destructors. Consider following code:
int do2();
int do() {
std::string x;
// ...
return do2();
}
Is it a tail-call? First impression - yes, it is. Nothing is happening, right? Second impression - no, it is not! x destructor needs to happen! Third impression - yes, it is - because compiler, seeing as x is not used after the call, can easily destruct x before.
But, look at that:
int do2(const std::string& );
int do() {
std::string x;
// ...
return do2(x);
}
Here it is not a tail-call! x has to outlive do2, so going back to my original (deliberately vague) definition, something is happening.
Tail-calls are funny!

Trouble "overriding" values in a Groovy closure with .delegate

I'd like to call a closure with a delegate parameter to override or shadow the calling context. But the following example prints prints "outside" where I expect "inside".
What am I doing wrong?
def f(String a){
def v = { return a }
v.delegate = [a:"inside"]
// Makes no difference:
// v.resolveStrategy = Closure.DELEGATE_FIRST
println(v.call())
}
f("outside")
I believe the issue is that when the closure is declared inside the function, it 'closes' round the known values in the method (a), so that value becomes effectively hard-coded into the closure (it never hits the delegate to find the unknown value as it is known to the Closure).
If you move the closure v definition outside of the function f, then it works:
v = { return a }
def f(String a){
v.delegate = [a:"inside"]
println(v.call())
}
f("outside")
Other option is to use getProperty('a') instead of directly using a as this forces the use of the delegate to retrieve the value of a.
Can also be done by referring the delegate in the closure. For v as a closure, a does not make any sense (equivalent to use of ExpandoMetaClass)
def f(String a){
def v = { delegate.a }
v.delegate = [a:"inside"]
println v()
}
f("outside")

How do I use groovy's AS keyword

This may be a duplicate but "as" is an INCREDABLY hard keyword to google, even S.O. ignores "as" as part of query.
So I'm wondering how to implement a class that supports "as" reflexively. For an example class:
class X {
private val
public X(def v) {
val=v
}
public asType(Class c) {
if (c == Integer.class)
return val as Integer
if(c == String.class)
return val as String
}
}
This allows something like:
new X(3) as String
to work, but doesn't help with:
3 as X
I probably have to attach/modify the "asType" on String and Integer somehow, but I feel any changes like this should be confined to the "X" class... Can the X class either implement a method like:
X fromObject(object)
or somehow modify the String/Integer class from within X. This seems tough since it won't execute any code in X until X is actually used... what if my first usage of X is "3 as X", will X get a chance to override Integer's asType before Groovy tries to call is?
As you say, it's not going to be easy to change the asType method for Integer to accept X as a new type of transformation (especially without destroying the existing functionality).
The best I can think of is to do:
Integer.metaClass.toX = { -> new X( delegate ) }
And then you can call:
3.toX()
I can't think how 3 as X could be done -- as you say, the other way; new X('3') as Integer is relatively easy.
Actually, you can do this:
// Get a handle on the old `asType` method for Integer
def oldAsType = Integer.metaClass.getMetaMethod( "asType", [Class] as Class[] )
// Then write our own
Integer.metaClass.asType = { Class c ->
if( c == X ) {
new X( delegate )
}
else {
// if it's not an X, call the original
oldAsType.invoke( delegate, c )
}
}
3 as X
This keeps the functionality out of the Integer type, and minimizes scope of the effect (which is good or bad depending on what you're looking for).
This category will apply asType from the Integer side.
class IntegerCategory {
static Object asType(Integer inty, Class c) {
if(c == X) return new X(inty)
else return inty.asType(c)
}
}
use (IntegerCategory) {
(3 as X) instanceof X
}

C# 4.0 optional out/ref arguments

Does C# 4.0 allow optional out or ref arguments?
No.
A workaround is to overload with another method that doesn't have out / ref parameters, and which just calls your current method.
public bool SomeMethod(out string input)
{
...
}
// new overload
public bool SomeMethod()
{
string temp;
return SomeMethod(out temp);
}
If you have C# 7.0, you can simplify:
// new overload
public bool SomeMethod()
{
return SomeMethod(out _); // declare out as an inline discard variable
}
(Thanks #Oskar / #Reiner for pointing this out.)
As already mentioned, this is simply not allowed and I think it makes a very good sense.
However, to add some more details, here is a quote from the C# 4.0 Specification, section 21.1:
Formal parameters of constructors, methods, indexers and delegate types can be declared optional:
fixed-parameter:
attributesopt parameter-modifieropt type identifier default-argumentopt
default-argument:
= expression
A fixed-parameter with a default-argument is an optional parameter, whereas a fixed-parameter without a default-argument is a required parameter.
A required parameter cannot appear after an optional parameter in a formal-parameter-list.
A ref or out parameter cannot have a default-argument.
No, but another great alternative is having the method use a generic template class for optional parameters as follows:
public class OptionalOut<Type>
{
public Type Result { get; set; }
}
Then you can use it as follows:
public string foo(string value, OptionalOut<int> outResult = null)
{
// .. do something
if (outResult != null) {
outResult.Result = 100;
}
return value;
}
public void bar ()
{
string str = "bar";
string result;
OptionalOut<int> optional = new OptionalOut<int> ();
// example: call without the optional out parameter
result = foo (str);
Console.WriteLine ("Output was {0} with no optional value used", result);
// example: call it with optional parameter
result = foo (str, optional);
Console.WriteLine ("Output was {0} with optional value of {1}", result, optional.Result);
// example: call it with named optional parameter
foo (str, outResult: optional);
Console.WriteLine ("Output was {0} with optional value of {1}", result, optional.Result);
}
There actually is a way to do this that is allowed by C#. This gets back to C++, and rather violates the nice Object-Oriented structure of C#.
USE THIS METHOD WITH CAUTION!
Here's the way you declare and write your function with an optional parameter:
unsafe public void OptionalOutParameter(int* pOutParam = null)
{
int lInteger = 5;
// If the parameter is NULL, the caller doesn't care about this value.
if (pOutParam != null)
{
// If it isn't null, the caller has provided the address of an integer.
*pOutParam = lInteger; // Dereference the pointer and assign the return value.
}
}
Then call the function like this:
unsafe { OptionalOutParameter(); } // does nothing
int MyInteger = 0;
unsafe { OptionalOutParameter(&MyInteger); } // pass in the address of MyInteger.
In order to get this to compile, you will need to enable unsafe code in the project options. This is a really hacky solution that usually shouldn't be used, but if you for some strange, arcane, mysterious, management-inspired decision, REALLY need an optional out parameter in C#, then this will allow you to do just that.
ICYMI: Included on the new features for C# 7.0 enumerated here, "discards" is now allowed as out parameters in the form of a _, to let you ignore out parameters you don’t care about:
p.GetCoordinates(out var x, out _); // I only care about x
P.S. if you're also confused with the part "out var x", read the new feature about "Out Variables" on the link as well.
No, but you can use a delegate (e.g. Action) as an alternative.
Inspired in part by Robin R's answer when facing a situation where I thought I wanted an optional out parameter, I instead used an Action delegate. I've borrowed his example code to modify for use of Action<int> in order to show the differences and similarities:
public string foo(string value, Action<int> outResult = null)
{
// .. do something
outResult?.Invoke(100);
return value;
}
public void bar ()
{
string str = "bar";
string result;
int optional = 0;
// example: call without the optional out parameter
result = foo (str);
Console.WriteLine ("Output was {0} with no optional value used", result);
// example: call it with optional parameter
result = foo (str, x => optional = x);
Console.WriteLine ("Output was {0} with optional value of {1}", result, optional);
// example: call it with named optional parameter
foo (str, outResult: x => optional = x);
Console.WriteLine ("Output was {0} with optional value of {1}", result, optional);
}
This has the advantage that the optional variable appears in the source as a normal int (the compiler wraps it in a closure class, rather than us wrapping it explicitly in a user-defined class).
The variable needs explicit initialisation because the compiler cannot assume that the Action will be called before the function call exits.
It's not suitable for all use cases, but worked well for my real use case (a function that provides data for a unit test, and where a new unit test needed access to some internal state not present in the return value).
Use an overloaded method without the out parameter to call the one with the out parameter for C# 6.0 and lower. I'm not sure why a C# 7.0 for .NET Core is even the correct answer for this thread when it was specifically asked if C# 4.0 can have an optional out parameter. The answer is NO!
For simple types you can do this using unsafe code, though it's not idiomatic nor recommended. Like so:
// unsafe since remainder can point anywhere
// and we can do arbitrary pointer manipulation
public unsafe int Divide( int x, int y, int* remainder = null ) {
if( null != remainder ) *remainder = x % y;
return x / y;
}
That said, there's no theoretical reason C# couldn't eventually allow something like the above with safe code, such as this below:
// safe because remainder must point to a valid int or to nothing
// and we cannot do arbitrary pointer manipulation
public int Divide( int x, int y, out? int remainder = null ) {
if( null != remainder ) *remainder = x % y;
return x / y;
}
Things could get interesting though:
// remainder is an optional output parameter
// (to a nullable reference type)
public int Divide( int x, int y, out? object? remainder = null ) {
if( null != remainder ) *remainder = 0 != y ? x % y : null;
return x / y;
}
The direct question has been answered in other well-upvoted answers, but sometimes it pays to consider other approaches based on what you're trying to achieve.
If you're wanting an optional parameter to allow the caller to possibly request extra data from your method on which to base some decision, an alternative design is to move that decision logic into your method and allow the caller to optionally pass a value for that decision criteria in. For example, here is a method which determines the compass point of a vector, in which we might want to pass back the magnitude of the vector so that the caller can potentially decide if some minimum threshold should be reached before the compass-point judgement is far enough away from the origin and therefore unequivocally valid:
public enum Quadrant {
North,
East,
South,
West
}
// INVALID CODE WITH MADE-UP USAGE PATTERN OF "OPTIONAL" OUT PARAMETER
public Quadrant GetJoystickQuadrant([optional] out magnitude)
{
Vector2 pos = GetJoystickPositionXY();
float azimuth = Mathf.Atan2(pos.y, pos.x) * 180.0f / Mathf.PI;
Quadrant q;
if (azimuth > -45.0f && azimuth <= 45.0f) q = Quadrant.East;
else if (azimuth > 45.0f && azimuth <= 135.0f) q = Quadrant.North;
else if (azimuth > -135.0f && azimuth <= -45.0f) q = Quadrant.South;
else q = Quadrant.West;
if ([optonal.isPresent(magnitude)]) magnitude = pos.Length();
return q;
}
In this case we could move that "minimum magnitude" logic into the method and end-up with a much cleaner implementation, especially because calculating the magnitude involves a square-root so is computationally inefficient if all we want to do is a comparison of magnitudes, since we can do that with squared values:
public enum Quadrant {
None, // Too close to origin to judge.
North,
East,
South,
West
}
public Quadrant GetJoystickQuadrant(float minimumMagnitude = 0.33f)
{
Vector2 pos = GetJoystickPosition();
if (minimumMagnitude > 0.0f && pos.LengthSquared() < minimumMagnitude * minimumMagnitude)
{
return Quadrant.None;
}
float azimuth = Mathf.Atan2(pos.y, pos.x) * 180.0f / Mathf.PI;
if (azimuth > -45.0f && azimuth <= 45.0f) return Quadrant.East;
else if (azimuth > 45.0f && azimuth <= 135.0f) return Quadrant.North;
else if (azimuth > -135.0f && azimuth <= -45.0f) return Quadrant.South;
return Quadrant.West;
}
Of course, that might not always be viable. Since other answers mention C# 7.0, if instead what you're really doing is returning two values and allowing the caller to optionally ignore one, idiomatic C# would be to return a tuple of the two values, and use C# 7.0's Tuples with positional initializers and the _ "discard" parameter:
public (Quadrant, float) GetJoystickQuadrantAndMagnitude()
{
Vector2 pos = GetJoystickPositionXY();
float azimuth = Mathf.Atan2(pos.y, pos.x) * 180.0f / Mathf.PI;
Quadrant q;
if (azimuth > -45.0f && azimuth <= 45.0f) q = Quadrant.East;
else if (azimuth > 45.0f && azimuth <= 135.0f) q = Quadrant.North;
else if (azimuth > -135.0f && azimuth <= -45.0f) q = Quadrant.South;
else q = Quadrant.West;
return (q, pos.Length());
}
(Quadrant q, _) = GetJoystickQuadrantAndMagnitude();
if (q == Quadrant.South)
{
// Do something.
}
What about like this?
public bool OptionalOutParamMethod([Optional] ref string pOutParam)
{
return true;
}
You still have to pass a value to the parameter from C# but it is an optional ref param.
void foo(ref int? n)
{
return null;
}

Resources