Se i dati sono semplici e gli oggetti sono complessi , sono curioso di sapere se esistono lingue digitate che sarebbero in grado di aumentare (?) un tipo di mappa in un tipo con campi garantiti. Mi rendo conto che in fase di esecuzione, in qualsiasi lingua questo tipo di controllo è abbastanza fattibile. Ma in teoria credo anche che questo dovrebbe essere possibile verificare con un compilatore. Fare tutto quanto in basso in Java, sarebbe un'esplosione di interfacce (HasComplete, HasTitle, HasTitleAndComplete)
Quindi qualcuno l'ha fatto? Se no, come mai? Se sì, come è stato implementato?
Questo ti permetterebbe di leggere i dati ma poi di manipolarli con almeno alcuni tipi di sicurezza:
// User input is often simply converted to a Map
function parse(json) -> Map {...}
// result still has all user input fields,
// but this would be a runtime exception
// if specified fields are missing
function cast(Map, Map<fields...>) -> Map<fields...> { ... }
input = "{title:'do it', complete: false, rank: 5, subtitle: 'now'}"
// Would throw class cast exception if complete or title were missing
todo = cast(parse(input), Map<title:str, complete:bool>)
// Runtime introspection
todo instanceOf Map -> true
todo instanceOf Map<title:str, complete:bool> -> true
todo instanceOf Map<title:str> -> true
todo instanceOf Map<complete:bool> -> true
todo instanceOf Map<complete:date> -> false
todo instanceOf Map<rank:int> -> false because cast() did not specify rank
todo instanceOf Map<title:str, complete:bool, author:str> -> false
// Typed methods based on map with certain fields
function capitalize_title(Map<title:str>) {...}
function finish_task(Map<complete:bool>) {...}
function finish_and_rename(Map<title:str, complete:bool>, newTitle) {...}
function increase_rank(Map<rank:int>) {...}
// Static Check compile pass
todo = capitalize_title(todo)
todo = finish_task(todo)
todo = finish_and_rename(todo, "[complete]")
// Static Check Compile Fail because cast() did not specify rank
increase_rank(todo)
// Methods could return a type with added (or removed) fields
function add_uuid(Map) -> Map<+id:int> {...}
todo_with_id = add_uuid(todo)
todo_with_id instanceOf Map<title:str, complete:bool, id:int> // true