No time like the present.
What Iâd like it to be: Win32/64 native codegen.
What I think it is: Linux support
Which leaves plenty of other possibilities for me to be entirely wrong on both counts.
In terms of suggestions⌠one thing that Iâve been pondering on is how the necessary conditional directives involved in mapping types could be reduced/simplified/made more âPascallyâ. I havenât thought it through thoroughly, so the initial ideas Iâve had may be fundamentally flawed, but I was thinking about limited, contextual support for a way of tidying up all those {$if XXX} ⌠{$endif}'s:
Example (from a class Iâve been playing with):
type
Dictionary<K, V> = public class mapped to {$if ECHOES} System.Collections.Generic.Dictionary<K, V>
{$elseif COCOA} Foundation.NSMutableDictionary
{$elseif COOPER} Hashtable<K, V>
{$endif}
public
method Add(aKey: K) Value(aValue: V); {$if COCOA} mapped to setObject(aValue) forKey(aKey); {$elseif COOPER} mapped to put(aKey, aValue); {$endif}
method Clear; {$if ECHOES} mapped to Clear;
{$elseif COCOA} mapped to removeAllObjects;
{$elseif COOPER} mapped to clear;
{$endif}
method ContainsKey(aKey: K): Boolean; {$if ECHOES} mapped to ContainsKey(aKey);
{$elseif COOPER} mapped to containsKey(aKey);
{$endif}
method ContainsKey(aKey: K) ReturningValue(out aValue: V): Boolean; {$if ECHOES} mapped to TryGetValue(aKey, out aValue);
{$endif}
One approach that occured to me was to combine the conditional symbol involved with the mapped keyword, so that where-ever mapped
were legal, then $XXX.mapped could be used:
{$ifdef ECHOES} mapped .... [;] {$endif}
becomes:
$ECHOES.mapped ... [;]
You could call it a âconditional mappingâ.
The [;] simply indicates that in the class mapping there is no ;
but there would be for a method mapping. I think the compiler should still naturally be able to identify the âendâ of the conditional map clause. To simplify matters such conditional maps must be completely self contained, couldnât be nested and implicitly terminates any immediately previous conditional map.
As far as I can tell, it should even be possible to mix Conditional Maps and conditional compilation without any problems. i.e. both of these should be possible I think without causing any problems for the compiler:
{$if COOPER} $PUREJAVA.mapped to ... ; $ANDROID.mapped to ...; {$endif}
or exactly equivalent but even more concise:
$COOPER.mapped to {$if PUREJAVA} ... {$else} ... {$endif} ;
This is a bit artificial though since neither is really much more âefficientâ than simply using $PUREJAVA and $ANDROID conditional maps (the $COOPER being implicit in those conditional maps).
At the same time, when mapping methods, if the method being mapped to has the same name and signature as the method begin mapped then it would be nice to be able to simply declare it as mapped
without having to replicate the signature (this would of course be a compilation error if no corresponding method with the required signature exists in the mapped type).
Applying all that to the class fragment above:
type
Dictionary<K, V> = public class $ECHOES.mapped to System.Collections.Generic.Dictionary<K, V>
$COCOA.mapped to Foundation.NSMutableDictionary
$COOPER.mapped to Hashtable<K, V>
public
method Add(aKey: K) Value(aValue: V); $COCOA.mapped to setObject(aValue) forKey(aKey);
$COOPER.mapped to put(aKey, aValue);
method Clear; $ECHOES.mapped; // method exists verbatim in the mapped type
$COCOA.mapped to removeAllObjects;
$COOPER.mapped to clear;
method ContainsKey(aKey: K): Boolean; $ECHOES.mapped; // exists verbatim in mapped type
$COOPER.mapped to containsKey(aKey);
method ContainsKey(aKey: K) ReturningValue(out aValue: V): Boolean; $ECHOES.mapped to TryGetValue(aKey, out aValue);
To go along with this, I wonder if it might not also then be possible to support a âConditional Method Implementationâ, re-purposing an attribute-like syntax on a method body in the implementation section:
[$SYMBOLA, SYMBOLB]
Which would be exactly equivalent to surrounding the immediately following method implementation (and only that immediately following method) with $ifdef SYMBOLA or SYMBOLB
⌠$endif
.
So taking that final ContainsKey
method (which is only mapped for ECHOES and requires an implementation for COCOA and COOPER. Currently this looks something like this:
{$if COCOA or COOPER}
method Dictionary<K, V>.ContainsKey(aKey: K) ReturningValue(out aValue: V): Boolean;
begin
{$if COCOA}
aValue := mapped.objectForKey(aKey);
result := aValue <> nil;
{$else}
aValue := mapped.get(aKey);
result := aValue <> nil;
{$endif}
end;
{$endif}
Which might then become something like:
[$COCOA,COOPER]
method Dictionary<K, V>.ContainsKey(aKey: K) ReturningValue(out aValue: V): Boolean;
begin
{$if COCOA}
aValue := mapped.objectForKey(aKey);
result := aValue <> nil;
{$else}
aValue := mapped.get(aKey);
result := aValue <> nil;
{$endif}
end;
This is less about removing/reducing the amount of conditional directive (which in this case donât add much in the way of âcodeâ) but more about simplifying the implementation section where nested $ifdefs and keeping track of which methods are in which conditional blocks can get a bit out of hand when you have larger methods causing those conditional sections to span multiple pages/screens.
Being able to âattributeâ each method individually as required would help keep that simple/manageable.
As I say, none of this has been thought through to the nâth degree and may be fundamentally flawed.
But you did ask.