This is an experimental repository to convert a lispy DSL named James to a subset of Javascript named Jessie. In the future, maybe more tools to translate between lispy and javascript worlds too! It uses Guile’s language tooling to do so.
It’s very experimental, not really usable yet. Warning, warning, warning.
You can see them yourself, run:
guile james-to-jessie.scm
Look at the bottom of the file to see the code that’s being converted.
(Thank you to Dan Connolly for supplying some of these examples, some of which were converted from the Agoric and Endo meta-codebases!)
James program:
(module
(defconst makeCounter
(fn (init)
(let value init)
(return (%r
(: increment (fn () (+= value 1)))
(: decrement (fn () (-= value 1)))
(: makeOffsetCounter
(fn (delta)
(return (makeCounter (+ value delta)))))))))
(defconst c1 (makeCounter 1))
(c1 .increment)
(console .log (c1 .decrement)))
Jessie output:
const makeCounter = function (init) {
let value = init;
return {
increment: function () {
value += value;
},
decrement: function () {
value -= value;
},
makeOffsetCounter: delta => (makeCounter(value + delta))
};
};
const c1 = makeCounter(1);
c1.increment();
console.log(c1.decrement());
(module
(defn (makeMint)
(defconst ledger (makeWeakMap))
(defconst issuer
(harden (%r (: makeEmptyPurse (fn () (mint.makePurse 0))))))
(defconst mint
(harden
(%r
(: makePurse
(fn (initialBalance)
(defconst purse
(harden
(%r
(: getIssuer (fn () (return issuer)))
(: getBalance (fn () (ledger.get purse)))
(: deposit
(fn (amount src)
(Nat (+ (ledger.get purse) (Nat amount)))
(ledger.set src (- (Nat (ledger.get src))
amount))
(ledger.set purse (+ (ledger.get purse) amount))))
(: withdraw
(fn (amount)
(defconst newPurse
(issuer.makeEmptyPurse))
(newPurse.deposit amount purse)
(return newPurse))))))
(ledger.set purse initialBalance)
(return purse))))))
(return mint))
;; example from http://erights.org/elib/capability/ode/ode-capabilities.html
(defconst carolMint (makeMint))
(defconst aliceMainPurse (carolMint.makePurse 1000))
(defconst bobMainPurse (carolMint.makePurse 0))
(defconst paymentForBob (aliceMainPurse.withdraw 10))
;; (.-> bob (.foo paymentForBob))
(bobMainPurse.deposit 10 paymentForBob)
(console.log (aliceMainPurse.getBalance))
(console.log (bobMainPurse.getBalance)))
Jessie output:
function makeMint () {
const ledger = makeWeakMap();
const issuer = harden({
makeEmptyPurse: function () {
mint.makePurse(0);
}
});
const mint = harden({
makePurse: function (initialBalance) {
const purse = harden({
getIssuer: () => issuer,
getBalance: function () {
ledger.get(purse);
},
deposit: function (amount, src) {
Nat(ledger.get(purse) + Nat(amount));
ledger.set(src, Nat(ledger.get(src)) - amount);
ledger.set(purse, ledger.get(purse) + amount);
},
withdraw: function (amount) {
const newPurse = issuer.makeEmptyPurse();
newPurse.deposit(amount, purse);
return newPurse;
}
});
ledger.set(purse, initialBalance);
return purse;
}
});
return mint;
}
const carolMint = makeMint();
const aliceMainPurse = carolMint.makePurse(1000);
const bobMainPurse = carolMint.makePurse(0);
const paymentForBob = aliceMainPurse.withdraw(10);
bobMainPurse.deposit(10, paymentForBob);
console.log(aliceMainPurse.getBalance());
console.log(bobMainPurse.getBalance());
Not yet for anything serious. Maybe soon.
I know, me too. It’s early, though.
Soon, I hope.
Apache v2, though it might eventually include some LGPL bits borrowed from Guile.
What? No. Whaaaaat???? Haha no.....