On 18/08/2012, at 12:56 AM, Dobes Vandermeer wrote:

> 
> Yes, I do think this is a bit troublesome.  The compiler should not allow you 
> to use a val or var before it is initialized.

Its hard to stop. And they are initialised, just not by the initialiser you 
give.
Semantically variables are initialised by their C++ default constructor,
and the user "initialisation" is always an assignment -- if the val/var or
whatever is represented by storage that is.

>  What if the val is a reference type?  Does that let you dereference a 
> dangling or null pointer, or does it just give you a reference to some kind 
> of placeholder object?

If the representation is a pointer, it will be initialised by C++ by 
the default initialiser, which is trivial, and does nothing, so it will
be garbage bits.

This kind of thing is an unfortunate consequence of pandering
the "block structured programming style" of C and C++.

FPL's use a better but less familiar syntax:

        let x = y in ...
        let a = b and c= d in ..
        let rec ...

in Ocaml is much more powerful than blocks:

        var x : int;
        {
                val a = 1;
                val b = 2;
                x = a + b;
        };

However, the Ocaml system has some pain too:
sometimes you're forced to initialise things to dummy values.
Underneath, it has even worse problems: you're basically
forced to heap allocate every variable separately,
which in turn gives closures fine control of what they
access at the cost of garbage collecting individual variables
instead of frames.

This is reasonable using a high performance generational
incremental copying collector. Felix uses a naive mark-sweep
collector because we cannot copy primitive objects
(i.e. unknown C++ data can't be copied).

Hate to say it .. but the Java rule would be appropriate: you can
declare something wherever you like, you just can't use it until
after it is *manifestly initialised*.

It is hard to do properly in Felix though, because Felix has pointers.
Hence aliasing. Hence you'd need sophisticated data flow analysis
to catch many errors and probably you still couldn't be sure in all cases.

> Your tutorial says "vals are constants.  They cannot be changed."  

It isn't correct. They cannot be assigned to. They can be changed
if control flows through the initialisation again.

It's even wuss dan dat! Consider:

        val x = if a then b else c endif

That reduces (internally) to

        val x;
        if a then x = b;
        else x = c;

so the optimiser actually sees two initialisations of the one variable.
Only one gets executed (on a single control sweep).


> This made sense to me, now you're saying they're not really constant and they 
> might change, and furthermore you don't want to fix problem that but instead 
> introduce "const" as the REALLY constant version of val.
> 
> Why not make val stricter instead?  Take all the parts of the val expression 
> that "might" change (vars, function calls) and evaluate at least those parts 
> where the val is initialized.  

Because the point of initialisation is not well defined, deliberately.
If you write:

        var x = 1;
        val y = x;
        ++x;
        println$ y;

you might get 1 or 2. You will get 1 with eager evaluation and 2 with lazy 
evaluation.

Straight line code like this is analysed and usually results in eager evaluation
if Felix can detect the dependence on a variable.

However if its a function argument, and the function is inlined,
it is usually lazily evaluated.

The moral of the story is: you are free (at the moment) to allow vals to depend
on vars. It may or may not matter, depending on when the val might be 
initialised.
(well if it is inlined, it isn't initialised -- its *eliminated* and replaced 
by its initialiser).

To put this another way: the semantics of "val" at present, are specifically
designed to allow the compiler to choose eager or lazy evaluation,
which every it thinks is faster (or easier to implement .. :)

If your val only depends on constants it cannot make a difference.
If it depends on variables it may or may not make a difference,
depending on when the val is used and when the var is changed.
For example:

        var x = 1;
        fun f() { val a = x + 1; return a + 2 * a; }

Here, even though "a" depends on x, it makes no difference
how it is evaluated because the variable x cannot change
during the lifetime of the function f, because functions aren't
allowed to have side-effects.

So I don't want to ban vals for depending on variables.
[note this is just one example where you can prove, even with
the current semantics, that the value of a val is deterministic,
even if it depends on variables or dereferences pointers]

> Do not allow a val to be initialized more than once or be used before it is 
> initialized.

How do i stop it? Don't allow vals at all after a label?

> Hmmm that seems like a bug.  Shouldn't inlining create a copy of the 
> parameters?

Nope. If the parameter is a var parameter, it is evaluated eagerly.
But even that may not be enough.

> I think inlining should not change behavior from the non-inlined version, 
> given that inlining is supposed to be a transparent optimization.

In C++ it is supposed to be. 
In Felix it turns out to have actual semantics.

I would bet it matters in C++ too. But then C++ isn't very good at optimisation.
Just about the only thing equivalent in C++ is elision or introduction
of copy constructors. Which means C++ is typically almost
impossible to optimise.

> If we are changing the way C bindings are done perhaps we could start to move 
> in another direction with it and use some kind of prefix to transition into 
> "C" land, like the way things were being done in "cgram.flxh":
> 
> extern "C" {
>   int x;
> }

Yes,  ideally this is horrible:

        fun f: int -> int = "HG"

GAK! Its only a trick that assigning a string to a function name is interpreted
as a C binding.

        val x = "1"

really IS a string so if you want to bind C a new invention is required:

        const x : int  = "1'

there now its C again not a string. Arggg .. it works but its not really all 
that consistent.


> There is a certain amount of flexibility with the C template system that is 
> there now, but cases where that flexiblity is used one continue to use the 
> code keyword:
> 
> fun + : int * int -> int = "$1+$2";
> proc puts : string = "puts($1.c_str())"
> 
> becomes:
> 
> fun +(a:int, b:int) => code[int]"$1+$2";
> proc puts(s:string) = { code 'puts($1.c_str())'; }

That's pretty ugly :)

> 
> For now it might be fine to initially support the extern "C" syntax only for 
> constants (since they're losing their keyword) and add the rest later.

As mentioned some time ago .. if you want to write some Scheme to decode C/C++ 
type
specification, at least to get C/C++ typedef to work, that would be a start.

extern "C" { .. }

is universally useless until it can parse abstract types and type declarators.

ALSO : be aware there are several possible meanings of "C code in Felix".

You could just be emitting that code. OR you could be binding to something.
Just saying "extern C" doesn't make it clear which you mean.

There's a big difference between:

        header "void f(); ";

and

        proc f: unit = "f();";

One emits C code which Felix ignores, the other binds 
to existing C code. There's THIRD option too:

        proc f() {}

That's Felix code. That makes a binding to Felix AND emits
C code. So also note:

        struct X { .. }

Binding for Felix, emist C code. whereas

        cstruct X { .. }

just creates a binding.

Now again .. exactly what do you want extern "C" to do??
It is a binding only, or does it generate something?

--
john skaller
skal...@users.sourceforge.net
http://felix-lang.org




------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and 
threat landscape has changed and how IT managers can respond. Discussions 
will include endpoint security, mobile security and the latest in malware 
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
Felix-language mailing list
Felix-language@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/felix-language

Reply via email to