Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

Protocols implementation affordances using defrecord/deftype vs. extend-protocol

Aperta
#216 3 commenti 1 reazione 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
4/5
Tempo stimato
3-5 giorni
Idoneità per principianti
35/100
Tipo di issue
Documentazione
Chiarezza
Abbastanza chiara
Stato di attività
Ferma
Stack tecnologico
clojure
Ambito
documentation

Direzione di ricerca

Esamina l’attuale elenco puntato sulle opzioni di implementazione dei protocolli e confronta le possibilità mostrate negli esempi defrecord/deftype e extend-protocol dell’issue. Documenta le differenze in una tabella completa delle funzionalità, includendo il comportamento delle precondizioni e delle postcondizioni, in modo da rendere più chiari i compromessi.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

help wanted

When implementing Protocols using defrecord there are some missing affordances.

As an example, :pre and :post conditions cannot be applied.

[ Yes, I know we will soon have spec but these affordances will not be deprecated AFAIK. ]

Affordances not available on defrecord or deftype
(defprotocol Squarer (square [x]))

(defrecord PosIntSquarer [x]
  Squarer
  (square [_] (* x x)))

; Usage
(defprotocol Squarer (square [x]))
;=> Squarer

(defrecord PosIntSquarer [x]
  Squarer
  (square [_] (* x x)))
;=> practice1.core.PosIntSquarer

(square (->PosIntSquarer 2))
;=> 4
;---^^^ All good

(square (->PosIntSquarer "A"))
;CompilerException java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Number, compiling:(.../core.clj:162:1) 
;---^^^ We would like to prevent this using a simple assertion

(defrecord PosIntSquarer [x]
  Squarer
  (square [_]
    {:pre  [(pos-int? x)]}
    (* x x)))
;=> practice1.core.PosIntSquarer

(square (->PosIntSquarer "A"))
;CompilerException java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Number, compiling:(.../core.clj:162:1) 
;---^^^ The pre-condition is being ignored 

(defrecord PosIntSquarer [x]
  Squarer
  (square [_]
    {:pre  [(pos-int? x)]
     :post [(pos? %)]}
    (* x x)))
CompilerException java.lang.RuntimeException: Unable to resolve symbol: % in this context, compiling:(.../core.clj:158:13) 
;---^^^ The post condition compilation fail shows that all affordances are not available

; Calling externally declared functions is one solution

(defn positive-square [x]
  {:pre  [(pos-int? x)]
   :post [(pos? %)]}
  (* x x))
;=> #'practice1.core/positive-square

(defrecord PosIntSquarer [x]
  Squarer
  (square [_]
    (positive-square x)))
;=> practice1.core.PosIntSquarer

(square (->PosIntSquarer "A"))
;CompilerException java.lang.AssertionError: Assert failed: (pos-int? x), compiling:(.../core.clj:163:1) 
Affordances are available via extend-protocol
(defrecord DirectSquarer [x])
=> practice1.core.DirectSquarer
(extend-protocol Squarer
  DirectSquarer
  (square [this]
    {:pre  [(pos-int? (:x this))]
     :post [(pos? %)]}
    (* (:x this) (:x this))))
;=> nil

(square (->PosIntSquarer 2))
;=> 4

(square (->PosIntSquarer "A"))
;CompilerException java.lang.AssertionError: Assert failed: (pos-int? x), compiling:(.../core.clj:178:1) 

(square (->PosIntSquarer -2))
;CompilerException java.lang.AssertionError: Assert failed: (pos-int? x), compiling:(.../core.clj:176:1) 

I don't want to claim this is a bug. But it's a sign that these options have pros and cons which are not currently well explained.

I would like to develop a more comprehensive table of features / affordances might be nicer than the current bullet list

Lingua principale
HTML
Stelle
259
Fork
275
Metriche di merge delle PR
Nessuna PR unita negli ultimi 30g

Guida per i contributori

Apri la guida per i contributori

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di clojure/clojure-site

Tutte le issue di clojure/clojure-site

Issue simili

Altre issue su Documentation

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.