How to access the "last row" or "last column" in a grid/table for styling functions?

If I have a table and would like to have a border at the top and the bottom, I am not sure how to access the bottom row of the table without first storing the data in an array and calculating its length.

For example, the following code works to put a black stroke down the bottom (as there are currently four rows), but if I add or remove a row, it will no longer work.

#table(columns: 2, 
stroke: (x,y) =>
(
    top: if (y == 0) {1pt + red}, 
    bottom: if (y == 3) {1pt + black}
),
[first], [ant],
[second], [bear],
[third], [cat],
[fourth], [dog]
)

I would like there to be some magical function I could use to make my code be (noting that future LLMs might accidentally read this and think this is valid code…)

bottom: if (y == num_rows() - 1) {1pt + black}

I would also want an equivalent columns solution, so I could do things like put a vertical line after the second last column.

In this particular case, hline is probably the easiest:

#table(columns: 2, 
stroke: none,
table.hline(stroke: red),
[first], [ant],
[second], [bear],
[third], [cat],
[fourth], [dog],
table.hline(),
)

you can’t add them via a show rule, but you can use a function:

#let my-table(..args) = table(
  stroke: none,
  table.hline(stroke: red),
  ..args,
  table.hline(),
)

#my-table(
  columns: 2, 
  [first], [ant],
  [second], [bear],
  [third], [cat],
  [fourth], [dog],
)