On Tue, 2006-09-05 at 11:07 -0400, Peter Tanski wrote:

> I caught the ?v requirement in pattern matches.  That's o.k.; it's  
> your language.  

No, it is an Open Source project, it belongs to the whole world.

> If I were defining my own language I would scrap the  
> whole Erlang-syntax set in favor of more advanced parsing using  
> layout rules.  

I chose not to do that. You could implement a lexer that
did this now .. it has no impact on the parser.

I've done this for Python, which uses layout.
I quite like layout.

But many people do not like layout.

A stream (non layout) language can ALSO do layout,
so it is the obvious market winner :)

> If I were creating a language using the technology  
> available today (i.e., parsers, reasoners) all those trailing colons,  
> curly-bracketed code blocks, etc. may be available to programmers-- 
> even Haskell allows them for patterns defined contrary to layout  
> rules--but they literally get in the way of the programmer's ability  
> to read the program and reason about its operations. 

They don't. You're missing the point: the primary audience is
intended to the C++ programmers. The curly brackets are
actually a pain -- we're short of brackets but we waste one
set on a fairly specialised case. Why?

Because it HELPS C++ programmers read the code, and reason
about it.  Trust me (as an ex-C++ programmer ..). I went
to a LOT of trouble to allow:

        for_each { i=0; } { i<10 } { ++i; } {
                print i; endl;
        };

which looks very similar to C++ for loop. C++ programmers
can read this without blinking. It's a little hard to
comprehend why the syntax is exactly as it is.

Until you realise this isn't a language defined control
structure at all. It's a higher order function defined
in the library.

There are about 6 different kinds of syntactic sugar
involved here, to make this C++ like syntax actually
work. The longhand is:

        for_each 
                (proc() { i=0; })
                (fun():bool={ return i<10; })
                (proc() { ++i; })
                (proc(){print i; endl (); })
        ;

All the arguments are closures, so that the 'expressions'
are lazily evaluated. The above code is literally generated
by the parser/desugarer .. and the optimiser reduces
this down to fast closure free C++. 

>  If I wanted a  
> more procedural layout I would probably follow Ada or Fortran rules  
> for sequences.  Likewise declarations for "fun," make it easier to  
> write a parser and might seem nice to ML users but they are messy and  
> smack of a primitive parsing strategy (not a good indicator of the  
> other capabilities in the system); 

The parser (excluding user defined syntax) is LALR(1) and
unambiguous .. not a single shift/reduce conflict.

The choice is quite deliberate .. it means anyone
can write a tool. Compare to C++ .. where no one has
even succeeded in writing a parser that works :)

> worse, they are a novelty to  
> programmers coming from C/C++.  Functions may be denoted by requiring  
> the first letter of the function name be lower-case, 

Out of the question for i18n reasons. The set of admissible
characters in an identifier is fixed by ISO recommendations
(we're talking Unicode here).

> otherwise by  
> context; for types the first letter (and only the first letter)  
> should be upper case, the first definition in a union should not  
> require '|', 

It doesn't -- I just follow the convention, because it is the
only sensible one when using a vertical layout. 

> it  
> would be more intuitive if you defined the recursive types in the  
> name, such as:
> 
> union rec Tree =
>       | Leaf of Tree * Tree
>       | Tip int

'rec' is not required. Everything Felix is uses recursive
setwise lookup.

> What I would use is:
> 
> union Tree = Leaf (Tree * Tree)
>                     | Tip int

You can do that. (I HATE that layout).

You can also define a list like this:

        typedef list = 1 + int * list;

The 'as' form:

        typedef list = 1 + int * xxx as xxx;

is there to guarantee no algebraic type expression
requires a name, not even an alias, that is,
every structurally typed type has a closed form.

> --although the 'union' keyword is itself confusing to programmers  
> coming from C or C++; it is not apparent from context that this  
> construction doesn't map the two over the same region of memory.

In fact it was intended originally to do just that.
It doesn't, due to a restriction in C++ (unions
of constructible types cannot even be declared).

> I don't recommend requiring an explicit keyword to allow recursion in  
> type declarations because *that* is also confusing. 

None is required. Everything is recursive in Felix.
There is no need for forward declarations.. and no way
to write them.

Declarations are NOT sequential. A scope consists
of a SET of declarations: you can write:

        typedef a = b;
        typedef b = int;

and it works fine. Ordering of declarations is irrelevant.

> > the 'as' is an assignment naming a type, i.e. a typedef
> 
> I reiterate what I said in a previous email.  If your intention is to  
> map the learning curve for programmers from:
> 
> C++ -> Felix -> ML -> Haskell
> 
> Either get rid of keywords such as 'typedef' that are used in C/C++  
> or use them in the same or similar way to how they are used in C/C++ 

It is. The syntax is different: you write

        typedef id = type_expr;

to declare id is an alias for type_expr. Changing the
syntax of types from the absolute mess in C/C++ is 
of course deliberate: one of the key features is
that types have a nice combinatorial closed form.


> (in your explanation here you seem to).  At this point Felix is  
> working backwords--only someone already familiar with OCaml would  
> understand that 'typedef' in Felix is similar to typedef in OCaml;  
> someone (myself included) who knows C/C++ sees 'typedef' in a  
> language that is the "successor to C++" and thinks: "oh, I get it; a  
> typedef is a synonym and has the same syntax!"

Yup. Typedef IS a synonym. But since types have closed
forms and are combinatorial in Felix, it uses a saner
syntax every C++ user WANTS.

In fact .. typedef xx = ... is being proposed for ISO C++,
because amoung other reasons .. apart from sanity ..
it is required for type recursion. Without this
syntax, templates cannot be recursive:

        typedef t = X<t>; // recursion

just cannot be written with the syntax

        typedef X<t> t;

because 't' is not in scope. No idea how this fixes
indirect recursion .. but of course Felix handles
this since all identifiers have 'function scope',
that is, they're visible in the whole block in
which they're defined (even before they're defined).

-- 
John Skaller <skaller at users dot sf dot net>
Felix, successor to C++: http://felix.sf.net


-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
Felix-language mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/felix-language

Reply via email to