From: kers@hplb.hpl.hp.com (Chris Dollin)
Newsgroups: comp.sys.acorn.tech
Subject: Re: New Language/Compiler (ideas wanted)
Date: 17 Aug 92 07:35:17 GMT
Organization: Hewlett-Packard Laboratories, Bristol, UK.

In article ... bwc@waikato.ac.nz (Ug!) writes:

|    Halfdan Ingvarsson asks for ideas on new language features.
|
|    (deep breath)  Hokay, here we go:
|
|    Firstly, have a look at Oberon-2.  The descriptions are available 
|    by anonymous ftp from ETH.  Some really neat ideas there.

Make sure you've looked hard at Lisp, Scheme, and Pop11 too. The pure
functional languages are also a good source of ideas.

| Generics. Any new language worth its salt should consider this
| issue. One of the reasons why Ada beats C++ for productivity is
| that generics beats object oriented for reuseability.  (the
| other reasons have to do with the great tools that come with
| Ada, and the strict licensing scheme which ensures
| compatability)

C++ *has* generics, although they call them ``templates'', they were added
late in the day, they have a horrid syntax [*1], and they silently explode
your code for you.

| Subranges.  At some stage I'd love to build a language which has
| *no* concept of fixed data-type sizes.  Of course, you could
| then have a library routine which defines a type Word (much like
| Modula-2's System.WORD) and Byte and so forth.  However, this is
| entirely a portability concept, and so is not really applicable
| to what you are trying to do, but even so, just think how nice
| it would be to be able to use 320-bit integers...

Lisp. Scheme. Poplog Pop11. Smalltalk. Don't forget ratios and complexes.

| Overloading.  Ada has this, without being Object-oriented.  This
| coupled with generics gives you better reuseability than object
| instantiation. Both functional and operator please.  Don't worry
| about redefining operator precedence:  leave 'em as they are,
| and folks can work with that.

Common Lisp + CLOS has this. If you want to do it properly, allow
user-definable operator *symbols*, don't restrict them to built-in operators
(both Ada and C++ have this totally unnecessary restriction). [User-definable
precedence is, sadly, a Bad Idea.

| One of the things I would like is a 'string' concept, which
| automatically handles groups (arrays) of items which grow and
| shrink - maybe a 'bag'.  In this way you could have a 'STRING OF
| CHARACTER' or a 'STRING OF INTEGER'. 'STRING', like 'ARRAY'
| allocates space, but it can be resized etc dynamically.  Useful.

Lists. Sets. Hash tables (both content and address based).

| Projection.  See previously mentioned Oberon-2.  This completely
| redefines the way inheritance and stuff works.  Keeps the
| language procedural rather than data-driven, which is nice for
| those of us who think in processes, not in data-flows.  Coupled
| with generics, should make life very interesting. Also, by
| combining with overloading gives similar capability to object-
| oriented, although dynamic binding might be tricky to fudge.

| Packages or Modules or *something*!  Preferably coping
| automatically with linking (C... yuck!).

Yes.

| No limitations like 'strings can only be up to 255 in length'.
| Yuck!

The restriction I have in mind for my language Pepper is that no object can
have a length bigger than that which will fit in a fixnum (an immediate-value
integer), which limits them to 2^29 elements. This limits bit arrays to 64Mb.
Fortunately this restriction seems unlikely to bite for a few years yet.

| There is no number 8.

Ahem. I deleted the section numbers when I reformatted the message.

| Can link up with C, including C I/O.

Yes, cross-calling in some manner is essential. What's more difficult -- but
necessary in the long run -- is to give C some way of calling *your* routines.

| A good 'ABSTRACT' (or opaque) data type.  Modula-2 almost does
| it, but not quite, since it limits the size of its opaque types
| to the size of a pointer.  Ada goes one better, but then
| requires you to say what's actually in it, so what's the point?
| Opaque data types enable data-hiding (great for abstraction
| purposes), and are all too often very useful.  In C, I kludge
| this by passing back a pointer to the type as a 'void *'.

I'd vote *against* abstract data types and *for* a simple but powerful module
structure. After all, all ADTs do is to restrict the names that the user is
allowed access to -- they're not allowed to use the representational names,
eg, the fields of a structure; rather, they have access via a set of
procedures. But this is just what modules are for, so why conflate the two
concepts? [C++ does this with classes, and look at the resulting mess.]

Have we said ``Garbage collection'' yet? Have garbage collection. Have Garbage
Collection. HAVE GARBAGE COLLECTION.

Words of advice:

Read Hoares ``Hints on Programming Language design''.

Favour simplicity of explanation over simplicity of implementation.

Make it easy to relate different language structures.

When in doubt, throw it out.

Avoid designing your first language. Experience shows that the second and
subsequent ones are better.

Programmers should not design languages; they're too close to the problem, and
want features that make some of their pet hates easier to cope with.

Non-programmers should not design languages; they have no idea what kinds of
things should go into a language.

Always have someone else critique your language. You don't have to do what
they say, but listen carefully to what they *do* say.

[*1] For compatability with the rest of the language.
--

Regards,    | "Layered protocols give the software implementor a chance to
Kers.       | ruin his performance in each layer." - Don Gillies