Twoim zadaniem jest zaadaptowanie funkcji do języka programowania, albo przez wdrożenie bardzo sprytnej biblioteki, albo przez przetworzenie tekstu wejściowego i / lub dostosowanie procesu kompilacji.
Pomysły:
- Dodaj przeplatanie prezentacji w stylu PHP do C (np
<?c printf("Hello,"); ?> world!
.). - Dodaj zerowy operator koalescencyjny do jednego z tych języków, który nie jest C #.
- Dodaj makra do PHP.
- Dodaj
goto
do JavaScript. - Dodaj dopasowanie wzorca do języka X.
- Dodaj obsługę przestrzeni nazw do języka, który jej nie ma.
- Spraw, aby C wyglądał jak PHP.
- Spraw, by Haskell wyglądał jak Pascal.
- ... (zachęcamy do publikowania pomysłów w sekcji komentarzy)
Zasady:
- Przynieś coś do stołu. Nie mów tylko „Szablon Haskell”, aby dodać funkcje metaprogramowania do Haskell. To nie jest StackOverflow.
- Cała implementacja powinna zmieścić się na jednym ekranie (nie licząc przykładu).
- Nie hostuj kodu w witrynie zewnętrznej specjalnie do tego zadania.
- Najbardziej imponująca lub zaskakująca funkcja wygrywa.
Nie martw się o prawidłowe wdrożenie tej funkcji w 100%. Daleko stąd! Głównym wyzwaniem jest ustalenie, co chcesz zrobić, i brutalne wycięcie szczegółów, dopóki planowane przedsięwzięcie nie stanie się wykonalne.
Przykład:
Dodaj operator lambda do języka programowania C.
Wstępne podejście:
Okej, wiem, że chciałbym użyć libgc, aby moje lambdas rozwiązały problemy ze wzrostem i spadkiem. Myślę, że pierwszą rzeczą, którą muszę zrobić, to napisać / znaleźć parser dla języka programowania C, a następnie musiałbym dowiedzieć się wszystkiego o systemie typów C. Musiałbym dowiedzieć się, jak to zrozumieć, jeśli chodzi o typy. Czy musiałbym wdrożyć wnioskowanie o typie, czy powinienem po prostu wymagać, aby parametr formalny był wpisany tak, jak podano? Co z tymi wszystkimi szalonymi funkcjami w CI, o których jeszcze nie wiem?
Jest całkiem jasne, że poprawne wdrożenie lambda w C byłoby dużym przedsięwzięciem. Zapomnij o poprawności! Uprość, uprość.
Lepszy:
Pieprzyć się w górę, kto ich potrzebuje? Mogę być w stanie coś zrobić trudne z GNU C na zagnieżdżone funkcje i wyrażenia rachunku . Chciałem pochwalić się niesamowitą syntaktyczną transformacją na C za pomocą zwięzłego, zhackowanego kodu, ale nie potrzebuję nawet parsera do tego. To może poczekać na kolejny dzień.
Wynik (wymaga GCC):
#include <stdio.h>
#include <stdlib.h>
#define lambda(d,e)({d;typeof(e)f(d){return(e);};f;})
#define map(F,A)({typeof(F)f=(F);typeof(*(A))*a=(A);({int i,l=((int*)(a))[-1]; \
typeof(f(*a))*r=(void*)((char*)malloc(sizeof(int)+l*sizeof(*r))+sizeof(int)); \
((int*)r)[-1]=l;for(i=0;i<l;i++)r[i]=f(a[i]);r;});})
#define convert_to(T) lambda(T x, x)
#define print(T, fmt) lambda(T x, printf(fmt "\n", x))
int main(void)
{
int *array = 1 + (int[]){10, 1,2,3,4,5,6,7,8,9,10};
map(print(int, "%d"), array);
double *array2 = map(lambda(int x, (double)x * 0.5), array);
map(print(double, "%.1f"), array2);
long *array3 = map(convert_to(long), array2);
map(print(long, "%ld"), array3);
long product = 1;
map(lambda(int x, product *= x), array);
printf("product: %ld\n", product);
return 0;
}
To było łatwe, prawda? Wrzuciłem nawet map
makro, aby było użyteczne i ładne.
źródło
Odpowiedzi:
Składnia OOP w Haskell
Obiekty mogą mieć właściwości:
... i metody:
źródło
&
i zdefiniowanego w ten sposób(&) = flip ($)
.&
ponieważ jest to jedyny operator „adres” (implementacja wskaźników w Haskell pozostawia się jako ćwiczenie dla czytelnika).flip id
goto
w JavaScript?Moją pierwszą myślą było podejście funkcjonalne - dodanie parametru do funkcji, aby wskazać, od którego miejsca ma się rozpocząć wykonywanie, przy użyciu tego
switch
polecenia i pętli zewnętrznej, która wielokrotnie wywołuje funkcję na podstawie własnej wartości zwracanej . Niestety wykluczałoby to stosowanie zmiennych lokalnych, ponieważ tracą one swoje wartości z każdym goto.Mogłem użyć
with
instrukcji i przenieść wszystkie deklaracje zmiennych na początek funkcji, ale musiał być lepszy sposób. W końcu przyszło mi do głowy wykorzystanie wyjątków JavaScript . W rzeczywistości Joel Spolsky powiedział: „Uważam wyjątki za nie lepsze niż„ goto ... ” - oczywiście idealne dopasowanie.Pomysł polegał na umieszczeniu nieskończonej pętli wewnątrz funkcji, zakończonej jedynie
return
instrukcją lub nieprzechwyconym wyjątkiem. Wszystkie gotos, traktowane jako wyjątki, zostałyby złapane w pętlę, aby zapobiec jej zakończeniu. Oto wynik tego podejścia:Możesz używać go w ten sposób - nawet w trybie ścisłym ES5 - z wyjątkiem przeglądarki Internet Explorer ( wersja demonstracyjna ):
[Internet Explorer z jakiegoś powodu nie ewaluuje kodu funkcji anonimowej, więc należałoby nadać tej funkcji nazwę (przed przepisaniem) i wywołać ją przy użyciu tej nazwy. Oczywiście prawdopodobnie złamałoby to zasady trybu ścisłego.]
Nie pozwala to na przeskakiwanie do instrukcji znajdującej się w bloku (dopóki takie konstrukcje jak urządzenie Duffa nie staną się legalne), ale możemy sobie z tym poradzić (kolejna, samoczynnie wykonująca się przepisana funkcja), prawda?
źródło
goto
zostałyby w pełni zaimplementowane w JavaScript (gdzie można użyć,goto
aby wyskoczyć z dowolnego zakresu, nawet funkcji ), oznaczałoby to wsparcie dla kontynuacji.# zdefiniować w Javie
Pomyślałem, że fajnie byłoby wdrożyć makra w Javie.
Przykładowe użycie (konwertuje na wcześniej opublikowany kod; zróbmy to dziwne):
źródło
Foreach in C
Iteruj tablice (działa dla tablic statycznych, a nie tych otrzymywanych przez wskaźnik)
Aby to przetestować:
wynik:
źródło
Właściwości w C.
Tomasz Wegrzanowski zaimplementował właściwości w zwykłym C, celowo segregując program, gdy właściwość jest dostępna.
Obiekt z „właściwością” jest konfigurowany przez utworzenie
struct
przecinającego wiele stron, zapewniając, że adres pamięci właściwości znajduje się na innej stronie niż rzeczywiste elementy danych. Strona właściwości jest oznaczona jako niedostępna, co gwarantuje, że próba uzyskania dostępu do właściwości spowoduje awarię. Następnie moduł obsługi błędów ustala, który dostęp do właściwości spowodował segfault, i wywołuje odpowiednią funkcję w celu obliczenia wartości właściwości, która jest przechowywana pod adresem pamięci właściwości.Procedura obsługi błędów oznacza również stronę danych jako tylko do odczytu, aby zapewnić spójność obliczonej wartości; przy następnej próbie zapisu do elementu danych, który uruchamia segfault, którego moduł obsługi ustawia stronę danych jako odczyt-zapis, a stronę właściwości brak dostępu (wskazując, że należy ją ponownie obliczyć).
źródło
Obliczono, że pochodzi z Common Lisp
Początkowo wdrażałem come-from. Ale to nie wystarczyło.
Zainspirowany obliczonym goto, postanowiłem wdrożyć obliczone źródło.
Przykłady użycia
Dla każdej deklaracji przychodzącej w tagbody sprawdzi na każdej etykiecie, czy zmienna przychodząca jest równa bieżącej etykiecie, a jeśli tak, przeskoczy do odpowiedniej deklaracji przychodzącej.
Pozdrawiacz
FizzBuzz
źródło
„Automatyczne ciągi znaków” w Rubim
Kod jest dość prosty:
Teraz możesz zrobić
źródło
Dodaj makra do PHP
Do tego zadania możemy po prostu użyć preprocesora C.
Skrypt php:
Pipe to chociaż cpp:
Wynik:
źródło
<<<HEREDOC
jest niczym więcej niż 3 niższymi niż lub lewymi zmianami i identyfikatorem :-) To jednak spowoduje podstawienie makr w ciągach heredoc.grep -v ^#
to naprawić. Myślę, że to wystarczy na to pytanie :-)Wzorce dopasowywania wzorcóww PythonieCiało funkcji ma 288 znaków.
Wzorce dopasowania wzorcówpozwalają na używanie zupełnie różnych funkcji w zależności od wartości argumentów. Chociaż można go łatwo emulować za pomocą szereguif
instrukcji, osłonydopasowujące wzorcemogą pomóc w oddzieleniu sekcji kodu i jest to świetna wymówka, aby wykonać szalone metaprogramowanie.pattern_match
jest dekoratorem, który tworzy nową funkcję, która implementuje zabezpieczeniadopasowywania wzorów. Warunki dla każdej „podfunkcji” podane w każdym dokumencie w wierszach rozpoczynających się od potoku (|
). Jeśli wszystkie warunki są zgodne z prawdą, uruchamiana jest ta wersja funkcji. Funkcje są testowane w kolejności, dopóki nie zostanie znalezione dopasowanie. W przeciwnym razieNone
jest zwracany.Przykład pomoże wyjaśnić:
źródło
f [a,b,c] = ...
, co nie tylko testuje argument względem predykatu, ale wiąże odpowiednie zmienne po pomyślnym dopasowaniu. Ale to wciąż całkiem fajne.f (x:xs) = ...
If [] = ...
). W jakiś sposób zwiodłem tam strażników, ale od tego zacząłem|
.Coroutine
Nie mogę tego przypisać, więc zaznaczyłem to jako CW.
Coroutines in C autorstwa Simona Tathama
źródło
Operatorzy celni w Lua
Pogs sprytnie wykorzystał przeciążanie operatora w Lua , aby umożliwić zdefiniowanie niestandardowych operatorów infix . Rozszerzyłem to, aby obsługiwać sekcje operatora (częściowo stosując operator z dowolnym operandem) i wywoływać wynikowy obiekt tak, jakby to była funkcja.
źródło
Ciągi wielowierszowe w javascript
w tej skomplikowanej składni dla ciągów wielowierszowych każdy ciąg wielowierszowy będzie poprzedzony
(function(){/*
znakiem nowej linii i znakiem nowej linii, a po nim znak nowej linii i*/}+'').split('\n').slice(1,-1).join('\n')
.używając tej niesamowitej, intuicyjnej składni, możemy w końcu użyć ciągów wieloliniowych:
dla osób, które nie lubią naszej prostej składni, mamy kompilator naszego wspaniałego nowego języka:
ten sam przykład w skompilowanej wersji językowej:
źródło
*/
moich wielowierszowych ciągów. Jest to bardzo denerwujące, gdy zawiera wyrażenia regularne w ciągach!Listowalna lista w C # (jak Python)
Zawsze podobała mi się notacja plastra Pythona i chciałbym, żeby była dostępna w C #
Stosowanie:
Kod daleki od odporności na błędy:
źródło
Uprość C
Ten kod pozwala pisać programy w C, które bardziej przypominają język skryptowy. Zawiera słowa kluczowe, takie jak „var”, „is”, „string”, „plus”, „równo” i kilka innych. Działa poprzez wiele instrukcji definiujących.
Umożliwia to pisanie kodu takiego jak:
Powyższe zostaje rozszerzone do:
Prawdopodobnie nie jest to zbyt przydatne, ale uznałem za całkiem interesujące, że można zasadniczo stworzyć cały język programowania za pomocą kilku
#define
s.źródło
#define
s możesz nawet nadać swojemu językowi takie funkcje, jak obsługa wyjątków i wyrzucanie elementów bezużytecznych przy jednoczesnym zachowaniu podstawowej warstwy C pod spodem.Tcl
TCL nie ma
do ... while
albodo ... until
tak ...Przykład:
uplevel
wykonuje skrypt w zakresie wywołującym.źródło
Idź w PostScript
Moją pierwszą myślą było to, że musiałbym się zepsuć ze stosem exec, więc ten fałszywy start wykopuje operator kontynuacji dla zatrzymania z ghostscript (lub xpost).
Ale to jest prostsze niż to. Ponieważ pozycja pliku jest taka sama dla wszystkich duplikatów uchwytu pliku (
setfileposition
zużywa swój argument, więc jest to jedyna przydatna semantyka dla tej funkcji).Drukuje
5
.Istnieją pewne ograniczenia związane z powyższym. Skok nie jest natychmiastowy, ale ma miejsce, gdy if-body powraca na najwyższy poziom, a interpreter ponownie odczytuje z pliku (zamiast odczytywać z tablicy zawierającej if-body). W tym momencie plik został zmieniony i „goto” zaczyna obowiązywać.
źródło
currentfile <pos> setfileposition
, licząc bajty od początku pliku.Symbol#to_proc
z argumentami w RubySymbol#to_proc
jest prawdopodobnie jedną z moich ulubionych sztuczek polegających na pisaniu naprawdę zwięzłego kodu Ruby. Załóżmy, że maszi chcesz przekonwertować odpowiednio zawartość
nums
itext
na zmiennoprzecinkowe i wielkie litery.Symbol#to_proc
pozwala skrócić kod w następujący sposób:do tego:
Niesamowite! Ale co, jeśli chcemy podnieść każdy element
nums
doi
XX władzy, lub zastąpić każde wystąpienies
ze*
wtext
? Czy jest jakiś sposób na skrócenie takiego kodu?Niestety, nie ma łatwego sposobu przekazywania argumentów podczas używania
Symbol#to_proc
. Widziałem to na wiele sposobów, ale prawdopodobnie dwa najbardziej sprytne i użyteczne obejmują łatanie małpSymbol
klasy [ 1 , 2 ]. Zilustruję pierwszy sposób poniżej.Teraz możesz robić takie rzeczy jak:
źródło
Foreach JavaScript
Wynik
Alternatywna składnia, bardziej jak Tcl.
źródło
Gotos w Haskell
podstawową ideą jest to, że gotos może być częściowo symulowany przy użyciu ostatniego
do
komentarza instrukcji. na przykład:jest równa
ponieważ wykonanie przeskoczy do ostatniej instrukcji, optymalne jest wyrażanie gotos.
ponieważ sposób, w jaki to jest zrobione, gotos skacze tylko wtedy, gdy znajdują się bezpośrednio w
do
bloku definicji najwyższego poziomu. w rzeczywistości jest to „wywołaj x i zignoruj pozostałe stwierdzenia leksykalne ” zamiast „wszystkie x i zignoruj resztę instrukcji”, jak prawdziwe goto.największym problemem jest to, że gdy nie ma możliwości pozostawienia wykonania ze środka akcji IO - nawet
return
nie;return
nic nie robi, gdy nie jest to ostatnie zdanie.rozwiązuje to ten problem, przechwytując pozostałe instrukcje w innym
do
bloku.staje się
print 3
oświadczenie zostaje schwytany przezdo
blok, więcloop
staje się ostatnią wypowiedź.transformacja ta obsługuje również zmienne występujące w zakresie działań. odbywa się to poprzez zapamiętywanie zmiennych, które są w zasięgu, i przekazywanie ich do akcji. na przykład:
to po prostu przekłada się na:
kilka notatek:
return undefined
dodano również instrukcję, aby upewnić się, żedo
blok przechwytywania nie jest pusty.ponieważ czasami w
do
bloku przechwytującym występuje niejednoznaczność typu , zamiast tegoconst
używamyasTypeOf
, co jest takie samo,const
ale wymaga, aby oba jego parametry miały ten sam typ.faktyczna implementacja (w javascript):
przykład:
staje się:
wynik:
źródło
return
w Haskell jest funkcją regularną i niezwiązaną ze słowem kluczowym w C / itp.Python Goto
goto.py
Stosowanie
Przykładowy przypadek testowy
Dane wyjściowe przykładowego przypadku testowego
Trochę zabawy z exec (). Może podnieść błąd maksymalnej głębokości rekurencji, jeśli nie zostanie właściwie użyty.
źródło
// zaimportuj javascript bez specjalnego użycia znacznika script na stronie HTML
To kiepskie, tak, wiem. Długość: 99
źródło
script
tagu wokół tego. Gdzie dokładnie jest nowa funkcja?