Blocchi try transazionali in ValueScript
Le eccezioni sono difficili da ottenere. Un problema particolarmente delicato che è facile trascurare è la possibilità di una valutazione parziale all'interno trydei blocchi.
Considera il seguente programma JavaScript:
let a = new SmallQueue(["item1"]);
let b = new SmallQueue(["item2", "item3", "item4"]);
try {
const item = a.pop();
b.push(item);
} catch (e) {
console.error("Failed to move item from a to b", e);
}
console.log({ a, b });
{
a: [],
b: ["item2", "item3", "item4", "item1"],
}
{
a: [],
b: ["item2", "item3", "item4"],
}
let a = new SmallQueue(["item1"]);
let b = new SmallQueue(["item2", "item3", "item4"]);
try {
if (b.isFull()) {
throw new Error("b is full");
}
const item = a.pop();
b.push(item);
} catch (e) {
console.error("Failed to move item from a to b", e);
}
console.log({ a, b });
Un'altra opzione è salvare una copia delle variabili che potrebbero cambiare e ripristinarle su catch:
let a = new SmallQueue(["item1"]);
let b = new SmallQueue(["item2", "item3", "item4"]);
const aCopy = a.copy();
const bCopy = b.copy();
try {
const item = a.pop();
b.push(item);
} catch (e) {
a = aCopy;
b = bCopy;
console.error("Failed to move item from a to b", e);
}
console.log({ a, b });
- Potresti non farlo perché è prolisso e sembra inutilmente difensivo
- Richiede
copyun'operazione da definire - Se l'
copyoperazione esiste, potrebbe non essere efficiente - Se
a.popha effetti collaterali, quegli effetti collaterali non verranno ripristinati
let a = new SmallQueue(["item1"]);
let b = new SmallQueue(["item2", "item3", "item4"]);
let item;
try {
item = a.pop();
} catch (e) {
console.error("Failed to move item from a to b", e);
console.log({ a, b });
return;
}
try {
b.push(item);
} catch (e) {
a.unPop(item);
console.error("Failed to move item from a to b", e);
}
console.log({ a, b });
- Estremamente prolisso
a.unPop(item)ci richiede di capire che questa operazione è necessaria quandob.push(item)fallisce, il che è ancora facile da perdere
In ValueScript, tryi blocchi sono transazionali: vengono eseguiti fino al completamento o vengono ripristinati.
Il nostro programma originale fa quello che volevamo senza alcuna modifica:
let a = new SmallQueue(["item1"]);
let b = new SmallQueue(["item2", "item3", "item4"]);
try {
const item = a.pop();
b.push(item);
} catch (e) {
console.error("Failed to move item from a to b", e);
}
console.log({ a, b });
{
a: ["item1"],
b: ["item2", "item3", "item4"],
}
- "Potresti non farlo"
— Il compilatore ValueScript inserisce automaticamente le istruzioni - "Richiede
copyoperazione"
: ValueScript utilizza la semantica del valore, utilizza soloaCopy = a, e questo equivale a copiare - "
copypotrebbe non essere efficiente"
— ValueScript utilizza il copy-on-write fino in fondo, è abbastanza efficiente - "Gli effetti collaterali di
a.popnon verranno annullati"
— ValueScript non ha effetti collaterali
* alcune fantastiche funzioni esterne potrebbero includere operazioni di ripristino e queste verrebbero chiamate automaticamente
ValueScript è un dialetto di TypeScript con semantica del valore. Ha un parco giochi online che include una dimostrazione del programma di questo articolo ed è open source .

![Che cos'è un elenco collegato, comunque? [Parte 1]](https://post.nghiatu.com/assets/images/m/max/724/1*Xokk6XOjWyIGCBujkJsCzQ.jpeg)



































