The Odin language has a type called any.

The Odin language has a type called string.

The Odin language has a type called rawptr.

These are all instances of a more general type of pointer, although, Odin makes no such generalization.

Odin’s String Type

In Odin, a string is described by a block of contiguous bytes pointed to by a fat pointer that contains the address of the first byte, and, the length of the block.

Odin String Type

Odin’s Any Type

The point of Odin’s any type is to allow introspection.

The any type contains enough information to allow examining the type of the datum at runtime.

Odin Any Type For "ABC"

Note that the type table size can be optimized by inserting knowledge of types into the Odin compiler. In essence, these are hard-wired, ad-hoc edge-cases for various distinguished types.

Odin’s Rawptr Type

A rawptr is like a pointer in the C language - a single address with type runtime information removed from it.

Usage Issues With Any

Sometimes, the Odin compiler needs to create transient fat pointers for data. For example, if a constant string is passed as an any parameter to a function, the compiler quietly creates the transient fat string pointer and (at time of writing) places this pointer into the local scope (i.e. the stack).

This behaviour - automatic creation of transients - makes it difficult to understand how to write Odin code when any is used as a formal parameter to a function, e.g. cloning a string places only part of the string in the heap and leaves the other part on the stack. Evaluation of expressions for use as formal parameters can result in the automatic creation of transient pointers.

The general response to this kind of problem is the edict “don’t use any”, but, any is useful beyond what it was originally designed for, e.g. type freedom at design time, followed by gradual static typing later during the production engineering phases.

An easier-to-use variant of any is required - maybe subdividing the type into more-specific types, e.g. any that can only point to data, but, cannot point to other pointers, indirectany that can only point to pointers, and, not to data, etc.

Subsuming All Pointers Into A Single Pointer Type

In essence, the any type is a dynamic type, like that used in dynamically-typed languages, such as Lisp, Python, JavaScript, etc.

When all of the runtime type information is stripped away, one gets the effect of assembler and/or the C language.

The job of a production-engineering compiler is to strip away as much type information from the final product as is possible. This is usually done through the use of static type checking, which is most effective after the fundamental design has been completed.

The job of a design-oriented programming language, though, is to make iterative design more convenient, e.g. by keeping all type information and making it available to the programmer.

The ideal language would allow full flexibility during design, then allow Production Engineers to apply gradual typing to the design in ways that preserve the provenance of the original design. Obviously, tools that would aid in Production Engineering might include memory footprint profilers and speed profilers, allowing Production Engineers to measure and tune the design for desired product characteristics.

For example, JavaScript programmers tend to favour design over production engineering and optimization and tend not to worry about size and speed issues of their code, whilst C programmers jump into optimization by using pointers to construct data and to reduce memory footprints.

It should be possible to make all pointer types the same at design time, while allowing compilers to automatically optimize away type information that can be determined at “compile time”. In fact, “compile time” itself might be chopped up into a pipeline of smaller, easier-to-understand units of compilation and culling.

Given this goal, it is possible to view the above Odin pointer types as being all the same, i.e. all pointers can be treated as fat any pointers.

Fat Any Rawptr

Fat Any Rawptr

Fat Any String (Pointer)

Fat Any String Pointer

The above diagram shows a distinct type for string[3].

In general string[3] is but a byte[3] which is but an array of unit with length 3, so, the above might be expressed something like:

Revised Type Table

Unexplored Ideas

  • what are the base units for describing types in this way?
    • unit
    • sequential group (array)
    • ordered group (struct)
  • it should be possible to describe all types, however inefficiently, in terms of base units
  • later, compilation-allocation phases can be used to compress types to conserve footprint, to reduce indirections, etc.
  • a struct is an ordered group of items
  • an or-type is a group of items, only one of which is used in any given instance
  • a union is a or-type that has been optimized by an allocator to reduce memory footprint by overlaying all items in the group to share the same memory

See Also

Blogs

blog

obsidian blogs (see blogs that begin with a date 202x-xx-xx-)

Videos

videos - programming simplicity playlist

Books

leanpub’ed (disclaimer: leanpub encourages publishing books before they are finalized - these books are WIPs)
Programming Simplicity Takeaways, and, Programming Simplicity Broad Brush

Discord

Programming Simplicity all welcome, I invite more discussion of these topics, esp. regarding Drawware and 0D

Twitter

@paul_tarvydas

Mastodon

(tbd, advice needed re. most appropriate server(s))