[JAVA] Poney et fermeture de capacité de référence

Qu'est-ce que Pony

Connaissez-vous la langue Pony? En termes simples, il s'agit d'un "langage orienté objet de type statique qui peut effectuer un traitement parallèle et parallèle à l'aide du modèle Actor". De plus, il s'agit d'un langage appelé ** capabilities-secure ** qui possède de nombreuses fonctions pour détecter non seulement les types mais également les erreurs liées au traitement parallèle au moment de la compilation. Parmi eux, je voudrais présenter brièvement la ** capacité de référence **, qui est un concept rudimentaire, par la clôture.

Compteur utilisant une fermeture

Une contre-implémentation souvent citée comme exemple de fermeture. Je l'ai implémenté en plusieurs langues pour faciliter la compréhension de la puissance de la capacité de référence de Pony.

On suppose que les résultats suivants seront générés pour les deux langues.

1
2
3
4
5
6
7
8
9
10

JavaScript

const createCounter = () => {
    let count = 0;

    return () => {
        count += 1;
        return count;
    }
}

const counter = createCounter();

Array.from({length: 10}, () =>
    console.log(counter())
)

Java

import java.util.function.*;
import java.util.stream.IntStream;

public class Counter {
    public static void main(String ...args) {
        final Supplier<IntSupplier> createCounter = () -> {
            //Puisque count est final, la valeur est réécrite à l'aide d'un tableau.
            final Integer[] count = {0};

            return () -> {
                count[0]++;
                return count[0];
            };
        };

        IntSupplier counter = createCounter.get();
        IntStream.rangeClosed(1, 10).forEach(i -> {
            System.out.println(counter.getAsInt());
        });
    }
}

Scala

object Counter extends App {
  val createCounter = () => {
    var count = 0

    () => {
      count += 1
      count
    }
  }

  val counter = createCounter()

  (1 to 10).foreach { _ =>
    println(counter())
  }
}

L'implémentation par JavaScript et Scala est similaire dans son concept. Ce qui est similaire, c'est qu'une fonction anonyme peut prendre une variable libre, devenir une fermeture et réécrire la valeur de la variable libre.

D'un autre côté, Java ne peut importer que des variables (* 1) déclarées avec `` final '' comme variables libres, donc importer des objets mutables tels que des tableaux au lieu de valeurs primitives et réécrire la destination de référence. Vous ne pouvez modifier la valeur qu'avec. Il s'agit d'un comportement sûr et correct pour une fermeture, mais il peut être difficile en termes de commodité et de lisibilité.

Comptoir par poney

Alors, quelle approche Pony prend-il pour résoudre les problèmes de langue énumérés ci-dessus? Notez la variable count '' qui apparaît dans le code. Par défaut, Pony ne peut pas réécrire la valeur d'une variable libre extraite de l'expression lambda. À cet égard, il se comporte comme Java. Si vous souhaitez réécrire la valeur d'une variable, ajoutez le mot-clé ref '' à l'expression lambda. Cela permet à l'expression lambda elle-même de réécrire les variables à l'intérieur. De plus, `` count``` reste à 0, sauf pour les expressions lambda mettant à jour `count```. Si vous voulez vraiment le mettre à jour, vous avez besoin d'une approche telle que le placer dans un tableau comme Java, mais il semble qu'il y ait peu de cas de ce type, vous pouvez donc écrire du code très sûr.

use "collections"

actor Main
  new create(env:Env) =>
    let createCounter = {(): {ref(): U32} => 
      var count = U32(0)
      
      //En utilisant le mot-clé ref, il est possible de réécrire la valeur de count.
      {ref()(count): U32 => 
          count = count + 1
          count
      }
    }
    
    let counter = createCounter()
    
    for i in Range[U32](0,10) do
      env.out.print(counter().string())
    end

refSi vous compilez avec les mots-clés supprimés, vous obtiendrez l'erreur suivante: C'est très facile à comprendre.

Error:
main.pony:9:17: cannot write to a field in a box function. If you are trying to change state in a function use fun ref
          count = count + 1

Résumé

C'est un exemple très simple, mais est-ce que la puissance du code ** sécurisé par les capacités ** s'est manifestée par la fermeture? Je pense qu'il est intéressant de pouvoir écrire du code en toute sécurité en changeant de mode, plutôt que d'unifier si la réécriture est possible ou impossible en fonction des spécifications du langage. Ce n'est qu'une partie de l'attrait ** de Pony sécurisé **. Entrons en contact avec le charme de Pony ensemble!

Supplément

Recommended Posts

Poney et fermeture de capacité de référence
Type de données de base et type de référence
Types de données de base et types de référence (Java)
Mécanisme de référence Java (pile et tas)
[PHP] Patrons d'héritage, protégés et de référence
Java passe par valeur et passe par référence
Différence entre le type primitif et le type de référence
A propos des types primitifs et des types de référence Java
Types de données de base et types de référence Java