Fork me on GitHub

Hello everyone. Slipway by Factor House is now GA and published to Clojars:

🎉 5

Slipway is a Clojure Companion to Jetty.


I'm not much of a regular on this slack but I'll check back in this thread later on to answer questions if there are any. Ta.

Martynas Maciulevičius07:12:50

How does this companionship work? The README doesn't describe anything useful in one sentence. So is it a configuration helper or is it some kind of a separate UI tool? There is a UI so why do you need it if it's a config helper? Is it a UI server configuration tool? Is there a simple way to understand what it accomplishes?

Martynas Maciulevičius07:12:17

Also this post should've probably be posted into #announcements instead.


🎄 🎁 Merry Christmas everybody! I made you a present: a nestable version of #() anonymous functions.

clapping 6
🎄 2
🎁 3

Hi guys, question, I have multiple records, that implement a protocol, but the implementation of each protocol method is basically the same for every record that implements it (might vary one or more form record to record). That said, the records have values passed in the constructor, values which are needed inside the implementation of each method. I know this might sound crazy, but is there a way to reference those values in a way where they are only defined in runtime? Macros are expanded in compile time, so that wouldn’t work I guess. Thoughts? Example:

(defprotocol TestProtocol
  (getFile [this])
  (getName [this]))

(defrecord TestRecord [conf])

(def default-implementation
  {:getFile (fn [this] (:file conf)
   :getName (fn [this] (:name conf)})

(extend TestRecord TestProtocol default-implementation)


You can write (.-conf this) to access the conf field of a record in the default-implementation map.


I am going to try that out, thanks!


also ... you have some missing ) in the code you posted


(defprotocol TestProtocol
  (getFile [this])
  (getName [this]))

(defrecord TestRecord [conf])

(def default-implementation
  {:getFile (fn [this] (:file (.-conf this)))
   :getName (fn [this] (:name (.-conf this)))})

(extend TestRecord TestProtocol default-implementation)

(getFile (TestRecord. {:file "filename" :name "Bob Dabolina"})) ;; => "filename"

👀 1
Fabio Francisco19:12:33

It works! Do you have any idea how and if reflection can be avoided here?

Fabio Francisco19:12:07

Btw, same guy, different username idk why

Fabio Francisco20:12:26

I might need to add type hint or just use a keywordized version of the field name, it should work as well


@U0P0TMEFJ thanks for your help, it worked and I am now able to do what I wanted 🙂

👍 1

Just doing (:conf this) didn't work? It should work, and it is preferable over using the interop syntax when working with records.


Like this should work:

(def default-implementation
  {:getFile (fn [this] (-> this :conf :file))
   :getName (fn [this] (-> this :conf :name))})


this refers to the record, and you can use it like you would use the record anywhere, which is normally to treat it like a map.


This is a somewhat contrived example but there is a curious behavior that may or may not be a bug. Suppose you have the following protocol:

(defprotocol P (f [this]))
And concrete type with a mutable parameter and lock:
(deftype T [^:volatile-mutable x lock]
 (f [this]
   (locking lock
      (set! x true)
      (prn ""))))
Compiler has no problem with this. But move the (prn "") statement outside the (locking …) block and you get:
(deftype T [^:volatile-mutable x lock]
 (f [this]
   (locking lock
     (set! x true))
   (prn "")))

Syntax error (IllegalArgumentException) compiling fn* at (REPL:4:5).
Cannot assign to non-mutable: x
@dmiller spotted this behavior in the lastest ClojureCLR and is sleuthing it on his end but the fact the same error is raised in JVM Clojure suggests that either there is a bug in Clojure proper, or some highly counterintuitive rule is at work here, the details of which are probably worth understanding. Why the compiler would view x as non-mutable in the 2nd example is not clear. Any clarification appreciated.


Tested this in 1.11.1 and 1.12.0-alpha1

Alex Miller (Clojure team)17:12:41

I know we have in the 1.12 list which is in this ballpark (but kind of the opposite)


I added it at and referred to David's bug report at ClojureCLR atlassian:

👍 1

my guess is that this is a by-product of


The compiler will often hoist things like try/catch into immediately invoked anonymous functions, easiest way to give expression like semantics to more complex bytecode


I'm quite relieved to learn that CLJCLR-122 is also a problem over on the JVM, in the hope that someone else will solve the problem before I have to. (The immediate locus of the problem is at the ClojureCLr equivalent to , but the most obvious fix at that location does not work.) (In contrast, CLJ-2126 is not a problem for ClojureCLR; I think this is called a 'happy accident'.)


It turns out that try is sufficient, even without a finally.

(deftype T [^:volatile-mutable x] 
   (f []  
       (set! x 7) 
       (prn ""))))
(deftype T [^:volatile-mutable x] 
   (f []  
       (set! x 7))
     (prn ""))))


I tracked down the cause. Comment added to the CLJ-2743. The cause was code added in 2008.

👍 2

I’m looking to write an efficient repeat-twice transducer that will the elements it receives twice. Of course I’m having trouble with it.


hmmm looking at the source code for partition-all


look at the source of cat, another expansive transducer. 🐱

😻 3

ahh thanks!