Skip to content
This repository has been archived by the owner on May 24, 2024. It is now read-only.
/ go-stackage Public archive

stackage implements flexible stack and condition types with useful features

License

Notifications You must be signed in to change notification settings

JesseCoretta/go-stackage

Repository files navigation

go-stackage

Go Report Card Go Reference CodeQL Software License codecov contributions welcome Experimental GitHub Workflow Status (with event) Author GitHub release (with filter) Help Animals

stacks03

Summary

The stackage package implements flexible Stack and Condition types with many useful features. It can be used to create object-based Boolean statements, abstract mathematical constructs, simple lists and much more: the possibilities are endless!

Mission

The main goal of this package is provide an extremely reliable and accommodating stack/condition solution that is suitable for use in virtually any conceivable Go-based scenario in which objects of these types are needed. While extremely extensible and flexible, it should always be possible to use this package with no need for additional (non main) code while operating in extremely simple scenarios.

Features

  • Stack instances are either LIFO (stack based, default) or FIFO (queue based)
    • FIFO is First-In/First-Out (like a line at your favorite deli: first come, first serve)
    • LIFO is Last-In/First-Out (like those plate-stacking apparatuses found in restaurant kitchens, in which the first plate inserted shall be the last plate removed)
  • Flexible Stack configuration controls, allowing custom stringer presentation, push controls and validity-checking policies to be imposed
  • Recursive design - Stacks can reside in Stacks. Conditions can reside in Stacks. Conditions can contain other Stacks. Whatever!
    • Eligible values are easily navigated using the Stack.Traverse method using an ordered sequence of indices, or slice index numbers
    • Conversely, recursion capabilities can also be easily disabled per instance!
  • Observable - flexible logging facilities, using the log package are available globally, or on a per-instance basis
  • Interrogable - Stacks and Conditions extend many interrogation features, allowing the many facets and "states" of an instance to be queried simply
  • Resilient - Stack writeability can be toggled easily, allowing safe (albeit naïve) read-only operation without the need for mutexing
  • Fluent-style - Types which offer methods for cumulative configuration are written in fluent-form, allowing certain commands to be optionally "chained" together
  • Extensible
    • Logical operator framework allows custom operators to be added for specialized expressions, instead of the package-provided ComparisonOperator constants
    • Users can add their own Evaluator function to perform computational tasks, value interrogation, matching procedures ... pretty much anything you could imagine
  • Stack instances are (independently) MuTeX capable, thanks to the sync package
    • Recursive locking mechanisms are NOT supported due to my aversion to insanity
  • Adopters may create a type alias of the Condition and/or Stack types
  • Fast, reliable, useful, albeit very niche

Status

Although fairly well-tested, this package is in its early stages and is undergoing active development. It should only be used in production environments while under heavy scrutiny and with great care.

License

The stackage package, from go-stackage, is released under the terms of the MIT license. See the LICENSE file in the repository root, or click the License badge above, for complete details.

Type Aliasing

When needed, users may opt to create their own derivative alias types of either the Stack or Condition types for more customized use in their application.

The caveat, naturally, is that users will be expected to wrap all of the package-provided methods (e.g.: String, Push, Pop, etc) they intend to use.

However, the upside is that the user may now write (extend) wholly new methods that are unique to their own application, and without having to resort to potentially awkward measures, such as embedding.

To create a derivative type based on the Stack type, simply do something similar to the following example in your code:

type MyStack stackage.Stack

// Here we extend a wholly new function. The input and output signatures
// are entirely defined at the discretion of the author and are shown in
// "pseudo code context" here.
func (r MyStack) NewMethodName([input signature]) [<output signature>] {
	// your custom code, do whatever!
}

// Here we wrap a pre-existing package-provided function, String, that
// one would probably intend to use.
// 
// To run the actual String method, we need to first CAST the custom
// type (r, MyStack) to a bonafide stackage.Stack instance as shown
// here. Unlike the above example, this is NOT "pseudo code" and will
// compile just fine.
//
// Repeat as needed for other methods that may be used.
func (r MyStack) String() string {
 	// return the result from a "TYPE CAST -> EXEC" call
	return stackage.Stack(r).String()
}

The procedure would be identical for a Condition alias -- just change the name and the derived stackage type from the first example line and modify as desired.

If you'd like to see a more complex working example of this concept in the wild, have a look at the go-aci package, which makes heavy use of derivative stackage types.