From a87bfa238c8bf421bc15ad13477b037136e9028d Mon Sep 17 00:00:00 2001 From: Gabriel Gonzalez Date: Tue, 1 Sep 2015 17:24:41 -0700 Subject: [PATCH 1/3] Changes --- slides/slides.md | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/slides/slides.md b/slides/slides.md index 0c9b829..c458a3a 100644 --- a/slides/slides.md +++ b/slides/slides.md @@ -41,7 +41,7 @@ $ cabal install turtle-1.1.0 * Folds * Patterns -I've hosted slides on go/learn so that people can follow along locally +I'm hosting slides on Github so that people can follow along locally # Overview of Haskell @@ -58,13 +58,13 @@ Haskell can be both **interpreted** or **compiled** to a native binary Haskell is a managed language, providing garbage collection, concurrency, and transactional shared memory: -* **Garbage collection** is generational and efficient (measured in GB / s) -* **Concurrency** uses green-threads and is efficient (world record for SDN) -* **Transactional memory** simplifies race-free concurrent code without polling +* **Garbage collection** is efficient (throughput measured in GB / s) +* **Concurrency** uses green-threads and is efficient (can handle 1M threads) +* **Transactional memory** simplifies race-free concurrent code -# Biggest disadvantages of Haskell +# Big disadvantages of Haskell -* Not a JVM language +* No JVM backend * Beginners can't easily reason about performance * Built-in record syntax is clumsy * Most language features are libraries, which hampers discoverability @@ -122,7 +122,7 @@ import Turtle -- main = echo "Hello, world!" -- echo Hello, world! ``` -... then run the example: +... then run the example script: ```bash $ chmod u+x example.hs @@ -133,7 +133,7 @@ Hello, world! # Create a native binary ```bash -$ ghc -O2 -threaded example.hs +$ ghc -O2 example.hs $ ./example Hello, world! ``` @@ -312,7 +312,7 @@ main = do -- ```haskell $ ./example.hs -2015-01-24 03:40:31 UTC +2015-09-01 23:56:03.245 UTC ``` Why not this? @@ -341,6 +341,17 @@ scala> for { x <- Seq(1, 2); y <- Seq(3, 4) } yield (x, y) res0: Seq[(Int, Int)] = List((1,3), (1,4), (2,3), (2,4)) ``` +... or LINQ/`from`/`select` in C#: + +```cs +List xs = new List { 1, 2 } +List ys = new List { 3, 4 } +var result = + from x in xs + from y in ys + select Tuple(x, y) +``` + # Nesting subroutines ```haskell @@ -362,7 +373,7 @@ Same result: ```haskell $ ./example.hs -2015-01-24 03:40:31 UTC +2015-09-01 23:56:03.245 UTC ``` # Unnecessary `return` From 7b35eb4da8bfd55a17d0a33982ee9dba31a6c307 Mon Sep 17 00:00:00 2001 From: Gabriel Gonzalez Date: Wed, 2 Sep 2015 11:02:54 -0700 Subject: [PATCH 2/3] Backup --- slides/slides.md | 39 +++++++++++++++------------------------ 1 file changed, 15 insertions(+), 24 deletions(-) diff --git a/slides/slides.md b/slides/slides.md index c458a3a..c9cfb9f 100644 --- a/slides/slides.md +++ b/slides/slides.md @@ -1,19 +1,16 @@ % Haskell for Shell Scripting % Gabriel Gonzalez -% April 8, 2015 +% September 3, 2015 # Before class -If you haven't installed `ghc`, yet: +If you haven't installed `ghc`, visit: -```bash -$ echo "/home/ggonzalez/tools/ghc-7.8.3-Darwin.x86_64" >> ~/.tools -$ sync-dottools.sh -``` +* [https://www.haskell.org/downloads](https://www.haskell.org/downloads) -... then open a new terminal window. +... and install a GHC distribution appropriate to your operating system. -To test your Haskell installation, run these commands: +To test your Haskell installation, run these commands from a terminal: ```bash $ echo 'main = putStrLn "Hello, world!"' > hello.hs @@ -25,7 +22,7 @@ Install the shell scripting library using these commands: ```bash $ cabal update -$ cabal install turtle-1.1.0 +$ cabal install turtle-1.2.1 ``` # Outline @@ -253,6 +250,8 @@ The top level of a Haskell program is declarative and only allows definitions You cannot execute code at the top level +The runtime only executes `main`! + # Subroutines Use `do` to create a subroutine that runs more than one command: @@ -950,15 +949,15 @@ Prelude Turtle> format "I take 0 arguments" ```haskell (%) :: Format b c -> Format a b -> Format a c -"A " :: Format a a -s :: Format a (String -> a) -" string that takes " :: Format a a -d :: Format a (Int -> a) -" arguments" :: Format a a +"A " :: Format a a +s :: Format a (Text -> a) +" string that takes " :: Format a a +d :: Format a (Int -> a) +" arguments" :: Format a a "A "%s%" string that takes "%d%" arguments" :: Format a (Text -> Int -> a) -format "A "%s%" string that takes "%d%" arguments" :: Text -> Int -> Text +format ("A "%s%" string that takes "%d%" arguments") :: Text -> Int -> Text ``` You can build your own format specifiers! @@ -1498,7 +1497,7 @@ Fold.head :: Fold a (Maybe a) ``` ```haskell -ls :: Shell Turtle.FilePath +ls "/tmp" :: Shell Turtle.FilePath fold :: Shell a -> Fold a b -> IO b fold (ls "/tmp") :: Fold Turtle.FilePath b -> IO b @@ -1733,13 +1732,5 @@ tuple = do You can use Haskell as a "better Bash", getting types for free without slow startup times or heavyweight syntax. -If you want others to run your Haskell scripts, they can use `dottools` to install -`ghc` on their machine. - -I also have a relocatable `ghc` uploaded to Packer that you can use to interpret -scripts on Mesos. - -We also have an internal Hackage server at Twitter (go/hackage) - Visit https://hackage.haskell.org/package/turtle for more extensive documentation on the shell scripting library we used today From 17aefb8e54353654cf0128491ce95ba3202f6b60 Mon Sep 17 00:00:00 2001 From: Gabriel Gonzalez Date: Thu, 3 Sep 2015 14:58:18 -0700 Subject: [PATCH 3/3] Updated slides --- slides/slides.md | 65 +++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 59 insertions(+), 6 deletions(-) diff --git a/slides/slides.md b/slides/slides.md index c9cfb9f..6507537 100644 --- a/slides/slides.md +++ b/slides/slides.md @@ -491,7 +491,6 @@ main = do ```haskell $ ghci -v0 -Prelude> :set -XOverloadedStrings Prelude> import Turtle ``` @@ -919,16 +918,12 @@ format (s%" failed with exit code: "%d) :: Text -> Int -> Text # Exercise -What do you think these print out? +What do you think this prints out? ```haskell Prelude Turtle> format ("A "%s%" string that takes "%d%" arguments") "format" 2 ``` -```haskell -Prelude Turtle> format "I take 0 arguments" -``` - # The `Format` type A format string is not `Text`! @@ -942,6 +937,7 @@ So what is going on here? ```haskell Prelude Turtle> format "I take 0 arguments" +"I take 0 arguments" ``` # `Format` implements `IsString` @@ -1727,6 +1723,63 @@ tuple = do # Questions? +# Backup utility example + +```haskell +{-# LANGUAGE OverloadedStrings #-} + +import Turtle +import Prelude hiding (FilePath) + +parser = (,) <$> argPath "src" "Source directory" + <*> argPath "dst" "Destination directory" + +backup file = do + exists <- testfile file + when exists (do + let backupFile = file <.> "bak" + backup backupFile + mv file backupFile ) + +main = do + (src, dest) <- options "Backup a directory" parser + sh (do + inFile <- lstree src + Just suffix <- return (stripPrefix src inFile) + let outFile = dest suffix + backup outFile + echo (format ("Copying "%fp%" to "%fp) inFile outFile) + cp inFile outFile ) + echo "Done!" +``` + +# Command line usage + +```bash +$ ./backup --help +Backup a directory + +Usage: backup SRC DST + +Available options: + -h,--help Show this help text + SRC Source directory + DST Destination directory +``` + +```bash +$ ./backup a/ b/ +Copying a/1 to b/1 +Copying a/2 to b/2 +$ ls b/ +1 2 +$ ./backup a/ b/ +Copying a/1 to b/1 +Copying a/2 to b/2 +$ ls b/ +1 1.bak 2 2.bak +``` + # Conclusions You can use Haskell as a "better Bash", getting types for free without slow