Question

Pour une personne sans comp-sci fond, qu'est ce qu'un lambda dans le monde de l'Informatique?

Était-ce utile?

La solution

Lambda vient de la Lambda Calcul et se réfère à des fonctions anonymes dans la programmation.

Pourquoi est-ce cool?Il vous permet d'écrire rapidement jeter les fonctions sans les nommer.Il fournit également une belle façon d'écrire des fermetures.Avec ce pouvoir, vous pouvez faire des choses comme ça.

Python

def adder(x):
    return lambda y: x + y
add5 = adder(5)
add5(1)
6

Comme vous pouvez le voir dans l'extrait de Python, la fonction additionneur prend un argument x, et retourne une fonction anonyme, ou lambda, qui prend un argument de y.Cette fonction anonyme qui vous permet de créer des fonctions de fonctions.C'est un simple exemple, mais il doit transmettre la puissance des lambdas et des bouchons.

Des exemples dans d'autres langues

Perl 5

sub adder {
    my ($x) = @_;
    return sub {
        my ($y) = @_;
        $x + $y
    }
}

my $add5 = adder(5);
print &$add5(1) == 6 ? "ok\n" : "not ok\n";

JavaScript

var adder = function (x) {
    return function (y) {
        return x + y;
    };
};
add5 = adder(5);
add5(1) == 6

JavaScript (ES6)

const adder = x => y => x + y;
add5 = adder(5);
add5(1) == 6

Régime

(define adder
    (lambda (x)
        (lambda (y)
           (+ x y))))
(define add5
    (adder 5))
(add5 1)
6

C# 3.5 ou supérieur

Func<int, Func<int, int>> adder = 
    (int x) => (int y) => x + y; // `int` declarations optional
Func<int, int> add5 = adder(5);
var add6 = adder(6); // Using implicit typing
Debug.Assert(add5(1) == 6);
Debug.Assert(add6(-1) == 5);

// Closure example
int yEnclosed = 1;
Func<int, int> addWithClosure = 
    (x) => x + yEnclosed;
Debug.Assert(addWithClosure(2) == 3);

Swift

func adder(x: Int) -> (Int) -> Int{
   return { y in x + y }
}
let add5 = adder(5)
add5(1)
6

PHP

$a = 1;
$b = 2;

$lambda = function () use (&$a, &$b) {
    echo $a + $b;
};

echo $lambda();

Haskell

(\x y -> x + y) 

Java voir ce post

// The following is an example of Predicate : 
// a functional interface that takes an argument 
// and returns a boolean primitive type.

Predicate<Integer> pred = x -> x % 2 == 0; // Tests if the parameter is even.
boolean result = pred.test(4); // true

Lua

adder = function(x)
    return function(y)
        return x + y
    end
end
add5 = adder(5)
add5(1) == 6        -- true

Kotlin

val pred = { x: Int -> x % 2 == 0 }
val result = pred(4) // true

Ruby

Ruby est un peu différent dans le sens que vous ne pouvez pas appeler un lambda en utilisant la même syntaxe que l'appel d'une fonction, mais il a encore des lambdas.

def adder(x)
  lambda { |y| x + y }
end
add5 = adder(5)
add5[1] == 6

Rubis était Ruby, il y a un raccourci pour les lambdas, de sorte que vous pouvez définir adder de cette façon:

def adder(x)
  -> y { x + y }
end

Autres conseils

Un lambda est un type de fonction, définie sur la ligne.Avec un lambda-vous aussi souvent une sorte de type de variable qui peut contenir une référence à une fonction, lambda ou autrement.

Par exemple, voici un C# morceau de code qui n'utilise pas un lambda:

public Int32 Add(Int32 a, Int32 b)
{
    return a + b;
}

public Int32 Sub(Int32 a, Int32 b)
{
    return a - b;
}

public delegate Int32 Op(Int32 a, Int32 b);

public void Calculator(Int32 a, Int32 b, Op op)
{
    Console.WriteLine("Calculator: op(" + a + ", " + b + ") = " + op(a, b));
}

public void Test()
{
    Calculator(10, 23, Add);
    Calculator(10, 23, Sub);
}

Cela demande de la Calculatrice, en passant le long de ce ne sont pas deux numéros, mais la méthode à appeler à l'intérieur de la Calculatrice pour obtenir les résultats du calcul.

