exp

package module
v0.0.0-...-9687f63 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 12, 2024 License: Apache-2.0 Imports: 14 Imported by: 0

README

exp

Go Reference Build status

Experiments 🧑‍🔬

Documentation

Overview

Package exp contains some code that should be considered experimental and comes with absolutely no guarantees whatsoever (particularly around compatibility, consistency, or functionality).

Index

Examples

Constants

This section is empty.

Variables

View Source
var Break = errors.New("break")

Break is used to exit the RangeCh loop early without error.

Functions

func Fmatchf

func Fmatchf(input io.Reader, format string, into ...any) bool

Fmatchf wraps fmt.Fscanf, reporting whether input was scanned successfully.

func Must

func Must[T any](t T, err error) T

Must returns t if err is nil. If err is not nil, it panics. In other words, Must is a "do-or-die" wrapper for function calls that can return a value and an error. This is a helper intended for very simple programs (e.g. Advent of Code) and is not recommended for production code (handle errors properly!)

func Must0

func Must0(err error)

Must0 panics if err is not nil. This is a helper intended for very simple programs (e.g. Advent of Code) and is not recommended for production code (handle errors properly!)

func Must2

func Must2[T, U any](t T, u U, err error) (T, U)

Must2 returns (t, u) if err is nil. If err is not nil, it panics. This is a helper intended for very simple programs (e.g. Advent of Code) and is not recommended for production code (handle errors properly!)

func Must3

func Must3[T, U, V any](t T, u U, v V, err error) (T, U, V)

Must3 returns (t, u, v) if err is nil. If err is not nil, it panics. This is a helper intended for very simple programs (e.g. Advent of Code) and is not recommended for production code (handle errors properly!)

func MustAtoi

func MustAtoi(s string) int

MustAtoi parses the string as an integer, or panics. This is a helper intended for very simple programs (e.g. Advent of Code) and is not recommended for production code (handle errors properly!)

func MustCut

func MustCut(s, sep string) (before, after string)

MustCut is a version of strings.Cut that panics if sep is not found within s. This is a helper intended for very simple programs (e.g. Advent of Code) and is not recommended for production code (handle errors properly!)

func MustForEachLineIn

func MustForEachLineIn(path string, cb func(line string))

MustForEachLineIn calls cb with each line in the file. It uses a bufio.Scanner internally, which can fail on longer lines. If an error is encountered, it calls log.Fatal. This is a helper intended for very simple programs (e.g. Advent of Code) and is not recommended for production code, particularly because the logged message may be somewhat unhelpful.

func MustFunc

func MustFunc[S, T any](f func(s S) (T, error)) func(S) T

MustFunc converts a func (S -> (T, error)) into a func (S -> T) that instead panics on any error. This is a helper intended for very simple programs (e.g. Advent of Code) and is not recommended for production code (handle errors properly!)

func MustReadByteGrid

func MustReadByteGrid(path string) grid.Dense[byte]

MustReadByteGrid reads the entire file into memory and returns the contents in the form of a dense byte grid.

func MustReadDelimited

func MustReadDelimited(path, delim string) []string

MustReadDelimited reads the entire file into memory, splits the contents by a delimiter, trims leading and trailing spaces from each component, and returns the results as a slice. If an error is encountered, it calls log.Fatal. This is a helper intended for very simple programs (e.g. Advent of Code) and is not recommended for production code, particularly because the logged message may be somewhat unhelpful.

func MustReadInts

func MustReadInts(path, delim string) []int

MustReadInts reads the entire file into memory, splits the contents by the delimiter, parses each component as a decimal integer, and returns them as a slice. If an error is encountered, it calls log.Fatal. This is a helper intended for very simple programs (e.g. Advent of Code) and is not recommended for production code, particularly because the logged message may be somewhat unhelpful.

func MustReadLines

func MustReadLines(path string) []string

MustReadLines reads the entire file into memory and returns a slice containing each line of text (essentially, strings.Split(contents, "\n"), but ignoring the final element if it is empty). If an error is encountered, it calls log.Fatal. This is a helper intended for very simple programs (e.g. Advent of Code) and is not recommended for production code, particularly because the logged message may be somewhat unhelpful.

func MustSscanf

func MustSscanf(s, f string, a ...any)

MustSscanf parses strings, or panics. This is a helper intended for very simple programs (e.g. Advent of Code) and is not recommended for production code (handle errors properly!)

func Ptr

func Ptr[T any](t T) *T

