Documentación
Comentarios
En heza declaramos los comentarios con el token @, solo soporta comentarios de una linea.
@Comentario
@esto esta comentado
pero esto no
Palabras clave
En Heza actualmente solo se emplean 5 palabras clave, aqui se detalla que hace cada una
@Palabras clave
data @Declarar variables
trace @Habilitar historial de cambios en variables (o extraer dicho historial)
end @Finalizar bloques de codigo (for, condicionales)
play @Para bucles while
stop @Detener bucles (while o for)
Tipos de datos
En Heza existen 7 tipos de datos primitivos y 2 compuestos
@Tipo de datos primitivos
12 5.6 @Number
false true @Bool
"Hola Mundo" @Text
'x^2' @Expresion
∅ @Null
∞ @Inf
∄ @Nah (indeterminate)
@Tipo de datos compuestos
{1,2,3,4} @Set
&(f(x) - 8) @Reference
Declaracion de variables
Para declarar variables se utiliza la palabra reservada data, se pueden declarar multiples valores e incluso asignarles valores iniciales usando el operador de asignacion =, opcionalmente se puede activar el historial de cambios en vairables con la palabra reservada trace
@Declaracion simple
data x
@Declaracion multiple
data a, b, c
@Declaracion con asignacion
data x = 5
@Declaracion multiple con asignacion
data a = 5, b = 10, c = 15
@Declaracion con historial de cambios
trace data y = 10
Operadores aritmeticos
En heza se emplean 5 operadores aritmeticos unarios y 6 binarios para cubrir todas las operaciones numericas básicas
@Operadores unarios
-x @Negacion
+x @Positivo
|x| @Valor absoluto
!x @Factorial
√x @Raiz cuadrada
@Operadores binarios
x + y @Suma
x - y @Resta
x * y @Multiplicacion
x / y @Division
x ^ y @Potenciacion
x % y @Modulo
Operadores logicos
En Heza utilizamos los operadore logicos propios de la logica proposicional
@Operadores logicos
x ∧ y @Y (AND)
x ∨ y @O (OR)
¬x @NO (NOT)
x → y @Implica
Operadores de relacion
Usamos los operadores estandares de los demas lenguajes con la excepcion del operador diferente de
@Operadores de relacion
x = y @Igual a
x ≠ y @Diferente de
x < y @Menor que
x > y @Mayor que
x <= y @Menor o igual que
x >= y @Mayor o igual que
Operadores de conjuntos
En Heza soportamos de forma nativa las operaciones con conjuntos
@Operadores de conjuntos
A ∪ B @Union
A ∩ B @Interseccion
A Δ B @Diferencia simetrica
A ⊂ B @Subconjunto
a ∈ B @Pertenencia
Operadores especiales
En Heza agregamos una serie de operadores especiales que ayudan a mantener la notacion matematica
@Operadores especiales
A ← y @Agregar x al conjunto A
$x @Copiar el valor de x del scope padre en el scope actual
&(f(x)) @Referencia a la expresion f(x)
≔ @Declarar funciones
↩ @Retornar un valor de una funcion
∀ @Cuantificador universal
∃ @Cuantificador existencial
∑ @Sumatoria
∏ @Productoria
∫ @Integral (definida o indefinida)
∂ @Derivada (no parcial)
→ @tendencia (en limites)
: @Condicion (en conuntos), apuntador (en end y trace), paso (en rangos) o tipo de dato (en variables)
? @Operador ternario (condicional)
Imprimir
Para imprimir un valor en la consola simplemente se agrega el valor al conjunto de salida (OUTPUT)
@Imprimir hola Mundo
OUTPUT ← "Hola Mundo"
Cabe destacar que OUTPUT es un conjunto normal por lo cual se puede acceder a sus valores (los datos impresos) en cualquier momento despues de agregarlos
Conversion
Se Emplea la notacion 'dato >> Tipo' para la conversion
@Conversion
data x = "123"
data y = x >> Number @y vale 123 como Number
data z = y >> Text @z vale "123" como Text
@Conversion invalida
data a = "Hola"
data b = a >> Number @Error, no se puede convertir "Hola" a Number
No se puede convertir un valor en un objeto Reference y en algunos casos como el Text no esta permitida la conversion a Inf ya no que se puede seleccionar el signo
Acceso a conjuntos
Empleamos la notacion Set{Index} para acceder al valor almacenado en la posicion Index del conjunto Set, los indices negativos se entienden como |Set|+Index, es decir que -1 representa el ultimo valor, -2 el penultimo y asi
@Acceso a conjuntos
data A = {10, 20, 30, 40, 50}
data x = A{2} @x vale 30
data y = A{-1} @y vale 50
Los indices inician en 0 como el los demas lenguajes
Sumatorias
En Heza soportamos las sumatorias de forma nativa, aqui te explicamos su notacion
@Sumatorias
∑(k ∈ Set, f(k)) @Suma f(k) para cada k en Set
@ejemplo:
data A = {1,2,3,4,5}
data suma = ∑(k ∈ A, k^2) @suma vale 55 (1^2 + 2^2 + 3^2 + 4^2 + 5^2)
Productorias
Emplean una notacion muy similar a las sumatorias
@Productorias
∏(k ∈ Set, f(k)) @Multiplica f(k) para cada k en Set
@ejemplo:
data A = {1,2,3,4,5}
data prod = ∏(k ∈ A, k) @prod vale 120 (1 * 2 * 3 * 4 * 5)
Cuantificador existencial
Verifica que una condicion se cumpla para al menos un elemento del conjunto
@Cuantificador existencial
∃k ∈ Set: condicion(k) @Verdadero si existe al menos un k en Set que cumple condicion(k)
@ejemplo:
data A = {2,4,6,8,10}
data existe_impar = ∃k ∈ A: k % 2 = 1 @existe_impar vale false
Cuantificador universal
Verifica que la condicion se cumpla para todos los elementos del conjunto
@Cuantificador universal
∀k ∈ Set: condicion(k) @Verdadero si todos los k en Set cumplen condicion(k)
@ejemplo:
data A = {2,4,6,8,10}
data todos_pares = ∀k ∈ A: k % 2 = 0 @todos_pares vale true
Rangos
Un Rango es un conjunto de numeros que delimitados inferior y superiormente, al cual se le puede especificar o no la distancia entre los valores (1 0 -1 si no se especifica), los valor from y to deben cumplir unas ciertas normas dependiendo del paametro step
@Rangos
data R1 = [1..10] @R1 vale {1,2,3,4,5,6,7,8,9,10} y step por defecto es 1
data R2 = [10..1] @R2 vale {10,9,8,7,6,5,4,3,2,1} y step por defecto es -1
@Paso especifico
data R3 = [1..10:2] @R3 vale {1,3,5,7,9}
data R4 = [10..1:-2] @R4 vale {10,8,6,4,2}
@Error de rango invalido
data R5 = [1..10:-1] @Error, el paso no concuerda con from y to
data R6 = [10..1:1] @Error, el paso no concuerda con from y to
@Error de step 0
data R7 = [1..10:0] @Error, el paso no puede ser 0
Referencias
En heza soportamos de forma nativa la referencia a expresiones complejas, funciona almacenando el AST de la expresion y usando el metodo de lazy-evaluation para obtener el valor solo cuando se solicite (desreferenciacion automatica)
@Referencias
data x = 5
data ref = &(x + 10) @ref es una referencia a la expresion (x + 10), es decir, no almacena 15 sino la expresion misma
x = 20 @Cambiamos el valor de x
data valor_ref = ref @valor_ref vale 30, ya que al desreferenciar ref se evalua la expresion (x + 10) con el nuevo valor de x pero ref sigue almacenando la expresion original (x + 10)
data y = &(u + 5) @y es una referencia a la expresion (u + 5), aunque u no este declarada aun
OUTPUT ← y @Al desreferenciar y se busca el valor de u en el scope actual, si u no esta declarada en el scope actual o en los scopes padres se genera un error
Las referencias no necesitan que las variables de las cuales dependen esten declaradas al momento de crear la referencia, pero si al momento de evaluar, por lo cual al desreferenciar la expresion buscara los valores en el scope actual y no en el scope donde de declaro
Expresion
En Heza manejamos de forma nativa las expresiones simbolicas, las cuales son necesarias para resolver limites, derivadas e integrales, ademas tienen integradas una notacion para sustitucion de variables por valores
@Expresion
data expr = 'x^2 + 2*x + 1' @expr almacena la expresion simbolica
@Sustitucion de variables
data resultado = eval(expr, x = 3) @resultado vale 16, ya que se sustituye x por 3 en la expresion y luego se evalua (3^2 + 2*3 + 1)
Aunque el resultado ya no contiene variables libres, el resultado es un objeto Expresion, no un Number, por lo cual para tratarlo como un numero hay que usar una operacion de conversion
@Obteniendo el resultado en un Number
data num_result = resultado >> Number @num_result vale 16 como Number
@Caso invalido
data invalid = expr >> Number @Error, no se puede convertir una expresion con variables libres a Number
Cuando en la funcion eval no se especifica que variable sera la sustituida, el interprete busca los valores para las variables declaradas en el scope para sustituir (no recomendado)
@eval global
data x = 4
data expr2 = 'x^3 + x^2 + x + 1'
data result = eval(expr2) @result vale 85 (como Expresion), ya que se sustituye x por 4 en la expresion y luego se evalua (4^3 + 4^2 + 4 + 1)
Limites
Los limites son nativos en heza y aqui te mostramos su notacion
@Limites (Expresion)
lim(f(x), x → a dir) @Limite de f(x) cuando x tiende a a desde la direccion dir (opcional, dir puede ser +, - o vacío)
@ejemplo:
data limite1 = lim('1/x', x → 0+) @limite1 vale ∞
data limite2 = lim('1/x', x → 0-) @limite2 vale -∞
data limite3 = lim('1/x', x → 0) @limite3 vale Nah (indeterminate)
data limite4 = lim('x^2', x → 3) @limite4 vale 9
@Ejemplos de limites xon variables libres
data expr = '((x+h)^2 - x^2) / h'
data limite5 = lim(expr, h → 0) @limite5 vale 2*x (como Expresion y no se puede convertir a Number ya que depende de x)
Derivadas
En Heza trabajamos las derivadas de forma nativa, aun no hay soporte para derivadas parciales
@Derivadas (Expresion)
∂(f(x), x) @Derivada de f(x) con respecto a x
@ejemplo:
data derivada1 = ∂('x^3 + 2*x^2 + x + 1', x) @derivada1 vale '3*x^2 + 4*x + 1' (Expresion)
data derivada2 = ∂('Sin(x)', x) @derivada2 vale 'Cos(x)' (Expresion)
Integrales
Las integrales son nativas en Heza, te mostramos la notacion de la integrales definidas e indefinidas
@Integrales (Expresion)
∫(f(x), x) @Integral indefinida de f(x) con respecto a x
∫(f(x), x ∈ [a..b]) @Integral definida de f(x) con respecto a x desde a hasta b (esa es la notacion para los limites de integracion, no esta permito usar otros conjuntos o variables)
@ejemplo de error:
data integral_error = ∫('x^2', x ∈ {1,2,3}) @Error, los limites de integracion deben ser un rango
data rango = [0..1]
data integral_definida = ∫('x^2', x ∈ rango) @Error, los limites de integracion deben ser un rango definido en el mismo lugar
@ejemplo de integral indefinida:
data integral_indefinida = ∫('x^2', x) @integral_indefinida vale '(1/3)*x^3' (Expresion)
@ejemplo de integral definida:
data integral_definida2 = ∫('x^2', x ∈ [0..3]) @integral_definida2 vale 9 (Number)
Filtros
Tenemos una notacion espeficica para filtrar los elementos de los conjuntos
@Filtros (Set)
{ x ∈ Set: condition(k) } @Crea un nuevo conjunto con los elementos k de Set que cumplen condition(k)
@ejemplo:
data A = {1,2,3,4,5,6,7,8,9,10}
data pares = { x ∈ A: x % 2 = 0 } @pares vale {2,4,6,8,10}
data mayores_5 = { x ∈ A: x > 5 } @mayores_5 vale {6,7,8,9,10}
Transformacion
Podemos tranformar (mapear) un conjunto a un nuevo valor e incluso agregar la notacion de filtro y multiples conjuntos a la vez (todos deben ser del mismo tamaño)
@Transformation (Set)
{ f(k) | k ∈ Set } @Crea un nuevo conjunto aplicando f(k) a cada elemento k de Set
@ejemplo:
data A = {1,2,3,4,5}
data cuadrados = { k^2 | k ∈ A } @cuadrados vale {1,4,9,16,25}
data B = {10,20,30,40,50}
@ejemplo con filtro:
data cuadrados_pares = { k^2 | k ∈ A: k % 2 = 0 } @cuadrados_pares vale {4,16}
@ejemplo con multiples conjuntos:
data sumas = { x + y | x ∈ A, y ∈ B } @sumas vale {11,22,33,44,55}
Bucle For
Empleamos la notacion matematica de realizar una accion para cada elemento de un conjunto
@Bucle For
∀k ∈ Set: accion(k) @Realiza accion(k) para cada k en Set
@ejemplo:
data A = {1,2,3,4,5}
∀k ∈ A: OUTPUT ← k^2 @Imprime los cuadrados de los elementos de A (1,4,9,16,25)
@Bucle For con multiples acciones
∀k ∈ A::
@ acciones
@finalizar
end:k
@ejemplo:
data A = {1,2,3,4,5}
∀k ∈ A::
OUTPUT ← k
OUTPUT ← k^2
end:k @Imprime los elementos de A y sus cuadrados
Tambien se pueden recorrer multiples conjuntos en un mismo bucle con distintas variables iteradoras (todos los conjuntos deben tener el mismo tamaño), en caso de bucle multilinea la variable que se situa luego de end: es el nombre de la primera variable
@Recorrer multiples conjuntos
data B = {10,20,30,40,50}
∀x ∈ A, y ∈ B::
OUTPUT ← x + y
end:x @Imprime la suma de los elementos correspondientes de A y B (11,22,33,44,55)
@Una sola accion sin end
∀x ∈ A, y ∈ B: OUTPUT ← x + y @Imprime la suma de los elementos correspondientes de A y B (11,22,33,44,55)
Condicionales
En heza usamos una notacion especial para manejar los condicionales usando como condicion variables de tipo Reference y la notacion de bucles For para los bloques de codigo
@Condicionales
condicion: unica_accion
condicion::
@ multiples acciones
@finalizar
end:condicion
@If-else
condicion: unica_accion_si_verdadero : unica_accion_si_falso
condicion::
@ multiples acciones si verdadero
:
@ unica_accion_si_falso
condicion::
@ multiples acciones si verdadero
::
@ multiples acciones si falso
end:condicion
@ejemplos:
data x = 10
data y = 20
data condicion = &(x > y)
condicion: OUTPUT ← "x es mayor que y" : OUTPUT ← "x no es mayor que y"
&(x > y) ::
OUTPUT ← "x es mayor que y"
:
OUTPUT ← "x no es mayor que y"
end:&
condicion::
OUTPUT ← "x es mayor que y"
:
OUTPUT ← "x no es mayor que y"
condicion::
OUTPUT ← "x es mayor que y"
::
OUTPUT ← "x no es mayor que y"
end:condicion
Cuando la condcion es un valor y no el nombre de la variable se coloca & despues de end:
El operador : indica unica accion (como verdadero o como falso) y el operador :: indica bloque de codigo (requiere end), si las acciones de verdadero son varias pero las acciones de falso es una sola (:) el final del condicional no requiere end:condition_name
Bucles While
Se emplea una notacion muy parecida a los condicionales pero agregando la palabra reservada play para indicar que las acciones se repiten mientras se cumpla la condicion. Nota: El bloque de codigo flase se ejecuta una sola vez solo si la condicion no se cumple inicialmente
@Bucles While
condicion play: unica_accion
condicion play::
@ multiples acciones
@finalizar
end:condicion
@While-else
condicion play: unica_accion_si_verdadero : unica_accion_si_falso
condicion play::
@ multiples acciones si verdadero
:
@ unica_accion_si_falso
condicion play::
@ multiples acciones si verdadero
::
@ multiples acciones si falso
end:condicion
@ejemplos:
data x = 1
&(x <= 5) play::
OUTPUT ← x
x = x + 1
end:& @Imprime los numeros del 1 al 5
data y = 10
data condicion2 = &(y < 5)
condicion2 play::
OUTPUT ← y
y = y - 1
:
OUTPUT ← "y no es menor que 5"
end:condicion2 @Imprime "y no es menor que 5"
Cuando la condicion es una expresion y no el nombre de la variable se coloca & despues de end:
Stop
La palabra reservada stop solo se puede utilizar dentro de un bucle for o while (el el bloque que se repite, no el la accion por default) y rompe el bucle mas interno (si estan anidados)
@Stop
data x = 1
data condicion = &(x <= 10)
data parada = &(x = 5)
condicion play::
OUTPUT ← x
x = x + 1
parada: stop
end:condicion @Imprime los numeros del 1 al 4
Funciones
En Heza declaramos las funciones un poco distinto a lo habitual
@Declaracion de funciones
funcion_name ≔ (param1, param2, ...): unica_accion
funcion_name ≔ (param1, param2, ...)::
@ multiples acciones
@finalizar
end:funcion_name
@Ejemplos:
@Saludar
saludar ≔ (nombre): OUTPUT ← "Hola, " + nombre
@Para Retornar un valor en una funcion usamos el operador ↩ (Solo se puede retornar un valor por funcion)
sumar ≔ (a, b): ↩ a + b
multiplicar ≔ (a, b)::
resultado = a * b
↩ resultado
end:multiplicar
Trace
Como se menciono anteriormente, la palabra reservada trace habilita el historial de variables, ahora te explicamos como obtener dicho historial, el cual es un conjunto con todos los valores que ha tomado la variable desde su creacion en orden cronologico
@Trace
trace:x @Obtiene el historial de la variable x como un conjunto
@Ejemplo:
data trace a = 5
a = 10
OUTPUT ← trace:a @Imprime {5,10}
@Caso error
OUTPUT ← trace:b @Error, b no tiene historial ya que no fue declarada con trace
Nota: si una variable no se declara inicialmente con trace ya no se puede activar durante la ejecucion
Reasignacion
En Heza soportamos la reasignacion multiple de variables de forma segura, realizando una copia inicial de los valores antes de reasignar
@Reasignacion
data x = 5
data y = 10
x,y = y,x @Ahora x vale 10 e y vale 5
Es importante que la cantidad de variables corresponda a la cantidad de nuevos valores
Obtener tipo
Para obtener el typo de dato (en formato Text) de un valor puedes seguir la siguiente notacion
@Obtener tipo
:value @Obtiene el tipo de dato de value como Text
@Ejemplo:
data x = 5
data tipo_x = :x @tipo_x vale "Number"
Tambien se puede usar en conversor para convertir un dato en el tipo de otro
@Como conversor
data x = 5
data y = "10"
data z = y >> :x @z vale 10 como Number, ya que :x devuelve "Number" y se convierte y a ese tipo
@Caso invalido
data tipo = :x
data invalid = y >> tipo @Error, tipo esta en formato Text y no se puede usar como tipo de dato directamente
Entrada por consola
Para recibir datos pos consola se usa la funcion INPUT(msg1, msg2, ...) que recibe tantos valores como parametros se indiquen mostrando antes el mensaje correspondiente, luego esos datos se almacenan en el conjunto INPUT del cual se pueden extraer
@Entrada por consola
INPUT("Ingrese su nombre:", "Ingrese su edad:") @Muestra los mensajes y espera la entrada del usuario
data nombre = INPUT{0} @Extrae el primer valor ingresado (nombre)
data edad = INPUT{1} @Extrae el segundo valor ingresado (edad)
Nota: los datos obtenido por consola se almacenan en formato Text y admiten espacios en blanco
Secuencias de escape
A diferencia de otros lenguajes, en Heza las Secuencias de escape como \n o \t no se interpretan como salto de linea o tabulador sino como una secuancia de carateres mas, por lo cual se emplean las constantes de tipo Text que cumplen esa tarea
@Secuencias de escape
LINE @Constante de tipo Text que representa un salto de linea
TAB @Constante de tipo Text que representa un tabulador
data texto = "Hola," + LINE + TAB + "Mundo!" @texto vale "Hola,\n\tMundo!" (segun la notacion de secuencias de escape)
Operador ternario
Es una expresion de tres valores que devuelve un valor si se cumple una condicion u otro si no se cumple (la condicion es una variable de tipo Reference)
@Operador ternario
condicion ? valor_si_verdadero : valor_si_falso
@Ejemplo:
data x = 10
data resultado = &(x > 5) ? "x es mayor que 5" : "x no es mayor que 5"
@resultado vale "x es mayor que 5"