Si vous deviez concevoir un langage de programmation, comment le feriez-vous? Quelles fonctionnalités mettriez-vous? Que laisseriez-vous dehors? Statiquement ou dynamiquement typé? Fortement ou faiblement typé? Compilé ou interprété? Justifie tes réponses.
programming-languages
language-design
Chinmay Kanchi
la source
la source
Réponses:
Je pense vraiment que les langages de programmation fonctionnels vont faire leur chemin, alors mon langage sera fonctionnel. Voir Effets de maturation avec programmation fonctionnelle
Je pense que les processeurs auront bientôt des centaines de cœurs, et que les threads seront un enfer à gérer. Donc, le modèle d'acteur est un must au lieu de threads. Voir Erlang - logiciel pour un monde concurrentiel
Je pense aussi que la POO a échoué, la communication entre les objets était supposée être asynchrone . Je pense donc que nous avons besoin de transmettre des messages, avec des messages immuables. Envoyez et oubliez. Comme dans le modèle de l'acteur. Voir Programmation orientée objet: le mauvais chemin?
Je pense qu'il serait bon d'avoir un typage statique , donc les erreurs sont détectées plus tôt dans le cycle de développement. Mais j'utiliserais l' inférence de type comme dans Haskell, afin que le développeur n'ait pas besoin d'écrire le type partout dans le code, comme en C, C # et Java. Voyez vous apprendre un Haskell pour le grand bien
Je voudrais également concevoir une excellente bibliothèque d’interface utilisateur , avec une disposition déclarative , comme dans WPF et Android. Mais je voudrais l'avoir comme dans la programmation réactive fonctionnelle .
Donc, mon langage ressemblerait à celui de la concurrence d'accès à Erlang mais avec le typage comme dans Haskell et un framework d'interface graphique comme dans WPF.NET.
la source
Remarque: j'ai utilisé la syntaxe C-like pour décrire les fonctionnalités de cet article, mais je ne suis pas pointilleux à propos de la syntaxe elle-même tant que ce n'est pas quelque chose de ridicule, comme tous les mots clés sont CAPS.
1. Système de dactylographie
La fonctionnalité numéro un que je souhaiterais dans une langue est le typage statique avec le typage dynamique facultatif . La raison en est que le typage statique vous permet a) de détecter les erreurs plus tôt que prévu et b) la plupart du code est implicitement typé de manière statique, que la langue fasse la distinction ou non. Cependant, il existe plusieurs cas d'utilisation où le typage dynamique est extrêmement utile. Par exemple, lors de la lecture de données dans un fichier, vous avez souvent des champs de types différents, et le typage dynamique facilite la manipulation de conteneurs hétérogènes. Donc, ma langue idéale aurait quelque chose comme ça:
2. Compilé vs interprété
J'aimerais que le langage soit soit compilé à l'avance, soit que le JIT soit compilé, mais pas simplement interprété, la vitesse étant la raison. Cela rejoint le point 1 , car un compilateur / optimiseur optimisé aura beaucoup plus de facilité à optimiser un code statiquement typé, et le code dynamiquement typé pourrait simplement être laissé tel quel.
3. Fermetures
Le langage doit prendre en charge les structures de programmation fonctionnelles et les fonctions doivent être des objets de première classe.
4. Orienté objet
Le langage devrait vous permettre d'écrire du code orienté objet, mais un simple code impératif devrait également être autorisé. c'est-à-dire qu'il devrait être possible d'écrire un programme hello world comme ceci:
5. Espaces de noms
Les espaces de noms sont une bonne chose. Très peu de choses devraient aller dans l'espace de noms global. Mais si vous devez placer des éléments dans l’espace de noms global, vous pouvez (ala C ++).
6. Types de données intégrés
Le langage doit avoir, en tant que types de données intégrés, les constructions suivantes:
int
type de données ou types. S'il n'y a qu'un seulint
type, il devrait avoir une portée illimitée. S'il y en a plus, il devrait y avoir une conversion ascendante implicite dans le type le plus petit capable de contenir le résultat d'un calcul, le type de plage illimitée étant le plus grand.float
type binaire intégré , équivalent à un IEEE 754double
list
type mutable implémenté sous forme de liste à double liaison ou de bloc de mémoire contiguë contenant des pointeurs sur chaque élémentlist
type immuable qui agit comme un tableau mais dont la taille ne peut pas être modifiée après la créationstring
Types mutables et immuables , la valeur par défaut étant immuable.map
ou undict
type qui est modifiable et contient des clés immuables et des valeurs modifiables et / ou immuables.vartype
d si nécessaireboolean
typenull
ou unnone
type pouvant être affecté à une variable de tout type.set
Types mutables et immuablesdecimal
type qui implémente des variables décimales à virgule flottantefixed
type qui implémente un nombre à virgule fixeLes types
decimal
,float
etfixed
doivent partager exactement la même interface publique (via un héritage ou un dactylographie), ce qui leur permet d'être transmis de manière transparente à des fonctions. Le type de parent pourrait être appeléreal
.7. Appel par valeur et par référence
Vous devriez être capable d'appeler des fonctions à la fois par valeur et par référence, la valeur par défaut étant valeur (c'est-à-dire qu'une copie de l'argument est créée et utilisée dans la fonction).
8. pointeurs
La langue doit avoir des pointeurs et permettre l'arithmétique des pointeurs. Les pointeurs ne peuvent être typés que de manière statique (pour éviter le cauchemar qui est a
void*
).vartype
les pointeurs sont explicitement interdits. Avoir des pointeurs et une arithmétique de pointeur permet au langage d'être sérieusement utilisé comme langage de programmation système.9. Assemblage en ligne
En relation avec 8. , Le langage doit permettre le code de langue d'assemblage en ligne pour les situations où il est nécessaire.
10. sécurité
Le langage devrait être principalement sûr à utiliser, prenant en charge la gestion des exceptions, etc. L'arithmétique de pointeur et l'assemblage en ligne peuvent être relégués à des parties du code explicitement marquées comme non sécuritaires. Le code non sécurisé est autorisé mais fortement déconseillé.
11. Comportement indéfini
La norme de langage doit spécifier le comportement du programme dans toutes les circonstances, sauf dans le code explicitement marqué comme étant non sécurisé, c'est-à-dire qu'aucun comportement non défini ne doit exister en dehors des blocs non sécurisés. Cela permet au langage d'être utilisé comme langage de développement d'application viable, tout en vous permettant de dire, d'écrire un système d'exploitation.
C'est tout ce à quoi je peux penser pour le moment, mais je vais éditer / mettre à jour le post car je pense à plus de choses.
la source
decimal
type ici.Voici à quoi ressemblerait le langage de programmation de mes rêves:
la source
yield
dans Smalltalk? Devrait être aussi propre à utiliser.Je l'aurais assez bien conçu en C #, mais Microsoft m'a battu. :)
(Sauf bien sûr que le mien aurait été moins bien pensé et plus amateur.)
Peu importe que ce soit compilé ou interprété, je n'ai donc pas besoin de justifier cela.
En ce qui concerne le typage statique fort, j'ai du mal à comprendre pourquoi cela nécessite même une justification. Le typage statique est une fonctionnalité qui détecte les bogues lors de la compilation. Le typage dynamique est l'absence de cette fonctionnalité et reporte les bogues jusqu'à l'exécution. D'après mon expérience personnelle, il y avait peu de cas d'utilisation où la répartition dynamique avait un sens et était utile, aussi les convolutions que je devais passer en C # avant la version 4.0 pour l'obtenir étaient-elles facilement justifiées. Avec C # 4.0, je n'ai même plus besoin de justifier cela, car nous avons maintenant une répartition dynamique.
Cependant, j'aurais probablement créé une nouvelle syntaxe au lieu de rester fidèle à l'ancienne syntaxe C comme l'a fait C #. L'instruction switch est particulièrement horrible, et je n'aime pas non plus la syntaxe de casting (c'est l'inverse). Cependant, je ne fais pas beaucoup de bruit sur les détails de la syntaxe, je n'ai donc pas besoin de la justifier en détail, sauf que je ne voudrais pas qu'elle soit aussi détaillée que Visual Basic.
Que voulez-vous que je justifie?
la source
Eh bien voici une liste de fonctionnalités que je mettrais dans:
Lisp comme syntaxe
Style Lisp
Avantages :
(eval "your data files")
Inconvénients :
Programmation fonctionnelle
Style Haskell
Avantages :
Inconvénients :
Typage dynamique fort
Style python
Avantages :
Mise en œuvre :
Autorise la surcharge de fonctions basée sur des types, similaires aux CL
defgeneric
:Compilable et interprétable
Avantages :
Inconvénients :
Programmation de systèmes
Style C
Avantages :
Inconvénients :
Macros hygiéniques (style CL et style Scheme)
Avantages :
Inconvénients :
À bien y penser, ce schéma définit plus ou moins, à l’exception du bit de compilation et de programmation système. Cela peut être contourné en utilisant libguile et en écrivant ces bits en C.
la source
car
la fonctioncdr
est et les arguments, vous avez un objet dont lename
terrain est la méthode et dont learguments
terrain est les arguments et au lieu de nidification, vous avez.prev
etnext
champs pointeur).Il y a plusieurs langues que je considère comme sacrément bonnes (C # étant mon préféré actuellement). Comme il s’agit de mon langage fantastique, voici ce que je veux vraiment:
la source
Astuces du compilateur
Je parle de moi, crétin, car je ne connais pas grand-chose à la conception des langues, mais je pense que la fonctionnalité dont je parle est appelée des astuces dans d'autres langues. Des astuces pour le compilateur , peut-être?
Je ne sais pas si j'ai lu ceci dans un brouillon Perl6 ou si j'étais juste élevé à l'époque, mais j'imagine un langage où tout est défaut par défaut, capricieux et automagique. Mais si vous voulez vraiment améliorer les performances et dire, hé, cette valeur est toujours un entier ou elle n'est jamais nulle, ou cela peut être parallèle, ou c'est sans état, des choses comme ça ... Que le compilateur puisse automatiquement aller en ville sur ces zones spécifiquement marquées.
E: J'apprécierais les commentaires clarifiant ce que je demande ou citant des exemples où cela existe déjà.
la source
safety
etspeed
, vous pouvez souvent demander au compilateur de vérifier et d’appliquer (pour rechercher des problèmes) ou d’assumer ce que vous dites est vrai (et compiler du code plus rapide).Pour essayer de nouvelles idées:
Je créerais un langage de programmation fonctionnel à typage dynamique, il vous permet de faire toutes les astuces sur l’expression d’une déclaration et la syntaxe lambda la plus simple avec correspondance de motif. Règle hors-jeu activée.
Voici une explication:
default =
définit le stockage,\def val
commence une fonction curry avec deux arguments,val.Type
est identique àType[val]
,!!
convertit en boolean, et boolean peut être appliqué, etval
ainsidef are after it.
f x
=f[x]
=x.f
.f
=f[]
et dans
greet
, il a utiliséname<(default "world")
ethasType Str>
, cela signifie que le motifdefault "world"
sera utilisé et lié àname
. Le modèle par défaut spécifie une valeur par défaut.and
est un autre motif qui enchaîne deux motifs. ledefault
modèle ne peut pas échouer alors quehasType
peut échouer. Dans ce cas, il lève une exception.Les variables sont en réalité des stockages, qui peuvent être passés fonctionnellement, et les tables de stockage peuvent être des références, créées et détruites lorsque les étendues changent.
Les hachages et autres seront comme dans Lua et JavaScript.
Si je veux créer un langage compilé, je vais créer un F # pour Java, avec des fonctionnalités similaires à celles de Haskell. Il s’agit d’un langage purement fonctionnel, à l’exception d’une fonctionnalité qui associe Quotations et Comp Exprs pour réaliser une programmation impérative en écrivant des blocs de type pseudocode.
la source
Gardant à l'esprit que les seuls langages que je connais sont PHP et javascript, et que je devrais vraiment en apprendre un peu plus avant de concevoir un langage:
Syntaxe: Réfléchissez bien aux noms de fonction et à l'ordre des arguments (c.-à-d. Soyez moins compliqué que PHP).
Fonctionnalités: Avoir un ensemble de
string
fonctions, qui fonctionnent sur des variables comme une série d'octets, mais ne comprend pas le texte, et un ensemble detext
fonctions, comprenant beaucoup d'encodages et pouvant fonctionner sur les chaînes UTF-8 et autres chaînes multi-octets. (Et avez des contrôles de cohérence d'encodage intégrés dans la langue, avec une fonction commetext.isValidEncoding(text, encoding)
qui vous dira si une séquence d'octets est mal formée et dangereuse à traiter en tant que texte.Je pense que j'aime l'idée de dactylographie statique forte, mais je ne l'ai jamais utilisée, donc je ne peux pas vraiment le dire.
la source
Avant de concevoir un langage de programmation, je trouverais une bonne réponse à la question: pourquoi avons-nous besoin d’un autre langage de programmation? Rosetta Code au moment de la rédaction de cet article répertorie 344 langues. Si aucun de ceux-ci ne répondait à mes besoins, les raisons pour lesquelles ils ne le faisaient pas détermineraient le point de départ (les langues qui se rapprochent le plus) et ce qui y serait ajouté.
Si je gagnais à la loterie et que, pour une raison quelconque, je n'avais rien de mieux à faire, je commencerais par Liskell et en ferais une langue à part entière, par opposition à une interface GHC, puis je simplifierais (et automatiserais) FFI. Bibliothèque C / C ++.
la source
Une bonne langue est une langue qui est:
Il est assez difficile de transformer cela en une liste de fonctionnalités, mais je pense que la programmation fonctionnelle, bien qu'elle ne semble pas naturelle , est plus proche de cela que la programmation impérative (en particulier pour cacher les détails les plus importants)
Pour le moment, le langage le plus proche de cette liste est probablement le haskell:
la source
A votre première question, "comment le feriez-vous" - réponse courte, je ne le ferais pas. Je n'ai pas assez de théorie de l'analyseur / compilateur pour retirer cela. Mais je programme depuis 25 ans et j’ai donc quelques idées et opinions à partager.
Tout d’abord, j’essayerais de proposer une approche POO permettant de créer des modèles vraiment connectés. Ce que je veux dire par là, c’est que les modèles sont l’un des éléments les plus importants dans presque tous les types de projets de programmation - il faut toujours beaucoup de travail ingrat et de refactorisation continue Langues OO.
Permettez-moi de démontrer. Disons qu'une maison de classe a une propriété Door.
Vous avez maintenant une variable locale avec une référence à l'instance Door.
Mais considérez ce qui vient de se passer: vous venez de déchirer la porte de la maison, et maintenant vous êtes plutôt heureux de la faire passer, et le reste de votre code ignore que cette porte est en fait attachée à une maison.
Pour moi, c'est fondamentalement faux.
Et oui, je sais, cela est "facilement" résolu au cas par cas - en maintenant une référence inverse de chaque porte vers la maison à laquelle elle est actuellement rattachée. Ceci ouvre évidemment votre modèle aux erreurs, puisqu'il est maintenant de votre devoir de maintenir avec précision deux références inverses, de sorte que vous rendez les propriétés House.Doors et Door.House privées et que vous ajoutez des méthodes telles que House.AddDoor (), House.RemoveDoor ( ), Door.SetHouse () etc., connectez le tout et testez-le à l'unité pour vous assurer qu'il fonctionne réellement.
N'est-ce pas commencer à ressembler à beaucoup de travail pour modéliser une relation aussi simple? Beaucoup de code à maintenir? Beaucoup de code à refactoriser à mesure que le modèle évolue?
Le problème est des pointeurs. Tous les langages OO que j'ai vus souffrent intrinsèquement du fait qu'une référence d'objet est en réalité un pointeur, car c'est ce que les ordinateurs utilisent.
Les pointeurs ne sont pas un bon moyen de modéliser le monde réel. Quel que soit le monde que vous essayez de modéliser, il est presque garanti que toutes les relations dans ce monde seront des relations à double sens. Les pointeurs pointent dans une seule direction.
J'aimerais voir un langage où le modèle de données fondamental est un graphe - où toutes les relations, par défaut, ont deux extrémités. Cela offrirait presque certainement un ajustement beaucoup plus naturel pour modéliser le monde réel, ce qui est vraiment la seule chose pour laquelle nous avons besoin d’ordinateurs au départ. (ça et les jeux vidéo.)
Je ne sais pas du tout à quoi ressemblerait la syntaxe d'un tel langage, ni même si elle pouvait même être exprimée en texte. (Je me suis demandé si un tel langage devrait être graphique, en quelque sorte ...)
J'aimerais aussi voir éliminer toutes les formes d'état accidentel.
Par exemple, dans le développement Web, nous passons beaucoup de temps à façonner des données à partir de bases de données, dans des modèles commerciaux, des modèles de vues pour présentation ... certaines de ces données sont ensuite présentées sur des formulaires, ce qui n’est en réalité qu’une autre transformation. .. et state proviennent des formulaires, puis nous remodelons ces données et les projetons sur le modèle de vue, par exemple, des classeurs de modèle de vue, etc., puis nous projetons à partir du modèle de vue sur l'entreprise. model ... nous utilisons ensuite des mappeurs relationnels-objets (ou grunt work) pour transformer les données du modèle-vue et les projeter sur une base de données relationnelle ...
Est-ce que cela commence à paraître redondant? À quel moment pendant toute cette folie avons-nous vraiment accompli quelque chose d'utile? Et par utile, je veux dire quelque chose de concret - quelque chose que l’utilisateur final peut comprendre et se préoccuper. À la fin de la journée, les heures que vous avez réellement consacrées à la création de quelque chose que les utilisateurs peuvent même comprendre sont réellement les seules heures bien dépensées. Tout le reste est des effets secondaires.
Je voudrais un langage très dynamique. Le cycle écriture / compilation / exécution est une perte de temps fastidieuse. Idéalement, le langage devrait simplement comprendre ce qui a changé et compiler / charger de manière transparente en arrière-plan, selon les besoins.
Idéalement, vous ne devriez même pas avoir à appuyer sur "Exécuter" - les choses doivent apparaître à l'écran, lorsque vous apportez des modifications, reflétant immédiatement les modifications que vous apportez. Le problème du cycle écriture / compilation / exécution, ou même du cycle écriture / exécution plus direct, est que vous êtes trop déconnecté de ce que vous faites. Pour vous sentir connecté à notre travail, nous besoin d'un retour immédiat, de résultats instantanés. Toute attente est trop longue!
Encore une fois, je ne sais même pas si cela pourrait être réalisé avec un IDE traditionnel ou si cela nécessiterait un tout nouveau type d'interface.
Vous devriez pouvoir utiliser un mélange de frappe faible et forte, ce qui convient le mieux au problème sur lequel vous travaillez.
L'état en général devrait être quelque chose que la langue gère entièrement pour vous. Pourquoi devriez-vous avoir besoin d'une base de données pour la persistance? Idéalement, j'aimerais pouvoir spécifier simplement la durée de vie de toute variable du modèle: une requête Web, une session, 24 heures sur 24, en permanence.
Pourquoi devons-nous choisir entre toute une gamme de solutions de stockage pour différents supports et conditions de vie? - sans parler de la transformation et de la mise en forme des données pour s'adapter à chaque média; cache du navigateur, base de données, mémoire, disque, peu importe! Les données sont des données. Où stocker vos données (et pendant combien de temps) devrait être un choix simple, pas une bataille contre les dieux!
Eh bien, bonne chance avec ça.
la source
Ce serait probablement un langage multi-paradigme, supportant les éléments suivants:
Pourquoi ceux-ci? Orienté objet car c'est un excellent moyen d'organiser de grands programmes, en particulier pour organiser les données. Structuré parce que vous ne voulez pas / besoin toujours (OOP), les gens devraient avoir le choix. Fonctionnel parce qu'il facilite le débogage pour les programmeurs et rend les programmes plus clairs.
J'utiliserais le modèle de Python avec des blocs en retrait pour marquer des blocs de code. C'est très clen et agréable à lire.
En fait, je volerais pas mal d’idées parce que Python est un très beau langage. Je prendrais cela pour une déclaration et je copierais ses cartes, sa liste et ses tuples.
Maintenant, je ne prendrais probablement pas les concepts dynamiques de Python: d’une part, ils seraient probablement typés de manière explicite et statique. Je pense que les programmes deviennent plus clairs avec cela. Les variables seraient probablement toutes des objets avec des méthodes, alors vous pourriez faire quelque chose comme
str.length()
obtenir la longueur d'une chaîne. Dans les définitions de fonction, vous devez spécifier le type de retour et les types des arguments (prenant également en charge certains types de types génériques).Revenons à la copie depuis Python ;-). J'aime sa façon d'avoir des arguments de procédure optionnels alors je l'aurais probablement. Python ne supporte cependant pas la surcharge de procédures, je le voudrais bien.
Regardons les classes, je laisserais tomber l'héritage multiple; trop facile d'abuser. Je mettrais en œuvre des portées privées et similaires et je mettrais probablement cela en œuvre de la même manière qu'en C ++. J'aurais aussi des classes abstraites et des interfaces; Je ne crois pas que Python a cela.
Cela soutiendrait les classes internes, en fait, je voudrais un langage orienté objet très puissant.
Cela serait probablement interprété. Il est possible de l'obtenir très rapidement en utilisant une bonne compilation JIT (je voudrais un langage rapide, bien que la productivité du programmeur passe avant tout) et la compilation est simplement mauvaise pour la productivité à plusieurs reprises. Les langues interprétées favorisent également l'indépendance des plateformes, ce qui compte de plus en plus pour chaque jour.
Il aurait intégré le support Unicode; l'internationalisation compte beaucoup aujourd'hui.
Ce serait certainement des ordures collectées. Zut je déteste faire la gestion de la mémoire moi-même; pas bon pour la productivité non plus.
Enfin, il aurait une bonne bibliothèque standard.
Wow, je viens de réaliser à quel point j'aime vraiment Python.
la source
Interpreted languages also promote platform independance
? Je suppose qu'il y a plus d'interprètes multiplateformes que de compilateurs (pourcentage), mais je ne peux pas comprendre pourquoi cette phrase devrait être vraie. Je pense qu'il n'y a aucune différence entre eux, en ce qui concerne les capacités multiplateformes.Tout d'abord, j'achèterais quelques livres sur les compilateurs, quelques normes et suivrais un ou deux cours de langues et de compilateurs. Je contribuerais PEP et assisterais aux réunions du comité de normalisation C ++. J'apporterais des correctifs aux compilateurs que j'utilise, espérons-le pour les fonctionnalités et les bogues.
Ensuite, je reviens avec horreur à la liste que je viens d’afficher et qui indique les directions dans lesquelles j’allerais avec une langue si j’avais commencé tout de suite:
Considérer que même ces points assez généraux changerait probablement rapidement si je commençais à mettre en place le langage, je pense donc qu'il est inutile d'entrer dans les détails.
la source
Si j'avais le temps, je concevrais un langage de programmation localisable basé sur Scala, de sorte qu'il aurait la plupart de ses fonctionnalités, sauf probablement pour XML. Mon objectif est de créer une langue qui se lit presque naturellement dans des langues ayant une structure différente de l'anglais, telle que l'arabe (ma langue maternelle). Je pense aux fonctionnalités suivantes:
#lang
directive pré-processeur , utilisée pour informer le pré-processeur du langage humain utilisé pour la programmation. Par exemple:#lang ar
autoriserait l’utilisation du motفئة
au lieu declass
,عرف
au lieu dedef
, et ainsi de suite. Les mots-clés spécifiques au langage humain seraient définis dans des fichiers de préprocesseur standard.class MyClass is composed of {
pour devenirclass MyClass {
et supprimera "en"def MyMethod(x: Int) as {
pour devenirdef MyMethod(x: Int) {
. Dans certaines langues (humaines), cela rendrait le code beaucoup plus facile à comprendre, en particulier pour les étudiants.اعرض طول اسم محمد
, ce qui équivaut àprint(length(name(Mohammad)))
programmation en anglais. (Les parenthèses sont pour la clarté.)Je pense que ces changements minimes apportés au pré-processeur et au compilateur faciliteraient grandement la programmation pour les non-anglophones.
la source
print
n’auront probablement pas besoin d’utiliser des bibliothèques externes, et créer des wrappers localisés pour certaines petites (par exemple ) ne ferait pas de mal.