Conditionnels
Très tôt dans sa conception, il a été décidé que OK ? ne comporterait pas d'opérateur ternaire. L'opérateur ternaire ressemble à ceci :
let a = isprod ? 'prod' : 'dev' ;
Que signifie le point d'interrogation ? Que signifient les deux points ? Dans OK ?, nous laissons ces questions aux philosophes pour nous concentrer sur l'essentiel : écrire un code propre.
Un langage n'a besoin que d'une seule construction de flux de contrôle conditionnel, et dans OK ?, cette construction est l'instruction switch. Les instructions switch sont plus polyvalentes et expressives que les opérateurs ternaires et les instructions if, et après un certain temps, vous oublierez l'existence de ces autres constructions. Voici l'instruction ci-dessus en langage idiomatique OK ?
Code OK ? : | Sélectionner tout |
1 2 3 4 | let a = switch isprod { case true : "prod" ; case false : "dev" ; } |
La forme switch, bien que plus longue, est incontestablement plus claire. Comprendre la valeur de la simplicité par rapport à la complexité est la première étape de l'apprentissage de OK ?
Des Switches lisibles
Étant donné que les Switches sont si centraux dans OK ?, les responsables du langage voulaient éviter certains pièges communs autour des Switches trouvés dans d'autres langages. Dans d'autres langages, il est courant qu'une seule instruction de switch prenne plusieurs pages d'un éditeur avec une logique gonflée qui est poussée dans chaque cas de switch, donc dans OK ? il est question que l'utilisateur ne puisse avoir qu'une seule instruction par cas :
Si l'utilisateur veut exécuter plusieurs instructions par switch case, il suffit de les intégrer dans une fonction :
Code : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | // INVALID: switch x { case true: z = z + 2 case false: x = x + 1; y = y - 1; // <-- ERROR: switch blocks can only contain a single statement } // VALID: let onfalse = fn() { x = x + 1; y = y - 1; }; switch x { case true: z = z + 2; case false: onfalse(); } |
Les valeurs nulles ne sont pas acceptables
Null implicite est une épine dans le pied de tout développeur qui se respecte et c'est pourquoi dans OK ? les valeurs nulles ne sont PAS OK, OK ?
Les valeurs nulles auraient pu être dans OK ?, « mais vous auriez alors oublié à quel point elles sont mauvaises, alors nous les avons incluses, représentées non pas par nil ou null mais par NO !, qui est la seule réponse sensée à la question Are nulls OK ? », déclarent les responables du langage. Pour faire passer le message, ils ont également ajouté une fonction intégrée appelée ayok ? qui prend une valeur et retourne si cette valeur est OK.
Code : | Sélectionner tout |
1 2 3 4 5 | let x = NO! puts(ayok?(x)) // prints 'false' let y = 10 puts(ayok?(y)) // prints 'true' |
Dans OK ?, les erreurs sont simplement des valeurs, comme n'importe quelle autre valeur. Une valeur à laquelle elles ressemblent particulièrement est la chaîne de caractères, car par convention, elles sont en fait des chaînes de caractères. Par exemple :
Code : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 | let divide = fn(a, b) { return switch b { case 0: [NO!, "cannot divide by zero"]; default: [a / b, ""]; }; }; result = divide(5, 0) switch result[1] { case "": puts(result[0]) default: puts(result[1]) // prints "cannot divide by zero" } |
Opérateurs logiques lisibles
Dans le cas d'une instruction conditionnelle qui enchaîne un tas de longues expressions booléennes.
Code : | Sélectionner tout |
1 2 3 | switch p.isactive() && p.credits() >= reqcreds && p.nottype("Admin") { ... } |
Code : | Sélectionner tout |
1 2 3 4 | // ERROR: '&&' operator must act on variables switch p.isactive() && p.credits() >= reqcreds && p.nottype("Admin") { ... } |
Code : | Sélectionner tout |
1 2 3 4 5 6 | let isactive = p.isactive() let enoughcr = p.credits() >= reqcreds let notadmin = p.nottype("Admin") switch isactive && enoughcr && notadmin { ... } |
Code : | Sélectionner tout |
1 2 3 4 5 6 | let isactive = p.isactive() let enoughcr = lazy p.credits() >= reqcredits let notadmin = lazy p.nottype("Admin") switch isactive && enoughcr && notadmin { ... } |
Dans OK ?, 5 + 2 * 3 donne 21 et non 11, car l'addition et la multiplication ont la même préséance d'opérateur. Si l'utilisateur souhaite évaluer son expression dans un autre ordre, il suffit d'utiliser des parenthèses : 5 + (2 * 3).
Ce simple ordre par défaut de gauche à droite évite d'avoir à chercher sur Internet une table de précédence des opérateurs et permet de garder les yeux sur le code.
MLes classes
Les auteurs de OK ? ont assisté à l'explosion de la popularité des langages orientés objet (OO), pour les voir bientôt crouler sous leur propre poids. Au cœur de cette obésité clinique se trouve la classe.
« Une classe reprend une idée sensée, à savoir la définition de données et de méthodes qui agissent sur ces données, puis la pousse du haut d'une falaise en ajoutant l'héritage et le polymorphisme des sous-types », déclare Jesse Duffield, Créateur de lazygit, lazydocker, horcrux, et du langage OK ?. « Il n'est pas surprenant qu'un groupe de vieux aristocrates obsédés par les classes dans les années 60, qui passaient probablement tout leur temps à décider quel enfant devait hériter de la plupart des biens, aient décidé d'ajouter une construction appelée "classe" qui tourne autour de l'héritage », poursuit-il.
Jesse Duffield précis : « Eh bien, la révolution est enfin arrivée ! Il n'y a pas d'héritage dans OK ? en solidarité avec tous ceux qui se sont battus contre la bourgeoisie dans le passé. D'autres langages ont opté pour les structures au lieu des classes, mais malgré le fait que leurs développeurs dénoncent honorablement l'OO, les vieilles habitudes ont la vie dure et certains prononcent accidentellement "classe" alors qu'ils veulent dire "structure". Certains développeurs disent même "class" délibérément, un moyen de revenir à l'époque où l'aristocratie OO tenait encore la profession de développeur par la gorge. »
Afin de lever toute ambiguïté et de garantir un engagement total en faveur de la mort des classes, l'équipe de OK ? a décidé d'utiliser sa propre terminologie : notaclass, ou nac en abrégé.
Code : | Sélectionner tout |
1 2 3 4 | notaclass person { field name field email } |
Il n'est pas possible de marquer un champ comme public dans OK ? parce que l'API publique d'un nac doit décrire un comportement, pas un état.
Code : | Sélectionner tout |
1 2 | let p = new person() p.name = "Jesse" // <-- ERROR: access of private field 'name' |
Code : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 | notaclass person { pack "I am a stupid piece of shit who should not be doing this" field name field email } let p = new person() // I acknowledge that I am a stupid piece of shit who should not be doing this p.name = "Jesse" // <-- No error |
Pas de constructeurs
Les constructeurs sont une chose basée sur les classes, et OK ? n'a pas de classes. Le mot Constructeur contient également le mot struct, et OK ? n'a pas de structs. Si vous voulez définir l'état initial d'un nac, il suffit de l'ajouter comme une méthode distincte :
Code : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 | notaclass person { field name field email public init fn(selfish, name, email) { selfish.name = name; selfish.email = email; } } let p = new person() p.init("Jesse", "jesse@test.com") |
Selon Jesse Duffield, la composition corrige le problème fragile de la classe de base introduit par l'héritage, pour ensuite introduire son propre problème de composant de base, où vous ne pouvez pas vous défaire du sentiment que vous vous êtes en fait un peu handicapé en dépendant de la composition pour la réutilisation du code, surtout lorsque le composant n'a pas la capacité d'interagir avec son parent.
Pour activer l'évolution, il suffit de définir une méthode evolve dans votre nac. La méthode evolve est invoquée après l'exécution de toute autre méthode du nac et détermine si les conditions préalables ont été remplies pour faire évoluer l'instance du nac vers un nouveau type de nac.
Code : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | notaclass brgousie { public whoami fn(selfish) { return "a good-for-nothing aristocrat who likes classes" } } notaclass person { field name field email field likeclas ... public whoami fn(selfish) { return selfish.name; } public makeold fn(selfish) { selfish.likeclas = true; } evolve fn(selfish) { switch selfish.likeclas { case true: return new brgousie(); default: return NO!; } } } let p = new person(); p.init("John", "") puts(p.whoami()); // prints "John" p.makeold(); // evolve() method is called behind the scenes puts(p.whoami()); // prints "a good-for-nothing aristocrat who likes classes" |
Et vous ?
Quel est votre avis sur le langage OK ? ?
Face à la multitude des langages de programmation, quel pourrait être selon vous l'intérêt du langage OK ? ?
Véritable innovation ? ou alors blague étudiante pour faire le buzz ?
Voir aussi :
80 % des technologies pourraient être créées par des professionnels extérieurs à l'informatique d'ici 2024, grâce aux outils low-code, selon Gartner
Forrester : l'utilisation des plateformes de développement low-code gagne du terrain dans les processus de transformation numérique des entreprises
Le marché mondial des technologies de développement low-code va augmenter de 23 % en 2021, selon les prévisions de Gartner
Microsoft lance Power Fx, un nouveau langage de programmation low-code open source basé sur Excel