En C# 2.0 nous avons obtenu des méthodes anonymes, ce qui raccourcit le code ci-dessus pour:

public delegate Int32 Op(Int32 a, Int32 b);

public void Calculator(Int32 a, Int32 b, Op op)
{
    Console.WriteLine("Calculator: op(" + a + ", " + b + ") = " + op(a, b));
}

public void Test()
{
    Calculator(10, 23, delegate(Int32 a, Int32 b)
    {
        return a + b;
    });
    Calculator(10, 23, delegate(Int32 a, Int32 b)
    {
        return a - b;
    });
}

Et puis C# 3.0 nous avons obtenu des lambdas qui rend le code encore plus courte:

public delegate Int32 Op(Int32 a, Int32 b);

public void Calculator(Int32 a, Int32 b, Op op)
{
    Console.WriteLine("Calculator: op(" + a + ", " + b + ") = " + op(a, b));
}

public void Test()
{
    Calculator(10, 23, (a, b) => a + b);
    Calculator(10, 23, (a, b) => a - b);
}

Il se réfère à lambda calcul, qui est un système formel qui a juste les expressions lambda, qui représentent une fonction qui prend une fonction pour son seul argument et retourne une fonction.Toutes les fonctions dans le lambda calcul sont de ce type, c'est à dire, λ : λ → λ.

Lisp utilisé le lambda concept au nom de sa fonction anonyme littéraux.Cette lambda représente une fonction qui prend deux arguments x et y, et retourne leur produit:

(lambda (x y) (* x y)) 

Il peut être appliqué en ligne comme cela (donne 50):

((lambda (x y) (* x y)) 5 10)

Le nom de "lambda" n'est qu'un artefact historique.Nous parlons est une expression dont la valeur est une fonction.

Un exemple simple (à l'aide de la Scala pour la ligne suivante) est:

args.foreach(arg => println(arg))

d'où l'argument de la foreach la méthode est une expression pour une fonction anonyme.La ligne ci-dessus est plus ou moins la même chose que d'écrire quelque chose comme ceci (pas tout à fait vrai code, mais vous obtenez l'idée):

void printThat(Object that) {
  println(that)
}
...
args.foreach(printThat)

sauf que vous n'avez pas besoin de s'embêter avec:

  1. Déclarer la fonction de quelque part d'autre (et d'avoir à les chercher quand vous revenez sur le code plus tard).
  2. Nommage quelque chose que vous êtes seulement en utilisant une seule fois.

Une fois que vous êtes utilisé pour les valeurs de la fonction, le fait de devoir faire sans eux semble aussi ridicule que d'être nécessaire pour nom de chaque expression, telles que:

int tempVar = 2 * a + b
...
println(tempVar)

au lieu de simplement l'écriture de l'expression où vous en avez besoin:

println(2 * a + b)

La notation exacte varie d'une langue à l'autre;Le grec n'est pas toujours nécessaire!;-)

Le lambda calcul est une constante mathématique de la théorie de la substitution.En mathématiques à l'école on voit par exemple x+y=5 jumelé avec x−y=1.Avec les moyens de manipuler des équations individuelles, il est aussi possible de mettre l'information à partir de ces deux ensemble, à condition de la croix-équation de substitutions sont fait logiquement.Lambda calcul codifie la façon correcte de faire de ces substitutions.

Étant donné que y = x−1 est valable un réarrangement de la deuxième équation, cela: λ y = x−1 désigne une fonction de substitution de symboles x−1 pour le symbole y.Maintenant, imaginez l'application λ y pour chaque terme dans la première équation.Si un terme est y puis effectuer la substitution;sinon ne rien faire.Si vous faites cela sur le papier, vous allez voir comment l'application de cette λ y fera la première équation résoluble.

C'est une réponse sans n'importe quel ordinateur de la science ou de la programmation.

Le plus simple exemple de programmation je pense, vient de http://en.wikipedia.org/wiki/Joy_(programming_language)#How_it_works:

voici comment le carré de la fonction peut être définie dans un impératif langage de programmation (C):

int square(int x)
{
    return x * x;
}

La variable x est un paramètre formel qui est remplacé par le valeur au carré lorsque la fonction est appelée.Dans une fonctionnelle langue (Schéma) de la même fonction est définie:

