10
votes

Scala factoriel sur grand nombre se bloque parfois et parfois pas

Le programme suivant a été compilé et testé, il renvoie parfois le résultat et remplit parfois l'écran avec xxx

le programme: xxx

Mes questions:

  • est-ce parce qu'il y a un débordement de pile sur la JVM, ce qui arrive parfois et parfois pas?
  • est ce comportement non déterministe considéré comme un bug?
  • Je suppose que Scala n'a pas retrouvé la queue de la queue? Comment puis-je le faire de la queue-recueille ceci?

    Détails:

    Scala Compiler Version 2.7.5.finale - Copyright 2002-2009, Lampe / Scala EPFL Code Runner version 2.7.5.final - Copyright 2002-2009, Lampe / EPFL

    Version Java "1.6.0_0" openjdk Environnement d'exécution (construction 1.6.0_0-B11) OpenJDK Client VM (version 1.6.0_0-B11, mode mixte, partage)

    Ubuntu 2.6.24-24-générique


4 commentaires

Qu'entendez-vous par «ne pouvait pas voir la première ligne de cela»? Pouvez-vous piper la sortie dans un fichier?


@msiemeri, étrangement lorsque je "Scala Bigint> Fichier" ne fonctionne que lorsque le programme n'écrase pas.


Avez-vous essayé "Scala Bigint> Fichier 2> & 1" aussi? Avec 2> & 1, il redirige la sortie de STDRER à l'évier stdout (qui est dans ce cas, «fichier»).


Merci @MSIEMERI, édité la partie d'erreur.


3 Réponses :


13
votes

L'optimisation des appels de queue ne fonctionnera que dans scala si l'appel récursif est la dernière instruction dans la fonction. C'est très limité. Le livre Scala dit:

[...] l'optimisation des appels de queue est limité à des situations dans lesquelles un la méthode ou la fonction imbriquée s'appelle elle-même directement comme sa dernière opération, Sans traverser une valeur de fonction ou un autre intermédiaire.

Dans votre cas, l'appel récursif fait partie d'une expression plus grande et n'est pas elle-même la dernière opération - la dernière opération ici est la multiplication.

Cet article montre comment le faire fonctionner: < Pré> xxx


3 commentaires

Je ne suis pas sûr que je comprenne, imprimée ne fait pas partie de la fonction factorielle ou n'est-ce pas?


Vous avez raison, j'ai mal interprété votre code (j'ai reformaté cela pour le rendre un peu plus clair et je mettrai à jour ma réponse).


Cela a fonctionné, bien fait, également merci pour le lien avec le grand article sur le sujet.



7
votes

dans SCALAA 2.8 Vous pouvez utiliser l'annotation @TataileRec lorsque vous vous attendez à ce que l'optimisation de l'appel de la queue soit utilisée et obtenez un avertissement s'il n'est pas possible pour le compilateur de le faire.


1 commentaires

Merci, as-tu utilisé? Je ne suis pas sûr qu'il ait encore été libéré. scala-lang.org/downloads