unofficial mirror of guile-user@gnu.org 
 help / color / mirror / Atom feed
* Weird behavior of hash-table
@ 2019-11-23 22:39 Zelphir Kaltstahl
  2019-11-24  8:04 ` Mark H Weaver
  0 siblings, 1 reply; 9+ messages in thread
From: Zelphir Kaltstahl @ 2019-11-23 22:39 UTC (permalink / raw)
  To: Guile User

Hi Guile Users!

I've noticed a strange behavior of hash tables. I put in symbols as keys
and integers as values, but when I try to get the integers out again by
using the same symbol, I get back a #f instead. Here is the code I am using:

~~~~~~~~
(use-modules
 ;; SRFI 60: procedures for treating integers as bits
 (srfi srfi-60)
 (ice-9 hash-table))


(define SQUARES
  ;; vector, constant time access
  #('A1 'B1 'C1 'D1 'E1 'F1 'G1 'H1
    'A2 'B2 'C2 'D2 'E2 'F2 'G2 'H2
    'A3 'B3 'C3 'D3 'E3 'F3 'G3 'H3
    'A4 'B4 'C4 'D4 'E4 'F4 'G4 'H4
    'A5 'B5 'C5 'D5 'E5 'F5 'G5 'H5
    'A6 'B6 'C6 'D6 'E6 'F6 'G6 'H6
    'A7 'B7 'C7 'D7 'E7 'F7 'G7 'H7
    'A8 'B8 'C8 'D8 'E8 'F8 'G8 'H8))


(define square-pos->bit-integer
  (lambda (pos)
    (expt 2 pos)))


(define make-squares-to-integer-mapping
  (lambda (squares)
    (let* ([num-squares (vector-length squares)]
           [lookup-table (make-hash-table num-squares)])
      (let loop ([square-pos 0])
        (cond
         [(< square-pos num-squares)
          #;(display
           (simple-format
            #f "setting at key: ~a\n" (vector-ref squares square-pos)))
          (hash-set! lookup-table
                     (vector-ref squares square-pos)
                     (square-pos->bit-integer square-pos))
          (loop (+ square-pos 1))]
         [else lookup-table])))))


(define SQUARES-TO-INTEGERS
  (make-squares-to-integer-mapping SQUARES))


(hash-ref SQUARES-TO-INTEGERS 'A1)
~~~~~~~~

Surprisingly, I cannot get out any value of the ones stored in the hash
table. But when I use:

(hash-map->list cons SQUARES-TO-INTEGERS)

I can clearly see, that under the keys I have in SQUARES, are the
numbers stored in the hash table.

Also I use hash-ref, which is supposed to compare using equal?, which
for symbols like 'A1 and 'A1 returns #t, so I think my lookup should work.

Why can I not get the integers out of the hash table?

Regards,

Zelphir




^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Weird behavior of hash-table
  2019-11-23 22:39 Weird behavior of hash-table Zelphir Kaltstahl
@ 2019-11-24  8:04 ` Mark H Weaver
  2019-11-24  8:57   ` tomas
  2019-11-24 10:51   ` Zelphir Kaltstahl
  0 siblings, 2 replies; 9+ messages in thread
From: Mark H Weaver @ 2019-11-24  8:04 UTC (permalink / raw)
  To: Zelphir Kaltstahl; +Cc: guile-user

Hi Zelphir,

Zelphir Kaltstahl <zelphirkaltstahl@posteo.de> writes:

> I've noticed a strange behavior of hash tables. I put in symbols as keys
> and integers as values, but when I try to get the integers out again by
> using the same symbol, I get back a #f instead. Here is the code I am using:
>
> ~~~~~~~~
> (use-modules
>  ;; SRFI 60: procedures for treating integers as bits
>  (srfi srfi-60)
>  (ice-9 hash-table))
>
>
> (define SQUARES
>   ;; vector, constant time access
>   #('A1 'B1 'C1 'D1 'E1 'F1 'G1 'H1
>     'A2 'B2 'C2 'D2 'E2 'F2 'G2 'H2
>     'A3 'B3 'C3 'D3 'E3 'F3 'G3 'H3
>     'A4 'B4 'C4 'D4 'E4 'F4 'G4 'H4
>     'A5 'B5 'C5 'D5 'E5 'F5 'G5 'H5
>     'A6 'B6 'C6 'D6 'E6 'F6 'G6 'H6
>     'A7 'B7 'C7 'D7 'E7 'F7 'G7 'H7
>     'A8 'B8 'C8 'D8 'E8 'F8 'G8 'H8))

