Mitigando la torre de Babel del Software en buena medida
Descargar…
Solo descarga y descomprime segun tu sistema y ejecuta algo como…
./abcodec -s abc/hello.abc
abcodec
es el compilador yabc/hello.abc
representa tu codigo fuente con ABCode.
Antes de hablar de una nueva especificación y lenguaje de programación ABCode, me permiteré contarte una pequeña experiencia…
Notando ciertas habilidades para interactuar con diferentes lenguajes de programación (como si fuera un políglota informático) se me ocurrió buscar una forma de lograr un lenguaje abstracto para el componente que se encarga de lo que sucede en el servidor (backend), acompañando a un gestor de base de datos (OnMind-XDB) que también hice junto con mi propia plataforma OnMind. De modo que decidí crear una especificación de lenguaje que convirtiera el código a otro lenguaje de interés. Finalmente, así nació el lenguaje de programación
ABCode
.
Efectivamente encontré ideas similares pero requería algo distinto y como he enfatizado: “abstracto”. Luego se me ocurrió combinar YAML (un lenguaje de marcado para datos) y algo de Python (con una sintaxis restringida), dónde cada línea comienza con un atributo (distinguido por terminar con dos puntos :
) que guarda sangría cada dos espacios (según YAML), el resto de la línea podría ser código (como Javascript). Validé la idea de este lenguaje de programación con un gran amigo y colega, quién le pareció interesante y entusiasta.
Como dato curioso, antes de pensar en
YAML
, la idea se gestó originalmente usando como editor de código una hoja de cálculo y su disposición por columnas (como una sangría), aplicando color a las celdas con sentencias.
Un lenguaje para muchos entornos y una especificación como puente
Es una especificación y lenguaje de programación interpretado (creado por Cesar A. Arcila) que combina el estilo de un lenguaje de marcado como YAML
con algo de Python
y Javascript
, bajo la premisa de ser abstracto y con un enfoque inicial en código para servidor, para lograr generar (transpilar) principalmente código Javascript
, quizás algún otro lenguaje experimental como un dialecto, variante o sabor (ej. Python
).
Puede pensarse como un Typescript con un estilo peculiar. Transpila a Javascript con un “look” que mezcla aspectos de Python y YAML, orientado a la lógica de negocio (casos de uso o lógica de “core”).
La estrategia inicial de ABCode
está orientada dónde opera Javascript
y WebAssembly
(luego Python
), pensando principalmente en el Backend, es decir, en la portabilidad o la legibilidad de la lógica de negocio (casos de uso). Puede verse también como el sustituto para la capa de código que promovían las bases de datos relaciones con procedimientos almacenados, por ejemplo, con AWS Lambda.
En otras palabras y en principio, puedes asociar a ABCode
con…
Lógica más interna (de dominio o “core”)
cuyas funciones componen un Backend
de modo embebido y portable (también modo script)
siendo invocado por otro lenguaje o entorno, o por él mismo
Cada línea de código inicia con una palabra reservada o sentencia definida que correspondería a un atributo en YAML
con sangría, el resto de la línea podría ser código cercano a Python
y Javascript
.
ABCode
supone una capa adicional para interactuar con distintos lenguajes de programación buscando un sentido unificador o conciliador, quizás a futuro con dialectos que comparten la misma raíz, por ejemplo, pensar en abcode:py
o abcode:go
.
INDICACION: En el mundo del desarrollo de aplicaciones (web) que usan Internet se designa la palabra Backend para aquello que está destrás de la red (en un servidor), y con la palabra Frontend nos referimos al aspecto visual que ve el usuario, este puede apreciarse en el navegador o en un dispositivo móvil (ejemplo: desarrollo móvil nativo). ABCode
comienza con énfasis en el servidor y propone un camino conciliador para el navegador (dominado por el lenguaje Javascript).
Traducción multi-lenguaje, multi-entorno, multi-plataforma y multi-paradigma.
ABCode
es sinónimo de la portabilidad de tu código.ABCode
se enfoca en principio en código del lado del servidor (backend) combinando YAML
con algo de Python
y Javascript
, usando una sintaxis restringida de estos lenguajes.ABCode
está pensado para ser fácil de aprender siendo cercano a un algoritmo. También puedes hacer una transición ágil cuando vienes de un lenguaje como Python
. Por otra parte, YAML
es un lenguaje de marcado expresivo y legible al humano, por lo que ABCode
también lo es. Puede ser aconsejable revisar la referencia de YAML
antes de empezar pero tampoco es requerido.ABCode
apoya el Método OnMind y la base de datos OnMind-XDB del mismo autor.ABCode
se proyecta para llegar a funcionar alternativamente como una especificación en la que se transpila otro lenguaje (distinto a Javascript
). Con esto se buscaría guardar legibilidad aunque la implementación sea específica para un lenguaje y no para muchos, además se alcanza personalización cuando una tecnología requiere el potencial de un determinado lenguaje de programación.ABCode
el impacto puede ser menor, teniendo el potencial para facilitar el cambio entre tecnologías (en principio, del lado del servidor).Node
, Deno
y WebAssembly
.Pensando en la portabilidad del código de la lógica de negocio
Creo que se ha indicado el motivo entre las líneas anteriores, pero podemos enfatizar que se busca mitigar algo… debido a: “la torre de Babel del Software”.
También se comprende que la idea se ha originado al requerir un nivel de abstracción o capa para una tecnología que también usaba componentes con orientación genérica (la base de datos y plataforma de OnMind), además de apoyar el Método OnMind. Seguramente otros pueden identificar una necesidad similar así como el interés de algo multiplataforma, o quizás observe la fatiga de la batalla comercial y comunitaria sobre el mejor lenguaje o tecnología.
Unificar, embeber, portar código, integrar sistemas, conservar cierta simplicidad, aportar en agilismo, persistir con el tiempo la lógica de negocio o casos de uso, reducir la complejidad dando apertura a programadores sin que sean expertos, romper ciertos paradigmas actuales y doctrinas informáticas retornando a los fundamentos, generar el impacto correspondiente donde tenga acogida, son los motivos de que se haya concebido ABCode
En lo personal, tendría que contar otra parte de la historia. La plataforma de la que soy autor, fué construida con Javacript
y Kotlin
. Luego identifiqué que si llegara a involucrar Machine Learning, incluso DevOps, sería genial aprender Python
. Así que pensé que podía ser útil aprender otros lenguajes y mejorar mis habilitades en ellos aplicando ABCode
, y lo que estaba codificado en OnMind podía quedar en Javascript
y Kotlin
respectivamente, siendo la parte de la lógica de negocio introducida con ABCode
(hasta llegar a sustituir ese aspecto en el Backend). De este modo, en OnMind se usarían multiples lenguajes y ABCode
para complementar los proyectos y entornos objetivo, orientándose como tecnología multiplaforma.
Las dos primeras letras (“ab”) se deletrean con su pronunciación en inglés, cuando llegas a la “c” dices la palabra “code” (en inglés). Y por cierto, se promueve escribirlo con las tres primeras letras en mayúsculas.
echo: "Hello World!"
Este programa en
ABCode
imprime un saludo en la pantalla usandoecho:
. Ten presente que, en principio, cada instrucción de lógica enABCode
correspondería a una línea de código.
Una variación más completa sería por ejemplo:
fun: hello()
echo: "Hello World!"
run: hello()
Nótese que en este caso
echo:
se deriva o pertenece afun:
(que veremos avanzando) y por esto se dejan dos espacios como sangría.
En un sentido general y espontáneo, un lenguaje natural puede verse como un acuerdo que llega a tener acogida para comunicar, expresar o indicar algo. ABCode
suele usar palabras en inglés de 3 o 4 letras. Conocer su significado puede darnos una comprensión de éste lenguaje, es decir, aquello que se le estaría indicando a un computador que haga. Veamos que significan cada una de las palabras reservadas para ABCode
.
ABCode |
Significado |
---|---|
root: |
raíz |
fun: |
algo divertido |
set: |
conjunto (sustantivo) o establecer (verbo) |
var: |
abreviatura de variable (variar) |
let: |
fijar o determinar |
run: |
correr |
send: |
enviar |
if: |
si… (expresa una condición) |
when: |
cuando… (expresa otra condición o al no cumplir) |
else: |
sino… (de lo contrario) |
for: |
para… (por cada uno) |
sub: |
subrutina (derivación) |
try: |
intentar |
fail: |
fallo |
use: |
usar |
type: |
clase |
echo: |
eco |
goal: |
objetivo |
Para quien tenga habilidades, experticia en programación y/o requiera agilidad en conceptos técnicos, pueden resumirse los siguientes tips esenciales del lenguaje:
int
, float
, boolean
, string
, array
, object
, any
. Las variables se definen iniciando con el atributo var:
, el nombre de la variable, dos puntos de nuevo (:
), el tipo de datos y puede asignarse un valor. Puede omitirse la indicación del tipo de dato cuando se trata de uno básico o genérico.fun:
al nombre de la función, luego los parámetros van entre paréntesis (...)
, continuando con el nombre del parámetro, el caracter :
que separa el tipo de datos posteriormente (y separando los parámetros con coma ,
). El tipo de datos a retornar va también después de :
. Además, se usa send:
para retornar un valor. La función principal de un programa se denomina main
(fun: main()
).YAML
y cada línea de un bloque corresponde a una sentencia con un atributo, es decir, las líneas inician con un atributo YAML
que corresponda a la especificación del lenguaje. No aplican los corchetes de otros lenguajes ni el punto y coma, por lo que la indentación del código toma mayor importancia para legibilidad e incidencia del mismo.C
, Java
, Javascript
, Kotlin
, pero encuentras una forma equivalente para el uso de if
y for
, incluso para el manejo de excepciones (try
), cuyas palabras clave deben llevar a continuación el caracter :
.fun:
y el valor new
(fun: new()
) y la clase se define con el atributo type:
.set:
seguido por el nombre y aplicando YAML
en los atributos asociados. No obstante, al usar YAML
y Python
, el uso de JSON es prácticamente nativo, comprendiendo que no es un tipo o estructura natural del lenguaje.La declaración de variables y funciones presenta una variación respecto a
Python
.ABCode
maneja tipos de datos genéricos para guardar compatibilidad con otros lenguajes, por lo que es un lenguaje tipado. Sin embargo, puede omitirse la indicación del tipo de dato en la declaración de la variable cuando se inicializa un valor con un tipo básico o genérico.
Dado que la programación se asocia con información, los datos se tipifican para identifcar si se trata de un texto, número u otro tipo. Se pueden citar los siguientes tipos de datos.
Tipo | Descripción |
---|---|
string | Cadena de caracteres o texto |
int | Números enteros |
float | Número flotante (con decimales) |
boolean | Booleano (True/False) |
array | Arreglo o vector, se representa como corchetes [] |
object | Objeto, se representa como llaves {} |
any | Para casos en donde puede aplicar varios tipos (dinámico) |
void | Vacío (para métodos o funciones) |
Varios de estos tipos de datos se inspiran en
Typescript
, salvo que se usaint
yfloat
para números y no existenumber
.
Recordando que la variable es como un dato a tener en cuenta (en memoria), se puede expresar una variable asignándo un valor con el operador igual (=
). Cada vez que se mencione o use posteriormente la variable, esta debe aparecer con el mismo nombre original (respetando mayúsculas y minúsculas). Sin embargo, la convención para declarar variables inicia la línea con var:
o let:
(este último para valores constantes o inmutables), el nombre de la variable, dos puntos de nuevo (:
) el tipo de datos, luego puede asignarse un valor (con =
). Puede omitirse la indicación del tipo de dato en la declaración de la variable cuando se trata de uno básico o genérico.
Ejemplo:
var: variable = "Ana"
var: i = 0
let: list = [10, 20, 30]
echo: variable
echo:
es una sentencia que viene en el lenguaje para mostrar algo en pantalla (en este caso imprime el valor de la variable). En un lenguaje comoPython
se usaríaprint()
En programación de computadoras las variables tienen un tipo de dato que indica la naturaleza del contenido, por ejemplo, si una variable contiene un texto (string
) o si es un número entero (int
) o flotante (float
), incluso si se trata de un valor verdadero o falso (boolean
) o una lista (array
). Veamos el ejemplo indicando el tipo de datos.
var: variable:string = "Ana"
var: i:int = 0
let: list:array = [10, 20, 30]
Si prefieres el estilo de Python
, puedes usar las funciones simples para establecer el tipo de datos con str()
, int()
, float()
, bool()
, list()
.
var: variable = str()
var: i = int()
var: f = float()
var: imagine = bool()
let: list = list()
En lugar de esto, podría asignarse respectivamente
""
,0
,0.0
,False
,[]
. No obstante, el tipo de datos es requerido por compatibilidad con ciertos lenguajes.
Las funciones realizan algo o definen una serie de instrucciones que cumplen un propósito, es decir, se relacionan con lógica en bloques bien definidos según se organicen. Para el caso de ABCode
se antepone fun:
al nombre de la función, luego los parámetros van entre paréntesis (...)
, continuando con el nombre del parámetro, el caracter :
que separa el tipo de datos posteriormente (y separando los parámetros con coma ,
). El tipo de dato a retornar va también después de :
. Veamos a continuación un ejemplo.
fun: myFunction()
echo: "Hi there!"
run: myFunction()
Quién conoce
Python
puede observar que se omite la palabra reservadadef
siendo innecesaria al usarfun:
. Además, en este caso no requiere retornar un tipo de datos (aunque podría usarse:void
al final de la declaración de la función).
run:
se usa para invocar operaciones, funciones o sentencias. En la mayoría de lenguajes no se antepone algo comorun:
para operaciones o sentencias, siendo éstas las líneas comunes, pero aquí se requiere un atributo para conservar el estiloYAML
.
Veamos otro ejemplo.
fun: sayMyName(name:string):string
send: name
echo: sayMyName("Andrey")
En este caso se usa
send
para devolver el valor contenido en la variable (que en otros lenguajes suele serreturn
).
Si estás comenzando con la programación de computadores, quizás no convenga distinguir cierto aspecto de las funciones. Pero si ya tienes algún conocimiento, es bueno aclarar que las fuciones en ABCode
son de naturaleza pública. Para indicar que una función es privada, en el contexto de una clase dada, se debe anteponer el signo @
al nombre, por ejemplo: @sayMyName
.
Principalmente, los operadores son aquellos que nos permiten realizar operaciones, aunque también se encuentran aquellos que nos permiten evaluar algo (basados en tautología o tabla de la verdad). Con los operadores se pueden sumar dos expresiones o números, así como las demás operaciones matemáticas. Esto se asocia también al algebra esencial que se refiere a funciones y variables. Por otra parte, en los operadores que permiten evaluar algo, se puede comparar o determinar si dos valores son diferentes, o definir condiciones complejas (y, o, no).
Veamos a continuación los operadores del lenguaje.
Operador | Descripción |
---|---|
= |
igual (asignación) |
+ |
suma |
- |
resta |
* |
multiplicación |
/ |
división |
% |
módulo de una división |
+= |
incremento |
-= |
decremento |
== |
comparación exacta (igual a) |
!= |
comparación de diferencia (diferente de) |
> |
mayor que |
< |
menor que |
>= |
mayor o igual que |
<= |
menor o igual que |
&& |
y (también: and) |
` | |
! |
no, negación (también: not) |
@ |
sustituto de self o this para uso de propiedades de clases en otros lenguajes, indica también si una función es privada en el contexto de una clase |
Aunque
ABCode
acepta los operadores lógicosand
,or
ynot
dePython
, promueve en su lugar&&
,||
y!
en favor deABCode:js
y varios lenguajes.
Debe distinguirse entre el atributo@:
(usado como decorador) y el uso de@
en clases. Quizás se cuestione si es un operador o no, en este caso opera para referencia en clases (que es un tema avanzado).
Los operadores de inclusión and
(también: &&
) y de opción or
(también: ||
) tienen incidenca en la evaluación de una condición en un programa. Partimos de la siguiente tabla, dónde p
es la primera variable y la segunda es q
, además se usa True
y False
para indicar si es verdadero o falso (respectivamente).
p | q | p and q |
p or q |
---|---|---|---|
True | True | True | True |
True | False | False | True |
False | True | False | True |
False | False | False | False |
Si una variable o expresión se niega con
not
(también:!
) entonces se invierte su valor: si es verdadera se interpreta como falsa y si es falsa se interpreta como verdadera.
Las condiciones permiten determinar los puntos de validación en la lógica que se plantee. Por ejemplo, imagina que vas a comprar una bebida para alguien que te la encargó y llevas planteados unas posibles escenarios en caso de que no se encuentre la bebida originalmente solicitada.
Se usa if:
para establecer un punto de validación con una condición y when: no
, o simplemente else:
, cuando no cumple algo. Veamos un ejemplo.
let: i = 1
if: i == 1
echo: "coffee"
when: no
echo: "tea"
when: no
oelse:
corresponden a lo que ocurriría cuando no se cumple una condición y debe dejarse siempre como última condición, queriendo indicar lo que sucede en caso contrario.
Se usa when:
con una condición (que sería como else if
en otros lenguajes) para evaluar otras condiciones determinadas. Veamos el siguiente ejemplo.
let: i = 3
if: i == 1
echo: "coffee"
when: i == 2
echo: "tea"
else:
echo: "aha"
Nótese que se usa doble igual (
==
) como operador de comparación, distinguiéndose de la asignación que usa de modo natural un signo de igual (=
). En ese orden de ideas, para evaluar valores diferentes (comparación negativa) se usaría el signo de admiración y un igual (!=
).
Pueden existir escenarios en los que no se evalúe alternativa, es decir, una condición simple (if:
). Por ejemplo:
let: i = 2
if: i == 1
echo: "coffee"
Los ciclos se refieren a instrucciones que se repiten o en donde se da lugar a ciertas iteraciones. Ten presente que la línea del for:
suele incluir in
, veamos a continuación.
var: names = ["Ana", "Alex", "Janeth"]
for: x in names
echo: x
if: x == "Alex"
run: break
Nótese que la variable
names
es una lista de valores de texto (también conocida con el nombre de arreglos) cuya convención usa corchetes[]
separando cada valor por una coma. Cuando se usabreak
se interrumpe el ciclo, dado que está bajo una condición se imprimirían los nombres hasta que se de lugar a la condición (por tanto no se imprimiría Janeth).
Se puede usar la funcion range
para recorrer un rango, incluso combinarla con len
que obtiene el tamaño de un arreglo. Veamos un par de ejemplos:
for: i in range(10)
echo: i
var: n = [10, 20, 30, 40]
for: i in range(len(n))
echo: n[i]
En estos casos se termina el ciclo cuando se alcanza el tope (restando 1).
range
puede usarse también dos parámetros indicando el primero el inicio y el segundo el tope. Su tercera manera de llamarse es con un tercer parámetro que indicaría un incremento (en caso de ser distinto de 1).
Una tercera variación sería incluyendo una condición y evitando el uso de in
, es decir, sin in
se interpretaría como while
en otros lenguajes. Veamos el ejemplo:
var: i = 0
for: i < 10
run: i += 1
echo: i
Nótese que
for:
recibe en este caso una condición y no llevain
.
Una variación adicional consistiría en entrar en un ciclo e interrumpirlo (usando: break
) cuando cumpla una condición determminada. Veamos el ejemplo:
var: i = 0
for: True
run: i += 1
echo: i
if: i < 10
run: break
Quién ya tiene conocimiento en programación puede asociar esto con la sentencia
do...while
de otros lenguajes, siendo el modo de emularla.
Las excepciones se originan cuando se interrumpe la lógica esperada debido a un error en medio de la ejecución del programa de modo que podríamos gestionarlas, en otras palabras, son útiles para manejo de errores generalmente de caracter técnico.
try:
echo: n
fail:
echo: "error"
try:
indica que se inicia un bloque de código controlado y que en caso de una excepción se pasa al bloque correspondiente afail:
.
run:
se usa para invocar operaciones, funciones o sentencias. En la mayoría de lenguajes no se antepone algo como run:
siendo las operaciones o sentencias las líneas comunes, pero aquí se requiere un atributo para conservar el estilo YAML
. También se usa para invocar break
, continue
, incrementos. Veamos a continuación un par de aclaraciones sobre este punto.
En ABCode
se usa var:
para declarar variables y se pueden inicializar allí mismo. Por otra parte, cuando se trata de operaciones posteriores se usa run:
, por lo que es posible encontrar código semejante en ambos casos, pero en uno cumple una función de inicialización y otro correspondería al flujo común (posterior a la definición). Veamos el ejemplo:
var: i = 0
echo: i
run: i = 1
echo: i
No se ha mencionado
let:
, que se usa para variables inmutables o constantes, puesto que no debe admitirse una asignación conrun:
sobre variables inmutables.
En teoría, las líneas que no corresponden a atributos como fun:
, send:
, if:
, when:
, for:
, try:
, fail:
, type:
, corresponderían a una sentencia que utiliza run:
. Sin embargo, pueden existir variaciones para casos específicos que es apropiado que el lenguaje distinga. Tal es el caso de echo:
que se usa para imprimir algo en pantalla. Pensando en implementación a futuro, se tendrían también las palabras reservadas read
, file:
, link:
, web:
, dbc:
, ask:
, page:
, jsx:
, html:
, css:
, code:
como sentencias complementarias a run:
, conocidas también como macros.
Los comentarios ofrecen indicaciones para legibilidad y comprensión del código pero no tienen efecto en la ejecución del programa, es decir, van dirigidos a la documentación del código o al equipo.
# Esto es un comentario
Quien tiene conocimientos en
YAML
oPython
debe saber que el uso de la almoadilla (#
) para comentarios coincide conABCode
.
A diferencia deYAML
,ABCode
admite comentarios de línea completa, es decir, no se interpreta al final de línea salvo excepción de comentario especial del lenguaje (ej.#$:
).
Si estás comenzando con la programación de computadores, quizás comprendas mejor este tópico avanzando en la codificación de programas. ABCode
introduce tres tipos de comentarios especiales que en realidad son más que comentarios, puesto que ofrecen una orientación en el lenguaje. Veamos:
Etiqueta | Descripción |
---|---|
goal: |
indica el modo o el lenguaje destino (any, cli, api, fun, dbs o un entorno de lenguaje: python, deno, etc.) |
#if: |
comentario que indica lenguaje para el cual se traduce la línea siguiente |
#in: |
comentario que indica lenguaje literal expresado en la línea siguiente |
goal:
no es un comentario pero es una etiqueta (o atributo) que no opera como una sentencia. Por ejemplo,goal: fun
se usa para las funciones más internas o scripts embebidos (ej.Lua
), ygoal: dbs
es comofun
para bases de datos consql
.
Revisemos lo siguiente:
goal:
determina el lenguaje que se expresa en el código y se omite cuando se usa la sintáxis estricta de ABCode
para generar código a varios lenguajes.goal:
actualmente admitiría valores como any
y cli
(ABCode
para programas planos), más los lenguajes python
, deno
(typescript
), ruby
, rust
, kotlin
y nodejs
. Adicionalmente, api
para indicar destinos compatibles con librería web para servidor, quizás en un futuro, pwa
para indicar destino compatible con el aspecto visual (javascript
en el navegador).goal:
puede ser usado para reportar un destino distinto a any
, cli
, api
, fun
o dbs
(incluso pwa
en un futuro), así se debe entender como una modalidad de puente para otro lenguaje. De esta manera se conserva la estructura expresiva (YAML
) y la parte de código se orienta para traducción a un lenguaje en particular. Esto es útil para implementar soluciones específicas en un lenguaje o entorno determinado.#if:
es útil cuando la sintáxis corresponde al estándar de ABCode
y se desea traducir una línea de código con un lenguaje en particular (por ejemplo, debido a diferencias en librerías), refiriéndose siempre a la siguiente línea, es decir, aplicando una traducción literal. Sería como usar goal:
para la siguiente línea de código en lugar de hacerlo global. Lo anterior sugiere que si se usa goal:
con un destino distinto de any
, cli
, api
, fun
o dbs
, no se requiere usar #if:
, siendo en ese caso excluyentes.#if:
puede ser asignado con el valor else
(#if: else
), indicando que para los demás lenguajes aplicaría el código que se reporte en la siguente línea (en ABCode
).#in:
no opera actualmente y se reserva como especificación para implementación a futuro. Esto serviría para hacer una traducción literal, expresándose la siguiente línea directamente en el lenguaje destino tal cual corresponda su sintáxis, es decir, semejante a if:
pero en lugar de usar ABCode
usaría literalmente el lenguaje destino (como un escape al código estándar). Podría usar también el valor else
(#in: else
), indicando que para los demás lenguajes aplicaría el código que se reporte en la siguente línea (en ABCode
).
goal: any
se usa para programas planos en los que no se requieren dependencias (librerías), motivo por el cual se está preparando el uso degoal: cli
ygoal: api
para soportar una librería compatible con destinos oficiales.goal: fun
se usa para indicar que el contenido corresponde a funciones más internos o scripts (ej.Lua
).goal: dbs
es comofun
para bases de datos consql
.
Pueden existir restricciones para el uso de#if
y#in
con alguna sentencia, por ejemplo,fun:
,if:
,for:
,try:
yfail:
deben acoger lo propuesta deABCode
.
Las estructuras de datos representan un modelo o tuplas, y pueden definirse bajo el atributo set:
de la siguiente manera:
set: Person
name: string
age: int
Se usa la misma disposición de
YAML
indicando los tipos de datos de cada atributo.
Las librerías o bibliotecas de programas permiten organizar y usar código que se encuentra en otro archivo. Se usa la palabra reservada use:
para indicar la librería que se importa y dónde se encuentra (ruta), o en su defecto una incorporada en el sistema. Esto es semejante a lo que se conoce en otros senguajes como import
.
use: sys
Actualmente,
use:
está pendiente por definir detalles del modo de uso mientras se implementan funciones incorporadas o librerías esenciales para el lenguaje.
Las clases permiten un paradigma que se conoce como programación orientada a objetos, buscando representar todo como un objeto. Si conoces Python
, cuando se manejan clases esto debe reinterpretarse conforme a ABCode
, encontrándose variaciones o diferencias en este aspecto.
type: Circle
var: @radious
fun: new(radious)
run: @radious = radious
fun: print()
echo: @radious
new
es el nombre de la funcion con la que se inicializa la clase, es decir, el constructor de la clase se expresa como:fun: new()
. Esto difiere dePython
y se inspira enRust
.
@
se usa para dar referencia a una propiedad directa de la clase, distinguiédose de una variable común. Esto difiere dePython
que usaself
u otros que usanthis
, y se inspira enRuby
, pero debe declararse usandovar:
.
Para indicar que una función es privada, en el contexto de una clase dada, se debe anteponer el signo @
al nombre, por ejemplo: @printer()
.
En lenguajes como C#
o Java
(incluso PHP
y Kotlin
), las clases se organizan o agrupan, bien sea con namespace
o package
(respectivamente). En ABCode
encuentras la palabra reservada root:
para estos casos y suele ubicarse en las primeras líneas del programa, antes de definir una clase. Por ejemplo:
root: awesome
type: Circle
...
cast:
es reservada para otro concepto conocido como interfaces.
root: awesome
cast: Area
...
La sentencia web:
usa métodos para la Web implementando código para cada lenguaje (según librería usada internamente). web:
tiene tres métodos basicos que son: :server
, :listen
y :handle
. Veamos un ejemplo…
use: api
web: :server = app
sub: get("/") = index
web: :handle = "Hi there!"
fun: main()
let: port:int = 8000
echo: port
web: :listen = port
run: main()
Nótese que web: :server =
establece variable del servidor, luego web: :handle =
asigna un gestor de peticiones, que en este caso devuelve un texto, y web: :listen =
inicia el servicio en el puerto indicado.
Por otra parte, en lugar de fun:
se usa sub: get(...) = ...
para definir las funciones asociadas a una petición web según la ruta. De este modo, podría ser get
, post
, put
o delete
.
En el caso de ask:
se buscaría una estructura de consulta a base datos para que internamente se traduzca a SQL
(Structured Query Language) conservando el estilo YAML
y un patrón, usando la base de datos OnMind-XDB. Por ejemplo:
ask:
what: find
some: persons
with: name = 'peter'
how: order age
Con ask:
se usarían los atributos way:
, what:
, some:
, with:
, puts:
, show:
o how:
para establecer un patrón en la consulta. way:
indica si se especifica mql
o sql
(siendo este último el defecto y se podría omitir), to:
para la colección o tabla, what:
para la acción (find
, insert
, update
, delete
), with:
para el criterio de búsqueda o filtro, y how:
para indicaciones complementarias (por ejemplo: order
, limit
). show:
cuando encuentras algo and puts:
podría incluirse para operaciones de insercción o actualización. Veamos otros ejemplos:
ask:
what: find
some: persons
with: name = 'peter'
show: name,age
Para
find
se usashow:
separando con,
, ywith:
usa un modo cercano aSQL
.
En lugar de usarLIKE
dentro dewith:
se usa la funciónbegins_with(field, value)
ocontains(field, value)
(reportando campo y valor)
ask:
what: insert
some: persons
puts: {name:'peter',age:25}
Para
insert
se usaputs:
con{}
(JSON).
ask:
what: update
some: persons
with: name = 'peter'
puts: {age:20}
En este caso,
puts:
estableceage = 20
, ywith:
usa el modoSQL
.
ask:
what: delete
some: persons
with: name = 'peter'
Adicionalmente, dbc:
para indicar la conexión específica, keys:
para establecer parámetros nombrados que corresponden a una lista clave-valor ({}
), call:
para invocar funciones, user:
y auth:
para reportar usuario y token de sesión. También from:
cuando se refiere a un respositorio orientado con el Método OnMind.
De modo esencial podemos citar las siguientes palabras reservadas o tipo de sentencia.
Sentencia | Descripción |
---|---|
root: |
paquete o módulo de programa (referido por compatibilidad, por ejemplo con package o namespace ) |
fun: |
establece una función o método (rutina que cumple una función) |
set: |
establece estructura de datos (modelo) |
var: |
declaración de variable (incluye asignación inicial) |
let: |
declaración para fijar inmutables (incluye asignación) |
run: |
sentencia, operación o asignación (también para break, continue) |
send: |
retorna o concluye una función con un valor (si aplica) |
if: |
condición establecida o inicio de validación |
when: |
condición adicional (else if ). when: no o simplemente else: cuando no cumple algo |
for: |
ciclo convencional (el codigo respectivo puede incluir in ) |
sub: |
bloque de código, para iterar o derivarse como subrutina |
try: |
inicia bloque para excepciones |
fail: |
indica evento generado para el control de excepción |
use: |
importa librería (funciones de otro archivo de programas, import ) |
type: |
define una clase, como constructor de la clase se usa fun: new() |
echo: |
imprime o registra salida de consola (con parámetros usa: ${param} ) |
read: |
captura entrada desde la consola |
file |
gestiona archivos locales (open , write , close ) |
@: |
decorador (@) usado en ciertos lenguajes (router, component, tag, widget, etc.) |
Debe distinguirse entre el atributo
@:
(usado como decorador) y el uso de@
en clases.
Actualmente no se implementa la sentenciasub:
, quedando reservada como especificación del lenguaje para incorporar en futuras versiones.
Para quién tenga conocimientos en otro lenguaje, una manera ágil de comprender ABCode
consiste en citar el siguiente paralelo o lista comparativa:
ABCode |
Otros lenguajes |
---|---|
root: |
package , namespace |
fun: |
function , func , def , proc |
set: |
struct , type , data class |
var: |
let , var , let mut |
let: |
const , val , let |
send: |
return |
if: |
if |
when: |
else if , elif , elsif , else |
for: |
for , while |
try: |
try |
fail: |
catch , exception , rescue |
use: |
import , include , using , require |
type: |
class |
echo: |
print , echo , puts , console.log |
read: |
input |
# |
// (comentarios de línea) |
@: |
@ (decorador) |
run:
no suele tener paralelo y por esto no se encuentra en la tabla anterior. En la mayoría de lenguajes no se antepone algo comorun:
para operaciones o sentencias, siendo éstas las líneas comunes, pero aquí se requiere un atributo para conservar el estiloYAML
.
Para quién tenga conocimientos en Python
, y sin hablar de la incidencia de YAML
, se indica a continuación las principales diferencias:
ABCode
inician con fun:
(inspirado en Kotlin
) y se omite la palabra reservada def
de Python
.:
) al final y el tipo de datos respectivo.return
del lenguaje Python
cuando se usa send:
.:
) después del nombre y el tipo de datos respectivo, antes de asignar un valor (antes de =
).Python
u otros lenguajes. Tal es el caso de while
que no existe y se usa for:
(inspirado en Go
), o switch...case
que tampoco existen y se debe usar if:
y when:
. En principio, tampoco se piensa en implementar finally
que correspondería a try:
, con el fin de guardar simplicidad y compatibilidad con ciertos lenguajes.type:
, sustituyendo la palabra reservada class
de Python
, y el constructor de la clase se debe llamar new
(inspirado en Rust
).@
(inspirado en Ruby
) en lugar de la palabra reservada self
de Python
, que en otros lenguajes sería this
. Esto se verá reflejado en sentencias como run:
cuando se usa una propiedad, es decir, que cuando se manejan clases esto debe reinterpretarse conforme a ABCode
, el cual presenta variaciones en este tema respecto a Python
.Python
incorpora print()
mientras ABCode
usa echo:
para mostrar algo en pantalla (inspirado en PHP
).Aunque
ABCode
acepta los operadores lógicosand
,or
ynot
dePython
, promueve en su lugar&&
,||
y!
en favor de varios lenguajes.
Hasta ahora no se mencionan variaciones respecto a YAML
dado que en un sentido práctico se respeta su estilo. Se puede apreciar, por ejemplo, que la palabra reservada run:
se introduce debido al estilo YAML
, puesto que no existe en otros lenguajes este concepto en el caso de sentencias u operaciones.
Por otra parte, es posible que en versiones tempranas se llegue a introducir la notación YAML
para textos largos usando el caracter >
, por ejemplo, en el caso de la sentencia echo:
o send:
.
echo: >
This text
is wrapped
as a paragraph
Sin embargo, en otros casos (como var:
, let:
, run:
) se está revisando la manera apropiada de proceder puesto que podrían combinarse propuestas. Por ejemplo, que una asignación de cadenas de texto (con var:
o let:
) termine en >
(pensando en =>
), y en la siguientes líneas se establece el valor, algo como lo siguiente:
var: text =>
This text
is wrapped
as a paragraph
Especificación lista, trabajo en progreso, el auspicio es bienvenido
El presente documento ya es una especificación del lenguaje de programación ABCode
creada y elaborada por César Andrés Arcila Buitrago (© 2022 by César Arcila). En 2022, al interior de la plataforma OnMind se tiene un transpilador (traductor de lenguaje fuente a otro fuente) como prueba de concepto que permite ejecutar programas sencillos que no requieren dependencias, para algunos lenguajes o entornos (Deno
, Nodejs
).
Para escribir con ABCode
no se necesita una nueva aplicación, es decir, se usa un editor (como VSCode
o Sublime
que descargas de Internet) asociando el formato YAML
con archivos de extensión .abc
. Sin embargo, se está pensando en preparar un editor para una mejor integración con el transpilador.
Si hablamos de una tecnología que puede llegar a ser Open Source (de código abierto) ya se estaría pensando en cierto soporte pero no impositivo, debido precisamente al tipo de licencia. Considero que para distinguir los lenguajes objetivos y su nivel de soporte lo más coherente es hablar de un nivel de intención de soporte por lenguaje destino o prioridad, dónde cinco (5) es una posibilidad remota. Es verdad que suele usarse la palabra experimental para características no prioritarias y pueden no ser atendidos. A continuación veamos la propuesta de intención del nivel de soporte.
Item | Destino | Nivel | Característica de interés o estrategia |
---|---|---|---|
1 | NodeJS | 1 | Servidor Web y Microservicios, AWS Lambda, CDK |
2 | Deno | 2 | Multiplataforma, Typescript |
3 | Wasm (AssemblyScript) | 2 | WebAssembly basado en Typescript (wasm) |
0
está reservado para compilación directa desdeABCode
a futuro.4
podría corresponder aPython
, luegoLua
, quizásKotlin
como dialectos (ya se verá después).
Dado que la estrategia inicial de ABCode
es operar como lenguaje portable y embebido en otro lenguaje (ej. usando quickjs) o en un entorno destacado para Backend, debe entenderse que se podría llegar a usar desde PHP
, NodeJS
, Java
, C
, Python
, Ruby
, Dart
, Deno
, Rust
, Go
, Swift
, Kotlin
, C#
, Pascal
, PostgreSQL
y quizás más por medio de entorno de ejecución.
No se trataría sólo de pensar en el destino sino también de las posibilidades de los lenguajes y entornos de origen que integran
wasm
(WebAssembly) oquickjs
.
Se piensa que Python
llege a ser un destino nativo siendo también una especificación, motivo por el cual puedes encontrar proyectos que acogen este lenguaje en un entorno (tales como: GraalVM
, Jython
, IronPython
, Python.Net
, PyScript
), o traducen Python
a otro lenguaje (tales como: transcrypt
, javascripthon
, pscript
, py2many
, py2rb
, py2php
, py2dart
, pytocs
, py2nim
, rustpython
, pytago
, peryton
, python-lua
, scoder/lupa
, dragon/haxe
, prometeo
), y algún proyecto para dispositivos móviles (como BeeWare
, Kivy
).
Como detalle técnico, no se requiere un gestor de paquetes (al dejar esto a cada lenguaje destino) pero tampoco se ha implementado una librería estándar o SDK oficial del lenguaje. Sin embargo, se ha empezado a revisar algún programa esencial con alguna librería sencilla y ligera muy específica. Se consideran aplicaciones web para alguna API
de modo clásico o plano (sin requerir librería), es decir, un controlador principal (endpoint
) sin enrutamiento de url
(se haría mediante POST
con parámetro que indique la función a invocar y un token para la seguridad), por lo que puede implementarse de modo estandard.
Aunque el código del transpilador que se produzca se estima liberar bajo licencia Open Source (de código abierto), aún no se ha publicado en repositorios de internet (por ejemplo en GitHub
) y hasta último momento esto puede cambiar (quizás por licencia Apache
u otra).
Ya venía de producir una plataforma que ha costado una enorme inversión (tiempo, dinero, esfuerzo intelectual, adicional y personal), un proyecto como estos no es para tomarlo a la ligera y se necesita cubrir el factor financiero, por esto…
Se buscan vías de ingresos que son bienvenidos para soportar esta obra.
Specs ready, Work In Progress, Let’s…
© 2022 by César Arcila