France IOI : qui êtes vous et où en êtes vous ?

C'est plutôt ça oui. France-ioi ne cesse d'être réformé pour être de plus en plus simple, dans le but que les gens soient de plus en plus mauvais (indeed).

Troll à part, il n'y a encore pas si longtemps on pouvait accéder à la première section du site (en bidouillant idChapter), où il y avait 10 exos dont la difficulté passait très vite à un niveau IOI (de l'époque).
Le bon vieux temps où les comptes avec pseudo=mot de passe=une lettre étaient abondants...

En utilisant Java c'est étonnant que tu aies passé un test... On avait pas un détecteur de langage merdique sur ce site ?

J'allais le dire.

C'est un peu con d'essayer de passer les tests avec Java.

C'est pas encore aussi horrible que PHP, mais pas loin.

Un peu des deux.

A priori Java n'est pas vraiment mauvais en soi (on lui reproche plein de trucs mais pas vraiment plus qu'aux autres langages qui marchent bien). C'est juste que Java ne doit pas être du tout adapté pour résoudre des problèmes sur ce genre de sites, à la base il n'a pas été créé pour ça.

Ah, je vois que je ne suis pas le seul à penser ça.

Quels sont vos arguments à
l'encontre de ce langage ?

Personnellement j'en ai pas énormément (je ne le connais pas assez) mais j'ai été dégoûté rien que par les entrées-sortie (surtout les entrées d'ailleurs, pareille mocheté est plutôt rare).

Sachant que le Java reprend une partie de la syntaxe du C (et C++), je ne vais pas critiquer le language en soi...
Non en gros son défaut c'est qu'il est... LENT... Le fait que ce ne soit pas un langage compilé peut être désavantageux pour résoudre des problèmes d'algorithmique où le but est d'être rapide. (Mais c'est quand même cool de faire des applications portables)

Bah, venant du C++, je ne peux que déplorer :

Pas de généricité

1
2
3
4
    ArrayList<Integer> li = new ArrayList<Integer>();
    ArrayList<Float> lf = new ArrayList<Float>();
    if (li.getClass() == lf.getClass())
        System.out.println("Equal");

Oui… ce code affiche Equal.

Mais du coup…

1
2
    void method(Parameterized_type<Type_a> x){}
    void method(Parameterized_type<Type_b> x){}

Ne compile pas :

1
2
3
    error: name clash: method(Parameterized_type<Type_b>) and method(Parameterized_type<Type_a>) have the same erasure
    void method(Parameterized_type<Type_b> x);
         ^

Ridicule. Le pire c'est quand on essaye d'écrire la méthode equals d'un type paramétré. Ou simplement un « new Type_paramètre » (oui, cela aussi ça ne compile pas).

Typage
Codons :

1
2
    short a=1, b=1;
    short c = a + b;

Compilons :

1
2
3
4
5
    error: possible loss of precision
    short c = a + b;
                ^
      required: short
      found:   int

Normal dirons les Javaistes, c'est parce que Java permet de coder bien et secure, il pourrait y avoir un overflow… Remplaçons short par int :

1
2
    int a=1, b=1;
    int c = a + b;

Ça compile… oh bah ça alors, il ne nous sort plus un « possible loss of precision » ? inconsistant ? oui, oui.

Si vous pensez vraiment que le programmeur est stupide et ne pense à rien, codez en Ada : « type A is range 0..5; ».

Gestion des ressources
Il y a une seule ressource qui est gérée automatiquement en Java, c'est la mémoire. Et c'est tellement mal fait…
Beaucoup de “développeur” (terme approximatif) croient qu'il faut gérer la mémoire en C++ et pas en Java et donc Java est bien puisqu'il y a une chose de moins à faire.
Déjà, en Java on n'a pas à gérer la mémoire… mais le gros problème c'est qu'on ne le peut même pas, vous avez un mem leak dans votre programme, bah tant pis pour vous (il y a des langages avec GC qui sont très bien et qui permettent entre autre de libérer un chunk donné, ce n'est pas le cas de Java).
Le problème, c'est que non on ne gère pas la mémoire en C++ et mieux… on ne gère aucune ressource. En C++ on a une merveilleuse chose : le SBRM.
En Java par contre…

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
    void method(String path){
        File f = new File;
        f.open(path);
    
        // [traitement utilisant f…]
        if(traitement_fini){
            f.close();
            return resultat;
        }
    
        // [traitement utilisant f…]
        try{
            // [traitement utilisant f…]
        } catch(MyFuckingException){
            f.close();
            return erreur;
        }
        // [traitement utilisant f…]
        f.close();
        return resultat;
    }

Il faut s'occuper de tout…

Et ce n'est pas fini…
Je ne parlerais pas de l'héritage multiple, de la pseudo-portabilité, de la pseudo-facilité à programmer, de l'horreur de l'OOP et surtout pas des performances.
Mais sérieusement, citez un gros logiciel largement utilisé codé en Java qui n'est pas de Sun/Oracle.

1
2
3
             +-----------+
roket reçoit | 1 point ! |
             +-----------+

/me n'a jamais joué à Minecraft.

Epsilon, je ne veux pas te contredire, mais c++ fait pareil que java sur au moins un point : le typage. Exemple en direct :

1
2
3
4
#include <iostream>
int main() {
   short a = 1;
   short b = a    std::cout }

(Strange le besoin de mettre < pour un

1
2
3
tmp$ g++ -Wconversion a.cpp 
a.cpp: In function 'int main()':
a.cpp:4:19: warning: conversion to 'short int' from 'int' may alter its value [-Wconversion]

(Oui, certaines personnes ont une liste de toutes les options de warning et les activent toutes dans leur Makefile / autre ; et j'ai découvert ça avec un projet qui était légèrement plus complexe ... Tu devines mon étonnement !)

  • généricité/introspection

CAMP ? (Jamais utilisé, j'ai toujours trouvé l'introspection inutile.)
Et qu'appelles-tu généricité ?

  • mémoire/fichiers

En c++ ?
Exactement le même exemple, traduit :
std::ifstream f(path);

// [traitement utilisant f…]
if(traitement_fini){
return resultat;
}

// [traitement utilisant f…]
try{
// [traitement utilisant f…]
} catch(MyFuckingException){
return erreur;
}
// [traitement utilisant f…]
return resultat;

Difficile de faire plus simple. Non ?

J'suis pas particulièrement fan de Java, loin de là, j'suis d'accord avec la plupart de ce que tu as dit. Mais tu peux pas dire que Java est très minoritaire.
Java est extrèmement utilisé pour des logiciels internes en entreprise par exemple.

Après le C ou C++ et le Java ne sont pas utilisés dans les mêmes buts.

mer, 23/05/2012 - 12:42 — Ekleog

> Epsilon, je ne veux pas te contredire, mais c++ fait pareil que java
> sur au moins un point : le typage. Exemple en direct :
>
> #include \<iostream>
> int main() {
>   short a = 1;
>   short b = a \<\< 1;
>   std::cout \<\< b;
> }
> (Strange le besoin de mettre < pour un \< dans une balise
> code ...)
>
> tmp\$ g++ -Wconversion a.cpp
> a.cpp: In function 'int main()':
> a.cpp:4:19: warning: conversion to 'short int' from 'int' may alter
> its value [-Wconversion]
>
> (Oui, certaines personnes ont une liste de toutes les options de
> warning et les activent toutes dans leur Makefile / autre ; et j'ai
> découvert ça avec un projet qui était légèrement plus complexe ... Tu
> devines mon étonnement !)
gcc te propose (c'est une option hein) de te sortir un warning si une telle conversion apparait, ce n'est en aucun cas standard :

n3290 4.7 [conv.integral]

§1 A prvalue of an integer type can be converted to a prvalue of another integer type. A prvalue of an unscoped enumeration type can be converted to a prvalue of an integer type.
§3 If the destination type is signed, the value is unchanged if it can be represented in the destination type (and bit-field width); otherwise, the value is implementation-defined.
En java, c'est une erreur.

Il y a juste un cas où C++ est un peu piquant sur les types c'est avez les initializer lists, mais en même temps c'est obligatoire pour pouvoir déterminer son type.

mer, 23/05/2012 - 16:49 — Shloub

> - généricité/introspection
>
> Il y a de l'introspection en C++ ? (C'est pas ce que j'ai lu dans
> l'article https://sites.google.com/site/steveyegge2/tour-de-babel)
En effet, Java permet l'introspection alors qu'en C++ ce n'est qu'un proposal ou il faut passer par des moc.
Je parlais de la programmation générique, Java implémente les generics en utilisant le type erasure, c'est à dire que en fait, Java ne supporte pas vraiment la programmation générique. Après ça dépend ce que tu appelles généricité, certains dirons que « void f(int){} int main(void){ f(4.2); } » c'est de la programmation générique en C à cause de l'implicit cast double -> int.

Dans le même domaine, C++ permet de faire de la metaprogrammation, pas Java (pas de la même manière pour être précis). À ce sujet, je conseille aux programmeurs C++ de regarder : Metaparse: Compile-time parsing with template metaprogramming qui permet de construire et d'utiliser un parseur au compile time avec des string literals et définir ainsi des DSL simplement… au compile time. Simplement WTF.

mer, 23/05/2012 - 16:49 — Shloub

> - typage/short
>
> Je suis pas sûr que short soit fait pour ce type d'opérations, assez
> subjectif, certes.
Le problème c'est que ce n'est pas consistant. Et short est fait pour rien en Java, sérieusement Java se veut orienté objet et ils ont des “types primitifs” et des arrays…

mer, 23/05/2012 - 16:49 — Shloub

> - mémoire/fichiers
>
> Finally ? Sinon ce serait comment en C++ ?
Tu fais un bloc try/finally sur toute ta fonction ? Une chose très belle à n'en pas douter. Dans tout les cas il faut le faire (et c'est pas aussi simple que d'écrire juste « finally », tu peux vouloir relancer la même exception selon quelle instruction l'a causé), en C++ le fichier est fermé dans le destructeur qui est appelé à la fin du scope (SBRM = Scope Bound Ressource Management), on fait pareil avec la mémoire. C.f. le code écrit par Ekleog.

mer, 23/05/2012 - 16:49 — Shloub

> - gros logiciel
>
> La surcouche Android ? SAP & co ?
Je vais arrêter avec les logiciels parce qu'apparemment je suis le seul à ne pas utiliser Java. Je pense tout de même que ça reste très minoritaire par rapport à C ou C++ (et ceux citant le pseudo-index tiobe devraient regarder comment il est calculé et en rire).

Répondre au sujet

Vous devez vous enregistrer ou vous connecter pour poster des messages.