2010-08-11 7 views
13

Mam do czynienia z zadaniem zbudowania nowego komponentu, który ma zostać zintegrowany z dużą istniejącą bazą kodów C. Komponent jest zasadniczo rodzajem kompilatora i będzie na tyle skomplikowany, że chciałbym go napisać w OCaml (z powodów zgodnych z tymi podanymi here). Wiem, że interakcja OCaml-C jest możliwa (jak w przypadku manual i tej tutorial), ale wydaje się nieco bolesna.Mieszanie OCaml i C: czy to jest warte bólu?

Chciałbym wiedzieć, czy inni tutaj próbowali zintegrować na dużą skalę kod OCaml i kod C, jakie były niektóre z nieoczekiwanych błędów, które znaleźli, i czy pod koniec dnia doszli do wniosku, że lepiej napisać nowy kod w C.

Uwaga, jestem nie próbuje rozpocząć debatę na temat zalet programowania funkcjonalnego i imperatywnego: załóżmy, że zakładamy, że OCaml okazuje się być prawidłowym narzędzie do pracy, które mam na myśli, a potencjalna trudność w integracji jest jedynym problemem. Nie mam też możliwości przepisywania reszty kodu.

Aby podać nieco więcej szczegółów na temat zadania: elementem, który muszę wdrożyć, jest pewien rodzaj optymalizatora zapytań, który zawiera pewne pomysły badawcze, nad którymi pracuje moja grupa w UC Davis, i zostaną zintegrowane z PostgreSQL, aby może przeprowadzać eksperymenty. (Optymalizator zapytań jest w zasadzie kompilatorem.) Komponent byłby wywoływany z kodu C, działałby głównie niezależnie, ale wykonywałby pewną liczbę wywołań do innych komponentów PostgreSQL w celu pobrania takich informacji jak informacje o katalogu systemowym i tworzyłby kompleks Struktura danych C (reprezentująca fizyczny plan kwerend) jako wynik.

Przepraszamy za nieco otwartym pytanie, ale mam nadzieję, społeczność może być w stanie zapisać mi trochę problemów :)

Dzięki,

TJ

+0

Z ciekawości, jakiego typu ocaml się spodziewasz, że C musi rozpakować? – nlucaroni

Odpowiedz

10

Świetne pytanie. Powinieneś używać lepszego narzędzia do pracy.

Jeśli w rzeczywistości twoje intencje będą używać lepszego narzędzia do pracy (i jesteś pewny, że lexx i yacc będą cierpieć), to będę miał coś do przekazania; nie jest bolesne wywoływanie ocaml z c, i vice versa. Przez większość czasu pisałem o nazwie ocaml, nazywając C, ale napisałem kilka w inny sposób. W większości były to funkcje debugowania, które nie zwracają wyniku.Mimo, że powracające i czwarte dotyczy pakowania i rozpakowywania typu ocaml value po stronie C. Wspomniany samouczek obejmuje to wszystko i bardzo dobrze.

Jestem przeciwny Ronowi Savage'owi, że musisz być ekspertem od tego języka. Pamiętam, że zaczynałem pracę w miejscu, w ciągu kilku miesięcy, nie wiedząc, czym jest "funktor", będąc w stanie zadzwonić do C, i napisać tysiąc wierszy C dla receptur numerycznych i abstrakcyjnych typów danych, i było trochę czkawki (nie z rozpakowywaniem typów, ale ze zbieraniem śmieci abstrakcyjnych typów danych), ale wcale nie było tak źle. Większość wewnętrznych pętli w projekcie jest napisanych w języku C - wykorzystując zalety SSE, bibliotek zewnętrznych (lapack), mocniej zoptymalizowanych pętli i niektórych wbudowanych układów zoptymalizowanych ręcznie.

Myślę, że być może trzeba mieć doświadczenie w projektowaniu dużego projektu i rozgraniczaniu sekcji funkcjonalnych i imperatywnych. Naprawdę oceniłbym, ile ocaml zamierzasz napisać i jakie wartości chcesz przekazać C - Mówię to, ponieważ obawiałbym się polecić komuś przekazać rekursywną strukturę danych z od ocaml do C, w rzeczywistości byłoby dużo rozpakowywania krotek, ich zawartości, a zatem wiele możliwości pomyłki i błędów.

+2

Bardzo dobra odpowiedź. Powinienem zdecydowanie zaznaczyć, że jest to silnie uzależnione od ilości pracy OCaml, którą należy wykonać w porównaniu z bólem C związanym z integracją (rozmiar API). Ma zastosowanie do integracji dowolnego nowego języka z dowolnym istniejącym projektem. –

+0

Nie tylko jest to dobra odpowiedź, ale nawet ta, którą chciałem usłyszeć :) – tjgreen

1

Moja zasada to trzymać się języka/modelu/stylu używanego w istniejącej bazie kodu, aby przyszli deweloperzy konserwacji odziedziczyli spójny i zrozumiały zestaw kodów aplikacji.

Jedynym sposobem mogę usprawiedliwić coś takiego, co sugeruje byłoby, gdyby:

  1. jesteś ekspertem w SML I nowicjuszem w C (tak będziesz 20x jako produktywne)
  2. pomyślnie zintegrować go z biblioteką C przed (widocznie nie)

Jeśli w ogóle bardziej zaznajomieni z C niż SML, który właśnie stracił żadnego „teoretyczną” zysk z SML jest łatwiejszy w użyciu podczas pisania kompilator - a wygląda na to, że będziesz miał więcej rówieśników Bardziej podobny do C niż OCaml.

To jest mój "zrzędliwy stary koder" 2 centy (które kiedyś tylko kosztowały grosza!).

+6

Nie rozumiem, dlaczego przyjmujesz założenie, że trzeba być ekspertem w OCaml i nowicjuszem w C, aby być bardziej produktywnym przy użyciu OCaml w obszarze, który jest dokładnie jego mocną stroną. Jeśli byłby komponent sieciowy, czy napisałbyś to wszystko w C zamiast, powiedzmy, Python + HTML + JavaScript? – Chuck

+4

Pytanie: Czy odpowiedź Rona Savage'a jest rzeczywiście oparta na jakiejkolwiek wiedzy/szczegółach dotyczących OCaml, a nawet C? –

+1

@Chuck - Ponieważ wykonanie funkcji w ciągu 1 miesiąca w porównaniu do 5 miesięcy może sprawić, że będzie ona warta dodatkowej złożoności, problemów z utrzymaniem i ryzyka wprowadzenia zupełnie nowego języka do istniejącego projektu i zespołu programistów języka C. 1 miesiąc vs 2 miesiące? Nie jest tego warte. –

1

Ja napisałem dość złożony program hybrydowy OCaml-C. Byłem sfrustrowany tym, co uznałem za nieodpowiednią dokumentację, a ja spędziłem zbyt wiele czasu na rozwiązywaniu problemów związanych z usuwaniem śmieci. Jednak wynikowy program działał i był szybki.

Myślę, że jest miejsce na integrację OCaml-C, ale upewnij się, że jest to warte kłopotów. Może być prostsze, gdy programy komunikują się przez gniazdo (zakładając, że takie operacje IO nie wyeliminują pożądanej wydajności). To może być bardziej rozsądne, aby napisać całą rzecz w C.

1

Interoperacyjność to pięta achillesowa samodzielnych implementacji statycznie napisanych języków, szczególnie tych bez kompilacji JIT, jak OCaml. Moje własne doświadczenie, w którym używano OCaml przez ponad 5 lat jest takie, że jedyne niezawodne powiązania występują w prostych API, które nie przekraczają dużych tablic, np. LAPACK. Nawet nieco bardziej skomplikowane wiązania, takie jak te na FFTW, trwały lata, aby ustabilizować się, a inne, takie jak OpenGL i GLU, pozostają nierozwiązanym problemem. W szczególności znalazłem poważne błędy w kodzie wiążącym napisane przez dwóch autorów kompilatora OCaml. Jeśli nie mogą tego zrobić, to dla reszty z nas jest mało nadziei ...

Jednak wszystko nie jest stracone. Rozwiązaniem jest po prostu użycie luźniejszych wiązań. Zamiast obsługi interoperacyjności na poziomie C z niskonapięciowym typem niebezpiecznego interfejsu, należy używać interfejsu wysokiego poziomu, takiego jak XML-RPC z przekazywaniem ciągów, a nawet ponad gniazdami. Jest to znacznie łatwiejsze do uzyskania i, jak mówisz, pozwoli ci wykorzystać olbrzymie praktyczne korzyści oferowane przez OCaml dla tej aplikacji.

+1

Używanie IPC zamiast pisania wiązań jest niezwykle często pomijanym pomysłem. Dlaczego zawsze szukają skomplikowanych rozwiązań? –