Skip to content

Commit 7643bf4

Browse files
committed
Deprecate CLOSURE => <durable>, PROC, PROCEDURE
This commit makes the next step toward FUNCTION! and CLOSURE! unification by eliminating the CLOSURE! type, in favor of the ability to mark a function's arguments <durable>. (Note: The name <durable> is tentative, and at present durable is "all or nothing"...it is not possible to specify some arguments or locals as surviving and others not. However, that selectivity is planned in the design and should be added at a later date.) Marking a function's arguments <durable> currently has the other effect historically of a closure--to give them specific binding. This feature is planned to be implemented in a way that does not require a deep copy of the function's body on each execution as closure does--so all FUNCTION!s will have that property. Only the selection of individual arguments as durable will remain. Taking the place of CLOS and CLOSURE are the PROC and PROCEDURE function generators. Instead of RETURN they have a definitional-scoped 0-arity function called LEAVE. This returns UNSET! always, and in addition they suppress any return value from falling out: >> foo: procedure [] [leave print "This won't print"] >> foo ; No result >> foo: proc [y] [y + 20] >> foo 10 ; No result
1 parent 3b380ea commit 7643bf4

25 files changed

+469
-214
lines changed

src/boot/root.r

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ empty-block ; a value that is an empty BLOCK!
2929
transparent-tag ; func w/o definitional return, ignores non-definitional ones
3030
infix-tag ; func is treated as "infix" (first parameter comes before it)
3131
local-tag ; marks the beginning of a list of "pure locals"
32+
durable-tag ; !!! In progress - argument word lookup survives call ending
3233

3334
;; Natives can usually be identified by their code pointers and addresses
3435
;; (e.g. `VAL_FUNC_CODE(native) == &N_parse`) and know their own values via
@@ -38,6 +39,7 @@ local-tag ; marks the beginning of a list of "pure locals"
3839
;; (PARSE just wants access to its D_FUNC more convenient from a nested call)
3940

4041
return-native
42+
leave-native
4143
parse-native
4244

4345
;; The BREAKPOINT instruction needs to be able to re-transmit a RESUME
@@ -49,14 +51,16 @@ parse-native
4951
resume-native
5052
quit-native
5153

52-
;; The FUNC and CLOS function generators are native code, and quick access
53-
;; to a block containing [RETURN:] is useful to share across all of the
54+
;; The FUNC and PROC function generators are native code, and quick access
55+
;; to a block of [RETURN:] or [LEAVE:] is useful to share across all of the
5456
;; instances of functions like those created by DOES. Having a filled
5557
;; REBVAL of the word alone saves a call to Val_Init_Word_Unbound with
5658
;; the symbol as well.
5759

5860
return-set-word
5961
return-block
62+
leave-set-word
63+
leave-block
6064

