Le blog à Fred

Aller au contenu | Aller au menu | Aller à la recherche

mercredi 10 février 2016

Why you should define your own types

Most of the people coming here know that I'm an Ada enthusiast.
In my job, I'm mostly developing in Java and one of the remarks I got in the past about Ada type system is that it's useless.
A lot of developers are arguing that they never have bugs due to a type error. So, the use of range constraints and so on in Ada are almost seen as useless verbosity.
For once, I've another point of view about this feature and it's not related to bugs but to maintainability.

The reason

It's not really a secret that I'm working on cartographic products. Our product is written in Java and we use OpenMap for displaying some kind of maps.
Few weeks ago, we found that the old version of OpenMap we were using contained a bug about a specific raster format. After looking into the new source code[1], I found that the bug was still there.
One of my colleague fixed it and provided a patch to the project. Then I decided to test the patch on the brand new version of OpenMap by migrating to the last version.

The problem

Migrating is not always as simple as it might seem.
Between the two versions, 4.6.5 and 5.1.13, there has been a lot of changes that were easily detected by the compiler but the main one only seemed to be a package name change.
The LatLonPoint class was in the past inside the package com.bbn.openmap and changed to com.bbn.openmap.proj.coords.
Ok, that's easy but if I show you the beginning of the code, you will see.

/*
* For version 4.6.5
*
*/
public class LatLonPoint implements Cloneable, Serializable {
    // SOUTH_POLE <= phi <= NORTH_POLE
    // -DATELINE <= lambda <= DATELINE
    public final static float NORTH_POLE = 90.0f;
    public final static float SOUTH_POLE = -NORTH_POLE;
    public final static float DATELINE = 180.0f;
    public final static float LON_RANGE = 360.0f;
    // initialize to something sane
    protected float lat_ = 0.0f;
    protected float lon_ = 0.0f;
 
    public final static float EQUIVALENT_TOLERANCE = 0.00001f;

And the newest one

/*
* For version 5.1.13
*
*/
public abstract class LatLonPoint extends Point2D implements Cloneable, Serializable {
 
    /**
     * 
     */
    private static final long serialVersionUID = 4416029542303298672L;
    public final static double NORTH_POLE = 90.0;
    public final static double SOUTH_POLE = -NORTH_POLE;
    public final static double DATELINE = 180.0;
    public final static double LON_RANGE = 360.0;


Do you see ?
First of all, the class is now abstract... You can imagine what happened in my code as this class is really centric :)
So how do you create LatLonPoint ?
Inside the LatLonPoint, you have two inner classes defined as follows

public static class Float extends LatLonPoint {
 
        /**
         * 
         */
        private static final long serialVersionUID = -2447464428275551182L;
        protected float lat;
        protected float lon;
        protected transient float radLat;
        protected transient float radLon;
 
[...]
 
/**
     * Double precision version of LatLonPoint.
     * 
     * @author dietrick
     */
    public static class Double extends LatLonPoint {
        /**
         * 
         */
        private static final long serialVersionUID = -7463055211717523471L;
 
