All the side effects were never mentioned to me
I am innocent of uncontrolled abuse

  • 120 Posts
  • 46 Comments
Joined 1 year ago
cake
Cake day: June 17th, 2023

help-circle

















  • We can make it a lot more performant, shorter, and also safer by using lazy byte strings:

    {- cabal:
    build-depends: base, network, network-run, bytestring
    -}
    
    {-# LANGUAGE OverloadedStrings #-}
    
    import Network.Run.TCP (runTCPServer)
    import qualified Network.Socket.ByteString.Lazy as Net
    import qualified Data.ByteString.Lazy.Char8 as Str
    
    main = runTCPServer (Just "127.0.0.1") "9999" $ \s -> do
      request <- Net.getContents s
      case Str.words (Str.takeWhile (/= '\r') request) of
        ["GET", resource, "HTTP/1.1"] -> do
          let path = Str.concat
                [ "htdocs/"
                , Str.dropWhile (== '/') resource
                , if Str.last resource == '/' then "index.html" else ""
                ]
          page <- Str.readFile (Str.unpack path)
          Net.sendAll s ("HTTP/1.1 200 OK\r\n\r\n" <> page)
        _ -> error "todo"
    
    













  • @kosmikus @mangoiv I’m not really the right person to ask, having spent exactly zero time in industry. But I can imagine most industrial users have little interest in the main ICFP program and the other co-hosted workshops. So hosting the event separately at a smaller venue for just two days could make it possible to substantially lower the fees (and individual accommodation costs) which naturally makes the event more accessible. And I expect that the fees are generally a bigger problem outside of academia, so it cater more to industrial users and hobbyists.







  • I think Idris’ bang notation for performing effects in a do-block is pretty, it could look like this:

    main = do putStrLn ("You said: " ++ !getLine)
    
    

    Today, you’d have to come up with a new variable name or figure out the right combinator names:

    main = do line &lt;- getLine; putStrLn ("You said: " ++ line)
    
    main = putStrLn . ("You said: " ++) =&lt;&lt; getLine
    
    

    But unfortunately there are more complicated cases:

    main = do print (True || !getLine == "foo")
    
    

    In a strict language with built-in short-circuiting logical operations the getLine would never be performed, but in Haskell || is just a normal function that happens to be lazy in its second argument. The only reasonable way to implement it seems to be to treat every function as if it was strict and always perform the getLine:

    main = do line &lt;- getLine; print (True || line == "foo")
    
    

    Do you think this is confusing? Or is the bang notation useful enough that you can live with these odd cases? I’m not very happy with this naive desugaring.