Claude Code for funcy: Functional Programming Utilities in Python — Claude Skills 360 Blog
Blog / AI / Claude Code for funcy: Functional Programming Utilities in Python
AI

Claude Code for funcy: Functional Programming Utilities in Python

Published: June 4, 2028
Read time: 5 min read
By: Claude Skills 360

funcy is a practical functional programming library for Python. pip install funcy. Compose: from funcy import compose; fn = compose(str, abs, int) — right-to-left. rcompose: left-to-right. partial: from funcy import partial; double = partial(mul, 2). curry: from funcy import curry; @curry; def add(a,b): return a+b; add(1)(2). memoize: from funcy import memoize; @memoize; def fib(n): .... memoize_plain: no cache invalidation. group_by: from funcy import group_by; group_by(len, ["hi","hello","hey"]) → {2:[“hi”],5:[“hello”],3:[“hey”]}. count_by: count_by(len, words) → {2:1,5:1,3:1}. distinct: from funcy import distinct; distinct([1,2,1,3]) → [1,2,3]. flatten: from funcy import flatten; flatten([[1,2],[3,4]]) → [1,2,3,4]. chunks: from funcy import chunks; chunks(2, [1,2,3,4]) → [[1,2],[3,4]]. first: from funcy import first; first([3,2,1]) → 3. last: last(seq). nth: nth(2, seq). take: from funcy import take; take(3, range(100)). drop: drop(2, seq). rest: rest(seq) — skip first. take_while: from funcy import take_while; take_while(lambda x: x<5, range(10)). imap: from funcy import imap; imap(fn, seq) — lazy. ifilter: from funcy import ifilter. merge: from funcy import merge; merge(d1, d2) — deep merge. project: project({"a":1,"b":2}, ["a"]) → {“a”:1}. omit: omit(d, ["key"]). select_keys: select_keys(fn, d). walk_values: from funcy import walk_values; walk_values(str.upper, d). retry: from funcy import retry; @retry(3, errors=RequestException). silent: from funcy import silent; silent(int)("bad") → None. Claude Code generates funcy data transformers, memoized fetchers, retry wrappers, and functional pipelines.

CLAUDE.md for funcy

## funcy Stack
- Version: funcy >= 2.0 | pip install funcy
- Compose: compose(f3, f2, f1)(x) → f3(f2(f1(x))) | rcompose(f1,f2,f3)
- Group: group_by(key_fn, seq) | count_by(key_fn, seq)
- Sequence: take(n, seq) | drop(n, seq) | chunks(n, seq) | flatten(nested)
- Dict: merge(a, b) | project(d, keys) | omit(d, keys) | walk_values(fn, d)
- Retry: @retry(3, errors=MyError) | @silent wraps exceptions → None

funcy Functional Utilities Pipeline

# app/functional.py — funcy compose, group, sequence, dict, memoize, retry, predicates
from __future__ import annotations

import time
from typing import Any, Callable, Iterable, TypeVar

from funcy import (
    autocurry,
    chunks,
    compose,
    count_by,
    curry,
    distinct,
    drop,
    first,
    flatten,
    group_by,
    ifilter,
    imap,
    last,
    memoize,
    merge,
    nth,
    omit,
    partial,
    project,
    rcompose,
    rest,
    retry,
    select_keys,
    silent,
    take,
    take_while,
    walk_keys,
    walk_values,
)


T = TypeVar("T")
K = TypeVar("K")
V = TypeVar("V")


# ─────────────────────────────────────────────────────────────────────────────
# 1. Function composition
# ─────────────────────────────────────────────────────────────────────────────

def pipeline(*fns: Callable) -> Callable:
    """
    Create a left-to-right function pipeline (rcompose).

    Example:
        clean = pipeline(str.strip, str.lower, str.title)
        clean("  hello world  ")  # "Hello World"

        to_int = pipeline(str.strip, int)
        to_int("  42  ")  # 42
    """
    return rcompose(*fns)


def transform(value: Any, *fns: Callable) -> Any:
    """
    Apply a sequence of functions left-to-right to a value.

    Example:
        transform("  HELLO  ", str.strip, str.lower)  # "hello"
        transform(4, lambda x: x**2, lambda x: x+1)   # 17
    """
    result = value
    for fn in fns:
        result = fn(result)
    return result


def memoized(fn: Callable) -> Callable:
    """
    Memoize a function using funcy's @memoize.
    Results are cached indefinitely (LRU available via functools.lru_cache).

    Example:
        @memoized
        def expensive(n):
            time.sleep(0.1)
            return n * n
    """
    return memoize(fn)


# ─────────────────────────────────────────────────────────────────────────────
# 2. Collection grouping and counting
# ─────────────────────────────────────────────────────────────────────────────

def group_records(records: list[dict], key: str) -> dict[Any, list[dict]]:
    """
    Group a list of dicts by a field value.

    Example:
        users = [{"dept": "eng", "name": "Alice"}, {"dept": "hr", "name": "Bob"}, ...]
        by_dept = group_records(users, "dept")
        # {"eng": [{"dept":"eng","name":"Alice"},...], "hr": [...]}
    """
    return group_by(lambda r: r.get(key), records)


def count_records(records: list[dict], key: str) -> dict[Any, int]:
    """
    Count records by a field value.

    Example:
        count_records(orders, "status")
        # {"pending": 3, "shipped": 10, "returned": 1}
    """
    return count_by(lambda r: r.get(key), records)


def group_by_fn(key_fn: Callable, seq: Iterable) -> dict:
    """
    Group sequence items by a key function.

    Example:
        group_by_fn(len, ["hi", "hello", "hey"])
        # {2: ["hi"], 5: ["hello"], 3: ["hey"]}

        group_by_fn(lambda x: x % 3, range(9))
        # {0: [0,3,6], 1: [1,4,7], 2: [2,5,8]}
    """
    return group_by(key_fn, seq)


def frequencies(seq: Iterable) -> dict:
    """Count occurrences of each element."""
    return count_by(lambda x: x, seq)


# ─────────────────────────────────────────────────────────────────────────────
# 3. Sequence utilities
# ─────────────────────────────────────────────────────────────────────────────

def batch(seq: Iterable[T], size: int) -> list[list[T]]:
    """
    Split sequence into fixed-size batches.

    Example:
        batch(range(10), 3)  # [[0,1,2], [3,4,5], [6,7,8], [9]]
    """
    return list(chunks(size, seq))


def unique(seq: Iterable[T], key: Callable | None = None) -> list[T]:
    """
    Remove duplicates while preserving order.

    Example:
        unique([3, 1, 4, 1, 5, 9, 2, 6, 5])    # [3, 1, 4, 5, 9, 2, 6]
        unique(users, key=lambda u: u["email"])  # deduplicate by email
    """
    return list(distinct(seq, key=key) if key else distinct(seq))


def flatten_list(nested: Iterable, depth: int = 1) -> list:
    """
    Flatten a nested list structure.
    depth=1 flattens one level; pass a large number for full flatten.

    Example:
        flatten_list([[1, 2], [3, [4, 5]]])        # [1, 2, 3, [4, 5]]
        flatten_list([[1, 2], [3, [4, 5]]], depth=2)  # [1, 2, 3, 4, 5]
    """
    result = list(nested)
    for _ in range(depth):
        result = list(flatten(result))
    return result


def window(seq: list[T], size: int, step: int = 1) -> list[list[T]]:
    """
    Sliding window over a sequence.

    Example:
        window([1, 2, 3, 4, 5], 3)        # [[1,2,3], [2,3,4], [3,4,5]]
        window([1, 2, 3, 4, 5], 3, step=2) # [[1,2,3], [3,4,5]]
    """
    return [seq[i:i + size] for i in range(0, len(seq) - size + 1, step)]


def page(seq: list[T], page_num: int, per_page: int = 20) -> list[T]:
    """
    Return a single page from a list.

    Example:
        page(items, 2, per_page=10)  # items[10:20]
    """
    start = (page_num - 1) * per_page
    return seq[start:start + per_page]


def safe_first(seq: Iterable[T], default: T | None = None) -> T | None:
    """Return first element or default."""
    result = first(seq)
    return result if result is not None else default


def safe_last(seq: list[T], default: T | None = None) -> T | None:
    """Return last element or default."""
    result = last(seq)
    return result if result is not None else default


# ─────────────────────────────────────────────────────────────────────────────
# 4. Dict operations
# ─────────────────────────────────────────────────────────────────────────────

def pick(d: dict, keys: list) -> dict:
    """
    Extract only the specified keys from a dict.

    Example:
        pick({"a": 1, "b": 2, "c": 3}, ["a", "c"])  # {"a": 1, "c": 3}
    """
    return project(d, keys)


def omit_keys(d: dict, keys: list) -> dict:
    """
    Return dict without the specified keys.

    Example:
        omit_keys(user, ["password", "_id"])
    """
    return omit(d, keys)


def deep_merge(*dicts: dict) -> dict:
    """
    Merge multiple dicts, later values overwrite earlier (shallow).

    Example:
        deep_merge(defaults, overrides, local_overrides)
    """
    result = {}
    for d in dicts:
        result = merge(result, d)
    return result


def rename_keys(d: dict, mapping: dict[str, str]) -> dict:
    """
    Rename dict keys.

    Example:
        rename_keys({"firstName": "Alice", "lastName": "Smith"},
                    {"firstName": "first_name", "lastName": "last_name"})
        # {"first_name": "Alice", "last_name": "Smith"}
    """
    return {mapping.get(k, k): v for k, v in d.items()}


def transform_values(d: dict, fn: Callable) -> dict:
    """Apply fn to all values in a dict."""
    return walk_values(fn, d)


def transform_keys(d: dict, fn: Callable) -> dict:
    """Apply fn to all keys in a dict."""
    return walk_keys(fn, d)


def filter_dict(d: dict, predicate: Callable) -> dict:
    """
    Keep only keys that pass the predicate.

    Example:
        filter_dict({"a": 1, "b": None, "c": 3}, lambda k: d[k] is not None)
    """
    return {k: v for k, v in d.items() if predicate(k)}


def filter_values(d: dict, predicate: Callable) -> dict:
    """
    Keep only entries whose value passes the predicate.

    Example:
        filter_values({"a": 1, "b": None, "c": 3}, lambda v: v is not None)
        # {"a": 1, "c": 3}
    """
    return {k: v for k, v in d.items() if predicate(v)}


# ─────────────────────────────────────────────────────────────────────────────
# 5. Retry and error-silent wrappers
# ─────────────────────────────────────────────────────────────────────────────

def with_retry(
    fn: Callable,
    times: int = 3,
    errors: type | tuple = Exception,
    delay: float = 1.0,
) -> Callable:
    """
    Wrap a function with retry logic.
    delay: seconds to sleep between attempts.

    Example:
        safe_fetch = with_retry(requests.get, times=3, errors=ConnectionError, delay=2.0)
        response   = safe_fetch("https://api.example.com/data")
    """
    @retry(times, errors=errors)
    def wrapper(*args, **kwargs):
        try:
            return fn(*args, **kwargs)
        except errors:
            time.sleep(delay)
            raise
    return wrapper


def silent_call(fn: Callable, *args, default: Any = None, **kwargs) -> Any:
    """
    Call fn, returning default instead of raising on any exception.

    Example:
        val = silent_call(int, "abc", default=0)     # 0
        val = silent_call(json.loads, "{bad}", default={}) # {}
    """
    try:
        return fn(*args, **kwargs)
    except Exception:
        return default


def safe_map(fn: Callable, seq: Iterable, skip_errors: bool = True) -> list:
    """
    Map fn over seq, optionally skipping items that raise exceptions.

    Example:
        ints = safe_map(int, ["1", "2", "bad", "4"])  # [1, 2, 4]
    """
    results = []
    for item in seq:
        try:
            results.append(fn(item))
        except Exception:
            if not skip_errors:
                raise
    return results


# ─────────────────────────────────────────────────────────────────────────────
# Demo
# ─────────────────────────────────────────────────────────────────────────────

if __name__ == "__main__":
    print("=== Function composition ===")
    clean = pipeline(str.strip, str.lower)
    print(f"  clean('  HELLO  '): {clean('  HELLO  ')!r}")
    print(f"  transform(4, sq, +1): {transform(4, lambda x: x**2, lambda x: x+1)}")

    print("\n=== Grouping ===")
    words = ["hi", "hello", "hey", "bye", "world"]
    print(f"  group_by(len):   {group_by_fn(len, words)}")
    print(f"  count_by(len):   {count_by(len, words)}")
    print(f"  frequencies:     {frequencies(['a','b','a','c','b','a'])}")

    print("\n=== Sequences ===")
    nums = list(range(10))
    print(f"  batch(range(10),3): {batch(range(10), 3)}")
    print(f"  unique([3,1,4,1,5]): {unique([3,1,4,1,5])}")
    print(f"  flatten([[1,2],[3,[4]]],2): {flatten_list([[1,2],[3,[4]]], 2)}")
    print(f"  window(range(5),3): {window(list(range(5)), 3)}")

    print("\n=== Dict ops ===")
    user = {"id": 1, "name": "Alice", "password": "secret", "email": "[email protected]"}
    print(f"  pick keys:   {pick(user, ['id','name'])}")
    print(f"  omit_keys:   {omit_keys(user, ['password'])}")
    print(f"  rename:      {rename_keys({'firstName': 'Alice'}, {'firstName': 'first_name'})}")
    print(f"  filter_vals: {filter_values({'a':1,'b':None,'c':3}, lambda v: v is not None)}")

    print("\n=== safe_map ===")
    print(f"  safe_map(int, ['1','bad','3']): {safe_map(int, ['1','bad','3'])}")

    print("\n=== silent_call ===")
    import json
    print(f"  silent_call(int, 'abc', default=0): {silent_call(int, 'abc', default=0)}")
    print(f"  silent_call(json.loads, '{{bad}}', default={}): {silent_call(json.loads, '{bad}', default={})}")

For the toolz alternative — toolz provides a similar set of functional utilities (compose, curry, merge, groupby, partition) with a focus on performance via C-accelerated cytoolz; funcy has a broader API including retry, silent, memoize_plain, walk_keys/walk_values, first/last/rest, and decorator utilities — use toolz/cytoolz when raw iteration performance is the priority, funcy when you want a broader set of higher-level utilities including error handling and decorators. For the itertools / more-itertools alternative — itertools and more-itertools are stdlib/extension packages for iterator operations; funcy wraps many of their patterns with named, self-documenting functions (chunks, flatten, take_while, distinct) and adds dict utilities, function composition, and retry/silent helpers that itertools does not cover — use itertools for zero-dependency core iteration, funcy when you also need dict ops, memoize, and function composition in the same import. The Claude Skills 360 bundle includes funcy skill sets covering pipeline()/rcompose(), transform(), memoized(), group_records()/count_records()/group_by_fn()/frequencies(), batch()/unique()/flatten_list()/window()/page(), safe_first()/safe_last(), pick()/omit_keys()/deep_merge()/rename_keys()/transform_values()/transform_keys()/filter_dict()/filter_values(), with_retry()/silent_call()/safe_map(). Start with the free tier to try functional programming utility code generation.

Keep Reading

AI

Claude Code for email.contentmanager: Python Email Content Accessors

Read and write EmailMessage body content with Python's email.contentmanager module and Claude Code — email contentmanager ContentManager for the class that maps content types to get and set handler functions allowing EmailMessage to support get_content and set_content with type-specific behaviour, email contentmanager raw_data_manager for the ContentManager instance that handles raw bytes and str payloads without any conversion, email contentmanager content_manager for the standard ContentManager instance used by email.policy.default that intelligently handles text plain text html multipart and binary content types, email contentmanager get_content_text for the handler that returns the decoded text payload of a text-star message part as a str, email contentmanager get_content_binary for the handler that returns the raw decoded bytes payload of a non-text message part, email contentmanager get_data_manager for the get-handler lookup used by EmailMessage get_content to find the right reader function for the content type, email contentmanager set_content text for the handler that creates and sets a text part correctly choosing charset and transfer encoding, email contentmanager set_content bytes for the handler that creates and sets a binary part with base64 encoding and optional filename Content-Disposition, email contentmanager EmailMessage get_content for the method that reads the message body using the registered content manager handlers, email contentmanager EmailMessage set_content for the method that sets the message body and MIME headers in one call, email contentmanager EmailMessage make_alternative make_mixed make_related for the methods that convert a simple message into a multipart container, email contentmanager EmailMessage add_attachment for the method that attaches a file or bytes to a multipart message, and email contentmanager integration with email.message and email.policy and email.mime and io for building high-level email readers attachment extractors text body accessors HTML readers and policy-aware MIME construction pipelines.

5 min read Feb 12, 2029
AI

Claude Code for email.charset: Python Email Charset Encoding

Control header and body encoding for international email with Python's email.charset module and Claude Code — email charset Charset for the class that wraps a character set name with the encoding rules for header encoding and body encoding describing how to encode text for that charset in email messages, email charset Charset header_encoding for the attribute specifying whether headers using this charset should use QP quoted-printable encoding BASE64 encoding or no encoding, email charset Charset body_encoding for the attribute specifying the Content-Transfer-Encoding to use for message bodies in this charset such as QP or BASE64, email charset Charset output_codec for the attribute giving the Python codec name used to encode the string to bytes for the wire format, email charset Charset input_codec for the attribute giving the Python codec name used to decode incoming bytes to str, email charset Charset get_output_charset for returning the output charset name, email charset Charset header_encode for encoding a header string using the charset's header_encoding method, email charset Charset body_encode for encoding body content using the charset's body_encoding, email charset Charset convert for converting a string from the input_codec to the output_codec, email charset add_charset for registering a new charset with custom encoding rules in the global charset registry, email charset add_alias for adding an alias name that maps to an existing registered charset, email charset add_codec for registering a codec name mapping for use by the charset machinery, and email charset integration with email.message and email.mime and email.policy and email.encoders for building international email senders non-ASCII header encoders Content-Transfer-Encoding selectors charset-aware message constructors and MIME encoding pipelines.

5 min read Feb 11, 2029
AI

Claude Code for email.utils: Python Email Address and Header Utilities

Parse and format RFC 2822 email addresses and dates with Python's email.utils module and Claude Code — email utils parseaddr for splitting a display-name plus angle-bracket address string into a realname and email address tuple, email utils formataddr for combining a realname and address string into a properly quoted RFC 2822 address with angle brackets, email utils getaddresses for parsing a list of raw address header strings each potentially containing multiple comma-separated addresses into a list of realname address tuples, email utils parsedate for parsing an RFC 2822 date string into a nine-tuple compatible with time.mktime, email utils parsedate_tz for parsing an RFC 2822 date string into a ten-tuple that includes the UTC offset timezone in seconds, email utils parsedate_to_datetime for parsing an RFC 2822 date string into an aware datetime object with timezone, email utils formatdate for formatting a POSIX timestamp or the current time as an RFC 2822 date string with optional usegmt and localtime flags, email utils format_datetime for formatting a datetime object as an RFC 2822 date string, email utils make_msgid for generating a globally unique Message-ID string with optional idstring and domain components, email utils decode_rfc2231 for decoding an RFC 2231 encoded parameter value into a tuple of charset language and value, email utils encode_rfc2231 for encoding a string as an RFC 2231 encoded parameter value, email utils collapse_rfc2231_value for collapsing a decoded RFC 2231 tuple to a Unicode string, and email utils integration with email.message and email.headerregistry and datetime and time for building address parsers date formatters message-id generators header extractors and RFC-compliant email construction utilities.

5 min read Feb 10, 2029

Put these ideas into practice

Claude Skills 360 gives you production-ready skills for everything in this article — and 2,350+ more. Start free or go all-in.

Back to Blog

Get 360 skills free