CtrlK
BlogDocsLog inGet started
Tessl Logo

pseudocode-to-java-code

Translates pseudocode into idiomatic Java, inferring types, choosing collection classes, and handling exceptions per Java conventions. Use when implementing an algorithm from a paper or spec, when the user hands you pseudocode and wants Java, or when realizing a verified-pseudocode artifact.

Install with Tessl CLI

npx tessl i github:santosomar/general-secure-coding-agent-skills --skill pseudocode-to-java-code
What are skills?

100

Quality

100%

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SKILL.md
Review
Evals

Pseudocode → Java

Pseudocode is under-specified on purpose. The Java you produce has to commit to everything pseudocode leaves open: types, nullability, error handling, mutability, collection implementations.

Decisions pseudocode doesn't make (but Java requires)

Pseudocode saysJava must decide
let S be a setHashSet? TreeSet? LinkedHashSet? (Does order matter?)
x ← lookup(k)Returns null on miss? Optional<V>? Throws?
list of numbersint[]? List<Integer>? IntStream? (Boxed vs primitive matters.)
error: ...Checked Exception? RuntimeException? Return sentinel?
for each x in SEnhanced for? Stream? (Mutation during iteration → ConcurrentModificationException.)
procedure f(x)Static method? Instance method? What class does it live on?

Default choices (absent a reason to deviate):

  • Sets/maps → HashSet/HashMap unless order is mentioned; LinkedHash* if insertion order matters; Tree* if sorted iteration is used.
  • Missing lookup → Optional for new code, null if matching an existing API.
  • Number list → List<Integer> for flexibility, int[] if the pseudocode indexes and size is fixed.
  • Errors → IllegalArgumentException for bad inputs, IllegalStateException for bad state, checked only if the caller can meaningfully recover.
  • Home for the method → a final utility class with static methods, unless there's obvious object state.

Type inference from pseudocode

Pseudocode variables are used before typed. Infer from usage:

Usage in pseudocodeInferred Java type
x ← 0; x ← x + 1int (or long if values look big)
x ← []; x.append(y)List<typeof(y)> (ArrayList)
x ← {}; x[k] ← vMap<typeof(k), typeof(v)>
x ← ∅; x ← x ∪ {y}Set<typeof(y)>
for i ← 1 to nint i (1-indexed — watch off-by-one)
x ← head(list); rest(list)Consider Deque or LinkedList

Worked example

Pseudocode (Dijkstra, textbook style):

function shortest_paths(G, source):
    dist ← map with dist[source] = 0, all others = ∞
    visited ← ∅
    Q ← priority queue of all vertices, keyed by dist

    while Q is not empty:
        u ← extract-min(Q)
        visited ← visited ∪ {u}
        for each neighbor v of u where v ∉ visited:
            alt ← dist[u] + weight(u, v)
            if alt < dist[v]:
                dist[v] ← alt
                decrease-key(Q, v, alt)

    return dist

Java:

import java.util.*;

public final class Dijkstra {
    private Dijkstra() {}

    public record Edge(int to, int weight) {}

    /**
     * Computes shortest distances from {@code source} to all reachable vertices.
     * @param adj adjacency list: adj.get(u) is the outgoing edges from u
     * @param source starting vertex
     * @return map from vertex to shortest distance; unreachable vertices absent
     * @throws IllegalArgumentException if source is not in adj
     */
    public static Map<Integer, Integer> shortestPaths(
            Map<Integer, List<Edge>> adj, int source) {
        if (!adj.containsKey(source)) {
            throw new IllegalArgumentException("source vertex not in graph");
        }

        Map<Integer, Integer> dist = new HashMap<>();
        dist.put(source, 0);
        Set<Integer> visited = new HashSet<>();

        // Java's PriorityQueue has no decrease-key. Standard workaround:
        // insert duplicates, skip stale entries on poll.
        PriorityQueue<int[]> pq = new PriorityQueue<>(Comparator.comparingInt(a -> a[1]));
        pq.offer(new int[]{source, 0});

        while (!pq.isEmpty()) {
            int[] top = pq.poll();
            int u = top[0], d = top[1];
            if (visited.contains(u)) continue;          // stale entry — already settled
            visited.add(u);

            for (Edge e : adj.getOrDefault(u, List.of())) {
                if (visited.contains(e.to())) continue;
                int alt = d + e.weight();
                Integer cur = dist.get(e.to());
                if (cur == null || alt < cur) {
                    dist.put(e.to(), alt);
                    pq.offer(new int[]{e.to(), alt});   // "decrease-key" = insert new, ignore old
                }
            }
        }
        return dist;
    }
}

Decisions made (and why):

  • → absent from map. dist.get(v) == null means infinity. Avoids Integer.MAX_VALUE overflow when adding weights.
  • decrease-key → Java's PQ doesn't have it. Lazy deletion: insert duplicates, skip visited on poll. O((V+E) log V) — same asymptotic.
  • int[]{vertex, dist} in PQ instead of a record — cheap, no boxing. Comment explains.
  • adj.getOrDefault(u, List.of()) — graph might have vertices with no outgoing edges.
  • Unreachable vertices absent from result — documented. Caller checks containsKey.

Preserving annotations from verified pseudocode

If the pseudocode came from → verified-pseudocode-extractor, it has // PRE:, // POST:, // INV: annotations. Keep them as Javadoc and comments:

  • PRE@throws IllegalArgumentException if ... or @param ... must be ...
  • POST@return clause
  • INV → comment at the loop head (don't delete — it's why the loop is correct)

Do not

  • Do not use Integer.MAX_VALUE for infinity without guarding additions. MAX_VALUE + weight overflows to negative. Use absent-from-map, or Long, or check before adding.
  • Do not mutate a collection while iterating it with for-each. ConcurrentModificationException. Use an explicit iterator with .remove(), or iterate over a copy.
  • Do not translate 1-indexed pseudocode without adjusting. for i ← 1 to nfor (int i = 0; i < n; i++) and every a[i] stays a[i] (not a[i-1]) — or keep 1-indexed loops and adjust all accesses. Pick one, consistently.
  • Do not make everything a static utility method if the pseudocode has persistent state between calls. That's an object.

Output format

## Type decisions
| Pseudocode var | Java type | Why |
| -------------- | --------- | --- |

## Code
<java>

## Deviations from pseudocode
<decrease-key workaround, ∞ encoding, index base — anything where the Java isn't a direct reading>

## Javadoc
<pre/post conditions translated>
Repository
santosomar/general-secure-coding-agent-skills
Last updated
Created

Is this your skill?

If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.