Skip to content

No windowed/pairwise iteration — "line after a match" requires enumerate + manual nth indexing #280

Description

@mitchpaulus

Claude whining about this:

Problem

A common shell task is: scan lines, and when a line matches a marker, grab the next line. Example: extracting object names from an EnergyPlus IDF, where the name is the field on the line following each Zone, header.

Minimal input (zones.idf):

Zone,
103_VAV-1.6, ! Name
0, ! Direction of Relative North
Zone,
104_IDU-1, ! Name
0, ! Direction of Relative North

Desired output: [103_VAV-1.6 104_IDU-1]

Current state

All the list iterators (map, filter, each, linearSearch) see one element at a time with no access to neighbors, so the natural higher-order style doesn't apply. The workaround is enumerate to smuggle in the index, then indexing back into the original list with nth, plus manual accumulator management:

mshell
zones.idf str readFile lines idfLines!
[] zoneNames!
@idfLines enumerate each. e!
@e :item? trim 'Zone,' = if
@idfLines @e :index? 1 + nth ',' split :0: trim zoneName!
@zoneNames @zonename append zoneNames!
end
end
@zoneNames

Issues with this: it forces two names (e, and re-fetching from @idfLines) for what is conceptually one value, hand-rolls the accumulator that filter/map normally hide, and has a latent out-of-bounds error if the marker is the last line (index + 1 nth would fail).

Proposal

A sliding-window helper, e.g. windows / pairs (([a] int -- [[a]]), à la Rust slice::windows or Clojure partition 2 1), turning [l1 l2 l3] into [[l1 l2] [l2 l3]]. Then the task composes like everything else:

mshell
zones.idf str readFile lines 2 windows
filter. :0: trim 'Zone,' = end
map. :1: ',' split :0: trim end

The last-line edge case disappears for free (a trailing marker simply produces no window). An eachWindow/mapWindow quotation form would also work, but a plain list→list windows composes with the existing filter/map/match vocabulary and seems the smallest addition.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions