class: center, middle # Un Paseo por el Laberinto de las Representaciones Mariano Guerra [@warianoguerra](https://twitter.com/warianoguerra) [instadeq.com](https://instadeq.com) [@instadeq](https://twitter.com/instadeq) --- background-image: url(img/rich-hickey.jpeg) --- class: middle, center # /ht @davecaos --- * Una imagen, **modelo** u otra representacion de alguien o algo * Un estado mental o concepto considerado correspondiente a la cosa percibida --- background-image: url(img/borges.jpg) --- class: center Diccionario: vease *Diccionario* --- class: center, middle background-image: url(img/alice.webp) --- class: center "Cuando uso una palabra", dijo Humpty Dumpty [..] "Significa solo lo que yo elijo que signifique - ni mas ni menos" --- class: center background-image: url(img/Ptolemaico.gif) # Un tal Claudio Ptolomeo --- # Representaciones Concretas ``` 85 170 ``` --- # Representaciones Concretas ``` 0b01010101 0b10101010 ``` ``` 0b01010101 ^ 0b11111111 ``` ``` 0b01010101 << 1 ``` --- # Representaciones Concretas ``` 0b00001111101000 0b10011100010000 ``` --- # Representaciones Concretas ``` 10000 * 10 = 100000 ``` --- background-image: url(img/Pictionary.jpg) --- class: center # Representacion Abstracta "estado mental o concepto considerado correspondiente a la cosa **percibida**" --- class: center # Representacion Concreta Numeros (base), Aritmetica, Geometria --- class: center # Complejidad Esencial Del problema **real** --- class: center # Complejidad Accidental De las representaciones del problema --- class: center # Una buena representacion Permite realizar operaciones comunes y utiles de manera simple y eficiente --- class: center # Una buena representacion Hace posible realizar otras operaciones --- class: center # Una buena representacion No permite realizar operaciones invalidas (o al menos lo hace dificil) --- class: center # Una buena representacion Minimiza la cantidad de complejidad accidental --- class: center # Una buena representacion Pone la representacion concreta al servicio de la representacion abstracta --- class: center # Una buena representacion **abstracta** Tiene "integridad conceptual" Se concentra en el **que** Ej: Algebra Relacional, Datalog, Lisp, APL --- class: center # Una buena representacion **concreta** Tiene "simpatia mecanica" Se concentra en el **como** Ej: Lectura/Escritura secuencial en HDDs ??? https://dzone.com/articles/mechanical-sympathy The term Mechanical Sympathy was coined by racing driver Jackie Stewart and applied to software by Martin Thompson. Jackie Stewart said, “You don’t have to be an engineer to be be a racing driver, but you do have to have Mechanical Sympathy.” He meant that understanding how a car works makes you a better driver. This is just as true for writing code. You don’t need to be a hardware engineer, but you do need to understand how the hardware works and take that into consideration when you design software. Let’s take something simple like writing a file to disk. Disks are random access, right? Well, not really. Disks work by encoding data in sectors and addressing them in segments of the disk. When you read or write data to disk, youneed to wait for the heads to move to the correct physical location. If you do this randomly, then you will incur performance penalties as the heads are physically moved across the surface of the disk and you wait for the spin of the disk to place the sector you want beneath the read/ write heads. This averages out to about 3ms per seek for the heads, and about 3ms rotational latency. That makes for an average total of about 6ms per seek! --- class: center # Y Elixir? --- background-image: url(img/fellowkids.jpg) --- class: center # efe: Erlang Flavoured Elixir https://gitlab.com/marianoguerra/efe ``` efe pp foo.erl > foo.ex ``` --- # foo.erl ```erlang -module(foo). -export([f1/2, f2/2]). f1(A, B) -> f2(B, A). f2(A, B) -> A + B. ``` --- # Codigo a Tokens (Lexer) ```elixir {:ok, code} = :file.read_file('foo.erl') code_list = :erlang.binary_to_list(code) {:ok, tokens, _} = :erl_scan.string(code_list) ``` --- ```elixir # f1(A {:atom, 4, :f1}, {:"(", 4}, {:var, 4, :A}, # , B) {:",", 4}, {:var, 4, :B}, {:")", 4}, # -> f2(B {:->, 4}, {:atom, 4, :f2}, {:"(", 4}, {:var, 4, :B}, # , A). {:",", 4}, {:var, 4, :A}, {:")", 4}, {:dot, 4}, ``` --- # Operaciones a este nivel * Descartar comentarios * Descartar formato * `include`s * Macros **lexicos** --- # Problemas Lost in translation Dificil reconstruir codigo original al 100% * Pretty printers * Herramientas de refactoring --- # Macros lexicos ```erlang -module(foo1). -export([f1/2, f2/2]). -define(OPEN, (A,). -define(CLOSE, B)). -define(OP, A + B). % un comentario f1?OPEN ?CLOSE -> f2(B, A). f2?OPEN ?CLOSE -> ?OP * 2. ``` --- ``` efe pp foo1.erl ``` ```elixir defmodule :foo1 do def f1(a, b) do f2(b, a) end def f2(a, b) do a + b * 2 end end ``` --- # Tokens a AST ```elixir {:ok, ast} = :epp.parse_file('foo1.erl', []) ``` --- ```elixir {:attribute, 1, :file, {'foo1.erl', 1}}, {:attribute, 1, :module, :foo1}, {:attribute, 2, :export, [f1: 2, f2: 2]}, {:function, 7, :f1, 2, [ {:clause, 7, [{:var, 7, :A}, {:var, 7, :B}], [], [{:call, 7, {:atom, 7, :f2}, [{:var, 7, :B}, {:var, 7, :A}]}]} ]}, {:function, 8, :f2, 2, [ {:clause, 8, [{:var, 8, :A}, {:var, 8, :B}], [], [ {:op, 8, :+, {:var, 8, :A}, {:op, 8, :*, {:var, 8, :B}, {:integer, 8, 2}}} ]} ]}, ``` --- # Un pretty printer basico ```elixir code = :erl_prettypr.format(:erl_syntax.form_list(ast)) IO.puts(code) ``` ```erlang -file("foo1.erl", 1). -module(foo1). -export([f1/2, f2/2]). f1(A, B) -> f2(B, A). f2(A, B) -> A + B * 2. ``` --- class: center ![PPrinter Paper](img/pprinter.png) --- # Representacion abstracta * above * beside * break * follow * nest * par * sep * text --- # Representacion concreta ```elixir doc = :prettypr.follow(:prettypr.text('a'), :prettypr.text('b')) 👉🏾 {:beside, {:sep, [text: [1, 97], text: [0]], 0, true}, 👉🏾 {:text, [1, 98]}} paper = 80 ribbon = 56 :prettypr.format(doc, paper, ribbon) 👉🏾 'a b' ``` [prettypr.erl](http://erlang.org/doc/man/prettypr.html) --- # Repasemos * Lexer + `foo1.erl` 👉🏾 Lista de tokens * epp + Tokens 👉🏾 Tokens * Parser + Tokens 👉🏾 AST erl * Translator + AST erl 👉🏾 AST ex * Translator + AST ex 👉🏾 AST doc * Printer + AST doc 👉🏾 `foo1.ex` --- # Y al reves? ```elixir for f <- :filelib.wildcard('./_build/dev/lib/*/*/*.beam') do result = :beam_lib.chunks(f,[:abstract_code]) {:ok,{_,[{:abstract_code,{_,ac}}]}} = result code = :erl_prettypr.format(:erl_syntax.form_list(ac)) out_path = :string.replace(f, '.beam', '.erl') :file.write_file(out_path, code) end ``` --- # Y Elixir? * Lexer + `foo1.ex` 👉🏾 Lista de tokens * Parser + Tokens 👉🏾 AST ex * Translator + AST ex 👉🏾 AST erl * 👉🏾 Compilador de Erlang desde absform hasta el bytecode --- # Y el compilador? * Lexer * Pre Processor + pp: includes, macros + exp: expande records a tuplas * Parser: absform * Core Erlang * Kernel erlang * SSA * Codegen --- # Y el compilador? ``` erlc +to_pp foo1.erl erlc +to_exp foo1.erl erlc +to_core foo1.erl erlc +to_kernel foo1.erl erlc +dssa foo1.erl erlc +to_asm foo1.erl ``` --- # PP y Exp ```erlang {function,8,f1,2, [{clause,8, [{var,8,'A'},{var,8,'B'}], [], [{call,8,{atom,8,f2},[{var,8,'B'},{var,8,'A'}]}]}]}. {function,9,f2,2, [{clause,9, [{var,9,'A'},{var,9,'B'}], [], [{op,9,'+', {var,9,'A'}, {op,9,'*',{var,9,'B'},{integer,9,2}}}]}]}. ``` ??? Iguales porque no hay records que expandir --- # Core Erlang ```erlang 'f1'/2 = fun (_0,_1) -> apply 'f2'/2 (_1, _0) 'f2'/2 = fun (_0,_1) -> let <_2> = call 'erlang':'*' (_1, 2) in call 'erlang':'+' (_0, _2) 'module_info'/0 = fun () -> call 'erlang':'get_module_info' ('foo1') 'module_info'/1 = fun (_0) -> call 'erlang':'get_module_info' ('foo1', _0) ``` --- # Kernel Erlang ``` erlang fdef 'f1'/2(_0, _1) = match _0,_1 enter (local 'f2'/2)(_1, _0) end >> <> fdef 'f2'/2(_0, _1) = match _0,_1 do bif (remote 'erlang':'*'/2)(_1, 2) >> <_2> then do bif (remote 'erlang':'+'/2)(_0, _2) >> <_3> then <<_3>> end >> <> fdef 'module_info'/0() = match enter (remote 'erlang':'get_module_info'/1)('foo1') end >> <> fdef 'module_info'/1(_0) = match _0 enter (remote 'erlang':'get_module_info'/2)('foo1', _0) end >> <> end ``` --- # SSA ```erlang function foo1:f1(_0, _1) { 0: @ssa_ret:3 = call local literal f2/2, _1, _0 ret @ssa_ret:3 1: @ssa_ret = call remote (literal erlang):(literal error)/1, literal badarg ret @ssa_ret } function foo1:f2(_0, _1) { 0: _2 = bif:'*' _1, literal 2 @ssa_bool = succeeded _2 br @ssa_bool, label 3, label 1 3: _3 = bif:'+' _0, _2 @ssa_bool:4 = succeeded _3 br @ssa_bool:4, label 5, label 1 5: ret _3 1: @ssa_ret = call remote (literal erlang):(literal error)/1, literal badarg ret @ssa_ret } function foo1:module_info() { 0: @ssa_ret:3 = call remote (literal erlang):(literal get_module_info)/1, literal foo1 ret @ssa_ret:3 1: @ssa_ret = call remote (literal erlang):(literal error)/1, literal badarg ret @ssa_ret } function foo1:module_info(_0) { 0: @ssa_ret:3 = call remote (literal erlang):(literal get_module_info)/2, literal foo1, _0 ret @ssa_ret:3 1: @ssa_ret = call remote (literal erlang):(literal error)/1, literal badarg ret @ssa_ret } ``` --- # Codegen ```erlang {function, f1, 2, 2}. {label,1}. {line,[{location,"foo1.erl",8}]}. {func_info,{atom,foo1},{atom,f1},2}. {label,2}. {move,{x,1},{x,2}}. {move,{x,0},{x,1}}. {move,{x,2},{x,0}}. {call_only,2,{f,4}}. ``` --- # Codegen ```erlang {function, f2, 2, 4}. {label,3}. {line,[{location,"foo1.erl",9}]}. {func_info,{atom,foo1},{atom,f2},2}. {label,4}. {line,[{location,"foo1.erl",9}]}. {gc_bif,'*',{f,0},2,[{x,1},{integer,2}],{x,1}}. {line,[{location,"foo1.erl",9}]}. {gc_bif,'+',{f,0},2,[{x,0},{x,1}],{x,0}}. return. ``` --- # Cuantas son muchas representaciones? http://nanopass.org/ The Nanopass Framework is an embedded domain-specific language for creating compilers that focuses on creating **small passes** and **many intermediate representations**. Nanopass reduces the boilerplate required to create compilers making them **easier to understand and maintain**. --- class: center # Cuantas son muchas representaciones? Chez scheme: 58 fases ![chez scheme](img/nanopass.png) --- # Sistemas formales de calculo * Turing Machine (Alan Turing, 1930s) * Lambda Calculus (Alonzo Church, 1930s) * Recursive Functions (Kurt Gödel, 1930s) * Combinatory Logic (Moses Schönfinkel, Haskell Curry, 1950s) [Source](https://youtu.be/\_IgqJr8jG8M?t=468) --- # Code **is** Data * [Von Neumann Architecture](https://en.wikipedia.org/wiki/Von_Neumann_architecture) + x86, ARM + Security --- background-image: url(img/Von_Neumann_Architecture_1.svg) --- # Code "is" Data * [Harvard Architecture](https://en.wikipedia.org/wiki/Harvard_architecture) + WASM + Harder to build JITs --- background-image: url(img/Harvard_Architecture.svg) --- class: center # Un tal Claudio Ptolomeo --- class: center # Unconventional Programming Paradigms ![book](img/unconventional.png) --- # Unconventional Programming Paradigms * Chemical Computing * Amorphous Computing * Bio-insired Computing * Autonomic Computing * Generative Computing --- class: center # Organic Computing ![book](img/organic.png) --- class: center # Robust-first Computing ![screenshot](img/robust.png) [Dave Ackley Youtube Channel](https://www.youtube.com/channel/UClOeW4P8ekXaKxJaZU_LK6w) --- # Unison Un nuevo lenguaje de programacion distribuida influenciado por Haskell, Erlang y Frank Codigo "content addressed" e inmutable Append only, solo se agregan cambios, nada cambia una vez creado --- # Unison: Propiedades * No hay builds * No hay conflicto de dependencias * Renombrar algo es trivial * "deployless": deployment de codigo dinamico bajo demanda * cacheo de tests y resultados de compilacion, lo que no cambia no se reevalua + incluso otros usuarios no requieren recompilar lo que ya se compilo ??? La idea mas importante que permite todo esto es el concepto de codigo content addressed. El codigo no se almacena como texto, sino como un AST normalizado, ese AST no sabe de nombres, todos los valores son hashes de sus definiciones, argumentos y variables locales son simplemente indices. Los nombres son asociados en los metadatos, dos usuarios pueden tener distintos nombres para las mismas variables sin generar ningun conflicto. --- class: center
--- class: center # APL `life←{↑1 ω∨.∧3 4=+/,¯1 0 1∘.⊖¯1 0 1∘.⌽⊂ω}` ![This is your keyboard on APL](img/APL_keyboard.jpg) [Explicacion](https://www.youtube.com/watch?v=a9xAKttWgP4) --- class: center # Gracias Mariano Guerra [@warianoguerra](https://twitter.com/warianoguerra) [instadeq.com](https://instadeq.com) [@instadeq](https://twitter.com/instadeq)