0 Daumen
224 Aufrufe

Frage:

Dieser Codeschnippsel tut nicht, was er suggeriert. Welche suspekten "Techniken" werden hier verwendet?

(1) Gruppieren von zwei Anweisungen in einem do
(2) def in def (Redefinition von globalen Bezeichnern)
(3) Verwendung veränderlicher Datenstrukturen
(4) Vermeiden von higher-order Functions
(5) nur ein Parameter an die Funktion

Ansatz/Problem:

Redefinition von globalen Bezeichnern sollte man natürlich vermeiden sowie veränderliche Datenstrukturen, da man Zustand vermeiden will. Das Vermeiden von higher-order functions würd ich auch nicht unbedingt als suspekt bezeichnen. Genau so wie nur einen Parameter an eine Funktion zu übergeben.

Übersehe ich irgendwas?


Code:

(defn my-fancy-function [coll]
(def result [])
(def x 0)
(for [element coll]
  (do
    (def result (conj result (* element x)))
    (def x (inc x))))
result)

Avatar von

1 Antwort

0 Daumen

Antwort mit KI erzeugt

Analyse des Codes und der fraglichen Techniken

Zunächst ist es wichtig, den gegebenen Clojure-Code zu analysieren, um zu verstehen, warum er suboptimal oder "suspekt" ist:

clojure
(defn my-fancy-function [coll]
  (def result [])
  (def x 0)
  (for [element coll]
    (do
      (def result (conj result (* element x)))
      (def x (inc x))))
  result)


Hier sind die problematischen Aspekte und die benutzten Techniken:

(1) Gruppieren von zwei Anweisungen in einem do:
Die Verwendung von do ist hier nicht unbedingt suspekt, da do dazu dient, mehrere Ausdrücke zu sequenzieren und den Wert des letzten Ausdrucks zurückzugeben. Im vorliegenden Fall, könnte der do Block berechtigt sein, um mehrere Operationen durchzuführen.

(2) def in def (Redefinition von globalen Bezeichnern):
Dies ist tatsächlich ein großes Problem. def wird normalerweise verwendet, um globale, unveränderliche Bindungen zu erstellen. Es sollte nicht innerhalb einer Funktion verwendet werden, um lokale Variablen zu erzeugen oder zu modifizieren. Dadurch überschreiben wir globale Definitionen, was zu unvorhersehbarem Verhalten führt.

(3) Verwendung veränderlicher Datenstrukturen:
Die def-Bindungen in dem vorliegenden Code verwenden veränderliche Datenstrukturen (result, x). Dies führt zu unerwünschtem Zustand und macht die Funktion nicht-funktional und schwer testbar.

(4) Vermeiden von Higher-Order-Functions:
Dieser Punkt ist offiziell im Code nicht ersichtlich, aber in Clojure und der funktionalen Programmierung sollte man vermehrt auf Higher-Order-Functions wie map, reduce und andere setzen, um Funktionen zu schreiben, die ohne Seiteneffekte auskommen.

(5) Nur ein Parameter an die Funktion:
Dies ist kein Problem. Eine Funktion kann berechtigterweise nur einen Parameter haben. Es ist nicht grundsätzlich problematisch oder suspekt.

Basierend auf den Erkenntnissen erklären sich die suspekten Techniken insbesondere durch Punkt 2 und 3. Der Code versucht, den Zustand zu modifizieren und verwendet def innerhalb einer Funktion, was falsch ist.

Verbesserter Code:

Stattdessen könnten wir eine pure funktionale Lösung anbieten, die keine globalen Zustände verändert und stabil und vorhersagbar ist. Wir könnten reduce nutzen, um dies zu erreichen:

clojure
(defn my-fancy-function [coll]
  (let [result (reduce
                 (fn [[res x] elem]
                   [(conj res (* elem x)) (inc x)])
                 [[] 0]
                 coll)]
    (first result)))


Erklärung des verbesserten Codes:

1. Wir verwenden let, um eine lokale Bindung result zu erstellen.
2. Die reduce-Funktion iteriert durch das coll, wobei es einen Akkumulator [res x] führt.
- [res x] ist ein Vektor, der aus dem Ergebnis-Vektor res und dem Zähler x besteht.
3. Die Lambda-Funktion innerhalb von reduce:
- res ist der bisherige Ergebnis-Vektor.
- x ist der aktuelle Zähler.
- elem ist das aktuelle Element aus coll.
- (conj res (* elem x)) fügt das Produkt des aktuellen Elementes und des Zählers hinzu.
- (inc x) erhöht den Zähler.
4. Nach der Reduktion geben wir nur den Ergebnis-Vektor zurück.

Diese Version vermeidet globale Zustände und ist vollständig funktional und sicher in einem Clojure-Umfeld.
Avatar von

Ein anderes Problem?

Stell deine Frage

Ähnliche Fragen

0 Daumen
1 Antwort
0 Daumen
1 Antwort
0 Daumen
1 Antwort

Willkommen bei der Stacklounge! Stell deine Frage einfach und kostenlos

x
Made by a lovely community