On Fri, Aug 17, 2012 at 4:32 AM, john skaller <skal...@users.sourceforge.net
> wrote:

> Functions in Felix may not have side effects, but they're not
> referentially transparent because they can still depend on
> variables in their context.
>
> I'd like to split them up into pure functions and the other kind.
>
>         fun ... pure
>         method .. may depend on variables
>
> Neither can modify their environment.
>

Are you saying that "method" would be the keyword for a non-pure function?

There's a similar problem with "val" style variables (only worse);
> A val takes on the value of its initialiser when control passes through it,
> so it can depend on variables. The value cannot change, but it does
> depend on when the val is initialised.
>
> Worse, you can currently initialise a val twice, and, you can refer to it
> before it is initialised:
>
>                 var z = x; // not init yet
>                 var y = 1;
>         label:>
>                 val x = y; // multiple initialisations
>                 ++y;
>                 goto label;
>

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.  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?


> I think I would like:
>
>         const x = expr; // may not depend on variables
>
> Reference before use and multiple initialisation can be
> prevented for consts, by evaluation them all at the top
> of a function in order of dependencies (topological sort).
>

Your tutorial says "vals are constants.  They cannot be changed."  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.  Do not allow a val to be
initialized more than once or be used before it is initialized.

This is a know problem in Felix (its NOT a bug, but its
> hard to deal with:
>
> for var i in 0 upto 10 do
>         spawn_fthread { println$ i; };
> done
>
> True the fthread is a procedure, but the point remains that
> this exact problem has bitten almost everyone: all the fthreads
> can print 10. you cannot fix this with a closure either,
> not even my passing i as an argument:
>
>         proc f (y:int) () { println$ y; }
>         for var i in 0 upto 10 do
>                 spawn_fthread ( f x );
>         done
>
> Doesn't help, because proc f will be inlined. [marking f noinline fixes
> it, but that's an implementation detail!]


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

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


> It follows const expressions can only depend on consts
> and funs, not vals, vars, methods, or generators.
>

So a const would take parameters like a function, then?

Unfortunately const is already used:
>
>         const x : int = "x";
>
> so I propose to change that to
>
>         expr x : int = "x";
>
> because actually the RHS can be any expression.
> in fact this is just an argument-less version of
>
>         fun f: unit -> int = "x";
>

It's true that the "const" is not enforced as such, but it does encourage
one to use an actual constant expression.  One could conceivably put
"getch()" or "counter++" if they wanted to get some weird effects but at
some point you just have to ask people to be sensible.  I think I saw in
the library some clever use of const like this, maybe it was const
memcount[T] where the result depended on the type of its parameter.

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;
}

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())'; }

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.

If I'm prompted to go back and redo the "const" part of my marmalade
bindings I might try to add syntax rules for some of the other constructs
they use, too, to support those inside extern "C" as well.
------------------------------------------------------------------------------
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