New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
EVERY loop construct semantics unclear #847
Comments
Originally, the idea that each frame needed one cell's worth of allocation came out of the need to be able to have a place to put a generated value value during an EVAL operation. Not only did it need a location to be written into, but it also had to be GC protected: eval (func [] [recycle | 'print]) "What keeps func alive?" Eventually, designing Eval_Core() to be re-entered allowed eval to keep its argument alive by leaving it exactly where it was...in the argument slot of the frame of the EVAL call. Yet in the meantime, the frame's cell had been exported as "D_CELL"...to be visible as a way for native actions to get a scratch cell "for free" that was GC safe. But unlike EVAL, a non-negotiable need for a non-movable per-frame cell of storage space arose with the SHOVE operation. The right hand side of the operator can only be evaluated once, and its product must be able to outlive evaluations on the left hand side. Putting it on the data stack is not an option, as it would be movable and the f->gotten pointer could not stay fixed to it...not to mention needing to adjust the data stack pointer to account for it during another evaluation. This removes D_CELL, and takes away the idea that natives are allowed access to the frame's cell...reserving it for the evaluator's internal usage. Instead, it uses locals pushed with PUSH_GC_GUARD(). Includes improvements to catch unbalanced GC guards correctly, as the feature of checking it had atrophied from lack of use. Also removes the EVERY operation, as it was a client of the D_CELL that had become broken. It would involve thinking to fix it, and removing it entirely seems better than leaving it broken. See: #847
This has essentially been resolved by the loop result protocol's increased willingness to mutate loop results (e.g. blanks to become void, to distinguish them from the case of a loop body never running). In EVERY's case, the protocol "falsifies" null and blank...which means it's still able to use blank for the loop body never getting a chance to run, and NULL for the loop breaking. Since all three are falsey, this presents a particularly interesting "we had content, and it passed" default condition. In any case, the feature has been restored: |
EVERY is a loop construct which was introduced to address those who might have a naming objection to FOR-EACH being hyphenated. The proposal was that it would be like FOR-EACH but have a different return result...responding if every iteration of the loop is truthy...and if so, returning the last truthy result, sort of like a non-short-circuit ALL.
Yet there have been no usages and no tests written, and there are open semantic questions. For instance, as a loop construct it is supposed to be reserving NULL for BREAK... which is contentious with acting like ALL and using NULL as the differentiating result for when no value is found.
It's not a hard construct to write if it were understood what it should do. But in the interests of not dragging down other development for something no one has used yet, it is being cut from Beta/One. Here was what was written on the Trello Card about it previously:
Here was the native spec:
A further comment from the Trello on naming:
The text was updated successfully, but these errors were encountered: