Universal Absorption Tutorial
Learn how to absorb external code into Grey
Advanced • Time: 45 minutesContents
Introduction
Welcome to the Universal Absorption tutorial! This advanced guide will teach you how to use one of GreyOS's most powerful features: the ability to absorb and transform code from other languages into optimized Grey code using Recursive Symbolic Execution (RSE).
Universal Absorption allows you to:
- Convert existing JavaScript, Python, HTML, CSS, and WebAssembly to Grey
- Integrate third-party libraries and applications into your Grey projects
- Achieve significant performance improvements through symbolic optimization
- Create unified applications that combine code from different sources
Note: Universal Absorption is an advanced feature that leverages GreyOS's symbolic execution engine to translate and optimize code across language boundaries.
Prerequisites
Before you begin this tutorial, make sure you have:
- Completed the Hello World Tutorial and UI Basics Tutorial
- Intermediate understanding of Grey programming concepts
- Basic familiarity with at least one other programming language (JavaScript, Python, etc.)
- GreyOS installed with the Universal Absorber module
To check if your GreyOS installation includes the Universal Absorber, run this command in the Grey Shell:
grey module list | grep absorber
If it's not installed, you can add it with:
grey module install universal-absorber
Understanding Universal Absorption
Universal Absorption is built on the principle of Recursive Symbolic Execution (RSE), which allows GreyOS to understand the meaning of code rather than just its syntax. Here's how it works:
The absorption process involves three main stages:
- Parsing: The source code is parsed into a language-specific abstract syntax tree (AST)
- Symbolic Translation: The AST is converted to Grey's universal symbolic representation
- Optimization: The symbolic representation is optimized using Grey's RSE engine
Important: Not all code constructs have direct equivalents in Grey. The absorber will generate the closest semantic match and include compatibility layers when necessary.
Step 1: Absorbing JavaScript
Let's start by absorbing a simple JavaScript function. Create a file named fibonacci.js
with the following content:
// JavaScript implementation of Fibonacci function fibonacci(n) { if (n <= 1) return n; return fibonacci(n - 1) + fibonacci(n - 2); } // Calculate and print Fibonacci numbers for (let i = 0; i < 10; i++) { console.log(`Fibonacci(${i}) = ${fibonacci(i)}`); }
Now, let's absorb this JavaScript code into Grey using the Universal Absorber CLI:
grey absorb js fibonacci.js --output fibonacci.grey
This command will generate a fibonacci.grey
file with the absorbed code. Let's examine the result:
// Absorbed from JavaScript using Universal Absorber // Original source: fibonacci.js symbolic Math { // Fibonacci function with symbolic optimization function fibonacci(n: Int) -> Int { // Grey's symbolic engine detects recursive pattern // and applies memoization automatically if (n <= 1) { return n; } return fibonacci(n - 1) + fibonacci(n - 2); } } symbolic Main { function run() -> Void { // Loop converted to Grey's range-based iteration for i in range(0, 10) { // Console.log mapped to Grey's print function print("Fibonacci(" + i + ") = " + Math.fibonacci(i)); } } } // Entry point entry(Main.run);
You can run the absorbed Grey code with:
grey run fibonacci.grey
Notice how the Universal Absorber made several optimizations:
- Organized code into symbolic structures
- Added type annotations (Int)
- Automatically applied memoization to the recursive function
- Converted JavaScript's for loop to Grey's range-based iteration
- Mapped console.log to Grey's print function
Step 2: Absorbing Python
Now let's try absorbing a Python script. Create a file named data_processor.py
with the following content:
#!/usr/bin/env python3 # Python data processor example class DataProcessor: def __init__(self, data): self.data = data self.results = {} def process(self): # Calculate statistics self.results['sum'] = sum(self.data) self.results['avg'] = sum(self.data) / len(self.data) self.results['min'] = min(self.data) self.results['max'] = max(self.data) return self.results def print_results(self): print("Data Analysis Results:") for key, value in self.results.items(): print(f"{key.capitalize()}: {value}") # Sample data sample_data = [12, 45, 33, 27, 89, 54, 18, 76] # Process and print results processor = DataProcessor(sample_data) processor.process() processor.print_results()
Now, absorb the Python code into Grey:
grey absorb python data_processor.py --output data_processor.grey
Let's examine the absorbed Grey code:
// Absorbed from Python using Universal Absorber // Original source: data_processor.py symbolic DataProcessor { // Properties data: List; results: Map ; // Constructor equivalent function init(data: List ) -> DataProcessor { let processor = DataProcessor { data: data, results: {} }; return processor; } // Process method with Grey optimizations function process(self) -> Map { // Grey's symbolic execution optimizes these calculations // by recognizing common patterns and avoiding redundant computations let sum_value = self.data.reduce((a, b) => a + b, 0); self.results["sum"] = sum_value; self.results["avg"] = sum_value / self.data.length(); self.results["min"] = self.data.min(); self.results["max"] = self.data.max(); return self.results; } function printResults(self) -> Void { print("Data Analysis Results:"); // Iterate over map entries for (key, value) in self.results { // String interpolation converted to Grey's format print(key.capitalize() + ": " + value); } } } symbolic Main { function run() -> Void { // Sample data let sampleData = [12, 45, 33, 27, 89, 54, 18, 76]; // Create processor instance let processor = DataProcessor.init(sampleData); // Process and print results processor.process(); processor.printResults(); } } // Entry point entry(Main.run);
You can run the absorbed Grey code with:
grey run data_processor.grey
Notice the transformations applied to the Python code:
- Converted Python class to Grey symbolic structure
- Transformed Python's __init__ method to a factory function
- Added static type annotations (List
, Map ) - Optimized calculations by identifying common sub-expressions
- Transformed Python's dictionary iteration to Grey's for-in loop
Step 3: Absorbing Web Applications
The Universal Absorber can also convert entire web applications (HTML, CSS, and JavaScript) into Grey. Let's create a simple web calculator:
First, create an app
directory and add these files:
index.html:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Simple Calculator</title> <link rel="stylesheet" href="style.css"> </head> <body> <div class="calculator"> <div class="display" id="display">0</div> <div class="buttons"> <button onclick="clearDisplay()">C</button> <button onclick="appendToDisplay('7')">7</button> <button onclick="appendToDisplay('8')">8</button> <button onclick="appendToDisplay('9')">9</button> <button onclick="appendToDisplay('/')">/</button> <button onclick="appendToDisplay('4')">4</button> <button onclick="appendToDisplay('5')">5</button> <button onclick="appendToDisplay('6')">6</button> <button onclick="appendToDisplay('*')">*</button> <button onclick="appendToDisplay('1')">1</button> <button onclick="appendToDisplay('2')">2</button> <button onclick="appendToDisplay('3')">3</button> <button onclick="appendToDisplay('-')">-</button> <button onclick="appendToDisplay('0')">0</button> <button onclick="appendToDisplay('.')">.</button> <button onclick="calculate()">=</button> <button onclick="appendToDisplay('+')">+</button> </div> </div> <script src="script.js"></script> </body> </html>
style.css:
body { font-family: Arial, sans-serif; display: flex; justify-content: center; align-items: center; height: 100vh; background-color: #f0f0f0; margin: 0; } .calculator { background-color: #333; border-radius: 10px; padding: 20px; box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2); } .display { background-color: #222; color: white; font-size: 2rem; padding: 10px; text-align: right; margin-bottom: 20px; border-radius: 5px; min-height: 40px; } .buttons { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; } button { background-color: #444; color: white; border: none; padding: 15px; font-size: 1.2rem; border-radius: 5px; cursor: pointer; } button:hover { background-color: #555; } button:active { background-color: #666; }
script.js:
let displayValue = '0'; function updateDisplay() { document.getElementById('display').textContent = displayValue; } function appendToDisplay(value) { if (displayValue === '0') { displayValue = value; } else { displayValue += value; } updateDisplay(); } function clearDisplay() { displayValue = '0'; updateDisplay(); } function calculate() { try { // Using Function constructor for evaluation (safer than eval) displayValue = String(new Function('return ' + displayValue)()); updateDisplay(); } catch (error) { displayValue = 'Error'; updateDisplay(); } }
Now, absorb the entire web application into Grey:
grey absorb web app --output calculator_app.grey
The absorbed code will be a complete Grey application. Here's a simplified version of what it might look like:
// Absorbed web application using Universal Absorber // Original source: app/index.html, app/style.css, app/script.js import { UI } from "greyos.ui"; import { App } from "greyos.app"; symbolic CalculatorApp { // State state: { displayValue: "0" }, // Methods updateDisplay: function() -> Void { this.components.display.update({ content: this.state.displayValue }); }, appendToDisplay: function(value: String) -> Void { if (this.state.displayValue === "0") { this.state.displayValue = value; } else { this.state.displayValue += value; } this.updateDisplay(); }, clearDisplay: function() -> Void { this.state.displayValue = "0"; this.updateDisplay(); }, calculate: function() -> Void { try { // Symbolic execution converts JavaScript's dynamic evaluation // to Grey's safer expression evaluation this.state.displayValue = String( GreyMath.evaluateExpression(this.state.displayValue) ); this.updateDisplay(); } catch (error) { this.state.displayValue = "Error"; this.updateDisplay(); } }, // Components (absorbed from HTML/CSS) components: { calculator: UI.Container { style: { background: "#333", borderRadius: "10px", padding: "20px", boxShadow: "0 5px 15px rgba(0, 0, 0, 0.2)" }, children: [ UI.Container { id: "display", content: "0", style: { background: "#222", color: "white", fontSize: "2rem", padding: "10px", textAlign: "right", marginBottom: "20px", borderRadius: "5px", minHeight: "40px" } }, UI.Grid { columns: 4, gap: "10px", children: [ UI.Button { text: "C", onClick: function() { CalculatorApp.clearDisplay(); }, style: { background: "#444", color: "white" } }, UI.Button { text: "7", onClick: function() { CalculatorApp.appendToDisplay("7"); }, style: { background: "#444", color: "white" } }, // Other buttons omitted for brevity... UI.Button { text: "=", onClick: function() { CalculatorApp.calculate(); }, style: { background: "#444", color: "white" } } ] } ] } }, // Initialize and return the main component initialize: function() -> UI.Component { return this.components.calculator; } } // Entry point App.render(CalculatorApp.initialize());
You can run the absorbed Grey calculator app with:
grey run calculator_app.grey
The Universal Absorber has performed several transformations:
- Combined HTML, CSS, and JavaScript into a single Grey application
- Converted the DOM structure to Grey's UI component hierarchy
- Transformed CSS styles into component style properties
- Converted event handlers to Grey's event system
- Replaced unsafe evaluation with Grey's secure expression evaluator
Step 4: Performance Analysis
One of the key benefits of Universal Absorption is the automatic performance optimization. Let's analyze the performance difference between the original code and the absorbed Grey code.
We can use Grey's benchmarking tools to compare the performance:
grey benchmark compare fibonacci.js fibonacci.grey
This will output performance metrics like execution time, memory usage, and CPU utilization. Typically, you'll see significant improvements in the Grey version due to:
Optimization Type | Original Code | Grey Code |
---|---|---|
Memoization | Manual implementation | Automatic |
Type Optimization | Dynamic typing | Static type inference |
Memory Management | Garbage collection | Reference counting & pooling |
Symbolic Folding | None | Automatic expression simplification |
Parallelization | Manual thread management | Automatic task parallelization |
Tip: The Universal Absorber excels at optimizing mathematical and recursive algorithms, often achieving 2-10x performance improvements without any manual intervention.
Next Steps
Congratulations! You've learned how to use the Universal Absorber to convert code from other languages into optimized Grey code. Here are some suggestions for continuing your journey:
- Try absorbing more complex applications and libraries
- Experiment with absorbing WebAssembly modules using
grey absorb wasm file.wasm
- Learn how to customize the absorption process with transformation rules
- Explore the WASM Integration Tutorial to learn how to directly interact with WebAssembly modules
Advanced tip: For large projects, use the --profile
flag to generate a detailed absorption report that highlights optimization opportunities and potential issues.