[ Usenet FAQs | Search | Web FAQs | Documents | RFC Index ]
    Search the FAQ Archives


FAQ: BETA Programming Language (version 1.11 - 08 Dec 97)


From: jlk@daimi.aau.dk (Jorgen Lindskov Knudsen)
Newsgroups: comp.lang.beta
Subject: FAQ: BETA Programming Language (version 1.11 - 08 Dec 97)
Date: 15 Dec 1997 10:49:19 GMT
Message-ID: <6731vf$la1$1@nf.aau.dk>
Reply-To: beta-language-faq@mjolner.dk
Summary: Frequently Asked Questions (with answers) for
         the object-oriented programming language BETA
Archive-name: beta-language-faq
Last-modified: Dec 8, 1997
Version: 1.11 (last public version 1.10)
Maintained-by: Jorgen Lindskov Knudsen <jlk@daimi.aau.dk>

BETA: Frequently Asked Questions (FAQ)

----------------------------------------------------------------------------
This question-and-answer list is posted regularly to the BETA mail group,
and to the Usenet newsgroups comp.lang.beta, comp.answers, and news.answers.

Please send corrections, additions and comments to Jorgen Lindskov Knudsen
(jlk@daimi.aau.dk).

This information is abstracted and condensed from the posts of many
different contributors. No guarantees are made regarding its accuracy.
----------------------------------------------------------------------------
There are several ways to get this document:

   * E-mail: The FAQ can be obtained by sending a message to
     info@mjolner.com with the following message body:

        send BETA beta-language-faq

   * FTP: The FAQ can be fetched via anonymous ftp from ftp.daimi.aau.dk as

        pub/beta/faq/beta-language-faq.txt

   * WWW: The FAQ is available in hypertextualized form on the World Wide
     Web at URL

        http://www.daimi.aau.dk/~beta/FAQ.

     (This site always contains the most recent version.)

More information on BETA can be found on:

   * The BETA Home Page:

        http://www.daimi.aau.dk/~beta/

   * The Mjolner System Home Page:

        http://www.mjolner.com/

----------------------------------------------------------------------------

Changes since version 1.10

New entries:

   * Why does my guienvsystemenv program stop at startup? (B09)
   * What is the maximum length of a BETA identifier? (L24)
   * What is the exact qualification rules for nested patterns? (L25)
   * Does BETA work on Motorola machines? (M05)
   * Known bugs, limitations and inconveniences in release 4.0.2 (W06)
   * Known bugs, limitations and inconveniences in release 4.1 (W07)
   * What are the system requirements to run BETA on HPUX workstations?
     (HP01)
   * What are the system requirements to run BETA on Linux machines? (Lx01)
   * Why does GuiEnv demos segmentation fail? [error in r4.0 & r4.0.1]
     (Lx03)
   * What are the system requirements to run BETA on Sun workstations?
     (Sun01)
   * Using BETA on IRIX 6 machines(SG04)
   * How to format BETA programs in LaTeX? (Q19)
   * xxx? (ref)
   * New features in version 5.3 of the Compiler (C14.1)

Changed entries:

   * What are the system requirements to run BETA on Macintosh? (M01)
   * What is MPW. Where do I get it? (M02)
   * Does BETA work on PowerPC machines? (M04)
   * SDK Requirements for Windows 95 or Windows NT (W02) [Updated info
     related to r4.0.1]
   * Limitations, bugs and inconveniences (SG05)
   * Disclaimer (Slow startup of tools) (SG06)
   * xxx? (ref)

Removed entries:

   * System Requirements for specific platforms (old Q19)

In addition, a number of minor changes and corrections have been made to
other entries.
----------------------------------------------------------------------------

Contents

   * Part I: Frequently Asked Questions
        o Q01) What is BETA?
        o Q02) Where did BETA come from?
        o Q03) What BETA products are available?
        o Q04) Are there any school or student discounts?
        o Q05) Is BETA available in the public domain?
        o Q06) What books are available for learning about BETA?
        o Q07) Does an introduction to BETA besides the BETA book exist?
        o Q08) Are any magazines or newsletters concerning BETA available?
        o Q09) Are there any user groups related to BETA?
        o Q10) Are there any mailing lists related to BETA?
        o Q11) Are there any newsgroups related to BETA?
        o Q12) Is there an archive of BETA postings?
        o Q13) Are there any conferences for BETA users?
        o Q14) Is BETA available on PC, Mac, NeXT, Amiga, Atari, ...?
        o Q15) Are there standards for the BETA language?
        o Q16) What is Mjolner, Sif, Valhalla, Bifrost, Yggdrasil, etc.?
        o Q17) Is it possible to obtain an evaluation version of the Mjolner
          System?
        o Q18) What is the origin of the name BETA?
        o Q19) How to format BETA programs in LaTeX?
   * Part II: Language Issues
        o L01) What features do BETA have?
        o L02) What changes have been made to the BETA language definition?
        o L03) How do I deal with concurrency in BETA?
        o L04) How do I deal with persistence in BETA?
        o L05) How do I deal with distribution in BETA?
        o L06) How do I deal with exception handling in BETA?
        o L07) Can classes be treated as first-order elements in BETA?
        o L08) What about garbage collection in BETA?
        o L09) How do I create a "parameterized class"?
        o L10) What is the difference between a virtual binding, a further
          binding and a final binding (i.e. between :<, ::<, and ::)?
        o L11) What about invariants in BETA?
        o L12) What about change propagation in BETA?
        o L13) What about futures in BETA?
        o L14) Why can't local variables be accessed in INNER?
        o L15) How do I implement a copy (or clone) operation?
        o L16) Why doesn't BETA have multiple inheritance?
        o L17) What is the rationale behind the syntax of BETA?
        o L18) How do the scope rules of BETA actually work?
        o L19) What is a pattern?
        o L20) Are identifiers and keyworks case-sensitive in BETA?
        o L21) What characters are allowed in BETA identifiers?
        o L22) What is the exact semantics of leave P and restart P, when P
          is the name of a pattern?
        o L23) What is the BETA lexem syntax?
        o L24) What is the maximum length of a BETA identifier?
        o L25) What is the exact qualification rules for nested patterns?
   * Part III: Environment Issues
        o E01) What is the Mjolner System?
        o E02) What does the Mjolner System contain?
        o E03) What libraries come with the Mjolner System?
        o E04) What frameworks come with the Mjolner System?
        o E05) What tools come with the Mjolner System?
        o E06) Does a beta-mode for Emacs exist?
   * Part IV: Specific Issues
        o Section I: The Fragment System
             + F01) What is the purpose of the fragment system?
             + F02) How do I separate implementation and specification code?
             + F03) How do I work around "*****Only pattern-declarations may
               appear in a fragment of category 'attributes'"?
             + F04) Why can't I have instances in attributes-fragments?
             + F05) Why can't I have virtual declarations/bindings in
               attributes-fragments?
             + F06) What are the differences between the INCLUDE facilities
               of BETA and C?
             + F07) Why doesn't the compiler complain about a missing inner
               in a body fragment?
             + F08) Can <<Attributes>> be used instead of <<AttributeDecl>>?
        o Section II: The X libraries
             + X01) Why does my label widget sometimes get the attribute
               name as label-string, and sometimes not?
             + X02) Why do I get the error "There must be only one non-shell
               widget which is son of Toplevel"?
             + X03) How do I get a separate window for my widget?
             + X04) Why do I get the error "clockWidgetClass: undefined"
               when linking my AwEnv program? [corrected in r4.0]
             + X05) Why do I get the error "Error: NULL ArgVal in
               XtGetValues" when executing my Xt program? [corrected in
               r4.0]
             + X06) How do I set font information in MotifStrings?
             + X07) Resource specification errors in Xt/v1.9
        o Section III: The BETA compiler
             + C01) What is the execution speed of BETA programs?
             + C02) How do I get rid of the warning: "A run-time
               qualification check will be inserted here"?
             + C03) What *does* that Qua-check warning mean, anyway?
             + C04) How do I work around "*****Repetition of non simple
               patterns is not implemented"? [corrected in r4.0]
             + C05) How do I work around "Labeled imperative not
               implemented"?
             + C06) Why does a BETA program called test.bet cause problems
               on some UNIX installations?
             + C07) How do I disable qualification check warnings?
             + C08) What is the difference between P and &P?
             + C09) What does "virtual prefix not implemented" mean?
               [corrected in r4.0]
             + C10) What should I do if the compiler prints "Please report
               the error to Mjolner Informatics" and stops?
             + C11) What are the known errors the compiler?
                  + C11.1) Bugs in version 5.0
                  + C11.2) Bugs in version 5.1
                  + C11.3) Bugs in version 5.2
             + C12) Tracing the work of compiler?
             + C13) Problem with floating point expressions in connection
               with repetitions
             + C14) New features introduced in the Compiler
                  + C14.1) New features in version 5.3 of the Compiler
                  + C14.2) New features in version 5.2 of the Compiler
                  + C14.3) New features in version 5.1 of the Compiler
                  + C14.4) New features in version 5.0 of the Compiler
        o Section IV: The Basic libraries
             + B01) How do you compare text strings in BETA?
             + B02) How do you read and write text in BETA?
             + B03) Why does getInt followed by getLine not necessarily work
               as expected?
             + B04) What is the rationale behind the Mjolner System file
               directory structures?
             + B05) What do the (* idx+ *), etc. comments mean?
             + B06) Error in v1.4/seqContainer.bet? [corrected in r4.0]
             + B07) Error in v1.4/regexp.bet? [corrected in r4.0]
             + B08) Error in v1.4/basicsystemenv.bet? [corrected in r4.0]
             + B09) Why does my guienvsystemenv program stop at startup?
   * Part V: Platform Specific Issues
        o Section V: BETA on Macintosh
             + M01) What are the system requirements to run BETA on
               Macintosh?
             + M02) What is MPW. Where do I get it?
             + M03) Do I need a floating point unit to use BETA?
             + M04) Does BETA work on PowerPC machines?
             + M05) Does BETA work on Motorola machines?
             + M06) Known bugs, limitations and inconveniences in release
               4.0.2
             + M07) Known bugs, limitations and inconveniences in release
               4.1
        o Section VI: BETA on Windows 95 and Windows NT
             + W01) What are the system requirements to run BETA on Windows
               95 and Windows NT?
             + W02) SDK Requirements for Windows 95 or Windows NT
             + W03) Why do I need a MAKE facility?
             + W04) Error in directory scan using Borland SDK? [corrected in
               r4.0]
             + W05) Make-error for lazyref_gc.c using Borland SDK?
               [corrected in r4.0.2]
             + W06) Known bugs, limitations and inconveniences in release
               4.0.2
        o Section VII: BETA on HPUX
             + HP01) What are the system requirements to run BETA on HPUX
               workstations?
             + HP02) Why do some callbacks cause "Illegal Instruction" on
               hpux9pa (using v5.0 of the compiler)?
        o Section VIII: BETA on Linux
             + Lx01) What are the system requirements to run BETA on Linux
               machines?
             + Lx02) How to make the BETA compiler version 5.0/5.1 work with
               Linux ELF libraries [corrected in r4.0]
             + Lx03) Why does GuiEnv demos segmentation fail? [error in r4.0
               & r4.0.1]
        o Section IX: BETA on Silicon Graphics
             + SG01) What are the system requirements to run BETA on Silicon
               Graphics workstations?
             + SG02) Gnu C Compiler gcc not supported
             + SG03) Remember to set LD_LIBRARY_PATH
             + SG04) Using BETA on IRIX 6 machines
             + SG05) Limitations, bugs and inconveniences
             + SG06) Disclaimer (Slow startup of tools)
        o Section X: BETA on Sun workstations
             + Sun01) What are the system requirements to run BETA on Sun
               workstations?

----------------------------------------------------------------------------

PART I: Frequently Asked Questions

----------------------------------------------------------------------------

Q01) What is BETA?

BETA is a modern object-oriented language with comprehensive facilities for
procedural and functional programming. BETA has powerful abstraction
mechanisms than provide excellent support for design and implementation,
including data definition for persistent data. The abstraction mechanisms
include support for identification of objects, classification, and
composition. BETA is a strongly typed language (like Simula, Eiffel, and
C++), with most type checking being carried out at compile-time.

The abstraction mechanisms include class, procedure, function, coroutine,
process, exception, and many more, all unified into the ultimate abstraction
mechanism: the pattern. In addition to the pattern, BETA has subpattern,
virtual pattern, and pattern variable.

BETA does not only allow for passive objects as in Smalltalk, C++, and
Eiffel. BETA objects may also act as coroutines, making it possible to model
alternating sequential processes and quasi-parallel processes. BETA
coroutines may also be executed concurrently with supported facilities for
synchronization and communication, including monitors and rendezvous
communication.
----------------------------------------------------------------------------

Q02) Where did BETA come from?

BETA originates from the Scandinavian school of object-orientation where the
first object-oriented language Simula was developed. Object-oriented
programming originated with the Simula languages developed at the Norwegian
Computing Center, Oslo, in the 1960s. The first Simula language, Simula I,
was intended for writing simulation programs. Simula I was later used as a
basis for defining a general-purpose programming language, Simula 67 (later
renamed to Simula). Simula has been used by a relatively small community for
a number of years, although it has had a major impact on research in
computer science.

The BETA language development process started out in 1975 with the aim to
develop concepts, constructs and tools for programming, partly based on the
Simula languages. The BETA language team consists of Bent Bruun Kristensen,
Birger Moller-Pedersen, Ole Lehrmann Madsen, and Kristen Nygaard. Kristen
Nygaard was one of the two original designers of the Simula languages.
----------------------------------------------------------------------------

