Re: To & or not to &
David Hakim <dhakim-Gkm/TONP9n1Wk0Htik3J/[email protected]> Wed, 5 Mar 2003 12:37:09 -0500
| Newsgroups | gmane.comp.lang.moto.devel |
|---|---|
| Message-ID | <[email protected]> |
On Wednesday, March 5, 2003, at 11:37 AM, Charles Patterson wrote:
>>>> I need the '&' to distinguish between a function I'm calling right
>>>> away vs a function I'm defining to call later
>>>>
>>>> void() myhello = &hello("Dave");
>>>>
>>>> Or do I ? With any one of the anonymous function syntaxes I've
>>>> discussed with people I could accomplish the same thing by doing:
>>>>
>>>> void() myhello = <void()>{hello("Dave");} ;
>>>
>>> Looks good (except I wish it didn't have the curly braces)
>>
>> Without curly braces I may be able to turn a single expression into a
>> function. But how would I be able to define a function inline that was
>> made up of a whole series of expressions / statements one after the
>> other ?
>
> Converting a single 'expression' to a function sounds right to me. I
> guess
> you are saying that, in the above example, you don't directly assign a
> function to another, but you assign an entire code block to another.
> In the
> above case, it happens that the entire block contains one function. I
> don't
> think that will work. I think the code block will resolve to the
> return
> from the function, which is "void", then you will try to cast that to a
> function.
>
The code block will not execute at runtime, rather the syntactic
structure of
<functional type>{code}
will be identified at parse time as an anonymous function definition
and will be generated as such. At runtime a 'closure' object will be
created to represent that block (
http://www.perl.com/doc/FAQs/FAQ/oldfaq-html/Q3.14.html ) . This
representation will really be a structure that contains the values of
all variables used from parent scopes at the time of anonymous function
definition. The closure structure will also contain a function pointer
to the real function definition generated. The real behind the scenes
'function' takes all the closure variables as implicit arguments.
The return type of the anonymous function is fully specified by the
return type specified in the cast. If the wrong type is returned from
the anonymous function this will be identified at parse time and a
verification error will be generated.
If anything the single expression is what is much harder to implement
since as soon as an 'unfilled argument' is encountered the 'type' of
all ancestor expressions will be effected.
> So...
>
>>> , but will you
>>> ever need this new syntax when calling the function immediately? For
>>> instance,
>>>
>>> Object foo(String s){ return an object that is really a function
>>> ptr; }
>>>
>>> void() bar= <void()>{foo("Dave");} ;
>>>
>>> hello would return an Object but you know it is really a function
>>> pointer
>>> and want to convert it.
>>
>> The above example confuses me :)
>
> Perhaps I wrote it wrong. I think there is ambiguity as to what you
> are
> assigning to bar. Is it the partially completed foo("Dave"); or is it
> the
> return from foo("Dave") casted to a void().
>
This expression:
<void()>{foo("Dave");}
corresponds to the execution of the partially completed foo("Dave") . I
do not believe there is ambiguity since the type of the anonymous
function is fully specified in the cast and the anonymous function
itself returns nothing and does nothing but call the function foo with
the argument "Dave".
The expression
foo("Dave")
is also non ambiguous. Its type is the return type of foo (Object) and
it causes the function foo to be called with the argument "Dave" at
runtime at the point the expression appears. The question I have is
should I allow
&foo("Dave")
as a short form for
<Object()>{return foo("Dave");}
> In Moto, Object is the base class of everything, correct?
Every reference type is considered an Object. This does not include
int, float, boolean, double, long, char and byte since these are not
reference types. The rules here are the same as in Java
-Dave
> This way, you can
> have an array of mixed type, call it "Object[] A". Eventually you
> will cast
> an element back to a useful type as in "int e = <int> Object[3]".
> Likewise,
> if a function returns an Object, it may be a function ptr and need
> casting.
> So I don't know if you are assinging foo("Dave") to bar, or if you are
> casting the return Object of foo("Dave") to a void() and assinging it
> to
> bar.
>
> One more thought. Compare this problem to arrays and initialization.
> There
> is a different syntax to know wether you are initializing it or
> calling it:
>
> int[] A = { 3, 5, 6 };
> int i = A[0];
>
> So, likewise, perhaps you could have two syntaxes for something as
> important
> as functions:
>
> Assuming <> were unused in Moto:
> // <> brackets would mean you are defining or referring to
> functions
> String F1<String S> { return "output: " + S; } // define F1
> String<String> makefunc<void> { return F1; } // define makefunc
> to
> return a function "pointer"
>
> // but () brackets would mean you are calling functions
> String r = F1("Dave"); // call F1
>
> // the culmination
> String F2<void> = F1<"Dave">; // just (partially) assinging F1
> to F2
> String r = F1("Dave"); // calling F1
> String F3<String> = makefunc("Charlie"); // calling makefunc and
> assinging return to F3
> String<String> F4<void> = makefunc<void>; // just assigning
> makefunc
> to F4
>
> sort( A, compare<int> ); // calling sort with function "pointer"
> compare
>
>
>
>
>