Subject: FAQ: BETA Programming Language (version 1.7 - 05 Feb 96)
Date: 5 Feb 1996 12:46:07 GMT
Summary: Frequently Asked Questions (with answers) for
         the object-oriented programming language BETA
Version: 1.7
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.dk 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 BETA System Home Page: 

      http://www.mjolner.dk/



Changes since version 1.6

New entries:

   What is the exact semantics of leave P and restart P, when P is the
   name of a pattern? (L23) 
   Bugs in version 5.0 of the compiler (C11.1). 
   Bugs in version 5.1 of the compiler (C11.2). 
   Problem with floating point expressions in connection with
   repetitions (C13). 
   Platform Specific Issues (Part V). 
   BETA on Windows 95 and Windows NT (Section VI) 
   What are the system requirements to run BETA on Windows 95 and
   Windows 95? (W01) 
   SDK Requirements for Windows 95 or Windows NT (W02) 
   Why do I need a MAKE facility? (W03) 
   Error in directory scan using Borland SDK? (W04) 
   Make-error for lazyref_gc.c using Borland SDK? (W05) 
   BETA on HPUX (Section VII) 
   Why do some callbacks cause "Illegal Instruction" on hpux9pa (HP01)
   BETA on Linux (Section VII) 
   How to make the BETA compiler version 5.0/5.1 work with Linux ELF
   libraries (Lx01). 

Changed entries:

   Changed title and split into two subsections (C11) 
   Added information on check of index variables (C11) 
   Changed title and text (C12) 
   Is BETA available on PC, Mac, NeXT, Amiga, Atari, ...? (Q14) 
   System Requirements for specific platforms? (Q19) 
   How do the scope rules of BETA actually work? (L18) 
   What characters are allowed in BETA identifiers? (L21) 
   Entry X07 have been moved to HP01. 

Other entries might have been changed, but then only minor changes
have been made (correction of typing errors, etc.) 


Contents

   Part I: Frequently Asked Questions 
      Q01) What is BETA? 
      Q02) Where did BETA come from? 
      Q03) What BETA products are available? 
      Q04) Are there any school or student discounts? 
      Q05) Is BETA available in the public domain? 
      Q06) What books are available for learning about BETA? 
      Q07) Does an introduction to BETA besides the BETA book exist? 
      Q08) Are any magazines or newsletters concerning BETA available?
      Q09) Are there any user groups related to BETA? 
      Q10) Are there any mailing lists related to BETA? 
      Q11) Are there any newsgroups related to BETA? 
      Q12) Is there an archive of BETA postings? 
      Q13) Are there any conferences for BETA users? 
      Q14) Is BETA available on PC, Mac, NeXT, Amiga, Atari, ...? 
      Q15) Are there standards for the BETA language? 
      Q16) What is Mjolner, Sif, Valhalla, Bifrost, Yggdrasil, etc.? 
      Q17) Is it possible to obtain an evaluation version of the
      Mjolner BETA System? 
      Q18) What is the origin of the name BETA? 
      Q19) System Requirements for specific platforms? 
   Part II: Language Issues 
      L01) What features do BETA have? 
      L02) What changes have been made to the BETA language
      definition? 
      L03) How do I deal with concurrency in BETA? 
      L04) How do I deal with persistence in BETA? 
      L05) How do I deal with distribution in BETA? 
      L06) How do I deal with exception handling in BETA? 
      L07) Can classes be treated as first-order elements in BETA? 
      L08) What about garbage collection in BETA? 
      L09) How do I create a "parameterized class"? 
      L10) What is the difference between a virtual binding, a further
      binding and a final binding (i.e. between :<, ::<, and ::)? 
      L11) What about invariants in BETA? 
      L12) What about change propagation in BETA? 
      L13) What about futures in BETA? 
      L14) Why can't local variables be accessed in INNER? 
      L15) How do I implement a copy (or clone) operation? 
      L16) Why doesn't BETA have multiple inheritance? 
      L17) What is the rationale behind the syntax of BETA? 
      L18) How do the scope rules of BETA actually work? 
      L19) What is a pattern? 
      L20) Are identifiers and keyworks case-sensitive in BETA? 
      L21) What characters are allowed in BETA identifiers? 
      L22) What extensions to the BETA language are supported by v5.0
      of the BETA compiler? 
      L23) What is the exact semantics of leave P and restart P, when 
      P is the name of a pattern? 
   Part III: Environment Issues 
      E01) What is the Mjolner BETA System? 
      E02) What does the Mjolner BETA System contain? 
      E03) What libraries come with the Mjolner BETA System? 
      E04) What frameworks come with the Mjolner BETA System? 
      E05) What tools come with the Mjolner BETA System? 
      E06) Does a beta-mode for Emacs exist? 
   Part IV: Specific Issues 
      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>>?
      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? 
         X05) Why do I get the error "Error: NULL ArgVal in
         XtGetValues" when executing my Xt program? 
         X06) How do I set font information in MotifStrings? 
      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"? 
         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? 
         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 
         C12) Tracing the work of compiler? 
         C13) Problem with floating point expressions in connection
         with repetitions 
      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 BETA System
         file directory structures? 
         B05) What do the (* idx+ *), etc. comments mean? 
   Part V: Platform Specific Issues 
      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? 
      Section VI: BETA on Windows 96 and Windows NT 
         W01) What are the system requirements to run BETA on Windows
         95 and Windows 95? 
         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? 
         W05) Make-error for lazyref_gc.c using Borland SDK? 
      Section VII: BETA on HPUX 
         HP01) Why do some callbacks cause "Illegal Instruction" on 
         hpux9pa (using v5.0 of the compiler)? 
      Section VIII: BETA on Linux 
         Lx01) How to make the BETA compiler version 5.0/5.1 work with
         Linux ELF libraries 



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 BETA System) based on the BETA language. In the US, the
MacTech Magazine Mail Store is the new distributor of the Mjolner BETA
System (replacing the former distributor, SFA). In France and the
French parts of Belgium and Switzerland, the Mjolner BETA System is
distributed by ObjectLand. 

Mjolner Informatics offers the Mjolner BETA 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 BETA 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.dk
     WWW: http://www.mjolner.dk
     WWW Sales: http://www.mjolner.dk/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

  ObjectLand 
     26 rue Jules Lanery
     F-59240 Dunkerque
     France
     Phone: +33 28 59 36 47
     Fax: +33 28 59 36 46
     E-mail: Laurent.Debrauwer@lifl.fr
     AppleLink: DEBRAUWER



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 courtc
es, in which BETA is used. 


Q05) Is BETA available in the public domain?

The BETA language definition is in the public domain. However, no
public domain implementations of the BETA language exist. 


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

The Mjolner BETA 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 BETA 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.dk 

The BETA user group is one of the important sources of information on
the developments of the Mjolner BETA 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.dk

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

   usergroup-request@mjolner.dk

(Do not send subscription requests to usergroup@mjolner.dk 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
autoimatically posted on 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 to the 
usergroup@mjolner.dk 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 Macintosh and on
Intel-based PCs. 

On UNIX, the platforms supported are: Sun Sparc (Sun OS and Solaris)
and HP 9000 (series 300, 400, and 700). 
Work is currently conducted by Mjolner Informatics to port the system
to Silicon Graphics machines under IRIX. 

Mjolner BETA 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 BETA System is also available for Windows 95 and Windows NT
(386/486/Pentium). 

There are no current plans to port the Mjolner BETA 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 BETA System have reported that the Mjolner BETA 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. 

The BETA and the Mjolner BETA 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 BETA 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 people the "spelling of the pronunciation" could be:
   "Myolner" or "Myulner", and for French 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. 
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
BETA System?

Well, yes and no. Mjolner Informatics has previously offered a demo
version of the Mjolner BETA 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.dk 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 BETA 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 BETA 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) System Requirements for specific platforms?

The system requirements for the different platforms are: 

Windows 95 and Windows NT

   CPU: Intel 386/486/Pentium
   RAM: 16Mb (32 recommended)
   Disk: 45 Mb of free space.
   Microsoft SDK or Borland SDK (only assembler, linker, make
   utilities and C libraries required). Microsoft SDK recommended. 

For more information, see W02. 

Linux

   Linux 1.0 or later (BETA works also with ELF-based Linux versions,
   please look at question Lx01)
   CPU: Intel 386/486/Pentium
   RAM: 4Mb (8 to 16 recommended)
   X11 Release 3 or later
   OSF/Motif 1.1 or later (for MotifEnv programs only; not required to
   run compiler) 
   Programs needed: (g)as, ld, make.

Macintosh

   System 7.x (or MultiFinder)
   CPU: MC68020 processor or later. (BETA works on PowerPC, please
   look at question M04)
   RAM: 4Mb (8 to 16 recommended)
   Disk: 16 Mb of free space.
   The MPW environment, please see question M02.
   An FPU to be able to use reals, please see question M03. 

For more information, see M01. 



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 for about three years,
and no major changes are expected in the near future. 


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 BETA 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 BETA 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). The
distributed object system will be included in the next major releases
of the Mjolner BETA System. 


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 BETA 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. Please refer to the
Compiler Manual for details. 


L21) What characters are allowed in BETA identifiers? 

The BETA Language identifiers 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 extensions to the BETA language are supported by the BETA
compiler?

Version 5.0 of the BETA Compiler introduces the following extensions:

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

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

   is now possible. 
Simple If 
   Often the following If statement is used 

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

   From version 5.0, the BETA 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);

Labelled imperatives 
   Labelled imperatives are defined in two forms: 

      L: Imp;

   and 

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

   The second form 

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

   has been removed from the language. Instead the following may be
   used 

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

   and the compiler implements this form of labelled imperative very
   efficiently in the case of no declarations in the object descriptor
   (# do Imp1; ... #). 



L23) 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+]



PART III: Environment Issues



E01) What is the Mjolner BETA System?

The Mjolner BETA 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. 


E02) What does the Mjolner BETA System contain?

The Mjolner BETA 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 BETA System are constructed using the BETA language. 

Major parts of the Mjolner BETA 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 BETA 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. 
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(# ... #);

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 and Macintosh processes. 
The External Language Interface Patterns 
   To enable interfacing with external languages (such as C), the
   basic libraries define the external, cStruct, and externalRecord
   patterns. 
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. 
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. 
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. 



E04) What frameworks come with the Mjolner BETA 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. 
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 BETA system currently includes object-oriented
   interfaces to the Athena Widgets (AwEnv) and to Motif (MotifEnv). 
Macintosh Toolbox framework 
   MacEnv is a family of libraries abstracting the Macintosh Toolbox
   into an object-oriented framework. Every object in the Macintosh
   user interface, like windows and menus, has a corresponding BETA
   pattern definition in MacEnv. In order to create, say, a new
   window, you just create an instance of the Window pattern and tell
   it to display itself. All the other Macintosh user interface
   objects can be created and displayed in the same way. User-defined
   objects like dialog boxes are easily created by specializing the
   Dialog pattern, and using the various Control patterns defined in
   MacEnv. MacEnv includes a series of predefined patterns for making
   text editors, scrolling windows with pictures, object-oriented
   graphics with QuickDraw, easy interface to the Macintosh resources,
   files, clipboard, sound, and QuickTime. 
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 currently being developed. 
OODB framework 
   A distributed object-oriented database system for BETA objects is
   currently being developed. 



E05) What tools come with the Mjolner BETA 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-level debugger 
   A source-level debugger for the BETA language is available on the
   Unix platform. It contains facilities for specifying break-points,
   single stepping, inspection of object states, inspecting the
   run-time organization, etc. The debugger uses a graphical interface
   running under the X Window System. 
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 
      graphical structure editing of design diagrams 
      textual structure editing of programs 
      automatic program generation from design diagrams 
      reverse engineering from programs to design diagrams 
      simultaneous editing of design diagrams and programs 
   No CASE gap: 
      A single abstract language is used throughout analysis, design,
      and implementation. 
      Different concrete syntaxes are used to present the different
      models: 
         graphical syntax for design 
         textual syntax for programs 
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
BETA System. This beta-mode is in the public domain and can be
obtained by sending an e-mail to support@mjolner.dk 


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.4/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. 


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/v1.8/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. 


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?

The X libraries in the Mjolner BETA System are based on X11 release 4
and 5 (X11R4/R5). Support for X11R6 is not included in release 3.0 of
the Mjolner BETA System. But with a few exceptions, X11R6 is backward
compatible with X11R4/R5. 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
BETA System, release 3.0 and 3.1 has been supplied. It can be fetched
from ftp://ftp.mjolner.dk/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?

This is due to a programming error in the Mjolner BETA System
interface to the X toolkit. The error does not seem to influence
programs linked under X11 release 4 or 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
BETA System, release 3.0 and 3.1 has been supplied. It can be fetched
from ftp://ftp.mjolner.dk/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;                  
          #);
     #);



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)?

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 arrise 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. 

In 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?

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): 
      all relevant .bet source files 
      the .dump file of the compiler, if it exists 
      a file with the compiler output leading to the error 
   Then please mail this file to support@mjolner.dk with a short
   description of the error. 



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.4/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]

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.4/betaenv';
        INCLUDE 'foo';
        --PROGRAM: descriptor--
        (# 
        do foo
        #)

   foo.bet:
        ORIGIN '~beta/basiclib/v1.4/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.4/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  in ~beta/.../system/v5.1/LINUXmachine
         -- GDIV-~ in ~beta/.../system/v5.1/LINUXmachine

then it is this error that has occurred. 

On linux, the error will occur if you compile e.g. the demo 
~beta/demo/r3.1/Xt/awenv/scroll.bet. None of the demos on Windows
NT/95 contain expressions that will cause this error, but you may
encounter the problem in files of your own. 

The solution is to split up the expression involving the division into
simpler expressions. Use option --traceCode to find out what
expression is causing the error. 


C12) Tracing the work of compiler?

In the extremely rare event that the compiler crashes during
compilation of your program, you may yourself do some tracing of the
compilation to find out what particular part of your program, that
makes the compiler crash. You do this by specifying some compiler
switches: 

1. If the compiler crashes during *code generation* of a fragment,
   please do this: 

      beta -s 308 311 0 <file>

   This will make the compiler print out each declaration and
   imperative just before code is generated for it. Thus when the
   compiler crashes, you can see what part of your program caused it. 
2. If the compiler crashes during *checking* of a fragment, please do
   this: 

      beta -s 191 192 193 0 <file>

   This will make the compiler print out each descriptor, declaration
   and imperative just before checking it. Thus when the compiler
   crashes, you can see what part of your program caused it. 

In version v5.1 of the compiler, you can use the two new compiler
switches --traceCode and --traceCheck instead. 


C13) Problem with floating point expressions in connection with
repetitions [fixed in v5.1]

The compiler does not generate correct code when floating point
expressions are used in the calculation of repetition ranges as in: 

        R: [FR1] ...

        FR2->R.extend
        FR3->R.new

where FR1, FR2 and FR3 are expressions yielding a floating point
value. The compiler should convert these floating point values into
integer values, but fails in doing so. 

You can get around the error by explicitly converting the expression
to an integer value. If "I" is an integer variable, then the following
will work: 

        R: [FR1->I] ...

        FR2->I->R.extend
        FR3->I->R.new

This problem have been fixed in version v5.1 of the compiler. 


SECTION IV: The basic libraries



B01) How do you compare text strings in BETA?

Let's assume that we have: 

   t1, t2: @text;

Then: 

   t1[]->t2.equal

returns true if and only if t1 and t2 are equal, and 

   t1[]->t2.equalNCS

returns true if and only if t1 and t2 are equal up to differences in
case. 


B02) How do you read and write text in BETA?

Texts are written onto standard output by: 

   'hello'->screen.puttext;

which writes the string 'hello' on the screen at current cursor
position. 

   'hello'->screen.putline;

also writes a carriage-return. 

Integers are written by: 

   7->screen.putInt;

If you want to write onto other text variables (such as t: @text), you
can do it by: 

   'hello'->t.puttext;
   'hello'->t.putline;
   7->t.putInt;

Reading texts is equally easy: 

   keyboard.getline->s[];

reads a line of text from the keyboard, and assigns a reference to the
read text to the text reference s (assumed to be declared as s: ^text).

Reading from other texts (e.g. t) is done by: 

   t.getline->s[];



B03) Why does getInt followed by getLine not necessarily work as expected?

You have to be careful when scanning input entered from the keyboard.
For example, if your program has a section of the form 

   keyboard.getInt->...; 
   ...
   keyboard.getLine->...;

and you enter, say, 

   42<return>
   foo<return>

then the string returned by keyboard.getLine will be empty because 
getInt stops scanning immediately after 42 and does not consume the
(non-numeric) new-line character. [Thus, entering 

   42foo<return>

works correctly.] You may insert the line 

   (if keyboard.peek=ascii.newline then keyboard.get if);

between the calls to getInt and getLine to get the desired effect, or
even call 

   keyboard.scanWhiteSpace

in which case, however, you won't be able to enter a string starting
with white-space characters, similar to the functionality of C's
library function scanf(). 


B04) What is the rationale behind the Mjolner BETA System file
directory structures?

This entry describes the file structure of the Mjolner BETA System.
The entry is intended as an illustration of one efficient way to
structure the files of a BETA development project. At the same time,
this file structure is used all over the existing Mjolner BETA System
to structure the various subsystems of the Mjolner BETA System. 

Let us assume that the development project is called odin, and that it
consists of (at least) three subprojects, called brage, vidar, and 
vale. 

We would then define the following file structure (brage/ indicates
that brage is the name of a subdirectory): 

   odin --+-- brage/
          |
          +-- vidar/
          |
          +-- vale/

Each of the three subprojects may exists in different versions,
reflecting the development history. These versions are kept in
separate subdirectories for each subproject. Let us illustrate with 
vidar (having versions 1.0, 1.1, and 1.2): 

   vidar -+-- v1.0/
          |
          +-- v1.1/
          |
          +-- v1.2/

A configuration of odin now consists of the combination of the
corresponding versions of the subprojects. 

Each version of each subproject has the following directory structure
(here illustrated with the 1.1 version): 

   v1.1 --+-- F1.bet
          |
          +-- F2.bet
          |
          +-- ...
          |
          +-- Fn.bet
          |
          +-- private/
          |
          +-- demo/
          |
          +-- test/
          |
          +-- (* ast files *)
          |
          +-- (* code directories *)

The Fi.bet files contain the public interface files for the v1.1
version of the subproject. 

The private subdirectory contains the implementation fragments for the
Fi.bet interface files (see later). 

The demo subdirectory contains demo programs illustrating the usage of
this subproject. 

The test subdirectory contains programs for testing the functionality
of this subproject. 

The (* ast files *) indicates that there will be an Fi.ast file (or an
Fi.astL for PC systems) for each Fi.bet, containing the abstract
syntax tree (AST) representation of the Fi.bet. 

The (* code directories *) indicates that there will be one
subdirectory for each machine type. Currently, the possible
subdirectories are: sun3, sun4, sun4s, hpux8, hpux9, snake, mac, and 
linux. There may be one subdirectory of each machine type. 

The substructure consisting of (* ast files *) and (* code directories
*) is shared by ALL directories, containing compiled BETA source
files, and will therefore not be mentioned further below. 

The demo and test subdirectories may be further structured, possibly
with a subdirectory for each interface file Fi, but may also follow
different layouts. 

The private subdirectory is divided into the following substructure: 

   private -+-- F1Body.bet
            |
            +-- F2Body.bet
            |
            +-- ...
            |
            +-- FnBody.bet
            |
            +-- external/
            |
            +-- (* ast files *)
            |
            +-- (* code directories *)

where FiBody.bet contains the implementation fragments for the
interface files. 

The FiBody.bet files may be machine-independent implementations or
machine-dependent implementations. The FiBody.bet files therefore
follow the following naming convention: 

FiBody.bet 
   is the name of a machine-independent implementation 
Fi_macBody.bet 
   is the name of a machine-dependent implementation(here for
   macintosh) 

In most cases, there exists one implementation file for each interface
file, but for large (or complex) interface files, multiple
implementation files may exist (apart from the different machine
dependent implementation files). 

The external subdirectory contains non-BETA source files (such as C
source code), and other files which are not used directly by the
Mjolner BETA System, such as Makefiles, etc. The directory structure
of external follows the conventions of the non-BETA system used (e.g.
the C compiler). 


B05) What do the (* idx+ *), etc. comments mean?

At different places in the Mjolner BETA System interface files, you
may encounter comments of the form (* idx=2 *), (* idx+ *), or (* idx-
*). These are not compiler options - the compiler totally ignores all
comments. Instead, the comments are used for formatting the interface
files for the documentation. They can be safely ignored. 


PART V: Platform Specific Issues



SECTION V: BETA on Macintosh



M01) What are the system requirements to run BETA on Macintosh?

You need a minimum machine configuration of 5 Mb memory (8 Mb is
recommended running system 7.x or MultiFinder), and a MC68020
processor or later. That is, BETA runs on machines like Classic II,
SE/30, LC, LC II, LC III, Centris, and all Macintosh II, Quadra and
PowerBook models (except PowerBook 100). BETA cannot be used at Mac
Plus, SE, and Classic. BETA works on PowerPC, please look at question 
M04. You will need at least 16 Mb of free space on your harddisk. You
will also need the MPW environment, please see question M02. Finally
you will need an FPU to be able to use reals, please see question M03.


M02) What is MPW. Where do I get it?

MPW stands for "Macintosh Programmers Workshop", which is the official
programming environment for the Macintosh, supported by Apple, Inc.
The BETA compiler runs as a MPW tool, that is, it is a command, that
can be invoked from the MPW Shell. 

You will need MPW 3.2 or later to use BETA. In addition to the MPW 
Shell, the compiler uses the MPW Link and Rez tools to build the
programs. 

MPW can be obtained from APDA, Apple Programmers Developer
Association, e-mail: apda@applelink.apple.com. 

Mjolner Informatics is currently working on a new compiler, that can
be run without MPW, based on the Toolserver technology. 


M03) Do I need a floating point unit to use BETA?

Yes, to be able to run BETA programs, that use "reals", your machine
should have a built-in FPU, *or* you can install an FPU simulator.
Several free/shareware FPU simulators are available, e.g. SoftwareFPU,
which can be fetched from any info-mac site, e.g. 
sumex-aim.stanford.edu. 


M04) Does BETA work on PowerPC machines?

BETA can be run on PowerMac's using the MC680x0 simulator. That is,
the applications will run with the usual slowdown for simulated
programs on PowerMac. Mjolner Informatics is currenly working on a
compiler generating native PowerPC code. 


SECTION VI: BETA on Windows 95 and Windows NT



W01) What are the system requirements to run BETA on Windows 95 and
Windows 95?

You need a hardware configuration with Intel 386/486/Pentium CPU (or
equivalent) with 16Mb RAM (32 recommended) and 45 Mb of free disk
space. 


W02) SDK Requirements for Windows 95 or Windows NT

In order to use the Mjolner BETA System you need to have an assembler,
a linker, a make utility and C libraries from either Microsoft or
Borland. The Microsoft utilities are recommended. 

These utilities must satisfy the following: 

