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

Katy

v1.0.0

Published

CoffeeScript Combinators

Downloads

7

Readme

Katy: Coffeescript Combinators

Katy makes writing fluent Coffeescript easy by providing the .K and .T combinators for Coffeescript objects.

The tl;dr is that Katy adds two methods, .K and .T to any class or classes you desire:

KT = require('Katy').KT

KT.mixInto(String)

# K calls a function on the receiver and returns the receiver

'Hello'.K (s) -> s + ' World'
  # => returns 'Hello'
  
# T calls a function on the receiver and returns the result

'Hello'.K (s) -> s + ' World'
  # => returns 'Hello World'

You can also call any method by name:

KT.mixInto(Array)

[1..10]
  .K('pop')
  .K('pop')
  .K('pop')
  .T('pop')
  # => returns 7

How does that make my code more fluent?

You're familiar with fluent interfaces. They're great, but they rely on the author of the API making sure that each function returns its receiver. The .K method allows you to make any function or method "fluent" even if the original author has other ideas. The .K and .T methods also allow you to write your own methods and 'call' them just as if they were baked into the original object. For example, you can fake an identifiers filter for arrays of strings:

require 'underscore'

identifiers = (arrOfSymbols) ->
  _.select arrOfSymbols, (str) ->
    /^[_a-zA-Z]\w*$/.test(str)
  
someArray
  .T(identifiers)
  .K('someMethodName')
  .T(someOtherFilter)

This is cleaner than trying to mix oridinary functions with methods and adopting tenporary variables when you want to work around what the function was written to return. In this example, having extended Array.prototype with .K and .T once, you need not extend it any more to add your own custom methods.

To recap:

  1. You can make any function into something that can be called like a method, making your code read more naturally, and;
  2. You can give any function or built-in method either "fluent" (return the receiver) or "pipeline" (return its value) semantics as you please.

Monkey-patching is evil!

I agree. KT(foo).K(...) and KT(foo).T(...) work just fine without mixing .K and .T into an existing class, much as _(...).tap and other methods work without modifying an existing class. Also:


KT([1..10])
  .chain()
  .K('pop')
  .K('pop')
  .K('pop')
  .T('pop')
  .value()
  # => returns 7

Stuff and nonsense, this is a syntax issue, not a functional issue

I agree, but that being said:

  1. You can use katy now instead of waiting to see if Coffeescript adopts a syntax for chaining methods, and;
  2. The .K and .T methods turn any function into something you can call like a method, which makes your code read more cleanly.

Is Katy any good?

Yes.

Cool! Does it work with jQuery?

Yes, but if you like jQuery and like Katy, you'll love jQuery Combinators.

Calling a method by name is cool, but can you do more with Strings?

Try KT.installStringLambdas(). The result is not to everybody's taste, but those who like it, like it a lot.

What's with the naming conventions?

.T is known in some CS circles as the Thrush or T combinator. Likewise, .K is known in combinatory logic circles as the "K Combinator" or Kestrel. To simplify the explanation radically, T and K are called combinators because they combine things to produce a result in different ways. Functional programmers call such things higher-order functions, but what makes combinators interesting is that combinators work by rearranging the order of things in an expression.

For example, T reverses the order of two things. Think about it: Instead of writing identifiers(some_array), we use T to write some_array.T(identifiers). That rearrangement is very handy for making our code conform to fluent style. Likewise, K leaves them in the same order but removes something. This ability to rearrange things is what makes them so useful for taking code that would normally have function calls sprinkled throughout it and rearranging it into a nice tree of method calls in fluent style.

Many other combinators exist, and they are all interesting with applications for functional and OO programmers. With combinators you can even get rid of parentheses in a programming language! If you aren't familiar with Combinatory Logic, I encourage you to follow the links to my posts about Kestrels and Thrushes, and better still do a little digging about Combinatory Logic in general. It's a rich, fascinating field of study that is so simple it's incredibly easy to pick up, and it leads naturally into functional and concatenative languages.