Forum: Compiler & IDEs Ein Programm, zwei Sprachen


von Tobias P. (hubertus)


Lesenswert?

Hallo zusammen,
ich habe mich in letzter Zeit einmal mit den Sprachen Prolog und LISP 
beschäftigt, was sehr interessant und lehrreich ist. Und so habe ich nun 
auch gesehen, dass es gewisse Dinge gibt, die z.B. mit LISP sich viel, 
viel einfacher lösen lassen, als wenn man C oder C++ verwenden würde. 
Und wieder für anderes ist C/C++ besser; z.B. ein GUI möchte ich nicht 
in LISP programmieren.

Was ich mich nun frage - ist es auf irgend eine Art möglich, ein 
Programm mit zwei Sprachen zu schreiben? Ich schreibe also z.B. das GUI 
in C oder C++, und das, was das Programm eigentlich machen soll, der 
"Kern" quasi, in, sagen wir mal, LISP. Ginge sowas? Wenn ja, wie macht 
man das? gibts da eine elegante Möglichkeit? was z.B. ja sicher ginge, 
wäre, wenn man 2 unabhängige Programme schreibt; einerseits das GUI in 
C, und andererseits dann den LISP-Teil als unabhängiges Programm, und 
dann ruft man diesen einfach per Kommandozeile dann aus dem GUI-Programm 
heraus auf. Das ist sicher machbar, aber gäbe es noch eine elegantere 
Möglichkeit?

Gruss Tobias

von G ast (Gast)


Lesenswert?

Eventuell könnte man etwas mit Sockets machen. Beide Programm sprechen 
über "localhost" miteinander und tauschen so Informationen aus.

von Penner (Gast)


Lesenswert?

In der Vorstufe zum eigendlichen Kompilat, welches man z.B. in einen µC 
flashen kann, erzeugen Compiler sog. Object-Codes. Du mußt nur dem 
Linker, der diese Object-Codes adresskonform bindet, sagen, wie er das 
machen soll. Soweit die Theorie. Praktisch sehe ich für dein Vorhaben 
keine Umsetzungsmöglichkeit, lasse mich aber auch eines Besseren 
belehren.

von Dumdi D. (dumdidum)


Lesenswert?

lisp wird doch eigentlich nicht kompiliert, oder?

von Michael H. (michael_h45)


Lesenswert?

Tobias Plüss schrieb:
> Was ich mich nun frage - ist es auf irgend eine Art möglich, ein
> Programm mit zwei Sprachen zu schreiben? Ich schreibe also z.B. das GUI
> in C oder C++, und das, was das Programm eigentlich machen soll, der
> "Kern" quasi, in, sagen wir mal, LISP.
Was du suchst, heißt Bibliothek. Allerdings muss der eine Compiler die 
auch erzeugen und der andere sie auch referenzieren können.

oder halt kommunikation irgendeiner art... pipe, file, netzwerk, etc...

von Yalu X. (yalu) (Moderator)


Lesenswert?

Die meisten Programmiersprachen bieten (mehr oder weniger 
standardisierte) Möglichkeiten, Module aus anderen Sprachen auch ohne 
den Umweg über Pipes u. ä. einzubinden, so auch Lisp:

  http://en.wikipedia.org/wiki/Foreign_function_interface

dumdi dum schrieb:
> lisp wird doch eigentlich nicht kompiliert, oder?

Es gibt Interpreter und Compiler. Viele Lisp-Systeme haben beides. CMU 
Common Lisp bietet sogar drei Möglichkeiten: Einen reinen Interpreter, 
einen Bytecode-Compiler und -Interpreter und einen Native-Code-Compiler.

Stand-Alone-Lisp-Programme werden aus Geschwindigkeitsgründen meist in 
Native-Code kompiliert. Man kann aber auch aus einem kompilierten 
Programm den Interpreter aufrufen, um bspw. eine benutzerdefinierte 
Funktion aus einer Datei auszuführen. Stellt das Programm fest, dass 
diese Funktion häufiger zum Einsatz kommt, kann es sie auch zu einem 
späteren Zeitpunkt noch kompilieren, denn der Compiler ist nicht nur 
während der Entwicklung, sondern auch während der Ausführung eines 
Programms ständig präsent. Er muss auch nicht umständlich als externes 
Tool aufgerufen werden, sondern ist direkt als Lisp-Funktion verfügbar.

