saltzm / xlang

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Declaring a struct

// In-line requires commas
type MyStruct = (a: String, b: Foo)
// No commas needed!
type Foo = (
   a: String
   b: Bar
)
// Create an alias
// TODO: Decide whether this is a usual alias or whether it's a "copy", i.e. whether 
// objects of type Bar can be passed to functions expecting type Foo, or whether this
// Just says that Bar has the same structure as Foo but is a separate type, which I could
// see being useful in certain cases if you want to use the type system to enforce certain
// behaviors that don't actually influence the structure of the data. (E.g. I could imagine 
// an "OwnedPtr" type that is actually just a pointer, but functions taking OwnedPtr should reject
// things of type Ptr. Could maybe have both concepts as separate things maybe, but don't know 
// how useful that is.
type Bar = Foo
// TODO: Consider using "struct" instead of "type" as keyword

Variable creation/assignment

// Type-deduction works most of the time
let x = 23 // int
let x = 2.3 // double
let x = FnReturningFoo() // Foo
// All blocks of { } are expressions that can return something
// TODO: type inference needs to work for this, which means it 
// needs to work for functions as well... 
let x = {
   let a = 5
   let b = 10
   a + b
} 

// Struct creation requires type specifier
let my_struct : MyStruct = ("hello", "world")
// TODO: Do I like this?
let my_struct : MyStruct = (
   "hello" // a
   "world" // b
)
// TODO: Allow struct init with field names? Leaning towards no...

Function declaration

// "Add is a function from (i32, i32) to i32"
fn Add = (a: i32, b: i32) -> i32 {
   // No "return" required because all block expressions ({ }) can return a value
   a + b 
}

// TODO: Consider this syntax
let Add = fn (a: i32, b: i32) -> i32 {
   // No "return" required because all block expressions ({ }) can return a value
   a + b 
}
// And this syntax along with it
let MyStruct = struct (
    a: int
    b: int
)

// Or even
let Add = (a: i32, b: i32) -> i32 {
   // No "return" required because all block expressions ({ }) can return a value
   a + b 
}

let MyStruct = (
    a: int
    b: int
)

Open questions:

  • Do I want to allow nested scopes, or should I force you to call a function?
  • Do I want to allow variable shadowing?
  • Pass by val or by pointer?
    • I want to make handling structs and heap allocated pointers the same...
  • Do I want inc/dec operators?
  • Do I want to allow named struct as input parameter that does unpacking? E.g. fn Foo = Bar -> Baz { /* ... */ } where Bar is some type Bar = (a : A, b: B) and then the function receives a/b as inputs
  • Constant ?
  • enum?
  • var/val vs. let and let mut
  • can i get away without variable reassignment
  • Assignments as expressions
  • Consider bizarre piping form of function calls, e.g. (2, 3) | Add | TimesTwo, or my_struct | GetSize

Features:

  • Variable assignment to constants
  • Variable assignment to structs
  • Struct declaration/definition
  • Named function declaration/definition/usage
  • Type inference for non-struct variables
  • Type inference for block expression return types
  • "Official way" to include types from C
  • "Official way" to call functions from C
  • "Official way" to include libraries from C
  • Passing structs as function arguments by pointer
  • Lambdas (no captures)
  • Allocate/deallocate heap memory
  • Generics
  • Modules
  • Variable reassignment
  • defer/destructors?
  • Conditionals
  • Loops
  • Having more than one file (lol)

About


Languages

Language:Rust 100.0%