Les fonctions

Il est possible de définir une fonction de trois façons différentes :

Définition en ligne


In [1]:
f(x)=x+1


Out[1]:
f (generic function with 1 method)

In [2]:
f(2)


Out[2]:
3

In [3]:
g(x,y)=[x*y+1, x-y]


Out[3]:
g (generic function with 1 method)

In [4]:
g(1,2)


Out[4]:
2-element Array{Int64,1}:
  3
 -1

Il est possible d'utiliser begin-end ou ( ; ) pour délimiter la fonction la dernière valeur calculée est retournée


In [5]:
h(x)=begin
    y=2
    x+y
end


Out[5]:
h (generic function with 1 method)

In [6]:
h(3)


Out[6]:
5

In [7]:
h(x)=(y=2;x+y) # equivallent à la première écriture


Out[7]:
h (generic function with 1 method)

In [8]:
h(3)


Out[8]:
5

Structurée

JULIA possède une structure plus classique à l'aide de function-end comme précédemment la dernière valeur calculée est par défaut la variable de retour autrement l'utilisation de return spécifie la ou les variables de sortie.


In [9]:
function H(x,y)
    z=x+y;
    z^2/(abs(x)+1)
end


Out[9]:
H (generic function with 1 method)

In [10]:
H(1,2)


Out[10]:
4.5

L'usage de return pour fixer la sortie


In [13]:
function Choix(x)
    if x>0
        return "Positif"
    else
        return "Négatif"
    end
end


Out[13]:
Choix (generic function with 1 method)

In [14]:
txt=Choix(3)


Out[14]:
"Positif"

Anonyme

Le concept peut paraître abstrait mais on peut définir une fonction sans la nommer puis l'affecter à une variable...


In [15]:
x->x^2


Out[15]:
#3 (generic function with 1 method)

In [16]:
G=x->sqrt(x)


Out[16]:
#5 (generic function with 1 method)

In [17]:
G(1)


Out[17]:
1.0

In [18]:
typeof(G)


Out[18]:
getfield(Main, Symbol("##5#6"))

Arguments de sortie

Pour avoir plusieurs arguments de sortie il faut utiliser un "tuple" autrement dit une collection d'éléments


In [20]:
function multi_output(x,y)
    return x+y, x-y
end


Out[20]:
multi_output (generic function with 1 method)

In [21]:
a=multi_output(1,2) # un seul argument de sortie qui contient un tuple


Out[21]:
(3, -1)

In [22]:
typeof(a)


Out[22]:
Tuple{Int64,Int64}

In [23]:
a[1]


Out[23]:
3

In [24]:
a[2]


Out[24]:
-1

In [25]:
a , b =multi_output(1,2) # assignation aux 2 arguments de sortie


Out[25]:
(3, -1)

In [26]:
a


Out[26]:
3

In [27]:
b


Out[27]:
-1

Portée des variables

Quelle est la portée des variables autrement dit une variable définie peut elle être accessible, modifiable dans une fonction sans la passer en paramètre ?


In [28]:
a=1
f(x)=a+x
f(1)


Out[28]:
2

In [29]:
a=1
function ff(x)
    x+a
end
ff(1)


Out[29]:
2

In [30]:
a=1
function ff(x)
    x+a # on utilise a défini en dehors de la fonction
    a=2 # on tente de changer la valeur de a... error !
end
ff(1)


UndefVarError: a not defined

Stacktrace:
 [1] ff(::Int64) at ./In[30]:3
 [2] top-level scope at In[30]:6

In [31]:
a=1
function ff(x)
    a=2
    x+a
end
ff(1)


Out[31]:
3

In [32]:
a


Out[32]:
1

Donc par défaut une variable définie est connue et utilisable par toute fonction appelée (de même à l'intérieure d'une fonction).

Si on redéfinie localement dans la fonction la variable alors "elle écrase localement" la dite variable et en sortie de fonction rien n'est modifié.

Attention à l'utilisation dans la fonction d'une variable extérieure puis d'affecter une valeur à cette variable...

Le mapping

Souvent on écrit une fonction sous une forme scalaire sans chercher à utiliser les opérations vectorielles pour appliquer cette fonction à un tableau


In [37]:
f(x)=x^2 +1
f(1:5)  # il aurait fallu définir f(x)=x.^2.+1


MethodError: no method matching ^(::UnitRange{Int64}, ::Int64)
Closest candidates are:
  ^(!Matched::Float16, ::Integer) at math.jl:795
  ^(!Matched::Missing, ::Integer) at missing.jl:124
  ^(!Matched::Missing, ::Number) at missing.jl:97
  ...

Stacktrace:
 [1] macro expansion at ./none:0 [inlined]
 [2] literal_pow at ./none:0 [inlined]
 [3] f(::UnitRange{Int64}) at ./In[37]:1
 [4] top-level scope at In[37]:2

La fonction map permet de palier à ce manquement


In [38]:
map(f,1:5)


Out[38]:
5-element Array{Int64,1}:
  2
  5
 10
 17
 26

In [39]:
f.(1:5)


Out[39]:
5-element Array{Int64,1}:
  2
  5
 10
 17
 26

In [41]:
map(f,[1 2; 3 4])


Out[41]:
2×2 Array{Int64,2}:
  2   5
 10  17

In [42]:
f.([1 2; 3 4])


Out[42]:
2×2 Array{Int64,2}:
  2   5
 10  17

In [43]:
g(x,y)=x+y
map(g,0:3,1:4)


Out[43]:
4-element Array{Int64,1}:
 1
 3
 5
 7

In [44]:
map(g,[1 2;3 4],[2 3;4 5])


Out[44]:
2×2 Array{Int64,2}:
 3  5
 7  9

In [46]:
g(f,x)=f(x)+1


Out[46]:
g (generic function with 2 methods)

In [47]:
g(sin,1)


Out[47]:
1.8414709848078965

In [ ]: