summaryrefslogtreecommitdiffhomepage
path: root/es-es
diff options
context:
space:
mode:
Diffstat (limited to 'es-es')
-rw-r--r--es-es/awk-es.html.markdown3
-rw-r--r--es-es/common-lisp-es.html.markdown692
-rw-r--r--es-es/dart-es.html.markdown529
-rw-r--r--es-es/kotlin-es.html.markdown68
-rw-r--r--es-es/python-es.html.markdown2
-rw-r--r--es-es/pythonstatcomp-es.html.markdown3
-rw-r--r--es-es/scala-es.html.markdown741
-rw-r--r--es-es/visualbasic-es.html.markdown2
8 files changed, 2021 insertions, 19 deletions
diff --git a/es-es/awk-es.html.markdown b/es-es/awk-es.html.markdown
index 0516ea92..8da8f024 100644
--- a/es-es/awk-es.html.markdown
+++ b/es-es/awk-es.html.markdown
@@ -1,5 +1,6 @@
---
-language: awk
+category: tool
+tool: awk
filename: learnawk-es.awk
contributors:
- ["Marshall Mason", "http://github.com/marshallmason"]
diff --git a/es-es/common-lisp-es.html.markdown b/es-es/common-lisp-es.html.markdown
new file mode 100644
index 00000000..526ea621
--- /dev/null
+++ b/es-es/common-lisp-es.html.markdown
@@ -0,0 +1,692 @@
+---
+
+language: "Common Lisp"
+filename: commonlisp-es.lisp
+contributors:
+ - ["Paul Nathan", "https://github.com/pnathan"]
+ - ["Rommel Martinez", "https://ebzzry.io"]
+translators:
+ - ["ivanchoff", "https://github.com/ivanchoff"]
+ - ["Andre Polykanine", "https://github.com/Menelion"]
+lang: es-es
+---
+
+Common Lisp es un lenguaje de proposito general y multiparadigma adecuado para una amplia variedad
+de aplicaciones en la industria. Es frecuentemente referenciado como un lenguaje de programación
+programable.
+
+EL punto de inicio clásico es [Practical Common Lisp](http://www.gigamonkeys.com/book/). Otro libro
+popular y reciente es [Land of Lisp](http://landoflisp.com/). Un nuevo libro acerca de las mejores
+prácticas, [Common Lisp Recipes](http://weitz.de/cl-recipes/), fue publicado recientemente.
+
+```lisp
+
+;;;-----------------------------------------------------------------------------
+;;; 0. Sintaxis
+;;;-----------------------------------------------------------------------------
+
+;;; Forma general
+
+;;; CL tiene dos piezas fundamentales en su sintaxis: ATOM y S-EXPRESSION.
+;;; Típicamente, S-expressions agrupadas son llamadas `forms`.
+
+10 ; un atom; se evalua a sí mismo
+:thing ; otro atom; evaluando el símbolo :thing
+t ; otro atom, denotando true
+(+ 1 2 3 4) ; una s-expression
+'(4 :foo t) ; otra s-expression
+
+
+;;; Comentarios
+
+;;; comentarios de una sola línea empiezan con punto y coma; usa cuatro para
+;;; comentarios a nivel de archivo, tres para descripciones de sesiones, dos
+;;; adentro de definiciones, y una para líneas simples. Por ejemplo,
+
+;;;; life.lisp
+
+;;; Foo bar baz, porque quu quux. Optimizado para máximo krakaboom y umph.
+;;; Requerido por la función LINULUKO.
+
+(defun sentido (vida)
+ "Retorna el sentido de la vida calculado"
+ (let ((meh "abc"))
+ ;; llama krakaboom
+ (loop :for x :across meh
+ :collect x))) ; guarda valores en x, luego lo retorna
+
+;;; Comentarios de bloques, por otro lado, permiten comentarios de forma libre. estos son
+;;; delimitados con #| y |#
+
+#| Este es un comentario de bloque el cual
+ puede abarcar multiples líneas y
+ #|
+ estos pueden ser anidados
+ |#
+|#
+
+
+;;; Entorno
+
+;;; Existe una variedad de implementaciones; La mayoría son conformes a los estándares. SBCL
+;;; es un buen punto de inicio. Bibliotecas de terceros pueden instalarse fácilmente con
+;;; Quicklisp
+
+;;; CL es usualmente desarrollado y un bucle de Lectura-Evaluación-Impresión (REPL), corriendo
+;;; al mismo tiempo. El REPL permite la exploración interactiva del programa mientras este esta
+;;; corriendo
+
+
+;;;-----------------------------------------------------------------------------
+;;; 1. Operadores y tipos de datos primitivos
+;;;-----------------------------------------------------------------------------
+
+;;; Símbolos
+
+'foo ; => FOO Note que el símbolo es pasado a mayúsculas automáticamente.
+
+;;; INTERN manualmente crea un símbolo a partir de una cadena.
+
+(intern "AAAA") ; => AAAA
+(intern "aaa") ; => |aaa|
+
+;;; Números
+
+9999999999999999999999 ; enteros
+#b111 ; binario=> 7
+#o111 ; octal => 73
+#x111 ; hexadecimal => 273
+3.14159s0 ; simple
+3.14159d0 ; double
+1/2 ; proporciones
+#C(1 2) ; números complejos
+
+;;; las funciones son escritas como (f x y z ...) donde f es una función y
+;;; x, y, z, ... son los argumentos.
+
+(+ 1 2) ; => 3
+
+;;; Si deseas crear datos literales use QUOTE para prevenir que estos sean evaluados
+
+(quote (+ 1 2)) ; => (+ 1 2)
+(quote a) ; => A
+
+;;; La notación abreviada para QUOTE es '
+
+'(+ 1 2) ; => (+ 1 2)
+'a ; => A
+
+;;; Operaciones aritméticas básicas
+
+(+ 1 1) ; => 2
+(- 8 1) ; => 7
+(* 10 2) ; => 20
+(expt 2 3) ; => 8
+(mod 5 2) ; => 1
+(/ 35 5) ; => 7
+(/ 1 3) ; => 1/3
+(+ #C(1 2) #C(6 -4)) ; => #C(7 -2)
+
+;;; Boleanos
+
+t ; true; cualquier valor non-NIL es true
+nil ; false; también, la lista vacia: ()
+(not nil) ; => T
+(and 0 t) ; => T
+(or 0 nil) ; => 0
+
+;;; Caracteres
+
+#\A ; => #\A
+#\λ ; => #\GREEK_SMALL_LETTER_LAMDA
+#\u03BB ; => #\GREEK_SMALL_LETTER_LAMDA
+
+;;; Cadenas son arreglos de caracteres de longitud fija
+
+"Hello, world!"
+"Benjamin \"Bugsy\" Siegel" ; la barra invertida es un carácter de escape
+
+;;; Las cadenas pueden ser concatenadas
+
+(concatenate 'string "Hello, " "world!") ; => "Hello, world!"
+
+;;; Una cadena puede ser tratada como una secuencia de caracteres
+
+(elt "Apple" 0) ; => #\A
+
+;;; FORMAT es usado para crear salidas formateadas, va desde simple interpolación de cadenas
+;;; hasta bucles y condicionales. El primer argumento de FORMAT determina donde irá la cadena
+;;; formateada. Si este es NIL, FORMAT simplemente retorna la cadena formateada como un valor;
+;;; si es T, FORMAT imprime a la salida estándar, usualmente la pantalla, luego este retorna NIL.
+
+(format nil "~A, ~A!" "Hello" "world") ; => "Hello, world!"
+(format t "~A, ~A!" "Hello" "world") ; => NIL
+
+
+;;;-----------------------------------------------------------------------------
+;;; 2. Variables
+;;;-----------------------------------------------------------------------------
+
+;;; Puedes crear una variable global (ámbito dinámico) usando DEFVAR y DEFPARAMETER
+;;; el nombre de la variable puede usar cualquier carácter excepto: ()",'`;#|\
+
+;;; La diferencia entre DEFVAR y DEFPARAMETER es que reevaluando una expresión
+;;; DEFVAR no cambia el valor de la variable. DEFPARAMETER, por otro lado sí lo hace.
+
+;;; Por convención, variables de ámbito dinámico tienen "orejeras" en sus nombres.
+
+(defparameter *some-var* 5)
+*some-var* ; => 5
+
+;;; Puedes usar también caracteres unicode.
+(defparameter *AΛB* nil)
+
+;;; Accediendo a una variable sin asignar tienen como resultado el error
+;;; UNBOUND-VARIABLE, sin embargo este es el comportamiento definido. no lo hagas
+
+;;; puedes crear enlaces locales con LET. en el siguiente código, `me` es asignado
+;;; con "dance with you" solo dentro de (let ...). LET siempre retorna el valor
+;;; del último `form`.
+
+(let ((me "dance with you")) me) ; => "dance with you"
+
+
+;;;-----------------------------------------------------------------------------;
+;;; 3. Estructuras y colecciones
+;;;-----------------------------------------------------------------------------;
+
+
+;;; Estructuras
+
+(defstruct dog name breed age)
+(defparameter *rover*
+ (make-dog :name "rover"
+ :breed "collie"
+ :age 5))
+*rover* ; => #S(DOG :NAME "rover" :BREED "collie" :AGE 5)
+(dog-p *rover*) ; => T
+(dog-name *rover*) ; => "rover"
+
+;;; DOG-P, MAKE-DOG, y DOG-NAME son creados automáticamente por DEFSTRUCT
+
+
+;;; Pares
+
+;;; CONS crea pares. CAR y CDR retornan la cabeza y la cola de un CONS-pair
+
+(cons 'SUBJECT 'VERB) ; => '(SUBJECT . VERB)
+(car (cons 'SUBJECT 'VERB)) ; => SUBJECT
+(cdr (cons 'SUBJECT 'VERB)) ; => VERB
+
+
+;;; Listas
+
+;;; Listas son estructuras de datos de listas enlazadas, hechas de pares CONS y terminan con un
+;;; NIL (o '()) para marcar el final de la lista
+
+(cons 1 (cons 2 (cons 3 nil))) ; => '(1 2 3)
+
+;;; LIST es una forma conveniente de crear listas
+
+(list 1 2 3) ; => '(1 2 3)
+
+;;; Cuando el primer argumento de CONS es un atom y el segundo argumento es una lista,
+;;; CONS retorna un nuevo par CONS con el primer argumento como el primer elemento y el
+;;; segundo argumento como el resto del par CONS
+
+(cons 4 '(1 2 3)) ; => '(4 1 2 3)
+
+;;; Use APPEND para unir listas
+
+(append '(1 2) '(3 4)) ; => '(1 2 3 4)
+
+;;; o CONCATENATE
+
+(concatenate 'list '(1 2) '(3 4)) ; => '(1 2 3 4)
+
+;;; las listas son un tipo de datos centrales en CL, por lo tanto hay una gran variedad
+;;; de funcionalidades para ellas, algunos ejemplos son:
+
+(mapcar #'1+ '(1 2 3)) ; => '(2 3 4)
+(mapcar #'+ '(1 2 3) '(10 20 30)) ; => '(11 22 33)
+(remove-if-not #'evenp '(1 2 3 4)) ; => '(2 4)
+(every #'evenp '(1 2 3 4)) ; => NIL
+(some #'oddp '(1 2 3 4)) ; => T
+(butlast '(subject verb object)) ; => (SUBJECT VERB)
+
+
+;;; Vectores
+
+;;; Vectores literales son arreglos de longitud fija
+
+#(1 2 3) ; => #(1 2 3)
+
+;;; Use CONCATENATE para juntar vectores
+
+(concatenate 'vector #(1 2 3) #(4 5 6)) ; => #(1 2 3 4 5 6)
+
+
+;;; Arreglos
+
+;;; Vectores y cadenas son casos especiales de arreglos.
+
+;;; Arreglos bidimensionales
+
+(make-array (list 2 2)) ; => #2A((0 0) (0 0))
+(make-array '(2 2)) ; => #2A((0 0) (0 0))
+(make-array (list 2 2 2)) ; => #3A(((0 0) (0 0)) ((0 0) (0 0)))
+
+;;; Precaución: los valores iniciales por defecto de MAKE-ARRAY son implementaciones definidas
+;;; para definirlos explícitamente:
+
+(make-array '(2) :initial-element 'unset) ; => #(UNSET UNSET)
+
+;;; Para acceder al elemento en 1, 1, 1:
+
+(aref (make-array (list 2 2 2)) 1 1 1) ; => 0
+
+;;; Este valor es definido por implementación:
+;;; NIL en ECL, 0 en SBCL and CCL.
+
+;;; vectores ajustables
+
+;;; los vectores ajustables tienen la misma representación en la impresión como los vectores literales
+;;; de longitud fija.
+
+(defparameter *adjvec* (make-array '(3) :initial-contents '(1 2 3)
+ :adjustable t :fill-pointer t))
+*adjvec* ; => #(1 2 3)
+
+;;; Agregando nuevos elementos
+
+(vector-push-extend 4 *adjvec*) ; => 3
+*adjvec* ; => #(1 2 3 4)
+
+
+;;; Conjuntos, ingenuamente son listas:
+
+(set-difference '(1 2 3 4) '(4 5 6 7)) ; => (3 2 1)
+(intersection '(1 2 3 4) '(4 5 6 7)) ; => 4
+(union '(1 2 3 4) '(4 5 6 7)) ; => (3 2 1 4 5 6 7)
+(adjoin 4 '(1 2 3 4)) ; => (1 2 3 4)
+
+;;; Sin embargo, necesitarás una mejor estructura de datos que listas enlazadas
+;;; cuando trabajes con conjuntos de datos grandes
+
+;;; Los Diccionarios son implementados como tablas hash.
+
+;;; Crear tablas hash
+
+(defparameter *m* (make-hash-table))
+
+;;; definir valor
+
+(setf (gethash 'a *m*) 1)
+
+;;; obtener valor
+
+(gethash 'a *m*) ; => 1, T
+
+;;; las expresiones en CL tienen la facultad de retornar multiples valores.
+
+(values 1 2) ; => 1, 2
+
+;;; los cuales pueden ser asignados con MULTIPLE-VALUE-BIND
+
+(multiple-value-bind (x y)
+ (values 1 2)
+ (list y x))
+
+; => '(2 1)
+
+;;; GETHASH es un ejemplo de una función que retorna multiples valores. El primer
+;;; valor es el valor de la llave en la tabla hash: si la llave no existe retorna NIL.
+
+;;; El segundo valor determina si la llave existe en la tabla hash. si la llave no existe
+;;; en la tabla hash retorna NIL. Este comportamiento permite verificar si el valor de una
+;;; llave es actualmente NIL.
+
+;;; Obteniendo un valor no existente retorna NIL
+
+(gethash 'd *m*) ;=> NIL, NIL
+
+;;; Puedes declarar un valor por defecto para las llaves inexistentes
+
+(gethash 'd *m* :not-found) ; => :NOT-FOUND
+
+;;; Vamos a manejar los multiples valores de retornno en el código.
+
+(multiple-value-bind (a b)
+ (gethash 'd *m*)
+ (list a b))
+; => (NIL NIL)
+
+(multiple-value-bind (a b)
+ (gethash 'a *m*)
+ (list a b))
+; => (1 T)
+
+
+;;;-----------------------------------------------------------------------------
+;;; 3. Funciones
+;;;-----------------------------------------------------------------------------
+
+;;; Use LAMBDA para crear funciones anónimas. las funciones siempre retornan el valor
+;;; de la última expresión. la representación imprimible de una función varia entre
+;;; implementaciones.
+
+(lambda () "Hello World") ; => #<FUNCTION (LAMBDA ()) {1004E7818B}>
+
+;;; Use FUNCALL para llamar funciones anónimas.
+
+(funcall (lambda () "Hello World")) ; => "Hello World"
+(funcall #'+ 1 2 3) ; => 6
+
+;;; Un llamado a FUNCALL es también realizado cuando la expresión lambda es el CAR de
+;;; una lista.
+
+((lambda () "Hello World")) ; => "Hello World"
+((lambda (val) val) "Hello World") ; => "Hello World"
+
+;;; FUNCALL es usado cuando los argumentos son conocidos de antemano.
+;;; de lo contrario use APPLY
+
+(apply #'+ '(1 2 3)) ; => 6
+(apply (lambda () "Hello World") nil) ; => "Hello World"
+
+;;; Para nombrar una funcion use DEFUN
+
+(defun hello-world () "Hello World")
+(hello-world) ; => "Hello World"
+
+;;; Los () en la definición anterior son la lista de argumentos
+
+(defun hello (name) (format nil "Hello, ~A" name))
+(hello "Steve") ; => "Hello, Steve"
+
+;;; las functiones pueden tener argumentos opcionales; por defecto son NIL
+
+(defun hello (name &optional from)
+ (if from
+ (format t "Hello, ~A, from ~A" name from)
+ (format t "Hello, ~A" name)))
+
+(hello "Jim" "Alpacas") ; => Hello, Jim, from Alpacas
+
+;;; Los valores por defecto pueden ser especificados
+
+
+(defun hello (name &optional (from "The world"))
+ (format nil "Hello, ~A, from ~A" name from))
+
+(hello "Steve") ; => Hello, Steve, from The world
+(hello "Steve" "the alpacas") ; => Hello, Steve, from the alpacas
+
+;;; Las funciones también tienen argumentos llaves para permitir argumentos no positionados
+
+(defun generalized-greeter (name &key (from "the world") (honorific "Mx"))
+ (format t "Hello, ~A ~A, from ~A" honorific name from))
+
+(generalized-greeter "Jim")
+; => Hello, Mx Jim, from the world
+
+(generalized-greeter "Jim" :from "the alpacas you met last summer" :honorific "Mr")
+; => Hello, Mr Jim, from the alpacas you met last summer
+
+
+;;;-----------------------------------------------------------------------------
+;;; 4. Igualdad
+;;;-----------------------------------------------------------------------------
+
+;;; CL tiene un sistema sofisticado de igualdad. Una parte es tratada aquí.
+
+;;; Para números use `=`
+(= 3 3.0) ; => T
+(= 2 1) ; => NIL
+
+;;; Para identidad de objetos (aproximadamente) use EQL
+(eql 3 3) ; => T
+(eql 3 3.0) ; => NIL
+(eql (list 3) (list 3)) ; => NIL
+
+;;; para listas, cadenas y bit vectores use EQUAL
+(equal (list 'a 'b) (list 'a 'b)) ; => T
+(equal (list 'a 'b) (list 'b 'a)) ; => NIL
+
+
+;;;-----------------------------------------------------------------------------
+;;; 5. Control de flujo
+;;;-----------------------------------------------------------------------------
+
+;;; Condicionales
+
+(if t ; testar expresión
+ "this is true" ; then expression
+ "this is false") ; else expression
+; => "this is true"
+
+;;; En condicionales, todo valor non-NIL es tratado como true
+
+(member 'Groucho '(Harpo Groucho Zeppo)) ; => '(GROUCHO ZEPPO)
+(if (member 'Groucho '(Harpo Groucho Zeppo))
+ 'yep
+ 'nope)
+; => 'YEP
+
+;;; COND en cadena una serie de pruebas para seleccionar un resultado
+(cond ((> 2 2) (error "wrong!"))
+ ((< 2 2) (error "wrong again!"))
+ (t 'ok)) ; => 'OK
+
+;;; TYPECASE evalua sobre el tipo del valor
+(typecase 1
+ (string :string)
+ (integer :int))
+; => :int
+
+
+;;; Bucles
+
+;;; Recursión
+
+(defun fact (n)
+ (if (< n 2)
+ 1
+ (* n (fact(- n 1)))))
+
+(fact 5) ; => 120
+
+;;; Iteración
+
+(defun fact (n)
+ (loop :for result = 1 :then (* result i)
+ :for i :from 2 :to n
+ :finally (return result)))
+
+(fact 5) ; => 120
+
+(loop :for x :across "abcd" :collect x)
+; => (#\a #\b #\c #\d)
+
+(dolist (i '(1 2 3 4))
+ (format t "~A" i))
+; => 1234
+
+
+;;;-----------------------------------------------------------------------------
+;;; 6. Mutación
+;;;-----------------------------------------------------------------------------
+
+;;; use SETF para asignar un valor nuevo a una variable existente. Esto fue demostrado
+;;; previamente en el ejemplo de la tabla hash.
+
+(let ((variable 10))
+ (setf variable 2))
+; => 2
+
+;;; Un estilo bueno de lisp es minimizar el uso de funciones destructivas y prevenir
+;;; la mutación cuando sea posible.
+
+
+;;;-----------------------------------------------------------------------------
+;;; 7. Clases y objetos
+;;;-----------------------------------------------------------------------------
+
+;;; No más clases de animales, tengamos transportes mecánicos impulsados por el humano
+
+(defclass human-powered-conveyance ()
+ ((velocity
+ :accessor velocity
+ :initarg :velocity)
+ (average-efficiency
+ :accessor average-efficiency
+ :initarg :average-efficiency))
+ (:documentation "A human powered conveyance"))
+
+;;; Los argumentos de DEFCLASS, en orden son:
+;;; 1. nombre de la clase
+;;; 2. lista de superclases
+;;; 3. slot list
+;;; 4. Especificadores opcionales
+
+;;; cuando no hay lista de superclase, la lista vacia indica clase de
+;;; objeto estándar, esto puede ser cambiado, pero no mientras no sepas
+;;; lo que estas haciendo. revisar el arte del protocolo de meta-objetos
+;;; para más información.
+
+(defclass bicycle (human-powered-conveyance)
+ ((wheel-size
+ :accessor wheel-size
+ :initarg :wheel-size
+ :documentation "Diameter of the wheel.")
+ (height
+ :accessor height
+ :initarg :height)))
+
+(defclass recumbent (bicycle)
+ ((chain-type
+ :accessor chain-type
+ :initarg :chain-type)))
+
+(defclass unicycle (human-powered-conveyance) nil)
+
+(defclass canoe (human-powered-conveyance)
+ ((number-of-rowers
+ :accessor number-of-rowers
+ :initarg :number-of-rowers)))
+
+;;; Invocando DESCRIBE en la clase HUMAN-POWERED-CONVEYANCE en REPL obtenemos:
+
+(describe 'human-powered-conveyance)
+
+; COMMON-LISP-USER::HUMAN-POWERED-CONVEYANCE
+; [symbol]
+;
+; HUMAN-POWERED-CONVEYANCE names the standard-class #<STANDARD-CLASS
+; HUMAN-POWERED-CONVEYANCE>:
+; Documentation:
+; A human powered conveyance
+; Direct superclasses: STANDARD-OBJECT
+; Direct subclasses: UNICYCLE, BICYCLE, CANOE
+; Not yet finalized.
+; Direct slots:
+; VELOCITY
+; Readers: VELOCITY
+; Writers: (SETF VELOCITY)
+; AVERAGE-EFFICIENCY
+; Readers: AVERAGE-EFFICIENCY
+; Writers: (SETF AVERAGE-EFFICIENCY)
+
+;;; Tenga en cuenta el comportamiento reflexivo disponible. CL fue diseñado
+;;; para ser un systema interactivo
+
+;;; para definir un método, encontremos la circunferencia de la rueda usando
+;;; la ecuación C = d * pi
+
+(defmethod circumference ((object bicycle))
+ (* pi (wheel-size object)))
+
+;;; PI es definido internamente en CL
+
+;;; Supongamos que descubrimos que el valor de eficiencia del número de remeros
+;;; en una canoa es aproximadamente logarítmico. Esto probablemente debería
+;;; establecerse en el constructor / inicializador.
+
+;;; Para inicializar su instancia después de que CL termine de construirla:
+
+(defmethod initialize-instance :after ((object canoe) &rest args)
+ (setf (average-efficiency object) (log (1+ (number-of-rowers object)))))
+
+;;; luego para construir una instancia y revisar la eficiencia promedio
+
+(average-efficiency (make-instance 'canoe :number-of-rowers 15))
+; => 2.7725887
+
+
+;;;-----------------------------------------------------------------------------
+;;; 8. Macros
+;;;-----------------------------------------------------------------------------
+
+;;; las Macros le permiten extender la sintaxis del lenguaje, CL no viene con
+;;; un bucle WHILE, por lo tanto es facil escribirlo, Si obedecemos nuestros
+;;; instintos de ensamblador, terminamos con:
+
+(defmacro while (condition &body body)
+ "While `condition` is true, `body` is executed.
+`condition` is tested prior to each execution of `body`"
+ (let ((block-name (gensym)) (done (gensym)))
+ `(tagbody
+ ,block-name
+ (unless ,condition
+ (go ,done))
+ (progn
+ ,@body)
+ (go ,block-name)
+ ,done)))
+
+;;; revisemos la versión de alto nivel para esto:
+
+(defmacro while (condition &body body)
+ "While `condition` is true, `body` is executed.
+`condition` is tested prior to each execution of `body`"
+ `(loop while ,condition
+ do
+ (progn
+ ,@body)))
+
+;;; Sin embargo, con un compilador moderno, esto no es necesario; El LOOP se
+;;; compila igualmente bien y es más fácil de leer.
+
+;;; Tenga en cuenta que se utiliza ```, así como `,` y `@`. ``` es un operador
+;;; de tipo de cita conocido como quasiquote; permite el uso de `,` . `,` permite
+;;; variables "entre comillas". @ interpola las listas.
+
+;;; GENSYM crea un símbolo único que garantiza que no existe en ninguna otra parte
+;;; del sistema. Esto se debe a que las macros se expanden en el momento de la compilación
+;;; y las variables declaradas en la macro pueden colisionar con las variables utilizadas
+;;; en un código regular.
+
+;;; Consulte Practical Common Lisp y On Lisp para obtener más información sobre macros.
+```
+
+
+## Otras Lecturas
+
+- [Practical Common Lisp](http://www.gigamonkeys.com/book/)
+- [Common Lisp: A Gentle Introduction to Symbolic Computation](https://www.cs.cmu.edu/~dst/LispBook/book.pdf)
+
+
+## Información extra
+
+- [CLiki](http://www.cliki.net/)
+- [common-lisp.net](https://common-lisp.net/)
+- [Awesome Common Lisp](https://github.com/CodyReichert/awesome-cl)
+- [Lisp Lang](http://lisp-lang.org/)
+
+
+## Creditos
+
+Muchas Gracias a la gente de Scheme por proveer un gran punto de inicio
+el cual puede ser movido fácilmente a Common Lisp
+
+- [Paul Khuong](https://github.com/pkhuong) para un buen repaso.
diff --git a/es-es/dart-es.html.markdown b/es-es/dart-es.html.markdown
new file mode 100644
index 00000000..d0f57b95
--- /dev/null
+++ b/es-es/dart-es.html.markdown
@@ -0,0 +1,529 @@
+---
+language: dart
+contributors:
+ - ["Joao Pedrosa", "https://github.com/jpedrosa/"]
+translators:
+ - ["Jorge Antonio Atempa", "http://www.twitter.com/atempa09"]
+filename: dart-es.md
+lang: es-es
+---
+
+Dart es un recién llegado al ámbito de los lenguajes de programación.
+Toma prestado mucho de otros lenguajes principales, con el objetivo de no desviarse demasiado de
+su hermano JavaScript. Tal como JavaScript, Dart tiene como objetivo una gran integración en el navegador.
+
+La característica más controvertida de Dart debe ser su escritura opcional.
+
+```dart
+import "dart:collection";
+import "dart:math" as DM;
+
+// Bienvenido a Aprende Dart en 15 minutos. http://www.dartlang.org/
+// Este es un tutorial ejecutable. Puedes ejecutarlo con Dart o en
+// el sitio de ¡Try Dart! solo copiando y pegando en http://try.dartlang.org/
+
+// La declaración de función y de método tienen el mismo aspecto.
+// Las funciones pueden estar anidadas.
+// La declaración toma la forma name() {} o name() => expresionEnUnaLinea;
+// La declaración de la función de flecha gorda, tiene un retorno implícito
+// para el resultado de la expresión.
+example1() {
+ nested1() {
+ nested2() => print("example1 anidado 1 anidado 2");
+ nested2();
+ }
+ nested1();
+}
+
+// Las funciones anónimas no incluyen un nombre.
+example2() {
+ nested1(fn) {
+ fn();
+ }
+ nested1(() => print("example2 anidado 1"));
+}
+
+// Cuando se declara un parámetro de función, la declaración puede incluir el
+// número de parámetros que toma la función especificando los nombres de los
+// parámetros que lleva.
+example3() {
+ planA(fn(informSomething)) {
+ fn("example3 plan A");
+ }
+ planB(fn) { // O no declarar el número de parámetros.
+ fn("example3 plan B");
+ }
+ planA((s) => print(s));
+ planB((s) => print(s));
+}
+
+// Las funciones tienen acceso de cierre a variables externas.
+var example4Something = "Example4 anidado 1";
+example4() {
+ nested1(fn(informSomething)) {
+ fn(example4Something);
+ }
+ nested1((s) => print(s));
+}
+
+// La declaración de la clase con un método sayIt, el cual también tiene acceso de cierre
+// a la variable exterior como si fuera una función como se ha visto antes.
+var example5method = "example5 sayIt";
+class Example5Class {
+ sayIt() {
+ print(example5method);
+ }
+}
+example5() {
+ // Crear una instancia anónima de Example5Class y la llamada del método sayIt
+ new Example5Class().sayIt();
+}
+
+// La declaración de clase toma la forma NombreDeClase { [cuerpoDeClase] }.
+// Donde cuerpoDeClase puede incluir métodos de instancia y variables, pero también
+// métodos y variables de clase.
+class Example6Class {
+ var instanceVariable = "Example6 variable de instancia";
+ sayIt() {
+ print(instanceVariable);
+ }
+}
+example6() {
+ new Example6Class().sayIt();
+}
+
+// Los métodos y variables de clase son declarados con términos "static".
+class Example7Class {
+ static var classVariable = "Example7 variable de clase";
+ static sayItFromClass() {
+ print(classVariable);
+ }
+ sayItFromInstance() {
+ print(classVariable);
+ }
+}
+example7() {
+ Example7Class.sayItFromClass();
+ new Example7Class().sayItFromInstance();
+}
+
+// Las literales son geniales, pero hay una restricción para lo que pueden ser las literales
+// fuera de los cuerpos de función/método. Literales en el ámbito exterior de clase
+// o fuera de clase tienen que ser constantes. Las cadenas de caracteres y los números
+// son constantes por defecto. Pero los arreglos y mapas no lo son.
+// Ellos pueden hacerse constante anteponiendo en la declaración el término "const".
+var example8Array = const ["Example8 arreglo constante"],
+ example8Map = const {"algunaKey": "Example8 mapa constante"};
+example8() {
+ print(example8Array[0]);
+ print(example8Map["algunaKey"]);
+}
+
+// Los bucles en Dart toman la forma estándar para for () {} o ciclos while () {} ,
+// ligeramente más moderno for (.. in ..) {}, o llamadas funcionales con muchas
+// características soportadas, comenzando con forEach.
+var example9Array = const ["a", "b"];
+example9() {
+ for (var i = 0; i < example9Array.length; i++) {
+ print("example9 ciclo for '${example9Array[i]}'");
+ }
+ var i = 0;
+ while (i < example9Array.length) {
+ print("example9 ciclo while '${example9Array[i]}'");
+ i++;
+ }
+ for (var e in example9Array) {
+ print("example9 ciclo for-in '${e}'");
+ }
+ example9Array.forEach((e) => print("example9 ciclo forEach '${e}'"));
+}
+
+// Para recorrer los caracteres de una cadena o para extraer una subcadena.
+var example10String = "ab";
+example10() {
+ for (var i = 0; i < example10String.length; i++) {
+ print("example10 Recorrido de caracteres en la cadena '${example10String[i]}'");
+ }
+ for (var i = 0; i < example10String.length; i++) {
+ print("example10 ciclo de subcadena '${example10String.substring(i, i + 1)}'");
+ }
+}
+
+// Formato de números Int y double son soportados.
+example11() {
+ var i = 1 + 320, d = 3.2 + 0.01;
+ print("example11 int ${i}");
+ print("example11 double ${d}");
+}
+
+// DateTime ofrece aritmética de fecha/hora.
+example12() {
+ var now = new DateTime.now();
+ print("example12 ahora '${now}'");
+ now = now.add(new Duration(days: 1));
+ print("example12 manana '${now}'");
+}
+
+// Expresiones regulares son soportadas.
+example13() {
+ var s1 = "alguna cadena", s2 = "alguna", re = new RegExp("^s.+?g\$");
+ match(s) {
+ if (re.hasMatch(s)) {
+ print("example13 regexp embona '${s}'");
+ } else {
+ print("example13 regexp no embona '${s}'");
+ }
+ }
+ match(s1);
+ match(s2);
+}
+
+// Las expresiones booleanas admiten conversiones implícitas y tipos dinámicos.
+example14() {
+ var a = true;
+ if (a) {
+ print("true, a is $a");
+ }
+ a = null;
+ if (a) {
+ print("true, a es $a");
+ } else {
+ print("false, a es $a"); // corre aquí
+ }
+
+ // el tipado dinámico null puede convertirse a bool
+ var b; // b es de tipo dinámico
+ b = "abc";
+ try {
+ if (b) {
+ print("true, b es $b");
+ } else {
+ print("false, b es $b");
+ }
+ } catch (e) {
+ print("error, b es $b"); // esto podría ser ejecutado pero consiguió error
+ }
+ b = null;
+ if (b) {
+ print("true, b es $b");
+ } else {
+ print("false, b es $b"); // corre aquí
+ }
+
+ // tipado estático null no puede ser convertido a bool
+ var c = "abc";
+ c = null;
+ // compilación fallida
+ // if (c) {
+ // print("true, c is $c");
+ // } else {
+ // print("false, c is $c");
+ // }
+}
+
+// try/catch/finally y throw son utilizados para el manejo de excepciones.
+// throw toma cualquier objeto como parámetro;
+example15() {
+ try {
+ try {
+ throw "Algun error inesperado.";
+ } catch (e) {
+ print("example15 una excepcion: '${e}'");
+ throw e; // Re-throw
+ }
+ } catch (e) {
+ print("example15 atrapa la excepcion que ha sido relanzada: '${e}'");
+ } finally {
+ print("example15 aún ejecuta finally");
+ }
+}
+
+// Para ser eficiente cuando creas una cadena larga dinámicamente, usa
+// StringBuffer. O podrías unir un arreglo de cadena de caracteres.
+example16() {
+ var sb = new StringBuffer(), a = ["a", "b", "c", "d"], e;
+ for (e in a) { sb.write(e); }
+ print("example16 cadena de caracteres dinamica creada con "
+ "StringBuffer '${sb.toString()}'");
+ print("example16 union de arreglo de cadena de caracteres '${a.join()}'");
+}
+
+// Las cadenas de caracteres pueden ser concatenadas contando solo
+// con literales una después de la otra sin algún otro operador necesario.
+example17() {
+ print("example17 "
+ "concatenar "
+ "cadenas "
+ "asi");
+}
+
+// Las cadenas de caracteres utilizan comilla simple o comillas dobles como delimitadores
+// sin ninguna diferencia entre ambas. Esto proporciona flexibilidad que puede ser efectiva
+// para evitar la necesidad de 'escapar' el contenido. Por ejemplo,
+// las dobles comillas de los atributos HTML.
+example18() {
+ print('Example18 <a href="etc">'
+ "Don't can't I'm Etc"
+ '</a>');
+}
+
+// Las cadenas de caracteres con triple comilla simple o triple comillas dobles
+// dividen múltiples lineas e incluyen como delimitador el salto de línea.
+example19() {
+ print('''Example19 <a href="etc">
+Example19 Don't can't I'm Etc
+Example19 </a>''');
+}
+
+// Las cadenas de caracteres cuentan con una extraordinaria característica
+// para la interpolación de caracteres utilizando el operador $
+// Con $ { [expresion] }, devolvemos la expresion interpolada.
+// $ seguido por el nombre de una variable interpola el contenido de dicha variable.
+// $ puede ser escapado con \$ para solo agregarlo a la cadena.
+example20() {
+ var s1 = "'\${s}'", s2 = "'\$s'";
+ print("Example20 \$ interpolation ${s1} or $s2 works.");
+}
+
+// Hasta ahora no hemos declarado ningún tipo de dato y los programas
+// han funcionado bien. De hecho, los tipos no se toman en cuenta durante
+// el tiempo de ejecución.
+// Los tipos incluso pueden estar equivocados y al programa todavía se le dará
+// el beneficio de la duda y se ejecutará como si los tipos no importaran.
+// Hay un parámetro de tiempo de ejecución que comprueba los errores de tipo que es
+// el modo de verificación, el cuál es útil durante el tiempo de desarrollo,
+// pero que también es más lento debido a la comprobación adicional y, por lo tanto
+// se evita durante el tiempo de ejecución de la implementación.
+class Example21 {
+ List<String> _names;
+ Example21() {
+ _names = ["a", "b"];
+ }
+ List<String> get names => _names;
+ set names(List<String> list) {
+ _names = list;
+ }
+ int get length => _names.length;
+ void add(String name) {
+ _names.add(name);
+ }
+}
+void example21() {
+ Example21 o = new Example21();
+ o.add("c");
+ print("example21 nombres '${o.names}' y longitud '${o.length}'");
+ o.names = ["d", "e"];
+ print("example21 nombres '${o.names}' y longitud '${o.length}'");
+}
+
+// La herencia de clases toma la forma NombreDeClase extends OtraClase {}.
+class Example22A {
+ var _name = "¡Algun Nombre!";
+ get name => _name;
+}
+class Example22B extends Example22A {}
+example22() {
+ var o = new Example22B();
+ print("example22 herencia de clase '${o.name}'");
+}
+
+// La mezcla de clases también esta disponible y toman la forma de
+// NombreDeClase extends AlgunaClase with OtraClase {}.
+// Es necesario extender de alguna clase para poder mezclar con otra.
+// La clase de plantilla de mixin no puede en este momento tener un constructor.
+// Mixin se utiliza principalmente para compartir métodos con clases distantes,
+// por lo que la herencia única no interfiere con el código reutilizable.
+// Mixins se colocan despues de la palabra "with" durante la declaración de la clase.
+class Example23A {}
+class Example23Utils {
+ addTwo(n1, n2) {
+ return n1 + n2;
+ }
+}
+class Example23B extends Example23A with Example23Utils {
+ addThree(n1, n2, n3) {
+ return addTwo(n1, n2) + n3;
+ }
+}
+example23() {
+ var o = new Example23B(), r1 = o.addThree(1, 2, 3),
+ r2 = o.addTwo(1, 2);
+ print("Example23 addThree(1, 2, 3) results in '${r1}'");
+ print("Example23 addTwo(1, 2) results in '${r2}'");
+}
+
+// El método constructor de la clase utiliza el mismo nombre de la clase
+// y toma la forma de AlgunaClase() : super() {}, donde la parte ": super()"
+// es opcional y es utilizado para delegar parametros constantes
+// al método constructor de la clase padre o super clase.
+class Example24A {
+ var _value;
+ Example24A({value: "algunValor"}) {
+ _value = value;
+ }
+ get value => _value;
+}
+class Example24B extends Example24A {
+ Example24B({value: "algunOtroValor"}) : super(value: value);
+}
+example24() {
+ var o1 = new Example24B(),
+ o2 = new Example24B(value: "aunMas");
+ print("example24 llama al método super desde el constructor '${o1.value}'");
+ print("example24 llama al método super desde el constructor '${o2.value}'");
+}
+
+// Hay un atajo para configurar los parámetros del constructor en el caso de clases más simples.
+// Simplemente use el prefijo this.nombreParametro y establecerá el parámetro
+// en una variable de instancia del mismo nombre.
+class Example25 {
+ var value, anotherValue;
+ Example25({this.value, this.anotherValue});
+}
+example25() {
+ var o = new Example25(value: "a", anotherValue: "b");
+ print("example25 atajo para el constructor '${o.value}' y "
+ "'${o.anotherValue}'");
+}
+
+// Los parámetros con nombre están disponibles cuando se declaran entre {}.
+// El orden de los parámetros puede ser opcional cuando se declara entre {}.
+// Los parámetros pueden hacerse opcionales cuando se declaran entre [].
+example26() {
+ var _name, _surname, _email;
+ setConfig1({name, surname}) {
+ _name = name;
+ _surname = surname;
+ }
+ setConfig2(name, [surname, email]) {
+ _name = name;
+ _surname = surname;
+ _email = email;
+ }
+ setConfig1(surname: "Doe", name: "John");
+ print("example26 name '${_name}', surname '${_surname}', "
+ "email '${_email}'");
+ setConfig2("Mary", "Jane");
+ print("example26 name '${_name}', surname '${_surname}', "
+ "email '${_email}'");
+}
+
+// Las variables declaradas con final solo se pueden establecer una vez.
+// En el caso de las clases, las variables de instancia final se pueden establecer
+// a través de la constante del parámetro constructor.
+class Example27 {
+ final color1, color2;
+ // Un poco de flexibilidad para establecer variables de instancia finales con la sintaxis
+ // que sigue a :
+ Example27({this.color1, color2}) : color2 = color2;
+}
+example27() {
+ final color = "orange", o = new Example27(color1: "lilac", color2: "white");
+ print("example27 color es '${color}'");
+ print("example27 color es '${o.color1}' y '${o.color2}'");
+}
+
+// Para importar una librería utiliza la palabra reservada import "rutaLibrería" o si es una biblioteca central,
+// import "dart:NombreLibrería". También está el "pub" administrador de paquetes con
+// su propia convensión import "package:NombrePaquete".
+// Ve import "dart:collection"; al inicio. Las importaciones deben venir antes
+// de la delcaración de algún otro código. IterableBase proviene de dart:collection.
+class Example28 extends IterableBase {
+ var names;
+ Example28() {
+ names = ["a", "b"];
+ }
+ get iterator => names.iterator;
+}
+example28() {
+ var o = new Example28();
+ o.forEach((name) => print("example28 '${name}'"));
+}
+
+// Para el control de flujo tenemos:
+// * estandard switch
+// * if-else if-else y el operador ternario ..?..:..
+// * closures y funciones anonimas
+// * sentencias break, continue y return
+example29() {
+ var v = true ? 30 : 60;
+ switch (v) {
+ case 30:
+ print("example29 sentencia switch");
+ break;
+ }
+ if (v < 30) {
+ } else if (v > 30) {
+ } else {
+ print("example29 sentencia if-else");
+ }
+ callItForMe(fn()) {
+ return fn();
+ }
+ rand() {
+ v = new DM.Random().nextInt(50);
+ return v;
+ }
+ while (true) {
+ print("example29 callItForMe(rand) '${callItForMe(rand)}'");
+ if (v != 30) {
+ break;
+ } else {
+ continue;
+ }
+ // Nunca llega aquí.
+ }
+}
+
+// La sentencia int.parse, convierte de tipo double a int, o simplemente mantener int cuando se dividen los números
+// utilizando ~/ como operación. Vamos a jugar un juego de adivinanzas también.
+example30() {
+ var gn, tooHigh = false,
+ n, n2 = (2.0).toInt(), top = int.parse("123") ~/ n2, bottom = 0;
+ top = top ~/ 6;
+ gn = new DM.Random().nextInt(top + 1); // +1 porque nextInt top es exclusivo
+ print("example30 Adivina un número entre 0 y ${top}");
+ guessNumber(i) {
+ if (n == gn) {
+ print("example30 ¡Adivinaste correctamente! El número es ${gn}");
+ } else {
+ tooHigh = n > gn;
+ print("example30 Número ${n} es demasiado "
+ "${tooHigh ? 'high' : 'low'}. Intenta nuevamente");
+ }
+ return n == gn;
+ }
+ n = (top - bottom) ~/ 2;
+ while (!guessNumber(n)) {
+ if (tooHigh) {
+ top = n - 1;
+ } else {
+ bottom = n + 1;
+ }
+ n = bottom + ((top - bottom) ~/ 2);
+ }
+}
+
+// Los programas tienen un solo punto de entrada en la función principal.
+// No se espera que se ejecute nada en el ámbito externo antes de que un programa
+// comience a funcionar con su función principal.
+// Esto ayuda con una carga más rápida e incluso con una carga lenta
+// de lo que necesita el programa para iniciar.
+main() {
+ print("Learn Dart in 15 minutes!");
+ [example1, example2, example3, example4, example5, example6, example7,
+ example8, example9, example10, example11, example12, example13, example14,
+ example15, example16, example17, example18, example19, example20,
+ example21, example22, example23, example24, example25, example26,
+ example27, example28, example29, example30
+ ].forEach((ef) => ef());
+}
+
+```
+
+## Lecturas adicionales
+
+Dart tiene un sitio web muy completo. Cubre referencias de API, tutoriales, artículos y más, incluyendo una
+útil sección en línea Try Dart.
+[https://www.dartlang.org](https://www.dartlang.org)
+[https://try.dartlang.org](https://try.dartlang.org)
diff --git a/es-es/kotlin-es.html.markdown b/es-es/kotlin-es.html.markdown
index 045f92d1..80d7a4bb 100644
--- a/es-es/kotlin-es.html.markdown
+++ b/es-es/kotlin-es.html.markdown
@@ -2,6 +2,7 @@
language: kotlin
contributors:
- ["S Webber", "https://github.com/s-webber"]
+- ["Aitor Escolar", "https://github.com/aiescola"]
translators:
- ["Ivan Alburquerque", "https://github.com/AlburIvan"]
lang: es-es
@@ -40,6 +41,12 @@ fun main(args: Array<String>) {
    Podemos declarar explícitamente el tipo de una variable así:
*/
val foo: Int = 7
+
+ /*
+ A diferencia de JavaScript, aunque el tipo se infiera, es tipado, por lo que no se puede cambiar el tipo a posteriori
+ */
+ var fooInt = 14 // Se infiere tipo Int
+ fooInt = "Cadena" // ERROR en tiempo de compilación: Type mismatch
/*
Las cadenas pueden ser representadas de la misma manera que Java.
@@ -84,7 +91,6 @@ fun main(args: Array<String>) {
println(fooNullable?.length) // => null
println(fooNullable?.length ?: -1) // => -1
-
/*
Las funciones pueden ser declaras usando la palabra clave "fun".
Los argumentos de las funciones son especificados entre corchetes despues del nombre de la función.
@@ -122,6 +128,40 @@ fun main(args: Array<String>) {
fun even(x: Int) = x % 2 == 0
println(even(6)) // => true
println(even(7)) // => false
+
+ /*
+ Kotlin permite el uso de lambdas, o funciones anónimas
+ */
+
+ // Sin lambda:
+ interface MyListener {
+ fun onClick(foo: Foo)
+ }
+
+ fun listenSomething(listener: MyListener) {
+ listener.onClick(Foo())
+ }
+
+ listenSomething(object: MyListener {
+ override fun onClick(foo: Foo) {
+ //...
+ }
+ })
+
+ // Con lambda:
+ fun listenSomethingLambda(listener: (Foo) -> Unit) {
+ listener(Foo())
+ }
+
+ listenSomethingLambda {
+ //Se recibe foo
+ }
+
+ // el operador typealias permite, entre otras cosas, simplificar las expresiones con lambdas
+ typealias MyLambdaListener = (Foo) -> Unit
+ fun listenSomethingLambda(listener: MyLambdaListener) {
+ listener(Foo())
+ }
// Las funciones pueden tomar funciones como argumentos y
// retornar funciones.
@@ -219,6 +259,11 @@ fun main(args: Array<String>) {
val fooMap = mapOf("a" to 8, "b" to 7, "c" to 9)
// Se puede acceder a los valores del mapa por su llave.
println(fooMap["a"]) // => 8
+
+ // Tanto Map como cualquier colección iterable, tienen la función de extensión forEach
+ fooMap.forEach {
+ println("${it.key} ${it.value}")
+ }
/*
Las secuencias representan colecciones evaluadas diferidamente.
@@ -245,7 +290,7 @@ fun main(args: Array<String>) {
val y = fibonacciSequence().take(10).toList()
println(y) // => [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
- // Kotlin provee funciones de Orden-Mayor para trabajar con colecciones.
+ // Kotlin provee funciones de orden superior para trabajar con colecciones.
val z = (1..9).map {it * 3}
.filter {it < 20}
.groupBy {it % 2 == 0}
@@ -305,17 +350,11 @@ fun main(args: Array<String>) {
ese tipo sin convertido de forma explícita.
*/
fun smartCastExample(x: Any) : Boolean {
- if (x is Boolean) {
- // x es automaticamente convertido a Boolean
- return x
- } else if (x is Int) {
- // x es automaticamente convertido a Int
- return x > 0
- } else if (x is String) {
- // x es automaticamente convertido a String
- return x.isNotEmpty()
- } else {
- return false
+ return when (x) {
+ is Boolean -> x // x es automaticamente convertido a Boolean
+ is Int -> x > 0 // x es automaticamente convertido a Int
+ is String -> x.isNotEmpty() // x es automaticamente convertido a String
+ else -> false
}
}
println(smartCastExample("Hola, mundo!")) // => true
@@ -345,7 +384,8 @@ enum class EnumExample {
/*
La palabra clave "object" se puede utilizar para crear objetos únicos.
No podemos asignarlo a una variable, pero podemos hacer referencia a ella por su nombre.
-Esto es similar a los objetos únicos de Scala
+Esto es similar a los objetos únicos de Scala.
+En la mayoría de ocasiones, los objetos únicos se usan como alternativa a los Singleton.
*/
object ObjectExample {
fun hello() : String {
diff --git a/es-es/python-es.html.markdown b/es-es/python-es.html.markdown
index a27203d1..2b8f498a 100644
--- a/es-es/python-es.html.markdown
+++ b/es-es/python-es.html.markdown
@@ -467,7 +467,7 @@ Humano.roncar() #=> "*roncar*"
# Puedes importar módulos
import math
-print math.sqrt(16) #=> 4
+print math.sqrt(16) #=> 4.0
# Puedes obtener funciones específicas desde un módulo
from math import ceil, floor
diff --git a/es-es/pythonstatcomp-es.html.markdown b/es-es/pythonstatcomp-es.html.markdown
index 0130b72a..b3d2f0ff 100644
--- a/es-es/pythonstatcomp-es.html.markdown
+++ b/es-es/pythonstatcomp-es.html.markdown
@@ -1,5 +1,6 @@
---
-language: Statistical computing with Python
+category: tool
+tool: Statistical Computing with Python
contributors:
- ["e99n09", "https://github.com/e99n09"]
filename: pythonstatcomp-es.py
diff --git a/es-es/scala-es.html.markdown b/es-es/scala-es.html.markdown
new file mode 100644
index 00000000..2dcb9e7f
--- /dev/null
+++ b/es-es/scala-es.html.markdown
@@ -0,0 +1,741 @@
+---
+language: Scala
+filename: learnscala-es.scala
+contributors:
+ - ["George Petrov", "http://github.com/petrovg"]
+ - ["Dominic Bou-Samra", "http://dbousamra.github.com"]
+ - ["Geoff Liu", "http://geoffliu.me"]
+ - ["Ha-Duong Nguyen", "http://reference-error.org"]
+translators:
+ - ["Pablo Arranz Ropero", "http://arranzropablo.com"]
+lang: es-es
+---
+
+Scala - El lenguaje escalable
+
+```scala
+
+/////////////////////////////////////////////////
+// 0. Básicos
+/////////////////////////////////////////////////
+/*
+ Configurar Scala:
+
+ 1) Descarga Scala - http://www.scala-lang.org/downloads
+ 2) Unzip/untar a tu carpeta elegida y pon la subcarpeta bin en tu variable de entorno `PATH`
+*/
+
+/*
+ Prueba REPL
+
+ Scala tiene una herramienta llamada REPL (Read-Eval-Print Loop, en español: Bucle de lectura-evaluación-impresión) que es analogo a interpretes de la linea de comandos en muchos otros lenguajes.
+ Puedes escribir cualquier expresión en Scala y el resultado será evaluado e impreso.
+
+ REPL es una herramienta muy práctica para testear y verificar código.
+ Puedes usarla mientras lees este tutorial para explorar conceptos por tu cuenta.
+*/
+
+// Inicia Scala REPL ejecutando `scala` en tu terminal. Deberías ver:
+$ scala
+scala>
+
+// Por defecto cada expresión que escribes es guardada como un nuevo valor numerado:
+scala> 2 + 2
+res0: Int = 4
+
+// Los valores por defecto pueden ser reusados. Fíjate en el tipo del valor mostrado en el resultado...
+scala> res0 + 2
+res1: Int = 6
+
+// Scala es un lenguaje fuertemente tipado. Puedes usar REPL para comprobar el tipo sin evaluar una expresión.
+scala> :type (true, 2.0)
+(Boolean, Double)
+
+// Las sesiones REPL pueden ser guardadas
+scala> :save /sites/repl-test.scala
+
+// Se pueden cargar archivos en REPL
+scala> :load /sites/repl-test.scala
+Loading /sites/repl-test.scala...
+res2: Int = 4
+res3: Int = 6
+
+// Puedes buscar en tu historial reciente
+scala> :h?
+1 2 + 2
+2 res0 + 2
+3 :save /sites/repl-test.scala
+4 :load /sites/repl-test.scala
+5 :h?
+
+// Ahora que sabes como jugar, aprendamos un poco de Scala...
+
+/////////////////////////////////////////////////
+// 1. Básicos
+/////////////////////////////////////////////////
+
+// Los comentarios de una linea comienzan con dos barras inclinadas
+
+/*
+ Los comentarios de varias lineas, como ya has visto arriba, se hacen de esta manera.
+*/
+
+// Así imprimimos forzando una nueva linea en la siguiente impresión
+println("Hola mundo!")
+println(10)
+// Hola mundo!
+// 10
+
+// Así imprimimos sin forzar una nueva linea en la siguiente impresión
+print("Hola mundo")
+print(10)
+// Hola mundo10
+
+// Para declarar valores usamos var o val.
+// Valores decalrados con val son inmutables, mientras que los declarados con var son mutables.
+// La inmutabilidad es algo bueno.
+val x = 10 // x es 10
+x = 20 // error: reassignment to val
+var y = 10
+y = 20 // y es 20
+
+/*
+ Scala es un lenguaje tipado estáticamente, aunque se puede ver en las expresiones anteriores que no hemos especificado un tipo.
+ Esto es debido a una funcionalidad del lenguaje llamada inferencia. En la mayoría de los casos, el compilador de Scala puede adivinar cual es el tipo de una variable, así que no hace falta escribirlo siempre.
+ Podemos declarar explicitamente el tipo de una variable de la siguiente manera:
+*/
+val z: Int = 10
+val a: Double = 1.0
+
+// Observa la conversión automática de Int a Double, el resultado será 10.0, no 10
+val b: Double = 10
+
+// Valores Booleanos
+true
+false
+
+// Operaciones Booleanas
+!true // false
+!false // true
+true == false // false
+10 > 5 // true
+
+// Las operaciones matemáticas se realizan como siempre
+1 + 1 // 2
+2 - 1 // 1
+5 * 3 // 15
+6 / 2 // 3
+6 / 4 // 1
+6.0 / 4 // 1.5
+6 / 4.0 // 1.5
+
+
+// Evaluar una expresión en REPL te da el tipo y valor del resultado
+
+1 + 7
+
+/* La linea superior tienen como resultado:
+
+ scala> 1 + 7
+ res29: Int = 8
+
+ Esto quiere decir que el resultado de evaluar 1 + 7 es un objeto de tipo Int con valor 8
+
+ Observa que "res29" es un nombre de variable secuencialmente generado para almacenar los resultados de las expresiones escritas, la salida que observes puede diferir en este sentido.
+*/
+
+"Las cadenas en Scala están rodeadas por comillas dobles"
+'a' // Un caracter en Scala
+// 'Las cadenas con comillas simples no existen' <= Esto causa un error
+
+// Las cadenas tienen los los típicos metodos de Java definidos
+"hello world".length
+"hello world".substring(2, 6)
+"hello world".replace("C", "3")
+
+// También tienen algunos métodos extra de Scala. Ver: scala.collection.immutable.StringOps
+"hello world".take(5)
+"hello world".drop(5)
+
+// Interpolación de cadenas: Observa el prefijo "s"
+val n = 45
+s"Tengo $n manzanas" // => "Tengo 45 manzanas"
+
+// Es posible colocar expresiones dentro de cadenas interpoladas
+val a = Array(11, 9, 6)
+s"Mi segunda hija tiene ${a(0) - a(2)} años." // => "Mi segunda hija tiene 5 años."
+s"Hemos doblado la cantidad de ${n / 2.0} manzanas." // => "Hemos doblado la cantidad de 22.5 manzanas."
+s"Potencia de 2: ${math.pow(2, 2)}" // => "Potencia de 2: 4"
+
+// Podemos formatear cadenas interpoladas con el prefijo "f"
+f"Potencia de 5: ${math.pow(5, 2)}%1.0f" // "Potencia de 5: 25"
+f"Raiz cuadrada de 122: ${math.sqrt(122)}%1.4f" // "Raiz cuadrada de 122: 11.0454"
+
+// Las cadenas puras ignoran caracteres especiales.
+raw"Nueva linea: \n. Retorno: \r." // => "Nueva linea: \n. Retorno: \r."
+
+// Algunos caracteres necesitn ser escapados, por ejemplo unas comillas dobles dentro de una cadena:
+"Se quedaron fuera de \"Rose and Crown\"" // => "Se quedaron fuera de "Rose and Crown""
+
+// Las triples comillas dobles dejan que las cadenas se expandan por multiples filas y contengan comillas dobles o simples
+val html = """<form id="daform">
+ <p>Press belo', Joe</p>
+ <input type="submit">
+ </form>"""
+
+
+/////////////////////////////////////////////////
+// 2. Funciones
+/////////////////////////////////////////////////
+
+// Las funciones se definen de la siguiente manera:
+//
+// def nombreFuncion(argumentos...): TipoRetorno = { cuerpo... }
+//
+// Si estás acostumbrado a lenguajes más tradicionales, observa la omisión de la palabra return.
+// En Scala, la última expresión en el bloque de función es el valor de retorno.
+def sumaDeCuadrados(x: Int, y: Int): Int = {
+ val x2 = x * x
+ val y2 = y * y
+ x2 + y2
+}
+
+// Los { } pueden omitirse si el cuerpo de la función es una única expresión:
+def sumaDeCuadradosCorta(x: Int, y: Int): Int = x * x + y * y
+
+// La sintaxis para llamar funciones es familiar:
+sumaDeCuadrados(3, 4) // => 25
+
+// Puedes usar los nombres de los parámetros para llamarlos en orden diferente
+def restar(x: Int, y: Int): Int = x - y
+
+restar(10, 3) // => 7
+restar(y=10, x=3) // => -7
+
+// En la mayoría de los casos (siendo las funciones recursivas la excepción más notable),
+// el tipo de retorno de la función puede ser omitido, y la misma inferencia de tipos que vimos con las variables
+// funcionará con los valores de retorno de las funciones:
+def sq(x: Int) = x * x // El compilador puede adivinar que el tipo de retorno es Int
+
+// Las funciones pueden tener parametros por defecto:
+def sumarConDefecto(x: Int, y: Int = 5) = x + y
+sumarConDefecto(1, 2) // => 3
+sumarConDefecto(1) // => 6
+
+
+// Las funciones anónimas se escriben así:
+(x: Int) => x * x
+
+// Al contrario que los defs, incluso el tipo de entrada de las funciones anónimas puede ser omitido si
+// el contexto lo deja claro. Observa el tipo "Int => Int" que significa que es una función
+// que recibe Int y retorna Int.
+val sq: Int => Int = x => x * x
+
+// Las funciones anónimas pueden ser llamadas como las demás:
+sq(10) // => 100
+
+// Si cada argumento en tu función anónima es usado solo una vez,
+// Scala te da una manera incluso más corta de definirlos.
+// Estas funciones anónimas son extremadamente comunes,
+// como será obvio en la sección de estructuras de datos.
+val sumarUno: Int => Int = _ + 1
+val sumaRara: (Int, Int) => Int = (_ * 2 + _ * 3)
+
+sumarUno(5) // => 6
+sumaRara(2, 4) // => 16
+
+
+// La palabra return existe en Scala, pero solo retorna desde la función más interna que la rodea.
+// ADVERTENCIA: Usar return en Scala puede inducir a errores y debe ser evitado
+// No tiene efecto en funciones anónimas. Por ejemplo:
+def foo(x: Int): Int = {
+ val funcAnon: Int => Int = { z =>
+ if (z > 5)
+ return z // Esta línea hace que z sea el valor de retorno de foo!
+ else
+ z + 2 // Esta línea es el valor de retorno de funcAnon
+ }
+ anonFunc(x) // Esta línea es el valor de retorno de foo
+}
+
+
+/////////////////////////////////////////////////
+// 3. Control del flujo
+/////////////////////////////////////////////////
+
+1 to 5
+val r = 1 to 5
+r.foreach(println)
+
+r foreach println
+// Nota: Scala es un lenguaje muy permisivo cuando se trata de puntos y parentesis - estudia las
+// reglas separadamente. Esto ayuda a escribir DSLs y APIs que se lean en lenguaje natural.
+
+// Por qué `println` no necesita parámetros aquí?
+// Presta atención a las funciones de primera clase en la sección de Programación Funcional más abajo!
+(5 to 1 by -1) foreach (println)
+
+// Un bucle while
+var i = 0
+while (i < 10) { println("i " + i); i += 1 }
+
+while (i < 10) { println("i " + i); i += 1 } // Si, de nuevo. Qué ocurrió? Por qué?
+
+i // Muestra el valor de i. Observa que while es un loop en el sentido clásico -
+ // se ejecuta secuencialmente mientras cambia la variable del bucle. while es muy
+ // rápido, pero los combinadores y comprensiones anteriores son más sencillos
+ // de entender y paralelizar
+
+// Un bucle do-while
+i = 0
+do {
+ println("i es aún menor que 10")
+ i += 1
+} while (i < 10)
+
+// La recursion es la manera idiomática de repetir una acción en Scala (como en la mayoría de
+// lenguajes funcionales).
+// Las funciones recursivas necesitan un tipo de retorno explicito, el compilador no puede inferirlo.
+// En Scala tenemos Unit, que es análogo al tipo de retorno `void` en Java
+def enseñaNumerosEnUnRango(a: Int, b: Int): Unit = {
+ print(a)
+ if (a < b)
+ enseñaNumerosEnUnRango(a + 1, b)
+}
+enseñaNumerosEnUnRango(1, 14)
+
+
+// Condicionales
+
+val x = 10
+
+if (x == 1) println("yeah")
+if (x == 10) println("yeah")
+if (x == 11) println("yeah")
+if (x == 11) println("yeah") else println("nay")
+
+println(if (x == 10) "yeah" else "nope")
+val text = if (x == 10) "yeah" else "nope"
+
+
+/////////////////////////////////////////////////
+// 4. Estructuras de datos
+/////////////////////////////////////////////////
+
+val a = Array(1, 2, 3, 5, 8, 13)
+a(0) // Int = 1
+a(3) // Int = 5
+a(21) // Lanza una excepción
+
+val m = Map("fork" -> "tenedor", "spoon" -> "cuchara", "knife" -> "cuchillo")
+m("fork") // java.lang.String = tenedor
+m("spoon") // java.lang.String = cuchara
+m("bottle") // Lanza una excepción
+
+val mapaSeguro = m.withDefaultValue("no lo se")
+mapaSeguro("bottle") // java.lang.String = no lo se
+
+val s = Set(1, 3, 7)
+s(0) // Boolean = false
+s(1) // Boolean = true
+
+/* Hecha un vistazo a la documentación de Map aquí -
+ * http://www.scala-lang.org/api/current/index.html#scala.collection.immutable.Map
+ * y asegúrate de que puedes leerla
+ */
+
+
+// Tuplas
+
+(1, 2)
+
+(4, 3, 2)
+
+(1, 2, "three")
+
+(a, 2, "three")
+
+// Por qué tener esto?
+val dividirEnteros = (x: Int, y: Int) => (x / y, x % y)
+
+// La función dividirEnteros te da el resultado y el resto
+dividirEnteros(10, 3) // (Int, Int) = (3,1)
+
+// Para acceder a los elementos de una tupla, usa _._n donde n es el indice (comenzando por 1)
+// del elemento
+val d = dividirEnteros(10, 3) // (Int, Int) = (3,1)
+
+d._1 // Int = 3
+d._2 // Int = 1
+
+// Alternativamente puedes asignar multiples variables desde una tupla, lo que
+// resulta más conveniente y legible en muchos casos.
+val (div, mod) = dividirEnteros(10, 3)
+
+div // Int = 3
+mod // Int = 1
+
+
+/////////////////////////////////////////////////
+// 5. Programación Orientada a Objetos
+/////////////////////////////////////////////////
+
+/*
+ Nota: Todo lo que hemos hecho hasta ahora en este tutorial han sido
+ simples expresiones (valores, funciones, etc). Estas expresiones son validas
+ para hacer pruebas rapidas en el interprete de la linea de comandos,
+ pero no pueden existir por si solas en un archivo de Scala. Por ejemplo,
+ no puedes tener simplemente "val x = 5" en un archivo Scala. En lugar de eso,
+ las únicas construcciones de alto nivel en Scala son:
+
+ - Objetos
+ - Clases
+ - Case clases
+ - Traits
+
+ Y ahora explicaremos lo que son estas.
+*/
+
+// Las clases son similares a las clases de otros lenguajes. Los argumentos del constructor
+// son declarados despues del nombre de la clase, y la inicialización se hace en el cuerpo de la clase.
+class Perro(r: String) {
+ // Código del constructor aquí
+ var raza: String = r
+
+ // Define un método llamado ladrar, que devuelva un String
+ def ladrar = "Woof, woof!"
+
+ // Los valores y métodos son asumidos como públicos.
+ // Las palabras "protected" y "private" también son válidas.
+ private def dormir(horas: Int) =
+ println(s"Estoy durmiendo $horas horas")
+
+ // Los métodos abstractos son simplemente métodos sin cuerpo.
+ // Si descomentamos la linea de debajo, la clase Perro necesitaría ser abstracta:
+ // abstract class Perro(...) { ... }
+ // def perseguir(algo: String): String
+}
+
+val miperro = new Dog("greyhound")
+println(mydog.raza) // => "greyhound"
+println(mydog.ladrar) // => "Woof, woof!"
+
+
+// La palabra "object" crea un tipo y una instancia singleton de ese tipo.
+// Es común que las clases en Scala tengan un "companion object", de manera que
+// el comportamiento por instancia es controlado por las clases y el comportamiento
+// relacionado a todas las instancias de esa clase es controlado por el objeto
+// La relación es similar a los métodos de las clases con los métodos estáticos
+// en otros lenguajes. Observa que los objetos y clases pueden tener el mismo nombre.
+object Perro {
+ def todasLasRazasConocidas = List("pitbull", "shepherd", "retriever")
+ def crearPerro(raza: String) = new Dog(breed)
+}
+
+
+// Case clases son clases que tienen funcionalidad extra añadida. Una pregunta
+// común para los principiantes en Scala es cuando usar case clases y cuando usar
+// clases. La linea no está bien definida, pero en general, las clases tienden a
+// enfocarse en la encapsulación, polimorfismo y comportamiento. Los valores en
+// estas clases tienden a ser privados, y solo se exponen los métodos.
+// El propósito principal de las case clases es tener datos inmutables.
+// A menudo tienen pocos métodos, y los métodos raramente tienen efectos secundarios.
+case class Persona(nombre: String, telefono: String)
+
+// Para crear instancia nuevas, observa que las case clases no necesitan "new"
+val george = Persona("George", "1234")
+val kate = Persona("Kate", "4567")
+
+// Con las case clases tienes unas pocas ventajas, como el acceso a los campos:
+george.telefono // => "1234"
+
+// Para la igualdad de campos no necesitas sobreescribir el método equals
+Persona("George", "1234") == Persona("Kate", "1236") // => false
+
+// Manera fácil de copiar
+// otroGeorge == Persona("George", "9876")
+val otroGeorge = george.copy(telefono = "9876")
+
+// Y muchas otras. Las case clases también tienen comparación de patrones, que veremos más abajo.
+
+// Traits
+// De manera similar a las interfaces Java, los traits definen un tipo de objeto y métodos.
+// Scala permite la implementación parcial de dichos métodos.
+// No se permiten parámetros de constructor. Los traits pueden heredar de otros traits o
+// clases sin parámetros.
+
+trait Perro {
+ def raza: String
+ def color: String
+ def ladra: Boolean = true
+ def muerde: Boolean
+}
+class SanBernardo extends Perro {
+ val raza = "San Bernardo"
+ val color = "marrón"
+ def muerde = false
+}
+
+scala> b
+res0: SanBernardo = SanBernardo@3e57cd70
+scala> b.raza
+res1: String = San Bernardo
+scala> b.ladra
+res2: Boolean = true
+scala> b.muerde
+res3: Boolean = false
+
+// Un trait tambien puede ser usado mezclado con otros traits.
+// La clase extiende el primer trait, pero la palabra "with"
+// puede añadir traits adicionales.
+
+trait Ladra {
+ def ladra: String = "Guau"
+}
+trait Perro {
+ def raza: String
+ def color: String
+}
+class SanBernardo extends Perro with Ladra {
+ val raza = "San Bernardo"
+ val color = "marrón"
+}
+
+scala> val b = new SanBernardo
+b: SanBernardo = SanBernardo@7b69c6ba
+scala> b.ladra
+res0: String = Guau
+
+
+/////////////////////////////////////////////////
+// 6. Comparación de patrones
+/////////////////////////////////////////////////
+
+// La comparación de patrones es una poderosa función de Scala.
+// Ahora veremos como comparar patrones en una case clase.
+// Nota: A diferencia de otros lenguajes, Scala "cases" no necesitan
+// "break", porque no ejecuta los "case" posteriores.
+
+def comparaPersona(persona: Persona): String = persona match {
+ // Aqui especificas los patrones:
+ case Persona("George", telefono) => "Hemos encontrado a George! Su número es " + telefono
+ case Persona("Kate", telefono) => "Hemos encontrado a Kate! Su número es " + telefono
+ case Persona(nombre, telefono) => "Hemos encontrado alguien : " + nombre + ", teléfono : " + telefono
+}
+
+// Las expresiones regulares también están incorporadas.
+// Creas una expresión regular con el método `r` en una cadena:
+val email = "(.*)@(.*)".r
+
+// La comparación de patrones puede parecerse al bloque switch en la familia de lenguajes de C,
+// pero aquí es mucho más poderosa. En Scala, puedes hacer más comparaciones:
+def comparaTodo(obj: Any): String = obj match {
+ // Puedes comparar valores:
+ case "Hola mundo" => "Tengo la cadena Hola mundo"
+
+ // Puedes comparar tipos:
+ case x: Double => "Tengo un double: " + x
+
+ // Puedes especificar condiciones:
+ case x: Int if x > 10000 => "Tengo un número muy grande!"
+
+ // Puedes comparar case clases como antes:
+ case Persona(nombre, telefono) => s"Tengo la información de contacto de $nombre!"
+
+ // Puedes comparar expresiones regulares:
+ case email(nombre, dominio) => s"Tengo la dirección de correo $nombre@$dominio"
+
+ // Puedes comparar tuplas:
+ case (a: Int, b: Double, c: String) => s"Tengo la tupla: $a, $b, $c"
+
+ // Puedes comparar estructuras:
+ case List(1, b, c) => s"Tengo un alista con tres elementos que empieza con 1: 1, $b, $c"
+
+ // Puedes anidar patrones:
+ case List(List((1, 2, "YAY"))) => "Tengo una lista de listas de tuplas"
+
+ // Comparar cualquier case (default) si todos los anteriores no han coincido
+ case _ => "Tengo un objeto desconocido"
+}
+
+// De hecho puedes comparar un patrón con cualquier objeto con el método "unapply".
+// Esta función es tan poderosa que Scala te deja definir funciones enteras como patrones:
+val funcPatron: Person => String = {
+ case Persona("George", telefono) => s"Teléfono de George: $telefono"
+ case Persona(nombre, telefono) => s"Teléfono de una persona aleatoria: $telefono"
+}
+
+
+/////////////////////////////////////////////////
+// 7. Programación funcional
+/////////////////////////////////////////////////
+
+// Scala permite a los métodos y funciones devolver o
+// recibir como parámetros otras funciones o métodos
+
+val suma10: Int => Int = _ + 10 // Una función que recibe y devuelve un Int
+List(1, 2, 3) map suma10 // List(11, 12, 13) - suma10 es aplicado a cada elemento
+
+// Las funciones anónimas pueden ser usadas en vez de funciones con nombre:
+List(1, 2, 3) map (x => x + 10)
+
+// Y la barra baja puede ser usada si solo hay un argumento en la función anónima.
+// Se usa como la variable.
+List(1, 2, 3) map (_ + 10)
+
+// Si el bloque anónimo Y la función que estás usando usan los dos un argumento,
+// puedes incluso omitir la barra baja.
+List("Dom", "Bob", "Natalia") foreach println
+
+
+// Combinadores
+// Usando s de arriba:
+// val s = Set(1, 3, 7)
+
+s.map(sq)
+
+val sCuadrado = s. map(sq)
+
+sSquared.filter(_ < 10)
+
+sSquared.reduce (_+_)
+
+// La función filter toma un predicado (una función A -> Boolean) y
+// selecciona todos los elementos que satisfacen el predicado.
+List(1, 2, 3) filter (_ > 2) // List(3)
+case class Persona(nombre: String, edad: Int)
+List(
+ Persona(nombre = "Dom", edad = 23),
+ Persona(nombre = "Bob", edad = 30)
+).filter(_.edad > 25) // List(Persona("Bob", 30))
+
+
+// Ciertas colecciones (como List) en Scala tienen un método `foreach`,
+// que toma como argumento un tipo que devuelva Unit (un método void)
+val unaListaDeNumeros = List(1, 2, 3, 4, 10, 20, 100)
+unaListaDeNumeros foreach (x => println(x))
+unaListaDeNumeros foreach println
+
+// Para comprensiones
+
+for { n <- s } yield sq(n)
+
+val nCuadrado2 = for { n <- s } yield sq(n)
+
+for { n <- nSquared2 if n < 10 } yield n
+
+for { n <- s; nSquared = n * n if nSquared < 10} yield nSquared
+
+/* Nota: Esos no son bucles. La semántica de un bucle es repetir, mientras que un for de comprension define una relación entre dos conjuntos de datos.*/
+
+
+/////////////////////////////////////////////////
+// 8. Implicitos
+/////////////////////////////////////////////////
+
+/* ATENCIÓN ATENCIÓN: Los implicitos son un conjunto de poderosas características de Scala
+ * y es fácil abusar de ellos. Si eres principiante en Scala deberías resistir la tentación
+ * de usarlos hasta que entiendas no solo como funcionan, sino también las mejores prácticas
+ * con ellos. Nosotros solo incluiremos esta sección en el tutorial porque son tan comunes
+ * en las librerias de Scala que es imposible hacer algo significativo sin usar una librería
+ * que tenga implicitos. Esto es para que entiendas como funcionan los implicitos, no para
+ * que definas los tuyos propios.
+ */
+
+// Cualquier valor (val, funciones, objetos, etc) puede ser declarado como implicito usando
+// la palabra "implicit". Observa que usamos la clase Perro de la sección 5.
+implicit val miEnteroImplicito = 100
+implicit def miFunciónImplicita(raza: String) = new Perro("Golden " + raza)
+
+// Por si misma, la palabra implicit no cambia el comportamiento de un valor,
+// así que estos valores pueden ser usados como siempre.
+miEnteroImplicito + 2 // => 102
+miFunciónImplicita("Pitbull").raza // => "Golden Pitbull"
+
+// La diferencia es que estos valores ahora pueden ser usados cuando otra pieza de código
+// necesite un valor implicito. Una situación así puede darse con argumentos implicitos de función:
+def enviaSaludos(aQuien: String)(implicit cuantos: Int) =
+ s"Hola $aQuien, $cuantos saludos a ti y a los tuyos!"
+
+// Si proporcionamos un valor para "cuantos", la función se comporta como siempre
+enviaSaludos("John")(1000) // => "Hola John, 1000 saludos a ti y a los tuyos!"
+
+// Pero si omitimos el parámetro implicito, un valor implicito del mismo tipo es usado,
+// en este caso, "miEnteroImplicito":
+enviaSaludos("Jane") // => "Hello Jane, 100 blessings to you and yours!"
+
+// Los parámetros de función implicit nos permiten simular clases tipo en otros lenguajes funcionales.
+// Es usado tan a menudo que tiene su propio atajo. Las dos siguientes lineas significan lo mismo:
+// def foo[T](implicit c: C[T]) = ...
+// def foo[T : C] = ...
+
+
+// Otra situación en la que el compilador busca un implicit es si tienes
+// obj.método(...)
+// pero "obj" no tiene "método" como un método. En este caso, si hay una conversión
+// implicita de tipo A => B, donde A es el tipo de obj y B tiene un método llamado
+// "método", esa conversión es aplicada. Así que teniendo miFunciónImplicita, podemos decir:
+"Retriever".raza // => "Golden Retriever"
+"Sheperd".ladra // => "Woof, woof!"
+
+// Aquí la cadena es convertida primero a Perro usando nuestra función miFunciónImplicita,
+// y entonces el método apropiado es llamado. Esta es una herramienta extremadamente poderosa
+// pero de nuevo, no puede usarse con ligereza. De hecho, cuando definiste la función implicita,
+// tu compilador debería haber mostrado una advertencia, diciendo que no deberías hacer esto
+// a no ser que realmente sepas lo que estás haciendo.
+
+/////////////////////////////////////////////////
+// 9. Misc
+/////////////////////////////////////////////////
+
+// Importando cosas
+import scala.collection.immutable.List
+
+// Importando todos los "sub paquetes"
+import scala.collection.immutable._
+
+// Importando multiples clases en una línea
+import scala.collection.immutable.{List, Map}
+
+// Renombrar un import usando '=>'
+import scala.collection.immutable.{List => ImmutableList}
+
+// Importar todas las clases, excepto algunas. La siguiente linea excluye Map y Set:
+import scala.collection.immutable.{Map => _, Set => _, _}
+
+// Las clases de Java pueden ser importadas también con sintaxis de Scala:
+import java.swing.{JFrame, JWindow}
+
+// El punto de entrada de tus programas está definido en un fichero scala usando un object,
+// con un solo método, main:
+object Application {
+ def main(args: Array[String]): Unit = {
+ // Aquí va tu código.
+ }
+}
+
+// Los ficheros pueden contener multiples clases y objetos. Compila con scalac
+
+
+// Salida y entrada
+
+// Leer un fichero línea por línea
+import scala.io.Source
+for(line <- Source.fromFile("miarchivo.txt").getLines())
+ println(line)
+
+// Para escribir un archivo usa el PrintWriter de Java
+val writer = new PrintWriter("miarchivo.txt")
+writer.write("Escribiendo linea por linea" + util.Properties.lineSeparator)
+writer.write("Otra linea" + util.Properties.lineSeparator)
+writer.close()
+
+```
+
+## Más recursos
+
+* [Scala para los impacientes](http://horstmann.com/scala/)
+* [Escuela de Scala en Twitter](http://twitter.github.io/scala_school/)
+* [La documentación de Scala](http://docs.scala-lang.org/)
+* [Prueba Scala en tu navegador](http://scalatutorials.com/tour/)
+* Unete al [grupo de usuarios de Scala](https://groups.google.com/forum/#!forum/scala-user)
diff --git a/es-es/visualbasic-es.html.markdown b/es-es/visualbasic-es.html.markdown
index ca00626b..c677c20f 100644
--- a/es-es/visualbasic-es.html.markdown
+++ b/es-es/visualbasic-es.html.markdown
@@ -4,8 +4,6 @@ contributors:
- ["Brian Martin", "http://brianmartin.biz"]
translators:
- ["Adolfo Jayme Barrientos", "https://github.com/fitojb"]
-author: Brian Martin
-author_url: https://github.com/fitojb
filename: learnvisualbasic-es.vb
lang: es-es
---