Arc Forumnew | comments | leaders | submitlogin
2 points by rincewind 5975 days ago | link | parent

Can you define a setter for my-type annotated objects? Like this:

  (= tab (annotate 'my-table (table)))
  (defcall my-table (self arg)
     self.arg)

  ;what i'd like to do:
  (defset 'my-table ((self arg) value)
      (= self.arg upcase.value))

  (= (tab 'test) "foo bar baz")

  (tab 'test)
  ;should return ("FOO BAR BAZ")
If not, it should not be too hard to implement, but I would rather not put redundant effort into it.


1 point by almkglor 5974 days ago | link

An alternative is to use the "lib/settable-fn.arc" or "lib/settable-fn2.arc" frameworks for this.

When using settable-fn.arc:

  (def create-my-type ()
    (add-attachments
      'key (fn () (generate-keys))
               ; note the order: value before key(s)
      '=   (fn (v k)  (assign-value-v-to-key-k v k))
      (annotate 'my-type
        (fn (k)
          (lookup-in-k k)))))
lib/settable-fn2.arc:

  (def create-my-type ()
    (add-attachments
      'key (fn () (generate-keys))
      '=   (fn (v k)  (assign-value-v-to-key-k v k))
      'type 'my-type
      (fn (k)
        (lookup-in-k k))))
Aside from 'keys and '=, it allows you to overload 'len

-----

2 points by almkglor 5974 days ago | link

The "Create your own collection" series should help a bit - these collections all use lib/settable-fn.arc, and with minimal modification should be useable with lib/settable-fn2.arc

http://arclanguage.com/item?id=3595 Suggest PG: Settable function objects

http://arclanguage.com/item?id=3698 Create your own collection in Arc: settable functions now implemented on arc-wiki.git

http://arclanguage.com/item?id=3762 Create your own collection: use directories as if they were tables with file-table

http://arclanguage.com/item?id=3858 Create your own collection: bidirectional tables

http://arclanguage.com/item?id=5254 Create your own collection: cached-table

http://arclanguage.com/item?id=7365 Create your own collection: proto-table, when you want prototyping semantics in your object system

-----

1 point by absz 5975 days ago | link

Yes, you can; it involves redefining sref. When you write (= (obj key) value), it becomes (sref obj value key). So in this case, you would write

  (redef sref (x v k)
    (if (isa x 'my-table)
      (let y (rep x)
        (annotate 'my-table (= y.k (upcase v))))
      (old x v k)))
Or, if you're using nex3's defm,

  (defm sref ((t x my-table) v k)
    (let y (rep x)
      (annotate 'my-table (= y.k (upcase v)))))
If you do this a lot, you could probably wrap a macro around it to eliminate some of the boilerplate.

-----

1 point by stefano 5975 days ago | link

'= is a macro, and therefore it needs to know how to assign to the variable at compile time, but the type information is known only at run time, but it should be possible to get something like:

  (= (my-table tab 'test) "foo bar baz")
to work. It's a little more verbose and if you changed the name of the type from my-table to something else you would have to change every assignment.

-----