        protected double lat;
        protected double lon;
        protected transient double radLat;
        protected transient double radLon;

This was done to mimic the Point2D class but everywhere I instanciated a LatLonPoint, I now need to choose between Float or Double version.
Ok but what happens if I prefer to keep the higher abstract view ?
Well, for getting latitude in degrees the type returned is float whereas for radians, it's double.
Mixing such kind of types creates a mess inside our application because everything was float in the past.

The Ada solution

First try

A first solution might be to declare types for latitude, longitude and radians.

type Latitude is digits 10 range -90.0 .. 90.0;
type Longitude is digits 11 range -180.0 .. 180.0; -- for 7 digits after dot
type radian is digits 15 range -2*π .. 2*π; -- with π from Ada.numerics
 
type LatLonPoint is private; -- which should define the way we store the coordinates

The problem is that the client code don't have any way to change the precision the same way Java more or less allows it.
It's time to extend the functionalities with generics.

Second try

It would be better for the client code to define the precision.
Here is one solution... But I'm sure there's something clever than this[2]

generic 
	type real is digits <>;
package coords is
   type latitude is new real range -90.0 .. 90.0;
   type longitude is new real range -180.0 .. 180.0;
   type radian is new real range -2*π .. 2*π; -- with π from Ada.numerics
 
type LatLonPoint is private; -- Using the types defined above
end coords;


You should wonder why not using Real types directly. First, because I want the compiler to check as much as possible.
Second, because I don't need the precision of a Java double.
Let me explain :
With 7 digits after the dot for a latitude in decimal degrees, two latitudes in my code will be distant at equator level from 1 centimetre.

Conclusion

By providing the precision on the client side through a generic unit, it is possible to avoid the types mixing we had with the Java version while keeping type safety.
Changing precision is a client decision and not a implementer one. This way, the compilation problem[3] can be avoided.

Notes

[1] Open source is really great for this

[2] Maybe because I wrote it after drinking wine with another Ada enthusiast :D

[3] Around 1500 compilation errors in my software

vendredi 19 avril 2013

Balancing bullshits

After spreading bullshits, our Bullshit Company has been overflown by bullshit requests.
It's time to provide a bigger architecture than the one we used. Let's balance the Bullshit Generator.

For the impatients, this post will deal with several problems that a beginner could encounter or fear : exceptions handling and sequences

Lire la suite...

mardi 4 septembre 2012

Et qu'on n'en parle plus !!

Encore un billet excellent sur Subversion et l'utilisation au jour le jour que je suis amené à en faire.
Bon, en gros, pour que vous sachiez si vous devez lire la suite, ça traite des ajouts automatiques faits par les greffons Subversion d'Eclipse.

Lire la suite...

mardi 6 septembre 2011

It's Java time !

My friend ''Vibi'', after sleeping only few hours for the the last 48 hours, came in my office this afternoon to submit me his misunterstanding about the behaviour of the Java class SimpleDateFormat.
By just telling me his code, he finally found his somehow funny mistake... but this mistake describe a totally undocumented behaviour :D

Lire la suite...

lundi 5 septembre 2011

Le temps de la Java

Mon ami ''Vibi'', ayant peu dormi ces dernières 48 heures, est venu cet après-midi me soumettre une incompréhension du comportement de la classe SimpleDateFormat de Java.
Il lui a suffi de me dicter son code pour se rendre compte de l'erreur qui, finalement, est assez cocasse et décrit un comportement totalement non documenté :D

Lire la suite...

mardi 6 juillet 2010

XML et mon CV

Je me suis toujours posé la question en lisant certains CV de la présence d'XML dans la rubrique Langages de développement.
En effet, quand on y regarde de plus près, c'est surtout un langage de balises comme HTML. Certes, on nous fait croire depuis les débuts d'Internet que l'on peut être développeur Web en codant uniquement en HTML et en faisant de belles pages... Ce qui a permis à tout un chacun de s'auto-proclamer développeur, au grand dam des Véritables.
Tout ça, c'est ce que je croyais jusqu'à mon entrée fracassante dans le développement de Web-Services en Java. Et oui, ma vie vient de basculer !!
Moi qui appréciait les compilations de plusieurs dizaines de minutes, le typage et la gestion des flux de données, la grammaire précise et stricte des langages classiques, je suis tombé de haut.
Et oui !! Tout ça, ça ne vaut plus rien ! Aujourd'hui, on décrit ses données et ses traitements dans un banal fichier texte[1], tout ça grâce à BPEL.
Mes amis, la Révolution est en marche, c'est beau, c'est grand, c'est In.

Bon, si je vous dis qu'en programmant comme ça, vous ne disposez pas de débuggeur, pas de compilation[2], tout est high level. Vous allez être heureux avec une techno comme ça, mes chéris... Jusqu'à la première merde. Parce qu'à ce moment-là, se repalucher ce que fait un compilateur ou un lieur, c'est pas franchement la panacée.
Et oui, ces deux outils avaient le bon goût de vérifier que vous ne vous étiez pas trompé dans les noms de fonctions, de variables, dans les types... Là, c'est à la warrior, on code, on déploie, ça merde et on recommence

J'ai peur de passer pour un rétrograde mais pour avoir passé trois jours sur un problème de ce type, je dois bien avouer que là, ça me prend la tête.
Le point positif, c'est que le boulot de développeur est pas prêt de disparaitre avec une telle charge de travail.

Notes

[1] Même si d'autres techno comme IDL le faisaient déjà pour des raisons d'intéropérabilité

[2] Plus besoin de tout ça, c'est pour les dinos

lundi 29 septembre 2008

Les lignes de code, les lignes de code... Ils n'ont que ça à la bouche

Vendredi dernier, grande relance du chef sur le nombre de lignes de code du projet.
Off course avec mon acolyte Marcello[1], nous avons recommencé à expliquer le pourquoi du le nombre de lignes de code, c'est mal et ça mesure pas combien on gland... Travaille dur.
Et là, quasi-éclair de quasi-génie !!!
Vous ai-je déjà dit que j'étais aussi le grand Manitou du serveur Subversion ?
Oui, je l'ai fait ? Bon, bah, je le redis :

Je suis le grand Manitou Subversion dans mon boulot... Enfin, dans mon département... Bon, okay, dans ma salle de dev

Il m'est venu une idée: Plutôt que de mesurer le nombre de lignes de code à un moment donné[2], ne serait-il pas opportun de regarder l'évolution de ce nombre au fur et à mesure du projet ?
En effet, ce nombre ne fait pas qu'augmenter. Par exemple, lors d'un refactoring, il n'est pas rare de supprimer plus de lignes que d'en rajouter.
Du coup, en comptant l'ensemble des variations de lignes de code depuis le début du projet et en appliquant une règle pondérant le nombre de lignes supprimées par rapport au nombre de lignes ajoutées[3], on peut rapprocher cette variation du temps de développement. Car au final, c'est bien le nombre demandé par le chef : "Combien de lignes de code vous écrivez à l'heure ? Combien ça me coûte ?".
Bon, on a déjà eu le même coup avec le nombre de bugs et on en a pris plein la figure à l'époque donc finalement, je crois que je vais laisser traîner :-/

Enfin, votre avis m'intéresse sur la question, chers lecteurs et lectrices.

Notes

[1] Je ne donnerai pas ici de précision sur lui pour sa sécurité :D

[2] Lundi, y a huit jours pour mon chef ;-)

[3] C'est toujours plus rapide de supprimer des pans entiers de code que d'en rajouter... Quoique !! -;)

mardi 23 septembre 2008

Write once...

Debug everywhere !!

Alors comme ça, Java n'est pas multi-plateforme ? Ben oui mais non !


Constat difficile mais même si sur le papier, Java fonctionne partout, le dur monde de l'informatique est bel et bien différent.
Problème de comportement de l'IHM[1] différent, ordonnancement des threads, sensibilité de la casse sont autant d'obstacles à la portabilité complète du binaire. On se retrouve alors confronté aux mêmes problèmes qu'avec des langages promettant la portabilité au niveau source à savoir l'établissement des bonnes règles de codage et des tests spécifiques par plateforme. Enfin, heureusement qu'il y a plein d'autres trucs que l'on n'a pas besoin de porter from scratch comme l'IHM.
Si je dis tout ça, c'est que l'on a porté un soft java de Window$ vers Solaris et qu'il aurait mieux valu que cela se passe dans l'autre sens. Et oui, parcourir quelques 250000 lignes de code source pour trouver toutes les créations, ouvertures de fichier où on a fait gentiment joujou avec la casse[2], les bidouilles sur la taille des buffers de socket et les architectures multi-threadée mal gaulées, c'est super la galère.
Et là, je parle même pas des perfs de Java sur Solaris !!!
A croire que les équipes de dev chez Sun ne se causent jamais !!!
Java fonctionne beaucoup mieux sur un X86 Window$ que sur une Sun Solaris.

Enfin, bon, c'est comme ça et ça n'a pas fini de nous filer du boulot.

Notes

[1] Interface homme-machine

[2] because développement à la rache

mercredi 21 mai 2008

Un blog sympa

Certains le savent, d'autres s'en seront rendus compte, j'ai l'immense plaisir d'être ingénieur informaticien.
Ce status d'être supérieur capable de murmurer aux oreilles des PC (et autres ordinateurs) me permet d'être beau, mais avec de moins en moins de cheveux de plus en plus gris, intelligent et d'avoir le poil brillant et la truffe chaude.

Bon, tout ça pour vous raconter une partie de ma vie passionnante d'informatichien (à sa mémère off course). Dans les langages que j'ai pu étudier, il y a par ordre chronologique :

  • Le Pascal (mais Turbo, ça a plus de reprise),
  • Le C (histoire de créer un générateur de fichier core non-aléatoire),
  • Le C++ (Hum, comme une femme, plus on la connaît, plus c'est compliqué),
  • Le Lisp (un bon langage pour extra-terrestres autistes),
  • Le Java (En version 1.0, s'il vous plaît),
  • L'ObjectiveC (apprentissage perso suite à un article de LinuxMag) et récemment,
  • L'Ada.


Les gens qui connaissent auront remarqué à quel point tout cela ne suit absolument aucune logique, surtout pour les deux derniers qui ne m'ont pas été imposés et qui sont carrément antagonistes d'un point de vue typage.
Et bien, depuis bientôt trois ans, c'est Ada qui capte mon attention et tout ce qui gravite autour, ce qui m'amène enfin à vous parler de ce blog en deux parties, plus très vivant mais avec des infos sympas sur le langage sus-cité.

Voilà, vous pouvez retourner à vos occupations, merci de m'avoir lu.