Thoughts on lambda syntax if we had them in PureBasic

Everything else that doesn't fall into one of the other PB categories.
Mistrel
Addict
Addict
Posts: 3415
Joined: Sat Jun 30, 2007 8:04 pm

Thoughts on lambda syntax if we had them in PureBasic

Post by Mistrel »

I was brainstorming today about what lambdas might look like if they were implemented in PureBasic:

Code: Select all

Procedure SomeFunction()
  Protected a.l=1
  Protected b.l=2
  
  ;/ Lambda as a function with capture group
  Lambda.l [a, b]SomeLambda(c.l)
    LambdaReturn a+b+c
  EndLambda
  
  ;/ Lambda as a c-function with capture group
  LambdaC.l [a, b]SomeLambdaC(c.l)
    LambdaReturn a+b+c
  EndLambda
  
  ;/ Lambda as a thread function with capture group
  Lambda [a, b]SomeLambdaThread(*Tuple.TUPLE_INT_2)
    PokeI(*Tuple\i[1],a+b+*Tuple\i[0])
  EndLambda
  
  ;/ 1 + 2 + 3 = 6
  Debug SomeLambda(3)
  Debug CallFunctionFast(SomeLambda(3))
  Debug CallCFunctionFast(SomeLambdaC(3))
  
  Protected Result.Long
  
  ThreadId=CreateThread(SomeLambdaThread,TupleI2(3, @Result))
  WaitThread(ThreadId)
  
  ;/ 6
  Debug Result\l
EndProcedure
While this does functionally work, the strict syntax of PureBasic with regards to whitespace would make this difficult to implement as an anonymous function; which is where the power of lambdas truly shine.

See here for some examples of my frustrations with whitespace:
http://www.purebasic.fr/english/viewtop ... =3&t=66631

Can anyone propose a format for anonymous lambda functions that would look reasonable with PureBasic syntax rules?
HanPBF
Enthusiast
Enthusiast
Posts: 564
Joined: Fri Feb 19, 2010 3:42 am

Re: Thoughts on lambda syntax if we had them in PureBasic

Post by HanPBF »

PureBasic is really verbose; using interface or nested structures or callbacks always need their own name of a procedure/sub structure.

In Delphi, complete syntax is pushed forward into closures.

In PureBasic would look like this:

Code: Select all

MyList\forEachDo(procedure (P)

endProcedure)
or

Code: Select all

procedure test()
  protected P1
  procedure myLocalProcedure()
    debug P1
  endProcedure
  otherProc(@myLocalProc) ; otherProc would have indirect access to P1
endProcedure
In JavaScript, closures bind variables from the outer scope to the inner:

Code: Select all

// some constructed method (forEachDo not defined here)
MyList.forEachDo(function (P){
  // do something for each element
});
The indirect access to properties/variables of a closure used by receiver may be only a problem in JavaScript.

Maybe PureBasic could allow code blocks given around with programmer full in charge:

Code: Select all

MyList\forEachDo((P){
  debug P
})
I think the { } are free in PureBasic and they are far shorter than those procedure-endProcedure constructs.
Yes, I know... "curly brackets vs. begin end"...
Mistrel
Addict
Addict
Posts: 3415
Joined: Sat Jun 30, 2007 8:04 pm

Re: Thoughts on lambda syntax if we had them in PureBasic

Post by Mistrel »

Binding variable scope is another issue as PureBasic is very weak in this regard. See here:
http://www.purebasic.fr/english/viewtop ... =3&t=66784
HanPBF wrote:I think the { } are free in PureBasic and they are far shorter than those procedure-endProcedure constructs.
Yes, I know... "curly brackets vs. begin end"...
I thought about proposing something with curly braces as well. But this would be impossible as PureBasic is still not flexible enough with whitespace. I do like the idea of using closures as an alternative.

My primary motivation is to make it easier to spin off tasks to a thread pool with anonymous inner functions which I can have return a future, etc. I've been doing this a lot in Java and it makes programming with threads a breeze.
User avatar
fsw
Addict
Addict
Posts: 1572
Joined: Tue Apr 29, 2003 9:18 pm
Location: North by Northwest

Re: Thoughts on lambda syntax if we had them in PureBasic

Post by fsw »

I'm not sure I understand what your intention with Lambda's is.
I'm used to Go's Lambda/Closures implementation which is nothing else than inline nameless procedures.
But the Lambda procedures in your examples have names:

Code: Select all

  Lambda.l [a, b]SomeLambda(c.l)
    LambdaReturn a+b+c
  EndLambda
besides, what you did above can be done like this:

Code: Select all

  Procedure.l SomeLambda(a.l, b.l, c.l)
    ProcedureReturn a+b+c
  EndProcedure
Or is the Lambda function you are referring to "naked functions"?

Surely, there is something I missed...
and I apologize for that :mrgreen:

I am to provide the public with beneficial shocks.
Alfred Hitshock
Mistrel
Addict
Addict
Posts: 3415
Joined: Sat Jun 30, 2007 8:04 pm

Re: Thoughts on lambda syntax if we had them in PureBasic

Post by Mistrel »

I made an attempt at a lambda syntax where you could define a procedure and assign it to a variable within a function. Anonymous functions are more useful but I couldn't come up with a reasonable syntax that fit well with PureBasic; which is why I made this thread.
User avatar
Lunasole
Addict
Addict
Posts: 1091
Joined: Mon Oct 26, 2015 2:55 am
Location: UA
Contact:

Re: Thoughts on lambda syntax if we had them in PureBasic

Post by Lunasole »

What is a point of lambda expressions at all? Any examples where they are really useful/better than something else?

I've made few attempts time ago to find practical usage of them, but never seen it. Just a syntax trash which opposites KISS principle and makes extra problems with debugging/code understanding... as for me ^^
"W̷i̷s̷h̷i̷n̷g o̷n a s̷t̷a̷r"
Mistrel
Addict
Addict
Posts: 3415
Joined: Sat Jun 30, 2007 8:04 pm

Re: Thoughts on lambda syntax if we had them in PureBasic

Post by Mistrel »

Part of the power of lambdas comes from chaining anonymous functions which can be spun off to threads so that work can be done in parallel.

This thread is for discussing what kind of syntax would work for this in PureBasic. We will be able provide better examples to prove tangible benefit once we find something that works.

As I mentioned before, I believe that the major limiting factor is the inflexibility of PureBasic's handling of whitespace.
HanPBF
Enthusiast
Enthusiast
Posts: 564
Joined: Fri Feb 19, 2010 3:42 am

Re: Thoughts on lambda syntax if we had them in PureBasic

Post by HanPBF »

@Lunasole
yes, closures like database triggers can be problematic.

@fsw
Sure, closures bind variables; anonymous procedures are blocks; I like the latter.

I'd like only those things advance reducing artificial naming of things and typing

Whitespace: not so good (tab vs. space)
Mistrel
Addict
Addict
Posts: 3415
Joined: Sat Jun 30, 2007 8:04 pm

Re: Thoughts on lambda syntax if we had them in PureBasic

Post by Mistrel »

I think it would be important to consider various proposals and non-standard implementations of lambdas for C, as many of the examples I'm familiar with handle call chaining through objects, which PureBasic does not have.

As mentioned previously, my personal motivation is to see a lambda implementation which enhances productivity when working with deeply threaded applications. I welcome examples on how else lambdas can be used to enhance productivity in other areas as well.
Mistrel
Addict
Addict
Posts: 3415
Joined: Sat Jun 30, 2007 8:04 pm

Re: Thoughts on lambda syntax if we had them in PureBasic

Post by Mistrel »

Lambda quicksort in PureBasic:

Code: Select all

Structure ArrayI
  *i.Integer[0]
EndStructure

;/ Variable names in lambda declaration are for reference only and provided as
;/ a mean of defining the parameter types; they are not actual variables and
;/ and an error should be thrown if an attempt is made to pass a previously
;/ defined variable (global, shared, threaded)
Procedure.VOID QSortI(*Base.ArrayI, nItems.i, Size.i, Lambda.i(*Left, *Right))
  ;/ Quicksort
EndProcedure


*Array.ArrayI=AllocateMemory(SizeOf(Integer)*6)

*Array\i[0]=6
*Array\i[1]=2
*Array\i[2]=1
*Array\i[3]=3
*Array\i[4]=5
*Array\i[5]=4

;/ Lambda definitions always move to the next line. Additional arguments after
;/ the lambda appear on the next line
QSort(*Array,6,SizeOf(Integer)*6,
  []Lambda.i(*a.Integer, *b.Integer)
    LambdaReturn *a\i-*b\i
  EndLambda
)
Lambdas would also accept procedures but these would be checked by the compiler to be sure that they conform to the parameter and return types:

Code: Select all

Procedure.i QSortICallback(*a.Integer, *b.Integer)
  ProcedureReturn *a\i-*b\i
EndProcedure

QSort(*Array,6,SizeOf(Integer)*6,@QSortICallback())
This gives the added benefit of type safety when an explicit call to a predefined function is provided. Calls to other pointers are allowed but do not benefit from being checked for type safety.

These examples would also work by replacing the keyword "Lambda, etc" with "Procedure, etc", depending on how Fred et al. might choose to implement them. I will continue to use the keyword "Lambda" for clarity.
Last edited by Mistrel on Sun Jan 08, 2017 4:43 pm, edited 3 times in total.
Mistrel
Addict
Addict
Posts: 3415
Joined: Sat Jun 30, 2007 8:04 pm

Re: Thoughts on lambda syntax if we had them in PureBasic

Post by Mistrel »

Lambda thread:

Code: Select all

Define a.l=1
Define b.l=2

;/ Lambda as a thread function with capture group
CreateThread(SomeLambdaThread,
  [a, b]Lambda(c)
    ;/ 6
    Debug a+b+c
  EndLambda,
3)
Post Reply