evincarofautumn / kitten

A statically typed concatenative systems programming language.
http://kittenlang.org/
Other
1.09k stars 39 forks source link

Treat types as compile-time expressions #132

Open evincarofautumn opened 9 years ago

evincarofautumn commented 9 years ago

Types are currently parsed specially. It would be simpler and more consistent if they were treated as ordinary compile-time expressions, which happen to produce types for use by the typechecker. This would be a big step toward static metaprogramming. Thoughts on how to do this:

dmbarbour commented 9 years ago

I think this is a great direction to go. It allows abstraction of the type descriptors. Do keep in mind the possibility of: "a b -- b a" parseType.

On Wed, Oct 1, 2014 at 8:21 PM, Jon Purdy notifications@github.com wrote:

Types are currently parsed specially. It would be simpler and more consistent if they were treated as ordinary compile-time expressions, which happen to produce types for use by the typechecker. This would be a big step toward static metaprogramming. Thoughts on how to do this:

  • Type applications should look like function applications:
    • Stream@a → a Stream
    • These@(a, b) → a b These
    • Vectors might be called something like T vector instead of [T]
  • The type of stack-products must be explicit: a, b instead of a b
  • Kind sigils are not required: s instead of s...
  • Stack variables might need to be explicit: s, a -> s, a, a instead of a -> a a
  • Type operators and value operators might need to live in separate namespaces, so that a | b can denote a sum type or a bitwise OR without dealing with overloading (yet (again))

— Reply to this email directly or view it on GitHub https://github.com/evincarofautumn/kitten/issues/132.

brendanzab commented 9 years ago

So would types more or less follow the same syntax as expressions, like in Haskell?

evincarofautumn commented 9 years ago

@dmbarbour A parseType function sounds perfectly feasible—it could just call the compiler, actually—but I wonder how useful it would actually be.

@bjz Yes, they would have exactly the same syntax, just a different set of operators.

I would like a way to avoid requiring stack variables, because they would be on every function. We could have two different function arrows:

[a] -> [a, a]
r, (r => s) => s

Or “type holes”:

_, a -> _, a, a

, is a nice operator for stack-conses, but it conflicts slightly with vectors [1, 2, 3]. We could change vectors to [1; 2; 3] like in OCaml. That would allow a value-level , operator for tuples:

["one", 1; "two", 2; "three", 3] vectorToDictionary

Vectors were originally [1 2 3], but having a separator turned out to be useful for providing type error messages.

jeaye commented 9 years ago

I believe I see a potential problem with this. There is an ambiguity if ever you support non-type template params (which I'd really like you to). The special syntax allows you to be clear that foo<4> is an instantiation and not calling foo with 4 as 4 foo may imply. If you can resolve this by checking whether or not foo expects template params, I wonder if it's still easier on the reader to see the explicit specialization.

(forgive my C++ terms, I'm still adjusting)