ietf-mta-filters
[Top] [All Lists]

Re: variables: open issue a) date variables

2003-05-09 09:17:49
On Wednesday 07 May 2003 22:59, Kjetil Torgrim Homme wrote:
<snip>
I agree [system variables] need to be recognisable by syntax alone.
one type of prefix could be "date." or "imap.", ie. the distinguishing
feature is the presence of one or more periods.
<snip>

That was my first reaction, too, but I thought that would be too verbose 
and I remembered there was opposition to "named namespaces", so I chose 
a single character prefix.

there was objection
to define extensions that have any kind of "internal variable" (as
imapflags once called it) without first having variables for Sieve
in general.

I don't understand this reasoning.  you want "internal variables"
with properties very different from those of the general variables. 
where is the connection between the features?
<snip>

I want a single syntactical element for a common concept instead of 
every extension brewing it's own thing. (Notify: $subject$ etc 
substitution in the :message text; Imapflags: :(global)flags; 
Variables: setdate).

The connection is the general variables syntax: ${}.

ok.  I honestly don't know what's the best way to handle the IMAP
flags.

1)
part of me wants to add a list variable type.  the main sticky point
is the interpolation.  my suggestion was:

  set "foo" [ "one", "two", "three" ];
  set "bar" [ "${foo}", "four" ];
  set "zot" [ "woo${foo}hoo" ];

now ${bar} is [ "one", "two", "three", "four" ] and ${zot} is [
"woo", "one", "two", "three", "four", "hoo" ].  this makes
"${foo}${bar}" equivalent with [ "${foo}", "${bar}" ].
<snip failure discussion>
this could be solved by making making a new list variable syntax,
e.g., @{folder} becomes a list, while ${folder} is becomes a single
string with a single space as delimiter or something.

This might work - for imapflags. What about ${#currentdate}, ${#size} 
(see below). And what about initial content?
<sidenote>
I don't understand why imapflags requires it's internal set to be empty 
on startup. Wouldn't it be more useful to allow implementations to 
preload the set with the current flags? E.g. when applying scripts to a 
selection of messages from an IMAP folder or in sequential script 
("multiscript" environment) execution?
</sidenote>

2)
part of me thinks strings will work OK.  it just needs careful
programming to keep everything padded with spaces.

  set "flags" "${flags} \\Flagged ";  # note trailing space
  if string :matches "${flags}" "* \\Flagged *" {
    set "flags" "${1} ${2}";
  }

Ugh. Too subtle. It's a open invitation for bugs in scripts.

3)
part of me thinks an intrinsic variable is the solution which appears
cleanest to the user.

why do you need variables at all for IMAP flags?  to keep state, it
seems.

Yes. And I want to use a system variable for that because that's the 
_concept_ behind it. A new imapflags draft revision can then say:
"fileinto uses the current content of the ${#imapflags} system variable 
as the set of flags to use" or "Scoping? See variables!" So this:

  if something {
     addflag "\\Flagged";
     if somethingelse {
        addflag "Big";
        keep :globalflags;
     }
  }
  # now we want to restore the flags to the values before the if.
  # or do we?
<snip>

Won't confuse anyone anymore, since the set of flags is scoped like any 
other variable (ie. globally - currently). If you want to restore the 
imapflags from before the first if, save them away in a user variable 
and restore them after the fact:

set "myimapflags" "${#imapflags}";
if .... {
  ....
}
setflags "${myimapflags}";

  if date :current :timezone "+0200" :hour :matches "*" {
    set "${hour}" "${1}";
  }

you won't get daylight savings time handled correctly this way.
compare with

  setdate "Europe/Oslo";
  if not string "${timezone}" "Europe/Oslo" {
    setdate "+0100";
  }

ie., use Europe/Oslo if the server recognises the time zone,
otherwise fall back to +0100.

My feeling is that trying to use an unknown timezone should flag an 
error.

I used :numericzone to work around the tagged argument name clash. Maybe  
instead of the :timezone parameter there should be a ${#timezone} 
variable that can be altered by a settimezone action?

settimezone "Europe/Berlin";
if not string "${#timezone}" "Europe/Berlin" {
  settimezone "+0100";
}

That introduces the question of which date tests should honour the 
timezone? Maybe all, since you can always say:

set "mytimezone" "${#timezone}";
settimezone ""; # use local (:current) or implied (else) timezone
if date :comparator "i;ascii-numeric" :sent :hour :value "lt" "6" {
  set "prefix" "Oh, my. Nightshift again? ";
}
vacation
    "${prefix}I'm on vacation (Hawaii :-P) until the end of the month.";
settimezone "${mytimezone}";

  where the date test syntax would be:

  date [COMPARATOR] WHICH [TIMEZONE] [DATE-PART] [MATCH-TYPE]
       <key-list: string-list>

  WHICH := ":current" / ":received" / ":sent"
           / ( ":header" <headerfield: string-list> )
  DATE-PART := ":weekday" / ":day" / ":month" / ":year"
           / ":hour" / ":minute" / ":second" / ":numericzone"
           / ":all" / ... ; ":all" is default
  TIMEZONE := ":timezone" <timezone: string>
       ; server's local timezone is default for :current,
         timezone specified in the header is default for :received,
:sent and :header.

I think this is nice.  but for a user simply wanting to save his mail
in different folders depending on month would write

  setdate;
  fileinto "INBOX.${year}-${month}";

which now becomes

  if date :current :year :matches "*" {
     set "year" "${1}";
  }
  if date :current :month :matches "*" {
     fileinfo "INBOX.${year}-${1}";
  }

  Together with the relational extension and a rfc822-date
  comparator,

please make it an ISO 8601 date comparator ...
<snip>

But rfc822 messages have rfc822 dates? Or is it the engine's job to 
convert the string representation of the dates into ISO 8601 strings? I 
think not, since it's also not the engine's job to convert strings to 
numbers before handing them off to i;ascii-numeric.

the existence of a global "setdate" script is not guaranteed.  isn't
it better to make the support for this certain?

It would be cute to have a "sieve stdlib". However, just providing this 
script on the homepage or as an appendix to the variables rfc would 
probably suffice. Those that want it can either include it or 
cut'n'paste it into their scripts.

I think your date 
test and SETDATE can co-exist.
<snip>

I don't like setdate polluting the "user namespace" with unused 
variables. How many people will need ${second} compared to ${year} and 
${month}? If setdate remains, I'd like to see it write to ${#year} etc, 
but I'd really prefer to have it's functionality go into a date test, 
else why do we have a setdate and no setenvelope, setaddress, 
setheader, setsize[1]? With a date test, all but the last are equally 
superfluous. Should every foo test have a corresponding setfoo action 
that optimizes away the otherwise necessary matches-set idioms?

[1] This might even be useful, since the relational extension failed to 
redefine the size test to take a [MATCH-TYPE] parameter, so you 
_cannot_ say
  if size :matches "*" {
    set "size" "${1}";
  }
So ${#size} perfectly fits the definition of a system variable :-):

It affects the size test, ...
  is read-only, it's natural representation is not a string,
  it's value can't be computed with Sieve and it can't be extracted
  from the message.

but is this a good thing,

It's simply needed. Size is just another example[2]. Whether it's good 
or not that there are such variables, they're (implicitly) there even 
in the Sieve base spec.

[2] And one which the variables spec needs to define, so it addresses 
Ned's concerns about defining a concept and not instantly making use of 
it.

or do we want to make generic mechanisms 
instead?

What do you mean with "generic mechanism"? Isn't "system variable" such 
a generic mechanism?

Marc

-- 
I am Bush of USA. You will be pacified. Resistance is futile.

Attachment: pgpodoFG2ORc4.pgp
Description: signature