Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

  1. #1
    Membre à l'essai
    Homme Profil pro
    Gestionnaire Infrastructures Matériel Logiciel
    Inscrit en
    décembre 2012
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Gestionnaire Infrastructures Matériel Logiciel
    Secteur : Santé

    Informations forums :
    Inscription : décembre 2012
    Messages : 9
    Points : 12
    Points
    12
    Par défaut Passer une fonction quelconque, dont le nombre de paramètres est variable, en paramètre d'une autre fonction
    Bonjour,

    je voudrais connaître l'implémentation Scala de ce morceau de code en Python
    C'est uniquement le passage en paramètre d'une fonction quelconque, elle-même constituée d'un nombre indéterminé de paramètres, qui m'intéresse.

    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    import time
    def timer(n, func, *pargs, **kargs):
       start = time.clock()
       for i in range(n):
          result = func(*pargs, **kargs)
       elapsed = time.clock() - start
    return (elapsed, result)

    Merci d'avance.

  2. #2
    Expert éminent

    Avatar de sjrd
    Homme Profil pro
    Directeur de projet
    Inscrit en
    juin 2004
    Messages
    4 516
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : Suisse

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Enseignement

    Informations forums :
    Inscription : juin 2004
    Messages : 4 516
    Points : 9 996
    Points
    9 996
    Par défaut
    Bonjour,

    Étant donnée la nature statiquement typée de Scala, en général on évite de manipuler des fonctions avec un nombre arbitraire de paramètres. Ça ne se prête généralement pas bien au langage. Au lieu de cela, dans ce cas spécifique, on va plutôt tabler sur le fait que Scala gère bien mieux les captures que Python, et donc on va simplement gérer le cas d'une fonction ne prenant aucun paramètre :

    Code scala : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    def timer[A](n: Int, f: () => A): (Long, A) = {
      val start = System.nanoTime()
      var result: A = null.asInstanceOf[A] // on arrangera ça plus tard
      for (_ <- 0 until n)
        result = f()
      val elapsed = System.nanoTime() - start
      (elapsed, result)
    }
    Note que l'usage d'une `var` ici n'est pas terrible (et c'est encore pire à cause du `null.asInstanceOf[A]`) donc on va réorganiser ça :
    Code scala : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    def timer[A](n: Int, f: () => A): (Long, A) = {
      assert(n > 0, "n must be strictly positive")
      val start = System.nanoTime()
      for (_ <- 0 until n-1)
        f()
      val result = f()
      val elapsed = System.nanoTime() - start
      (elapsed, result)
    }
    Maintenant, on peut appeler cette fonction avec :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    val (elapsed, result) = timer(5, { () =>
      uneFonction(avec, ses, parametres)
    })
    Remarque que les paramètres peuvent tout à fait se référer à des vals et vars déclarées en dehors de l'appel à `timer`. Ce qui veut dire que cette fonction gère tout à fait le passage d'un nombre arbitraire de paramètres à `uneFonction`. C'est juste qu'on les captures dans la fonction anonyme qui appelle en fait `uneFonction`. Perso je trouve ça nettement plus lisible que la version Python originale.

    On peut encore améliorer un peu l'API pour la rendre plus Scala-esque avec deux listes de paramètres, et un paramètre "by-name" :
    Code scala : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    def timer[A](n: Int)(f: => A): (Long, A) = {
      assert(n > 0, "n must be strictly positive")
      val start = System.nanoTime()
      for (_ <- 0 until n-1)
        f
      val result = f
      val elapsed = System.nanoTime() - start
      (elapsed, result)
    }
    À appeler comme suit :
    Code scala : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    val (elapsed, result) = timer(5) {
      uneFonction(avec, ses, parametres)
    }
    sjrd, ancien rédacteur/modérateur Delphi.
    Auteur de Scala.js, le compilateur de Scala vers JavaScript, et directeur exécutif du Scala Center à l'EPFL.
    Découvrez Mes tutoriels, ou mon logiciel phare FunLabyrinthe : un jeu de labyrinthe gratuit et personnalisable à l'infini avec des scripts Delphi-like.

  3. #3
    Membre à l'essai
    Homme Profil pro
    Gestionnaire Infrastructures Matériel Logiciel
    Inscrit en
    décembre 2012
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Gestionnaire Infrastructures Matériel Logiciel
    Secteur : Santé

    Informations forums :
    Inscription : décembre 2012
    Messages : 9
    Points : 12
    Points
    12
    Par défaut
    Quand on maîtrise ce dont on parle ...

    Merci sjrd


  4. #4
    Membre à l'essai
    Homme Profil pro
    Gestionnaire Infrastructures Matériel Logiciel
    Inscrit en
    décembre 2012
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Gestionnaire Infrastructures Matériel Logiciel
    Secteur : Santé

    Informations forums :
    Inscription : décembre 2012
    Messages : 9
    Points : 12
    Points
    12
    Par défaut
    Au fait sjrd !

    Quelques mots subtilement distillés dans les explications apportées mériteraient pour moi un petit développement supplémentaire :

    "Scala gère bien mieux les captures que Python"

    Je n'ai pas tout de suite saisi la portée de cette affirmation somme toute si anodine au premier abord.
    Serait-il possible d'avoir un soupçon d'explication (voire plus) ?
    Cela m'intéresse réellement.

    Merci par avance.

    Alain

  5. #5
    Expert éminent

    Avatar de sjrd
    Homme Profil pro
    Directeur de projet
    Inscrit en
    juin 2004
    Messages
    4 516
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : Suisse

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Enseignement

    Informations forums :
    Inscription : juin 2004
    Messages : 4 516
    Points : 9 996
    Points
    9 996
    Par défaut
    Oui en fait ce n'est pas tellement que scala gère ça mieux, mais plutôt que Python a quelques surprises liées aux closures à cause de sa combinaison de 1. déclaration implicite de variables locales et 2. captures des variables muables.

    Une bonne explication peut être trouvée ici (en anglais) :
    http://eev.ee/blog/2011/04/24/gotcha...ping-closures/
    sjrd, ancien rédacteur/modérateur Delphi.
    Auteur de Scala.js, le compilateur de Scala vers JavaScript, et directeur exécutif du Scala Center à l'EPFL.
    Découvrez Mes tutoriels, ou mon logiciel phare FunLabyrinthe : un jeu de labyrinthe gratuit et personnalisable à l'infini avec des scripts Delphi-like.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [XL-2007] assembler des fichiers dont le nombre de colonne est de 7
    Par Ben1988 dans le forum Macros et VBA Excel
    Réponses: 5
    Dernier message: 07/08/2015, 17h42
  2. [XL-2000] Gérer un tableau dont le nombre de dimensions est variable
    Par jax54000 dans le forum Macros et VBA Excel
    Réponses: 0
    Dernier message: 11/11/2011, 09h10
  3. Réponses: 7
    Dernier message: 14/05/2009, 17h22
  4. Réponses: 3
    Dernier message: 18/09/2007, 11h27
  5. Réponses: 2
    Dernier message: 10/07/2007, 10h28

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo