Compare commits
4 Commits
afe7826d58
...
05c04b209c
| Author | SHA1 | Date | |
|---|---|---|---|
| 05c04b209c | |||
| 13fe22a804 | |||
| dedfbfce64 | |||
| d3d720b3bc |
4
.gitignore
vendored
4
.gitignore
vendored
@@ -3,6 +3,10 @@ result
|
||||
result-*
|
||||
.direnv/
|
||||
|
||||
# Compiled binaries
|
||||
grapho
|
||||
*_test
|
||||
|
||||
# Secrets (NEVER commit unencrypted secrets)
|
||||
secrets/*.yaml
|
||||
!secrets/secrets.yaml.example
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Ultimate Notetaking, Sync & Backup System
|
||||
|
||||
A NixOS-based system for managing the three types of data in a computer:
|
||||
A NixOS-based system for managing the three types of data across devices:
|
||||
|
||||
| Tier | Type | Examples | Sync Model |
|
||||
|------|------|----------|------------|
|
||||
|
||||
1617
cli/grapho.lux
1617
cli/grapho.lux
File diff suppressed because it is too large
Load Diff
@@ -1,218 +0,0 @@
|
||||
# Lux Language Limitations (grapho CLI)
|
||||
|
||||
This document tracks limitations encountered while developing the grapho CLI in Lux, to help improve the language.
|
||||
|
||||
## Fixed Issues
|
||||
|
||||
### 1. Double Execution Bug (FIXED)
|
||||
**Severity:** Critical
|
||||
**Status:** Fixed in Lux c_backend.rs
|
||||
|
||||
When using `let result = run main() with {}` to invoke the main function, the entire program was executing twice.
|
||||
|
||||
**Root Cause:** In `c_backend.rs:3878-3907`, the generated C code was:
|
||||
1. Executing all `run` expressions (including `run main() with {}`)
|
||||
2. Then ALSO calling `main_lux()` separately because `has_main` was true
|
||||
|
||||
**Fix:** Added tracking of whether main was already called via a `run` expression, and skip the separate `main_lux()` call if so.
|
||||
|
||||
---
|
||||
|
||||
## String Handling Issues
|
||||
|
||||
### 2. No Escape Sequences in String Literals
|
||||
**Severity:** High
|
||||
**Status:** Confirmed
|
||||
|
||||
Lux does not support backslash escape sequences like `\"`, `\n`, `\t` in string literals.
|
||||
|
||||
```lux
|
||||
// This FAILS - backslash causes parse error
|
||||
Console.print("Hello \"World\"") // ERROR: Unexpected character: '\'
|
||||
|
||||
// This FAILS
|
||||
Console.print("Line1\nLine2") // ERROR: Unexpected character: '\'
|
||||
```
|
||||
|
||||
**Impact:** Cannot include quotes in strings, cannot create multi-line strings, cannot output JSON with proper formatting.
|
||||
|
||||
**Workaround:**
|
||||
- Use shell commands via `Process.exec` to generate quoted output
|
||||
- Use `String.fromChar('"')` for quotes (but this had issues too)
|
||||
- For JSON output, use key=value format instead
|
||||
|
||||
### 3. Dollar Sign in Strings Causes Parse Error
|
||||
**Severity:** Medium
|
||||
**Status:** Confirmed
|
||||
|
||||
The `$` character in strings triggers the string interpolation lexer, even inside shell command strings.
|
||||
|
||||
```lux
|
||||
// This FAILS
|
||||
execQuiet("jq -n --arg x '$foo' ...") // ERROR: Unexpected character: '$'
|
||||
```
|
||||
|
||||
**Impact:** Cannot use shell variable syntax or jq arguments in command strings.
|
||||
|
||||
**Workaround:** Avoid `$` in strings, or construct commands differently.
|
||||
|
||||
### 4. String.fromChar Returns Int, Not String
|
||||
**Severity:** Medium
|
||||
**Status:** Bug
|
||||
|
||||
`String.fromChar('"')` appears to return an Int instead of a String, causing C compilation errors.
|
||||
|
||||
```lux
|
||||
let q = String.fromChar('"') // Compiles but C code is wrong
|
||||
Console.print(q + "hello") // C error: int + string
|
||||
```
|
||||
|
||||
**Impact:** Cannot use character literals to build strings.
|
||||
|
||||
**Workaround:** Use `execQuiet("printf '%s' '\"'")` to get a quote character.
|
||||
|
||||
---
|
||||
|
||||
## Type System Issues
|
||||
|
||||
### 5. Record Type Definitions Don't Work as Expected
|
||||
**Severity:** Medium
|
||||
**Status:** Needs Investigation
|
||||
|
||||
Defining a record type and then creating values of that type doesn't work:
|
||||
|
||||
```lux
|
||||
type ComponentStatus = {
|
||||
name: String,
|
||||
status: HealthStatus,
|
||||
message: String,
|
||||
fix: String
|
||||
}
|
||||
|
||||
fn checkNb(): ComponentStatus with {Process} = {
|
||||
// ...
|
||||
{ name: "nb", status: Healthy, message: "ok", fix: "" }
|
||||
// ERROR: Cannot unify { name: String, ... } with ComponentStatus
|
||||
}
|
||||
```
|
||||
|
||||
**Impact:** Cannot use structured types for cleaner code organization.
|
||||
|
||||
**Workaround:** Avoid record types, use multiple return values via tuples or restructure code.
|
||||
|
||||
### 6. Int.parse Doesn't Exist or Has Wrong Signature
|
||||
**Severity:** Low
|
||||
**Status:** Confirmed
|
||||
|
||||
There's no obvious way to parse a string to an integer.
|
||||
|
||||
```lux
|
||||
let count = Int.parse(someString) // ERROR: Unknown effect operation
|
||||
```
|
||||
|
||||
**Impact:** Cannot convert string output from shell commands to numbers.
|
||||
|
||||
**Workaround:** Keep numbers as strings, use shell for numeric comparisons.
|
||||
|
||||
---
|
||||
|
||||
## C Backend Issues
|
||||
|
||||
### 7. String Equality Comparison Generates Incorrect C Code
|
||||
**Severity:** High
|
||||
**Status:** Bug
|
||||
|
||||
Using `==` to compare strings generates C code that compares pointers instead of string contents.
|
||||
|
||||
```lux
|
||||
let result = execQuiet("echo yes")
|
||||
if result == "yes" then ... // C code: (result == "yes") - pointer comparison!
|
||||
```
|
||||
|
||||
**Impact:** String comparisons fail in compiled binaries.
|
||||
|
||||
**Workaround:** Use `String.contains` for comparison:
|
||||
```lux
|
||||
fn isYes(s: String): Bool = String.contains(s, "yes")
|
||||
if result |> isYes then ...
|
||||
```
|
||||
|
||||
### 8. String.startsWith Not Available in C Backend
|
||||
**Severity:** Medium
|
||||
**Status:** Bug
|
||||
|
||||
`String.startsWith` works in interpreter but generates undefined function calls in C.
|
||||
|
||||
```lux
|
||||
String.startsWith(s, "prefix") // C error: lux_string__startsWith undefined
|
||||
```
|
||||
|
||||
**Workaround:** Use `String.contains` instead.
|
||||
|
||||
### 9. `let _ = expr` Pattern Not Supported
|
||||
**Severity:** Low
|
||||
**Status:** Bug
|
||||
|
||||
The underscore wildcard pattern for discarding results doesn't work.
|
||||
|
||||
```lux
|
||||
let _ = Process.exec("...") // ERROR: Expected identifier
|
||||
```
|
||||
|
||||
**Workaround:** Use a named binding:
|
||||
```lux
|
||||
let ignore = Process.exec("...")
|
||||
```
|
||||
|
||||
### 10. List Literals and Recursion Cause Segfaults
|
||||
**Severity:** High
|
||||
**Status:** Bug
|
||||
|
||||
Combining list literals with recursive functions can cause segmentation faults in compiled binaries while working fine in interpreter.
|
||||
|
||||
```lux
|
||||
// This crashes when compiled:
|
||||
let dirs = ["a", "b", "c"]
|
||||
fn processDirs(dirs: List<String>): Unit =
|
||||
match List.head(dirs) {
|
||||
Some(d) => { ...; match List.tail(dirs) { Some(rest) => processDirs(rest), ... } }
|
||||
None => ()
|
||||
}
|
||||
```
|
||||
|
||||
**Workaround:** Avoid list literals with recursive processing. Inline the operations:
|
||||
```lux
|
||||
fn processA(): Unit = ...
|
||||
fn processB(): Unit = ...
|
||||
fn processC(): Unit = ...
|
||||
// Call each individually
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Suggestions for Lux
|
||||
|
||||
1. **Add escape sequence support** - At minimum `\"`, `\\`, `\n`, `\t`
|
||||
2. **Fix String.fromChar** to return String, not Int
|
||||
3. **Add raw string literals** - Something like `r"..."` or `'''...'''` for shell commands
|
||||
4. **Fix the double execution bug** in the runtime (DONE)
|
||||
5. **Support record type literals** matching their declared type
|
||||
6. **Add Int.parse and Float.parse** for string-to-number conversion
|
||||
7. **Consider a heredoc syntax** for multi-line strings with special characters
|
||||
8. **Fix string equality** - Use strcmp in C backend for string ==
|
||||
9. **Support `let _ = `** - Allow underscore as discard binding
|
||||
10. **Fix String.startsWith** in C backend
|
||||
11. **Fix list literals with recursion** causing segfaults
|
||||
|
||||
---
|
||||
|
||||
## Current Workarounds in grapho CLI
|
||||
|
||||
1. **Double output:** FIXED in Lux c_backend.rs
|
||||
2. **JSON output:** Using key=value format instead of proper JSON
|
||||
3. **Quotes in output:** Avoided entirely or generated via shell
|
||||
4. **Structured types:** Using individual variables instead of records
|
||||
5. **Numeric parsing:** Keeping counts as strings throughout
|
||||
6. **String comparison:** Using `String.contains` with helper functions instead of `==`
|
||||
7. **Discarding results:** Using `let ignore = ...` instead of `let _ = ...`
|
||||
8. **Lists with recursion:** Replaced with individual function calls
|
||||
Reference in New Issue
Block a user