Wszyscy widzieliśmy liczbę całkowitą, zmiennoprzecinkową, łańcuch i okazjonalny typ dziesiętny. Jakie są najbardziej dziwne, unikalne lub przydatne typy, z którymi się spotkałeś, przydatne czy nie?
Wszyscy widzieliśmy liczbę całkowitą, zmiennoprzecinkową, łańcuch i okazjonalny typ dziesiętny. Jakie są najbardziej dziwne, unikalne lub przydatne typy, z którymi się spotkałeś, przydatne czy nie?
Odpowiedzi:
Będę krótki:
Maybe a
w Haskell.
Dzięki tej prostej konstrukcji język rozwiązuje problem awarii lub NullPointerException
zgrabnie omija „One Million Mistake” Tony'ego Hoare'a :)
Szczerze mówiąc, opcjonalna obecność sprawdzana w czasie kompilacji? To marzenie ...
Option
imię. Dlaczego nie Optional
! Może dlatego, że nie jestem native speakerem, ale Option
nie przekazuje mi „opcjonalnego” znaczenia.
Maybe
Nazwa jest słodkie: „Co masz?” „Może int”. Jednak naprawdę schludne jest to, że jest to zarówno funktor, jak i monada, co, mówiąc prosto, oznacza, że otrzymujesz zerową propagację za darmo. Nigdy nie musisz umieszczać kontroli zerowej w funkcjach lub w środku kodu; wystarczy, że w ogóle to sprawdzisz na samym końcu kodu.
Maybe
Dla Ruby jest monada: lostechies.com/derickbailey/2010/10/10/the-maybe-monad-in-ruby
Od zawsze lubię void *
. Prawdopodobnie jest to objaw czegoś głęboko we mnie wadliwego.
void *
i Pascal / Delphi Pointer
.
Lua ma wbudowany stół, który robi największe wrażenie. Ma wbudowany hashtable i wektor, a przy użyciu metatablów może być podstawową podstawą programowania obiektowego w języku proceduralnym.
Każdy indeks tabeli może odbierać dowolną z podstawowych struktur językowych (liczba, wartość logiczna, ciąg, funkcja-tak, funkcje są typami w lua - i tabele).
Dziwię się, że nikt jeszcze nie wspomniał o Monadach ani Algebraicznych Typach Danych.
Lisp ma dwa ciekawe typy: t
i nil
. Interesujące w nich jest to, że wszystko jest t
i nic nie jestnil
.
nil
t
SNOBOL: wzorzec (zasadniczo drzewo analizatora składni LL (1), jeśli dobrze go pamiętam).
Fortran ma wspólne bloki; jest to jeden z najmniej popularnych typów danych we współczesnych językach lub raczej nietypowy sposób efektywnego udostępniania danych.
Fortran 95 ma typy interwałów i wbudowaną arytmetykę interwałów.
Lista nie byłaby kompletna bez typów monadycznych znalezionych w Haskell. Aby je zrozumieć, potrzebujesz trochę wysiłku.
Delphi ma zestawy ( patrz także ), które, jak sądzę, nie są implementowane w ten sam sposób w innych językach.
To sprawia, że przechowywanie atrybutów o wielu zmiennych w bazach danych jest dziecinnie proste: D
Przypuszczam, że to naprawdę dziwne, że pochodzi z programowania na klasycznej architekturze, ale z pewnością jednym z najtrudniejszych rodzajów, dla których na początku zawinąłem głowę, był rejestr kwantowy , który pojawia się w QCL .
PL / SQL pozwala zadeklarować zmienne typu my_table.some_column%type
... Uważam, że to cholernie przydatne.
A C # pozwala zadeklarować obiekty jako zerowalne lub nie, chociaż nie jestem pewien, czy liczy się to jako typ.
cursor%rowtype
jest jeszcze zabawniejszy: jest to dynamicznie formowany typ rekordu, który odzwierciedla, które kolumny zwraca zapytanie kursora.
Miałem słabość w sercu Euphoria typów danych „s, kiedy byłem młodszy
Ma następującą strukturę:
Object
-> Atom
-> Sequence
Sekwencja = Sekwencja obiektów
-- 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
Zobacz: Podręcznik referencyjny
Uwaga: „jon” jest w rzeczywistości krótkim sposobem na napisanie sekwencji wartości ASCII. Na przykład "ABCDEFG"
jest taki sam jak{65, 66, 67, 68, 69, 70, 71}
Felix ma anonimowe typy sum. Typ jest zapisany w następujący sposób:
typedef il = int + long;
jak byłoby w teorii. Wartości są brzydkie:
case 0 of il (1)
case 1 of il (2L)
z wyjątkiem być może sumy jednostkowej, takiej jak 3 = 1 + 1 + 1
case 0 of 3
case 1 of 3
który niestety wykorzystuje zerowe liczenie początku dla „zgodności C”. Anonimowe sumy są niezbędne dla strukturalnie typowanych typów algebraicznych, na przykład:
(1 + T * li) as li
jest (pojedynczo połączoną) listą T. Wszystkie inne języki, jakie znam, o wymaganych nominalnie wpisanych sumach, przy czym zarówno sam typ, jak i konstruktory muszą mieć nazwy.
Skrót 3 użyty powyżej jest uroczy, w bibliotece znajduje się:
typedef void = 0;
typedef unit = 1;
typedef bool = 2;
i ta notacja:
T ^ 3
jest tablicą o długości statycznej 3 .. 3 nie jest liczbą całkowitą, ale sumą 3 jednostek. Jaka szkoda + nie kojarzy się :)
q / kdb + ma wbudowane tabele. Ponieważ jest to język programowania i zorientowana na kolumny baza danych w jednym, nie ma potrzeby korzystania z LINQ ani ORM.
Na przykład można utworzyć tabelę podobną do tej (przypisanie wyróżnia się :
raczej niż =
w większości języków):
people:([]name:`Joe`Amy`Sarah; age:17 15 18; GPA:3.5 3.8 3.33)
Teraz mogę spojrzeć na mój stół:
q)show people
name age GPA
--------------
Joe 17 3.5
Amy 15 3.8
Sarah 18 3.33
I mogę zapytać:
q)select from people where GPA>3.4
name age GPA
------------
Joe 17 3.5
Amy 15 3.8
Kiedy po raz pierwszy o nich usłyszałem, związek w C ++ był „dziwaczny”. Nadal nie natrafiłem na scenariusz, w którym są oczywistym wyborem do wdrożenia.
Wciąż próbuję zawinąć głowę wokół tego, czym staje się funkcja wieloparametrowa w języku F # i innych językach funkcjonalnych. Zasadniczo int f (Foo, Bar) staje się func f (Foo)
Jest to funkcja dwuparametrowa, która pobiera Foo, a Bar i zwraca int jest tak naprawdę funkcją jednoparametrową, która pobiera Foo i zwraca funkcję jednego parametru, która bierze pręt i zwraca int. Ale jakoś możesz to nazwać za pomocą dwóch parametrów, jeśli chcesz. Tutaj napisałem o tym post
f(Foo, Bar)
jest taka sama jak funkcja, f(Foo)
która zwraca inną funkcję, f'(Bar)
która zwraca wartość, która f(Foo, Bar)
by zwróciła. Oznacza to, że jeśli naprawisz argument „Foo”, ale nie „Bar”, masz funkcję, która nie zależy od „Foo”, ale nadal zależy od argumentu „Bar”. Jest to typowe dla języków funkcjonalnych; nazywa się to „curry”.
Są niezwykle potężnymi, ale kompaktowymi obiektami.
Języki, w których są wbudowane, mają dużą zdolność do manipulowania tekstem (nie słychać parsowania słowa, że nie są tak dobre).
Kilka języków w rodzinie funkcjonalnej ma klasę typów znanych jako Jedność. Cechą wyróżniającą typy Unity jest to, że nie zawierają żadnych informacji, są to typy zero-bitowe. Typ jedności (w niektórych odmianach) jest również jego jedyną wartością lub (w większości innych) ma tylko jedną wartość (która sama nie jest typem).
Są one jednak przydatne, ponieważ są to typy wyróżnione. Ponieważ nie można niejawnie konwertować z jednego typu jedności na inny, można sprawić, że sprawdzanie typu statycznego będzie działać w bardzo wydajny i ekspresyjny sposób.
Jedność jest także sposobem, w jaki większość takich języków opisuje Enums, pozwalając, aby nowy typ był dowolnym zdefiniowanym zestawem innych typów, lub opisywać może typy, które mogą być albo wartością typowego typu (powiedzmy liczbą całkowitą) lub mieć wartość reprezentującą brak wartości.
Niektóre języki, które nie wykorzystują bogactwa typów jedności zdefiniowanych przez użytkownika, nadal mają w sobie jedność, w takiej czy innej formie. Na przykład, Python ma co najmniej trzy rodzaje jedności NoneType
, NotImplementedType
orazEllipsisType
. Interesujące jest to, że pierwsze dwa oba oznaczają coś w rodzaju „Brak wartości”, ale trzecia jest używana w wartościach złożonych (w szczególności wyrażeniach plasterków) w celu przedstawienia interesujących przypadków specjalnych.
Inne ciekawe przykłady jedności obejmują NULL
w SQL i undefined
javascript, ale nie void
w C lub C ++. void
zawodzi. Mimo że opisuje wartość braku informacji, ale żadna rzeczywista wartość nie może być typu void
.
symbol
Typ Ruby jest nieco niezwykły. Jest to zasadniczo ciąg implementujący wzorzec singletonu. Lub coś. Jak dotąd znalazłem najlepsze zastosowanie symboli w stanach śledzenia i przekazywaniu nazw funkcji.
COBOL. Zasadniczo tylko dwa podstawowe typy danych, ciągi i liczby, ale musisz dokładnie określić , jak są ułożone w pamięci, np PIC S9(5)V99 COMP-3
.
S
= podpisany, 9(5)
= 5 cyfr, V
= domyślny przecinek dziesiętny, 99
= 2 dodatkowe cyfry, COMP-3
= BCD + znak nybble.
Clipper miał „Bloki kodu”, które były podobne do metod anonimowych. Można je przekazywać i oceniać w razie potrzeby, zwykle jako formę oddzwaniania. Często używasz ich do wykonywania obliczeń w locie podczas prezentacji tabel danych.
VHDL ma typy fizyczne. Literał tego typu zawiera zarówno wartość, jak i jednostkę. Możesz również zdefiniować podjednostki. Na przykład predefiniowanym typem fizycznym jest 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;
Wraz z przeciążeniem operatora możesz zdefiniować bardzo interesujące rzeczy.
Clojure jest interesujący, ponieważ ma meta-koncepcję „abstrakcji”, która przenika język. Przykłady:
W pewnym stopniu abstrakcje doprowadzają do skrajności „ zasadę pojedynczej odpowiedzialności ”. To Ty musisz je skomponować, aby uzyskać pożądaną funkcjonalność, ale możesz być bardzo elastyczny w kwestii tego, jak je sklejasz.
Na przykład, jeśli chcesz oparty na klasach system OOP z dziedziczeniem, możesz stosunkowo szybko zbudować jeden z tych podstawowych abstrakcji.
W praktyce same abstrakcje są zaprojektowane w taki sposób, że możliwe są liczne implementacje, np. Poprzez określone interfejsy, takie jak clojure.lang.ISeq dla sekwencji lub clojure.lang.IFn dla funkcji wyższego rzędu.
Jest ciekawy film na ten temat: The Art of Abstraction
Googles Go ma unikalny typ „kanału”.