On 22/07/2012, at 5:17 PM, Dobes Vandermeer wrote:
> On Sat, Jul 21, 2012 at 6:59 PM, john skaller <[email protected]>
> wrote:
> Arrays of one element are now distinguished from values of the same type.
> So array polymorphic functions will now work with arrays length 1.
>
> however this may not be sustainable because you can
> also copy an array x like:
>
> array ( x )
>
> Copy constructors are a bitch, eh?
Heh! Of course, despite the keyword "ctor" used in Felix none of the
things named "ctor" are actually constructors. They're all conversion
operators that convert a value of one type to a value of another;
that is, they're just ordinary functions with sexy names.
In a union
union X = | Double of double | Int of int;
Double and Int are type constructors. That is, they're a mapping:
Double, Int : TYPE -> TYPE
from the category of types to the category of types. A function is not,
it's a function of type
A -> B : TYPE
is an ordinary value with an ordinary type which is in the category TYPE.
In Felix union type constructors can be USED as functions:
fun f(mk: double -> X) (x:double) => mk x;
... f Double of (double) 1.2 ...
but this is only because Felix automagically generates the wrapper:
fun Double_as_function (x:double) => Double x;
which is used when you use Double "as a function".
Union type constructors can be pattern matched against too.
There is another kind of constructor: the "C++ class object constructor".
That too is a real type constructor. Felix can't make objects like that yet
due to the lack of a name for the concept: a type unsafe implementation
already exists and is called "class constructor".
When you say:
new X (a,b)
you'd expect an X to be created on the heap, but that is NOT what happens
with a "ctor" function. What actually happens is:
val x = X (a,b);
.. new x ..
which copies the value x onto the heap. This sucks!
You should note that despite the impression a C++ constructor is a function
its is NOT a function! It is in fact a *procedure* which is passed a pointer
to allocated store, and some arguments, and then proceeds to initialise
that store.
>
> I've always found it annoying in all the languages that use constructors that
> they all use same name (usually as the class). In felix this is optional as
> you can construct objects in a generator or function.
In Felix you can have any number of distinct names for the same type!
Consider:
type complex = "complex<double>";
// cartesian coordinates
ctor complex : double * double = "complex ($1,$2)";
// polar coordinates
typedef polar = complex;
ctor polar : double * double = "make_complex_by_polar ($1, $2)";
The "constructor name" can be a typedef name!
Of course you could just write
fun make_polar : double * double -> complex = " ... "
instead, it's exactly the same (except you have to specify the return value
after the -> which
is inserted by magic for a "ctor" thing).
The "use the type name as a function" idea was instituted by Erick.
I didn't like it at first, but it does make it easy to create various data
structures
without having to think what function to call.
> Nevertheless, I'd rather the copy constructor were called "copy" instead,
> throughout the library.
That's probably reasonable. The only caveat is .. I'm not sure that these
"ctors" actually copy
anything. If you write:
fun copy (x:int) => x;
and "copy" is inlined .. well no copy is made! For functional code, you can't
tell the difference, but you can if you start mutating things. The only way to
force
copying is probably:
noinline copy (x:int) => x;
and to be honest I'm not even sure about that :)
> The core verbs "array", "list", "varray" should have a similar and consistent
> meaning - "give me one with the parameter(s) in it!". Or they should have a
> different name for that case ("array_with", "list_with", "varray_with").
No argument, stuff should be consistent. I generally programming by throwing
everything in ad hoc, including the kitchen sink, until it is overweight and
confusing .. but there are enough use cases to visualise a pattern and start
thinking about how to make it all simpler and consistent.
I'm too dumb to implement the right abstractions first off.
>
> Currently list(x) typically returns a list containing x. varray(x) returns
> an array of x *unless* x is a varray, then it copies it. It smells rotten to
> me ... I like consistency.
Agree.
>
> Explicitly named functions:
>
> array_copy
> singleton_array
>
> may be better.
>
> With overloading, I think you can just call it "copy" or "clone" rather than
> array_copy. As I said above, you can use that name for ALL copy constructors
> to avoid this kind of problem, otherwise ALL collection types (list, array,
> set, tree, bag, ...) are going to suffer from this same copy / contain
> ambiguity for a single element.
Yes, but the problem is that these things are NOT copy constructors,
they're typically identity functions.
They're copies, usually, when they're applied to an object represented
by a pointer and the function makes a new object on the heap
and returns a pointer to that. That one is a real copy.
Value copies don't make sense: values are immutable so copying them
is a no-op and Felix typically will inline away any attempt to make a copy.
You'll only know if either
(a) you cheat
(b) Felix is broken
(c) all the above
--
john skaller
[email protected]
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
[email protected]
https://lists.sourceforge.net/lists/listinfo/felix-language