(define square
  (lambda (x) 
    (* x x)))

C'est différent à bien des égards, mais il utilise toujours le paramètre formel x de la même manière.


Ajouté: http://imgur.com/a/XBHub

lambda

Légèrement simplifiée à l'extrême:une fonction lambda est que l'on peut passer à d'autres fonctions, et il est logique d'accès.

En C# lambda syntaxe est souvent compilé à l'aide de méthodes simples de la même manière que les délégués anonymes, mais il peut également être ventilé et sa logique de lecture.

Par exemple (en C#3):

LinqToSqlContext.Where( 
    row => row.FieldName > 15 );

LinqToSql peut lire que la fonction (x > 15) et de le convertir au réel SQL à exécuter à l'aide de l'expression des arbres.

La déclaration ci-dessus devient:

select ... from [tablename] 
where [FieldName] > 15      --this line was 'read' from the lambda function

Ceci est différent de la normale, des méthodes ou des délégués anonymes (qui sont juste compilateur magie vraiment) parce qu'ils ne peuvent pas être lire.

Pas toutes les méthodes en C# qui utilisent lambda syntaxe peut être compilé à l'expression des arbres (c'est à direréelle lambda fonctions).Par exemple:

LinqToSqlContext.Where( 
    row => SomeComplexCheck( row.FieldName ) );

Maintenant l'arborescence d'expression ne peut pas être lu - SomeComplexCheck ne peut pas être divisé.L'instruction SQL exécute sans la où les, et chaque ligne de données sera mis à SomeComplexCheck.

Lambda fonctions ne doivent pas être confondus avec les méthodes anonymes.Par exemple:

LinqToSqlContext.Where( 
    delegate ( DataRow row ) { 
        return row.FieldName > 15; 
    } );

Cela a aussi un 'inline' fonction, mais cette fois c'est juste compilateur de la magie - le compilateur C# va diviser ce à une nouvelle méthode d'instance avec un nom généré automatiquement.

Les méthodes anonymes ne peuvent pas être lus, et donc la logique ne peut pas être traduit comme il peut pour les lambda fonctions.

J'ai comme l'explication des Lambdas dans cet article: L'Évolution de LINQ Et De Son Impact Sur La Conception De C#.Il fait beaucoup de sens pour moi, car il montre un monde réel pour les Lambdas et l'a construit comme un exemple pratique.

Leur explication rapide:Les Lambdas sont une façon de traiter le code (fonctions) en tant que données.

Un exemple d'un lambda en Ruby, c'est comme suit:

hello = lambda do
    puts('Hello')
    puts('I am inside a proc')
end

hello.call

Va genereate la sortie suivante:

Hello
I am inside a proc

@Brian-je utiliser les lambdas tout le temps en C#, en LINQ et non des opérateurs LINQ.Exemple:

string[] GetCustomerNames(IEnumerable<Customer> customers)
 { return customers.Select(c=>c.Name);
 }

Avant le C#, j'ai utilisé les fonctions anonymes en JavaScript pour les rappels de fonctions AJAX, avant le terme Ajax a même été inventé:

getXmlFromServer(function(result) {/*success*/}, function(error){/*fail*/});

La chose intéressante avec C#'s lambda syntaxe, cependant, c'est que sur leurs propres à leur type de ne peut pas être inférer (c'est à dire, vous ne pouvez pas le type var foo = (x,y) => x * y), mais en fonction de quel type ils sont affectés, ils vont vous être compilé en tant que délégués ou l'arbre de syntaxe abstraite représentant de l'expression (ce qui est la façon dont LINQ objet mappeurs de faire leur "langue intégrée" de la magie).

Les Lambdas en LISP peut également être transmis à une offre de l'opérateur puis traversé comme une liste de listes.Certains de puissantes macros sont faites de cette façon.

La question est officiellement répondu à beaucoup, je ne vais pas essayer d'ajouter plus de sur cette.

Dans de très simple, informel les mots de quelqu'un qui sait très peu ou rien sur les mathématiques ou de la programmation, je voudrais l'expliquer comme une petite "machine" ou "boîte" qui prend en entrée, en fait le travail et qui produit une sortie, n'a pas de nom particulier, mais nous savons d'où il est et en cette connaissance, nous les utilisons.

Pratiquement parlant, pour une personne qui sait ce qu'une fonction est, je dirai que c'est une fonction qui n'a pas de nom, l'habitude de mettre à un point dans le mémoire qui peut être utilisé simplement par référence à cette mémoire (généralement par le biais de l'utilisation d'une variable - s'ils ont entendu parler de la notion de pointeurs de fonction, je voudrais l'utiliser comme un concept similaire) - cette réponse couvre la jolie notions de base (pas de mention de fermetures etc), mais on peut obtenir le point facilement.

Vous pouvez la considérer comme une fonction anonyme - voici quelques infos: Wikipédia - Fonction Anonyme

Juste parce que je ne peux pas le voir un de C++11 exemple ici, je vais aller de l'avant et l'après de ce bel exemple de ici.Après recherche, c'est le langage le plus clair exemple précis que j'ai pu trouver.

Bonjour, Lambdas, version 1

template<typename F>

void Eval( const F& f ) {
        f();
}
void foo() {
        Eval( []{ printf("Hello, Lambdas\n"); } );
}

Bonjour, Lambdas, version 2:

void bar() {
    auto f = []{ printf("Hello, Lambdas\n"); };
    f();
}

J'ai du mal à enveloppant ma tête autour des expressions lambda parce que je travaille dans Visual FoxPro, qui a substitution de Macro et de la ExecScript{} et d'Évaluer les fonctions de (), qui semblent servir le même but.

? Calculator(10, 23, "a + b")
? Calculator(10, 23, "a - b");

FUNCTION Calculator(a, b, op)
RETURN Evaluate(op)

Un avantage certain pour l'aide formelle lambdas est (je suppose) au moment de la compilation de la vérification:Fox ne saurez pas si vous faute de frappe à la chaîne de texte ci-dessus jusqu'à ce qu'il essaie de l'exécuter.

C'est aussi utile pour piloté par les données de code:vous pouvez stocker l'ensemble de routines dans les champs mémo dans la base de données et ensuite il suffit de les évaluer au moment de l'exécution.Cela vous permet de modifier le cadre de l'application sans avoir accès à la source.(Mais c'est un autre sujet tout à fait.)

Pour une personne sans comp-sci fond, qu'est ce qu'un lambda dans le monde de l'Informatique?

Je vais l'illustrer de manière intuitive, étape par étape, en simple et lisible python codes.

En bref, un lambda est juste un anonyme et de la fonction inline.

Commençons par l'affectation à comprendre lambdas comme un étudiant de première année avec l'arrière-plan de l'arithmétique de base.

Le plan de cession est le "nom = valeur", voir:

In [1]: x = 1
   ...: y = 'value'
In [2]: x
Out[2]: 1
In [3]: y
Out[3]: 'value'

'x', 'y' sont des noms et des 1, 'valeur' sont des valeurs.Essayez d'une fonction en mathématiques

In [4]: m = n**2 + 2*n + 1
NameError: name 'n' is not defined

Les rapports d'erreur,
vous ne pouvez pas écrire une mathématique directement en tant que code, " n " doit être défini ou être affecté à une valeur.

In [8]: n = 3.14
In [9]: m = n**2 + 2*n + 1
In [10]: m
Out[10]: 17.1396

Il fonctionne maintenant,si vous insistez sur la combinaison des deux seperarte lignes à un.Il arrive lambda

In [13]: j = lambda i: i**2 + 2*i + 1
In [14]: j
Out[14]: <function __main__.<lambda>>

Pas d'erreurs signalées.

C'est un coup d'œil à lambda, il vous permet d'écrire une fonction en une ligne unique que vous ne vous en mathématique dans l'ordinateur directement.

Nous verrons plus tard.

Nous allons continuer à creuser plus profondément sur 'affectation'.

Comme illustré ci-dessus, le symbole égal = les œuvres de données simples(1 et 'valeur') le type et le simple expression(n**2 + 2*n + 1).

Essayez ceci:

In [15]: x = print('This is a x')
This is a x
In [16]: x
In [17]: x = input('Enter a x: ')
Enter a x: x

Il travaille pour de simples déclarations,il y a 11 types d'eux en python 7.De simples états — Python 3.6.3 documentation

Comment sur instruction composée,

In [18]: m = n**2 + 2*n + 1 if n > 0
SyntaxError: invalid syntax
#or
In [19]: m = n**2 + 2*n + 1, if n > 0
SyntaxError: invalid syntax

Il arrive def activer de travail

In [23]: def m(n):
    ...:     if n > 0:
    ...:         return n**2 + 2*n + 1
    ...:
In [24]: m(2)
Out[24]: 9

Tada, de les analyser, de " m " est le nom, 'n**2 + 2*n + 1 est valeur.: est une variante de '='.
Trouver, si juste pour comprendre, tout commence à partir de l'affectation et de tout ce qui est d'affectation.

Maintenant de retour à lambda, nous avons une fonction appelée 'm'

Essayez:

In [28]: m = m(3)
In [29]: m
Out[29]: 16

Il y a deux noms de 'm' ici, la fonction m a déjà un nom, dupliqué.

Elle est mise en forme comme:

In [27]: m = def m(n):
    ...:         if n > 0:
    ...:             return n**2 + 2*n + 1
    SyntaxError: invalid syntax

Ce n'est pas une stratégie intelligente, de sorte que les rapports d'erreur

Nous avons pour supprimer l'un d'entre eux,de définir une fonction sans nom.

m = lambda n:n**2 + 2*n + 1

Il est appelé "fonction anonyme'

En conclusion,

  1. lambda dans une fonction en ligne qui vous permet d'écrire une fonction dans une ligne droite comme dans les mathématiques
  2. lambda est anonyme

L'espoir, ce qui permet de.

C'est une fonction qui n'a pas de nom.Par exempleen c#, vous pouvez utiliser

numberCollection.GetMatchingItems<int>(number => number > 5);

pour retourner les nombres supérieurs à 5.

number => number > 5

est le lambda de la partie ici.Il représente une fonction qui prend un paramètre (nombre) et renvoie une valeur booléenne (nombre > 5).GetMatchingItems méthode utilise cette lambda sur tous les éléments de la collection et renvoie les éléments correspondants.

En Javascript, par exemple, les fonctions sont considérées comme le même type mixte comme tout le reste (int, string, float, bool).En tant que tel, vous pouvez créer des fonctions à la volée, de les affecter à des choses, et de les rappeler plus tard.Il est utile mais pas quelque chose que vous souhaitez utiliser ou vous allez confondre tous ceux qui ont à maintenir votre code après vous...

C'est un code que j'était en train de jouer avec pour voir quelle est la profondeur de ce trou de lapin va:

var x = new Object;
x.thingy = new Array();
x.thingy[0] = function(){ return function(){ return function(){ alert('index 0 pressed'); }; }; }
x.thingy[1] = function(){ return function(){ return function(){ alert('index 1 pressed'); }; }; }
x.thingy[2] = function(){ return function(){ return function(){ alert('index 2 pressed'); }; }; }

for(var i=0 ;i<3; i++)
    x.thingy[i]()()();

Dans le contexte de CS un lambda est une fonction mathématique abstrait concept qui s'attaque à un problème de la symbolique de l'évaluation des expressions mathématiques.Dans ce contexte, une fonction lambda est le même que pour un lambda terme.

Mais dans les langages de programmation, c'est quelque chose de différent.C'est un morceau de code qui est déclaré "en place", et qui peuvent être passés comme un "citoyen de première classe".Ce concept est apparu utile de sorte qu'il est entré dans presque tous les langages de programmation modernes (voir lambda fonctions de partout post).

Je l'ai eu aussi.Je l'ai essayé en JS avec celui-ci:

var addAndMult = function(x) {
        return (function(y) {
            return (function(z) {
                return (x+y)*z; 
                });
            });
        };

Il ajoute 2 à 4 multis le résultat par 6.Cependant, je trouve qu'il est parfois difficile à lire :(

Aussi j'ai fait une intéressante fonction forEach:

var forEach = function(arr) {
            return (function(x) {
            for (var i=0; arr[i]; i++) {
                 x(arr[i]);
             }
        });
    }

forEach([1,2,3,4,5])(de la console.journal);

Cette méthode va se répéter un tableau et effectue une action - dans le cas de l'impression à la console.Maintenant, je reçois trop pourquoi labmdas sont puissants.

En programmation informatique, lambda est un morceau de code (déclaration, d'une expression ou un groupe d'entre eux), ce qui prend quelques arguments à partir d'une source externe.Il ne doit pas toujours être une fonction anonyme - nous avons plusieurs façons de les mettre en œuvre.

Nous avons une séparation claire entre les expressions, les instructions et les fonctions, qui les mathématiciens n'ont pas.

Le mot "fonction" dans la programmation est également différente - nous avons de la fonction "est une série d'étapes à faire" (du Latin "exécuter").En mathématiques, c'est quelque chose sur la corrélation entre les variables.

Les langages fonctionnels sont en essayant d'être aussi semblables à des formules mathématiques que possible, et leurs paroles, dire presque la même chose.Mais dans d'autres langages de programmation, nous avons différents.

Un Lambda Function, ou un Small Anonymous Function, est lui-même un bloc de fonctionnalités qui peuvent être transmis et utilisé dans votre code.Lambda a différents noms dans différents langages de programmation – Lambda dans Python et Kotlin, Closure dans Swift, ou Block dans C et Objective-C.Bien que lambda sens est assez similaire pour ces langues, il a une légère distinctions parfois.

Nous allons voir comment Lambda (Fermeture) des œuvres de Swift 4.2 avec triés() la méthode de la fonction normale jusqu'à la plus courte de l'expression:

let coffee: [String] = ["Cappuccino", "Espresso", "Latte", "Ristretto"]

1.Fonction Normale

func backward(_ n1: String, _ n2: String) -> Bool {
    return n1 > n2
}
var reverseOrder = coffee.sorted(by: backward)


// RESULT: ["Ristretto", "Latte", "Espresso", "Cappuccino"]

2.Fermeture Expression

reverseOrder = coffee.sorted(by: { (n1: String, n2: String) -> Bool in
    return n1 > n2
})

3.Inline Fermeture Expression

reverseOrder = coffee.sorted(by: { (n1: String, n2: String) -> Bool in return n1 > n2 } )

4.L'Inférence De Type De Contexte

reverseOrder = coffee.sorted(by: { n1, n2 in return n1 > n2 } )

5.Rendement implicite de la Simple Expression des Fermetures

reverseOrder = coffee.sorted(by: { n1, n2 in n1 > n2 } )

6.Abréviation Noms D'Argument

reverseOrder = coffee.sorted(by: { $0 > $1 } )

// $0 and $1 are closure’s first and second String arguments.

7.Opérateur De Méthodes

reverseOrder = coffee.sorted(by: >)

// RESULT: ["Ristretto", "Latte", "Espresso", "Cappuccino"]

Espérons que cette aide.

La question a été répondu pleinement, je ne veux pas entrer dans les détails.Je souhaite partager l'utilisation lors de l'écriture du calcul numérique dans la rouille.

Il est un exemple d'un lambda(fonction anonyme)

let f = |x: f32| -> f32 { x * x - 2.0 };
let df = |x: f32| -> f32 { 2.0 * x };

Quand j'ai écrit un module de Newton–Raphson la méthode, il a été utilisé comme premier et du second ordre dérivés.(Si vous voulez savoir ce qu'est le Newton–Raphson la méthode, s'il vous plaît "https://en.wikipedia.org/wiki/Newton%27s_method".

La sortie comme suit

println!("f={:.6}      df={:.6}", f(10.0), df(10.0))

f=98.000000       df=20.000000

Imaginez que vous avez un restaurant avec une option de livraison et vous avez une commande qui doit être fait en moins de 30 minutes.Le point est que les clients ne se soucient pas si vous envoyez leur nourriture en vélo, en voiture ou à pieds nus, aussi longtemps que vous gardez le repas chaud et ligoté.Donc permet de convertir cet idiome de Javascript avec des anonymes et défini les fonctions de transport.

Ci-dessous, nous avons défini la manière de notre prestation de aka-on définir un nom pour une fonction:

// ES5 
var food = function withBike(kebap, coke) {
return (kebap + coke); 
};

Que si nous utilisons la flèche/lambda fonctions à accomplir ce transfert:

// ES6    
const food = (kebap, coke) => { return kebap + coke };

Vous voyez il n'y a pas de différence pour le client et pas de perte de temps à réfléchir à comment envoyer de la nourriture.Il suffit de lui envoyer.

Btw, je ne recommande pas le kebap avec de la coke c'est pourquoi supérieure codes de vous donner des erreurs.Avoir du plaisir.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top