Rosetta 1
Posted on September 2, 2022
Tags: codeetc
1 OOP
- Plain JS classes only allow
extends
with concrete classes - Plain JS do not have interfaces nor abstract classes/methods
- C only has structs, not classes
2 Basics
: any = 5
let bleh : string = "hello"
let msg : number = 2
let two : bool = false
let flag : string[] = ["bob","rex","luke"]
let kids : (string | number) = 6
let coproduct : (string | number)[] = [4,"hi",6,"no"]
let listCoproduct
= {
interface BlogEntry : number;
id: string;
content
}
function somethn <Type>(x : Type) : Type[] {
,x];
return [x
}
= <T,>(x: T) : T => {
const hi ;
return x }
- We intentionally add a comma after T, in
<T,>(x: T)
otherwise it will conflict with jsx dom tags.
var bleh any
= 2
bleh := 3
blehX var s string = "hello"
- Variables in rust are by default
const
in C
let mut hah : i32 = 99;
= 43;
hah const bleh: string = "Ha";
let AHH: char = 'h';
let mut v : Vec<i32>= vec![10,20,30,40];
println!("Hello {}!","hi");
#destructuringlet 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) {
- 10 #w/o semi-colon
price - 10; #w/ semi-colon
#return price } else {
- 3
price }
}
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> {
.iter().map(|num| {
v// TODO: Do the same thing as above - but instead of mutating the
// Vec, you can just return the new number!
* 2
num }).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
- init Pointers in rust using
let & a : i32;
- deref pointer in rust using
*a
- deref pointer in rust using
- init Pointers in C using
int* a; * deref pointer in C using
*a`
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);
.push(88);
vec1
println!("{} has length {} content `{:?}`", "vec1", vec1.len(), vec1);
}
fn fill_vec(vec: Vec<i32>) -> Vec<i32> {
let mut vec = vec;
.push(22);
vec.push(44);
vec.push(66);
vec
vec}
do get copied
#numbers and characters are trivial literals that 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)
; // function parameter `x` is now the pointer to 0x123 = addr(A)
move_to(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; //let a = A; in rust
a int *x;
= a; //move_to(a); in rust
x = NULL; a
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
: i32 ,
red : i32,
green : i32,
blue }
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 {
String), //Echo :: String -> Message
Echo({x: i32, y:i32}, // Move :: Struct{i32,i32} -> Message
Move i32,i32,i32), // ChangeColor :: Tuple(i32,i32,i32) -> Message
ChangeColor(, // Quit :: Message
Quit}
match Message{
Message::Echo(p) => ...,
Message::Move(s) => ...,
Message::ChangeColor(a,b,c) =>...,
Message::Quit => ...,
}
7 Strings
- Rust
String
vs&str
- Rust
&str
is like C*char
- Rust
String
is like Cstd::string
8 Hashmap,Dict
2 ways to insert items into hashmap if item doesnt exist.
//method 1
if basket.get(&fruit) == None {
.insert(fruit,11);
basket}
//method2
.entry(fruit).or_insert(0); //init if does not exist
basket.entry(fruit) += 11; //then modify basket
9 Error
- Rust uses
Result<S,T>
types for error handling
10 Typescript
: any = "Hello World";
let message = "Hello World"; //same
let messageA //var message in vanilla JS
console.log(message);
//string type
: string;
let StringA = "hello";
StringA //number type
: number;
let numA = 4;
numA //boolean type
: boolean;
let boolA = false;
boolA
//list functor
: string[] = ['a','b','c'];
let arrStr 0] = 'e';
arrStr[.push('e');
arrStr
//Coproduct
: string | number;
let coproductA = 4;
coproductA console.log(coproductA);
= "hi";
coproductA console.log(coproductA);
//list functor applied to coproduct
: (string | number)[] = [1,"a",3];
let listcoproduct console.log(listcoproduct);
//Product type
= {
let dog : "fido",
name: 10
age
}console.log(dog);
//type alias
type AnotherType = string | number;
: AnotherType;
let SomeObj = 3;
SomeObj = "a";
SomeObj
//function
= (x:number, y:number):number =>{
let mult * y;
return x
}console.log(mult(2,4));
: (x:number, y:number) => number; //predeclare type
let sum
= (p:number,q: number) => {
sum + q;
return p
}console.log(sum(2,4));
//generics or templates in C++
= <T>(x : T): T[] => {
let somethn,x];
return [x
}console.log(somethn<string>("somethn"));
//another form
function somethn2<T>(x : T) : T[] {
,x];
return [x
}console.log(somethn2<string>("somethn2"))
//Unit type function
= () => {
const hey console.log("hey");
}//Interface
interface CarInterface {: string;
model: number;
year
}
: CarInterface = {
let somecar: "Honda",
model : 1996
year
}//Class
class electricCar implements CarInterface {: string;
model : number;
year : string;
private msg constructor(x: string, y : number, z : string){
.model = x;
this.year = y;
this.msg = z;
this
}= ():string => {
outp .msg;
return this
}
}
= new electricCar("model E",2012,"Honk Honk")
let tesla console.log(tesla.outp());
//Typescript with HTML
//---------------------------------------------------------------------------mini project [START]
//hook html inputform to javascript, ! tells compiler it will not be empty
= document.querySelector('form')!;
const inputform console.log(inputform);
//get textbox text by the id
= document.querySelector('#modelid') as HTMLInputElement;
const modelxinput 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>
= document.querySelector('.someclass') as HTMLDivElement;
const someclassA
.addEventListener("submit", (msg) => {
inputform.preventDefault();
msg.innerText = modelxinput.value;
someclassA.reset();
inputform
})
//---------------------------------------------------------------------------mini project [END]