von Tobias P. (hubertus)


Lesenswert?

Hallo zusammen,

ich habe mir noch überlegt, ob es evtl. ginge, einen kleinen 
Lisp-Interpreter in das fragliche Programm mit einzubauen. Wir haben 
hier in der Firma eine SW, wo sowas mit Prolog gemacht wird, so bin ich 
auch überhaupt erst auf die Idee gekommen, dass man was mit Lisp machen 
könnte.
Da wurde ein kleiner Interpreter geschrieben in C, der direkt in die 
"normale" GUI Anwendung integriert ist. Der Interpreter liest dann das 
Prolog-Programm aus einer separaten Textdatei und interpretiert dieses, 
so kann man dann die Sprache nutzen. Ob sowas wohl auch für Lisp geht? 
Zwar habe ich einen Interpeter in 90 Zeilen C Code gefunden, aber dieser 
scheint doch recht unausgereigt zu sein.

Ausserdem ist mir dann noch immer nicht klar, wie man die Kommunikation 
dann lösen kann - obwohl sie so sicher einfacher ist. Wahrscheinlich 
müsste der Interpreter irgend ein Interface zur Verfügung stellen, mit 
dem man von C aus auf die Variablen von Lisp zugreifen kann?

Gruss Tobias

von Karl H. (kbuchegg)


Lesenswert?

Tobias Plüss schrieb:

> ich habe mir noch überlegt, ob es evtl. ginge, einen kleinen
> Lisp-Interpreter in das fragliche Programm mit einzubauen.

Die erste Frage ist, was du dir eigentlich davon versprichst. So etwas 
macht in den meisten Fällen nur dann Sinn, wenn man beide Sprachen gut 
genug beherrscht, so dass es überhaupt Sinn macht, einen Teil davon in 
Lisp zu machen.

> so kann man dann die Sprache nutzen. Ob sowas wohl auch für Lisp geht?

Natürlich geht das

> Zwar habe ich einen Interpeter in 90 Zeilen C Code gefunden, aber dieser
> scheint doch recht unausgereigt zu sein.

Das denke ich allerdings auch. Alleine das Garbage Collecten dürfte 
schon um einiges mehr Code brauchen.

> Ausserdem ist mir dann noch immer nicht klar, wie man die Kommunikation
> dann lösen kann - obwohl sie so sicher einfacher ist.

Na, dein C-Programm verwaltet ja den Interpreter. D.h. da gibt es dann 
einen Aufruf in den Interpreter mit dem man ihn anweist eine 
LISP-Funktion zu starten. Das Ergebnis kriegt man dann vom Interpreter 
wieder. Genauso sieht das mit Variablen aus. Der Interpreter muss die ja 
verwalten. Also kann man sich auch eine Funktion schreiben, mit der man 
den Interpreter neue Belegungen für Variablen gibt oder Werte abfrägt.


Aber frag dich ernsthaft, was du dir davon versprichst, LISP zu benutzen 
und ob du mit einer ordentlich gemachten Listenverwaltung in C nicht 
letzten Endes besser fährst. D.h. das du dir den Teil von LISP in C 
nachbildest, den du tatsächlich brauchst. Das Konzept von Dotted-Paits 
und Atomen; von CAR und CDR; von APPEND und CONS ist ja so aufregend 
schwer dann auch wieder nicht in C umzusetzen.

von Karl H. (kbuchegg)


Lesenswert?

Zur allgemeineren Frage.
Ja, das geht/ging schon. Betriebssysteme definieren ja normalerweise wie 
zb Library-Schnittstellen technisch aussehen. Solange sich alle Compiler 
an dieses ABI halten, kann man durchaus Object-Module, die aus 
unterschiedlichen Sprachen stammen zusammenlinken.
Details dazu finden sich aber in den diversen Compiler/Linker Dokus, 
bzw. den ABI Beschreibungen, die auf einem Betriebssystem gelten. Was 
allerdings nicht heißt, dass man nicht ein wenig Lehrgeld zahlen muss.

von testX (Gast)


Lesenswert?

Wenn dir Lisp gefaellt versuch doch einmal F#.
das bietet aehnliche funktionalitaet und lasst sich aehnlich leicht 
schreiben

Vorteil, es laesst sich nahtlos in eine c# applikation einbinden.

also hast du eine Gui in c# und funktionalitaet in f# in einem Prozess

