Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Administre sus recursos con tipos lineales

Facundo
November 11, 2019

Administre sus recursos con tipos lineales

Presentada en el seminario de Teoría e Inteligencia Artificial en Univeridad ORT, Uruguay.

En esta charla discutimos cómo utilizar tipos lineales para controlar el uso de recursos escasos. Los tipos lineales son una de las próximas extensiones de Haskell [1] que vendrán en el compilador GHC.

Presentaremos come caso de estudio inline-java [2], una librería que permite incluir fragmentos de Java en módulos de Haskell, y ejecutar los dos lenguajes conjuntamente.

Mantener acotada las referencias a objetos en Java desde Haskell ha sido hasta ahora un problema de ingeniería difícil. El programador es responsable de borrar las referencias a tiempo. Borrarlas demasiado pronto implica errores al acceder a referencias que ya han sido borradas. Borrarlas demasiado tarde produce escases de memoria transitoria en la máquina virtual de Java. Olvidarse de borrarlas, implica que la memoria que la aplicación utiliza aumentará con el tiempo. Estos problemas son comunes a cualquier integración de lenguajes donde los recolectores de basura no están coordinados.

Por ello exploramos como los tipos lineales pueden involucrar al compilador para detectar los errores más comunes al manejar recursos.

[1]https://github.com/ghc-proposals/ghc-proposals/pull/111
[2]https://github.com/tweag/inline-java

Facundo

November 11, 2019
Tweet

More Decks by Facundo

Other Decks in Programming

Transcript

  1. Tweag I/O • Contribuciones a GHC • -XStaticPointers • WebAssembly

    backend (Asterius) • -XLinearTypes • Dependent types in Haskell • Paquetes: inline-java, inline-js, inline-r, ormolu, capability, porcupine, funflow, sparkle, network-transport-tcp, . . . • Build systems/devops: bazel, rules_haskell, nix 2
  2. Plan • Problemas de la programación con recursos • Solución

    con tipos lineales • Caso de uso con inline-java • Cosas para mejorar de la solución 3
  3. Programación con recursos • Memoria • Conexiones a bases de

    datos • Conexiones de red en general • File handles • Procesos • Hilos • Locks • Semáforos 4
  4. Tareas comunes // Adquirir el recurso char *c = (char*)malloc(100);

    // usarlo strcpy(c, "Hello"); printf("%s World!", c) // liberarlo free(c); 5
  5. Tareas comunes -- adquirir el recurso do h <- openFile

    "fulano.txt" ReadMode -- usarlo line <- hGetLine h -- liberarlo hClose h return line 6
  6. Cosas malas que pasan // Uso luego de liberado char

    *c = (char*)malloc(100); strcpy(c, "Hello"); free(c); printf("%s World!", c) 7
  7. Cosas malas que pasan // Uso luego de liberado char

    *c = (char*)malloc(100); strcpy(c, "Hello"); free(c); printf("%s World!", c) // No liberar el recurso char *c = (char*)malloc(100); strcpy(c, "Hello"); printf("%s World!", c) 7
  8. Cosas malas que pasan // Uso luego de liberado char

    *c = (char*)malloc(100); strcpy(c, "Hello"); free(c); printf("%s World!", c) // No liberar el recurso char *c = (char*)malloc(100); strcpy(c, "Hello"); printf("%s World!", c) -- Liberar el recurso tarde do h <- openFile "fulano.txt" ReadMode hGetLine h 7
  9. Plan • Problemas de la programación con recursos • Solución

    con tipos lineales • Caso de uso con inline-java • Cosas para mejorar de la solución 8
  10. Lógica lineal 1987 - Jean-Yves Girard Lambda cálculo polimórfico (System-F)

    Lógica de recursos (Yves Lafont) No contraction rule No weakening rule 9
  11. Tipos lineales -- Programa no lineal do h <- openFile

    "fulano.txt" ReadMode line <- hGetLine h hClose h return line 10
  12. Tipos lineales -- Programa no lineal do h <- openFile

    "fulano.txt" ReadMode line <- hGetLine h hClose h return line -- Linealizado do h1 <- openFile "fulano.txt" ReadMode (line1, h2) <- hGetLine h1 (line2, h3) <- hGetLine h2 hClose h3 return (line1, line2) 10
  13. Tipos lineales en acción -- uso luego de liberado do

    h1 <- openFile "fulano.txt" ReadMode (line, h2) <- hGetLine h1 hClose h2 (line, h3) <- hGetLine h2 return line 11
  14. Tipos lineales en acción -- uso luego de liberado do

    h1 <- openFile "fulano.txt" ReadMode (line, h2) <- hGetLine h1 hClose h2 (line, h3) <- hGetLine h2 return line -- no liberado do h1 <- openFile "fulano.txt" ReadMode (line, h2) <- hGetLine h1 return line 11
  15. ¿Cómo se especifica la “linealidad”? -- Caso no lineal do

    h <- openFile "fulano.txt" ReadMode line <- hGetLine h hClose h return line 12
  16. ¿Cómo se especifica la “linealidad”? -- Caso no lineal do

    h <- openFile "fulano.txt" ReadMode line <- hGetLine h hClose h return line -- Como lambda expression openFile "fulano.txt" ReadMode >>= (\h -> hGetLine h >>= (\line -> hClose h >>= (\() -> return line) ) ) 12
  17. Cómo se especifican la “linealidad”? -- Como lambda expression openFile

    "fulano.txt" ReadMode >>= (\h -> hGetLine h >>= (\line -> hClose h1 >>= (\() -> return line) ) ) (>>=) :: m a -> (a -> m b) -> m b return :: a -> m a 13
  18. Cómo se especifican la “linealidad”? -- Como lambda expression openFile

    "fulano.txt" ReadMode >>= (\h -> hGetLine h >>= (\line -> hClose h1 >>= (\() -> return line) ) ) (>>=) :: m a -> (a -> m b) -> m b return :: a -> m a openFile :: FilePath -> IO Handle hClose :: Handle -> IO () hGetLine :: Handle -> IO String 13
  19. ¿Cómo se especifica la “linealidad”? -- Caso lineal do h1

    <- openFile "fulano.txt" ReadMode (line, h2) <- hGetLine h2 hClose h2 return line -- Como lambda expression openFile "fulano.txt" ReadMode >>= (\h1 -> hGetLine h1 >>= (\(line, h2) -> hClose h2 >>= (\() -> return line) ) ) 14
  20. ¿Cómo se especifica la “linealidad”? -- Como lambda expression openFile

    "fulano.txt" ReadMode >>= (\h1 -> hGetLine h1 >>= (\(line, h2) -> hClose h2 >>= (\() -> return line) ) ) (>>=) :: m a -> (a -> m b) -> m b return :: a -> m a (>>=) :: m a ->. (a ->. m b) ->. m b return :: a ->. m a 15
  21. ¿Cómo se especifica la “linealidad”? -- Como lambda expression openFile

    "fulano.txt" ReadMode >>= (\h1 -> hGetLine h1 >>= (\(line, h2) -> hClose h2 >>= (\() -> return line) ) ) (>>=) :: m a ->. (a ->. m b) ->. m b return :: a ->. m a openFile :: FilePath -> IOL Handle hClose :: Handle ->. IOL () hGetLine :: Handle ->. IOL (Handle, String) 16
  22. ¿Para qué más sirve la linealidad? • para actualizar memoria

    sin copiarla • para asegurar el orden de más operaciones • para mejorar el paralelismo 17
  23. Escapando de la linealidad do h1 <- openFile "fulano.txt" ReadMode

    (line, h2) <- hGetLine h2 hClose h2 return line 18
  24. Escapando de la linealidad do h1 <- openFile "fulano.txt" ReadMode

    (Unrestricted line, h2) <- hGetLine h2 hClose h2 return line hGetLine :: Handle ->. m (Handle, Unrestricted String) 19
  25. Escapando de la linealidad do h1 <- openFile "fulano.txt" ReadMode

    (Unrestricted line, h2) <- hGetLine h2 hClose h2 return line hGetLine :: Handle ->. m (Handle, Unrestricted String) data Unrestricted a where Unrestricted :: a -> Unrestricted a 19
  26. Las garantías de tipos lineales f :: a ->. a

    f x = x g :: Int -> Int g x = f x * f x 20
  27. Las garantías de tipos lineales f :: a ->. a

    f x = x g :: Int -> Int g x = f x * f x -- Como lambda expression openFile "fulano.txt" ReadMode >>= (\h1 -> hGetLine h1 >>= (\(line, h2) -> hClose h2 >>= (\() -> return line) ) ) (>>=) :: m a ->. (a ->. m b) ->. m b return :: a ->. m a 20
  28. Las garantías de tipos lineales -- Excepciones do h1 <-

    openFile "fulano.txt" ReadMode (Unrestricted line, h2) <- hGetLine h2 hClose h2 return line 21
  29. Plan • Problemas de la programación con recursos • Solución

    con tipos lineales • Caso de uso con inline-java • Cosas para mejorar de la solución 22
  30. inline-java jsonHandler resp = do jmsg <- reflect $ encode

    $ object ["message" .= Text.pack "Hello, World!"] [java| { $resp.setBody($jmsg) .appendHeader( Header.KV_CONTENT_TYPE_APPLICATION_JSON ); } |] -- byte[] reflect :: ByteString -> IO (J ( Array ( Prim "byte"))) 23
  31. inline-java – convertible types jmsg :: J ( Array (

    Prim "byte")) -- byte[] resp :: J ( Class "com.wizzardo.http.response.Response") Bool boolean CChar byte Word16 char Int16 short Int32 int Int64 long Float float Double double J ( Class "java.lang.String") java.lang.String J ( Array ...) ...[] 24
  32. Cosas malas que pasan jsonHandler :: J ( Class "com.wizzardo.http.response.Response")

    -> IO () jsonHandler resp = do jmsg <- reflect $ encode $ object ["message" .= Text.pack "Hello, World!"] [java| { $resp.setBody($jmsg) .appendHeader( Header.KV_CONTENT_TYPE_APPLICATION_JSON ); } |] deleteLocalRef resp 26
  33. Pero con tipos lineales . . . jsonHandler :: J

    ( Class "com.wizzardo.http.response.Response") ->. IOL () jsonHandler resp = do jmsg <- reflect $ encode $ object ["message" .= Text.pack "Hello, World!"] [java| { $resp.setBody($jmsg) .appendHeader( Header.KV_CONTENT_TYPE_APPLICATION_JSON ); } |] -- deleteLocalRef resp reflect :: ByteString -> IOL (J ( Array ( Prim "byte"))) 27
  34. Plan • Problemas de la programación con recursos • Solución

    con tipos lineales • Caso de uso con inline-java • Cosas para mejorar de la solución 28
  35. Puntos para mejorar -- Sintaxis the do do h1 <-

    openFile "fulano.txt" ReadMode (line, h2) <- hGetLine h1 hClose h2 return line (>>=) :: m a -> (a -> m b) -> m b return :: a -> m a 29
  36. Puntos para mejorar -- Sintaxis the do do h1 <-

    openFile "fulano.txt" ReadMode (line, h2) <- hGetLine h1 hClose h2 return line (>>=) :: m a -> (a -> m b) -> m b return :: a -> m a RebindableSyntax https://downloads.haskell.org/~ghc/latest/docs/html/users_guide /glasgow_exts.html#extension-RebindableSyntax 29
  37. Puntos para mejorar -- Sintaxis the do do @lineal h1

    <- openFile "fulano.txt" ReadMode (line, h2) <- hGetLine h1 hClose h2 return line Local do https://github.com/ghc-proposals/ghc-proposals/pull/216 30
  38. Puntos para mejorar -- Combinación de mónadas do h1 <-

    openFile "fulano.txt" ReadMode logMessge "archivo abierto" (line, h2) <- hGetLine h1 logMessage "linea leida" hClose h2 return line 31
  39. Puntos para mejorar -- Duplicación de nombres do h1 <-

    openFile "fulano.txt" ReadMode (line1, h2) <- hGetLine h1 (line2, h3) <- hGetLine h2 hClose h3 return (line1, line2) 32
  40. Puntos para mejorar -- Duplicación de nombres do h <-

    openFile "fulano.txt" ReadMode line1 <- hGetLine h line2 <- hGetLine h hClose h return (line1, line2) linear-constraints https://github.com/tweag/linear-constraints 33
  41. Puntos para mejorar -- Duplicación de referencias do h1 <-

    openFile "fulano.txt" ReadMode let (h2, h3) = duplicate h1 (h4, h5) = duplicate h3 line1 <- hGetLine h2 line2 <- hGetLine h4 line3 <- hGetLine h5 return (line1, line2, line3) duplicate :: Handle ->. (Handle, Handle) 34
  42. Puntos para mejorar -- Duplicación de referencias do h@_ <-

    openFile "fulano.txt" ReadMode line1 <- hGetLine h line2 <- hGetLine h line3 <- hGetLine h return (line1, line2, line3) duplicate :: Handle ->. (Handle, Handle) 35
  43. Referencias Artículo de tipos lineales https://arxiv.org/abs/1710.09756 Propuesta de tipos lineales

    https://github.com/ghc-proposals/ghc-proposals/pull/111 inline-java http://github.com/tweag/inline-java Tweag I/O http://tweag.io/blog 36