Tipi nel linguaggio delle formule M di Power Query
Il linguaggio delle formule M di Power Query è un linguaggio di mashup dei dati utile ed espressivo, che presenta tuttavia alcune limitazioni. Non esiste, ad esempio, un'imposizione efficace del sistema dei tipi. In alcuni casi, è necessaria una convalida più rigorosa. Fortunatamente, M offre una libreria predefinita con il supporto per i tipi per consentire una convalida più efficace.
Gli sviluppatori dovrebbero avere una conoscenza approfondita del sistema dei tipi per poter eseguire una convalida di questo genere in qualsiasi situazione. E anche se la specifica del linguaggio M di Power Query spiega il sistema dei tipi, riserva tuttavia alcune sorprese. Per la convalida delle istanze di una funzione, ad esempio, è necessario poter confrontare la compatibilità dei tipi.
Esplorando il sistema dei tipi M con maggiore attenzione, è possibile chiarire molti di questi problemi e gli sviluppatori potranno creare le soluzioni necessarie.
La notazione usata è facilmente comprensibile se si ha una conoscenza adeguata del calcolo dei predicati e della teoria ingenua degli insiemi.
ELEMENTI PRELIMINARI
(1) B := { true; false }
B è il set tipico di valori booleani
(2) N := { identificatori M validi }
N è il set di tutti i nomi validi in M. Questo set è definito altrove.
(3) P := ⟨B, T⟩
P è il set di parametri di funzione. Ognuno può essere facoltativo e ha un tipo. I nomi dei parametri sono irrilevanti.
(4) Pn := ⋃0≤i≤n ⟨i, Pi⟩
Pn è il set di tutte le sequenze ordinate di n parametri di funzione.
(5) P* := ⋃0≤i≤∞ Pi
P* cè il set di tutte le possibili sequenze dei parametri di funzione, a partire dalla lunghezza 0.
(6) F := ⟨B, N, T⟩
F è il set di tutti i campi di record. Ogni campo può essere facoltativo, ha un nome e un tipo.
(7) Fn := ∏0≤i≤n F
Fn è il set di tutti i set di n campi di record.
(8) F* := ( ⋃0≤i≤∞ Fi ) ∖ { F | ⟨b1, n1, t1⟩, ⟨b2, n2, t2⟩ ∈ F ⋀ n1 = n2 }
F* è il set di tutti i set (di qualsiasi lunghezza) di campi di record, fatta eccezione per i set in cui più campi hanno lo stesso nome.
(9) C := ⟨N,T⟩
C è il set di tipi di colonna, per le tabelle. Ogni colonna ha un nome e un tipo.
(10) Cn ⊂ ⋃0≤i≤n ⟨i, C⟩
Cn è il set di tutte le sequenze ordinate di n tipi di colonna.
(11) C* := ( ⋃0≤i≤∞ Ci ) ∖ { Cm | ⟨a, ⟨n1, t1⟩⟩, ⟨b, ⟨n2, t2⟩⟩ ∈ Cm ⋀ n1 = n2 }
C* è il set di tutte le combinazioni (di qualsiasi lunghezza) di tipi di colonna, fatta eccezione per quelle in cui più colonne hanno lo stesso nome.
TIPI M
(12) TF := ⟨P, P*⟩
Un tipo funzione è costituito da un tipo restituito e da un elenco ordinato di zero o più parametri di funzione.
(13) TL :=〖T〗
Un tipo elenco viene indicato da un tipo specificato (denominato "tipo di elemento") racchiuso tra parentesi graffe.
Poiché le parentesi graffe vengono usate nel metalinguaggio. 〖 〗 parentesi quadre vengono usate in questo documento.
(14) TR := ⟨B, F*⟩
Un tipo record ha un flag indicante se è "aperto" e zero o più campi di record non ordinati.
(15) TRo := ⟨true, F⟩
(16) TR• := ⟨false, F⟩
TRo and TR• sono collegamenti di notazione per i tipi record aperti e chiusi, rispettivamente.
(17) TT := C*
Un tipo tabella è una sequenza ordinata di zero o più tipi di colonna, senza conflitti di nome.
(18) TP := { any; none; null; logical; number; time; date; datetime; datetimezone; duration; text; binary; type; list; record; table; function; anynonnull }
Un tipo primitivo è uno di quelli inclusi in questo elenco di parole chiave M.
(19) TN := { tn, u ∈ T | tn = u+null } = nullable t
Qualsiasi tipo può anche essere contrassegnato come nullable, usando la parola chiave "nullable" .
(20) T := TF ∪ TL ∪ TR ∪ TT ∪ TP ∪ TN
Il set di tutti i tipi M è l'unione di questi sei set di tipi:
tipi funzione, tipi elenco, tipi record, tipi tabella, tipi primitivi e tipi nullable.
FUNZIONI
È necessario definire una funzione: Non Nullable : T ← T
Questa funzione accetta un tipo e restituisce un tipo equivalente, a eccezione del fatto che non è conforme al valore Null.
IDENTITÀ
Alcune identità sono necessarie per definire alcuni casi speciali e possono anche chiarire quanto è stato detto sopra.
(21) nullable any = any
(22) nullable anynonnull = any
(23) nullable null = null
(24) nullable none = null
(25) nullable nullable t ∈ T = nullable t
(26) NonNullable(nullable t ∈ T) = NonNullable(t)
(27) NonNullable(any) = anynonnull
COMPATIBILITÀ DEL TIPO
Come è stato definito altrove, un tipo M è compatibile con un altro tipo M se e solo se tutti i valori conformi al primo tipo sono conformi anche al secondo tipo.
Qui viene definita una relazione di compatibilità che non dipende dai valori conformi e si basa sulle proprietà dei tipi stessi. È previsto che questa relazione, come definito in questo documento, sia completamente equivalente alla definizione semantica originale.
Relazione "è compatibile con" : ≤ : B ← T × T
Nella sezione seguente una t minuscola rappresenterà sempre un tipo M, un elemento di T.
A Φ rappresenterà un subset di F*, or of C*.
(28) t ≤ t
Questa relazione è riflessiva.
(29) ta ≤ tb ∧ tb ≤ tc → ta ≤ tc
Questa relazione è transitiva.
(30) nessuno ≤ t ≤ qualsiasi
I tipi M formano un reticolo sopra questa relazione. none è la parte inferiore e any è la parte superiore.
(31) ta, tb ∈ TN ∧ ta ≤ ta → NonNullable(ta) ≤ NonNullable(tb)
Se due tipi sono compatibili, anche gli equivalenti NonNullable sono compatibili.
(32) null ≤ t ∈ TN
Il tipo primitivo null è compatibile con tutti i tipi nullable.
(33) t ∉ TN ≤ anynonnull
Tutti i tipi nonnullable sono compatibili con anynonnull.
(34) NonNullable(t) ≤ t
Un tipo NonNullable è compatibile con l'equivalente nullable.
(35) t ∈ TF → t ≤ funzione
Tutti i tipi funzione sono compatibili con function.
(36) t ∈ TL → t ≤ elenco
Tutti i tipi elenco sono compatibili con list.
(37) t ∈ TR → t ≤ record
Tutti i tipi record sono compatibili con record.
(38) t ∈ TT → t ≤ taberlla
Tutti i tipi tabella sono compatibili con table.
(39) ta ≤ tb ↔ 〖ta〗≤〖tb〗
Un tipo elenco è compatibile con un altro tipo elenco se i tipi di elemento sono compatibili e viceversa.
(40) ta ∈ TF = ⟨ pa, p* ⟩, tb ∈ TF = ⟨ pb, p* ⟩ ∧ pa ≤ pb → ta ≤ tb
Un tipo funzione è compatibile con un altro tipo funzione se i tipi restituiti sono compatibili e gli elenchi di parametri sono identici.
(41) ta ∈ TRo, tb ∈ TR• → ta ≰ tb
Un tipo record aperto non è mai compatibile con un tipo record chiuso.
(42) ta ∈ TR• = ⟨false, Φ⟩, tb ∈ TRo = ⟨true, Φ⟩ → ta ≤ tb
Un tipo record chiuso è compatibile con un tipo record aperto altrimenti identico.
(43) ta ∈ TRo = ⟨true, (Φ, ⟨true, n, any⟩)⟩, tb ∈ TRo = ⟨true, Φ⟩ → ta ≤ tb ∧ tb ≤ ta
Un campo facoltativo con il tipo any può essere ignorato quando si confrontano due tipi record aperti.
(44) ta ∈ TR = ⟨b, (Φ, ⟨β, n, ua⟩)⟩, tb ∈ TR = ⟨b, (Φ, ⟨β, n, ub⟩)⟩ ∧ ua ≤ ub → ta ≤ tb
Due tipi record che differiscono solo per un campo sono compatibili se il nome e la facoltatività del campo sono identici e i tipi di campo indicato sono compatibili.
(45) ta ∈ TR = ⟨b, (Φ, ⟨false, n, u⟩)⟩, tb ∈ TR = ⟨b, (Φ, ⟨true, n, u⟩)⟩ → ta ≤ tb
Un tipo record con un campo non facoltativo è compatibile con un tipo record identico, con l'eccezione che tale campo è facoltativo.
(46) ta ∈ TRo = ⟨true, (Φ, ⟨b, n, u⟩)⟩, tb ∈ TRo = ⟨true, Φ⟩ → ta ≤ tb
Un tipo record aperto è compatibile con un altro tipo record aperto con un campo in meno.
(47) ta ∈ TT = (Φ, ⟨i, ⟨n, ua⟩⟩), tb ∈ TT = (Φ, ⟨i, ⟨n, ub⟩⟩) ∧ ua ≤ ub → ta ≤ tb
Un tipo tabella è compatibile con un secondo tipo tabella, che è identico se non per il fatto che una colonna ha un tipo diverso, quando i tipi per tale colonna sono compatibili.
REFERENCES
Microsoft Corporation (agosto 2015)
Specifica del linguaggio delle formule di Microsoft Power Query per Excel [PDF]
Recuperato da https://msdn.microsoft.com/library/mt807488.aspx
Microsoft Corporation (senza data)
Informazioni di riferimento sulle funzioni M di Power Query [pagina Web]
Recuperato da https://msdn.microsoft.com/library/mt779182.aspx