I'll cover the Haskell side because I'm more familiar with its library ecosystem:
> Read some environment variables and a local file
import System.Environment (getEnv)
import System.FilePath ((</>))
main = do
dir <- getEnv "WHATEVER_DIR"
data <- readFile (dir </> "foo.txt")
putStrLn ("Had " ++ show (length (lines data)) ++ " lines")
> Start a monitoring thread [...]
import Control.Concurrent
import Control.Concurrent.Chan
import Network.HTTP
-- also more stuff...
monitoringThread :: Chan String -> IO ()
monitoringThread chan = do
file <- openFile "log.txt" AppendMode
forever $ do -- no $ needed if you pass -XBlockArguments [0, 1]
batch <- replicateM 5 (readChan chan)
let chunk = unlines batch
hPutStr file chunk
simpleHTTP (postRequestWithBody "" "text/plain" chunk)
main :: IO ()
main = do
logChan <- newChan
void (forkIO (monitoringThread logChan))
-- ...
forever $ do
threadDelay (1000 * 1000) -- 1M usec
writeChan logChan "Hello, world!"
> Configure and start an http server
import Network.Wai
import Network.Wai.Handler.Warp
main = run 8000 $ \req respond ->
respond (responseLBS status200 [] "Hello, world!")
> Said server has [...]
Yeah, this is long. If you're just getting the current time with the timer, that's here[2]; synchronize across threads with MVars[3] or STM[4]; JSON is in aeson[5], which should feel broadly familiar if you know Rust's serde.
> server’s gotta be able to do concurrency > 1 with parallelism
Yep, GHC Haskell has _excellent_ concurrency support on top of a parallel runtime.
> On sigterm set the server to a state that rejects new requests, waits for existing requests to complete, then flushes the monitoring channel
I haven't personally tried this, but this[6] function sounds like... exactly this, actually, so I think its example should suffice?
On two separate notes:
- Common Lisp and Python 3 are a _lot_ closer than Common Lisp and Haskell, or even Python 3 and JavaScript; the Python 3 object model is very close to Common Lisp's, and Common Lisp is not particularly pure (setf isn't unidiomatic by a longshot), and supports a very non-functional style of programming (it has gotos!).
- "Haskell is worse at IO than other high-level languages" isn't particularly true. What _is_ true is that Haskell has the same "function coloring problem" as JavaScript (Haskell has the IO monad, JavaScript has the Promise monad); Haskell also has a "uses funny academic words" problem (well, debatably a problem...) which I think confuses the issue.
[1]: Haskell has a spec, one "main" implementation (GHC), little spec-committee activity, and a respect for that implementation not superseding the spec; many improvements become language extensions (-X flags or {-# LANGUAGE #-} pragmas), so when you invoke GHC you're getting a by-the-spec implementation by default.
> Read some environment variables and a local file
> Start a monitoring thread [...] > Configure and start an http server > Said server has [...]Yeah, this is long. If you're just getting the current time with the timer, that's here[2]; synchronize across threads with MVars[3] or STM[4]; JSON is in aeson[5], which should feel broadly familiar if you know Rust's serde.
> server’s gotta be able to do concurrency > 1 with parallelism
Yep, GHC Haskell has _excellent_ concurrency support on top of a parallel runtime.
> On sigterm set the server to a state that rejects new requests, waits for existing requests to complete, then flushes the monitoring channel
I haven't personally tried this, but this[6] function sounds like... exactly this, actually, so I think its example should suffice?
On two separate notes:
- Common Lisp and Python 3 are a _lot_ closer than Common Lisp and Haskell, or even Python 3 and JavaScript; the Python 3 object model is very close to Common Lisp's, and Common Lisp is not particularly pure (setf isn't unidiomatic by a longshot), and supports a very non-functional style of programming (it has gotos!).
- "Haskell is worse at IO than other high-level languages" isn't particularly true. What _is_ true is that Haskell has the same "function coloring problem" as JavaScript (Haskell has the IO monad, JavaScript has the Promise monad); Haskell also has a "uses funny academic words" problem (well, debatably a problem...) which I think confuses the issue.
[0]: https://ghc.gitlab.haskell.org/ghc/doc/users_guide/exts/bloc...
[1]: Haskell has a spec, one "main" implementation (GHC), little spec-committee activity, and a respect for that implementation not superseding the spec; many improvements become language extensions (-X flags or {-# LANGUAGE #-} pragmas), so when you invoke GHC you're getting a by-the-spec implementation by default.
[2]: https://hackage.haskell.org/package/time-1.12.2/docs/Data-Ti...
[3]: https://hackage.haskell.org/package/base-4.18.0.0/docs/Contr...
[4]: https://hackage.haskell.org/package/stm-2.5.1.0/docs/Control...
[5]: https://hackage.haskell.org/package/aeson-2.2.0.0/docs/Data-...
[6]: https://hackage.haskell.org/package/warp-3.3.28/docs/Network...