Binding attributes to values/variables

Description

From Vern:

In abstract terms, we need to marry two notions: per-variable
attributes (those introduced when defining the variable) and
per-value attributes (those introduced when creating a value).
These both exist under-the-hood, but the rules for propagating
them are ad hoc.

I'm attaching the follow-up email thread with further thoughts on
streamlining this.

Robin

Did we ever reach resolution regarding the appended thread (from, um,
a year ago!), or at least put something in the Tracker so we don't lose
sight of it?

Vern

On Tue, Nov 03, 2009 at 17:25 -0800, you wrote:

> In abstract terms, we need to marry two notions: per-variable attributes
> (those introduced when defining the variable) and per-value attributes
> (those introduced when creating a value). These both exist under-the-hood,
> but the rules for propagating them are ad hoc.

This is something I've wondered about a few times already what the
right thing to do is. The keyword at the moment is indeed "ad-hoc":
I remember that a number of times I've been running into problems
with propagating (or not propagating) attributes, and while I was
always able to fix the immediate problem in some way, we don't have
a clear system at the moment when that happens and when not.

That said, I'm not really sure that this should ideally look like.
Intuitively, I'd actually say attributes belong to values, not
variables, because transfer-on-assignment can lead to subtle effects
(values are passed around, and what if the receiving function
happens to assign the value to the wrong variable?. Also what if you
assign a value with attribute X to a variable without X; shouldn't
the value then be deleted for consistency reasons?).

If we accept for a moment that attributes belong only to values,
then we can think about how to set them. A global definition such as

const log_file = open_log_file("foo") &rotate_interval

can be interpreted as assigning the attribute to the value returned
from the function (more generaly to whatever what the assigned
expression yields).

We can use the "add foo &raw_output" syntax you suggested for adding
attributes to the value of foo dynamically.

A declaration such as

const foo = F &redef;

can be interpreted as "we can rebind foo if it's current value has
the &redef attribute".

I haven't thought this through actually but I guess my question is
whether we need per-variable attributes at all?

Robin

On Nov 4, 2009, at 7:54 PM, Robin Sommer wrote:

>That said, I'm not really sure that this should ideally look like.
>Intuitively, I'd actually say attributes belong to values, not
>variables, because transfer-on-assignment can lead to subtle effects
>(values are passed around, and what if the receiving function
>happens to assign the value to the wrong variable?. Also what if you
>assign a value with attribute X to a variable without X; shouldn't
>the value then be deleted for consistency reasons?).

Attributes being attached to value really seems to make sense.

>If we accept for a moment that attributes belong only to values,
>then we can think about how to set them. A global definition such as
>
> const log_file = open_log_file("foo") &rotate_interval

It works in this case, but this has typically been where trouble was encountered. What about cases where there isn't a value assigned yet? Something like...

const bad_addrs_with_description: table[addr] of string &redef &write_expire=10mins;

There isn't a value yet, but it has an attribute applied to it. Would that style still be supported? It would seem to conflict with having only value attributes.

Even for my database backed variable stuff I'm working on, it created a stumbling block. What I'm doing internally is creating a copy of the value including attributes to a separate internal value when a query is being run. That value is then filled from the database and the script level variable is rebound to my newly filled internal value and the old value is deleted. I think that would be the right way to do it in this case even if only value attributes exist because it's an internal detail and the new value is being created internally, but it's certainly confusing sometimes.

.Seth

On Wed, Nov 04, 2009 at 20:26 -0500, you wrote:

> const bad_addrs_with_description: table[addr] of string &redef
> &write_expire=10mins;
>
> There isn't a value yet, but it has an attribute applied to it.

Actually there is: it's assigned an empty table. So, yes that would
still work.

What would be different however is a later assignment (redef for
const [1]), which would ignore the &write_expire of the original
definition and instead use the attributes from the assigned value.

Robin

[1] A "=" redef, not a "+=" redef which works on the original value.

On Nov 10, 2009, at 12:32 AM, Robin Sommer wrote:

>What would be different however is a later assignment (redef for
>const [1]), which would ignore the &write_expire of the original
>definition and instead use the attributes from the assigned value.
>
>[1] A "=" redef, not a "+=" redef which works on the original value.

Ah, ok. This is all coming together for me now.

