Re: [Chicken-users] Why does the JSON egg map JSON structs to Scheme vectors instead of alists?

2011-11-28 Thread Alan Post
On Sun, Nov 27, 2011 at 06:39:52PM +0100, Moritz Heidkamp wrote:
> Vok Vojwo  writes:
> > I think the Medea egg intends to do it the right way. But it seems to be 
> > buggy.
> >
> > And it has a voracious appetite
> 
> It does indeed :-)
> 
> 
> > Medea fails to parse the data:
> >
> > (use medea)
> > (read-json json) ;; => #f
> 
> Thanks for the hint. I managed to bisect it down to a Unicode character
> in one of the strings ("’"). Looking at medea's test suite I found this:
> 
> ;; (test-read '#("Дҫ") "[\"Дҫ\"]") ; FIXME genturfahi needs utf8 support for 
> that to work
> 
> So thanks for the reminder, I should mention this limitation in medea's
> documentation. Alan, would it be possible to make genturfahi UTF-8
> aware?
> 

Yes.  I will accomplish it over the hackathon weekend.  My first
attempt didn't go well, though it was because I was having trouble
getting basic UTF-like things working in Chicken at all.  I actually
have some of the required support ready to be checked in here in my
local repository.

-Alan
-- 
.i ma'a lo bradi cu penmi gi'e du

___
Chicken-users mailing list
Chicken-users@nongnu.org
https://lists.nongnu.org/mailman/listinfo/chicken-users


Re: [Chicken-users] Why does the JSON egg map JSON structs to Scheme vectors instead of alists?

2011-11-27 Thread Moritz Heidkamp
Moritz Heidkamp  writes:
> Thanks for the hint. I managed to bisect it down to a Unicode character
> in one of the strings ("’"). Looking at medea's test suite I found this:
>
> ;; (test-read '#("Дҫ") "[\"Дҫ\"]") ; FIXME genturfahi needs utf8 support for 
> that to work
>
> So thanks for the reminder, I should mention this limitation in medea's
> documentation. 

OK, the documentation mentions this now. Note by the way that Unicode
escape sequences (\u) work.

Moritz

___
Chicken-users mailing list
Chicken-users@nongnu.org
https://lists.nongnu.org/mailman/listinfo/chicken-users


Re: [Chicken-users] Why does the JSON egg map JSON structs to Scheme vectors instead of alists?

2011-11-27 Thread Moritz Heidkamp
Vok Vojwo  writes:
> I think the Medea egg intends to do it the right way. But it seems to be 
> buggy.
>
> And it has a voracious appetite

It does indeed :-)


> Medea fails to parse the data:
>
> (use medea)
> (read-json json) ;; => #f

Thanks for the hint. I managed to bisect it down to a Unicode character
in one of the strings ("’"). Looking at medea's test suite I found this:

;; (test-read '#("Дҫ") "[\"Дҫ\"]") ; FIXME genturfahi needs utf8 support for 
that to work

So thanks for the reminder, I should mention this limitation in medea's
documentation. Alan, would it be possible to make genturfahi UTF-8
aware?

Moritz

___
Chicken-users mailing list
Chicken-users@nongnu.org
https://lists.nongnu.org/mailman/listinfo/chicken-users


Re: [Chicken-users] Why does the JSON egg map JSON structs to Scheme vectors instead of alists?

2011-11-27 Thread Moritz Heidkamp
John Cowan  writes:
> They differ in their representation of JSON null, however: json-abnf
> uses 'null, whereas medea's default is ()

the other way around, actually :-)

Moritz

___
Chicken-users mailing list
Chicken-users@nongnu.org
https://lists.nongnu.org/mailman/listinfo/chicken-users


Re: [Chicken-users] Why does the JSON egg map JSON structs to Scheme vectors instead of alists?

2011-11-27 Thread John Cowan
Vok Vojwo scripsit:

> I am a bit confused by the way the JSON egg maps JSON structures to
> Scheme values.  [...]
> Is there any reason why the JSON egg creates vectors of pairs?

The problem is that JSON arrays and objects are disjoint, and the egg uses
lists to represent JSON arrays.  Since lists and a-lists are obviously
not disjoint, something else has to be done.

One alternative would be to represent JSON objects as a-lists and
JSON arrays as vectors.  This is the approach taken by the json-abnf
egg, and by the medea egg by default, although medea's representation
is customizable.  They differ in their representation of JSON null,
however: json-abnf uses 'null, whereas medea's default is (); the json
egg uses the undefined value.

I am going to be adding JSON support to my JSO egg when I can steal
a few cycles for it.  JSOs are specially marked a-lists that work
like JavaScript objects, so I will use them to represent JSON objects.
JSON null will be represented by a unique empty JSO.  I haven't yet settled
on the representation of JSON arrays; I might use specially marked JSOs,
or I might use lists (which would require the caller to test for arrays
before objects) or even vectors.

-- 
John Cowan  http://www.ccil.org/~cowan  co...@ccil.org
"After all, would you consider a man without honor wealthy, even if his
Dinar laid end to end would reach from here to the Temple of Toplat?"
"No, I wouldn't", the beggar replied.  "Why is that?" the Master asked.
"A Dinar doesn't go very far these days, Master.--Kehlog Albran
Besides, the Temple of Toplat is across the street."  The Profit

___
Chicken-users mailing list
Chicken-users@nongnu.org
https://lists.nongnu.org/mailman/listinfo/chicken-users


Re: [Chicken-users] Why does the JSON egg map JSON structs to Scheme vectors instead of alists?

2011-11-27 Thread Vok Vojwo
2011/11/27 Moritz Heidkamp :
>
> You may be interested in two alternative JSON eggs, namely json-abnf egg
> (GPLed) which represents both JSON objects as tagged lists alists
> (i.e. they have a symbol `object' their car) and arrays as vectors or
> the medea egg (BSD licensed) which uses alists for objects and vectors
> for arrays by default but can be parameterized to use whatever
> representation you prefer.

I think the Medea egg intends to do it the right way. But it seems to be buggy.

And it has a voracious appetite

; loading /usr/local/lib/chicken/6/chicken.import.so ...
; loading /usr/local/lib/chicken/6/data-structures.import.so ...
; loading /usr/local/lib/chicken/6/defstruct.so ...
; loading /usr/local/lib/chicken/6/extras.import.so ...
; loading /usr/local/lib/chicken/6/genturfahi.import.so ...
; loading /usr/local/lib/chicken/6/genturfahi-peg.so ...
; loading /usr/local/lib/chicken/6/genturfahi.so ...
; loading /usr/local/lib/chicken/6/irregex.import.so ...
; loading /usr/local/lib/chicken/6/iset.import.so ...
; loading /usr/local/lib/chicken/6/iset.so ...
; loading /usr/local/lib/chicken/6/lolevel.import.so ...
; loading /usr/local/lib/chicken/6/matchable.import.so ...
; loading /usr/local/lib/chicken/6/matchable.so ...
; loading /usr/local/lib/chicken/6/medea.import.so ...
; loading /usr/local/lib/chicken/6/medea.so ...
; loading /usr/local/lib/chicken/6/ports.import.so ...
; loading /usr/local/lib/chicken/6/posix.import.so ...
; loading /usr/local/lib/chicken/6/regex.import.so ...
; loading /usr/local/lib/chicken/6/regex.so ...
; loading /usr/local/lib/chicken/6/sandbox.so ...
; loading /usr/local/lib/chicken/6/scheme.import.so ...
; loading /usr/local/lib/chicken/6/srfi-13.import.so ...
; loading /usr/local/lib/chicken/6/srfi-14.import.so ...
; loading /usr/local/lib/chicken/6/srfi-18.import.so ...
; loading /usr/local/lib/chicken/6/srfi-1.import.so ...
; loading /usr/local/lib/chicken/6/srfi-4.import.so ...
; loading /usr/local/lib/chicken/6/srfi-69.import.so ...
; loading /usr/local/lib/chicken/6/unicode-char-sets.import.so ...
; loading /usr/local/lib/chicken/6/unicode-char-sets.so ...
; loading /usr/local/lib/chicken/6/utf8-case-map.import.so ...
; loading /usr/local/lib/chicken/6/utf8-case-map.so ...
; loading /usr/local/lib/chicken/6/utf8.import.so ...
; loading /usr/local/lib/chicken/6/utf8-lolevel.import.so ...
; loading /usr/local/lib/chicken/6/utf8-lolevel.so ...
; loading /usr/local/lib/chicken/6/utf8.so ...
; loading /usr/local/lib/chicken/6/utf8-srfi-13.import.so ...
; loading /usr/local/lib/chicken/6/utf8-srfi-13.so ...
; loading /usr/local/lib/chicken/6/utf8-srfi-14.import.so ...
; loading /usr/local/lib/chicken/6/utf8-srfi-14.so ...
; loading /usr/local/lib/chicken/6/vector-lib.import.so ...
; loading /usr/local/lib/chicken/6/vector-lib.so ...

compared to the Json egg:

; loading /usr/local/lib/chicken/6/json.import.so ...
; loading /usr/local/lib/chicken/6/scheme.import.so ...
; loading /usr/local/lib/chicken/6/chicken.import.so ...
; loading /usr/local/lib/chicken/6/ports.import.so ...
; loading /usr/local/lib/chicken/6/srfi-1.import.so ...
; loading /usr/local/lib/chicken/6/srfi-69.import.so ...
; loading /usr/local/lib/chicken/6/packrat.import.so ...
; loading /usr/local/lib/chicken/6/json.so ...
; loading /usr/local/lib/chicken/6/packrat.so ...

I am testing with Googles developer calendar:

(use http-client)
(define json
  (with-input-from-request
   
"http://www.google.com/calendar/feeds/developer-calen...@google.com/public/full?alt=json";
   #f read-string))

Medea fails to parse the data:

(use medea)
(read-json json) ;; => #f

Json works but it is quite slow:

(use json)
(time (begin (json-read (open-input-string json)) (if #f #f)))

0.228s CPU time, 0.12s GC time (major), 135063 mutations, 6/1835 GCs
(major/minor)
0.236s CPU time, 0.128s GC time (major), 135045 mutations, 6/1835 GCs
(major/minor)

compared to Json-abnf:

(use json-abnf)
(time (begin (parser json) (if #f #f)))

0.04s CPU time, 2380 mutations, 0/782 GCs (major/minor)
0.04s CPU time, 2398 mutations, 0/782 GCs (major/minor)

I am completely astonished that the performance difference is more
than 500%. Is this the typical packrat memorization penalty?

So in the end I have

- Medea which has the most useful data representation but does not work.
- Json which need the fewest number of modules, but which is slow and
produces strange pairs of vectors.
- Json-abnf which is the fastest but produces annoying object tags and
can not read from ports.

If it is possible to get rid of the object tags Json-abnf seems to be
the best choice right now.

___
Chicken-users mailing list
Chicken-users@nongnu.org
https://lists.nongnu.org/mailman/listinfo/chicken-users


Re: [Chicken-users] Why does the JSON egg map JSON structs to Scheme vectors instead of alists?

2011-11-27 Thread Moritz Heidkamp
Hi Vok,

Vok Vojwo  writes:
> I am a bit confused by the way the JSON egg maps JSON structures to
> Scheme values. The JSON egg maps a structure to a vector:
>
> (use json)
> (with-input-from-string "{\"pi\":3.14,\"e\":2.71}" json-read)
> ;; => #(("pi" . 3.14) ("e" . 2.71))

I agree, this is indeed a strange choice. My guess is that there is no
way to reliably detect whether a list is an alist or not. And since the
json egg maps lists to JSON arrays already, "avectors" were the only
choice left, it seems.

You may be interested in two alternative JSON eggs, namely json-abnf egg
(GPLed) which represents both JSON objects as tagged lists alists
(i.e. they have a symbol `object' their car) and arrays as vectors or
the medea egg (BSD licensed) which uses alists for objects and vectors
for arrays by default but can be parameterized to use whatever
representation you prefer.


Moritz

___
Chicken-users mailing list
Chicken-users@nongnu.org
https://lists.nongnu.org/mailman/listinfo/chicken-users


Re: [Chicken-users] Why does the JSON egg map JSON structs to Scheme vectors instead of alists?

2011-11-27 Thread Christian Kellermann
* Vok Vojwo  [27 14:37]:
> 2011/11/27 Christian Kellermann :
> >
> > My guess is that it makes it possible to write back to json, since
> > alists are already used for representing a different datatype.
> 
> But json-write does not accept alists as values. This
> 
> (json-write (vector (cons "x" (list (cons "a" 1) (cons "b" 2)
> 
> throws the following error:
> 
> Error: Invalid JSON object in json-write: ("a" . 1)

This is true. I mistook them for lists, which are already used.
Sorry for the noise.

-- 
Who can (make) the muddy water (clear)? Let it be still, and it will
gradually become clear. Who can secure the condition of rest? Let
movement go on, and the condition of rest will gradually arise.
 -- Lao Tse. 

___
Chicken-users mailing list
Chicken-users@nongnu.org
https://lists.nongnu.org/mailman/listinfo/chicken-users


Re: [Chicken-users] Why does the JSON egg map JSON structs to Scheme vectors instead of alists?

2011-11-27 Thread Daishi Kato
Even though I agree that it should be schemish,
it must be consistent.

How would you deal with
{"1":[2,3],"4":[5,6]}
and
[["1",2,3],["4",5,6]]
that must be distinguished?

Furthermore, if we were to change the spec of the json egg,
we should be aware with backward compatibility issues.
Otherwise, I need to change my all json-related code.

Best,
Daishi

At Sun, 27 Nov 2011 14:16:38 +0100,
Vok Vojwo wrote:
> 
> I am a bit confused by the way the JSON egg maps JSON structures to
> Scheme values. The JSON egg maps a structure to a vector:
> 
> (use json)
> (with-input-from-string "{\"pi\":3.14,\"e\":2.71}" json-read)
> ;; => #(("pi" . 3.14) ("e" . 2.71))
> 
> This makes it impossible to use the standard Scheme function assoc to
> read the data.
> 
> The following functions fix the problem:
> 
> (define (json->alist arg)
>   (cond
>((vector? arg)
> (map (lambda (pair)
>(cons (car pair) (json->alist (cdr pair
>  (vector->list arg)))
>((list? arg)
> (list->vector (map json->alist arg)))
>(else arg)))
> 
> (define (alist->json arg)
>   (cond
>((list? arg)
> (list->vector (map (lambda (pair)
>  (cons (car pair) (alist->json (cdr pair
>arg)))
>((vector? arg)
> (map alist->json (vector->list arg)))
>(else arg)))
> 
> A small verification test:
> 
> (use http-client)
> 
> (define (with-input-from-url url chunk)
>   (with-input-from-request url #f chunk))
> 
> (define json
>   (with-input-from-url
>
> "http://www.google.com/calendar/feeds/developer-calen...@google.com/public/full?alt=json";
>json-read))
> 
> (equal? json (alist->json (json->alist json)))
> ;; => #t
> 
> By using alists it is possible to use assoc to access the data:
> 
> (define (assoc* alist . path)
>   (let assoc* ((path path)
>(alist alist))
> (if (null? path)
> alist
> (assoc* (cdr path)
> (cdr (assoc (car path) alist))
> 
> (assoc* (json->alist json) "feed" "title" "$t")
> ;; => "Official Google External Developer Events"
> 
> Is there any reason why the JSON egg creates vectors of pairs?
> 
> If not I would suggest to fix it to make it more schemish.
> 
> ___
> Chicken-users mailing list
> Chicken-users@nongnu.org
> https://lists.nongnu.org/mailman/listinfo/chicken-users

___
Chicken-users mailing list
Chicken-users@nongnu.org
https://lists.nongnu.org/mailman/listinfo/chicken-users


Re: [Chicken-users] Why does the JSON egg map JSON structs to Scheme vectors instead of alists?

2011-11-27 Thread Vok Vojwo
2011/11/27 Christian Kellermann :
>
> My guess is that it makes it possible to write back to json, since
> alists are already used for representing a different datatype.

But json-write does not accept alists as values. This

(json-write (vector (cons "x" (list (cons "a" 1) (cons "b" 2)

throws the following error:

Error: Invalid JSON object in json-write: ("a" . 1)

___
Chicken-users mailing list
Chicken-users@nongnu.org
https://lists.nongnu.org/mailman/listinfo/chicken-users


Re: [Chicken-users] Why does the JSON egg map JSON structs to Scheme vectors instead of alists?

2011-11-27 Thread Christian Kellermann
* Vok Vojwo  [27 14:16]:
> (assoc* (json->alist json) "feed" "title" "$t")
> ;; => "Official Google External Developer Events"
> 
> Is there any reason why the JSON egg creates vectors of pairs?
> 
> If not I would suggest to fix it to make it more schemish.

I agree with you and I can only guess the original author's intentions.
My guess is that it makes it possible to write back to json, since
alists are already used for representing a different datatype.
Surely the choice could have been made in a more convenient way...

Kind regards,

Christian 

-- 
Who can (make) the muddy water (clear)? Let it be still, and it will
gradually become clear. Who can secure the condition of rest? Let
movement go on, and the condition of rest will gradually arise.
 -- Lao Tse. 

___
Chicken-users mailing list
Chicken-users@nongnu.org
https://lists.nongnu.org/mailman/listinfo/chicken-users


[Chicken-users] Why does the JSON egg map JSON structs to Scheme vectors instead of alists?

2011-11-27 Thread Vok Vojwo
I am a bit confused by the way the JSON egg maps JSON structures to
Scheme values. The JSON egg maps a structure to a vector:

(use json)
(with-input-from-string "{\"pi\":3.14,\"e\":2.71}" json-read)
;; => #(("pi" . 3.14) ("e" . 2.71))

This makes it impossible to use the standard Scheme function assoc to
read the data.

The following functions fix the problem:

(define (json->alist arg)
  (cond
   ((vector? arg)
(map (lambda (pair)
   (cons (car pair) (json->alist (cdr pair
 (vector->list arg)))
   ((list? arg)
(list->vector (map json->alist arg)))
   (else arg)))

(define (alist->json arg)
  (cond
   ((list? arg)
(list->vector (map (lambda (pair)
 (cons (car pair) (alist->json (cdr pair
   arg)))
   ((vector? arg)
(map alist->json (vector->list arg)))
   (else arg)))

A small verification test:

(use http-client)

(define (with-input-from-url url chunk)
  (with-input-from-request url #f chunk))

(define json
  (with-input-from-url
   
"http://www.google.com/calendar/feeds/developer-calen...@google.com/public/full?alt=json";
   json-read))

(equal? json (alist->json (json->alist json)))
;; => #t

By using alists it is possible to use assoc to access the data:

(define (assoc* alist . path)
  (let assoc* ((path path)
   (alist alist))
(if (null? path)
alist
(assoc* (cdr path)
(cdr (assoc (car path) alist))

(assoc* (json->alist json) "feed" "title" "$t")
;; => "Official Google External Developer Events"

Is there any reason why the JSON egg creates vectors of pairs?

If not I would suggest to fix it to make it more schemish.

___
Chicken-users mailing list
Chicken-users@nongnu.org
https://lists.nongnu.org/mailman/listinfo/chicken-users