Types intéressants ou uniques dans les langages de programmation? [fermé]


20

Nous avons tous vu entier, virgule flottante, chaîne et le type décimal occasionnel. Quels sont les types les plus étranges, uniques ou utiles que vous avez rencontrés, utiles ou non?


Salut user10008, bienvenue chez Programmers.SE! Avez-vous consulté notre FAQ ? Selon vous, laquelle des six directives subjectives répond à votre question?

4
Quelqu'un aimerait-il écrire l'entrée pour Lisp?
Mark C

Je pensais que ça aurait pu être une dupe, mais seulement parce que ma réponse aurait été une dupe, alors je posterai un lien et vous trouverez peut-être de bonnes réponses: programmers.stackexchange.com/questions/724/…
Peter Turner

@Mark: J'ai essayé, mais les types sont probablement l'une des choses les moins intéressantes à propos de Lisp.
Larry Coleman,

@LarryC Je pensais que c'était la question parfaite pour Lisp en raison de l'utilisation omniprésente des listes ! Les listes forment l'arbre de syntaxe et cela vous permet d'écrire des fonctions qui font des choses incroyables dans votre code, je suppose. J'apprends Racket (anciennement PLT Scheme ) maintenant. Lisp est le seul langage de programmation que j'ai vraiment été motivé et intéressé à apprendre.
Mark C

Réponses:


18

Je serai court:

Maybe a

à Haskell.

Avec cette construction simple, le langage résout le problème des plantages ou NullPointerException, il contourne proprement le "One Million Mistake" de Tony Hoare :)

Franchement, une présence facultative vérifiée au moment de la compilation? C'est onirique ...


1
Ou Option comme on l'appelle dans de nombreux autres langages de programmation.
Jonas

@Jonas: Je dois admettre que je n'aime pas le Optionnom. Pourquoi pas Optional! C'est peut-être parce que je ne suis pas un locuteur natif, mais Optionne me transmet pas le sens «facultatif».
Matthieu M.

Le Maybenom est mignon: "Qu'est-ce que tu as?" "Peut-être un Int". Cependant, ce qui est vraiment intéressant, c'est qu'il s'agit à la fois d'un foncteur et d'une monade, ce qui signifie, en clair, que vous obtenez gratuitement la propagation nulle. Vous n'avez jamais besoin de mettre des contrôles nuls à l'intérieur des fonctions ou au milieu de votre code; il vous suffit de le vérifier à la toute fin de votre code, voire pas du tout.
Tikhon Jelvis


15

Je l'aime toujours void *. C'est probablement le symptôme de quelque chose de profondément imparfait en moi.


2
Oui. J'ai bien peur que ce soit exactement ça. :) Oh, +1 pour "intéressant" plutôt que "unique". Objective-C a évidemment void *et Pascal / Delphi ont Pointer.
Frank Shearar,

haha plus d'un type non, mais vous ne pouvez pas affirmer qu'il n'est pas puissant
user10008

15
J'aime juste le pessimisme inhérent qu'il exprime: «Pouvez-vous voir cette chose là-bas? "Oui, qu'est-ce que c'est?", "Aucune idée."
biziclop

J'ai toujours pensé que c'était drôle que vous ne puissiez pas déclarer un vide mais vous pouvez en prendre l'adresse. Il me semble qu'avec struct s {int A; vide B; int C; } que l'adresse de B soit l'adresse de la fissure entre A et C. Mais non, pas autorisé.
Andy Canfield

C'est pourquoi en pascal "pointeur" est utilisé pour désigner un pointeur générique, et ne pas confondre avec "procédure".
umlcat

14

Lua a une table intégrée qui est la plus impressionnante. Il a une table de hachage et un vecteur intégrés, et avec l'utilisation de métatables peut être la base fondamentale de la programmation orientée objet dans un langage procédural.

Chaque index d'une table peut recevoir n'importe quelle structure de langage de base (nombre, booléen, chaîne, fonction -oui, les fonctions sont des types sur lua - et tables).


Notez comment Javascript est construit de manière très similaire, et Python est construit sur la même base, comme probablement Ruby.
9000

Je pense que c'est également possible en Perl et PHP, oui?
FrustratedWithFormsDesigner

Il y a une différence entre les tables en lua et les conteneurs de hachage dans d'autres langues. Il existe une subtile différence d'implémentation dans la façon dont lua distribue les valeurs de hachage qui fait fonctionner ses tables de manière presque magique. Je programme principalement en python, et à l'occasion, je trouve que j'utilise des hypothèses qui ne tiennent pas, en fonction de mes attentes concernant le fonctionnement des tables dans lua. Un exemple spécifique de cette magie est que les entiers sont hachés à eux-mêmes + 1. Cela signifie que les clés entières sont compressées de manière dense et que +0.0 et -0.0 ont le même hachage (ils sont égaux)
SingleNegationElimination

