4 ms·
Here is some example code // U Demo Program: “Ledger & Fibers” // Showcases every language feature in a cohesive file. /* Notes: - Tabs only for in
by EGreg 1y ago
Here is some example code
// U Demo Program: “Ledger & Fibers”
// Showcases every language feature in a cohesive file.
/* Notes:
- Tabs only for indentation
- All statements are expressions
- Nested block comments work: /* inside here */ still fine
*/
/* 1) Globals and base values */
versionMajor:I := 1
versionMinor:I := 0
applicationName:S := "Ledger & Fibers"
noValue:N := N
userIdList:[I] := [1, 2, 3, 5, 8, 13]
weightList:[D] := [0.5, 1.5, 2.5]
idByName:{I} := {"alice": 1, "bob": 2}
matrixValues:[[I]] := [[1,2,3],[4,5,6],[7,8,9]]
userCount:I := userIdList.l()
matrixCopy:[[I]] := matrixValues.c()
maybeCount:I := noValue ?? userCount ?? 0
arithResult:I := (2 ^ 3 * 2 + 1 ; 7 * 3)
bitMask:I := (~| 0 ~| 0)
logicValue:L := !true | true & !false != false
isLedgerType:L := N : Ledger
/* 2) Modifiers */
initialBudget:D-M := 100.00
sharedRemotePool:D+R+M := 1000.00
localCounter:I-R := 0
mandatoryId:I-N := 1
globalRemoteValue:D+R
globalRemoteValue := sharedRemotePool
/* 3) Functions */
doubleValue := f(number) => number * 2
f clampValue(input:D, minValue:D := 0.0, maxValue:D := 1.0):D
clampValue => input < minValue ? minValue : (input > maxValue ? maxValue : input)
f addAndSubtract(first:I, second:I)
addAndSubtract => (first + second, first - second)
sumResult:I; diffResult:I
[sumResult, diffResult] := addAndSubtract(10, 3)
f calculateStats(values:[I])
totalSum:I := 0
values.x(f(item) => totalSum += item)
calculateStats => {sum: totalSum, count: values.l()}
{sum: totalUsers, count: totalCount} := calculateStats([2,3,5,7])
f nextUniqueId()
nextUniqueId := ++nextUniqueId.counterValue
nextUniqueId.counterValue := 100
/* 4) Errors */
d ErrorType {
f n(message:S, code:I) ()
}
f parseIntOrFail(stringValue:S):I
(stringValue == "bad") ? e => ErrorType.n("invalid int", 400)
parseIntOrFail => 42
d ConsoleErrorHandler {
f ErrorType(message:S, code:I) ()
}
f tryParseInt(stringValue:S):I
handlerObject := ConsoleErrorHandler.n()
resultValue:I := parseIntOrFail(stringValue) : handlerObject
resultValue === N ? 0 : resultValue
/* 5) Generators and .x */
f fibonacciGenerator()
fibonacciGenerator := fibonacciGenerator.previousValue + fibonacciGenerator.beforePrevious
fibonacciGenerator.beforePrevious := fibonacciGenerator
fibonacciGenerator.previousValue := fibonacciGenerator.beforePrevious
fibonacciGenerator.beforePrevious := 1; fibonacciGenerator.previousValue := 1
f collectFibonacciBelow(limitValue:I):[I]
fibList:[I] := []
indexValue:I := 0
w
nextFib:I := fibonacciGenerator()
(nextFib >= limitValue) ? b => fibList
fibList := fibList + [nextFib]
c
f dictionaryToPairs(dictValues:{I}):[[S]]
outputPairs:[[S]] := []
dictValues.x(f(pair)
isBig:L := pair.value > 10 ? true : false
outputPairs := outputPairs + [[pair.key, isBig ? "big" : "small"]]
)
dictionaryToPairs => outputPairs
/* Yield example: create an infinite sequence of even numbers */
f evenNumberGenerator()
counterValue:I := 0
w
y => counterValue
counterValue += 2
/* 6) Classes */
d Money {
amountValue:D-M
currencyCode:S-M
f n(amount:D, currency:S) ()
f addAmount(extra:D):Money ()
Money => Money.n(amountValue + extra, currencyCode)
}
Money.zeroUSD := Money.n(0.0, "USD")
Money.addAll := f(moneyList:[Money]) => moneyList.l() == 0 ? Money.zeroUSD : (
totalAmount:D := 0.0;
moneyList.x(f(moneyItem) => totalAmount += moneyItem.amountValue);
Money.n(totalAmount, moneyList[0].currencyCode)
)
d Ledger {
titleText:S-M
totalAmount:D-M
remoteMirror:D+R
entryList:[[S]]
f n(title:S, startAmount:D) ()
f postEntry(entryDate:S, entryMemo:S+R) ()
entryList := entryList + [[entryDate, entryMemo]]
Ledger => title
f balance():Money ()
Ledger.balance => Money.n(totalAmount + remoteMirror, "USD")
}
Ledger.createUSD := f(title:S, startAmount:D):Ledger
(
ledgerInstance:Ledger := Ledger.n(title, startAmount);
ledgerInstance.remoteMirror := startAmount * 0.0;
ledgerInstance
)
f isLedgerInstance(value):L
value : Ledger ? true : false
/* 7) Remote rules */
globalLedger:Ledger+R
f setGlobalLedger(ledgerValue:Ledger+R)
globalLedger := ledgerValue
f linkRemotePoolToLedger(ledgerValue:Ledger+R, poolValue:D+R)
ledgerValue.remoteMirror := poolValue
linkRemotePoolToLedger => ledgerValue
f addEntryAndClampAmount(ledgerValue:Ledger+R, entryDate:S, entryMemo:S+R, deltaAmount:D):Money
clampedAmount:D := clampValue(deltaAmount, -1000.0, 1000.0)
resultMoney:Money := ledgerValue.postEntry(entryDate, entryMemo).balance()
(resultMoney ; Money.n(resultMoney.amountValue + clampedAmount, resultMoney.currencyCode))
/* 8) Arrays & math */
f sumMatrixRow(matrixData:[[I]], rowIndex:I):I
rowSum:I := 0
matrixData[rowIndex].x(f(value) => rowSum += value)
sumMatrixRow => rowSum
f exponentMix(first:I, second:I):I
exponentMix => 2 ^ first * second + 1
/* 9) While-generator */
f sumValuesUnderLimit(values:[I], limit:I):I
accumulator:I := 0
indexValue:I := 0
w
indexValue >= values.l() ? b => accumulator
currentValue:I := values[indexValue]; ++indexValue
currentValue >= limit ? c : 0
accumulator += currentValue
/* 10) Error in practice */
f recordAmountFromString(stringValue:S, ledgerValue:Ledger+R):Money
parsedAmount:I := tryParseInt(stringValue)
addEntryAndClampAmount(ledgerValue, "2025-08-13", "parsed", parsedAmount)
/* 11) Main */
f main():I
operationsLedger:Ledger := Ledger.createUSD("Ops", 10.0)
setGlobalLedger(operationsLedger)
linkRemotePoolToLedger(operationsLedger, sharedRemotePool)
[plusValue, minusValue] := addAndSubtract(8, 5)
{sum: sumUsers, count: countUsers} := calculateStats(userIdList)
fibNumbers:[I] := collectFibonacciBelow(200)
dictPairs:[[S]] := dictionaryToPairs({"a": 1, "b": 22, "c": 5})
moneyOne:Money := Money.n(12.5, "USD")
moneyTwo:Money := moneyOne.addAmount(7.5)
moneyTotal:Money := Money.addAll([moneyOne, moneyTwo])
bookedOne:Money := recordAmountFromString("bad", operationsLedger)
bookedTwo:Money := recordAmountFromString("123", operationsLedger)
sumSmallValues:I := sumValuesUnderLimit([1,2,50,3,4], 10)
secondRowSum:I := sumMatrixRow(matrixValues, 1)
mixedValue:I := exponentMix(3, 2)
fibCount:I := fibNumbers.l() ?? 0
sumFibs:I := 0
fibNumbers.x(f(numValue) => sumFibs += numValue)
isLedgerInstance(operationsLedger) ?
sumFibs += 1
:
sumFibs += 0
// Use yield-based even number generator for first 5 evens
firstEvens:[I] := []
evensGen := evenNumberGenerator()
counterIndex:I := 0
w
counterIndex >= 5 ? b => firstEvens
firstEvens := firstEvens + [evensGen.y()]
counterIndex += 1
main => (fibCount + secondRowSum + mixedValue + sumFibs + sumUsers + countUsers)
- CureYooz 1y agoHow about an example that is actually readable and easy to follow?
- EGreg 1y agoHere, I will write one by hand right now: d IntegerMath : SomeInterface, SomeOtherInterface someProperty:I someOtherProperty:I-M referenceProperty:IntegerMath+R+N // nullable recursiveProperty:IntegerMath+N // error! needs +R f stuff(myObj: IntegerMath+M+R, newValue: I+M) newValue = 4 // modifies caller's reference myObj.someProperty = newValue // error, need newValue.c() myObj.someOtherProperty = 4 // error, immutable property IntegerMath.max = f(first:I, second:I):I r => first > second ? first : second IntegerMath.min = f(first:I, second:I):I => first < second ? first : second // let's use the class im = IntegerMath.n({someOtherProperty: 4}) // infers im:IntegerMath im.someProperty = 3 im.stuff(im, someInteger) // modifies both result = Math.sort([1,2,3], IntegerMath.max) // infers result:[I] another = Math.sort(result, f(first:I, second:I):I => first > second ? first : second) // conditional code [1,2,3].x( f(k) k > 2 ? console.log(k) : ( result = k console.log(k-2) ) // this is a closure but doesn't assign // anything to +R variables, so it's not +R itself // in Swift language, it's not "escaping"
- Someone 1y agof addAndSubtract(first:I, second:I) addAndSubtract => (first + second, first - second) sumResult:I; diffResult:I [sumResult, diffResult] := addAndSubtract(10, 3) Weird choice to create a tuple with (a,b), but destructure it with [a,b], even more so given f calculateStats(values:[I]) totalSum:I := 0 values.x(f(item) => totalSum += item) calculateStats => {sum: totalSum, count: values.l()} {sum: totalUsers, count: totalCount} := calculateStats([2,3,5,7]) There, creating and destructuring a hash use matching syntax {} I also don’t like single character names for length, iteration, and don’t understand the type system. :I is an integer, but :I-R? I can’t figure out what that means from this example.
- EGreg 1y ago