Compare commits
30 Commits
2828b36251
...
main
Author | SHA1 | Date | |
---|---|---|---|
94bba82e49 | |||
151aeb4a5d | |||
698229eb45 | |||
1bc1c95904 | |||
456cf0cc7e | |||
c712b0d122 | |||
bf0d91a268 | |||
8754d3537a | |||
37064bc265 | |||
d1531d45d9 | |||
439eca6a95 | |||
768bb71b69 | |||
baea812155 | |||
ceb94046ab | |||
69e94d5fa4 | |||
775daf2271 | |||
59dc0307b3 | |||
0420a41d3d | |||
625233299a | |||
321b6d4067 | |||
b5a0c48aee | |||
ed3e43889e | |||
923a17f7ff | |||
0dd25768c8 | |||
c09b029e90 | |||
82296adba1 | |||
4d742b6b88 | |||
a30e91976a | |||
2e97717395 | |||
ab3c6ed53a |
117
README.md
117
README.md
@ -1,31 +1,112 @@
|
|||||||
# learning-languages
|
|
||||||
|
# Learning new languages and documenting my journey
|
||||||
|
|
||||||
Repository which documents my journey in learning new languages.
|
Repository which documents my journey in learning new languages.
|
||||||
|
|
||||||
Currently learning:
|
Currently learning:
|
||||||
<p align="center">
|
|
||||||
<img src="https://raw.githubusercontent.com/devicons/devicon/master/icons/rust/rust-original.svg" alt="Rust" width="50" height="50"/>
|
<style>
|
||||||
<img src="https://raw.githubusercontent.com/devicons/devicon/master/icons/haskell/haskell-original.svg" alt="Haskell" width="50" height="50"/>
|
/* center all content within cells */
|
||||||
<img src="https://raw.githubusercontent.com/devicons/devicon/master/icons/swift/swift-original.svg" alt="Swift" width="50" height="50"/>
|
table {
|
||||||
<img src="https://dashboard.snapcraft.io/site_media/appmedia/2021/01/coq.png" alt="Coq" width="50" height="50"/>
|
width: 100%;
|
||||||
</p>
|
border-collapse: collapse;
|
||||||
|
}
|
||||||
|
|
||||||
|
th, td {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<table align="center">
|
||||||
|
<tr>
|
||||||
|
<th>Language</th>
|
||||||
|
<th>Idea</th>
|
||||||
|
<th>Category</th>
|
||||||
|
<th>Algorithmics?</th>
|
||||||
|
<th>Practical?</th>
|
||||||
|
<th>Course?</th>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><a href="https://www.rust-lang.org/">
|
||||||
|
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/2/20/Rustacean-orig-noshadow.svg/220px-Rustacean-orig-noshadow.svg.png" alt="Rust" height="50"/>
|
||||||
|
</a></td>
|
||||||
|
<td>Daily drive</td>
|
||||||
|
<td>General</td>
|
||||||
|
<td>✅</td>
|
||||||
|
<td>✅</td>
|
||||||
|
<td>❌</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td><a href="https://www.swift.org/">
|
||||||
|
<img src="https://raw.githubusercontent.com/devicons/devicon/master/icons/swift/swift-original.svg" alt="Swift" height="50"/>
|
||||||
|
</a></td>
|
||||||
|
<td>Daily drive</td>
|
||||||
|
<td>General</td>
|
||||||
|
<td>✅</td>
|
||||||
|
<td>✅</td>
|
||||||
|
<td>❌</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td><a href="https://www.haskell.org/">
|
||||||
|
<img src="https://raw.githubusercontent.com/devicons/devicon/master/icons/haskell/haskell-original.svg" alt="Haskell" height="50"/>
|
||||||
|
</a></td>
|
||||||
|
<td>Understand functional programming</td>
|
||||||
|
<td>Theory</td>
|
||||||
|
<td>✅</td>
|
||||||
|
<td>❌</td>
|
||||||
|
<td>✅</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td><a href="https://coq.inria.fr/">
|
||||||
|
<img src="https://dashboard.snapcraft.io/site_media/appmedia/2021/01/coq.png" alt="Coq" height="50"/>
|
||||||
|
</a></td>
|
||||||
|
<td>Understand formal verification</td>
|
||||||
|
<td>Theory</td>
|
||||||
|
<td>❌</td>
|
||||||
|
<td>❌</td>
|
||||||
|
<td>🤷</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td><a href="https://futhark-lang.org/">
|
||||||
|
<img src="https://hackage.haskell.org/package/futhark-0.25.28/docs/assets/ohyes.png" alt="Futhark" height="50"/>
|
||||||
|
</a></td>
|
||||||
|
<td>Understand data parallelism</td>
|
||||||
|
<td>Theory/Fun</td>
|
||||||
|
<td>❌</td>
|
||||||
|
<td>❌</td>
|
||||||
|
<td>❌</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
</table>
|
||||||
|
|
||||||
(and C++, but that is gonna happen in embedded systems, so I won't document it here)
|
(and C++, but that is gonna happen in embedded systems, so I won't document it here)
|
||||||
|
|
||||||
## Idea
|
## Idea
|
||||||
I will spend about 5 hours a week learning each language. This is **NOT** a priority, but rather a side project to keep me entertained and to learn new things.
|
I will spend about 5 hours a week learning each language. This is **NOT** a priority, but rather a side project to keep me entertained and to learn new things.
|
||||||
|
|
||||||
The main idea is to use these new languages to solve problems I would normally solve with Python. Also, as the file structure suggests, I will also do some algorithmic problems in these languages.
|
The main idea is to use these new languages to solve relevant problems!
|
||||||
|
|
||||||
READMEs will be present in each practical folder, where I will document my thought process and the things I learned.
|
## Structure
|
||||||
|
```
|
||||||
|
.
|
||||||
|
├── language
|
||||||
|
│ ├── sessions -- if I am doing a course or something
|
||||||
|
│ │ ├── 13_03 -- date (dd_mm)
|
||||||
|
│ │ │ ├── notes.md
|
||||||
|
│ │ │ └── exercises/ -- if I have any
|
||||||
|
│ |-- algorithmic -- if I am doing algorithmic problems
|
||||||
|
| |-- practical -- if I decide to do something practical (usually documentation and a submodule of the main repo)
|
||||||
|
│ |-- README.md -- main README
|
||||||
|
```
|
||||||
|
|
||||||
A larger, more detailed README will be present in the root of each language folder, where I will document the resources I used and the things I learned.
|
## Writeups
|
||||||
|
Sometimes, I find some question and/or topic so interesting, that I decide to write a blog post about it.
|
||||||
|
Check out the `writeups` folder for more information.
|
||||||
|
|
||||||
## Books and resources
|
> [!NOTE]
|
||||||
- [The rust book](https://doc.rust-lang.org/book/)
|
> Once a writeup is finished, I will remove it from the folder and [post it here](https://confest.im).
|
||||||
- [Haskell Programming from first principles](http://haskellbook.com/)
|
|
||||||
- [Learn you a Haskell for great good](http://learnyouahaskell.com/)
|
|
||||||
- [Swift documentation](https://docs.swift.org/swift-book/documentation/the-swift-programming-language/)
|
|
||||||
|
|
||||||
## End goal
|
|
||||||
Achieve a somewhat adequate level of proficiency in these languages. I don't expect to be an expert, but I want to be able to write code in these languages without having to look up every single thing.
|
|
@ -1,8 +1,8 @@
|
|||||||
<p align = "center">
|
<p align = "center">
|
||||||
<img src = "https://upload.wikimedia.org/wikipedia/commons/d/d8/Coq_logo.png" width = "100">
|
<img src = "https://calebstanford.com/img/2018/coq-vector-logo/coq-logo-large.png" width = "200">
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
# Learn Coq with me
|
# Introduction
|
||||||
<a href = "https://github.com/alhassy/CoqCheatSheet/blob/master/CheatSheet.pdf">
|
<a href = "https://github.com/alhassy/CoqCheatSheet/blob/master/CheatSheet.pdf">
|
||||||
<img src = "https://img.shields.io/badge/-CheatSheet-blue">
|
<img src = "https://img.shields.io/badge/-CheatSheet-blue">
|
||||||
</a>
|
</a>
|
||||||
@ -18,12 +18,12 @@ When I feel confident enough, I will film a 1-2h tutorial on Coq and attach it t
|
|||||||
<!-- - [Software Foundations](https://softwarefoundations.cis.upenn.edu/current/index.html) by Benjamin C. Pierce et al. -->
|
<!-- - [Software Foundations](https://softwarefoundations.cis.upenn.edu/current/index.html) by Benjamin C. Pierce et al. -->
|
||||||
|
|
||||||
## ToC
|
## ToC
|
||||||
- [Learn Coq with me](#learn-coq-with-me)
|
- [Introduction](#introduction)
|
||||||
- [ToC](#toc)
|
- [ToC](#toc)
|
||||||
- [Motivation](#motivation)
|
- [Motivation](#motivation)
|
||||||
- [Installation](#installation)
|
- [Installation](#installation)
|
||||||
- [Basic Coq](#basic-coq)
|
- [Basic Coq](#basic-coq)
|
||||||
- [Introduction](#introduction)
|
- [Introduction](#introduction-1)
|
||||||
- [Comment on semantics](#comment-on-semantics)
|
- [Comment on semantics](#comment-on-semantics)
|
||||||
- [Type theory](#type-theory)
|
- [Type theory](#type-theory)
|
||||||
- [Basic Concepts + Syntax](#basic-concepts--syntax)
|
- [Basic Concepts + Syntax](#basic-concepts--syntax)
|
||||||
|
3
futhark/readme.md
Normal file
3
futhark/readme.md
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
<p align = "center">
|
||||||
|
<img src="https://hackage.haskell.org/package/futhark-0.25.28/docs/assets/ohyes.png" alt="Futhark" width="200"/>
|
||||||
|
</p>
|
77
haskell/README.md
Normal file
77
haskell/README.md
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
<p align = "center">
|
||||||
|
<img src="https://raw.githubusercontent.com/devicons/devicon/master/icons/haskell/haskell-original.svg" alt="Haskell" width="200"/>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
# Introduction
|
||||||
|
After miserably failing my Functional Programming exam and some soul searching, I realized that I never really learned Haskell nor did I ever really understand functional programming. So, I decided to learn Haskell properly. This repository will document my journey in learning Haskell.
|
||||||
|
|
||||||
|
With the help of some friends!
|
||||||
|
|
||||||
|
This is going to be structured in a different way than my other repositories. I will have a `sessions` folder where I will document my thought process and the things I learned while during my "lessons". Maybe do Haskell notebooks? I don't know yet.
|
||||||
|
|
||||||
|
This is the larger, more general README, which will house the main takeaways/revelations of the sessions.
|
||||||
|
|
||||||
|
## ToC
|
||||||
|
- [Introduction](#introduction)
|
||||||
|
- [ToC](#toc)
|
||||||
|
- [Books and resources](#books-and-resources)
|
||||||
|
- [13th of March - Introduction](#13th-of-march---introduction)
|
||||||
|
- [\[16th of March - Deriving types\]](#16th-of-march---deriving-types)
|
||||||
|
|
||||||
|
# Books and resources
|
||||||
|
- [Haskell Programming from first principles](http://haskellbook.com/)
|
||||||
|
- [Learn you a Haskell for great good](http://learnyouahaskell.com/)
|
||||||
|
|
||||||
|
|
||||||
|
## [13th of March - Introduction](sessions/13_03/notes.md)
|
||||||
|
|
||||||
|
Big question:
|
||||||
|
|
||||||
|
> Why is the singly-linked list the most common data structure in functional programming?
|
||||||
|
|
||||||
|
Because it is the simplest recursive data structure. It is a recursive data structure because it is defined in terms of itself. It is a singly-linked list because it has a head and a tail. The head is the first element of the list and the tail is the rest of the list.
|
||||||
|
|
||||||
|
<p align="center">
|
||||||
|
<img src="assets/list.png" alt="lists" width="700"/>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
> But why not a tree?
|
||||||
|
|
||||||
|
The tree is simply too complex. Linked lists are easy.
|
||||||
|
|
||||||
|
## [16th of March - Deriving types]
|
||||||
|
|
||||||
|
> How does one do this systematically?
|
||||||
|
**Eyeball method:**
|
||||||
|
Looking at the function definition:
|
||||||
|
|
||||||
|
1. Each parameter - what is the type of each parameter?
|
||||||
|
2. Return type - what is the type of the return value?
|
||||||
|
3. If the function calls another function, look at the type of that function.
|
||||||
|
4. Replace concrete types with type variables (a, b, c, etc.)
|
||||||
|
|
||||||
|
**Formal method[^2]:**
|
||||||
|
(on paper)
|
||||||
|
|
||||||
|
1. Write down the type of each argument and subexpression.
|
||||||
|
2. Generate equations for how types relate to each other and apply transitivity (if needed).
|
||||||
|
e.g.
|
||||||
|
$$
|
||||||
|
\begin{align*}
|
||||||
|
f &:: a \to b \to c \\
|
||||||
|
g &:: c \to e \\
|
||||||
|
|
||||||
|
\implies f \circ g &:: a \to b \to e
|
||||||
|
\end{align*}
|
||||||
|
$$
|
||||||
|
3. Solve the equations for the most general type.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
> Lazy and singly-linked lists, what's the relation?
|
||||||
|
A lazy list doesn’t compute all elements at once; it only computes elements as you need them.
|
||||||
|
A singly-linked list is naturally great for lazy, because each element points to the next, with the next being a thunk (actual fucking term, meaning a computation that hasn't been evaluated yet[^1]).
|
||||||
|
|
||||||
|
|
||||||
|
[^1]: More generally, a thunk is a subroutine used to inject computation into another subroutine. They delay computation until it is needed. It canonically originates from the verb *think* lmao.
|
||||||
|
[^2]: [Hindley–Milner type inference](https://en.wikipedia.org/wiki/Hindley%E2%80%93Milner_type_system)
|
BIN
haskell/assets/list.png
Normal file
BIN
haskell/assets/list.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 176 KiB |
BIN
haskell/scratch/Monadic
Executable file
BIN
haskell/scratch/Monadic
Executable file
Binary file not shown.
BIN
haskell/scratch/Monadic.hi
Normal file
BIN
haskell/scratch/Monadic.hi
Normal file
Binary file not shown.
90
haskell/scratch/Monadic.hs
Normal file
90
haskell/scratch/Monadic.hs
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
-- We want to take a list of divisors and a number
|
||||||
|
-- We traverse the list of divisors and check if the number is divisible by the divisor
|
||||||
|
-- If the number is divisible by the return the number divided by the divisor
|
||||||
|
-- If the number is not divisible repeatedly increment the number by 1 until it is divisible by the divisor
|
||||||
|
-- If the divisor is 0, throw an error
|
||||||
|
data MyMonad a = DivByZeroError String | NotDivisible Int | Divisible a deriving (Show)
|
||||||
|
|
||||||
|
-- This is where we define fmap (i.e. map but for monads)
|
||||||
|
-- Essentially, this is where we define what happens when we apply a function to a monad
|
||||||
|
-- i.e.:
|
||||||
|
-- fmap (+1) (Divisible 3) => Divisible 4
|
||||||
|
-- fmap (+1) (NotDivisible 3) => NotDivisible 3
|
||||||
|
-- fmap (+1) (DivByZeroError "error") => DivByZeroError "error"
|
||||||
|
instance Functor MyMonad where
|
||||||
|
fmap f (DivByZeroError s) = DivByZeroError s -- Note the error
|
||||||
|
fmap f (Divisible a) = Divisible (f a) -- Apply the function f to the value a
|
||||||
|
fmap f (NotDivisible a) = NotDivisible a -- Not divisible, propagate the value forward
|
||||||
|
|
||||||
|
-- This is where we define <*> (i.e. apply but for monads) essentially applying the
|
||||||
|
-- "wrapped" function to the "wrapped" value
|
||||||
|
-- i.e.:
|
||||||
|
-- (Divisible (+1)) <*> (Divisible 3) => Divisible 4
|
||||||
|
-- (Divisible (+1)) <*> (NotDivisible 3) => NotDivisible 3
|
||||||
|
-- (Divisible (+1)) <*> (DivByZeroError "error") => DivByZeroError "error"
|
||||||
|
instance Applicative MyMonad where
|
||||||
|
(DivByZeroError s) <*> _ = DivByZeroError s -- Note the error
|
||||||
|
(Divisible a) <*> b = fmap a b -- Apply the function a to the value b
|
||||||
|
(NotDivisible a) <*> b = NotDivisible a -- Not divisible, propagate the value forward
|
||||||
|
pure = Divisible -- Wrap the value in the Divisible constructor
|
||||||
|
|
||||||
|
-- This is where we define >>=, the bind operator, which chains monadic operations
|
||||||
|
-- i.e. in this case, we chain:
|
||||||
|
-- tryDivide 2 420 >>= tryDivide 3 >>= tryDivide 5 >>= tryDivide 9 >>= tryDivide 0
|
||||||
|
-- If we encounter a DivByZeroError, we propagate it forward (i.e. we don't do anything)
|
||||||
|
-- If we encounter a NotDivisible, we propagate it forward
|
||||||
|
-- If we encounter a Divisible, we apply the function f to the value x
|
||||||
|
instance Monad MyMonad where
|
||||||
|
DivByZeroError msg >>= _ = DivByZeroError msg -- if we encounter a DivByZeroError, we propagate it forward
|
||||||
|
NotDivisible n >>= _ = NotDivisible n -- if we encounter a NotDivisible, we propagate it forward
|
||||||
|
Divisible x >>= f = f x -- if we encounter a Divisible, we apply the function f to the value x
|
||||||
|
|
||||||
|
|
||||||
|
-- Try to divide the number n by d
|
||||||
|
tryDivide :: Int -> Int -> MyMonad Int
|
||||||
|
tryDivide 0 _ = DivByZeroError "Division by zero"
|
||||||
|
tryDivide d n
|
||||||
|
| n `mod` d == 0 = Divisible (n `div` d)
|
||||||
|
| otherwise = NotDivisible n
|
||||||
|
|
||||||
|
-- Sequentially divide the number n by the divisors in the list
|
||||||
|
sequentialDividing :: [Int] -> Int -> MyMonad Int
|
||||||
|
sequentialDividing [] n = return n
|
||||||
|
sequentialDividing (d:ds) n = do
|
||||||
|
newN <- tryDivide d n -- Note how we're not doing any pattern matching here, we're just applying the function, and the monad takes care of the rest
|
||||||
|
sequentialDividing ds newN
|
||||||
|
|
||||||
|
main :: IO ()
|
||||||
|
main = do
|
||||||
|
let divisors = [2, 3, 5, 9, 0]
|
||||||
|
let number = 420
|
||||||
|
-- 420/2 = 210
|
||||||
|
-- 210/3 = 70
|
||||||
|
-- 70/5 = 14
|
||||||
|
-- 14/9 not good => 14 is returned
|
||||||
|
print $ sequentialDividing divisors number
|
||||||
|
|
||||||
|
let divisors2 = [2, 3, 5, 7, 0]
|
||||||
|
let number2 = 420
|
||||||
|
-- 420/2 = 210
|
||||||
|
-- 210/3 = 70
|
||||||
|
-- 70/5 = 14
|
||||||
|
-- 14/7 = 2
|
||||||
|
-- 2/0 not good => error
|
||||||
|
|
||||||
|
print $ sequentialDividing divisors2 number2
|
||||||
|
|
||||||
|
|
||||||
|
let divisors3 = [2, 3, 5, 7, 2]
|
||||||
|
let number3 = 420
|
||||||
|
-- 420/2 = 210
|
||||||
|
-- 210/3 = 70
|
||||||
|
-- 70/5 = 14
|
||||||
|
-- 14/7 = 2
|
||||||
|
-- 2/2 = 1, all good => 1 is returned
|
||||||
|
print $ sequentialDividing divisors3 number3
|
||||||
|
|
||||||
|
-- [Divisible 210,Divisible 140,Divisible 84,NotDivisible 420,DivByZeroError "Division by zero"]
|
||||||
|
-- 420 is divisible by: [2,3,5]
|
||||||
|
|
||||||
|
-- Wtf is the point of a monad here?
|
BIN
haskell/scratch/Monadic.o
Normal file
BIN
haskell/scratch/Monadic.o
Normal file
Binary file not shown.
66
haskell/scratch/monadDumb.hs
Normal file
66
haskell/scratch/monadDumb.hs
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
-- error handling with a custom monad
|
||||||
|
-- say we want to divide a list of numbers by a divisor
|
||||||
|
-- if the divisor is even, we throw an error, then apply ^2 to the rest of the numbers
|
||||||
|
-- if the divisor is odd, we return the result
|
||||||
|
-- if the divisor is 0, we throw an error
|
||||||
|
|
||||||
|
-- custom monad
|
||||||
|
data MyMonad a = DivByZeroError String | DivByEven a | DivByOdd a deriving (Show)
|
||||||
|
|
||||||
|
-- instance of Functor
|
||||||
|
instance Functor MyMonad where -- Functor is where we define fmap (i.e. map)
|
||||||
|
-- customMap, where we have 2 functions, one for even and one for odd
|
||||||
|
fmap f (DivByZeroError s) = DivByZeroError s
|
||||||
|
fmap f (DivByEven a) = DivByEven (f a)
|
||||||
|
fmap f (DivByOdd a) = DivByOdd (f a)
|
||||||
|
|
||||||
|
-- instance of Applicative
|
||||||
|
instance Applicative MyMonad where
|
||||||
|
(DivByZeroError s) <*> _ = DivByZeroError s
|
||||||
|
-- DivByEvenError -> ^2
|
||||||
|
(DivByEven a) <*> b = fmap a b --
|
||||||
|
(DivByOdd a) <*> b = fmap a b
|
||||||
|
pure = DivByOdd
|
||||||
|
|
||||||
|
-- instance of Monad
|
||||||
|
instance Monad MyMonad where
|
||||||
|
return = pure
|
||||||
|
(DivByZeroError s) >>= _ = DivByZeroError s
|
||||||
|
(DivByEven a) >>= f =
|
||||||
|
case f a of
|
||||||
|
DivByOdd b -> DivByEven b -- propagate the "evenness context" forward
|
||||||
|
DivByEven b -> DivByEven b -- keep even state if it continues
|
||||||
|
DivByZeroError s -> DivByZeroError s
|
||||||
|
(DivByOdd a) >>= f = f a
|
||||||
|
|
||||||
|
safeDivide :: Int -> [Int] -> MyMonad [Int]
|
||||||
|
safeDivide 0 _ = DivByZeroError "Division by zero"
|
||||||
|
safeDivide d xs
|
||||||
|
| even d = DivByEven (map (^2) xs)
|
||||||
|
| otherwise = DivByOdd (map (`div` d) xs)
|
||||||
|
|
||||||
|
main :: IO ()
|
||||||
|
main = do
|
||||||
|
let nums = [69, 420, 666, 1337]
|
||||||
|
let divisor = 2
|
||||||
|
let result = safeDivide divisor nums
|
||||||
|
|
||||||
|
let nums2 = [1,2,3,4,5]
|
||||||
|
let divisor2 = 0
|
||||||
|
let result2 = safeDivide divisor2 nums2
|
||||||
|
|
||||||
|
let nums3 = [69, 420, 666, 1337]
|
||||||
|
let divisor3 = 3
|
||||||
|
let result3 = safeDivide divisor3 nums3
|
||||||
|
|
||||||
|
print result
|
||||||
|
print result2
|
||||||
|
print result3
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
BIN
haskell/sessions/13_03/folds.png
Normal file
BIN
haskell/sessions/13_03/folds.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 127 KiB |
132
haskell/sessions/13_03/notes.md
Normal file
132
haskell/sessions/13_03/notes.md
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
|
||||||
|
## Progress report - confidence scale
|
||||||
|
In the first meeting, we went through the structure of my exam on a very surface level.
|
||||||
|
I reached the conclusion that, although I have a vague idea of what the topics are, I don't have a deep understanding of them. All of my knowledge is very superficial.
|
||||||
|
|
||||||
|
Hence, this progress report will be a preamble of each session, where I will list the topics and the corresponding confidence I have in them.
|
||||||
|
|
||||||
|
The scale of my confidence in the topics:
|
||||||
|
1. 😎 - Very confident
|
||||||
|
2. 😊 - Confident
|
||||||
|
3. 😐 - Can solve, no intuition
|
||||||
|
4. 😕 - No idea
|
||||||
|
|
||||||
|
| Topic | Description | Confidence |
|
||||||
|
|-------|-------------|------------|
|
||||||
|
| Signatures | Checking whether the expression types are correct | 😊 |
|
||||||
|
| Programming | Writing code to solve an algorithmic problem | 😐 |
|
||||||
|
| Higher order functions | Demonstrate understanding of higher order functions, usually by chaining them | 😐 |
|
||||||
|
| List comprehensions | Demonstrate understanding of list comprehensions | 😐 |
|
||||||
|
| Recursion/infinite lists | Infinitely generating lists, usually by recursion and/or list comprehensions | 😕 |
|
||||||
|
| ADTs | Algebraic Data Types, usually defining a data type and writing functions that operate on it | 😕 |
|
||||||
|
| Proof on lists | Proving properties of functions that operate on lists | 😕 |
|
||||||
|
| Proof on trees/ADTs | Proving properties of functions that operate on trees or ADTs | 😕 |
|
||||||
|
|
||||||
|
## Basics
|
||||||
|
|
||||||
|
### Signatures
|
||||||
|
|
||||||
|
Example given - the `.` operator a.k.a. $f \circ g = f(g(x))$
|
||||||
|
|
||||||
|
```haskell
|
||||||
|
(.) :: (b -> c) -> (a -> b) -> a -> c
|
||||||
|
f . g = \x -> f (g x)
|
||||||
|
```
|
||||||
|
Why? Because the type of `f` is `b -> c`, the type of `g` is `a -> b`, and the type of `x` is `a`. Hence, the type of the output is `c`.
|
||||||
|
|
||||||
|
|
||||||
|
### Stack and heap
|
||||||
|
**What's the stack?**
|
||||||
|
> The stack is a data structure that stores information about the active subroutines of a computer program. It is used to store the return address of the function, the local variables of the function, and the parameters passed to the function.
|
||||||
|
> This is like CPU registers, but for functions.
|
||||||
|
|
||||||
|
**What's the heap?**
|
||||||
|
> The heap is a region of memory that is not managed automatically for you. This is a large pool of memory from which you can request blocks of memory.
|
||||||
|
> This is like the RAM of the computer.
|
||||||
|
|
||||||
|
**What's the difference between the stack and the heap?**
|
||||||
|
> The stack is used for static memory allocation and the heap is used for dynamic memory allocation, both stored in the computer's RAM.
|
||||||
|
i.e. in C:
|
||||||
|
```c
|
||||||
|
int main() {
|
||||||
|
int x = 5; // Stack
|
||||||
|
int* y = malloc(sizeof(int)); // Heap
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**What's the difference between the stack and the heap in Haskell?**
|
||||||
|
> In Haskell, the stack is used for function calls and the heap is used for storing data.
|
||||||
|
> This is because Haskell is a lazy language, so it doesn't evaluate the function calls immediately. Instead, it stores them in the stack and evaluates them when needed.
|
||||||
|
> The heap is used for storing data because Haskell is a functional language, so it doesn't have mutable variables. Hence, it stores the data in the heap.
|
||||||
|
> This is why Haskell is a pure language.
|
||||||
|
|
||||||
|
|
||||||
|
### Recursion
|
||||||
|
|
||||||
|
Recursion in Haskell is very similar to recursion in other languages. The only difference is that Haskell is a lazy language, so it doesn't evaluate the recursion immediately. Instead, it stores the recursion in the stack and evaluates it when needed.
|
||||||
|
|
||||||
|
Tail recursion is a special case of recursion where the recursive call is the last thing in the function.
|
||||||
|
|
||||||
|
Example of non-tail recursion:
|
||||||
|
```haskell
|
||||||
|
fib :: Int -> Int
|
||||||
|
fib 0 = 0
|
||||||
|
fib 1 = 1
|
||||||
|
fib n = fib (n-1) + fib (n-2)
|
||||||
|
```
|
||||||
|
|
||||||
|
To make the `fib` function tail recursive, we can use an accumulator[^1]
|
||||||
|
```haskell
|
||||||
|
fib :: Int -> Int
|
||||||
|
fib n = go n 0 1
|
||||||
|
where
|
||||||
|
go 0 a b = a
|
||||||
|
go n a b = go (n-1) b (a+b)
|
||||||
|
```
|
||||||
|
|
||||||
|
### `map, foldr, foldl, filter, zip`
|
||||||
|
|
||||||
|
These are higher order functions in Haskell. They are used to operate on lists.
|
||||||
|
|
||||||
|
`map` applies a function to each element of a list.
|
||||||
|
```haskell
|
||||||
|
map :: (a -> b) -> [a] -> [b]
|
||||||
|
map f [] = []
|
||||||
|
map f (x:xs) = f x : map f xs
|
||||||
|
```
|
||||||
|
|
||||||
|
<p align="center">
|
||||||
|
<img src="folds.png" alt="folds" width="700"/>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
`foldr` is a right fold. It is used to reduce a list to a single value.
|
||||||
|
```haskell
|
||||||
|
foldr :: (a -> b -> b) -> b -> [a] -> b
|
||||||
|
foldr f z [] = z
|
||||||
|
foldr f z (x:xs) = f x (foldr f z xs)
|
||||||
|
```
|
||||||
|
|
||||||
|
`foldl` is a left fold. It is used to reduce a list to a single value.
|
||||||
|
```haskell
|
||||||
|
foldl :: (b -> a -> b) -> b -> [a] -> b
|
||||||
|
foldl f z [] = z
|
||||||
|
foldl f z (x:xs) = foldl f (f z x) xs
|
||||||
|
```
|
||||||
|
|
||||||
|
`filter` is used to filter a list based on a predicate.
|
||||||
|
```haskell
|
||||||
|
filter :: (a -> Bool) -> [a] -> [a]
|
||||||
|
filter p [] = []
|
||||||
|
filter p (x:xs) = if p x then x : filter p xs else filter p xs
|
||||||
|
```
|
||||||
|
|
||||||
|
`zip` is used to combine two lists into a list of tuples.
|
||||||
|
```haskell
|
||||||
|
zip :: [a] -> [b] -> [(a, b)]
|
||||||
|
zip [] _ = []
|
||||||
|
zip _ [] = []
|
||||||
|
zip (x:xs) (y:ys) = (x, y) : zip xs ys
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
[^1]: This is a common pattern in functional programming. The idea is to pass an accumulator to the function and update it in each recursive call. This is to "circumvent" immutability by introducing a way to store the "state" of the function.
|
106
haskell/sessions/16_03/notes.md
Normal file
106
haskell/sessions/16_03/notes.md
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
## Table
|
||||||
|
| Topic | Description | Confidence |
|
||||||
|
|-------|-------------|------------|
|
||||||
|
| Signatures | Checking whether the expression types are correct | 😐 |
|
||||||
|
| Programming | Writing code to solve an algorithmic problem | 😐 |
|
||||||
|
| Higher order functions | Demonstrate understanding of higher order functions, usually by chaining them | 😊 |
|
||||||
|
| List comprehensions | Demonstrate understanding of list comprehensions | 😊 |
|
||||||
|
| Recursion/infinite lists | Infinitely generating lists, usually by recursion and/or list comprehensions | 😐 |
|
||||||
|
| ADTs | Algebraic Data Types, usually defining a data type and writing functions that operate on it | 😕 |
|
||||||
|
| Proof on lists | Proving properties of functions that operate on lists | 😕 |
|
||||||
|
| Proof on trees/ADTs | Proving properties of functions that operate on trees or ADTs | 😕 |
|
||||||
|
|
||||||
|
|
||||||
|
## Deducing types systematically
|
||||||
|
|
||||||
|
### (:).(:)
|
||||||
|
```hs
|
||||||
|
expr = (:) . (:)
|
||||||
|
|
||||||
|
(:) :: a -> [a] -> [a]
|
||||||
|
(.) :: (c -> d) -> (b -> c) -> b -> d
|
||||||
|
|
||||||
|
=>
|
||||||
|
|
||||||
|
a -> ([a] -> [a]) = b -> c
|
||||||
|
|
||||||
|
b = a
|
||||||
|
c = [a] -> [a]
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
a' -> [a'] -> [a'] = c -> d
|
||||||
|
a -> [a] -> [a] = b -> c
|
||||||
|
|
||||||
|
b = a
|
||||||
|
c = [a] -> [a]
|
||||||
|
|
||||||
|
a' = [a] -> [a]
|
||||||
|
[[a] -> [a]] -> [[a] -> [a]] = d
|
||||||
|
|
||||||
|
|
||||||
|
expr :: b -> d
|
||||||
|
=>
|
||||||
|
expr :: a -> [[a] -> [a]] -> [[a] -> [a]]
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### `f = \x y -> x (x (x y))` [^1]
|
||||||
|
|
||||||
|
```hs
|
||||||
|
f = \x y -> x (x (x y))
|
||||||
|
```
|
||||||
|
|
||||||
|
## Questions
|
||||||
|
> CLI is functional?
|
||||||
|
Not really. It fits the functional mindset.
|
||||||
|
Commands are:
|
||||||
|
- pure, input leads to output
|
||||||
|
- composable with the pipe, kinda like `(.)`
|
||||||
|
- They can be composed like higher order functions, i.e. one command can be the input to another command
|
||||||
|
|
||||||
|
In reality though, they are not functional. Their main goal is to interact with the system (a.k.a. a mutable state), which obviously breaks the functional paradigm.
|
||||||
|
|
||||||
|
> Y combinator?
|
||||||
|
A function, which allows us to define recursive functions without giving them a name. It gives us a fixed point of a function, i.e. a function that doesn't change when you apply it to itself.
|
||||||
|
|
||||||
|
In other words, finds a value $x$ such that $f(x) = x$.
|
||||||
|
|
||||||
|
```hs
|
||||||
|
y f = f (y f) -- this is the Y combinator
|
||||||
|
```
|
||||||
|
|
||||||
|
Example:
|
||||||
|
```hs
|
||||||
|
fact = \f n -> if n == 0 then 1 else n * f (n-1) -- n! = f(n) = n * f(n-1) = n * (n-1) * f(n-2) = ...
|
||||||
|
```
|
||||||
|
|
||||||
|
If we were to not use the Y combinator, we would have to define the function as:
|
||||||
|
```hs
|
||||||
|
fact = \n -> if n == 0 then 1 else n * fact (n-1)
|
||||||
|
```
|
||||||
|
|
||||||
|
> In which cases would it be impossible to not use the Y combinator?
|
||||||
|
Whenever we are working with a system that has no named functions, but we still want recursion.
|
||||||
|
|
||||||
|
In the context of Haskell, using the Y combinator (in the classical lambda calculus way) is elegant, yet not necessary.
|
||||||
|
Rewriting our factorial function using `where`:
|
||||||
|
|
||||||
|
```hs
|
||||||
|
fact :: Int -> Int
|
||||||
|
fact n = f n
|
||||||
|
where
|
||||||
|
f 0 = 1
|
||||||
|
f n = n * f (n-1)
|
||||||
|
```
|
||||||
|
|
||||||
|
is way more readable and intuitive.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Resources
|
||||||
|
- [course](https://www.cis.upenn.edu/~cis1940/spring15/lectures.html)
|
||||||
|
- [standard list](https://hackage.haskell.org/package/base-4.21.0.0/docs/Data-List.html)
|
||||||
|
|
||||||
|
[^1]: need to find the actual rigorous way of doing this
|
||||||
|
[^2]: Referential transparency
|
72
haskell/sessions/16_03/scratchpad/Adhoc.java
Normal file
72
haskell/sessions/16_03/scratchpad/Adhoc.java
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
// Java program to show working of user defined
|
||||||
|
// Generic classes
|
||||||
|
|
||||||
|
// We use < > to specify Parameter type
|
||||||
|
|
||||||
|
class Cat {
|
||||||
|
String breed;
|
||||||
|
String name;
|
||||||
|
boolean castrated;
|
||||||
|
|
||||||
|
Cat(String breed, String name, boolean castrated) {
|
||||||
|
this.breed = breed;
|
||||||
|
this.name = name;
|
||||||
|
this.castrated = castrated;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String makeNoise() {
|
||||||
|
return "Meow";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class Test<T> {
|
||||||
|
// An object of type T is declared
|
||||||
|
T obj;
|
||||||
|
|
||||||
|
Test(T obj) {
|
||||||
|
this.obj = obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
public T getObject() {
|
||||||
|
return this.obj;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class AdHocPolymorphic {
|
||||||
|
public String add(int x, int y) {
|
||||||
|
return "Sum: " + (x + y);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String add(String name) {
|
||||||
|
return "Added " + name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Adhoc {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
AdHocPolymorphic poly = new AdHocPolymorphic();
|
||||||
|
|
||||||
|
System.out.println(poly.add(1,2)); // prints "Sum: 3"
|
||||||
|
System.out.println(poly.add("Jay")); // prints "Added Jay"
|
||||||
|
|
||||||
|
// error the fuck out
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Driver class to test above
|
||||||
|
class Main {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
// instance of Integer type
|
||||||
|
Test<Integer> iObj = new Test<Integer>(15);
|
||||||
|
System.out.println(iObj.getObject());
|
||||||
|
|
||||||
|
// instance of String type
|
||||||
|
Test<String> sObj = new Test<String>("GeeksForGeeks");
|
||||||
|
System.out.println(sObj.getObject());
|
||||||
|
|
||||||
|
Test<Cat> cObj = new Test<Cat>(new Cat("Siamese", "Fluffy", true));
|
||||||
|
System.out.println(cObj.getObject().makeNoise());
|
||||||
|
}
|
||||||
|
}
|
BIN
haskell/sessions/16_03/scratchpad/a
Executable file
BIN
haskell/sessions/16_03/scratchpad/a
Executable file
Binary file not shown.
BIN
haskell/sessions/16_03/scratchpad/a.hi
Normal file
BIN
haskell/sessions/16_03/scratchpad/a.hi
Normal file
Binary file not shown.
62
haskell/sessions/16_03/scratchpad/a.hs
Normal file
62
haskell/sessions/16_03/scratchpad/a.hs
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
z :: Int -> Int
|
||||||
|
z a = 3 * a -- 3x3 = 9 => 3*3
|
||||||
|
|
||||||
|
y :: (Int -> Int) -> [Int] -> [Int]
|
||||||
|
-- y(\x -> 3*x) [1,2,3] -> [3,6,9]
|
||||||
|
y z lst = map z lst -- f(x) = 3x => f x = 3x
|
||||||
|
|
||||||
|
isEven :: Int -> Bool
|
||||||
|
isEven x = if x `mod` 2 == 0 then True else False
|
||||||
|
|
||||||
|
-- ~~mod(x, 2)~~ => x mod 2
|
||||||
|
-- isEven x = x `mod` 2 == 0
|
||||||
|
|
||||||
|
isAmongus :: String -> String
|
||||||
|
-- traverse each character and check if "amongus" is in the string, return the rest of the string
|
||||||
|
isAmongus [] = [] -- base case if the string is empty (or we reached the end of the string)
|
||||||
|
isAmongus (x : xs) -- recurse on the rest of the string
|
||||||
|
| (take 7 (x : xs) == "amongus") = drop 7 (x : xs)
|
||||||
|
| otherwise = isAmongus xs
|
||||||
|
|
||||||
|
b :: [Int] -> Int
|
||||||
|
b lst = sum (y z lst) -- = 18
|
||||||
|
|
||||||
|
allTogether :: [Int] -> Int
|
||||||
|
allTogether list = sum (map (3 *) list)
|
||||||
|
|
||||||
|
foo :: Integer -> Integer
|
||||||
|
foo 0 = 16
|
||||||
|
foo 1
|
||||||
|
| "Haskell" > "C++" = 3
|
||||||
|
| otherwise = 4
|
||||||
|
foo n
|
||||||
|
| n < 0 = 0
|
||||||
|
| n `mod` 17 == 2 = -43
|
||||||
|
| otherwise = n + 3
|
||||||
|
|
||||||
|
bogus :: [a] -> Bool
|
||||||
|
bogus (x:_) = True
|
||||||
|
bogus _ = False
|
||||||
|
|
||||||
|
|
||||||
|
main :: IO ()
|
||||||
|
main = do
|
||||||
|
print $ b [1, 2, 3]
|
||||||
|
putStrLn "AAAAAAAAA"
|
||||||
|
print $ allTogether [1, 2, 3]
|
||||||
|
|
||||||
|
putStrLn "Finding amongus"
|
||||||
|
print $ isAmongus "amongus"
|
||||||
|
print $ isAmongus "aaaaaaaaaaaaaa"
|
||||||
|
print $ isAmongus "askldhjewkjrhwekjrhwekjrhekjlfhbjerkshtjkernamogusejqwklwqhekqjwehqwjkamongusasdasdsad"
|
||||||
|
|
||||||
|
-- foos
|
||||||
|
print $ foo 0
|
||||||
|
|
||||||
|
print $ bogus [1,10..]
|
||||||
|
|
||||||
|
-- compose 2 functions with a dot
|
||||||
|
print $ (y z . y z) [1, 2, 3]
|
||||||
|
print $ (y z . y z . y z) [1, 2, 3]
|
||||||
|
print $ (.) (y z) (y z) [1, 2, 3]
|
||||||
|
print $ y z $ y z [1, 2, 3]
|
BIN
haskell/sessions/16_03/scratchpad/a.o
Normal file
BIN
haskell/sessions/16_03/scratchpad/a.o
Normal file
Binary file not shown.
17
haskell/sessions/23_03/notes.md
Normal file
17
haskell/sessions/23_03/notes.md
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
|
||||||
|
## Lists
|
||||||
|
|
||||||
|
```hs
|
||||||
|
------------ !! mapAccumL
|
||||||
|
mapAccumL :: (s -> a -> (s, b)) -> s -> [a] -> (s, [b])
|
||||||
|
------------
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
> Generics in C?
|
||||||
|
|
||||||
|
> Implement Haskell lists in Python
|
||||||
|
|
||||||
|
> Forall and exists in functional programming
|
||||||
|
|
||||||
|
https://hackage.haskell.org/package/base-4.3.1.0/docs/src/Data-List.html
|
28
rust/README.md
Normal file
28
rust/README.md
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
<style>
|
||||||
|
/* Invert rust logo */
|
||||||
|
#rust img {
|
||||||
|
filter: invert(1);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<p align = "center">
|
||||||
|
<span id=rust>
|
||||||
|
<img src="https://raw.githubusercontent.com/devicons/devicon/master/icons/rust/rust-original.svg" alt="Rust" width="200"/>
|
||||||
|
</span>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
# Introduction
|
||||||
|
On my journe to memory safety and due to lots of ridicule from my friends about daily-driving Python, I am currently looking for a systems programming language that is memory safe and has a good ecosystem (i.e. is not hated by everyone). In other words, I am looking for a *practically useful* language that is not Python or C++.
|
||||||
|
|
||||||
|
Rust seems to be the perfect fit for this. This repository will document my journey in learning Rust.
|
||||||
|
|
||||||
|
The process of learning this language is going to be quite different from my other repositories. I will try to design an embedded project in Rust, instead of focusing on algorithmic problems (i.e. practical problems). This will help me understand the language better and also give me a taste of what it is like to work with Rust in a real-world scenario.
|
||||||
|
|
||||||
|
I'm going to try and ***actually document*** my process instead of my usual cheat-sheet style.
|
||||||
|
|
||||||
|
## ToC
|
||||||
|
- [Introduction](#introduction)
|
||||||
|
- [ToC](#toc)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -2,6 +2,14 @@
|
|||||||
<img src="https://raw.githubusercontent.com/devicons/devicon/master/icons/swift/swift-original.svg" alt="Swift" width="250"/>
|
<img src="https://raw.githubusercontent.com/devicons/devicon/master/icons/swift/swift-original.svg" alt="Swift" width="250"/>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
# Introduction
|
||||||
|
I watched a Swift lecture by an apple guy at FOSDEM 2025. It was pretty cool. Inspired me to think about memory safety, and, needless to say, learn Swift.
|
||||||
|
|
||||||
|
|
||||||
|
## ToC
|
||||||
|
|
||||||
|
- [Introduction](#introduction)
|
||||||
|
- [ToC](#toc)
|
||||||
- [General Notes](#general-notes)
|
- [General Notes](#general-notes)
|
||||||
- [Swift project](#swift-project)
|
- [Swift project](#swift-project)
|
||||||
- [Package.swift](#packageswift)
|
- [Package.swift](#packageswift)
|
||||||
@ -27,12 +35,11 @@
|
|||||||
- [Project-specific Notes](#project-specific-notes)
|
- [Project-specific Notes](#project-specific-notes)
|
||||||
- [Most likely teammates for Software engineering](#most-likely-teammates-for-software-engineering)
|
- [Most likely teammates for Software engineering](#most-likely-teammates-for-software-engineering)
|
||||||
|
|
||||||
|
|
||||||
# General Notes
|
# General Notes
|
||||||
There are **NO** semicolons in Swift. The language is designed to be concise and readable. Very pythonic in that sense.
|
There are **NO** semicolons in Swift. The language is designed to be concise and readable. Very pythonic in that sense.
|
||||||
|
|
||||||
Swift is a statically-typed language. This means that the type of a variable is known at compile time. This is in contrast to dynamically-typed languages like Python, where the type of a variable is determined at runtime.
|
Swift is a statically-typed language. This means that the type of a variable is known at compile time. This is in contrast to dynamically-typed languages like Python, where the type of a variable is determined at runtime. It deals with memory by using Automatic Reference Counting (ARC). This means that the compiler automatically manages memory for us.
|
||||||
|
|
||||||
Swift deals with memory by using Automatic Reference Counting (ARC). This means that the compiler automatically manages memory for you. This is in contrast to languages like C and C++, where you have to manually manage memory.
|
|
||||||
|
|
||||||
Swift is a multi-paradigm language. This means that it supports multiple programming paradigms, such as object-oriented programming, functional programming, and procedural programming. We'll get into this later.
|
Swift is a multi-paradigm language. This means that it supports multiple programming paradigms, such as object-oriented programming, functional programming, and procedural programming. We'll get into this later.
|
||||||
|
|
||||||
|
21
writeups/README.md
Normal file
21
writeups/README.md
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
The most significant (prioritized) writeups that I'm working on can be seen in the footer at [confest.im](https://confest.im/blog), but this folder includes every "technical" (and related to the languages described here) writeup I am working on.
|
||||||
|
|
||||||
|
## Ideas and progress
|
||||||
|
Tables concerning the idea, the description and progress of the writeups I am working on.
|
||||||
|
Scale of progress:
|
||||||
|
1. 💡 - Idea stage
|
||||||
|
2. 🚧 - Structuring
|
||||||
|
3. ✏️ - Writing
|
||||||
|
4. ✅ - Finished
|
||||||
|
5. ❌ - Abandoned
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
| Idea | Description | Progress |
|
||||||
|
|------|-------------|----------|
|
||||||
|
| Memory safety | Understanding memory safety from the perspective of a Python developer | 🚧 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
1. The intersection of functional programming and formal verification as an amateur in both
|
||||||
|
## Miscellaneous ideas
|
Reference in New Issue
Block a user