26 Oct 2018

# Datafy and tap> in Clojure 1.10

I noticed couple of new features being added to Clojure 1.10. One is tap, which is added to the core ns, and the other is datafy, which is added to clojure.datafy ns.

tap essentially is an atom holding set of fns of single arity, which will be asynchronously called on any value you you send via tap>. You can add a single arity fn to the tap via (add-tap f) and remove the fn via (remove-tap f). Note that you have to remember the fn you added so you can remove it. Otherwise, you have no way of removing the fn, which is an inconvenience but there might be a reason why it is the way it is. I am not sure about its intended use cases but I know it comes handy when you have a set of transformation (important: order of those transformation should not matter) that you would like to apply to any value asynchronously. I can think of following uses cases for tap:

• Collecting some sort of diagnostic information about running system.
• Streaming serious of values to be processed and routed to a sink somewhere.
• May be used (rather abused) to execute some code? hope not.

Enough being said, let us see with a simple example to cover first uses case I said above.

(def context (StringBuilder.))

(defn ->context [x]
(doto context
(.append x)))

;; Then let us add above fn to the tapset
;; Then from any where of our running code, we can do:
(tap> "******* tap start ********\n ")
(tap> "runing.......................\n")
(tap> "******* tap end **********\n ")

;; It will be executed in a separate dedicated thread and will not
;; block or interfere with our running code. Then we print out the context:
(str context)
;; which results in:
;;******* tap start ********
;; runing.......................
;;******* tap end **********

;; Remember to remove the ->context fn once you are done with that session:
(remove-tap ->context)
;; If there is no fn added to the tap, any values you send to tap will be discarded.



The other one I noticed is datafy, which I am more excited about. I am already using it to find out about java classes members, methods and its object graph. Let us take a java class String as an example.

