Killer częściowo unikalne funkcje języka programowania [zamknięte]

25

Ucząc się nowego języka programowania czasami natrafiasz na funkcję językową, która sprawia, że ​​żałujesz, że nie znasz go w innych językach programowania, które znasz.

Jakie są niektóre funkcje językowe, które były w czasie nauki dla Ciebie bardzo nowe i które chciałbyś, aby posiadały inne języki programowania.

Przykładem tego są generatory w języku Python lub C #. Inne przykłady mogą obejmować rozumienie list w Pythonie, szablon w C ++ lub LINQ w .NET lub leniwe ocenianie w Haskell.

Jakie inne na wpół unikalne cechy językowe, z którymi się spotkałeś, były dla Ciebie zupełnie nowe i pouczające? Czy są inne cechy starszych języków programowania, które były wyjątkowe i wyszły z mody?

Brian R. Bondy
źródło

Odpowiedzi:

25

Praktycznie wszystko w Haskell

  • Monady Tak - wielkie przerażające słowo, które sprawia, że ​​parsery, operacje wejścia / wyjścia, operacje na listach i inne rzeczy stają się niezwykle łatwe (gdy zauważysz wspólny wzór)
  • Strzały To samo dotyczy zaawansowanych użytkowników;)
  • Standardowe rzeczy takie jak lambdas itp.
  • Funkcje curry
  • Algebraiczne typy danych
  • Dopasowywanie wzorów

I wiele więcej.

PS. Tak. Jestem fanboyem Haskell, jeśli ktoś zapyta.

Maciej Piechotka
źródło
12
Aby być uczciwym, powinieneś przyznać kredyt ML za większość tej listy.
wspaniałomyślny
1
Cóż - z wyjątkiem monad i strzał IIRC. Ale nadal są pół- unikatowe
Maciej Piechotka
Czy jest jakiś konkretny powód do głosowania?
Maciej Piechotka
2
+1 za dopasowanie wzoru. Pokazuję to innym ludziom, a oni tego nie rozumieją. Myślę, że to genialne.
Barry Brown
Obowiązkowe ( steve-yegge.blogspot.com/2010/12/… ). BTW, raczej nie uważam lambdas za unikalne, python, C #, javascript itp. Monady? Większość innych języków nazywa to łańcuchem; rdzeń jquery jest zasadniczo jednym ogromnym zestawem monad HTML / DOM i AJAX (Google: jQuery.fn). Curry jest również stosunkowo powszechne w dzisiejszych czasach.
Evan Plaice
21

Makra Lisp.

Językiem makro Lisp jest Lisp, z kilkoma predefiniowanymi funkcjami składni dla wygody. Korzystając z nich, można dodawać do języka najważniejsze funkcje, takie jak wybór stylów orientacji obiektów lub dopasowanie deterministyczne przypominające Prolog, bez patrzenia na miejsce. Umożliwia to setfmakro, które jest koncepcyjnie bardzo silnym makro: (setf A B)oznacza, że ​​kiedy ocenisz A, dostaniesz B, i które można rozszerzyć do dowolnego limitu, który ci się podoba.

Metaprogramowanie szablonów w C ++ jest zdolne do podobnych rzeczy, ale w znacznie innym języku niż w zwykłym C ++.

David Thornley
źródło
+1 Mam nadzieję, że pewnego dnia będę mógł programować w dialekcie Lisp.
Oliver Weiler
@Helper ... za pomocą szablonów C ++ [straszny śmiech]
mlvljr
@mlvjr: Jesteś przerażający.
David Thornley
W rzeczywistości jest to jedyna gotowa funkcja, jakiej kiedykolwiek potrzebujesz w języku. Za pomocą makr Lisp możesz później dodać wszystkie inne możliwe funkcje.
SK-logic
18

Dekorator Pythona.

Za pomocą dekoratora niezwykle łatwo jest zaimplementować zapamiętywanie lub synchronizację funkcji.

Przykład timera funkcji.

class FuncTimer(object):
    """ Time how much time a function takes """
    def __init__(self, fn):
        self.fn = fn
        self.memo = {}
        self.start_time = time.time()
    def __call__(self, *args):
        self.memo['return'] = self.fn(*args)
        print("Function '%s' took %u seconds" % (self.fn.__name__, time.time() - self.start_time))
        return self.memo['return']

Teraz, jeśli masz funkcję foo, którą chcesz poświęcić czas, możesz po prostu to zrobić,

@FuncTimer
def foo():
    # foo's implememtation goes here

Zobaczysz coś takiego,

Funkcja „foo” zajęła 3 sekundy.

grokus
źródło
Java ma adnotacje, które mają podobny cel i składnię, ale działają zupełnie inaczej
Casebash
1
+1: Dekoratorzy Pythona zrobili na mnie wrażenie bardziej niż prawie jakakolwiek inna funkcja w języku. Są bardzo piękne i proste!
Adam Paynter,
Może mógłbyś podzielić się z nami prostym przykładem? Nie wiem, czy Python jest szczery.
ShdNx
@ShdNx, właśnie dodałem przykład.
grokus
1
Czy czas rozpoczęcia nie powinien być obliczany jako część połączenia?
detly
14

Przesyłanie do void*C. Możesz rzutować wszystko na surowe bajty i robić, co chcesz z tymi danymi.

(Tak, obecnie jest wyjątkowy ...)

P Shved
źródło
1
Obiekt w językach .Net jest bardzo podobny. Tylko bardziej bezpieczne dla typu itp.
Maciej Piechotka,
Możesz rzutować na obiekt w wielu językach. Główny problem polega na tym, że wiele języków oddziela prymitywy i obiekty
Casebash
5
@Maciej: nawet w .NET nie można tak naprawdę rzucać prymitywów na Object. Ty box je, i to zupełnie inna bestia. Poza tym wciąż jest to zupełnie inne niż casting na void*...
Dean Harding
1
Przesyłanie do PointerPascala i Object Pascal robi to samo.
Frank Shearar
1
@DeanHarding: Cóż - w C masz, do int64_tktórego nie zawsze możesz bezpiecznie przesyłać void *(Przepraszam za późne - 2 lata - odpowiedź).
Maciej Piechotka,
12

Wydajność w Pythonie

W Pythonie (i wierzę w C #) możesz zdefiniować tak zwany generator, który wstrzymuje wykonywanie funkcji w yieldinstrukcji, zwraca wartość i przy kolejnych wywołaniach, restartuje funkcję od momentu jej przerwania (z zachowaniem stanu między wywołaniami). Jest to doskonałe do generowania długich list wartości, w których interesuje Cię tylko bieżąca wartość funkcji (co jest bardzo powszechne). Pozwala budować potencjalnie nieskończenie długie sekwencje, zajmując jedynie bardzo ograniczoną przestrzeń w pamięci.

Chinmay Kanchi
źródło
1
Wydajność jest już wymieniona w pytaniu.
Trynidad,
To sięga aż do BCPL.
Peter Taylor
8

Wyrażenia lambda (zamknięcia, funkcje zagnieżdżone, metody anonimowe, jakkolwiek je nazwiesz).

Po raz pierwszy spotkałem ich w Perlu, od razu je pokochałem i zastanawiałem się, dlaczego inne języki ich nie mają. Wydaje mi się, że obecnie nie jest już tak wyjątkowy; nawet PHP udało się je w jakiś sposób zhakować. Ale wtedy były na wpół wyjątkowe.

Timwi
źródło
5
Wyjątkowy, o ile liczysz na powrót do Lisp, który jest drugim najstarszym językiem programowania. ;-)
Michael H.
-1: Nie na wpół unikalny
Casebash
7

Zestawy w Delphi są bardzo przydatne, właściwie tylko nazwana tablica boolowska. Są bardzo przydatne do zapisywania formularza ustawień z 32 polami wyboru. Ale mają wszystkie te same funkcje teorii mnogości (tj. Różnicę, przecięcie, połączenie).

Nie jestem pewien, czy wypadły z mody, ale używam ich cały czas.

Peter Turner
źródło
Fajnie, ale czy nie byłoby to łatwe do wdrożenia w Javie, na przykład: boolean []?
Mark C
Tak, możesz, ale nie sądzę, że jest tak zwięzły jak: TForm = (FF_1500 = 1, FF_CA251 = 5, FF_UB04 = 6, FF_MA10 = 7); TFormSet = zestaw TForm;
Peter Turner
7

Wysłać

Z Erlang. Wysyła wiadomość asynchroniczną do innego wątku.

Expr1 ! Expr2

Otrzymać

Z Erlang. Odbiera wiadomość z innego wątku.

receive
    Pattern1 [when GuardSeq1] ->
        Body1;
    ...;
    PatternN [when GuardSeqN] ->
        BodyN
end
Jonas
źródło
5

Właściwości C #

/// <summary>
/// Get ID
/// </summary>
public int ID
{
    get; set;
}

vs

(Jawa)

/**
 * Name of user
 */
private String name;

/**
 * Gets name of user
 * @return Name of user
 */
public String getName() {
    return this.name;
}

/**
 * Sets name of user. 
 * @param name
 */
public void setName(final String name) {
    this.name = name;
}
TheLQ
źródło
2
Tak, są lepsze, ale to zły przykład. Różnica byłaby znacznie mniejsza, gdyby program pobierający / ustawiający zrobiłby coś specjalnego, a wersja C # jest mniej udokumentowana.
Bart van Heukelom,
1
Mój szef jest zdecydowanie przeciwny automatycznym właściwościom języka C # i za każdym razem, gdy się o to kłócą, żadne z nas nie jest w stanie zrozumieć, dlaczego drugi ma rację, czy nie. Po prostu je uwielbiam, ponieważ sprawiają, że kod jest o wiele bardziej przejrzysty i na dłuższą metę oszczędza mi dużo czasu.
mbillard
2
Po prostu nie pozwól, aby zachęciło to ludzi do pobierania i pobierania. Należy używać tylko tych modułów pobierających i ustawiających, które mają sens jako działania na obiekcie.
David Thornley,
3
Nie są nazywane właściwościami C #, nazywane są właściwościami automatycznymi
Jaco Pretorius
1
Auto-właściwości są obecnie bardzo powszechne. Python, Objective-C ...
Casebash
5

Związki w C

Nie mogę szczerze powiedzieć, że sam nie napisałem wystarczająco dużo C, aby zrobić którykolwiek z nich, ale pracowałem z kodem innego, który to robi.

Jeśli chodzi o pakowanie mieszanin różnych danych w aplikacjach, które manipulują nieprzetworzonymi bitami / bajtami, takimi jak sieć lub przechowywanie danych binarnych. W silnie pisanych językach nie ma łatwego sposobu na zrobienie tego.

Zrzeczenie się:

Chociaż związki są bardzo przydatne w niektórych przypadkach, nie można ich znaleźć w większości języków wyższego poziomu, ponieważ nie są bezpieczne pod względem typu. IE, możesz sprawić, by dane przeciekły przez granice zmiennych przy użyciu związków (duże nie, nie w świecie bezpiecznym dla typu). Z dużą mocą przychodzi duża odpowiedzialność.

Evan Plaice
źródło
2
IMHO z dobrego powodu. Reinterpretacja danych to piękny sposób na strzelanie sobie w stopy ( en.wikipedia.org/wiki/Aliasing_(computing) ). Lepiej używaj jawnych konwersji IMHO. Związki postępujące właściwie to algebraiczne typy danych IMHO.
Maciej Piechotka,
@Maciej Dodałem niezbędne wyłączenie odpowiedzialności. Chociaż nie jestem pewien, czy dokładnie wyjaśnia niebezpieczeństwa związane ze stosowaniem związków, ponieważ tak naprawdę nie mam dogłębnej wiedzy o ich stosowaniu. Wiem tylko, że tam, gdzie widziałem, jak używali, kod był o wiele bardziej zwięzły i łatwiejszy w obsłudze niż odpowiednik języka wyższego poziomu.
Evan Plaice,
Problem polega na tym, że C jest „językiem wyższego poziomu” (po prostu językiem wyższego poziomu). Od K&R C uzyskuje się wiele reguł, które pozwalają na użycie szybszego przenośnego kodu. Cena jest taka, że ​​kompilator może zakładać różne rzeczy, a niektóre mogą się mylić. WIĘKSZOŚĆ unionużycia jest bezpieczna, niektóre są dobrze obsługiwanymi idiomami (chociaż technicznie niepoprawne) - patrz cellperformance.beyond3d.com/articles/2006/06/… (chociaż jest więcej poblem ze wskazówkami związki mogą to sfałszować).
Maciej Piechotka,
Delphi rozszerzyła swoją recordskładnię o obsługę związków:in_addr = record case integer of 0: (S_un_b: SunB); 1: (S_un_w: SunW); 2: (S_addr: u_long); end;
Frank Shearar
5

Naprawdę podoba mi się modyfikator chyba, że w Ruby . Wydaje się to takie naturalne i zastępuje wiele scenariuszy, w których Twój kod wydaje się bez niego bardzo nieporządny.

puts "All good" unless input.nil?

Jak możesz tego nie lubić? :RE

Jaco Pretorius
źródło
6
Perl miał to przed Ruby. Też to uwielbiam.
Barry Brown,
1
Nemerle ma podobne słowa kluczowe unlessi whenzastępują najczęstsze scenariusze rozgałęziania, które tradycyjnie by się używały if/else.
MattDavey,
5

