Forum: PC-Programmierung lisp: Aufruf der Lambda Funktion


von Daniel(root) (Gast)


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

von Stefan B. (stefan) Benutzerseite


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

von Zwie B. (zwieblum)


Lesenswert?

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

von Stefan B. (stefan) Benutzerseite


Lesenswert?

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

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Zwie Blum ist Kaiser!

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

von Zwie B. (zwieblum)


Lesenswert?

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

von daniel(root) (Gast)


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

von Karl H. (kbuchegg)


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
1
class inc
2
{
3
  public:
4
    inc( int n ) : n_( n ) {}
5
    int operator()( int x ) const { return n_ + x; }
6
7
  private:
8
    int n_;
9
};
10
11
int main()
12
{
13
  int j = inc(10)(1);
14
}

von daniel(root) (Gast)


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

von Zwie B. (zwieblum)


Lesenswert?

@daniel: In SCHEME geht's so, wie du dir das denkst, aber nicht in LISP:
1
> (define (inc n) (lambda(x)(+ x n)))
2
> inc
3
#<procedure:inc>
4
> (inc 10)
5
#<procedure>
6
> ((inc 10) 1)
7
11

von Frank B. (foobar)


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)

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.