6165
boot ; boot block defined in boot.r (GC'd after boot is done)
6266

src/boot/sysobj.r

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ script: context [
177177

178178
standard: context [
179179

180-
; FUNC+CLOS implement a native-optimized variant of a function generator.
180+
; FUNC+PROC implement a native-optimized variant of a function generator.
181181
; This is the body template that it provides as the code *equivalent* of
182182
; what it is doing (via a more specialized/internal method). Though
183183
; the only "real" body stored and used is the one the user provided
@@ -195,6 +195,15 @@ standard: context [
195195
#BODY
196196
]
197197

198+
proc-body: [
199+
leave: make function! [
200+
[{Leaves a procedure, giving no result to the caller.}]
201+
[exit/from (context-of 'leave)]
202+
]
203+
#BODY
204+
comment {No return value.}
205+
]
206+
198207
error: context [ ; Template used for all errors:
199208
code: none
200209
type: 'user

src/boot/types.r

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,6 @@ native (function) * - - * function
9494
action (function) * - - * function
9595
routine (routine) * - - * function
9696
command (function) - - - * function
97-
closure (function) * - - * function
9897
function (function) * - - * function
9998

10099
object context * f* * * context

src/boot/typespec.r

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ binary ["string series of bytes" string]
2121
bitset ["set of bit flags" string]
2222
block ["array of values that blocks evaluation unless DO is used" block]
2323
char ["8bit and 16bit character" scalar]
24-
closure ["function with persistent locals (indefinite extent)" function]
2524
callback ["function to be called from C" scalar]
2625
datatype ["type of datatype" symbol]
2726
date ["day, month, year, time of day, and timezone" scalar]

src/boot/words.r

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ exit
127127
quit
128128
;break ;-- covered by parse below
129129
;return ;-- covered by parse below
130+
leave ;-- for PROC
130131
continue
131132

132133
; PARSE - These words must not be reserved above!! The range of consecutive

src/core/b-init.c

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -767,19 +767,26 @@ static void Init_Root_Context(void)
767767
SERIES_SET_FLAG(VAL_SERIES(ROOT_EMPTY_BLOCK), OPT_SER_LOCKED);
768768
SERIES_SET_FLAG(VAL_SERIES(ROOT_EMPTY_BLOCK), OPT_SER_FIXED_SIZE);
769769

770-
// Used by FUNC and CLOS generators: RETURN:
770+
// Used by FUNC and PROC generators - RETURN: & LEAVE:
771+
//
771772
Val_Init_Word(ROOT_RETURN_SET_WORD, REB_SET_WORD, SYM_RETURN);
773+
Val_Init_Word(ROOT_LEAVE_SET_WORD, REB_SET_WORD, SYM_LEAVE);
772774

773775
// Make a series that's just [return:], that is made often in function
774776
// spec blocks (when the original spec was just []). Unlike the paramlist
775777
// a function spec doesn't need unique mutable identity, so a shared
776-
// series saves on allocation time and space...
778+
// series saves on allocation time and space...do the same for [leave:]
777779
//
778780
Val_Init_Block(ROOT_RETURN_BLOCK, Make_Array(1));
779781
Append_Value(VAL_ARRAY(ROOT_RETURN_BLOCK), ROOT_RETURN_SET_WORD);
780782
ARRAY_SET_FLAG(VAL_ARRAY(ROOT_RETURN_BLOCK), OPT_SER_LOCKED);
781783
ARRAY_SET_FLAG(VAL_ARRAY(ROOT_RETURN_BLOCK), OPT_SER_FIXED_SIZE);
782784

785+
Val_Init_Block(ROOT_LEAVE_BLOCK, Make_Array(1));
786+
Append_Value(VAL_ARRAY(ROOT_LEAVE_BLOCK), ROOT_LEAVE_SET_WORD);
787+
ARRAY_SET_FLAG(VAL_ARRAY(ROOT_LEAVE_BLOCK), OPT_SER_LOCKED);
788+
ARRAY_SET_FLAG(VAL_ARRAY(ROOT_LEAVE_BLOCK), OPT_SER_FIXED_SIZE);
789+
783790
// We can't actually put an end value in the middle of a block, so we poke
784791
// this one into a program global. We also dynamically allocate it in
785792
// order to get uninitialized memory for everything but the header (if
@@ -1389,6 +1396,7 @@ void Init_Core(REBARGS *rargs)
13891396
const REBYTE transparent[] = "transparent";
13901397
const REBYTE infix[] = "infix";
13911398
const REBYTE local[] = "local";
1399+
const REBYTE durable[] = "durable";
13921400

13931401
REBVAL result;
13941402
VAL_INIT_WRITABLE_DEBUG(&result);
@@ -1552,6 +1560,13 @@ void Init_Core(REBARGS *rargs)
15521560
SERIES_SET_FLAG(VAL_SERIES(ROOT_LOCAL_TAG), OPT_SER_FIXED_SIZE);
15531561
SERIES_SET_FLAG(VAL_SERIES(ROOT_LOCAL_TAG), OPT_SER_LOCKED);
15541562

1563+
Val_Init_Tag(
1564+
ROOT_DURABLE_TAG,
1565+
Append_UTF8(NULL, durable, LEN_BYTES(durable))
1566+
);
1567+
SERIES_SET_FLAG(VAL_SERIES(ROOT_DURABLE_TAG), OPT_SER_FIXED_SIZE);
1568+
SERIES_SET_FLAG(VAL_SERIES(ROOT_DURABLE_TAG), OPT_SER_LOCKED);
1569+
15551570
// Special pre-made errors:
15561571
Val_Init_Error(TASK_STACK_ERROR, Error(RE_STACK_OVERFLOW));
15571572
Val_Init_Error(TASK_HALT_ERROR, Error(RE_HALT));

0 commit comments

Comments
 (0)