Page 1 of 1

Allow the procedure keyword to be used for assignment

Posted: Mon Jun 11, 2018 3:44 pm
by Mistrel
As it could be for assignment:

Code: Select all

*a=Procedure()
  Debug "Test"
EndProcedure

CallFunctionFast(*a)
Definition within another function:

Code: Select all

Procedure PrintTest()
  *a=Procedure()
    Debug "Test"
  EndProcedure
  
  CallFunctionFast(*a)
EndProcedure
Note that because the procedure is anonymous the pointer is only available where it is assigned. It is still contained within the CODE section but it can only be referenced from wherever it is passed by value.

This would be equivalent by the compiler to the following where 0x1 is considered the address of the procedure:

Code: Select all

;/ Located at address 0x1
Procedure()
  Debug "Test"
EndProcedure

Procedure PrintTest()
  CallFunctionFast(0x1)
EndProcedure

Re: Allow the procedure keyword to be used for assignment

Posted: Mon Jun 11, 2018 8:00 pm
by mk-soft
There are many ways to call procedures indirectly.

Right now, I don't know what you're doing.
I often work with tables on procedures...

Code: Select all

;-TOP

#Max_Func = 10

Global Dim *pFunction(#Max_Func)

Macro Function()
  Procedure func_#MacroExpandedCount()
EndMacro

Macro EndFunction()
  EndProcedure
  *pFunction(MacroExpandedCount) = @func_#MacroExpandedCount()
EndMacro

Macro InvokeFunction(Number)
  CallCFunctionFast(*pFunction(Number))
EndMacro

Global number

Function()
number = 100
Debug "Test " + number
EndFunction()

Function()
number = 200
Debug "Test " + number
EndFunction()

Function()
number = 300
Debug "Test " + number
EndFunction()

Function()
number = 300
Debug "Test " + number
EndFunction()

InvokeFunction(1)
InvokeFunction(2)
InvokeFunction(3)
InvokeFunction(4)

Re: Allow the procedure keyword to be used for assignment

Posted: Mon Jun 11, 2018 9:35 pm
by Trond
What would be the advantage, compared to this?

Code: Select all

; *a=Procedure()
;   Debug "Test"
; EndProcedure
; 
; CallFunctionFast(*a)

Procedure A()
  Debug "Test"
EndProcedure

CallFunctionFast(@A())
The only difference is that *a can be reassigned to point to another procedure, while @A() can't. However, if you need a reassignable variable, just add *a = @A().

Re: Allow the procedure keyword to be used for assignment

Posted: Tue Jun 12, 2018 2:04 pm
by Mistrel
Trond wrote:What would be the advantage, compared to this?
It's probably just the sound of me pining for lambdas and anonymous functions or a simpler form thereof. :|

viewtopic.php?f=7&t=67416

I rarely program in PureBasic anymore because of the level of verbosity I use has become so extreme that it's now become difficult to read due to whitespace constraints. I use SAL everywhere and an impressive amount of macros for typedefs and self-documenting code.

I don't see myself using PureBasic very often for anything meaningful outside of small hobby projects because of the real issue that's been eating my soul:

viewtopic.php?f=3&t=66631

When I do pick it up I end up coming here to write feature requests to ask for things that are so much easier in other languages. A lot of this can be mitigated through macros except for the limits of what I can do with whitespace that impact readability.

Re: Allow the procedure keyword to be used for assignment

Posted: Wed Jun 13, 2018 1:20 pm
by Trond
I agree that PB is really verbose. Some of it is just syntax (Procedure vs fun, ProcedureReturn vs return), but there is also a deep rooted reason for the difference.

These other languages have garbage collection. Without gc, the same style quickly becomes a nightmare with regards to memory management.

Edit: That said, allowing procedures to be within another procedures would be nice, to hide small private functions without having to use the Module system.

Re: Allow the procedure keyword to be used for assignment

Posted: Wed Jun 13, 2018 7:37 pm
by Mistrel
The verbosity isn't the issue. I think that strictly-typed language with self-documenting verbosity is a good thing. The only real frustration I have with using PureBasic is the inability to lay my code out in a clear and concise manner with the added verbosity I need to keep things clear.

My memory isn't what it used to be and I need the added verbosity to help me read and understand the intent of my code. I do document my code of course but because PureBasic is still fairly loosely typed I end up using macros as typedefs throughout my code to clearly define types.

Here is one example:

Code: Select all

Procedure Map_InsertNode(*Map, *Node, Key, Value, *OldValue, *HasKey, CanReplace)
This is a single procedure from a left-leaning red-black tree (map) data structure written in traditional PureBasic without any added self-documenting verbosity. It would work just fine as it is but it's difficult to know how to use and call it at a glance. All of the parameters are documented but I don't want to have to refer to the documentation every single time I want to call it because the declaration is inherently ambiguous.

Here is the actual procedure as it appears in my code (notice that it is very difficult to read due to line-splitting constraints):

Code: Select all

Procedure.MAP_NODE_POINTER Map_InsertNode(_IN *Map.MAP_TREE,
  _IN *Node.MAP_NODE, _IN Key.MAP_KEY, _IN Value.MAP_VALUE,
  _OUT *OldValue.MAP_VALUE_REFERENCE, _OUT *HasKey.BOOLEAN_REFERENCE,
    _IN CanReplace.BOOLEAN)
The return type and each parameter is clearly declared as to what it is through macro-defined typedefs. Here is a breakdown of just this ONE procedure with related snippets:

h.Types.pb:

Code: Select all

Macro POINTER
  i
EndMacro

Macro UINT_8
  a
EndMacro

Macro UINT_32
  l
EndMacro

Macro INT_32_64
  i
EndMacro

Macro BOOLEAN
  b
EndMacro

Structure _Types_Boolean_Reference
  Deref.b
EndStructure

;/ IDE auto-complete workaround
CompilerIf #False
Structure BOOLEAN_REFERENCE Extends _Types_Boolean_Reference
EndStructure
CompilerEndIf
Macro BOOLEAN_REFERENCE
  _Types_Boolean_Reference
EndMacro

...
h.SAL.pb:

Code: Select all

Macro _IN
EndMacro

Macro _OUT
EndMacro

...
h.Map.pb:

Code: Select all

Macro MAP_NODE_COLOR
  UINT_8
EndMacro

Macro MAP_NODE_POINTER
  POINTER
EndMacro

Structure _Map_Tree
  *Root._Map_Node
EndStructure

Structure _Map_Node
  *Left._Map_Node
  *Right._Map_Node
  Key.INT_32_64
  Value.POINTER
  Color.MAP_NODE_COLOR
  Size.UINT_32
EndStructure

;/ IDE auto-complete workaround
CompilerIf #False
Structure MAP_NODE Extends _Map_Node
EndStructure
CompilerEndIf
Macro MAP_NODE
  _Map_Node
EndMacro

;/ IDE auto-complete workaround
CompilerIf #False
Structure MAP_TREE Extends _Map_Tree
EndStructure
CompilerEndIf
Macro MAP_TREE
  _Map_Tree
EndMacro

Structure _Map_Value_Reference
  Deref.INT_32_64
EndStructure

Macro MAP_KEY
  INT_32_64
EndMacro

Macro MAP_VALUE
  POINTER
EndMacro

Procedure.MAP_NODE_POINTER Map_InsertNode(_IN *Map.MAP_TREE,
  _IN *Node.MAP_NODE, _IN Key.MAP_KEY, _IN Value.MAP_VALUE,
  _OUT *OldValue.MAP_VALUE_REFERENCE, _OUT *HasKey.BOOLEAN_REFERENCE,
    _IN CanReplace.BOOLEAN)
 
 ...
And this is how I would like to write this procedure if I could:

Code: Select all

Procedure.MAP_NODE_POINTER
  _Map_InsertNode(
    _IN  *Map.MAP_TREE,
    _IN  *Node.MAP_NODE,
    _IN  Key.MAP_KEY,
    _IN  Value.MAP_VALUE,
    _OUT *OldValue.MAP_VALUE_REFERENCE,
    _OUT *HasKey.BOOLEAN_REFERENCE,
    _IN  CanReplace.BOOLEAN
)
Other issues with the verbosity I use include:

viewtopic.php?f=3&t=66909
viewtopic.php?f=3&t=66910

Related requests on whitespace:
viewtopic.php?f=3&t=66631
viewtopic.php?f=3&t=61025

As much as I appreciate the features added to PureBasic over the years, I've barely used any of them. The only time I ever get excited about a release is when there will be improvements to the language itself which is rare to see.

I may sound bitter but it's only because of how many years I've used PureBasic. I love it. But as I've grown as a programmer and been exposed to other languages, it's no longer the pleasure to use that it once was.

Re: Allow the procedure keyword to be used for assignment

Posted: Wed Jun 13, 2018 7:54 pm
by NicTheQuick
I can sign that.

Re: Allow the procedure keyword to be used for assignment

Posted: Wed Jun 13, 2018 10:15 pm
by Josh
Mistrel wrote:And this is how I would like to write this procedure if I could:

Code: Select all

Procedure.MAP_NODE_POINTER
  _Map_InsertNode(
    _IN  *Map.MAP_TREE,
    _IN  *Node.MAP_NODE,
    _IN  Key.MAP_KEY,
    _IN  Value.MAP_VALUE,
    _OUT *OldValue.MAP_VALUE_REFERENCE,
    _OUT *HasKey.BOOLEAN_REFERENCE,
    _IN  CanReplace.BOOLEAN
)
Then maybe you should look for a programming language that can do that. To be honest, it really annoys me that the 'Feature Requests and Wishlists' forum is always crammed with your threads in various titles that all run in the same direction.

Of course, anyone can express their wishes, but that should then be limited to one thread and not warmed up every few months by the thread creator.
Mistrel wrote:I rarely program in PureBasic anymore because of the level of verbosity I use has become so extreme that it's now become difficult to read due to whitespace constraints. I use SAL everywhere and an impressive amount of macros for typedefs and self-documenting code.
If you have already found your programming language, then I do not understand why you have to cry here again and again.


@Pb-Team
Adding '(' to the operators of line continuation should probably be easy to implement.

Re: Allow the procedure keyword to be used for assignment

Posted: Thu Jun 14, 2018 6:04 am
by IceSoft
maybe this is a small solution:

Code: Select all

    Macro _IN: EndMacro
    Macro _OUT: EndMacro

    Procedure   _Map_InsertNode( _IN  *Map.MAP_TREE, _IN  *Node._Map_Node, , _OUT  *NodeRet._Map_Node)
      
    EndProcedure

Re: Allow the procedure keyword to be used for assignment

Posted: Thu Jun 14, 2018 7:42 am
by Lord
@mistrel
I'm just wondering.

Your Procedure looks like this:
Mistrel wrote:...
Here is the actual procedure as it appears in my code (notice that it is very difficult to read due to line-splitting constraints):

Code: Select all

Procedure.MAP_NODE_POINTER Map_InsertNode(_IN *Map.MAP_TREE,
  _IN *Node.MAP_NODE, _IN Key.MAP_KEY, _IN Value.MAP_VALUE,
  _OUT *OldValue.MAP_VALUE_REFERENCE, _OUT *HasKey.BOOLEAN_REFERENCE,
    _IN CanReplace.BOOLEAN)
...
Here it looks like this:

Code: Select all

Procedure.MAP_NODE_POINTER Map_InsertNode(_IN *Map.MAP_TREE,
                                          _IN *Node.MAP_NODE, _IN Key.MAP_KEY, _IN Value.MAP_VALUE,
                                          _OUT *OldValue.MAP_VALUE_REFERENCE, _OUT *HasKey.BOOLEAN_REFERENCE,
                                          _IN CanReplace.BOOLEAN)
  
It even can look like this:

Code: Select all

Procedure.MAP_NODE_POINTER Map_InsertNode(_IN *Map.MAP_TREE,
                                          _IN *Node.MAP_NODE,
                                          _IN Key.MAP_KEY,
                                          _IN Value.MAP_VALUE,
                                          _OUT *OldValue.MAP_VALUE_REFERENCE,
                                          _OUT *HasKey.BOOLEAN_REFERENCE,
                                          _IN CanReplace.BOOLEAN)
 
In both examples I didn't add "EndProcedure".
Is that (your example) how you want it to look?

Re: Allow the procedure keyword to be used for assignment

Posted: Thu Jun 14, 2018 8:03 pm
by Mistrel
Lord wrote:It even can look like this:

Code: Select all

Procedure.MAP_NODE_POINTER Map_InsertNode(_IN *Map.MAP_TREE,
                                          _IN *Node.MAP_NODE,
                                          _IN Key.MAP_KEY,
                                          _IN Value.MAP_VALUE,
                                          _OUT *OldValue.MAP_VALUE_REFERENCE,
                                          _OUT *HasKey.BOOLEAN_REFERENCE,
                                          _IN CanReplace.BOOLEAN)
 
This is exactly why I would like better control over my whitespace. As much as I would like to split my lines anywhere, some incremental improvements can simply be to how it is currently handled, such as allowing a newline after the "(" and before the ")" of procedures and checking the next line for operators such as "+, *, &, |", etc.

Re: Allow the procedure keyword to be used for assignment

Posted: Thu Jun 14, 2018 8:10 pm
by mk-soft
Boolean ist not a BYTE. It´s always a INTEGER

Re: Allow the procedure keyword to be used for assignment

Posted: Fri Jun 15, 2018 12:49 am
by Mistrel
mk-soft wrote:Boolean ist not a BYTE. It´s always a INTEGER
There is no boolean type in PureBasic therefore the definition is whatever I want it to be. When written to disk it may even be only a bit. But at runtime and in my data structures it's a byte.

Because it's just a macro I can always redefine it in my project if I need or want it to change.