Another question I have is if the change was made to allow attribute additions and deletions at runtime, does it sort of violate the concept of const? const seems to tie together the value and variable together and make them unchangeable at runtime but it's a little confusing conceptually if you're able to still change the attributes of a const at runtime.

Am I thinking about that right?

.Seth

On Fri, Nov 13, 2009 at 13:24 -0500, you wrote:

> Another question I have is if the change was made to allow attribute
> additions and deletions at runtime, does it sort of violate the concept
> of const?

That's a good point, yes. Perhaps "const foo = xxx" should actually
mean that the value xxx gets an (internal) attribute &const so that
it's not changeable? And then assigning to a global with a current
value that has the &const attribute would be prohibited as well.
Does that make sense?

Robin

Environment

None

Activity

Show:
Robin Sommer
November 29, 2010, 4:36 PM

To clarify, the attached thread does not necessarily reflect a
resolution we fully converged on. We will need to rediscuss the
right approach before tackling this.

Robin

Seth Hall
May 2, 2012, 1:16 AM

Eventually we'll have to try and figure out where we were going with this conversation. Bumping it for now.

Jon Siwek
December 11, 2012, 8:03 PM

In [784adf3f6ba781f0ade427d8f7177c540d8f7100/bro]:

Jon Siwek
December 11, 2012, 9:34 PM

Replying to [robin|comment:1]:
> To clarify, the attached thread does not necessarily reflect a
> resolution we fully converged on. We will need to rediscuss the
> right approach before tackling this.

Feel like discussing more?

> From Vern:
>
> In abstract terms, we need to marry two notions: per-variable
> attributes (those introduced when defining the variable) and
> per-value attributes (those introduced when creating a value).
> These both exist under-the-hood, but the rules for propagating
> them are ad hoc.

My description of it would be that the contexts in which attributes are used are ad hoc while the propagation rules for most contexts are just mostly non-existing.

Specifically for the context of local/global variable declarations, the only propagation that occurred was at init/parse time when the declaration also included an initialization. This seems to cause the most confusion for people as they expect values assigned to such a variable at run time to inherit the attributes. I did some changes in topic/jsiwek/attr-propogation (sic) that I think fixes the propagation expectations for this context with the rules being that attributes in declarations will propagate in the "type -> variable -> value" direction for values assigned at either init-time or run-time.

Some of the other contexts that use attributes don't have such a clear propagation expectation (record fields are currently ambiguous and function/events don't seem to require any propagation technique). So I think if there were a strong need to be able to apply attributes specifically to a value, those cases should be approached by adding the new "add <attr_list> <id>;" statement or with BIFs.

> That said, I'm not really sure that this should ideally look like.
> Intuitively, I'd actually say attributes belong to values, not
> variables, because transfer-on-assignment can lead to subtle effects
> (values are passed around, and what if the receiving function
> happens to assign the value to the wrong variable?. Also what if you
> assign a value with attribute X to a variable without X; shouldn't
> the value then be deleted for consistency reasons?).

I would think of it as values being able to inherit attributes from variables with the variable's attributes taking precedence over a value's in case of conflict. But that doesn't preclude a value from being able to own separate attributes.

> A declaration such as
>
> const foo = F &redef;
>
> can be interpreted as "we can rebind foo if it's current value has
> the &redef attribute".
>
> I haven't thought this through actually but I guess my question is
> whether we need per-variable attributes at all?

There's the cases were a "variable" may not have a value yet (table types are an exception to this). The way around that would be the dynamic attribute application methods mentioned before (a BIF or "add <attr_list> <id>;" statement) and then probably get rid of attributes in variable declarations completely because otherwise you still would need the variable identifier to hold on to attributes until the first value assignment. That approach seems a little inconvenient/cumbersome.

There's also record field attributes which apply more to the field itself and not the value assigned to it.

So do you think that my branch would be worth merging on the grounds that it aligns local/global variable attribute propagation with people's expectation, but it doesn't claim to unify attributes to a single usage context (maybe it's too late for that)?

Vlad Grigorescu
March 19, 2015, 9:40 PM

The discussion in needs to be resolved before topic/jsiwek/attr-propogation can be merged, which has at least partial fixes for all 5 tickets.

Assignee

Unassigned

Reporter

Robin Sommer

Labels

None

External issue ID

327

Components

Affects versions

Priority

Normal
Configure