Tipos interessantes ou únicos em linguagens de programação? [fechadas]


20

Todos nós vimos inteiro, ponto flutuante, string e o tipo decimal ocasional. Quais são alguns dos tipos mais estranhos, únicos ou úteis que você encontrou, úteis ou não?


Olá user10008, bem-vindo ao Programmers.SE! Você já consultou nossas perguntas frequentes ? Qual das seis diretrizes subjetivas você acha que sua pergunta atende?

4
Alguém gostaria de escrever a entrada para Lisp?
Mark C

Eu pensei que poderia ter sido um idiota, mas apenas porque minha resposta teria sido um idiota, então postarei um link e talvez você encontre algumas boas respostas: programmers.stackexchange.com/questions/724/…
Peter Turner

@ Mark: Eu tentei, mas os tipos são provavelmente uma das coisas menos interessantes sobre o Lisp.
Larry Coleman

@ LararC Eu pensei que essa era a pergunta perfeita para o Lisp por causa do uso generalizado de listas ! As listas formam a árvore de sintaxe e isso permite que você escreva funções que fazem coisas incríveis no seu código, pelo que entendi. Estou aprendendo Racket (anteriormente PLT Scheme ) agora. Lisp é a única linguagem de programação que eu tenho realmente motivado e interessado em aprender.
C #

Respostas:


18

Vou ser breve:

Maybe a

em Haskell.

Com essa construção simples, a linguagem resolve o problema das falhas ou NullPointerExceptionevita o "erro de um milhão de dólares" de Tony Hoare :)

Francamente, uma presença opcional verificada em tempo de compilação? É como um sonho ...


1
Ou Option, como é chamado em muitas outras linguagens de programação.
Jonas

@Jonas: Devo admitir que não gosto do Optionnome. Por que não Optional! Pode ser porque eu não sou falante nativo, mas Optionnão me transmite o significado "opcional".
Matthieu M.

O Maybenome é fofo: "O que você tem?" "Talvez um Int". No entanto, o mais interessante é que ele é um functor e uma mônada, o que, em termos simples, significa que você obtém propagação nula gratuitamente. Você nunca precisa colocar verificações nulas dentro de funções ou no meio do seu código; você só precisa verificá-lo no final do seu código, se houver.
Tikhon Jelvis


15

Eu sempre gosto void *. Provavelmente é um sintoma de algo profundamente defeituoso em mim.


2
Sim. Receio que seja exatamente o que é. :) Ah, +1 para "interessante" ao invés de "único". Objetivo-C obviamente tem void *e Pascal / Delphi Pointer.
precisa saber é o seguinte

haha mais de um não tipo, mas você não pode argumentar que não é poderoso
user10008

15
Eu simplesmente amo o pessimismo inerente que expressa: 'Você consegue ver aquela coisa ali?' 'Sim, o que é isso?', 'Não faço ideia.'
biziclop

Eu sempre achei engraçado não poder declarar um vazio, mas você pode pegar o endereço dele. Parece-me que com struct s {int A; vazio B; int C; } que o endereço de B deve ser o endereço do crack entre A e C. Mas não, não é permitido.
Andy Canfield

É por isso que em pascal "ponteiro" é usado para indicar um ponteiro genérico, e não confundir com "procedimento".
umlcat

14

Lua tem uma tabela interna que é mais impressionante. Possui uma hashtable e um vetor embutidos e, com o uso de meta-tabelas, pode ser a base fundamental para a programação orientada a objetos em uma linguagem procedural.

Cada índice de uma tabela pode receber qualquer uma das estruturas básicas de linguagem (número, booleano, string, função -y, funções são tipos em lua - e tabelas).


Observe como o Javascript é construído de maneira muito semelhante e o Python é construído com a mesma base, como provavelmente é o Ruby.
9000

Eu acho que isso também é possível em Perl e PHP, sim?
FrustratedWithFormsDesigner

Há uma diferença entre as tabelas em lua e os contêineres de hash em outros idiomas. Há uma diferença sutil de implementação na maneira como a lua distribui valores de hash que faz com que suas tabelas funcionem de maneiras quase mágicas. Geralmente programa em python e, de vez em quando, acho que estou usando suposições que não são válidas, com base em minhas expectativas de como as tabelas funcionam em lua. Um exemplo específico dessa mágica é que os números inteiros têm hash para si mesmos + 1. Isso significa que as chaves inteiras são compactadas densamente e que +0,0 e -0,0 têm o mesmo hash (são iguais)
SingleNegationElimination

9

Estou surpreso que ninguém tenha mencionado mônadas ou tipos de dados algébricos ainda.


Pode ser mostrar-nos exemplos :)
Nawfal



6

Fortran tem blocos comuns; é um dos tipos de dados menos comuns nas linguagens modernas ou, antes, uma maneira incomum de compartilhar dados com eficiência.

O Fortran 95 possui tipos de intervalo e aritmética de intervalo integrada.

A lista não estaria completa sem os tipos monádicos encontrados em Haskell. Para entendê-los, você precisa de um pouco de esforço.


Ah, os UniData / UniVerse DBs também têm blocos comuns em seu idioma interno (UniBasic).
Dan McGrath

Um bloco comum é um bloco de código usado por diferentes partes do programa?
C #

1
O @MarkC IIRC é basicamente um dado global, mas cada função acessada deve dizer explicitamente que está no topo
jk.

5

O Delphi possui conjuntos ( veja também ), que não acredito que sejam implementados da mesma maneira em outras línguas.

Isso facilita muito o armazenamento de atributos multivariáveis ​​nos bancos de dados: D


4

Suponho que é realmente apenas estranho proveniente da programação em uma arquitetura clássica, mas certamente um dos tipos mais difíceis de entender em primeiro lugar foi o registro quântico , que aparece na QCL .


3

PL / SQL permite declarar variáveis ​​do tipo my_table.some_column%type... Acho isso muito útil.

E o C # permite que você declare objetos como anuláveis ​​ou não, embora não tenha certeza de que conta como um tipo.


4
Mas cursor%rowtypeé ainda mais engraçado: é um tipo de registro formado dinamicamente que reflete quais colunas a consulta do cursor retorna.
9000

.NET "Nullable" é na verdade um tipo (genérico) em si.
27511 Konamiman

3

Eu tinha uma queda pelo meu coração pelos tipos de dados de Euphoria quando era mais jovem

Está estruturado da seguinte forma:

Object
-> Atom
-> Sequence
  • Atom = Um único valor numérico
  • Sequência = Uma sequência de Objetos

    -- 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
    

    Veja: O manual de referência

Nota: "jon" é realmente uma maneira curta de escrever a sequência de valores ASCII. Por exemplo, "ABCDEFG"é o mesmo que{65, 66, 67, 68, 69, 70, 71}


7
Isso é parecido com LISP ...
FrustratedWithFormsDesigner

Os tipos de dados reais são o único bit.
precisa saber é o seguinte

1
@FrustratedWithForms Mesmo, pensei: "Ei, ele disse: 'Atom'! Isso parece (a) Lisp, mas com divisórias desnecessárias.: P
Mark C

3

Felix tem tipos de somas anônimas. O tipo é escrito como:

typedef il = int + long;

como seria em teoria. Os valores são feios:

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

exceto talvez por uma soma unitária como 3 = 1 + 1 + 1

case 0 of 3
case 1 of 3 

que, infelizmente, usa origem zero contando para "compatibilidade C". Somas anônimas são necessárias para tipos algébricos de tipo estrutural, por exemplo:

(1 + T * li) as li

é uma lista (ligada a um só) de T. Todos os outros idiomas que conheço de somas nominalmente tipificadas necessárias, em que tanto o tipo em si quanto os construtores devem receber nomes.

A abreviação 3 usada acima é fofa, o seguinte está na biblioteca:

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

e esta notação:

 T ^ 3

é uma matriz de comprimento estático 3. o 3 não é um número inteiro, mas uma soma de 3 unidades. Que pena + não é associativo :)


2