(require '[clojure.datafy :as d])
(d/datafy String) ;; which will print all about its members in a nice clojure ds

;; let us write an fn to give use any member that we would like to find more about:
(defn member-lookup [class member]
(->> class
d/datafy
:members
(filter (fn [[k v]] (= (symbol member) k)))))
;; then use it to find about "intern"
(member-lookup String "intern")
;; returns:
([intern
[{:name intern,
:return-type java.lang.String,
:declaring-class java.lang.String,
:parameter-types [],
:exception-types [],
:flags #{:public :native}}]])

;; public native method that takes no argument, called on string object
;; and returns string like this:
(.intern "test") ;; => "test"



This means we can use above information to create Clojure fns on the fly for java inter-op. One great use case would be to generate Clojure fns out of AWS Java SDK, which I might do if time permits.

20 Oct 2018

# Debug VoidLinux unresolvable lib issue

I have been a happy user of VoidLinux for about a year now and so far have had almost no glitches whatsoever except for updating a year old version of it installed on one of my spare laptop. The issue started as following:

xbps-install -Su
# resulted in following:
# mozjs: broken, unresolvable shlib libicu.so'
# Transaction aborted due to unresolved shlibs.


I do not now about you but I usually start with a google search of what I think is somewhat general terms in my error message, which is “Transaction aborted due to unresolved shlibs” in my case. Searching with the above term came up with number of results and all point to the build system is still running. You can check the status of it here: Void Build Status, which I did find that all is green and idle. So it did not help me resolve my issue. Then, I decided to do one more search with “mozjs: broken, unresolvable shlib libicu.so’”, which is more specific to the state of my box only but that did not help me go anywhere. Then I decided to debug it myself. Following is my commandline session how I resolved it:

# Ran the command again to make sure I have above issue
xbps-install -Su
# again resulted in following:
# mozjs: broken, unresolvable shlib libicu.so'
# Transaction aborted due to unresolved shlibs.
# Notice the /*mozjs*/, which is my clue. Then I did:
xbps-query -Rs mozjs
# from the output, I confirmed that it was not installed on my box,
# which is my second clue to check if my repos url are
# up-to-date. Remember it is a year old version of VoidLinux.  I
# noticed from the output of xpbs-install -u, that the
# void-repo-nonfree url does indeed point to an old url. So, I did:
xbps-remove void-repo-nonfree && xbps-install void-repo-nonfree
# to make sure my repo url is up-to-date. Then it is time to clean my
# repo cache and remove any packages that might be orphened since my
# repo url is pointing to a different url now. Using manpages for
# xpbs-remove, I can do above with:
xbps-remove -Oo
# Then I ran:
xbps-install -Su
# Voila!, My one year old box is up-to-date without any issues now.
# After all of this, I just made an one liner alias in my shell config:
alias c='xbps-remove void-repo-nonfree && xbps-install void-repo-nonfree && xbps-install -Su


So no love lost for VoidLinux and it is still as awesome as ever. Just to recap steps that I took to solve the issue:

1. Start using more general term to do a google search then narrow it to specific ones. If it works, you save time and unneeded effort.
2. Check for the problem package reported. Is it installed? If yes, try removing or updating it to see if it resolves your issue.
3. If you do not see the package installed, it might be repo url + orphaned package issue. So update the repo url, remove orphan packages and rebuild the cache.

If you tried all of the above and your issue still did not get resolved, you might want to post it in VoidLinux forum for help.

04 Oct 2018

# Visualize Google search results from Clojure REPL

While back when I was learning Clojure, I have written a small lib that allows me directly generate bar chart out of google search results from Clojure. I updated it with latest deps and added a fn to save the bar-chart to a png file. You can checkout the project here: https://github.com/oneness/gcount. Here is a one liner to get you going:

git clone git@github.com:oneness/gcount.git && cd gcount && lein repl


Once you are in repl, you can type following:

(search-view-terms ["Clojure Programming" "Elixir Programming" "Elm Programming"])


Above will produce something like this:

03 Oct 2018

# VM flags from running JVM

While I was doing some JVM GC analysis recently, I got curious about the vm flags that java command uses by default if you do not specify it when starting your JVM. Reading up JDK docs, I found jcmd is exactly what you need:

jcmd


That will list all jvm instances running on your system beginning with its pids, which you can pass into jcmd with options to print VM flags like this:

jcmd <pid> VM.flags


There are many options you can use other than VM.flags, which you can get a full list by:

jcmd <pid> help

19 Sep 2018

After taking some time off from work to focus on projects that I like to take on, I set out to find a simple way to use git and emacs workflow to start blogging again. Among plethora of options on the web, I came across this project - Org Static Blog - that I resonated with. It took me no time to set it up and start blogging. Below is my setup:

(use-package org-static-blog
:straight t
:config
;; -----------------------------------------------------------------------------
;; Set up blogging in Emacs
;; -----------------------------------------------------------------------------

(setq org-static-blog-publish-title "BirkeyCo")
(setq org-static-blog-publish-url "https://www.birkey.co/")
(setq org-static-blog-publish-directory "~/github/oneness.github.io/")
(setq org-static-blog-posts-directory "~/github/oneness.github.io/posts/")
(setq org-static-blog-drafts-directory "~/github/oneness.github.io/drafts/")
;;(setq org-static-blog-enable-tags t)
(setq org-export-with-toc nil)
(setq org-export-with-section-numbers nil)

"<meta name=\"author\" content=\"Kasim Tuman\">
<meta name=\"referrer\" content=\"no-referrer\">
<link href= \"static/style.css\" rel=\"stylesheet\" type=\"text/css\" />
<script src=\"static/katex.min.js\"></script>
<script src=\"static/auto-render.min.js\"></script>
<meta http-equiv=\"content-type\" content=\"application/xhtml+xml; charset=UTF-8\">
<meta name=\"viewport\" content=\"initial-scale=1,width=device-width,minimum-scale=1\">")

(setq org-static-blog-page-preamble
<a href=\"https://birkey.co\">Code, Data and Network</a>
`