I guess that you meant for this to be a vector of symbols.  In fact, it
is a vector of lists of the form (quote <symbol>), for which '<symbol>
is a shorthand.

  scheme@(guile-user)> (vector-ref SQUARES 0)
  $10 = (quote A1)

To fix the problem, remove all of the apostrophes (') from the elements
of the vector literal above.  Like list literals, vector literals take
raw values, not expressions.

> (hash-ref SQUARES-TO-INTEGERS 'A1)

  scheme@(guile-user)> (hash-ref SQUARES-TO-INTEGERS 'A1)
  $11 = #f
  scheme@(guile-user)> (hash-ref SQUARES-TO-INTEGERS ''A1)
  $12 = 1

       Mark



^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Weird behavior of hash-table
  2019-11-24  8:04 ` Mark H Weaver
@ 2019-11-24  8:57   ` tomas
  2019-11-24 10:55     ` Zelphir Kaltstahl
                       ` (2 more replies)
  2019-11-24 10:51   ` Zelphir Kaltstahl
  1 sibling, 3 replies; 9+ messages in thread
From: tomas @ 2019-11-24  8:57 UTC (permalink / raw)
  To: guile-user

[-- Attachment #1: Type: text/plain, Size: 877 bytes --]

On Sun, Nov 24, 2019 at 03:04:36AM -0500, Mark H Weaver wrote:
> Hi Zelphir,
> 
> Zelphir Kaltstahl <zelphirkaltstahl@posteo.de> writes:
> 
> > I've noticed a strange behavior of hash tables [...]

> > (define SQUARES
> >   ;; vector, constant time access
> >   #('A1 'B1 'C1 'D1 'E1 'F1 'G1 'H1
[...]

> I guess that you meant for this to be a vector of symbols.  In fact, it
> is a vector of lists of the form (quote <symbol>), for which '<symbol>
> is a shorthand.
> 
>   scheme@(guile-user)> (vector-ref SQUARES 0)
>   $10 = (quote A1)

Yikes. I'd fall into this trap, too. Thanks you both for illustrating
it so well -- and thanks, Mark, for your unfailing sharp vision :-)

So the best thing for one's brain is to train it to read #(...)
as some weird relative of '(...)?

Is there a corresponding weird relative of `(...)?

Cheers
-- tomás

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Weird behavior of hash-table
  2019-11-24  8:04 ` Mark H Weaver
  2019-11-24  8:57   ` tomas
@ 2019-11-24 10:51   ` Zelphir Kaltstahl
  1 sibling, 0 replies; 9+ messages in thread
From: Zelphir Kaltstahl @ 2019-11-24 10:51 UTC (permalink / raw)
  To: Mark H Weaver; +Cc: guile-user

Hi Mark!

Thank you, that is the solution and the explanation!

I read my procedures multiple times, wondering whether I am returning
another hash table or anything. It would have taken me a long time
before trying to create the vector without the additional quotes.

Regards,
Zelphir

On 11/24/19 9:04 AM, Mark H Weaver wrote:
> Hi Zelphir,
>
> Zelphir Kaltstahl <zelphirkaltstahl@posteo.de> writes:
>
>> I've noticed a strange behavior of hash tables. I put in symbols as keys
>> and integers as values, but when I try to get the integers out again by
>> using the same symbol, I get back a #f instead. Here is the code I am using:
>>
>> ~~~~~~~~
>> (use-modules
>>  ;; SRFI 60: procedures for treating integers as bits
>>  (srfi srfi-60)
>>  (ice-9 hash-table))
>>
>>
>> (define SQUARES
>>   ;; vector, constant time access
>>   #('A1 'B1 'C1 'D1 'E1 'F1 'G1 'H1
>>     'A2 'B2 'C2 'D2 'E2 'F2 'G2 'H2
>>     'A3 'B3 'C3 'D3 'E3 'F3 'G3 'H3
>>     'A4 'B4 'C4 'D4 'E4 'F4 'G4 'H4
>>     'A5 'B5 'C5 'D5 'E5 'F5 'G5 'H5
>>     'A6 'B6 'C6 'D6 'E6 'F6 'G6 'H6
>>     'A7 'B7 'C7 'D7 'E7 'F7 'G7 'H7
>>     'A8 'B8 'C8 'D8 'E8 'F8 'G8 'H8))
> I guess that you meant for this to be a vector of symbols.  In fact, it
> is a vector of lists of the form (quote <symbol>), for which '<symbol>
> is a shorthand.
>
>   scheme@(guile-user)> (vector-ref SQUARES 0)
>   $10 = (quote A1)
>
> To fix the problem, remove all of the apostrophes (') from the elements
> of the vector literal above.  Like list literals, vector literals take
> raw values, not expressions.
>
>> (hash-ref SQUARES-TO-INTEGERS 'A1)
>   scheme@(guile-user)> (hash-ref SQUARES-TO-INTEGERS 'A1)
>   $11 = #f
>   scheme@(guile-user)> (hash-ref SQUARES-TO-INTEGERS ''A1)
>   $12 = 1
>
>        Mark



^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Weird behavior of hash-table
  2019-11-24  8:57   ` tomas
@ 2019-11-24 10:55     ` Zelphir Kaltstahl
  2019-11-24 11:20       ` tomas
  2019-11-24 11:00     ` Mark H Weaver
  2019-11-24 18:15     ` John Cowan
  2 siblings, 1 reply; 9+ messages in thread
From: Zelphir Kaltstahl @ 2019-11-24 10:55 UTC (permalink / raw)
  To: tomas; +Cc: guile-user

Hi Tomas!

On 11/24/19 9:57 AM, tomas@tuxteam.de wrote:
> Yikes. I'd fall into this trap, too. Thanks you both for illustrating
> it so well -- and thanks, Mark, for your unfailing sharp vision :-)
>
> So the best thing for one's brain is to train it to read #(...)
> as some weird relative of '(...)?

I guess so, because it is a reader syntax. So it is free to not evaluate
the things in the parentheses.

> Is there a corresponding weird relative of `(...)?
>
> Cheers
> -- tomás

Do you mean a way to write a vector and evaluate only some of the
elements in the vector?

Regards,

Zelphir




^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Weird behavior of hash-table
  2019-11-24  8:57   ` tomas
  2019-11-24 10:55     ` Zelphir Kaltstahl
@ 2019-11-24 11:00     ` Mark H Weaver
  2019-11-24 11:23       ` tomas
  2019-11-24 18:15     ` John Cowan
  2 siblings, 1 reply; 9+ messages in thread
From: Mark H Weaver @ 2019-11-24 11:00 UTC (permalink / raw)
  To: tomas; +Cc: guile-user

Hi tomás,

<tomas@tuxteam.de> wrote:

> So the best thing for one's brain is to train it to read #(...)
> as some weird relative of '(...)?

Yes.  They are both literals, and no part of a literal is evaluated.
#(...) is actually a shorthand for '#(...), and incidentally, one which
was not standardized until the R7RS.  In portable R[3456]RS code, you
must explicitly quote vector literals.

It's important to distinguish between an expression and the value(s) it
evaluates to.  It's easy to confuse them in Scheme, where every
expression is a value, but not necessarily the same value that it
evaluates to.  For example, the expression (+ 1 1) is a list of length 3
which evaluates to the number 2.  Similarly, 'A1, which is a shorthand
for (quote A1), is a list of two symbols which evaluates to the symbol
A1.  Only the "self-evaluating" values evaluate to themselves.

In general, you should not put a quote (') anywhere that you could not
write (+ 1 1) in place of 2, unless of course you *want* a list starting
with the symbol 'quote'.

> Is there a corresponding weird relative of `(...)?

Yes.  Remember that #(...) is a shorthand for '#(...).  You can replace
the "'" with "`", just as you would for a quasiquoted list.  For
example:

  scheme@(guile-user)> `#(1 2 3)
  $1 = #(1 2 3)
  scheme@(guile-user)> `#(1 ,(+ 1 1) 3)
  $2 = #(1 2 3)
  scheme@(guile-user)> `#(1 (+ 1 1) 3)
  $3 = #(1 (+ 1 1) 3)

      Regards,
        Mark



^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Weird behavior of hash-table
  2019-11-24 10:55     ` Zelphir Kaltstahl
@ 2019-11-24 11:20       ` tomas
  0 siblings, 0 replies; 9+ messages in thread
From: tomas @ 2019-11-24 11:20 UTC (permalink / raw)
  To: Zelphir Kaltstahl; +Cc: guile-user

[-- Attachment #1: Type: text/plain, Size: 425 bytes --]

On Sun, Nov 24, 2019 at 11:55:40AM +0100, Zelphir Kaltstahl wrote:
> Hi Tomas!
> 
> On 11/24/19 9:57 AM, tomas@tuxteam.de wrote:
> > Yikes. I'd fall into this trap, too [...]

> > Is there a corresponding weird relative of `(...)?
> >
> > Cheers
> > -- tomás
> 
> Do you mean a way to write a vector and evaluate only some of the
> elements in the vector?

Yes, and yes. See Mark's answer :-)

Cheers
-- t

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Weird behavior of hash-table
  2019-11-24 11:00     ` Mark H Weaver
@ 2019-11-24 11:23       ` tomas
  0 siblings, 0 replies; 9+ messages in thread
From: tomas @ 2019-11-24 11:23 UTC (permalink / raw)
  To: Mark H Weaver; +Cc: guile-user

[-- Attachment #1: Type: text/plain, Size: 791 bytes --]

On Sun, Nov 24, 2019 at 06:00:43AM -0500, Mark H Weaver wrote:
> Hi tomás,
> 
> <tomas@tuxteam.de> wrote:
> 
> > So the best thing for one's brain is to train it to read #(...)
> > as some weird relative of '(...)?
> 
> Yes.  They are both literals, and no part of a literal is evaluated.
> #(...) is actually a shorthand for '#(...) [...]

Aha. Thanks for setting my light bulb on fire :-)

[...]

> > Is there a corresponding weird relative of `(...)?
> 
> Yes.  Remember that #(...) is a shorthand for '#(...).  You can replace
> the "'" with "`", just as you would for a quasiquoted list [...]

Thanks, Mark!

IMO Andy and you are doing invaluable work for Guile (and Scheme in
general) by making it mentally more accessible. Again, thanks.

Cheers
-- tomás

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Weird behavior of hash-table
  2019-11-24  8:57   ` tomas
  2019-11-24 10:55     ` Zelphir Kaltstahl
  2019-11-24 11:00     ` Mark H Weaver
@ 2019-11-24 18:15     ` John Cowan
  2 siblings, 0 replies; 9+ messages in thread
From: John Cowan @ 2019-11-24 18:15 UTC (permalink / raw)
  To: tomas; +Cc: guile-user

On Sun, Nov 24, 2019 at 3:58 AM <tomas@tuxteam.de> wrote:

So the best thing for one's brain is to train it to read #(...)
> as some weird relative of '(...)?
>

Not really: that oversimplification will get you into trouble in more
complex cases.

In Scheme (and Lisp languages generally), there are two contexts for
interpreting S-expressions: datum context and expression context.  In datum
context, as when you are calling "read", the S-expression (foo bar baz) is
a list of three elements.  In expression context, it is either syntax (if
foo is a macro) or a call on the procedure named foo, passing it the values
of the variables bar and baz.

The purpose of quote is to allow you to embed a datum into expression
context.  3 has the same value as a datum and as an expression, so if you
want an expression that evaluates to 3, either 3 or (quote 3), which is
abbreviated '3, will work.  In datum context, though, 3 is a number and '3
is a two-element list whose first element is the symbol named "quote" and
whose second element is 3.  They *evaluate* to the same thing, but don't
*represent* the same datum.

But symbols and lists don't work this way: in expression context, foo's
value is whatever the variable named foo is bound to, but the value of 'foo
is the symbol foo.  Just like 3, in datum context foo and 'foo are *never*
the same thing: the first is a symbol, the second is a two-element list
whose members are the symbols named "quote" and "foo". The same is true for
(foo bar baz) and '(foo bar baz): they don't mean the same thing either in
expression context or in datum context.

Now vector syntax is like number syntax: it has the same value as an
expression or a datum.  So #(a b c) and '#(a b c) have the same value in
expression context, but mean different things in datum context.  What is
more, once in datum context, always in datum context: you don't write '('a
'b 'c) unless you actually want a list of three two-element lists.  So
either #('a 'b 'c) or (in expression context) '#('a 'b 'c) is a vector of
two-element lists, which is how the OP got into trouble.

Is there a corresponding weird relative of `(...)?


No, because the elements of a vector literal, like those of a quoted list,
are in datum context.  The way to achieve that is `(vector 1 ,bar 2 ,baz).
This works because (vector ...) is a procedure call and its elements are in
expression context.



John Cowan          http://vrici.lojban.org/~cowan        cowan@ccil.org
So they play that [tune] on their fascist banjos, eh?
        --Great-Souled Sam


^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2019-11-24 18:15 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-11-23 22:39 Weird behavior of hash-table Zelphir Kaltstahl
2019-11-24  8:04 ` Mark H Weaver
2019-11-24  8:57   ` tomas
2019-11-24 10:55     ` Zelphir Kaltstahl
2019-11-24 11:20       ` tomas
2019-11-24 11:00     ` Mark H Weaver
2019-11-24 11:23       ` tomas
2019-11-24 18:15     ` John Cowan
2019-11-24 10:51   ` Zelphir Kaltstahl

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).