Skip to content

Conversation

@codeshaunted
Copy link
Contributor

@codeshaunted codeshaunted commented Jul 18, 2025

Added a predicate type made with rust-style closure syntax (|x| x == 10). Hardcoded as an 80% solution specifically for use with the array type. To try this out I’ve added array member functions for any and all, along with an accompanying test.

To resolve the predicate argument type, this uses a hardcoded hack on function call resolution. Not sure if this is acceptable, let me know.

The main goal of this is to work towards closing #1328, which will require additional work for inferring a return type on the built in function. But, this also could be added as-is, or with a lowering pass to close #4801.

Implementation here is incomplete (missing interpreter impl) and likely buggy, just pushing now for feedback.

@ogoffart
Copy link
Member

Nice! Thanks for working on it.
I'll be busy next week so i'm not going to able to review the details until then, but i can already say this looks promising. Maybe other will chime in for review. A few point though.

I notice you went for the rust syntax for closure, but from the discussion in #1328 (comment) , I feel the JS syntax may be a more intuitive syntax. (x => x == 10)
I'm open for other syntax, but it seems that overall this may be more intuitive for everyone but rust developers.

To resolve the predicate argument type, this uses a hardcoded hack on function call resolution. Not sure if this is acceptable, let me know.

I think that's fine for now. A generalisation would be nice, but could be done later.

What's important is to test that we get proper error with all the error cases (in the syntax_test)

Stuff like the predicate returning the wrong type, or passing a non predicate to one of these functions, or passing a predicate to other function that do not expect a predicate, stuff like debug(|x| x==10), clicked => |x| x==10; Or any place that accept an expression and it wouldn't make sense: if |x| x==10 : Rectangle {}
Also test what happen if you have embedded predicate (with array of array) array_of_array.any(|x| x.all(|y| y==10))
Also test side effect in the callbacks and things like that.

This comment is just a preliminary brain dump of some side special case that comes to my mind.

@codeshaunted
Copy link
Contributor Author

I've updated this to change the syntax to the preferred one and add an interpreter implementation. Let me know if you think there's a better way to accomplish this in the interpreter, as I struggled a bit to do it cleanly. Will add syntax tests + compilation errors for various cases soon.

Copy link
Member

@ogoffart ogoffart left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the delayed answer.
This looks good I think.

Just one comment about the generated code. (C++ and Rust) where the user specified argument could override local variable that needs to be there.

?MemberAccess ],
/// Concatenate the Expressions to make a string (usually expanded from a template string)
?MemberAccess, ?Predicate ],
/// Concatenate the Expressions to make a string (usually expended from a template string)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the previous spelling of expanded was correct. (Maybe a merge conflict?)

}
},
Expression::Predicate { arg_name, expression } => {
let arg = ident(arg_name);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm thinking we probably want to add some kind of prefix here. For example pred_arg_{} so that you don't get mismatch with existing local variables. (and then we need to figure out that the ReadLocalVariable is actually reading a predicate of this name)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature: allow arrays in .slint to use .contains()

2 participants