Subject: imapflags and variables

From: Kjetil Torgrim Homme <[email-masked]>
Date: Sun, 11 May 2003 05:16:04 +0200

short recap: imapflags consists of five actions

  MARK
  UNMARK
  ADDFLAG <flags: string-list>
  REMOVEFLAG <flags: string-list>
  SETFLAG <flags: string-list>

and a number of tagged arguments for KEEP and FILEINTO

  :flags <flags: string-list>
  :globalflags
  :globalflags_plus <flags: string-list>
  :globalflags_minus <flags: string-list>

without one of the tagged arguments, no flags will be set.

there are two things some people desire:

  a) being able to restore an old set of flags
  b) get rid of some of the tagged argument variants

Marc suggests a system variable for accessing the current value,
${#imapflags}.  you can get rid of ':globalflags_plus "Flag"' like
this:

        keep :flags "${#imapflags} Flag";

and ':globalflags_minus "Flag"' like this:

        set "safe_copy" "${#imapflags}";
        removeflag "Flag";
        keep :globalflags
        setflag "${safe_copy}";

the downside to this proposal is that it introduces a new syntax for
system variables since we don't want to allow assignment to them.
I'll also note that the first snippet will misbehave with no
diagnostics if the user has forgotten 'require "variables"'.

my suggestion is to add a another action instead, only available when
the variables extension is in effect:

        STOREFLAGS <variable: string>

the result of this is that the variable contains the list of flags
currently set.  the code to replace ':globalflags_plus "Flag"' becomes
a little more verbose:

        storeflags "curr_flags";
        keep :flags "${curr_flags} Flag";

the code for ':globalflag_minus "Flag"' is essentially the same.

        storeflags "safe_copy";
        removeflag "Flag";
        keep :globalflags
        setflag "${safe_copy}";

for both proposals, :globalflags is sufficient, but verbosity is
slightly increased without :flags <flag-list>.  more radically, we
could remove both and make :globalflags the default and mandatory
behaviour for KEEP/FILEINTO.  this way the implicit keep can set flags
on the message.  I think that would be useful.

-- 
Kjetil T.

---

From: Marc Mutz <[email-masked]>
Date: Mon, 12 May 2003 22:21:26 +0200

On Sunday 11 May 2003 05:16, Kjetil Torgrim Homme wrote:
<snip>
> ${#imapflags}.

Actually, I suggested a test for it, but ok.

> you can get rid of ':globalflags_plus "Flag"' like 
> this:
>
<snip>

more like

  set "safe_flags" "${#imapflags}";
  addflag "Flag";
  keep :globalflags
  setflags "${safe_flags}";

> diagnostics if the user has forgotten 'require "variables"'.

"imapflags" would require "variables". I know that there's currently no 
extension that depends on another, but it's not uncommon. E.g. ESMTP's 
BINARYMIME depends on CHUNKING. Variables is a candidate that 
extensions will want to depend on.

>         STOREFLAGS <variable: string>
<snip>

The downside of that is that you need to come up with such an action for 
each and every extension that possibly wants to store away state 
temporarily.

> behaviour for KEEP/FILEINTO.  this way the implicit keep can set
> flags on the message.  I think that would be useful.

Rereading the "progressing various sieve drafts" thread, I get the 
impression that people were ok with :flags, but not with :globalflags. 
The main reason seemed to be that setflags/addflags/etc alter global 
state and that was a new thing for an extension to do.

Thus, there was thought about deferring this until variables are 
available. Says Tim:

On Wednesday 17 July 2002 19:49, Tim Showalter wrote:
> On Wed, 2002-07-17 at 06:57, Ken Murchison wrote:
<snip>
> > I have -03 implemented in Cyrus and I find the global flags nature
> > very useful,
<snip>
> > That being said, I find the :globalflags stuff kind of crufty ;)
>
> There's no argument from me that it's *useful*, but that it's cruft
> that we'll need to replicate again and again in the future that looks
> exactly like variables with an undesirable syntax.

So it seems to me that the feeling "back then" was to let extensions 
with actions that alter global state depend on a (then non-existant) 
variables extension. I think the variables extension needs to reflect 
this. I've proposed the "system variable" concept to this end, I'm open 
to other solutions.

Reviving the old action-affects-global-state method seems undesirable to 
me.

So how could imapflags progress in this light? I see two routes:

I non-system variables:

1. Dump :globalflags, keep only :flags. This means that implicit keep
   never sets any flags, but you can always end your script with an
   explicit keep (multiscript might make problems, though).
2. Iff - additionally - variables is required, then you can either
   2a. fill a user variable with flags and leave the whitespace,
      duplicates and ordering issues to the user. Dump
      *flags/mark/unmark.
   2b. introduce a required string argument to the *flags/*mark actions
      that specifies a variable name for the action to act on. The
      actions ensure validity of their arguments and maintain
      uniqueness, order and whitespace conventions inside the (user)
      variable.
   this way, you can emulate :globalflags with a explicit variable.

II system-variables / no tags

1. Dump :globalflags and :flags altogether.
2. Make imapflags depend on variables and introduce the system variable
   ${#imapflags}.
3. Make keep and fileinto use the current value of ${#imapflags}.
4. keep the set actions with alter #imapflags.

III system-variables / :useflags

like II, but fileinto and keep only use ${#imapflags} if the :useflags 
tag is present on them.

(I) has the advantage of being explicit, but requires the user to 
maintain the variables constraints herself, which is error-prone.

(II/III) have the advantage of being less error-prone, but are not 
_that_ explicit.

Either way, I don't see an approach that combines the advantages of 
both. I'd be glad to be shown one.

Marc

-- 
They that can give up essential liberty to obtain a little temporary
safety deserve neither liberty nor safety.      -- Benjamin Franklin

---

From: Kjetil Torgrim Homme <[email-masked]>
Date: Tue, 13 May 2003 00:15:32 +0200

>   Actually, I suggested a test for it, but ok.

sorry, I have missed that.  would you mind repeating it?  I think it
makes sense.

>     setflags "${safe_flags}";

this was the added verbosity I hinted at if :flags was removed.

>   The downside of that is that you need to come up with such an
>   action for each and every extension that possibly wants to store
>   away state temporarily.

true.  it remains to be seen how common that is, though.

>   1. Dump :globalflags, keep only :flags. This means that implicit
>   keep never sets any flags, but you can always end your script with
>   an explicit keep (multiscript might make problems, though).

the implicit keep can't be emulated _that_ easily.  consider

  if ... {
     fileinto "somewhere";
  }
  keep :flags "${myflags}";

(message uniqueness only concerns a single folder.)

so you'd need to keep track of it yourself.

  if ... {
    set "kept" "yes";
    fileinto "somewhere";
  }
  if not string "${kept}" "yes" {
    keep :flags "${myflags}";
  }

thank you for your very useful summary!

-- 
Kjetil T.