2012-08-13 5 views
5

Ich bin immer noch mit diesem fremden funktionalen Paradigma lernen ...Wie soll ich eine Liste erstellen und sie in clojure zurückgeben?

Wie würde ich den folgenden Code in Clojure, und in einer funktionalen Weise schreiben? Angenommen, diese fehlenden Teile sind an anderer Stelle definiert und verhalten sich wie in den Kommentaren beschrieben. Hier ist es in Python, die ich kenne.

usernames = [] 
# just the usernames of all the connections I want to open. 
cancelfunctions = {} 
# this global contains anonymous functions to cancel connections, keyed by username 

def cancelAll(): 
    for cancel in cancelfunctions.values(): 
     cancel() 

def reopenAll(): 
    cancelfunctions = {} 
    for name in usernames: 
     # should return a function to close the connection and put it in the dict. 
     cancelfunctions[name] = openConnection() 

Alles, was ich wirklich wissen muß, ist, wie eine neue dict von Rückrufen aufzubauen, wie in der reopenAll Funktion, aber ich bin auch etwas hier mehr Kontext, weil die Chancen ich begehen eine Art funktional Paradigma Grausamkeit, und Sie werden wahrscheinlich das ganze Programm reparieren wollen. :)

+0

Ich weiß, dass dies wahrscheinlich nicht angemessen ist, aber ich konnte nicht widerstehen zu teilen, wenn ich Ihren Hinweis auf die "[Alien Functional Paradigma] (http://landoflisp.com/#guilds)" sah. – DaoWen

Antwort

6

Zum Aufbau von Datenstrukturen in Clojure gehört oft reduce, die eine Folge von Eingaben an eine Funktion liefert, die einen endgültigen Rückgabewert akkumuliert. Hier sind zwei Möglichkeiten, eine Funktion zu schreiben, die eine Zuordnung (d. H. Wörterbuch) von Benutzername zu dem Rückgabewert von open-connection erstellt.

Beachten Sie, dass diese beiden Funktionen einen Wert zurückgeben und den globalen Status nicht mutieren, wie es bei Ihrem Python-Code der Fall ist. Der globale Zustand ist nicht von Natur aus schlecht, aber es ist gut, die Wertgenerierung von der Zustandsmanipulation zu trennen. Für den Zustand, werden Sie wahrscheinlich wollen ein atom:

(def usernames [...]) 
(def cancel-fns (atom nil)) 

(defn init [] 
    (reset! cancel-fns (reopen-all usernames))) 

Und hier sind cancel-all die Vollständigkeit halber:

(defn cancel-all [] 
    (doseq [cancel-fn (vals @canel-fns)] 
    (cancel-fn))) 
+0

Danke, das ist eine sehr gute Antwort! – user1552512

2

Hier ist ein funktionaler Ansatz in Python:

def reopen(usernames): 
    return dict((name, openConnection()) for name in usernames) 

Sie können feststellen, Es ist einfacher, in Python in einen funktionalen Stil zu "übersetzen", bevor man versucht, eine hauptsächlich funktionale Sprache zu verwenden.