Skip to content

Add edge result return#10

Merged
code-shoily merged 6 commits intomainfrom
add-edge-result-return
Mar 18, 2026
Merged

Add edge result return#10
code-shoily merged 6 commits intomainfrom
add-edge-result-return

Conversation

@code-shoily
Copy link
Owner

@code-shoily code-shoily commented Mar 18, 2026

PR: Safe Edge Addition API with Result Type

Summary

This PR introduces a breaking change to the edge addition API to address partial integrity (aka Ghost Nodes) — nodes that exist in edge dictionaries but not in the graph's nodes map. The add_edge() function now returns Result(Graph, String) instead of Graph, forcing explicit handling of missing node scenarios.

Breaking Changes

Edge Addition API

  • add_edge() now returns Result(Graph, String)

    • Returns Error("Node X does not exist") if either endpoint node is missing
    • Previously would silently create "ghost nodes" in edge dictionaries
  • Migration Guide:

    // Before (would create ghost nodes)
    let graph = graph |> add_edge(from: 1, to: 2, with: 10)
    
    // After - Option 1: Assert when nodes are guaranteed
    let assert Ok(graph) = add_edge(graph, from: 1, to: 2, with: 10)
    
    // After - Option 2: Chain with result.try
    use graph <- result.try(add_edge(graph, from: 1, to: 2, with: 10))
    
    // After - Option 3: Auto-create missing nodes
    let graph = add_edge_ensure(graph, from: 1, to: 2, with: 10, default: Nil)
    
    // After - Option 4: Custom node data provider
    let graph = add_edge_with(graph, from: 1, to: 2, with: 10, using: get_node_data)

Renamed Functions

  • add_edge_ensured()add_edge_ensure()
  • add_edge_ensured_with()add_edge_with()

Added

Bulk Edge Addition Functions

New convenience functions for adding multiple edges with a single Result unwrap:

  • add_edges(graph, edges: List(#(NodeId, NodeId, e))) — Add weighted edges
  • add_simple_edges(graph, edges: List(#(NodeId, NodeId))) — Add edges with weight 1
  • add_unweighted_edges(graph, edges: List(#(NodeId, NodeId))) — Add edges with weight Nil

These functions fail fast on the first missing node, reducing boilerplate compared to chaining individual add_edge calls:

// Before: Multiple Result unwrapping
let assert Ok(graph) = add_edge(graph, from: 1, to: 2, with: 10)
let assert Ok(graph) = add_edge(graph, from: 2, to: 3, with: 20)
let assert Ok(graph) = add_edge(graph, from: 3, to: 4, with: 30)

// After: Single Result unwrapping
let assert Ok(graph) = add_edges(graph, [
  #(1, 2, 10),
  #(2, 3, 20),
  #(3, 4, 30),
])

Rationale

The Partial Integrity Problem

Previously, add_edge would silently add entries to edge dictionaries even when nodes didn't exist in graph.nodes. This caused:

  • Unexpected behavior in algorithms using all_nodes() (would miss ghost nodes)
  • Inconsistent state where edge dictionaries had more node references than the nodes map
  • Silent failures that were hard to debug in complex graph operations

Design Decisions

Why not panic? Panicking on missing nodes is not the Gleam way — explicit error handling is preferred.

Why not make add_edge_ensure the default? Too verbose for the common case where nodes are already added. The explicit Result type makes the contract clear.

Why bulk functions? They maintain the safety of Result while reducing verbosity for the common pattern of adding multiple edges at once.

Documentation

  • Added GLEAM_FSHARP_COMPARISON.md documenting feature parity and migration guidance between Gleam and F# implementations
  • Updated all examples to use add_edges or proper Result handling
  • Refactored test suite to demonstrate best practices

Migration Checklist

  • Search for |> add_edge( patterns — replace with |> add_edges([...]) where possible
  • Search for let graph = ... |> add_edge( — add assert Ok(graph) = or use add_edge_ensure
  • Update any custom code using add_edge_ensuredadd_edge_ensure
  • Review algorithms that depend on all_nodes() — they now have consistent behavior

@code-shoily code-shoily merged commit d13062e into main Mar 18, 2026
1 check passed
@code-shoily code-shoily deleted the add-edge-result-return branch March 18, 2026 21:24
@code-shoily code-shoily self-assigned this Mar 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant