Skip to content

Latest commit

 

History

17 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Java Functional Style Skill for AI Agents

tessl

Java callbacks are easy to make plausible and hard to keep honest. A hand-written x -> x hides that an API wanted Function.identity(), a block lambda buries logic that belongs in a named method, an eager orElse(load()) defeats the laziness the API offers, and a method reference can quietly change when its receiver is evaluated.

This Tessl package teaches AI coding agents to write, review, and refactor Java lambdas, method references, and functional-interface callbacks (Function, Predicate, Supplier, Consumer, Comparator, BiFunction) so they stay readable while preserving behavior.

The GitHub repository and the Tessl plugin are public.

Contents

Getting Started

Tool Command
npm npx tessl i martinfrancois/java-functional-style
yarn yarn dlx tessl i martinfrancois/java-functional-style
pnpm pnpx tessl i martinfrancois/java-functional-style
bun bunx tessl i martinfrancois/java-functional-style
Tessl CLI tessl i martinfrancois/java-functional-style

The package ships one skill (java-functional-style) and one always-on rule with the same conventions, so the guidance applies to any Java edit even when the agent does not activate the skill on its own.

Why This Exists

Two pieces of maintainer feedback started this package. A reviewer of the Java Streams skill pointed out that agents keep writing multi-line lambdas instead of extracting a method (lambdas are glue code), and a cleanup sweep produced Collectors.toMap(x -> x, ...) where Function.identity() was the obvious choice. Both are general Java callback habits, not stream or Optional semantics, so they belong in a package that any Java skill can sit next to.

What It Helps With

  • Function.identity() and UnaryOperator.identity() where an API needs an identity callback
  • removing no-op stages such as .map(x -> x) instead of renaming them
  • extracting named helpers and predicates from block or multi-condition callbacks
  • keeping fallback work lazy in orElseGet, computeIfAbsent, and requireNonNullElseGet
  • method references that keep receiver timing, overload choice, argument order, and boxing intact
  • checked exceptions kept at a visible boundary instead of buried in a callback
  • side-effecting callbacks only where the side effect is the point and safe for the execution mode
  • Java baseline compatibility for functional APIs (Predicate.not, ifPresentOrElse, toList())
  • knowing when a plain loop or branch is the better shape, and saying so in reviews

It does not force streams, Optionals, or functional style where a loop or branch is clearer.

Ownership Boundaries

java-functional-style owns general Java lambda and functional-interface style.

martinfrancois/java-streams (repository) owns stream and collector semantics. martinfrancois/java-optionals (repository) owns Optional semantics.

Each package works on its own. Install the domain skill and this package together when you want both semantic guidance and callback-style guidance.

Examples

Use the JDK identity helper when the API needs one:

Map<String, Exhibit> exhibitsById = exhibits.stream()
        .collect(Collectors.toMap(Exhibit::id, Function.identity(), Gallery::keepEarlier, LinkedHashMap::new));

Remove a redundant identity stage instead of replacing it with another one:

String title = exhibitTitle.orElse(fallbackTitle);

Extract callbacks that do real work:

List<MaintenanceAlert> alerts = readings.stream()
        .filter(reading -> exceedsHumidityLimit(reading, limits))
        .map(reading -> toAlert(reading, limits))
        .toList();

Keep expensive fallback work lazy:

Settings settings = Objects.requireNonNullElseGet(loaded, this::buildDefaults);

How It's Evaluated

The skill is tested on Java implementation, review, and cleanup tasks that involve callbacks. Each task is run without the skill and with the skill, then scored on whether the agent keeps the requested behavior while writing clearer callback code.

The published score comes from the main eval set, which covers the places where the default eval model still writes weak callbacks: block lambdas with derived values and branching in stream pipelines, in Map.merge and CompletableFuture callbacks, and in Optional.map and collector downstreams. Identity lambdas, eager fallback computation, checked exceptions wrapped inside callbacks, method references that change behavior, and forced functional rewrites are covered by reference and regression scenarios, because the default model already handles them without the skill; they protect against regressions rather than contribute to the score.

Current published scores are shown on the Tessl plugin.

Contributing

See CONTRIBUTING.md for local validation, eval design rules, commit-message format, and release workflow details.

AI-assisted contributions are welcome when they are transparent, reviewed, and owned by a human. See AI_CONTRIBUTION_POLICY.md.

For suspected vulnerabilities, use the private reporting path in SECURITY.md.

License

MIT

About

Java functional style guidance for AI coding agents

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages