The TYPESET! Representation Problem

TYPESET! took advantage of 64-bit integers--and a limitation of 64 fundamental types--to fit 64 bit flags into a single value cell to represent a typeset. Besides the obvious lack of extensibility, this has a number of problems. One of which is that typesets render in a pretty ugly way...a seemingly simple concept like ANY-TYPE! expands out fairly monstrously:

r3-alpha>> print mold any-type!
make typeset! [unset! none! logic! integer! decimal! percent! money! char!
pair! tuple! time! date! binary! string! file! email! url! tag! bitset! image!
vector! block! paren! path! set-path! get-path! lit-path! map! datatype!
typeset! word! set-word! get-word! lit-word! refinement! issue! native!
action! rebcode! command! op! closure! function! frame! object! module!
error! task! port! gob! event! handle! struct! library! utype!]

red>> print mold any-type!
make typeset! [datatype! unset! none! logic! block! paren! string! file!
url! char! integer! float! word! set-word! lit-word! get-word! refinement!
issue! native! action! op! function! path! lit-path! set-path! get-path!
routine! bitset! object! typeset! error! vector! hash! pair! percent! tuple!
map! binary! time! tag! email! handle! date! port! image! event!]

People are used to typing in variables--like arrays or objects--and seeing what they look up to be a large amount of data. But a typeclass like ANY-TYPE! doesn't typically have this "explosive" character...and it impedes readability.

If you look closely you'll see another sneaking problem hinted at by R3-Alpha's never-implemented UTYPE! (for user-defined type). Imagining that it had an implementation, this would suggest that all user-defined types would be considered equivalent in a TYPESET!. If you took one user-defined type as a parameter, you would have to take them all, and do some filtering on it after the fact.

(In fact, extension types in Ren-C (which are on hold at time of writing) had this very problem. If you passed a GOB! to a native routine that expects a VECTOR! or a STRUCT!, it would crash. It's something that a real answer to typesets would have to address, part of why I'm mentioning all this.)

This doesn't even touch upon the idea of "type-classes"...

e.g. if you decide to make a base object with something like book!: make object! [...] and later make book! [...], this "book!" is the kind of thing you might consider in some languages to be a class. You might want to write a routine like library-checkout: function [b [book!]] [...]. But there is no facility for this.

But..."Derived binding" in Ren-C set up some groundwork for understanding derivation. This was done for efficiency: to know the relationships in order to be able to forward references to base class members downward to the instance. That avoided needing to make deep copies of every member function of objects each time a new instance is made...just so those functions could refer to the variables in the derivations. Yet the relationship it had to encode to accomplish this could also be used as a type test to see if something came from a given type hierarchy.

So the mechanics are there...and it seems it would be cool to implement. But again, that depends on a notion of what a "typeset" actually is, which is the limiting factor.

And what about "type-tests..."?

Still another question comes along for tests that are basically functions. How about even-integer?, or block-2? where that's a block containing two elements? These seem very useful, though potentially dangerous if the function has side effects... leading one to wonder if there should be a PURE annotation for functions that promise not to have side effects, and that they take all their parameters as CONST and won't use any non-PURE functions in their implementations or look at any variables that aren't parameters that haven't been permanently LOCK'd.

I actually think "type test" is the fundamental thing to be looking at, instead of some nebulous TYPESET! construct.

You'd not get the flattened list of types out, because it would be a function:

>> my-check?: typechecker [any-series! integer!]
== ~#[frame! [value]]~  ; anti

>> my-check? "abc"
== ~okay~  ; anti

>> my-check?:type integer!
== ~okay~  ; anti

Sorry, I don't buy that. By the same token you could stop showing binaries, blocks and strings in the console.

Maybe types in a typeset are always shown in the same order, then it is less ambiguous which types are dropped in the display.

Furthermore the number of types won't grow indefinitely, so just showing the full list may not be that bad after all.

1 Like

2 posts were split to a new topic: What If "DATATYPE" Was Isotopic (TL;DR: Bad Idea)

A post was merged into an existing topic: What Should TYPE OF an Isotope Be?

3 posts were split to a new topic: Old Stuff Regarding &[type] Conventions

Things are indeed now built on top of typechecker functions. And those functions indeed don't show you that much:

>> any-series?/
== ~#[frame! "any-series?" [value]]~  ; anti

But on the bright side, functions cache their symbols. So you're not completely in the dark about what a typeset represents.

Also: function dispatchers have reflectors now. So you can ask them questions. There's no reason the built-in typecheckers couldn't cook up an answer to TYPES OF...

>> types of any-series?/
== [text! block! ...<whatever>]

So look on the bright side, things aren't that bad.... :sun:

Also... PARAMETER!

Another concept that may come into play here is PARAMETER!.

There's no MAKE for them yet. But we can get one out of the frame of a prebuilt function:

>> negate/
== ~#[frame!! [
    number: #[parameter! [any-number? pair! money! time!]]
]]~  ; anti

>> negate.number
== #[parameter! [any-number? pair! money! time!]]

We can use it with match:

>> match frame.number 10
== 10

>> match frame.number <abcd>
== ~null~  ; anti

So that's something like a TYPESET!. It's not a set of bits, but an array of constraints augmented by some optimizations that speed up matching. I'm not sure how much of a role PARAMETER! will play, but it may fulfill some purposes people had in mind for typesets.