Skip to content

Jjoon0513/Lucid

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

8 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Lucid

"One file tells you everything."

Lucid is an intermediate language designed for AI-generated code. Unlike existing languages built for human readability, Lucid is designed with one priority — eliminating any room for AI to guess.


Why Lucid

The reason AI gets code wrong isn't because syntax is complex. There's one root cause — it doesn't know.

# A situation where AI gets confused
result = some_lib.process(data, True, None, 3)
# What is True, what is 3, what does it return — all guesswork

AI cannot reliably know the function signatures of externally included files. APIs differ across versions, deprecated functions get used, argument orders get mixed up.

Lucid solves this at the language level.


Core Philosophy

Everything is in one file

Opening a Lucid file gives you the name, parameters, return type, and side effects of every function — without ever looking at another file.

extern math.add :: (a:Int, b:Int) -> Int !pure
extern io.write  :: (path:Str, data:Str) -> () !io

fn main :: () -> () = {
    let x:Int = math.add(1, 2)
    io.write("out.txt", "hello")
}

What you can tell from this file alone:

  • math.add takes two Ints, returns an Int, and is a pure function
  • io.write touches the filesystem (!io)
  • x is of type Int

extern

extern is the core of Lucid.

When using a function from another file, declare its full specification at the top of the current file.

extern module.function :: (param:Type, ...) -> ReturnType [!attribute]

Attributes

Attribute Meaning
!pure Pure function — no side effects
!io Performs I/O (file, network, etc.)
!mut Mutates state
@deprecated("2.0") No longer recommended

lucid include

You don't have to write extern declarations by hand. The lucid include command generates them automatically.

lucid include math.lcd --target main.lcd

Parses math.lcd and injects the externs into the top of main.lcd automatically.

// extern from math.lcd
extern math.add      :: (a:Int, b:Int) -> Int !pure
extern math.multiply :: (a:Int, b:Int) -> Int !pure

no_extern

Declaring every function as extern makes files very long. Simple functions like those in the std library don't need to be extern'd one by one.

Adding #![no_extern] embeds all information directly in the function name.

#![no_extern]
fn add :: (a:Int, b:Int) -> Int !pure = a + b

The compiler automatically transforms the name:

add$a_Int$b_Int$to_Int

The name alone tells you the arguments and return type, so no extern declaration is needed. If a function name exceeds 60 characters, the compiler warns you — suggesting you use extern instead.

To use a no_extern function from another file, reference it with include:

include math

fn main :: () -> () = {
    let x:Int = add$a_Int$b_Int$to_Int(1, 2)
}

Syntax Summary

// Function definition
fn name :: (param:Type, ...) -> ReturnType [!attribute] = expression

// Variable binding
let name:Type = expression

// Conditional
condition ? then_expr : else_expr

// Lambda
lambda (param:Type, ...) -> expression

// Loop
loop (init, condition, step) { expression }

// Block (last expression is the return value)
{
    let x:Int = ...
    x
}

Types

Int, Float, Str, Bool   // Primitive types
()                       // Unit (void)
Int[]                    // Array
(Int, Str)               // Tuple
Result<Int, Err>         // Result type
(Int, Int) -> Bool       // Function type

Examples

Fibonacci

fn fib :: (n:Int) -> Int !pure =
    n <= 1 ? n : fib(n-1) + fib(n-2)

Read a file and count lines

extern io.read    :: (path:Str) -> Str !io
extern str.lines  :: (s:Str) -> Str[] !pure
extern arr.len    :: (arr:Str[]) -> Int !pure

fn count_lines :: (path:Str) -> Int !io = {
    let content:Str  = io.read(path)
    let lines:Str[]  = str.lines(content)
    arr.len(lines)
}

Sum of even numbers

extern arr.filter :: (arr:Int[], pred:Int -> Bool) -> Int[] !pure
extern arr.fold   :: (arr:Int[], init:Int, f:(Int,Int) -> Int) -> Int !pure

#![no_extern]
fn is_even :: (n:Int) -> Bool !pure = n % 2 == 0

fn sum_evens :: (arr:Int[]) -> Int !pure = {
    let evens:Int[] = arr.filter(arr, is_even$n_Int$to_Bool)
    arr.fold(evens, 0, lambda (acc:Int, x:Int) -> acc + x)
}

CLI

lucid build main.lcd --output out.c        # Compile to C
lucid check main.lcd                        # Type check only
lucid include math.lcd --target main.lcd   # Auto-generate externs
lucid query math.lcd add                   # Look up a function definition
lucid lsp                                  # Start LSP server

Package Manager — Prism

Lucid's package manager is Prism.

prism install math
prism build
prism publish
# prism.toml
[package]
name    = "myproject"
version = "0.1.0"

[dependencies]
math = "0.1.0"
io   = "0.1.0"

$$ \begin{aligned} bug_n &= \left(\frac{coffee}{sleep}\right)^n + \text{Jjoon} \\ n &\in \mathbb{N} \\ \text{Jjoon} &= \text{Me} \end{aligned} $$

About

AI바이브코딩을 빠르게하기 위한 프로그래밍 언어

Resources

Stars

Watchers

Forks

Packages

 
 
 

Languages