On Mon, 6 Jan 2014 13:00:02 +0100
Martin Schreiber <[email protected]> wrote:
 
> > I would like a language that needs few strokes 
> > ... precise, expressive, powerful and smart
> Yup, mostly the intention of MSElang too, I like to add "readability".
Of course.
 
> > verbosity:
> > ...
> >     lab1.: create; left=10; top=20
> > The trick is the colon...
> 
> What I do not like in this approach is the dependency of semantic by
> the layout. For MSElang it is a no-go because MSElang is layout
> independent...
I think that program sources are text files and always will be.
Text files are organized in lines containing words separated by
blanks and punctuation, and I stick to it. I don't need to write things
like:
        writeln
        ;

or 

        procedure doit; begin writeln end; procedure again; begin
        doit end;

So, I think that line ends, expressive for the human being, can well be
expressive for the compiler too.


> In MSEgui with-statements are used often. I know that most Delphi
> experts preach that "with" is evil, I don't think so. MSElang has the
> mandatory alias name in with statements in order to avoid overlooked
> name clashes. In MSElang the example would be written as
> "
>  lab1:= tlabel.create();
>  with l:lab1 do
>   l.left:= 10;
>   l.top:= 20;
>  end;
> "
> The example makes not much sense because...
No problem, this example is clear, and it shows that me and you have
opposite ideas. First, the mandatory "()" for function calls, similar to
C. I really don't understand what is its purpose - unless the language
allows two identical identifiers in the same scope, "procedure create"
and "var create". For C it is different: it is so stupid that I can
understand anything.
Then your comment cites "overlooked name clashes", and I know the
problem. It is a phylosophic concept: should a language assume that the
programmer is wrong, or should it assume that the programmer knows
what he is doing? I prepend for the second... even if I know that
programmers sometimes overlook. But again see:

        lab1:
          .create
          .left = 10
          .top = 20

what can be overlooked? Of course, if you open a colon and then write a
hundred lines, you can feel a little lost because the code you are
writing at line 50 depends heavily on what you wrote on line 1. But
program sources are not romantic novels!

> > ";". A complete statement. A note about this: "lab1.create" is
> > interpreted as "lab1 := Tlabel.create" (what else could be this
> > statement: a constructor invocation without assignment?).
> 
> This also is against the philosophy of MSElang. Things what happen
> should be visible in code and they should look always the same. If
> there is an assignment, write it as assignment.
In this case I must say that there is nothing hidden.
"Class variable dot constructor" always means "construct that variable",
and probably nobody could write such a thing by mistake.
It resembles the problem some people have when writing in C:

        if (a=3) blabla;

As you know, this statement is wrong. I arrived from pascal to C about
10 years ago; in ten years, may be I made this error a couple of times;
too little to say that it is a serious C problem.

> > ... This idea goes even
> > further because the colon can be implicit ...
> >
> Against the MSElang design principles too, things should always look
> the same. In MSElang the ';' for example becomes a mandatory
> statement terminator. It helps to separate the statements while
> reading the code. In procedure headers the ';' has been replaced by
> ',' so in header definition and procedure call parameter separators
> look similar.
Even in my idea they always look the same, if you know the language.
But please note that you don't need to use the colon or implicit colon,
if you don't want.
And about the use of comma and semicolon in order to have the same
appearance in declaration and invocation... could be debatable.
Declarations and invocations are different things - why they should
appear the same?


> 
> >     var
> >             // after a "var" keyword, shouldn't be an
> > identifier? // but there is not: so the compiler tells the parser
> >             // "assume an implied colon"
> > This paradigm is simpler and more consistent...
> I don't understand the motivation. To solve a fascinating
> intellectual puzzle? This is another thing I like to avoid in MSElang.
> Terminating 'var' by 'end' is a possibility I have to think about. I
> assume same applies to 'const' and 'type'?
Perhaps you are missing a little! Of course colon and block termination
by "end" applies to everything - not only const var type... -
everything. Otherwise, it would not be consistent and useful.
Look:
    // inside a class declaration...
    procedure DoSelectDir(Sender: TObject);
    procedure DoSaveLayout(Sender: TObject);
    procedure ReadConfig; virtual;
    procedure WriteConfig; virtual;

becomes:
    procedure 
      DoSelectDir of TObject Sender
      DoSaveLayout of TObject Sender
      virtual
        ReadConfig
        WriteConfig
        end
      end

For my eyes it is cleaner.



> 
> > At a certain point, freepascal had to forbid 
> > declaring object variables after its methods, just because of that
> > ambiguity.
> 
> I don't understand, please explain.
Yes. I discovered this, because in more than one point my sources
stopped to work after upgrading freepascal. I don't remember precisely
in which upgrade it happened, perhaps from 2.4.x to 2.6.x.

Here:
http://www.freepascal.org/docs-html/user/userse62.html
you find:
"Error: Fields cannot appear after a method or property definition,
start a new visibility section first. Once a method or property has been
defined in a class or object, you cannot define any fields afterwards
without starting a new visibility section (such as public, private,
etc.). The reason is that otherwise the source code can appear
ambiguous to the compiler, since it is possible to use modifiers such
as default and register also as field names."

What to say. It may be that the programmer at freepascal chose the
wrong way. They could have simply forbidden to create identifiers named
"register" or "default" and so on. Or they may be right. Or pascal
language is flawed from the base. It is difficult to say. I think that
putting optional modifiers *after* the declaration is a bad idea. But
no languages are perfect. In my design, the general form of a
declaration is:

        keyword [modifiers] type identifier

like:
        var global int copies

There are very few clashes doing so. Probably you can not create a
variable named "var", but you can name it "global".

> 
> > You may ask "why the type specifier stays before the identifier, as
> > in C?". Because I think it is better, but the explanation is long.
> >
> I don't think it is better. When one searches a variable definition
> in code normally one want to find the variable name to check the type
> not the opposite. So scanning the name at the left edge of the editor
> window is easier than to follow the gap between type and name.

Yes I agree in part. But putting the type in front of the identifier
leads to a flexible syntax. And here the discussion can go anywhere...
because someone searches a lot, someone else uses funny names like
"iCounter" and "szMyName". I prefer the type before, because it lets me
write:

        int a=10 b=20


> 
> > Second heretic idea. One of the best things of pascal is its strong
> > typing system. But it is not strong enough, especially when some
> > kind of automatic type conversion is desired. ...
> > ... automatic conversions (I would call them "promoters").
> 
> Ouch. Another design principle of MSElang is: there are no implicit
> type conversions... :-)

Ouch. Closed mind? I must explain better. Implicit does not mean hidden.
Pascal itself does a lot of impliciting promoting, and nobody ever
complained about. Pure C does not, and sometimes I go crazy for that
(remember, I came from pascal...). Then I used a language for a while
(I don't name it: a visual basic for linux... :-) ). It had full and
outrageous implicit conversion. It lets you write:

        myname += 1             // myname is a string
        print counter+"12"      // counter is an integer

Most of the times things go smooth, anyway; but sometimes it produced
very funny and strange results.
Now a serious discussion; I've read some messages on this list about
types, conversions and so on. I found them very extreme, especially if
you think that every processor has a preferred bit size. I agree that
promoting from number to string should not be implicit; but why not,
under precise rules?. This is why I say that type system is too loose
in almost any language. Because "integer" can signify too many things,
not to say strings.

> 
> In MSElang one probably would write
> "
> sub s(const value: thenewtype): str8;
> begin
>  := DoTheConversionWithValue;
> end;
> ...
>  print(s(TheNewTypeValue));
> "
So you must remeber how is the name for converting thenewtype to str8.
And integer to str8, and boolean to str8, and boolean to utf8, and
integer to utf16. And what is worse, you always have to write them each
time you need them.


> > This 
> > way, the single print() can print anything. We can put it in a unit
> > and forget it.

> MSElang supports string8 (utf-8), string16 (utf-16), string32(UCS4)
> and bytestring which can contain any 8 bit encoding and binary data.
> There is no automatic or implicit conversion between different string
> types. There is no string type named "string" in MSElang, the users
> can define "string" as any of the four or even a self made object.
This seems to me very complicated. On the contrary, I think that
computers and compilers should work instead of the programmer, free in
the end to concentrate on the real problems instead of converting from
utf8 to ucs4. Because I suppose that, if the programmer passes an ucs4
to an utf8 routine, the compiler complains and stops, right?


> 
> > I have other heretic things in my mind, but for now it should be
> > enough. Let me know what do you think.
> >
> I am curious about more and what you think about the MSElang
> approach. :-)
I think we have nothing to share, until now. No offence, of course - we
are speaking of different ideas. The MSELang approach seems to me a
worser pascal, and that is all. If you will succeed in writing a
MSELang compiler, it will be 20% faster in compilation, 3% faster in
execution, and users will not want to use it. Of course, there will be
a 2% users, targeted perhaps to embedded systems, which will appreciate
the precision and rigidness, but the 98% will think that MSELang is not
enough modern. I must add that I don't understand users, perhaps
because there are so many, and also because of market strategies.
So there is place in the world for everything.

You are curious about more of my ideas, if I well understand. I believe
that any my idea is opposite of your, but a pair of them can be
introduced, for the sake of discussion. Let's talk about write/writeln
in pascal. It is funny that such a beatiful language has write/writeln
which violate the own pascal syntax. It is a pity that the user can not
do the same. So my design allows a variable number of
arguments, natively, with heavy use of overloading and "implicit
repetition" which are so bad for you. Let's say that we write a
procedure "print", so called to distinguish it from writeln. The set of
declarations is:

        // prints a text
        proc print of text what is
          ...
          end
        // we want other kinds too:
        proc print of int number is ...
        proc print of bool truefalse is ...

Now the invocation:

        print "My name is " myname " and I am " myage

As you have seen earlier, an automatic repetition takes place.
The compiler sees "print"; from the current scope it builds a list of
all procedures named "print". The it looks at the first argument, and
determine its type. With these two informations, it deletes from the
list of candidates all the procedure not suitable. It remains with only
one, "print text", so this gets compiled. But the statement is not
terminated! So it builds again a list of candidates, and restarts. When
it is time to print "myage", of course it will choose "print int". Then
the statement is finished. In assembler, the above single statement
looks like this:

        push "My name is "
        call print_text
        push myname
        call print_text
        push myage
        call print_int

If defined, a "print_init" and a "print_finish" are invoked as the
first and last step. Please note that every routine has a
well defined stack configuration, differently from C, where a routine
does not know what is in the stack. For this reason, this method of
repeated call may be slower than C, but more controlled. I stop here to
make it simple, because there is much more regarding keywords, optional
arguments, aliases and more all developed around this paradigma. But
one thing is important, about cycles. Too many times one must write a
cycle to operate on an array or list. In my language, if I want to dump
an entire list to console, I can write:

        print "The contents of mylist are: " every mylist

The compiler compiles a cycle for every element of the list, thanks to
the fact that procedures are "restartable". This is different from some
facilities of other languages, like map(); very different.

Last curious thing, "outer". It simply means "one level of lexical scope
above the current". It can be used in cycles:

        repeat
          ...
          while
            ...
            outer break         // this breaks two cycles
          end
        until

It can be used to access global variables from inside routines, in
case of name conflict:

        var int i
        proc sum is
          var int i
          for i in 1..10 outer i = outer i + i
          end

This is a stupid example, but outer is useful in other situations. I
don't want to write a complete tractation, it would take some days.

To conclude, it should seem clear now that what I have in mind has
nothing to do with pascal; it sometimes borrows ideas here and there
from other languages, but still other are very new. My goal is to
generate bytecode, in order to port the language quickly everywhere and
use it as a scripting language for complex application and embedded
systems. An interpreter for bytecode is easy and quick to do, while a
single compiler on linux would be enough for many situations.

With the time I am granting to this project, it will take for ever...
but this is the situation.

Regards,
linuxfan


------------------------------------------------------------------------------
Rapidly troubleshoot problems before they affect your business. Most IT 
organizations don't have a clear picture of how application performance 
affects their revenue. With AppDynamics, you get 100% visibility into your 
Java,.NET, & PHP application. Start your 15-day FREE TRIAL of AppDynamics Pro!
http://pubads.g.doubleclick.net/gampad/clk?id=84349831&iu=/4140/ostg.clktrk
_______________________________________________
mseide-msegui-talk mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mseide-msegui-talk

Reply via email to