9

Je suis surpris que personne n'ait encore mentionné les monades ou les types de données algébriques.


Peut-être montrez-nous des exemples :)
nawfal

8

Lisp a deux types intéressants: tet nil. Ce qui est intéressant chez eux, c'est que tout est un tet rien n'est un nil.


Es-tu sérieux? Je ne le savais pas.
Mark C

Est nilun t?
Jon Harrop


6

Fortran a des blocs communs; c'est l'un des types de données les moins courants dans les langues modernes, ou plutôt une manière inhabituelle de partager efficacement des données.

Fortran 95 a des types d'intervalles et des arithmétiques d'intervalles intégrés.

La liste ne serait pas complète sans types monadiques trouvés à Haskell. Pour les comprendre, il faut un peu d'effort.


Ah, les bases de données UniData / UniVerse ont également des blocs communs dans leur langage interne (UniBasic).
Dan McGrath

Un bloc commun est-il un bloc de code utilisé par différentes parties du programme?
Mark C

1
@MarkC IIRC ses données essentiellement globales, mais chaque fonction qui accède doit dire explicitement qu'elle va en haut
jk.

5

Delphi a des ensembles ( voir aussi ), qui, je ne pense pas, sont implémentés de la même manière dans d'autres langages.

Cela rend le stockage d'attributs multi-variables dans les bases de données un jeu d'enfant: D


4

Je suppose que c'est vraiment étrange de la programmation sur une architecture classique, mais certainement l'un des types les plus difficiles pour moi de tourner la tête au début était le registre quantique , qui apparaît dans QCL .


3

PL / SQL vous permet de déclarer des variables de type my_table.some_column%type... Je trouve ça sacrément utile.

Et C # vous permet de déclarer des objets comme nullables ou non, même si je ne suis pas sûr que cela compte comme un type.


4
Mais cursor%rowtypec'est encore plus drôle: c'est un type d'enregistrement formé dynamiquement qui reflète les colonnes que la requête du curseur renvoie.
9000

.NET "Nullable" est en fait un type (générique) en soi.
Konamiman

3

J'avais un faible pour mon cœur les types de données d' Euphoria quand j'étais plus jeune

Il est structuré comme suit:

Object
-> Atom
-> Sequence
  • Atom = Une seule valeur numérique
  • Séquence = une séquence d'objets

    -- examples of atoms:
    
    0
    98.6
    -1e6
    
    -- examples of sequences:
    
    {2, 3, 5, 7, 11, 13, 17, 19}
    {1, 2, {3, 3, 3}, 4, {5, {6}}}
    {{"jon", "smith"}, 52389, 97.25}
    {}                        -- the 0-element sequence
    

    Voir: Le manuel de référence

Remarque: "jon" est en fait un moyen rapide d'écrire la séquence de valeurs ASCII. Par exemple, "ABCDEFG"c'est la même chose que{65, 66, 67, 68, 69, 70, 71}


7
Cela ressemble à LISP ...
FrustratedWithFormsDesigner

Les types de données réels sont le seul bit.
Dan McGrath

1
@FrustratedWithForms Idem, je me suis dit: "Hé, il a dit 'Atom'! Cela ressemble à (a) Lisp mais avec des séparateurs inutiles.: P
Mark C

3

Felix a des types de somme anonymes. Le type est écrit comme:

typedef il = int + long;

comme ce serait en théorie. Les valeurs sont moches:

case 0 of il (1)
case 1 of il (2L)

sauf peut-être pour une somme unitaire telle que 3 = 1 + 1 + 1

case 0 of 3
case 1 of 3 

qui utilise malheureusement zéro origine pour la "compatibilité C". Des sommes anonymes sont nécessaires pour les types algébriques structurellement typés, par exemple:

(1 + T * li) as li

est une liste (liée individuellement) de T. Toutes les autres langues que je connais des sommes typiquement requises, où le type lui-même et les constructeurs doivent recevoir des noms.

Le raccourci 3 utilisé ci-dessus est mignon, ce qui suit est dans la bibliothèque:

typedef void = 0;
typedef unit = 1;
typedef bool = 2;

et cette notation:

 T ^ 3

est un tableau de longueur statique 3 .. le 3 n'est pas un entier mais une somme de 3 unités. Quel dommage + n'est pas associatif :)


2

q / kdb + a des tables intégrées. Puisqu'il s'agit d'un langage de programmation et d'une base de données orientée colonne en un, il n'y a pas besoin de LINQ ou d'ORM.

