Initial commit

This commit is contained in:
Aleksandr 2024-10-15 19:03:39 +03:00
commit 85b08fe00b
29 changed files with 750 additions and 0 deletions

35
README.md Normal file
View 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.