von Tobias P. (hubertus)


Lesenswert?

Hallo Karl Heinz,

klar, ob das so extrem Sinn macht, ist schon fraglich. Es ist eher als 
ein Experiment anzusehen. Ich pröble gerade ein wenig in Lisp herum, 
habe mir auch ein Buch drüber beschafft, und für gewisse Dinge ist es 
schon nett, und da ich hier in der Firma mit dieser Prolog-SW arbeite 
tauchte bei mir halt die Frage auf, ob sowas auch mit C und Lisp ginge.
Es gibt ja z.B. auch das Computeralgebrasystem maxima, bzw. wxmaxima, 
das in Lisp geschrieben ist. Ich habe mir den Source noch nicht 
angeschaut, aber es würde mich doch sehr wundern, wenn da das GUI auch 
in Lisp ist, also muss es ja auch irgend eine Möglichkeit für ein 
Interface geben.

von Rolf M. (rmagnus)


Lesenswert?

Schau dir mal http://www.swig.org/ an. Das unterstützt unter anderem 
Common Lisp.

von Karl H. (kbuchegg)


Lesenswert?

Tobias Plüss schrieb:
> Hallo Karl Heinz,
>
> klar, ob das so extrem Sinn macht, ist schon fraglich. Es ist eher als
> ein Experiment anzusehen. Ich pröble gerade ein wenig in Lisp herum,
> habe mir auch ein Buch drüber beschafft, und für gewisse Dinge ist es
> schon nett

Wir haben sowas Ende der 80-er Jahre mal auf einer VAX gemacht. Da ging 
es um ein 'intelligentes Bauteil Schachteln auf Blechtafeln'. Fortran 
und LISP gemischt und zu einem gemeinsamen Programm gelinkt. Die Dame, 
die damals den LISP Part übernommen hat, konnte wirklich gut LISP 
(meinem Gefühl nach). Der Katzenjammer kam danach, als sie das Projekt 
verliess und von uns keiner den LISP Part warten konnte. Wir sassen dann 
mit einem Programmteil da, den von uns keiner warten oder bugfixen 
konnte.
Auch diesen Aspekt sollte man nicht vergessen und aus den Augen lassen.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Tobias Plüss schrieb:
> ich habe mir noch überlegt, ob es evtl. ginge, einen kleinen
> Lisp-Interpreter in das fragliche Programm mit einzubauen.

Muss es unbedingt Lisp sein?

Tobias Plüss schrieb:
> Und so habe ich nun auch gesehen, dass es gewisse Dinge gibt, die z.B.
> mit LISP sich viel, viel einfacher lösen lassen, als wenn man C oder C++
> verwenden würde.

Das ist schon richtig. Aber es gibt hunderte anderer 
Programmiersprachen, bei denen du ein ähnliches Aha-Erlebnis haben 
wirst.

Welches sind denn die Features, die dir in Lisp so gut gefallen und die 
du in C[++] vermisst?

Vielleicht sind diese Features auch in Python, Lua, ... enthalten. Diese 
Sprachen haben ebenfalls eine gute Anbindung an C[++]. Im Gegensatz zu 
Lisp sind sie aber leichter zu lernen und haben eine sehr viel größere 
Community, was die Gefahr von "Katzenjammer" (s. vorangegangener Beitrag 
von Karl Heinz) deutlich mindert.

Tobias Plüss schrieb:
> Es gibt ja z.B. auch das Computeralgebrasystem maxima, bzw. wxmaxima,
> das in Lisp geschrieben ist. Ich habe mir den Source noch nicht
> angeschaut, aber es würde mich doch sehr wundern, wenn da das GUI auch
> in Lisp ist, also muss es ja auch irgend eine Möglichkeit für ein
> Interface geben.

XMaxima ist in Tcl/Tk, WxMaxima in C++ geschrieben. Beides sind m.W. 
separate Anwendungen, die mit Maxima über Sockets kommunizieren. Das ist 
ein im Unix-Umfeld gängiger Weg, um das GUI und die eigentliche 
Anwendung sauber voneinander zu trennen.

von makefile (Gast)


Lesenswert?

Chicken Scheme [1] als Lisp-Dialekt hat ein recht praktisches Foreign
Funktion Interface. Damit lassen sich direkt beliebige Funktionen aus
shared Libraries aufrufen. Daneben kann C-Code auch unmittelbar in
Scheme-Programme integriert werden. Beispiele aus dem Manual:

