mikrocontroller.net

Forum: PC-Programmierung lisp: Aufruf der Lambda Funktion


Autor: Daniel(root) (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

mich interessiert gerade folgendes Problem

(lambda(x)(+ x 10))
#<FUNCTION :LAMBDA (X) (+ X 10)>

((lambda(x)(+ x 10))1)
11

ok soweit, jetzt generische Version

(defun inc(n)(lambda(x)(+ x n)))
INC

(inc 10)
#<FUNCTION :LAMBDA (X) (+ X N)>

((inc 10)1)

*** - EVAL: (INC 10) is not a function name; try using a symb
The following restarts are available:
USE-VALUE      :R1      Input a value to be used instead.

ich hoffe ihr erkennt was ich vorhabe
alternativ in Python

inc = lambda n: lambda x: x+n
inc(10)(1)
11

ich würde gerne wissen wie das in CLisp funktioniert.
Ich vermute, dass das an der folgenden Zeile liegt
(inc 10)
#<FUNCTION :LAMBDA (X) (+ X N)>
hier steht N und nicht 10 .. als ob keine "Ersetzung"
stattgefunden hat.

Grüsse, Daniel

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Interessant, SCNR, meine ersten beiden Lisp Zeilen :-)

Wenn du die Rechenvorschrift bei der Definition der Funktion nicht nicht 
hast:

(defun inc (fn n) (funcall fn n))
(inc #'(lambda(x)(+ x 1)) 10)

Bzw. bei manchen Lisp gleichbedeutend

(defun inc (fn n) (funcall fn n))
(inc (lambda (x) (+ x 1)) 10)

Oder wenn du die Rechenvorschrift bei der Definition von inc hast aber 
noch nicht die Parameter (vgl. dein Pythonfall):

(defun inc (a b) ((lambda(x y)(+ x y)) a b))
(inc 1 10)

Königsklasse dann: Wenn du bei der Definition von inc noch nix hast 
außer der Zahl der Parameter

(defun inc (fn a b) (funcall fn a b))
(inc (lambda(x y)(+ x y)) 1 10)

Die Kaiserklasse dann wenn du auch die Zahl der Parameter nicht kennst. 
Müsste man die Argumentliste abarbeiten bis sie leer ist z.B. über 
Rekursion. Sorry, da steige ich mal aus. ;-)

Tipp für Onlineexperimente
http://www.solve-et-coagula.com/As3Lisp.html

Autor: Zwie Blum (zwieblum)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
das da ist die Vorschrift, wie die Funktion gebaut wird:
(defun inc(n)(lambda(x)(+ x n)))
Wenn du jetzt
(inc 10)
aufrufst, liefert es dir eine Funktion, mit der du machen kannst, was du 
willst. z.B.:
(setq zippy (inc 10))
zippy
#<FUNCTION :LAMBDA (X) (+ X N)>
(funcall zippy 3)
13

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nachtrag: Die Experimente habe ich mit http://gigamonkeys.com/book/ 
Unterstützung gemacht.

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Zwie Blum ist Kaiser!

(defun inc(n)(lambda(x)(+ x n)))
((inc 10) 3)

Autor: Zwie Blum (zwieblum)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
grins und weil's so spassig ist, wie geht das in C++?

Autor: daniel(root) (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
(defun inc(n)(lambda(x)(+ x n)))
(funcall (inc 10) 1)
11

funktioniert, nicht aber

(defun inc(n)(lambda(x)(+ x n)))
((inc 10)1)

wobei ich ja der Meinung bin, dass es ebenfalls funktionieren soll.
Soweit ich verstanden haben, läuft es ja auch bei Stefan B(?)
Im Moment nutze ich clisp unter cygwin und ihr?

apply kenne ich aus Python auch, empfinde es aber irgendwie
krückenhaft .. weiss selbst nicht warum :)

>>> from math import log10
>>>
>>> log = lambda base: lambda x: log10(x)/log10(base)
>>>
>>> log(2)(8)
3.0
>>>
>>> apply(log, (2,))
<function <lambda> at 0x021F11F0>
>>>
>>> apply(apply(log, (2,)), (8,))
3.0
>>>

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Zwie Blum schrieb:
> grins und weil's so spassig ist, wie geht das in C++?


Ich hab leider keinen VC++ 2010 da, der schon lambda Funktionen kann, 
daher kann ich das nicht ausprobieren. Selbst hab ich lamda Funktionen 
in C++ noch nicht benutzt und was ich auf die Schnelle gegoogelt habe 
hat mich nicht wirklich weiter gebracht, als das ich mich trauen würde 
da etwas ungetestet hinzuschreiben.

Ansonsten gehts natürlich immer über einen Funktor, also einer Klasse 
die einen operator() hat
class inc
{
  public:
    inc( int n ) : n_( n ) {}
    int operator()( int x ) const { return n_ + x; }

  private:
    int n_;
};

int main()
{
  int j = inc(10)(1);
}

Autor: daniel(root) (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:
> Ansonsten gehts natürlich immer über einen Funktor, also einer Klasse
> die einen operator() hat

das ist ganz nützlich und sauber
am besten noch die Klasse als template class auslegen, damit
auch return vom operator() sich anpassen kann.
Beim Hinzufügen noch einer Ebene wird man eine wrapper Klasse
brauchen .. vielleicht lokale Klasse. Ob es dann noch sauber empfunden
wird, weiss ich nicht. Ich habe noch das Haskell currying im Hinterkopf
was recht elegante Idee ist. Die Funktion x von a,b,c,d wird beim
Aufruf x(a,b,c) in Funktion von einer Variable "konvertiert".

Autor: Zwie Blum (zwieblum)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@daniel: In SCHEME geht's so, wie du dir das denkst, aber nicht in LISP:
> (define (inc n) (lambda(x)(+ x n)))
> inc
#<procedure:inc>
> (inc 10)
#<procedure>
> ((inc 10) 1)
11

Autor: Frank Buss (foobar)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Grund liegt in dem Unterschied von Lisp-1 und Lisp-2. Scheme ist 
z.B. ein Lisp-1 und Common Lisp ein Lisp-2. Hier die Details:

http://www.dreamsongs.org/Separation.html

(PS: CLisp ist übrigens nicht die Abkürzung für Common Lisp, sondern 
CLisp ist nur eine von vielen Common Lisp Implementierungen, die gut 
portierbar ist und auch unter Windows läuft)

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.