Let's say you want a version of append that just appends random numbers to things:
>> append-random: adapt get $append [
value: random 10
]
This works, but the function interface still thinks it takes two arguments:
>> append-random [a b c] [d e]
== [a b c 10]
So fine, you can just specialize out the argument. Both ADAPT of a SPECIALIZE and SPECIALIZE of an ADAPT would remove an argument. But you want the specialize to run first, otherwise it would overwrite the adapted value. So SPECIALIZE the ADAPT, to put the specialize earlier in the composition process.
But what value do you put in the specialized-out slot if you're just going to overwrite it?
Today we have quite the awesome answer: use a TRIPWIRE! Sounds great!
>> append-random: specialize (adapt get $append [
value: random 10
]) [
value: ~<specialized out>~
]
** Script Error: append expects [~void~ element? splice?] for its value argument
Ooops. SPECIALIZE Typechecked That
There are two good reasons for specialization to type check:
-
You find out about bad types at the moment of specialization--instead of having to wait until the function is called to know there are problems.
-
It can speed up the system by not type checking those parameters again (though it occurs to me this may be broken right now, and fixing it sooner than later would probably be smart)
Historically what I've done just to get things going is to use some value that typechecks in the argument slot:
>> append-random: specialize (adapt get $append [
value: random 10
]) [
value: [something that typechecks]
]
>> append-random [a b c]
== [a b c 7]
>> append-random [a b c]
== [a b c 9]
>> append-random [a b c]
== [a b c 7]
For the sake of education, notice what happens if you did it backwards and ADAPT the SPECIALIZE:
>> append-random: adapt (specialize get $append [
value: [something that typechecks]
]) [
value: random 10
]
>> append-random [a b c]
== [a b c [something that typechecks]]
Seems We Need SPECIALIZE:RELAX
Having to pick an arbitrary meaningless value that won't trip up the type checking is bad.
While we want to type check 99% of the time, this kind of scenario calls for a version of specialize that does not do typechecking.
Hence I propose SPECIALIZE:RELAX
.
Tripwires seem like the go-to datatype to use for these specialized-out values. Rather than just say ~<specialized out>~
you can be as detailed as you like, to help inform on what should happen:
>> append-random: specialize:relax (adapt get $append [
value: random 10
]) [
value: ~<ADAPT phase of APPEND-RANDOM puts INTEGER! here>~
]
Tripwires are great! You don't have to stress too much about cost...the string inside the tag only exists as one instance in memory.
But you could be lazy and/or cheap, and just unset it.
>> append-random: specialize:relax (adapt get $append [
value: random 10
]) [
value: ~
]
There might be other uses for not typechecking at the moment of specialization, but I can't think of what they would be.