xsharp.eu • TIP: C# to X# Lambda Conversion
Page 1 of 1

TIP: C# to X# Lambda Conversion

Posted: Thu Nov 14, 2019 9:46 pm
by Jamal
I have the following C# code snippet which uses a lambda expression. I wanted to convert it to X#, and finally found the solution after reading the X# docs and dealing with the craziness of the dots and colons. and now it works :lol:

C#

Code: Select all

        
            DataTable db = GetCustomers("ACCTINFO.dbf");

            string[] postSource = db
                .AsEnumerable()
                .Select<System.Data.DataRow, String>(x => x.Field<String>("ACTNUMBER"))
                .ToArray();


X#

Code: Select all

  local db := GetCustomers("ACCTINFO.dbf"as DataTable 
                   
  local postSource as string[]   
  postSource  := db:AsEnumerable():select<DataRow, string>( {x => x:Field<string>("ACTNUMBER")}):ToArray()           // I prefer this syntax

/*
// alternate syntax with ; as line continuation character ( I am not talking C#)
           postSource := db:AsEnumerable();
               :select<System.Data.DataRow, string>( {x => x:Field<string>("ACTNUMBER")});
               :ToArray() 
*/
                
Notice the Lambda expression in X# has to be specified within { } as:

Code: Select all

{x => x:Field<string>("ACTNUMBER")}


x is of type DataRow which is implicit, but may be strongly typed as:

Code: Select all

{x as DataRow => x:Field<string>("ACTNUMBER")}
HTH,
Jamal

TIP: C# to X# Lambda Conversion

Posted: Fri Nov 15, 2019 5:45 am
by lumberjack
Hi Jamal,
Jamal wrote:I have the following lambda expression.
Notice the Lambda expression in X# has to specified within { }
Further to your example, here was my first try at an IntegerSolver using Lambda:

Code: Select all

FUNCTION StartSolver() AS VOID
	VAR oP1 := Prop{"P1", 30, 95.57}
	VAR oP2 := Prop{"P2", 100, 358.54}
	VAR oP3 := Prop{"P3", 300, 859.3}
	LOCAL  dPot AS System.Func<Prop, List<Prop> >
//	LOCAL  dSol AS System.Func<Prop, List<Prop> >
	dPot := ;
		{ p AS Prop => // Notice, no ";" for line continuation
			VAR Potentials := List<Prop>{}
			VAR pcs := 0
			Potentials:Add(p)
			LOCAL oP AS Prop
			REPEAT
				oP := Prop{p:Name, p:Quantity, p:Price}{Pieces := ++pcs}
				Potentials:Add(oP)
			UNTIL Prop.Qualify(oP:Constraint())
			RETURN Potentials
		}
	VAR oPot1 := dPot(oP1)
	VAR oPot2 := dPot(oP2)
	VAR oPot3 := dPot(oP3)

	VAR oSol := (FROM p1 IN oPot1 ;
						JOIN p2 IN oPot2 ON TRUE EQUALS TRUE ;
						JOIN p3 IN oPot3 ON TRUE EQUALS TRUE ;
						WHERE Prop.Qualify(p1:Constraint() + p2:Constraint() + p3:Constraint()) ;
						ORDERBY (p1:Minimize() + p2:Minimize() + p3:Minimize()) ;
						SELECT <INT>{p1:Pieces, p2:Pieces, p3:Pieces}):Take(3)
	FOREACH VAR s IN oSol
		? s[0], s[1], s[2]
	NEXT
/* The result of oSol should be List<Prop> where last item the number of pieces required:
Prop{"P1", 30, 95.57, 5}
Prop{"P2", 100, 358.54, 2}
Prop{"P3", 300, 859.3, 0}
*/
RETURN

CLASS Prop

	HIDDEN _name AS STRING
	HIDDEN _price AS REAL8
	HIDDEN _qty AS INT

	PROPERTY Name AS STRING GET _name
	PROPERTY Price AS REAL8 GET _price
	PROPERTY Quantity AS INT GET _qty
	PROPERTY Pieces AS INT AUTO

	CONSTRUCTOR(n AS STRING, q AS INT, p AS REAL8)
		_name := n
		_price := p
		_qty := q
		Pieces := 0
	RETURN

	METHOD Minimize() AS REAL8
	RETURN _price * Pieces

	METHOD Constraint() AS INT
	RETURN _qty * Pieces

	STATIC METHOD Qualify(val AS INT) AS LOGIC
	RETURN val >= 241
END CLASS

TIP: C# to X# Lambda Conversion

Posted: Fri Nov 15, 2019 6:35 am
by wriedmann
Hello,
what I like most on the lambda expression is that I can strongly type the parameters.
That is helpful when writing them, makes code more stable and faster.
Wolfgang

TIP: C# to X# Lambda Conversion

Posted: Fri Nov 15, 2019 6:44 am
by lumberjack
Hi Wolfgang,
wriedmann wrote:Hello,
what I like most on the lambda expression is that I can strongly type the parameters.
That is helpful when writing them, makes code more stable and faster.
Indeed and also sometimes shorten it and keep the readability...

TIP: C# to X# Lambda Conversion

Posted: Fri Nov 15, 2019 1:37 pm
by Chris
In this particular case (lambda expressions), the advantage is only readability, code stability and speed is exactly the same, because the compiler automatically resolves and under the hood strongly types the parameter types (it can do it here by checking the generic parameters of the delegate "System.Func<Prop, List<Prop> >" that is used).

In my opinion it is still a lot better to manually strongly type the params, mostly in order to make the code easier to understand.

TIP: C# to X# Lambda Conversion

Posted: Sat Nov 16, 2019 5:42 am
by lumberjack
Hi Chris,
Chris wrote: In my opinion it is still a lot better to manually strongly type the params, mostly in order to make the code easier to understand.
Can you expand and show on my example? I thought I did "strong type" my oProp AS Prop... ???

TIP: C# to X# Lambda Conversion

Posted: Mon Nov 18, 2019 10:45 pm
by Chris
Hi Johan,
lumberjack wrote:Hi Chris,
Chris wrote: In my opinion it is still a lot better to manually strongly type the params, mostly in order to make the code easier to understand.
Can you expand and show on my example? I thought I did "strong type" my oProp AS Prop... ???
I didn't say you didn't, I agreed with you :)
I just failed to include the original message as I should had done, but was responding to Wolfgang, clearing up that in lambda expressions the types are always strongly typed, either inferred from usage, or explicitly in their declaration.

TIP: C# to X# Lambda Conversion

Posted: Tue Nov 19, 2019 4:09 am
by lumberjack
Hi Chris,
Chris wrote: I didn't say you didn't, I agreed with you :)
I just failed to include the original message as I should had done, but was responding to Wolfgang, clearing up that in lambda expressions the types are always strongly typed, either inferred from usage, or explicitly in their declaration.
Thanks, you had me worried there for a moment that I am missing something seriously...