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

domingo, 22 de marzo de 2026

Una comparativa entre C# y Beef

Como vimos en una entrega anterior, Beef es un lenguaje de programación similar a C#. Con la peculiaridad que al instalarlo nos provee de su propio IDE.

Observemos un ejemplo. El clásico programa "Hola, mundo" escrito en Beef(lang):

HolaMundo.bf

using System;

class Program
{
    public static void Main()
    {
        Console.WriteLine("Hola, mundo en Beef!");
    }
}

Cualquier despistado diría que está escrito en C#, pero no nos confiemos en lo que vemos. Ahora observemos el mismo programa escrito en C#.

Program.cs

using System;

class Program
{
    public static void Main(string[] args)
    {
        Console.WriteLine("Hola, mundo en C#!");
    }
}

La diferencia entre un programa y el otro es casi nula. Para hacer una comparativa entre estos dos lenguajes nos enfocaremos en:

  1. Paradigma que usan.
  2. Características más importantes.
  3. Tipos de datos que manejan.
  4. Sus estructuras de control.
  5. Funciones y procedimientos.
  6. Estructuras de datos.
  7. Manejo de errores.

Comparativa entre C# y Beef

1. Paradigma.

  • Ambos lenguajes son multiparadigma. 
  • Lo que sugiere que puedes crear programas con paradigma estructurado, funcional y orientado a objetos.

2. Principales características.

De C#:

  • Orientado a Objetos (POO). 
  • Seguridad de Tipos (Strongly Typed).
  • Multiplataforma.
  • Gestión Automática de Memoria.
  • Orientado a Componentes.
  • Integración con .NET. 
  • Sintaxis Moderna y Limpia. 
  • Interoperabilidad. 
  • Programación Asíncrona. 
  • LINQ (Language Integrated Query).

De Beef:

  • Sintaxis y Estructura. 
  • Alto Rendimiento. 
  • Productividad del Desarrollador. 
  • Gestión de Memoria. 
  • Características Modernas. 
  • Seguridad en Depuración. 
  • Compilación e IDE.

3. Tipos de datos.

Observemos una tabla comparativa.

Categoría C# Beef
Booleano bool bool
Enteros con signo sbyte, short, int, long, nint int8, int16, int32, int64, int
Enteros sin signo byte, ushort, uint, ulong, nuint uint8, uint16, uint32, uint64, uint
Punto flotante float, double, decimal float, double
Caracteres char char8, char16, char32
Cadenas string No hay tipo nativo, se usan arrays de char*
Referencia / Objeto object, dynamic, delegate structs (colecciones definidas por el usuario)
Especiales void, nullable types (ej. int?) void

C# es más rico que Beef en tipos de referencia y abstracciones de alto nivel.

Categoría C# Beef
Booleano
// C#
bool flag = true;
// Beef
bool flag = true;
Enteros con signo
// C#
int x = -42;
long y = 123456789;
// Beef
int32 x = -42;
int64 y = 123456789;
Enteros sin signo
// C#
uint a = 42;
byte b = 255;
// Beef
uint32 a = 42;
uint8 b = 255;
Punto flotante
// C#
float pi = 3.14f;
double e = 2.718;
decimal money = 99.99m;
// Beef
float pi = 3.14f;
double e = 2.718;
Caracteres
// C#
char letter = 'A';
// Beef
char16 letter = 'A';
Cadenas
// C#
string name = "Carlos";
// Beef
char8* name = "Carlos";
Referencia / Objeto
// C#
object obj = new object();
delegate void MyDelegate();
// Beef
struct Point { int x; int y; }
Point p = .(10, 20);
Especiales
// C#
void DoSomething() { }
int? maybe = null;
// Beef
void DoSomething() { }

4. Estructuras de control.

Observemos la siguiente tabla comparativa entre C# y Beef.

Estructura C# Beef
Condicional if/else
// C#
if (x > 10)
{
    Console.WriteLine("Mayor a 10");
}
else
{
    Console.WriteLine("Menor o igual a 10");
}
// Beef
if (x > 10)
{
    Console.WriteLine("Mayor a 10");
}
else
{
    Console.WriteLine("Menor o igual a 10");
}
switch / match
// C#
switch (day)
{
    case 1: Console.WriteLine("Lunes"); break;
    case 2: Console.WriteLine("Martes"); break;
    default: Console.WriteLine("Otro día"); break;
}
// Beef
switch (day)
{
    case 1: Console.WriteLine("Lunes"); break;
    case 2: Console.WriteLine("Martes"); break;
    default: Console.WriteLine("Otro día"); break;
}
Bucle for
// C#
for (int i = 0; i < 5; i++)
{
    Console.WriteLine(i);
}
// Beef
for (int i = 0; i < 5; i++)
{
    Console.WriteLine(i);
}
Bucle while
// C#
while (x < 10)
{
    x++;
}
// Beef
while (x < 10)
{
    x++;
}
Bucle do-while
// C#
do
{
    x++;
} while (x < 10);
// Beef
do
{
    x++;
} while (x < 10);
foreach
// C#
foreach (var item in list)
{
    Console.WriteLine(item);
}
// Beef
for (var item in list)
{
    Console.WriteLine(item);
}
break / continue
// C#
for (int i = 0; i < 10; i++)
{
    if (i == 5) break;
    if (i % 2 == 0) continue;
    Console.WriteLine(i);
}
// Beef
for (int i = 0; i < 10; i++)
{
    if (i == 5) break;
    if (i % 2 == 0) continue;
    Console.WriteLine(i);
}

La sintaxis de estructuras de control en Beef es prácticamente idéntica a la de C#, lo que facilita la transición entre ambos lenguajes.

La diferencia más notable está en el uso de foreach : en C# existe como palabra reservada, mientras que en Beef se usa un for con iteración directa sobre colecciones.

Ambos lenguajes soportan break y continue dentro de bucles, así como switch con casos y default.

5. Funciones y procedimientos.

Concepto C# Beef
Función simple
// C#
int Sumar(int a, int b)
{
    return a + b;
}
// Beef
int Sumar(int a, int b)
{
    return a + b;
}
Procedimiento (sin retorno)
// C#
void MostrarMensaje(string msg)
{
    Console.WriteLine(msg);
}
// Beef
void MostrarMensaje(String msg)
{
    Console.WriteLine(msg);
}
Parámetros por referencia
// C#
void Incrementar(ref int x)
{
    x++;
}
// Beef
void Incrementar(ref int x)
{
    x++;
}
Parámetros opcionales
// C#
void Saludar(string nombre = "Invitado")
{
    Console.WriteLine($"Hola {nombre}");
}
// Beef
void Saludar(String nombre = "Invitado")
{
    Console.WriteLine("Hola " + nombre);
}
Funciones anónimas / lambdas
// C#
Func cuadrado = x => x * x;
// Beef
function int(int) cuadrado = (x) => x * x;
Funciones dentro de estructuras/clases
// C#
class Persona
{
    public void Hablar()
    {
        Console.WriteLine("Hola!");
    }
}
// Beef
struct Persona
{
    public void Hablar()
    {
        Console.WriteLine("Hola!");
    }
}

6. Estructuras de datos.

Observemos la siguiente tabla comparativa.

Estructura C# Beef
Arreglos
// C#
int[] numeros = {1, 2, 3};
// Beef
int[] numeros = .(1, 2, 3);
Listas dinámicas
// C#
List lista = new List();
lista.Add(10);
// Beef
List lista = new List();
lista.Add(10);
Diccionarios / Mapas
// C#
Dictionary edades = new Dictionary();
edades["Ana"] = 25;
// Beef
Dictionary edades = new Dictionary();
edades["Ana"] = 25;
Conjuntos
// C#
HashSet conjunto = new HashSet();
conjunto.Add(5);
// Beef
HashSet conjunto = new HashSet();
conjunto.Add(5);
Pilas (Stack)
// C#
Stack pila = new Stack();
pila.Push(1);
// Beef
Stack pila = new Stack();
pila.Push(1);
Colas (Queue)
// C#
Queue cola = new Queue();
cola.Enqueue(2);
// Beef
Queue cola = new Queue();
cola.Enqueue(2);
Estructuras definidas por el usuario
// C#
struct Punto
{
    public int X;
    public int Y;
}
// Beef
struct Punto
{
    public int X;
    public int Y;
}

7. Manejo de errores.

Observemos la siguiente tabla comparativa.

Concepto C# Beef
Bloque básico try-catch
// C#
try
{
    int x = int.Parse("abc");
}
catch (FormatException ex)
{
    Console.WriteLine("Error de formato: " + ex.Message);
}
// Beef
try
{
    int x = int.Parse("abc");
}
catch (Exception ex)
{
    Console.WriteLine("Error: " + ex.Message);
}
try-catch-finally
// C#
try
{
    var file = File.Open("data.txt", FileMode.Open);
}
catch (IOException ex)
{
    Console.WriteLine("Error de E/S: " + ex.Message);
}
finally
{
    Console.WriteLine("Liberando recursos...");
}
// Beef
try
{
    var file = File.Open("data.txt", FileMode.Open);
}
catch (Exception ex)
{
    Console.WriteLine("Error: " + ex.Message);
}
finally
{
    Console.WriteLine("Liberando recursos...");
}
Lanzar excepciones
// C#
throw new InvalidOperationException("Operación inválida");
// Beef
throw new Exception("Operación inválida");
Excepciones personalizadas
// C#
class MiExcepcion : Exception
{
    public MiExcepcion(string msg) : base(msg) { }
}
// Beef
struct MiExcepcion : Exception
{
    public this(String msg) : base(msg) { }
}

Ejemplo. Crear un procedimiento donde se calcule el nuevo salario de una persona. Si el empleado es casado, tiene un salario menor a $30000.00 se le de un aumento del 0.05, en caso contrario solo será del 0.01.

En Beef:

        static void CalculoSalario()
	{
	        Console.WriteLine("\t [ Calculando nuevo salario en Beef  ]");
	        int edad = 0;
		String nombre = scope String();
		String edo_civil = scope String();
		double salario_bruto = 0;
		double salario_neto = 0;

		Console.WriteLine("Introduce tu nombre:");
		Console.ReadLine(nombre); // escribe en el buffer 'nombre'

		Console.WriteLine("Introduce tu edad:");
		String edadStr = scope String();
		Console.ReadLine(edadStr);
		edad = int.Parse(edadStr);

		Console.WriteLine("Introduce tu estado civil:");
		Console.ReadLine(edo_civil);

		Console.WriteLine("Introduce tu salario bruto:");
		String salarioStr = scope String();
		Console.ReadLine(salarioStr);
		salario_bruto = double.Parse(salarioStr);

		if (salario_bruto < 30000)
		{
		    if (edo_civil == "casado")
		    {
		        salario_bruto += salario_bruto * 0.05;
		    }
		    else
		    {
		        salario_bruto += salario_bruto * 0.01;
		    }

		    if (edad > 40)
		    {
		        salario_bruto += salario_bruto * 0.05;
		    }
		    else
		    {
		        salario_bruto += salario_bruto * 0.01;
		    }
		}

		salario_neto = salario_bruto;
		Console.WriteLine("Salario neto: {0}", salario_neto);
	}

En C#:

public static void CalculoSalario()
    {
        Console.WriteLine("\t [ Calculando nuevo salario en C# ]");
        int edad = 0;
        string nombre = "";
        string edo_civil = "";
        double salario_bruto = 0;
        double salario_neto = 0;

        Console.WriteLine("Introduce tu nombre:");
        nombre = Console.ReadLine();

        Console.WriteLine("Introduce tu edad:");
        string edadStr = Console.ReadLine();
        edad = int.Parse(edadStr);

        Console.WriteLine("Introduce tu estado civil:");
        edo_civil = Console.ReadLine();

        Console.WriteLine("Introduce tu salario bruto:");
        string salarioStr = Console.ReadLine();
        salario_bruto = double.Parse(salarioStr);

        if (salario_bruto < 30000)
        {
            if (edo_civil == "casado")
            {
                salario_bruto += salario_bruto * 0.05;
            }
            else
            {
                salario_bruto += salario_bruto * 0.01;
            }

            if (edad > 40)
            {
                salario_bruto += salario_bruto * 0.05;
            }
            else
            {
                salario_bruto += salario_bruto * 0.01;
            }
        }

        salario_neto = salario_bruto;
        Console.WriteLine("Salario neto: {0}", salario_neto);
      
    }

Salida:

         [ Calculando nuevo salario en C# ]
Introduce tu nombre:
Thomas Muller
Introduce tu edad:
34
Introduce tu estado civil:
casado
Introduce tu salario bruto:
29000
Salario neto: 30754.5

Como hemos visto, Beef es un lenguaje de programación que toma inspiración del lenguaje C#. Tanto su sitaxis como tipos de datos. Paradigma y esencia.

Sin embargo, C# es mucho más rico, más completo. Si tuvieras que elegir un lenguaje para crear un nuevo proyecto, C# sería mejor opción, pero Beef no se queda atrás, apenas comienza.

Continuaremos con esta serie de lenguajes de programación.

Enlaces:

https://www.beeflang.org/
https://dotnet.microsoft.com/es-es/languages/csharp
https://codemonkeyjunior.blogspot.com/2026/02/beef-y-c3-dos-lenguajes-de-programacion.html



sábado, 7 de febrero de 2026

Beef y C3, dos lenguajes de programación que evolucionan a C

En este 2026 la programación será cada vez más díficil de aprender y enseñar. La I.A. ha surgido como una herramienta útil para el desarrollador moderno, aunque también un lastre para quienes no quieren evolucionar (o morir en el intento). Es por eso que es necesario el estudio y práctica de la programación.

Existen dos lenguajes llamados Beef y C3 respectivamente que prometen ser la evolución directa al lenguaje mítico C.

Beef se siente como un híbrido entre C++ y C#, con tooling propio y características modernas (tuplas, pattern matching, mixins, reflexión, compilación en caliente). Es ideal para quienes buscan un lenguaje nativo con ecosistema completo y mayor productividad.

La documentación oficial nos dice:

"Beef es un lenguaje de programación de código abierto multiparadigma de alto rendimiento centrado en la productividad del desarrollador".

Beef soporta programación orientada a objetos, funcional y estructurada.

Enfocado a la alta productividad y rendimiento, con fuerte integración C/C++. Busca ser un lenguaje moderno para aplicaciones nativas con tooling propio (IDE, depurador, profiler).

C3 es más conservador. Se mantiene muy cerca de C, pero añade mejoras puntuales (contratos, macros más potentes, genéricos claros, mejor manejo de errores). Es atractivo para proyectos que ya usan C y quieren evolucionar sin perder compatibilidad.

La documentación oficial nos dice:

"C3 es una evolución, no una revolución: el C-like para programadores a quienes les gusta C".

El paradigma de C3 es ser imperativo y estructurado, con extensiones modernas (contratos, macros, genéricos).

Se conidera así mismo como una evolución ergonómica de C, manteniendo compatibilidad total con ABI de C. Su meta es mejorar la seguridad y expresividad sin perder la familiaridad para programadores de C.

Cada uno tiene sus propias características y peculiaridades.

Filosofía de Beef

Se basa en:

  • "Productividad sin sacrificar rendimiento". 
  • Ofrece compilación incremental, detección de fugas en tiempo real, generación de código en tiempo de compilación y un IDE dedicado.
  • Se centra en mejorar la experiencia del desarrollador.

Filosofía de C3

Se basa en:

  • "Una evolución, no una revolución". 
  • Mantiene la simplicidad y cercanía a C, pero añade contratos, macros semánticos, reflexión y manejo de errores más seguro. 
  •  Busca ser C mejorado, no reemplazarlo.

Relación con C/C++

Beef:

  • Interoperabilidad directa con librerías C/C++ (estáticas y dinámicas).
  • Permite mezclar niveles de optimización en un mismo proyecto.
  • Sintaxis inspirada en C#, pero con bajo nivel similar a C++.

C3:

  • Compatibilidad ABI completa con C.
  • Puede integrarse en proyectos C/C++ sin esfuerzo.
  • Sintaxis muy cercana a C, con mejoras inspiradas en C++ pero sin su complejidad.

Instalación

Ambos lenguajes pueden ser instalados en plataformas Linux, Mac OS y Windows.

Este es el IDE de Beef

Hola mundo

Observemos el clásico programa de "Hola, mundo" escrito en ambos lenguajes.

Beef:

HolaMundo.bf

using System;

class Program
{
    public static void Main()
    {
        Console.WriteLine("Hola, mundo en Beef!");
    }
}

Como se puede observar, la extensión de un programa Beef es *.bf.

Beef puede usarse desde una terminal o desde su IDE.

Podemos crear un proyecto con los siguientes comandos:

$ beef new HolaMundo

Coloca el código en HolaMundo/src/HolaMundo.bf

Ejecuta el proyecto:

$ beef run

C3:

holamundo.c3

module hola_mundo;
import std::io;

fn void main()
{
io::printn("Hola, mundo en C3!");
}

La extensión de un programa en C3 no podría ser otro que *.c3.

Tiene una cercanía más expresiva a C.

Compilamos:

$ c3c compile holamundo.c3 -o holamundo

Ejecutamos:

$ holamundo.exe

Tipos de datos y estructuras de control básicas

Ejemplo 1. Crear un programa que muestre los tipos de datos y estructuras de control en ambos lenguajes. Para el caso de Beef usaremos su IDE. C3 será compilado y ejecutado desde terminal

Beef:

Program.bf

using System;

namespace HelloWorld;

class Program
{
    static void Main()
    {
        Console.WriteLine("\t [ Fundamentos de Beef ]");
		TestA();
		TestB();
    }

	static void TestA(){
		Console.WriteLine("\t [ Tipos de variables en Beef ]");
		int entero = 42;
		float flotante = 3.14f;
		double doble = 2.71828;
		bool booleano = true;
		char8 caracter = 'A';
		String texto = "Hola, mundo";

		Console.WriteLine($"Entero: {entero}");
		Console.WriteLine($"Flotante: {flotante}");
		Console.WriteLine($"Doble: {doble}");
		Console.WriteLine($"Booleano: {booleano}");
		Console.WriteLine($"Caracter: {caracter}");
		Console.WriteLine($"Texto: {texto}");

	}


	static void TestB(){
		Console.WriteLine("\t [ Estructuras de control en Beef ]");
		bool numeroV =  23 > 20;
		if(numeroV){
			Console.WriteLine("Verdadero: 23 > 20");
			numeroV = 300 < 100;
		}

		if(numeroV){
			Console.WriteLine("Verdadero: 300 < 10");
		}else{
			Console.WriteLine("Falso: 300 < 100");
		}

		int x = 3;
		if (x < 0)
		    Console.WriteLine("x es negativo");
		else if (x == 0)
		    Console.WriteLine("x es cero");
		else
		    Console.WriteLine("x es positivo");

		switch (x)
		{
		    case 1:
		        Console.WriteLine("x es uno");
		        break;
		    case 10:
		        Console.WriteLine("x es diez");
		        break;
		    default:
			    Console.WriteLine($"x no es ni 1 ni 10 es: {x}");    
		        break;
		}


	}


}

Salida:

         [ Fundamentos de Beef ]
         [ Tipos de variables en Beef ]
Entero: 42
Flotante: 3.14
Doble: 2.71828
Booleano: True
Caracter: A
Texto: Hola, mundo
         [ Estructuras de control en Beef ]
Verdadero: 23 > 20
Falso: 300 < 100
x es positivo
x no es ni 1 ni 10 es: 3

C3:

fundamentos.c3

module fundamentos;

import std::io;

fn void main()
{
    io::printn("\t [ Fundamentos en C3 ]");
    test_a();
    test_b();
}

fn void test_b()
{
   io::printn("\t [ Estructuras de control en C3 ]");
    int x = 10;

   
    if (x > 5){
        io::printn("x es mayor que 5");
    }
    
    if (x % 2 == 0){
        io::printn("x es par");
    }else{
        io::printn("x es impar");
    }
   
    if (x < 0){
        io::printn("x es negativo");
    }else if (x == 0){
        io::printn("x es cero");
    }else{
        io::printn("x es positivo");
    }
    
    switch (x) {
        case 1:
            io::printn("x es uno");
            break;
        case 10:
            io::printn("x es diez");
            break;
        default:
            io::printf("x no es ni 1 ni 10 es: %d\n", x);
            break;
    }
}

fn void test_a()
{
    io::printn("\t [ Tipos de datos en C3 ]");

    int entero = 42;
    float flotante = 3.14f;
    double doble = 2.71828;
    bool booleano = true;
    char caracter = 'A';
    ZString texto = (ZString)"Hola, mundo";


    io::printf("Entero: %d\n", entero);
    io::printf("Flotante: %f\n", flotante);
    io::printf("Doble: %f\n", doble);
    io::printf("Booleano: %s\n", booleano ? "true" : "false");
    io::printf("Caracter: %c\n", caracter);
    io::printf("Texto: %s\n", texto);
}

Compilación:

$ c3c compile fundamentos.c3 -o fundamentos

Salida:

         [ Fundamentos en C3 ]
         [ Tipos de datos en C3 ]
Entero: 42
Flotante: 3.140000
Doble: 2.718280
Booleano: true
Caracter: A
Texto: Hola, mundo
         [ Estructuras de control en C3 ]
x es mayor que 5
x es par
x es positivo
x es diez

Ejemplo 2. Crear un programa que muestre las estructuras de control iterativas como for, while y foreach.

Beef:

Program.bf

         using System;

namespace HelloWorld;

class Program
{
    static void Main()
    {
        Console.WriteLine("\t [ Fundamentos de Beef ]");
        TestA();
    }


    static void TestA()
    {
        Console.WriteLine("\t [ Estructuras de control iterativas en Beef ]");

	    // for
	    for (int x = 0; x < 5; x++){
			Console.WriteLine($"for: i = {x}");
		}
	        

	    // while
	    int j = 0;
	    while (j < 5)
	    {
	        Console.WriteLine($"while: j = {j}");
	        j++;
	    }

	    // do-while
	    int k = 0;
	    do repeat
	    {
	        Console.WriteLine($"do-while: k = {k}");
	        k++;
	    } while (k < 5);

	    
		int[] numeros = new int[] { 1, 2, 3, 4, 5 };
		// foreach para recorrerlo
		foreach (int n in numeros){
			Console.WriteLine($"foreach: n = {n}");
		}
		 
    }
}

Salida:

         [ Fundamentos de Beef ]
         [ Estructuras de control iterativas en Beef ]
for: i = 0
for: i = 1
for: i = 2
for: i = 3
for: i = 4
while: j = 0
while: j = 1
while: j = 2
while: j = 3
while: j = 4
do-while: k = 0
do-while: k = 1
do-while: k = 2
do-while: k = 3
do-while: k = 4
foreach: n = 1
foreach: n = 2
foreach: n = 3
foreach: n = 4
foreach: n = 5

C3:

fundamentos.c3

module fundamentos;

import std::io;

fn void main()
{
    io::printn("\t [ Fundamentos en C3 ]");
    test_a();
}

fn void test_a()
{
   io::printn("\t [ Estructuras de control iterativas en C3 ]");
    
    for (int i = 0; i < 5; i++){
        io::printf("for: i = %d\n", i);
    }
    
    int j = 0;
    while (j < 5) {
        io::printf("while: j = %d\n", j);
        j++;
    }

    
    int k = 0;
    do {
        io::printf("do-while: k = %d\n", k);
        k++;
    } while (k < 5);

    

   int[5] numeros = {1, 2, 3, 4, 5};
    for (int idx = 0; idx < numeros.len; idx++){
        io::printf("array[%d] = %d\n", idx, numeros[idx]);
   }

}

Compilación:

$ c3c compile fundamentos.c3 -o fundamentos

Salida:

         [ Fundamentos en C3 ]
         [ Estructuras de control iterativas en C3 ]
for: i = 0
for: i = 1
for: i = 2
for: i = 3
for: i = 4
while: j = 0
while: j = 1
while: j = 2
while: j = 3
while: j = 4
do-while: k = 0
do-while: k = 1
do-while: k = 2
do-while: k = 3
do-while: k = 4
array[0] = 1
array[1] = 2
array[2] = 3
array[3] = 4
array[4] = 5

En conclusión:

  • Si buscas un lenguaje moderno con tooling completo y sintaxis más expresiva, Beef es la apuesta. 
  •  Si prefieres una transición suave desde C, con mejoras de seguridad y ergonomía pero sin perder compatibilidad total, C3 es la opción.

Continuaremos con esta serie sobre lenguajes de programación.

Enlaces:

https://www.beeflang.org/
https://c3-lang.org/

El lenguaje de programación C

El mítico lenguaje de programación C sigue siendo el lenguaje que definió todo. Y con todo nos referimos a todo lo referente a la inf...

Etiquetas

Archivo del blog