Skip to content
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

Allow "or" for default/fallback values #7255

Closed
Bryce-Dixon opened this issue Jul 10, 2023 · 1 comment
Closed

Allow "or" for default/fallback values #7255

Bryce-Dixon opened this issue Jul 10, 2023 · 1 comment

Comments

@Bryce-Dixon
Copy link

Describe the project you are working on

Turn-based RPG featuring hand-drawn 2D characters in a 3D space

Describe the problem or limitation you are having in your project

Overly verbose gdscript in value validation

Describe the feature / enhancement and how it helps to overcome the problem or limitation

# Current functionality
func do_something(x, y = null):
  # Default to `do_something(x, x)` if `y` is not provided
  y = y if y else x
  # Use `x` and `y`

# Desired functionality
func do_something(x, y = null):
  # Default to `do_something(x, x)` if `y` is not provided
  y = y or x
  # Use `x` and `y`

This can also be compounded for various levels of fallbacks:

var cached_values := {}

# Assume load_value(key) will add the key-value-pair to the dictionary
#   and return the value or return null if the key is invalid

# Current functionality
func get_value(key, default = null):
  if not cached_values.has(key):
    load_value(key)
  return cached_values.get(key, default)

# Desired functionality
func get_value(key, default = null):
  # Condensed a lot of logic into a single line with clear precedence of potential results
  return cached_values.get(key) or load_value(key) or default

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

The "arbitrary" or operator will be a binary function taking two expressions, returning the first if it isn't null and the second otherwise. Similar to the boolean logical or/|| operators, the second expression will only be evaluated if the first is null. Effectively:

var x = (expression_a)
return x if x else (expression_b)
# Same functionality as
return (expression_a) or (expression_b)

If this enhancement will not be used often, can it be worked around with a few lines of script?

There's no clean way to lazy-evaluate expressions just within gdscript. It's possible with lambdas and bound callables, but significantly longer and arguably less readable:

class_name Utils

static func a_or_b(a: Callable, b: Callable):
  var x = a.call()
  return x if x else b.call()
@onready var thing = Utils.a_or_b(get_node.bind("MyChild"), Utils.a_or_b.bind(func(): get_viewport().get_camera_3d(), self))

Alternatively:

@onready var thing = get_node.bind("MyChild") or get_viewport().get_camera_3d() or self

Is there a reason why this should be core and not an add-on in the asset library?

Assuming it were a successful add-on, there would be a disruptive split in gdscript functionality with many users who take advantage of the asset potentially sharing code that confuses users who aren't aware of the add-on.

@AThousandShips
Copy link
Member

AThousandShips commented Jul 10, 2023

Please add your support and opinions there

@AThousandShips AThousandShips closed this as not planned Won't fix, can't repro, duplicate, stale Jul 10, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants