Git Product home page Git Product logo

pure4j's Introduction

Build Status Download Coverage Status

Pure4J

Compile-Time Purity and Immutability Semantics For The Java Language

Please Note: This project was an experiment: While it achieves the goals of providing immutability and purity constraints for Java, coding using Pure4J is hard work. If you're interested in playing with these concepts in Java then you've come to the right place, but having tried to build projects using this, I don't recommend using it in-the-large. Feel free to experiment though.

Forces

  • Code correctness is a primary concern (more so than productivity).
  • You are working in Java Language environment.
  • Parts of the codebase should be isolated and treated in a “pure” way for testing.
  • You want to ensure your code is testable.
  • You want to be able to reuse your code in other contexts, and know that it is dependency-free.

Supporting Argument:

Quick Start

  1. Add the maven plugin to your java project.
  2. Add the library to your java project.
  3. Annotate some classes with @ImmutableValue.
  4. Run a maven install to see if your classes are pure.

What is Function Purity?

  • The function always evaluates the same result value given the same argument value(s). i.e. the results are deterministic.
  • Evaluation of the result does not cause any semantically observable side effect or output. Such as output to I/O devices.

See wikipedia for further details.

Islands Of Purity

One of the main reasons for using Java as a programming language is because of its library support for integration with other systems, e.g. JDBC, XML, Web-Services, JMS etc. Pure4J allows you to write "islands" of pure code within the context of a larger, side-effecting code-base.

Major Components Of Pure4J

1. Annotations

You apply these annotations to your code to indicate the purity constraints.

  • @Pure is applied on a method level, and indicates that the method is deterministic and has no side effects.
  • @ImmutableValue is applied on a class-level. It indicates that the class is immutable after construction. Also it indicates that the instance methods on the class are @Pure.
  • @MutableUnshared is also applied at class-level. It indicates that the class contains some mutable state, however, that mutable state never leaves the class: all method arguments are immutable and return types are immutable too.

There are various other supporting annotations, but these are the main ones. Specification for each is here.

2. Maven Purity Checker

As part of the build pipeline, you add the purity checker. If any of the purity semantics indicated by the annotations are broken, errors occur. To add the Pure4J checker to your build pipeline, add this to your Maven pom.xml file:

...
<build>
	<plugins>
		...
		<plugin>
			<groupId>org.pure4j</groupId>
			<artifactId>pure4j-maven-plugin</artifactId>
			<version>*latest version - see top of this file*</version>
			<executions>
	         	<execution>
                    <goals>
                        <goal>pure4j</goal>
                    </goals>   
		         </execution>
		     </executions>
		</plugin>

3. Persistent Collections

Persistent versions of the Java Collections library are provided. These fulfil the @ImmutableValue contract, and return a new collection whenever a mutating operation is applied. This means that you can construct your @ImmutableValue object with a collection of Strings (say) and be sure that the collection is also immutable.

NB. These are versions of the Clojure Persistent Collections, developed by Rich Hickey, modified for use with generics and to have regular constructors, and some alterations to the inheritance hiearchy.

Import the annotations and the persistent collections into your project with the following dependency:

		<dependency>
			<groupId>org.pure4j</groupId>
			<artifactId>pure4j-core</artifactId>
	        <version>*see version info at top of this page*</version>
		</dependency>

Also provided are subclasses of existing Java Collections, having the @MutableUnshared contract.

4. Knowledge of Java Language Purity

There are many methods in the Java language which are already pure (no side effects, deterministic) and many classes which produce immutable objects (e.g. String, Integer, LocalDate).

This library keeps track of these and allows your pure functions to use existing pure functions in Java.

Tutorials

There is an example project in the pure4j-examples folder which builds has some example use cases, and builds them using the Maven Plugin. If you are starting a project and want to use Pure4J, start by looking at this.

FAQ

Please see the FAQ here.

Specifications

Concordion specifications detailing the interface of the project are available online here.

Effectively this forms the Javadoc for the project, though the assertions made in the documentation are tested.

Status of this Project

This is currently an idea under investigation. It’s quite possible that the contracts and semantics provided by this project will change in the future as new use cases are discovered.

Group

Visit the Google Group to join in the discussion

Known Remaining Issues

See Github Issues Page

pure4j's People

Contributors

peterjeschke avatar robmoffat avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pure4j's Issues

Gradle plugin

Hi, I love the idea of pure4j, the documentation and everything, thank you so much for it!

In our project I've created our own versions of immutable collections which I am willing to port to the ones you provide in pure4j and I really want to annotate half of our code with @ImmutableValue (because it already is immutable) but I cannot do that without a Gradle plugin - we use Gradle for everything and just using pure4j without the static checking seems... wasteful. :) Have you researched into that? Has anyone helped? Has any progress been made?

Thanks again!

Annotation for specifying that an implementation function must be pure

I have two questions which I couldn't find in the docs:

Let's say I have a class like this:

abstract class Strict<State> {
    State state;

    @Pure
    protected abstract String functionThatMustBePure(State state, String input);

    public String apply(String input) {
        return functionThatMustBePure(state, input);
    }
}

Can I use the @Pure annotation in this way, to enforce that subclasses implement the function in a pure way?

Along the same lines, is it possible to annotate a @FunctionalInterface argument of a function to be pure?

public static Supplier<R> memoizeResult(T input, @Pure Function<T, R> result) { ... }

Cascading Implementation Impurity

One impure function should 'taint' those that use it,
when we come to write out the list of pure functions at the end. This is useful when we are constructing the pure list of java built-in functions.

Error Message Improvement

  • They don't need to extend exception
  • They should provide a list of remedial steps
  • Anonymous classes: hard to say which one we're talking about without a line-number.
  • -- change this to say constructor, and the line number
  • Non-static pure method on class which is not immutable: should give line number of ALOAD 0.

Stream counter-examples.

We need some examples of using the Java8 streams API that aren't pure, for comparison with the existing pure ones, and also to show that purity checking is in force around these too.

Maven Plugin: Add custom .pure files to configuration

As a developer on a large project, I have huge swaths of code that are effectively immutable except for a single method (in my case a call to Apache's ToStringBuilder in toString methods). I would very much like to be able to force ToStringBuilder to be considered Pure, so that I can gain the benefits of purity checking on the rest of the code and I can look into what to do about ToStringBuilder separately.

It would be ideal to be able to tell the pure4j maven plugin of extra .pure files of my own creation. It would further be handy to have one central .pure files (or set of them) in a multi-module Maven build. This is not as effortful as it may sound - the maven-pmd-plugin does exactly this.

The maven-pmd-plugin supports the ability to specify a list of rulesets in its configuration. The ruleset itself may exist in a jar file.

             <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-pmd-plugin</artifactId>
                    <executions>
                        <execution>
                            <id>pmd-check</id>
                            <goals>
                                <goal>check</goal>
                            </goals>
                        </execution>
                    </executions>
                    <configuration>
                        <rulesets>
                            <ruleset>pmd-ruleset.xml</ruleset>
                        </rulesets>
                    </configuration>
                    <dependencies>
                        <dependency>
                            <groupId>org.example</groupId>
                            <artifactId>code-style-requirements</artifactId>
                            <version>${code-style-requirements.version}</version>
                        </dependency>

This allows an organization to build an artifact which lists the PMD rules it wants, put them in an Maven artifact and then have it versioned and depended upon by different teams.

Possibly a separate issue, but it would be really cool if the maven plugin dumped a results.pure into the target directory after it ran which listed anything it found that was NOT_PURE. This would give me something analyse.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.