Arc Forumnew | comments | leaders | submitlogin
1 point by absz 5924 days ago | link | parent

That should be doable with a new primitive and a modification to ar-apply in ac.scm. If we define a primitive called, say, behave (or rather, a much better name that I can't think of), such that

  (behave
    'foo
    (fn (self x y) (list (+ (self 0) x) (- (self 1) y)))
lets us write

  (let obj (annotate 'foo '(42 2))
    (rep (obj 5 2)))
to return (47 0), and we modify ar-apply to look for that, this should work. behave should be something like

  (define (ar-behave type fn)
    (hash-table-put! ar-behaviours type fn))
, and ar-apply would change

  ((ar-tagged? fn) (ar-apply (ar-rep fn) args))
to

  ((ar-tagged? fn) (ar-apply (hash-table-get ar-behaviours (ar-type fn)) args))
. (This is all untested.) In fact, we could even move everything but functions (and macros?) out of ar-apply and define them all in arc.arc, removing the (ar-tagged? fn) check, but this would break on the release of a new arcn.tar.

(Oh, and behave is still an awful name.)



2 points by nex3 5924 days ago | link

I'm working on something like this. Should be done in half an hour or so.

-----

2 points by nex3 5924 days ago | link

It took longer than I expected, but http://www.arclanguage.org/item?id=3743.

-----

2 points by almkglor 5924 days ago | link

Here's an objection:

The main reason my settable-fn works the way it does is so that attachments are orthogonal to annotations. An object might be tagged, or it might be attached, or it might be both tagged and attached.

This means that I could have defined a function, tagged it as 'table, and provided a '= attachment for a setterfunction and a 'keys attachment for a redef'ed 'maptable and 'keys. This way, I don't have to modify, say, 'each, which will simply see that it's a 'table and pass it to 'maptable, without ever realizing that it isn't a hash table.

With this system, everything that takes an attachment must be a settable-fn (or whatever). This means that I need to modify about a dozen existing macros so that it will work with my "table", so that they will also check for a 'keys attachment, and probably I want to do this for any new macros. Sure, I could redef 'type, but this gets more complicated (and potentially risky).

So no, I don't agree with this mod, because I think attachments should be orthogonal to annotations. I don't want an object-with-attachments to have its own annotation, I want the user to specify his or her own annotation for the object. In any case, since the mod has been pushed on arc-wiki, I'll have to work around it, possibly having to redef 'type.

-----

2 points by nex3 5924 days ago | link

I'm not sure I understand... defcall doesn't really have much at all to do with annotate. It certainly doesn't change the way it works. It just allows you to make user-defined types work like functions.

In any case, it seems un-Lispy to me in general to redefine behavior by attaching things to objects. I'd rather see us redefining and tweaking the verbs rather than adding information to the nouns. This is also, I think, how PG envisioned annotate and friends working. From http://www.paulgraham.com/ilc03.html :

"If you want to overload existing operators to do the right thing when given your new type, you don't need anything new in the core. As long as you have lexical scope, you can just wrap a new definition of the operator around the old one. So if you want to modify print to display objects of your new type foo in a special way, you write something like this:

  (let orig print
    (def print (x str)
      (if (is (type x) 'foo)
          ...new code...
          (orig x str))))"
I don't know, maybe I'm being short-sighted and attaching information to objects is really necessary. But I'm not seeing a case right now where it wouldn't be just as easy (or easier, with stuff like defcall) to define something like an attached-object type and use that.

-----

1 point by almkglor 5923 days ago | link

defcall specifies how an 'annotate 'd object will work in function position. This meant that it dispatches on the claimed type of the object, not on the real type. So (at least in your original version) a type masquerading as another type will be difficult to implement:

  arc> (= test (annotate 'table (fn (x) x)))
  #3(tagged table <procedure>)
  arc> test!x
  Error: "Can't get reference"
I've since modified it so that if it's a tagged type, 'ref will perform apply on its representation. This means that currently, (= call 'type ref) will cause an object typed as 'type to dispatch as if it were its representation, while using (defcall 'type ...) will dispatch based on its type (meaning it can't be faked)

-----

3 points by nex3 5923 days ago | link

I don't think types should masquerade as other types, by which I mean they shouldn't annotate themselves with other types' symbols. I think the proper way to act like another type is to behave like that type, not to annotate yourself with that type.

The thing is, if we expect (annotate 'table (fn (x) x)) to act just like a table out of the box, we have a lot of work to do. Every table axiom has to check for an annotation and recurse if one exists.

This may not seem so bad for tables, but consider: if ((annotate 'table (fn (x) x)) 'foo) works, shouldn't ((annotate 'cons (fn (x) x)) 1)? What about (+ (annotate 'num (fn (x) x)) 2)? What does that even mean?

It seems to me that the easiest and most consistent way to mimic other types is to annotate with a new type but to redef functions like keys and defcall to work in functional position.

I urge you to check out settable-fn2.arc if you haven't already - I re-implement get- and add-attachment using this style of annotation, and it comes out quite nicely. Rather than annotating the attached functions with their types, I add a 'type attachment which overrides isa. It appears to work fine with file-table.arc, too.

-----

2 points by almkglor 5923 days ago | link

From my point of view, attachments should be orthogonal to types. Basically, an attachment is any piece of information you want to attach to an object, and lives and dies with that object. That an attachment is used to overload 'keys or '= is just a use of the attachment concept.

For example, we might want to build a reader which keeps track of line numbers. The reader's output is still 'cons and 'sym, etc., but with an attachment. Each 'cons cell has a 'linenumber attachment which we can use. For example, a macro whose syntax has been violated would be able to report the line number where this violation occurs. This is useful if the macro is used often enough and there is a need to locate the line number of the error, or if its syntax is like CL 'loop and you expect it to span several lines.

In all cases, the cons cell produced by this hypothetical reader is a cons cell. Its representation is a cons cell and is only a cons cell. However, we can extract additional data from it. After it passes through the evaluator and is discarded as trash, its attached data can be thrown away.

In any case file-table.arc only cares that settable functions work, and settable functions only care that attachments work. Whether we make attachments orthogonal to types, or separate stuff-with-attachments as types may not really matter so much anyway. This is Lisp, after all.

-----

2 points by nex3 5923 days ago | link

I agree that attachments should be orthogonal to types - that's why I added the "isa" overloading to settable-fn2. But I don't think annotations should be orthogonal.

The thing is, there's no way we'll be able to add arbitrary attachments to any object and have it continue to behave just as if there were no attachments in Arc. We'd need to either modify the core to give each object a Python/Ruby/Javascript/etc-style implicit table, which I don't think PG is likely to be very fond of (and which I don't think is a good idea besides); or we need to accept that there will be some cases where we won't be able to get attachments without a few compromises.

-----

3 points by almkglor 5923 days ago | link

Well, I thought annotations were types!

Anyway:

"Now this is the noble truth of the origin of suffering: it is this attachment which leads to renewed existence, accompanied by delight and lust, seeking delight here and there, that is, attachment to sensual pleasures, attachment to existence, attachment to extermination."

Therefore... buddha pg, please enlighten us and deliver us from attachment! ^^

-----

3 points by nex3 5923 days ago | link

Buddha PG will free us from suffering by means of s-expression Koans and well-timed whacks to the head!

-----

1 point by nex3 5923 days ago | link

Also, I just pushed a settable-fn2.arc that uses annotations how I envisioned them being used (it's also pure Arc). Hopefully that should make it more clear what I'm thinking.

-----