reflection.txt 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. We'd like pieces of code to be reifiable, synthesizable, and
  2. re-absorbable. Including types.
  3. How?
  4. dyn -- a (value,type) pair, plus an operator to dyn-ify any typed value
  5. typecase -- ability to switch out of a dyn
  6. type comparisons -- ability to compare 2 unknown types
  7. type reification -- ability to traverse and analyze a type term
  8. ast -- representatives of all rust terms
  9. reify -- operator to turn a value into its ast
  10. quote -- syntax extension for entering literal asts
  11. env -- ability to reify the current environment
  12. mask -- separating off sections of the environment?
  13. eval -- operator to absorb an ast into an environment
  14. What does it mean for a value to have a type?
  15. Structure of types. Literally: telling the runtime how to traverse
  16. the structure of the object. Which bits to consider as pointers
  17. vs. integers vs. container-parts.
  18. In a variable stored in a static environment -- say an activation
  19. frame -- the frame stores a pointer to its code value, and that
  20. code value stores a frame layout description, including the types
  21. of all the slots. No problemo.
  22. If I pass a dyn to you, you have no idea what the type of the thing
  23. is. Your frame has no idea. So I have to pass the type with the
  24. value.
  25. Should the type be separable? Sure, why not? Suppose I want to run
  26. a function to perform some calculation on the type alone. Might as
  27. well be possible.
  28. What difficulties arise when traversing a type?
  29. If I hit a named subterm, I have to look it up (or it can be
  30. expanded inline, if it's acyclic)
  31. Suppose I package a type by saying "here is an environment with N
  32. terms, and the one we're talking about is term K in this
  33. environment". Is that useful? Practical?
  34. The environment can carry a minimal set of terms, rather than say
  35. an entire module of unrelated terms. This is useful in a
  36. compatibility sense: types T and V are equal when their minimal
  37. dependency environments are equal?
  38. Working from slightly modified napier88 design: system should be
  39. persistable (not persistent). That is: every running program should
  40. serialize in a way that is both sensibly de-serializable *and* can be
  41. massaged into working / being interpreted in a future context.
  42. Persistence of data should, in other words, not prevent *evoution* of
  43. the system.
  44. How?
  45. Napier decided to do structural typing, on the basis that the bindings
  46. from types to environments became basically irrelevant: types are
  47. closed terms in this model, and with a little bit of clever
  48. hash-consing and care to chose normalizing forms, you don't need to
  49. worry about which environment a type gets defined in. This is very
  50. helpful in evolving the system.
  51. The napier docs are concerned that combining universal quantifiers and
  52. recursive structural types leads to undecidable equivalence, for
  53. example they give this term:
  54. type anyarr[T] = variant { simple: t, complex: anyarr[array[T]] }
  55. They claim this is not decidable. Why? Hmm. Because anyarr[T] expands
  56. at each unfolding rather than contracting or remaining constant,
  57. i.e. the checking process potentially diverges? Well, it's a messy
  58. term anyways. One way or another -- we need to find the rationale! --
  59. they add a restriction that supposedly recovers decidability:
  60. The specialisation of a recursive operator on the right hand side of
  61. its own definition may not include any types which are constructed
  62. over its own formal parameters.
  63. IOW the term has to contract. These are ok:
  64. type x[T] = ... x[T] ...
  65. type x[T] = ... x[Y] ...
  66. but this is not:
  67. type x[T] = ... x[foo[x[T]]]
  68. That's fine. Let's assume we have to use that too for now.
  69. Persistence! I want to think about this and be clear about it. Rust
  70. modules should be persistable.
  71. level 0 encoding: the elias omega octet code
  72. level 1 encoding: the code numbers for a file:
  73. "Rust" : ascii < omega-octets, so just |0x52 0x75 0x73 0x74|
  74. <vers> : a version number (hint), we start with 0
  75. <body> : an artifact constructed from a grammar!
  76. type terms:
  77. hw types
  78. ----------------------
  79. s<N>
  80. u<N>
  81. flo = ieee754.bfp
  82. dec = ieee754r.dfp
  83. prim types
  84. ----------------------
  85. nil
  86. bool
  87. int
  88. char = unicode5.codepoint
  89. str = unicode5.utf8_nfc
  90. prog
  91. proc
  92. dynamics
  93. ----------------------
  94. dyn
  95. env (is this required? merely a napier idiom, or deep issue?)
  96. anonymous constructors
  97. ----------------------
  98. vec[]
  99. tup[]
  100. abs[]
  101. func[]()->
  102. func?[]()->
  103. func![]()->
  104. func*[]()->
  105. func+[]()->
  106. port[]()->
  107. port?[]()->
  108. port![]()->
  109. port*[]()->
  110. port+[]()->
  111. chan[]()->
  112. chan?[]()->
  113. chan![]()->
  114. chan*[]()->
  115. chan+[]()->
  116. labeling constructors
  117. ----------------------
  118. rec{}
  119. alt{}
  120. AST nodes:
  121. ...