Metody Bezpiecznego Programowania
mgr inż. Konrad Siek <imię.nazwisko@cs.put.edu.pl>
Walcz z entropią! Umieszczaj [MBP] jako prefiks tytułu mejla!
Warunki konieczne do otrzymania zaliczenia bloku FP:
Zagadnienia z bloku FP są uwzględnione w kolokwium zaliczeniowym/egzaminie.
Programowanie Funkcyjne
PB by Evan Amos
(c) Fir0002/Flagstaffotos
$ cat > crew.csv
Name, Rank, Position, Post
James T. Kirk, Captain, Commanding Officer, USS Enterprise
Spock, Commander, Science Officer, USS Enterprise
Leonard McCoy, Lt. Commander, Chief Medical Officer, USS Enterprise
Montgomery Scott, Lt. Commander, Chief Engineer, USS Enterprise
Nyota Uhura, Lieutenant, Communications Officer, USS Enterprise
Hikaru Sulu, Lieutenant, Helmsman, USS Enterprise
Pavel Chekov, Ensign, Navigator, USS Enterprise
# MAGIC!
JAMES T. KIRK, CAPTAIN SPOCK, COMMANDER LEONARD MCCOY, LT. COMMANDER MONTGOMERY SCOTT, LT. COMMANDER NYOTA UHURA, LIEUTENANT HIKARU SULU, LIEUTENANT PAVEL CHEKOV, ENSIGN
$ cat > crew.csv
Name, Rank, Position, Post
James T. Kirk, Captain, Commanding Officer, USS Enterprise
Spock, Commander, Science Officer, USS Enterprise
Leonard McCoy, Lt. Commander, Chief Medical Officer, USS Enterprise
Montgomery Scott, Lt. Commander, Chief Engineer, USS Enterprise
Nyota Uhura, Lieutenant, Communications Officer, USS Enterprise
Hikaru Sulu, Lieutenant, Helmsman, USS Enterprise
Pavel Chekov, Ensign, Navigator, USS Enterprise
$ <crew.csv tail -n +2
James T. Kirk, Captain, Commanding Officer, USS Enterprise Spock, Commander, Science Officer, USS Enterprise Leonard McCoy, Lt. Commander, Chief Medical Officer, USS Enterprise Montgomery Scott, Lt. Commander, Chief Engineer, USS Enterprise Nyota Uhura, Lieutenant, Communications Officer, USS Enterprise Hikaru Sulu, Lieutenant, Helmsman, USS Enterprise Pavel Chekov, Ensign, Navigator, USS Enterprise
$ cat > crew.csv
Name, Rank, Position, Post
James T. Kirk, Captain, Commanding Officer, USS Enterprise
Spock, Commander, Science Officer, USS Enterprise
Leonard McCoy, Lt. Commander, Chief Medical Officer, USS Enterprise
Montgomery Scott, Lt. Commander, Chief Engineer, USS Enterprise
Nyota Uhura, Lieutenant, Communications Officer, USS Enterprise
Hikaru Sulu, Lieutenant, Helmsman, USS Enterprise
Pavel Chekov, Ensign, Navigator, USS Enterprise
$ <crew.csv tail -n +2 | cut -f 2,1 -d,
James T. Kirk, Captain Spock, Commander Leonard McCoy, Lt. Commander Montgomery Scott, Lt. Commander Nyota Uhura, Lieutenant Hikaru Sulu, Lieutenant Pavel Chekov, Ensign
$ cat > crew.csv
Name, Rank, Position, Post
James T. Kirk, Captain, Commanding Officer, USS Enterprise
Spock, Commander, Science Officer, USS Enterprise
Leonard McCoy, Lt. Commander, Chief Medical Officer, USS Enterprise
Montgomery Scott, Lt. Commander, Chief Engineer, USS Enterprise
Nyota Uhura, Lieutenant, Communications Officer, USS Enterprise
Hikaru Sulu, Lieutenant, Helmsman, USS Enterprise
Pavel Chekov, Ensign, Navigator, USS Enterprise
$ <crew.csv tail -n +2 | cut -f 2,1 -d, | tr [:lower:] [:upper:]
JAMES T. KIRK, CAPTAIN SPOCK, COMMANDER LEONARD MCCOY, LT. COMMANDER MONTGOMERY SCOTT, LT. COMMANDER NYOTA UHURA, LIEUTENANT HIKARU SULU, LIEUTENANT PAVEL CHEKOV, ENSIGN
$ cat > crew.csv
Name, Rank, Position, Post
James T. Kirk, Captain, Commanding Officer, USS Enterprise
Spock, Commander, Science Officer, USS Enterprise
Leonard McCoy, Lt. Commander, Chief Medical Officer, USS Enterprise
Montgomery Scott, Lt. Commander, Chief Engineer, USS Enterprise
Nyota Uhura, Lieutenant, Communications Officer, USS Enterprise
Hikaru Sulu, Lieutenant, Helmsman, USS Enterprise
Pavel Chekov, Ensign, Navigator, USS Enterprise
$ <crew.csv tail -n +2 | cut -f 2,1 -d, | tr [:lower:] [:upper:] | tr -s ' ' | sed 's/^ *//g'
JAMES T. KIRK, CAPTAIN SPOCK, COMMANDER LEONARD MCCOY, LT. COMMANDER MONTGOMERY SCOTT, LT. COMMANDER NYOTA UHURA, LIEUTENANT HIKARU SULU, LIEUTENANT PAVEL CHEKOV, ENSIGN
Co w tym takiego ciekawego?
(za darmo!)
<crew.csv tail -n +2 | cut -f 2,1 -d, | tr [:lower:] [:upper:] | tr -s ' ' | sed 's/^ *//g'
vs
first_line=true while IFS='' read -r line do if $first_line then first_line=false continue fi IFS=, read -ra fields <<< "$line" echo ${fields[0]^^}, ${fields[1]^^} done <crew.csv
<crew.csv tail -n +2 | cut -f 2,1 -d, | tr [:lower:] [:upper:] | tr -s ' ' | sed 's/^ *//g'
<crew.csv tail -n +2 | cut -f 2,1 -d, | tr [:lower:] [:upper:] | tr -s ' ' | sed 's/^ *//g'
<crew.csv tail -n +2 | cut -f 2,1 -d, | tr [:lower:] [:upper:] | tr -s ' ' | sed 's/^ *//g'
<crew.csv tail -n +2 | cut -f 2,1 -d, | tr [:lower:] [:upper:] | tr -s ' ' | sed 's/^ *//g'
<crew.csv tail -n +2 | cut -f 2,1 -d, | tr [:lower:] [:upper:] | tr -s ' ' | sed 's/^ *//g'
<crew.csv tail -n +2 | cut -f 2,1 -d, | tr [:lower:] [:upper:] | tr -s ' ' | sed 's/^ *//g'
sed 's/^ //g' | sed 's/LIEUTENANT/LT./g' | sed 's/COMMANDER/CMDR./g'
<crew.csv tail -n +2 | tr -s ' ' | cut -f 2,1 -d, | tr [:lower:] [:upper:] | sed 's/^ //g' \ | sed 's/^ //g' | sed 's/LIEUTENANT/LT./g' | sed 's/COMMANDER/CMDR./g'
<crew.csv tail -n +2 | cut -f 2,1 -d, | tr [:lower:] [:upper:] | tr -s ' ' | sed 's/^ *//g'
<crew.csv tail -n +2 | cut -f 2,1 -d, | tr [:lower:] [:upper:] | tr -s ' ' | sed 's/^ *//g'
<crew.csv tail -n +2 | cut -f 2,1 -d, | tr [:lower:] [:upper:] | tr -s ' ' | sed 's/^ *//g'
<crew.csv tail -n +2 | cut -f 2,1 -d, | tr [:lower:] [:upper:] | tr -s ' ' | sed 's/^ *//g'
Współbieżne wykonanie:
<crew.csv tail -n +2 | cut -f 2,1 -d, | tr [:lower:] [:upper:] | tr -s ' ' | sed 's/^ *//g' & <crew.csv tail -n +2 | cut -f 2,1 -d, | tr [:lower:] [:upper:] | tr -s ' ' | sed 's/^ *//g' & <crew.csv tail -n +2 | cut -f 2,1 -d, | tr [:lower:] [:upper:] | tr -s ' ' | sed 's/^ *//g' &
Jakie założenia robimy, żeby mieć komponowalność, przejżystość referencyjną i bezpieczeństwo?
<crew.csv tail -n +2 | cut -f 2,1 -d, | tr [:lower:] [:upper:] | tr -s ' ' | sed 's/^ *//g'
Jakie założenia robimy, żeby mieć komponowalność, przejżystość referencyjną i bezpieczeństwo?
<crew.csv tail -n +2 | cut -f 2,1 -d, | tr [:lower:] [:upper:] | tr -s ' ' | sed 's/^ *//g'
Jakie założenia robimy, żeby mieć komponowalność, przejżystość referencyjną i bezpieczeństwo?
<crew.csv tail -n +2 | cut -f 2,1 -d, | tr [:lower:] [:upper:] | tr -s ' ' | sed 's/^ *//g'
memosed vs bezstanowość
memosed_args= memosed_content_hash= memosed_processed_content= memosed () { content=`cat <&0` content_hash=`echo "$content" | md5sum` if [ "$memosed_content_hash" -eq "$content_hash" ] then echo "$memosed_processed_content" else memosed_content_hash="$content_hash" memosed_processed_content=`echo "$content" | sed $@` echo "$memosed_processed_content" fi } <crew.csv tail -n +2 | cut -f 2,1 -d, | tr [:lower:] [:upper:] | tr -s ' ' | memosed 's/^ *//g' & <crew.csv tail -n +2 | cut -f 2,1 -d, | tr [:lower:] [:upper:] | tr -s ' ' | memosed 's/^ *//g' & <crew.csv tail -n +2 | cut -f 2,1 -d, | tr [:lower:] [:upper:] | tr -s ' ' | memosed 's/^ *//g' & <crew.csv tail -n +2 | cut -f 2,1 -d, | tr [:lower:] [:upper:] | tr -s ' ' | memosed 's/^ *//g' &
ettail vs efekty uboczne
ettail () { echo 'Somebody is using ettail!' | mutt -s '[MBP] Oh, happy day! :D' 'konrad.siek@cs.put.edu.pl' tail $@ <&0 } # run always <crew.csv ettail -n +2 | tee tmp.csv | cut -f 2,1 -d, | tr [:lower:] [:upper:] | tr -s ' ' | sed 's/^ *//g' <crew.csv ettail -n +2 | tee tmp.csv | cut -f 2,1 -d, | tr [:lower:] [:upper:] | tr -s ' ' | sed 's/^ *//g' # run sometimes <crew.csv ettail -n +2 | tee tmp.csv | cut -f 2,1 -d, | tr [:lower:] [:upper:] | tr -s ' ' | sed 's/^ *//g' <tmp.csv | cut -f 2,1 -d, | tr [:lower:] [:upper:] | tr -s ' ' | sed 's/^ *//g' # sadness :c <preprepared_tmp.csv | cut -f 2,1 -d, | tr [:lower:] [:upper:] | tr -s ' ' | sed 's/^ *//g' <preprepared_tmp.csv | cut -f 2,1 -d, | tr [:lower:] [:upper:] | tr -s ' ' | sed 's/^ *//g'
magic () { ettail -n +2 | cut -f 2,1 -d, | tr [:lower:] [:upper:] | tr -s ' ' | memosed 's/^ *//g' } something_else () { # ... <crew.rst magic # ... }
<crew.csv tail -n +2 | cut -f 2,1 -d, | tr [:lower:] [:upper:] | tr -s ' ' | sed 's/^ *//g'
tail: Int × String → String = ...
cut: Int Set × Char × String → String = ...
tr: Char Set × Char Set × String → String = ...
squeeze: Char × String → String = ...
sed: Regex × String → String = ...
crew: String = ...
<crew.csv tail -n +2 | cut -f 2,1 -d, | tr [:lower:] [:upper:] | tr -s ' ' | sed 's/^ *//g'
tail: Int × String → String = ...
cut: Int Set × Char × String → String = ...
tr: Char Set × Char Set × String → String = ...
squeeze: Char × String → String = ...
sed: Regex × String → String = ...
crew: String = ...
tail(2, crew)
<crew.csv tail -n +2 | cut -f 2,1 -d, | tr [:lower:] [:upper:] | tr -s ' ' | sed 's/^ *//g'
tail: Int × String → String = ...
cut: Int Set × Char × String → String = ...
tr: Char Set × Char Set × String → String = ...
squeeze: Char × String → String = ...
sed: Regex × String → String = ...
crew: String = ...
cut({2,1}, ",", tail(2, crew))
<crew.csv tail -n +2 | cut -f 2,1 -d, | tr [:lower:] [:upper:] | tr -s ' ' | sed 's/^ *//g'
tail: Int × String → String = ...
cut: Int Set × Char × String → String = ...
tr: Char Set × Char Set × String → String = ...
squeeze: Char × String → String = ...
sed: Regex × String → String = ...
crew: String = ...
tr({A..Z}, {a..z}, cut({2,1}, ",", tail(2, crew)))
<crew.csv tail -n +2 | cut -f 2,1 -d, | tr [:lower:] [:upper:] | tr -s ' ' | sed 's/^ *//g'
tail: Int × String → String = ...
cut: Int Set × Char × String → String = ...
tr: Char Set × Char Set × String → String = ...
squeeze: Char × String → String = ...
sed: Regex × String → String = ...
crew: String = ...
sed(s/^ *//g, squeeze(" ", tr({A..Z}, {a..z}, cut({2,1}, ",", tail(2, crew)))))
Paradygmat programowania za pomocą funkcji (matematycznych)
Mam zbiór S który zawiera liczby całkowite. Chce mieć zbiór T który będzie miał te same liczby całkowite, ale powiększone o jeden.
Mam zbiór S który zawiera liczby całkowite. Chce mieć zbiór T który będzie miał te same liczby całkowite, ale powiększone o jeden.
Mam zbiór S który zawiera liczby całkowite. Chce mieć zbiór T który będzie miał te same liczby całkowite, ale powiększone o jeden.
Mam zbiór S który zawiera liczby całkowite. Chce mieć zbiór T który będzie miał te same liczby całkowite, ale powiększone o jeden.
Można programować funkcyjnie (prawie) w dowolnym języku, ale języki funkcyjne mają mechanizmy które ułatwiają takie programowanie.
Twierdzenie Church'a-Turing'a.
Twierdzenie Church'a-Turing'a.
Monady.
Maybe functional programming isn't the answer... or maybe functional programming can't magically protect you from using poor abstractions and writing bad code.
Michael Shaw. Game development in Scala.
Space | Forward |
---|---|
Right, Down, Page Down | Next slide |
Left, Up, Page Up | Previous slide |
P | Open presenter console |
H | Toggle this help |