reporting pop bugs (and pvars) 
Author Message
 reporting pop bugs (and pvars)

Quote:

> Date: Sat, 25 Nov 95 20:19:20 GMT
> ...
> I read in the REAME file for Linux poplog that it is completely unsupported
> and that we should come here for assistance. That's fair enough, but what
> I want to know is: Are they interested in hearing bug reports though?

Probably. See HELP BUGFORM if you wish to report a bug. But users of
free versions can't expect answers.

Quote:
> ...When compiling the example 'wine-advisor' program from TEACH *
> PRODSYS, it gives lots of warnings about using vars where I should be using
> dlocals. When the same thing is done on the system in COGS it works fine. The
> version in COGS is still 14.51.

All sorts of students and teachers are going to complain about this
change. I think a dreadful design decision has been taken, in complete
disregard of the needs of students and teachers, who are, at present,
the main users of Pop-11, and are likely to be for the foreseeable
future.

Quote:
> I assume this is something to do with the change of default vars variable
> status in poplog 15.00 that it mentions in help news. This is fair enough, but
> shouldn't somebody update lib prodsys to take this into account???

It was perhaps tolerable to change the default procedure definition
semantics so that input and output variables now are automatically
interpreted as "lvars" if they are not declared otherwise using
"dlocal";

What was completely unacceptable was forcing warning messages on the
user wherever "vars" is used simultaneously to declare a variable as
"permanent" and dynamically local (e.g. for the pattern matcher). It's
completely stupid to try to force people to write

        vars p1 p2;

        define foo .....

                dlocal p1, p2;

                ....
        enddefine;

instead of simply

        define foo .....

                vars p1, p2;

                ....
        enddefine;

e.g. where p1 and p2 are pattern variables (e.g. as used in lib
prodsys). Nobody will want to use a language that requires so much
tiresome repetition.

The "official" answer to this is that one should not use the pattern
matcher because it is flawed (e.g. because it does not work with
"lvars" and section variables, and has some other problems - which is
why I introdced LIB FMATCHES, which only partly solves the problems
and can be hard to use in some contexts).

However, to use such an argument as a basis for making such a change
without FIRST fixing the pattern matcher is extremely insensitive and is
exactly the sort of bad decision that alienates users.

It's even worse to make the change and then leave lots of libraries and
documentation that are then broken. I feel particularly annoyed because
I have spent a lot of time over the last five years trying to improve
the usefulness of Pop-11 for teaching, by producing a lot of teaching
materials, including a new primer. In my teach files and the primer,
I've encouraged the use of "lvars" for input and output variables (so
the first part of the new semantics will not do any harm), but also
making heavy use of the pattern matcher, one of the strongest features
of Pop-11 for teaching. (E.g. it has several advantages over Prolog's
unification in teaching beginners.)

Thus I've got masses of teaching documentation using "vars" for local
declaration of pattern variables, including the Pop-11 Primer which was
included in version 15 of Poplog at the same time as the new semantics
was introduced to make the Primer incorrect! I have no intention of
wasting my time revising all that documentation, especially as there's
no telling when yet another arbitrary change will make it out of date
again.

Similarly, published books are suddenly rendered wrong because of this
change.

A partial solution is to use the compile_mode option described in the
HELP NEWS file to restore the old behaviour. But that doesn't work on
libraries! So it will not help teachers who have produced demonstration
libraries.

Anyhow, I think it is totally wrong to encourage the use of compile time
switches which drastically change the semantics of the language
constructs since this is likely to lead to cases of "borrowed" code that
don't work, and maintenance problems because people forget which mode
code is compiled in.

What a shambles!

Pop-11 used to be such a nice language. (It always had flaws, but there
were far more important things to do to fix them than this kind of
irksome tinkering.)

A partial solution:

People who don't want to use compile time switches and who insist, as I
do, on wanting to use a SINGLE local declaration for pattern variables,
can adopt the following, which declares a new autoloadable syntax word
"pvars", which can be used like "vars" for local declarations except
that (a) it does not accept initialisations, so that default values
have to be assigned after the declaration, (b) it can't be used to
re-declare an input or output local, (c) it doesn't produce the annoying
warning messages. (A later version could fix (a), and possibly (b).)

=======================================================================
/* --- The University of Birmingham 1995.  --------------------------------
 > File:            $poplocal/local/auto/pvars.p
 > Purpose:                  Introduce way of declaring local pattern variables.
 > Author:          Aaron Sloman, Nov 26 1995
 > Documentation:    TEACH * VARS_AND_LVARS, HELP * PVARS
 > Related Files:
 */

compile_mode: pop11+strict;

section;

define global constant syntax pvars;
        ;;; Like vars but suppress warning messages inside procedure definitions.
        lvars item;
        repeat
                readitem() -> item;
        quitif(item = ";");
                unless item = "," then
                        ;;; compile([vars ^item;]);
                        sysSYNTAX(item, 0, false);
                        sysLOCAL(item)
                endunless;
        endrepeat;
        ";" :: proglist -> proglist;
enddefine;

sysprotect("pvars");

