2019, huh?
![]()
Well I think this aspect is sorted out. We control the GET or SET based on the decoration of what gets passed in.
>> x: ~#trashy~
>> $x
== x ; bound
>> get $x
** PANIC: x is TRASH! (~#trashy~), must use ^META to GET
>> meta $x
== ^x ; bound
>> get meta $x
== \~#trashy~\ ; antiform (trash!)
Doing it this way makes it easy for people writing dialects to "do the right thing according to decoration" with their SETs and GETs.
If their dialect had someone writing var: then they probably by default want plain assignment semantics. If they said ^var: they probably want meta-assignment semantics. (At least, this is the case for me, when I'm implementing something like UPARSE).
We don't want refinements that duplicate this configurability, because if the refinements contradict the decorations on the value itself, which do we listen to?
How Many Types Should GET and SET accept?
I've been leaning to saying not that many.
If you're doing a GET of @foo: what are the odds you know what you are talking about, such that we just throw up our hands and give you the same thing as GET of foo? And what happens when the day comes that we decide eval [@foo: 10] actually does something meaningful (that day may come soon!)
So I propose that GET and SET be pretty conservative in the sense of pick apart things in the way the evaluator would be willing to.
e.g. we've already got the machinery to handle something like [foo ^baz {bar}]: ^some-pack
So there's no point in being antagonistic and forcing people to write:
>> my-block: $[foo ^baz {bar}]
== [foo ^baz {bar}] ; bound
>> code: compose [(my-block): ('^some-pack)]
== [[foo ^baz {bar}: ^some-pack] ; bound
Instead, I'm proposing you should be able to say:
set my-block ^some-pack
And it runs through the same code path.
If the evaluator already does the thing, then expose the thing as a function that does it without the overhead of building a code block and instantiating an evaluator level.
But don't make up behaviors that haven't been condoned by the evaluator for "convenience". Factor the "convenience" part out with other tools, e.g. in functions like DECORATE
Framing it in reverse: if it is good enough for people to really need it programmatically in functions like SET and GET, it's probably good enough to have a syntax in the evaluator as well.
So if eval [@x: 10] does something, I'd expect set @x 10 to do it too. If it doesn't do anything, I don't expect SET to strip off the @ sign just for the sake of making it "easier" for someone who has an @x in a variable and feels like setting it. If the evaluator wouldn't know what it meant, the caller needs to take it off, or they'll get the same error they'd get if they tried that in the evaluator.
The nuance of if it should accept a trailing colon on the block is something likely worth making a concession for:
>> my-block1: $[foo ^baz {bar}]
== [foo ^baz {bar}] ; bound
>> my-block2: $[foo ^baz {bar}]:
== [foo ^baz {bar}]: ; bound
set my-block1 ^some-pack ; legal
set my-block2 ^some-pack ; concession: also legal?
This hinges on the idea that there's no such thing as [foo ^baz {bar}]::, because if there were, I would not advise making this concession.
And for this reason I would think that trying to SET :[foo ^baz {bar}] shouldn't strip off the leading chain, because you could write:
:[foo ^baz {bar}]: ^some-pack ; ???
And I haven't decided if that should mean anything or not.
This Isn't Coming Completely Out of the Blue
I've been factoring the evaluator to take all the random historical uncommon paths and force them through chokepoints of common behavior.
It's feeling very solid and coherent to do so (even if it's leading to near term slowness).
So this is the direction I imagine it's best to take.
And get meta word looks better than get:any word any day.