Skip to content

Conversation

@UnderscoreTud
Copy link
Member

@UnderscoreTud UnderscoreTud commented Oct 17, 2025

Problem

There are a few issues that this PR aims to address. Most notably, there is currently no straightforward way to pass entire list structures around. The other issues consist of a couple of minor bugs.

  1. Setting the default value of a function parameter to a list throws an error when the function is ran. This is caused by the function not properly ensuring (More info here Returning list of default values of function throws severe error #8220).
  2. Providing a function parameter with a list of separate keyed expressions containing the same keys (for example, foo(keyed {_list1::*}, keyed {_list2::*}) where list1 and list2 both contain values corresponding to the same key) would throw an exception.
  3. Attempting to get the indices of a list containing null values (sublists) in ascending/descending order would throw an exception due to mismatch in the amount of keys vs values. For example:
set {_list::*} to 10, 20, 30
set {_list::sublist::b} to 1 
# {_list::*} now has the keys: [1, 2, 3, sublist], but the values: [10, 20, 30]
broadcast sorted indices of {_a::*} in descending order # throws an error due to mismatched keys and values
  1. Looping a list using the alphabetically sorted list, reversed list, shuffled list or sorted list expressions does not retain the list's indices.

Solution

This PR introduces new method to get an expression's values recursively, along with a corresponding recursive expression that makes use of that behavior. When combined with the keyed expression, it allows both keys and values to be returned recursively, allowing entire structures to passed around seamlessly between different contexts.

Addressing the aforementioned issues:

  1. Add a centralized method to the Parameter class that evaluates expressions with respect to the parameter's modifiers. This unfortunately makes Fix function parameters with default value as list causing error #8221 obsolete.
  2. Ensure that any duplicate keys are discarded when being passed to a parameter. If a key appears multiple times, only the first value is kept.
  3. Exclude indices that don't correspond to a value when using indices of x in ascending/descending order
  4. Extract the iterator methods in KeyProviderExpression into its own interface and implement it in ExprAlphabetList, ExprReversedList, ExprShuffledList and ExprSortedList

Testing Completed

StructFunction.sk, ExprRecursive.sk, ExprAlphabetList.sk, ExprReversedList.sk, ExprShuffledList.sk, ExprSortedList.sk and manual testing

Supporting Information

Below is a complete example showing how various combinations behave:

set {_first::a::b} to "value1"
set {_first::c} to "value2"

set {_second::*} to {_first::*}
# {_second::1} = "value2"

set {_second::*} to keyed {_first::*}
# {_second::c} = "value2"

set {_second::*} to recursive {_first::*}
# {_second::1} = "value1"
# {_second::2} = "value2"

set {_second::*} to keyed recursive {_first::*}
# {_second::a::b} = "value1"
# {_second::c} = "value2"

Using functions:

function shallow_list(list: objects) returns objects:
    return {_list::*}

function deep_list(list: objects) returns objects:
    return recursive {_list::*}

# ...

set {_first::a::b} to "value1"
set {_first::c} to "value2"

set {_second::*} to shallow_list({_first::*})
# {_second::1} = "value2"

set {_second::*} to keyed shallow_list({_first::*})
# {_second::1} = "value2"

set {_second::*} to shallow_list(keyed {_first::*})
# {_second::1} = "value2"

set {_second::*} to keyed shallow_list(keyed {_first::*})
# {_second::c} = "value2"

# =============

set {_second::*} to deep_list({_first::*})
# {_second::1} = "value2"

set {_second::*} to keyed deep_list({_first::*})
# {_second::1} = "value2"

set {_second::*} to deep_list(keyed {_first::*}) # passing in a keyed list will automatically
                                                                      #   pass it as a keyed recursive list
# {_second::1} = "value1"
# {_second::2} = "value2"

set {_second::*} to keyed deep_list(keyed {_first::*})
# {_second::a::b} = "value1"
# {_second::c} = "value2"

Completes: #8220, #1419
Related: none

@UnderscoreTud UnderscoreTud requested review from a team and Efnilite as code owners October 17, 2025 17:34
@UnderscoreTud UnderscoreTud requested review from APickledWalrus and erenkarakal and removed request for a team October 17, 2025 17:34
@skriptlang-automation skriptlang-automation bot added the needs reviews A PR that needs additional reviews label Oct 17, 2025
@UnderscoreTud UnderscoreTud added bug An issue that needs to be fixed. Alternatively, a PR fixing an issue. enhancement Feature request, an issue about something that could be improved, or a PR improving something. and removed needs reviews A PR that needs additional reviews labels Oct 17, 2025
@UnderscoreTud UnderscoreTud changed the base branch from master to dev/feature October 17, 2025 17:37
@skriptlang-automation skriptlang-automation bot added the needs reviews A PR that needs additional reviews label Oct 17, 2025
@sovdeeth sovdeeth moved this to In Review in 2.14 Releases Oct 18, 2025
Copy link
Member

@APickledWalrus APickledWalrus left a comment

Choose a reason for hiding this comment

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

seems ok overall just a couple thoughts

@skriptlang-automation skriptlang-automation bot removed the needs reviews A PR that needs additional reviews label Nov 9, 2025
Copy link
Member

@APickledWalrus APickledWalrus left a comment

Choose a reason for hiding this comment

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

Just about ready

@github-project-automation github-project-automation bot moved this from In Review to Awaiting Merge in 2.14 Releases Dec 22, 2025
@skriptlang-automation skriptlang-automation bot added the feature-ready A PR/issue that has been approved, tested and can be merged/closed in the next feature version. label Dec 22, 2025
@sovdeeth
Copy link
Member

needs to re-add atomicboolean import

@APickledWalrus APickledWalrus merged commit 0cbcaff into dev/feature Jan 1, 2026
10 checks passed
@github-project-automation github-project-automation bot moved this from Awaiting Merge to Done - Awaiting Release in 2.14 Releases Jan 1, 2026
@skriptlang-automation skriptlang-automation bot added completed The issue has been fully resolved and the change will be in the next Skript update. and removed feature-ready A PR/issue that has been approved, tested and can be merged/closed in the next feature version. labels Jan 1, 2026
@APickledWalrus APickledWalrus linked an issue Jan 1, 2026 that may be closed by this pull request
@APickledWalrus APickledWalrus moved this from Done - Awaiting Release to Done - Released in 2.14 Releases Jan 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug An issue that needs to be fixed. Alternatively, a PR fixing an issue. completed The issue has been fully resolved and the change will be in the next Skript update. enhancement Feature request, an issue about something that could be improved, or a PR improving something.

Projects

Status: Done - Released

Development

Successfully merging this pull request may close these issues.

Suggestion: add tree loop functionality

4 participants