There are two forms of EVALUATE with FRAME!... one of which consumes the memory of the frame so it can't be used again, and another that evaluates with a copy of the memory...leaving the original and its fields available after the eval.
>> f: make frame! negate/
== &[frame! [
number: ~
]]
>> f.^number: 1020 ; as of today, you need lifts when using raw frames
== 1020
>> f
== &[frame! [
number: ''1020 ; extra quote protects the single quoted value
]]
>> evaluate f
== -1020
>> f
== &[frame! [
number: ''1020
]]
>> eval-free f
== -1020
>> f
** Panic: FRAME! was freed, memory no longer avaliable
EVALUATE and EVAL-FREE are two separate functions at the moment. The reasoning is that if you are performance-conscious (hence the kind of person who'd want EVAL-FREE) you want to be able to use an intrinsic, and intrinsic (FRAME!-less) dispatch happens when you have a single argument and no refinements. Hence it shouldn't be EVALUATE:FREE or similar.
This drew me to a weird idea: what if you could say eval @f
and that meant EVAL-FREE ?
>> eval @f
== -1020
>> f
** Panic: FRAME! was freed, memory no longer avaliable
That's just one argument. It takes advantage of the unusual property that pinned values have of just evaluating to themself, so the decoration is visible to the function being called...kind of like if it were inside a block.
Basically it's a really, really small dialect.
Is This A Good Or Bad Idea?
I can't tell. It's kind of slick, but also kind of random... nowhere else does @
mean "destructively utilize memory".
It pushes the responsibility of fetching the variable onto EVAL, but that's the same as any dialect which would take variables in a block and interpret them and need to look them up.
I'm tempted to say that maybe this is not a feature of EVALUATE itself, but just a quirk of the shorthand EVAL.
Anyway, food for thought.