Παρασκευή 26 Δεκεμβρίου 2025

Nested Functions

The M2000 programming language has two types of inner (nested) functions (and some variations for the first type).

Normal Function: 

- We can nest normal functions:

Here we have two functions beta(), but only one inner (nested) in afa() function. A normal function may have modules and functions. Each inner function has own scope, so we can't call something out of block of code of function (except the sane name, as a recursion call)

function beta(y) {
=y/2
}
function alfa(x) {
function beta(y) {
=y*100
}
=x*beta(x)
}
print alfa(20)=40000
print beta(40000)=20000


- Using lambda functions:

A lambda function is an object which combines a list of variables and code for normal function. We can place a lambda function as variable in the list of variables of lambda. The first part of the next example has alfa function which define a nested function beta(). The second part, has a alfa function which have a closure beta which is lambda function, so this definition of alfa has beta all the time (but the first definition has beta at the moment we defined it - so we have some space before which beta not exist).

beta=lambda (y)-> {
=y/2
}
alfa=lambda (x) ->{
function beta(y) {
=y*100
}
=x*beta(x)
}
print alfa(20)=40000
print beta(40000)=20000


beta=lambda (y)-> {
=y/2
}
alfa=lambda (y)->y*100
alfa=lambda beta=alfa (x) ->{
=x*beta(x)
}
print alfa(20)=40000
print beta(40000)=20000


The alfa lambda function can be written like these too:

alfa=lambda
beta=lambda (y)
->{
=y*100
}
(x)
->{
=x*beta(x)
}
print alfa(20)=40000


alfa=lambda
beta=lambda (y)->y*100
(x)
->{
=x*beta(x)
}
print alfa(20)=40000

alfa=lambda
beta=lambda (y)->{
=y*100
}
(x) ->{
=x*beta(x)
}


alfa=lambda
beta=lambda (y) ->y*100

(x) ->{
=x*beta(x)
}


- We can use normal functions as object functions, so we can use siblings functions (as objects functions) as well as inner functions. Using object we gain a state part which we can study or display later:

group delta {
long counter
function beta(y) {
// increment this.counter
.counter++
=y*10
}
function alfa(x) {
function beta(y) {
=y*100
}
=x*.beta(x)+beta(x/2)
}
function alfa2(x) {
function beta(y) {
=y*500
}
// call this.beta() and local beta()
=x*.beta(x)+beta(x/2)
}
}
print delta.beta(10)=100
print delta.alfa(20)=5000
print delta.alfa2(20)=9000
print delta.counter=3


We can't call delta.alfa2().beta() becauses beta() not exist at the level of delta. When we call the delta.alfa2() then the Function statement define the function (writing in a list of functions), and at the exit from delta.alfa2() the inner function deleted. From delta.alfa2() we can call the delta.beta() because it is a member of delta, but without using the delta (because this is something not known for the context of delta.alfa2()). We use the THIS object as this.beta() or .beta() which is the same.

We can use Class statement to make one or more objects:

class delta {
long counter
function beta(y) {
// increment this.counter
.counter++
=y*10
}
function alfa(x) {
function beta(y) {
=y*100
}
=x*.beta(x)+beta(x/2)
}
function alfa2(x) {
function beta(y) {
=y*500
}
// call this.beta() and local beta()
=x*.beta(x)+beta(x/2)
}
}
delta=delta()
print delta.beta(10)=100
print delta.alfa(20)=5000
print delta.alfa2(20)=9000
print delta.counter=3

We can make pointers to objects too. An object created as a pointer to object deleted after last pointer deleted, but an object like delta which created as "named object" or group, deleted same time as all variabled deleted in a module or function, at the end of call, or in the For object { } block at the exit of block. See the => used instead of dot for addressing a member through a pointer of object (group).

// same as delta=pointer(delta())
delta1->delta()
print delta1=>beta(10)=100
print delta1=>alfa(20)=5000
print delta1=>alfa2(20)=9000
print delta1=>counter=3


Simple Function:

This example is like the one with an object (group delta), but now we use simple functions. We can define functions in a simple function using @ (which call always the normal function constructor). Without the @ workaround the search for a simple function return error. Simple functions are not listed in the list of functions, but instead first time searched from the end and then listed as part of code of current scope. A simple function has no own scope (use the caller scope, so in the example counter is on scope in any simple function) but anything new defined (using Local statement to hide a previous defined identifier) would erased at the end of call. Also a simple function use same stack of values from the caller (this speed up the call). The function new variation make a new function always (without new the new definition replace an old one if the name exist).

long counter


print @beta(10)=100
print @alfa(20)=5000
print @alfa2(20)=9000
print counter=3


function beta(y)
counter++
=y*10
end function
function alfa(x)
@function new beta(y) {
=y*100
}
=x*@beta(x)+beta(x/2)
end function
function alfa2(x)
@function new beta(y) {
=y*500
}
=x*@beta(x)+beta(x/2)
end function



Δεν υπάρχουν σχόλια:

Δημοσίευση σχολίου

You can feel free to write any suggestion, or idea on the subject.