Re: cannot compile: srfi-10 define-reader-ctor 'hash '#,(

2014-08-14 Thread Panicz Maciej Godek
2014-08-13 21:59 GMT+02:00 Jan Nieuwenhuizen jann...@gnu.org:
 Ludovic Courtès writes:

 The problem is that SRFI-10 itself does not specify an external
 representation for hash tables, nor does Guile.  Thus this patch cannot
 be applied.

 Yes, I understand that...Still, wouldn't it be nice if Scheme/Guile
 had something that javascript has, in JSON hash tables are simply

{key0: value, key1: value}

I have been thinking about that issue a lot, and concluded that it
wouldn't be the Scheme way.
Scheme already has a nice representation for associactions, namely the
assoc lists. However, they are a bit problematic, because they are
ordered by nature and hence there's not much one can do with their
linear access time.

The proper solution, I believe, is to provide some means to create
unordered collections (i.e. sets or multisets). Some hints for
constructing such collections were given by Daniel Friedman and
reminded recently (like 10 years ago ;]) in Guy Steele's talk for
Friedman's 60th birthday:
http://www.youtube.com/watch?v=IHP7P_HlcBk

After that, a paper came out which described that idea in greater detail:
http://projects.csail.mit.edu/wiki/pub/JoeNear/FernMonad/frons.pdf

Anyway, I think it would be nice to provide a notation for unordered
collections in Scheme, so that the associations, written as '{(key .
value) ...}, could eventually be optimized and perhaps implemented as
hash tables internally in some cases.



Re: cannot compile: srfi-10 define-reader-ctor 'hash '#,(

2014-08-14 Thread Marko Rauhamaa
Panicz Maciej Godek godek.mac...@gmail.com:

 Scheme already has a nice representation for associactions, namely the
 assoc lists. However, they are a bit problematic, because they are
 ordered by nature and hence there's not much one can do with their
 linear access time.

When we are talking about the representation of a mapping, it will be a
full content dump, thus O(n) regardless. You don't gain anything by
adding substructure to the assoc list.

When you read in the collection, you can put it in the data structure of
your choice (with alist-hash-table, for example).

Sexps are perfectly suitable to represent any imaginable data.

Circular sexps create funny effects in guile, though. Try inputting

   '(1 . #0#) 

to the (guile-1.8) reader.

Unfortunately, even

   (define a '(1 . #0#))

fails to finish.

Compare this with elisp, which is perfectly happy with:

   (setq a '#0=(1 . #0#))


Marko



Re: cannot compile: srfi-10 define-reader-ctor 'hash '#,(

2014-08-14 Thread Taylan Ulrich Bayirli/Kammer
Neil Jerram n...@ossau.homelinux.net writes:

 I wonder about possibly having some magic that would automatically
 match certain top-level forms and evaluate them at compile time.  The
 case for this for 'define-reader-ctor' feels quite strong.  For the
 load path case, it feels too hacky to try to recognize patterns like
 (set! %load-path (append %load-path ...))', but perhaps OK if we
 defined an 'add-to-load-path' procedure and applied the magic to that.

We already have an 'add-to-load-path' syntax.  That way it doesn't need
any special magic since it can just expand to an `eval-when' usage but
apparently for some reason it doesn't do that at the moment (2.0.11):

scheme@(guile-user) ,expand (add-to-load-path foo)
(set! (@@ (guile) %load-path)
  ((@@ (guile) cons) foo (@@ (guile) %load-path)))

Taylan



Re: cannot compile: srfi-10 define-reader-ctor 'hash '#,(

2014-08-14 Thread Panicz Maciej Godek
2014-08-14 11:53 GMT+02:00 Marko Rauhamaa ma...@pacujo.net:
 Scheme already has a nice representation for associactions, namely the
 assoc lists. However, they are a bit problematic, because they are
 ordered by nature and hence there's not much one can do with their
 linear access time.

 When we are talking about the representation of a mapping, it will be a
 full content dump, thus O(n) regardless. You don't gain anything by
 adding substructure to the assoc list.

We're talking about access time, so in this particular case -- about
assoc-ref and the like; not about printing. And about having an
efficient representation for sets, because obviously sets can be
represented using lists as well, although inefficiently.

 When you read in the collection, you can put it in the data structure of
 your choice (with alist-hash-table, for example).

Of course I can. But that isn't something that I wish to do. It simply
adds another layer of indirection, which is irrelevant to programmer's
intention. Using dictionaries is programmers' daily bread, yet Scheme
has no common way for doing that (unlike Perl, PHP, Python,
JavaScript, Clojure and other popular languages).



Re: cannot compile: srfi-10 define-reader-ctor 'hash '#,(

2014-08-14 Thread Panicz Maciej Godek
2014-08-14 12:36 GMT+02:00 Marko Rauhamaa ma...@pacujo.net:
 Panicz Maciej Godek godek.mac...@gmail.com:

 Using dictionaries is programmers' daily bread, yet Scheme has no
 common way for doing that (unlike Perl, PHP, Python, JavaScript,
 Clojure and other popular languages).

 I disagree. S-expressions far surpass whatever the others have to offer.

You disagree on which point exactly?
- that using dictionaries is programmers' daily bread?
- that Perl, PHP, Python, JavaScript, Clojure and other popular
languages offer a common way for using dictionaries? or
- that Scheme has no common way for using dictionaries?



Re: cannot compile: srfi-10 define-reader-ctor 'hash '#,(

2014-08-14 Thread Taylan Ulrich Bayirli/Kammer
Marko Rauhamaa ma...@pacujo.net writes:

 Panicz Maciej Godek godek.mac...@gmail.com:

 Using dictionaries is programmers' daily bread, yet Scheme has no
 common way for doing that (unlike Perl, PHP, Python, JavaScript,
 Clojure and other popular languages).

 I disagree. S-expressions far surpass whatever the others have to offer.


 Marko

To be fair, when your read syntax makes dictionaries explicit, you get
an additional bit of safety in your program because if you receive a
dictionary where a list was expected then the list-ref will error and
make the problem surface, whereas if you get an alist you can list-ref
it and have the program keep running a bit farther (maybe to the end,
producing wrong output).

(I've been bitten by this in PHP once where associative arrays are also
just arrays and some stupid web interface delivered me a single assoc
array where it should have delivered an array with one assoc array in
it.)

On the other hand, if you just implement full validation which walks
your input and turns all expected alists into suitable record types
(think DTD) then it's about equally safe either way I guess.  That is
the ideal long-term solution, validating most of your input as soon as
it's received, and preventing silly mistakes like typos in alist keys
because instead you use accessor procedures on records.

All in all, having to use alists for hash tables can be an annoyance
when you don't use eager input validation; it forces you to use extra
alist-hash-table and hash-table-alist calls where you could otherwise
just read and write an object if all it contains is lists, vectors, and
hash tables, and it can cause some bugs to remain hidden for longer.

Taylan



Re: cannot compile: srfi-10 define-reader-ctor 'hash '#,(

2014-08-14 Thread Marko Rauhamaa
Panicz Maciej Godek godek.mac...@gmail.com:

 I disagree. S-expressions far surpass whatever the others have to offer.

 You disagree on which point exactly?
 - that using dictionaries is programmers' daily bread?

No, we are talking about the external representation of hash tables. I'm
saying the alist format is sufficient to communicate the abstract
contents of hash tables or any other mapping. You don't need any new
representation format for hash tables -- or I can't think of a use case.


Marko



Re: cannot compile: srfi-10 define-reader-ctor 'hash '#,(

2014-08-14 Thread Marko Rauhamaa
Taylan Ulrich Bayirli/Kammer taylanbayi...@gmail.com:

 To be fair, when your read syntax makes dictionaries explicit, you get
 an additional bit of safety [...]
 (I've been bitten by this [...]

 On the other hand, if you just implement full validation [...]

Yes, validation is a much more generic issue that can be used for all
kinds of bounds-checks and interrelationships.

On the other hand, I wouldn't put too much emphasis into validation (as
in, none at all). For example, I have customized emacs with all kinds of
lisp data structures. None of those data structures are validated by the
respective emacs modules; they are simply obeyed. Typos create errors
and misbehaviors -- so I must fix them, simple as that.

 All in all, having to use alists for hash tables can be an annoyance
 when you don't use eager input validation; it forces you to use extra
 alist-hash-table and hash-table-alist calls where you could
 otherwise just read and write an object if all it contains is lists,
 vectors, and hash tables, and it can cause some bugs to remain hidden
 for longer.

A hash table is an optimized, internal lookup object. It is not a
meaningful representation format. An AVL tree and a hash table should
have identical external representations in almost all cases. Thus, my
implementation would have to make the translation on input anyway.


Marko


PS Speaking of AVL trees, my AVL tree implementation is bitten by the
apparent lack of a numeric object identifier in guile. Python has the
id() function that can be used to sort interned objects effectively. In
guile, I have to use

   (lambda (sym1 sym2)
 (string (symbol-string sym1)
  (symbol-string sym2)))

instead of something like:

   (lambda (sym1 sym2)
 ( (id sym1)
(id sym2)))

or even:

   below?

(in analogy with eq?).


Marko



Re: cannot compile: srfi-10 define-reader-ctor 'hash '#,(

2014-08-14 Thread Panicz Maciej Godek
2014-08-14 14:59 GMT+02:00 Marko Rauhamaa ma...@pacujo.net:
 Panicz Maciej Godek godek.mac...@gmail.com:

 I disagree. S-expressions far surpass whatever the others have to offer.

 You disagree on which point exactly?
 - that using dictionaries is programmers' daily bread?

 No, we are talking about the external representation of hash tables. I'm
 saying the alist format is sufficient to communicate the abstract
 contents of hash tables or any other mapping. You don't need any new
 representation format for hash tables -- or I can't think of a use case.

I agree that it is sufficient. It's just that it isn't handy.
It's more succinct to write

x = {a : 5, b : 10} ...

or

(let ((x '{(a . 5)(b . 10)}))
  ...)

or

(let ((x '((a . 5)(b . 10
  ...)

than

(let ((x (alist-hash-table '((a . 5)(b . 10)
  ...)

Also, there's less that you (as a programmer) need to memoize, because
otherwise you'd need to check the documentation if it's
alist-hash-table or alist-hash-map or something else. Furthermore,
using alist-hash-table and hash-table-alist adds no value to your
program -- it's there only to optimize lookups, compared to assoc-ref
and assoc-set!, and essentialy has no impact on the semantics of your
program.

(however, weak hash-tables are an exception, because they represent a
concept that wouldn't otherwise be representable using alists)



Re: cannot compile: srfi-10 define-reader-ctor 'hash '#,(

2014-08-14 Thread Marko Rauhamaa
Taylan Ulrich Bayirli/Kammer taylanbayi...@gmail.com:

 Though when I think of it, often I would be fine with O(n) too and could
 use alists in my code to begin with.

Yes. In my recent tests, I found (assq-ref) was twice as fast as
(hashq-ref) when there were 100 entries even when I made the hash table
quite large (1000 entries IIRC).

 There is (pointer-address (object-pointer obj)) if that helps.
 (Nonstandard Scheme of course.)

Thanks for the tip. Unfortunately, I couldn't locate those on my guile
installation.


Marko



Re: cannot compile: srfi-10 define-reader-ctor 'hash '#,(

2014-08-14 Thread Taylan Ulrich Bayirli/Kammer
Marko Rauhamaa ma...@pacujo.net writes:

 Yes. In my recent tests, I found (assq-ref) was twice as fast as
 (hashq-ref) when there were 100 entries even when I made the hash
 table quite large (1000 entries IIRC).

Do you mean the averages?  For me, accessing the *first* entry of an
alist already seems to be almost as slow as accessing any entry of a
hash table, and accessing the 100th about thrice as slow.

 I couldn't locate those on my guile installation.

They're in (system foreign).

You can hit 'i' in GNU Info to find a variable or other keyword, though
I just had to notice that the intro node on the FFI, (guile) Foreign
Function Interface, doesn't mention (system foreign).  Our manual seems
to generally lack in telling the user what module needs to be loaded for
what...

Taylan



Re: cannot compile: srfi-10 define-reader-ctor 'hash '#,(

2014-08-14 Thread Marko Rauhamaa
Taylan Ulrich Bayirli/Kammer taylanbayi...@gmail.com:

 Marko Rauhamaa ma...@pacujo.net writes:

 Yes. In my recent tests, I found (assq-ref) was twice as fast as
 (hashq-ref) when there were 100 entries even when I made the hash
 table quite large (1000 entries IIRC).

 Do you mean the averages?

I was looking for the 50th entry.

 For me, accessing the *first* entry of an alist already seems to be
 almost as slow as accessing any entry of a hash table, and accessing
 the 100th about thrice as slow.

Ok. I ran the test again, with a couple of parameter settings this time
round:

   ===
   Data Structure# Entries   Look-up Duration (µs)
   ===
   hash-table   2000   0.37
   alist2000   5.88
   AVL tree 2000  15.65
   hash-table100   0.35
   alist 100   0.31
   AVL tree  100  11.09
   ===

The entry that was looked up was the middle element. The lookup was
performed 1,000,000 times. The AVL tree was wholly implemented in
scheme.

So the alist wasn't twice as fast. Must have been with fewer entries.


Marko



Re: cannot compile: srfi-10 define-reader-ctor 'hash '#,(

2014-08-14 Thread Neil Jerram

On 2014-08-14 11:27, Taylan Ulrich Bayirli/Kammer wrote:

Neil Jerram n...@ossau.homelinux.net writes:


I wonder about possibly having some magic that would automatically
match certain top-level forms and evaluate them at compile time.  The
case for this for 'define-reader-ctor' feels quite strong.  For the
load path case, it feels too hacky to try to recognize patterns like
(set! %load-path (append %load-path ...))', but perhaps OK if we
defined an 'add-to-load-path' procedure and applied the magic to that.



We already have an 'add-to-load-path' syntax.  That way it doesn't need
any special magic since it can just expand to an `eval-when' usage


Ah, good, thanks for pointing that out.


but
apparently for some reason it doesn't do that at the moment (2.0.11):

scheme@(guile-user) ,expand (add-to-load-path foo)
(set! (@@ (guile) %load-path)
  ((@@ (guile) cons) foo (@@ (guile) %load-path)))

Taylan


I'm not sure what that demonstrates.  add-to-load-path _does_ appear to 
work for me as hoped (and documented) when used in a situation like that 
of the recent ossaulib thread - i.e. where a top level script wants to 
extend the load path and then load modules from there:


---ctest.scm
(define-module (ctest)
  #:export (square))

(define (square x) (* x x))
---ctest.scm

---ctst.scm
(add-to-load-path /home/neil)
(use-modules (ctest))
(display (square 5))
(newline)
---ctst.scm


neil@nj-debian-7:~$ guile -s ctst.scm
;;; note: auto-compilation is enabled, set GUILE_AUTO_COMPILE=0
;;;   or pass the --no-auto-compile argument to disable.
;;; compiling /home/neil/ctst.scm
;;; compiling /home/neil/ctest.scm
;;; compiled 
/home/neil/.cache/guile/ccache/2.0-LE-8-2.0/home/neil/ctest.scm.go
;;; compiled 
/home/neil/.cache/guile/ccache/2.0-LE-8-2.0/home/neil/ctst.scm.go

25

Regards,
 Neil




Re: cannot compile: srfi-10 define-reader-ctor 'hash '#,(

2014-08-14 Thread Taylan Ulrich Bayirli/Kammer
Neil Jerram n...@ossau.homelinux.net writes:

 I'm not sure what that demonstrates.  add-to-load-path _does_ appear
 to work for me as hoped (and documented) when used in a situation like
 that of the recent ossaulib thread - i.e. where a top level script
 wants to extend the load path and then load modules from there:

Never mind, 'eval-when' is a macro too of course so ',expand' makes it
disappear.

Taylan