Language Syntax Suggestion

Matthew Tuck matty@box.net.au
Sat, 13 Mar 1999 15:58:17 +1030


Jeremy Dunn wrote:

>> Actually the term "collection" seems to be becoming the standard for
>> discussing this sort of structure - ...
> Fine, a COLLECTION then. I don't care what we call it just so long as we
> all agree on what we are talking about. When I say SET I mean a
> collection of items that may or may not be ordered and which may or may
> not be of the same type and which may or may not have duplicates.

That's no problem, I was only trying to prevent talking about different
things, and if everything uses different terms for different things it
can be difficult.

> Defining literals for both ordered and unordered collections can have
> its advantages in certain cases. Let us say I write the expression
> {A.3.4} (where A is the subtraction operator), this represents both the
> expressions {A,3,4} and {A,4,3}. The result of the expression {A.3.4}
> would then be a set of all possible results obtained by permuting the
> arguments, or a set {,-1,1} in this case.

In a permutation wouldn't you have to permute the A as well?

I'm not convinced that unordered and dupeless literals are useless, but
I would not think it was a good idea to allow implicit permutation like
this.  It's similar to implicit conversion, in that you might not want
it (wrote . instead of ,) and could get the wrong result.  Plus I don't
remember ever having to need to take the permutation of a set into all
possible lists.  A "permute" function would be nicer than trying to
embed this implicit behaviour into the language.

> There are certain functions
> (string pattern matching comes to mind) where this is useful for
> defining a range of inputs rather than explicitly typing them all out.

OK.  I think that it might certainly be useful sometimes, but often
enough to warrant specially expressing it in the language?
 
>> This is basically what LISP does.  Everything is done with lists,
>> including function applications.
 
> This is true to a point. LISP does allow you to create lists like '(a b
> c) but it does not treat what I call a FUNCTION SET as a list i.e. you
> cannot cannot write something like (nth (+ 2 3 4) 1) to extract one of
> the arguments to the expression. Being able to do this would eliminate
> the need for many math functions that are necessary in other languages.
> I will come back to this point later.

So the result of your expression would be +?

> LISP also does not allow you to
> collect functions or arguments in the manner that I was proposing using
> the apostrophe and caret, this feature reduces expressions and reduces
> the amount of bracketing that one has to do. I tried this out on my CRC
> math tables book with large lists of equations to experiment with
> notational choices and found this to work far better than other choices.

OK, LISP might not but it could, and this is probably orthogonal to the
choice of infix or prefix operators.
 
>> Just a question - why do you allow two different ways of writing
>> strings, yet not two different ways of writing expressions?
> I assume you mean why do I allow both (boat) and (,b,o,a,t)? In a holor
> set like {,1,2,3} we have to write it this way because we have to insure
> that we are not confusing it with {123} which would simply be the
> integer 123 rather than the separate integers 1, 2 and 3. In a string
> set it is fairly safe and convenient to make the assumption that
> whatever is in the set is an ordered set. We want to do this so that we
> do not have to double our typing by putting in all those commas.

What I'm essentially saying is that sometimes you have to add
technically superfluous syntactical structures.

> We do
> have to add some extra punctuation if we have any unordered elements
> however. For instance, if we write (,book.k.e,eper) we have to add the
> two commas to indicate that the two parts of the string on either side
> of the "ke" are ordered while only "ke" is unordered.

I would have interpreted this as {,{,b,o,o,k,.,k,.,e},{,e,p,e,r}}.

> We can use the
> convention that the ordering remains the same until changed by a new
> ordering. Doing this we can eliminate one more period and write
> (,book.ke,eper), which would be equivalent to both the string
> "bookkeeper" and "bookekeper". These types of conveniences only work for
> strings and would be very ambiguous for numbers, that is why I made the
> special case for strings.

Why ambiguous for numbers.  Even though I admit it might be very decimal
system oriented, 5.0 still make sense to match 510, 520 etc.   Sure it
might clash with the number 5 point 0, but the "." symbol is arbitrary
anyway.

>> I thought that was a set?  Does that mean I can assign a complex number
>> to a set of numbers?
> This refers to a complex number being denoted as {,a,b}. Yes, a complex
> number is simply a specific type of Holor set (or matrix). Any holor can
> be part of another holor. You could write {{,a,b}{,c,d}} if you wanted
> to. The addition, subtraction, division and multiplication operators all
> become polymorphic and perform matrix-matrix, matrix-vector,
> matrix-scalar, vector-scalar and scalar-scalar forms of the operation.
> The arithmetic operators determine the kind and order of the input holor
> and perform the holor algebra necessary with no need for separate
> functions to do all of these tasks.

OK, we're really talking about treating numbers as matrices here,
sorry.  That's reasonable, I've always liked this concept.

I would set up some sort of type that applies for numbers, vectors,
matrices etc. with the usual operations.  It's unlikely we would ever do
implementation inheritance since the matrix addition would be too
inefficient for numbers although I could they could be optimised.

But the issue still remains that if you represent sets and vectors as
the same sort of structure you can end up assigning one to the other
when you don't want to.  If you set up your typing system like so:

                  - Base -
                 /   |    \ 
           Matrix  Number  Set

etc., you can still specify the operations once for the base, put syntax
over them just fine, and avoid mixing them.

>                         a,A addition/subtraction
>                         b,B multiplication/division
>                         c,C power/root
>                         d,d log/antilog
> 
> The function names are short because they are common operations. Upper
> case function names help designate operations that are inverses of the
> lower case ones and the letter progression is coincident with the
> heirarchy of how one operation is an expansion of the preceding one.

How is log an expansion of power?  Binary operations have TWO inverses,
it just so happens + and / are commutative so the inverses are the
same.  Both root and log are the inverses of exponentation.

> Any
> of these operations may have multiple inputs i.e. {c,2,3,4} is the same
> as {c,{c,{c,2},3},4} and so on. A notion that I would like to introduce
> is the use of default arguments to these functions if certain arguments
> are missing. For instance:

Wouldn't you mean {c,{c,2,3},4}?

> Addition: If the addition function has one argument it is assumed that
> we are adding 1 to it. {a,x} is the same as x+1.
> Subtraction: If the subtraction function has one argument it is assumed
> that we are decrementing the value by 1. {A,x} is the same as x-1.

I would think it would be 0 for consistency, ie {a,3} = 3, {a,3,3} = 6,
{a,3,3,3} = 9.

> etc.
> It should be clear that these changes are very simple to make and exist
> in no language that I can think of. We eliminate the need for several
> functions and make many very common arithmetical procedures very simple.

I don't really see that setting defaults on everything is a good idea. 
Default parameters are there to save space where there is a very common
default, and although your defaults are not uncommon and probably more
used than most, they're still often not used.  Hence defaults are not
really worth a programmer having to read an expression and think 'what
was that default again?'

I think a better use of leaving parameters blank is for partial
application, e.g. *2 is a double function, or alternatively just
creating a "Double" wrapper function whose meaning is immediately
obvious.

> Matthew questions the utility of writing a real number in the form
> {r,x,y}, is there any advantage? Perhaps only in having a completely
> rigid format, doing it this way enables us to use any operation which
> can operate upon a set operate upon a real number that way too if we
> wish.

What functions would be useful on r's?

> Another reason would be that we are using the period to denote
> unordered elements in collections and wish to avoid using the same
> symbol for another purpose, ideally, one function name or symbol should
> be used only once. By writing all operations in this way the user is
> never bothered with learning rules of precedence or of context.

How does this improve on "5"?  If you try to make everything fit into {}
you're essentially removing programmers' readability cues as to what
that thing is.

Different things should look different, and that means using different
symbols.  If you have things in the language that have different
semantics, that would usually translate into different syntax.

If there is benefit in fitting numbers into sets, OK, but is there?

-- 
     Matthew Tuck - Software Developer & All-Round Nice Guy
             mailto:matty@box.net.au (ICQ #8125618)
       Check out the Ultra programming language project!
              http://www.box.net.au/~matty/ultra/