Par exemple, peut créer une table comme celle-ci (l'affectation est distinguée par :plutôt que =comme dans la plupart des langues):

people:([]name:`Joe`Amy`Sarah; age:17 15 18; GPA:3.5 3.8 3.33)

Maintenant je peux regarder ma table:

q)show people
name  age GPA 
--------------
Joe   17  3.5 
Amy   15  3.8 
Sarah 18  3.33

Et je peux l'interroger:

q)select from people where GPA>3.4
name age GPA
------------
Joe  17  3.5
Amy  15  3.8

2

J'ai trouvé que les syndicats en C ++ étaient «originaux» quand j'ai entendu parler d'eux pour la première fois. Je n'ai toujours pas atteint un scénario où ils sont le choix évident à mettre en œuvre.


3
Les syndicats venaient de C. Un bon exemple est la structure zval en php.
Martin Wickman,

2
Je les ai utilisés dans un émulateur Z80, pour accéder facilement aux registres 16 bits en tant que registres entiers (HL, BC) et en tant que registres 8 bits (H, L, B et C). Cela reflète la façon dont ils sont utilisés dans l'asm Z80. Toujours dans "variantes", une classe qui peut contenir une valeur de différents types (par exemple int / float) - je ne sais pas pourquoi je n'ai pas utilisé de sous-classes, mais cela avait du sens à l'époque :)
ggambett

@ggambett: J'ai fait exactement la même chose pour mes programmes Z80! Seulement, j'ai également ajouté un champ de bits pour accéder aux drapeaux individuels dans le registre F.
Konamiman

2

J'essaie toujours de comprendre ce qu'une fonction multi-paramètres devient en F # et dans d'autres langages fonctionnels. Fondamentalement, int f (Foo, Bar) devient func f (Foo)

C'est la fonction à deux paramètres qui prend un Foo, et une barre et retourne un int est vraiment une fonction à un paramètre qui prend un Foo et renvoie une fonction à un paramètre qui prend une barre et retourne un int. Mais vous pouvez l'appeler avec deux paramètres si vous le souhaitez. J'ai écrit un article à ce sujet ici


8
Au lieu de cela, une fonction f(Foo, Bar)est la même que la fonction f(Foo)qui renvoie une autre fonction f'(Bar)qui renvoie la valeur qui f(Foo, Bar)retournerait. Autrement dit, si vous corrigez l'argument «Foo», mais pas «Bar», vous avez une fonction qui ne dépend pas de «Foo» mais dépend toujours de l'argument «Bar». Ceci est typique des langages fonctionnels; cela s'appelle «curry».
9000

2

Expressions régulières:

Ce sont des objets extrêmement puissants mais compacts.
Les langues qui les ont intégrées ont une grande capacité à manipuler du texte (ne permet pas d'entendre le mot analyser, elles ne sont pas si bonnes).


2
Il est tout à fait possible d'analyser de nombreuses grammaires simples avec des expressions rationnelles. Par exemple, il est relativement trivial d'analyser un fichier ini avec un minimum de logique au-dessus d'un ensemble d'expressions régulières. L'erreur que beaucoup de gens font est d'essayer d'analyser des grammaires très complexes avec lui (c'est-à-dire XML / HTML).
Matthew Scharley


@Mark C: La réponse est en haut (avec un record de 4320 votes). Vous ne pouvez pas
Martin York

Oui, c'était pour l'humour. Cela m'est venu à l'esprit lorsque j'ai lu le commentaire de Matthew.
Mark C

2

Une poignée de langues de la famille fonctionnelle ont une classe de types connue sous le nom d'Unity. La particularité des types Unity est qu'ils ne contiennent aucune information, ce sont des types à zéro bit. Un type d'unité (dans certaines variantes) est également sa seule valeur, ou (dans la plupart des autres) n'a qu'une seule valeur (qui n'est pas elle-même un type).

Ils sont cependant utiles, car ce sont des types distincts. Comme vous ne pouvez pas implicitement convertir d'un type d'unité à un autre, vous pouvez utiliser la vérification de type statique de manière très efficace et expressive.

L'unité est également la façon dont la plupart de ces langages décrivent les Enums, en permettant à un nouveau type d'être l'un d'un ensemble défini d'autres types, ou de décrire peut - être des types, des valeurs qui peuvent être soit une valeur d'un type typique (par exemple, un entier) ou ont une valeur qui représente aucune valeur.

Certains langages qui n'utilisent pas la richesse des types d'unités définis par l'utilisateur contiennent toujours l'unité, sous une forme ou une autre. Par exemple, Python a au moins trois types d'unité, NoneType, NotImplementedTypeet EllipsisType. Il est intéressant de noter que les deux premiers signifient tous deux quelque chose comme "Aucune valeur", mais le troisième est utilisé dans des valeurs complexes (en particulier, des expressions de tranche) pour représenter des cas spéciaux intéressants.

D'autres exemples intéressants d'unité incluent NULLen sql et undefineden javascript, mais pas voiden C ou C ++. voidéchoue. Même si elle décrit une valeur sans information, mais aucune valeur réelle ne peut être de type void.


Je pense que vous voulez dire "type d'unité".
Jason Baker,

2

Le symboltype de Ruby est un peu inhabituel. Il s'agit essentiellement d'une chaîne implémentant le modèle singleton. Ou quelque chose. Jusqu'à présent, j'ai trouvé que les meilleures utilisations des symboles étaient les états de suivi et les noms de fonction.


Également comme clés d'une carte pour la comparaison des clés O (1).
Jeremy Heiler

Eh bien, ce n'est pas vraiment si inhabituel. Ruby l'a hérité de Smalltalk, qui l'a hérité de Lisp. Scala l'a aussi, je pense. En fait, presque chaque implémentation de langage (compilateur ou interprète) a une table de symboles en interne, Lisp, Smalltalk et Ruby l'exposent simplement au programmeur.
Jörg W Mittag

1

COBOL. Essentiellement, seuls deux types de données de base, des chaînes et des nombres, mais vous devez spécifier exactement comment ils sont disposés en mémoire, par exemple PIC S9(5)V99 COMP-3.


Je peux battre ça. BCPL a un type de données - mot; voir en.wikipedia.org/wiki/BCPL
Stephen C

Il existe différents types de nombres (COMP, COMP-1, COMP-2, COMP-3).
David Thornley

Ça a l'air horrible. Pouvez-vous expliquer ce que ces détails signifient?
Mark C

S= signé, 9(5)= 5 chiffres, V= virgule décimale implicite, 99= 2 chiffres supplémentaires, COMP-3= BCD + signe nybble.
dan04

1

Clipper avait des «blocs de code», qui étaient similaires aux méthodes anonymes. Ils peuvent être transmis et évalués au besoin, généralement sous forme de rappel. Vous les utiliseriez souvent pour des choses comme effectuer des calculs à la volée lors de la présentation de tableaux de données.


0

VHDL a des types physiques. Un littéral de ce type comprend à la fois une valeur et une unité. Vous pouvez également définir des sous-unités. Par exemple, un type physique prédéfini est time:

type time is range <machine dependant> to <machine dependant> 
units
  fs;
  ps = 1000 fs;
  ns = 1000 ps;
  us = 1000 ns;
  Ms = 1000 us;
  sec = 1000 ms;
  min = 60 sec;
  hr = 60 min;
end units;

Avec la surcharge de l'opérateur, vous pouvez définir des choses très intéressantes.


0

Clojure est intéressant car il a un méta-concept "d'abstractions" qui imprègne le langage. Exemples:

  • Les collections
  • Séquences (paresseux et non paresseux)
  • Fonctions d'ordre supérieur
  • Multiméthodes
  • Protocoles
  • Références gérées
  • Macros
  • divers autres .....

Dans une certaine mesure, les abstractions poussent à l'extrême le " principe de responsabilité unique ". C'est à vous de les composer pour obtenir les fonctionnalités que vous souhaitez, mais vous pouvez être extrêmement flexible sur la façon de les coller ensemble.

Par exemple, si vous voulez un système OOP basé sur une classe avec héritage, vous pouvez en créer une à partir de ces abstractions de base assez rapidement.

En pratique, les abstractions elles-mêmes sont conçues de manière à ce que plusieurs implémentations soient possibles, par exemple via des interfaces spécifiques comme clojure.lang.ISeq pour les séquences ou clojure.lang.IFn pour les fonctions d'ordre supérieur.

Il y a une vidéo intéressante sur ce sujet: L'art de l'abstraction


0

Si vous voulez une langue avec un type unique, dirigez-vous vers BCPL . Cette langue n'a qu'un seul type de données, le mot, étant un nombre fixe de bits pour l'implémentation de la langue.


0

Googles Go a un type "Channel" qui est tout à fait unique.


1
Les chaînes ne sont pas uniques. De nombreuses langues en ont. Felix les avait 10 ans avant que Google existe :) Ocaml les avait 10 ans avant que Felix existe.
Yttrill

Et il y avait au moins une autre langue qui avait des canaux avant que Ocaml existe. Encore l'un des types les moins disponibles dans les langages de programmation.
Brainlag
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.