q / kdb + possui tabelas embutidas. Como é uma linguagem de programação e um banco de dados orientado a colunas em um, não há necessidade de LINQ ou ORMs.

Por exemplo, pode criar uma tabela como esta (a atribuição é distinta por :e não =na maioria dos idiomas):

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

Agora eu posso olhar para a minha mesa:

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

E eu posso consultá-lo:

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

2

Eu achei o sindicato em C ++ muito peculiar quando ouvi falar deles. Ainda não cheguei a um cenário em que elas sejam a escolha óbvia para implementar.


3
As uniões vieram de C. Um bom exemplo é a estrutura zval no php.
Martin Wickman

2
Eu os usei em um emulador Z80, para acessar facilmente os registros de 16 bits como registros inteiros (HL, BC) e como registros de 8 bits (H, L, B e C). Isso reflete como eles são usados ​​no Z80 asm. Também em "variantes", uma classe que pode conter um valor de diferentes tipos (por exemplo, int / float) - não tenho certeza por que não usar subclasses, mas fazia sentido no momento :)
ggambett

@ggambett: Eu fiz exatamente o mesmo para meus programas Z80! Só que eu também adicionei um campo de bits para acessar sinalizadores individuais no registro F.
27511 Konamiman

2

Ainda estou tentando entender o que uma função multiparâmetros se torna em F # e outras linguagens funcionais. Basicamente, int f (Foo, Bar) se torna func f (Foo)

Essa é a função de dois parâmetros que pega um Foo, e uma barra e retorna um int é realmente uma função de um parâmetro que pega um Foo e retorna uma função de um parâmetro que pega uma barra e retorna um int. Mas, de alguma forma, você pode chamá-lo com dois parâmetros, se quiser. Eu escrevi um post sobre isso aqui


8
Em vez disso, uma função f(Foo, Bar)é igual à função f(Foo)que retorna outra função f'(Bar)que retorna o valor que f(Foo, Bar)retornaria. Ou seja, se você corrigir o argumento 'Foo', mas não 'Bar', terá uma função que não depende de 'Foo', mas ainda depende do argumento 'Bar'. Isso é típico para linguagens funcionais; é chamado de 'currying'.
9000

2

Expressões regulares:

São objetos extremamente poderosos e compactos.
Os idiomas que os incorporam têm grande capacidade de manipular o texto (não vamos ouvir a palavra analisar, eles não são tão bons).


2
É perfeitamente possível analisar muitas gramáticas simples com expressões regulares. Por exemplo, é relativamente trivial analisar um arquivo ini com um mínimo de lógica em cima de um conjunto de expressões regulares. O erro que muitas pessoas cometem é tentar analisar gramáticas muito complexas com ele (por exemplo, XML / HTML).
Matthew Scharley


@ Mark C: O topo da resposta é (com um recorde de 4320 votos). Você não pode
Martin York

Sim, isso foi por humor. Me veio à mente quando li o comentário de Matthew.
Mark C

2

Um punhado de idiomas na família funcional possui uma classe de tipos conhecida como Unity. A característica distintiva dos tipos Unity é que eles não contêm informações, são tipos de zero bits. Um tipo de unidade (em algumas variações) também é seu único valor ou (na maioria dos outros) tem apenas um valor (que não é, por si só, um tipo).

Porém, eles são úteis porque são tipos distintos. Como você não pode converter implicitamente de um tipo de unidade para outro, você pode colocar a verificação de tipo estático para funcionar de maneira muito eficiente e expressiva.

Unidade também é a maneira como a maioria dessas linguagens descreve as Enums, permitindo que um novo tipo seja um de um conjunto definido de outros tipos, ou para descrever talvez tipos, valores que podem ser o valor de um tipo típico (digamos, um número inteiro) ou tenha um valor que represente nenhum valor.

Algumas linguagens que não empregam a riqueza de tipos de unidade definidos pelo usuário ainda possuem unidade, de uma forma ou de outra. Por exemplo, Python tem pelo menos três tipos de unidade, NoneType, NotImplementedType, e EllipsisType. É interessante que os dois primeiros signifiquem algo como "Sem valor", mas o terceiro é usado em valores complexos (especificamente, expressões de fatia) para representar casos especiais interessantes.

