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?
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?
Respostas:
Vou ser breve:
Maybe a
em Haskell.
Com essa construção simples, a linguagem resolve o problema das falhas ou NullPointerException
evita 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 ...
Option
nome. Por que não Optional
! Pode ser porque eu não sou falante nativo, mas Option
não me transmite o significado "opcional".
Maybe
nome é 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.
Maybe
mônada para Ruby: lostechies.com/derickbailey/2010/10/10/the-maybe-monad-in-ruby
Eu sempre gosto void *
. Provavelmente é um sintoma de algo profundamente defeituoso em mim.
void *
e Pascal / Delphi Pointer
.
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).
Estou surpreso que ninguém tenha mencionado mônadas ou tipos de dados algébricos ainda.
Lisp tem dois tipos interessantes: t
e nil
. O interessante sobre eles é que tudo é um t
e nada é um nil
.
nil
um t
?
SNOBOL: pattern (essencialmente uma árvore do analisador LL (1), se bem me lembro).
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.
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
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 .
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.
cursor%rowtype
é ainda mais engraçado: é um tipo de registro formado dinamicamente que reflete quais colunas a consulta do cursor retorna.
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
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}
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 :)
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
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.
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
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'.
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).
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 NULL
sql e undefined
javascript, mas não void
em C ou C ++. void
falha. Mesmo que descreva um valor sem informação, mas nenhum valor real pode ser do tipo void
.
O symbol
tipo 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.
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
.
S
= assinado, 9(5)
= 5 dígitos, V
= ponto decimal implícito, 99
= mais 2 dígitos, COMP-3
= BCD + sinal de nybble.
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.
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.
Clojure é interessante porque tem um meta-conceito de "abstrações" que permeiam a linguagem. Exemplos:
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
O Googles Go possui um tipo de "canal" bastante exclusivo.