<https://gist.github.com/halgari/f431b2d1094e4ec1e...
# linking-together
s
https://gist.github.com/halgari/f431b2d1094e4ec1e933969969489854 Blurb titled "What I want from a Type System".
k
I was reading this as well, felt related to the Dark thread on #CCL5VVBAN (https://futureofcoding.slack.com/archives/CCL5VVBAN/p1561573844118300) which has veered away from the OP somewhat.
s
One aspect I'm interested is in if any type systems encourage/require extensive 'column types'. What I mean is typically you have this
Copy code
class Person:
   name: string
Now as soon as you deference
person.name
you've lost all context - you just have a string. Would be nice to have more meaning attached to the values themselves. You can kind of solve this by newtype/aliasing but it's very clunky and may require defining both a new type and the field with the same name.
👍 3
m
The way that shapeless models records in Scala is to represent a field
name: SomeType
as an element of an
HList
with the type
Tagged[SomeType, "name"]
where the "name" is a literal type, ie. the singleton type of the String precisely equal to "name".
Is that what you're looking for, or are you after more structure?
s
"2) Value types in structures would need to be nominal, not structural. I really don't care if I get a tuple of [Int32, String], I very rarely care what the machine level types are, what I really want is [ProductID, ProductName], what the underlying types are doesn't really matter to me." 😭
I think this is fine in certain applications and certain domains
but in other applications you absolutely need to care about the machine level types in order to hit performance or memory targets
k
Value types in structures would need to be nominal, not structural. I really don't care if I get a tuple of
[Int32, String]
, I very rarely care what the machine level types are, what I really want is
[ProductID, ProductName]
, what the underlying types are doesn't really matter to me.
The article is using nominal vs structural in a way that I can sympathize with but haven't seen before. Is
int32
a nominal type because you (often) can't cast it to a boolean? Or is it a structural type because you can use the same operations on it as
int64
? Our categories seem to break down at the event horizon of primitive types. Between this and Rich Hickey's recent critique [1], I feel like I'm seeing the word 'types' with new eyes in 2019. [1]

https://www.youtube.com/watch?v=YR5WdGrpoug

👏 2
s
Thanks @Miles Sabin - looks interesting, will check it out. The context I'm after is not just the name of the field and it's type, but also it's container type.
The tension between machine types and domain types hasn't been satisfactorily resolved in any language afaik. Do 'types' declare how bits are laid out in memory or do they declare what the domain meaning is? Without a good solution here, what we have is excessive domain model corruption to appease the machine layout. Starting with C, you had struct packing where you'd suffle fields in a perfectly readable struct just to make it efficient. Then you have the 'array of structs' vs 'structs of arrays' problem. This happens in databases too - the question of how much to normalize. There is absolutely no change to the domain data model across many implementation choices, yet the 'domain logic' code ends up being so tightly coupled to these decisions that switching it requires changing code all over the place. I think what the essay is saying that they want to work more with the domain types than memory layout types. Languages that I know of don't actually separate these two ideas - I wonder if there are any languages that do. E.g. if you define your domain types in a high level type system that is not tied to a specific memory layout. Then separately you define mappings between the domain types and machine types...
❤️ 1
s
@shalabh Sounds like you might want to look at what I just posted in #C5T9GPWFL: https://futureofcoding.slack.com/conversation/C5T9GPWFL/p1562167414128600
👍 1
k
@shalabh I like your categories better than 'nominal' and 'structural', which constantly slide past my brain. Arguably your requirement is met even by Java, using interfaces. Perhaps interfaces are just under-used? Part of the problem is that they make it too easy to exit them because their methods often operate on memory layout types. What if we required types within interfaces to only be other interfaces? Is this a well-known 'design pattern' or something? It isn't quite a Facade. http://wiki.c2.com/?CategoryStructuralPatterns
Somebody there mentioned refinement types, which seem at first glance to be an interesting halfway point to dependent types.
I've also received a suggestion to check out Ada 2012: https://www.adacore.com/uploads/books/pdf/SafeSecureAdav2015-covered.pdf (page 21)
s
Yeah structural vs nominal seems to only apply for composite user defined types. Primitive types are.. both? Interfaces do seem like one possible way to decouple the domain aspects from the machine representation aspects, but as you say, often use the machine types across the interface boundary.
What if we required types within interfaces to only be other interfaces?
This is somwhat the thing I'm looking for. Maybe it's possible as a design pattern. I feel this idea needs to be provided by the system. One key aspect would be the definition of the 'mapping' between the domain types and the machine types. If this was powerful there's no reason to always clump domain structs together in memory. Perhaps it's also possible have multiple possible underlying representations used in different scenarios for the same domain types and have the system be aware of this mapping. Higher level logic could be written against the domain data model only and optimizations would be defined only in the mappings/hints to machine types.