Outros exemplos interessantes de unidade incluem NULLsql e undefinedjavascript, mas não voidem C ou C ++. voidfalha. Mesmo que descreva um valor sem informação, mas nenhum valor real pode ser do tipo void.


Eu acho que você quer dizer "tipo de unidade".
Jason Baker

2

O symboltipo de Ruby é um pouco incomum. É essencialmente uma string implementando o padrão singleton. Ou alguma coisa. Até agora, descobri que os melhores usos para símbolos estão no rastreamento de estados e na passagem de nomes de funções.


Também como chaves para um mapa para comparação de chaves O (1).
Jeremy Heiler

Bem, não é realmente tão incomum. Ruby o herdou do Smalltalk, que o herdou do Lisp. Scala também tem, eu acho. De fato, quase toda implementação de linguagem (compilador ou intérprete) possui uma tabela de símbolos internamente, Lisp, Smalltalk e Ruby apenas a expõem ao programador.
Jörg W Mittag

1

COBOL. Essencialmente, apenas dois tipos de dados básicos, seqüências de caracteres e números, mas você precisa especificar exatamente como eles são dispostos na memória, por exemplo PIC S9(5)V99 COMP-3.


Eu posso vencer isso. BCPL tem um tipo de dados - palavra; veja en.wikipedia.org/wiki/BCPL
Stephen C

Existem diferentes tipos de números (COMP, COMP-1, COMP-2, COMP-3).
David Thornley

Isso parece horrível. Você pode elaborar o que esses detalhes significam?
C #

S= assinado, 9(5)= 5 dígitos, V= ponto decimal implícito, 99= mais 2 dígitos, COMP-3= BCD + sinal de nybble.
precisa saber é

1

O Clipper tinha 'Code Blocks', que eram semelhantes aos métodos anônimos. Eles poderiam ser repassados ​​e avaliados conforme necessário, geralmente como uma forma de retorno de chamada. Você costuma usá-los para realizar cálculos em tempo real ao apresentar tabelas de dados.


0

VHDL tem tipos físicos. Um literal desse tipo inclui um valor e uma unidade. Você também pode definir subunidades. Por exemplo, um tipo físico predefinido é 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;

Juntamente com a sobrecarga do operador, você pode definir coisas muito interessantes.


0

Clojure é interessante porque tem um meta-conceito de "abstrações" que permeiam a linguagem. Exemplos:

  • Colecções
  • Sequências (preguiçosas e não preguiçosas)
  • Funções de ordem superior
  • Multimétodos
  • Protocolos
  • Referências gerenciadas
  • Macros
  • vários outros .....

Até certo ponto, as abstrações levam o " princípio da responsabilidade única " ao extremo. Cabe a você compô-las para obter a funcionalidade desejada, mas você pode ser extremamente flexível sobre como as cola.

Por exemplo, se você quiser um sistema OOP baseado em classe com herança, poderá criar uma dessas abstrações principais de maneira relativamente rápida.

Na prática, as abstrações são projetadas de uma maneira que várias implementações são possíveis, por exemplo, através de interfaces específicas como clojure.lang.ISeq para seqüências ou clojure.lang.IFn para funções de ordem superior.

Há um vídeo interessante sobre esse tópico: A arte da abstração


0

Se você deseja um idioma com um tipo único, siga para BCPL . Esse idioma possui apenas um tipo de dados, a palavra, sendo um número fixo de bits para a implementação do idioma.


0

O Googles Go possui um tipo de "canal" bastante exclusivo.


1
Canais não são únicos. Muitos idiomas os possuem. Felix os tinha 10 anos antes da existência do Google :) Ocaml os tinha 10 anos antes da existência de Felix.
Yttrill

E havia pelo menos um outro idioma que tinha canais antes da existência de Ocaml. Ainda é um dos tipos menos disponíveis nas linguagens de programação.
Brainlag
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.