V2 features apparently no longer supported

This forum is to report technical problems with Rel.
Post Reply
HughDarwen
Posts: 124
Joined: Sat May 24, 2008 4:49 pm

V2 features apparently no longer supported

Post by HughDarwen »

I'm not sure you would regard this as a bug, but I couldn't find a more appropriate section to raise this issue in. Two V2 features I was using seem to be no longer available.

The first is <iterate statement>, though the use I was putting this to is now subsumed by the new "enhanced" feature for displaying relations in tabular form. While I greatly sympathise with a desire to prevent misuse of <iterate statement>, I suspect it has "good" uses as well as "bad" ones and I certainly would not object to its return.

More importantly, we seem to have lost the ability, in DBrowser, to specify an ordering of a relation's tuples in the output pane. In V2 this was a possibly undocumented feature of OUTPUT (explicit and implicit). In V3 it appears to be available only on LOAD. That's the only place in Tutorial D where ORDER is available, but Tutorial D doesn't include any client-side language and expects OUTPUT (an operation executed at the client) to use LOAD.

Hugh
Dave
Site Admin
Posts: 372
Joined: Sun Nov 27, 2005 7:19 pm

Re: V2 features apparently no longer supported

Post by Dave »

The return of FOR (the <iterate statement>) and ORDER is imminent, possibly as soon as version 0.3.10. Along with these, I'm inclined to provide a command-line switch to optionally disable such extensions, for use in pedagogical (or other) contexts where strict adherence to Tutorial D is desirable.

In Rel2, ORDER was implemented as a relational operator (it was the simplest way to build it) and could be used anywhere a monadic relational operator was allowed, though I made no effort to promote that fact. Of course, that meant it could be used in all manner of places where it would serve no purpose. Ideally, I'd like to make it only available as the final operator to be evaluated in a relational expression.
HughDarwen
Posts: 124
Joined: Sat May 24, 2008 4:49 pm

Re: V2 features apparently no longer supported

Post by HughDarwen »

The return of FOR (the <iterate statement>) and ORDER is imminent, possibly as soon as version 0.3.10. Along with these, I'm inclined to provide a command-line switch to optionally disable such extensions, for use in pedagogical (or other) contexts where strict adherence to Tutorial D is desirable.
Many thanks. I think the FOR switch is an excellent idea. In fact, I logged on today with the intention of questioning my own request, having had second thoughts about it. But by all means go ahead with your plan.
In Rel2, ORDER was implemented as a relational operator (it was the simplest way to build it) and could be used anywhere a monadic relational operator was allowed, though I made no effort to promote that fact. Of course, that meant it could be used in all manner of places where it would serve no purpose. Ideally, I'd like to make it only available as the final operator to be evaluated in a relational expression.
That's a very good explanation!

Hugh
Dave
Site Admin
Posts: 372
Joined: Sun Nov 27, 2005 7:19 pm

Re: V2 features apparently no longer supported

Post by Dave »

I've been giving some more thought to FOR, ORDER, and the switch that can make these available or unavailable.

I'm now inclined to implement FOR and ORDER, but make them always available. I.e., not provide a switch to turn them off.

My reasoning is this:
  • Pragmatic argument: Use of a switch means Author A (with switch 'on') can produce code or whole scripts that Author B (with switch 'off') cannot run.
    • Theoretical argument: We can presume that the reason for evaluating any relational expression is to produce a relation for some purpose. Inevitably, that purpose will involve iterating the tuples in the relation. If we don't intend to iterate the tuples in a relation, then a relation is merely a meaningless "black box"; we might as well not have obtained it in the first place.
      • If Tutorial D is a database sublanguage, then we can assume that tuple iteration will typically occur on the "client side", i.e., somewhere that is of no concern to the database sublanguage. As such, ARRAY would be sufficient for the rare tuple iterations that will be needed, and the absence of FOR would encourage users to employ relational operators rather than ad-hoc iteration.
      • However, if Tutorial D is a general-purpose programming language -- which, I would argue, it is -- then there is no "client side". The result of every relational expression will involve tuple iteration. Of course, some tuple iteration will be invisible to the end-user; it will happen inside some pre-written library operator. However, another Tutorial D user had to write that library operator, and had to use tuple iteration to do it. If no pre-written library operator exists, the Tutorial D end-user will have to explicitly iterate tuples. As such, Tutorial D users inevitably deal with tuple iteration. Therefore, it makes sense to unconditionally facilitate tuple iteration rather than deprecate it.
    • Pedagogical argument: As iterating the tuples of a relation is inevitable if Tutorial D is a general-purpose programming language (see "Theoretical argument"), it makes sense to provide reasonable facilities for tuple iteration, and to teach when and where it is, or isn't, appropriate.
    As an example, the Rel backup script -- DatabaseToScript.d -- could make use of FOR and ORDER. It currently looks like this:

    Code: Select all

    // Version 0.3.1 Database Backup Script
    
    BEGIN TRANSACTION;
    
    WRITELN "/*** Rel Database Backup ***/";
    WRITELN;
    
    WRITELN "// Created in Rel Version " || (ver FROM TUPLE FROM (EXTEND sys.Version ADD (major || "." || minor || "." || revision || " " || release AS ver)));
    WRITELN "// Using DatabaseToScript version 0.3.1";
    WRITELN;
    
    WRITELN "BEGIN TRANSACTION;";
    WRITELN;
    
    VAR schema ARRAY SAME_TYPE_AS (TUPLE FROM EXTEND sys.Catalog {Name, Owner, CreationSequence, Definition, isVirtual} ADD ("var" AS objectType));
    LOAD schema FROM 
        UNION {
             EXTEND sys.Catalog {Name, Owner, CreationSequence, Definition, isVirtual} WHERE Owner <> "Rel" ADD ("var" AS objectType),
             EXTEND (sys.Operators WHERE CreatedByType="") {Name, Owner, CreationSequence, Definition} WHERE Owner <> "Rel" ADD ("operator" AS objectType, false AS isVirtual),
             EXTEND sys.Types {Name, Owner, CreationSequence, Definition} WHERE Owner <> "Rel" ADD ("type" AS objectType, false AS isVirtual)
        }
        ORDER (ASC CreationSequence);
    
    VAR i INTEGER;
    DO i := 0 TO COUNT(schema) - 1;
    BEGIN;
        VAR object INIT (schema[i]);
        VAR objectType INIT (objectType FROM object);
        VAR name INIT (Name FROM object);
        VAR definition INIT (Definition FROM object);
        CASE;
             WHEN objectType = "var" THEN
                BEGIN;
                      WRITELN "ANNOUNCE 'VAR " || name || "';";
                      WRITELN "VAR " || name || " " || definition || ";";
                      VAR isRealRelvar INIT (NOT (isVirtual FROM object));
                      IF isRealRelvar THEN
                          BEGIN;
    	     EXECUTE "IF COUNT(" || name || ") > 0 THEN BEGIN; WRITE '" || name || " := '; OUTPUT " || name || "; WRITELN ';'; END; END IF;";
                          END;
                      END IF;
                END;
             WHEN objectType = "operator" THEN
                BEGIN;
                      WRITELN "ANNOUNCE 'OPERATOR " || name || "';";
                      WRITELN definition;
                END;
             WHEN objectType = "type" THEN
                BEGIN;
                      WRITELN "ANNOUNCE 'TYPE " || name || "';";
                      WRITELN definition;
                END;
        END CASE;
        WRITELN;
    END;
    END DO;
    
    LOAD schema FROM 
             EXTEND sys.Constraints {Name, Owner, CreationSequence, Definition} WHERE Owner <> "Rel" ADD ("constraint" AS objectType, false AS isVirtual)
        ORDER (ASC CreationSequence);
    
    DO i := 0 TO COUNT(schema) - 1;
    BEGIN;
        object := schema[i];
        name := Name FROM object;
        definition := Definition FROM object;
        WRITELN "ANNOUNCE 'CONSTRAINT " || name || "';";
        WRITELN "CONSTRAINT " || name || " " || definition || ";";
        WRITELN;
    END;
    END DO;
    
    WRITELN "COMMIT;";
    WRITELN;
    
    WRITELN "/*** End of Rel Database Backup ***/";
    
    WRITELN "ANNOUNCE 'End of Script.';";
    
    Note, in particular, the rather inelegant use of temporary variables to extract the relevant attributes from the ARRAY.

    With the use of FOR and ORDER (and some other simplifications that aren't relevant here), it becomes the following:

    Code: Select all

    // Version 0.3.2 Database Backup Script
    
    WRITELN "/*** Rel Database Backup ***/";
    WRITELN;
    
    WRITELN "// Created in Rel Version " || (ver FROM TUPLE FROM (EXTEND sys.Version ADD (major || "." || minor || "." || revision || " " || release AS ver)));
    WRITELN "// Using DatabaseToScript version 0.3.2";
    WRITELN;
    
    WRITELN "BEGIN TRANSACTION;";
    WRITELN;
    
    BEGIN TRANSACTION;
    
    FOR
    	UNION {
    		EXTEND sys.Catalog {Name, Owner, CreationSequence, Definition, isVirtual} WHERE Owner <> "Rel" ADD (0 AS ProcessSequence, "var" AS objectType),
    		EXTEND (sys.Operators WHERE CreatedByType="") {Name, Owner, CreationSequence, Definition} WHERE Owner <> "Rel" ADD (0 AS ProcessSequence, "operator" AS objectType, false AS isVirtual),
    		EXTEND sys.Types {Name, Owner, CreationSequence, Definition} WHERE Owner <> "Rel" ADD (0 AS ProcessSequence, "type" AS objectType, false AS isVirtual),
    		EXTEND sys.Constraints {Name, Owner, CreationSequence, Definition} WHERE Owner <> "Rel" ADD (1 AS ProcessSequence, "constraint" AS objectType, false AS isVirtual)
    	} ORDER (ASC ProcessSequence, ASC CreationSequence);
    BEGIN;
    	WRITELN "ANNOUNCE '" || objectType || " " || Name || "';";
    	CASE;
    		WHEN objectType = "var" THEN
    			BEGIN;
    				WRITELN "VAR " || Name || " " || Definition || ";";
    				IF NOT isVirtual THEN
    					EXECUTE "IF COUNT(" || Name || ") > 0 THEN BEGIN; WRITE '" || Name || " := '; OUTPUT " || Name || "; WRITELN ';'; END; END IF;";
    				END IF;
    			END;
    		WHEN objectType = "constraint" THEN WRITELN "CONSTRAINT " || Name || " " || Definition || ";";
    		ELSE WRITELN Definition;
    	END CASE;
    	WRITELN;
    END;
    END FOR;
    
    COMMIT;
    
    WRITELN "COMMIT;";
    WRITELN;
    
    WRITELN "/*** End of Rel Database Backup ***/";
    
    WRITELN "ANNOUNCE 'End of Script.';";
    
    The above is considerably simpler and more elegant than the original script. If ORDER and FOR can be switched off, I can only provide the first version -- otherwise users who turn off FOR and ORDER can't make backups. I could provide two versions, of course, but this introduces unnecessary complexity and the need to maintain two separate but functionally equivalent pieces of code.

    The script also provides a good example of the appropriate use of FOR and ORDER; one in which tuple iteration is necessary and unavoidable. Since there are an infinite number of cases where tuple iteration will be necessary and unavoidable in a general-purpose programming language -- i.e., on the result of every relational expression evaluation for which a pre-existing operator doesn't do what we need -- FOR and ORDER should be unconditionally available. If this means students mis-use the facility and employ FOR where appropriate relational operators should be used instead... Well, for them I have plenty of 'D' and 'F' grades to give out!
    Dave
    Site Admin
    Posts: 372
    Joined: Sun Nov 27, 2005 7:19 pm

    Re: V2 features apparently no longer supported

    Post by Dave »

    As a result of discussions on the TTM list and considerable thought about ORDER() and FOR, version 0.3.12 will incorporate some changes: ORDER() now returns an ARRAY instead of a "sorted" relation. FOR now iterates the tuples of an ARRAY instead of a relation. This involves no significant syntactic changes; most existing TutorialD/Rel scripts will continue to work, but Relationland is no longer corrupted with notions of tuple iteration or tuple order.
    Post Reply