Actions that lack RETURN functions might nevertheless want to document their potential return product.
intsum: lambda [x [integer!] y [integer!]] [
x + y ; want to document this will be an integer
]
twoints: yielder [n [integer!]] [
yield n + 10, yield n + 20 ; want to document it yields integers
]
The yielder seems pretty obviously like you should say yield: [integer!]:
twoints: yielder [yield: [integer!] n [integer!]] [
yield n + 10, yield n + 20
]
It's a rather direct parallel to FUNC: YIELD is the word you're using (like RETURN) and it's definitional to the FRAME! so you can't have another parameter called YIELD. You could have one called RETURN, though:
twoints: yielder [yield: [integer!] return [integer!]] [
yield return + 10, yield return + 20
]
But LAMBDA is a different beast. Especially if you're building a FUNC-like construct on top of LAMBDA, you're likely going to define a frame local called RETURN.
We could just say that you put return: [integer!] in the spec anyway, and understand that there's no actual return function.
intsum: lambda [return: [integer!] x [integer!] y [integer!]] [
x + y ; want to document this will be an integer
]
But I feel like it's good to reinforce that there isn't a return, and there's no word in the frame.
There could be another annotation or part of speech, like #result
intsum: lambda [
#result [integer!]
x [integer!]
y [integer!]
][
x + y
]
Or we could think about dropping a label entirely, and saying you just understand the first block is a description of the result:
intsum: lambda [
[integer!]
x [integer!]
y [integer!]
][
x + y
]
But the speedbump on that is that it flies in the face of my preferred syntax, which is to put the parameter label before the type spec. This provides a good rhythm that you don't need to break when you have refinements with no arguments.
You'd have to put it after, or it would be considered part of the function description.
intsum: lambda [
"An Integer Sum Expressed as a Lambda"
[integer!] "Result is the sum of first and second"
x "The first value"
[integer!]
y "The second value"
[integer!]
][
x + y
]
Mechanically, New Ideas Are Coming
It may be that the way to typecheck a lambda in the event you want that is to use another component:
intsum: returns [integer!] lambda [
"An Integer Sum Expressed as a Lambda"
x "The first value"
[integer!]
y "The second value"
[integer!]
][
x + y
]
Maybe it could notice if you put a block-in-a-block for a description:
intsum: returns [
"Description of return value"
[integer!]
] lambda [
"An Integer Sum Expressed as a Lambda"
x "The first value"
[integer!]
y "The second value"
[integer!]
][
x + y
]
And it's just that FUNCTION and YIELDER make it a bit easier by rolling that all together for you. Which is an interesting thought, though it's kind of ugly.
Outside The Box Thinking: Colons With No Words?
A single colon, perhaps? RETURN: without the RETURN?
intsum: lambda [
"An Integer Sum Expressed as a Lambda"
: "Result is the sum of first and second"
[integer!]
x "The first value"
[integer!]
y "The second value"
[integer!]
][
x + y
]
Hm. No, lone : is a WORD!, you could take a parameter called that and it would be legitimate.
Instead you could use #: or []: or something to give this impression of a result:
intsum: lambda [
"An Integer Sum Expressed as a Lambda"
[]: "Result is the sum of first and second"
[integer!]
x "The first value"
[integer!]
y "The second value"
[integer!]
][
x + y
]
intsum: lambda [
"An Integer Sum Expressed as a Lambda"
#: "Result is the sum of first and second"
[integer!]
x "The first value"
[integer!]
y "The second value"
[integer!]
][
x + y
]
I actually think I like the []:
It hints at the absence of a word to the left of the colon, because there's no word in the frame for returning. I like how it points to whats missing, so you see it very semiotically: "this action has no RETURN, see? It's what you expected to see but aren't seeing, and we're emphasizing that your eyes do not deceive you."
In a more reduced view, with no strings:
intsum: lambda [[]: [integer!] x [integer!] y [integer!]] [
x + y ; want to document this will be an integer
]
Nothing's going to be perfect here, but I think I like that enough to go with it. And it solves one of my major gripes about not wanting to use LAMBDA--losing a return spec is never worth it to me for "don't have to put in a RETURN".
But this tips the scale, and I'd use LAMBDA quite often.
This looks like it's probably close to as good as it can get if SET-WORD is what we are using for RETURN: and YIELD: (I think using FENCE! for locals will sufficiently space off any locals assignments in the spec, to not have SET-WORD! at the same level)