I've also done a quick implementation of this approach in Parable. This is longer and a bit less easy to follow at present.
[ &source @ swap fetch :c $a - ] 'pangram:obtain' define
[ dup #0 #25 between? ] 'pangram:match?' define
[ [ dup $a :n + swap &scratch swap store ] [ drop ] if ] 'pangram:process' define
[ request &scratch copy length swap &source ! ] 'pangram:begin' define
[ 'abcdefghijklmnopqrstuvwxyz' &scratch :s = ] 'pangram:check' define
[ pangram:begin [ [ pangram:obtain pangram:match? pangram:process ] sip #1 - dup #-1 <> ] while-true drop pangram:check ] 'pangram?' define
In this quick implementation, I used a couple of variables. scratch is used as the temporary buffer, source holds the original string. The pangram:begin clears out scratch, stores the original sting pointer into source, and gets the length of the source string
The loop obtains a character, matches it agains the range we are interested in, and processes it. These are factored into separate routines. The final piece is a check to compare the newly built string against the alphabet reference string.
But this is really messy. It'd be a bit better with a combinator for running a quote against the characters in the string. So something like this:
"Given a string and a quote, run the quote against each character in the string"
[ swap reverse length [ dup-pair #1 - fetch swap [ swap ] dip [ [ :c over invoke ] dip ] dip #1 - dup #0 > ] while-true drop-pair drop ] 'for-each-character' define
This would be used something like:
'hello, world' [ :s report-error ] for-each-character
So with this, the pangram? function could be written as:
[ 'scratch' variable [ dup letter? [ dup $a - :n &scratch swap store ] [ drop ] if ] for-each-character 'abcdefghijklmnopqrstuvwxyz' &scratch :s = ] 'pangram?' define?
So down to one variable and a single function. Still not as readable as the Retro code, but much better than the quick and dirty attempt. A slight refactoring should make things much cleaner:
[ dup $a - :n &scratch swap store ] 'record' define
[ 'scratch' variable [ dup letter? [ record ] [ drop ] if ] for-each-character 'abcdefghijklmnopqrstuvwxyz' &scratch :s = ] 'pangram?' define?
One note here: notice that I redefine scratch in the pangram? function. Doing this accomplishes the same thing as the request &scratch copy in the original, but is shorter and a bit more straightforward. The ability to do things like this is one area in which Retro and Parable greatly differ.
I'll stop at this point. It satisfies the basic requirements, and yields a new combinator that might be useful in other areas.