-
-
Notifications
You must be signed in to change notification settings - Fork 21.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Lambda notation for anonymous funcrefs #27718
Comments
My idea for this would be to allow multiline lambdas as well. Somewhat like this: func _ready():
print("okay")
var lambda = ():
print("inside")
print("also inside")
lambda()
connect("toggled", x: print(x))
[1,2,3].reduce((x, y): x + y, 7)
[1,2,3].map((x: int):
var temp = x * 2
return pow(temp, temp)
)
var transform = x:
return x * 2
# Binding from external context (syntax can change)
[1,2,3].map((x).(transform): return transform(x)) Might be a little trick to implement all the nuances with indentation, but should be doable. @jabcross suggested replacing the |
I really like this idea, and I would make the parenthesis mandatory, like this: func _ready():
print("okay")
var lambda = ():
print("inside")
print("also inside")
lambda()
connect("toggled", (x): print(x))
[1,2,3].reduce((x, y): x + y, 7)
[1,2,3].map((x: int):
var temp = x * 2
return pow(temp, temp)
)
var transform = (x):
return x * 2 That way, every time one sees |
I find this part a bit confusing:
|
Why would I want to do this:
Instead of this:
Isn't the latter more readable as it requires knowing fewer syntactic rules? |
@aaronfranke In the example you mention, a lambda wouldn't be worth it. But in other cases such as:
...lambdas are worth it. Specially when a function doesn't need a function name. (*) I am currently using these kind of functions in a Godot 3.1 project with |
I have recently published an experimental library Golden Gadget where lambdas are simulated (not ideal - essentially eval under the hood) and for some functions they are directly usable: # monsters is an array of objects
var res = G(monsters).filter("x => x.is_alive && x.hp < 10").map("x => x.name").val It also has a shorthand for creating F("x => x.b").call_func({b = true}) # true At least until lambdas are in GDScript this might be a good enough solution. Of course all depends on your use case - array wrapper isn't free and while lambdas are being cached, their performance will undoubtedly be worse than native |
Looks like we're gettting first class functions with Godot 4.0 :) Feature and improvement proposals for the Godot Engine are now being discussed and reviewed in a dedicated Godot Improvement Proposals (GIP) (godotengine/godot-proposals) issue tracker. The GIP tracker has a detailed issue template designed so that proposals include all the relevant information to start a productive discussion and help the community assess the validity of the proposal for the engine. The main (godotengine/godot) tracker is now solely dedicated to bug reports and Pull Requests, enabling contributors to have a better focus on bug fixing work. Therefore, we are now closing all older feature proposals on the main issue tracker. If you are interested in this feature proposal, please open a new proposal on the GIP tracker following the given issue template (after checking that it doesn't exist already). Be sure to reference this closed issue if it includes any relevant discussion (which you are also encouraged to summarize in the new proposal). Thanks in advance! |
Right now, the function a funcref (or a object-methodname pair) points to needs to be declared separately, which is inconvenient for small one-liners, especially in cases like
connect()
.This is a proposal for some syntax that would automate the creation of these one-off functions. Keep in mind that this does not entail having functions as first-class citizens (yet), just a compile-time nicety. The generated function would still exist and have a name in the bytecode.
This would also have the side-effect of allowing things like
connect()
andTween.interpolate*()
to receive funcrefs directly, in addition to object-methodname pairs.My proposal is inspired by JavaScript's notation, rather than Python's (since
:
now has typing connotation):() -> return_value
param -> return_expression * 2
(param1: String, param2: int) -> (x = return_statement)
Just like Python, multi-statement lambdas would not be allowed.
The variable context would be that of the closest class, so
would compile to the same bytecode as something like
Some usage examples could be:
And it would fit nicely with map, reduce and filter, which have also been requested.
As a bonus, we could detect if any properties from
self
are being used and otherwise define the generated function asstatic
(which also would requirefuncref
support for static functions).The text was updated successfully, but these errors were encountered: