Z is a Java library providing accessible, consistent function combinators.

Related tags

Spring Boot z
Overview

Fearless function combination in Java

Maven Central Javadoc License

codecov dependency count jar size Lines of code GitHub repo size

Techniques

Unlock your functional programming potential with these combination techniques:

Fusion

Z.fuse(fn1, fn2) Combine two functions.

var internedTrim = Z.fuse(String::trim, String::intern);

assertEquals("hello", internedTrim.apply(" hello "));

// Protip: Interned strings can use == directly.
assertTrue("hello" == internedTrim.apply(" hello "));

Fission

Z.split(fn) Split a multiargs function into a curried form.

var concat = Z.split(String::concat);

assertEquals("hotpot", concat.apply("hot").apply("pot"));

// Protip: "Curried" functions can be partially applied.
var goodSomething = concat.apply("pre");

assertEquals("prefix", goodSomething.apply("fix"));
assertEquals("presume", goodSomething.apply("sume"));

// Protip: Z also has a "flip" function to change order.
var fixedSomething = Z.flip(concat).apply("fix");

assertEquals("prefix", fixedSomething.apply("pre"));
assertEquals("suffix", fixedSomething.apply("suf"));

Assimilation

Z.assimilate[N](curriedFn) Flatten a curried function into a multiargs function.

var checkoutMessage = Z.assimilate2(
    (String item) ->
        (String name) -> String.format("Enjoy your %s, %s!", item, name)
);

assertEquals(
    "Enjoy your bike, Alice!",
    checkoutMessage.apply("bike", "Alice")
);

Absorption

Z.absorb(fn1, fn2) Unnaturally combine two functions.

This is an evil technique. It's provided as a tool to control evil problems, not to encourage evil code.

var heroes = new ArrayList<>(List.of("joker"));

var emptiedHeroes = Z.absorb(heroes::clear, () -> heroes);

assertEquals(List.of(), emptiedHeroes.get());

heroes.add("twoface");
emptiedHeroes.get().add("batman");
assertEquals(List.of("batman"), heroes);

Super Fusion

Z.with(var or fn1).fusing(fn2).[...].fuse(fn[N]) Combine N functions.

var isLocalHost = Z.with("https?://localhost(:\\d+)?(/\\S*)?")
    .fusingFunction(Pattern::compile)
    .fusing(Pattern::matcher)
    .fuse(Matcher::matches);

assertTrue(isLocalHost.test("https://localhost:443"));

Z is lean and predictable

  1. Z only provides function combinators
  2. Z will never need other dependencies
  3. Z will never rely on reflection or code generation
  4. Techniques with the potential to cause problems are annotated as @Evil; choose your path wisely...

Comparisons and advantages

Z fusion

var asciiSum = Z.fuse(String::chars, IntStream::sum);

int sum = asciiSum.applyAsInt("abc");

Equivalent with Function::compose

Function<IntStream, Integer> sumInts = IntStream::sum;
var asciiSum = sumInts.compose(String::chars);

// Captures as a Function<String, Integer> (autoboxing/unboxing occurs)
int sum = asciiSum.apply("abc");

Equivalent with a lambda

// Inference (e.g. with var) is not possible
ToIntFunction<String> asciiSum = s -> s.chars().sum();

int sum = asciiSum.applyAsInt("abc");

Some advantages of Z here:

  1. Tacit yet explicit - Z allows for point-free function combination. This means you state your logic as a fact, and don't worry as much about the exact syntax for instructions. (Of course, Z can accept lambdas!)
  2. Explicit ordering of actions - Z lets you consistently define actions in the order they'll execute.
  3. "Just works" inference - Z techniques are optimized for a wider variety of functional interfaces. It's not necessary to define (or cast) things to a Function<A, B> in order just to expose Function::compose.
  4. Idiomatic functions - Z doesn't reimplement functional interfaces or conventions that already exist. A Predicate will have a test method, a Consumer will have an accept method, etc.

These and more examples can be found in the Usage Examples in the project's tests.

Comments
  • Add spotless for code formatting

    Add spotless for code formatting

    I'd like to see spotless added

    To be really disciplined, maybe it can go as far as

    tasks.named('build') {
        dependsOn spotlessApply // or whatever the task is
    }
    
    opened by hiljusti 2
  • Abstract more, repeat less

    Abstract more, repeat less

    There's a lot of repetition in Z code.

    Some repetition is inevitable due to limitations in the type system. Especially because it's not possible to specify primitives with generics, and the number of permutations that arise

    That said, there has got to be ways to abstract a lot of the repetition? I want to avoid code generation or reflection solutions (it has a place, but I don't think it's necessary here)

    opened by hiljusti 1
  • Write a Z announcement blog post

    Write a Z announcement blog post

    1. Write up a blog post or something
    2. Post it to Medium (however that works)
    3. Post it to Reddit places that might be interested in Java and functional programming ideas
    opened by hiljusti 1
  • Add `absorb`

    Add `absorb`

    add an absorb that can take a consumer and "peek" it in while retaining the initial function's arguments

    (use case is things like loggers etc)

    a special case can be added for tapping in loggers implementing the Slf4j interface

    opened by hiljusti 1
  • Publish to maven central

    Publish to maven central

    opened by hiljusti 0
  • Add a github workflow that runs `./gradlew build` against pull requests

    Add a github workflow that runs `./gradlew build` against pull requests

    Docs start here: https://docs.github.com/categories/automating-your-workflow-with-github-actions

    I don't have a gradle example handy (maybe one just exists?)

    I have a cargo/rust example here: https://github.com/hiljusti/sigi/blob/core/.github/workflows/cargo-build.yml

    opened by hiljusti 0
  • Document!

    Document!

    Create a documentation project to improve or add:

    • High level documentation (the "pitch")
      • Readme update
      • More articles (Z for Haskellers, Z for DBZ fans, etc)
    • Tutorials
      • Use Z to avoid static mocking
      • Use Z with dependency injection
      • Use Z for simplifying repeated logic
    • Javadocs (API documentation)
    opened by hiljusti 0
  • Currying types for deep fusions

    Currying types for deep fusions

    A proper explanation is lacking, but...

    Some sketches in Haskell of what I'm hoping to create:

    Two "BiFunction"s combined

    -- Single BiFunction
    fused a b = f a b
    fused = f
    
    -- Two BiFunctions
    fused a b c = g (f a b) c
    fused = (g .) . f
    
    fuse f g = (g .) . f
    fuse = flip ((.) . (.))
    
    -- Three BiFunctions
    fused a b c d = h (g (f a b) c) d
    fused = (((h .) . g) .) . f
    
    fuse f g h = (((h .) . g) .) . f
    fuse = flip (flip . (((.) . (.)) .) . flip ((.) . (.)))
    
    -- Four BiFunctions
    fused a b c d e = i (h (g (f a b) c) d) e
    fused = (((((i .) . h) .) . g) .) . f
    
    fused f g h i = (((((i .) . h) .) . g) .) . f
    fuse = flip (flip . ((flip . (((.) . (.)) .)) .) . flip (flip . (((.) . (.)) .) . flip ((.) . (.))))
    

    So, carve some time and see if there's a way to emulate a pattern like this in Java

    opened by hiljusti 1
Releases(v3.0.0)
  • v3.0.0(Jun 11, 2022)

    Z version 3

    This version brings more simplification and focus to Z. The total source lines of code has reduced by a little more than 12,000 lines (roughly a 40% reduction in the entire project).

    There are also less options (no multi-argument fusion functions) and less verbosity... no no need to call resolve() at the end of a fusion chain, and no fusing() or absorbing() semantic for continuations rather than terminal fusions.

    The quick changes:

    // v2 Z (these were all equivalent)
    var c = Z.fuse(a, b);
    var c = Z.with(a).fuse(b);
    var c = Z.with(a).fusing(b).resolve();
    
    // v3 Z
    var c = Z.fuse(a).fuse(b);
    

    Now .fuse(...) and .absorb(...) always result in functional interfaces. They can also be chained indefinitely unless the number of inputs required grows. (For example by fusing BiFunctions)

    For details on how to translate a more specific call pattern, see the changes in tests since 2.0.0:

    Full Changelog: https://github.com/hiljusti/z/compare/v2.0.0...v3.0.0

    Source code(tar.gz)
    Source code(zip)
  • v2.0.0(Jun 22, 2021)

    Z: 2.0.0

    Added:

    • Huge extensions to the "deep fusion" paths. (Z.with(fn1).fusing(fn2).fusing(fn3).fuse(fn4))
      • No longer marked @Experimental
    • Z.flip(fn) is introduced for argument order swapping

    Removed:

    • All unoptimized code paths for booleans have been removed. E.g.*Predicate -> Function<Boolean, ...> has been removed (or BiFunction, etc)

    Misc:

    • PMD is used (via the build.gradle) for static code analysis
    • Spotless and prettier are used (via the build.gradle) for code lint & formatting
    • Internal reorganization, renaming and editing passes performed (but more needed)
    Source code(tar.gz)
    Source code(zip)
  • v1.1.0(May 27, 2021)

    Z 1.1.0

    Added:

    • More javadocs, more tests (4% coverage to 100%)
    • More Boolean[ETC] functional interfaces
    • More "super fusions" with fusing and absorbing

    Changed:

    • BooleanUnaryOperator is now BooleanPredicate
    Source code(tar.gz)
    Source code(zip)
  • v1.0.0(May 20, 2021)

    This release finalizes the techniques:

    • Z::fuse
    • Z::split
    • Z::absorb
    • Z::assimilate[N]

    The following techniques are experimental and will be fleshed out as part of the 1.x.x versions:

    • Z::with
    Source code(tar.gz)
    Source code(zip)
  • v0.0.2(May 18, 2021)

  • v0.0.1(May 16, 2021)

Owner
J.R. "hiljusti" Hill
Programming Philologist
J.R.
🔥 强大的动态线程池,并附带监控报警功能(没有依赖中间件),完全遵循阿里巴巴编码规范。Powerful dynamic thread pool, does not rely on any middleware, with monitoring and alarm function.

?? 动态线程池(DTP)系统,包含 Server 端及 SpringBoot Client 端需引入的 Starter. 这个项目做什么? 动态线程池(Dynamic-ThreadPool),下面简称 DTP 系统 美团线程池文章 介绍中,因为业务对线程池参数没有合理配置,触发过几起生产事故,进而

longtai 3.4k Dec 30, 2022
Pulsar airquality function

pulsar-airquality-function Developer Workspace Using JDK 8. 1.8.0_292. OPEN JDK 64-bit Server Using IntelliJ IDEA CE 2021.2 Developer Deployment Serve

Timothy Spann 3 Jun 27, 2022
spring-cloud-function SpEL RCE, Vultarget & Poc

spring-cloud-function SpEL RCE Vultarget You can build it for youself. here is the source of the Vuln App Or you can use the release which built by cc

cckuailong 133 Nov 30, 2022
A spring boot application for providing loom-ld services

LOOM-LD Structures sparql_based-linking It is a java project using maven to manage dependencies. loom-ld It is a spring boot application for providing

Ontology Engineering Group (UPM) 2 Apr 19, 2022
Tool for providing an HTTP endpoint to retrieve predefined aggregations on metrics of an InfluxDB.

InfluxDB DWH Exporter This application provides an HTTP endpoint that can deliver metrics from an InfluxDB in an aggregated form when called. This can

Novatec Consulting GmbH 1 Jan 18, 2022
An intelliJ plugin providing a UI layer for git-flow, which in itself is a collection of Git extensions to provide high-level repository operations for Vincent Driessen's branching model.

Git Flow Integration Plus for Intellij An intelliJ plugin providing a UI layer for git-flow, which in itself is a collection of Git extensions to prov

RubinCarter 35 Nov 8, 2022
Tinker is a hot-fix solution library for Android, it supports dex, library and resources update without reinstall apk.

Tinker Tinker is a hot-fix solution library for Android, it supports dex, library and resources update without reinstalling apk. Getting started Add t

Tencent 16.6k Dec 30, 2022
Trust-java - Test Results Verification library for Java

TRUST - Test Results Verification library for Java The TRUST's primary goal is to provide the simple way of different test results verification. Gener

Serhii Shymkiv 2 Nov 19, 2017
Library for converting from one Java class to a dissimilar Java class with similar names based on the Bean convention

Beanmapper Beanmapper is a Java library for mapping dissimilar Java classes with similar names. The use cases for Beanmapper are the following: mappin

null 26 Nov 15, 2022
Create a Music Playlist Library -Core JAVA, JAVA Swing, AWT

Project Specifications Manage Everything about a basic Music Playlist Application in Java A Music Library for Listing, Replaying, Navigating between c

Muhammad Asad 7 Nov 8, 2022
Resconstruct is a java library to infer missing information vectors of java classes.

Reconstruct Resconstruct is a java library to infer missing information vectors of java classes. Features Phantom classes Inheritance solving Dummy fi

Nowilltolife 14 Nov 17, 2022
This is a small library written in Java for minecraft login.

minecraft-auth-library This is a small library written in Java for minecraft login. Usage: Login with microsoft MinecraftAuthenticator minecraftAuthen

Sandro 7 Feb 5, 2022
SpringBoot show case application for reactive-pulsar library (Reactive Streams adapter for Apache Pulsar Java Client)

Reactive Pulsar Client show case application Prerequisites Cloning reactive-pulsar Running this application requires cloning https://github.com/lhotar

Lari Hotari 9 Nov 10, 2022
A bitcoin explorer Java library that utilizes multiple data sources at once.

Bitcoin Explorer A bitcoin explorer library that utilizes multiple data sources at once. Branch Build Unit Tests master development Table of Contents

Scorpius 3 Jan 31, 2022
Nrich is a Java library developed at CROZ whose purpose is to make development of applications on JVM a little easier.

nrich Nrich is a Java library developed at CROZ whose purpose is to make development of applications on JVM a little easier. It contains modules that

CROZ 44 Nov 12, 2022
Portaudio4j - An exploratory project to interact with the PortAudio C library using Java's FFI (Panama) APIs

Examples of PortAudio called by Java's Panama APIs JEP 412. At the moment this is purely exploratory (still kicking the tires) as it progresses in the

Carl Dea 4 Dec 29, 2021
Tzatziki - Decathlon library to ease and promote Test Driven Development of Java microservices!

Tzatziki Steps Library This project is a collection of ready-to-use Cucumber steps making it easy to TDD Java microservices by focusing on an outside-

Decathlon 32 Dec 15, 2022
libraw4j - Java interface to the libraw library

libraw4j (1.0.0-SNAPSHOT) This is heavily W.I.P. Help is welcome! Java interface to the libraw library. Used for reading data from raw images. src/mai

Jacob Andersen 2 Apr 18, 2022
Java library to launch external processes

ch.vorburger.exec If you like/use this project, a Star / Watch / Follow me on GitHub is appreciated! This project is a small library allowing to launc

Michael Vorburger ⛑️ 25 Sep 7, 2022