From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Panicz Maciej Godek Newsgroups: gmane.lisp.guile.user Subject: Re: guile-json 0.2.0 released Date: Thu, 4 Apr 2013 14:06:50 +0200 Message-ID: References: <871uaqha98.fsf@taylan.dyndns.org> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: multipart/alternative; boundary=f46d044402823b4acd04d987ce8a X-Trace: ger.gmane.org 1365077239 6622 80.91.229.3 (4 Apr 2013 12:07:19 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Thu, 4 Apr 2013 12:07:19 +0000 (UTC) Cc: guile-user To: "Taylan Ulrich B." Original-X-From: guile-user-bounces+guile-user=m.gmane.org@gnu.org Thu Apr 04 14:07:45 2013 Return-path: Envelope-to: guile-user@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1UNixD-0004lR-H0 for guile-user@m.gmane.org; Thu, 04 Apr 2013 14:07:43 +0200 Original-Received: from localhost ([::1]:50301 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UNiwo-0007uh-Jc for guile-user@m.gmane.org; Thu, 04 Apr 2013 08:07:18 -0400 Original-Received: from eggs.gnu.org ([208.118.235.92]:35048) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UNiwS-0007jS-PJ for guile-user@gnu.org; Thu, 04 Apr 2013 08:07:02 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1UNiwO-0006Zf-QZ for guile-user@gnu.org; Thu, 04 Apr 2013 08:06:56 -0400 Original-Received: from mail-wg0-f48.google.com ([74.125.82.48]:55646) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UNiwO-0006ZR-5u for guile-user@gnu.org; Thu, 04 Apr 2013 08:06:52 -0400 Original-Received: by mail-wg0-f48.google.com with SMTP id m15so2634373wgh.27 for ; Thu, 04 Apr 2013 05:06:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:x-received:in-reply-to:references:date:message-id :subject:from:to:cc:content-type; bh=0GMT1q6onJZGTm6J156JuOz6D5qXD2t4RcocT9wRba8=; b=k9MeCwEFg9hZKHmXzwM6cwxnbmyLJ0hYmV5TH9xkL+Cn5NDKoo3fbmEwYDSTG3T2fv KmHF/62vP9uLVhrDn1SdRWGGrayO6tgvERLBdem+IfaGl60fRSij1+AMwSJg+Dk5PhF5 b1Z7H+rBw8wQC30x32cpChi0rmEb1wFLaxQUb961YInUO2hr45MBRVfgVwUiPz397r77 HtwGXsvkam+pNUDspuQJ/sjkcxTv+R6Up1JC6qH40/x1MK/io9ovcU3K0Kc/ooWu9LAI DJGOHnj6qi5/bmB6BfYxa/XOL7yh63l/feN6fKhAzq6RRm6fTgf26HVuHVcxHq+1r+YH vNJA== X-Received: by 10.180.87.97 with SMTP id w1mr3069675wiz.2.1365077210645; Thu, 04 Apr 2013 05:06:50 -0700 (PDT) Original-Received: by 10.194.60.100 with HTTP; Thu, 4 Apr 2013 05:06:50 -0700 (PDT) In-Reply-To: <871uaqha98.fsf@taylan.dyndns.org> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 74.125.82.48 X-BeenThere: guile-user@gnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: General Guile related discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guile-user-bounces+guile-user=m.gmane.org@gnu.org Original-Sender: guile-user-bounces+guile-user=m.gmane.org@gnu.org Xref: news.gmane.org gmane.lisp.guile.user:10230 Archived-At: --f46d044402823b4acd04d987ce8a Content-Type: text/plain; charset=ISO-8859-1 2013/4/4 Taylan Ulrich B. > Panicz Maciej Godek writes: > > > - firstly, guile's hash tables are maps, not dictionaries, so they are > > insensitive to order. This behaviour is desired if we want to use them > > to represent sets or maps; however, PHP arrays, and -- as I presume -- > > JavaScript objects -- store the information about the order of their > > elements. Lisp-style sollution would be to store them as assoc lists, > > which in turn have linear access time. > > From json.org (which is official): > "An object is an unordered set of name/value pairs." > > (Object means dictionary/map in JSON terminology.) > > I think this is consistent with common expectations from a dictionary > data structure. At least in my experience. Should the ordering be > important, a supplementary key-vector (or list) could be used easily > enough in my opinion; bundling that functionality into hash-tables is > probably not worth it unless it is trivial to implement. Well, I see why the representation based on hash tables is adequate for JSON. There are, however, situations, when one wants to have an ordered set, and it's good to have choice. Clojure, for instance, offers such choice, and from the perspective of a programmer it's better to have a choice. > > - secondly, there is no default notation to create hash tables nor > > sets; using them forces > > a programmer to drop homoiconicity, as their default print > > representation is # or something even uglier. > > I think that this is done properly in Clojure. > > That is not what homoiconicity means. There are more data types that > lack a proper external representation; most notably procedures. For > transmission of data, converting to an alist and back is probably good > enough; this can also be used as a "hack" for having "literal" > dictionaries in code: (alist->dictionary '(...)) > > Of course it can. However it's not convenient. I use emacs+geiser and when I want to see the content of a variable -- if it's a list or some other basic type -- I just point a cursor on it and I get the value in a minibuffer. When I want to see the content of hash-table, I need to explicitly evaluate (hash-map->list cons my-hash-table), which seems unnecessary When a hash-table is nested, it turns into a nightmare. If there was a more reader-friendly representation of hashes, it would be far more convenient. I could come up with some representation myself, and use it in my programs, but I guess that this problem is more serious and requires more attention. All in all, you don't write vector->list and list->vector to get a nice printable representation of vectors -- there was an issue, and it has been solved. Racket has its printable representation of hashes, which is much nicer than the one of guile (although still not perfect). So again, this is probably nothing that needs be implemented urgently. Judging by the speed at which subsequent Reports on algorithmic language Scheme are released, schemers don't seem know the word "urgent" :) Which is good. However, I think it is an important matter. I also think that it is no good for scheme implementations to diverge from one another, if there is no good reason for that. Note that easy-to-use hash tables are what win the market for PHP, despite many drawbacks of that language. > - thirdly, refering to hashes (as well as assoc lists, goops' object > > slots, vector/array elements) is truly cumbersome. I once wrote a > > hash-read-extension that allowed to refer to hashes/arrays/slots... > > using uniform notation #[object key], and to allow for nested > > references like #[ ... #[#[object key1] key2 ] ... ] using simpified > > notation #[object : key1 : key2 : ... ]. The implementation is rather > > inefficient when it comes to performance, but makes coding much more > > efficient, and it can be found here, if anyone's interested: > > > https://bitbucket.org/panicz/slayer/src/33cf0116da95dea6928ab1011994569b5a5181ad/extra/ref > . > > scm?at=goose-3d > > One could ask: why can't vectors, arrays, objects and hashes simply be > > applicable? (Of course, it is possible to implement applicable > > collections even now, but at a cost of loosing their print > > representation) > > SRFI-105 is probably the preferable solution to this problem, since it's > an SRFI. Guile already supports it, but I don't know how many accessors > are built-in; it should be trivial to implement any you want though. > > I know of no other implementation of Scheme than Guile which supports SRFI-105. And I guess that the implementators will remain reluctant with regard to it, as it introduces more randomness to the way the code can be written. On the other hand, what are the argumets against making hash-tables, vectors et al. applicable, assuming that "programming languages should be designed not by piling feature on top of feature, but by removing the weaknesses and restrictions that make additional features appear necessary"? > - lastly, guile's support for hash tables is limited -- there ain't > > even a built-in function that would return the size of a hash-table. > > My implementation is inefficient (linear time), and it looks like > > this: > > (define (hash-size hash-map) > > (length (hash-values hash-map))) > > I don't know how exactly hash-tables are implemented in Guile, but one > probably needs to walk through the whole structure to count the size; > then the most efficient simple implementation of `hash-size' is one > which walks through it only once: > > (hash-fold (lambda (key value size) (1+ size)) 0 hash-table) > > Other than that, the size could be kept in the internal representation > of the hash-table, but I'm not sure of the pay-offs. > > Plainly, the size is kept in the internal representation of the hash table: typedef struct scm_t_hashtable { unsigned long n_items; /* number of items in table */ ... cf. http://git.savannah.gnu.org/gitweb/?p=guile.git;a=blob;f=libguile/hashtab.h;h=82ed22e66eb1f5045793cfc55cca0be040d4aab1;hb=HEAD#l66 It would be really cheap&easy to get it from there. I just wanted to show that hash-tables are neglected in Scheme in general, and in Guile in particular. Best regards! M. --f46d044402823b4acd04d987ce8a Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable

= 2013/4/4 Taylan Ulrich B. <taylanbayirli@gmail.com>
Panicz Maciej Godek <godek.maciek@gmail.com> writes:

> - firstly, guile's hash tables are maps, not dictionaries, so they= are
> insensitive to order. This behaviour is desired if we want to use them=
> to represent sets or maps; however, PHP arrays, and -- as I presume --=
> JavaScript objects -- store the information about the order of their > elements. Lisp-style sollution would be to store them as assoc lists,<= br> > which in turn have linear access time.

From json.org (whic= h is official):
"An object is an unordered set of name/value pairs."

(Object means dictionary/map in JSON terminology.)

I think this is consistent with common expectations from a dictionary
data structure. =A0At least in my experience. =A0Should the ordering be
important, a supplementary key-vector (or list) could be used easily
enough in my opinion; bundling that functionality into hash-tables is
probably not worth it unless it is trivial to implement.
<= br>
Well, I see why the representation based on hash tables= is adequate for JSON. There are, however, situations, when one wants to ha= ve an ordered set, and it's good to have choice. Clojure, for instance,= offers such choice, and from the perspective of a programmer it's bett= er to have a choice.
=A0
> - secondly, there is no default notation to create hash tables nor
> sets; using them forces
> a programmer to drop homoiconicity, as their default print
> representation is #<hash-table 1c8a940 1/31> or something even u= glier.
> I think that this is done properly in Clojure.

That is not what homoiconicity means. =A0There are more data types th= at
lack a proper external representation; most notably procedures. =A0For
transmission of data, converting to an alist and back is probably good
enough; this can also be used as a "hack" for having "litera= l"
dictionaries in code: (alist->dictionary '(...))

Of course it can. However it's not convenie= nt. I use emacs+geiser and when I want to see the content of a variable -- = if it's a list or some other basic type -- I just point a cursor on it = and I get the value in a minibuffer. When I want to see the content of hash= -table, I need to explicitly evaluate (hash-map->list cons my-hash-table= ), which seems unnecessary When a hash-table is nested, it turns into a nig= htmare. If there was a more reader-friendly representation of hashes, it wo= uld be far more convenient. I could come up with some representation myself= , and use it in my programs, but I guess that this problem is more serious = and requires more attention.

All in all, you don't write vector->= list and list->vector to get a nice printable representation of vectors = -- there was an issue, and it has been solved. Racket has its printable rep= resentation of hashes, which is much nicer than the one of guile (although = still not perfect).

So again, this is probably nothing that needs be implemented urgently.
=A0
Judging by the speed at which subsequent R= eports on algorithmic language Scheme are released, schemers don't seem= know the word "urgent" :) Which is good.
However, I think it is an important matter. I also think that it= is no good for scheme implementations to diverge from one another, if ther= e is no good reason for that.
=A0
Note that easy-= to-use hash tables are what win the market for PHP, despite many drawbacks = of that language.

> - thirdly, refering to hashes (as well as assoc lists, goops' obje= ct
> slots, vector/array elements) is truly cumbersome. I once wrote a
> hash-read-extension that allowed to refer to hashes/arrays/slots... > using uniform notation #[object key], and to allow for nested
> references like #[ ... #[#[object key1] key2 ] ... ] using simpified > notation #[object : key1 : key2 : ... ]. The implementation is rather<= br> > inefficient when it comes to performance, but makes coding much more > efficient, and it can be found here, if anyone's interested:
> https://bitbucket.org/pa= nicz/slayer/src/33cf0116da95dea6928ab1011994569b5a5181ad/extra/ref.
> scm?at=3Dgoose-3d
> One could ask: why can't vectors, arrays, objects and hashes simpl= y be
> applicable? (Of course, it is possible to implement applicable
> collections even now, but at a cost of loosing their print
> representation)

SRFI-105 is probably the preferable solution to this problem, since i= t's
an SRFI. =A0Guile already supports it, but I don't know how many access= ors
are built-in; it should be trivial to implement any you want though.

I know of no other impl= ementation of Scheme than Guile which supports SRFI-105. And I guess that t= he implementators will remain reluctant with regard to it, as it introduces= more randomness to the way the code can be written.
On the other hand, what are the argumets against making hash-tab= les, vectors et al. applicable, assuming that "programming languages should be designed not by pil= ing feature on top of feature, but by removing the weaknesses and restricti= ons that make additional features appear necessary"?

> - lastly, guile's support for hash tables is limited -- there ain&= #39;t
> even a built-in function that would return the size of a hash-table. > My implementation is inefficient (linear time), and it looks like
> this:
> (define (hash-size hash-map)
> (length (hash-values hash-map)))

I don't know how exactly hash-tables are implemented in Guile, bu= t one
probably needs to walk through the whole structure to count the size;
then the most efficient simple implementation of `hash-size' is one
which walks through it only once:

(hash-fold (lambda (key value size) (1+ size)) 0 hash-table)

Other than that, the size could be kept in the internal representation
of the hash-table, but I'm not sure of the pay-offs.

Plainly, the size is kept in the internal representation of th= e hash table:

typedef=A0struct=A0scm_t_hashtable=A0{
unsigned=A0long=A0n_ite= ms;=A0=A0=A0=A0=A0=A0=A0=A0/*=A0number=A0of=A0items=A0in=A0table=A0*/
=
...

cf.=A0http://git.savannah.gnu.org= /gitweb/?p=3Dguile.git;a=3Dblob;f=3Dlibguile/hashtab.h;h=3D82ed22e66eb1f504= 5793cfc55cca0be040d4aab1;hb=3DHEAD#l66

It would be really cheap&easy to get it from there. I just wanted to s= how that hash-tables are neglected in Scheme in general, and in Guile in pa= rticular.

Best regards!
M.
--f46d044402823b4acd04d987ce8a--