endsection;
=======================================================================

Example of use:

define list_between(item1, item2, list) -> newlist;
        ;;; if item1 and item2 occur in that order in list, return a list
        ;;; of the intervening items, or false.

        pvars found;

        if list matches [== ^item1 ??found ^item2 ==] then
                found
        else
                false
        endif -> newlist;
enddefine;

The inability to initialise variables doesn't matter for pattern
variables, since one cannot assume any value will be preserved, even if
the match fails. So default values must be assigned after a match fails.

I hope that helps. The use of "pvars" should work on older vesrions of
Pop-11 as well as in V15.0 and later.

One advantage of moving towards a new declaration of pattern variables
is that it could later interact usefully with the pattern matcher.

Aaron



Thu, 14 May 1998 03:00:00 GMT  
 reporting pop bugs (and pvars)
Having noticed a complaint by John Gillespie that this newsgroup
was a bit slow, I feel entitled to respond unnecessarily to a post :-).


(snip)

Quote:
>What was completely unacceptable was forcing warning messages on the
>user wherever "vars" is used simultaneously to declare a variable as
>"permanent" and dynamically local (e.g. for the pattern matcher). It's
>completely stupid to try to force people to write

>    vars p1 p2;

>    define foo .....

>            dlocal p1, p2;

>            ....
>    enddefine;

>instead of simply

>    define foo .....

>            vars p1, p2;

>            ....
>    enddefine;

>e.g. where p1 and p2 are pattern variables (e.g. as used in lib
>prodsys). Nobody will want to use a language that requires so much
>tiresome repetition.

Sigh! Aaron, you should be forced to write in C++ for a while, and _then_
you would have reason to complain about tiresome repetition.

Last week I rewrote a small library to store lists of lists, with a trivial
amount of extra indexing. Ok, it was _slightly_ more complicated than
that, but I estimate a couple of dozen lines of pop code. Including
a small test program, in C++ it came to 310 lines of code _not_ including
reuse of a class I'd written for some other purpose. It took several
hours (including testing) to do something that would have taken half
an hour in a nice language.

So don't talk to me about tiresome repetition :-).

Actually, if you want a fast prototyping language, I don't understand why
you should have to declare any local variables at all (this criticism
applies equally to lisp and other dynamic languages). The compiler could
easily notice all the free variables in a procedure and declare them
as lvars _unless_ they were explicitly declared otherwise. Why restrict
this to input/output? Or did I misinfer from your post (I haven't seen
more recent poplog versions).

Jonathan



Fri, 15 May 1998 03:00:00 GMT  
 reporting pop bugs (and pvars)

Quote:

> [Tirade against warning messages deleted...]
> The "official" answer to this is that one should not use the pattern
> matcher because it is flawed...

I don't know where this curious idea came from. There is no "official"
opposition to the pattern matcher. It's unfortunate that the matcher
works only with permanent variables, making it more cumbersome to use
than it could be, but anyone who's happy using it is quite entitled to
carry on doing so.

Quote:
> I think a dreadful design decision has been taken... complete
> disregard... completely unacceptable... completely stupid... tiresome...
> extremely insensitive... bad decision... even worse... wasting my
> time... arbitrary change... totally wrong... irksome tinkering...

etc. etc.

Quote:
> What a shambles!

Never mind. Perhaps it's something to do with writing messages at 03:15
on a Sunday morning.

Robert
------------------------------------------------------------------------

School of Cognitive & Computing Sciences               tel: 01273 678881
University of Sussex, Brighton, BN1 9QH, UK            fax: 01273 671320
------------------------------------------------------------------------



Fri, 15 May 1998 03:00:00 GMT  
 reporting pop bugs (and pvars)

Quote:

> All sorts of students and teachers are going to complain about this
> change. I think a dreadful design decision has been taken, in complete
> disregard of the needs of students and teachers, who are, at present,
> the main users of Pop-11, and are likely to be for the foreseeable
> future.

I think it's an excellent design decision. It makes Pop11 a "serious"
language which means that more than "students and teachers" are likely to
use it.

Quote:
> What was completely unacceptable was forcing warning messages on the
> user wherever "vars" is used simultaneously to declare a variable as
> "permanent" and dynamically local (e.g. for the pattern matcher). It's
> completely stupid to try to force people to write

>    vars p1 p2;

>    define foo .....

>            dlocal p1, p2;

>            ....
>    enddefine;

Not at all. Imagine the following program:

    define f1;
            vars foo;
    enddefine;

    define f2;
            vars fooo;
            foo =>
    enddefine;

It has a bug in it (I've misstyped foo in f2). In v<15 Pop11 this compiles
completely silently (as foo and fooo are really globals now) but will fail
to work. As a novice (or even an expert) I imagine it would be very hard
to spot this typo in a morass of code. Novices would have a particularly
hard time as

        "vars are local to the procedure, yes???"

I've heard this many times times when during lab classes...

Whereas if I'm forced to do this:

    vars foo, fooo;

    define f1;
        dlocal foo;
    enddefine;

    define f2;
        dlocal fooo;
        foo =>
    enddefine;

(which is what is really going on) then I know I should keep much firmer
control on my name space (or, at least, keep a firm eye on those foos)

Quote:
> However, to use such an argument as a basis for making such a change
> without FIRST fixing the pattern matcher is extremely insensitive and is
> exactly the sort of bad decision that alienates users.

I'm with you on that one.

Quote:
> It's even worse to make the change and then leave lots of libraries and
> documentation that are then broken.

Absolutely. It wouldn't have been hard to search all the libraries and put

        compile_mode :pop11 +oldvar;

at the head of each file that used the matcher.

Quote:
> What a shambles!

Yup

Quote:
> Pop-11 used to be such a nice language. (It always had flaws, but there
> were far more important things to do to fix them than this kind of
> irksome tinkering.)

I dissagree that this is "tinkering". It was a major design flaw in the
old defaults. It was about time it was fixed.

Quote:
> A partial solution:
> People who don't want to use compile time switches and who insist, as I
> do, on wanting to use a SINGLE local declaration for pattern variables,
> can adopt the following, which declares a new autoloadable syntax word
> "pvars", which can be used like "vars" for local declarations except
> that (a) it does not accept initialisations, so that default values

No, no, no, no, no....  arrrghhhh

Please don't start pushing yet another variable type (particularly as this
isn't - it just looks like it is)!

The correct solution is to fix the matcher to recognise lvars.

All IMHO of course ;-)

Ian.



Fri, 15 May 1998 03:00:00 GMT  
 reporting pop bugs (and pvars)

Quote:
> > What a shambles!

> Never mind. Perhaps it's something to do with writing messages at 03:15
> on a Sunday morning.

Yes, and worrying about all the hassles of teaching - I have four and a
half courses this term, as a result of an administrative accident and
every little irritation like having to re-write all my teaching
documentation for no good reason makes me lose my cool...

Sorry about that.

(At least I'll be moving to the pure research role I came here for,
shortly.)

There are some good things in V15, especially the sockets package.
Speaking of which... I've converted my lib ved_gn (nntp news reader) to
use
        sys_socket_to_service(nntp_host_spec, "line");

This creates a connected socket which works like a charm with sysread
and syswrite, and noticeably faster than my previous trick of using
run_unix_program to invoke telnet. However, as someone who knows nothing
about sockets, I am puzzled by the fact that REF SOCKETS states:

For most purposes, sysread and  syswrite are sufficient for reading  and
writing sockets. However, these cannot be used

      o For out-of-band data on stream sockets.

and I have not been able to find out whether I need to take account of
that or not, since I can't find out what it means.

I experimented with sys_socket_recv instead of sysread, but it produced
different behaviour: the strings returned seemed to be different from
those produced by sysread, and consequently ved_gn stopped working. Does
anyone have a simple explanation of the conditions under which one
should use sys_socket_recv and sys_socket_send instead of sysread and
syswrite?

Aaron



Fri, 15 May 1998 03:00:00 GMT  
 reporting pop bugs (and pvars)

Quote:


> > All sorts of students and teachers are going to complain about this
> > change. I think a dreadful design decision has been taken, in complete
> > disregard of the needs of students and teachers, who are, at present,
> > the main users of Pop-11, and are likely to be for the foreseeable
> > future.

> I think it's an excellent design decision. It makes Pop11 a "serious"
> language which means that more than "students and teachers" are likely to
> use it.

Are you offering to re-write all the teaching documentation we use?
(Not just Sussex local teach files, but teaching material developed
elsewhere, into which a lot of work has gone.)

That would be very kind of you.

If not, the people who now try using Pop-11 for teaching and who
find that the language doesn't work as the teaching documentation
says it does, will certainly not want to use it. They will decide
that it is a language associated with sloppy people.

[AS]

Quote:
> > It's
> > completely stupid to try to force people to write

> >       vars p1 p2;

> >       define foo .....

> >               dlocal p1, p2;

> >               ....
> >       enddefine;
> Not at all. Imagine the following program:

>     define f1;
>        vars foo;
>     enddefine;

>     define f2;
>        vars fooo;
>        foo =>
>     enddefine;

> It has a bug in it (I've misstyped foo in f2).

Of course you can produce bugs, of all sorts, in Pop-11 or any other
useful language. The fact that you (or other people you know) happen
to produce this sort of bug very frequently doesn't meant that
everyone else needs to be forced to use a redundant syntax.

Remember: people who are worried about that kind of bug can freely
adopt the strategy of doing what you recommend, i.e. never use
"vars" locally. Making the compiler shout at you every time you do
it is what I've heard referred to in another context as "fascist"
language design.

If you want to worry about common bugs in Pop-11, stack bugs are far
more of a problem, and a collection of utilities for checking that
the stack hasn't changed when it shouldn't have would be a much more
significant contribution to program development.

Another frequent source of bugs is use of uninitialised lvars which
turn up as unexpected occurrences of 0. There should be a compile
time debugging option to initialise lvars to have undef objects with
the name of the lvar, e.g. so that a bug involving an uninitialised
lvars fred would show up as something like "<undef 'lvars fred'>".

There are lots more, all of them more important than banning the use
of vars to declare and localise simultaneously and inflicting a lot
of trouble in people who have spent several years producing
documentation.

Aaron
--
Aaron Sloman, ( http://www.cs.bham.ac.uk/~axs )
School of Computer Science, The University of Birmingham, B15 2TT, England

Phone: +44-121-414-4775 (Sec 3711)       Fax:   +44-121-414-4281



Sat, 16 May 1998 03:00:00 GMT  
 reporting pop bugs (and pvars)

Quote:

> Date: 27 Nov 1995 16:10:32 GMT
> Organization: University of Sussex


> ....
> > It's even worse to make the change and then leave lots of libraries and
> > documentation that are then broken.

> Absolutely. It wouldn't have been hard to search all the libraries and put

>    compile_mode :pop11 +oldvar;

> at the head of each file that used the matcher.

Unfortunately that would not fix all the teaching documentation. I
think I'd have to search through about 3 Megabytes of stuff and I am
far too busy with other things. Besides which there are printed
versions....

Quote:
> The correct solution is to fix the matcher to recognise lvars.

Here's a first simple shot at that. This works with the ordinary
Pop-11 matcher, but only in V15.0 because of the extension to valof.
Ignore the references to doesmatch. You can simply compile the
following and then try out the examples given.
===================================================================

/* --- The University of Birmingham 1995.  --------------------------------
 > File:            $poplocal/local/lib/readpattern.p
 > Purpose:         Read in a pattern, changing variables to idents
 >                                   Define new syntax word "!" for this purpose
 > Author:          Aaron Sloman, Nov 26 1995 (see revisions)
 > Documentation:    See HELP * DOESMATCH
 > Related Files:   LIB * DOESMATCH, LIB * FMATCHES,
 */

/*
    ![ .... ]
        creates a new type of pattern structure for use with lvars, etc.

        ![?x ison ??y]

        creates a list in which the words "x" and "y" are replaced
                by the corresponding current identifiers.

The syntactic operator "!" defined below can ONLY be followed by list
expressions, and it reads them in and replaces occurrences of variable
names after "?" or "??" with identifiers. The resulting list can be used
as a pattern to be given to either the standard pattern matcher (in
Poplog Version 15.0 onwards) or the more general matcher doesmatch,
defined in LIB * DOESMATCH (available from Birmingham).

A pattern read in after "!" works with lexical variables as they are
treated like dynamic variables.

I think it is more efficient to use dlvars than lvars, but am not sure.

Here is an example, which can be tried after compiling this file.

define list_between(item1, item2, list) -> found;
    ;;; Here found is automatically declared as lvars, as are the
    ;;; input variables in Poplog version 15, but just to make
    ;;; the point we declare it

    lvars found;

    unless list matches ![== ^item1 ??found  ^item2 ==] then
        false -> found;
    endunless;

enddefine;

;;; Now test the procedure

vars words = [a b c d e f g];

list_between("a", "g", words) =>
** [b c d e f]
list_between("d", "e", words) =>
** []
list_between("e", "c", words) =>
** <false>

It works also with restriction elements (See HELP * MATCHES).

;;; Mark and load the next two lines together.
lvars x;
[[a b c]] matches ![[== ??x:2]], x =>
** <true> [b c]

;;; Try that without "!"

;;; Or a procedure restriction
lvars n;
[a b c 3 4 d 4 5 e] matches ![== ?n == ?n:isinteger ==], n=>
** <true> 4

;;; Some test cases, showing that in vector expressions the "?" and "??"
;;; are ignored.
vars v1,v2,v3;

! [v1 ?v1 {v2 ?v2 [?v2]} [v3 ?v3]] =>
** [v1 ? <ident <undef v1>> {v2 ? v2 [? v2]} [v3 ? <ident <undef v3>>]]

lvars lv1, lv2, lv3;
! [lv1 ?lv1 {lv2 ?lv2 [?lv2]} [lv3 ?lv3]] =>
** [lv1 ? <ident <undef>> {lv2 ? lv2 [? lv2]} [lv3 ? <ident <undef>>]]

Note: if procedures using patterns created with "!" are traced, then
identifiers will show up in patterns with their current values, not the
names of the identifiers, as here:

lvars lv4 = 99, lv5 = "cat" ;
![lv4 ?lv4 lv5 ?lv5] =>
** [lv4 ? <ident 99> lv5 ? <ident cat>]

WARNING:
        Patterns should NOT contain evaluated sub-expressions quoting
        "?" or "??", e.g.

                ![== [?x b] == [?x h ^(consword("?" >< 'foo')] ==], x =>

        Finally note that patterns containing lexically scoped variables
        cannot be compiled as constants. (See LIB * COMPILE_MODE)
*/

compile_mode: pop11 +strict;

#_INCLUDE '$usepop/pop/lib/include/pop11_flags.ph'
#_INCLUDE '$usepop/pop/lib/include/vm_flags.ph'

section;

applist([! where readpattern sysPUSHQ], sysunprotect);

lvars procedure oldPUSHQ;

define lconstant Readpattern();

        ;;; Read in a list or vector expression minus the closing bracket,
        ;;; replacing words following "?", "??", and ":" with the corresponding
        ;;; identifier, in nested lists, but not inside nested vectors.

        dlvars
                was_query = false,
                in_vector = iscaller(nonsyntax {);

        ;;; It would be nice to make patterns constants where possible,
        dlocal pop_pop11_flags = pop_pop11_flags || POP11_CONSTRUCTOR_CONSTS;

        ;;; Discount lexical idents pushed in patterns. I.e. don't treat as type 3
        ;;; See REF * VMCODE, and REF * pop_vm_flags
        ;;; IS THIS SAFE ???? A.S. Nov 1995
        dlocal pop_vm_flags = pop_vm_flags || VM_DISCOUNT_LEX_PROC_PUSHES;

        dlocal oldPUSHQ;
        if isundef(oldPUSHQ) then sysPUSHQ -> oldPUSHQ endif;

        define dlocal sysPUSHQ(item);
                lvars idprops item;

                lvars invec, inlist, inpat;

                if was_query then
                        if isword(item) then
                                identprops(item) -> idprops;
                                if idprops == undef or isinteger(idprops) then
                                        sysIDENT(item)
                                else
                                        mishap(item, 1, 'UNSUITABLE ITEM AFTER ' sys_>< was_query)
                                endif
                        elseif was_query == ":" and isinteger(item) then
                                oldPUSHQ(item)
                        elseif isident(item) then
                                oldPUSHQ(item)
                        else
                                mishap(item, 1, 'NON-WORD AFTER ' sys_>< was_query)
                        endif;
                        false -> was_query
                else
                        oldPUSHQ(item);
;;;;                    Removed the colon. A.S. 29Nov95
;;;;                    if lmember(item, #_< [? ?? :] >_#) then
                        if lmember(item, #_< [? ?? ] >_#) then
                                ;;; could the next item be a query variable? Or a restriction
                                if lmember(nextreaditem(), #_<[% "]", "}", "%", "^", """ %]>_# ) then
                                        ;;; end of expression
                                        false;
                                elseif in_vector then
                                        ;;; make sure "{" is higher in calling chain than Readpattern
                                        ;;; and that current context is a list expression lower down
                                        lvars
                                                invec = iscaller(nonsyntax {),
                                                inlist = iscaller(nonsyntax [),
                                                inpat = iscaller(Readpattern);

                                        (inpat < invec) and (inlist < inpat) and item
                                elseif iscaller(nonsyntax {) then
                                        ;;; in an embedded vector
                                        false
                                else
                                        item
                                endif
                        else
                                false
                        endif ->  was_query
                endif
        enddefine;

        ;;; Read in the list expression, planting special code
        apply(nonsyntax [)
enddefine;

;;; Prepare for expressions of the form
;;;             ![ ....] where <exp>
;;; to be compiled as if written
;;;             (![ ....],  procedure; <exp> endprocedure)

global constant syntax where = pop_undef;

define constant readpattern(trywhere);
        ;;; Check that a list expression follows on proglist
        ;;; Read in its items using Readpattern to replace variable
        ;;; names with identifiers.
        lvars item, trywhere;

        readitem() -> item;
        if item /== "[" then
                mishap(item, 1, 'LIST EXPECTED AFTER "!"')
        endif;

        ;;; Now read in the list, replacing pattern variables with
        ;;; identifiers
        Readpattern();

        ;;; Check if a "where <test> " expression follows. If so compile it as
        ;;; procedure; <test> endprocedure; and push the procedure. This is for
        ;;; matchers which accept a third argument which is a boolean procedure
        ;;; to determine whether a match is successful.

        if trywhere then
                if pop11_try_nextreaditem("where") then
                        sysPROCEDURE("where",0);
                        ;;; Read expression with precedence 11. (It's debatable whether it
                        ;;; makes syntactic sense to grab operators of higher precedence
                        ;;; than "!" itself, but it needs to be left this way for backward
                        ;;; compatibility and allows and/or expresions to be included in the where
                        ;;; expression.)
                        pop11_comp_prec_expr(221,false) ->;
                        sysPUSHQ(sysENDPROCEDURE())
                endif
        else
                if nextitem() == "where" then
                        mishap('"where" FOUND WHERE NOT PERMITTED', [])
                endif
        endif;
enddefine;

define global syntax 7 ! = readpattern(%true%)
        ;;; The precedence must be less than that of doesmatch
enddefine;

applist([! readpattern where sysPUSHQ], sysprotect);

endsection;

===================================================================

Aaron
--
Aaron Sloman, ( http://www.cs.bham.ac.uk/~axs )
School of Computer Science, The University of Birmingham, B15 2TT, England

Phone: +44-121-414-4775 (Sec 3711)       Fax:   +44-121-414-4281



Sat, 16 May 1998 03:00:00 GMT  
 reporting pop bugs (and pvars)

[stuff deleted because it's not what I want to respond to, although I do
have opinions, then:]

| Another frequent source of bugs is use of uninitialised lvars which
| turn up as unexpected occurrences of 0. There should be a compile
| time debugging option to initialise lvars to have undef objects with
| the name of the lvar, e.g. so that a bug involving an uninitialised
| lvars fred would show up as something like "<undef 'lvars fred'>".

My personal and technical opinion is that this is more simply fixed by
disallowing uninitialised declarations, with an ``old code'' switch to
allow them (and force initialisation to a suitable undef value).

The occasions on which I have needed to declare a variable but do not
know what value to give it are so few and far between that I think it
would be better to disallow it. There is no loss of generality; one can
always write a junk value if one is *convinced* that the code cannot be
written any other way. There need be no loss of efficiency; the compiler
can optimise out those assignments when it can prove that the values
will ``never'' be seen.

| There are lots more, all of them more important than banning the use
| of vars to declare and localise simultaneously and inflicting a lot
| of trouble in people who have spent several years producing
| documentation.

How much code would it break (probably lots, and someone should write a
utility to find out) if ``vars'' declarations local to a procedure
invented a *new* permanent variable which it then dlocalised? Then the
intuition ``"vars" are local to a procedure, aren't they?'' would be
more accurately reflected.

Regards,    | Applicants must also have extensive knowledge of Unix,    | MIT
Kers.       | although they should have sufficiently good programming   | job
            | taste to not consider this an achievement.                | ad.



Sun, 17 May 1998 03:00:00 GMT  
 reporting pop bugs (and pvars)
: Are you offering to re-write all the teaching documentation we use?
: (Not just Sussex local teach files, but teaching material developed
: elsewhere, into which a lot of work has gone.)
: That would be very kind of you.

: If not, the people who now try using Pop-11 for teaching and who
: find that the language doesn't work as the teaching documentation
: says it does, will certainly not want to use it. They will decide
: that it is a language associated with sloppy people.

Not to mention the fact that there is no current textbook for pop11. The most
commonly used one (Ramsay et al.) doesn't even cover lvars it's that old.
Hacker types like me are happy to use on-line documentation, but a lot of
students (probably the majority) prefer to have a text-book for some unknown
reason.

At the moment the most complete single work on pop11 is Aaron Slomans primer
which is really only intended for programmers rather than beginners, and now
that is out of date too!

Richard
--

============================================================
"And when they come to  ethnically cleanse me will you speak
out will  you defend me, freedom of  expression doesn't make
it alright, {*filter*}led under foot by the rise of the right"
-----------------------PWEI - Ich Bien Ein Auslander--------

============================================================



Mon, 18 May 1998 03:00:00 GMT  
 reporting pop bugs (and pvars)

Quote:

> Date: Mon, 27 Nov 1995 13:05:37 +0000
> Organization: SofLuc Ltd
> ...
> Sigh! Aaron, you should be forced to write in C++ for a while, and _then_
> you would have reason to complain about tiresome repetition.

Thanks for the tip. I'll try to remain as far away from C++ as I
can.

Quote:
> Actually, if you want a fast prototyping language, I don't understand why
> you should have to declare any local variables at all (this criticism
> applies equally to lisp and other dynamic languages). The compiler could
> easily notice all the free variables in a procedure and declare them
> as lvars _unless_ they were explicitly declared otherwise.

That would not work for languages like Pop-11 and Scheme where there
is no difference between an identifier holding a procedure as its
value and an identifier holding anything else as its value. For the
vast majority of `free' variables in a typical procedure are names
of procedures defined outside the current procedure, and the above
suggestion would stop them working completely, unless you declared
all procedure names used in procedure P as global to P, which would
be at least as tedious as having to declare lvars.

Quote:
> Why restrict
> this to input/output? Or did I misinfer from your post (I haven't seen
> more recent poplog versions).

By far the most common use of input and output parameters is to hold
values only for the benefit of the code textually scoped within the
procedure. So it is reasonable for declaration of such things as
lvars to be the default. Occasionally one needs to locally redirect
printing in a procedure that's given a character consumer, in which
case writing

    define redirect(...., cucharout, .....);
        dlocal cucharout;
        ...

will do the trick. But that sort of thing is so rare that the lvars
default seems right. One reason we did not do that years ago was
that many people argued that it was better to have access to
variable values at run time for debugging purposes, which is hard
with lvars. But there are now better debugging tools, (LIB DE{*filter*})
and any, with current machine speeds, and the speed of incremental
compilation it is often just as simple and quick to insert trace
printing commands recompile and re-run. I often use temporary
commands of this sort of form
    [fred ^fred joe ^joe]==>
for this purpose.

Best wishes.
Aaron
--
Aaron Sloman, ( http://www.*-*-*.com/ ~axs )
School of Computer Science, The University of Birmingham, B15 2TT, England

Phone: +44-121-414-4775 (Sec 3711)       Fax:   +44-121-414-4281



Tue, 19 May 1998 03:00:00 GMT  
 reporting pop bugs (and pvars)

Quote:

> Date: 29 Nov 1995 09:28:39 -0000

[AS]
> | Another frequent source of bugs is use of uninitialised lvars which
> | turn up as unexpected occurrences of 0. There should be a compile
> | time debugging option to initialise lvars to have undef objects with
> | the name of the lvar, e.g. so that a bug involving an uninitialised
> | lvars fred would show up as something like "<undef 'lvars fred'>".

> My personal and technical opinion is that this is more simply fixed by
> disallowing uninitialised declarations, with an ``old code'' switch to
> allow them (and force initialisation to a suitable undef value).

> The occasions on which I have needed to declare a variable but do not
> know what value to give it are so few and far between that I think it
> would be better to disallow it.

That's because you don't use a pattern matcher ????

Anyhow, this sort of thing depends on one's programming style. Some
people like to have all their variable declarations near the top of
each procedure so that gives an immediate indication of some of
what's going on in the procedure, and also makes it easy to check
which variables are and are not used in the procedure. On the other
hand I find myself increasingly writing at arbitrary locations in
procedures things like

    lvars xxx = fff(ppp,qqq,rrr....);

What's not so natural perhaps is to use that in a loop where a
variable gets a value every time round the loop. For it might
suggest to some people that something more complex than an
assignment is happening each time round the loop. On the other hand
if you understand that
    lvars xxx = ....;

is doing TWO things at once, namely (1) at compile time telling the
compiler something about xxx and (2) at run time doing an assignment
to xxx, then there's no worry about (1) being done each time round
the loop.

Of course, people who don't like "vars" to do TWO things in a
procedure body will probably object to initialised declarations of
lvars, on similar grounds - it uses one instruction to do two
totally different things?

Aaron

There is no loss of generality; one can

- Show quoted text -

Quote:
> always write a junk value if one is *convinced* that the code cannot be
> written any other way. There need be no loss of efficiency; the compiler
> can optimise out those assignments when it can prove that the values
> will ``never'' be seen.

> | There are lots more, all of them more important than banning the use
> | of vars to declare and localise simultaneously and inflicting a lot
> | of trouble in people who have spent several years producing
> | documentation.

> How much code would it break (probably lots, and someone should write a                  
> utility to find out) if ``vars'' declarations local to a procedure                  
> invented a *new* permanent variable which it then dlocalised? Then the                  
> intuition ``"vars" are local to a procedure, aren't they?'' would be                  
> more accurately reflected.                  

> Regards,    | Applicants must also have extensive knowledge of Unix,    | MIT                  
> Kers.       | although they should have sufficiently good programming   | job                  
>             | taste to not consider this an achievement.                | ad.                  

--
Aaron Sloman, ( http://www.cs.bham.ac.uk/~axs )
School of Computer Science, The University of Birmingham, B15 2TT, England

Phone: +44-121-414-4775 (Sec 3711)       Fax:   +44-121-414-4281


Tue, 19 May 1998 03:00:00 GMT  
 reporting pop bugs (and pvars)

Quote:
Aaron writes:


|
| > Date: 29 Nov 1995 09:28:39 -0000
| >
| [AS]
| > | Another frequent source of bugs is use of uninitialised lvars which
| > | turn up as unexpected occurrences of 0. There should be a compile
| > | time debugging option to initialise lvars to have undef objects with
| > | the name of the lvar, e.g. so that a bug involving an uninitialised
| > | lvars fred would show up as something like "<undef 'lvars fred'>".
| >
| > My personal and technical opinion is that this is more simply fixed by
| > disallowing uninitialised declarations, with an ``old code'' switch to
| > allow them (and force initialisation to a suitable undef value).
| >
| > The occasions on which I have needed to declare a variable but do not
| > know what value to give it are so few and far between that I think it
| > would be better to disallow it.
|
| That's because you don't use a pattern matcher ????

Good catch.

It's true that I don't use the matcher; I've rarely found anywhere where
it would do anything useful for me. This may just reflect the kind of
programs I write, or the way I want to write them.

[I must revisit my recent Magic-cards-nad-rulings-to-html converter;
the matcher might have been useful there ...]

But my functional programming background would drive me to use a matcher
that didn't update any (non-private) variables at all; it would *deliver
a result*. This seems more natural to me (I realise this says a lot
about my background and style, rather than being a Law of Programming).
Then the results of a match could be used in expressions without having
to introduce unnecessary variables.

| Anyhow, this sort of thing depends on one's programming style. Some
| people like to have all their variable declarations near the top of
| each procedure so that gives an immediate indication of some of
| what's going on in the procedure,

Is *that* why they do it? I find it makes the code incomprehensible.

| and also makes it easy to check which variables are and are not used
| in the procedure.

Why would one want to check? Assuming that they're genuine locals
(which, I think, will cover almost all the cases), then they're used if
they're used, and not if they're not, and the outside would doesn't
care.

| On the other
| hand I find myself increasingly writing at arbitrary locations in
| procedures things like
|
|     lvars xxx = fff(ppp,qqq,rrr....);

Well, of course. I've being doing that for years.

| What's not so natural perhaps is to use that in a loop where a
| variable gets a value every time round the loop. For it might
| suggest to some people that something more complex than an
| assignment is happening each time round the loop.

That depends on what you think is happening. Something more complex *is*
happening each time round the loop; a variable comes into being, and is
initialised (or rather, a value is computed and named).

| On the other hand if you understand that
|     lvars xxx = ....;
|
| is doing TWO things at once, namely (1) at compile time telling the
| compiler something about xxx and (2) at run time doing an assignment
| to xxx, then there's no worry about (1) being done each time round
| the loop.

I think the problem here is a Pop problem, that loops are not properly
scoped, so that variables introduced in a loop are visible afterwards.
If they were not, it would be clear that ``the'' variable *did* appear
and disappear each time round, and there'd be nothing wrong with that.

| Of course, people who don't like "vars" to do TWO things in a
| procedure body will probably object to initialised declarations of
| lvars, on similar grounds - it uses one instruction to do two
| totally different things?

For ``vars'' this is more the case, although one can claim that the
``vars'' does one thing and the ``='' another. In any case, doing
several things at once is hardly a potent criticism.

Regards,    | "You're better off  not dreaming of  the things to come;
Kers.       | Dreams  are always ending  far too soon." - Caravan.



Tue, 19 May 1998 03:00:00 GMT  
 reporting pop bugs (and pvars)

Quote:
Jonathan writes:
> Having noticed a complaint by John Gillespie that this newsgroup
> was a bit slow, I feel entitled to respond unnecessarily to a post :-).

Absolutely!  It's nice to get some heat and smoke going.  What?  You
want light as well?!  Some people are never satisfied ...

Quote:
> Actually, if you want a fast prototyping language, I don't understand why
> you should have to declare any local variables at all (this criticism
> applies equally to lisp and other dynamic languages). The compiler could
> easily notice all the free variables in a procedure and declare them
> as lvars _unless_ they were explicitly declared otherwise.

Duh.  I think this is just poorly worded.  Here's my spin on
this issue and, I suspect, something similar to Jonathan's
view.

There are certain syntactic contexts (input/output locals, loop
variables) which name variables that, almost always, are declared
the same way, as a lexical local.  For example, in the code fragments
below, the variable "x" is almost always going to be declared
as an "lvars".

    define foo( x ); ...
    for x in ....
    ... fmatches [ ... ?x ... ] ...

If these contexts were to be considered to be implicit declarations of
the usual type, the number of explicit declarations would be significantly
reduced and the code would be less error-prone and easier to understand.
I think that Jonathan is saying that with the appropriate default
declarations and appropriate syntactic constructs, the need for explicit
local declarations disappears - and that is quite right.

The recent change to Pop11, that of making input/output locals be
implicitly declared as "lvars" goes part of the way towards this.
And because I believe that this is a highly desirable change, I
am pleased to see it.  Aaron's complaints about the change are, I
think, not so much about the merit of the change but about the
migration policy that was adopted - and I would agree with that.
But the change itself is wonderful.  (The business about forbidding
local vars declarations is unfortunate and, from what I can gather,
likely to be put into the right state.   This is NOT a reversal to
the original position which was a complete disaster and totally
unsatisfactory to everyone.)

Chris Dollin's Pepper language, a variant of Pop11, goes much further
and, I think, demonstrates just how much room for improvement there
is.  Personally, I would like to see at least 4 more ideas
incorporated into Pop11 in the short term.  (However, rather than use
a compile-mode to distinguish it, I would like to see a ".pop"
extension and a subsystem.  I think that's a much superior route
and likely to cause much less hassle.)

Firstly, I think that for loops should implicitly declare the
loop variables.  (And to make this work, we need explicit "free"
declarations as Jonathan suggests.)  Secondly, the for-loop
syntax should be rationalised to eliminate the completely pointless
exceptions.  Thirdly, all block constructs (especially loops and
if expressions) should introduce lexical blocks.  And fourth, and
most important of all, implicitly declared variables should be
made non-assignable.  The missing category of contant-lexical
variables is sorely missed in Pop11.  (N.B. lconstant is
an entirely different concept, despite the name.)

All these suggestions need justifying and I don't propose to
do that here since the arguments are extensive.  However, all these
ideas are present in Pepper and this is a demonstration of how
they all play together marvellously to create a simpler language
that is (in my view) easier, safer and more natural to program
with.  

Steve



Wed, 20 May 1998 03:00:00 GMT  
 
 [ 22 post ]  Go to page: [1] [2]

 Relevant Pages 

1. reporting pop bugs.

2. declaring CM pvars as classes

3. Tcl8.0p1 error reporting bug report and patches

4. Reporting bugs to the net (was Re: Another bug in DEC Fortran)

5. BUG REPORT: Color bugs in tk4.0???

6. I can't find my bug report in the Scriptics Bug DB.

7. expr bug report not a bug

8. POP Bug or Lamer Ignornace?

9. comp.lang.pop (and pop-forum) FAQ available in html

10. comp.lang.pop (and pop-forum) FAQ available in html

11. comp.lang.pop -> pop-forum gateway

12. comp.lang.pop and pop-forum gateway

 

 
Powered by phpBB® Forum Software