|
|
Los vectores son una estructura de datos secuenciales indexados. Los vectores se representan con [] así:
[1 2 3]
"Indexado" significa que los elementos de un vector se pueden recuperar por índice. En Clojure (como en Java), los índices comienzan en 0, no en 1. Usamos la función get para recuperar un elemento en un índice:
user=> (get ["abc" false 99] 0)
"abc"
user=> (get ["abc" false 99] 1)
false
Todas las colecciones de Clojure se pueden contar:
user=> (count [1 2 3])
3
Además de la sintaxis literal [], los vectores Clojure se pueden crear con la función vector:
user=> (vector 1 2 3)
[1 2 3]
Los elementos se agregar a un vector con conj (abreviatura de unir). Los elementos siempre se agregan a un vector al final:
user=> (conj [1 2 3] 4 5 6)
[1 2 3 4 5 6]
Las colecciones de Clojure comparten propiedades importantes de valores simples como cadenas y números, como la inmutabilidad y la comparación de igualdad por valor.
Por ejemplo, creemos un vector y modifiquémoslo con conj.
user=> (def v [1 2 3])
#'user/v
user=> (conj v 4 5 6)
[1 2 3 4 5 6]
Aquí conj devolvió un nuevo vector, pero si examinamos el vector original, vemos que no ha cambiado:
user=> v
[1 2 3]
Cualquier función que "cambie" una colección devuelve una nueva instancia. Su programa deberá recordar o transmitir la instancia modificada para aprovecharla.
Dragonwell de Alibaba es una versión posterior de OpenJDK, que tiene algunas características importantes que no están disponibles en la línea principal de OpenJDK. Alibaba lo describe como una compilación OpenJDK optimizada para aplicaciones de comercio electrónico, financieras y logísticas. Alibaba utiliza Dragonwell para ejecutar sus aplicaciones en más de 100.000 servidores.
En 2019, Dragonwell se convirtió en código abierto y está disponible de forma gratuita. Linux x86-64 es oficialmente compatible, sin embargo, también hay una compilación aarch64 disponible y hay una versión experimental para Windows. Alibaba menciona que brindará soporte a largo plazo, pero no se ha definido el período exacto.
Las compilaciones para Dragonwell 8 y 11 se publicarán en el sitio web AdoptOpenJDK. Esto significa que la API AdoptOpenJDK se puede utilizar para descargar los binarios. Esto es particularmente útil para organizaciones que automatizan la instalación de nuevos binarios.
Una de las características únicas de Dragonwell es JWarmup. JWarmup intenta reducir los desafíos de rendimiento en caliente provocados por la compilación JIT. La solución utiliza métodos en caliente precompilados para mejorar el rendimiento. Para lograrlo, se definen dos fases: la pre-ejecución y la ejecución normal.
En la fase previa a la ejecución, los datos de generación de perfiles de los métodos en caliente se registran durante una prueba de carga y se almacenan en un archivo en el disco. Ese archivo se usa durante la ejecución normal donde el hilo JIT compila los métodos en el archivo en versiones nativas. Ahora esos métodos se ejecutan de forma nativa desde el inicio en lugar de interpretarse. Esto reduce la fase de calentamiento de una aplicación, lo que se traduce en un rendimiento mejorado para las aplicaciones que recién se inician.
Otra característica interesante es el soporte de corrutinas Wisp2. Wisp2 asigna subprocesos de Java a corrutinas en lugar de subprocesos a nivel de kernel. El rendimiento de la aplicación se mejora potencialmente ya que se pueden programar muchas corrutinas en una pequeña cantidad de líneas centrales. Esto reduce la sobrecarga de programación y puede mostrar una mejora en función de la carga de trabajo que se esté ejecutando.
El motor Wisp2 es similar en algunos aspectos a los objetivos de Project Loom, que también intenta eliminar el cuello de botella del número de subprocesos activos al permitir a los desarrolladores "virtualizar" sus subprocesos y multiplexarlos en un número menor de subprocesos de plataforma que utilizan enfoques a las corrutinas.
La idea central de Wisp2 es que (a diferencia de Loom) funciona de forma inmediata en el código existente habilitándolo con estos argumentos de Java:
java -XX: + UnlockExperimentalVMOptions -XX: + UseWisp2
Como Wisp2 no requiere cambios en el código fuente, el costo de la migración es bajo. Los desarrolladores no necesitan implementar corrutinas ellos mismos y las características de concurrencia de Java existentes aún se pueden usar.
Sin embargo, no todas las aplicaciones se benefician de Wisp2 y el impacto de mover automáticamente todos los hilos a las corrutinas puede ser muy grande (y no necesariamente positivo).
Las aplicaciones intensivas de Entrada-Salida donde las tareas se bloquean en eventos y luego se programan pueden beneficiarse del soporte de corrutinas. Por otro lado, las aplicaciones con uso intensivo de CPU probablemente no se beneficiarán de las corrutinas. La forma más sencilla de averiguar si una aplicación se beneficia de Wisp2 es habilitar el soporte y ejecutar una prueba de rendimiento.
Alibaba está trabajando activamente para contribuir con estas y otras características y parches al OpenJDK ascendente. Por ejemplo, JWarmup se describe en una propuesta de mejora de Java (JEP), pero todavía está en estado de borrador.
AdoptOpenJDK y Dragonwell son dos de las distribuciones más conocidas basadas en OpenJDK, pero hay muchas más opciones como: Corretto de Amazon, SapMachine de Sap, Liberica de BellSoft, Zulu de Azul y ojdkbuild. Las organizaciones entregan JDK y JRE con diferentes características y parches. Además, cada organización determina sus propios niveles de soporte, algunos de los cuales son de pago. Esto les da a los clientes más libertad, ya que pueden elegir su JDK preferido en función de las funciones y el soporte que necesitan.
Dejo link : https://blog.adoptopenjdk.net/2020/11/adoptopenjdk-welcomes-dragonwell/
from pprint import pprint
my_dict = {'name': 'Yasoob', 'age': 'undefined', 'personality': 'awesome'}
print(dir(my_dict))
# ['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']
pprint(dir(my_dict))
# ['__add__',
# '__class__',
# '__contains__',
# '__delattr__',
# '__delitem__',
# '__dir__',
# '__doc__',
# '__eq__',
# '__format__',
# '__ge__',
# '__getattribute__',
# '__getitem__',
# '__gt__',
# '__hash__',
# '__iadd__',
# '__imul__',
# '__init__',
# '__init_subclass__',
# '__iter__',
# '__le__',
# '__len__',
# '__lt__',
# '__mul__',
# '__ne__',
# '__new__',
# '__reduce__',
# '__reduce_ex__',
# '__repr__',
# '__reversed__',
# '__rmul__',
# '__setattr__',
# '__setitem__',
# '__sizeof__',
# '__str__',
# '__subclasshook__',
# 'append',
# 'clear',
# 'copy',
# 'count',
# 'extend',
# 'index',
# 'insert',
# 'pop',
# 'remove',
# 'reverse',
# 'sort']
Dejo link : https://wiki.python.org/moin/Powerful%20Python%20One-Liners
La versión 12.2 de Apache NetBeans ofrece, entre otros, soporte (mejorado) para Java 14 y 15. Las características de NetBeans como el color de código, el formateo de código y el autocompletado ahora admiten nuevas características del lenguaje Java como registros y palabras claves.
Por lo visto Netbeans sigue creciendo.
Dejo link: https://netbeans.apache.org/download/nb122/nb122.html
# Python 2
python -m SimpleHTTPServer
# Python 3
python -m http.server
Podemos poner el puerto si lo deseamos por defecto es 8080, por ejemplo:
python -m SimpleHTTPServer 9999
Y listo si accedes a http://localhost:8080 (en caso que no hayas cambiado el puerto) podes ver los archivos.
;; bindings name is defined here
;; ------------ ----------------------
(let [name value] (code that uses name))
Cada let puede definir 0 o más enlaces y puede tener 0 o más expresiones en el cuerpo.
(let [x 1
y 2]
(+ x y))
Esta expresión let crea dos enlaces locales para x e y. La expresión (+ x y) está en el ámbito léxico de let y resuelve x en 1 ey en 2. Fuera de la expresión let, x e y no tendrán un significado continuo, a menos que ya estén vinculados a un valor.
(defn messenger [msg]
(let [a 7
b 5
c (clojure.string/capitalize msg)]
(println a b c)
) ;; end of let scope
) ;; end of function
La función messenger toma un argumento msg. Aquí, defn también crea un alcance léxico para msg; solo tiene significado dentro de la función.
Dentro de ese alcance de función, let crea un nuevo alcance para definir a, b y c. Si intentáramos usar una expresión después de let, el compilador reportaría un error.
Clojure tiene clusuras, la expresión fn crea una "clausura". La clausura existe en el ámbito léxico circundante (como msg, a, boc arriba) y captura sus valores más allá del ámbito léxico.
(defn messenger-builder [greeting]
(fn [who] (println greeting who))) ; closes over greeting
;; greeting provided here, then goes out of scope
(def hello-er (messenger-builder "Hello"))
;; greeting value still available because hello-er is a closure
(hello-er "world!")
;; Hello world!
(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))
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 %&)
(defn greet [name] (str "Hello, " name))
(def greet (fn [name] (str "Hello, " name)))
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.
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.