Fork me on GitHub

So example encrypt: (shell/sh "openssl" "aes-256-cbc" "-a" "-pass" "pass:password" :in "hola") Decrypt (shell/sh "openssl" "aes-256-cbc" "-a" "-d" "-pass" "pass:password" :in "U2FsdGVkX18B/CGSxe0V6G0HmcIuKUzkMhNC0Q9T61g=\n") Notice I can use the :in if I add a \n for the input. The problem is when I receive an encrypted string from a friend who did it with their console, I get the bad decrypt error. Any idea why?


That part I'm not sure of. Backing up a moment to your initial issue, you can do aes-256-cbc via interop directly without shelling out.


I'll have a small POC of that momentarily


@alexmiller is the site a stackoverflow instance, or a custom webapp clone?

Alex Miller (Clojure team)01:11:59

it's question2answer, which is a php/mysql oss app


@josh_tackett I'm not sure but I think that's related to padding behavior on input? here's something that uses the java classes for encode - it's not done as it doesn't match the encoding you get, but it might be a start if you want to use that approach

(import (javax.crypto.spec IvParameterSpec
        (javax.crypto Cipher)
        (java.util Base64))

(defn zero-pad-bytes
  [n s]
  (let [output (byte-array n)
        fill (.getBytes s "UTF-8")]
    (dotimes [i (count fill)]
      (let [write-pos (dec (- (count output) i))
            read-pos (dec (- (count fill) i))]
        (aset output write-pos ^byte (get fill read-pos))))

(defn aes-cbc-encrypt
  (let [enc-key "password"
        init-vector "encryptionIntVec"
        iv (IvParameterSpec. (.getBytes init-vector "UTF-8"))
        skey-spec (SecretKeySpec. (zero-pad-bytes 64 enc-key) "AES")
        cipher (Cipher/getInstance "AES/CBC/PKCS5PADDING")
        _ (.init cipher Cipher/ENCRYPT_MODE skey-spec iv)
        encrypted (.doFinal cipher (.getBytes s "UTF-8"))]
    (String. (.encode  (Base64/getEncoder) encrypted))))


delurks for over a year or so - recording an Illegal Argument podcast episode tonight - wondering how many clojurians are running UNDER Java 11+ at all?


@talios We're still on OpenJDK 8 because we have some pieces of legacy infrastructure that won't run on 9+ (and that's why we've migrating off those things).


fun. good to know - sounds like we’re about to have another “but Java 11+ is dead/ignored rant” from Greg hah.


co-host of #illegalargument


We've been testing against OpenJDK 11 for quite a while and we're close to moving up to that on some servers I think. We found an interesting change of behavior in the Locale class with currency formatting 🙂

Alex Miller (Clojure team)02:11:30

Based on the last Clojure survey, most are

Alex Miller (Clojure team)02:11:49 Q16 - this is multi-select, so it's hard to tell exactly but almost 70% were still using Java 8

Alex Miller (Clojure team)02:11:12

I am very curious to see what this looks like for 2020. I expect 9 and 10 should be mostly dead (no one should use those now), but I'm expecting maybe about equal for 8 and 11

Alex Miller (Clojure team)02:11:31

that's my prediction at least :)


@alexmiller cheers for the link


Java 9 was a very disruptive release for a lot of people -- so I can certainly see people staying on 8 much longer than they might have stayed on previous releases.

Sandae Macalalag03:11:02

Why would I use Clojure? I used it before during the early years of my career and it did help me to become a better programmer. I guess what is I'm asking now is, why would I use it? When most of the tooling/language now can make us productive? i.e. Functional Javascript, Immutable JS libraries, TypeScript typings, etc.


I did listen to this podcast episode a few days ago and I might answer a few of your questions


Having a common language for back-end and front-end development is cited by some as an advantage. Yes, I know JavaScript can do that, too, although I don't know whether server-side JavaScript is capable of achieving the same performance that Clojure on the JVM is (I haven't looked carefully to see).


Clojure is, by culture/convention/included-libraries, immutable by default, as opposed to something you have to go out of your way to opt into. Is that the case for JavaScript development these days?


@sandae.macalalag We use it because we're on the JVM and it's a great general-purpose language that eliminates whole classes of potential errors by virtue of immutable data structures and the ability to work consistently with higher-level abstractions more easily than most other JVM languages. We also use it for the pure "joy" it brings with the fluid REPL-driven/-based workflow 🙂 It sounds like you're asking from a JS background p.o.v. so more from a client side of the house than the server side?

Sandae Macalalag04:11:36

On server-side as well with NodeJS.


FWIW, I've been a professional programmer for about 35 years and I've been using Clojure for close to nine years in production now, and I'm the happiest I've ever been -- and that counts for a lot, for me 🙂

👍 20
clj 4

Overall tho', I think it's very hard to persuade folks to switch to Clojure(Script) when they believe they are already happy and productive with the language/tooling they already use... and I'm not sure how much effort it's worth putting into "evangelism"...?


Regardless of how many years as a programmer, I always found it interesting that most of the people working with Clojure always bring the "I enjoy the workflow with the REPL and I'm just a happier programmer" to the surface of this discussion. IMO, if a language/tooling can bring you joy on tasks you have to do more or less 40h per week its enough to at least give it a try. Going around the topic of putting effort into evangelism, I personally found easier to do pair programming with people and show them how's the workflow on a daily basis rather than just talk about the language, unfortunately, this takes more time and the person need to be open to experimenting with new language/tooling.

💯 8
Sandae Macalalag06:11:46

What IDE or editor you guys used to get the benefit of REPL fully?


There's plenty of them out in the wild and on top of my mind are emacs + cider, spacemacs, IntelliJ + Cursive, and Vim. Before Clojure I was working with Ruby and JavaScript with Vi so I opted for emacs + evil + cider. Most of my teammates are using IntelliJ + Cursive It always depends on what you want for yourself. As far as I understood, you're curious about Clojure and you want to try it. This is great! If you don't mind I'll give you one advice: if you choose emacs, I do not recommend you try to learn Clojure and it at the same time. Most likely you'll be frustrated with either of them because you introduced too many changes at the same time in your workflow. Try something with an easy setup like IntelliJ + Cursive while you're learning the basics of the language. Furthermore, it always interesting to see what the community is doing on a daily basis. The survey is a rich source of information. Source:


The workflow thing is interesting because that isn't inherent in the language or the tools -- it's a practice you have to learn (or be taught), but it's a practice that doesn't "fit" with a lot of other technology because even those with "REPLs" don't have the same semantics and therefore can't really support that practice... I don't think we do a very good job of onboarding new folks with that practice...


is there any particular reason clojure.core's comparison operators (< etc) only work with numbers instead of using Comparable?

👍 4

You mean like (< \a \b) for example? My (wild) guess is that they’re optimized for numbers for performance reasons.


yes. my use case would be comparing datetimes


optimizing for numbers is fine but that shouldn't mean throwing everything else out


You can use clojure.core/compare on any two Comparable objects, I believe, and define your own functions on top of clojure.core/compare with names more similar to what you want.


Yes, as above. It’s not that you can’t do it, you just have to reach for the more general compare to do it. Take subs and subvec. They do the same thing, albeit on strings vs vectors. You could write a single function that checks the type of incoming argument and then delegates to the correct machinery, but that would incur some overhead for things commonly appear in hot code paths. I guess someone decided at some point (probably Rich), that it wasn’t worth it.


ok i'll just go override all the comparison operators in core brb my point is that at the language level it really shouldn't be hard to optimize for hot paths while also being convenient


I do not know how difficult or time consuming it would be to change Clojure's < > etc. to do as you wish, as I haven't investigated closely. I know that there are inner loops involving < > on long and int values that are desired to produce high performance JVM byte code, and it isn't clear to me that the compiler can always do as good a job of that if those functions worked on arbitrary objects, too.


As my own personal guess, I suspect the Clojure core developers would prefer to focus their efforts on other language enhancements than that one, even if it is possible.


those high-performance loops already expect numeric values, so i'd assume that optimizing the hot paths based on those inferred types shouldn't be impossible...


It seems impossible that generalizing < > etc. would make them faster. It might make them slower, although perhaps it could be done in such a way that they do not get much slower, true. As I mentioned, I think the main issue is that such a generalization of those functions isn't interesting to the Clojure core developers (again, my guess, not from certain knowledge of their priorities)


> it's a practice you have to learn (or be taught) True. IMO, it's like learning Vim just by yourself. Most of time you have no idea of what you can do and some times you do but you have no idea how to Google it. However, when you pair programming with someone in order to learn Vim it's so much easier. @ericnormand did a great job on this REPL-Driven Development course (thank you for that)

Michael J Dorian14:11:35

Actually, can anyone recommend information on repl-based development practices? I use the repl a fair amount when writing my hobby code but I'd love to hear more ideas on the subject. Bonus points if I can convince the other dev on my hobby project that repl based development isn't total nonsense!


It looks like the link above, while not free, can give you access to all of Eric's courses, including the ones on REPL driven development, for $49/mo, so for $49 you can find out whether you like his courses or not, then stop if you don't want any more.


(I am not affiliated with that business, nor am I even a customer, but I've heard good reviews about his courses)

Michael J Dorian14:11:05

Thanks! I'll take a look! I don't suppose I could get that information in a book format could I? 😁


I really enjoyed this video back in the day:

👍 8
Michael J Dorian14:11:35

Lol, ok, I will just get over my video aversion! Thanks!


I think it would take a lot of pages of screen shots to give a detailed account of what REPL driven development is like. Someone may have written it in book form, but it would be quite long in that form, I believe.

Michael J Dorian14:11:39

That makes sense!


Sean Corfield has a few videos publicly available where he demonstrates his workflow, which includes REBL. REBL is included with Datomic licenses, or is available for $3/month via Patreon subscription from Cognitect. Videos: . REBL:


thank you for mentioning (and creating?) this - am happily digesting it now :)

Noah Bogart15:11:10

Does anyone know of a project like that handles things like “before” and “after” blocks?


There's a variant that is 100% compatible with clojure.test as well, including all the editor/tooling support


(you just don't quite get such nice output because the latter has to use clojure.test reporting mechanism, whereas the former has its own)

👍 4
Noah Bogart16:11:55

Oh wow I’ve not seen that! Thanks, I’ll check those out!


There's a #expectations channel if you have deeper questions. expectations.clojure.test is actively maintained and in heavy use where I work.


Hmm, I should add an example of expecting which makes it flow a bit more like speclj:

(defexpect some-test
  (expecting "it is even"
    (expect even? (some-function))))
You can "expect" any predicate and you can "expect" a Spec (`clojure.spec`) as well -- plus all the destructuring more... predicates.


(readme updated 🙂 )

😍 4
Noah Bogart17:11:21

Damn, what speed!


You caught me just after my morning coffee -- it was a good time 🙂

Noah Bogart15:11:41

Sadly, that one has been defunct (and certainly not feature complete lol) for a couple years now


I'm trying to achieve something that feels like there is probably a pattern/idiom for... but I'm not aware if there's any function to deal with it. I have a collection [a b c d e f] which I want to transform into a collection of collections [[a b c] [d e] [f]]. The way to aggregate is... take elements until a sum of a property of each element is met. On a more meta question, does anyone now of a search engine where I can search for type/shape interfaces? Something similar to what Haskell has, where I can find functions that map from [] to [[]].


That seems exactly what I need 🙂 thank you!


And for your second question, a reduce would suffice. A stateful transducer would also do the trick (look into partition-by for inspiration)

thanks 4
Alex Miller (Clojure team)16:11:15

and partition-all is prob useful

thanks 4

Thanks 🙂 looking into the partition functions now.


what’s the best way to run an embedded JS engine in the JVM? Still nashorn?


thanks y’all. I think I specifically need Node.js. I don’t think I can change the VM it runs in otherwise Graal would work


I’ll check out J2V8, which might be close enough, but I also found

Jakub Holý (HolyJak)21:11:34

Hi hackers! I need to replace a single occurrence of a string close to the beginning of a file . Is there a better way than invoking sed -i s/.../? Slurp + replace-first + spit is nice simple but not good and wasteful if the file is large. Perhaps line-seq and something to write it, but can I write into the file line-seq is reading? (Ideally I'd not pass the rest of the file after the change through my program as it is unchanged but I guess that isn't possible.)


the underlying problem is that on disk a file is not a random access linked list of lines


anything you do that changes the length of the file requires changing everything to the end of that inode (and potentially allocating a new inode and/or altering later ones) - but that's all OS and fs specific

👍 4
Jakub Holý (HolyJak)22:11:01

I was afraid so. Thank you.