Hello Aleix, Aleix Conchillo Flaqué writes: > On Sun, Dec 9, 2018 at 10:33 PM Aleix Conchillo Flaqué > wrote: >> >> On Sun, Dec 9, 2018 at 2:56 AM Aleix Conchillo Flaqué >> wrote: >> > >> > Hi guilers, >> > >> > a new guile-json issue came to me recently: >> > >> > https://github.com/aconchillo/guile-json/issues/22 >> > >> > I don't really have a solution yet on how to solve this, so I would >> > love some advice. The issue is that one can do: >> > >> > (scm->json '(1 2 3)) which returns [1,2,3] >> > >> > however, if you do: >> > >> > (scm->json '((1 2 3)) it returns {"1":[2,3]} but one would probably >> > expect [[1,2,3]] >> > (scm->json '((1 2 3) (4 5 6)) it returns {"1":[2,3], "4":[5,6]} but >> > one would probably expect [[1,2,3], [4,5,6]] >> > >> > I guess the first question is, does everyone else feel the same way >> > about the return value? >> > >> > The problem is that there's a function that checks if something is an >> > alist by basically checking if it's a pair? recursively and if so, it >> > builds a json object. >> > >> >> Just to clarify, the problem is not when parsing JSON to scheme data >> types, this is fine as internally guile-json uses hash tables and >> lists properly. >> >> The problem is with going from scheme to json. For convenience, >> guile-json doesn't expect a hash table from the user, instead it tries >> to guess what's a list and what's an alist however, that seems not >> really distinguishable. That is, there's no way to tell if '((1 2)) is >> [[1, 2]] or {"1" : [2]} or {"1" : "2"}. >> >> I guess going back to a macro approach for these type of cases would >> help (even though I had the same problem with my initial macro). >> > > Answering myself again. Re-adding the macro fixes the issue, but with > a breaking change. > > (scm->json '(1 2 3)) > -> [1,2,3] > > (scm->json '((1 2 3) (4 5 6))) > -> [[1,2,3],[4,5,6]] > > (scm->json (json (object ("key1" "value1") ("key2" (1 2 3))))) > -> {"key2":[1,2,3],"key1":"value1"} > > (scm->json `((1 2 3) ,(json (object (4 5))))) > -> [[1,2,3],{"4":5}] > > So, the (json) macro is only needed to specify JSON objects, otherwise > you can use scheme types directly (and lists are always arrays). > Another ambuiguity would be that both [] and {} corresponds to (). It seems to me that the core of this problem is that the Pair, List and Alist (which is a List of Pairs) types in scheme are not orthogonal, i.e. () are both List and Alist, and (1 2 3) are both List and Pair. Therefore, one fix would be to make Vector instead of List to corresponds to Json Array, but maybe this change will cause too much breakage, so I am not sure it is practical. Another way would be to make some other type other than Alist to corresponds to Json Object. If we were in Clojure, it would be Hash Map. I think VHash is a good candidate, but I am not happy with it not having a read/write syntax (Hash Table has the same problem too) which makes it not as flexible as Alist. (Actually, I had been trying to write a reader macro for VHash (w/ or w/o the Guile Reader library) but I didn't succeed in doing so because of my limited knowledge in how lexing works in Guile.) > Aleix Cheers, Alex