Same loop. Same result.
75× faster.

Nothing about the loop changes. What changes is what you hand it — and that one choice is the whole of pillar one.

A question you've probably never had to ask

In Ring, when you pass a list into a function, Ring hands over its address — instant, no matter how big the list is. When you pass a string, Ring copies the whole thing, every time, before the function's first line even runs. You've never had to think about this, because most strings are short enough that the copy is free. The moment a "string" is really a buffer — a document, a file you're building, a big block of bytes you read once and touch a thousand times — that copy stops being free, and nothing in the code you'd naturally write tells you so.

Watch it happen

A helper function that reads one byte out of a 1 MB buffer, called 1,500 times — a parser, a validator, anything with a loop and a helper. The helper looks cheap: it reads one byte. The two versions below are otherwise identical.

What most Ring code does copies every call
func RawWay cData, nCalls, nSize
    # cData is a plain string. Ring copies the
    # whole megabyte onto the stack, on every call.
    nSum = 0
    for i = 1 to nCalls
        nSum += ByteAtRaw(cData, (i * 7919) % (nSize - 1))
    next
    return nSum
With Ring++ nothing is copied
func RppWay oBuf, nCalls, nSize
    # oBuf is an OBJECT. Objects are lists under the
    # hood, and lists cross by address, not by copy.
    nSum = 0
    for i = 1 to nCalls
        nSum += ByteAtRpp(oBuf, (i * 7919) % (nSize - 1))
    next
    return nSum
75×
faster, 302 ms → 4 ms
1,430 MB
copied the plain-Ring way — for 1,500 one-byte reads
0
bytes copied with Ring++, identical result

Not asserted, checked: both versions must produce the exact same answer before the timing is even printed — the whole file is one of eight that hold both paths side by side. Try it: ring examples/02-pass-a-large-value/example.ring.

What Ring already gave you, and what Ring++ adds

Ring already has this

An object crossing a function call is a reference, not a copy — that's not new, and it's not a Ring++ invention. It's how every class instance in Ring already behaves.

What was missing

A way to hold a block of bytes — the kind of thing you'd normally reach for a string to hold — as an object instead, so it gets that same reference behaviour, plus safe, bounds-checked reads and writes into it.

What Ring++ is

RppBuffer and RppView are exactly that: a buffer that crosses calls by reference and writes in place, and a zero-copy window into part of one. No new syntax, no new runtime — a class, like any other Ring class.

The trip inside Ring, if you want it

You don't need any of this to use RppBuffer — the example above is the whole interface. But if you're curious why Ring behaves this way at all: the answer is one line deep in Ring's C source, RING_VM_STACK_PUSHCVAR — the exact spot where a string gets copied onto Ring's internal stack before a function call. It is not a bug and it is not an oversight; a copy is the simplest, safest thing to do with a value whose lifetime you can't otherwise reason about, and Mahmoud Fayed built Ring's whole object system on the other side of that choice — objects are reference-counted, precisely so they don't need to be copied. Ring++ doesn't change that design. It just gives you a second way to say "this one, I promise, wants to be held, not copied" — using the reference behaviour that was already there for objects, on bytes instead of business logic. The fuller design story is its own page, alongside the other two doors and the contract that keeps this working as Ring evolves.

Where this loses — said before anything else is claimed

Below roughly 512 bytes, the machinery that makes RppBuffer fast costs more than the copy it's avoiding — at that size, plain Ring wins, measured. RppBuffer is for something you hold and hit repeatedly, not for building one short string once. Three of Ring++'s eight worked examples reach the same conclusion for their own shape: plain Ring is the right answer. Saying so is part of the product, not a footnote to it.

Next

Static analysis — what it found in Ring's own stdlib Native build