ietf-openproxy
[Top] [All Lists]

RE: Decision on Rules Language

2003-09-17 11:17:57

Hi Alex,

The (Core.)nil object is a special object that is the result of a
failed expression or statement. Operations on the nil object results
in a nil object, except in the case of the '==' operator in which
case a semantic comparision is made to see if the compared
expression also results in a nil object.

I think we can simplify quite a bit: Any use of an undefined value
must result in a failure (and not not another nil object). This makes
it easy to catch errors and abort early if needed. It also has a more
clear/uniform/straightforward semantics.

I agree with this.

Note that the operator takes a name as input, it does not use the
value the name represents. No need for a special "nil"
constant/token!

Did I miss any use cases?

BTW, which name (exists or defined or something else) would you
prefer? I wish one could type the existential predicate using
ASCII :).

I would go with defined, since it goes with the term 'undefined' (even if we
decide to get rid of the 'undefined value' concept).

To detect and substitute for missing services, for example, one would
write:

      { service := Services.find("A"); } or
      { service := Services.find("B"); }

Even a simpler expression below can probably be supported within the
current design, perhaps after defining "or" operator more clearly:

      service := Services.find("A") or Services.find("B");

Do you think using failures like that is sufficient?

I would think that we should stay with maintaining the "{}" brackets before
the or for clarity - especially for cases with multiple statements within
the blocks. Also in section 2, we would need to add:

Section 2:
   expression =
        name / function-call / "{" code "}" *( "or {" code "}" )


this will result in a failure generated as a result of applying the
nil object in an assignment as previously mentioned.

Agreed. The above no-undefined-use rule covers all these cases, IMO
(but using failure feature instead seems cleaner). What do you think?

Yes, I would agree with this as well.

XXX: Code blocks and inclusion of libraries:
     my_freq_rule_library -> {
             some_older_useful_code;
             quick_expression -> {
                     code;
             };
     };

I am probably missing something important, but how is that different
from the current mechanism of assigning a piece of code?

The key difference here was unique identification of the 'member code'
within a block. By 'member code', I refer to the ability to identify the
block of code assigned to 'quick_expression' within the larger block,
'my_freq_rule_library'. This might be useful when including libraries where
there might be conflicts due single assignment. Included libraries are
identifed by a unique code-block name, preventing conflict of names. This
might make large rule files more structured similar to 'rule' blocks
("<rule></rule>") in IRML deliniated rules.

Did you overlook that hidden(?) possibility or can your proposal do
more than name a piece of code?

I wasn't sure if the assignment of code with a name was intended to do this
as well.

Blocks of code from other files may be included in a P language program
using the 'include' statement. For example:
This is already supported, I believe:

      my_freq_rule_library := Core.import("my_freq_rule_library.p");

True, I hadn't thought of Core.import being used that way. I agree that the
algorithm to find module using its string name is  left to the Core
implementation. Although, I would suggest that we do mention how the code is
imported and appended to the program that is including this.

("my_freq_rule_library.p") is Core implementation-dependent. I would
suggest that environments that support loading modules from P files,
use more explicit name syntax:

      Core.import("file://my_freq_rule_library.p");

Should these suggestions be mentioned in the draft as 'recommended
practices' ?

The "next expression" part may not be desirable because it would leave
certain failures undetected. Programmers must be explicit if they want
to ignore an error:

      { /* code that may fail */ } or {};

I believe current failure rules are close to exceptions in modern
programming languages. Do you agree that the current failure design is
sufficient to address your needs or do you see any missing
pieces/flaws?

This seems sufficient.

Thanks for discovering more missing pieces and suggesting specific
improvements. I will try to incorporate all "undocumented but needs to
be" features you recently pointed out into the next draft release.

Glad to be of help.

Thanks,
Anwar


<Prev in Thread] Current Thread [Next in Thread>