Arc Forumnew | comments | leaders | submitlogin
Table constructor
4 points by bogomipz 5901 days ago | 6 comments
The table constructor should accept values. I'd like to be able to write

  (table 'x 1 'y 2)
This is practical in lots of situations. Let's say you have a list of alternating keys and values from somewhere. You can easily turn that into a hash table with

  (apply table keys-and-values)
By the way, is there a reason why the above apply could not be written like this?

  (table . keys-and-values)


1 point by icemaze 5901 days ago | link

Another thing that has been very useful to me is a function that creates a table with a given list of keys all initialized to a given initial value. For instance:

  (def table-w/keys (value . keys) ....)

  (table-w/keys 0 'cars 'planes 'ships)
  ; -> #hash((cars . 0) (planes . 0) (ships . 0))

-----

1 point by cje 5901 days ago | link

I've no idea what this is useful for, but:

  (def table-w/keys (value . keys)
    (= tab (table))
    (each key keys
      (= (tab key) value))
    tab)
Also, the feature you want in table is easily done by fill-table:

  (def new-table args
     (fill-table (table) args))
Use the source, Luke!

-----

1 point by bogomipz 5901 days ago | link

table-w/keys is useful for counting. After creating the table in icemaze's exemple you can for instance do

  (++ (h 'cars))
Even more useful, however, is to specify a default value for keys not yet in the table, so you can do the above without first initializing for the keys you intend to use. PG mentioned in Arc at 3 Weeks that lookup failure should return the global value * fail* , in which case you would be able to do

  (with (h (table) *fail* 0)
        (++ (h 'red))
        (++ (h 'blue))
        (++ (h 'blue))
        (++ (h 'green))
        h)
which returns a table where red is 1, blue is 2, green is 1, and no other keys exist. The example is kind of stupid, but the concept is quite powerful.

Edit: spaces added so * fail* doesn't become fail

-----

1 point by bogomipz 5901 days ago | link

Good point about fill-table. I didn't think of how easy it is to give this function a newly created table. It still kind of feels like a shortcoming that (table) doesn't accept values like (list) does. And I don't want to define a different function to behave like this. If it's a good idea, it should be in the main table constructor. PG seems to have thought of this already because there's a comment in ac.arc with a definition that involves fill-table. I do, however, see that this would slightly bloat the constructor.

-----

1 point by emmett 5901 days ago | link

(obj x 1 y 2) isn't close enough?

-----

1 point by bogomipz 5901 days ago | link

obj is a macro, which means it can't be used with higher order functions. Also, what if my keys are held in variables? I can't write this with obj:

  (table name-key name age-key age)

-----