Why a lambda cannot make the enclosing function return? - function

I'm quite new to Kotlin. I hit this part while I was going over the docs:
"a lambda cannot return from the enclosing function" (unless it's inlined).
So, this doesn't work;
fun foo() {
ordinaryFunction {
return // ERROR: cannot make `foo` return here
}
}
I wonder why it works that way?
The only thing I can think of it's dangerous since there might be some extra stuff the enclosing function might be doing after the lambda execution. But I'm not sure that's the reason because you can overcome this by using qualified returns or using inline keyword. So, that kind of implies there's a technical reason behind it (apart from any usability/safety reasons) like the compiler cannot figure out where to return unless it's labeled or inlined.
Any help would be great!

The problem is here that non-local returns can't be done on the JVM.
If you want to return from lambda (local return) you can add label #ordinaryFunction:
fun foo() {
ordinaryFunction {
return#ordinaryFunction
}
}
Docs say:
If we need to return from a lambda expression, we have to label it and qualify the return. Oftentimes it is more convenient to use implicit labels: such a label has the same name as the function to which the lambda is passed. In our case it is #ordinaryFunction.

Someone else can probably explain this better but in pretty much any programming language, when you call a function, a new entry is created on top of the stack. The stack keeps information about the arguments that the function was called with and the place you should return to when the function completes.
Kotlin doesn't have a feature that lets you return from multiple function calls in one return, so you have to return from each function call manually.
When you inline a function the machine code that would normally execute in a separate subroutine is now copy pasted to the function call site instead. That's why return from an inline function actually returns from the function that called the inlined lambda.

there might be some extra stuff the enclosing function might be doing after the lambda execution.
The problem is the other way around: the lambda can "escape" from the enclosing function's scope and end up executing after the function returns. E.g. consider
fun foo() {
Thread(Runnable {
Thread.sleep(1000)
return
})
}
Or just
fun foo() = // lambda
In either case it makes no sense for the lambda to return from foo, does it? And the compiler doesn't know if your ordinaryFunction lets the lambda escape foo's scope unless it's inline.
you can overcome this by using qualified returns
That's not really overcoming, that's just not returning from the enclosing function.

Related

Are function declarations and function expressions implemented differently in Go? If yes, why?

I just got into programming again with Go (with no experience whatsoever in low-level languages), and I noticed that function expressions are not treated the same as function declarations (go1.18.5 linux/amd64).
For instance, this works (obviously):
package main
import "fmt"
func main() {
fmt.Println("Do stuff")
}
But this outputs an error:
package main
import "fmt"
var main = func() {
fmt.Println("Do stuff")
}
./prog.go:3:8: imported and not used: "fmt"
./prog.go:5:5: cannot declare main - must be func
Go build failed.
Even specifying the type as in var main func() = func() {} does nothing for the end result. Go seems to, first of all, evaluate if the main identifier is being used in any declaration, ignoring the type. Meanwhile, Javascript folks seem to choose what is more readable, like there's no underlying difference between them.
Questions:
Are function declarations and function expressions implemented differently under the hood, or is this behavior just hard-coded?
If yes, is the difference between these implementations critical?
Is Go somewhat better in any way for doing it the way it does?
From the spec:
The main package must [...] declare a function main that takes no arguments and returns no value.
The moment you write var main you prevent the above requirement from being met, because what you are creating is a variable storing a reference to a function literal as opposed to being a function declaration.
A function declaration binds an identifier, the function name, to a function.
A function literal represents an anonymous function.
So:
Are function declarations and function expressions implemented differently under the hood?
Yes.
Is Go somewhat better in any way for doing it the way it does?
Generally, no. It comes with the territory of being a typed language, which has all sorts of pros and cons depending on use.
If yes, is the difference between these implementations critical?
By what standard? As an example, a variable referencing a function literal could be nil, which isn't usually something you'd like to call. The same cannot happen with function declarations (assuming package unsafe is not used).
The code
func main() {
fmt.Println("Do stuff")
}
binds a function to the identifier main.
The code
var main = func() {
fmt.Println("Do stuff")
}
binds a variable of type func () to the identifier main and initializes the variable to the result of a function expression.
Are function declarations and function expressions implemented differently under the hood, or is this behavior just hard-coded?
A function expression evaluates to a function value. A function declaration binds a function value to a name. There is no difference in the implementation of these function values (but the result of an expressions can additionally close over function scoped variables).
If yes, is the difference between these implementations critical?
Yes.
The question points out one scenario where the difference is important (program execution starts at the function main in package main)
The compiler cannot inline a function called through a variable.
Functions cannot be declared inside another function, but a function expression can be assigned to a variable in a function.
Is Go somewhat better in any way for doing it the way it does?
Other languages make a distinction between an identifier bound a function and and identifier bound to a variable with a function type. Go is no better or worse in than those languages with regards to the binding of identifiers.
The OP says in a comment:
The question was about the difference between javascript and go, though, but you also answered it with "It comes with the territory of being a typed language".
The difference is unrelated to being a typed language. Identifiers can be bound to constants, types, variables and functions in Go. I may be going out on a limb here, but non-reserved identifiers in Javascript are always bound to variables.

How are functions implemented?

I've been playing around with the reflect package, and I notice how limited the functionality of functions are.
package main
import (
"fmt"
"reflect"
"strings"
)
func main() {
v := reflect.ValueOf(strings.ToUpper)
fmt.Printf("Address: %v\n", v) // 0xd54a0
fmt.Printf("Can set? %d\n", v.CanSet()) // False
fmt.Printf("Can address? %d\n", v.CanAddr()) // False
fmt.Printf("Element? %d\n", v.Elem()) // Panics
}
Playground link here.
I've been taught that functions are addresses to memory with a set of instructions (hence v prints out 0xd54a0), but it looks like I can't get an address to this memory address, set it, or dereference it.
So, how are Go functions implemented under the hood? Eventually, I'd ideally want to manipulate the strings.ToUpper function by making the function point to my own code.
Disclaimers:
I've only recently started to delve deeper into the golang compiler, more specifically: the go assembler and mapping thereof. Because I'm by no means an expert, I'm not going to attempt explaining all the details here (as my knowledge is most likely still lacking). I will provide a couple of links at the bottom that might be worth checking out for more details.
What you're trying to do makes very, very little sense to me. If, at runtime, you're trying to modify a function, you're probably doing something wrong earlier on. And that's just in case you want to mess with any function. The fact that you're trying to do something with a function from the strings package makes this all the more worrying. The reflect package allows you to write very generic functions (eg a service with request handlers, but you want to pass arbitrary arguments to those handlers requires you to have a single handler, process the raw request, then call the corresponding handler. You cannot possibly know what that handler looks like, so you use reflection to work out the arguments required...).
Now, how are functions implemented?
The go compiler is a tricky codebase to wrap ones head around, but thankfully the language design, and the implementation thereof has been discussed openly. From what I gather, golang functions are essentially compiled in pretty much the same way as a function in, for example, C. However, calling a function is a bit different. Go functions are first-class objects, that's why you can pass them as arguments, declare a function type, and why the reflect package has to allow you to use reflection on a function argument.
Essentially, functions are not addressed directly. Functions are passed and invoked through a function "pointer". Functions are effectively a type like similar to a map or a slice. They hold a pointer to the actual code, and the call data. In simple terms, think of a function as a type (in pseudo-code):
type SomeFunc struct {
actualFunc *func(...) // pointer to actual function body
data struct {
args []interface{} // arguments
rVal []interface{} // returns
// any other info
}
}
This means that the reflect package can be used to, for example, count the number of arguments and return values the function expects. It also tells you what the return value(s) will be. The overall function "type" will be able to tell you where the function resides, and what arguments it expects and returns, but that's about it. IMO, that's all you really need though.
Because of this implementation, you can create fields or variables with a function type like this:
var callback func(string) string
This would create an underlying value that, based on the pseudo code above, looks something like this:
callback := struct{
actualFunc: nil, // no actual code to point to, function is nil
data: struct{
args: []interface{}{string}, // where string is a value representing the actual string type
rVal: []interface{}{string},
},
}
Then, by assigning any function that matches the args and rVal constraints, you can determine what executable code the callback variable points to:
callback = strings.ToUpper
callback = func(a string) string {
return fmt.Sprintf("a = %s", a)
}
callback = myOwnToUpper
I hope this cleared 1 or 2 things up a bit, but if not, here's a bunch of links that might shed some more light on the matter.
Go functions implementation and design
Introduction to go's ASM
Rob Pike on the go compiler written in go, and the plan 9 derived asm mapping
Writing a JIT in go asm
a "case study" attempting to use golang ASM for optimisation
Go and assembly introduction
Plan 9 assembly docs
Update
Seeing as you're attempting to swap out a function you're using for testing purposes, I would suggest you not use reflection, but instead inject mock functions, which is a more common practice WRT testing to begin with. Not to mention it being so much easier:
type someT struct {
toUpper func(string) string
}
func New(toUpper func(string) string) *someT {
if toUpper == nil {
toUpper = strings.ToUpper
}
return &someT{
toUpper: toUpper,
}
}
func (s *someT) FuncToTest(t string) string {
return s.toUpper(t)
}
This is a basic example of how you could inject a specific function. From within your foo_test.go file, you'd just call New, passing a different function.
In more complex scenario's, using interfaces is the easiest way to go. Simply implement the interface in the test file, and pass the alternative implementation to the New function:
type StringProcessor interface {
ToUpper(string) string
Join([]string, string) string
// all of the functions you need
}
func New(sp StringProcessor) return *someT {
return &someT{
processor: sp,
}
}
From that point on, simply create a mock implementation of that interface, and you can test everything without having to muck about with reflection. This makes your tests easier to maintain and, because reflection is complex, it makes it far less likely for your tests to be faulty.
If your test is faulty, it could cause your actual tests to pass, even though the code you're trying to test isn't working. I'm always suspicious if the test code is more complex than the code you're covering to begin with...
Underneath the covers, a Go function is probably just as you describe it- an address to a set of instructions in memory, and parameters / return values are filled in according to your system's linkage conventions as the function executes.
However, Go's function abstraction is much more limited, on purpose (it's a language design decision). You can't just replace functions, or even override methods from other imported packages, like you might do in a normal object-oriented language. You certainly can't do dynamic replacement of functions under normal circumstances (I suppose you could write into arbitrary memory locations using the unsafe package, but that's willful circumvention of the language rules, and all bets are off at that point).
Are you trying to do some sort of dependency injection for unit testing? If so, the idiomatic way to do this in Go is to define interface that you pass around to your functions/methods, and replace with a test version in your tests. In your case, an interface may wrap the call to strings.ToUpper in the normal implementation, but a test implementation might call something else.
For example:
type Upper interface {
ToUpper(string) string
}
type defaultUpper struct {}
func (d *defaultUpper) ToUpper(s string) string {
return strings.ToUpper(s)
}
...
// normal implementation: pass in &defaultUpper{}
// test implementation: pass in a test version that
// does something else
func SomethingUseful(s string, d Upper) string {
return d.ToUpper(s)
}
Finally, you can also pass function values around. For example:
var fn func(string) string
fn = strings.ToUpper
...
fn("hello")
... but this won't let you replace the system's strings.ToUpper implementation, of course.
Either way, you can only sort of approximate what you want to do in Go via interfaces or function values. It's not like Python, where everything is dynamic and replaceable.

Ada package function identifier expected

Learning Ada and trying to make a stack ADT and I'm using this webpage to figure it out.
http://www.functionx.com/ada/Lesson06.htm
eightqueens.adb
with Ada.Text_IO;
use Ada.Text_IO;
with Stack;
use Stack;
procedure EightQueens is
begin
put_line ("awd");
end EightQueens;
stack.ads
package Stack is
function awd () return Integer;
end Stack;
stack.adb
package body Stack is
function awd () return integer is
begin
return 1;
end awd;
end Stack;
Error is
stack.ads:2:19: identifier expected
I'm most certain I did everything correctly.
Ada doesn't use empty parentheses, either for defining or for calling functions or procedures.
And for future reference, the phrase "I'm most certain I did everything correctly." is a red flag indicating that you've almost certainly done something wrong.
Just to elaborate, there are some syntactic decisions that Ada made that IMHO are superior to what you may be used to from C-syntax languages.
Functions with no parameters don't use empty parenthesis in their calls. This allows you to change a contant to a function call without having to recode any of the clients.
Arrays use parentheses like function calls do, rather than some unique syntax. This allows you to change an array constant to a function call without having to recode any of the clients.
To look at it another way, a constant is just a simplified version of a parameterless function, for when you can get away with always returning the same value. Likewise, a constant array is a simplified version of a parametered function call, for when you can get away with always returning the same value. If you later discover you need a more complex implementation, that's not the client's concern, and should not affect their code.

Can if statements be implemented as function calls?

One of the stylistic 'conventions' I find slightly irritating in published code, is the use of:
if(condition) {
instead of (my preference):
if (condition) {
A slight difference, and probably an unimportant one, but it occurred to me that the first style might be justified if 'if' statements were implemented as a kind of function call. Then I could stop objecting to it.
Does anyone know of a programming language where an if statement is implemented as a function call, where the argument is a single boolean expression?
EDIT: I realise the blocks following the if() are problematic, and the way I expressed my question was probably too naive, but I'm encouraged by the answers so far.
tcl is one language which implements if as a regular in built function/command which takes two parameters ; condition and the code block to execute
if {$vbl == 1} { puts "vbl is one" }
http://tmml.sourceforge.net/doc/tcl/if.html
In fact, all language constructs in tcl (for loop , while loop etc.) are implemented as commands/functions.
It's impossible for it to have a single argument since it has to decide which code path to follow, which would have to be done outside of said function. It would need at least two arguments, but three would allow an "else" condition.
Lisp's if has exactly the same syntax as any other macro in the language (it's not quite exactly a function, but the difference is minimal): (if cond then else)
Both the 'then' and 'else' clauses are left unevaluated unless the condition selects them.
In Smalltalk, an if statement is kind of a function call -- sort of, in (of course) a completely object oriented way, so it's really a method not a free function. I'm not sure how it would affect your thinking on syntax though, since the syntax is completely different, looking like:
someBoolean
ifTrue: [ do_something ]
ifFalse: [ do_something_else ]
Given that this doesn't contain any parentheses at all, you can probably interpret it as proving whatever you wanted to believe. :-)
If the if function is to be a regular function, then it can't just take the condition, it needs as its parameters the block of code to run depending on whether the condition evaluates to true or not.
A prototype for a function like that in C++ might be something along the lines of
void custom_if(bool cond, void (*block)());
This function can either call the block function, or not, depending on cond.
In some functional languages things are much easier. In Haskell, a simple function like:
if' True a _ = a
if' _ _ b = b
allows you to write code like this:
if' (1 == 1)
(putStrLn "Here")
(putStrLn "There")
which will always print Here.
I don't know of any languages where if(condition) is implemented as a regular function call, but Perl implements try { } catch { } etc.. {} as function calls.

Checking anonymous function signatures at runtime (reflection) in AS3

Is there any way to have a look at signatures of anonymous functions in ActionScript 3 during runtime?
I would like to validate Function objects passed in as arguments to other functions and make sure that they accept the correct number of arguments (with the correct types) and return a value of the correct type.
flash.utils.describeType() doesn't seem to return this info for anonymous functions.
It doesn't look like the runtime allows you to reflect on anonymous functions, which is a shame.
Anonymous functions are (perhaps by definition) marked as dynamic. If you pass an incompatible type into an anonymous function, no error is thrown. Any type mismatches will be silently cast as best they can. Passing something like "minotaur" as a uint parameter will yield 0 (zero), for example.
If you REALLY want to over-engineer it, you could get all OO on it. Instead of accepting anonymous functions, you could declare an interface which contains the appropriate function signature, and accept objects that implement that interface.
public interface IFancyCallback {
public function fancyFunction(frog:Frog, princess:Girl):UsefulReturnType;
}
And your function would just have to be packaged up in an object:
public class ConcreteCallback implements IFancyCallback {
public function fancyFunction(frog:Frog, princess:Girl):UsefulReturnType {
princess.kiss(frog);
return new UsefulReturnType("jabberwocky");
}
}
Could have the potential to create a lot of code overhead. Depends how many callbacks you intend to have, who's going to be making them, and what how serious it would be if the anon function's signature was incorrect.
Can you share any more about the problem you're trying to solve?
As a rough approximation you can check the number of parameters using length property, e.g.:
function doStuff(callback:Function) {
trace(callback.length);
}
I'm not aware of any way to enumerate the arguments of an anonymous functions; you can of course validate ex-post catching ArgumentError.