Feng,Clarté intégrée

Feng aide les développeurs et l’IA à écrire du code clair, fiable et facile à maintenir

  • Adapté à l’IA
  • Contrats explicites
  • Typage statique
  • Mémoire gérée
  • Compilé
  • Multiplateforme

Installation rapide

Copiez la commande et exécutez-la dans votre terminal

curl -fsSL https://feng-lang.com/install.sh | bash
module app;

import std.io;

// main est l’unique point d’entrée d’un programme exécutable
func main(args: string[]) {
  println("Hello, world!");
  println("你好,世界!");
  println("¡Hola, mundo!");
  println("Olá, mundo!");
  println("こんにちは、世界!");
  println("Привет, мир!");
  println("Hallo, Welt!");
  println("Bonjour le monde !");
}
module app;

// type regroupe les données et le comportement dans un type statique
type User {
  // les champs let sont en lecture seule ; les champs var peuvent être modifiés
  let name: string;
  let email: string;
  var active: bool;

  // Les méthodes accèdent à l’instance courante via self
  func greeting(): string {
    return "Bonjour, " + self.name;
  }
}
module app;

// Un contrat d’objet déclare le comportement requis
spec Named {
  func name(): string;
}

spec Persistable {
  func save(): void;
}

// Un contrat de fonction déclare la signature complète d’une valeur appelable
spec Formatter(value: string): string;

// Un contrat d’union accepte les valeurs de plusieurs types possibles
spec Identifier: int | string;

// Un contrat d’intersection exige tous les contrats membres
spec Entity: Named & Persistable;

type User {
  let username: string;
}

// fit satisfait les contrats d’objet sans modifier la déclaration du type
fit User: Named, Persistable {
  func name(): string {
    return self.username;
  }

  func save(): void {
  }
}
module app;

import std.io;

// T rend la logique réutilisable tout en conservant le typage statique
func identity<T>(value: T): T {
  return value;
}

func main(args: string[]) {
  let language = identity("Feng");
  println("Bonjour, {0} !", language);
}
module app;

func calculate_total(): int {
  var total = 0;

  // Une boucle for en trois parties convient à une plage de comptage définie
  for var i = 1; i <= 3; i += 1 {
    total += i;
  }

  // for/in parcourt les éléments du tableau dans l’ordre
  let values = [4, 5, 6];
  for let value in values {
    total += value;
  }

  // while vérifie de nouveau sa condition avant chaque itération
  var remaining = 2;
  while remaining > 0 {
    total += remaining;
    remaining -= 1;
  }
  return total;
}
module app;

func evaluate(score: int): string {
  var status = "";

  // Une instruction if/else effectue des actions différentes selon la condition
  if score >= 60 {
    status = "Réussi";
  } else {
    status = "Échec";
  }

  // Une expression if produit directement une valeur à lier
  let level = if score >= 90 {
    "Excellent"
  } else if score >= 60 {
    "Admis"
  } else {
    "À améliorer"
  };
  return status + ": " + level;
}
module app;

func describe(code: int): string {
  var detail = "";

  // Une instruction match exécute la première branche correspondante
  match code {
    200 { detail = "Requête réussie"; }
    404 { detail = "Ressource introuvable"; }
    else { detail = "État inconnu"; }
  }

  // Une expression match renvoie la valeur de la branche correspondante
  let category = match code {
    200...299 { "Succès" }
    400...499 { "Erreur client" }
    else { "Autre" }
  };
  return category + ": " + detail;
}
module app;

import std.io;

func require_port(port: int): int {
  if port <= 0 {
    // throw termine le chemin courant et transmet une exception à l’appelant
    throw "Le port doit être positif";
  }
  return port;
}

func main(args: string[]) {
  // La forme instruction effectue des actions lors du traitement d’une exception
  try require_port(-1) catch error: string {
    println(error);
  };

  // La forme expression peut fournir une valeur de repli en cas d’exception
  let port = try require_port(-1) catch error: string {
    println(error);
    3000
  };
  println("Port utilisé : {0}", port);
}