HezaLogo

Heza Languaje

Las matemáticas en acción

General

Heza es un lenguaje de programación diseñado para facilitar la realización de cálculos matemáticos complejos y la manipulación de datos numéricos. Su sintaxis intuitiva y sus potentes funciones integradas permiten a los usuarios centrarse en la lógica matemática sin preocuparse por los detalles de implementación.

A quien va dirigido

Heza no es un software optimizado ni profesional por lo que no se recomienda su uso en industrias, está mas dirigido a estudiantes que cursan matematicas discretas o logica y principios de programacion paralelamente, funciona como un puente entre la notacion declarativa y la logica matematica y la programacion imperativa que se enseña en las universidades, en un punto medio (ej. Math > Heza > CPP/Java) puede reducir la curva de aprendizaje de los lenguajes de bajo nivel y ayudar a los estudiantes a ver la logica fuera de papel o como decimos: Las matematicas en acción.

Arquitectura y tecnologias

Este projecto esta hecho 100% en python, y se apoya de la libreria de SymPy para el calculo simbolico, todas las demas fucnionalidades estan programadas con las librerias estandares.

La arquitectura del interprete consta de 3 pasos (archivos) principales:

El Lexer funciona mediante la busqueda de expresiones regulares (Ragex) en el codigo Heza identificando patrones para construir una lista de tokens, en caso de leer un token ivalido (ej, \ ~) fuera de comillas simples o dobles lanza un error Lexico y detiene la ejecucion. El Lexer tambien es el encargado de ignorar los comentarios, espacios en blanco, tabulacion y saltos de linea.

Un ejemplo de lo hace el lexer al leer el siguiente codigo:

data x = 5

Lee la palabra 'data' y la detecta como keyword, luego la letra x como un identificador, luego lee el operador de asignacion y de ultimo el numero 5 quedando asi:

[(KEYWORD, DATA), (IDENTIFIER, x), (ASIG, =), (NUMBER, 5)]

Esta lista de tokens verificados son los que usa el Parser para crear el AST (Arbol de sintaxis Abstracta). El Lexer solo detecta que los tokens sean validos y les asigna el nombre del patron para identificarlos

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"

Instalación

Para utilizar Heza en tu computadora instala el Interprete de Heza y descarga la Extension de VS Code para el resaltado de sintaxis y los snippets, una vez instalados crea un archivo .hz y pulsa el boton Heza Run en el panel de vs code y ¡Listo! tu codigo Heza estará funcionando.

Ejemplos de codigo

Hola mundo

Codigo que muestra un Hola Mundo! en la consola

@Hola mundo OUTPUT ← "Hola Mundo!"

Calculo de la suma de los primeros n numeros naturales

Codigo que calcula la suma de los primeros n numeros naturales usando una sumatoria

@Suma de los primeros n numeros naturales INPUT("Ingrese un numero natural n:") data n = INPUT{0} >> Number data A = [1..n] data suma = ∑(k ∈ A, k) OUTPUT ← "La suma de los primeros " + n >> Text + " numeros naturales es: " + suma >> Text

Factorial con productoria

Calculo del factorial de un numero n usando la productoria

@Factorial con productoria INPUT("Ingrese un numero natural n:") data n = INPUT{0} >> Number data A = [1..n] data factorial = ∏(k ∈ A, k) OUTPUT ← "El factorial de " + n >> Text + " es: " + factorial >> Text

Calculo de la integral definida de x^2 desde 0 hasta 3

Codigo que calcula la integral definida de x^2 desde 0 hasta 3

@Integral definida de x^2 desde 0 hasta 3 data integral = ∫('x^2', x ∈ [0..3]) OUTPUT ← "La integral definida de x^2 desde 0 hasta 3 es: " + integral >> Text

Obtener numeros primos del 0 a 100

Codigo que obtiene el conjunto de los numeros primos del 0 al 100 usando los filtros y la funcion es primo

@Numeros primos data es_primo ≔ (num):: data i = 2 &(i <= √num) play:: &(num % i = 0): ↩ false i = i + 1 end:& ↩ true end:es_primo data A = [2..100] data primos = { k ∈ A: es_primo(k) } OUTPUT ← "Los numeros primos del 0 al 100 son: " + primos >> Text

Preguntas comunes

Existe una version para movil o interprete Web?

Actualmente no existen un interprete web de Heza ni una version movil, y aunque se puede usar por linea de comandos lo mas recomendable es usar la extensionde vs code ya que los snippets ayudan con el tipeo de algunos simbolos dificiles de conseguir.

Nulo es 0?

El objeto Null esta programado para en contextos numericos funcionar como el 0, y en contextos de Conjuntos como un conjunto vacio, pero su funcion principal es representar la ausencia de un valor, por ejemplo si en una funcion numerica se retorna 0 seguramente es un resultado valido o incluso esperado, pero el valor nulo significa que no retorno nada y en ese sentido y otros mas nos dan informacion muy distinta.

¿Los objetos Reference son Lambdas?

La respuesta corta es no, en terminos de funcionalidad las lambdas (de otros lenguajes) son instrucciones en linea, es decir, cuando una funcion de orden superior requiere una funcion como parametro y no es necesario crear una funciona apodada se declara una funcion anonima con las instrucciones a ejecutar para que la funcion o metodo reciban el argumento, por otro lado los objetos Reference (de Heza) son una especie de apuntadores, solo que en vez de apuntar a la direecion de memoria de una variable apuntan a un nodo del AST, su funcion se basa en la evaluacion peresoza (lazy-evaluation) que consiste en no calcular el valor hasta que se pida, su funcionamiento pareciera ser una funcion pero en realidad es un valor ya que no realiza ningun procedimiento de control (declaracion, secuencias) y tampoco tiene parametros.
En resumen, una lambda es una funcion anomina y un objeto Reference es un valor que puede depender de variables del scope pero solo los utiliza cuando es necesario

Cualquier otra duda o consulta la puedes enviar al correo