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

var in lambda #4493

Open
hrf3 opened this issue Dec 12, 2024 · 5 comments
Open

var in lambda #4493

hrf3 opened this issue Dec 12, 2024 · 5 comments
Labels
bug An unexpected problem or unintended behavior of the Core

Comments

@hrf3
Copy link

hrf3 commented Dec 12, 2024

oH 4.3.0.M5

var wIL = true // val is the same

val xx = [ |
  if (wIL) {logInfo("x","x");}
  true]

rule "x" when
  System started
then
  xx.apply();
end

The rule is executed without an error message even though the variable is not defined within the lambda, but the global variable is correctly not recognized within the lambda either. If I delete the variable I get a corresponding message during execution.

@hrf3 hrf3 added the bug An unexpected problem or unintended behavior of the Core label Dec 12, 2024
@rkoshak
Copy link

rkoshak commented Dec 12, 2024

If you delete which variable? What specifically is the "corresponding message" Please provide more details and logs.

In Rules DSL, variables defined in the global context cannot see each other. So wIL will not exist inside the lambda. However, Rules DSL won't actually discover that that variable doesn't exist until runtime. It doesn't have enough information at compile time to know whether wIL exists or not. I'm pretty sure it doesn't even try to parse the lambda until runtime.

Are you reporting a change from this expected behavior or is it working as expected?

@hrf3
Copy link
Author

hrf3 commented Dec 12, 2024

// vaL wIL = true
2024-12-12 17:34:42.849 [INFO ] [el.core.internal.ModelRepositoryImpl] - Validation issues found in configuration model 'test.rules', using it anyway: Constant condition is always true.

// var wIL = true
... no message

// var wIL = true
2024-12-12 17:37:24.918 [ERROR] [.handler.AbstractScriptModuleHandler] - Script execution of rule with UID 'test-1' failed: The name 'wIL' cannot be resolved to an item or type; line 4, column 7, length 3 in test

@rkoshak
Copy link

rkoshak commented Dec 12, 2024

The Validation warning is just that, a warning. It's just letting you know that you may not have wanted to create an expression like that as a constant in that context. But it's using it anyway since it's syntactically valid.

And there isn't an error when the lambda runs because lambdas in general can see constants without problems. Though because the constant is declared globally I'm a little suprised it worked, but I guess it did (I assume you saw the x logged out showing the lambda worked).

The error in the second case comes from what I explained above. Globally defined lambdas cannot see any vars defined outside of it. So when the lambda is called it doesn't know anything about the variable wIL. This is how Rules DSL has always worked and it's a feature controlled by the upstream Xtend repo and not something OH has control over.

It's weirdness like this (and this is a minor one) that cause me to recommend against new development of rules using Rules DSL. Any of the other languages work in a more consistent way and are now just as easy to work with.

If you need to change a global variable in a globally defined lambda, use the privateCache instead of a global variable or use the sharedCache if it's a variable that needs to be shared across multiple rules. And then you either need to pull that value from the cache inside the lambda or pass the value as an argument to the lambda.

But as far as I can tell, this is working as it always has and it's working as Xtend has designed.

@hrf3
Copy link
Author

hrf3 commented Dec 13, 2024

It is and was already clear to me that lambdas cannot/should not access global variables. This isn't about me having a problem with it either. I only find the corresponding reactions to this problem irritating, even for others. With global val a "Validation issues" is output. The condition if(wIL) in Lambda is not satisfied. With global var nothing happens. In my opinion, correct information only comes if var is not defined. All of this should just be a help to make it even better for beginners. If this is not desired, we can also save ourselves the effort in the future.

@rkoshak
Copy link

rkoshak commented Dec 13, 2024

All of this should just be a help to make it even better for beginners. If this is not desired, we can also save ourselves the effort in the future.

I'm not saying this isn't desired. We have no control over it. All of that stuff is AFAIK implemented upstream, not by OH.

And I'm strongly of the opinion that beginners should not be using Rules DSL any more anyway. This is only one tiny problem with Rules DSL that will mess users up which OH has no control over. For example:

var myNumber = 5
var int myOtherNumber = 6
logInfo("test", myNumber + " is a number") // will most likely fail with a null exception
logInfo("test", myNumber.toString + " is a number") // will succeed
logInfo("test", myOtherNumber.toString + " is a number") // will most likely fail
logInfo("test", "a number is " + myNumber) // will succeed

The advantages Rules DSL once had are no longer advantages over the other options and the disadvantages are severe. New users should not be using Rules DSL and existing users should not be using Rules DSL for new rules development. That's just my opinion but it's an informed one. Rules DSL was great through about OH 3.2 but it has since been surpassed by Blockly, jRuby, and JS Scripting in completeness, ease of use, and consistency.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug An unexpected problem or unintended behavior of the Core
Projects
None yet
Development

No branches or pull requests

2 participants