On 17/04/2021 5:34 pm, fredvs wrote: > There was some work done to make it work: > https://github.com/mse-org/mselang/releases > > I was able to do some console application on Linux (the version of LLVM for > Windows was not yet working when I try it 3 years ago).
Thank you Fred for all the information. I'm looking at the MSELang repo as we speak. The reason I ask, I was comparing Delphi's Anonymous Methods (lambdas) + Generics to how Java does it. It is crazy how verbose Embarcadeco made the syntax. The compiler is supposed to be inteligent, yet with the Delphi syntax, you are spoon-feeding the compiler with things it could have figured out from the code itself, and often duplicating information. You really don't save much typing that way. I'm toying with the idea of experimenting with the Free Pascal Compiler, and was looking at maybe contributing to FPC (if they don't want it - most likely outcome - as they only like to copy Embarcadero), then the other option might be MSELang. But I don't know anything about MSELang and what its goals were. But I've got a better idea now - thanks to all your links. The rest of this message is optional... ;-) Here is a simple example: ========[ As done in Delphi ]======================== type TSimpleProcedure = reference to procedure; TSimpleFunction = reference to function(x: string): Integer; var x1: TSimpleProcedure; y1: TSimpleFunction; begin x1 := procedure begin Writeln('Hello World'); end; x1; //invoke anonymous method just defined y1 := function(x: string): Integer begin Result := Length(x); end; Writeln(y1('bar')); end. ==================[ end Delphi ]===================== Now for my idea... There are some standard "functional interfaces" defined in the RTL like, but in your own code, you can define your own ones too. The compile will treat them in the same way is I describe here: type // Represents a function that accepts one argument and produces a result. IFunction<T,R> = interface function apply(T): R; end; // Represents a predicate (boolean-valued function) of one argument. IPredicate<T> = interface function test(T): boolean; end; // Represents an operation that accepts a single input argument and returns no result. IConsumer<T> = interface procedure accept(T); end; // Represents a supplier of results. ISupplier<T> = interface function get: T; end; // Represents a prodecute that takes no argument and produces no result. IRunnable = interface procedure run; end; You can then use those in anonymous methods like this: ========[ Mine ]=================================== var x1: IRunnable; y1: IFunction<string, integer>; begin x1 := () -> Writeln('Hello World'); (1) x1; //invoke anonymous method just defined y1 := s -> Result := Length(s); (2) Writeln(y1('bar')); end. ==================[ end Mine ]===================== (1) - The () syntax lists any parameters. It's empty, so no parameters are used. They are only required if the parameter list is empty. - The -> syntax borrows from Java and lets the compiler know this is a lambda (anonymous method) - IRunnable's method takes no parameters and has no return type - The code after the -> is the body of the method. This is a 1 line body, so doesn't require the verbose begin/end pair. IRunnable is a "functional inteface" with only one method that needs to be implemented. From that the compiler knows the name and signature of the method, by looking it up from the interface definition. The compiler can construct a anonymous class to implement the anonymous method. That could automatically result in something like this - all done by the compiler itself: type TInternalAnonymousClassName = class(TInterfaceObject) implements IRunnable public function run; end; TInternalAnonymousClassName.run; begin Writeln('Hello World'); end; (2) - The process is pretty much the same as (1), but this time the functional inteface signater is different. - IFunction takes one parameter and returns a result. - The definition of y1 tells the compiler that the parameter is of type String and the return type is of type Integer. So when you define the lambda, you don't have to repeat the data type information - s is the name of the parameter, and the compiler already knows is must be of type String. - agian it's a one line method, so no need for the begin/end pair. type TInternalAnonymousClassName = class(TInterfaceObject) implements IFunction public procedure apply(s: String): Integer; end; TInternalAnonymousClassName.apply(s: String): Integer; begin Result := Length(s); end; Regards, Graeme _______________________________________________ mseide-msegui-talk mailing list mseide-msegui-talk@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mseide-msegui-talk