sábado, 2 de enero de 2021

Primeros pasos con Clojure, parte 15


Seguimos con Clojure... 

apply es una función que invoca una función con 0 o más argumentos fijos y extrae el resto de los argumentos necesarios de una secuencia final. El argumento final debe ser una secuencia.


(apply f '(1 2 3 4))    ;; same as  (f 1 2 3 4)

(apply f 1 '(2 3 4))    ;; same as  (f 1 2 3 4)

(apply f 1 2 '(3 4))    ;; same as  (f 1 2 3 4)

(apply f 1 2 3 '(4))    ;; same as  (f 1 2 3 4)


Las 4 de estas llamadas son equivalentes a (f 1 2 3 4). apply es útil cuando los argumentos se le entregan como una secuencia, pero debe invocar la función con los valores en la secuencia.

Por ejemplo, puede usar aplicar para evitar escribir esto:


(defn plot [shape coords]   ;; coords is [x y]

  (plotxy shape (first coords) (second coords)))


En su lugar, puede simplemente escribir:


(defn plot [shape coords]

  (apply plotxy shape coords))

Primeros pasos con Clojure, parte 14


Seguimos con Clojure... 

Hay una forma más corta para la sintaxis de la función anónima fn implementada en el lector de Clojure: # (). Esta sintaxis omite la lista de parámetros y nombra los parámetros en función de su posición.

% se usa para un solo parámetro

% 1,% 2,% 3, etc. se utilizan para varios parámetros

% & se usa para los parámetros restantes (variadic)

Las funciones anónimas anidadas crearían una ambigüedad ya que los parámetros no tienen nombre, por lo que no se permite la anidación.

;; Equivalent to: (fn [x] (+ 6 x))

#(+ 6 %)

;; Equivalent to: (fn [x y] (+ x y))

#(+ %1 %2)

;; Equivalent to: (fn [x y & zs] (println x y zs))

#(println %1 %2 %&)

Primeros pasos con Clojure, parte 13


Seguimos con Clojure... 

Puede resultar útil pensar en defn como una contracción de def y fn. La fn define la función y la def la vincula a un nombre. Es decir, estas expresiones son equivalentes:

(defn greet [name] (str "Hello, " name))

(def greet (fn [name] (str "Hello, " name)))


Primeros pasos con Clojure, parte 12

 



Seguimos con Clojure... 

Clojure como buen lenguaje funcional tiene funciones anónimas, como por ejemplo : 

;;    params         body

;;   ---------  -----------------

(fn  [message]  (println message) )

Dado que la función anónima no tiene nombre, no se puede hacer referencia a ella más adelante. Más bien, la función anónima generalmente se crea en el punto en que se pasa a otra función. O es posible invocarlo inmediatamente (no es lo común):

;;     operation (function)             argument

;; --------------------------------  --------------

(  (fn [message] (println message))  "Hello world!" )


Aquí definimos la función anónima en la posición de función de una expresión más grande que inmediatamente invoca la expresión con el argumento.

Muchos lenguajes tienen tanto declaraciones, que imperativamente hacen algo y no devuelven un valor, como expresiones que lo hacen. Clojure solo tiene expresiones que devuelven un valor. Más adelante veremos que esto incluye incluso expresiones de control de flujo como el if.

miércoles, 30 de diciembre de 2020

Libros Gratuitos de Java Code Geeks

 

Download IT Guides!

 

Spring Integration for EAI

Spring Integration extends the Spring programming model to support the well-known Enterprise Integration Patterns. Enables lightweight messaging within Spring-based applications and...

 
 

Jetty Server Cookbook

The web server is used in products such as Apache ActiveMQ, Alfresco, Apache Geronimo, Apache Maven, Apache Spark, Google App Engine, Eclipse, FUSE, iDempiere, Twitter’s Streaming API and...

 
 

JAXB Tutorial

The first specification of JAXB was done in March 2003 and the work process is tracked in the Java Specification Request 31. In this specification request you can find a lot of...

 
 

JavaFX Programming Cookbook

JavaFX 2.0 and later is implemented as a native Java library, and applications using JavaFX are written in native Java code. JavaFX Script has been scrapped by Oracle, but development is...

 

sábado, 26 de diciembre de 2020

Feliz Navidad y buen año para todos!!


Como todos los años les deseo una feliz navidad y un buen 2021. 

Gracias por leerme! 

lunes, 21 de diciembre de 2020

Primeros pasos con Clojure, parte 11

Seguimos con Clojure... 

La wikipedia nos indica que : En matemáticas y en programación de computadoras, una función variadica o Variadic function es una función de aridad indefinida, es decir, una que acepta un número variable de argumentos. El soporte para funciones variadas difiere ampliamente entre los lenguajes de programación. El término variadic es un neologismo, que se remonta a 1936-1937. 

Hablando mal y pronto es como en java que ponemos los 3 puntos en los argumentos de la función, algo así : 

void printArgs(String... strings) {

        for (String string : strings) {

            System.out.println(string);

        }

    }

Entonces podemos pasarle un número n de argumentos : 

        printArgs("hello");                 // short for printArgs( ["hello"] )

        printArgs("hello", "world");        // short for printArgs( ["hello", "world"] )


En clojure, las funciones también pueden definir un número variable de parámetros. Los parámetros de las variables deben aparecer al final de la lista de parámetros. Se recopilarán en una secuencia para que los utilice la función.

El comienzo de los parámetros variables está marcado con &. Por ejemplo : 

(defn hello [greeting & who]

  (println greeting who))

Esta función toma un saludo de parámetro y un número variable de parámetros (0 o más) que se recopilarán en una lista denominada who. Podemos ver esto invocándolo con 3 argumentos:

user=> (hello "Hello" "world" "class")

Hello (world class)

Se puede ver que cuando println imprime who, se imprime como una lista de dos elementos que se recopilaron.


domingo, 20 de diciembre de 2020

Primeros pasos con Clojure, parte 10

 


Seguimos con Clojure... 

Las funciones se pueden definir para tomar diferentes números de parámetros. Funciona como el pattetn matching, veamos un ejemplo : 

(defn messenger

  ([]     (messenger "Hello world!"))

  ([msg]  (println msg)))


Esta función esta declarada 2 veces con 0 parámetros y 1 parámetro. La función de 0 parámetros llama a la función de 1 parámetro con un valor predeterminado para imprimir. Invocamos estas funciones pasando el número apropiado de argumentos:

user=> (messenger)

Hello world!

nil


user=> (messenger "Hello class!")

Hello class!

nil



sábado, 19 de diciembre de 2020

Primeros pasos con Clojure, parte 9

Seguimos con Clojure... 

Clojure es un lenguaje funcional. Las funciones son ciudadanos de primera clase y pueden pasarse por parámetros o devolverse desde otras funciones. La mayoría del código de Clojure consta principalmente de funciones puras (sin efectos secundarios), lo que quiere decir que si invocamos una función con las mismas entradas o parámetros, produce la misma salida.


defn define una función nombrada:

;;    name   params         body

;;    -----  ------  -------------------

(defn greet  [name]  (str "Hello, " name) )


Esta función tiene un solo parámetro, sin embargo, se puede incluir cualquier número de parámetros en el vector params.

Luego podemos llamar la función de esta manera :

user=> (greet "mundo")

"Hello, mundo"


miércoles, 16 de diciembre de 2020

Libros Gratuitos de Java code Geeks

 

Download IT Guides!

 

JDBC Tutorial

JDBC (Java Database Connectivity) is an API provided by Oracle that allows programmers to handle different databases from Java applications: it allows developers to establish connections...

 
 

JSF 2.0 Programming Cookbook

JavaServer Faces (JSF) is a Java specification for building component-based user interfaces for web applications. JSF 2 uses Facelets as its default templating system. Other view...

 
 

Developing Modern Applications with Scala

Scala is a general-purpose programming language. It has full support for functional programming and a very strong static type system. Designed to be concise, many of Scala's design...

 
 

iText Tutorial

Text provides support for most advanced PDF features such as PKI-based signatures, 40-bit and 128-bit encryption, color correction, Tagged PDF, PDF forms (AcroForms), PDF/X, color...

 

martes, 15 de diciembre de 2020

Primeros pasos con Clojure, parte 8


Seguimos con Clojure... 

Una de las cosas más comunes que se hace al aprender un lenguaje es imprimir valores. Clojure proporciona varias funciones para imprimir valores.

println y print traducirán los caracteres impresos especiales (como nuevas líneas y tabulaciones) a su forma impresa y omitirán las comillas en las cadenas. A menudo usamos println para depurar funciones o imprimir un valor en el REPL. println toma cualquier número de argumentos e interpone un espacio entre el valor impreso de cada argumento:

user=> (println "¿Qué es esto?" (+ 1 2))

¿Qué es esto? 3

nil

La función println tiene efectos secundarios (impresión) y devuelve nil como resultado.

Tengamos en cuenta que (println "¿Qué es esto?" (+ 1 2)) no imprimió las comillas circundantes y no es una cadena que el lector pueda volver a leer como datos.

Para ese propósito, podemos usar prn o pr para imprimir como datos:

user=> (prn "one\n\ttwo")

"one\n\ttwo"

nil

Dependiendo del contexto, es posible que prefieramos usar println o print o pr o prn.

lunes, 14 de diciembre de 2020

Primeros pasos con Clojure, parte 7


Seguimos con Clojure... 


Con def podemos guardar un valor en una variable pero ojo al piojo que en los lenguajes funcionales las variables no varían. Son constantes donde guardamos un valor, para utilizarlo más adelante o puede ser un pero eso es otro tema... Lo importante, es que en Clojure estamos lejos del concepto de mutabilidad. 

Para definir una variable podemos hacer: 

user=> (def x 6)

#'user/x

Y luego lo podemos usar : 

user=> (+ x x)
12

def es una forma especial que asocia un símbolo (x) en el espacio de nombres actual con un valor (6). Este enlace se llama var. En la mayoría del código Clojure actual, las vars deben referirse a un valor constante o una función, pero es común definirlas y redefinirlas por conveniencia cuando se trabaja en REPL.

Tengamos en cuenta que el valor de retorno anterior es #'user/x; esa es la representación literal de una var: #' seguida del símbolo de espacio de nombres, user es el espacio de nombres predeterminado.

Recuerde que los símbolos se evalúan buscando a qué se refieren, por lo que podemos recuperar el valor simplemente usando el símbolo, como vimos en el ultimo ejemplo. 




domingo, 13 de diciembre de 2020

Primeros pasos con Clojure, parte 6

 


Seguimos con Clojure... 

Antes de empezar a hablar del Relp de Clojure, tenemos que saber un aspecto importante del Relp es que Clojure siempre compila la expresión antes de ejecutarla; Clojure siempre se compila en bytecode de JVM. No hay intérprete de Clojure.

El Relp de Clojure esta recopado, trae como unos trucos, que nos hacen la vida más fácil. Por ejemplo, algunos símbolos especiales recuerdan los resultados de evaluar las últimas tres expresiones:

  • * 1 (el último resultado)
  • * 2 (el resultado hace dos expresiones)
  • * 3 (el resultado hace tres expresiones)
Veamoslo en acción : 

user=> (+ 3 4)
7
user=> (+ 10 *1)
17
user=> (+ *1 *2)
24

Podemos llamar al espacio de nombres clojure.repl que se incluye en la biblioteca estándar de Clojure que proporciona una serie de funciones útiles. Para cargar esa biblioteca y hacer que sus funciones estén disponibles en nuestro contexto actual, debemos escribir :

user=> (require '[clojure.repl :refer :all])
nil

Ahora tenemos acceso a algunas funciones adicionales que son útiles en REPL: doc, find-doc, apropos, source y dir.

La función doc muestra la documentación de cualquier función. Veamos un ejemplo :

user=> (doc +)
-------------------------
clojure.core/+
([] [x] [x y] [x y & more])
  Returns the sum of nums. (+) returns 0. Does not auto-promote
  longs, will throw on overflow. See also: +'
nil

La función doc imprime la documentación para +, incluidas las firmas válidas.

La función doc imprime la documentación, luego devuelve nil como resultado; verá ambos en la salida de evaluación.

También podemos invocar doc sobre sí mismo:

user=> (doc doc)

-------------------------

clojure.repl/doc

([name])

Macro

  Prints documentation for a var or special form given its name,

   or for a spec if given a keyword

nil

Si no estamos seguros de cómo se llama algo podemos usar el comando apropos para buscar funciones que coincidan con una cadena o expresión regular en particular.

user=> (apropos "+")
(clj-stacktrace.repl/pst+ clojure.core/+ clojure.core/+' clojure.core/read+string clojure.spec.alpha/+ clojure.spec.alpha/rep+impl net.cgrand.parsley.grammar/->Repeat+ net.cgrand.parsley.grammar/map->Repeat+ net.cgrand.regex/+ net.cgrand.regex.charset/+)

También puede ampliar la búsqueda para incluir las cadenas de documentos en sí mismas con find-doc:

user=> (find-doc "trim")
-------------------------
clojure.pprint/ltrim
([s c])
  Trim all instances of c from the beginning of sequence s
-------------------------
clojure.pprint/rtrim
([s c])
  Trim all instances of c from the end of sequence s
-------------------------
clj-stacktrace.core/parse-cause-exception
([causer-e caused-parsed-elems])
  Like parse-exception, but for causing exceptions. The returned map has all
  of the same keys as the map returned by parse-exception, and one added one:
  :trimmed-elems  A subset of :trace-elems representing the portion of the
                  top of the stacktrace not shared with that of the caused
                  exception.
-------------------------
clj-stacktrace.core/trim-redundant
([causer-parsed-elems caused-parsed-elems])
  Returns the portion of the tail of causer-elems that is not duplicated in
  the tail of caused-elems. This corresponds to the "...26 more" that you
  see at the bottom of regular trace dumps.
-------------------------
leiningen.core.utils/git-file-contents
([git-dir ref-path])
  Returns the (trimmed) contents by the given git path, or nil if it is
  inacessible or nonexisting. If it exists and is not readable, a warning is
  printed.
-------------------------
clojure.string/trim
([s])
  Removes whitespace from both ends of string.
-------------------------
clojure.string/trim-newline
([s])
  Removes all trailing newline \n or return \r characters from
  string.  Similar to Perl's chomp.
-------------------------
clojure.string/triml
([s])
  Removes whitespace from the left side of string.
-------------------------
clojure.string/trimr
([s])
  Removes whitespace from the right side of string.
-------------------------
clojure.core/read+string
([] [stream] [stream eof-error? eof-value] [stream eof-error? eof-value recursive?] [opts stream])
  Like read, and taking the same args. stream must be a LineNumberingPushbackReader.
  Returns a vector containing the object read and the (whitespace-trimmed) string read.
-------------------------
clojure.core/subvec
([v start] [v start end])
  Returns a persistent vector of the items in vector from
  start (inclusive) to end (exclusive).  If end is not supplied,
  defaults to (count vector). This operation is O(1) and very fast, as
  the resulting vector shares structure with the original and no
  trimming is done.
nil

Si desea ver lla lista completa de las funciones en un espacio de nombres en particular, puede usar la función dir. Aquí podemos usarlo en el espacio de nombres clojure.repl:

user=> (dir clojure.repl)
apropos
demunge
dir
dir-fn
doc
find-doc
pst
root-cause
set-break-handler!
source
source-fn
stack-element-str
thread-stopper
nil

Y finalmente, podemos ver no solo la documentación sino el código fuente subyacente de cualquier función accesible por el tiempo de ejecución:

user=> (source dir)
(defmacro dir
  "Prints a sorted directory of public vars in a namespace"
  [nsname]
  `(doseq [v# (dir-fn '~nsname)]
     (println v#)))
nil


Primeros pasos con Clojure, parte 5


Seguimos con Clojure... 

A veces es útil suspender la evaluación, en particular para símbolos y listas. A veces, un símbolo debería ser simplemente un símbolo sin buscar a qué se refiere:

user=> 'x

x

Y, a veces, una lista debería ser solo una lista de valores de datos (no un código para evaluar):

user=> '(1 2 3)

(1 2 3)

Un error confuso que puede suceder es el resultado de intentar evaluar accidentalmente una lista de datos como si fuera un código:

user=> (1 2 3)

Execution error (ClassCastException) at user/eval156 (REPL:1).

class java.lang.Long cannot be cast to class clojure.lang.IF

Esto porque nos olvidamos el ' 


Dejo link: https://clojure.org/guides/learn/syntax

Primeros pasos con Clojure, parte 4

Seguimos con cloujure...

Si sabes lisp, clojure es casi natural : 



Este diagrama se puede ver la diferencia entre la sintaxis en verde (la estructura de datos de Clojure producida por el Reader) y la semántica en azul (cómo el tiempo de ejecución de Clojure entiende esos datos).

La mayoría de las formas literales de Clojure se evalúan a sí mismas, excepto los símbolos y las listas. Los símbolos se utilizan para referirse a otra cosa y cuando se evalúan, devuelven a qué se refieren. Las listas (como en el diagrama) se evalúan como invocaciones.

En el diagrama, (+ 3 4) se lee como una lista que contiene el símbolo (+) y dos números (3 y 4). El primer elemento (donde se encuentra +) se puede llamar "posición de función", es decir, un lugar para encontrar la cosa a invocar. Si bien las funciones son algo obvio para invocar, también hay algunos operadores especiales conocidos para el tiempo de ejecución, macros y un puñado de otras cosas invocables.

Considerando la evaluación de la expresión anterior:

  • 3 y 4 se evalúan a sí mismos 
  • + evalúa a una función que implementa +
  • evaluar la lista invocará la función + con 3 y 4 como argumentos

Muchos lenguajes tienen tanto declaraciones como expresiones, donde las declaraciones tienen algún efecto con estado pero no devuelven un valor. En Clojure, todo es una expresión que se evalúa como un valor. Algunas expresiones (pero no la mayoría) también tienen efectos secundarios.

Dejo link: https://clojure.org/guides/learn/syntax