O.K., now. Sorry for the late reply. Thanks for answering my pseudo-
rants; I apologise. I would help with the documentation problems but
since I have little idea of what is available in this language I am
rather stuck.
On the matter of using a C++ list<>, I meant implement your own
container (I could at least help with that). The gcc-STL does allow
you to override the allocator but you would still run into the
problem of storing higher-level values (such as a list of lambda
expressions) in it. The stream solution looks nice.
As for syntax, I would fairly say that less than half of my friends
who know and work with C++ on a daily basis actually like C++ syntax,
despite its other advantages; the rest continue to dabble in
languages they *wish* they could use at work :) It isn't out of the
question for me to write a lexer in Felix's own GLR--assuming I
actually start to understand what Felix is about so I might inject
some consistency between functional syntax and the functionality.
Now back to fun stuff: I tried (again) to figure out the problem of
using the new typecase ... endcase construction to produce generic
functions over types. First, I ran into another parsing problem I
don't know the answer to:
fun gmapT_one[A,B,T] (f:A->B, x:T): T =
{
return ({typecase[c,a] c a => c ({f a;}) endcase x;});
}
returns this error:
CLIENT ERROR
[rex] Unexpected typecase [c,a] (c a) => (c (fun () = {
call noexpand(f) a;
}))endcase
--I tried a bunch of different variations so if this seems messy it
is the closest parsable construction I could come up with.
There are several things to note here:
(1) since Felix does not have type classes, in order to make typecase
matching type-safe, I have to wrap it in a function. What I mean by
type-safe is:
if you have a construction like this:
typedef g_one =
typecase[c,a] c a => a
endcase;
'a' is returned (probably inside a function), you will manipulate it,
and then you have to reconstruct the type at the end of the function,
like this:
fun gmap[A,B,Company] (f:A->B) (x:Company): Company =
{
var y = g_one x;
return (C (map f {g_one x}));
}
--at this point 'g_one' has stripped the constructor for Company off
and you have to reconstruct Company again later. For a simple single
constructor this would be o.k. but as a general rule it is a bad
idea: for a library of generics you never know whether "c" in 'g_one'
is a simple constructor or not. It is much safer to maintain the 'c'
constructor in 'g_one' itself without losing any information--it
simply carries over. So the first reason to wrap typecase in a
function is to inject the function application into it, as I did in
gmapT_one function: the c ({f a;}) construct.
(2) without type classes (or some other construction, such as a
class), you need to wrap typecase in a function in order to handle
the overload resolution for recursively applying typecase
deconstructors over a type. This may be a subtle point. If you want
to map a function over "real" data embedded in a type hierarchy the
functions to map need some way of resolving which function gets
applied where. In the 'gmap' example I was running the function over
a Company type; if I needed control over the application of the
function to the underlying data type, say whether to 'map f' or apply
'f', I would have to define such a function for every type in the
hierarchy. (With type classes or a similar construction, these
'functions' would be defined there.) In order to work my way into a
hierarchy I could name all functions 'gmap' and let first-order
polymorphism take care of which function to apply over which type.
Eventually I would be able to define:
fun incrSalary[Company] (i:int,x:Company):Company =
{
return (gmap (proc() = {+i}) x);
}
and the 'gmap' defined in gmap[Company] would call gmap[Dept] ...
down to gmap[Employee] which actually contains the salary.
Another place I am stuck is where (or how) to expand typecase[ h ..
t ] for tuples and similar types. The type-safe solution would be to
define a template-style function, makeTypeVariable (mkTyVar), which
would create a list of type variables to replace 'h .. t' in the
typecase specification and body. Bringing the literal OCaml function
into Felix would be easy but you would have to do it for every such
type and it wouldn't give the programmer as much control. The x.(n)
component selector is destructive and not type-safe; recursively
applying a function over a typecase may be another solution but it
would require defining a "range variable" type within the typecase
[free variable list]. (At least I think that is the problem.)
-Pete
-------------------------------------------------------------------------
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