diff options
Diffstat (limited to 'es-es')
| -rw-r--r-- | es-es/c++-es.html.markdown | 829 | ||||
| -rw-r--r-- | es-es/git-es.html.markdown | 166 | ||||
| -rw-r--r-- | es-es/go-es.html.markdown | 618 | ||||
| -rw-r--r-- | es-es/javascript-es.html.markdown | 12 | ||||
| -rw-r--r-- | es-es/julia-es.html.markdown | 1268 | ||||
| -rw-r--r-- | es-es/python-es.html.markdown | 120 | 
6 files changed, 2107 insertions, 906 deletions
| diff --git a/es-es/c++-es.html.markdown b/es-es/c++-es.html.markdown new file mode 100644 index 00000000..bcc775e5 --- /dev/null +++ b/es-es/c++-es.html.markdown @@ -0,0 +1,829 @@ +--- +language: c++ +filename: learncpp.cpp +contributors: +    - ["Steven Basart", "http://github.com/xksteven"] +    - ["Matt Kline", "https://github.com/mrkline"] +    - ["Geoff Liu", "http://geoffliu.me"] +    - ["Connor Waters", "http://github.com/connorwaters"] +translators: +    - ["Gerson Lázaro", "https://gersonlazaro.com"] +lang: es-es +--- + +C++ es un lenguaje de programación de sistemas que, +[de acuerdo a su inventor Bjarne Stroustrup](http://channel9.msdn.com/Events/Lang-NEXT/Lang-NEXT-2014/Keynote), +fue diseñado para + +- ser un "mejor C" +- soportar abstracción de datos +- soportar programación orientada a objetos +- soportar programación genérica + +Aunque su sintaxis puede ser más difícil o compleja que los nuevos lenguajes,  +es ampliamente utilizado, ya que compila instrucciones nativas que pueden ser  +directamente ejecutadas por el procesador y ofrece un estricto control sobre  +el hardware (como C), mientras ofrece características de alto nivel como  +genericidad, excepciones, y clases. Esta combinación de velocidad y  +funcionalidad hace de C ++ uno de los lenguajes de programación más utilizados. + +```c++ +//////////////////// +// Comparación con C +//////////////////// + +// C ++ es _casi_ un superconjunto de C y comparte su sintaxis básica para las  +// declaraciones de variables, tipos primitivos y funciones. + +// Al igual que en C, el punto de entrada de tu programa es una función llamada  +// main con un retorno de tipo entero.  +// Este valor sirve como código de salida del programa. +// Mira http://en.wikipedia.org/wiki/Exit_status para mayor información. +int main(int argc, char** argv) +{ +	// Los argumentos de la línea de comandos se pasan por argc y argv de la  +	// misma manera que en C. +	// argc indica el número de argumentos,  +	// y argv es un arreglo de strings de estilo C (char*)  +	// representando los argumentos. +	// El primer argumento es el nombre con el que el programa es llamado. +	// argc y argv pueden omitirse si no te preocupan los argumentos,  +	// dejando la definición de la función como int main () + +	// Un estado de salida 0 indica éxito. +    return 0; +} + +// Sin embargo, C ++ varía en algunas de las siguientes maneras: + +// En C++, los caracteres literales son caracteres +sizeof('c') == sizeof(char) == 1 + +// En C, los caracteres literales son enteros +sizeof('c') == sizeof(int) + + +// C++ tiene prototipado estricto +void func(); // función que no acepta argumentos + +// En C +void func(); // función que puede aceptar cualquier número de argumentos + +// Use nullptr en lugar de NULL en C++ +int* ip = nullptr; + +// Las cabeceras (headers) estándar de C están disponibles en C ++,  +// pero tienen el prefijo "c" y no tienen sufijo .h. +#include <cstdio> + +int main() +{ +    printf("Hola mundo!\n"); +    return 0; +} + +////////////////////////// +// Sobrecarga de funciones +////////////////////////// + +// C++ soporta sobrecarga de funciones +// siempre que cada función tenga diferentes parámetros. + +void print(char const* myString) +{ +    printf("String %s\n", myString); +} + +void print(int myInt) +{ +    printf("Mi entero es %d", myInt); +} + +int main() +{ +    print("Hello"); // Resolves to void print(const char*) +    print(15); // Resolves to void print(int) +} + +//////////////////////////////////// +// Argumentos de función por defecto +//////////////////////////////////// + +// Puedes proporcionar argumentos por defecto para una función si no son  +// proporcionados por quien la llama. + +void doSomethingWithInts(int a = 1, int b = 4) +{ +    // Hacer algo con los enteros aqui +} + +int main() +{ +    doSomethingWithInts();      // a = 1,  b = 4 +    doSomethingWithInts(20);    // a = 20, b = 4 +    doSomethingWithInts(20, 5); // a = 20, b = 5 +} + +// Los argumentos predeterminados deben estar al final de la lista de argumentos. + +void invalidDeclaration(int a = 1, int b) // Error! +{ +} + +///////////////////// +// Espacios de nombre +///////////////////// + +// Espacios de nombres proporcionan ámbitos separados para variable, función y  +// otras declaraciones. +// Los espacios de nombres se pueden anidar. + +namespace First { +    namespace Nested { +        void foo() +        { +            printf("Esto es First::Nested::foo\n"); +        } +    } // fin del nombre de espacio Nested +} // fin del nombre de espacio First + +namespace Second { +    void foo() +    { +        printf("Esto es Second::foo\n") +    } +} + +void foo() +{ +    printf("Este es global: foo\n"); +} + +int main() +{ + +	// Incluye todos los símbolos del espacio de nombre Second en el ámbito  +	// actual. Tenga en cuenta que simplemente foo() no funciona, ya que ahora  +	// es ambigua si estamos llamando a foo en espacio de nombres Second o en +	// el nivel superior. +    using namespace Second; + +    Second::foo(); // imprime "Esto es Second::foo" +    First::Nested::foo(); // imprime "Esto es First::Nested::foo" +    ::foo(); // imprime "Este es global: foo" +} + +///////////////// +// Entrada/Salida +///////////////// + +// La entrada y salida de C++ utiliza flujos (streams) +// cin, cout, y cerr representan a stdin, stdout, y stderr. +// << es el operador de inserción >> es el operador de extracción. + + +#include <iostream> // Incluir para el flujo de entrada/salida + +using namespace std; // Los streams estan en std namespace (libreria estandar) + +int main() +{ +   int myInt; + +   // Imprime a la stdout (o terminal/pantalla) +   cout << "Ingresa tu número favorito:\n"; +   // Toma una entrada +   cin >> myInt; + +   // cout puede también ser formateado +   cout << "Tu número favorito es " << myInt << "\n"; +   // imprime "Tu número favorito es <myInt>" + +    cerr << "Usado para mensajes de error"; +} +//////////////////// +// Cadenas (Strings) +//////////////////// + +// Las cadenas en C++ son objetos y tienen muchas funciones +#include <string> + +using namespace std; // Strings también estan en namespace std + +string myString = "Hola"; +string myOtherString = " Mundo"; + +// + es usado para concatenar. +cout << myString + myOtherString; // "Hola Mundo" + +cout << myString + " Tu"; // "Hola Tu" + +// Las cadenas en C++ son mutables y tienen valor semántico. +myString.append(" Perro"); +cout << myString; // "Hola Perro" + + +////////////// +// Referencias +////////////// + +// Además de punteros como los de C, +// C++ tiene _references_. +// Estos tipos de puntero no pueden ser reasignados una vez establecidos +// Y no pueden ser nulos. +// También tienen la misma sintaxis que la propia variable: +// No es necesaria * para eliminar la referencia y +// & (dirección) no se utiliza para la asignación. + +using namespace std; + +string foo = "Yo soy foo"; +string bar = "Yo soy bar"; + +string& fooRef = foo; // Crea una referencia a foo. +fooRef += ". Hola!"; // Modifica foo través de la referencia +cout << fooRef; // Imprime "Yo soy foo. Hola!" + +// No trate de reasignar "fooRef". Esto es lo mismo que "foo = bar", y +//   foo == "Yo soy bar" +// después de esta linea. +fooRef = bar; + +const string& barRef = bar; // Crea una referencia constante a bar. +// Como en C, los valores constantes (y punteros y referencias) no pueden ser +// modificados. +barRef += ". Hola!"; // Error, referencia constante no puede ser modificada. + +// Sidetrack: Antes de hablar más sobre referencias, hay que introducir un  +// concepto llamado objeto temporal. Supongamos que tenemos el siguiente código: +string tempObjectFun() { ... } +string retVal = tempObjectFun(); + +// Lo que pasa en la segunda línea es en realidad: +// - Un objeto de cadena es retornado desde tempObjectFun +// - Una nueva cadena se construye con el objeto devuelto como argumento al +// constructor +// - El objeto devuelto es destruido +// El objeto devuelto se llama objeto temporal. Objetos temporales son +// creados cada vez que una función devuelve un objeto, y es destruido en el +// fin de la evaluación de la expresión que encierra (Bueno, esto es lo que la +// norma dice, pero los compiladores están autorizados a cambiar este  +// comportamiento. Busca "return value optimization" para ver mas detalles).  +// Así que en este código: +foo(bar(tempObjectFun())) + +// Suponiendo que foo y bar existen, el objeto retornado de tempObjectFun es +// pasado al bar, y se destruye antes de llamar foo. + +// Ahora, de vuelta a las referencias. La excepción a la regla "en el extremo  +// de la expresión encerrada" es si un objeto temporal se une a una  +// referencia constante, en cuyo caso su vida se extiende al ámbito actual: + +void constReferenceTempObjectFun() { +  // ConstRef obtiene el objeto temporal, y es válido hasta el final de esta +  // función. +  const string& constRef = tempObjectFun(); +  ... +} + +// Otro tipo de referencia introducida en C ++ 11 es específicamente para +// objetos temporales. No se puede tener una variable de este tipo, pero tiene  +// prioridad en resolución de sobrecarga: + +void someFun(string& s) { ... }  // Referencia regular +void someFun(string&& s) { ... }  // Referencia a objeto temporal + +string foo; +someFun(foo);  // Llama la función con referencia regular +someFun(tempObjectFun());  // Llama la versión con referencia temporal + +// Por ejemplo, puedes ver estas dos versiones de constructores para +// std::basic_string: +basic_string(const basic_string& other); +basic_string(basic_string&& other); + +// La idea es que si estamos construyendo una nueva cadena de un objeto temporal  +// (que va a ser destruido pronto de todos modos), podemos tener un constructor +// mas eficiente que "rescata" partes de esa cadena temporal. Usted verá este +// Concepto denominado "movimiento semántico". + +//////////////////////////////////////////// +// Clases y programación orientada a objetos +//////////////////////////////////////////// + +// Primer ejemplo de clases +#include <iostream> + +// Declara una clase. +// Las clases son usualmente declaradas en archivos de cabeceras (.h o .hpp) +class Dog { +    // Variables y funciones de la clase son privados por defecto. +    std::string name; +    int weight; + +// Todos los miembros siguientes de este son públicos +// Hasta que se encuentre "private" o "protected". +// All members following this are public +// until "private:" or "protected:" is found. +public: + +    // Constructor por defecto +    Dog(); + +	// Declaraciones de funciones de la clase (implementaciones a seguir) +    // Nota que usamos std::string aquí en lugar de colocar +    // using namespace std; +    // arriba. +    // Nunca ponga una declaración "using namespace" en un encabezado. +    void setName(const std::string& dogsName); + +    void setWeight(int dogsWeight); +	// Funciones que no modifican el estado del objeto +	// Deben marcarse como const. +	// Esto le permite llamarlas si se envia una referencia constante al objeto. +	// También tenga en cuenta que las funciones deben ser declaradas  +	// explícitamente como _virtual_ para que sea reemplazada en las clases  +	// derivadas. +	// Las funciones no son virtuales por defecto por razones de rendimiento.	 +    virtual void print() const; + +    // Las funciones también se pueden definir en el interior  +    // del cuerpo de la clase. +	// Funciones definidas como tales están entre líneas automáticamente. +    void bark() const { std::cout << name << " barks!\n"; } + +    // Junto a los constructores, C++ proporciona destructores. +	// Estos son llamados cuando un objeto se elimina o está fuera del ámbito. +	// Esto permite paradigmas potentes como RAII +	// (mira abajo) +	// El destructor debe ser virtual si una clase es dervada desde el; +	// Si no es virtual, entonces la clase derivada destructor +	// No será llamada si el objeto se destruye a través de una referencia de  +	// la clase base o puntero. +    virtual ~Dog(); + + + +}; // Un punto y coma debe seguir la definición de clase. + +// Las funciones de una clase son normalmente implementados en archivos .cpp. +Dog::Dog() +{ +    std::cout << "Un perro ha sido construido\n"; +} + +// Objetos (tales como cadenas) deben ser pasados por referencia +// Si los estas modificando o referencia constante en caso contrario. +void Dog::setName(const std::string& dogsName) +{ +    name = dogsName; +} + +void Dog::setWeight(int dogsWeight) +{ +    weight = dogsWeight; +} + +// Nota que "virtual" sólo se necesita en la declaración, no en la definición. +void Dog::print() const +{ +    std::cout << "El perro es " << name << " y pesa " << weight << "kg\n"; +} + +Dog::~Dog() +{ +    cout << "Adiós " << name << "\n"; +} + +int main() { +    Dog myDog; // imprime "Un perro ha sido construido" +    myDog.setName("Barkley"); +    myDog.setWeight(10); +    myDog.print(); // imprime "El perro es Barkley y pesa 10 kg" +    return 0; +} // imprime "Adiós Barkley" + +// Herencia: + +// Esta clase hereda todo lo público y protegido de la clase Dog +class OwnedDog : public Dog { + +    void setOwner(const std::string& dogsOwner); + +	// Reemplaza el comportamiento de la función de impresión  +	// de todos los OwnedDogs. Mira +	// http://en.wikipedia.org/wiki/Polymorphism_(computer_science)#Subtyping +	// Para una introducción más general si no está familiarizado con el +	// polimorfismo de subtipo. +	// La palabra clave override es opcional, pero asegura que estás +	// reemplazando el método de una clase base. +    void print() const override; + +private: +    std::string owner; +}; + +// Mientras tanto, en el archivo .cpp correspondiente: + +void OwnedDog::setOwner(const std::string& dogsOwner) +{ +    owner = dogsOwner; +} + +void OwnedDog::print() const +{ +    Dog::print(); // Llama a la función de impresión en la clase base Dog +    std::cout << "El perro es de " << owner << "\n"; +    // Imprime "El perro es <name> y pesa <weight>" +    //         "El perro es de <owner>" +} + +//////////////////////////////////////////// +// Inicialización y sobrecarga de operadores +//////////////////////////////////////////// + +// En C ++ se puede sobrecargar el comportamiento  +// de los operadores como +, -, *, /, etc. +// Esto se hace mediante la definición de una función que es llamada +// cada vez que se utiliza el operador. + +#include <iostream> +using namespace std; + +class Point { +public: +    // Las variables de la clase pueden dar valores por defecto de esta manera. +    double x = 0; +    double y = 0; + +	// Define un constructor por defecto que no hace nada +    // pero inicializa el punto al valor por defecto (0, 0) +    Point() { }; + +    // The following syntax is known as an initialization list +    // and is the proper way to initialize class member values +    Point (double a, double b) : +        x(a), +        y(b) +    { /* No hace nada excepto inicializar los valores */ } + +    // Sobrecarga el operador + +    Point operator+(const Point& rhs) const; + +    // Sobrecarga el operador += +    Point& operator+=(const Point& rhs); + +    // También tendría sentido añadir los operadores - y -=, +   	// Pero vamos a omitirlos por razones de brevedad. +}; + +Point Point::operator+(const Point& rhs) const +{ +    // Crea un nuevo punto que es la suma de este y rhs. +    return Point(x + rhs.x, y + rhs.y); +} + +Point& Point::operator+=(const Point& rhs) +{ +    x += rhs.x; +    y += rhs.y; +    return *this; +} + +int main () { +    Point up (0,1); +    Point right (1,0); +    // Llama al operador + de Point +    // Point llama la función + con right como parámetro +    Point result = up + right; +    // Prints "Result is upright (1,1)" +    cout << "Result is upright (" << result.x << ',' << result.y << ")\n"; +    return 0; +} + +///////////////////////// +// Plantillas (Templates) +///////////////////////// + +// Las plantillas en C++ se utilizan sobre todo en la programación genérica,  +// a pesar de que son mucho más poderoso que los constructores genéricos  +// en otros lenguajes. Ellos también soportan especialización explícita y  +// parcial y clases de tipo estilo funcional; de hecho, son un lenguaje  +// funcional Turing-completo incrustado en C ++! + +// Empezamos con el tipo de programación genérica que podría estar  +// familiarizado.  +// Para definir una clase o función que toma un parámetro de tipo: +template<class T> +class Box { +public: +    // En este caso, T puede ser usado como cualquier otro tipo. +    void insert(const T&) { ... } +}; + +// Durante la compilación, el compilador realmente genera copias de cada  +// plantilla con parámetros sustituidos, por lo que la definición completa  +// de la clase debe estar presente en cada invocación.  +// Es por esto que usted verá clases de plantilla definidas +// Enteramente en archivos de cabecera. + +//Para crear una instancia de una clase de plantilla en la pila: +Box<int> intBox; + +y puedes utilizarlo como era de esperar: +intBox.insert(123); + +// Puedes, por supuesto, anidar plantillas: +Box<Box<int> > boxOfBox; +boxOfBox.insert(intBox); + +// Hasta C++11, había que colocar un espacio entre los dos '>'s,  +// de lo contrario '>>' serían analizados como el operador de desplazamiento  +// a la derecha. + + +// A veces verás +//   template<typename T> +// en su lugar. La palabra clave "class" y las palabras clave "typename" son +// mayormente intercambiables en este caso. Para la explicación completa, mira +//   http://en.wikipedia.org/wiki/Typename +// (sí, esa palabra clave tiene su propia página de Wikipedia). + +// Del mismo modo, una plantilla de función: +template<class T> +void barkThreeTimes(const T& input) +{ +    input.bark(); +    input.bark(); +    input.bark(); +} + +// Observe que no se especifica nada acerca de los tipos de parámetros aquí.  +// El compilador generará y comprobará cada invocación de la plantilla,  +// por lo que la función anterior funciona con cualquier tipo "T"  +// que tenga un método 'bark' constante! + + +Dog fluffy; +fluffy.setName("Fluffy") +barkThreeTimes(fluffy); // Imprime "Fluffy barks" 3 veces. + +Los parámetros de la plantilla no tienen que ser las clases: +template<int Y> +void printMessage() { +  cout << "Aprende C++ en " << Y << " minutos!" << endl; +} + +// Y usted puede especializar explícitamente plantillas  +// para código más eficiente.  +// Por supuesto, la mayor parte del mundo real que utiliza una especialización  +// no son tan triviales como esta. +// Tenga en cuenta que usted todavía tiene que declarar la función (o clase)  +// como plantilla incluso si ha especificado de forma explícita todos  +// los parámetros. + +template<> +void printMessage<10>() { +  cout << "Aprende C++ rapido en solo 10 minutos!" << endl; +} + +printMessage<20>();  // Prints "Aprende C++ en 20 minutos!" +printMessage<10>();  // Prints "Aprende C++ rapido en solo 10 minutos!" + + +///////////////////// +// Manejador de excepciones +///////////////////// + +// La biblioteca estándar proporciona algunos tipos de excepción +// (mira http://en.cppreference.com/w/cpp/error/exception) +// pero cualquier tipo puede ser lanzado como una excepción +#include <exception> +#include <stdexcept> + +//Todas las excepciones lanzadas dentro del bloque _try_ pueden ser  +// capturados por los siguientes manejadores _catch_. +try { +    // No asignar excepciones en el heap usando _new_. +    throw std::runtime_error("Ocurrió un problema"); +} + +// Captura excepciones por referencia const si son objetos +catch (const std::exception& ex) +{ +    std::cout << ex.what(); +} +******************************************************************************** +// Captura cualquier excepción no capturada por bloques _catch_ anteriores +catch (...) +{ +    std::cout << "Excepción desconocida capturada"; +    throw; // Re-lanza la excepción +} + +/////// +// RAII +/////// + +// RAII significa "Resource Acquisition Is Initialization" +// (Adquisición de recursos es inicialización). +// A menudo se considera el paradigma más poderoso en C++ +// Y el concepto es simple: un constructor de un objeto +// Adquiere recursos de ese objeto y el destructor les libera. + +// Para entender cómo esto es útil, +// Considere una función que utiliza un identificador de archivo C: +void doSomethingWithAFile(const char* filename) +{ +    // Para empezar, asuma que nada puede fallar. + +    FILE* fh = fopen(filename, "r"); // Abre el archivo en modo lectura + +    doSomethingWithTheFile(fh); +    doSomethingElseWithIt(fh); + +    fclose(fh); // Cierra el manejador de archivos +} + +// Por desgracia, las cosas se complican rápidamente por el control de errores. +// Supongamos que fopen puede fallar, y que doSomethingWithTheFile y +// DoSomethingElseWithIt retornan códigos de error si fallan. +// 	(Excepciones son la mejor forma de manejar los fallos, +// 	 pero algunos programadores, especialmente los que tienen un fondo C, +// 	 estan en desacuerdo sobre la utilidad de las excepciones). +// Ahora tenemos que comprobar cada llamado por fallos y cerrar el manejador  +// del archivo si se ha producido un problema. +bool doSomethingWithAFile(const char* filename) +{ +    FILE* fh = fopen(filename, "r"); // Abre el archivo en modo lectura +    if (fh == nullptr) // El puntero retornado es nulo o falla. +        return false; // Reporta el fallo a quien hizo el llamado. + +    // Asume que cada función retorna falso si falla +    if (!doSomethingWithTheFile(fh)) { +        fclose(fh); // Cierre el manejador de archivo para que no se filtre. +        return false; // Propaga el error. +    } +    if (!doSomethingElseWithIt(fh)) { +        fclose(fh); // Cierre el manejador de archivo para que no se filtre. +        return false; // Propaga el error. +    } + +    fclose(fh); // Cierre el archivo. +    return true; // Indica que todo funcionó correctamente. +} + +// Programadores C suelen limpiar esto un poco usando goto: +bool doSomethingWithAFile(const char* filename) +{ +    FILE* fh = fopen(filename, "r"); +    if (fh == nullptr) +        return false; + +    if (!doSomethingWithTheFile(fh)) +        goto failure; + +    if (!doSomethingElseWithIt(fh)) +        goto failure; + +    fclose(fh); // Cierre el archivo. +    return true; // Indica que todo funcionó correctamente. + +failure: +    fclose(fh); +    return false; // Propagate el error +} + +// Si las funciones indican errores mediante excepciones, +// Las cosas son un poco más claras, pero pueden optimizarse mas. +void doSomethingWithAFile(const char* filename) +{ +    FILE* fh = fopen(filename, "r"); // Abrir el archivo en modo lectura +    if (fh == nullptr) +        throw std::runtime_error("No puede abrirse el archivo."); + +    try { +        doSomethingWithTheFile(fh); +        doSomethingElseWithIt(fh); +    } +    catch (...) { +        fclose(fh); // Asegúrese de cerrar el archivo si se produce un error. +        throw; // Luego vuelve a lanzar la excepción. +    } + +    fclose(fh); // Cierra el archivo +} + +// Compare esto con el uso de la clase de flujo de archivos de C++ (fstream) +// fstream utiliza su destructor para cerrar el archivo. +// Los destructores son llamados automáticamente  +// cuando un objeto queda fuera del ámbito. +void doSomethingWithAFile(const std::string& filename) +{ +    // ifstream es la abreviatura de el input file stream +    std::ifstream fh(filename); // Abre el archivo + +    // Hacer algo con el archivo +    doSomethingWithTheFile(fh); +    doSomethingElseWithIt(fh); + +} // El archivo se cierra automáticamente aquí por el destructor + + +// Esto tiene ventajas _enormes_: +// 1. No importa lo que pase, +//    El recurso (en este caso el manejador de archivo) será limpiado. +//    Una vez que escribes el destructor correctamente, +//    Es _imposible_ olvidar cerrar el identificador y permitir  +//    fugas del recurso. +// 2. Tenga en cuenta que el código es mucho más limpio. +//    El destructor se encarga de cerrar el archivo detrás de cámaras +//    Sin que tenga que preocuparse por ello. +// 3. El código es seguro. +//    Una excepción puede ser lanzado en cualquier lugar de la función +//    y la limpieza ocurrirá. + +// Todo el código idiomático C++ utiliza RAII ampliamente para todos los  +// recursos. +// Otros ejemplos incluyen +// - Memoria usando unique_ptr y shared_ptr +// - Contenedores (Containers) - la biblioteca estándar linked list, +//   vector (es decir, array con auto-cambio de tamaño), hash maps, etc. +//   Destruimos todos sus contenidos de forma automática  +//   cuando quedan fuera del ámbito. +// - Mutex utilizando lock_guard y unique_lock + + +///////////////////// +// Cosas divertidas +///////////////////// + +// Aspectos de C ++ que pueden sorprender a los recién llegados  +// (e incluso algunos veteranos). +// Esta sección es, por desgracia, salvajemente incompleta;  +// C++ es uno de los lenguajes con los que mas facil te disparas en el pie. + +// Tu puedes sobreescribir métodos privados! +class Foo { +  virtual void bar(); +}; +class FooSub : public Foo { +  virtual void bar();  // Sobreescribe Foo::bar! +}; + + +// 0 == false == NULL (La mayoria de las veces)! +bool* pt = new bool; +*pt = 0; // Establece los puntos de valor de 'pt' en falso. +pt = 0;  // Establece 'pt' al apuntador nulo. Ambas lineas compilan sin error. + +// nullptr se supone que arregla un poco de ese tema: +int* pt2 = new int; +*pt2 = nullptr; // No compila +pt2 = nullptr;  // Establece pt2 como null. + +// Hay una excepción para los valores bool. +// Esto es para permitir poner a prueba punteros nulos con if (!ptr), +// pero como consecuencia se puede asignar nullptr a un bool directamente! +*pt = nullptr;  // Esto todavía compila, a pesar de que '*pt' es un bool! + +// '=' != '=' != '='! +// Llama Foo::Foo(const Foo&) o alguna variante (mira movimientos semanticos)  +// copia del constructor. +Foo f2; +Foo f1 = f2; + +// Llama Foo::Foo(const Foo&) o variante, pero solo copia el 'Foo' parte de +// 'fooSub'. Cualquier miembro extra de 'fooSub' se descarta. Este  +// comportamiento horrible se llama "Corte de objetos." +FooSub fooSub; +Foo f1 = fooSub; + +// Llama a Foo::operator=(Foo&) o variantes. +Foo f1; +f1 = f2; + + +// Cómo borrar realmente un contenedor: +class Foo { ... }; +vector<Foo> v; +for (int i = 0; i < 10; ++i) +  v.push_back(Foo()); +// La siguiente línea establece el tamaño de v en 0,  +// pero los destructores no son llamados y los recursos no se liberan! + +v.empty(); +v.push_back(Foo());  // Nuevo valor se copia en el primer Foo que insertamos + +// En verdad destruye todos los valores en v.  +// Consulta la sección acerca de los objetos temporales para la +// explicación de por qué esto funciona. +v.swap(vector<Foo>()); + +``` +Otras lecturas: + +Una referencia del lenguaje hasta a la fecha se puede encontrar en +<http://cppreference.com/w/cpp> + +Recursos adicionales se pueden encontrar en <http://cplusplus.com> diff --git a/es-es/git-es.html.markdown b/es-es/git-es.html.markdown index 5c9d3378..18b544b4 100644 --- a/es-es/git-es.html.markdown +++ b/es-es/git-es.html.markdown @@ -11,15 +11,15 @@ lang: es-es  ---  Git es un sistema de control de versiones distribuido diseñado para manejar -cualquier tipo de proyecto ya sea largos o pequeños, con velocidad y eficiencia. +cualquier tipo de proyecto, ya sea grande o pequeño, con velocidad y eficiencia.  Git realiza esto haciendo "snapshots" del proyecto, con ello permite  versionar y administrar nuestro código fuente.  ## Versionamiento, conceptos. -### Que es el control de versiones? -El control de versiones es un sistema que guarda todos los cambios realizados a +### Qué es el control de versiones? +El control de versiones es un sistema que guarda todos los cambios realizados en  uno o varios archivos, a lo largo del tiempo.  ### Versionamiento centralizado vs Versionamiento Distribuido. @@ -31,15 +31,15 @@ uno o varios archivos, a lo largo del tiempo.  + El versionamiento distribuido no tiene una estructura definida, incluso se    puede mantener el estilo de los repositorios SVN con git. -[Informacion adicional](http://git-scm.com/book/es/Empezando-Acerca-del-control-de-versiones) +[Información adicional](http://git-scm.com/book/es/Empezando-Acerca-del-control-de-versiones) -### Por que usar Git? +### Por qué usar Git?  * Se puede trabajar sin conexion. -* Colaborar con otros es sencillo!. -* Derivar, Crear ramas del proyecto (aka: Branching) es facil!. -* Combinar (aka: Marging) -* Git es rapido. +* ¡Colaborar con otros es sencillo!. +* Derivar, crear ramas del proyecto (aka: Branching) es fácil. +* Combinar (aka: Merging) +* Git es rápido.  * Git es flexible.  ## Arquitectura de Git. @@ -48,10 +48,10 @@ uno o varios archivos, a lo largo del tiempo.  Un repositorio es un conjunto de archivos, directorios, registros, cambios (aka:  comits), y encabezados (aka: heads). Imagina que un repositorio es una clase, -y que sus atributos otorgan  acceso al historial del elemento, ademas de otras +y que sus atributos otorgan acceso al historial del elemento, además de otras  cosas. -Un repositorio esta compuesto por la carpeta .git y un "arbol de trabajo". +Un repositorio esta compuesto por la carpeta .git y un "árbol de trabajo".  ### Directorio .git (componentes del repositorio) @@ -62,38 +62,38 @@ y mas.  ### Directorio de trabajo (componentes del repositorio) -Es basicamente los directorios y archivos dentro del repositorio. La mayorioa de +Es basicamente los directorios y archivos dentro del repositorio. La mayoría de  las veces se le llama "directorio de trabajo". -### Inidice (componentes del directorio .git) +### Índice (componentes del directorio .git) -El inidice es la area de inicio en git. Es basicamente la capa que separa el -directorio de trabajo, del repositorio en git. Esto otorga a los desarrolladores -mas poder sobre lo que envia y recibe en el repositorio. +El índice es el área de inicio en git. Es basicamente la capa que separa el +directorio de trabajo del repositorio en git. Esto otorga a los desarrolladores +más poder sobre lo que se envía y se recibe del repositorio.  ### Commit (aka: cambios)  Un commit es una captura de un conjunto de cambios, o modificaciones hechas en -el directorio de trabajo. Por ejemplo, si se añaden 5 archivos, se remueven 2, -estos cambios se almacenaran en un commit (aka: captura). Este commit puede ser o +el directorio de trabajo. Por ejemplo, si se añaden 5 archivos, se eliminan 2, +estos cambios se almacenarán en un commit (aka: captura). Este commit puede ser o  no ser enviado (aka: "pusheado") hacia un repositorio.  ### Branch (rama) -Un "branch", es escencialmente un apuntador hacia el ultimo commit (cambio -registrado) que se ha realizado. A medida que se realizan mas commits, este -apuntador se actualizara automaticamente hacia el ultimo commit. +Un "branch", es escencialmente un apuntador hacia el último commit (cambio +registrado) que se ha realizado. A medida que se realizan más commits, este +apuntador se actualizará automaticamente hacia el ultimo commit. -### "HEAD" y "head" (component of .git dir) +### "HEAD" y "head" (componentes del directorio .git)  "HEAD" es un apuntador hacia la rama (branch) que se esta utilizando. Un  repositorio solo puede tener un HEAD activo. En cambio "head", es un apuntador a -cualquier commit realizado, un repositorio puede tener cualquier numero de +cualquier commit realizado, un repositorio puede tener cualquier número de  "heads".  ### conceptos - recursos. -* [Git para informaticos](http://eagain.net/articles/git-for-computer-scientists/) +* [Git para informáticos](http://eagain.net/articles/git-for-computer-scientists/)  * [Git para diseñadores](http://hoth.entp.com/output/git_for_designers.html) @@ -102,8 +102,8 @@ cualquier commit realizado, un repositorio puede tener cualquier numero de  ### init -Crear un repositorio de git vacio. Las configuraciones, informacion almacenada y -demas son almacenadas en el directorio ".git". +Crear un repositorio de git vacio. Las configuraciones, información almacenada y +demás son almacenadas en el directorio ".git".  ```bash  $ git init @@ -115,7 +115,7 @@ Se utiliza para configurar las opciones ya sea globalmente, o solamente en el  repositorio.  ```bash -# Imprime y guarda algunas variables de configuracion basicas. (Globalmente) +# Imprime y guarda algunas variables de configuracion básicas. (Globalmente)  $ git config --global user.email  $ git config --global user.name @@ -123,15 +123,15 @@ $ git config --global user.email "corre@gmail.com"  $ git config --global user.name "nombre"  ``` -[Mas sobre git config.](http://git-scm.com/book/es/Personalizando-Git-Configuración-de-Git) +[Más sobre git config.](http://git-scm.com/book/es/Personalizando-Git-Configuración-de-Git)  ### help -Otorga un accceso rapido a una guia extremadamente detallada de cada comando en +Otorga un accceso rápido a una guía extremadamente detallada de cada comando en  git. O puede ser usada simplemente como un recordatorio de estos.  ```bash -# Una vista rapido de los comandos disponibles. +# Una vista rápida de los comandos disponibles.  $ git help  # Chequear todos los comandos disponibles @@ -146,12 +146,12 @@ $ git help init  ### status -Muestra las diferencias entre el archivo indice y el commit al cual apunta el +Muestra las diferencias entre el archivo índice y el commit al cual apunta el  HEAD actualmente.  ```bash -# Mostrara el "branch", archivos sin añadir a la repo, cambios y otras +# Mostrará el "branch", archivos sin añadir al repo, cambios y otras  # diferencias  $ git status @@ -161,9 +161,9 @@ $ git help status  ### add -Para añadir archivos al arbol (directorio, repositorio) de trabajo. Si no se -utiliza `git add`, los nuevos archivos no se añadiran al arbol de trabajo, por -lo que no se incluiran en los commits (cambios). +Para añadir archivos al árbol (directorio, repositorio) de trabajo. Si no se +utiliza `git add`, los nuevos archivos no se añadirán al arbol de trabajo, por +lo que no se incluirán en los commits (cambios).  ```bash  # Añade un archivo en el directorio de trabajo actual. @@ -178,31 +178,31 @@ $ git add ./*.py  ### branch -Administra las ramas del repositorios ("branches"). Puedes ver, editar, crear y +Administra las ramas del repositorio ("branches"). Puedes ver, editar, crear y  borrar ramas ("branches"), usando este comando.  ```bash  # lista todas las ramas (remotas y locales)  $ git branch -a -# Añada una nueva rama ("branch"). +# Añadir una nueva rama ("branch").  $ git branch branchNueva  # Eliminar una rama.  $ git branch -d branchFoo -# Renombra una rama. +# Renombrar una rama.  # git branch -m <anterior> <nuevo>  $ git branch -m youngling padawan -# Edita la descripcion de la rama. +# Editar la descripcion de la rama.  $ git branch master --edit-description  ```  ### checkout  Actualiza todos los archivos en el directorio de trabajo para que sean igual que -las versiones almacenadas en el indice, o en un arbol de trabajo especificado. +las versiones almacenadas en el índice, o en un árbol de trabajo especificado.  ```bash  # Despachar un repositorio. - Por defecto la master branch. (la rama principal llamada 'master') @@ -215,8 +215,8 @@ $ git checkout -b jdei  ### clone -Clona, o copia, una repo existente en un nuevo directorio. Tambien añada el -seguimiento hacia las ramas existentes del repo que ha sido clonada, lo que +Clona, o copia, un repositorio existente en un nuevo directorio. También añade el +seguimiento hacia las ramas existentes del repositorio que ha sido clonado, lo que  permite subir (push) los archivos hacia una rama remota.  ```bash @@ -226,60 +226,60 @@ $ git clone https://github.com/jquery/jquery.git  ### commit -Almacena los cambios que almacenados en el indice en un nuevo "commit". Este -commit contiene los cambios hechos mas un resumen hecho por el desarrollador. +Almacena el contenido actual del índice en un nuevo "commit". Este +commit contiene los cambios hechos más un resumen proporcionado por el desarrollador.  ```bash -# commit with a message  # realizar un commit y añadirle un mensaje.  $ git commit -m "jedi anakin wil be - jedis.list"  ```  ### diff -Muestra las diferencias entre un archivo en el directorio de trabajo, el indice -y commits. +Muestra las diferencias entre un archivo en el directorio de trabajo, el índice +y los commits.  ```bash -# Muestra la diferencia entre un directorio de trabajo y el indice. +# Muestra la diferencia entre un directorio de trabajo y el índice.  $ git diff -# Muestra la diferencia entre el indice y los commits mas recientes. +# Muestra la diferencia entre el índice y los commits más recientes.  $ git diff --cached -# Muestra la diferencia entre el directorio de trabajo y el commit mas reciente. +# Muestra la diferencia entre el directorio de trabajo y el commit más reciente.  $ git diff HEAD  ```  ### grep -Permite realizar una busqueda rapida en un repositorio. +Permite realizar una busqueda rápida en un repositorio. -Configuracion opcionales: +Configuraciones opcionales:  ```bash  # Gracias a Travis Jeffery por compartir lo siguiente.  # Permite mostrar numeros de lineas en la salida de grep.  $ git config --global grep.lineNumber true -# Realiza una busqueda mas lejible, incluyendo agrupacion. +# Realiza una búsqueda mas legible, incluyendo agrupación.  $ git config --global alias.g "grep --break --heading --line-number"  ```  ```bash -# Busca por "unaVariable" en todos los archivos ,java +# Busca por "unaVariable" en todos los archivos .java  $ git grep 'unaVariable' -- '*.java' -# Busca por una linea que contenga "nombreArreglo" y , "agregar" o "remover" +# Busca por una línea que contenga "nombreArreglo" y "agregar" o "remover"  $ git grep -e 'nombreArreglo' --and \( -e agregar -e remover \)  ``` -Mas ejemplos: -[Git Grep Ninja](http://travisjeffery.com/b/2012/02/search-a-git-repo-like-a-ninja) +Más ejemplos: + +- [Git Grep Ninja](http://travisjeffery.com/b/2012/02/search-a-git-repo-like-a-ninja)  ### log -Muestra los commits (cambios) registrados en el repositotrio. +Muestra los commits (cambios) registrados en el repositorio.  ```bash  # Muestra todos los commits. @@ -288,7 +288,7 @@ $ git log  # Muestra un numero x de commits.  $ git log -n 10 -# Muestra solo los commits que se han combinado en el hisotrial +# Muestra solo los commits que se han combinado en el historial.  $ git log --merges  ``` @@ -301,7 +301,7 @@ que se trabaja.  # Combina la rama especificada en la rama actual.  $ git merge jediMaster -# Siempre genere un solo merge commit cuando se utilizar merge. +# Siempre genere un solo merge commit cuando se utiliza merge.  $ git merge --no-ff jediMaster  ``` @@ -310,7 +310,7 @@ $ git merge --no-ff jediMaster  Renombra o mueve un archivo  ```bash -# Renombrando un archivo +# Renombrando un archivo.  $ git mv HolaMundo.c AdiosMundo.c  # Moviendo un archivo. @@ -322,33 +322,31 @@ $ git mv -f archivoA archivoB  ### pull -Sube (Empuja) de un repositorio y lo combina en otro en una rama diferente. +Trae los cambios de un repositorio y los combina en otro en una rama diferente.  ```bash -# Actualiza el repositorio local, combinando los nuevos cambios. +# Actualiza el repositorio local, combinando los nuevos cambios  # de las ramas remotas "origin" y "master". -# from the remote "origin" and "master" branch.  # git pull <remota> <rama>  $ git pull origin master  ```  ### push -Push and merge changes from a branch to a remote & branch. +Envía y combina los cambios de un repositorio local a un repositorio y rama remotos.  ```bash -# Push and merge changes from a local repo to a -# Empuja y combina cambios de un repositorio local hacian un repositorio remoto +# Envía y combina cambios de un repositorio local hacia un repositorio remoto  # llamados "origin" y "master", respectivamente.  # git push <remota> <rama>  # git push => por defecto es lo mismo que poner =>  git push origin master  $ git push origin master  ``` +### rebase  Toma todos los cambios que fueron registrados en una rama, y los repite dentro -de otra rama. -*No reescribe los commits que se han empujado antes a un repositorio publico* +de otra rama. *No reescribe los commits que se han empujado antes a un repositorio público.*  ```bash  # Integrar ramaExperimento dentro de la rama "master" @@ -356,47 +354,47 @@ de otra rama.  $ git rebase master experimentBranch  ``` -[Informacion adicional.](http://git-scm.com/book/es/Ramificaciones-en-Git-Procedimientos-básicos-para-ramificar-y-fusionar) +[Información adicional.](http://git-scm.com/book/es/Ramificaciones-en-Git-Procedimientos-básicos-para-ramificar-y-fusionar) -### reset (precaucion) +### reset (precaución) -Reinicia el cabezal actual hacia un estado especificado. Esto permite desacer -combinaciones (merges), pulls, commits, adds y mas. Es un comando util, pero -tambien peligrosa si no se sabe lo que se hace. +Reinicia el HEAD actual hacia un estado especificado. Esto permite deshacer +combinaciones (merges), pulls, commits, adds y más. Es un comando útil, pero +tambien peligroso si no se sabe lo que se hace.  ```bash -# Reinica el area principal, con el ultimo cambio registrado. (deja los +# Reinicia el área principal, con el último cambio registrado. (deja los  # directorios sin cambios)  $ git reset -# Reinica el area principal, con el ultimo cambio registrado, y reescribe el +# Reinicia el área principal, con el último cambio registrado, y reescribe el  # directorio de trabajo.  $ git reset --hard  # Mueve la rama actual hacia el commit especificado (no realiza cambios a los -# directorios), todos los cambios aun existen el directorio. +# directorios), todos los cambios aún existen el directorio.  $ git reset 31f2bb1 -# Mueve la rama actual devuelta a un commit especificado asi como el -# directorios (borra todos los cambios que no fueron registros y todos los -# cambios realizados despues del commit especificado). +# Mueve la rama actual devuelta a un commit especificado, así como el +# directorio (borra todos los cambios que no fueron registrados y todos los +# cambios realizados después del commit especificado).  $ git reset --hard 31f2bb1  ```  ### rm -Lo contrario de git add, git rm remueve los archivos del directorio de trabajo +Lo contrario de git add, git rm elimina los archivos del directorio de trabajo  actual.  ```bash -# Remueve FooBar.c +# Elimina FooBar.c  $ git rm FooBar.c -# Remueve un archivo de un directorio. +# Elimina un archivo de un directorio.  $ git rm /directorio/del/archivo/FooBar.c  ``` -## Informacion Adicional +## Información Adicional  * [tryGit - Una forma entretenida y rapida de aprender Git.](http://try.github.io/levels/1/challenges/1) diff --git a/es-es/go-es.html.markdown b/es-es/go-es.html.markdown index 86de33ec..c41d693d 100644 --- a/es-es/go-es.html.markdown +++ b/es-es/go-es.html.markdown @@ -1,326 +1,450 @@  --- +name: Go +category: language  language: Go  lang: es-es  filename: learngo-es.go  contributors:      - ["Sonia Keys", "https://github.com/soniakeys"] +    - ["Christopher Bess", "https://github.com/cbess"] +    - ["Jesse Johnson", "https://github.com/holocronweaver"] +    - ["Quint Guvernator", "https://github.com/qguv"] +    - ["Jose Donizetti", "https://github.com/josedonizetti"] +    - ["Alexej Friesen", "https://github.com/heyalexej"]  translators:      - ["Adrian Espinosa", "http://www.adrianespinosa.com"]      - ["Jesse Johnson", "https://github.com/holocronweaver"] +    - ["Nacho Pacheco -- Feb/2015", "https://github.com/gitnacho"]  --- -Go fue creado por la necesidad de hacer el trabajo rápidamente.  No es -la última tendencia en informática, pero es la forma nueva y más -rápida de resolver problemas reales. +Go fue creado por la necesidad de hacer el trabajo rápidamente. No es la +última tendencia en informática, pero es la forma nueva y más rápida de +resolver problemas reales. -Tiene conceptos familiares de lenguajes imperativos con tipado -estático.  Es rápido compilando y rápido al ejecutar, añade una -concurrencia fácil de entender para las CPUs de varios núcleos de hoy -en día, y tiene características que ayudan con la programación a gran -escala. +Tiene conceptos familiares de lenguajes imperativos con tipado estático. +Es rápido compilando y rápido al ejecutar, añade una concurrencia fácil de +entender para las CPUs de varios núcleos de hoy día, y tiene +características que ayudan con la programación a gran escala. -Go viene con una librería estándar muy buena y una comunidad entusiasta. +Go viene con una biblioteca estándar muy buena y una entusiasta comunidad.  ```go  // Comentario de una sola línea -/* Comentario  -   multi línea */ +/* Comentario +   multilínea */ -// La cláusula package aparece al comienzo de cada archivo fuente. -// Main es un nombre especial que declara un ejecutable en vez de una librería. +// La cláusula `package` aparece al comienzo de cada fichero fuente. +// `main` es un nombre especial que declara un ejecutable en vez de una +// biblioteca.  package main -// La declaración Import declara los paquetes de librerías -// referenciados en este archivo. +// La instrucción `import` declara los paquetes de bibliotecas referidos +// en este fichero.  import ( -    "fmt"      // Un paquete en la librería estándar de Go. -    "net/http" // Sí, un servidor web! -    "strconv"  // Conversiones de cadenas. -    m "math"   // Librería matemáticas con alias local m. +	"fmt"      // Un paquete en la biblioteca estándar de Go. +	"io/ioutil" // Implementa algunas útiles funciones de E/S. +	m "math"   // Biblioteca de matemáticas con alias local m. +	"net/http" // Sí, ¡un servidor web! +	"strconv"  // Conversiones de cadenas.  ) -// Definición de una función. Main es especial.  Es el punto de -// entrada para el ejecutable.  Te guste o no, Go utiliza llaves. +// Definición de una función. `main` es especial. Es el punto de entrada +// para el ejecutable. Te guste o no, Go utiliza llaves.  func main() { -    // Println imprime una línea a stdout. -    // Cualificalo con el nombre del paquete, fmt. -    fmt.Println("Hello world!") +	// Println imprime una línea a stdout. +	// Cualificalo con el nombre del paquete, fmt. +	fmt.Println("¡Hola mundo!") -    // Llama a otra función de este paquete. -    beyondHello() +	// Llama a otra función de este paquete. +	másAlláDelHola()  }  // Las funciones llevan parámetros entre paréntesis.  // Si no hay parámetros, los paréntesis siguen siendo obligatorios. -func beyondHello() { -    var x int // Declaración de una variable. -              // Las variables se deben declarar antes de utilizarlas. -    x = 3     // Asignación de variables. -    // Declaración "corta" con := para inferir el tipo, declarar y asignar. -    y := 4 -    sum, prod := learnMultiple(x, y)        // Función devuelve dos valores. -    fmt.Println("sum:", sum, "prod:", prod) // Simple salida. -    learnTypes()                            // < y minutes, learn more! +func másAlláDelHola() { +	var x int // Declaración de una variable. + 	          // Las variables se deben declarar antes de utilizarlas. +	x = 3     // Asignación de variable. +	// Declaración "corta" con := para inferir el tipo, declarar y asignar. +	y := 4 +	suma, producto := aprendeMúltiple(x, y) // La función devuelve dos +											// valores. +	fmt.Println("suma:", suma, "producto:", producto) // Simple salida. +	aprendeTipos()                        // < y minutos, ¡aprende más!  } -// Las funciones pueden tener parámetros y (múltiples!) valores de retorno. -func learnMultiple(x, y int) (sum, prod int) { -    return x + y, x * y // Devolver dos valores. +// Las funciones pueden tener parámetros y (¡múltiples!) valores de +// retorno. +func aprendeMúltiple(x, y int) (suma, producto int) { +    return x + y, x * y // Devuelve dos valores.  }  // Algunos tipos incorporados y literales. -func learnTypes() { -    // La declaración corta suele darte lo que quieres. -    s := "Learn Go!" // tipo cadena - -    s2 := ` Un tipo cadena "puro" puede incluir +func aprendeTipos() { +	// La declaración corta suele darte lo que quieres. +	s := "¡Aprende Go!" // tipo cadena. +	s2 := `Un tipo cadena "puro" puede incluir  saltos de línea.` // mismo tipo cadena -    // Literal no ASCII. Los fuentes de Go son UTF-8. -    g := 'Σ' // Tipo rune, un alias de int32, alberga un punto unicode. -    f := 3.14195 // float64, el estándar IEEE-754 de coma flotante 64-bit. -    c := 3 + 4i  // complex128, representado internamente por dos float64. -    // Sintaxis Var con inicializadores. -    var u uint = 7 // Sin signo, pero la implementación depende del -                   // tamaño como en int. -    var pi float32 = 22. / 7 - -    // Sintáxis de conversión con una declaración corta. -    n := byte('\n') // byte es un alias de uint8. - -    // Los Arrays tienen un tamaño fijo a la hora de compilar. -    var a4 [4]int           // Un array de 4 ints, inicializados a 0. -    a3 := [...]int{3, 1, 5} // Un array de 3 ints, inicializados como se indica. - -    // Los Slices tienen tamaño dinámico. Los arrays y slices tienen sus ventajas -    // y desventajas pero los casos de uso para los slices son más comunes. -    s3 := []int{4, 5, 9}    // Comparar con a3. No hay puntos suspensivos. -    s4 := make([]int, 4)    // Asigna slices de 4 ints, inicializados a 0. -    var d2 [][]float64      // Solo declaración, sin asignación. -    bs := []byte("a slice") // Sintaxis de conversión de tipo. - -    p, q := learnMemory() // Declara p, q para ser un tipo puntero a int. -    fmt.Println(*p, *q)   // * sigue un puntero. Esto imprime dos ints. - -    // Los Maps son arrays asociativos dinámicos, como los hash o -    // diccionarios de otros lenguajes. -    m := map[string]int{"three": 3, "four": 4} -    m["one"] = 1 - -    // Las variables no utilizadas en Go producen error. -    // El guión bajo permite "utilizar" una variable, pero descartar su valor. -    _, _, _, _, _, _, _, _, _ = s2, g, f, u, pi, n, a3, s4, bs -    // Esto cuenta como utilización de variables. -    fmt.Println(s, c, a4, s3, d2, m) - -    learnFlowControl() // Vuelta al flujo. +	// Literal no ASCII. Los ficheros fuente de Go son UTF-8. +	g := 'Σ' // Tipo rune, un alias de int32, alberga un carácter unicode. +	f := 3.14195 // float64, el estándar IEEE-754 de coma flotante 64-bit. +	c := 3 + 4i  // complex128, representado internamente por dos float64. +	// Sintaxis Var con iniciadores. +	var u uint = 7 // Sin signo, pero la implementación depende del tamaño +	               // como en int. +	var pi float32 = 22. / 7 + +	// Sintáxis de conversión con una declaración corta. +	n := byte('\n') // byte es un alias para uint8. + +	// Los Arreglos tienen un tamaño fijo a la hora de compilar. +	var a4 [4]int           // Un arreglo de 4 ints, iniciados a 0. +	a3 := [...]int{3, 1, 5} // Un arreglo iniciado con un tamaño fijo de tres +							// elementos, con valores 3, 1 y 5. +	// Los Sectores tienen tamaño dinámico. Los arreglos y sectores tienen +	// sus ventajas y desventajas pero los casos de uso para los sectores +	// son más comunes. +	s3 := []int{4, 5, 9}     // Comparar con a3. No hay puntos suspensivos. +	s4 := make([]int, 4)     // Asigna sectores de 4 ints, iniciados a 0. +	var d2 [][]float64       // Solo declaración, sin asignación. +	bs := []byte("a sector") // Sintaxis de conversión de tipo. +	// Debido a que son dinámicos, los sectores pueden crecer bajo demanda. +	// Para añadir elementos a un sector, se utiliza la función incorporada +	// append(). +	// El primer argumento es el sector al que se está anexando. Comúnmente, +	// la variable del arreglo se actualiza en su lugar, como en el  +	// siguiente ejemplo. +	sec := []int{1, 2 , 3}      // El resultado es un sector de longitud 3. +	sec = append(sec, 4, 5, 6)  // Añade 3 elementos. El sector ahora tiene una +								// longitud de 6. +	fmt.Println(sec) // El sector actualizado ahora es [1 2 3 4 5 6] +	// Para anexar otro sector, en lugar de la lista de elementos atómicos +	// podemos pasar una referencia a un sector o un sector literal como +	// este, con elipsis al final, lo que significa tomar un sector y +	// desempacar sus elementos, añadiéndolos al sector sec. +	sec = append(sec, []int{7, 8, 9} ...) // El segundo argumento es un +										  // sector literal. +	fmt.Println(sec)  // El sector actualizado ahora es [1 2 3 4 5 6 7 8 9] +	p, q := aprendeMemoria() // Declara p, q para ser un tipo puntero a +							 // int. +	fmt.Println(*p, *q)      // * sigue un puntero. Esto imprime dos ints. + +	// Los Mapas son arreglos asociativos dinámicos, como los hash o +	// diccionarios de otros lenguajes. +	m := map[string]int{"tres": 3, "cuatro": 4} +	m["uno"] = 1 + +	// Las variables no utilizadas en Go producen error. +	// El guión bajo permite "utilizar" una variable, pero descartar su +	// valor. +	_, _, _, _, _, _, _, _, _ = s2, g, f, u, pi, n, a3, s4, bs +	// Esto cuenta como utilización de variables. +	fmt.Println(s, c, a4, s3, d2, m) + +	aprendeControlDeFlujo() // Vuelta al flujo. +} + +// Es posible, a diferencia de muchos otros lenguajes tener valores de +// retorno con nombre en las funciones. +// Asignar un nombre al tipo que se devuelve en la línea de declaración de +// la función nos permite volver fácilmente desde múltiples puntos en una +// función, así como sólo utilizar la palabra clave `return`, sin nada +// más. +func aprendeRetornosNombrados(x, y int) (z int) { +	z = x * y +	return // aquí z es implícito, porque lo nombramos antes.  } -// Go posee recolector de basura. Tiene puntero pero no aritmética de -// punteros.  Puedes cometer un errores con un puntero nil, pero no +// Go posee recolector de basura. Tiene punteros pero no aritmética de +// punteros. Puedes cometer errores con un puntero nil, pero no  // incrementando un puntero. -func learnMemory() (p, q *int) { -    // q y p tienen un tipo puntero a int. -    p = new(int) // Función incorporada que asigna memoria. -    // La asignación de int se inicializa a 0, p ya no es nil. -    s := make([]int, 20) // Asigna 20 ints a un solo bloque de memoria. -    s[3] = 7             // Asignar uno de ellos. -    r := -2              // Declarar otra variable local. -    return &s[3], &r     // & toma la dirección de un objeto. +func aprendeMemoria() (p, q *int) { +	// Los valores de retorno nombrados q y p tienen un tipo puntero +	// a int. +	p = new(int) // Función incorporada que reserva memoria. +	// La asignación de int se inicia a 0, p ya no es nil. +	s := make([]int, 20) // Reserva 20 ints en un solo bloque de memoria. +	s[3] = 7             // Asigna uno de ellos. +	r := -2              // Declara otra variable local. +	return &s[3], &r     // & toma la dirección de un objeto.  } -func expensiveComputation() float64 { -    return m.Exp(10) +func cálculoCaro() float64 { +	return m.Exp(10)  } -func learnFlowControl() { -    // La declaración If requiere llaves, pero no paréntesis. -    if true { -        fmt.Println("told ya") -    } -    // El formato está estandarizado por el comando "go fmt." -    if false { -        // Pout. -    } else { -        // Gloat. -    } -    // Utiliza switch preferiblemente para if encadenados. -    x := 42.0 -    switch x { -    case 0: -    case 1: -    case 42: -        // Los cases no se mezclan, no requieren de "break". -    case 43: -        // No llega. +func aprendeControlDeFlujo() { +	// La declaración If requiere llaves, pero no paréntesis. +	if true { +		fmt.Println("ya relatado") +	} +	// El formato está estandarizado por la orden "go fmt." +	if false { +		// Abadejo. +	} else { +		// Relamido. +	} +	// Utiliza switch preferentemente para if encadenados. +	x := 42.0 +	switch x { +	case 0: +	case 1: +	case 42: +		// Los cases no se mezclan, no requieren de "break". +	case 43: +		// No llega. +	} +	// Como if, for no utiliza paréntesis tampoco. +	// Variables declaradas en for e if son locales a su ámbito. +	for x := 0; x < 3; x++ { // ++ es una instrucción. +		fmt.Println("iteración", x) +	} +	// aquí x == 42. + +	// For es la única instrucción de bucle en Go, pero tiene formas +	// alternativas. +	for { // Bucle infinito. +		break    // ¡Solo bromeaba! +		continue // No llega. +	} + +	// Puedes usar `range` para iterar en un arreglo, un sector, una +	// cadena, un mapa o un canal. +	// `range` devuelve o bien, un canal o de uno a dos valores (arreglo, +	// sector, cadena y mapa). +	for clave, valor := range map[string]int{"uno": 1, "dos": 2, "tres": 3} { +		// por cada par en el mapa, imprime la clave y el valor +		fmt.Printf("clave=%s, valor=%d\n", clave, valor) +	} + +	// Como en for, := en una instrucción if significa declarar y asignar +	// primero, luego comprobar y > x. +	if y := cálculoCaro(); y > x { +		x = y      } -    // Como if, for no utiliza paréntesis tampoco. -    // Variables declaradas en for y if son locales de su ámbito local. -    for x := 0; x < 3; x++ { // ++ es una sentencia. -        fmt.Println("iteration", x) -    } -    // x == 42 aqui. +	// Las funciones literales son "cierres". +	granX := func() bool { +		return x > 100 // Referencia a x declarada encima de la instrucción +							// switch. +	} +	fmt.Println("granX:", granX()) // cierto (la última vez asignamos +											 // 1e6 a x). +	x /= 1.3e3                   // Esto hace a x == 1300 +	fmt.Println("granX:", granX()) // Ahora es falso. + +	// Es más las funciones literales se pueden definir y llamar en línea, +	// actuando como un argumento para la función, siempre y cuando: +	// a) la función literal sea llamada inmediatamente (), +	// b) el tipo del resultado sea del tipo esperado del argumento +	fmt.Println("Suma dos números + doble: ", +		func(a, b int) int { +			return (a + b) * 2 +		}(10, 2)) // Llamada con argumentos 10 y 2 +	// => Suma dos números + doble: 24 + +	// Cuando lo necesites, te encantará. +	goto encanto +encanto: + +	aprendeFunciónFábrica() // func devolviendo func es divertido(3)(3) +	aprendeADiferir()       // Un rápido desvío a una importante palabra clave. +	aprendeInterfaces()     // ¡Buen material dentro de poco! +} -    // For es la única sentencia de bucle en Go, pero tiene formas alternativas. -    for { // Bucle infinito. -        break    // Solo bromeaba! -        continue // No llega. -    } -    // Como en for, := en una sentencia if significa declarar y asignar primero, -    // luego comprobar y > x. -    if y := expensiveComputation(); y > x { -        x = y -    } -    // Los literales de funciones son "closures". -    xBig := func() bool { -        return x > 100 // Referencia a x declarada encima de la sentencia switch. -    } -    fmt.Println("xBig:", xBig()) // verdadero (la última vez asignamos 1e6 a x). -    x /= m.Exp(9)                // Esto lo hace x == e. -    fmt.Println("xBig:", xBig()) // Ahora es falso. +func aprendeFunciónFábrica() { +	// Las dos siguientes son equivalentes, la segunda es más práctica +	fmt.Println(instrucciónFábrica("día")("Un bello", "de verano")) + +	d := instrucciónFábrica("atardecer") +	fmt.Println(d("Un hermoso", "de verano")) +	fmt.Println(d("Un maravilloso", "de verano")) +} -    // Cuando lo necesites, te encantará. -    goto love -love: +// Los decoradores son comunes en otros lenguajes. Lo mismo se puede hacer +// en Go con funciónes literales que aceptan argumentos. +func instrucciónFábrica(micadena string) func(antes, después string) string { +	return func(antes, después string) string { +		return fmt.Sprintf("¡%s %s %s!", antes, micadena, después) // nueva cadena +	} +} -    learnInterfaces() // Buen material dentro de poco! +func aprendeADiferir() (ok bool) { +	// las instrucciones diferidas se ejecutan justo antes de que la +	// función regrese. +	defer fmt.Println("las instrucciones diferidas se ejecutan en orden inverso (PEPS).") +	defer fmt.Println("\nEsta línea se imprime primero debido a que") +	// Defer se usa comunmente para cerrar un fichero, por lo que la +	// función que cierra el fichero se mantiene cerca de la función que lo +	// abrió. +	return true  }  // Define Stringer como un tipo interfaz con un método, String.  type Stringer interface { -    String() string +	String() string  } -// Define pair como un struct con dos campos int, x e y. -type pair struct { -    x, y int +// Define par como una estructura con dos campos int, x e y. +type par struct { +	x, y int  } -// Define un método del tipo pair. Pair ahora implementa Stringer. -func (p pair) String() string { // p se llama "recibidor" -    // Sprintf es otra función pública del paquete fmt. -    // La sintaxis con punto referencia campos de p. -    return fmt.Sprintf("(%d, %d)", p.x, p.y) +// Define un método en el tipo par. Par ahora implementa a Stringer. +func (p par) String() string { // p se conoce como el "receptor" +	// Sprintf es otra función pública del paquete fmt. +	// La sintaxis con punto se refiere a los campos de p. +	return fmt.Sprintf("(%d, %d)", p.x, p.y)  } -func learnInterfaces() { -    // La sintaxis de llaves es un "literal struct". Evalúa a un struct -    // inicializado.  La sintaxis := declara e inicializa p a este struct. -    p := pair{3, 4} -    fmt.Println(p.String()) // Llamar al método String de p, de tipo pair. -    var i Stringer          // Declarar i como interfaz tipo Stringer. -    i = p                   // Válido porque pair implementa Stringer. -    // Llamar al metodo String de i, de tipo Stringer. Misma salida que arriba. -    fmt.Println(i.String()) - -    // Las funciones en el paquete fmt llaman al método String para -    // preguntar a un objeto por una versión imprimible de si mismo. -    fmt.Println(p) // Salida igual que arriba. Println llama al método String. -    fmt.Println(i) // Salida igual que arriba. - -    learnVariadicParams("great", "learning", "here!") +func aprendeInterfaces() { +	// La sintaxis de llaves es una "estructura literal". Evalúa a una +	// estructura iniciada. La sintaxis := declara e inicia p a esta +	// estructura. +	p := par{3, 4} +	fmt.Println(p.String()) // Llama al método String de p, de tipo par. +	var i Stringer          // Declara i como interfaz de tipo Stringer. +	i = p                   // Válido porque par implementa Stringer. +	// Llama al metodo String de i, de tipo Stringer. Misma salida que +	// arriba. +	fmt.Println(i.String()) + +	// Las funciones en el paquete fmt llaman al método String para +	// consultar un objeto por una representación imprimible de si +	// mismo. +	fmt.Println(p) // Salida igual que arriba. Println llama al método +				   // String. +	fmt.Println(i) // Salida igual que arriba. +	aprendeNúmeroVariableDeParámetros("¡gran", "aprendizaje", "aquí!")  }  // Las funciones pueden tener número variable de argumentos. -func learnVariadicParams(myStrings ...interface{}) { -    // Iterar cada valor de la variadic. -    for _, param := range myStrings { -        fmt.Println("param:", param) -    } -     -    // Pasar valor variadic como parámetro variadic. -    fmt.Println("params:", fmt.Sprintln(myStrings...)) - -    learnErrorHandling() +func aprendeNúmeroVariableDeParámetros(misCadenas ...interface{}) { +	// Itera en cada valor de los argumentos variables. +	// El espacio en blanco aquí omite el índice del argumento arreglo. +	for _, parámetro := range misCadenas { +		fmt.Println("parámetro:", parámetro) +	} + +	// Pasa el valor de múltiples variables como parámetro variadic. +	fmt.Println("parámetros:", fmt.Sprintln(misCadenas...)) +	aprendeManejoDeError()  } -func learnErrorHandling() { -    // ", ok" forma utilizada para saber si algo funcionó o no. -    m := map[int]string{3: "three", 4: "four"} -    if x, ok := m[1]; !ok { // ok será falso porque 1 no está en el map. -        fmt.Println("no one there") -    } else { -        fmt.Print(x) // x sería el valor, si estuviera en el map. -    } -    // Un valor de error comunica más información sobre el problema aparte de "ok". -    if _, err := strconv.Atoi("non-int"); err != nil { // _ descarta el valor -        // Imprime "strconv.ParseInt: parsing "non-int": invalid syntax". -        fmt.Println(err) -    } -    // Revisarmeos las interfaces más tarde. Mientras tanto, -    learnConcurrency() +func aprendeManejoDeError() { +	// ", ok" forma utilizada para saber si algo funcionó o no. +	m := map[int]string{3: "tres", 4: "cuatro"} +	if x, ok := m[1]; !ok { // ok será falso porque 1 no está en el mapa. +		fmt.Println("nada allí") +	} else { +		fmt.Print(x) // x sería el valor, si estuviera en el mapa. +	} +	// Un valor de error comunica más información sobre el problema aparte +	// de "ok". +	if _, err := strconv.Atoi("no-int"); err != nil { // _ descarta el +																	  // valor +		// Imprime "strconv.ParseInt: parsing "no-int": invalid syntax". +		fmt.Println(err) +	} +	// Revisaremos las interfaces más adelante. Mientras tanto... +	aprendeConcurrencia()  } -// c es un canal,  un objeto de comunicación de concurrencia segura. +// c es un canal, un objeto de comunicación concurrente seguro.  func inc(i int, c chan int) { -    c <- i + 1 // <- es el operador "enviar" cuando un canal aparece a la izquierda. +	c <- i + 1 // <- es el operador "enviar" cuando aparece un canal a la +				  // izquierda.  }  // Utilizaremos inc para incrementar algunos números concurrentemente. -func learnConcurrency() { -    // Misma función make utilizada antes para crear un slice. Make asigna e -    // inicializa slices, maps, y channels. -    c := make(chan int) -    // Iniciar tres goroutines concurrentes. Los números serán incrementados -    // concurrentemente, quizás en paralelo si la máquina es capaz y -    // está correctamente configurada. Las tres envían al mismo channel. -    go inc(0, c) // go es una sentencia que inicia una nueva goroutine. -    go inc(10, c) -    go inc(-805, c) -    // Leer los tres resultados del channel e imprimirlos. -    // No se puede saber en que orden llegarán los resultados! -    fmt.Println(<-c, <-c, <-c) // Channel a la derecha, <- es el operador "recibir". - -    cs := make(chan string)       // Otro channel, este gestiona cadenas. -    ccs := make(chan chan string) // Un channel de cadenas de channels. -    go func() { c <- 84 }()       // Iniciar una nueva goroutine solo para -                                  // enviar un valor. -    go func() { cs <- "wordy" }() // Otra vez, para cs en esta ocasión. -    // Select tiene una sintáxis parecida a la sentencia switch pero -    // cada caso involucra una operacion de channels. Selecciona un caso -    // de forma aleatoria de los casos que están listos para comunicarse. -    select { -    case i := <-c: // El valor recibido puede ser asignado a una variable, -        fmt.Printf("it's a %T", i) -    case <-cs:     // o el valor puede ser descartado. -        fmt.Println("it's a string") -    case <-ccs:    // Channel vacío, no está listo para la comunicación. -        fmt.Println("didn't happen.") -    } - -    // En este punto un valor fue devuelvto de c o cs. Uno de las dos -    // goroutines que se iniciaron se ha completado, la otrá permancerá -    // bloqueada. - -    learnWebProgramming() // Go lo hace. Tu también quieres hacerlo. +func aprendeConcurrencia() { +	// Misma función make utilizada antes para crear un sector. Make asigna +	// e inicia sectores, mapas y canales. +	c := make(chan int) +	// Inicia tres rutinasgo concurrentes. Los números serán incrementados +	// concurrentemente, quizás en paralelo si la máquina es capaz y está +	// correctamente configurada. Las tres envían al mismo canal. +	go inc(0, c) // go es una instrucción que inicia una nueva rutinago. +	go inc(10, c) +	go inc(-805, c) +	// Lee los tres resultados del canal y los imprime. +	// ¡No se puede saber en que orden llegarán los resultados! +	fmt.Println(<-c, <-c, <-c) // Canal a la derecha, <- es el operador +										// "recibe". + +	cs := make(chan string)       // Otro canal, este gestiona cadenas. +	ccs := make(chan chan string) // Un canal de canales cadena. +	go func() { c <- 84 }()       // Inicia una nueva rutinago solo para +											// enviar un valor. +	go func() { cs <- "verboso" }() // Otra vez, para cs en esta ocasión. +	// Select tiene una sintáxis parecida a la instrucción switch pero cada +	// caso involucra una operacion con un canal. Selecciona un caso de +	// forma aleatoria de los casos que están listos para comunicarse. +	select { +	case i := <-c: // El valor recibido se puede asignar a una variable, +		fmt.Printf("es un %T", i) +	case <-cs:     // o el valor se puede descartar. +		fmt.Println("es una cadena") +	case <-ccs:    // Canal vacío, no está listo para la comunicación. +		fmt.Println("no sucedió.") +	} + +	// En este punto un valor fue devuelto de c o cs. Una de las dos +	// rutinasgo que se iniciaron se ha completado, la otrá permancerá +	// bloqueada. + +	aprendeProgramaciónWeb() // Go lo hace. Tú también quieres hacerlo.  }  // Una simple función del paquete http inicia un servidor web. -func learnWebProgramming() { -    // El primer parámetro de la direccinón TCP a la que escuchar. -    // El segundo parámetro es una interfaz, concretamente http.Handler. -    err := http.ListenAndServe(":8080", pair{}) -    fmt.Println(err) // no ignorar errores +func aprendeProgramaciónWeb() { +// El primer parámetro es la direccinón TCP a la que escuchar. +	// El segundo parámetro es una interfaz, concretamente http.Handler. +	go func() { +		err := http.ListenAndServe(":8080", par{}) +		fmt.Println(err) // no ignora errores +	}() +	consultaAlServidor()  } -// Haz pair un http.Handler implementando su único método, ServeHTTP. -func (p pair) ServeHTTP(w http.ResponseWriter, r *http.Request) { -    // Servir datos con un método de http.ResponseWriter. -    w.Write([]byte("You learned Go in Y minutes!")) +// Hace un http.Handler de par implementando su único método, ServeHTTP. +func (p par) ServeHTTP(w http.ResponseWriter, r *http.Request) { +	// Sirve datos con un método de http.ResponseWriter. +	w.Write([]byte("¡Aprendiste Go en Y minutos!")) +} + +func consultaAlServidor() { +	resp, err := http.Get("http://localhost:8080") +	fmt.Println(err) +	defer resp.Body.Close() +	cuerpo, err := ioutil.ReadAll(resp.Body) +	fmt.Printf("\nEl servidor web dijo: `%s`\n", string(cuerpo))  }  ``` -## Para leer más  +## Más información + +La raíz de todas las cosas sobre Go es el +[sitio web oficial de Go](http://golang.org/). +Allí puedes seguir el tutorial, jugar interactivamente y leer mucho más. -La raíz de todas las cosas de Go es la [web oficial de Go](http://golang.org/). -Ahí puedes seguir el tutorial, jugar interactivamente y leer mucho. +La definición del lenguaje es altamente recomendada.  Es fácil de leer y +sorprendentemente corta (como la definición del lenguaje Go en estos +días). -La propia definición del lenguaje también está altamente -recomendada. Es fácil de leer e increíblemente corta (como otras -definiciones de lenguajes hoy en día) +Puedes jugar con el código en el +[parque de diversiones Go](https://play.golang.org/p/ncRC2Zevag).  ¡Trata +de cambiarlo y ejecutarlo desde tu navegador!  Ten en cuenta que puedes +utilizar [https://play.golang.org]( https://play.golang.org) como un +[REPL](https://en.wikipedia.org/wiki/Read-eval-print_loop) para probar +cosas y el código en el navegador, sin ni siquiera instalar Go. -En la lista de lectura de estudiantes de Go está el código fuente de -la librería estándar. Muy bien documentada, demuestra lo mejor de Go -leíble, comprendible, estilo Go y formas Go. Pincha en el nombre de -una función en la documentación y te aparecerá el código fuente! +En la lista de lecturas para estudiantes de Go está el +[código fuente de la biblioteca estándar](http://golang.org/src/pkg/).  +Ampliamente documentado, que demuestra lo mejor del legible y comprensible +Go, con su característico estilo y modismos.  ¡O puedes hacer clic en un +nombre de función en [la documentación](http://golang.org/pkg/) y +aparecerá el código fuente! +Otro gran recurso para aprender Go está en +[Go con ejemplos](http://goconejemplos.com/). diff --git a/es-es/javascript-es.html.markdown b/es-es/javascript-es.html.markdown index a1348508..036d7082 100644 --- a/es-es/javascript-es.html.markdown +++ b/es-es/javascript-es.html.markdown @@ -16,8 +16,7 @@ con Java para aplicaciones más complejas. Debido a su integracion estrecha con  web y soporte por defecto de los navegadores modernos se ha vuelto mucho más común   para front-end que Java. -JavaScript no sólo se limita a los navegadores web: -* Node.js: Un proyecto que provee con un ambiente para el motor V8 de Google Chrome. +JavaScript no sólo se limita a los navegadores web, aunque: Node.js, Un proyecto que proporciona un entorno de ejecución independiente para el motor V8 de Google Chrome, se está volviendo más y más popular.  ¡La retroalimentación es bienvenida! Puedes encontrarme en:   [@adambrenecki](https://twitter.com/adambrenecki), o @@ -49,6 +48,7 @@ hazAlgo()  // Toda la aritmética básica funciona como uno esperaría.  1 + 1; // = 2 +0.1 + 0.2; // = 0.30000000000000004  8 - 1; // = 7  10 * 2; // = 20  35 / 5; // = 7 @@ -102,9 +102,11 @@ false;  // Los tipos no importan con el operador ==...  "5" == 5; // = true +null == undefined; // = true  // ...a menos que uses ===  "5" === 5; // = false +null === undefined; // false  // Los Strings funcionan como arreglos de caracteres  // Puedes accesar a cada caracter con la función charAt() @@ -126,7 +128,7 @@ undefined; // usado para indicar que un valor no está presente actualmente  // Aunque 0 === "0" sí es false.  /////////////////////////////////// -// 2. Variables, Arreglos y Objetos +// 2. Variables, Arrays y Objetos  // Las variables se declaran con la palabra var. JavaScript cuenta con tipado dinámico,  // así que no se necesitan aplicar tipos. La asignación se logra con el operador =. @@ -220,7 +222,6 @@ for (var i = 0; i < 5; i++){  }  // && es un "y" lógico, || es un "o" lógico -var casa = {tamano:"grande",casa:"color"};  if (casa.tamano == "grande" && casa.color == "azul"){      casa.contiene = "oso";  } @@ -477,9 +478,6 @@ miNumero === miNumeroObjeyo; // = false  if (0){      // Este código no se ejecutara porque 0 es false.  } -if (Number(0)){ -    // Este código sí se ejecutara, puesto que Number(0) es true. -}  // Aún así, los objetos que envuelven y los prototipos por defecto comparten  // un prototipo. así que puedes agregar funcionalidades a un string de la  diff --git a/es-es/julia-es.html.markdown b/es-es/julia-es.html.markdown index 203ee3bb..e4181609 100644 --- a/es-es/julia-es.html.markdown +++ b/es-es/julia-es.html.markdown @@ -4,757 +4,937 @@ contributors:      - ["Leah Hanson", "http://leahhanson.us"]  translators:      - ["Guillermo Garza", "http://github.com/ggarza"] +    - ["Ismael Venegas Castelló", "https://github.com/Ismael-VC"]  filename: learnjulia-es.jl  lang: es-es  --- -Julia es un nuevo lenguaje funcional homoiconic enfocado en computación técnica. -Aunque que tiene todo el poder de macros homoiconic, funciones de primera -clase, y control de bajo nivel, Julia es tan fácil de aprender y utilizar como -Python. + -Esto se basa en la versión de desarrollo actual de Julia, del 18 de octubre de -2013. +[Julia](http://julialanges.github.io) es un [lenguaje de programación](http://es.wikipedia.org/wiki/Lenguaje_de_programaci%C3%B3n) [multiplataforma](http://es.wikipedia.org/wiki/Multiplataforma) y [multiparadigma](http://es.wikipedia.org/wiki/Lenguaje_de_programaci%C3%B3n_multiparadigma) de [tipado dinámico](http://es.wikipedia.org/wiki/Tipado_din%C3%A1mico), [alto nivel](http://es.wikipedia.org/wiki/Lenguaje_de_alto_nivel) y [alto desempeño](http://es.wikipedia.org/wiki/Computaci%C3%B3n_de_alto_rendimiento) para la computación [genérica](http://es.wikipedia.org/wiki/Lenguaje_de_programaci%C3%B3n_de_prop%C3%B3sito_general), [técnica y científica](http://es.wikipedia.org/wiki/Computaci%C3%B3n_cient%C3%ADfica),  con una sintaxis que es familiar para los usuarios de otros entornos de computación técnica y científica. Provee de un [sofisticado compilador JIT](http://es.wikipedia.org/wiki/Compilaci%C3%B3n_en_tiempo_de_ejecuci%C3%B3n), [ejecución distribuida y paralela](http://docs.julialang.org/en/release-0.3/manual/parallel-computing), [precisión numérica](http://julia.readthedocs.org/en/latest/manual/integers-and-floating-point-numbers) y de una [extensa librería con funciones matemáticas](http://docs.julialang.org/en/release-0.3/stdlib). La librería estándar, escrita casi completamente en Julia, también integra las mejores y más maduras librerías de C y Fortran para el [álgebra lineal](http://docs.julialang.org/en/release-0.3/stdlib/linalg), [generación de números aleatorios](http://docs.julialang.org/en/release-0.3/stdlib/numbers/?highlight=random#random-numbers), [procesamiento de señales](http://docs.julialang.org/en/release-0.3/stdlib/math/?highlight=signal#signal-processing), y [procesamiento de cadenas](http://docs.julialang.org/en/release-0.3/stdlib/strings). Adicionalmente, la comunidad de [desarrolladores de Julia](https://github.com/JuliaLang/julia/graphs/contributors) contribuye un número de [paquetes externos](http://pkg.julialang.org) a través del gestor de paquetes integrado de Julia a un paso acelerado. [IJulia](https://github.com/JuliaLang/IJulia.jl), una colaboración entre las comunidades de [IPython](http://ipython.org) y Julia, provee de una poderosa interfaz gráfica basada en el [navegador para Julia](https://juliabox.org). -```ruby +En Julia los programas están organizados entorno al [despacho múltiple](http://docs.julialang.org/en/release-0.3/manual/methods/#man-methods); definiendo funciones y sobrecargándolas para diferentes combinaciones de tipos de argumentos, los cuales también pueden ser definidos por el usuario. + +### ¡Prueba Julia ahora mismo! + +* [TryJupyter](https://try.jupyter.org) +* [JuliaBox](https://juliabox.org) +* [SageMathCloud](https://cloud.sagemath.com) + +### Resumen de Características: -# Comentarios de una línea comienzan con una almohadilla (o signo gato) +* [Despacho múltiple](http://en.wikipedia.org/wiki/Multiple_dispatch): permite definir el comportamiento de las funciones a través de múltiples combinaciones de tipos de argumentos (**métodos**). +* Sistema de **tipado dinámico**: tipos para la documentación, la optimización y el despacho. +* [Buen desempeño](http://julialang.org/benchmarks), comparado al de lenguajes **estáticamente compilados** como C. +* [Gestor de paquetes](http://docs.julialang.org/en/release-0.3/stdlib/pkg) integrado. +* [Macros tipo Lisp](http://docs.julialang.org/en/release-0.3/manual/metaprogramming/#macros) y otras comodidades para la [meta programación](http://docs.julialang.org/en/release-0.3/manual/metaprogramming). +* Llamar funciones de otros lenguajes, mediante paquetes como: **Python** ([PyCall](https://github.com/stevengj/PyCall.jl)), [Mathematica](http://github.com/one-more-minute/Mathematica.jl), **Java** ([JavaCall](http://github.com/aviks/JavaCall.jl)), **R** ([Rif](http://github.com/lgautier/Rif.jl) y [RCall](http://github.com/JuliaStats/RCall.jl)) y **Matlab** ([MATLAB](http://github.com/JuliaLang/MATLAB.jl)). +* [Llamar funciones de C y Fortran](http://docs.julialang.org/en/release-0.3/manual/calling-c-and-fortran-code) **directamente**: sin necesidad de usar envoltorios u APIs especiales. +* Poderosas características de **línea de comandos** para [gestionar otros procesos](http://docs.julialang.org/en/release-0.3/manual/running-external-programs). +* Diseñado para la [computación paralela y distribuida](http://docs.julialang.org/en/release-0.3/manual/parallel-computing) **desde el principio**. +* [Corrutinas](http://en.wikipedia.org/wiki/Coroutine): hilos ligeros "**verdes**". +* Los [tipos definidos por el usuario](http://docs.julialang.org/en/release-0.3/manual/types) son tan **rápidos y compactos** como los tipos estándar integrados. +* [Generación automática de código](http://docs.julialang.org/en/release-0.3/stdlib/base/?highlight=%40code#internals) **eficiente y especializado** para diferentes tipos de argumentos. +* [Conversiones y promociones](http://docs.julialang.org/en/release-0.3/manual/conversion-and-promotion) para tipos numéricos y de otros tipos, **elegantes y extensibles**. +* Soporte eficiente para [Unicode](http://es.wikipedia.org/wiki/Unicode), incluyendo [UTF-8](http://es.wikipedia.org/wiki/UTF-8) pero sin limitarse solo a este. +* [Licencia MIT](https://github.com/JuliaLang/julia/blob/master/LICENSE.md): libre y de código abierto. + +Esto se basa en la versión `0.3.11`. + +```ruby +# Los comentarios de una línea comienzan con una almohadilla (o signo de gato). -#= Commentarios multilinea pueden escribirse -   usando '#=' antes de el texto  y '=#'  -   después del texto. También se pueden anidar. +#= +  Los comentarios multilínea pueden escribirse +  usando '#=' antes de el texto  y '=#' +  después del texto. También se pueden anidar.  =# -#################################################### -## 1. Tipos de datos primitivos y operadores. -#################################################### -# Todo en Julia es una expresión. +############################################## +# 1. Tipos de datos primitivos y operadores. # +############################################## + +# Todo en Julia es una expresión (Expr).  # Hay varios tipos básicos de números. -3 # => 3 (Int64) -3.2 # => 3.2 (Float64) -2 + 1im # => 2 + 1im (Complex{Int64}) -2//3 # => 2//3 (Rational{Int64}) +3          # => 3          # Int64 +3.2        # => 3.2        # Float64 +2 + 1im    # => 2 + 1im    # Complex{Int64} +2 // 3     # => 2//3       # Rational{Int64}  # Todos los operadores infijos normales están disponibles. -1 + 1 # => 2 -8 - 1 # => 7 -10 * 2 # => 20 -35 / 5 # => 7.0 -5/2 # => 2.5 # dividir un Int por un Int siempre resulta en un Float -div (5, 2) # => 2 # para un resultado truncado, usa div -5 \ 35 # => 7.0 -2 ^ 2 # => 4 # exponente, no es xor -12 % 10 # => 2 - -# Refuerza la precedencia con paréntesis -(1 + 3) * 2 # => 8 - -# Operadores a nivel de bit -~2 # => -3   # bitwise not -3 & 5 # => 1 # bitwise and -2 | 4 # => 6 # bitwise or -2 $ 4 # => 6 # bitwise xor -2 >>> 1 # => 1 # logical shift right -2 >> 1  # => 1 # arithmetic shift right -2 << 1  # => 4 # logical/arithmetic shift left - -# Se puede utilizar la función bits para ver la representación binaria de un -# número. +1 + 1        # => 2 +8 - 1        # => 7 +10 * 2       # => 20 +35 / 5       # => 7.0    # dividir un Int por un Int siempre resulta +                         # en un Float +5 / 2        # => 2.5 +div(5, 2)    # => 2      # para un resultado truncado, usa la función div +5 \ 35       # => 7.0 +2 ^ 2        # => 4      # exponente, no es XOR +12 % 10      # => 2 + +# Refuerza la precedencia con paréntesis. +(1 + 3) * 2    # => 8 + +# Operadores a nivel de bit. +~2         # => -3    # bitwise NOT +3 & 5      # => 1     # bitwise AND +2 | 4      # => 6     # bitwise OR +2 $ 4      # => 6     # bitwise XOR +2 >>> 1    # => 1     # desplazamiento lógico hacia la derecha +2 >> 1     # => 1     # desplazamiento aritmético hacia la derecha +2 << 1     # => 4     # desplazamiento lógico/aritmético hacia la izquierda + +# Se puede utilizar la función bits para ver la representación +# binaria de un número.  bits(12345)  # => "0000000000000000000000000000000000000000000000000011000000111001" +  bits(12345.0)  # => "0100000011001000000111001000000000000000000000000000000000000000" -# Valores 'boolean' (booleanos) son primitivos -true -false - -# Operadores Boolean (booleanos) -!true # => false -!false # => true -1 == 1 # => true -2 == 1 # => false -1 != 1 # => false -2 != 1 # => true -1 < 10 # => true -1 > 10 # => false -2 <= 2 # => true -2 >= 2 # => true +# Los valores booleanos (Bool) son primitivos. +true     # => true +false    # => false + +# Operadores booleanos. +!true     # => false +!false    # => true +1 == 1    # => true +2 == 1    # => false +1 != 1    # => false +2 != 1    # => true +1 < 10    # => true +1 > 10    # => false +2 <= 2    # => true +2 >= 2    # => true +  # ¡Las comparaciones pueden ser concatenadas! -1 < 2 < 3 # => true -2 < 3 < 2 # => false +1 < 2 < 3    # => true +2 < 3 < 2    # => false -# Strings se crean con "  -"Esto es un string." +# Los literales de cadenas (String) se crean con la comilla doble: " +"Esto es una cadena." -# Literales de caracteres se escriben con ' +# Los literales de caracteres (Char) se crean con la comilla simple: '  'a' -# Una string puede ser indexado como una array de caracteres -"Esto es un string."[1] # => 'E' # Índices en Julia empiezen del 1 -# Sin embargo, esto no va a funcionar bien para strings UTF8,  +# Una cadena puede ser indexada como una arreglo de caracteres. +"Esto es un string."[1]    # => 'E'    # Los índices en Julia comienzan en: 1 + +# Sin embargo, esto no va a funcionar bien para las cadenas UTF8 (UTF8String),  # Lo que se recomienda es la iteración (map, for, etc). -# $ puede ser utilizado para la interpolación de strings: -"2 + 2 = $(2 + 2)" # => "2 + 2 = 4" -# Se puede poner cualquier expresión de Julia dentro los paréntesis. +# $ puede ser utilizado para la interpolación de cadenas, se puede poner +# cualquier expresión de Julia dentro los paréntesis. +"2 + 2 = $(2 + 2)"    # => "2 + 2 = 4" -# Otro forma de formatear strings es el macro printf -@printf "%d es menor de %f" 4.5 5.3 # 5 es menor de 5.300000 +# Otra forma para formatear cadenas es usando el macro printf. +@printf "%d es menor de %f\n" 4.5 5.3    # 5 es menor de 5.300000 -# Imprimir es muy fácil -println("Soy Julia. ¡Encantado de conocerte!") +# ¡Imprimir es muy fácil! +println("¡Hola Julia!")    # ¡Hola Julia! -#################################################### -## 2. Variables y Colecciones -#################################################### + +############################## +# 2. Variables y Colecciones # +##############################  # No hay necesidad de declarar las variables antes de asignarlas. -una_variable = 5 # => 5 -una_variable # => 5 +una_variable = 5    # => 5 +una_variable        # => 5 -# Acceder a variables no asignadas previamente es una excepción. +# Acceder a una variable no asignada previamente es una excepción.  try -    otra_variable # => ERROR: some_other_var not defined +    otra_variable    # ERROR: otra_variable not defined  catch e -    println(e) +    println(e)       # UndefVarError(:otra_variable)  end -# Los nombres de variables comienzan con una letra. -# Después de eso, puedes utilizar letras, dígitos, guiones y signos de +# Los nombres de variables comienzan con una letra o guion bajo: _. +# Después de eso, puedes utilizar letras, dígitos, guiones bajos y signos de  # exclamación. -OtraVariable123! = 6 # => 6 +otraVariable_123! = 6    # => 6 + +# También puedes utilizar caracteres Unicode. +☃ = 8    # => 8 -# También puede utilizar caracteres unicode -☃ = 8 # => 8  # Estos son especialmente útiles para la notación matemática -2 * π # => 6.283185307179586 - -# Una nota sobre las convenciones de nomenclatura de Julia: -# -# * Los nombres de las variables aparecen en minúsculas, con separación de  -#   palabra indicado por underscore ('\ _').  -# -# * Los nombres de los tipos comienzan con una letra mayúscula y separación de -#   palabras se muestra con CamelCase en vez de underscore. -# -# * Los nombres de las funciones y los macros están en minúsculas, sin -#   underscore. -# -# * Funciones que modifican sus inputs tienen nombres que terminan en!. Estos  -#   funciones a veces se llaman mutating functions o in-place functions. - -# Los Arrays almacenan una secuencia de valores indexados entre 1 hasta n -a = Int64[] # => 0-element Int64 Array - -# Literales de arrays 1-dimensionales se pueden escribir con valores separados -# por comas. -b = [4, 5, 6] # => 3-element Int64 Array: [4, 5, 6] -b[1] # => 4 -b[end] # => 6 - -# Los arrays 2-dimensionales usan valores separados por espacios y filas -# separados por punto y coma. -matrix = [1 2; 3 4] # => 2x2 Int64 Array: [1 2; 3 4] - -# Añadir cosas a la final de una lista con push! y append! -push!(a,1)     # => [1] -push!(a,2)     # => [1,2] -push!(a,4)     # => [1,2,4] -push!(a,3)     # => [1,2,4,3] -append!(a,b) # => [1,2,4,3,4,5,6] - -# Eliminar de la final con pop -pop!(b)        # => 6 y b ahora es [4,5] - -# Vamos a ponerlo de nuevo  -push!(b, 6)   # b es ahora [4,5,6] de nuevo. - -a[1] # => 1 # recuerdan que los índices de Julia empiezan desde 1, no desde 0! - -# end es una abreviatura para el último índice. Se puede utilizar en cualquier  -# expresión  de indexación -a[end] # => 6 - -# tambien hay shift y unshift -shift!(a) # => 1 y a es ahora [2,4,3,4,5,6] -unshift!(a,7) # => [7,2,4,3,4,5,6] - -# Nombres de funciónes que terminan en exclamaciones indican que modifican  -# su argumento. -arr = [5,4,6] # => 3-element Int64 Array: [5,4,6] -sort(arr) # => [4,5,6]; arr es todavía [5,4,6] -sort!(arr) # => [4,5,6]; arr  es ahora [4,5,6] - -# Buscando fuera de límites es un BoundsError +# (multiplicación implicita). +2π    # => 6.283185307179586 + +#= +  Una nota sobre las convenciones de nomenclatura de Julia: + +  * Los nombres de las variables aparecen en minúsculas, con separación de +    palabra indicado por un guion bajo: + +    otra_variable + +  * Los nombres de los tipos comienzan con una letra mayúscula y separación de +    palabras se muestra con CamelCase en vez de guión bajo: + +    OtroTipo + +  * Los nombres de las funciones y los macros están en minúsculas, sin +    underscore: + +    otromacro + +  * Funciones que modifican sus entradas tienen nombres que terminan en: !. +    Estas funciones a veces se les llaman funciones transformadoras o +    funciones in situ: + +    otra_funcion! +=# + +# Los arreglos (Array) almacenan una secuencia de valores indexados de entre 1 hasta n. +a = Int64[]    # => 0-element Array{Int64,1} + +# Los literales de arregos unidimensionales se pueden escribir con valores +# separados por comas. +b = [4, 5, 6] +#= + => 3-element Array{Int64,1}: +     4 +     5 +     6 +=# +b[1]      # => 4 +b[end]    # => 6 + +# Los arreglos bidimensionales usan valores separados por espacios y filas +# separadas por punto y coma. +matrix = [1 2; 3 4] +#= + => 2x2 Array{Int64,2}: +     1  2 +     3  4 +=# + +# Añadir cosas al final de un arreglo con push! y append!. +push!(a, 1)      # => [1] +push!(a, 2)      # => [1,2] +push!(a, 4)      # => [1,2,4] +push!(a, 3)      # => [1,2,4,3] +append!(a, b)    # => [1,2,4,3,4,5,6] + +# Eliminar del final con pop!. +pop!(b)    # => 6 y b ahora es: [4,5] + +# Vamos a ponerlo de nuevo. +push!(b, 6)    # b es ahora [4,5,6] de nuevo + +a[1]    # => 1    # recuerda, los índices de Julia empiezan desde 1, no desde 0! + +# end es una abreviatura para el último índice. Se puede utilizar en cualquier +# expresión  de indexación. +a[end]    # => 6 + +# También hay shift! y unshift!. +shift!(a)         # => 1 y a es ahora: [2,4,3,4,5,6] +unshift!(a, 7)    # => [7,2,4,3,4,5,6] + +# Los nombres de funciones que terminan en exclamaciones indican que modifican +# su o sus argumentos de entrada. +arr = [5, 4, 6]    # => 3-element Array{Int64,1}: [5,4,6] +sort(arr)          # => [4,5,6] y arr es todavía: [5,4,6] +sort!(arr)         # => [4,5,6] y arr es ahora: [4,5,6] + +# Buscando fuera de límites es un BoundsError.  try -    a[0] # => ERROR: BoundsError() in getindex at array.jl:270 -    a[end+1] # => ERROR: BoundsError() in getindex at array.jl:270 +    a[0]          # ERROR: BoundsError() in getindex at array.jl:270 +    a[end+1]      # ERROR: BoundsError() in getindex at array.jl:270  catch e -    println(e) +    println(e)    # BoundsError()  end -# Errors dan la línea y el archivo de su procedencia, aunque sea en el standard -# library. Si construyes Julia de source, puedes buscar en el source para -# encontrar estos archivos. +# Las excepciones y los errores dan la línea y el archivo de su procedencia, +# aunque provenga de la librería estándar. Si compilas Julia del código fuente, +# puedes buscar en el código para encontrar estos archivos. -# Se puede inicializar arrays de un range -a = [1:5] # => 5-element Int64 Array: [1,2,3,4,5] +# Se puede inicializar un arreglo con un rango (Range). +a = [1:5]    # => 5-element Array{Int64,1}: [1,2,3,4,5] -# Puedes mirar en ranges con sintaxis slice. -a[1:3] # => [1, 2, 3] -a[2:end] # => [2, 3, 4, 5] +# Puedes mirar en los rangos con la sintaxis de rebanada. +a[1:3]       # => [1,2,3] +a[2:end]     # => [2,3,4,5] -# Eliminar elementos de una array por índice con splice! -arr = [3,4,5] -splice!(arr,2) # => 4 ; arr es ahora [3,5] +# Eliminar elementos de un arreglo por índice con splice! +arr = [3, 4, 5] +splice!(arr, 2)    # => 4 y arr es ahora: [3,5] -# Concatenar listas con append! -b = [1,2,3] -append!(a,b) # ahroa a es [1, 2, 3, 4, 5, 1, 2, 3] +# Concatenar arreglos con append! +b = [1, 2, 3] +append!(a, b)    # a ahora es: [1,2,3,4,5,1,2,3] -# Comprueba la existencia en una lista con in -in(1, a) # => true +# Comprueba la existencia de un elemento en un arreglo con in. +in(1, a)    # => true -# Examina la longitud con length -length(a) # => 8 +# Examina la longitud con length. +length(a)    # => 8 + +# Las tuplas (Tuple) son inmutables. +tup = (1, 2, 3)    # => (1,2,3)    # una tupla tipo (Int64,Int64,Int64) +tup[1]             # => 1 -# Tuples son immutable. -tup = (1, 2, 3) # => (1,2,3) # un (Int64,Int64,Int64) tuple. -tup[1] # => 1  try: -    tup[1] = 3 # => ERROR: no method setindex!((Int64,Int64,Int64),Int64,Int64) +    tup[1] = 3     # ERROR: no method setindex!((Int64,Int64,Int64),Int64,Int64)  catch e -    println(e) +    println(e)     # MethodError(setindex!,(:tup,3,1))  end -# Muchas funciones de lista también trabajan en las tuples -length(tup) # => 3 -tup[1:2] # => (1,2) -in(2, tup) # => true +# Muchas funciones de arreglos también trabajan en con las tuplas. +length(tup)    # => 3 +tup[1:2]       # => (1,2) +in(2, tup)     # => true + +# Se pueden desempacar las tuplas en variables individuales. +a, b, c = (1, 2, 3)    # => (1,2,3)    # ahora a es 1, b es 2 y c es 3 + +# Los tuplas se crean, incluso si se omiten los paréntesis. +d, e, f = 4, 5, 6    # => (4,5,6) -# Se puede desempacar tuples en variables -a, b, c = (1, 2, 3) # => (1,2,3)  # a is now 1, b is now 2 and c is now 3 +# Una tupla de un elemento es distinta del valor que contiene. +(1,) == 1    # => false +(1) == 1     # => true -# Los tuples se crean, incluso si se omite el paréntesis -d, e, f = 4, 5, 6 # => (4,5,6) +# Mira que fácil es cambiar dos valores! +e, d = d, e    # => (5,4)    # ahora d es 5 y e es 4 -# Un tuple 1-elemento es distinto del valor que contiene -(1,) == 1 # => false -(1) == 1 # => true +# Los diccionarios (Dict) son arreglos asociativos. +dicc_vacio = Dict()    # => Dict{Any,Any} with 0 entries -# Mira que fácil es cambiar dos valores -e, d = d, e  # => (5,4) # d is now 5 and e is now 4 +# Se puede crear un diccionario usando una literal. +dicc_lleno = ["uno" => 1, "dos" => 2, "tres" => 3] +#= + => Dict{ASCIIString,Int64} with 3 entries: +      "tres" => 3 +      "dos"  => 2 +      "uno"  => 1 +=# +# Busca valores con: []. +dicc_lleno["uno"]    # => 1 -# Dictionaries almanecan mapeos -dict_vacio = Dict() # => Dict{Any,Any}() +# Obtén todas las claves con. +keys(dicc_lleno) +#= + => KeyIterator for a Dict{ASCIIString,Int64} with 3 entries. Keys: +      "tres" +      "dos" +      "uno" +=# -# Se puede crear un dictionary usando un literal -dict_lleno = ["one"=> 1, "two"=> 2, "three"=> 3] -# => Dict{ASCIIString,Int64} +# Nota: los elementos del diccionario no están ordenados y no se guarda el orden +# en que se insertan. -# Busca valores con [] -dict_lleno["one"] # => 1 +# Obtén todos los valores. +values(dicc_lleno) +#= + => ValueIterator for a Dict{ASCIIString,Int64} with 3 entries. Values: +      3 +      2 +      1 +=# -# Obtén todas las claves  -keys(dict_lleno) -# => KeyIterator{Dict{ASCIIString,Int64}}(["three"=>3,"one"=>1,"two"=>2]) -# Nota - claves del dictionary no están ordenados ni en el orden en que se -# insertan. +# Nota: igual que el anterior en cuanto a ordenamiento de los elementos. -# Obtén todos los valores -values(dict_lleno) -# => ValueIterator{Dict{ASCIIString,Int64}}(["three"=>3,"one"=>1,"two"=>2]) -# Nota - Igual que el anterior en cuanto a ordenamiento de claves. +# Comprueba si una clave existe en un diccionario con in y haskey. +in(("uno", 1), dicc_lleno)     # => true +in(("tres", 3), dicc_lleno)    # => false -# Compruebe si hay existencia de claves en un dictionary con in y haskey -in(("uno", 1), dict_lleno) # => true -in(("tres", 3), dict_lleno) # => false -haskey(dict_lleno, "one") # => true -haskey(dict_lleno, 1) # => false +haskey(dicc_lleno, "uno")      # => true +haskey(dicc_lleno, 1)          # => false -# Tratando de buscar una clave que no existe producirá un error +# Tratar de obtener un valor con una clave que no existe producirá un error.  try -    dict_lleno["dos"] # => ERROR: key not found: dos in getindex at dict.jl:489 +    # ERROR: key not found: cuatro in getindex at dict.jl:489 +    dicc_lleno["cuatro"]  catch e -    println(e) +    println(e)    # KeyError("cuatro")  end -# Utilice el método get para evitar ese error proporcionando un valor -# predeterminado -# get(dictionary,key,default_value) -get(dict_lleno,"one",4) # => 1 -get(dict_lleno,"four",4) # => 4 +# Utiliza el método get para evitar este error proporcionando un valor +# predeterminado: get(diccionario, clave, valor_predeterminado). +get(dicc_lleno, "uno", 4)       # => 1 +get(dicc_lleno, "cuatro", 4)    # => 4 -# Usa Sets para representar colecciones (conjuntos) de valores únicos, no -# ordenadas -conjunto_vacio = Set() # => Set{Any}() -# Iniciar una set de valores -conjunto_lleno = Set(1,2,2,3,4) # => Set{Int64}(1,2,3,4) +# Usa conjuntos (Set) para representar colecciones de valores únicos, no +# ordenados. +conjunto_vacio = Set()    # => Set{Any}({}) -# Añadir más valores a un conjunto -push!(conjunto_lleno,5) # => Set{Int64}(5,4,2,3,1) -push!(conjunto_lleno,5) # => Set{Int64}(5,4,2,3,1) +# Iniciar una conjunto de valores. +conjunto_lleno = Set(1, 2, 2, 3, 4)    # => Set{Int64}({4,2,3,1}) -# Compruebe si los valores están en el conjunto -in(2, conjunto_lleno) # => true -in(10, conjunto_lleno) # => false +# Añadir más valores a un conjunto. +push!(conjunto_lleno, 5)    # => Set{Int64}({4,2,3,5,1}) +push!(conjunto_lleno, 5)    # => Set{Int64}({4,2,3,5,1}) -# Hay funciones de intersección de conjuntos, la unión, y la diferencia. -conjunto_otro= Set(3, 4, 5, 6) # => Set{Int64}(6,4,5,3) -intersect(conjunto_lleno, conjunto_otro) # => Set{Int64}(3,4,5) -union(conjunto_lleno, conjunto_otro) # => Set{Int64}(1,2,3,4,5,6) -setdiff(Set(1,2,3,4),Set(2,3,5)) # => Set{Int64}(1,4) +# Comprobar si los valores están en el conjunto. +in(2, conjunto_lleno)     # => true +in(10, conjunto_lleno)    # => false +# Hay funciones de intersección, unión y diferencia de conjuntos. +otro_conjunto = Set(3, 4, 5, 6)             # => Set{Int64}({6,4,5,3}) +intersect(conjunto_lleno, otro_conjunto)    # => Set{Int64}({3,4,5}) +union(conjunto_lleno, otro_conjunto)        # => Set{Int64}({1,2,3,4,5,6}) +setdiff(Set(1, 2, 3, 4), Set(2, 3, 5))      # => Set{Int64}({1,4}) -#################################################### -## 3. Control de Flujo -#################################################### -# Hagamos una variable +####################### +# 3. Control de Flujo # +####################### + +# Hagamos una variable.  una_variable = 5 -# Aquí está una declaración de un 'if'. La indentación no es significativa en -# Julia +# Aquí está la declaración de un if. La indentación no es significativa en +# Julia.  if una_variable > 10 -    println("una_variable es completamente mas grande que 10.") -elseif una_variable < 10    # Este condición 'elseif' es opcional. -    println("una_variable es mas chica que 10.") -else                    # Esto también es opcional. -    println("una_variable es de hecho 10.") +    println("una_variable es completamente mayor que 10.") +elseif una_variable < 10                     # esta condición elseif es opcional +    println("una_variable es menor que 10.") +else                                         # esto también es opcional +    println("De echo una_variable es 10.")  end -# => imprime "una_variable es mas chica que 10." +# imprime: una_variable es menor que 10. -# For itera sobre tipos iterables -# Tipos iterables incluyen Range, Array, Set, Dict, y String. -for animal=["perro", "gato", "raton"] -    println("$animal es un mamifero") -    # Se puede usar $ para interpolar variables o expresiónes en strings +# El bucle for itera sobre tipos iterables, ie. Range, Array, Set, +# Dict y String. +for animal in ["perro", "gato", "ratón"] +    # Se puede usar $ para interpolar variables o expresiones en ls cadenas. +    println("$animal es un mamífero.")  end -# imprime: -#    perro es un mamifero -#    gato es un mamifero -#    raton es un mamifero +#= + imprime: +   perro es un mamífero. +   gato es un mamífero. +   ratón es un mamífero. +=# -for a in ["perro"=>"mamifero","gato"=>"mamifero","raton"=>"mamifero"] -    println("$(a[1]) es un $(a[2])") +for a in ["perro" => "mamífero", "gato" => "mamífero", "ratón" => "mamífero"] +    println("$(a[1]) es un $(a[2]).")  end -# imprime: -#    perro es un mamifero -#    gato es un mamifero -#    raton es un mamifero +#= + imprime: +   perro es un mamífero. +   gato es un mamífero. +   ratón es un mamífero. +=# -for (k,v) in ["perro"=>"mamifero", "gato"=>"mamifero", "raton"=>"mamifero"] -    println("$k es un $v") +for (k,v) in ["perro"=>"mamífero", "gato"=>"mamífero", "ratón"=>"mamífero"] +    println("$k es un $v.")  end -# imprime: -#    perro es un mamifero -#    gato es un mamifero -#    raton es un mamifero +#= + imprime: +   perro es un mamífero. +   gato es un mamífero. +   ratón es un mamífero. +=# -# While itera hasta que una condición no se cumple. +# El bucle while itera hasta que una condición se deje de cumplir.  x = 0  while x < 4      println(x) -    x += 1  # versión corta de x = x + 1 +    x += 1    # versión corta de: x = x + 1  end -# imprime: -#   0 -#   1 -#   2 -#   3 +#= +imprime: +  0 +  1 +  2 +  3 +=# -# Maneja excepciones con un bloque try/catch -try -   error("ayuda") +# Maneja excepciones con un bloque try/catch. +try    # intentar +   error("Ooops!")  catch e -   println("capturando $e") +   println("capturando: $e")    # capturando: ErrorException("Ooops!")  end -# => capturando ErrorException("ayuda") -#################################################### -## 4. Funciones -#################################################### +################ +# 4. Funciones # +################ -# Usa 'function' para crear nuevas funciones +# Usa function para crear nuevas funciones. -#function nombre(arglist) -#  cuerpo... -#end +#= +    function nombre(arglist) +        cuerpo... +    end +=#  function suma(x, y)      println("x es $x e y es $y") -    # Las funciones devuelven el valor de su última declaración +    # las funciones devuelven el valor de su última expresión      x + y  end +# => suma (generic function with 1 method) + +suma(5, 6)    # => 11    # después de imprimir: x es 5 e y es 6 -suma(5, 6) # => 11 # después de imprimir "x es 5 e y es de 6" +# También puedes usar esta otra sintaxis para definir funciones! +resta(x, y) = x - y    # => resta (generic function with 1 method)  # Puedes definir funciones que toman un número variable de -# argumentos posicionales +# argumentos posicionales (el ... se llama un splat).  function varargs(args...) +    # Usa la palabra clave return para regresar desde cualquier +    # lugar de la función.      return args -    # Usa la palabra clave return para devolver en cualquier lugar de la función  end  # => varargs (generic function with 1 method) -varargs(1,2,3) # => (1,2,3) +varargs(1, 2, 3)      # => (1,2,3) +varargs([1, 2, 3])    # => ([1,2,3],) -# El ... se llama un splat. -# Acabamos de utilizar lo en una definición de función. -# También se puede utilizar en una llamada de función, -# donde va splat un Array o el contenido de un Tuple en la lista de argumentos. -Set([1,2,3])    # => Set{Array{Int64,1}}([1,2,3]) # Produce un Set de Arrays -Set([1,2,3]...) # => Set{Int64}(1,2,3) # esto es equivalente a Set(1,2,3) +# Acabamos de utilizar el splat (...) en la definición de una función. También +# se puede utilizar al llamar a una función, donde se esparce un arreglo, tupla +# o en general una secuencia iterable en la tupla de argumentos. +varargs([1, 2, 3]...)    # => (1,2,3)    # igual que: varargs(1, 2, 3) -x = (1,2,3)     # => (1,2,3) -Set(x)          # => Set{(Int64,Int64,Int64)}((1,2,3)) # un Set de Tuples -Set(x...)       # => Set{Int64}(2,3,1) +x = (1, 2, 3)    # => (1,2,3) +varargs(x)       # => ((1,2,3),) +varargs(x...)    # => (1,2,3) +varargs("abc"...)    # => ('a','b','c') -# Puede definir funciones con argumentos posicionales opcionales -function defaults(a,b,x=5,y=6) +# Puedes definir funciones con argumentos posicionales opcionales. +function defaults(a, b, x=5, y=6)      return "$a $b y $x $y"  end +# => defaults (generic function with 3 methods) + +defaults('h', 'g')              # => "h g y 5 6" +defaults('h', 'g', 'j')         # => "h g y j 6" +defaults('h', 'g', 'j', 'k')    # => "h g y j k" -defaults('h','g') # => "h g y 5 6" -defaults('h','g','j') # => "h g y j 6" -defaults('h','g','j','k') # => "h g y j k"  try -    defaults('h') # => ERROR: no method defaults(Char,) -    defaults() # => ERROR: no methods defaults() +    defaults('h')    # ERROR: `defaults` has no method matching defaults(::Char) +    defaults()       # ERROR: `defaults` has no method matching defaults()  catch e -    println(e) +    println(e)       # MethodError(defaults,('h',))  end -# Puedes definir funciones que toman argumentos de palabra clave -function args_clave(;k1=4,nombre2="hola") # note the ; -    return ["k1"=>k1,"nombre2"=>nombre2] +# Puedes definir funciones que tomen argumentos de palabras clave. +function args_clave(;k1=4, nombre2="hola")    # nota el punto y coma: ; +    return ["k1" => k1, "nombre2" => nombre2]  end +# => args_clave (generic function with 1 method) -args_clave(nombre2="ness") # => ["nombre2"=>"ness","k1"=>4] -args_clave(k1="mine") # => ["k1"=>"mine","nombre2"=>"hola"] -args_clave() # => ["nombre2"=>"hola","k1"=>4] +args_clave(nombre2="ness")    # => ["nombre2"=>"ness","k1"=>4] +args_clave(k1="mine")         # => ["k1"=>"mine","nombre2"=>"hola"] +args_clave()                  # => ["nombre2"=>"hola","k1"=>4] -# Puedes combinar todo tipo de argumentos en la misma función -function todos_los_args(arg_normal, arg_posicional_opcional=2; arg_clave="foo") -    println("argumento normal: $arg_normal") -    println("argumento optional: $arg_posicional_opcional") -    println("argumento de clave: $arg_clave") +# Puedes combinar todo tipo de argumentos en la misma función. +function todos_los_args(arg_posicional, arg_opcional=2; arg_clave="foo") +    println("argumento posicional: $arg_posicional") +    println("  argumento opcional: $arg_opcional") +    println("     argumento clave: $arg_clave")  end +# => todos_los_args (generic function with 2 methods) +# No se necesita punto y coma ; al llamar la función usando un argumento clave, +# esto solo es necesario en la definición de la función.  todos_los_args(1, 3, arg_clave=4) -# imprime: -#   argumento normal: 1 -#   argumento optional: 3 -#   argumento de clave: 4 +#= + imprime: +   argumento posicional: 1 +     argumento opcional: 3 +        argumento clave: 4 +=# -# Julia tiene funciones de primera clase +# Julia tiene funciones de primera clase.  function crear_suma(x) -    suma = function (y) +    suma = function (y)    # función anónima          return x + y      end      return suma  end +# => crear_suma (generic function with 1 method) -# Esta es el sintaxis "stabby lambda" para crear funciones anónimas -(x -> x > 2)(3) # => true +# Esta es otra sintaxis (estilo cálculo lambda), para crear funciones anónimas. +(x -> x > 2)(3)    # => true  # Esta función es idéntica a la crear_suma implementación anterior. -function crear_suma(x) -    y -> x + y -end +crear_suma(x) = y -> x + y -# También puedes nombrar la función interna, si quieres +# También puedes nombrar la función interna, si quieres.  function crear_suma(x)      function suma(y)          x + y      end      suma  end +# => crear_suma (generic function with 1 method) -suma_10 = crear_suma(10) -suma_10(3) # => 13 +suma_10 = crear_suma(10)    # => suma (generic function with 1 method) +suma_10(3)                  # => 13 +# Hay funciones integradas de orden superior. +map(suma_10, [1, 2, 3])                # => [11,12,13] +filter(x -> x > 5, [3, 4, 5, 6, 7])    # => [6,7] -# Hay funciones integradas de orden superior -map(suma_10, [1,2,3]) # => [11, 12, 13] -filter(x -> x > 5, [3, 4, 5, 6, 7]) # => [6, 7] +# Se puede pasar un bloque a las funciones cuyo primer argumento posicional +# es otra función, como en map y filter. +map([1, 2, 3]) do arr +    suma_10(arr) +end +#= + => 3-element Array{Int64,1}: +     11 +     12 +     13 +=# -# Podemos usar listas por comprensión para mapeos -[suma_10(i) for i=[1, 2, 3]] # => [11, 12, 13] -[suma_10(i) for i in [1, 2, 3]] # => [11, 12, 13] +filter([3, 4, 5, 6, 7]) do arr +    (x -> x > 5)(arr) +end +#= + => 2-element Array{Int64,1}: +     6 +     7 +=# -#################################################### -## 5. Tipos -#################################################### +# Podemos usar comprensiones de listas multidimensionales. +[suma_10(i) for i = [1, 2, 3]]     # => [11, 12, 13]    # 1D +[suma_10(i) for i in [1, 2, 3]]    # => [11, 12, 13] + +[i*j for i = [1:3], j in [1:3]]    # 2D +#= + => 3x3 Array{Int64,2}: +     1  2  3 +     2  4  6 +     3  6  9 +=# + +[i*j/k for i = [1:3], j = [1:3], k in [1:3]]    # 3D +#= + => 3x3x3 Array{Float64,3}: +     [:, :, 1] = +      1.0  2.0  3.0 +      2.0  4.0  6.0 +      3.0  6.0  9.0 + +     [:, :, 2] = +      0.5  1.0  1.5 +      1.0  2.0  3.0 +      1.5  3.0  4.5 + +     [:, :, 3] = +      0.333333  0.666667  1.0 +      0.666667  1.33333   2.0 +      1.0       2.0       3.0 +=# + + +############ +# 5. Tipos # +############ -# Julia tiene sistema de tipos.  # Cada valor tiene un tipo y las variables no tienen propios tipos. -# Se puede utilizar la función `typeof` para obtener el tipo de un valor. -typeof(5) # => Int64 +# Se puede utilizar la función typeof para obtener el tipo de un valor. +typeof(5)    # => Int64    # en un sistema de 64 bits, de lo contrario: Int32 -# Los tipos son valores de primera clase -typeof(Int64) # => DataType -typeof(DataType) # => DataType -# DataType es el tipo que representa los tipos, incluyéndose a sí mismo. +# Los tipos son valores de primera clase, DataType es el tipo que representa a +# los tipos, incluyéndose a sí mismo. +typeof(Int64)       # => DataType +typeof(DataType)    # => DataType -# Los tipos se usan para la documentación, optimizaciones, y envio. -# No están comprobados estáticamente. +# Los tipos se usan para la documentación, para optimizaciones +# y el despacho múltiple. No están comprobados estáticamente. -# Los usuarios pueden definir tipos  -# Son como registros o estructuras en otros idiomas.  -# Nuevos tipos se definen utilizado la palabra clave `type`. +# Los usuarios pueden definir sus propios tipos. +# Son como registros o estructuras en otros idiomas. +# Un nuevo tipos se define utilizado la palabra clave type.  # type Nombre -#   field::OptionalType +#   atributo::UnTipo    # las anotaciones de tipos son opcionales  #   ...  # end  type Tigre -  longituddecola::Float64 -  colordelpelaje # no incluyendo una anotación de tipo es el mismo que `::Any` +    longitud_cola::Float64 +    color_pelaje            # sin una anotación de tipo, es lo mismo que `::Any`  end -# Los argumentos del constructor por default son las propiedades  -# del tipo, en el orden en que están listados en la definición -tigger = Tigre(3.5,"anaranjado") # => Tiger(3.5,"anaranjado") +# Los argumentos del constructor por defecto son los atributos +# del tipo, en el orden en que están listados en la definición. +tigre = Tigre(3.5, "anaranjado")    # => Tigre(3.5,"anaranjado") -# El tipo funciona como la función constructora de valores de ese tipo -sherekhan = typeof(tigger)(5.6,"fuego") # => Tiger(5.6,"fuego") +# El tipo funciona como método constructor para los valores de ese tipo. +sherekhan = typeof(tigre)(5.6, "fuego")    # => Tigre(5.6,"fuego") -# Este estilo de tipos son llamados tipos concrete  -# Se pueden crear instancias, pero no pueden tener subtipos.  -# La otra clase de tipos es tipos abstractos (abstract types). +# Este estilo de tipos son llamados tipos concretos. +# Se pueden crear instancias de estos, pero no pueden tener subtipos. +# La otra clase de tipos son los tipos abstractos.  # abstract Nombre -abstract Gato # sólo un nombre y un punto en la jerarquía de tipos - -# De los tipos Abstract no se pueden crear instancias, pero pueden tener -# subtipos.  Por ejemplo, Number es un tipo abstracto. -subtypes(Number) # => 6-element Array{Any,1}: -                 #     Complex{Float16} -                 #     Complex{Float32} -                 #     Complex{Float64} -                 #     Complex{T<:Real} -                 #     Real -subtypes(Gato) # => 0-element Array{Any,1} - -# Cada tipo tiene un supertipo, utilice la función `súper` para conseguirlo. -typeof(5) # => Int64 -super(Int64) # => Signed -super(Signed) # => Real -super(Real) # => Number -super(Number) # => Any -super(super(Signed)) # => Number -super(Any) # => Any -# Todo de estos tipos, a excepción de Int64, son abstractos. - -# <: es el operador de subtipos -type Leon <: Gato # Leon es un subtipo de Gato -  color_de_crin -  rugido::String -end +abstract Gato    # sólo un nombre y un punto en la jerarquía de tipos + +# No se pueden crear instancias de los tipos abstractos, pero pueden tener +# subtipos. Por ejemplo, Number es un tipo abstracto. +subtypes(Number) +#= + => 2-element Array{Any,1}: +     Complex{T<:Real} +     Real +=# + +subtypes(Gato)    # => 0-element Array{Any,1} -# Se puede definir más constructores para su tipo. -# Sólo defina una función del mismo nombre que el tipo -# y llame a un constructor existente para obtener un valor del tipo correcto -Leon(rugido::String) = Leon("verde",rugido) -# Este es un constructor externo porque es fuera de la definición del tipo - -type Pantera <: Gato # Pantera tambien es un a subtipo de Cat -  color_de_ojos -  Pantera() = new("verde") -    # Panteras sólo tendrán este constructor, y ningún constructor -    # predeterminado. +# Cada tipo tiene un supertipo, utiliza la función súper para conseguirlo. +typeof(5)               # => Int64 +super(Int64)            # => Signed +super(Signed)           # => Integer +super(Integer)          # => Real +super(Real)             # => Number +super(Number)           # => Any +super(super(Signed))    # => Real +super(Any)              # => Any + +# Todos estos tipos, a excepción de Int64, son abstractos. + +# <: es el operador de subtipos. +type Leon <: Gato    # Leon es un subtipo de Gato +    color_crin +    rugido::String  end -# Utilizar constructores internos, como Panther hace, te da control sobre cómo -# se pueden crear valores del tipo.  Cuando sea posible, debes utilizar -# constructores exteriores en lugar de los internos. -#################################################### -## 6.  Envio múltiple -#################################################### +# Se pueden definir más constructores para un tipo. +# Sólo define una función del mismo nombre que el tipo y llama al constructor +# existente para obtener un valor del tipo correcto. -# En Julia, todas las funciones nombradas son funciones genéricas. -# Esto significa que se construyen a partir de muchos métodos pequeños  -# Cada constructor de Leon es un método de la función genérica Leon. +# Este es un constructor externo porque está fuera de la definición del tipo. +Leon(rugido::String) = Leon("verde", rugido) -# Por ejemplo, vamos a hacer un maullar función: +type Pantera <: Gato    # Pantera también es un a subtipo de Gato +    color_ojos -# Definiciones para Leon, Pantera, y Tigre -function maullar(animal::Leon) -  animal.rugido # acceso utilizando notación de puntos +    # Pantera sólo tendrá este constructor, y ningún constructor predeterminado. +    Pantera() = new("verde")  end -function maullar(animal::Pantera) -  "grrr" -end +# Utilizar constructores internos, como se hace en Pantera, te da control sobre +# cómo se pueden crear valores de este tipo. Cuando sea posible, debes utilizar +# constructores externos en lugar de internos. -function maullar(animal::Tigre) -  "rawwwr" -end -# Prueba de la función maullar -maullar(tigger) # => "rawwr" -maullar(Leon("cafe","ROAAR")) # => "ROAAR" -maullar(Pantera()) # => "grrr" +######################## +# 6. Despacho Múltiple # +######################## -# Revisar la jerarquía de tipos locales -issubtype(Tigre,Gato) # => false -issubtype(Leon,Gato) # => true -issubtype(Pantera,Gato) # => true +# En Julia, todas las funciones nombradas son funciones genéricas. +# Esto significa que se construyen a partir de muchos métodos más pequeños. +# Cada constructor de Leon es un método de la función genérica Leon. -# Definición de una función que toma Gatos -function mascota(gato::Gato) -  println("El gato dice $(maullar(gato))") -end +# Por ejemplo, vamos a hacer métodos para Leon, Pantera, y Tigre de una +# función genérica maullar: + +# acceso utilizando notación de puntos +maullar(animal::Leon) = animal.rugido +# => maullar (generic function with 1 method) +maullar(animal::Pantera) = "grrr" +# => maullar (generic function with 2 methods) +maullar(animal::Tigre) = "rawwwr" +# => maullar (generic function with 3 methods) + +# Se puede obtener una lista de métodos con la función methods. +methods(maullar) +#= +  # 3 methods for generic function "maullar": +  maullar(animal::Leon) at none:1 +  maullar(animal::Pantera) at none:1 +  maullar(animal::Tigre) at none:1 +=# + +# Prueba de la función maullar. +maullar(tigre)                    # => "rawwwr" +maullar(Leon("cafe", "ROAAR"))    # => "ROAAR" +maullar(Pantera())                # => "grrr" + +# Revisar la jerarquía de tipos locales. +issubtype(Tigre, Gato)      # => false    # igual que: Tigre <: Gato +issubtype(Leon, Gato)       # => true     # igual que: Leon <: Gato +issubtype(Pantera, Gato)    # => true + +# Definición de una función que acepta argumentos de tipo Gato. +mascota(gato::Gato) = println("El gato dice $(maullar(gato))") + +mascota(Leon("42"))    # El gato dice 42 -mascota(Leon("42")) # => imprime "El gato dice 42"  try -    mascota(tigger) # => ERROR: no method mascota(Tigre)) +    mascota(tigre)    # ERROR: `mascota` has no method matching mascota(::Tigre)  catch e -    println(e) +    println(e)        # MethodError(mascota,(Tigre(3.5,"anaranjado"),))  end -# En los lenguajes orientados a objetos, expedición única es común. Esto -# significa que el método se recogió basándose en el tipo del primer argumento. -# En Julia, todos los tipos de argumentos contribuyen a seleccionar el mejor -# método. +# En los lenguajes orientados a objetos, el despacho simple es común. Esto +# significa que la implementación del método a llamar se selecciona en base +# al tipo del primer argumento. + +# En Julia, los tipos de todos los argumentos contribuyen a seleccionar método +# más específico.  # Vamos a definir una función con más argumentos, para que podamos ver la  # diferencia -function pelear(t::Tigre,c::Gato) -  println("¡El tigre $(t.colordelpelaje) gana!") -end +pelear(t::Tigre, c::Gato) = println("¡El tigre $(t.color_pelaje) gana!")  # => pelear (generic function with 1 method) -pelear(tigger,Pantera()) # => imprime ¡El tigre anaranjado gana! -pelear(tigger,Leon("ROAR")) # => ¡El tigre anaranjado gana! +pelear(tigre, Pantera())       # ¡El tigre anaranjado gana! +pelear(tigre, Leon("ROAR"))    # ¡El tigre anaranjado gana! -# Vamos a cambiar el comportamiento cuando el Gato es específicamente un Leon -pelear(t::Tigre,l::Leon) = println("El león con melena $(l.color_de_crin) gana") +# Vamos a cambiar el comportamiento cuando el Gato sea específicamente un Leon. +pelear(t::Tigre, l::Leon) = println("El león con melena $(l.color_crin) gana.")  # => pelear (generic function with 2 methods) -pelear(tigger,Pantera()) # => imprime ¡El tigre anaranjado gana! -pelear(tigger,Leon("ROAR")) # => imprime El león con melena verde gana +pelear(tigre, Pantera())       # ¡El tigre anaranjado gana! +pelear(tigre, Leon("ROAR"))    # El león con melena verde gana. -# No necesitamos un tigre para poder luchar -pelear(l::Leon,c::Gato) = println("El gato victorioso dice $(maullar(c))") -# => fight (generic function with 3 methods) +# No necesitamos un tigre para poder luchar. +pelear(l::Leon, c::Gato) = println("El gato victorioso dice $(maullar(c)).") +# => pelear (generic function with 3 methods) -pelear(Leon("balooga!"),Pantera()) # => imprime El gato victorioso dice grrr +methods(pelear) +#= +  # 3 methods for generic function "pelear": +  pelear(t::Tigre,l::Leon) at none:2 +  pelear(t::Tigre,c::Gato) at none:1 +  pelear(l::Leon,c::Gato) at none:2 +=# + +pelear(Leon("balooga!"), Pantera())    # El gato victorioso dice grrr.  try -  pelear(Pantera(),Leon("RAWR")) # => ERROR: no method pelear(Pantera, Leon)) -catch +    # ERROR: `pelear` has no method matching pelear(::Pantera, ::Leon) +    pelear(Pantera(),Leon("RAWR")) +catch    # no hacer nada con la excepción atrapada  end -# Un metodo con el gato primero +# Un metodo con el tipo Gato primero.  pelear(c::Gato,l::Leon) = println("El gato le gana al León") -# Warning: New definition -#     pelear(Gato,Leon) at none:1 -# is ambiguous with: -#     pelear(Leon,Gato) at none:1. -# To fix, define -#     pelear(Leon,Leon) -# before the new definition. -# pelear (generic function with 4 methods) - -# Esta advertencia se debe a que no está claro que metodo de pelear será llamado -# en: -pelear(Leon("RAR"),Leon("cafe","rar")) # => imprime El gato victorioso dice rar -# El resultado puede ser diferente en otras versiones de Julia +#= +  Warning: New definition +      pelear(Gato,Leon) at none:1 +  is ambiguous with: +      pelear(Leon,Gato) at none:1. +  To fix, define +      pelear(Leon,Leon) +  before the new definition. +  pelear (generic function with 4 methods) +=# +# Esta advertencia se debe a que no está claro que método de pelear +# será llamado en: +pelear(Leon("RAR"),Leon("cafe","rar"))    # El gato victorioso dice rar. + +# El resultado puede ser diferente en otras versiones de Julia  pelear(l::Leon,l2::Leon) = println("Los leones llegan a un empate") -pelear(Leon("GR"),Leon("cafe","rar")) # => imprime Los leones llegan a un empate - - -# Un vistazo al nivel bajo -# Se puede echar un vistazo a la LLVM y el código ensamblador generado. - -area_cuadrada(l) = l * l      # area_cuadrada (generic function with 1 method) - -area_cuadrada(5) # => 25 - -# ¿Qué sucede cuando damos area_cuadrada diferentes argumentos? -code_native(area_cuadrada, (Int32,))   -	#	    .section    __TEXT,__text,regular,pure_instructions -	#	Filename: none -	#	Source line: 1              # Prologue -	#	    push    RBP -	#	    mov RBP, RSP -	#	Source line: 1 -	#	    movsxd  RAX, EDI        # Fetch l from memory? -	#	    imul    RAX, RAX        # Square l and store the result in RAX -	#	    pop RBP                 # Restore old base pointer -	#	    ret                     # Result will still be in RAX - -code_native(area_cuadrada, (Float32,)) -	#	    .section    __TEXT,__text,regular,pure_instructions -	#	Filename: none -	#	Source line: 1 -	#	    push    RBP -	#	    mov RBP, RSP -	#	Source line: 1 -	#	    vmulss  XMM0, XMM0, XMM0  # Scalar single precision multiply (AVX) -	#	    pop RBP -	#	    ret - -code_native(area_cuadrada, (Float64,)) -	#	    .section    __TEXT,__text,regular,pure_instructions -	#	Filename: none -	#	Source line: 1 -	#	    push    RBP -	#	    mov RBP, RSP -	#	Source line: 1 -	#	    vmulsd  XMM0, XMM0, XMM0 # Scalar double precision multiply (AVX) -	#	    pop RBP -	#	    ret -	#	 - -# Ten en cuenta que Julia usará instrucciones de "floating point" si alguno de -# los argumentos son "floats" -# Vamos a calcular el área de un círculo -area_circulo(r) = pi * r * r     # circle_area (generic function with 1 method) -area_circulo(5)                  # 78.53981633974483 + +pelear(Leon("GR"),Leon("cafe","rar"))    # Los leones llegan a un empate + + +################################ +# 7. Un vistazo de bajo nivel. # +################################ + +# Se puede echar un vistazo al código IR de LLVM y al código +# ensamblador generado. +area_cuadrado(l) = l * l    # => area_cuadrado (generic function with 1 method) + +area_cuadrado(5)    # => 25 + +# ¿Qué sucede cuando damos area_cuadrada diferentes tipos de argumentos? +code_native(area_cuadrado, (Int32,)) +#= +    .section  __TEXT,__text,regular,pure_instructions +  Filename: none +  Source line: 1      # prólogo +    push  RBP +    mov RBP, RSP +  Source line: 1 +    imul  RDI, RDI    # elevar l al cuadrado +    mov RAX, RDI      # almacenar el resultado en RAX +    pop RBP           # restaurar el puntero base anterior +    ret               # el resultado estará en RAX +=# + +code_native(area_cuadrado, (Float32,)) +#= +    .section  __TEXT,__text,regular,pure_instructions +  Filename: none +  Source line: 1 +    push  RBP +    mov RBP, RSP +  Source line: 1 +    mulss XMM0, XMM0    # multiplicación escalar de presición simple (AVX) +    pop RBP +    ret +=# + +code_native(area_cuadrado, (Float64,)) +#= +    .section  __TEXT,__text,regular,pure_instructions +  Filename: none +  Source line: 1 +    push  RBP +    mov RBP, RSP +  Source line: 1 +    mulsd XMM0, XMM0    # multiplicación escalar de presición doble (AVX) +    pop RBP +    ret +=# + +# Ten en cuenta que Julia usará instrucciones de punto flotante si el tipo de +# alguno de los argumentos es flotante. + +# Vamos a calcular el área de un círculo. +area_circulo(r) = π * r * r    # area_circulo (generic function with 1 method) +area_circulo(5)                # 78.53981633974483  code_native(area_circulo, (Int32,)) -	#	    .section    __TEXT,__text,regular,pure_instructions -	#	Filename: none -	#	Source line: 1 -	#	    push    RBP -	#	    mov RBP, RSP -	#	Source line: 1 -	#	    vcvtsi2sd   XMM0, XMM0, EDI          # Load integer (r) from memory -	#	    movabs  RAX, 4593140240              # Load pi -	#	    vmulsd  XMM1, XMM0, QWORD PTR [RAX]  # pi * r -	#	    vmulsd  XMM0, XMM0, XMM1             # (pi * r) * r -	#	    pop RBP -	#	    ret -	# +#= +    .section  __TEXT,__text,regular,pure_instructions +  Filename: none +  Source line: 1 +    push  RBP +    mov RBP, RSP +  Source line: 1 +    cvtsi2sd  XMM1, EDI            # cargar entero r de la memoria +    movabs  RAX, 4477117456        # cargar constante matemática π +    movsd XMM0, QWORD PTR [RAX] +    mulsd XMM0, XMM1               # π * r +    mulsd XMM0, XMM1               # (π * r) * r +    pop RBP +    ret +=#  code_native(area_circulo, (Float64,)) -	#	    .section    __TEXT,__text,regular,pure_instructions -	#	Filename: none -	#	Source line: 1 -	#	    push    RBP -	#	    mov RBP, RSP -	#	    movabs  RAX, 4593140496 -	#	Source line: 1 -	#	    vmulsd  XMM1, XMM0, QWORD PTR [RAX] -	#	    vmulsd  XMM0, XMM1, XMM0 -	#	    pop RBP -	#	    ret -	#	 +#= +    .section  __TEXT,__text,regular,pure_instructions +  Filename: none +  Source line: 1 +    push  RBP +    mov RBP, RSP +    movabs  RAX, 4477120336 +    movsd XMM1, QWORD PTR [RAX] +  Source line: 1 +    mulsd XMM1, XMM0 +    mulsd XMM1, XMM0 +    movaps  XMM0, XMM1 +    pop RBP +    ret +=#  ``` -## ¿Listo para más? + -Puedes obtener muchos más detalles en [The Julia Manual](http://docs.julialang.org/en/latest/manual/) +## ¿Listo para más? -El mejor lugar para obtener ayuda con Julia es el (muy amable) [lista de correos](https://groups.google.com/forum/#!forum/julia-users). +Para más detalles, lee el [manual de Julia](http://docs.julialang.org/en/release-0.3). +El mejor lugar para obtener ayuda con Julia, es en su amigable [lista de correos](https://groups.google.com/forum/#!forum/julia-users). diff --git a/es-es/python-es.html.markdown b/es-es/python-es.html.markdown index f7a0ec02..4930eebc 100644 --- a/es-es/python-es.html.markdown +++ b/es-es/python-es.html.markdown @@ -4,6 +4,7 @@ contributors:      - ["Louie Dinh", "http://ldinh.ca"]  translators:      - ["Camilo Garrido", "http://www.twitter.com/hirohope"] +    - ["Fabio Souto", "http://fabiosouto.me"]  lang: es-es  filename: learnpython-es.py  --- @@ -30,27 +31,47 @@ Nota: Este artículo aplica a Python 2.7 específicamente, pero debería ser apl  # Tienes números  3 #=> 3 -# Matemática es lo que esperarías -1 + 1 #=> 2 -8 - 1 #=> 7 -10 * 2 #=> 20 -35 / 5 #=> 7 +# Evidentemente puedes realizar operaciones matemáticas +1 + 1  #=> 2 +8 - 1  #=> 7 +10 * 2  #=> 20 +35 / 5  #=> 7  # La división es un poco complicada. Es división entera y toma la parte entera  # de los resultados automáticamente. -5 / 2 #=> 2 +5 / 2  #=> 2  # Para arreglar la división necesitamos aprender sobre 'floats'  # (números de coma flotante).  2.0     # Esto es un 'float' -11.0 / 4.0 #=> 2.75 ahhh...mucho mejor +11.0 / 4.0  #=> 2.75 ahhh...mucho mejor + +# Resultado de la división de enteros truncada para positivos y negativos +5 // 3     # => 1 +5.0 // 3.0 # => 1.0 # funciona con números en coma flotante +-5 // 3  # => -2 +-5.0 // 3.0 # => -2.0 + +# El operador módulo devuelve el resto de una división entre enteros +7 % 3 # => 1 + +# Exponenciación (x elevado a y) +2**4 # => 16  # Refuerza la precedencia con paréntesis -(1 + 3) * 2 #=> 8 +(1 + 3) * 2  #=> 8 + +# Operadores booleanos +# Nota: "and" y "or" son sensibles a mayúsculas +True and False #=> False +False or True #=> True -# Valores 'boolean' (booleanos) son primitivos -True -False +# Podemos usar operadores booleanos con números enteros +0 and 2 #=> 0 +-5 or 0 #=> -5 +0 == False #=> True +2 == True #=> False +1 == True #=> True  # Niega con 'not'  not True #=> False @@ -90,7 +111,7 @@ not False #=> True  # Una forma más reciente de formatear strings es el método 'format'.  # Este método es la forma preferida  "{0} pueden ser {1}".format("strings", "formateados") -# Puedes usar palabras claves si no quieres contar. +# Puedes usar palabras clave si no quieres contar.  "{nombre} quiere comer {comida}".format(nombre="Bob", comida="lasaña")  # None es un objeto @@ -107,8 +128,8 @@ None is None  #=> True  # None, 0, y strings/listas vacíos(as) todas se evalúan como False.  # Todos los otros valores son True -0 == False  #=> True -"" == False #=> True +bool(0) #=> False +bool("") #=> False  #################################################### @@ -130,16 +151,16 @@ otra_variable  # Levanta un error de nombre  # 'if' puede ser usado como una expresión  "yahoo!" if 3 > 2 else 2 #=> "yahoo!" -# Listas almacenan secuencias +# Las listas almacenan secuencias  lista = []  # Puedes empezar con una lista prellenada  otra_lista = [4, 5, 6]  # Añadir cosas al final de una lista con 'append' -lista.append(1)    #lista ahora es [1] -lista.append(2)    #lista ahora es [1, 2] -lista.append(4)    #lista ahora es [1, 2, 4] -lista.append(3)    #lista ahora es [1, 2, 4, 3] +lista.append(1)    # lista ahora es [1] +lista.append(2)    # lista ahora es [1, 2] +lista.append(4)    # lista ahora es [1, 2, 4] +lista.append(3)    # lista ahora es [1, 2, 4, 3]  # Remueve del final de la lista con 'pop'  lista.pop()        #=> 3 y lista ahora es [1, 2, 4]  # Pongámoslo de vuelta @@ -173,11 +194,11 @@ lista.extend(otra_lista) # lista ahora es [1, 2, 3, 4, 5, 6]  # Chequea la existencia en una lista con  1 in lista #=> True -# Examina el largo de una lista con 'len' +# Examina el tamaño de una lista con 'len'  len(lista) #=> 6 -# Tuplas son como listas pero son inmutables. +# Las tuplas son como las listas, pero son inmutables.  tupla = (1, 2, 3)  tupla[0] #=> 1  tupla[0] = 3  # Levanta un error TypeError @@ -266,7 +287,7 @@ conjunto_lleno | otro_conjunto #=> {1, 2, 3, 4, 5, 6}  # Hagamos sólo una variable  una_variable = 5 -# Aquí está una declaración de un 'if'. ¡La indentación es significativa en Python! +# Aquí está una declaración de un 'if'. ¡La indentación es importante en Python!  # imprime "una_variable es menor que 10"  if una_variable > 10:      print "una_variable es completamente mas grande que 10." @@ -400,12 +421,12 @@ class Humano(object):      # Un atributo de clase es compartido por todas las instancias de esta clase      especie = "H. sapiens" -    # Constructor basico +    # Constructor básico, se llama al instanciar la clase.      def __init__(self, nombre):          # Asigna el argumento al atributo nombre de la instancia          self.nombre = nombre -    # Un metodo de instancia. Todos los metodos toman self como primer argumento +    # Un método de instancia. Todos los metodos toman self como primer argumento      def decir(self, msg):         return "%s: %s" % (self.nombre, msg) @@ -470,6 +491,56 @@ import math  dir(math) +#################################################### +## 7. Avanzado +#################################################### + +# Los generadores permiten evaluación perezosa +def duplicar_numeros(iterable): +    for i in iterable: +        yield i + i + +# Un generador crea valores sobre la marcha +# En vez de generar y devolver todos los valores de una vez, crea un valor +# en cada iteración. En este ejemplo los valores mayores que 15 no serán  +# procesados en duplicar_numeros. +# Nota: xrange es un generador que hace lo mismo que range. +# Crear una lista de 1 a 900000000 lleva mucho tiempo y ocupa mucho espacio. +# xrange crea un generador, mientras que range crea toda la lista. +# Añadimos un guion bajo a los nombres de variable que coinciden con palabras  +# reservadas de python. +xrange_ = xrange(1, 900000000) + +# duplica todos los números hasta que encuentra un resultado >= 30 +for i in duplicar_numeros(xrange_): +    print i +    if i >= 30: +        break + +# Decoradores +# en este ejemplo pedir rodea a hablar +# Si por_favor es True se cambiará el mensaje. +from functools import wraps + + +def pedir(target_function): +    @wraps(target_function) +    def wrapper(*args, **kwargs): +        msg, por_favor = target_function(*args, **kwargs) +        if por_favor: +            return "{} {}".format(msg, "¡Por favor! Soy pobre :(") +        return msg + +    return wrapper + + +@pedir +def hablar(por_favor=False): +    msg = "¿Me puedes comprar una cerveza?" +    return msg, por_favor + +print hablar()  # ¿Me puedes comprar una cerveza? +print hablar(por_favor=True)  # ¿Me puedes comprar una cerveza? ¡Por favor! Soy pobre :(  ```  ## ¿Listo para más? @@ -481,6 +552,7 @@ dir(math)  * [The Official Docs](http://docs.python.org/2.6/)  * [Hitchhiker's Guide to Python](http://docs.python-guide.org/en/latest/)  * [Python Module of the Week](http://pymotw.com/2/) +* [A Crash Course in Python for Scientists](http://nbviewer.ipython.org/5920182)  ### Encuadernados | 
