npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@dashkite/katana

v0.4.8

Published

Stack-based composition combinators in JavaScript

Downloads

4

Readme

Katana

Daisho (stack- and context-based) composition combinators in JavaScript.

import {pipe} from "@dashkite/joy/function"
import {push, mpush, pop, stack} from "@dashkite/katana/sync"

pipe [
  push -> 3
  push -> 4
  mpush add
  pop (sum) -> assert.equal sum, 7
  stack
  (stack) -> assert.equal stack.length, 0
]

Table Of Contents

Installation

npm i @dashkite/katana

Browser-compatible. Use with your favorite bundler or import directly.

Motivation

Function composition is a powerful tool in theory, but in practice, it's often difficult for non-trivial scenarios because the arguments and return values of a given set of functions may not be amenable to simple composition. Stack-based composition provides generic context—the stack—and a set of combinators for adapting ordinary functions for use with it. This simplifies composition, even across libraries that were not designed to be used together. This is a key advantage of composition over chaining, which requires that each function be expressly added to an object as a method.

Daisho Data Structure

However, stack-based composition can lead to code that is difficult to reason about. Combining a stack with a context object makes possible variety of compositional scenarios. Context-based composition is the basis for method-chaining, or fluent, programming, popularized by jQuery, where the target object serves as the context. We call this hybrid stack/object data structure a daisho, because of its dual nature. We can use the stack for simple composition and the context for complex composition. In combination, we may use the stack to compute results we place into the context for later use.

API

Stack operations always apply a function, using the arity of the function to determine how many elements from the stack to pass into the function and possibly to remove from the stack. Applying a unary function will result in passing the top of the stack into the function. Applying a binary function will result in passing the first two elements from the stack into the function, and so on. Context operations do not apply a function, but simply move data to and from the context.

There are synchronous and asynchrouns variants for operations that apply a function. By default, when importing Katana, you get the asynchronous versions. These are bit slower since they yield control of the event loop after each operation that applies a function (since the function may return a promise). You may load the synchronous versions using a subpath:

import {push, pop} from "@dashkite/katana/sync"

You can load both variants using the wildcard import:

import * as ks from "@dashkite/katana/sync"
import * as ka from "@dashkite/katana/async"

Keep in mind that the async variants that apply a function will return a promise.

Mutability

Operations that mutate the given daisho operate on and return a clone. However, keep in mind that the values within it are not cloned (that is, it is not a deep clone).

Creating A Daisho

Daisho.create object → daisho

Daisho.create iterable → daisho

Daisho.create iterable, object → daisho

Daisho.create object, iterable → daisho

You may create a Daisho using an iterable, object, or both, in any order. The stack will be constructed from an iterable using Array.from. If you pass in an array, however, it will be used directly.

Stack Operations

Functions prefixed with an m will alter the stack based on the arity of the given function, ex: mpop, will not only pass arity elements to the given function, but will subsequently remove those elements from the stack (instead of just the first element).

push

push f, daisho → daisho

Calls f with arity f elements from the top of the stack. The result is added to the top of the stack.

pop | mpop

pop f, daisho → daisho

Calls f with arity f elements from the top of the stack. The top of the stack is removed.

peek

peek f, daisho → daisho

Calls f with arity f elements from the top of the stack. The stack is unchanged.

poke | mpoke

poke f, daisho → daisho

Calls f with arity f elements from the top of the stack. The top of the stack is replaced with the result.

pushn

pushn array<function>, daisho → daisho

Like push, but for an array of functions, pushing the result of each onto the stack.

discard

discard daisho → daisho

Discard the element at the top of the stack. Equvalent to pop -> but faster and there’s no need for a synchronous variant.

Context Operations

The read and write functions operate on the context.

read

read name, daisho → daisho

Reads a property from the context and pushes it.

write

write name, daisho → daisho

Writes the element at the top of the stack to the context.

assign

assign f, daisho → daisho

Applies the function, which should take and return a daisho as an argument and sets the context based on the returned context. Useful for performing a computation and writing the result to the context while discarding any changes to the stack.

Predicates

test predicate, action

Calls predicate with arity predicate elements from the top of the stack and calls action with the stack if the result is true.

branch conditions

Given an array of conditions whose elements are predicate, action pairs, calls predicatewitharity predicateelements from the top of the stack and callsaction` with the stack if the result is true, for each pair, until one is true.

The array may optionally take a last element as a default action (whose predicate is implicitly true).

Accessors

stack

daisho → stack

Pushes the entire stack onto the top of the stack.

context

daisho → context

Pushes the context onto the top of the stack.

get

daisho → value

Returns the top of the stack.