Ptr returns a pointer to a variable having the value t. (Because you can't just say &true, &42, or &"foo"; you have to put it in a variable first.)

func RangeCh

func RangeCh[T any](ctx context.Context, ch <-chan T, f func(T) error) error

RangeCh ranges over a channel in a context-aware way.

Example
ctx := context.Background()

ch := make(chan int)
wait := make(chan struct{})

go func() {
	defer close(wait)

	sum := 0
	err := RangeCh(ctx, ch, func(n int) error {
		sum += n
		return nil
	})
	if err != nil {
		fmt.Printf("Error: %v\n", err)
		return
	}
	fmt.Printf("Sum: %d\n", sum)
}()

for i := 1; i <= 10; i++ {
	ch <- i
}
close(ch)

<-wait
Output:

Sum: 55
Example (Timeout)
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Millisecond)
defer cancel()

// Waits forever because nothing closes the channel
ch := make(chan int)
err := RangeCh(ctx, ch, func(int) error {
	return nil
})

fmt.Printf("Error: %v\n", err)
Output:

Error: context deadline exceeded

func Retry

func Retry(ctx context.Context, count int, initial time.Duration, grow float64) <-chan time.Time

Retry creates a channel on which the current time is sent up to count times. The first time is sent immediately, with the nth subsequent time sent after waiting a random duration D ~ Uniform[0, initial*grow^n), i.e the upper bound of wait duration between sends is the geometric sequence: initial, initial*grow, initial*grow^2, ... Because the channel is unbuffered, the overall duration between consecutive sends can be greater than the time waited (by the time taken by the receive side), but the overall duration is not necessarily the sum of the Retry wait and the work. For example,

  for range Retry(ctx, 5, 1*time.Second, 1.0) {
	     // nothing
  }

will take around 2 seconds (sum of 4 random durations D ~ U[0, 1)), but

  for range Retry(ctx, 5, 1*time.Second, 1.0) {
	     time.Sleep(2*time.Second)
  }

will take 10 seconds (Retry tries to send during the sleep in the loop).

To ensure resources (internal goroutines) are cleaned up, cancel the context. The channel is closed when the internal goroutine returns.

Example
ctx, canc := context.WithCancel(context.Background())
defer canc()

attempts := 0
for range Retry(ctx, 5, 10*time.Millisecond, 2.0) {
	attempts++
}

fmt.Println(attempts)
Output:

5

func Retry2

func Retry2(ctx context.Context, count int, initial time.Duration, grow float64) func(func(time.Time) bool)

Retry2 is like Retry, but returns a Go 1.22 "GOEXPERIMENT=rangefunc" style "iterator" and does not use an extra goroutine under the hood. With the rangefunc experiment enabled, you can write:

for t := range exp.Retry2(ctx, 5, 1*time.Second, 2.0) {
	// try to do thing here
}

Without Go 1.22 and the experiment, you can exercise it manually:

exp.Retry2(ctx, 5, 1*time.Second, 2.0)(func(t time.Time) bool {
	// try to do thing here
	// return true to keep retrying
	return true
})

Because there is no underlying goroutine, to match the behaviour of original- flavour Retry, Retry2 measures how long `yield` takes and subtracts it from the next wait. Because `yield` can take arbitrarily long, it can therefore be called again immediately.

func Smatchf

func Smatchf(input, format string, into ...any) bool

Smatchf wraps fmt.Sscanf, reporting whether input was scanned successfully.

Types

type Uint128

type Uint128 struct {
	// contains filtered or unexported fields
}

func NewUint128

func NewUint128(hi, lo uint64) Uint128

func (Uint128) Add

func (x Uint128) Add(y Uint128) (z Uint128)

func (Uint128) Cmp

func (x Uint128) Cmp(y Uint128) int

func (Uint128) Lsh

func (x Uint128) Lsh(k int) Uint128

func (Uint128) Mul

func (x Uint128) Mul(y Uint128) (z Uint128)

func (Uint128) Rsh

func (x Uint128) Rsh(k int) Uint128

func (Uint128) Sub

func (x Uint128) Sub(y Uint128) (z Uint128)

Directories

Path Synopsis
Package algebra implements various generic algebra types.
Package algebra implements various generic algebra types.
Package algo implements a few generic algorithms.
Package algo implements a few generic algorithms.
Package emu provides a generalised virtual machine for executing toy programs that operate solely on integers.
Package emu provides a generalised virtual machine for executing toy programs that operate solely on integers.
Package para implements parallel versions of some things in algo.
Package para implements parallel versions of some things in algo.
Package parse contains string parsing helper functions.
Package parse contains string parsing helper functions.
Package stream provides a variety of context-aware generic functions that operate on channels.
Package stream provides a variety of context-aware generic functions that operate on channels.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL