- ABD Gelir İdaresi IRS, yeni Tax Withholding Estimator (TWE) aracını açık kaynak olarak yayımladı; temel tasarım ilkesi, ABD vergi hukukunu XML tabanlı bildirimsel bir spesifikasyon olarak modelleyen bir yapı
- TWE’nin vergi hesaplama mantığı, Fact Graph adlı bir mantık motoru üzerine kuruluyor ve her vergi kalemi, XML ile tanımlanan “fact”lerin bağımlılık grafiği olarak ifade ediliyor
- Vergi mantığını JavaScript gibi buyruksal dillerle uygulamak, yürütme sırasını yönetme, ara değerlerin kaybolması ve uygulama ayrıntılarının görünür hale gelmesi gibi sorunlar yarattığı için bildirimsel yaklaşım gerekli
- JSON, rastgele iç içe geçmiş ifadeleri işlemeye uygun değil; XML’de etiketin kendisi nesne türünü gösterdiğinden DSL kurmak için çok daha elverişli
- XML, XPath gibi olgun araç ekosistemlerinden ücretsiz yararlanmayı sağladığı için, çapraz platform bildirimsel spesifikasyonlar için en maliyet etkin seçenek
Fact Graph: ABD vergi hukukunun XML ile ifadesi
- ABD Gelir İdaresi IRS’nin yayımladığı Tax Withholding Estimator (TWE), mükelleflerin gelir ve indirim tutarlarını girerek vergi ve stopaj tutarlarını tahmin etmesini sağlayan bir araç
- Proje açık kaynak olarak yayımlandı ve kamu katkılarına da izin veriliyor
- TWE, iki XML yapılandırmasıyla üretilen statik bir site; bunlardan ilki ABD vergi hukukunu ifade eden Fact Dictionary
- Fact Graph, başlangıçta IRS Direct File projesi için geliştirilen bir mantık motoru; mükellefin vergi yükümlülüğünü ve stopajını, Fact Dictionary’de tanımlı fact’lere göre hesaplıyor
- Her fact XML ile tanımlanıyor; örneğin
/totalOwed, /totalTax değerinden /totalPayments çıkarılarak elde edilen türetilmiş bir Derived fact olarak ifade ediliyor
- “Toplam borç (total owed)”, gelir üzerinden hesaplanan toplam vergi (total tax) ile hâlihazırda ödenmiş tutarlar (total payments) arasındaki fark
- İade edilebilir krediler (refundable credits), vergi bakiyesini negatife düşürebilen vergi kredileridir; Earned Income Credit, Child Tax Credit ve American Opportunity Credit gibi kalemler
<Add> ile toplanır
- İade edilemez krediler (non-refundable credits), vergi yükünü en fazla 0’a kadar azaltabilir;
<GreaterOf> işleci ile 0 ve (geçici vergi - iade edilemez krediler) arasından büyük olan seçilir
- Kullanıcı girişleri
<Derived> yerine <Writable> etiketiyle tanımlanır ve <Dollar/>, <Boolean/> gibi türlerle değer tipi belirtilir
- Fact’lerin birbirine bağımlı olduğu ve nihai vergi sonucunu üreten bir graf yapısı bulunur
Vergi mantığında neden bildirimsel spesifikasyona ihtiyaç var
- Aynı hesaplama JavaScript ile
const totalOwed = totalTax - totalPayments gibi kısa biçimde yazılabilir; ancak bu, buyruksal (imperative) bir yaklaşımdır ve sıralı yürütmenin ardından ara adımlar kaybolur
- Bağımlılık ilişkileri derinleştikçe yürütme sırası sorunları ortaya çıkar:
getInput() gibi kullanıcı girdisi alan bir fonksiyon sonraki tüm hesaplamaları engeller ve eşin olup olmamasına göre soruların kendisinin değişmesi gerekebilir
- Social Security gelirlerinin toplanması mantığında
map/reduce gibi JavaScript uygulama ayrıntıları görünür hale gelirken, XML’deki <CollectionSum> doğrudan vergi matematiği kavramını ifade eder
<Dependency path="/socialSecuritySources/*/totalFederalTaxesPaid"/> ile koleksiyondaki kalemler toplanır
- Fact Dictionary, bildirimsel (declarative) biçimde çalışır; hesaplamanın somut yürütme adımları veya sırası anlatılmaz, yalnızca adlandırılmış hesaplamalar ve bağımlılıklar tanımlanır, motor da yürütme yöntemini otomatik belirler
- Bildirimsel vergi modelinin en önemli faydası denetlenebilirlik (auditability) ve iç gözlem (introspection): Programa “bu sayı nasıl elde edildi?” diye sorabilmek
- Buyruksal programlarda ara değerler çoktan atılmış olur; bunlar ancak log veya hata ayıklayıcıyla görülebilir ve ABD vergi hukuku gibi yüzlerce ara hesaplama içeren durumlarda bu yaklaşım ölçeklenmez
- Fact Graph’ın özgün yazarı Chris Given’a göre Fact Graph, “sorulmayan kalemlerin vergi beyanı sonucunu değiştirmediğini ve hak edilen tüm vergi avantajlarının alındığını kanıtlamanın bir yolu”
- TurboTax’ı geliştiren Intuit de aynı sonuca ulaştı ve 2020’de “Tax Knowledge Graph” başlıklı bir whitepaper yayımladı; ancak uygulama kapalı kaynak kaldı
- IRS Fact Graph ise açık kaynak ve public domain olduğu için herkes tarafından incelenebilir, paylaşılabilir ve genişletilebilir
XML neden DSL için JSON’dan çok daha uygun
- Vergi hukukunun bildirimsel veri gösterimi için JSON denendiğinde, rastgele iç içe geçmiş ifadeleri işlemek son derece zahmetli hale gelir
- JSON’daki tek birleşik veri yapısı nesnedir; bu yüzden her alt nesnenin kendi türünü
"type", "kind" gibi alanlarla ayrıca belirtmesi gerekir
- XML’de ise etiket adının kendisi nesnenin türünü gösterdiğinden ek bir bildirime ihtiyaç yoktur
- Aynı
/tentativeTaxNetNonRefundableCredits fact’inin JSON gösterimi, XML’den daha uzun ve daha karmaşıktır
- XML, yorum (comment) desteği ve makul boşluk/satır sonu işleme gibi, JSON’da sık görülen rahatsızlıkları barındırmaz
- Öznitelikler (attribute) ve adlandırılmış alt öğeler (named children), dil tasarımında neyin vurgulanacağını seçmeyi sağlayan bir ifade gücü sunar
- “Dolar” ile “tamsayı” ayrımı gibi özgün veri türleri tanımlamak mümkündür
- Uzun açıklama metinleriyle çalışırken XML, JSON’a kıyasla okuma ve elle düzenleme açısından çok daha rahattır
XML’in genelliği ve araç ekosistemi
- S-expression, Prolog ve KDL gibi alternatif sözdizimleri XML’den daha okunaklı olabilir; ancak XML kullanıldığında ayrıştırıcılar ve genel amaçlı araç ekosistemi ücretsiz olarak kazanılır
- S-expression Lisp’te, Prolog terimleri Prolog’da iyi çalışır; ama XML hemen her biçime dönüştürülebilir
- XML’i Prolog terimlerine dönüştürmek, Prolog’da tek bir predicate ile mümkündür
- Hacker News kullanıcısı ok123456’ın “Prolog/Datalog kullanılamaz mı?” sorusuna da değiniliyor; bu mümkün olsa da genellik bakımından XML üstün
- Chris Given, YAML hakkında “ABD vergi hukuku mantığını YAML ile ifade etmeye asla çalışmayın” diyor
- XPath ile gerçek bir kullanım örneği: tek satırlık bir shell komutuyla fact yollarını bulanık biçimde arayan ve seçilen yolun tanımını anında gösteren bir betik yazılmış
cat facts.xml | xpath -q -e '//Fact/@path' | grep -o '/[^"]*' | fzf ile fact arama
- Bağımlılık zincirini geriye doğru izleyip hangi fact’in ilgili fact’e bağımlı olduğunu takip eden özellik de eklenmiş
- Yaklaşık 60 satırlık bash betiği, neredeyse her gün kullanılan bir hata ayıklama aracına dönüşmüş
- Ekip üyeleri de benzer hızlı hata ayıklama araçlarını kendileri geliştirmiş; hepsi XML’i basitçe ayrıştırarak, Fact Graph’ın Scala uygulamasına dokunmadan kendi dillerinde çalışmış
- Temel ders şu: genel amaçlı veri gösterimi çok değerlidir ve bu kategoride fiilen yalnızca JSON ile XML vardır
- Çoğu durumda JSON seçilmelidir; ancak bir DSL gerektiğinde en ucuz seçenek XML’dir ve bu maliyet etkinliği sayesinde ekip, inovasyon bütçesini başka alanlara ayırabilir
Ek notlar
- Programcı olmayan kişiler de şema tasarımı iyi yapıldıysa XML okuyabilir; yine de alternatif görünümler ayrıca oluşturmak tercih edilir
- Son dönemde XML’e ilgi yeniden artıyor: Jake Low’un XML belgelerini düz, satır odaklı bir gösterime dönüştüren
grex aracı ve Martijn Faassen’in Rust ile yazdığı modern XPath/XSLT motoru Xee buna örnek
- TWE fact’leri stopaj tahmini içindir; doğrudan vergi beyanı için kullanılmamalıdır
1 yorum
Hacker News görüşleri
XML, birçok dilde düzgün şekilde ayrıştırılabilmesi için maliyetli bir biçim
Pratikte standarda yakın bir uygulama yapmak için libxml2, expat ve Xerces gibi üç açık kaynak uygulamaya bel bağlamak gerekiyor
SGML ailesi dillerin özü, “liste”yi birinci sınıf nesne, iç içe geçmeyi ise ikinci sınıf nesne olarak ele almasıdır; ayrıca etiket adları ve öznitelikler olmak üzere iki eksen üzerinden meta veri eklenebilir
XML, bir DSL olarak hâlâ yararlıdır, ancak gerçekten XML kullanacaksanız “cheap” kelimesini bir kenara bırakmanız gerekir
Ayrıca bildirimsel bir DSL’i buyruksal bir ifade gibi görünecek şekilde tasarlamak da mümkündür. Örneğin
totalOwed = totalTax - totalPaymentsgibi bir ifade, bir XML DSL ile aynı anlama gelebilirMETAFONT gibi diller bu yaklaşımı gösterir (örnek bağlantı)
XML’in tekrar tekrar aynı hataları yaptığını sık görüyorum
Biçime ne kadar çok özellik koyarsanız ayrıştırmak o kadar zorlaşır gibi basit bir gerçek çoğu zaman unutuluyor
JSON’un popüler olmasının nedeni, az özelliğe sahip olduğu için ayrıştırmasının kolay olması
Buna karşılık XML’e attributes, namespaces, CDATA, DTDs gibi fazla şey yüklendi
SQLite’ı değişim biçimi olarak kullanalım diyen tartışmalar da vardı, ama bunun da XML gibi karmaşıklaşma riski var
CSV’nin basit olduğu için hâlâ sevilmesinin sebebi de bu
Bugünlerde JSON’a zorla yorum ya da tip bilgisi ekleme girişimleri, kötü XML özniteliklerinin yeniden üretilmesi gibi
Yazının yazarı olarak katılıyorum
Bildirimsel bir tanımı matematiksel ifade gibi göstermek mümkün, ama bu sonuçta yeni bir dil yaratmak demek
Böyle olunca ayrıştırıcıyı her ortama taşımak zorunda kalıyorsunuz
Operatör önceliği ya da switch ifadeleri gibi sözdizimsel kararları da kendiniz vermelisiniz ve sonunda karmaşıklık patlıyor
Bu yüzden “cheap” kelimesini kullandım — zaten her ortamda ayrıştırıcısı ve araçları bulunan bir biçimi kullanmak maliyeti düşürüyor
İfade gücü azalıyor olabilir, ama küçük ekipler için akıllıca bir tercih
Kurumsal Java dünyasında XML’i çok kullandım ve bellek ile CPU darboğazlarının baş sorumlusu oydu
XML kesinlikle cheap değil
SGML’in özü, öğelerin düzenli ifade tabanlı içerik modelidir
Yalnızca liste yapısı değil, BNF gibi dilbilgisel üretim kuralları da tanımlanabilir
“XML proper” yerine “XML lookalike” denmesi gereğinden fazla titiz bir ifade gibi geliyor
XML’in tüm özelliklerini kullanmasanız da XML hâlâ XML’dir
Bu, bardak tutacağı yok diye okul otobüsüne “otobüs taklidi” demeye benziyor
XML yerine eDSL’yi iyi destekleyen bir dil kullanmanın yeterli olduğunu düşünüyorum
Haskell, OCaml, Scala gibi diller applicative ya da arrow gibi kavramlarla paralel hesaplamaları kolay ifade edebiliyor
JavaScript’te de
.reduce()yerinesumgibi soyutlamalar oluşturabilirsinizXML DSL yapmaya kalkınca paralelleştirme, okunabilirlik ve yeni sözdizimi icat etme gibi sorunları yine çözmeniz gerekiyor
Karmaşık alanlarda Greenspun’un 10. yasasına çarpma ihtimali yüksek
Ama Haskell gibi dilleri öğrenmek zor; bu da ayrı bir sorun
30 yıllık deneyimi olan geliştiriciler bile giriş eşiğinin yüksek olduğunu hissedebiliyor
Raku da iyi bir seçenek
Haskell tabanlı olarak başladı ve yerleşik Grammar ile işlevsel tarzı desteklediği için DSL yazımı için uygun
HTML! (şaka yollu kısa bir tepki)
Lisp de olur
S-expression’a bakınca XML’in ne kadar uzun ve ağır hissettirdiği hemen anlaşılıyor
JSON yapısı daha iyi tasarlanabilir
Her düğüm bir tip anahtarı ve dizi değeriyle kurulursa S-expression benzeri bir ifade elde edilebilir
Bu sayede akış tabanlı ayrıştırma mümkün olur ve tipi en baştan bilebilirsiniz
Büyük veri kümelerinde faydalı olur
JSON, XML’den çok daha basit ve ayrıştırma maliyeti daha düşük
XML’de etiket eşleştirme, öznitelik işleme gibi durum yönetimi karmaşıktır
JSON’da ise sadece
{},[]eşleşmesini takip etmek yeterlidirBu basitlik birikerek gecikmenin azalmasına yol açar
Ama JSON’daki tırnak işareti fazlalığı görsel gürültü gibi hissettiriyor
Ben şahsen Clojure’un EDN biçimini daha temiz buluyorum
Böyle bir JSON yapısı estetik açıdan yozlaşmış bir biçim gibi geliyor
Veri etiket gerektiriyorsa, ona uygun bir gösterim biçimi kullanmak daha iyi olabilir
The Lost Art of XML yazısı bana daha ilginç geldi
Web geliştirme araçlarının önemli bir kısmının, XML’in tarayıcı savaşlarında yenilmesinin sonucu olarak ortaya çıktığı görüşü dikkat çekiciydi
Ama “XML terk edildi çünkü JavaScript kazandı” iddiasına katılmak zor
Tarayıcılar aslında XML’i baştan beri destekliyordu (AJAX’taki X, XML’dir)
Geliştiriciler sadece XML’i sevmiyordu
Bence XML, aşırı tasarım ve karmaşıklık yüzünden gözden düştü
Eski XML API dönemini bizzat yaşamış biri olarak XML gerçekten çok acı vericiydi
Her dil için ayrı encoder/decoder yazmak gerekiyordu ve bakım da zordu
JSON ise yalnızca dizilere ve nesnelere eşlendiği için diller arası uyumluluğu çok yüksek
XML şeması tasarım toplantılarında zaman harcadığımız günleri düşününce, JSON API tasarımını Prettier’ın tab vs space tartışmasını bitirmesi gibi sadeleştirdi
Sonuçta çıkış noktası “karmaşık şeyler öğrenmek istemiyorum” tavrıydı, ama zaman geçince aynı özelliklere yeniden ihtiyaç duyuluyor
Polonya vergi idaresi XML’i seviyor
Ama onların XML’i insanın okuyamayacağı kadar anlaşılmaz
Alan adları
P_19Ngibi oluyor ve gerçek anlamı öğrenmek için şemaya bakmanız gerekiyorHatta yasa maddesi numaraları bile içine giriyor
İronik biçimde, KDV yasasını yazan kişi şu anda vergi danışmanlığı yapıyor
Ben de bizzat S-expression tabanlı bir DSL kullanıyorum
Bu, WebAssembly tabanlı bir masaüstü tarayıcı çalışma zamanında HTML ve CSS rolünü üstleniyor,
ayrıca belge eşzamanlama sorununu çözmek için kendi işaretleme dilimde de yeniden kullanıyorum
İlgili örnekler CanvasUI örnek kodunda, stil dosyasında ve dokümantasyon aracında görülebilir
Adayın kendi başına basit bir dili hayata geçirdiği andaki tepkisi etkileyiciydi
XML bir DSL’den çok genel amaçlı ayrıştırıcı/lexer aracıdır
Metni AST’ye dönüştürür; asıl DSL, bunun üzerinde tanımlanan belirtimdir
Çok özellikli ve karmaşıktır, ama araç ekosistemi zengindir
Elle yazmaktan çok, üretilmiş metinleri işlemek için uygundur
XSD şema doğrulaması yerleşik olduğu için belgenin tutarlılığını anında kontrol etmek mümkündür
Otomasyon araçları kullanmadan XML zor diye yakınmak, disassembler olmadan binary’lerle uğraşmaya benziyor
Ama şema doğrulaması tek başına içeriğin doğruluğunu garanti etmez
Bu, tip kontrolünün bir programın doğruluğunu garanti etmemesiyle aynı mantık
XSD yararlı ama karmaşık ve kısıtlayıcı
Bu yüzden bazı XML toplulukları RELAX-NG’ye geçti, ancak o da tamamen yerini alamadı
Hangi işlerin XSD doğrulamasını gerçekten zorunlu kıldığını merak ediyorum
XML, bir işaretleme dili olarak fena değil; veri değişim biçimi olarak da kullanılabilir, ama programlama dili olarak kullanıldığında korkunç
JSON da benzer şekilde veri değişimi için iyi, fakat dil olarak kullanırsanız pişman olursunuz
Ansible gibi YAML tabanlı diller bunun örneği
Buna karşılık Lisp’in S-expression yapısı, JSON’a benzer bir formdan çıkıp harika bir dil hâline geldi
XML’in sorunu XML’in kendisinden çok iyi XML üretmenin zor olması
Standart karmaşık, üreticiler de aynı şeyi farklı biçimlerde ifade ettiği için tutarlılık düşük
JSON’da bu standart sapma çok daha küçük
Finans kurumlarının XML’ine bakınca insanın umudu kırılıyor
XML’in sorunu sonuçta araçların yavaşlığı ve eksik doğrulayıcılar oldu
Veri gösteriminin karmaşıklığından çok, araç kalitesi daha büyük darboğazdı
Aslında mesele “iyi XML”den çok, berbat XML üretmenin fazla kolay olmasıydı
Bu yüzden topluluk ad alanları, doğrulama, dönüştürme, anlamsal web gibi yöntemlerle birlikte çalışabilirlik sağlamaya uğraştı
Mükemmel uzlaşının imkânsız olduğu ortamlarda işi sürdürebilmek için yapılan bir tavizdi