fantazyjne składnie argumentów python

Nie jestem pewien, jak wyjątkowe jest to, ale w Pythonie możesz robić fajne rzeczy, takie jak automatyczne ustawianie par słów kluczowych w słowniku i odwrotnie. To samo z listami:

def parrot(voltage, state='a stiff', action='voom', type='Norwegian Blue'):
    print "-- This parrot wouldn't", action,
    print "if you put", voltage, "volts through it."
    print "-- Lovely plumage, the", type
    print "-- It's", state, "!"


parrot(1000)
parrot(action = 'VOOOOOM', voltage = 1000000)
parrot('a thousand', state = 'pushing up the daisies')
parrot('a million', 'bereft of life', 'jump')

python docs (przewiń w dół, aby uzyskać więcej argumentów przekazujących)

Gordon Gustafson
źródło
1
+1 za możliwość przekazania parametru głęboko na liście bez konieczności przekazywania wartości wszystkich opcjonalnych parametrów przed nim.
eswald
4

Preprocesor C. Możesz nawet pisać wspólny kod na różnych platformach za pomocą - mniej lub więcej - ifdefs.

ern0
źródło
2
Dostępne są lepsze preprocesory, które wykonują swój własny dodatkowy krok i pracują we wszystkich językach.
David Thornley,
Jestem całkiem zadowolony z ifdef, ifndef i innych.
ern0
3

Kategorie celu C

Kategorie oferują łatwy sposób na rozszerzenie funkcjonalności obiektu w czasie wykonywania (myśl kompozycja kontra dziedziczenie). Klasycznym przykładem jest dodanie modułu sprawdzania pisowni do klasy NSString.

@interface NSString (SpellChecker)
- (BOOL) checkSpelling;
@end

Przydatny również w przypadku drobnych poprawek, ponieważ implementacja metody kategorii zastąpi jej implementację nadrzędną.

aprock
źródło
1
Bardzo podobny do metod rozszerzenia w C #
Casebash
2

Ruby „s inject metoda w połączeniu z symbolem # to_proc cechą Ruby 1.9 pozwala napisać kilka niezwykle zwięzły (ale nadal czytelny) Kod:

na przykład (1..10).inject(:+)

która sumuje liczby całkowite od 1 do 10 => 55

Takie przykłady sprawiły, że chciałem nauczyć się Ruby, co właśnie zacząłem.

tcrosley
źródło
9
Aby być uczciwym, inject jest wersja Ruby od fold / foldl / foldr z języków takich jak Lisp, Haskell, itp
mipadi
Tak naprawdę nie nazwałbym tego wyjątkowym.
Daenyth,
1
Tytuł pytania brzmi „pół-unikalny”, a nie niepowtarzalny. Z pewnością zwięzłość kodu zapewniona przez kombinację zastrzyku (lub mapy itp.) I symbolu # to_proc wykracza daleko poza podstawowe języki, takie jak C, Java i C ++.
tcrosley,
Bardzo zwięzłe (i podoba mi się), ale nie jestem pewien, czy różni się od czegoś takiego jak: Enumerable.Range (1, 10) .Aggregate ((s, x) => s + x); z C # lub innych języków
FinnNk
1

Mechanizm wiązania w JavaFX (RIP). Wiążą słów kluczowych pozwala powiązać wartość zmiennej wartości wyrażenia i coraz Państwo pozbyć się wszystkich tych brzydki Listener ogóle standardowy kod.

Podczas gdy JavaFX pod wieloma względami był dość nieudany, wiele funkcji języka skryptowego okazało się całkiem przyjemnych.

Oliver Weiler
źródło
1

Mixiny łańcuchowe oraz ocena funkcji czasu kompilacji w D to całkiem wyjątkowa funkcja zabójcy. Tak, technicznie rzecz biorąc, są to dwie cechy, ale prawdziwa moc pochodzi z ich połączenia. Dzięki tej kombinacji możesz pisać zwykłe funkcje D, które generują kod w postaci łańcucha w czasie kompilacji, a następnie mieszać ten kod w dowolnym zakresie i poddać go ocenie jako zwykły kod D. Kod jest w pełni skompilowany statycznie i działa dokładnie tak, jakby został napisany ręcznie. Ta funkcja jest nawet używana do obejścia kilku lepkich sytuacji w standardowej bibliotece.

dsimcha
źródło
Podoba mi się również typ zwracany automatycznie na podstawie metody ..
nawfal