1. Microsoft 

   Assembler:
      Install one of the following 
         MASM386.EXE and EDITBIN.EXE from the Microsoft WIN32SDK. 
         ML.EXE, which can be bought as a seperate tool from
         Microsoft. ML.EXE is also part of Microsoft Development
         Network (level 2). 
   Linker:
         LINK.EXE from the Microsoft WIN32SDK. LINK.EXE is also part
         of Microsoft Visual C++. 
   Make:
         NMAKE.EXE from the Microsoft WIN32SDK. NMAKE.EXE is also part
         of Microsoft Visual C++. 
   C libraries:
         from the Microsoft WIN32SDK, or from Microsoft Visual C++. 

   If you have installed Microsoft Visual C++ 2.0 or later for Windows
   95 or Windows NT, all you need to install additionally is an
   assembler. You can install either: 
      MASM386.EXE and EDITBIN.EXE from the Microsoft WIN32SDK. 
      or ML.EXE, which can be bought as a seperate tool from
      Microsoft. 
2. Borland. 

   Assembler:
         TASM32.EXE, which is sold as a separate tool from Borland. 
   Linker:
         TLINK32.EXE (version 1.0), which is included in the above
         Assembler package from Borland, does not work under Windows
         95. 
         You need to obtain the TLINK32.EXE linker (version 1.50),
         which is part of the Borland C++ (version >= 4.5). 
   Make:
         MAKE.EXE, which is included in the above Assembler package
         from Borland, and is also part of Borland C++ (version >=
         4.5). 
   C libraries:
         must be obtained from e.g. Borland C++ (version >= 4.5). 

   If you have installed Borland C++ for Windows 95/NT, version 4.5 or
   later, all you need to install additionally is Borland Assembler
   (available from Borland). 

You can purchase these utilities from either Microsoft or Borland.
Please contact their national representatives for ordering
information. 


W03) Why do I need a MAKE facility?

Question:
I do not have a MAKE facility on my Windows 95/NT machine. Why do I
need that - I thought that the BETA compiler analyzed the dependencies
itself? 

Answer:
The BETA compiler keeps track of dependencies between all involved
beta files. However, if you want to link in object files generated by
an external C compiler og assembler, you may add a MAKE property to
make the BETA compiler invoke the make-facility to keep the external
objectfiles up-to-date (see section 2.4 in "The Mjolner BETA System -
Using on Windows 95 / Windows NT [mia94-32]). 

If you do not use the MAKE property in your programs, in principle
you do not need a make facility. But since a few of the standard
libraries included in the Mjolner BETA System contains such MAKE
properties, you will need a make-facility anyway. However, since all
external object files in the standard libraries are up-to-date when
distributed by Mjolner Informatics, you can do with a dummy
make-utility. 

For instance you may create a C file like this: 

main()
{
  exit(0);
}

compile it with your C compiler, and install it in your path with the
name MAKE.EXE (if you use the Borland SDK) or NMAKE.EXE (if you use
the Microsoft SDK). 


W04) Error in directory scan using Borland SDK?

Question:
Why does the following program fail with a memory exception on my
windows 95/NT machine? I am using v5.1(6) of the compiler and SDK=bor.

ORIGIN '~beta/basiclib/v1.4/directory';
--PROGRAM:descriptor--
(# d: @directory; 
do '.' -> d.name;
   d.scanEntries
   (# 
   do select
      (# whenDir::<
           (# do (theDir).entry.path.name -> screen.putline #);
      #);
   #);
#)

Answer:
This is due to an error in the directory library. The problem is, that
the file %betalib%\sysutils\v1.4\private\nti\bor\directory_ntbody.obj
in the release 3.1 distribution of the Mjolner BETA System has been
compiled with an older version of the compiler. The solution is to
delete the obj-file and recompile 
%betalib%\sysutils\v1.4\private\directory_ntbody.bet. 


W05) Make-error for lazyref_gc.c using Borland SDK?

Question:
When I use persistentstore or objectserver in my Windows 95/NT
application I get this error from the compiler: 

MAKE Version 3.7  Copyright (c) 1987, 1994 Borland International
Fatal: 'c:\beta\betarun\v2.7\nti\c\lazyref_gc.c' does not exist -
don't know how to make it

I have installed BETA in C:\BETA. 

Answer:
The reason is that there were some problems to get the two make
facilities from Microsoft and Borland to work with BETA. The solution
was to handle the lazyref_gc.c file specially in the make files.
However, the lazyref_gc.c file is part of the source code for the BETA
runtime system, which is not distributed with the release. 

Solution:
Create a dummy lazyref_gc.c and update timestamp of corresponding .obj
file. This can be done by compiling and executing the following
program: 

ORIGIN '~beta/basiclib/v1.4/directory';
INCLUDE '~beta/sysutils/v1.4/envstring';
--PROGRAM: descriptor--
(# d: @directory;
   f: @file;
do ' Create directory for C file ' -> putline;
   '$(BETALIB)/betarun/v2.7/nti/C' -> expandEnvVar -> d.name;
   (if not d.entry.exists then d.touch if);
   
   ' Create dummy C file ' -> putline;
   '/lazyref_gc.c' -> ((d.name).copy).append -> f.name;
   (if not f.entry.exists then f.touch if);
   
   ' Update timestamp of dependant object file ' -> putline;
   '$(BETALIB)/objectserver/v2.1/private/nti/$(SDK)/lazyref_gc.obj' 
     -> expandEnvVar -> f.name;
   f.touch;
#)



SECTION VII: BETA on HPUX



HP01) Why do some callbacks cause "Illegal Instruction" on hpux9pa
(using v5.0 of the compiler)?

If the following program is compiled and run on an hpux9pa (HP series
700 HPPA, HP-UX 9.x) using the BETA compiler version v5.0), it
displays a window with the text "Timer" in it, prints a random number
of 7'digits on the screen, and then dies with "Illegal Instruction": 

   ORIGIN '~beta/Xt/v1.8/awenv';
   --- program: descriptor ---
   AwEnv
   (# l: @Command
        (# init:: (# do 'Timer'->label #)#);
      t: @Timer
        (# timeOut:: (# do 10->start; '7'->Put; #) #);
   do l.init;
      10->t.start;
   #)

The reason for this, is that in v2.6 of the hpux9pa runtime system for
BETA there is an error, which occurs if a callback is called very soon
after it is installed. In this case it is called ~10 ms after being
installed, and almost no other code has been executed in this period
of time. In this situation an HPPA cache should have been flushed to
ensure the correct behaviour, but there was an error in the runtime
system delivered with release 3.0 of the Mjolner BETA System. The
solution is to acquire a patched runtime system from Mjolner
Informatics. 


SECTION VII: BETA on Linux



Lx01) How to make the BETA compiler version 5.0/5.1 work with Linux
ELF libraries

If you are using a Linux version with support for the ELF libraries,
the Mjolner BETA System cannot be used immediately. You will have to
introduce the following patch: 

1. Make sure that /usr/lib/crt0.o can be found. E.g. do this: 

           pushd /usr/lib; ln -s /usr/i486-linuxaout/lib/crt0.o; popd

2. Make sure the linker is called with "-m i386linux", either by
   adding 

           LINKOPT linux '-m i386linux';

   in the top of basiclib/v1.4/private/betaenv_unixbody.bet, or
   (preferable) by adding this in your .bashrc (or the corresponding
   stuff in your .tcshrc): 

           export BETALINKOPTIONS='-dc -dp -X -m i386linux';

   The BETALINKOPTIONS environment variable sets *all* options to the
   linker, that is why you have to set the other stuff in the variable
   too. 

Disclaimer: This has not been tried with the Motif libraries, but it
ought to work. 

Thanks to Erik Ernst <eernst@daimi.aau.dk> and Stephen J Bevan
<bevan@cs.man.ac.uk> for their investigations on this subject.

Jorgen Lindskov Knudsen / Aarhus University / jlk@daimi.aau.dk 
