Initial commit
This commit is contained in:
commit
85b08fe00b
29 changed files with 750 additions and 0 deletions
35
README.md
Normal file
35
README.md
Normal file
|
@ -0,0 +1,35 @@
|
|||
# Shiny
|
||||
|
||||
Expressive systems language. Inspired by Rust, but different, "shiny" is kinda different than "rust".
|
||||
|
||||
# Design
|
||||
|
||||
1. Types and layouts are different things. Type defines
|
||||
**what** data is, **layout** defines how type laid in memory.
|
||||
|
||||
2. Typing discipline is structural, making language easier to use
|
||||
for application programming. Most hugely focus on data and its properties, like
|
||||
"the field xxx" needs to contain date between 2000.01.01 and 2027.01.01 or
|
||||
"the token in request is valid". Clearly, these patterns can be implemented without
|
||||
structural typing by using functions or traits, structural discipline makes it easier to write and
|
||||
easier to introspect, since this allows to make narrower definition
|
||||
of predicate in your domain, while passed function logic can be really arbitrary, it's more general,
|
||||
and you have to deal with that.
|
||||
|
||||
3. Reusing pattern matching for types. In Rust, traits are used to constrain types,
|
||||
in `shiny`, we reuse `pattern matching` to that kind of thing. So, all bounds are encoded
|
||||
as "types fits in this shape" rather than as "the type implements these traits".
|
||||
|
||||
# Some notes
|
||||
|
||||
`shiny` has product and sum types, I call these "binary" types - combination of two types. As an example:
|
||||
`i32 * i32`, alternatively can be written as `(i32, i32)`, also (1) `i32 * i32 * i32 * i32`
|
||||
(2) `(i32, (i32, (i32, i32)))` and `(i32, i32, i32, i32)` are the same types, but (3) `i32 * (i32 * i32) * i32` are NOT, multiplication
|
||||
operator here is left-associative, but all (1, 2, 3) types mentioned here are intechangable. Interchangable means here:
|
||||
If we have constrained type with 1 or 2 or 3 (disambiguation: `or` here means exclusive `or`) **pattern**,
|
||||
all mentioned types (1, 2, 3) will fulfill the constraint, by applying associativity and commutativity.
|
||||
|
||||
Necessary to note, if we have constraint, say, `i32 * str` and type `str * i32 * bool * i32 * str`, what should compiler choose?
|
||||
Compiler simply would prefer part of the type that can be moved to head with less number of expression
|
||||
rewrites. Less strict - we prefer types that are in head, rather than types that are in tail of the type.
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue