Translate

Mostrando las entradas con la etiqueta programación orientada a objeto. Mostrar todas las entradas
Mostrando las entradas con la etiqueta programación orientada a objeto. Mostrar todas las entradas

lunes, 26 de junio de 2017

Un Ejemplo de Polimorfismo en C++


La idea es mostrar un ejemplo de polimorfismo para los que comienzan a programar en el paradigma orientado a objetos.

La idea es que una empresa tiene un conjunto de bienes los cuales tienen un valor y a la vez algunos bienes pueden ser amortizados (La amortización es un término económico y contable, referido al proceso de distribución de gasto en el tiempo de un valor duradero. Adicionalmente se utiliza como sinónimo de depreciación en cualquiera de sus métodos.)

Los bienes se clasifican en inmuebles, muebles y rodados. A la vez los inmuebles no pierden el valor en el tiempo (es decir no son amortizables) . El software debe proveer una forma de saber el valor de todos los bienes y calcular su amortización.

Para resolver este problema vamos a definir 1 clase abstracta bien que describa la característica que tienen los bienes de saber su valor y la característica de calcular la amortización. A la vez vamos a crear un gestor contable que imprima las amortizaciones.

Veamos la clase abstracta bien:

bien.h :

#ifndef BIEN_H
#define BIEN_H

#include <iostream>

class Bien
{
protected:
    double valor = 0.0;
public:
    Bien();
    double virtual amortizar() = 0;

    void setValor(double valor);

    friend std::ostream& operator<<(std::ostream& os, const Bien& obj);
};

#endif // BIEN_H

bien.cpp : 

#include "bien.h"

Bien::Bien()
{
    this->valor = 0;
}

void Bien::setValor(double valor){
    this->valor = valor;
}

std::ostream& operator<<(std::ostream& os, const Bien& obj){
    return os << "Bien : " << obj.valor;
}

Ahora veamos sus implementaciones, empecemos con el Rodado:

rodado.h :

 #ifndef RODADO_H
#define RODADO_H

#include <iostream>
#include "bien.h"

class Rodado : public Bien
{
protected:
    int km = 0;
public:
    Rodado();
    double amortizar();
    void setKm(int km);
};

#endif // RODADO_H

rodado.cpp : 

#include "rodado.h"

Rodado::Rodado()
{
}

double Rodado::amortizar(){
    int por = this->km /1000;
    return this->valor * ((0.1) * por);
}

void Rodado::setKm(int km){
    this->km = km;
}

Veamos mueble.h

#ifndef MUEBLE_H
#define MUEBLE_H

#include <iostream>
#include "bien.h"

class Mueble : public Bien
{
protected:
    int anioCreacion = 1900;
public:
    Mueble(int anioCreacion);
    double amortizar();
    void setAnioCreacion(int anioCreacion);
};

#endif // MUEBLE_H

mueble.cpp :

#include "mueble.h"

Mueble::Mueble(int anioCreacion)
{
    this->anioCreacion = anioCreacion;
}

double Mueble::amortizar(){
    int dif = 2017 - this->anioCreacion;
    return this->valor * (dif * 0.05);
}

void Mueble::setAnioCreacion(int anioCreacion){
    this->anioCreacion = anioCreacion;
}

Veamos el inmueble que le puse "Terreno" por lo tanto veremos a terreno.h :

#ifndef TERRENO_H
#define TERRENO_H

#include <iostream>
#include "bien.h"

class Terreno : public Bien
{
public:
    Terreno();
    double amortizar();
};

#endif // TERRENO_H

terreno.cpp :

#include "terreno.h"

Terreno::Terreno()
{
}

double Terreno::amortizar(){
    return 0.0; //no amortiza por eso retorna 0
}

Ahora veremos el gestor contable que no hace mucho en el ejemplo, pero usen la imaginación y piensen que debería guardar los registros, calcular asientos, etc. 

gestorcontable.h :

#ifndef GESTORCONTABLE_H
#define GESTORCONTABLE_H

#include <iostream>
#include "bien.h"

using namespace std;

class GestorContable
{
public:
    GestorContable();
    void imprimir(Bien * unBien);
};

#endif // GESTORCONTABLE_H


gestorcontable.cpp :

#include "gestorcontable.h"

GestorContable::GestorContable()
{
}

void GestorContable::imprimir(Bien * unBien){
    cout << *unBien << " amortizacion : "<< unBien->amortizar() << endl;
}

Como pueden ver el Bien es abstracto y sus especializaciones polimorficas y el gestor contable usa esas características y utiliza el polimorfismo de esta manera no importa que bien deba imprimir, como el calculo de la amortización lo sabe hacer cada bien, cada bien calculara su amortización por lo tanto lo hará correctamente. 

Recuerden que el polimorfismo se refiere a la propiedad por la que es posible enviar mensajes sintácticamente iguales a objetos de tipos distintos. El único requisito que deben cumplir los objetos que se utilizan de manera polimórfica es saber responder al mensaje que se les envía.

Espero que les sirva!!

Antes de despedirme les muestro el main:

 #include <iostream>
#include "bien.h"
#include "mueble.h"
#include "rodado.h"
#include "terreno.h"
#include "gestorcontable.h"

using namespace std;

int main()
{
    GestorContable gestorContable = GestorContable();

    Bien * unTerreno = new Terreno();
    unTerreno->setValor(12000.0);
    gestorContable.imprimir(unTerreno);

    Bien * unRodado = new Rodado();
    Rodado * o = 0;
    // Esto lo hago solo para mostrar un cambio de tipos. 
    if (o = reinterpret_cast<Rodado*> (unRodado)) {
        o->setKm(2450);
    }

    unRodado->setValor(400000.00);
    gestorContable.imprimir(unRodado);

    Bien * unMueble = new Mueble(2000);
    unMueble->setValor(47000.00);
    gestorContable.imprimir(unMueble);

    return 0;
}




domingo, 25 de junio de 2017

Un Ejemplo de Polimorfismo en Java


La idea es mostrar un ejemplo de polimorfismo para los que comienzan a programar en el paradigma orientado a objetos.

La idea es que una empresa tiene un conjunto de bienes los cuales tienen un valor y a la vez algunos bienes pueden ser amortizados (La amortización es un término económico y contable, referido al proceso de distribución de gasto en el tiempo de un valor duradero. Adicionalmente se utiliza como sinónimo de depreciación en cualquiera de sus métodos.)

Los bienes se clasifican en inmuebles, muebles y rodados. A la vez los inmuebles no pierden el valor en el tiempo (es decir no son amortizables) . El software debe proveer una forma de saber el valor de todos los bienes y calcular su amortización.

Para resolver este problema vamos a definir 2 interfaces una que describa la característica que tienen los bienes de saber su valor y otra que describa la característica de calcular la amortización.

public interface Valorizable {

public Double getValor();

}


public interface Amortizable {

public Double calcularAmortizacion();

}

Programemos los bienes, empesamos con el mueble que para el ejemplo le puse Edificio:

import java.util.Calendar;
import java.util.Date;

public class Edificio implements Valorizable, Amortizable {

private Double valor;
private Date fechaDeCreacion;

public Edificio(Double valorInicial, Date fechaDeCreacion) {
this.valor = valorInicial;
this.fechaDeCreacion = fechaDeCreacion;
}

@Override
public Double calcularAmortizacion() {
Calendar cal = Calendar.getInstance();
int actualYear =cal.get(Calendar.YEAR);
cal.setTime(fechaDeCreacion);
int year =cal.get(Calendar.YEAR);
int diferencia = actualYear - year;
Double amortizacion = (diferencia * valor) / 300;
this.valor = this.valor - amortizacion;
return amortizacion;
}

@Override
public Double getValor() {
return this.valor;
}

@Override
public String toString() {
return "mueble " + this.valor;
}

}

Seguimos con el rodado:

public class Rodado implements Amortizable, Valorizable{

private static final Double VALOR_AMORTIZACION = 0.2;
private Double valor;
private Integer kms;

public Rodado(Double valorInicial, Integer kms) {
this.valor = valorInicial;
this.kms = kms;
}

public Double getValor() {
return valor;
}

public Double calcularAmortizacion() {
Double amotizacion = 0.0;
if (valor > 0.0) {
amotizacion = (VALOR_AMORTIZACION * kms.doubleValue())/100;
valor = valor - amotizacion;
}
return amotizacion;
}

@Override
public String toString() {
return "rodado " + this.valor;
}

}

Y por ultimo programemos el terreno: 


public class Terreno implements Valorizable {

private Double valor= 0.0;
private String direccion = "";
public Terreno(Double valor, String direccion) {
this.valor = valor;
this.direccion = direccion;
}

@Override
public Double getValor() {
return valor;
}

@Override
public String toString() {
return this.direccion;
}
}

De esta manera podemos tratar a todos los objetos amortizables como si fueran del mismo tipo y a todos los valorables como si fueran del mismo tipo, sin importarnos como calculan el valor o la amortización. 

Veamos el main: 

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.List;

public class Main {


public static void main(String[] args) {
// Construyo los Objetos
Calendar cal = Calendar.getInstance();
cal.set(1990, 02, 02);
Edificio unEdificio  = new Edificio(150000.00, cal.getTime());
Rodado unRodado = new Rodado(12000.00, 1000);
Terreno unTerreno = new Terreno(600000.00, "Los colibies 234");
List<Amortizable> list = new ArrayList<>();
list.add(unEdificio);
list.add(unRodado);
//list.add(unTerreno); No es posible agregar un terreno porque no es Amortizable
System.out.println();
System.out.println("Calcular Amortizacion");
for (Amortizable amortizar : list) {
System.out.println(amortizar.calcularAmortizacion());
}
List<Valorizable> list2 = new ArrayList<>();
list2.add(unEdificio);
list2.add(unRodado);
list2.add(unTerreno);
System.out.println();
System.out.println("Imprimir el valor");
for (Valorizable valorizar : list2) {
System.out.println(valorizar.getValor());
}

// En Java es común el uso de polimorfismo, veamos un ejemplo: 
List<Object> list3 = new ArrayList<>();
list3.add(unEdificio);
list3.add(unRodado);
list3.add(unTerreno);
list3.add("Hola!");
System.out.println();
System.out.println("Hacer to String");
for (Object object : list3) {
System.out.println(object.toString()); //toString es llamado de forma polimorfica.
}


}

}

Recuerden que el polimorfismo se refiere a la propiedad por la que es posible enviar mensajes sintácticamente iguales a objetos de tipos distintos. El único requisito que deben cumplir los objetos que se utilizan de manera polimórfica es saber responder al mensaje que se les envía.

Espero que les sirva!!



miércoles, 4 de enero de 2017

5 cursos para aprender a programar


No importa que no seas un experto, con estos cinco cursos puedes aprender desde lo más básico hasta las últimas versiones del lenguaje de programación para desarrollo de páginas web y aplicaciones.

De esta manera comienza este interesante articulo que selecciona 5 cursos para dar los primeros pasos en programación.

Dejo link: http://www.elfinanciero.com.mx/tech/cursos-gratis-para-aprender-a-programar-1.html

domingo, 7 de agosto de 2016

Para entender Smalltalk hay que entender la Programación orientada a Objetos

Smalltalk está definido con un conjunto muy pequeño de conceptos pero son un significado muy específico.  Es fácil confundir los conceptos porque estos son usados, en diferentes lenguajes, con definiciones muy diferentes.

Objetos
Todo en Smalltalk es un objeto.  Un objeto es una parte indistinguible del resto del ambiente, con características y responsabilidades bien demarcadas.

Mensajes
Un mensaje es un requerimiento, que se hace a un objeto determinado, para que este lleve a cabo algunas de sus responsabilidades.

Un mensaje especifica que es lo que se espera del receptor (el objeto que recibe el mensaje) pero no fuerza una determinada forma de resolverlo.  El receptor es el responsable de decidir como se lleva a cabo la operación para responder al mensaje.

Interfaz
El juego de mensajes que un determinado objeto puede entender se denomina su interfaz. La única forma de interactuar con un objeto es a través de su interfaz.

Encapsulación
Se llama encapsulación al hecho que ningún objeto puede acceder a la estructura interna de otro objeto.  Sólo el objeto conoce, y puede manipular, su propia estructura interna.

Ese hecho, sumado a que los mensajes sólo especifican que se espera del receptor pero no especifica como se debe realizar la tarea, aseguran que ningún objeto dependa de la estructura interna de otro.

El envío de mensajes sumado a la encapsulación permiten el desarrollo de sistemas muy modulares ya que cualquier parte puede ser reemplazada por otra mientras la nueva parte respete la interfaz de la parte reemplazada.

Polimorfismo
Dos objetos son polimórficos entre sí cuando un determinado emisor no puede distinguir a uno del otro. Dicho de otra forma: si podemos intercambiar un objeto por otro, en un determinado contexto, es porque son polimórficos.

Clases
Una clase describe la implementación de un conjunto de objetos.  Los objetos individuales, descritos por las clases, se llaman instancias.  La clase describe la estructura interna de los objetos y  describe, también, como se responde a los mensajes.

Variables de Instancia
La estructura interna de los objetos está compuesta por variables de instancia. La variables de instancia son nombres que el objeto puede usar para hacer referencia a otros objetos.

Métodos
Los métodos son la forma de especificar como los objetos de una determinada clase responden a los mensajes. Cada método especifica como se lleva a cabo la operación para responder a un determinado mensaje. Un método puede acceder a la estructura interna del objeto como así también enviar mensajes a si mismo o a otros objetos.  Los métodos especifican, también, cual es la respuesta que el emisor (el objeto que envía el mensaje) recibe.

Todos los objetos de Smalltalk son instancia de alguna clase.  La programación en Smalltalk consiste en crear clases, crear instancias de esas clases y especificar la secuencia de envío de mensajes entre esos objetos.

Herencia
Las clases, en Smalltalk, están organizadas jerárquicamente.  Una clase refina el concepto de otra clase más abstracta.  La clase más abstracta es Object.  Todas las clases son herencias de Object (porque todo es un objeto) o herencia de alguna clase que hereda de Object.

La relación que existe entre la clase más abstracta (la superclase) y la clase más concreta (la subclase) permite clasificar el conocimiento que tengamos del dominio modelado.

Programar es simular
Programar con objetos es programar una simulación.

La metáfora en la programación con objetos está basada en personificar a un objeto físico o conceptual del dominio real en objetos simulados del ambiente.  Tratamos de reencarnar los objetos reales en el ambiente dotándolos de las mismas características y funcionalidades que los objetos reales a los que representan.


domingo, 17 de junio de 2012

Encontrar los objetos apropiados


Cuando diseñamos, lo más dificil es encontrar objetos indicados que representen la realidad pero a la vez den flexibilidad a nuestros diseños como dice el libro Patrones de Diseño de Erich Gamma:

"Lo más complicado del diseño orientado a objetos es descomponer un sistema en objetos. La tarea es difícil porque entran en juego muchos factores: encapsulación, granularidad, dependencia, flexibilidad, rendimiento, evolución, reutilización, etc, etc. Todo ellos influyen en la descomposición, muchas veces de forma opuesta.

...

Muchos objetos del un diseño proceden del modelo del análisis. Pero los diseños orientados a objetos suelen acabar teniendo clases que no tiene su equivalente en el mundo real. Algunas de ellas son clases de bajo nivel como los arrays. Otras son de mucho más alto nivel... El modelado estricto del mundo real conduce a un sistema que refleja las realidades presentes pero no necesariamente las futuras. Las abstracciones que surgen durante el diseño son fundamentales para lograr un diseño flexible. "


Herencia frente a composición

Estoy leyendo Patrones de Diseño de Erich Gamma. En este libro discute sobre como es mejor reutilizar funcionalidad si por medio de la herencia o la composición. La idea de este post no es transcribir del libro sino hacer un resumen y analizar cada punto.

Vamos primero con la composición, la composición es una técnica en la cual descomponemos objetos para reutilizar funcionalidad. De esta forma componiendo objetos podemos obtener funcionalidad más compleja y completa.

Ventajas:

  • Reutilización de caja negra, los detalles internos de los objetos no son visibles.
  • La dependencia de objetos se puede definir dinamicamente si utilizamos interfaces. Disminuyendo el acoplamiento y aumentando la reutilización. 
  • Ayuda a mantener cada clase encapsulada y centrada en una sola tarea. De esta manera, nuestra clases y jerarquías de clases permanecerán pequeñas y sera menos probable que se conviertan en monstruos inmanejables. 
Desventajas:
  • Requiere más diseño (que tampoco es tan malo)
El mecanismo de herencia lo conocemos bien y también tiene sus ventajas y desventajas


Ventaja:

  • Es facil de usar lo provee los lenguajes.
  • Es más fácil modificar la implementación que esta siendo reutilizada. 
