Variables globales ? Où ça ?
Variables globales ? Où ça ?
One Web to rule them all
Ben, je n'ai pas vu un seul var/let, pour déclarer tes variables...
Pendant ce temps-là, j'ai encore réussi à raccourcir ma solution à 38 chars, avec un var ^^
Afin d'obtenir plus facilement de l'aide, n'hésitez pas à poster votre codede carte bancaire
Mon GitHub
Une alternative à jQuery, Angular, Vue.js, React, ... ? Testez anticore, en quelques secondes à peine !
(Contributions bienvenues)
Rha j'ai un truc qui fait 40 caractères mais qui ne marche pas avec arguments…
La FAQ JavaScript – Les cours JavaScript
Touche F12 = la console → l’outil indispensable pour développer en JavaScript !
Afin d'obtenir plus facilement de l'aide, n'hésitez pas à poster votre codede carte bancaire
Mon GitHub
Une alternative à jQuery, Angular, Vue.js, React, ... ? Testez anticore, en quelques secondes à peine !
(Contributions bienvenues)
39
Code : Sélectionner tout - Visualiser dans une fenêtre à part f=m=>(...a)=>b=>m.bind(...a).apply(8,b)
La FAQ JavaScript – Les cours JavaScript
Touche F12 = la console → l’outil indispensable pour développer en JavaScript !
Afin d'obtenir plus facilement de l'aide, n'hésitez pas à poster votre codede carte bancaire
Mon GitHub
Une alternative à jQuery, Angular, Vue.js, React, ... ? Testez anticore, en quelques secondes à peine !
(Contributions bienvenues)
Ce sont toutes des variables locales déclarées en tant qu'argument de fonction.
Il va falloir réviser ES6
Je reste sur ma dernière solution à 37 caractères :
Code : Sélectionner tout - Visualiser dans une fenêtre à part f=F=>(c,...r)=>a=>F.call(c,...r,...a)
One Web to rule them all
Désolé je ne trouve pas mieux que 39, je vais faire une pause et y revenir peut-être ce soir.
Au moins, ce défi m'a aidé à mieux comprendre l'opérateur ... que je maîtrisais mal
La FAQ JavaScript – Les cours JavaScript
Touche F12 = la console → l’outil indispensable pour développer en JavaScript !
Et ton f alors? ^^
Je pense que c'est la meilleure, jusqu'ici... concernant la mienne, j'sais pas trop ce que je testais mais j'crois que j'me suis emmêlé les pinceaux dans mes versions... car au reboot du pc, l'une marchait avec array/arguments, l'autre avec des params bindés...
Pour parfaire la tienne, mais qui ne peut, non-plus, respecter le "no globals", sans dépasser la limite de taille en même temps, je propose celle-ci :
f=m=>(i,...a)=>b=>m.apply(i,a.concat(b))
Afin d'obtenir plus facilement de l'aide, n'hésitez pas à poster votre codede carte bancaire
Mon GitHub
Une alternative à jQuery, Angular, Vue.js, React, ... ? Testez anticore, en quelques secondes à peine !
(Contributions bienvenues)
Parfaire ? Ta version est plus longue, *peut mieux faire* et on s'en fiche du f, c'est juste le nom donné à la fonction pour tester les exemples. Ça devrait même pas compter dans le décompte
Pour aller plus loin dans la recette du curry :
si F=>F.bind.bind(F) est la recette du curry en 2 temps, c'est à dire curry2(func)(...args1)(...args2) === func.call(...args1, ...args2)
- Quelle est la solution la plus courte pour le curry en 3 temps, c'est-à-dire curry3(func)(...args1)(...args2)(..args3) === func.call(...args1, ...args2, ..args3) ?
curry3("".substring)("hello world!")(6)(11) === "world";
- Quelle est le solution la plus courte pour le curry à n temps, c'est-à-dire curryN(n)(func)(...args1)(...args2) (...) (...argsN) === func.call(...args1, ..., ...argsN)
curryN(1)("".substring)("hello world", 6, 11) === "world";
curryN(2)("".substring)("hello world", 6)(11) === "world";
curryN(2)("".substring)("hello world")(6, 11) === "world";
curryN(3)("".substring)("hello world!")(6)(11) === "world";
curryN(3)("".substring)("hello world!",6)()(11) === "world";
curry curry ! curryyy !
One Web to rule them all
Hum, oui, il y avait visiblement un truc que j'avais pas saisi avec le spread... merci aussi et bien joué
Afin d'obtenir plus facilement de l'aide, n'hésitez pas à poster votre codede carte bancaire
Mon GitHub
Une alternative à jQuery, Angular, Vue.js, React, ... ? Testez anticore, en quelques secondes à peine !
(Contributions bienvenues)
Vous oubliez un détail : ni le spread ni concat ne marchent avec un objet arguments.
C'est à cause de ça que j'ai pas pu me débarrasser de mon apply
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 (function () { var result = substringFromHello(arguments); console.log(result); console.assert("world" === result, "failed"); }(6, 11));
La FAQ JavaScript – Les cours JavaScript
Touche F12 = la console → l’outil indispensable pour développer en JavaScript !
Si on oublie cette contrainte du arguments on peut descendre à 33 en reprenant la solution de Sylvain :
En effet rien ne nous oblige à distinguer le premier argument (anciennement c) du reste des arguments (r).
Code : Sélectionner tout - Visualiser dans une fenêtre à part f=F=>(...p)=>a=>F.call(...p,...a)
Avec le test case de mon précédent post, j'obtiens cette erreur sous Firefox :
Il semblerait que le spread appelle en interne le même mécanisme d'itération que for..of. Dans SpiderMonkey tout du moins.TypeError: a[Symbol.iterator] is not a function
Avec Chrome… Pas d'erreur. Ok, si je suis le seul ici à utiliser Firefox, je comprends mieux pourquoi personne n'avait remarqué ce problème avec arguments avant moi. Il s'agit d'un bug de Firefox.
Note au passage, les erreurs dûes au spread sous V8 sont plus difficiles à comprendre :
Code : Sélectionner tout - Visualiser dans une fenêtre à part (function (nonIterable) { console.log(...nonIterable); }(42))En attendant, on est sur un double score de 33 (V8) / 39 (SpiderMonkey).Uncaught TypeError: undefined is not a function(…)
Voilà voilà. Désolé. Vraiment.
Là ça me fait réfléchir. Qu'est-ce qui se passerait si on ne donnait pas le nombre de temps (l'arité) en paramètre ? A priori on ne saurait pas à quel moment renvoyer une fonction ou la valeur finale. Mais en utilisant un Proxy, je pense qu'on peut renvoyer un objet qui apparaît comme une valeur mais qui peut également se comporter comme une fonction.
Mais bref ^^ Je vais déjà tâcher de répondre à tes deux questions.
La FAQ JavaScript – Les cours JavaScript
Touche F12 = la console → l’outil indispensable pour développer en JavaScript !
Ah ben oui c'est évident comme optimisation, je ne sais pas comment j'ai pu louper ça... Parfois on ne voit pas les choses qui sautent aux yeux.
L'opérateur spread gère bien les arguments de fonction, c'est d'ailleurs l'exemple de démo le plus couramment utilisé. Mais son implémentation est encore balbutiante sur les navigateurs. Mieux vaut tester le code transpilé par Babel.
Ce qui serait à la fois très très cool et très très idiot Pour un usage "pratique" d'une telle fonction, l'arité est toujours prédéfinie. Sinon on ne sait plus ce qu'on manipule.
J'ai choisi de passer l'arité en argument initial parce que ça simplifie de mon point de vue le code la fonction derrière. On supposera qu'il s'agit toujours d'un nombre entier supérieur ou égal à 1.
Voilà ma solution :
Non minifié
curryN minifié:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 var curry3= function(F){ var n = 3; var argsStack = []; return function R(...args){ argsStack.push(...args); return --n ? R : F.call(...argsStack) } }
Code : Sélectionner tout - Visualiser dans une fenêtre à part var curryN = n=>(F,s=[],R=(...a)=>(s.push(...a),--n?R:F.call(...s)))=>R
Et une version encore plus récursive, mais pas forcément plus courte:
Code : Sélectionner tout - Visualiser dans une fenêtre à part var curryN = n=>(f,...s)=>(...a)=>--n?curryN(n)(f,...s,...a):f.call(...s,...a)
One Web to rule them all
J'ai trouvé des trucs pour curryN. Curieusement, j'ai deux solutions légèrement différentes mais qui font la même longueur :
Ce qui montre que ce n'est pas forcément gagnant de remplacer function par var.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 n=>f=>{var r=(n,...a)=>n?(...b)=>r(--n,...a,...b):f.call(...a);return r(n)} n=>f=>function r(n,...a){return n?(...b)=>r(--n,...a,...b):f.call(...a)}(n)
Je n'ai pas pensé à utiliser les valeurs d'arguments par défaut du coup on peut peut-être trouver plus court en mélangeant nos deux versions.
Au fait j'ai essayé Babel, c'est impressionnant Mais il doit y avoir des trucs qu'il ne peut pas faire, non ?
La FAQ JavaScript – Les cours JavaScript
Touche F12 = la console → l’outil indispensable pour développer en JavaScript !
J'pense avoir mieux, les gars...
Qu'en pensez-vous?
Code : Sélectionner tout - Visualiser dans une fenêtre à part var c,curryN=c=i=>(f,...a)=>i?c(--i).bind(i,f,...a):f.call(...a)
En non-minifié :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9 var curryN; curryN = function (arity) { return function (fn, ...args) { return arity ? curryN(--arity).bind(arity, fn, ...args) : fn.call(...args); }; };
EDIT:
En bonus, par rapport aux vôtres, la mienne marche aussi avec arity = 0
Afin d'obtenir plus facilement de l'aide, n'hésitez pas à poster votre codede carte bancaire
Mon GitHub
Une alternative à jQuery, Angular, Vue.js, React, ... ? Testez anticore, en quelques secondes à peine !
(Contributions bienvenues)
Vous aimez l'épicé? J'crois que ça va vous plaire... ^^
Cette version a la même longueur que celle de SylvainPV... mais elle est réutilisable et supporte des usages supplémentaires :
Démo
Code : Sélectionner tout - Visualiser dans une fenêtre à part var c,curryN=c=(...a)=>((i,f,...b)=>i--?c(i,f,...b):f.call(...b)).bind(a,...a)
Curry thaï?
EDIT :
Même si, perso, je trouverais plus logique et plus élégant que le arity = 0 ressemble à ceci :
Ce qui donnerait, en version courte ne permettant pas d'aliaser curryN :
Code : Sélectionner tout - Visualiser dans une fenêtre à part curryN(0, "".substring, "hello world!", 6, 11)
Démo
Code : Sélectionner tout - Visualiser dans une fenêtre à part var c,curryN=c=(i,f,...a)=>i?c.bind(i,--i,...(f?[f,...a]:a)):f.call(...a)
Ou en version longue, permettant d'aliaser curryN :
Démo
Code : Sélectionner tout - Visualiser dans une fenêtre à part var c,curryN=c=(i,f,...a)=>i<1?f.call(...a):c.bind(i,...(i?[--i]:[]),...(f?[f,...a]:a))
Afin d'obtenir plus facilement de l'aide, n'hésitez pas à poster votre codede carte bancaire
Mon GitHub
Une alternative à jQuery, Angular, Vue.js, React, ... ? Testez anticore, en quelques secondes à peine !
(Contributions bienvenues)
Ben si l'arité est nulle par définition c'est plus du Curry vu qu'on ne retourne plus de fonction. Et ça ne présente pas plus d'un intérêt qu'un f.call ^^
Pas bête le bind, j'oublie toujours que les arguments bound sont concaténés et non remplacés. Du coup je pense que ta solution curryN = i=>(f,...a)=>i?curryN(i-1).bind(f,f,...a):f.call(...a) est la meilleure.
Difficile de savoir quoi mettre comme premier argument du bind, le contexte des fonctions curry n'a en principe pas d'importance vu qu'on finit par un .call.
@Lcf: pas compris ce que tu voulais dire par "aliaser"
One Web to rule them all
C'était un peu l'idée, que l'on puisse aussi s'en servir comme d'un .call... avec une légère différence tout de même, c'est que dans l'usage avec une méthode d'un objet, c'est qu'on peut éviter l'accès à la méthode (en tant que telle) et/ou de devoir connaître l'objet en question.
La plus courte, oui... mais à mon sens, pas la meilleure, perso, je choisirais tout de même une des versions réutilisables...
En effet, si on ne peut se resservir d'une des fonctions résultantes, connaissant déjà les premiers arguments spécifiés, pour faire un second appel, on n'en utilise son potentiel qu'à moitié.
Pour ça que j'ai mis le arity, mais j'aurais pu mettre n'importe quoi, tant que ça fait sauter le param du contexte.
Bah, faire une copie de curryN, quoi...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 var alias; alias = curryN();
Afin d'obtenir plus facilement de l'aide, n'hésitez pas à poster votre codede carte bancaire
Mon GitHub
Une alternative à jQuery, Angular, Vue.js, React, ... ? Testez anticore, en quelques secondes à peine !
(Contributions bienvenues)
Je ne comprends pas pourquoi tu dis que cette version n'est pas réutilisable. Toutes les fonctions sont locales donc regenérées.
Dans tes dernières versions tu as réduit de 1 le décompte des appels en ajoutant l'arité avec le reste des paramètres, ce qui n'a pas beaucoup de sens selon moi. En repartant des tests d'origine, ça fonctionne très bien et c'est réutilisable : démo
One Web to rule them all
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager