Votre tâche consiste à intégrer une fonctionnalité à un langage de programmation, soit en implémentant une bibliothèque très astucieuse, soit en traitant le texte saisi et / ou en peaufinant le processus de compilation.
Idées:
- Ajoutez une présentation de type PHP entrelacée à C (par exemple
<?c printf("Hello,"); ?> world!
). - Ajoutez un opérateur de fusion nul à l'une de ces langues qui n'est pas C #.
- Ajouter des macros à PHP.
- Ajouter
goto
à JavaScript. - Ajoutez un motif correspondant à la langue X.
- Ajoutez la prise en charge des espaces de noms à une langue qui ne l’a pas.
- Faites en sorte que C ressemble à PHP.
- Faites ressembler Haskell à Pascal.
- ... (n'hésitez pas à poster des idées dans la section commentaire)
Règles:
- Apportez quelque chose à la table. Ne dites pas simplement "Template Haskell" pour ajouter des installations de métaprogrammation à Haskell. Ce n'est pas StackOverflow.
- L’ensemble de la mise en œuvre doit tenir dans un seul écran (sans compter l’exemple).
- N'hébergez pas de code sur un site externe spécifiquement pour cette tâche.
- La fonctionnalité la plus impressionnante ou surprenante gagne.
Ne vous inquiétez pas pour implémenter la fonctionnalité à 100% correctement. Loin de là! Le principal défi consiste à déterminer ce que vous voulez faire et à supprimer vicieusement les détails jusqu'à ce que votre projet devienne réalisable.
Exemple:
Ajoutez un opérateur lambda au langage de programmation C.
Approche initiale:
Ok, je sais que je voudrais utiliser libgc afin que mes lambdas résolvent les problèmes de funarg ascendants et descendants. Je suppose que la première chose à faire est d’écrire / de trouver un analyseur syntaxique pour le langage de programmation C, puis d’apprendre tout sur le système de types de C. Il faudrait que je trouve un sens à la typographie. Aurais-je besoin d'implémenter l'inférence de type ou devrais-je simplement exiger que le paramètre formel soit typé comme étant donné? Qu'en est-il de toutes ces fonctionnalités folles de CI que vous ne connaissez pas encore?
Il est tout à fait clair que la mise en œuvre correcte de lambda en C serait une entreprise énorme. Oubliez l'exactitude! Simplifier, simplifier.
Mieux:
Amusez-vous! Qui a besoin d'eux? Je pourrais peut - être faire quelque chose délicate avec GNU C fonctions imbriquées et expressions de déclaration . Je voulais montrer une transformation syntaxique étonnante sur C avec un code laconique, mais je n’ai même pas besoin d’un analyseur. Cela peut attendre un autre jour.
Résultat (nécessite GCC):
#include <stdio.h>
#include <stdlib.h>
#define lambda(d,e)({d;typeof(e)f(d){return(e);};f;})
#define map(F,A)({typeof(F)f=(F);typeof(*(A))*a=(A);({int i,l=((int*)(a))[-1]; \
typeof(f(*a))*r=(void*)((char*)malloc(sizeof(int)+l*sizeof(*r))+sizeof(int)); \
((int*)r)[-1]=l;for(i=0;i<l;i++)r[i]=f(a[i]);r;});})
#define convert_to(T) lambda(T x, x)
#define print(T, fmt) lambda(T x, printf(fmt "\n", x))
int main(void)
{
int *array = 1 + (int[]){10, 1,2,3,4,5,6,7,8,9,10};
map(print(int, "%d"), array);
double *array2 = map(lambda(int x, (double)x * 0.5), array);
map(print(double, "%.1f"), array2);
long *array3 = map(convert_to(long), array2);
map(print(long, "%ld"), array3);
long product = 1;
map(lambda(int x, product *= x), array);
printf("product: %ld\n", product);
return 0;
}
C'était facile, n'est-ce pas? J'ai même ajouté une map
macro pour la rendre utile et jolie.
la source
Réponses:
Syntaxe de la POO dans Haskell
Les objets peuvent avoir des propriétés:
... et méthodes:
la source
&
et défini comme ceci(&) = flip ($)
.&
parce que c'est l'opérateur unaire "adresse-de" (la mise en place de pointeurs en Haskell est laissée à un exercice pour le lecteur).flip id
goto
en JavaScript?Ma première pensée était une approche fonctionnelle - ajouter un paramètre à la fonction pour indiquer le début de l’exécution, en l’utilisant avec une
switch
instruction et une boucle externe appelant à plusieurs reprises la fonction avec sa propre valeur de retour . Malheureusement, cela empêcherait l'utilisation de variables locales, car elles perdraient leurs valeurs à chaque goto.Je pouvais utiliser une
with
instruction et déplacer toutes les déclarations de variable au début de la fonction, mais il devait y avoir un meilleur moyen. Il m'est finalement arrivé d'utiliser la gestion des exceptions JavaScript . En fait, Joel Spolsky a déclaré: "Je considère que les exceptions ne valent pas mieux que" goto's ... " - de toute évidence un ajustement parfait.L'idée était de placer une boucle infinie à l'intérieur d'une fonction, uniquement terminée par une
return
instruction ou une exception non interceptée. Tous les gotos, traités comme des exceptions, seraient pris dans la boucle pour éviter sa terminaison. Voici le résultat de cette approche:Vous pouvez l'utiliser comme ceci - même en mode strict ES5 - sauf dans Internet Explorer ( démo ):
[Internet Explorer, pour une raison quelconque, ne parvient pas à évaluer le code d’une fonction anonyme, il faudrait donc lui attribuer un nom (avant sa réécriture) et l’appeler avec ce nom. Bien sûr, cela enfreindrait probablement les règles du mode strict.]
Cela ne permet pas de sauter à une instruction située dans un bloc (jusqu'à ce que des constructions telles que le périphérique de Duff deviennent légales), mais nous pouvons en traiter (une autre fonction réécrite auto-exécutante), non?
la source
goto
implémenté entièrement en JavaScript (là où vous pourriez utilisergoto
pour sortir de n'importe quelle portée, même une fonction ), cela impliquerait une prise en charge des continuations.#define in Java
J'ai pensé qu'il serait amusant d'implémenter des macros en Java.
Exemple d'utilisation (converti en code précédemment posté; faisons-le bizarre):
la source
Foreach en C
Itérer les tableaux (fonctionne pour les tableaux statiques, pas ceux reçus par un pointeur)
Pour le tester:
résultat:
la source
Propriétés en C
Tomasz Wegrzanowski a implémenté les propriétés dans la plaine C, en commettant intentionnellement une erreur de segmentation avec le programme lors de l'accès à la propriété.
Un objet avec une "propriété" est créé en créant un élément
struct
qui traverse plusieurs pages, en s'assurant que l'adresse mémoire de la propriété se trouve dans une page différente de celle des membres de données réels. La page de la propriété est marquée comme sans accès, ce qui garantit que toute tentative d'accès à la propriété provoquera un segfault. Un gestionnaire d'erreurs détermine ensuite quelle propriété l'accès a provoqué le segfault et appelle la fonction appropriée pour calculer la valeur de la propriété, qui est stockée à l'adresse de mémoire de la propriété.Le gestionnaire d'erreurs marque également la page de données en lecture seule pour garantir la cohérence de la valeur calculée. lors de la prochaine tentative d'écriture dans un membre de données, un segfault est déclenché, son gestionnaire définissant la page de données en lecture-écriture et la page de propriétés en tant qu'absence d'accès (indiquant qu'il doit être recalculé).
la source
Venu calculé dans Common Lisp
J'ai initialement implémenté come-from. Mais cela ne suffisait pas.
Inspiré par le calcul obtenu, j'ai décidé de mettre en œuvre le calcul en provenance de.
Exemples d'utilisation
Pour chaque déclaration de provenance dans le tagbody, il vérifie sur chaque étiquette si la variable de provenance est égale à l'étiquette actuelle et, le cas échéant, passe à la déclaration de provenance correspondante.
Greeter
FizzBuzz
la source
"Auto-strings" en Ruby
Le code est assez simple:
Maintenant tu peux faire
la source
Ajouter des macros à PHP
Nous pouvons simplement utiliser le préprocesseur C pour cette tâche.
Un script php:
Pipe-le bien cpp:
Résultat:
la source
<<<HEREDOC
n'est rien de plus que 3 inférieur ou gauche et un identifiant :-) Cela fera une macro-substitution dans les chaînes heredoc, cependant.grep -v ^#
whould résoudre ce problème. Je suppose que cela suffit pour cette question :-)Gardes decorrespondance de motifsen PythonLe corps de la fonction comporte 288 caractères.
Les modèles de correspondance de modèlevous permettent d'utiliser des fonctions complètement différentes en fonction des valeurs d'argument. Bien qu'il puisse être facilement imité avec une série d'if
énoncés,lesgardes decorrespondance de modèlepeuvent aider à séparer des sections de code, et c'est une excellente excuse pour faire une métaprogrammation délirante.pattern_match
est un décorateur qui crée une nouvelle fonction qui implémentedesgardes defiltrage de motifs. Les conditions pour chaque "sous-fonction" données dans chaque docstring sur des lignes commençant par un pipe (|
). Si toutes les conditions sont évaluées de manière honnête, cette version de la fonction est exécutée. Les fonctions sont testées dans l'ordre jusqu'à ce qu'une correspondance soit trouvée. Sinon,None
est retourné.Un exemple aidera à clarifier:
la source
f [a,b,c] = ...
que non seulement teste l'argument par rapport à un prédicat, mais qu'il lie les variables respectives en cas de correspondance correcte. C'est quand même assez cool, cependant.f (x:xs) = ...
etf [] = ...
). D'une certaine manière, j'ai convoqué les gardes là-bas, mais c'est de là que j'ai pris le|
message.Coroutine
Je ne peux pas prendre le crédit pour cela, alors je l'ai marqué CW.
Coroutines in C de Simon Tatham
la source
Opérateurs personnalisés à Lua
Pogs a intelligemment abusé de la surcharge des opérateurs à Lua afin de permettre la définition d’opérateurs infixes personnalisés. J'ai développé cette fonctionnalité pour prendre en charge la section d'opérateur (appliquer partiellement un opérateur avec l'un des opérandes) et appeler l'objet résultant comme s'il s'agissait d'une fonction.
la source
Chaînes multilignes en javascript
Dans cette syntaxe élaborée pour les chaînes multilignes, chaque chaîne multiligne sera précédée d'
(function(){/*
un, d'un nouveau trait et sera suivie d'un nouveau et de*/}+'').split('\n').slice(1,-1).join('\n')
.en utilisant cette syntaxe étonnante et intuitive, nous pouvons enfin utiliser des chaînes multilignes:
pour les personnes qui n'aiment pas notre syntaxe simple, nous avons un compilateur pour notre nouveau langage fabuleux:
le même exemple, dans la version en langage compilé:
la source
*/
mes chaînes multilignes. C’est super gênant d’inclure des expressions rationnelles dans les chaînes!Liste Sliceable en C # (comme Python)
J'ai toujours apprécié la notation slice de python et je souhaite qu'elle soit disponible en C #
Usage:
Code, loin de la preuve d'erreur:
la source
Rendre C plus simple
Ce code vous permet d’écrire des programmes C qui ressemblent un peu plus à un langage de script. Il comporte des mots clés tels que "var", "est", "chaîne", "plus", "égal" et plusieurs autres. Cela fonctionne à travers de nombreuses déclarations.
Cela vous permet d'écrire du code comme:
Ce qui précède est étendu à:
Ce n’est probablement pas très utile, mais j’ai trouvé très intéressant de pouvoir créer un langage de programmation complet grâce à une série d’
#define
alb.la source
#define
, vous pouvez même donner à votre langage des éléments tels que la gestion des exceptions et la collecte des ordures tout en conservant le calque C fondamental en dessous.Tcl
Tcl a pas
do ... while
oudo ... until
si ...Exemple:
uplevel
exécute un script dans la portée des appelants.la source
Aller en PostScript
Ma première pensée a été que je devrais me mêler de la pile exec, donc ce faux départ récupère l'opérateur de continuation pour arrêté depuis ghostscript (ou xpost).
Mais c'est plus simple que ça. Parce que file-position est la même pour tous les doublons du descripteur de fichier (
setfileposition
consomme son argument, il s'agit donc de la seule sémantique utile pour cette fonction).Cela imprime
5
.Il existe certaines limitations à ce qui précède. Le saut n'est pas immédiat, mais se produit lorsque if-body retourne au niveau supérieur et que l'interprète lit à nouveau dans le fichier (au lieu de lire dans le tableau qui contient if-body). À ce stade, le fichier a été repositionné et le «goto» prend effet.
la source
currentfile <pos> setfileposition
comptant les octets à partir du début du fichier.Symbol#to_proc
avec des arguments en RubySymbol#to_proc
est probablement l’un de mes trucs préférés pour écrire du code Ruby très succinct. Supposons que vous ayezet vous voulez convertir le contenu de
nums
ettext
en Floats et majuscules, respectivement.Symbol#to_proc
vous permet de raccourcir le code comme ceci:pour ça:
Impressionnant! Mais si nous voulons relever tous les éléments de
nums
lai
ième puissance, ou de remplacer toutes les occurrences des
avec*
entext
? Est-il possible de raccourcir un code comme celui-ci?Hélas, il n'y a pas de moyen facile de passer des arguments lors de l'utilisation
Symbol#to_proc
. Je l'ai vu faire de multiples façons, mais deux des plus intelligentes et les plus utilisables impliquent probablement de patcher laSymbol
classe [ 1 , 2 ]. Je vais illustrer le premier moyen ci-dessous.Maintenant, vous pouvez faire des choses comme:
la source
JavaScript pour chaque
Sortie
Syntaxe alternative, plus proche de Tcl.
la source
Gotos dans Haskell
L'idée de base est que les gotos peuvent être partiellement simulés en utilisant le dernier énoncé de
do
-notations. par exemple:est équivalent à
parce que l'exécution sautera à la dernière instruction, il est optimal d'exprimer gotos.
parce que, comme cela est fait, gotos saute seulement quand ils sont
do
directement au bloc d’une définition de niveau supérieur. c'est en fait "appeler x et ignorer le reste des instructions vues lexicalement " plutôt que "tout x et ignorer le reste des instructions", comme un vrai goto.Le plus gros problème est que, quand il n'y a aucun moyen de quitter l'exécution du milieu d'une action IO, même
return
si ce n'est pas le cas;return
ne fait rien quand ce n'est pas la dernière déclaration.ceci surmonte ceci en capturant le reste des déclarations par un autre
do
bloc.devient
la
print 3
déclaration est capturée par ledo
bloc etloop
devient la dernière déclaration.cette transformation prend également en charge les variables présentes dans le champ des actions. Ceci est fait en se souvenant des variables qui sont dans la portée et en les passant dans les actions. par exemple:
cela se traduit simplement par:
quelques notes:
De plus, une
return undefined
instruction est ajoutée pour garantir que ledo
bloc de capture n'est pas vide.parce que parfois, il y a une ambiguïté de type dans le
do
bloc de capture , au lieu deconst
nous utilisonsasTypeOf
, qui est identique àconst
mais requiert que ses deux paramètres aient le même type.l'implémentation réelle (en javascript):
un exampe:
devient:
sortie:
la source
return
dans Haskell, il s’agit d’une fonction régulière et qu’elle n’est pas liée au mot clé dans C / etc.Python Goto
goto.py
Usage
Exemple de cas de test
Exemple de sortie de cas de test
Juste un peu de plaisir avec exec (). Peut générer une erreur de profondeur de récursivité maximale s'il n'est pas utilisé correctement.
la source
// importer du javascript sans utiliser spécifiquement la balise script dans une page HTML
C'est nul ouais je sais. Longueur: 99
la source
script
balise autour. Alors où est exactement la nouvelle fonctionnalité?