diff --git a/dt/slice.go b/dt/slice.go index d549e8d..8191a25 100644 --- a/dt/slice.go +++ b/dt/slice.go @@ -23,6 +23,10 @@ func NewSlice[T any](in []T) Slice[T] { return in } // Deprecated: use NewSlice for this case. func Sliceify[T any](in []T) Slice[T] { return NewSlice(in) } +// Variadic constructs a slice of type T from a sequence of variadic +// elements. +func Variadic[T any](in ...T) Slice[T] { return in } + // SlicePtrs converts a slice of values to a slice of // values. This is a helper for Sliceify(in).Ptrs(). func SlicePtrs[T any](in []T) Slice[*T] { return NewSlice(in).Ptrs() } @@ -70,10 +74,6 @@ func MergeSlices[T any](sls ...[]T) Slice[T] { return out } -// Variadic constructs a slice of type T from a sequence of variadic -// options. -func Variadic[T any](in ...T) Slice[T] { return in } - // DefaultSlice takes a slice value and returns it if it's non-nil. If // the slice is nil, it returns a slice of the specified length (and // capacity,) as specified. @@ -282,7 +282,7 @@ func (s Slice[T]) Ptrs() []*T { // reflection), if the value is nil, and only adds the item when it is // not-nil. func (s Slice[T]) Sparse() Slice[T] { - // use a List to avoid pre-allocating + // use a List to avoid (over) pre-allocating. buf := &List[T]{} for idx := range s { if !ft.IsNil(s[idx]) { diff --git a/ensure/is/is.go b/ensure/is/is.go index 66be3ba..0d8c005 100644 --- a/ensure/is/is.go +++ b/ensure/is/is.go @@ -5,6 +5,7 @@ package is import ( "fmt" + "slices" "strings" "github.com/tychoish/fun" @@ -156,13 +157,13 @@ func NotSubstring(s, substr string) That { // Contained asserts that the slice (sl) has at least one element // equal to the item. func Contained[T comparable](item T, sl []T) That { - return assertf(ft.Contains(item, sl), "list (len=%d) does not contain contains %v", len(sl), item) + return assertf(slices.Contains(sl, item), "list (len=%d) does not contain contains %v", len(sl), item) } // NotContained asserts that the slice (sl) has no elements that are // equal to the item. func NotContained[T comparable](item T, sl []T) That { - return assertf(!ft.Contains(item, sl), "list (len=%d) does not contain contains %v", len(sl), item) + return assertf(!slices.Contains(sl, item), "list (len=%d) does not contain contains %v", len(sl), item) } // Panic asserts that the function (op) panics when executed. diff --git a/ft/ft.go b/ft/ft.go index 2b2214a..ef9fecb 100644 --- a/ft/ft.go +++ b/ft/ft.go @@ -2,6 +2,7 @@ package ft import ( "context" + "slices" "sync" "time" @@ -177,11 +178,7 @@ func WhenApplyFuture[T any](cond bool, op func(T), arg func() T) { // WhenHandle passes the argument "in" to the operation IF the // condition function (which also takes "in") returns true. Panics if // the function is nil. -func WhenHandle[T any](cond func(T) bool, op func(T), in T) { - if cond(in) { - op(in) - } -} +func WhenHandle[T any](cond func(T) bool, op func(T), in T) { WhenApply(cond(in), op, in) } // DoTimes runs the specified option n times. func DoTimes(n int, op func()) { @@ -198,7 +195,7 @@ func SafeCall(op func()) { } // SafeDo calls the function when the operation is non-nil, and -// returns either the output of the function or +// returns either the output of the function or the zero value of T. func SafeDo[T any](op func() T) (out T) { if op != nil { out = op() @@ -214,7 +211,7 @@ func SafeWrap(op func()) func() { return func() { SafeCall(op) } } // Flip takes two arguments and returns them in the opposite // order. Intended to wrap other functions to reduce the friction when -// briding APIs +// briding APIs. func Flip[A any, B any](first A, second B) (B, A) { return second, first } // Ignore is a noop, but can be used to annotate operations rather @@ -237,8 +234,10 @@ func IgnoreSecond[A any, B any](a A, _ B) A { return a } // object. func Once(f func()) func() { o := &sync.Once{}; f = SafeWrap(f); return func() { o.Do(f) } } -// OnceDo runs a function, exactly once, to produce a value which is -// then cached, and returned on any successive calls to the function. +// OnceDo returns a function, that will run exactly once. The value +// returned by the inner function is cached transparently, so +// subsequent calls to the function returned by OnceDo will return the +// original value. func OnceDo[T any](op func() T) func() T { var cache T opw := Once(func() { cache = op() }) @@ -247,14 +246,9 @@ func OnceDo[T any](op func() T) func() T { // Contain returns true if an element of the slice is equal to the // item. -func Contains[T comparable](item T, slice []T) bool { - for _, i := range slice { - if i == item { - return true - } - } - return false -} +// +// Deprecated: use slices.Contains from the standard library. +func Contains[T comparable](item T, slice []T) bool { return slices.Contains(slice, item) } // Wrapper produces a function that always returns the value // provided. Useful for bridging interface paradigms, and for storing @@ -262,7 +256,8 @@ func Contains[T comparable](item T, slice []T) bool { func Wrapper[T any](in T) func() T { return func() T { return in } } // Join creates a function that iterates over all of the input -// functions and calls all non-nil functions. Nil inputs are ignored.. +// functions and calls all non-nil functions sequentially. Nil +// functions are ignored. func Join(fns ...func()) func() { return func() { for _, f := range fns { @@ -303,8 +298,8 @@ func WithContext(op func(context.Context)) { // and returns the first value if the second value is ok. Useful as // in: // -// out := ft.MustBeOk(func() (string ok) { return "hello world", true }) +// out := ft.MustBeOk(func() (string, bool) { return "hello world", true }) func MustBeOk[T any](out T, ok bool) T { - WhenCall(!ok, func() { panic(ers.Join(ers.New("ok check failed"), ers.ErrInvariantViolation)) }) + WhenCall(!ok, func() { panic(ers.Join(ers.New("check failed"), ers.ErrInvariantViolation)) }) return out } diff --git a/intish/atomic.go b/intish/atomic.go index 99d2662..835cdde 100644 --- a/intish/atomic.go +++ b/intish/atomic.go @@ -24,7 +24,8 @@ func (a *Atomic[T]) CompareAndSwap(oldVal, newValue T) bool { // AtomicFloat64 provides full-fidelity atomic storage for float64 // values (by converting them) as bits to int64 and storing them using // sync/atomic.Int64 values. The Add() method is correct, but must -// spin, unlike for integers which rely on an optimized underlying instruction. +// spin, unlike for integers which rely on an optimized underlying +// instruction. // // AtomicFloat64 shares an interface with the adt.Atomic wrapper types. type AtomicFloat64 struct{ n atomic.Int64 } diff --git a/intish/math.go b/intish/math.go index 05ea740..60dc8d6 100644 --- a/intish/math.go +++ b/intish/math.go @@ -7,7 +7,7 @@ import ( "fmt" ) -// Numbers are the set of singed and unsinged integers, used by this package. +// Numbers are the set of singed and unsinged integers as used by this package. type Numbers interface { Signed | Unsigned } @@ -70,7 +70,7 @@ func Max[T Numbers](a, b T) T { func Diff[T Numbers](a, b T) T { return Max(a, b) - Min(a, b) } // FloatMillis reverses, though potentially (often) not without some -// loss of fidelity +// loss of fidelity, the operation of Millis. func FloatMillis[T Signed](in T) float64 { return float64(in) / 1000 } // Millis converts a float into a an integer that represents one