commit 8e5d6b27ff960b76f887b905b8f87e7ea2eed2c7 Author: SowinskiBraeden Date: Tue Jan 13 09:30:23 2026 -0800 initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5dd1ae3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +*.cmo +*.cmi + diff --git a/lecture01/notes.ml b/lecture01/notes.ml new file mode 100644 index 0000000..a6b42d2 --- /dev/null +++ b/lecture01/notes.ml @@ -0,0 +1,279 @@ +(* + COMPILE = ocamlc -o outfile infile.ml + + UTOP = #use "filename.ml";; +*) + +(* + Ocaml is thankfully garbage collected + + Expressions must end with double semi colon + e.g. let name = "Bread";; + + expressions can be evaluated to a value + + ocaml is a statically typed and strongly typed language + meaning that at compile time the type of a variable will + be known. The compiler uses type inference to determine the + type of a variable that you dont need to specify; + + e.g. +*) + +(* string type *) +"Hello World";; + +(* character type *) +'A';; + +(* integer type *) +50;; + +(* floating type *) +20.3;; + +(* + OPERATIONS + + you have basic operations such as + +, -, *, /, that works with integer types + + to do these operations with floating point + numbers you need to use the following + + +., -., *., /., notice the "." after the operator + + ----------------------------------------------- + + MODULE does not use the % sign + + use "mod" e.g. + + 3 mod 2;; - : int = 1 (* evaluates to 1 *) + + ---------------------------------------------- + + NOT uses the word "not" instead of "!" e.g. + + not (1 < 2);; - : bool = false +*) + +(* + COMPARATORS + + standard and, or comparisons e.g. + + a && b, a || b + + you can use >, <, but the comparator uses a + single equal sign. e.g. + + 1. = 2.;; - : bool = false (* evaluates to false *) + + ----------------------------------------------- + + NOT EQUALS + + to check for inequality use "<>", e.g. + + 1. <> 2.;; - bool = true (* evaluates to true since 1. and 2. are not equal *) +*) + +(* + STRING CONCATONATION + + use the "^" (carrot operator) to concat strings e.g. +*) +"Braeden" ^ " " ^ "Sowinski" + +(* + FUNCTIONS + + define a function square that takes in a + parameter x and returns x * x +*) +let square x = x * x;; +square 5;; + +(* evaluates to 6 *) +let x = 1 in x + 5;; + +let add x y = x + y;; + +(* + arrows are right associative + + name : input -> input -> return type + val add : int -> int -> int = + + so this can be translated to int -> (int -> int) + + this means that every function essentially takes in 1 argument + that then returns another functoin that takes in another argument +*) + +(* valid *) +add 1 2;; + +(* valid *) +(add 1) 2;; + +(* invalid *) +(*add (1 2);;*) + +(* + Ocaml is functional and there are no loops + such as for or while, + + all variables are immutable +*) + +let x = 1;; +let x = 2;; +(* +x = 3;; (* cannot reassign, this evaluates as a comparison + therefore variables are immutable *) +*) +(* + RECURSION + + recursion is related to mathematical induction, + you typically have a proposition, e.g. P, where we + know P(1) is true, and we assume P(k) is true + where we can proove that P(k + 1) is true + + to declare a recursive function you need "rec" +*) +let rec factorial n = if n = 0 then 1 else n * factorial (n - 1);; +let r = (factorial 5);; +print_int r;; +print_endline "";; + +(* + tail-recursive + + a recursive function is tail-recursive if the recursive + call is the last thing we do, for example, factorial is not + tail-recursive, because we need to multiply n to the recursive call. + + non tail-recursive functions are bad since there is potential to bloew + through the stack. + + lets consider factorial 3 = 3 * fact 2 + = 3 * (2 * fact 1) + = 3 * (2 * (1 * fact 0)) + = 3 * (2 * 1) + = 3 * 2 + = 6 + + we can see that this is not tail recursive as we need to store a value for + each part of the iteration, we can solve this by rewriting the function a little + using an accumulator +*) +let rec fact n acc = if n = 0 then acc else fact (n - 1) (n * acc);; + +(* we can have primes, e.g. function f, and function f prime or f' *) + +let factorial' n = fact n 1;; +let r = (factorial 5);; +print_int r;; +print_endline "";; + +let factorial' = fact 1;; + +(* + consider the tail-recursive version of factorial, fact' + + the signature is fact' n acc + + fact' 1 3 = fact' 3 2 + = fact' 6 1 + = fact' 6 0 + + as you can see, the stack would not grow + + lets combine the functoins into a single one + with nesting +*) +(* final tail-recursive version *) +let fact n = + let rec fact' acc i = + if i = 0 then acc + else fact' (i * acc) (i - 1) + in + fact' 1 n;; (* automatically sets the accumulator to 1 *) + +let r = fact 5;; +print_int r;; +print_endline "";; + +(* example of a documentation comment *) + +(** [gcd a b] returns the greatest common divisor of [a] and [b] + * Requires:[a > 0] and [b > 0] + *) +let rec gcd a b = + if a mod b = 0 then b + else gcd b (a mod b);; +(* +let r = gcd 12 18;; +print_int r;; +print_endline "";; *) + +let rec fib n = + if n = 0 then 0 + else if n = 1 then 1 + else fib (n - 1) + fib (n - 2);; + +let r = fib 10;; +print_int r;; +print_endline "";; + +(* tail-recursive version *) +let rec fib n = + let rec fib' i a b = + if i = n then a + else fib' (i + 1) b (a + b) + in + fib' 0 0 1;; + +let r = fib 10;; +print_int r;; +print_endline "";; + +(* + MUTALLY-RECURSIVE FUNCTION +*) +let rec even n = + if n = 0 then true + else odd (n - 1) +and odd n = + if n = 0 then false + else even (n - 1);; + +(* + useful stuff + + float_of_int 4 + int_of_string "123" +*) + +let square_root x = + let good_enough y = abs_float (x -. y *. y) < 0.00000000001 in + let rec aux y = + if good_enough y then y + else aux (0.5 *. (y +. x /. y)) + in + aux 1.;; + +print_float (square_root 2.);; +print_endline "";; + +(* + Consider this + + create an exponential function + where it calculates e^x + + using recursion +*) diff --git a/lecture01/tinker.ml b/lecture01/tinker.ml new file mode 100644 index 0000000..4d603c4 --- /dev/null +++ b/lecture01/tinker.ml @@ -0,0 +1,41 @@ +(* + ocamlc -o tinker tinker.ml + + ^^^ compile command +*) + +(* Comments are weird *) + +(* + concat takes to paramters a and b and concats them + together while seperated by a space +*) +let concat a b = a ^ " " ^ b;; + +(* + describe maps the concat function to each element + in the list to describe the element with "eat" +*) +let describe = List.map (fun f -> concat "eat" f);; + + +let full_name = concat "Braeden" "Sowinski";; +print_endline full_name;; + +let gruit = ["apple"; "banana"; "grape"];; + +(* + takes in a list and iterates over elements + to print_endline the element +*) +let print_list_string list = + List.iter print_endline list;; + +(* + I think this acts like a main method, + creates the describe list then iterates + and passes to the print_list_string function +*) +let () = + let eating = describe gruit in + print_list_string eating;; diff --git a/tinker/exponential.ml b/tinker/exponential.ml new file mode 100644 index 0000000..99dd140 --- /dev/null +++ b/tinker/exponential.ml @@ -0,0 +1,20 @@ +let fact n = + let rec fact' acc i = + if i = 0. then acc + else fact' (i *. acc) (i -. 1.) + in + fact' 1. n;; + +let pow a b = + let rec pow' acc i = + if i = 0. then acc + else pow' (acc *. a) (i -. 1.) + in + pow' 1. b;; + +let expo n x = + let rec expo' acc i = + if i = 0. then acc + else expo' (acc +. pow x i /. fact i) (i -. 1.) + in + expo' 1. n;; diff --git a/tinker/tinker.ml b/tinker/tinker.ml new file mode 100644 index 0000000..e5bb181 --- /dev/null +++ b/tinker/tinker.ml @@ -0,0 +1,18 @@ +let pow b e = + let rec pow' acc i = + if i = 0 then acc + else pow' (acc * b) (i - 1) + in + pow' 1 e;; + +let rec root n k g = + let next = (1. /. k) *. ((k -. 1.) *. g +. n /. float_of_int (pow g (k - 1))) in + if abs(next - g) < 0.00000000001 then next + else root n k next;; + +let float_pow b e = + let rec float_pow' acc i = + if i <= 0. then acc + else float_pow' (acc *. b) (i -. 1.) + in + float_pow' 1. e;;