Stab : un langage pour découvrir C# quand on ne connait que java
Par Oaz » 20 décembre 2011, 14:01 - En français
Ce billet est issu de la concomitance de deux évènements :
- je me pose la question "comment peut-on écrire quelque chose proche de C# mais qui tourne avec une JVM ?" et je découvre le langage "stab"
- je lis ce billet "Sélection FooBarQix" où un même programme a été implémenté dans 13 langages différents ayant pour seul point commun la JVM.
Il ne m'en a pas fallu plus pour écrire un FooBarQix en stab.
Et je crois que ce programme a un intérêt pour montrer ce que l'on peut écrire quand on rajoute quelques éléments basiques de C# 3 à java 6.
Le code complet est dispo sur github.
J'ai fait au plus simple avec seulement deux fichiers.
Un fichier de tests qui utilise junit :
using java.lang;
using junit.framework;
public class TestFooBarQix : TestCase
{
delegate void Action<T1,T2>(T1 t1, T2 t2);
public void testFBQ()
{
Action<Integer,String> check = (src,dst) => { assertEquals(src+" => "+dst, dst, FooBarQix.from(src)); };
check(1,"1");
check(2,"2");
check(3,"FooFoo");
check(4,"4");
check(5,"BarBar");
check(6,"Foo");
check(8,"8");
check(9,"Foo");
check(10,"Bar");
check(11,"11");
check(12,"Foo");
check(13,"Foo");
check(15,"FooBarBar");
check(7,"QixQix");
check(14,"Qix");
check(16,"16");
check(17,"Qix");
check(18,"Foo");
check(19,"19");
check(20,"Bar");
check(21,"FooQix");
}
}
Et un fichier de code qui tire profit de quatre éléments majeurs de C# :
- les lambda expressions
- les générateurs
- les types anonymes
- LINQ (qui n'est presque rien de plus que la résultante des éléments précédents)
using java.lang;
using stab.query;
public static class FooBarQix
{
public static String from(Integer numberToConvert)
{
var fbqDigits = sequence(
new { Value=3, Text="Foo" },
new { Value=5, Text="Bar" },
new { Value=7, Text="Qix" }
);
Predicate<Integer> isNumberToConvertDivisibleBy = n => (numberToConvert % n == 0);
var divisors = fbqDigits.where(x => isNumberToConvertDivisibleBy(x.Value));
var digitsReplacement=digitsLeftToRight(numberToConvert).selectMany(digit => fbqDigits.where(x => x.Value==digit));
var fbqConversions = divisors.concat(digitsReplacement);
if( fbqConversions.count() == 0 )
return Integer.toString(numberToConvert);
else
return fbqConversions.select(x => x.Text).aggregate((a,b)=>a+b);
}
static Iterable<Integer> digitsLeftToRight(Integer number)
{
return digitsRightToLeft(number).reverse();
}
static Iterable<Integer> digitsRightToLeft(Integer number)
{
while(number != 0)
{
yield return number % 10;
number = number / 10;
}
}
delegate Boolean Predicate<T>(T t);
static Iterable<T> sequence<T>(params T[] items)
{
return Query.asIterable(items);
}
}


Commentaires / Comments