Swissbytes Ltda.
2008
Suiza, Dinamarca, Australia, Bolivia
ATM, BRMS, Web Applications
Programming Pearls Magazine, 1986
"Leer un archivo de texto, determinar la cantidad de palabras mas usadas, e imprimir una lista ordenada de estas palabras junto con sus frecuencias."Jon Bentley, Programming Pearls, 1986
- Donald Knuth
- Doug McIlroy
$> tr -cs A-Za-z '\n' |
tr A-Z a-z |
sort |
uniq -c |
sort -rn |
sed ${1}q
Programación procedimental
Orientada a objetos
Orientada a aspectos
Funcional
Lógica
El arte de la programación es el arte de organizar complejidad, de controlar el desorden y evitar el caos de la forma mas efectiva posible.Edsger W. Dijkstra
Los programas complejos tienen mas bugs
Los programas complejos son mas difíciles de cambiar
Los programas complejos son menos legibles
Los programas complejos son menos flexibles
Nosotros escribimos programas que toman decisiones
Las decisiones se basan en valores o datos
Los datos son percibidos o calculados
Los datos calculados son estables
Nuestros programas deben ser estables
La programación funcional es un estilo de programación que enfatiza la evaluación de expresiones por encima de la ejecución de comandoscom.lang.functional, 2014
Una función es la relación entre valores donde un valor de entrada retorna exactamente un valor de salida.comp.lang.functional, 2014
String readAsString(InputStream stream) throw IOException{
val reader = new InputStreamReader(stream);
return CharStreams.toString(reader);
}
List<String> readAsLines(InputStream stream) throw IOException{
return IOUtils.readLines(stream);
}
void main(){
val input = new FileInputStream("myfile.txt");
println("content: " + readAsString(input));
println("lines: " + readAsLines(input));
}
String readAsString(InputStream stream) throw IOException{
val reader = new InputStreamReader(cloneOf(stream));
return Streams.toString(reader);
}
List<String> readAsLines(InputStream stream) throw IOException{
return IOUtils.readLines(cloneOf(stream));
}
InputStream cloneOf(InputStream input){
val cloned ....
return cloned;
}
No tocar el estado global
No modificar datos de entrada
No interrumpir el flujo de ejecución
No usar NULL
Alcance local
Determinístico
Baja complejidad
No interrumpe el flujo de ejecución
El problema que tenemos es que por años hemos enseñado efectivamente a generaciones de programadores que el estado mutable nos permite trabajar de la mejor forma. Ahora estamos en una carrera para enseñar que no todo eso es ciertoAnders Hejlsberg, SEI-Radio, 2008
Valores < - > Tiempo
Git / Mercurial / Fossil
Request req = new Request("http://juanbandafanpage.com"); req.method(Request.POST); request.body("fanId=chichico"); request.fetch();Request req = new Request("http://juanbandafanpage.com"); // req.method(Request.POST); request.body("fanId=chichico"); request.fetch(); //NPE!!!
Request req = new Request("http://juanbandafanpage.com"); req = req.body("fanId=chichico"); req = req.post(); req.fetch();Request req = new Request("http://juanbandafanpage.com"); req.body("fanId=chichico").post().fetch();
Todo valor es inmutable por defecto
Todo valor modificado, genera un nuevo valor
Los estados mutables son privados/locales
Los valores no cambian, generan nuevos valores
Los valores no necesitan thread-safety
No existen efectos secundarios
Identidad!!!
int countBugs(String filePath){
Path path = Paths.get(filePath);
int count = 0;
try(FileReader reader = new FileReader(
Files.newInputStream(path))
){
String line = null;
while( (line = reader.readLine()) != null )
if(line.contains(“BUG”))
count++;
}catch(IOException e){
printErr(e);
}
}
int countBugs(String filePath){
return Files.readAllLines(Paths.get(filePath))
.stream()
.filter(line -> line.contains(“BUG”))
.count();
}
List<Deposit> deposits= …;
// give me the big transfers
long allBigTransfers = deposits.stream()
.filter(d -> d.amount > 10000L)
.mapToLong(d -> t.amount)
.sum();
// give me the smallest transfer
Optional<> minTransfer = deposits.stream()
.min((d1, d2) -> d1 > d2);
Enfocarse en el qué, no en el cómo
Abstraer infraestructura
Generar expresiones, y no órdenes
Código expresivo/legible
Enfoque en el fondo, no la forma
Simplicidad inherente
Evaluación optimizable
getAsyncContext,getAttribute, getAttributeNames,
getCharacterEncoding,getLength,getContentLength,
getType,getContentType,getDispatcherType,getLocalName,
getLocalAddr,getLocale,getLocales,getLocalName,
getLocalPort,getParameterNames,getParameterValues,
getProtocol,getReader,getRealPath,getRemoteAddr,
getRemoteHost,getRemotePort,getRequestDispatcher,
getScheme,getServerName,getServerPort,isSecure,
removeAttribute,setAttribute,setCharacterEncoding,
startAsync,getHeader,getHeaderNames,getIntHeader,
getResponseStream,
...
[
"remote-addr": "127.0.0.1",
"scheme": "http",
"form-params": [],
"query-string": "fanId=chichico",
"request-method": "GET",
"content-type": "text/csv",
"server-name": "localhost",
"params": ["key": "value"],
"server-port": 8080,
"headers": [
"accept-encoding" : "gzip, deflate",
"connection": "close",
"content-length": 0,
...
]
]
class CustomerId{
private int id;
private String value;
//.....
}
class InValue{
private int id;
private String value;
private int type;
//...
}
class OutValue{
//...
}
class InValueContainer{
//...
}
class OutValueContainer{
//...
}
Inconsistencia
Duplicidad
Acoplamiento
Primitives
Lists
Sets
Dictionary
Usar primitivos hasta donde se pueda
Usar estructuras hasta donde se pueda
Evitar los objetos anémicos
Evitar estructuras hereditarias
Datos expresivos y claros
Uniformidad y simplicidad de código
Re-utilización
JSON...
La simplicidad es la característica mas devaluada de los sistemas de software.Yo, hace 10 segs