Rosetta 1

Posted on September 2, 2022
Tags: codeetc

1 OOP

2 Basics

let bleh : any = 5
let msg : string = "hello"
let two : number = 2
let flag : bool = false
let kids : string[] = ["bob","rex","luke"]
let coproduct : (string | number) = 6
let listCoproduct : (string | number)[] = [4,"hi",6,"no"]

interface BlogEntry = {
    id: number;
    content: string;
}

function somethn <Type>(x : Type) : Type[] {
    return [x,x];
}

const hi = <T,>(x: T) : T => {
    return x;
}
  • We intentionally add a comma after T, in <T,>(x: T) otherwise it will conflict with jsx dom tags.
var bleh any
bleh = 2 
blehX := 3
var s string = "hello"
  • Variables in rust are by default const in C
let mut hah : i32 = 99;
hah = 43;
const bleh: string = "Ha";
let AHH: char = 'h';
let mut v : Vec<i32>= vec![10,20,30,40];
println!("Hello {}!","hi");

#destructuring
let kittycat = ("Furry McFurson", 3.5);
let (name,age) = kittycat;

let numbers = (1, 9, 3);
assert_eq!(9, numbers.1);

//if-let while-let syntax for pattern matching
let maybe4: Option<i32> = Some(4);
if let Some(x) = maybe4{...};
while let Some(x) = maybe4{...};


fn sale_price(price: i32) -> i32{
    if is_even(price) {
        price - 10 #w/o semi-colon 
        #return price - 10;  #w/ semi-colon
    } else {
        price - 3
    }
}

pub fn bigger(a: i32, b: i32) -> i32 {
    if a > b{
        a
    }else if a <= b{
        b
    }
}
Type Code
int i32
bool bool
char char
  • Assignment of non-trivial objects in Rust is actually consume/move

3 Array


fn main() {
    let a  = ["hi";100];

    if a.len() >= 100 {
        println!("Wow, that's a big array!");
    } else {
        println!("Meh, I eat arrays like that for breakfast.");
    }
}
#[test]
fn slice_out_of_array() {
    let a = [1, 2, 3, 4, 5];
    let nice_slice = &a[1..4];
    assert_eq!([2, 3, 4], nice_slice)
}

4 List/Vector/Slice


    let a = [10, 20, 30, 40]; // a plain array
    let v : Vec<i32>= vec![10,20,30,40];


fn vec_loop(mut v: Vec<i32>) -> Vec<i32> {
    for i in v.iter_mut() {
        // TODO: Fill this up so that each element in the Vec `v` is
        // multiplied by 2.
        *i = *i * 2;
    }

    // At this point, `v` should be equal to [4, 8, 12, 16, 20].
    v
}

fn vec_map(v: &Vec<i32>) -> Vec<i32> {
    v.iter().map(|num| {
        // TODO: Do the same thing as above - but instead of mutating the
        // Vec, you can just return the new number!
        num * 2
    }).collect()
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_vec_loop() {
        let v: Vec<i32> = (1..).filter(|x| x % 2 == 0).take(5).collect();
        let ans = vec_loop(v.clone());

        assert_eq!(ans, v.iter().map(|x| x * 2).collect::<Vec<i32>>());
    }

    #[test]
    fn test_vec_map() {
        let v: Vec<i32> = (1..).filter(|x| x % 2 == 0).take(5).collect();
        let ans = vec_map(&v);

        assert_eq!(ans, v.iter().map(|x| x * 2).collect::<Vec<i32>>());
    }
}

5 References

5.1 Ownership

fn main() {
    let vec0 = Vec::new();

    let mut vec1 = fill_vec(vec0);
    //ERROR below
    // Do not change the following line!
    println!("{} has length {} content `{:?}`", "vec0", vec0.len(), vec0);

    vec1.push(88);

    println!("{} has length {} content `{:?}`", "vec1", vec1.len(), vec1);
}

fn fill_vec(vec: Vec<i32>) -> Vec<i32> {
    let mut vec = vec;

    vec.push(22);
    vec.push(44);
    vec.push(66);

    vec
}
#numbers and characters are trivial literals that do get copied
let mut a = 5;
let mut b = a;
println!("{}",a); #5
  • vectors, strings, etc are non-trivial objects that do not get copied but moved
  • Rust is pass-by-destructive_move compared to C++ pass-by-value which copies a value into the function.
    • destructive_move from a “everything is a pointer perspective” is copying content of the pointer then NULLING the content of the older pointer.
    • visually a rust assignment is 2 arrows pointing to the same object, but then erasing the older arrow.
  • Rust pass-by-reference from a “everything is a pointer perspective” is taking the address of the pointer, meaning we are taking the pointer itself.
    In rust they call this borrowing AKA we are borrowing the pointer.
struct A;

fn move_to(x: A) {

}//Rust auto Drops a here

