8000 fix(package): [slice] functions with inconsistent return behaviour by idichekop · Pull Request #326 · duke-git/lancet · GitHub
[go: up one dir, main page]

Skip to content

Conversation

idichekop
Copy link
Collaborator

Hi Duke and all Lancet enthusiasts,

The following functions in the slice package have inconsistent behaviour in
its return value:

  • DeleteAt
  • Drop
  • DropRight
  • InsertAt
  • UpdateAt
  • Without

These functions return the same slice passed as input (in place modification) on
some conditions, and a copy of the input slice (no in place modification) on other
conditions. I use the DeleteAt function as an example:

func DeleteAt[T any](slice []T, index int) []T {
	if index < 0 || index >= len(slice) {
		return slice[:len(slice)-1]
	}

	result := append([]T(nil), slice...)
	copy(result[index:], result[index+1:])

	// Set the last element to zero value, clean up the memory.
	result[len(result)-1] = zeroValue[T]()

	return result[:len(result)-1]
}

Note that in case the slice is empty or the deletion index is negative, the return value
is the same passed slice. In this case, there is no modification of the passed input.
But if the code proceeds further, it will return a copy of the passed input.

This return/modification behaviour can be a source of confusion, as sometimes the user
will receive a copy, and sometimes the same passed slice.

This fix goes over all the mentioned functions above and corrects them for this
inconsistent behaviour
. The correction is applied in such form that a copy of the
passed slice is returned -- never a modified version of the passed slice.

Other remarks:

  1. Note that if a function modifies and returns the given slice in place for all cases;
    or it returns a modified copy for all cases. There is no fix. I consider this is
    the desired functionality of the function.
  2. The functions Unique, UniqueBy, UniqueByComparator, UniqueByField makes
    modifications in place in all situations. There is no inconsistency in this
    case. However, if the intention is that these functions also return copies, than
    they still need to be reviewed.
  3. The function SymmetricDifference uses Unique on the input slice. That makes it
    indirectly inconsistent. This fixes addressed that.
  4. Functions in the slice_concurrent.go file do not have this inconsistency.

@duke-git
Copy link
Owner

Hi idichekop:

Thanks for pointing this out and for providing a clear explanation with examples. I agree that the current mixed behavior between in-place modification and returning a copy can be confusing. Your fix to make these functions consistently return a copy makes sense and will help avoid unexpected side effects.

@duke-git duke-git merged commit 4c64a16 into duke-git:rc Aug 19, 2025
1 check passed
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.

2 participants
0