clojure / clojure/clojure-site

Protocols - clarify access to parameters

Open
#215 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

help wanted
Dominant language
HTML
Stars
259
Forks
275
PR merge metrics
No merged PRs in 30d

Description

There are various ways to define and access properties defined with protocols and data types which are non-obvious and not explained or clarified in the Protocols or Data Types guides

I propose updating the Protocol guide with this examples:

Names and values when using defrecord directly
(defprotocol DeviceRegistration
  "Protocol to register various IOT devices"
  (register [device])
  (ping [device]))

(defrecord RaspberryPi [device-id location registry-id]
  DeviceRegistration
  (register [_]
    (->RaspberryPi device-id location 789))

  (ping [_]
    (= 789 registry-id)))

register and ping ignore the method parameters. Instead they uses the properties directly from the record.

Sample Usage
(def rasp-pi (map->RaspberryPi {:device-id 123 :location {:x 123.4 :y 432.1}}))
;=> #'practice1.core/rasp-pi

(def registered-pi (register rasp-pi))
;=> #'practice1.core/registered-pi

(println (type registered-pi))
;practice1.core.RaspberryPi

(def pinged? (ping registered-pi))
;=> #'practice1.core/pinged?

(println pinged?)
; true

Note: Diligent readers will have observed that we can only ever register or ping one RaspberryPi using this code. It's good enough for the example but maybe not production quality.

Names and values when using extend-protocol
(defrecord Arduino [device-id location registry-id])

(extend-protocol DeviceRegistration
  Arduino
  (register [device]
    (assoc device :registry-id 890))

  (ping [device]
    (= 890 (:registry-id device))))

register and ping do not have access to the record directly. They access record properties from the method parameter, which is the Arduino record.

register creates a new Arduino record via assoc. In this case it is simpler than creating a new Arduino record using either ->Arduino or map->Arduino functions supplied by defrecord.

Sample Usage
(def arduino (map->Arduino {:device-id 345 :location {:x 432.1 :y 987.6}}))
;=> #'practice1.core/arduino

(def registered-arduino (register arduino))
;=> #'practice1.core/registered-arduino

(println (type registered-arduino))
;practice1.core.Arduino

(def pinged? (ping registered-arduino))
;=> #'practice1.core/pinged?

(println pinged?)
;true
Code in the wild uses this

Most code I see reads more like, ahem, this:

(extend-protocol DeviceRegistration
  Arduino
  (register [this]
    (assoc this :registry-id 890))

  (ping [this]
    (= 890 (:registry-id this))))

In some languages there is a keyword this or self and it has a special meaning. It kind of does in these cases too - even though the symbol itself is not special in Clojure. Rather than use conventionally privileged words, I prefer the more descriptive option.

Obligatory Clojure documentation rant

Following on from the this mini-rant, I am not a fan of x y z and foo and bar as example parameters or method calls.

Documentation comes to life when it is illustrated with simple and easily understood examples rather than abstract characters and meaningless phrases.

I know 'real things' come and go but these guides are not written to see the heat death of the universe. Are they?

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by locating the Protocols and Data Types guides in the clojure-site documentation and review how protocol methods, defrecord, and extend-protocol are currently explained. Use the issue's Clojure examples as the reference for the proposed clarification; done means the guides clearly explain property access and parameter naming in these cases.

Written by the indexing model from the issue text.

Assessment

Tech stack
clojure
Domain
documentation
Issue type
Documentation
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.