Integration von C in Scheme
1
(define my-strlen
2
  (foreign-lambda* int ((c-string str))
3
    "int n = 0;
4
     while(*(str++)) ++n;
5
     C_return(n);"))

Zugriff auf eine C-Variable my_version_string
1
(print (foreign-value "my_version_string" c-string))

Direkter Aufruf von Funktionen in Libraries
1
(#~printf "%d -> %g, ok: %s\n" 123 45.67 "hello")
2
(#~sin 33.4 return: double:)

Für Chicken Scheme existieren fertige Erweiterungen, dort Eggs genannt,
um mit ncurses, tk, FLTK und (teilweise) Qt zu arbeiten. Du kannst
deine GUI also vollständig in Scheme schreiben.

Ob es nicht doch besser und übersichtlicher ist, Applikationslogik und
GUI weiter zu trennen und sie in zwei Programme aufzuspalten, die über
einen  geeigneten Kanal miteinander kommunizieren, ist dann wieder eine
andere Frage.

[1] Chicken Scheme: http://www.call-cc.org/

von makefile (Gast)


Lesenswert?

Tobias Plüss schrieb:
> ich habe mir noch überlegt, ob es evtl. ginge, einen kleinen
> Lisp-Interpreter in das fragliche Programm mit einzubauen. Wir haben
> hier in der Firma eine SW, wo sowas mit Prolog gemacht wird,

Sorry, hatte deine Frage oben falsch verstanden. Du möchtest also nicht
aus einem Lisp-Programm C-Code aufrufen, sondern einen Interpreter in
ein bestehendes C-Programm einbauen und damit Lisp-Ausdrücke zur
Laufzeit evaluieren.

Auch das geht problemlos. Als Beispiel wieder Chicken Scheme.

Du linkst das Chicken-Runtimesystem inklusiv deiner
Scheme/Lisp-Applikation zu deinem C-Programm hinzu.
Mit der Funktion
1
CHICKEN_eval_string (char *str, C_word *result)

wertest du dann einen übergebenen String aus und bekommst das Ergebnis
in result zurück.

von Tobias P. (hubertus)


Lesenswert?

Hallo Makefile,

Danke für den Tipp, das schaue ich mir dann an.
Ist es auch möglich, ein komplettes Programm laufen zu lassen, also den 
Source aus z.B. einer *.lisp-Datei interpretieren zu lassen?
Ich habe hier ein Programm, was in GNU CLISP läuft und ein paar Dinge 
macht. Das liegt als *.lisp-Datei vor. Wenn man diese nun aus C aufrufen 
könnte, wäre das recht lustig :-)

von Rolf M. (rmagnus)


Lesenswert?

Wie gesagt, swig kann dir auch gleich passende Interfaces erzeugen.

von makefile (Gast)


Lesenswert?

Mit CLISP kenne ich mich leider nicht gut aus. Es scheint aber, dass das
Embedding dort sehr anspruchsvoll ist.

Als Beispiel deshalb wieder Chicken Scheme:

test.c
1
#include <chicken/chicken.h>
2
3
int main()
4
{
5
 C_word result;
6
7
 CHICKEN_run(CHICKEN_default_toplevel);
8
 CHICKEN_eval_string("(begin (load \"schemefile.scm\") (print (fac 50)))", &result);
9
 return 0;
10
}

schemefile.scm
1
(define (fac n)
2
    (if (= n 1)
3
        1
4
        (* n (fac (- n 1)))))

Übersetzen mit

gcc test.c -lchicken -o test

So könnte ein Minimalprogramm aussehen, wenn du den Rückgabewert
result in C auswerten möchtest, wird es etwas anspruchsvoller.

von Tobias P. (hubertus)


Lesenswert?

Hallo,
ah ja das sieht schon mal ganz interessant aus. Ich werde mir das noch 
anschauen.

Dann gab es ja noch die Idee mit dem Socket. Es gibt ja viele Programme, 
die so laufen. Das eigentliche Programm ist nur eine dumme 
Konsolenanwendung, aber man kann mit einem Socket sich darauf verbinden 
und kann dann so das GUI realisieren. Wie macht man das?
Da muss ich erst noch ein Protokoll erfinden, welche Daten ich über das 
Socket austauschen will, oder?

Gruss Tobias

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.