Old Idea Revisited: DATATYPE as... Antiform?

Join the club :slight_smile: But I've sort of moved in the direction of accepting that TYPE OF really just answers the fundamental type question, and other questions need to be more specific probes.

There's lots of choices (CLASS OF, or other fingerprinting routines).

"type of antiform" now possible... Should We Use It?

Been ruminating on it, and I think it's probably the right answer.

I've made the arguments above. But beyond the argumentation there's just sort of an intuition... that the answer to the TYPE OF question isn't something you think of as "in-band" in terms of what you generally think of as a "fundamental" value... e.g. one you can put in a block.

You've moved out of the domain of "things" and into a sort of domain of "meta things" when you ask a type question.

And of course, the original motivator still applies... which was the ambiguity of:

rebol2>> find [a 1 b c] integer!
== [1 b c]

rebol2>> find compose [a (integer!) b c] integer!
== [integer! b c]  ; not a word!, should render as [#[integer!] b c]

If INTEGER! is an antiform, then you don't have to worry about that ambiguity, since such a COMPOSE is impossible.

So it's a little funny that my gut reaction would be to be afraid to surrender FENCE!. Datatypes are really important, so "sacrificing" antiform fence for them shouldn't be the issue. If antiform FENCE! somehow solved the datatype problem it's not a sacrifice--it's a solution!

The question should be about fitness for purpose...does it work or is it advantageous to use a list.

Originally the choice to make datatypes like &[integer] instead of words as &integer was that I wanted to use &some-function? as an inert type that could be passed to things like MATCH or use in PARSE.

parse [a @b $c] [some &any-word?]

match &any-word? 'a

; vs...

parse [a @b $c] [some &[any-word?]]

match &[any-word?] 'a

Since datatypes existed under names, they wouldn't be used literally very often--but referred to from words as integer! instead--there was no real motivation to give datatypes the more succinct form. The brackets wouldn't hurt.

I now believe that type constraints are more attractively (and consistently) done with trailing slash:

parse [a @b $c] [some any-word?/]

match any-word?/ 'a  ; slash as barrier hints 'a is not an argument

It does mean that type constraints aren't a different entity from plain actions. But so far, it seems anywhere that was expecting a datatype or type constriant doesn't have any other overloaded meaning for actions...the action would always be interpreted as a test. And with intrinsics and the typeset table optimization it's no longer necessary for performance reasons to distinguish them.

Beyond that, there was some speculation that the answer to TYPE OF might expand out... an example might be forms that included the number of quotes.

 >> type of first ['''x]
 == &[quoted! quoted! quoted! word!]

My updated thinking is that this is a different question from what you get back as a default from TYPE OF.

How Would This Play Out With Antiform FENCE?

So if we believe that the new antiform DATATYPE! might store such answers, then using a list for it would be necessary:

 >> type:quotes of first ['''x]
 == ~{quoted! quoted! quoted! word!}~  ; anti

(Strangely enough, even with two tildes and an "anti", that does look better than the & sigil.)

The question arises: can this live up to the expected behaviors of DATATYPE?

>> qtype!!: type:quotes of first ['''x]
== ~{quoted! quoted! quoted! word!}~  ; anti

>> parse [a '''b] [word! qtype!!]
== '''b

The system could certainly do this for some limited set of representations. Maybe not that limited, if it dispatched as a generic to the datatype to ask if it matched.

Equality tests are out the window, though.

>> type-a: type of first ['''x]
== ~{quoted!}~  ; anti

>> type-b: type:quotes of first ['''x]
== ~{quoted! quoted! quoted! word!}~  ; anti

>> type-a = type-b
== ~null~  ; anti

There might be some limited set of ways to ask if they were "like":

>> type-a like type-b
== ~okay~  ; anti

And maybe that could be driven by logic of checking just the first element in the datatype fence's array. Or maybe that's something else methodized via generic. :man_shrugging:

Anyway, this would all motivate the idea that the list-like nature of fence for datatype is justified.

I'm Going Ahead With It

While it's hazy to think of exactly how this will work out, I'm going to likely be killing off the datatype-oriented usage of & - types.

The & types may remain and be used for some other purpose. Put a pin in that. :pushpin: Rather than delete them, for now I'm just going to call them WILD-WORD!, WILD-BLOCK! etc. and make them error in the evaluator. Worst case scenario they're just a type you know has no other meaning, so your dialect can ascribe whatever you want while delegating the other behaviors to the evaluator. But maybe there is a missing fundamental behavior I haven't identified yet and these can solve that problem.

Afterthought

It occurs to me that I've spoken about FENCE! as being tied in intimately with MAKE

MAKE Should Be Using *Dialected Constructors*

This sort of connects antiform/quasiform FENCE! with datatypes, in a way, if you squint at it.

2 Likes