Abstraction
Abstraction is the opposite of specialization. A specialized operation cares about the exact thing it works on; an abstract one steps back and works on a shape of data, no matter what's inside.
This is a WebAssembly-native reimagining of MIT's Computational Thinking lesson: the figures below are live WasmMakie islands — drag the sliders and they recompute in your browser, no server.
# ONE function, ANY element type — that is abstraction. It drops `new` into a
# flat (column-major) grid at row i, column j, without caring what `new` is.
function place(new, grid::Vector, i, j, nrows)
out = copy(grid)
out[(j - 1) * nrows + i] = new
return out
endThe same operation, on different types
place doesn't know or care what it's placing. Move the sliders — the same function fills a cell in a grid of numbers and a grid of pixels.
row
# numbers: a flat Int grid with a 5 dropped in (shown column-major).
place(5, fill(1, 12), ai, aj, 3)# pixels: the SAME `place`, now on a gray grid — a black square at (row, col).
gray_figure(place(0.0, fill(0.85, 12), ai, aj, 3), 3, 4)One more type — pick a fill
Still the same idea: choose a shade and we fill the whole grid with it, then drop a marker. The operation is abstract over what a "value" even is.
shade
gray_figure(place(0.0, fill(shade, 12), ai, aj, 3), 3, 4)Why it matters
We wrote place once and it worked for integers and for pixels — we never specialized it to a type. That's the whole game: a language that lets you operate at the level where the operation makes sense, and abstract away the rest.