Translate

Mostrando las entradas con la etiqueta Lisp. Mostrar todas las entradas
Mostrando las entradas con la etiqueta Lisp. Mostrar todas las entradas

lunes, 18 de diciembre de 2023

Contar valores que cumplan un criterio en Lisp

 


Función para contar valores de una lista en lisp según un criterio (que va a ser una función) : 

(defun contarSegun (lista fx) 

 (cond

     ((null lista) 0)

     ((funcall fx (first lista)) 

           (+ (contarSegun (rest lista) fx) 1))

     (T (contarSegun (rest lista) fx))

 )

)


Y vamos a probarla : 


> (contarSegun '(1 2 3 4 5 6) (lambda (a) (> a 3)))

3


> (contarSegun '(1 2 3 4 5 6) (lambda (a) (>= a 3)))

4


> (contarSegun '(1 2 3 4 5 6) (lambda (a) (= a 3)))

1


sábado, 2 de diciembre de 2023

Función para filtrar valores de una lista en lisp


Vamos a hacer rápidamente una función que permita filtrar valores de una lista según una función. Veamos el código : 

(defun filtrar (lista fx) 

  (cond 

     ((null lista) lista) 

     ((funcall fx (first lista)) 

         (cons (first lista) (filtrar (rest lista) fx)))

     (T (filtrar (rest lista) fx))

  )

Si la lista esta vacía la retorna, sino se fija si ese elemento cumple el criterio y si lo cumple construye una nueva lista con este elemento y el resto filtrado. Y si no retorna el resto de la lista filtrado. 


Veamos si funciona: 


> (filtrar '(1 2 3 4 5) (lambda (a) (> a 5)))

NIL


> (filtrar '(1 2 3 4 5) (lambda (a) (> a 2)))

(3 4 5)


> (filtrar '(1 2 3 4 5) (lambda (a) (< a 2)))

(1)



lunes, 27 de noviembre de 2023

Unir dos listas en lisp


Vamos a unir dos listas en Lisp. Si la primera lista es vacia, retornamos la otra lista y si no lo es, costruimos una nueva lista con el primer elemento de la primera lista y la union del resto de la primera lista (porque al primero ya lo sacamos) con la otra lista. 

(defun unir (lista1 lista2) 

  (cond 

    ((null lista1) lista2)

    (T (cons (first lista1) (unir (rest lista1) lista2)))

  )

)


Si probamos : 

> (unir '(1 2 3) '(4 5 6))

(1 2 3 4 5 6)


> (unir '(1 2 3) '(4))

(1 2 3 4)


sábado, 25 de noviembre de 2023

Buscando el mayor y el menor en lisp


Ahora lo que vamos a hacer es buscar el menor o el mayor de una lista. El algoritmo es similar, por lo tanto vamos a utilizar una función general que busque según una función y luego escribimos el mayor o menor pasando un lambda que busque eso (con eso me refiero al menor o al mayor) : 


(defun buscar (lista fx)

  (cond

    ((null (rest lista)) (first lista))

    ((funcall fx (first lista) (buscar (rest lista) fx)) (first lista))

    (T (buscar (rest lista) fx))

  )

)


(defun menor (lista)

  (buscar lista (lambda (a b) (< a b)))

)


(defun mayor (lista)

  (buscar lista (lambda (a b) (> a b)))

)

El algoritmo buscar lo que hace es si la lista tiene un solo elemento, ya esta ese es el menor o el mayor. Si no compara el primero con el buscar del resto, por ejemplo para el menor, compara el primero con el menor del resto, si es verdadero ese es el menor y si no el menor es el menor del resto. 

Y listo! 

Comenten si quieren más algoritmos así. 

miércoles, 22 de noviembre de 2023

Quicksort in lisp


Un Algoritmo que me gusta mucho es el quicksort, porque es un algoritmo por demás claro. Ya he escrito lo fácil que es implementarlo en haskell 

Ahora le toca a lisp. Básicamente el algoritmo toma un pivot y agrupa los menores del pivot al principio y los mayores al final y aplica quicksort a estos 2 grupos. Y si la lista es vacia, ya esta ordenada. 

Vamos al código: 


(defun qso (l) 

   (cond 

     ((null l) l)

     (T (append 

         (qso (remove-if (lambda (a) (> a (first l))) (rest l)))

         (cons 

           (first l)

           (qso (remove-if (lambda (a) (<= a (first l))) (rest l)))

         )

        )

     )

   )

)


lunes, 13 de noviembre de 2023

La función reduce en lisp


Vamos a hacer una función reduce o reducir en lisp. La función reduce nos permite acumular una lista de números por ejemplo o concatenar una lista de string. 

Es decir toma un valor inicial y va acumulando los valores que tiene una lista con una función que se pasa por parámetros. Veamos esto en lisp : 


(defun reducir(inicial lista fx) 

    (cond 

        ((Null lista) inicial)

        (T (reducir (Funcall fx inicial (first lista)) (rest lista) fx))

    )


Si la lista esta vacía, retornamos el acumulador. Si no volvemos a llamar a la función con el valor de la acumulación del primer elemento como valor inicial y el resto del la lista. 


Y podemos llamarlo de la siguiente manera: 

 > (reducir 0 '(1 2 3 4 5) (LAMBDA (a b) (+ a b))) 

15

> (reducir "" '("hola " "Mundo") (LAMBDA (a b) (concatenate 'string a b)))

"hola Mundo"

 > (reducir "" '("uno" "dos" "tres" "super tranquilo") (LAMBDA (a b) (concatenate 'string a " " b)))

" uno dos tres super tranquilo"

viernes, 10 de noviembre de 2023

Función map en lisp


Vamos a hacer una función transformar o map en lisp que lo que haga es tome una lista y una función y aplique esa función a cada elemento de la lista. 

Para esto vamos a analizar los casos si la lista esta vacía, ya esta retornamos la lista vacía. Si no esta vacía, creamos una nueva lista aplicando esa función al primer elemento y llamando de forma recursiva la función transformar para el resto. 

Sería así : 

(defun transformar (l fx)

   (cond 

      ((Null l) Nil)

      (T (cons (Funcall fx (first l)) 

           (transformar (rest l) fx)))

    )


Y la podemos llamar de esta manera : 

> (transformar '(1 2 3) (LAMBDA (a) (* a 2)))

(2 4 6)

o

 > (transformar '(1 2 3) (LAMBDA (a) (+ a 1)))

(2 3 4)



domingo, 13 de diciembre de 2020

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

lunes, 7 de diciembre de 2020

Primeros pasos con Clojure


Cloujure es un lenguaje funcional de tipado dinamico que corre sobre la maquina virtual java y es muy similar a lisp. 

Antes de empezar vamos a instalarlo. Yo tengo instalado sdkman, por lo tanto voy a utilizarlo instalando Leiningen : 

sdk install leiningen

Y listo! Ahora vamos a probar el lenguaje: 

Primero vamos a hacer una prueba, una suma de 2 numeros, para eso en nuestra consola escribimos :

lein repl

Con esta linea corremos el repl de clojure con Leiningen (la primera vez demora un toque). Ahora a programar, escribimos : 

> (+ 5 6)
Y el resultado es 11

Vamos bien, probemos una función como count : 

> (count '(1 2 3 4))
4

Si esto funciona, el primer paso esta hecho. Dejo link: https://clojure.org/guides/getting_started


lunes, 1 de junio de 2020

Erlang en el panorama de la programación funcional.

Erlang es pragmático. Erlang es funcional, pero permite algunos efectos secundarios. Por ejemplo, la forma en que se maneja la comunicación en Erlang es como un efecto secundario. Pero Erlang evita algunos tipos de efectos secundarios. No mantiene estado, tiene lo que se llama asignación única estática. Entonces, aunque el lenguaje en sí es relativamente libre, hay herramientas que ayudan a garantizar la seguridad de los programas que escribimos. Así que hay un buen equilibrio pragmático. 

Si nos fijamos en el panorama del lenguaje de programación funcional, hay bastantes lenguajes que se denominan funcionales. Muchos lenguajes son lo que se llama fuertemente tipado. Lo que queremos decir con tipado fuerte es que cualquier error de tipo que sucede en el lenguaje, lo obtendremos en el momento de la compilación. No se obtienen errores de tipo de tiempo de ejecución. En este grupo tenemos lenguajes como Haskell y Miranda, que tienen lo que se denomina evaluación perezosa.

Lo que eso significa es que la evaluación de las expresiones está impulsada por la demanda. Entonces, en lugar de la evaluación tradicional, que se llama evaluación estricta, donde los argumentos de las funciones se evalúan a medida que se pasan a la función, antes de evaluar el cuerpo de la función. En Haskell y Miranda, los argumentos solo se evalúan cuando la evaluación del cuerpo lo requiere. Por lo tanto, es muy posible que un argumento no se evalúe en absoluto. O es posible que un compuesto, una estructura de datos, solo se evalúe parcialmente. Y esto permite tipos de estructuras de datos infinitos. 

A la vez Haskell y Miranda son completamente puros. No tienen ningún efecto secundario en absoluto. Y eso se debe a que los efectos secundarios y la evaluación perezosa encajan muy mal. La pereza te obliga a ser puro. Esto se debe a que no sabe cuándo se evaluarán partes particulares de una expresión. Entonces, no sabes cuándo ocurriría ese efecto secundario, si estuviera allí. Por otro lado, lenguajes como ML y OCaml y F# tienen una evaluación estricta. Y tienen algunas impurezas. Diferentes lenguajes tienen diferentes equilibrios de impureza, así como Erlang tiene efectos secundarios, tiene impureza en sus primitivas de comunicación. 

Los demás, ML, OCaml, etc., la familia ML son estrictos. Pero estos lenguajes están fuertemente tipados. En el otro extremo del espectro, hay lenguajes débilmente tipados de la familia LISP. Y estos son inherentemente no escritos, si lo desea. Porque construido en el corazón de ellos, tienen una función de evaluación. Entonces puede construir datos y luego evaluar esos datos. Por lo tanto, no hay forma de que sepa de antemano qué tipo de datos tendrá la construcción cuando se evalúen. LISP tiene una larga historia. LISP se inventó por primera vez hace más de 50 años. Y los descendientes de LISP como Common Lisp y Scheme y Racket se usan ampliamente en la actualidad. Pero el núcleo de esos lenguajes es el uso sofisticado de macros y el uso de eval para hacer que estos lenguajes sean muy reflexivos. Pero eso difiere del tipo de cosas que se hacen en Erlang. 

Si para ser un lenguaje de programación funcional, todo lo que necesita es tener una lambda que le permita definir funciones anónimas, entonces tenemos una gran clase de lenguajes de programación funcional. Debido a que Java, JavaScript, Ruby, C ++, casi todos los lenguajes en los que se puede imaginar están obteniendo un lambda, permiten la facilidad de tener funciones anónimas simplemente porque han demostrado ser muy útiles en paradigmas de programación funcional como MapReduce, etc. Pero no se puede considerara estos últimos lenguajes como funcionales. 

repl.it, Una super IDE online


repl.it es un IDE gratuito, colaborativo y en el navegador para codificar en más de 50 lenguajes, sin gastar un segundo en la configuración.

Les cuento, quería probar algo en Haskell y me encontré con esta joya. Esta muy bueno, te haces un usuario si queres, codeas y si configuraste un repo en github te guarda los archivos ahí. Podes compartir codigo, trabajar en equipo...

Podes programar en : 

Python, Nodejs, C, Java, C++, Ruby, HTML, CSS, JS, Lisp, Go, Rust, Roy, kotlin, Swift, F#, C#, etc...

Punto bajo, no permite ni Scala, ni Grovyy... 


Dejo link: https://repl.it/

jueves, 2 de abril de 2020

Un poco de historia de Haskell

Los orígenes teóricos del modelo funcional se remontan a los años 30 en los cuales Church propuso un nuevo modelo de estudio de la computabilidad mediante el cálculo lambda. Este modelo permitía
trabajar con funciones como ciudadanos de primera clase. En esa misma época, Shönfinkel y Curry
construían los fundamentos de la lógica combinatoria que tendrá gran importancia para la implementación de los lenguajes funcionales.

Hacia 1950, John McCarthy diseñó el lenguaje LISP (List Processing) que utilizaba las listas como
tipo básico y admitía funciones de orden superior. Sin embargo, para que el lenguaje fuese práctico, fue necesario incluir características propias de los lenguajes imperativos como la asignación destructiva y los efectos laterales que lo alejaron del paradigma funcional. Actualmente ha surgido una nueva corriente defensora de las características funcionales del lenguaje encabezada por el dialecto Scheme, que aunque no es puramente funcional, se acerca a la definición original de
McCarthy.

En 1964, Peter Landin diseñó la máquina abstracta SECD para mecanizar la evaluación de expresiones, definió un subconjunto no trivial de Algol-60 mediante el cálculo lambda e introdujo la familia de lenguajes ISWIM (If You See What I Mean) con innovaciones sintácticas (operadores
infijos y espaciado) y semánticas importantes.

En 1978 J. Backus (uno de los diseñadores de FORTRAN y ALGOL) consiguió que la comunidad informática prestara mayor atención a la programación funcional con su artículo “Can Programming
be liberated from the Von Neumann style?” en el que criticaba las bases de la programación imperativa tradicional mostrando las ventajas del modelo funcional. Además Backus diseñó el lenguaje funcional FP (Functional Programming) con la filosofía de definir nuevas funciones combinando otras funciones.

A mediados de los 70, Gordon trabajaba en un sistema generador de demostraciones denominado
LCF que incluía el lenguaje de programación ML (Metalenguaje). Aunque el sistema LCF era interesante, se observó que el lenguaje ML podía utilizarse como un lenguaje de propósito general eficiente. ML optaba por una solución de compromiso entre el modelo funcional y el imperativo ya que, aunque contiene asignaciones destructivas y Entrada/Salida con efectos laterales, fomenta un estilo de programación claramente funcional. Esa solución permite que los sistemas ML compitan en eficiencia con los lenguajes imperativos.

A mediados de los ochenta se realizó un esfuerzo de estandarización que culminó con la definición de
SML (Stándar ML). Este lenguaje es fuertemente tipado con resolución estática de tipos, definición de funciones polimórficas y tipos abstractos. Actualmente, los sistemas en SML compiten en eficiencia con los sistemas en otros lenguajes imperativos.

A comienzos de los ochenta surgieron una gran cantidad de lenguajes funcionales debido
a los avances en las técnicas de implementación. Entre éstos, se podrían destacar Hope, LML, Orwell, Erlang, FEL, Alfl, etc. Esta gran cantidad de lenguajes perjudicaba el desarrollo del paradigma funcional. En septiembre de 1987, se celebró la conferencia FPCA en la que se decidió formar un comité internacional que diseñase un nuevo lenguaje puramente funcional de propósito general denominado Haskell.

Con el lenguaje Haskell se pretendía unificar las características más importantes de los lenguajes
funcionales. como las funciones de orden superior, evaluación perezosa, inferencia estática de tipos,
tipos de datos definidos por el usuario, encaje de patrones y listas por comprensión. Al diseñar el
lenguaje se observó que no existía un tratamiento sistemático de la sobrecarga con lo cual se construyó una nueva solución conocida como las clases de tipos. El lenguaje incorporaba, además, Entrada/Salida puramente funcional y definición de arrays por
comprensión.

Durante casi 10 años aparecieron varias versiones del lenguaje Haskell, hasta que en 1998 se decidió
proporcionar una versión estable del lenguaje, que se denominó Haskell98, a la vez que se continuaba
la investigación de nuevas características y nuevas extensiones al lenguaje.

Dejo link: https://es.wikipedia.org/wiki/Haskell

domingo, 21 de octubre de 2018

Jugando con Lisp y Racket

Hace rato que no juego con lisp, por lo tanto vamos a hacer una pequeña función para contar elementos de una lista:

(defun contar(lista)
  (cond
     ((null lista) 0)
     (T (+ 1 (contar (rest lista))))
  )
)

Si probamos esto:

CL-USER 1 > (contar '(1 2 3 4 5))
5

Veamos el mismo programa en Racket: 

(define (contar lista)
  (cond
     [(empty? lista) 0]
     [else (+ 1 (contar (rest lista)))] 
  )
)

> (contar (list 1 2 3))
3

Como se puede ver Racket es un hijo o nietos de lisp, por ende tienen la misma sintasis.  

jueves, 31 de agosto de 2017

7 lenguajes que se utilizan en inteligencia artificial


Leí un articulo por demás interesante sobre que lenguajes se utilizan en el desarrollo de sistemas inteligentes, es decir en el desarrollo de inteligencia artificial.

Los 7 lenguajes son:

  1. Python
  2. C++
  3. Lisp
  4. Java
  5. Prolog
  6. Javascript
  7. Haskell

Personalmente pienso que es bastante raro pero es explicable.

Python tiene la ventaja de ser fácil de utilizar por lo que los investigadores lo utilizan mucho.
C++ se utiliza para programar software que necesita alta performance como la ia.
Lisp, es el lenguaje de los matemáticos.
Java, no se :(
Prolog, es el lenguaje concebido para programar sistemas inteligentes
Javascript, ni idea
Y Haskell similar a lisp, es muy fácil de utilizar por matemáticos.

Otra cosa que me llama la atención es la cantidad de lenguajes funcionales: Lisp y Haskell.

Dejo link: http://www.rankred.com/best-artificial-intelligence-programming-language/

lunes, 8 de febrero de 2016

Lenguajes de programación más solicitados y mejor pagados



Bueno ya publique esto cientos de veces, pero es bueno recordar las implicancias que esta tomando la programación funcional y si no me creen vean este post, sobre todo la parte que indica:

A pesar de su poca frecuencia, los lenguajes mejor pagados son: 

1.-Lisp 

2.-F# 

3.-Haskell 

4.-Scala 

5.-Clojure 

6.-Erlang 

7.-Lua 

Dejo link: http://www.taringa.net/post/info/19148330/Lenguajes-de-programacion-mas-solicitados-y-mejor-pagados.html




lunes, 9 de noviembre de 2015

LISP (LISt Processing)

En el post anterior vimos programación funcional, ahora vamos a hacer un repaso de lisp, el lenguaje funcional más famoso.

Es el lenguaje más conocido de Programación Funcional. Aún así, no es un lenguaje funcional puro ya que posee asignación (SETF) e iteración (DO).

Se utiliza la notación prefijo para cualquier función, inclusive para las expresiones aritméticas

Funciones y constantes más importantes:

  • (FIRST lista)    o      (CAR lista)    //devuelve el primer elemento de lista
  • (REST lista)     o      (CDR lista)    //devuelve la lista resultante de quitar el primer elemento a lista
  • (NULL lista)     //determina si una lista está vacía
  • (CONS elemento lista)   //construye una nueva lista con elemento como primero y lista como resto
  • (DEFUN  nombreFuncion (parámetros)  resultado)   //define una función
  • (COND  (condición1  resultado1)  (condición2  resultado2) ... )   
  • //devuelve el i-ésimo resultado si la i-ésima condición es verdadera, partiendo por i=1
  • NIL // constante Lista Vacía y constante False
  • T          // constante True
  • ’()        // constante Lista Vacía
  • (FUNCALL  variableFuncion  Parámetro1 Parámetro2 ... ParámetroN)   //ejecuta la función asociada a la variableFuncion, normalmente pasada como parámetro, con los    parámetros indicados
  • (LISTP  objeto)     //verdadero si objeto es una lista
  • (NUMBERP objeto)     //verdadero si objeto es un número
  • (AND  condicion1 condicion2 ...)   //verdadero si todas las condiciones son verdaderas
  • (OR condicion1 condicion2 ...)   //verdadero si al menos una condición es verdadera
  • (+ num1 num2 … numN) // suma
  • (- num1 num2) // resta
  • (<  expr1  expr2) // verdadero si expr1 es menor que expr2
  • (=  expr1  expr2) // verdadero si expr1 es igual a expr2
Veamos una función en Lisp: 

(defun cuadrado(n) ( 
        (* n n)

Dejo link: 



sábado, 11 de julio de 2015

Lisp en python = Hy

Imaginen programar en Lisp en la plataforma python, bueno eso es Hy. Hy transforma código Lisp en python y lo ejecuta en su plataforma. 

Algo que me llamo la atención es lo maduro que esta el proyecto y a la vez que han creado un nuevo lenguaje ya que tiene muchas cosas de python.

Veamos un ejemplo:

=> (print "Hy!")
Hy!
=> (defn salutationsnm [name] (print (+ "Hy " name "!")))
=> (salutationsnm "YourName")
Hy YourName!

Como ven tiene un RELP y tambien se puede probar código desde una pagina web.

Y como están pensando tiene interoperabilidad con python:

=> (import [sh [cat grep wc]])
=> (-> (cat "/usr/share/dict/words") (grep "-E" "^hy") (wc "-l"))
210

En el ejemplo importa python-sh y utiliza los comandos como si fueran del propio lenguaje. Claro todo termina siendo python.

Dejo link:
https://hy.readthedocs.org

jueves, 21 de mayo de 2015

Si los lenguajes fueran autos.


En el blog hubo varias comparaciones de lenguajes de programación y comparándolo con varias cosas. Ahora llega una comparación con autos.

Dejo el link: http://crashworks.org/if_programming_languages_were_vehicles/