Q03) What BETA products and services are available?

Currently there is only one supplier of BETA products, namely Mjolner
Informatics, who is marketing an entire development system (the Mjolner
System) based on the BETA language.

In the US, the MacTech Magazine Mail Store is the distributor of the Mjolner
System.

In France and the French parts of Belgium and Switzerland, the Mjolner
System is distributed by BCDL-ObjectLand.

In UK, the Mjolner System is distributed by InterGlossa.

Mjolner Informatics offers the Mjolner System technology to other commercial
organizations who are interested in building BETA products (such as
alternative development systems), or who are interested in developing
value-added products for the Mjolner System. This offer is based on
licensing of the implementation of the existing system (including source
code, if needed).

     Mjolner Informatics
          Gustav Wieds Vej 10
          DK-8000 Aarhus C
          Denmark
          Phone: +45 86 12 20 00
          Fax: +45 86 12 20 22
          E-mail: info@mjolner.com
          WWW: http://www.mjolner.com
          WWW Sales: http://www.mjolner.com/warehouse/

     MacTech Magazine, Mail Order Store
          Xplain Corporation
          P.O. Box 250055
          1617 Pontius Avenue, 2nd Floor
          Los Angeles, CA 90025-9555, USA
          Phone: +1 310 575 4343
          Fax: +1 310 575 0925
          AppleLink: MACTECHMAG
          CompuServe: 71333,1064
          Internet: neil_ticktin@xplain.com
          America Online: MACTECHMAG
          GEnie: MACTECHMAG

     BCDL-ObjectLand
          26 rue Jules Lanery
          F-59240 Dunkerque
          France
          Phone: +33 28 66 53 00
          Fax: +33 28 66 53 01
          E-mail: ObjectLand@netinfo.fr
          WWW: http://www.netinfo.fr/ObjectLand/ (Journal of
          ObjectLand, the newsletter)
          WWW: http://www.netinfo.fr/BCDL/ (Home Page of BCDL)

     InterGlossa Ltd
          59, Alexandra Road
          Reading RG1 5PG
          UK
          Phone: +44 1734 561919
          Fax: +44 1734 561920
          E-mail: Tom.Lake@glossa.co.uk
          WWW: http://www.glossa.co.uk

----------------------------------------------------------------------------

Q04) Are there any school or student discounts?

Mjolner Informatics offers substantial discounts for educational purposes
(e.g. 45/%}. Also included in educational site licenses are attractive
offers for the institutions to freely distribute Personal Edition versions
of the system to those students, following the cources, in which BETA is
used.

Generally, the Personal Edition versions of the system is freely available
directly from Mjolner Informatics. Visit the download area for more
information.
----------------------------------------------------------------------------

Q05) Is BETA available in the public domain?

The BETA language definition is in the public domain. A reference manual on
the language is in progress (release-date not fixed yet).

The Personal Edition versions of the system is freely available from Mjolner
Informatics. Visit the download area for more information.

Kai Petzke has initiated a project for writing a freeware compiler for BETA.
It is implemented as a translator of BETA to C. For more information and to
download a working copy of the compiler, that understands most of BETA's
grammatical terms, see the web page:
http://troubadix.physik.tu-berlin.de/~petz0433/beta/eindex.html.
----------------------------------------------------------------------------

Q06) What books are available for learning about BETA?

The ultimate source of information on the BETA language is:

     Ole Lehrmann Madsen, Birger Moller-Pedersen, Kristen Nygaard:
     "Object-Oriented Programming in the BETA Programming Language"
     Addison-Wesley and ACM Press, 1993
     ISBN 0-201-62430-3

An german introduction to BETA can be found in the book:

     Ernst Erich Doberkat, Stefan Dißmann:
     "Einführung in die objectkorientierte Programmierung mit BETA"
     Addison-Wesley-Longman, 1996
     ISBN 3-8273-1026-1

The Mjolner System and the BETA language is also extensively described in
the book:

     Jorgen Lindskov Knudsen, Mats Lofgren, Ole Lehrmann Madsen, Boris
     Magnusson (eds.):
     "Object-Oriented Environments: The Mjolner Approach"
     Prentice-Hall, 1993
     ISBN 0-13-009291-6

----------------------------------------------------------------------------

Q07) Does an introduction to BETA besides the BETA book exist?

The previously mentioned book: "Object-Oriented Environments: The Mjolner
Approach" contains an introductory chapter on the BETA language.

Besides, various current activities indicate that introductory material in
the form of tutorials are in the pipeline.

See also question Q08.
----------------------------------------------------------------------------

Q08) Are any magazines or newsletters concerning BETA available?

The BETA language has been presented in several conference papers, including
the OOPSLA, ECOOP, and TOOLS conferences. BETA has also been described in a
couple of articles in Dr. Dobb's Journal, #206, October 1993. Furthermore,
Communications of the ACM, Vol. 37, No. 2, February 1994, is a special issue
on Hypermedia, including three papers on the use of the Mjolner System (and
the BETA language) for building hypermedia systems.

Mjolner Informatics produces a quarterly 8-page newsletter called "Mjolner
BETA Newsletter".
----------------------------------------------------------------------------

Q09) Are there any user groups related to BETA?

Yes, there is a user group hosted by Mjolner Informatics. The user group is
primarily organized around the BETA mailing list: usergroup@mjolner.com

The BETA user group is one of the important sources of information on the
developments of the Mjolner System, and an important source of information
to Mjolner Informatics on the users' expectations for future developments.

See also question Q10.
----------------------------------------------------------------------------

Q10) Are there any mailing lists related to BETA?

There is a mailing list for BETA, organized by Mjolner Informatics:

   usergroup@mjolner.com

In order to be added to, or removed from the mailing list, please send a
mail to:

   usergroup-request@mjolner.com

(Do not send subscription requests to usergroup@mjolner.com as they will be
mirrored onto comp.lang.beta.)

Mail sent to the mailing list is automatically forwarded to the
comp.lang.beta newsgroup and news posted on the newsgroup is automatically
forwarded (moderated) to the mailing list.
----------------------------------------------------------------------------

Q11) Are there any newsgroups related to BETA?

The comp.lang.beta Usenet newsgroup is available for discussing issues
related to the BETA language.

Postings to comp.lang.beta are automatically forwarded (moderated) to the
usergroup@mjolner.com mailing list and mails to the mailing list is
automatically posted to the newsgroup.
----------------------------------------------------------------------------

Q12) Is there an archive of BETA postings?

Mjolner Informatics keeps an archive of the BETA mailing list.

In addition, the University of Aarhus maintains an archive of all postings
to the comp.lang.beta newsgroup, available at:

   * http://www.daimi.aau.dk/~beta/News/
   * ftp://ftp.daimi.aau.dk/pub/beta/comp.lang.beta

The former is updated daily, the latter annually.
----------------------------------------------------------------------------

Q13) Are there any conferences for BETA users?

There are no conferences devoted entirely to the BETA language and
development system. BETA shares the spotlight with other object-oriented
languages including C++, Eiffel, and Smalltalk in conferences like:

TOOLS
     the major international conference devoted to the applications of
     Object-Oriented technology.
ECOOP
     the European Conference on Object-Oriented Programming.
OOPSLA
     the major international conference on Object-Oriented Programming,
     Systems, Languages, and Applications.

----------------------------------------------------------------------------

Q14) Is BETA available on PC, Mac, NeXT, Amiga, Atari, ...?

Currently, BETA is available on UNIX workstations, on PowerPC Macintosh and
on Intel-based PCs.

On UNIX, the platforms supported are: Sun Sparc (Solaris), HP 9000 (series
700) and Silicon Graphics MIPS machines running IRIX 5.3 or 6.

Mjolner System is also available for Linux (386/486/Pentium). Linux is a
very popular freely available UNIX implementation for Intel processors (for
more information, see the Linux FAQ).

Mjolner System is also available for Windows 95 and Windows NT
(386/486/Pentium).

There are no current plans to port the Mjolner System to neither DOS nor
Windows 3.1 due to the 16-bit addressing and 8-character filename
limitations.

Although not officially confirmed by Mjolner Informatics, users of the
Mjolner System have reported that the Mjolner System can be effectively used
on Amiga 4000 machines under the MacOS simulator, with an execution speed
reported to be comparable to that of an HP 9000/425 workstation.

The following additional info is kindly supplied by Juha Makinen
<Juha.Makinen@cs.Helsinki.FI>:

     Actually this program is an emulator, because it can run native
     Apple Macintosh 680x0-code in Amigas. The name of this program is
     an Emplant and it is a 99,9% compatible Apple Macintosh emulator.
     It emulates the Machintosh (like Quadra) even faster than an
     equivalent Macintosh is running with the same processor and
     clock-speed. (This is due to separate graphics, I/O etc.
     co-processors found on motherboard of the Amiga. Some programs
     show two times better performance.)

     The program is an multi-platform -emulator and can also multitask
     another emulation and/or AmigaOS on the backgroud. There is a
     rival (Amax IV) for this emulation-program, but it is only 99,5%
     Macintosh-compatible and is not supported as widely as this one
     is. (I'm not sure which one the original author refers to, but I'm
     quite sure that you can run Beta-compiler on Emplant with
     Macintosh Emulation. Every program which run in original Quadra
     should run on Emplant.)

     And as an addition, you can run Emplant-emulator also on the Amiga
     3000 (and A2000 if you have a processor-card with MMU).

----------------------------------------------------------------------------

Q15) Are there standards for the BETA language?

The definition of the BETA language is in the public domain. This definition
is controlled by the original designers of the BETA language: Bent Bruun
Kristensen, Ole Lehrmann Madsen, Birger Moller-Pedersen, and Kristen
Nygaard. This means that anyone or any company may create a compiler,
interpreter, or whatever having to do with BETA.

Currently, no language definition document exist. Work is in progress to
write this language definition document. The definition will be given in
strict natural language.

See section Q06 and L02 for information on available language descriptions
and latest changes to the language.

The BETA and the Mjolner System trademarks are owned and controlled by
Mjolner Informatics.
----------------------------------------------------------------------------

Q16) What is Mjolner, Sif, Valhalla, Bifrost, Yggdrasil, etc.?

Many have wondered about the origins of the strange product names used for
parts of the Mjolner System. Due to the origin of the Mjolner BETA System,
many of the components of the system bear Nordic names. These Nordic names
originate from the Nordic Mythology, and are thus names within the common
cultural background of people in the entire Nordic region:

Mjolner:
     is the name of the hammer of the god Thor. According to the Mythology,
     this hammer is the perfect tool that cannot fail, that grows with the
     task, and always returns to the hand of Thor if he throws it at
     something. Finally about the pronunciation of Mjolner. For English
     speaking people, the "spelling of the pronunciation" could be:
     "Myolner" or "Myulner", and for French speaking people it could be:
     "Mieulnor".
Yggdrasil:
     is the name of the Tree of the World, the ash tree of which the crown
     covers the whole world. The tree gets it power from the gods, from the
     evil giants, and from the kingdom of the dead. Everything in the world
     happens under the mighty crown of Yggdrasil. Yggdrasil is the name of
     the metaprogramming system.
Bifrost:
     is the name of the luminous bridge, the rainbow, that leads from
     Midgaard to Asgaard. Midgaard is the place where the human beings live,
     and Asgaard is the habitat of the Gods in the middle of the world.
     Bifrost is the name of the graphics system.
Valhalla:
     is the name of Odin's hall to where all dead warriors come when they
     have fallen as heroes on the battlefield. Valhalla is the name of the
     source-level debugger.
Sif:
     is the name of the wife of Thor. Sif is famous for her golden hair. Sif
     is the name of the hyper structure editor.
Freja:
     is the name of the goddess of love. She lives in Folkvang and is the
     most beautiful of all women in Asgaard. She owns the golden piece of
     jewelry Brisingemen. Freja is the name of the CASE tool.
Frigg:
     is the name of the wife of Odin and queen of Asgaard. Frigg is the name
     of the user interface editor.
Odin:
     is the name of the highest ranking god in Asgaard.
Thor:
     is the name of the strongest of all gods. He is the god for all
     peasants. He is the son of Odin and Frigg and lives together with his
     wife Sif in Trudvang on the farm Bilskirner which is the biggest house
     in the world, with 540 floors.

----------------------------------------------------------------------------

Q17) Is it possible to obtain an evaluation version of the Mjolner System?

Well, yes and no. Mjolner Informatics has previously offered a demo version
of the Mjolner System for the cost of media and shipment.

Due to the introduction of the very cheap Personal Edition versions on all
platforms, the demo offer has, however, been stopped. For evaluation
purposes, Mjolner Informatics suggests purchase of a PE system (price
currently US$ 60+VAT, media and shipment). Write info@mjolner.com for
details.
----------------------------------------------------------------------------

Q18) What is the origin of the name BETA?

[Ole Lehrmann Madsen (olm@daimi.aau.dk) writes:]

Originally Beta was just one of a series of languages developed at Nordic
universities.

The first object-oriented language Simula was originally designed as a
simulation language but it was soon realised that the main ideas could be
used for programming in general and this lead to Simula 67, which has class,
subclass, virtual function coroutines, etc. It also supplied the first
object-oriented framework in the form of Class Simulation which is a set of
classes to support the original goal of Simula to write simulation programs.

It turned out that many users of Simula seemed to get more understanding of
their problem domain by having to develop a model using Simula than of the
actual simulation results.

Kristen Nygaard and others then decided to develop a successor for Simula,
but with main focus of system description - not execution. This lead to a
language called

     Delta

In Delta you could express true concurrent objects and use predicates to
express state changes. Delta could, however, not be executed. Delta means
'participate' in Norwegian'. [E. Holbaek-Hannsen, P Haandlykken, K. Nygaard:
System Description and the Delta Language. Norwegian Computing Center, Publ.
no 523, 1973]

When Kristen Nygaard was a visiting professor at Aarhus University in
1973-75, a project was started to develop a programming language based on
the Delta ideas. This language should be a (programming language) successor
to Simula and was called

     Gamma

In the seventies, it was often assumed that a general programming language
was not usable as a systems programming langauge. It was therefore decided
to define a systems programming langauge which should also be used to
implement Gamma. This language was called

     BETA

Finally the machine level languages were referred to as

     Alpha

Long story:-)

So what happened to Delta and Gamma?

There is a (big) report describing Delta and there has later been some
related work on Delta including using it in a few projects, but it is no
longer being used or developed. The language

     Epsilon

was a simplified version of Delta and the result of attempts to formalize
Delta by means of Petri Nets.

The Gamma language was never developed. During the work on Beta it was soon
realized that there was no need for Gamma. It turned out that by having
powerful abstraction mechanisms in Beta, the Gamma-level could be handled by
supplying class libraries and frameworks. You may thus think on the
Gamma-level as the libraries and frameworks of the Mjolner System.

And this is where we are today.

Some of the stuff in Delta could be handled by adding constraints to BETA
and supporting invariants and pre/post conditions. (The idea of invariants
and pre/post conditions for classes were originally suggested by Tony Hoare
for Simula. [C.A.R. Hoare: Proof of correctness of data representation, Acta
Informatics, 4, 271-281, 1972]

The Mjolner System has some libraries supporting initial versions of
constraints and invariants.

It has often discussed changing the name BETA - to avoid the beta-testing
jokes. The suggestion for a name change is Scala - Scandinavian Language and
also Scala means 'going up'... But so far it has been decided to stick with
Beta.
----------------------------------------------------------------------------

Q19) How to format BETA programs in LaTeX?

The best way to format BETA programs in the LaTeX formatting system is by
using the lgrind LaTeX package.

You can use the following lgrind style:

beta|the BETA programming language:\
        :pb=(^\d?\p\d?\:\d?\p?\d?\(#\d?:\
        :id=_:\
        :bb=\d(\(#|\(if|\(for)\d:\
        :be=\d(#\)|if\)|for\))\d|;:\
        :oc:\
        :cb=\(*:\
        :ce=*\):\
        :sb=':\
        :se=':\
        :tb=%%:\
        :te=%%:\
        :mb=%\$:\
        :me=\$%:\
        :vb=%\|:\
        :ve=\|%:\
        :kw=if then else for repeat\
            do inner none this enter exit leave restart suspend\
            and or xor mod div\
            stop:

This lgrind style can be made available in two different ways:

   * Included in the among standard lgrind styles. This is done by copying
     the above definition into the lgrindefs styles file, which is installed
     as part of the lgrind installation (possibly in the
     /usr/share/local/lib/lgrindefs file - dependent on your local setup).
     This installation must be done by the local systems administrator.
   * You can also copy the lgrind style onto a file in your personal file
     system. Let us for further reference assume that this file is called:
     $HOME/lgrind/lgrindefs.

Q19.1) How to use the BETA lgrind style

When the lgrind style is made available (as above), you can use it in the
following way.

Let us assume, that you have a BETA source file called prog.bet.

   * If the lgrind style is saved among the standard lgrind styles, you
     execute:

        lgrind -lbeta -i prog.bet > prog.tex

   * If the lgrind style is saved in your personal file system, you execute:

        lgrind -lbeta -d $HOME/lgrind/lgrindefs -i prog.bet > prog.tex

You are now ready to include the BETA source into a LaTeX document. You do
this by inserting the following in the start of the LaTeX document:

   \usepackage{lgrind}

Please note, that you only need to insert this once.

This implies, that the lgrind LaTeX style is available. At the position in
the document, where you wish the BETA source code, you just insert one of
the following:

   * \lgrindfile{prog}
     which will simply include the file at that point of text, and will draw
     horizontal lines before and after the listing.
   * \lagrind[htbp]{prog.tex}{caption}{label}
     which will put the listing also within a figure environment, using the
     float options, caption and label you gave.

You insert one lgridfile or lagrind command for each piece of BETA source
code, you wish to include in the document.
----------------------------------------------------------------------------

PART II: Language Issues

----------------------------------------------------------------------------

L01) What features do BETA have?

BETA replaces classes, procedures, functions, and types by a single
abstraction mechanism, called the pattern. It generalizes virtual procedures
to virtual patterns, streamlines linguistic notions such as nesting and
block structure, and provides a unified framework for sequential, coroutine,
and concurrent execution. The resulting language is smaller than Simula in
spite of being considerably more expressive.

The pattern concept is the basic construct. A pattern is a description from
which objects may be created. Patterns describe all aspects of objects, such
as attributes and operations, as seen in traditional object-oriented
languages, but also aspects such as parameters and actions, as seen in
procedures.

Objects are created from the patterns. Objects may be traditional objects as
found in other languages, but they may also be objects which correspond to
procedure or function activations, exception occurrences, or even coroutines
or concurrent processes.

Objects may be created statically or dynamically and the objects are
automatically garbage collected by the runtime system when no references
exist to them any longer.

Patterns may be used as superpatterns to other patterns (the subpatterns).
This corresponds to traditional class hierarchies, but since patterns may
describe other types of objects, inheritance is a structuring means
available also for procedures, functions, exceptions, coroutines, and
processes.

Patterns may be virtual. This corresponds to traditional virtual procedures
but again the generality of the pattern construct implies that also classes,
exceptions, coroutines, and processes may be virtual.

Virtual patterns in the form of classes are similar to generic templates in
other languages. The prime difference is that the generic parameters (that
is, the virtual class patterns) may be further restricted without actually
instantiating the generic template. The generality of the pattern also
implies that genericity is available for classes, procedures, functions,
exceptions, coroutines, and processes.

Patterns may be be handled as first-order values in BETA. This implies the
possibility of defining pattern variables which can be assigned pattern
references dynamically at runtime. This gives the possibilities for a very
dynamic handling of patterns at runtime.

You can find more introductions to the BETA language by looking at the BETA
Language Tutorial.
----------------------------------------------------------------------------

L02) What changes have been made to the BETA language definition?

The BETA language definition has been stable since 1992, apart form the
following minor changes:

L02.1) String Literals as References

The pattern text enters and exits a char repetition. This means, that a text
may be initialized using constant strings as follows:

      t: @text;
   do 'hello' -> t;

Many operations involving texts, however, takes references to texts as
enter/exit parameters. This is mainly for efficiency reasons.

To allow easy invocation of such operations on string literals, the
following is also allowed:

      t: ^text;
   do 'hello' -> t[];

The semantics of this is, that a text object is instantiated, initialized by
the constant string, and finally assigned to the text reference.

L02.2) Simple If

Often the following If statement is used:

      b: @boolean;
   do (if b//TRUE then ... else ... if);

The current version of the compiler supports an extension to the BETA
language called Simple If. This extension means, that the case-selector //
may be omitted, if the evaluation on the left hand side exits a boolean.
That is, the above may be written

      b: @boolean;
   do (if b then ... else ... if);

Like in the general if-statement, the else part if optional.

L02.3) Xor Primitive

An xor primitive is supported as a basic operation on booleans. That is

      b1, b2, b3: @boolean
   do b1 xor b2 -> b3

is possible.

L02.4) Short-circuit Boolean Expressions

Boolean expressions are implemented as short-circuit. That is, in

      B1 or B2

B2 is not evaluated if B1 is true, and

      B1 and B2

B2 is not evaluated if B1 is false.

L02.4) Labelled imperatives

Labelled imperatives were previously defined in the language in two forms:

   L: Imp;

and

   (L: Imp1; ...; :L)

The second form has now been removed from the language. Instead, the
compiler offers the form

   L: (# do Imp1; ... #)

Note that this form is implemented very efficiently in the case where there
are no declarations in the object descriptor (i.e. between (# and do).
----------------------------------------------------------------------------

L03) How do I deal with concurrency in BETA?

The processes of BETA (concurrent objects) are based on a simple
fork-mechanism and semaphores. Based on these mechanisms, pattern
definitions are available for shared variables in the form of monitors, and
for synchronous process communication based on a port communication
metaphor. The abstractions also contain facilities for utilizing future
values in connection with process interactions.
----------------------------------------------------------------------------

L04) How do I deal with persistence in BETA?

The Mjolner System contains a library that implements a persistent store for
BETA objects. Any BETA object can be stored into the persistent store and
subsequent obtained from the store in a type-safe way. There are no
requirements that the persistent objects must inherit from any specific
superpattern, and persistent objects are fully type-checked both when saved
in the persistent store, and when retrieved from the persistent store.
----------------------------------------------------------------------------

L05) How do I deal with distribution in BETA?

The Mjolner System contains a distributed object system in which BETA
objects may reside on different hosts, and communicate transparently with
each others, just as if they were residing on the same host. The objects may
even be residing on different host types (e.g. on Macintosh and Unix
workstations, respectively).
----------------------------------------------------------------------------

L06) How do I deal with exception handling in BETA?

Exception handling is dealt with through a predefined library containing
basic exception handling facilities. The exception handling facilities are
fully implemented within the standard BETA language in the form of a library
pattern, and the usage is often in the form of virtual patterns, inheriting
from this library pattern.
----------------------------------------------------------------------------

L07) Can classes be treated as first-order elements in BETA?

Yes, they can. This is possible by using the pattern variable construct in
BETA. A pattern variable may dynamically be assigned pattern references.
Pattern variables may be used to dynamically create instances of the
pattern, currently contained in the pattern variable.
----------------------------------------------------------------------------

L08) What about garbage collection in BETA?

Garbage collection is conducted automatically by the BETA runtime system
when it is discovered that no references to the object exist. The garbage
collection mechanism is based on generation-based scavenging. The
implemented garbage collection system is very efficient.
----------------------------------------------------------------------------

L09) How do I create a "parameterized class"?

A parameterized class (a template in C++ or a generic class in Eiffel) is
created in BETA by using the virtual pattern mechanism. The generic
parameter is specified as a virtual attribute of the pattern, and
subpatterns of this patterns may now make further restrictions on the
generic parameter by further binding the virtual attribute. Generic
instantiation is done by either making a final binding of the virtual
attribute, or by instantiating an object directly from the pattern.
----------------------------------------------------------------------------

L10) What is the difference between a virtual binding, a further binding and
a final binding (i.e. between :<, ::<, and ::)?

To illustrate the difference between new and further-bindings, consider

   p:  (# v:<  (# do ...; inner #) #);
   q: p(# v::< (# do ...        #) #);
   r: p(# v:<  (# do ...        #) #);

in which a pattern p with a virtual attribute v, and two subpatterns, q and
r, are declared. Pattern q further-binds p's virtual attribute, while
pattern r declares a new virtual attribute v which has no connection to p's
v, except that it happens to have the same name. [This may or may not be
what the programmer intended, so perhaps a warning should be issued in this
case.]

Thus, if rp is a pointer of type p, and rp happens to denote a q object,
then calling rp.v will cause q's v part to be executed in addition to p's
(because v has been further-bound in q). However, if rp denotes an r object,
then calling rp.v will cause only p's v part to be executed, not r's
(because p's v attribute has not been further-bound). [Of course, if rr
denotes a pointer of type r, then rr.v will cause r's v part to be
executed.]

A final binding has the same effect as a further-binding, except that it
specifies that the virtual may not be further-bound from this point on.
There are (at least) three different reasons why you might want to use final
bindings:

   * Modelling: Final-bindings are often considered to be a nice feature
     from a purely object-oriented modelling perspective since it indicates
     that the model is no longer extensible with respect to this attribute.
   * Efficiency: The compiler is able to generate tighter code when it is
     known that a pattern is not virtual (any longer).
   * Inheritance: It is not allowed to inherit from a virtual pattern; but
     it is ok to inherit from a final-bound one.

----------------------------------------------------------------------------

L11) What about invariants in BETA?

Invariants are not an integrated part of the BETA language. However, it is
possible to create an invariant system as a framework or library, entirely
written in BETA. In the Mjolner System, an experimental invariant system is
available. The system offers class invariants as well as pre- and
post-conditions for operations. The invariant system also offers the ability
to control whether the invariants are checked or not, either on individual
object basis or system-wide.
----------------------------------------------------------------------------

L12) What about change propagation in BETA?

Change propagation (as in Model-View-Control - MVC) is also available in
BETA (with extended facilities). Change propagation is available as an
experimental part of the current system.
----------------------------------------------------------------------------

L13) What about futures in BETA?

Futures are used in concurrent programming to return results from a
concurrent computation, even before they have been calculated. The result
can then be passed around as any other value, and only when an attempt is
made to access it, the reader will be blocked until the result is made
available by the concurrent computation. Based on the existing BETA
facilities, futures can easily be implemented, and an experimental futures
library is available as part of the current system.
----------------------------------------------------------------------------

L14) Why can variables declared in execution blocks not be accessed in
INNER?

Consider the following code fragment:

   P: (# do ...; (# x: ... do inner P #); ... #)
   PP: P(# do ... #)

According to the BETA visibility rules, x may not be referenced from the
do-part of PP. Why?

The answer lies in the fact that patterns may have more than one inner
section. Consider the following (slightly modified) example, where inners
are placed in different inserted descriptors, each containing declarations
of different sets of local variables:

   P: (#
      do ...;
         (# x: ... do inner P #);
         ...;
         (# y: ... do inner P #);
          ...;
      #)
   PP: P(# do ... #)

In this case, the do-part of PP is executed twice via inner, but with
different sets of local variables (x and y, respectively). It is therefore
meaningless to refer to any one of these in the do-part of PP.
----------------------------------------------------------------------------

L15) How do I implement a copy (or clone) operation?

It is often useful to be able to make a genuine copy of an object. It is
currently being discussed to introduce a 'clone' operation into the object
pattern, which should take care of this copying automatically, but no
decision has been made as to how and when.

Until then, the following trick does the job:

   P: (# (* internal P structures *)
         copy:< (* generic copy operation *)
           (# copyType: ##P;
              theCopy: ^P;
           do this(P)##->copyType##;
              &copyType[]->theCopy[];
              (* insert here code to  implement the copying
               * of internal P structures into theCopy *)
              INNER copy;
              (* possible finalization of the copying process *)
           exit theCopy[]
           #)
      #);

   Q: P(# (* internal Q structures *)
          copy::<
            (# Qcopy: ^Q
            do theCopy[]->Qcopy[];
              (* insert here code to  implement the copying
               * of internal Q structures into Qcopy *)
              INNER copy;
              (* possible finalization of the Q copying process *)
            #)
       #);

   R: Q(# (* internal R structures *)
          copy::<
            (# Rcopy: ^R
            do theCopy[]->Rcopy[];
              (* insert here code to  implement the copying
               * of internal R structures into Rcopy *)
              INNER copy;
              (* possible finalization of the R copying process *)
            #)
       #);

Given the declarations

   a: @R;
   aCopy: ^R;

then

   a.copy->aCopy[]

will make a copy of the a object with the proper qualification (here R), and
a state that is a copy of the state of a.

Note: The

      Rcopy: ^R
   do theCopy[]->Rcopy[]

part of the copy further binding is an inconvenience, but is necessary to
persuade the type system to allow remote access to the R-parts of the
theCopy object.
----------------------------------------------------------------------------

L16) Why doesn't BETA have multiple inheritance?

[Ole Lehrmann Madsen (olm@daimi.aau.dk) writes:]

I shall try to explain why there is no (traditional) multiple inheritance in
BETA. Please note that I am not trying to argue against MI. The following is
only an attempt to explain why it is not in BETA.

When BETA was designed we did not think that the concept of multiple
inheritance was ready for being incorporated in the language. One of the
main design goals for BETA was that it should be good for modelling. Most
usages of MI seemed to be for pure code reuse, i.e. a new class may be
defined by inheriting from a number of classes and then redefining the parts
that should differ. Often this is done without there being any conceptual
relation between the new class and the ones it inherits from. We did not
like that way of using inheritance.

MI in BETA should be there to model classification hierarchies which are
non-tree structured. In my experience, such hierarchies are rare in
practice. What is more common is that you may want several independent
tree-structured classification hierarchies for the same objects. A set of
person objects might be classified according to their profession,
nationality, and religion. This gives three class-hierarchies. People often
handle such situation using MI, but this will merge the hierarchies in a way
that makes it difficult to identify the three original ones.

We would like to support such independent classification hierarchies in
BETA, but no concrete proposal exists.

The various proposals for solving name conflicts and overlapping
superclasses also seemed rather complex. We did not want the semantics of
basic constructs to be complicated to understand.

For BETA there are a number of additional problems:

   * Virtual patterns from a common superclass may have conflicting bindings
     in the superclasses:

        A: (# V:< A1; ... do ... inner ... #);
        B: A(# V::< A2; ... do ... inner ... #);
        C: A(# V::< A3; ... do ... inner ... #);
        D: B & C (# V:: A4; ... do ... #);

     (The syntax B & C has tentatively been used for MI in BETA.)

     Here A2 and A3 must both be subclasses of A1, and A4 must be a subclass
     of both A2 and A3. (In her Ph.D. Thesis, Kristine Thomsen defined a
     language along these lines, which handled virtual bindings a la those
     in BETA. It should be available from the Computer Science Department,
     Aarhus University.)

   * The semantics for combining inners of multiple superclasses must also
     be defined. In the example above, should B's do-part be executed before
     C's or vice versa? Since we are not in favour of making the order of
     superclasses significant, we were considering letting the execution
     order of B and C be non-deterministic, in the sense that the
     implementation may execute B or C in any order. (Thomsen's thesis also
     deals with combing inners and proposes a number of other alternatives.
     You may also want to take a look at: K. S. Thomsen: "Inheritance on
     Processes, Exemplified on Distributed Termination Detection",
     International Journal of Parallel Programming, pages 24-37, November
     1988.)

Finally, we have not felt an strong need to support MI in the traditional
sense, since BETA has other means for handling some of the most common MI
cases:

In BETA you may inherit from part-objects and at the same time further-bind
its virtuals:

   A: (# f:< ... #);
   B: (# g:< ... #);
   C: (# ...
         X: @A(# f::< (# ... #); ... #);
         Y: @B(# g::< (# ... #); ... #);
         ...
      #);

X and Y are singular part-objects; due to BETA's block structure the virtual
bindings of f and g may refer to variables in the enclosing C-object.

Given the declaration W: ^C, the functions f and g may be invoked as W.X.f
and W.Y.g. The difference from MI is that you have to qualify using X and Y.
Some people think of this as an inconvenience; others think of it as an
advantage since it forces them to be explicit about name conflicts between A
and B. If you prefer writing W.f and W.g, you may define f and g functions
in C and let them forward the calls to X.f and Y.g.

Given the declaration V: ^A, then W.X[]->V[] is possible, and an invocation
of V.f calls the further-binding of f in X, thereby possibly
accessing/changing the state of C.

To sum up, this form of multiple inheritance via part objects is very
similar to non-overlapping inheritance in C++.

As a final example, consider the following well-known MI case:

                  Window
                 /      \
   WindowWithBorder    WindowWithTitle
                 \      /
         WindowWithBorderAndTitle

In BETA this may be handled using block-structure

   Window:
     (# ...
        Border: (# ... #);
        Title: (# ... #);
     #);
   W1: @Window(# B: @Border; T: @Title #);
   W2: @Window(# T1,T2: @Title #);

Here W1 has a border and a title, whereas W2 has no border and two titles.
(For a further discussion, see K. Osterby: "Parts, Wholes, and Subclasses",
Proceedings of the 1990 European Simulation Multiconference, pages 259-263,
1990.)

To sum up, we did not think that traditional MI has been worth the
complications it will add to the language, since many of the MI cases can be
handled by other means. We are, however, still discussing MI, and it may end
up being supported more directly.
----------------------------------------------------------------------------

L17) What is the rationale behind the syntax of BETA?

[Ole Lehrmann Madsen (olm@daimi.aau.dk) writes:]

When we designed BETA, we spent a lot of time discussing syntax - it is one
of those things people can really disagree about. We tried to develop what
we considered to be a nice and readable syntax with as few long keywords as
possible.

The following type of brackets are used:

     (# ... #)     object
     (* ... *)     comment
    (if ... if)    if-imperative
   (for ... for)   for-imperative

We did consider using { and } for objects or comments, but ended up not
doing it; we did not feel a strong need to have BETA look like C.

As we did not like long keywords (as in Pascal or Ada), BETA uses symbols
like @, ^, |, and :< instead. We believe that for a small language like
BETA, it is an advantage to have a compact syntax. This way, you can have
more code on a page or in a window. (Of course, {,} is shorter than (#,#),
but we preferred the syntax to be consistent with (if,if), etc.)

It is not our experience that the syntax of BETA presents any obstacle to
learning the language. BETA has very few constructs (and symbols), and while
they may seem strange at first, they are easy to learn and use. Try it!

You can find a quick overview of the BETA syntax by looking at the BETA
Quick Reference Card
----------------------------------------------------------------------------

L18) How do the scope rules of BETA actually work?

The BETA scope rules may seem slightly complex to the new BETA programmer,
but are actually rather intuitive and simple. There are three visibility
rules:

  1. Names declared in the descriptor itself are visible within the
     descriptor.
  2. Names declared in the superpattern of a descriptor are visible within
     the descriptor.
  3. Names declared in outer blocks (i.e. enclosing descriptors) are visible
     within the descriptor.

These rules are applied in order to find the definition for a given name
application:

   * Start by using rule 1, looking for a local declaration.
   * If not found, then use rule 2 to find the declaration in the
     superpattern (if the descriptor has one). While using this rule, you
     may apply rule 1.
   * If still not found, then use rule 3 to find the declaration in the
     enclosing descriptors. While using this rule, you may apply rule 1 and
     2.

Note: This method implies that it is possible to reuse the same name for
different declarations, as long as the declarations are in different
descriptors.

To see how the rules interact, take a look at the example program below. It
illustrates most of the combinations, and has the resulting output is shown
in comments after each imperative.

   (# a: (# do 1->screen.putint #);
      P1: (# do a; INNER P1 #);
      P2: (# a: (# do 2->screen.putint #);
          do a
          #);
      P3: P1(# do a #);
      P4: P1(# a: (# do 3->screen.putint #);
          do a
          #);
      P5: P1(# foo1: (# do a; inner foo1 #);
               foo2: (# a: (# do 4->screen.putint #)
                     do a; inner foo2
                     #);
            #);
      P6: P5(# a: (# do 5->screen.putint #);
               foo3: (# do a; inner foo3 #);
               foo4: foo1(# do a; inner foo4 #);
               foo5: foo2(# do a; inner foo5 #);
            #);
      P: @P6;
   do
      a;                (*   1 *)
      P1;               (*   1 *)
      P2;               (*   2 *)
      P3;               (*  11 *)
      P4;               (*  13 *)
      P5;               (*   1 *)
      P6;               (*   1 *)

      P.foo1;           (*   1 *)
      P.foo2;           (*   4 *)
      P.foo3;           (*   5 *)
      P.foo4;           (*  15 *)
      P.foo5;           (*  44 *)

      P.foo1(# do a #); (*  11 *)
      P.foo2(# do a #); (*  44 *)
      P.foo3(# do a #); (*  51 *)
      P.foo4(# do a #); (* 151 *)
      P.foo5(# do a #); (* 444 *)
   #)

----------------------------------------------------------------------------

L19) What is a pattern?

The following is an attempt to explain the pattern concept. The description
is divided into two parts: a description in the form of examples, and a more
abstract explanation.

To begin with, think of a pattern as a generic word for the concepts class,
procedure and function. This is not all there is to it, but it will get you
started. In BETA, a pattern is anything starting with (# and ending with #).
As a simple example, here is a function that multiplies two numbers:

   multiply: (# a,b: @integer;
             enter (a,b)
             exit a*b
             #);

The multiply pattern takes two integers, a and b, and returns their product.
These kinds of patterns are often called functional patterns, since their
use correspond to functions (or procedures) in other languages. In BETA, a
call to multiply might look like:

   (7,17)->&multiply->&putInt;

putInt is a procedure that writes the result on the screen.

As another example, let's build a stack class in the typical object-oriented
paradigm:

   stack: (# content: [100] @integer;
             currentSize: @integer;
             push: (# e: @integer;
                   enter e
                   do currentSize+1->currentSize;
                      e->content[currentSize];
                   #);
             empty: (# exit (currentSize=0) #);
             pop: (# e: @integer;
                  do content[currentSize]->e;
                     currentSize-1->currentSize;
                  exit e
                  #);
          #);

Now, stack is also just a pattern. You may call it a class pattern since its
meant to be used as a class: to make instances, the actual stacks. And just
in case you were wondering: Yes, the push, empty, and pop methods defined
for stack are also patterns (functional/procedural patterns), defined inside
the stack pattern.

BETA offers a lot of extra functionality which could make the example much
more realistic (information hiding, generic stacks, exceptions due to
overflow, dynamic expansion of the stack capacity, etc.), but let's keep the
example simple.

Having shown a few practical examples, here's the more elaborate
explanation:

A pattern is used for instantiating objects (static objects, dynamic
objects, inserted objects, etc.). A pattern declaration in its full form
looks like this (other forms below):

   P: S(# decl1; decl2; ... decln;
       enter enterlist
       do imperatives
       exit exitlist
       #);

This declares P as a (direct) subpattern of S. (S thus is the (direct)
superpattern of P.) S may be omitted, in which case object (the direct or
indirect superpattern of all patterns) is assumed. Each part (declarations,
enter part, do part and exit part) can be omitted. (Thus "P: (# #);" is
legal.)

Each declaration can be a declaration of a pattern, a virtual pattern, a
further or final binding of a previously declared virtual pattern, a static
item, a dynamic item, a static component, a dynamic component, a repetition
(array) or a pattern variable (used for holding a pattern, popularly
speaking). Or a number of same.

Thus the above declaration of P fits into an outer pattern. If both P and S
have declared enter parts, the enter list of a P object consists of the
enter lists concatenated. The same goes for the exit list. Thus the
subpattern declaration can only add to the enter and exit lists, not make
other changes. A bit more complicated rules exist for do-parts, but the
basic principle is the same: only additions are possible.

A pattern can be virtual. There are three forms of virtual pattern
declarations:

   P: (# V:< Q; #);
   P: (# V:< Q(# ... #); #);
   P: (# V:< (# ... #); #);

where Q is a pattern name.

(For the sake of completeness, this should perhaps be written as

   P: S(# ...; V:< Q; ...; enter ... do ... exit ... #);
   P: S(# ...; V:< R(# ...; enter ... do ... exit ... #); ...;
       enter ... do ... exit ...
       #);

etc., but we'll leave the that out.)

Virtual declarations can be extended, or further bound, in subpatterns:

   P1: P(# V::< Q1; #);
   P1: P(# V::< Q1(# ... #); #);
   P1: P(# V::< (# ... #); #);

In the first two forms, it is required that one of the following two
conditions holds:

  1. V was declared in P (or some superpattern of P) as V:< Q, and Q1 is a
     direct or indirect subpattern of Q.
  2. V was already further bound in P (or some superpattern of P) using the
     form V::< Q0, and Q1 is a direct or indirect subpattern of Q0.

The third form V::< (# ... #) can be used regardless of which form was used
for the previous declaration or further binding of V. In this case, the
descriptor (# ... #) is used to automatically form a subpattern. (This form
of further binding is the only available one if V is declared using V:< (#
... #), or V has been further bound using V::< Q1(# ... #) or V::< (# ...
#).)

Thus, the further binding makes V a subpattern of what it was before.

Finally, a virtual pattern may be final bound. A final binding is a further
binding, except (syntactically) :: is used instead of ::<, and
(semantically) after a final binding, V is no longer virtual, and can
therefore not be further bound. The final binding must otherwise follow the
same rules as described above for further bindings.

Also, see Question L10.
----------------------------------------------------------------------------

L20) Are identifiers and keyworks case-sensitive in BETA?

Neither identifiers nor keywords of the BETA language are case-sensitive.
That is, the identifier hello is the same as the identifier HELlo, and the
keyword INNER is the same as the keywork inner. However, there is one
exception from this rule. Identifiers used for declaring Externals are
case-sensitive (due to identifiers in the C programming language being
case-sensitible). Please refer to the Compiler Manual for details.
----------------------------------------------------------------------------

L21) What characters are allowed in BETA identifiers?

The identifiers in the BETA language must obey the following literal syntax:

     A BETA indentifier has to start with a letter or '_', and may be
     followed by a sequence of letters, digits, and '_'.

----------------------------------------------------------------------------

L22) What is the exact semantics of leave P and restart P, when P is the
name of a pattern?

Leave and restart are the very basic local control mechanisms in BETA. Leave
and restart are specified by:

     restart id
     and
     leave id

where id is the name of either a label or an enclosing pattern. When id is
an enclosing pattern, id is defined to refer to the do-part of id (hence not
to the do-part of any superpattern of id).

Consider the pattern:

   P: A(# ...
       do (* L1 *)
          ...;
          leave/restart P;
          ...;
          (* L2 *)
       #)

restart P implies that execution continues at (* L1 *):

     This means that restart P has the effect of entering the do-part
     of P as after an inner in A.

leave P implies that execution continues at (* L2 *):

     This means that leave P has the effect that execution continues in
     the do-part of A after the inner that called the main-do-part of
     P.

Example:

   (# A: (#
         do (for 4 repeat '['->put; INNER; ']'->put for)
         #);
      P: A (# k: @integer
           do k+1->k->putInt;
              (if k=2 then '-'->put; leave P if);
              (if k=3 then '*'->put; restart P if);
              '+'->put
           #);
   do P
   #)

will give the following output:

   [1+][2-][3*4+][5+]

----------------------------------------------------------------------------

L23) What is the BETA lexem syntax?

The different lexems in the BETA language grammar (names, strings, and
numbers) are not precisely defined in any of the available documents. We
will therefore here give the definition:

<NameAppl> =    <NameDecl>
<NameDecl> =    (<letter>|"_")+(<digit>|<letter>|"_")*

<String>   =    "'"<char>*"'"
           where <char> can be any char except "'" and newline.
                        "'" are allowed in <String>, iff preceeded with "\".
                        "\n", "\t", etc. are allowed in <String> to
                        represent non-printable chars - see Compiler
                        manual (mia91-02) for details.

<Const>   =     (<int>|<based>|<real>) where
        <int>      = <digit>+
        <based>    = <int>("X"|"x")<basedNum>
        <basedNum> = (<digit>|<letter>)+
        <real>     = <int>["."<int>][("E"|"e")[("+"|"-")]<int>]

<letter>  =     "a"|"b"|...|"z"|"A"|"B"|...|"Z"
<digit>   =     "1"|"2"|...|"9"|"0"

The usage of |, +, *, (...), and [...] conform to standard regular
expressions syntax.
----------------------------------------------------------------------------

L24) What is the maximum length of a BETA identifier?

For most practical cases there is no maximum lenghth of a name. The length
of an name is currently limited by the representation of an abstract syntax
tree (AST). There is currently a limitation to the size of an AST. In the
AST representation, a 16-bit integer is used to represent the length of a
name. A name can thus in theory consist of more than 65000 characters.
However, it is much more likely that a BETA fragment breaks the limit of an
AST than an identifier becomes too large.
----------------------------------------------------------------------------

L25) What is the exact qualification rules for nested patterns?

In Chapter 8 on Block Structure in the BETA book it is (in section 8.2) said
that patterns like Pascal.Symbol and Simula.Symbol are different. The
corresponding declarations are as follows

        Grammar: (# ...; Symbol: (# ... #); ... #);
        Pascal: @Grammar;
        Simula: @Grammar;

The current implementation does, however, not consider nested patterns like
Pascal.Symbol and Simula.Symbol to be different. The reason for this is
historical.

Qualification check was implemented in two stages. First the compile-time
checks were implemented, and next the run-time checks. The qualification
rules for run-time checking were implemented such that nested pattern like
Pascal.Symbol and Simula.Symbol are identical.

This is a relaxation of the proper run-time qualification rule (as defined
by the BETA language), and a future release of the MBS will properly
implement run-time qualification check.
----------------------------------------------------------------------------

PART III: Environment Issues

----------------------------------------------------------------------------

E01) What is the Mjolner System?

The Mjolner System is an integrated and interactive general-purpose software
development environment that supports industrial strength programming using
object-oriented programming in the BETA programming language.
(Note: "Mjolner System" was formerly designated "Mjolner BETA system".)
----------------------------------------------------------------------------

E02) What does the Mjolner System contain?

The Mjolner System includes an implementation of the BETA language, a series
of libraries and application frameworks, a set of development tools, and a
metaprogramming system. All components of the Mjolner System are constructed
using the BETA language.

Major parts of the Mjolner System (e.g. the editor, parser, pretty-printer,
metaprogramming system, fragment system) are grammar-based in the sense that
tool generators exist that, given a specific grammar for a language, will
define a specific tool that is able to manipulate programs written in that
particular language.
----------------------------------------------------------------------------

E03) What libraries come with the Mjolner System?

Basic libraries
     The basic patterns are the object-oriented variants of the standard
     simple data types, such as char, boolean, integer, and real. These
     patterns make it possible to treat e.g. integers as ordinary objects.
     The basic patterns also includes the Object pattern which is the
     implicit superpattern for all patterns that have no explicit
     superpattern.
     See the Basic Libraries Manual for more details.

The Stream Patterns
     A Stream is a generalization of internal and external text objects. An
     internal text object (Text) is a sequence (repetition) of chars. An
     external text object (File) corresponds to a traditional text file.
     Stream, Text, and File are organized in the following hierarchy:

        Stream: (# ... #);
          Text: Stream(# ... #);
          File: Stream(# ... #);
            UnixFile: File(# ... #);
            MacFile: File(# ... #);

     As part of the interface to the operating system, the basic libraries
     include patterns for accessing the directory structures of hierarchical
     file systems:

        Directory: (# ... #);
          UnixDirectory: Directory(# ... #);
          MacDirectory: Directory(# ... #);

     See the Basic Libraries Manual p12 for more details.

The Process Patterns
     The Process interface facilitates execution of subprocesses,
     communication between several independent processes, client/server
     architectures, and it is even possible to establish communication
     between Unix, PC and Macintosh processes.
     See the Process Libraries Manual for more details.

The External Language Interface Patterns
     To enable interfacing with external languages (such as C), the basic
     libraries define the external, cStruct, and externalRecord patterns.
     See the Basic Libraries Manual p18 for more details.

Container libraries
     The standard container data structures are organized in the following
     inheritance hierarchy of patterns:

                              container
                  _________________|__________________________
                  |             |             |              |
              collection arrayContainer sequentialContainer list
            ______|_______         ___________|_______________
            |            |         |       |       |         |
         multiset    hashTable   stack   queue   deque  prioQueue
            |            |
           set   extensibleHashTable
          __|_____________________
          |                      |
     classificationSet   classificationSubSet

     Container patterns are generic patterns in the sense that the element
     type of the elements kept in the container can vary between different
     container instances.
     See the Container Libraries Manual for more details.

Persistent store:
     Support for saving any kind of object generated by a BETA program
     execution on secondary storage and restoring them in another BETA
     program execution. The persistent store is fully type safe. An
     object-oriented database for BETA objects is currently under
     development.
     See the Persistence in BETA Manual for more details.

Metaprogramming system libraries:
     A metaprogram is a program that manipulates other programs. Yggdrasil
     is a metaprogramming system that supports creation of metaprograms.
     Yggdrasil is grammar-based: a metaprogramming environment may be
     generated from the grammar of any language. The metaprograms manipulate
     programs through a common representation called abstract syntax trees
     (ASTs). An AST is modelled as an instance of a pattern. There is a
     pattern corresponding to each syntactic category (non-terminal) of the
     grammar. The grammar hierarchy is modelled by a corresponding pattern
     hierarchy, derived automatically from the grammar.
     See the Metaprogramming Manual for more details.

----------------------------------------------------------------------------

E04) What frameworks come with the Mjolner System?

Concurrency framework
     The basic libraries define various patterns for dealing with
     concurrency, synchronization, and communication. These patterns are:
     system, semaphore, fork, monitor, port, restrictedPort, objectPort,
     qualifiedPort, conc, and alt.
Graphical User Interface framework
     The Mjolner System contains from release 4.0 a platform independent
     framework for the construction of graphical user interfaces, called
     guienv..
X Window System framework
     The Mjolner BETA object-oriented interface to the X Toolkit Intrinsics
     (Xt) is called XtEnv. This pattern contains the basic patterns common
     for many user-interface toolkits built upon the X Window System, but it
     does not contain any higher-level user interface elements. It is
     typically used together with a widget set containing such user
     interface elements built on top of it. Examples of such widget sets are
     the Athena Widgets, OPEN LOOK, and Motif. The Mjolner System currently
     includes object-oriented interfaces to the Athena Widgets (AwEnv) and
     to Motif (MotifEnv).
Bifrost graphics framework
     The interactive object-oriented graphics system Bifrost is based on the
     Stencil & Paint imaging model. Bifrost models computer graphics images
     by abstracting the geometric and color properties of graphical objects.
     The important new concept introduced in Bifrost is that there is one
     basic drawing primitive, the graphical object. The graphical object
     unites interaction, graphics modelling, and graphics context. Bifrost
     includes extensive support for various kinds of interaction:
     interactive creation, reshaping, translation, scaling, and rotation of
     graphical objects. The object-oriented approach makes extensibility and
     tailorability a simple task, and facilitates object-oriented drawing
     applications. One of the main goals of the development of Bifrost was
     to make the graphics system independent of underlying graphics and
     hardware systems.
Distribution framework
     A distributed object system is available for enabling transparent
     access to BETA objects located on different hosts on the network.
OODB framework
     A distributed object-oriented database system for BETA objects is
     currently being developed.

----------------------------------------------------------------------------

E05) What tools come with the Mjolner System?

BETA Compiler
     The BETA compiler is a native code generation compiler.
Fragment System
     The fragment system is used for splitting BETA programs into smaller
     pieces (fragments). The fragment system is responsible for the
     dependencies between different fragment files, defining a given library
     or program. Due to the generality of the fragment system, a BETA
     program can be divided into smaller pieces in many different ways.
Source Browser
     The different tools in the Mjolner System uses the same source browser.
     This source browser gives easy access to the file system, and gives
     facilities for browsing in the entire set of source files, belonging to
     a given program (the dependency graph of the program).
Source-level Debugger
     A source-level debugger for the BETA language is available on all
     platform (except Macintosh and HP-PA). It contains facilities for
     specifying break-points, single stepping, inspection of object states,
     inspecting the run-time organization, etc. The debugger has a graphical
     interface.
Hyper Structure Editor
     The Mjolner BETA Hyper Structure Editor has the following properties:
     Syntax-directed Editing
          Syntax-directed editing makes it possible to construct and edit
          programs or other documents without introducing syntax errors.
          Syntax-directed editing is especially useful for
          application-oriented languages intended for end-users, casual
          users and beginners that may have difficulties in remembering the
          concrete syntax.
     Abstract Presentation and Browsing
          The editor is able to present a program at any level of detail. At
          the top-level of a program the user may get an overview of classes
          and procedures. It is then possible to browse through modules and
          procedures to see more and more details.
     Adaptive Pretty-Printing
          The editor includes an adaptive pretty-printing algorithm which
          prints the program or document such that it always fits within the
          size of the window or paper.
     Text Editing and Incremental Parsing
          The programmer may freely alternate between syntax-directed
          editing and textual editing. Any program part may be textually
          edited using keyboard, mouse, and menus in the usual style known
          from the Macintosh or the X Window System, respectively. Any
          program part that has been textually edited is immediately parsed.
     Fragment Manipulation and Browsing
          The editor provides an interface to the fragment system. It is
          possible to browse through the fragment structure and to create
          and combine fragments.
     Integration of Program and Documentation
          The user may add a comment at any place in a program. The user
          decides whether or not to display a comment. Also the user decides
          whether to display a comment as part of the program or in another
          window; in the latter case a comment is indicated by means of (*).
          Using abstract presentation it is possible to obtain a
          pretty-print of a program which includes just the classes and
          procedure headings and corresponding comments. This makes it
          possible to extract a functional specification from the program.
     Hypertext Facilities
          The editor includes hypertext facilities. The facility for
          handling comments is an example of a hyperlink between a program
          and a text document. Another type of hyperlink is a link from the
          use of a name to the declaration of the name (this is only
          implemented for BETA).
Object-oriented CASE Tool
     The Mjolner BETA CASE Tool provides
        o graphical structure editing of design diagrams
        o textual structure editing of programs
        o automatic program generation from design diagrams
        o reverse engineering from programs to design diagrams
        o simultaneous editing of design diagrams and programs
     No CASE gap:
        o A single abstract language is used throughout analysis, design,
          and implementation.
        o Different concrete syntaxes are used to present the different
          models:
             + graphical syntax for design
             + textual syntax for programs
User Interface Editor
     The graphical user interface editor gives a direct manipulation editor
     for the user interface of an application. The user interface editor is
     integrated with the structure editor, enabling both graphical,
     structured and textual editing of the user interface of the program.
Metaprogramming tools
     Supplementing the metaprogramming libraries, there is a number of
     grammar-based tools as part of the metaprogramming system, such as
     compiler-compiler, parser, pretty-printer, and the hyper structure
     editor. Being grammar-based, it is possible to customize them all
     towards specific grammars.

----------------------------------------------------------------------------

E06) Does a beta-mode for Emacs exist?

Yes, an Emacs mode for editing BETA programs is part of the Mjolner System.
This beta-mode is in the public domain and can be obtained by FTP at
ftp://ftp.daimi.aau.dk/pub/beta/emacs.
----------------------------------------------------------------------------

PART IV: Specific Issues

----------------------------------------------------------------------------

SECTION I: The Fragment System

----------------------------------------------------------------------------

F01) What is the purpose of the fragment system?

The purpose of the fragment system is to enable modularization of BETA
programs. The fragment system also supports separate compilation, dependency
analysis of modules, information hiding and separation of specification and
implementation modules. The fragment system also enables the co-existence of
different implementations of the same specification, depending on the target
machine type (on the same file system), and automatic selection of the
proper variant for the specific machine type.

The fragment system is based on the slot and fragment metaphors. A slot is a
specification in the source code which signifies that separately compiled
source code may be associated with that place. A fragment is a piece of
source code which can be separately compiled, and associated with a slot.

The fragment system takes care of the slots and fragments, and the
connections between them. Several different combination rules exist in the
fragment system, enabling the specification of different modularization
relations.
----------------------------------------------------------------------------

F02) How do I separate implementation and specification code?

Let us assume that we has the following source code:

   ORIGIN '...'
   --- lib: attributes ---
   f: (# t: @text; i,j: @integer; r: @real
      enter t[]
      do (* ... some code implementing f ... *)
      #)

This source code is assumed to reside in a source code file called
fSource.bet.

If we want to separate the implementation and the specification, we can make
the following change to fSource.bet:

   ORIGIN '...';
   BODY 'fBody'
   --- lib: attributes ---
   f: (# t: @text; i,j: @integer; r: @real
      enter t[]
      <<SLOT fBody: dopart>>
      #)

That is, we have replaced the implementation with a slot specification.

We now create another source file; let's call it fBody.bet:

   ORIGIN 'fSource'
   --- fBody: dopart ---
   do  (* ... some code implementing f ... *)

As can be seen, we have now modularized the implementation away from the
specification (except for the i, j, and r attributes (see question F05).
----------------------------------------------------------------------------

F03) How do I work around "*****Only pattern-declarations may appear in a
fragment of category 'attributes'"?

In F02, we didn't get rid of the i, j, and r implementation attributes of f.
The reason is that it is not possible to do the most obvious, which would
have been the following:

fSource.bet:
   ORIGIN '...';
   BODY 'fBody'
   --- lib: attributes ---
   f: (# t: @text;
         <<SLOT fLib: attributes>>
      enter t[]
      <<SLOT fBody: dopart>>
      #)

fBody.bet:
   ORIGIN 'fSource'
   --- fLib: attributes ---
   i,j: @integer; r: @real
   --- fBody: dopart ---
   do  (* ... some code implementing f ... *)

since it is not allowed to specify reference attributes (static or dynamic)
in attribute slots.

Instead we have to use the following trick:

fSource.bet:
   ORIGIN '...';
   BODY 'fBody'
   --- lib: attributes ---
   f: (# t: @text;
        fPrivate: @<<SLOT fLib: descriptor>>
      enter t[]
      <<SLOT fBody: dopart>>
      #)

fBody.bet:
   ORIGIN 'fSource'
   --- fLib: descriptor ---
   (# i,j: @integer; r: @real #)
   --- fBody: dopart ---
   do  (* ... some code implementing f ... *)

and in (* ... some code implementing f ... *) we have to change all
references to i, j, and r to fPrivate.i, fPrivate.j, and fPrivate.r.
----------------------------------------------------------------------------

F04) Why can't I have instances in attributes-fragments?

Allowing instances in attribute forms makes separate compilation of
fragments very difficult due to problems in calculating the size of objects
being allocated from the descriptor in which the fragment form is bound (to
a slot). E.g.

fSource.bet:
   ORIGIN '...'
   --- lib: attributes ---
   f: (# t: @text;
         <<SLOT fLib: attributes>>
      enter t[]
      <<SLOT fBody: dopart>>
      #)

fUsage.bet:
   ORIGIN '...';
   INCLUDE 'fSource'
   --- program: descriptor ---
   (# foo: @f
   do (* ... usage of foo ... *)
   #)

fImpl1.bet:
   ORIGIN 'fSource'
   --- fLib: attributes ---
   i,j: @integer; r: @real
   --- fBody: dopart ---
   do  (* ... some code implementing f ... *)

fImpl2.bet:
   ORIGIN 'fSource'
   --- fLib: attributes ---
   i,j,k: @integer; r, s: @real
   --- fBody: dopart ---
   do  (* ... some code implementing f ... *)

fProg1.bet:
   ORIGIN 'fUsage';
   BODY 'fImpl1'

fProg2.bet:
   ORIGIN 'fUsage';
   BODY 'fImpl2'

When compiling the fUsage.bet fragment separately, it is impossible to
pre-calculate the size of the foo object, since foo will contain i,j,r in
fProg1.bet, whereas foo will contain i,j,k,r,s in fProg2.bet.

A solution to this problem is being investigated by Mjolner Informatics, but
there are no plan for when this will be supported.
----------------------------------------------------------------------------

F05) Why can't I have virtual declarations/bindings in attributes-fragments?

There are two problems in allowing virtual declarations in attribute
fragments.

The first problem is a logical problem. Consider:

fSource.bet:
   ORIGIN '...'
   --- lib: attributes ---
   A: (# V:< T;
         ...
      #);
   B: A(# <<Blib: attributes>>
          ...
       #);
   C: B(# V::< T1;
          ...
       #)

fUsage.bet:
   ORIGIN 'fSource'
   --- Blib: attributes ---
   V::< T2

The problem is, that when doing the semantic checking of V::< T1 in C, it is
impossible to know the further binding in the fUsage.bet fragment, since it
may be compiled after the compilation of the fSource.bet fragment. Thus it
is impossible to ensure, that the further binding in C is in fact legal (to
be legal, T1 must be a subpattern of T and all further bindings that might
appear in all fragments later bound to the Blib slot.

The second problem is in calculating the size of the virtual dispatch table,
if declaration of new virtuals were allowed in fragments bound to the Blib
slot.
----------------------------------------------------------------------------

F06) What are the differences between the INCLUDE facilities of BETA and C?

It is important to note that the fragment system INCLUDE mechanism is
radically different from e.g. the C compilers' #include facility. The C
#include mechanism is merely a means for textual composition, without any
semantical implication. The fragment system's INCLUDE mechanism is a
semantical, separate compilation facility, and at the same time it describes
parts of the dependency relations between the program parts.
----------------------------------------------------------------------------

F07) Why doesn't the compiler complain about a missing inner in a body
fragment?

The BETA compiler permits the following fragments:

top.bet:
   ORIGIN '~beta/basiclib/v1.6/betaenv';
   BODY 'testBody'
   --- lib: attributes ---
   test: (# do <<SLOT testBody: descriptor>> #)
   --- program: descriptor ---
   (# do test(# do ... #) #)

testBody.bet:
   ORIGIN 'top'
   --- testBody: descriptor ---
   (# do (* no inner! *) #)

Why does the compiler allow the specialization of test in the program slot
even though there is no inner in the definition of test (as can be seen in
the testBody fragment)?

The reason is that the testBody fragment may be compiled separately, and
later changed without recompiling or rechecking the top.bet fragment. That
is, even though the testBody might originally have included an inner, there
is no way to ensure that later changes do not remove it (without sacrificing
the separate compilation ability).

Note: This behavior is consistent with the compiler not performing flow
analysis to ensure that all execution paths of a pattern contain an inner.
For example,

   foo: (# do (if true then (* nothing! *) else inner if) #)
   bar: foo(# do ... #);

is legal even though bar's do-part is never executed.
----------------------------------------------------------------------------

F08) Can <<Attributes>> be used instead of <<AttributeDecl>>?

The fragment system has a pragmatic treatment of the syntactic categories
<<AttributeDecl>> and <<Attributes>>. In general one may want to leave slots
in a delaration list for inserting declarations as in:

   (# a: @integer;
      <<SLOT lib1: attributes>>;
      b: ^ text;
      <<SLOT lib2: attributes>>;
      c: (# ... #)
   #)

It is, however, not possible to generate the above form from the BETA
grammar, since the nonterminal <attributes> cannot generate itself. It is
possible to make a grammar that can do this, but such a grammar is very
likely to be ambiguous. The following fragment can, however, be generated
from the grammar:

   (# a: @integer;
      <<SLOT lib1: attributeDecl>>;
      b: ^ text;
      <<SLOT lib2: attributeDecl>>;
      c: (# ... #)
   #)

This will, however, only allow one fragment-form to be inserted in a each
library slot. To handle this, the fragment system allows a fragment form of
category <attributes> to be inserted for an <attributeDecl>. This aliasing
between <attributeDecl> and <attributes> is handled by the alias mechanism
for the BOBS parser used by the meta programming system. See
$(BETALIB)/bobs/vx.y/bobs.bet, nontAlias. The alias mechanism also makes it
possible to use <descriptor> as a shorthand for <objectDescriptor>. The use
of syntac alias's is pragmatic and does not strictly follow the principles
of the fragment system, but it is considered a minor but practical
mechanism.
----------------------------------------------------------------------------

SECTION II: The X libraries

----------------------------------------------------------------------------

X01) Why does my label widget sometimes get the attribute name as
label-string, and sometimes not?

The following BETA program creates a window containing "Label"

   ORIGIN '~beta/Xt/current/awenv'
   --- program: descriptor ---
   AwEnv
   (# Hello: @Label;
   do Hello.init;
   #)

whereas the following program creates a window containing "Hello"

   ORIGIN '~beta/Xt/current/awenv'
   --- program: descriptor ---
   AwEnv
   (# Hello: @Label(##);
   do Hello.init;
   #)

Why?

The connection between the names used for widgets in BETA and the external
names used in the external widgets interfaced to from BETA is that the
pattern name of the BETA widget is used for the external widget name by
default. In the first example, the Hello widget is an instance of the
pattern Label, and in the second example the widget is the only possible
instance of the singular pattern Label(##), which is named Hello.

The appearance of the windows in this case comes from the fact that the
Athena Label widget uses the external name of the widget as default
label-string, if it is not specified otherwise. A variant of this problem is
the case where you specify a list of widgets using the same pattern:

   hello1, hello2: @Label(##);

In this case the default name will always be the first name in the list,
hello1. To avoid this behavior, use the scheme

   hello1: @Label(##);
   hello2: @Label(##);

or specify the name explicitly instead.
See the X Windows Libraries Manual p5-7 for more details.

----------------------------------------------------------------------------

X02) Why do I get the error "There must be only one non-shell widget which
is son of Toplevel"?

Consider the following program:

   ORIGIN '~beta/Xt/current/awenv';
   --- program: descriptor ---
   AwEnv
   (# faculty: label
        (# init:: (# do 2-> borderwidth #) #);
      University: @box
        (# Physics, Mathematics: @faculty;
           init:: (# do Physics.init; Mathematics.init #);
        #)
   do University.init;
   #)

The idea was that a window with two labels named Physics and Mathematics
should appear. But executing it gives the error message

     Xt Error: There must be only one non-shell widget which is son of
     Toplevel. The widget causing the conflict is named faculty.

This is because the program uses the init pattern of the widgets without
specifying the father and name of the widgets. In the Xt manual [MIA 91-16],
it is briefly explained that the father widget will default to "the
enclosing widget according to BETA's scope rules" (see the description of
Core in "Basic XtEnv patterns").

To be precise, this is what happens: When the init pattern of a widget is
invoked, it first checked to see if the father is NONE. This will be the
case if no father is specified in the enter part of init. If so, a search is
started in the statical environment of the widget pattern. If a
specialization of a Core widget is found, this widget is used as the father.
This search is continued until a pattern with no enclosing pattern is found.
In this case the widget named TopLevel (in xtenv) is used as the father. The
widget TopLevel is an instance of the pattern TopLevelShell, which among its
characteristics has the constraint that it wants to have exactly one
non-shell child.

Now consider the example program: The first thing that happens is that the
init attribute of University is invoked. Since no father is specified, a
search for one is started from the University pattern. This search finds the
pattern AwEnv(# ... #), which is not a Core, and which has no enclosing
pattern. Thus University will get the father widget TopLevel.

The final binding of University.init then invokes Physics.init. Physics is
an instance of the pattern faculty, which is declared in the same scope as
University. Thus the search for a father for Physics is identical to the
search for the father of University, and Physics also gets TopLevel as its
father. This is when the error occurs. The reason why the name reported in
the error message is faculty is explained in Question X01.

Notice that it did not matter that the instantiation of the Physics object
is done within University: the default father is searched for starting from
the pattern declaration of the object.

In general there are three possible solutions:

  1. Supply the father and name when initializing the faculty widgets:

        do ("Physics", University)->Physics.init;
           ("Mathematics", University)->Mathematics.init;

     In this case, no search for a default father is needed for the faculty
     widgets.
  2. Make (possibly empty) specializations of faculty inside University:

        Physics: @faculty(##);
        Mathematics: @faculty(##);

     Now the search for a default father of Physics will start at the
     pattern faculty(##) inside University, so the University pattern will
     be the first found in this search, and hence the University widget will
     become the father of the Physics widget. Likewise for Mathematics.
  3. Move the declaration of the faculty pattern inside the University
     pattern. This will give the same search path as in solution 2.
     (Conceptually, this might also be the best place to declare faculty in
     the first place.)

The above example was a simple one. In more complicated cases, the reason
for an error of this kind can be trickier to spot. If your program uses the
fragment system to move declarations of useful widgets into a library, this
kind of error is likely to occur. Remember that if an instance of an
unspecialized widget is used, the widget pattern being declared in, say, the
XtEnvLib attributes slot of xtenv, then the search for a default father is
started at the XtEnv pattern, and therefore no father widget is found. In
this case the widget will get TopLevel as father. Solutions 1 or 2 above
will be appropriate in these cases.
See the X Windows Libraries Manual p5-7 for more details.

----------------------------------------------------------------------------

X03) How do I get a separate window for my widget?

Widgets that create separate windows which can be individually moved,
resized, and so on, by the window manager are specializations of the Shell
pattern. Normally you would use a TopLevelShell (the pattern used for the
TopLevel widget created by default by XtEnv).

To make the following Athena Label appear in a separate window

   goodbye: @Label(# init:: (# do 'Goodbye World'->label #)

you would wrap a TopLevelShell around it:

   byewindow: @TopLevelShell
     (# goodbye: @Label
          (# init:: (# do 'Goodbye World'->label #) #);
        init:: (# do goodbye.init #);
     #);

To make the window appear, it should be initialized like any other widget,
and then the Shell method popup should be invoked:

   byewindow.init;
   byewindow.popup;

Notice that the first widget initialized by a program will by default become
a child of the TopLevel widget (see question X02), and will thus be in a
separate window.

There are other possible shells to use, such as OverrideShell. The
OverrideShell has gotten its name because although it creates a separate top
level window, it overrides all requests from the window manager, and will
therefore not be resizable, etc.
----------------------------------------------------------------------------

X04) Why do I get the error "clockWidgetClass: undefined" when linking my
AwEnv program using the xt/v1.8 libraries? [corrected in r4.0]

The X libraries in the Mjolner System are based on X11 release 5 (X11R4/R5).
Support for X11R6 is not included in release 3.0 of the Mjolner System. But
with a few exceptions, X11R6 is backward compatible with X11R5. One of the
few exceptions is the reason for the above error: Some very infrequently
used widgets have been removed from the Athena widget set in X11R6.

To fix the error you should have your system administrator apply the
following patch to the file ~beta/Xt/v1.8/private/external/awInt.c:

   13d12
   < #include <X11/Xaw/Clock.h>
   15,16d13
   < #include <X11/Xaw/Logo.h>
   < #include <X11/Xaw/Mailbox.h>
   37d33
   <
   53,55d48
   < int getClockWidgetClass(){return ( (long) clockWidgetClass);}
   < int getLogoWidgetClass(){return ( (long) logoWidgetClass);}
   < int getMailboxWidgetClass(){return ( (long) mailboxWidgetClass);}

That is, remove all lines referring to the clock, logo, and mailbox widgets.
Then the system administrator should compile one of the awenv demos to get
the changes incorporated into the system.

To simplify correction of the above errors, a patch for the Mjolner System,
release 3.0 and 3.1 has been supplied. It can be fetched from
ftp://ftp.mjolner.com/pub/X11R6_patch,`.

Please see the README file for details.
----------------------------------------------------------------------------

X05) Why do I get the error "Error: NULL ArgVal in XtGetValues" when
executing my Xt program using the xt/v1.8 libraries? [corrected in r4.0]

This is due to a programming error in the Mjolner System interface to the X
toolkit. The error does not seem to influence programs linked under X11
release 5, but (at least) X11R6 on Linux encounters it.

To fix the error have your system administrator change some files:

  1. In the file ~beta/Xt/v1.8/xtlib.bet, the definition of the pattern
     argList should be changed to:

     argList: cStruct
       (# byteSize::< (# do 100->value #);
          max: (# exit R.range div 2 #);
          extend:
            (# size: @integer;
            enter size
            do (if size=0 then R.range->size
                else size-R.range->size;
               if);
               size->R.extend;
            #);
          set: @
            (# number: @integer;
               cStr: @integer;
               value: @integer;
            enter (number,cstr,value)
            do (* Cannot check ranges since no GC's may occur.
                * The user needs to do the bookkeeping himself
                * using 'max' and 'extend'.
                * The reason for this is that 'value' may be
                * the computed address of an integer.
                *)
               cstr->R[number*2-1];
               value->R[number*2]
            #);
          get: @
            (# number: @integer;
            enter number
            exit R[number*2]
            #);
          getName: @
            (# number: @integer;
               t: ^text;
            enter number
            do r[2*number-1]->CStringToText->t[];
            exit t[]
            #);
       #);

  2. In the file ~beta/Xt/v1.8/private/xtenvbody.bet, the two fragments
     IntegerResourceGet and AncestorSensitiveGet should be changed to:

        --- IntegerResourceGet: dopart ---
        do (1,resourceName, @@value)->private.wargs.set;
           (Thewidget,private.wargs[],1)->XtGetValues;

     and

        --- AncestorSensitiveGet: dopart ---
        do (1,xtnancestorsensitive,@@value)->private.wargs.set;
           (Thewidget,private.wargs[],1)->XtGetValues;

     respectively.
  3. In the file ~beta/Xt/v1.8/private/awenvbody.bet, the fragment
     FloatResourceGet should be changed to:

        --- FloatResourceGet: descriptor ---
        (# status,res: @integer
        do (1,resourceName,@@value)->private.wargs.set;
           (theWidget,private.wargs[],1)->XtGetValues;
           resolution->res;
           (@@value,res)->getQuotFromFloat->value
        #)

  4. In the file ~beta/Xt/v1.8/motif/private/basicsbody.bet, the three
     fragments MotifStringResourceGetText, MotifStringResourceGet, and
     ProcResourceGet should be changed to:

        --- MotifStringResourceGetText: descriptor ---
        (# S: @MotifString;
        do (1,resourceName,@@S.value)->Private.Wargs.Set;
           (TheWidget,Private.Wargs[],1)->XtGetValues;
           S.getText->t[];
           S.destroy;
        #)

     and

        --- MotifStringResourceGet: descriptor ---
        (#
        do (1,resourceName,@@value)->private.wargs.set;
           (thewidget,private.wargs[],1)->XtGetValues;
        #)

     and

        --- ProcResourceGet: descriptor ---
        (#
        do (1,resourceName,@@p)->private.wargs.set;
           (Thewidget,private.wargs[],1)->XtGetValues;
        #)

     respectively.
  5. In the file ~beta/Xt/v1.8/motif/private/rowcolumnbody.bet the two
     fragments RowColumnLabelStringGetText and RowColumnLabelStringGet
     should be changed to:

        --- RowColumnLabelStringGetText: descriptor ---
        (# S: @MotifString;
        do (1,resourceName,@@S.value)->Private.Wargs.Set;
           (TheWidget,Private.Wargs[],1)->XtGetValues;
           S.getText->t[];
           S.destroy;
        #)

     and

        --- RowColumnLabelStringGet: descriptor ---
        (#
        do (1,resourceName,@@value)->private.wargs.set;
           (thewidget,private.wargs[],1)->XtGetValues;
        #)

     respectively.
  6. Then have your system administrator issue the commands

        cd $BETALIB/Xt/v1.8
        beta -q -c private/awenvbody.bet motif/private/rowcolumnbody.bet

     to get the changed files recompiled.

These changes will be incorporated in version 1.9 of the Xt libraries.

To simplify correction of the above errors, a patch for the Mjolner System,
release 3.0 and 3.1 has been supplied. It can be fetched from
ftp://ftp.mjolner.com/pub/X11R6_patch,`.

Please see the README file for details.
----------------------------------------------------------------------------

X06) How do I set font information in MotifStrings?

In order to set font information in MotifStrings, you can use the following
as a template:

   sensorLabel: @Label
     (# init::
          (# s: @labelString;
             t: @MotifString
                  (# init::
                       (#
                       do ('Sensor:','ItalFont',XmSTRING_DIRECTION_L_TO_R)
                            -> t.setTextSegment;
                       #);
                  #);
          do (...)
             t.init;
             t->s.set;
          #);
     #);

----------------------------------------------------------------------------

X07) Resource specification errors in Xt/v1.9 [corrected in r4.0]

Version 1.9 of the BETA interface to X (part of r4.0) solves most of the
errors appearing when using X11R6 (e.g. the errors in X04 and X05).

This is done, among other things, by introducing BooleanResource,
CharResource and ShortResource to correctly model the interface to X
resources with different physical representations.

Unfortunately a few of the resources was not converted correctly. This means
that you may get wrong behaviour when reading these resources.

To fix this you can change the following in the Xt/v1.9 sources, and
recompile the libraries (after appropriate setting of permissions):

   Change from IntegerResource to ShortResource:
   ---------------------------------------------
   motif/rowcolumn.bet:         RowColumn.numColumns
   motif/texts.bet:             TextField.columns

   Change from IntegerResource to BooleanResource:
   -----------------------------------------------
   awenv.bet:                   SimpleMenu.menuOnScreen
   awenv.bet:                   Paned.refigureMode
   awenv.bet:                   AsciiText.autoFill
   awenv.bet:                   AsciiText.resize
   awenv.bet:                   AsciiText.displayNonprinting
   awenv.bet:                   CoreLIB.resizable
   xtenv.bet:                   Core.mappedWhenManaged
   xtenv.bet:                   Shell.allowShellResize
   xtenv.bet:                   Shell.overrideRedirect
   xtenv.bet:                   Shell.saveUnder
   xtenv.bet:                   WMShell.input
   xtenv.bet:                   WMShell.transient
   xtenv.bet:                   WMShell.waitForWM
   xtenv.bet:                   TopLevelShell.iconic
   motif/bulletinboard.bet:     BulletinBoard.defaultPosition
   motif/lists.bet:             MotifList.automaticSelection
   motif/scale.bet:             Scale.highlightOnEnter
   motif/texts.bet:             ScrolledText.scrollVertical
   motif/texts.bet:             ScrolledText.scrollHorizontal
   motif/texts.bet:             ScrolledText.scrollLeftSide
   motif/texts.bet:             ScrolledText.scrollTopSide
   motif/texts.bet:             TextField.verifyBell

These errors will naturally be corrected in the next release.
----------------------------------------------------------------------------

SECTION III: The BETA compiler

----------------------------------------------------------------------------

C01) What is the execution speed of BETA programs?

For average programs, the execution speed of typical BETA programs is
comfortable. However, there are many possibilities for optimization in the
current BETA compiler, the generated code, and the run-time system. Mjolner
Informatics is constantly working on improving the execution speed of BETA.
----------------------------------------------------------------------------

C02) How do I get rid of the warning: "A run-time qualification check will
be inserted here"?

By using the -q or -w options to the compiler: "beta -q ..." or "beta -w
..."
----------------------------------------------------------------------------

C03) What *does* that Qua-check warning mean, anyway?

If you have:

   (# Vehicle: (# ... #);
      Bus: Vehicle(# ... #);
      aVehicle: ^Vehicle;
      aBus: ^Bus
   do ...
      aVehicle[]->aBus[]
      ...
   #)

the compiler will give a Qua-check warning at the "aVehicle[]->aBus[]". The
reason is that aBus can only refer to objects which are instances of a
pattern that is a subpattern of Bus (or is a Bus). But aVehicle may refer to
all objects which are instances of a pattern that is a subpattern of Vehicle
(or is a Vehicle) - that is, not necessarily Bus. The BETA runtime system
therefore inserts a test to verify that the object referenced by aVehicle[]
is actually an instance of a pattern that is a subpattern of Bus (or is a
Bus) - otherwise a runtime error occurs.

The Qua-warning is issued to direct your attention towards these places for
potential runtime errors.
----------------------------------------------------------------------------

C04) How do I work around "*****Repetition of non simple patterns is not
implemented" (using v5.0 of the compiler)? [corrected in r4.0]

If you want to write:

   persons: [100]@person

(which is not implemented in version 5.0 of the BETA compiler), you should
instead write:

   persons: [100]^persons

and then, before you start using the persons repetition, initialize it by:

   (for i: persons.range repeat
        &person[]->persons[i][]
   for)

Then you can use the persons repetition in the rest of the program, just as
if it was declared as a repetition of static persons.

In version 5.1 of the BETA compiler, persons: [100]@person is implemented.
----------------------------------------------------------------------------

C05) How do I work around "Labeled imperative not implemented"?

If you want to write:

   (L: Imp1; Imp2; ... Impi :L)

(which is not implemented), you should instead write:

   L: (# do Imp1; Imp2; ... Impi #)

In fact, the (L: ... :L) construct is being considered for exclusion from
the BETA language due to the very simple replacement shown above.

See also L22.
----------------------------------------------------------------------------

C06) Why does a BETA program called test.bet cause problems on some UNIX
installations?

By default, the executable generated from a BETA program called test.bet is
called test. Depending on your UNIX installation's defaults and your own
environment variables, attempts to execute the BETA program by typing test
may, however, result in the standard system program test being executed
instead. To avoid the problem, just type ./test instead of test.

Similar problems can arise with other, existing UNIX commands.

[Note: This is a typical beginner's problem, not related to the BETA
language or the BETA environment as such.]
----------------------------------------------------------------------------

C07) How do I disable qualification check warnings?

The "A run-time qualification check will be generated here" warning may be
disabled by using compiler switches. In version v5.0 of the compiler, you
can use the -noquawarn (or -q) switch. All warnings may disabled by using
the -nowarnings (or -w) switch. If you would like the -q option to become
the default, you can include it in your BETAOPTS environment variable, e.g.

   setenv BETAOPTS -q

If you would like to temporarily turn qualification check warnings back on,
you may then do so by specifying the -quawarn switch.

As of version v5.1 of the compiler, the switch -noquawarn have been renamed
to --noWarnQua, and the switch -quawarn have been renamed to --warnQua.
----------------------------------------------------------------------------

C08) What is the difference between P and &P?

Consider the following BETA program:

   (# P: (# do ... #)
   do P; &P
   #)

Compiling this program with the current BETA compiler shows no difference in
the code generated for P and &P.

However, the semantics of BETA defines a difference, namely that P is the
execution of an inserted item and that &P is the creation and execution of a
dynamic item, one of the differences being that inserted items are only
allocated once, irrespectively of how many times they are executed.

The current BETA compiler implements inserted items as dynamic ones, thereby
not taking advantage of the potential possibility for optimization. This
limitation will be removed in a future release of the compiler.
----------------------------------------------------------------------------

C09) What does "virtual prefix not implemented" mean? [corrected in r4.0]

A couple of typos in the compiler manual [MIA 90-02(1.3) August 1994] for
version v5.0 of the compiler have caused some confusion over this message.
Section 5, item 8 ("Implementation Restrictions") should read as follows:

     8. Virtual superpatterns, i.e.,

        A::< (# ... #); (* where A is some virtual *)
        B: A(# ... #);

     have not been implemented.

     By using a final binding, this limitation can often be overcome
     like this:

        A:: (# ... #); (* A is no longer virtual *)
        B: A(# ... #);

     The situation may also occur in a more indirect way:

        graph:
          (# node:< (# ... #);
             nodeList: @list(# element::< node #);
             ...
          #);

     Here the virtual further binding of element in list is not
     allowed, since node is itself virtual.

     The next version of the compiler will allow final binding using a
     pattern that is itself virtual. That is, you will be allowed to do
     this:

        graph:
          (# node:< (# ... #);
             nodeList: @list(# element:: node #);
             ...
          #);

     In version 5.0 of the compiler, this situation is not handled
     correctly. Instead you can do as follows:

        graph:
          (# node:< (# ... #);
             nodeListElement: (# n: ^node enter n[] exit n[] #);
             nodeList: @list(# element::< nodeListElement #);
             ...
          #);

     General virtual prefixes behave much like multiple inheritance and
     will not be implemented in the near future.

These errors have been fixed in the manual for the version v5.1 of the
compiler.
----------------------------------------------------------------------------

C10) What should I do if the compiler prints "Please report the error to
Mjolner Informatics" and stops?

The compiler may under very rare conditions run into an error from which it
is unable to recover. It will often print out the message "Please report the
error to Mjolner Informatics" just before stopping. If you run into an error
like this, you should do the following:

  1. Check in question C11, that the error has not yet been reported.
  2. If it has not been reported, please make an archive with the following
     files (using e.g. tar on UNIX, and e.g. StuffIt or CompactPro on
     macintosh):
        o all relevant .bet source files
        o the .dump file of the compiler, if it exists
        o a file with the compiler output leading to the error
     Then please mail this file to support@mjolner.com with a short
     description of the error.

For users of r4.0, you will find a new tool, betatar, which is usefull for
packing the entire set of source files into a tar-file (only available on
UNIX platforms)
----------------------------------------------------------------------------

C11) What are the known errors in v5.0 of the compiler?

The following paragraphs deals with various bugs and workarounds in the
different compiler versions.
----------------------------------------------------------------------------

C11.1) Bugs in version 5.0 of the compiler

Since the release of v5.0 of the compiler in august 1994, the following
errors have been reported.

Some of these errors occur in very specific situations, that are hard to
describe in general, but others may be generally presented, please see
below.

C11.1.1. Static Constants [fixed in v5.1]

The following program will make the compiler crash:

   ORIGIN '~beta/basiclib/current/betaenv';
   --- program: descriptor ---
   (# E: @(# exit 1 #) #)

The compiler reports:

   ******* System error!!!
   Constant used as static item
   Please report this error to Mjolner Informatics

and then stops.

This is because constants should be declared without the '@' sign, i.e.:

   ORIGIN '~beta/basiclib/current/betaenv';
   --- program: descriptor ---
   (# E: (# exit 1 #) #)

C11.1.2. Computed remotes and virtuals [fixed in v5.1]

The computed remotes, that the compiler supports in general from release
v5.0, will sometimes make the compiler crash, especially if virtuals are
involved. Example:

   ORIGIN '~beta/basiclib/current/betaenv';
   INCLUDE '~beta/containers/current/list';
   --- program: descriptor ---
   (# point: (# x: @integer; #);
      pointList: @List
        (# element::point;
           headx: (# exit (head).elm.x #);
        #);
   #)

This program makes the compiler crash with the error:

   ******* System error!!!
   Pre is empty/null(virtual binding)
   Please report this error to Mjolner Informatics

The workaround in this case is to avoid the computed remote in headx:

   ORIGIN '~beta/basiclib/current/betaenv';
   INCLUDE '~beta/containers/current/list';
   --- program: descriptor ---
   (# point: (# x: @integer; #);
      pointList: @List
        (# element::point;
           thehead: ^theCellType;
           headx: (# do head->thehead[]; exit thehead.elm.x #);
        #);
   #)

C11.1.3. "T1PROGRAM undefined" reported by the linker [fixed in v5.1]

As explained in section 7.3 "Assembler and Linker Errors" in the compiler
reference manual [MIA 90-02], if an unbound SLOT of category Descriptor or
Dopart exist in your program, then this is currently not reported by the
compiler itself, but will be detected as an "Undefined Entry" by the linker.
Especially if you are new to BETA programming, you may wonder why compiling
this fragment (foolib.bet):

   ORIGIN '~beta/basiclib/current/betaenv';
   --- lib: attributes ---
   foo: (# (* ... *) #);

with "beta foolib" causes the linker error "T1PROGRAM undefined". In this
case the reason is that the fragment is actually a library fragment - it
only declares attributes to be used by some program. Specifically the
PROGRAM descriptor SLOT defined in "betaenv" has not been bound, and thus
the error.

The solution is quite simple: Just compile the program as "beta -c foolib"
instead. The next version of the BETA compiler will not attempt to do the
linking if the PROGRAM SLOT is not bound.

If you think this is strange, compare to the equivalent situation in C
(foolib.c)

   foo() { /* ... */ }

If you compile this file with e.g. "cc foolib.c", you will often get the
linker error that "_main" is not defined. The solution here is like in BETA:
"cc -c foolib.c"

Version v5.1 of the compiler may under rare conditions exhibit the above
behaviour, in which case you should use the above workaround, except the the
compiler switch -c in v5.1 have been renamed to -x.

C11.1.4. Reference assignment of repetitions [fixed in v5.1]

Consider the following example:

   ORIGIN '~beta/basiclib/v1.6/betaenv';
   ---  program: descriptor ---
   (# P0: (# #); P1: P0 (# #);
      R1: [5] ^P0;
      R2: [5] ^P1;
   do R1[]->R2[]; (*not legal*)
   #)

It is not legal to assign a repetition reference to another repetition
reference. Unfortunately the compiler does NOT catch this error. The program
compiles and gives unpredictable results when executed.

It is possible to have the following assignment

   R1->R2

which makes R2 be a copy of R1. But R1 and R2 do not refer to the same
repetition.

Note, it is of course possible to have the elemenst of R1 point to the same
elemenst as P1:

   (for i: R1.range repeat R1[i][]->R2[i][] for)

It would be possible to extend BETA to allow assigning a reference to a
repetion object to another reptition, but there are currently no plans for
this.

C11.1.5. Assignment to index variables not checked

The BETA book states that it is not legal to assign to the index variable of
a for-imperative as in:

   (for i: 12 repeat ...; 5->i; ... for)

This restriction is currently not checked by the compiler.

Version v5.1 of the compiler still does not check for these assignments.
----------------------------------------------------------------------------

C11.2) Bugs in version 5.1 of the compiler

Since the release of v5.1 of the compiler ultimo 1995, the following errors
have been reported.

Some of these errors occur in very specific situations, that are hard to
describe in general, but others may be generally presented, please see
below.

C11.2.1) "T1PROGRAM undefined" still reported by the linker

As mentioned in C11.1.3, version 5.1 of the compiler partly fixes the
problem of "T1PROGRAM undefined". To be specific, v5.1 of the compiler
checks, that the PROGRAM slot is met before initiating a call to the linker.

However, it may fail as follows:

   beta frag1 frag2

if frag1 contains a PROGRAM slot, and frag2 does not, you will get the
linker error for frag2: Once a PROGRAM slot has been seen, all fragments
subsequently translated will be attempted linked. This error also happens if
you invoke the compiler as

   beta -r frag1

and then enters frag2 as second fragment to compile when the repeating
compiler asks for it.

Also, if you have declared a Dopart- or Descriptor-slot in one of your
files, and do not have a fragment, that binds these slots in any of the
files in the dependency graph, then the linker may still fail with an
undefined entry for this slot.

See also C11.2.2.

C11.2.2) Other undefined entries (compiler import error) [hpux9pa, nti only]
[corrected in r4.0]

Question:
I experience errors from the linker concerning undefined entries, and I am
sure that all of my slots are bound. What is wrong?

Answer:
You may have encountered a situation where the internal import tables of the
compiler gets confused because two of your slots have identical names.

Consider:

   main.bet:
        ORIGIN '~beta/basiclib/v1.6/betaenv';
        INCLUDE 'foo';
        --PROGRAM: descriptor--
        (#
        do foo
        #)

   foo.bet:
        ORIGIN '~beta/basiclib/v1.6/betaenv';
        BODY 'foobody';
        -- LIB: attributes --
        foo:
          (# size: (# s: @integer <<SLOT size:dopart>> exit s #);
          do size -> putint; newline;
          #)

   foobody.bet:
        ORIGIN 'foo';
        INCLUDE 'bar';
        -- size: dopart --
        do (&bar[]).size -> s

   bar.bet:
        ORIGIN '~beta/basiclib/v1.6/betaenv';
        BODY 'barbody';
        --LIB: attributes--
        bar:
          (# size: (# s: @integer <<SLOT size:dopart>> exit s #)#);

   barbody.bet:
        ORIGIN 'bar'
        -- size: dopart --
        do 1 -> s

Although somewhat stupid, you would expect this program to print "1" onto
the screen. And it does so on most platforms. But on the platforms hpux9pa
(HPPA 9000/700 running HP-UX 9) and nti (Windows 95 / Windows NT), when
assembling the code produced for foobody, you get an error like

   undefined label - M2BAR

The reason for this, is that the compiler gets confused by the two dopart
slots both tagged with "size".

The solution is to use two distinct names, e.g. foosize and barsize. Such a
naming scheme is advisable to use in general - notice that if the two SLOTs
had been of kind Descriptor, then on all platforms, you would get

   multiply defined: M1SIZE

C11.2.3) Qualification error in code generation of division expression
[linux, nti only]

Sometimes v5.1 of the compiler on Linux and Windows 95/NT will will crash
with a Qualification Error during code generation of expressions involving
division.

If the resulting dump file starts with something like

   item <op1ToEBX#> in ~beta/.../system/v5.1/LINUXmachine
   -- GDIV-~ in ~beta/.../system/v5.1/LINUXmachine

then it is this error that has occurred.

On l