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?

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.


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


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


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


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.


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.


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.


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

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

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ść.


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


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)


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.


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


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.


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.


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.


Podoba mi się również typ zwracany automatycznie na podstawie metody ..
nawfal
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.