Díky za článek.
Asi je to tím, že neznám closure, ale po přečtení článku k formátu nemám ve formátu (a konverzích) úplně jasno:
Jak je řešena rovnost klíčů? Je klíč 12 stejný jako 12.0, nebo je to různý klíč? Ztratí se rozdíl mezi :key a "key" v Pythonu už při načtení, nebo tam to ještě lze rozlišit (a je specifikováno co se má stát když tam je oboje, nebo :key dvakrát)?
Proč je problémem používání normálních symbolů (místo keywords) v EDN formátu to, že mají jhodnotu? Nepředpokládám, že by bylo potřeba je při načítání vyhodnocovat? (V Common Lispu se jako důvod používání uvádí spíše to, že pro keywords není třeba řešit balíky/namespace , a oproti řetězcům mají identitu)
Jak je to vůbec s namespacy při čtení EDN? Je specifikovaný namespace, ve kterém jsou symboly bez prefixu? Původně jsem četl článek jako že jméno namespace je povinné, ale pak vidím ?monster, takže asi ne. A jak to je s namespacy při konverzi z/do XML (jak v XML, tak v Closure) - jsou mapovány na sebe?
Jak je to s bezpečností - vypadá to, že read je standardní reader pro Closure. Jsou možnosti jak ho omezit na EDN? Pokud ne, je bezpečné nechat ho číst potenciálně škodlivý vstup?
Mohl bych to asi všechno postupně sám zkusit, ale to zjistím jen chování, ne specifikaci jak to "má" být.
Na potenciálně škodlivý vstup by se měl v Clojure (s -> j !) využívat clojure.edn/read-string.
Myslím, že symboly bez prefixu skončí v namespace :user, jinak si ale typicky data v EDN načítám do nějaké na to myšlené struktury, např. atomu nebo mi to jde jako vstup do funkce/ handleru apod.
V Clojure je 12 a 12.0 resp. :key a "key" něco jiného, EDN tu sémantiku přenáší. Jak to je při načtení do Pythonu netuším. Možná by si zde mohl člověk pomoct pomocí Hy (takový pseudo-Clojure nad Pythonem), kde tohle jistě řešili.
Dobrý den,
zkusím postupně odpovědět.
1) klíče 12 a 12.0 jsou podle specifikace odlišné (stejně jako hodnoty prvků, ale tam to pochopitelně není tak viditelné). Příklad příště doplním s info o tom, jak to řeší Python.
2) :key a "key" se odliší, protože ten první klíč se implicitně uloží ve formě typu (objektu) Keyword:
{Keyword(key): 'foo',
'key': 'bar'}
3) namespaces - výchozí se nepřidává, toto totiž do značné míry závisí na jakyku. Ony se symboly nevyhodnocují při čtení, takže se to (asi?) v praxi ani řešit na úrovni přenosu dat nemusí.
4) bezpečnost - v Clojure (a tedy i v EDN) se rozlišuje mezi operací "read/read-string" a "eval" s tím, že "eval" se asi nebude na data volat. To by bylo to stejné, jako vyhodnocovat JSON v JavaScriptu evalem - ano někdo to dělá, ale takový člověk si říká o problémy. Zkusím to ukázat na příkladu:
user=> (require '[clojure.edn :as edn])
nil
user=> (read-string "{:key (+ 1 2)}")
{:key (+ 1 2)}
user=> (edn/read-string "{:key (+ 1 2)}")
{:key (+ 1 2)}
user=> (eval (edn/read-string "{:key (+ 1 2)}"))
{:key 3}
Tj..jak read-string tak i edn/read-string sice mapu načtou a převedou do standardní podoby (tedy už se nejedná o řetězec, ale o plnohodnotná data/kód), ale dokud se nezavolá "eval", tak se funkce + nevyhodnotí.
20. 4. 2021, 13:01 editováno autorem komentáře
Děkuji oběma za odpověďi, asi je mi to jasnější (a u těch namespaces jsem dalším čtením jinde zjistil, že jsou celkově asi jinak než jsem předpokládal)
K bezpečnosti čtení - nešlo mi o evaluaci, ale opravdu o čtení - v Common Lispu (omlouvám se, že to mám pořád jako příklad, ale beru to jako známý podobný jazyk) je použití read pro čtení sexpu potenciálně nebezpečné v první řadě protože #., ale i kvůli #+ (umožní detekovat features), kvůli #1= a #1# (riziko různých forem DoS útoků) a dalším. Obdobně "plné" XML umožňuje pomocí entit získávání různých dat nebo DoS ještě předtím, než se obsah začne zpracovávat (XXE). Měl jsem na mysli, zda read v closure deklaruje (i do budoucna) odolnost proti podobným útokům (a A.K. z mého pohledu otázku zodpověděl).
Díky za článek. Už se těším na OpenCrux! Hodně by mě zajímalo, jak se Crux používá nad typickou databází typu PostgreSQL, což podporuje pomocí JDBC. Jak jsem na rootu už několikrát psal, v OrgPadu zvědavě po OpenCruxu koukáme, ale ještě jsme se nedostali k tomu něco zkoušet.
Ano, kdysi jsme o tom uvažovali (před více než rokem), ale byly to opravdu jen úvahy a s Datomicem nemáme praktickou zkušenost. Finanční stránka Datomicu s tím, jak děláme a chceme dělat startup, není kompatibilní. Prostě nejsme banka nebo Walmart, museli bychom nejspíš reálně do AWS, což by nám zase razantně navýšilo náklady atd... :-)
Pokud budeme něco nasazovat, tak ten OpenCrux.
Koukam dalsi datovy format, ale opet nema co bych potreboval.
Nevi nekdo o jednoduchem formatu, ktery by byl citelny lidmi, a umoznoval snadne citelne ukladani mensich matic? Ve vetsine formatu se daji rozumne ukladat vektory, ale matice uz byvaji stylem: [[1,2,3],[4,5,6],[7,8,9]], coz uz vubec neni lidsky citelne.
Pozadavek prichazi z oblasti presnych mereni - spousta malych kalibracnich matic, 5 bodu pres napetovou stupnici, 5 pres frekvencni, matice plna korekci. A clovek obvykle potrebuje mit kontrolu nad hodnotama v ruznych castech kalibracnich postupu, takze to musi byt citelne pro lidi, rychle prohlizeni, a snadno prenositelne z jednoho programu do druheho.
Priznam se ze jsem si neco vytvoril:
https://github.com/KaeroDot/info-strings
Textovy soubor, obsahue klic::hodnota, matice mam takhle:
#startmatrix:: simple matrix
1; 2; 3
4; 5; 6
#endmatrix:: simple matrix
Jenze nedostatky sveho reseni vnimam na kazdem kroku. Navic nejsem profesionalni programator, takze to je pomale a projevuje se to pri vetsim mnozstvi cteni/zapisu, protoze vse resim pres regexpy, a ty jsou krute pomale.
V biologii se používá formát NEXUS, který umožňuje uložit různé bloky, mj. (distanční) matici, která je fakticky zapsaná jako TSV. Používá to velké množství programů (často si definují vlastní bloky) a je to dostatečně jednoduché na to, aby se to dalo upravovat ručně. :-)
Tak jsem na disku našel nějaký příklad:
#nexus [! Cavalli-Sforza and Edwards chord distance (1967) ] BEGIN TAXA; DIMENSIONS NTAX=489; TAXLABELS [1] Kr001 [2] Kr002 [3] Kr003 ... [487] Kl004 [488] Kl005 [489] Kl006 ; END; BEGIN DISTANCES; DIMENSIONS NTAX=489; FORMAT TRIANGLE=BOTH DIAGONAL LABELS=LEFT ; MATRIX Kr001 0.00000 0.23621 0.22879 ... Kr002 0.23621 0.00000 0.18748 ... Kr003 0.22879 0.18748 0.00000 ... ... Kl004 0.72767 0.67895 0.67895 ... Kl005 0.76898 0.81770 0.81770 ... Kl006 0.81028 0.81028 0.81028 ... END;
Tohle načítá třeba SplitsTree (v nejnovější verzi jsem to nepoužil, mezi 4 a 5 tam bylo dost změn), ale jinak jsou matice spíš vzacnější příklad užití NEXU, spíš se tam ukládají sekvence, fylogenetické stromy a další data. Ten TAXLABELS
blok by tam být nemusel. Smysl má, když má člověk dlouhá jména vzorků --- potom lze v datových blocích (sekvence, matice, znaky, ...) používat čísla vzorků místo jmen. Jinak je asi zřejmé, co je co. Existuje spousta SW, co s tím pracuje, něco by se jistě dalo vykuchat. :-) Výhodou je rozšiřitelnost --- řada programů do toho přidává vlastní bloky, což zase ale někdy přináší problémy při přenosu dat mezi programy... ;-)
Odradkovani je dulezite, ale ta pripadna knihovna to musi delat. Pokud to vypise do souboru v jednom radku, je to napytel.
Ne, grafy jsou mi pro tohle pouziti nahouby. Porovnavat hodnoty v sesti grafech je opruz. A v grafu neuvidim hodnotu 6. desetinneho mista. Ano, opravdu potrebuju matice se sesti platnymi misty. Casto i s deviti.