Desventaja:
  • Reutilización de caja blanca, los hijos pueden modificar variables internas del padre (si están protegidas o publicas), la herencia suele decirse rompe el encapsulamiento. 
  • Existe más acoplamiento ya que cualquier cambio en el padre obligara a cambiar la subclase. 
Según lo dicho podemos afirmar:

"Favorecer la composición de objetos frente a la herencia de clases."


Idealmente, solo crearíamos nuevos componentes para lograr la reutilización. Deberíamos ser capases de conseguir toda la funcionalidad que necesitamos simplemente ensamblando componentes existentes a través de la composición de objetos. Sin embargo, rara vez este es el caso, por lo tanto reutilizar mediante herencia hace más fácil construir nuevos componentes que puedan ser combinados con los antiguos. La herencia y la composición trabajan juntas. Pero abusar de la herencia trae consigo diseños más complejos y utilizar composición hace más fácil y reutilizable el diseño. 

sábado, 4 de junio de 2011

Equals


Cuando creamos una clase es una buena práctica definir el método equals, dado que este representa con que campos se identifica esta clase; es decir dos objetos van a ser iguales si son iguales las propiedades usadas en el equals.

El EqualsBuilder de apache common nos puede hacer la vida más fácil a la hora de hacer los equals. Pero a la vez tenemos comprobaciones repetitivas que se pueden factorizar usando herencia.

Veamos un ejemplo de equals:
@Override
public boolean equals(Object obj) {
if (obj == null)
return false;
if (obj == this)
return true;
if (!obj.getClass().isAssignableFrom(getClass()))
return false;

Author otherAuthor = (Author) obj;

return new EqualsBuilder().append(this.user, otherAuthor.getUser())
.isEquals();
}


Si hacemos otro equals vamos a hacer algo muy similar. Una forma de factorizar las lineas que se repiten es mediante herencia podemos hacer una clase padre de todas las clases del modelo que haga lo siguiente:

@Override
public boolean equals(Object obj) {
if (obj == null)
return false;
if (obj == this)
return true;
if (!obj.getClass().isAssignableFrom(getClass()))
return false;

return businnessEquals(obj);
}

public abstract boolean businnessEquals(Object obj);


Y businnessEquals sea abstracto y obligue a todas las clases del modelo a implementarlo. Todos los objetos que hereden de la clase abstracta deben implementar bussinnessEquals pero se olvidan de hacer las validaciones repetitivas.

@Override
public boolean businnessEquals(Object obj) {
Author otherAuthor = (Author) obj;

return new EqualsBuilder().append(this.user, otherAuthor.getUser())
.isEquals();
}



Les gusto la solución? Se les ocurre otra?

lunes, 13 de septiembre de 2010

viernes, 23 de julio de 2010

Lenguaje de programación modernos

Un poco amarillista el titulo del post pero en los últimos años nos vimos bombardeados por nuevos lenguajes de programación como ruby, goovy, scala, ioke, python, etc. Y la verdad que están muy buenos.


Todo empezó con el bum de ruby, lenguaje script basado en smalltalk, que con railes parecía como que iba a conquistar el mundo. Pero otras plataformas no tardaron en copiar los beneficios del lenguaje para su plataforma así nació jruby, jython groovy (en java) y iron ruby y iron python (en .net).


Luego nació algo muy interesante la mezcla de paradigmas en particular la programación funcional con la programación orientada objetos, dando muy buenos lenguajes como scala, ioke o clojure en java y F# en .net.


En el blog se hablo de algunos de estos lenguajes:

http://emanuelpeg.blogspot.com/search/label/Clojure

http://emanuelpeg.blogspot.com/search/label/Ioke

http://emanuelpeg.blogspot.com/search/label/jython

http://emanuelpeg.blogspot.com/search/label/jRuby

http://emanuelpeg.blogspot.com/search/label/Lua

http://emanuelpeg.blogspot.com/search/label/Scala


Me quede pensando que esto esta buenísimo, la convivencia de diferentes paradigmas en un lenguaje, es raro que no se allá todavía inventado un lenguaje orientado a objeto y lógico como un prolog OO. Un ejemplo de esto es logtalk

¿Alguien conoce otro lenguaje multiparadigma?¿Alguien usa algun lenguaje multiparadigma?


viernes, 9 de julio de 2010

Scala


Estuve leyendo un rato sobre este lenguaje, para resumir un poco sus características, es un lenguaje multipropocito y multiparadigma ya que mezcla la programación Orientada a objetos y la programación funcional, esta es una característica que lo hace muy interesante.

Otra cosa importante es que scala es compatible con java es decir que corre sobre jvm y puede utilizar jars.

Veamos un ejemplo de Quicksort:

def sort(xs: Array[Int]): Array[Int] = {
if (xs.length <= 1) xs
else {
val pivot = xs(xs.length / 2)
Array.concat(
sort(xs filter (pivot >)),
xs filter (pivot ==),
sort(xs filter (pivot <)))
}
}

Como podemos ver en el ejemplo es diferente a lo que estamos acostumbrados, dado que se mezcla con la programación funcional.
  1. El algorismo lo primero que hace es ver si el vector tiene 1 o 0 elementos si es así ya se encuentra ordenado, así que lo devuelve.
  2. Si tiene más elementos toma el elemento del medio como pivot y luego corta el vector en 3 los menores al pivot, los iguales y los mayores.
  3. Luego ordena los subconjuntos menor y mayor y así recursivamente.
  4. El resultado es la suma de los subvectores.

Vieron lo raro que filtra los menores y mayores podria usar el “.” es decir xs.filter(pivot ==). Esto es smalltalk-like como cualquier elemento es un objeto y todo usa objetos el indicador de llamadas a metodos puede ser el espacio o punto. De esta forma podemos hacer 1 + 1 o 1.+(1)

Otra característica es que al igual que ruby la ultima expreción ejecutada es el return de la función.

Esta muy bueno no? Alguien lo utiliza?

Dejo links:

http://www.scala-lang.org/

sábado, 5 de junio de 2010

Frases

"Los programas deben ser escritos para que la gente los lea y sólo incidentalmente, para que las máquinas los ejecuten."

---Abelson / Sussman

"Mucho del software hoy en día se parece a una pirámide egipcia: con millones de ladrillos apilados uno encima del otro, sin integridad estructural y hecho por pura fuerza bruta y miles de esclavos."

--Alan Kay

"Cualquier tonto puede escribir código que un ordenador entiende. Los buenos programadores escriben código que los humanos pueden entender."

--Martin Fowler

"Hay dos formas de diseñar software: la primera es hacerlo tan simple que obviamente no hay deficiencias y la segunda es hacerlo tan complicado que no hay deficiencias obvias. La primera forma es mucho más difícil."

--C.A.R. Hoare

"Si deseas empezar y desarrollar algo grandioso, no necesitas millones de dólares de capitalización. Necesitas suficiente pizza y Diet Coke en la nevera, una PC barata y trabajo y dedicación para realizar tu idea."

---John Carmack

La mejor forma de predecir el futuro es inventarlo.

--Alan Kay

El software y las catedrales se parecen mucho. Primero lo construimos, después rezamos.

–-Anónimo


viernes, 17 de julio de 2009

Platon sera programador ??

Platon creía que antes de reencarnarse todas las almas beben agua del río Ameles olvidando de este modo su vida anterior, y reinician el proceso de purificación hasta su retorno al mundo de las Ideas. De esta forma nosotros traíamos conocimiento a este mundo pero olvidado. Por lo tanto el proceso de aprendizaje era recordar lo que sabíamos.

Aristoteles lejos de coincidir con Platon creía que el conocimiento era enteramente construido en este mundo. Es decir que adquiríamos todo el conocimiento.

Piaget nació unos cuantos siglos después y puso luz al asunto diciendo que hay conocimiento que aprendemos y otras habilidades la traemos con nosotros y a medida que la usamos, las pulimos, las intensificamos.

Sin duda la teoría de Piaget es la que creo más cerca de la verdad. Y la vivo que es peor ya que por más que lo intente no creo tener habilidad para ciertos deportes (casi todos).

¿Que piensan la capacidad de resolver un problema computacional es adquirido? ¿Todos tenemos la habilidad de programar en java, php, u otro lenguaje? ¿Programador se nace o hace?
Les dejo estas dudas existenciales.

jueves, 16 de julio de 2009

IOKE

Ioke es un lenguaje que mezcla la programación funcional con la orientada a objeto (similar a scala)
Pero Ioke es un desconocido, no se bien porque. Pero esta muy bueno el lenguaje y lo mejor de todo corre sobre jvm de java.

Les dejo la url de la wiki : http://ioke.org/wiki/index.php/Guide