fn test() {
    let a = A; //`a` is a pointer to 0x123 = addr(A)
    move_to(a); // function parameter `x` is now the pointer to 0x123 = addr(A)
                // `a` is now not a pointer to 0x123 = addr(A)
    let c = a; // error, `a` does not point to anything anymore
}
//example in C
int A = 9;
int *a;
a = &A;    //let a = A; in rust
int *x;
x = a;     //move_to(a); in rust
a = NULL;
let s = vec!["udon".to_string(), "ramen".to_string(), "soba".to_string()];

let t = s;

6 Struct

In rust a tuple is a struct. Below we have a struct, tuple and unit type.

struct ColorClassicStruct {
    // TODO: Something goes here
    red : i32 ,
    green : i32,
    blue : i32,
}

struct ColorTupleStruct(i32,i32,i32);

struct UnitLikeStruct;

// TODO: Instantiate a classic c struct!
let green = ColorClassicStruct{red: 0, green: 255, blue: 0};
// TODO: Instantiate a tuple struct!
let green = ColorTupleStruct(0,255,0);
// TODO: Instantiate a unit-like struct!
let unit_like_struct = UnitLikeStruct;

Comments below show how the enum constructors would be defined as an inductive type in lean or coq.

enum Message {
    Echo(String), //Echo :: String -> Message
    Move {x: i32, y:i32}, // Move :: Struct{i32,i32} -> Message
    ChangeColor(i32,i32,i32), // ChangeColor :: Tuple(i32,i32,i32) -> Message
    Quit, // Quit :: Message
}

match Message{
    Message::Echo(p) => ...,
    Message::Move(s) => ...,
    Message::ChangeColor(a,b,c) =>...,
    Message::Quit => ...,
}

7 Strings

8 Hashmap,Dict

2 ways to insert items into hashmap if item doesnt exist.

//method 1
if basket.get(&fruit) == None {
        basket.insert(fruit,11);
}
//method2
basket.entry(fruit).or_insert(0); //init if does not exist
basket.entry(fruit) += 11; //then modify

9 Error

10 Typescript

let message : any = "Hello World";
let messageA = "Hello World"; //same
//var message in vanilla JS

console.log(message);

//string type
let StringA : string;
StringA = "hello";
//number type
let numA : number;
numA = 4;
//boolean type
let boolA : boolean;
boolA = false;

//list functor
let arrStr : string[] = ['a','b','c'];
arrStr[0] = 'e';
arrStr.push('e');

//Coproduct
let coproductA : string | number;
coproductA = 4;
console.log(coproductA);
coproductA = "hi";
console.log(coproductA);

//list functor applied to coproduct
let listcoproduct : (string | number)[] = [1,"a",3];
console.log(listcoproduct);

//Product type
let dog = {
    name: "fido",
    age: 10
}
console.log(dog);

//type alias
type AnotherType = string | number;
let SomeObj : AnotherType;
SomeObj = 3;
SomeObj = "a";

//function
let mult = (x:number, y:number):number =>{
    return x * y;
}
console.log(mult(2,4));

let sum: (x:number, y:number) => number; //predeclare type

sum = (p:number,q: number) => {
    return p + q;
}
console.log(sum(2,4));

//generics or templates in C++
let somethn= <T>(x : T): T[] => {
    return [x,x];
}
console.log(somethn<string>("somethn"));
//another form
function somethn2<T>(x : T) : T[] {
    return [x,x];
}
console.log(somethn2<string>("somethn2"))

//Unit type function
const hey = () => {
    console.log("hey");
}
//Interface
interface CarInterface {
    model: string;
    year: number;
}

let somecar: CarInterface = {
    model : "Honda",
    year : 1996
}
//Class
class electricCar implements CarInterface {
    model : string;
    year : number;
    private msg : string;
    constructor(x: string, y : number, z : string){
        this.model = x;
        this.year = y; 
        this.msg = z;
    }
    outp = ():string => {
        return this.msg;
    }
}

let tesla = new electricCar("model E",2012,"Honk Honk")
console.log(tesla.outp());

//Typescript with HTML
//---------------------------------------------------------------------------mini project [START]
//hook html inputform to javascript, ! tells compiler it will not be empty
const inputform = document.querySelector('form')!;
console.log(inputform);

//get textbox text by the id
const modelxinput = document.querySelector('#modelid') as HTMLInputElement;
console.log(modelxinput); //<input type="text" name="modelx" id="modelid">
console.log(modelxinput.value); //outputs the textbox text

//change innerHTML of "someclass" class which is inside <div>
const someclassA = document.querySelector('.someclass') as HTMLDivElement;

inputform.addEventListener("submit", (msg) => {
    msg.preventDefault();
    someclassA.innerText = modelxinput.value;
    inputform.reset();
})

//---------------------------------------------------------------------------mini project [END]