Scope¶

you can watch parallel the video for C/C++ (german): https://www.youtube.com/watch?v=JDDWSWef0ng&list=PLEWVM-KBUSpmWSfyoFdD_hLWAY_9tTgi5&index=12

The scopes are implemented with a stack implemented with the CPU. https://de.wikipedia.org/wiki/Stapelspeicher#/media/Datei:ProgramCallStack2_en.svg

image.png

In [1]:
import ROOT
In [2]:
import fortranmagic
%load_ext fortranmagic
import os
import sys

import numpy as np

if sys.platform.startswith("win"):
        # Depends of system, python builds, and compilers compatibility.
        # See below.
    f_config = "--fcompiler=gnu95 --compiler=mingw32"
else:
        # For Unix, compilers are usually more compatible.
    f_config = ""

    # Disable only deprecated NumPy API warning without disable any APIs.
f_config += " --extra '-DNPY_NO_DEPRECATED_API=0'"

%fortran_config {f_config}
%load_ext rpy2.ipython
New default arguments for %fortran:
	 --extra '-DNPY_NO_DEPRECATED_API=0'
Error importing in API mode: ImportError('/home/k/miniforge3/envs/ROOT/lib/python3.14/site-packages/_rinterface_cffi_api.abi3.so: undefined symbol: R_ClosureEnv')
Trying to import in ABI mode.

C++¶

In [3]:
%%cpp
#include <iostream>
using namespace std;
int g=40;
//int main(int argc,char *argv[])
{                    
    cout <<"in main before local variable definition: "<<g<<endl;
    int g=42;             //the local scope does not overrides the global scope
    cout <<"in main after local variable definition: "<<g<<endl;
    {
        cout <<"in subscope before local variable: "<<g<<endl;
        int g=43;
        cout <<"in subscope after local variable: "<<g<<endl;
    }
    cout<<"in main after subscope: "<<g<<endl;                
}
in main before local variable definition: 40
in main after local variable definition: 42
in subscope before local variable: 42
in subscope after local variable: 43
in main after subscope: 42

C¶

In [4]:
%%cpp
#include <stdio.h>

int g=40;
//int main(int argc,char *argv[])
{                    
    //printf("in main before local variable definition: %d\n",g);     //this is not allowed in c, the definitions must come first
    int g=42;             //the local scope does not overrides the global scope
    printf("in main after local variable definition: %d\n",g);  //this is not allowed in c
    {
        //printf("in subscope before local variable: %d\n",g);  //this is not allowed in c
        int g=43;
        printf("in subscope after local variable: %d\n",g);
    }
    printf("in main after subscope: %d\n",g);
}
in main after local variable definition: 42
in subscope after local variable: 43
in main after subscope: 42

Javascript¶

javascript also has local scope as in c if defined with let

In [5]:
%%js //the next line is only necessary in jupyter notebooks
element.setAttribute('style', 'white-space: pre;');console.log=function(text){element.textContent+=text+"\n"}

let g=40
{
    console.log(g)
    g=41
    console.log(g)
}

console.log(g)
In [6]:
%%js //the next line is only necessary in jupyter notebooks
element.setAttribute('style', 'white-space: pre;');console.log=function(text){element.textContent+=text+"\n"}

let g=40
{
    //console.log(g) //not allowed
    let g=41
    {
        let g=42;
        console.log(g);
    }
    console.log(g)
}


console.log(g)
In [7]:
%%js //the next line is only necessary in jupyter notebooks
element.setAttribute('style', 'white-space: pre;');console.log=function(text){element.textContent+=text+"\n"}


{
    //console.log(g) //not allowed
    var g=41 //defines a global variable but not when used inside a function!
    {
        let g=42;
        console.log(g);
    }
    console.log(g)
}


console.log(g)
In [8]:
%%js //the next line is only necessary in jupyter notebooks
element.setAttribute('style', 'white-space: pre;');console.log=function(text){element.textContent+=text+"\n"}

//Variables declared with var, let and const are quite similar when declared inside a function.
let g=40;

function test(){
    var g=42;
    {
        //console.log(g); //not allowed
        let g=43;
        console.log(g);
    }
    console.log(g)
}

test()
console.log(g)

Python¶

Python only knows three scopes: global, local and class. In python scopes are defined by indentation. It is important to keep a consistent indentation. We need to use functions to show the scopes.

In [9]:
g=40
def myfunc():
  g = 42
  def myinnerfunc():
    print(g)
  myinnerfunc()
  print(g)

myfunc()
print(g)
42
42
40
In [10]:
g=40
def myfunc():
  g = 42
  def myinnerfunc():
    g=43
    print(g)
  myinnerfunc()
  print(g)

myfunc()
print(g)
43
42
40
In [11]:
def myfunc():
  g = 42
  def myinnerfunc():
    print(g)  #not allowed
    g=43
    print(g)
  myinnerfunc()
  print(g)

myfunc()
---------------------------------------------------------------------------
UnboundLocalError                         Traceback (most recent call last)
Cell In[11], line 10
      6     print(g)
      7   myinnerfunc()
      8   print(g)
      9 
---> 10 myfunc()

Cell In[11], line 7, in myfunc()
      3   def myinnerfunc():
      4     print(g)  #not allowed
      5     g=43
      6     print(g)
----> 7   myinnerfunc()
      8   print(g)

Cell In[11], line 4, in myfunc.<locals>.myinnerfunc()
      3   def myinnerfunc():
----> 4     print(g)  #not allowed
      5     g=43
      6     print(g)

UnboundLocalError: cannot access local variable 'g' where it is not associated with a value
In [12]:
g=40
def myfunc():
  g = 42
  def myinnerfunc():
    global g #this is accessing the global g
    g=43
    print(g)
  myinnerfunc()
  print(g)

myfunc()
print(g)
43
42
43

R¶

In [13]:
%%R
g <- 40
myfunc <- function() {
  g <- 42
  myinnerfunc <- function() {
    print(g)
  }
  myinnerfunc()
  print(g)
} 
myfunc()
print(g)
[1] 42
[1] 42
[1] 40
In [14]:
%%R
g <- 40
myfunc <- function() {
  g <- 42
  myinnerfunc <- function() {
    g<-43
    print(g)
  }
  myinnerfunc()
  print(g)
} 
myfunc()
print(g)
[1] 43
[1] 42
[1] 40
In [ ]:
 
In [15]:
%%R
g <- 40
myfunc <- function() {
  g <- 42
  myinnerfunc <- function() {
    print(g)
    g<-43
    print(g)
  }
  myinnerfunc()
  print(g)
} 
myfunc()
print(g)
[1] 42
[1] 43
[1] 42
[1] 40
In [19]:
%%R
g <- 40

myfunc <- function() {
    g <- 42 #myfunc scope variable g
    myinnerfunc <- function() {
        g<-42
        g<<-44 # this is accessing myfunc scope variable g
        assign("g", 43, envir = .GlobalEnv)  # like Python: global g
        print(get("g", envir = .GlobalEnv))
        print(g)
    }
    myinnerfunc()
    print(g)
}

myfunc()
print(g)
[1] 43
[1] 42
[1] 44
[1] 43

Fortran¶

Fortan does only have function scopes