<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><atom:link href="http://paolopiersanti.it" rel="self" type="application/rss+xml"/><title>slowcod's blog</title><link>http://paolopiersanti.it</link><description>Notes, thoughts about software &amp; more...</description><lastBuildDate>Fri, 08 Jan 2021 22:07:10 +0100</lastBuildDate><generator>clj-rss</generator><item><guid>http://paolopiersanti.it/blog/posts-output/2021-01-08-cider-save-history-file/</guid><link>http://paolopiersanti.it/blog/posts-output/2021-01-08-cider-save-history-file/</link><title>Cider: Save History File per Project</title><description>&lt;h2 id="how&amp;#95;to&amp;#95;have&amp;#95;a&amp;#95;cider-nrepl&amp;#95;history&amp;#95;file&amp;#95;per&amp;#95;project"&gt;How to have a cider-nrepl history file per project&lt;/h2&gt;&lt;p&gt;Well, indeed it is very simple, just set into &lt;code&gt;.dir-locals.el&lt;/code&gt; Emacs file the variable &lt;code&gt;cider-repl-history-file&lt;/code&gt;&lt;/p&gt;&lt;pre&gt;&lt;code class="lisp"&gt;&amp;#40;&amp;#40;cider-repl-mode
  &amp;#40;cider-repl-history-file . &amp;quot;.cider-nrepl.history&amp;quot;&amp;#41;&amp;#41;&amp;#41;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;When Emacs starts it reads this file and the variable get assigned the relative path bounded to the current directory - where the &lt;code&gt;.dir-locals.el&lt;/code&gt; is found -.&lt;/p&gt;&lt;p&gt;When Emacs is closed the history is saved into the &lt;code&gt;.cider-nrepl.history&lt;/code&gt; file, as expected.&lt;/p&gt;&lt;p&gt;Quit everything togheter (cider-nrepl and Emacs) to avoid what follows.&lt;/p&gt;&lt;p&gt;A little nuisance to keep in mind:&lt;/p&gt;&lt;p&gt;when cider-nrepl starts it binds some hooks in Emacs, to save history either at exiting or closing the buffer, if the cider-nrepl is quitted before exiting Emacs the aforementioned hooks are onset but the variable &lt;code&gt;cider-repl-history-file&lt;/code&gt; is not bounded anymore (only in &lt;code&gt;cider-repl-mode&lt;/code&gt;), and trying to exit from Emacs triggers the error&lt;/p&gt;&lt;pre&gt;&lt;code class="lisp"&gt;stringp, nil
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;To overcome this either quit everything togheter via &lt;code&gt;C-x C-c&lt;/code&gt; or open another buffer/file &amp;#42;Scratch&amp;#42; whatever not in cider-mode and exit from there. Reopening another cider-nrepl and hitting &lt;code&gt;C-x C-c&lt;/code&gt; works too.&lt;/p&gt;&lt;p&gt;Unluckily setting the variable to be bounded with other modes - i.e. cider-mode, clojure-mode or nil (all modes) - does not work in a smooth way, an empty &lt;code&gt;.cider-nrepl.history&lt;/code&gt; might be created nested in the project structure, in the same directory where Emacs started opening a file - i.e. &lt;code&gt;src/yourapp/.cider-nrepl.history&lt;/code&gt; -&lt;/p&gt;</description><pubDate>Fri, 08 Jan 2021 00:00:00 +0100</pubDate></item><item><guid>http://paolopiersanti.it/blog/posts-output/2019-10-25-shadows-cljs-cider-setup/</guid><link>http://paolopiersanti.it/blog/posts-output/2019-10-25-shadows-cljs-cider-setup/</link><title>shadows-cljs + Cider</title><description>&lt;h2 id="shadows-cljs&amp;#95;+&amp;#95;cider"&gt;Shadows-cljs + Cider&lt;/h2&gt;&lt;p&gt;The following Shadows-cljs project configuration enable to launch a REPL directly from Cider, opposed to the default setup, which starts a REPL from Shadows-cljs to which you can connect from Cider, choosing &lt;code&gt;Connect to an existing REPL&lt;/code&gt;.&lt;/p&gt;&lt;pre&gt;&lt;code class="clojure"&gt;{:source-paths
 &amp;#91;&amp;quot;src/cljs&amp;quot;&amp;#93;

 :dependencies &amp;#91;&amp;#91;binaryage/devtools &amp;quot;0.9.7&amp;quot;&amp;#93;
				&amp;#91;reagent &amp;quot;0.8.0-alpha2&amp;quot;&amp;#93;
				&amp;#91;cider/cider-nrepl &amp;quot;0.22.2&amp;quot;&amp;#93;
				&amp;#91;cider/piggieback &amp;quot;0.4.1&amp;quot;&amp;#93;
				&amp;#91;refactor-nrepl &amp;quot;2.5.0-SNAPSHOT&amp;quot;&amp;#93;&amp;#93;

 ;; set an nrepl port for connection to a REPL.
 :nrepl {:port       8777
		 :middleware &amp;#91;refactor-nrepl.middleware/wrap-refactor&amp;#93;}

 :builds
 {:app {:target     :browser
		:output-dir &amp;quot;public/js/compiled&amp;quot;
		:asset-path &amp;quot;/js/compiled&amp;quot;

		:modules
		{:main
		 {:entries &amp;#91;your.ns&amp;#93;}}

		:devtools
		;; before live-reloading any code call this function
		{:before-load vg.core/stop
		 ;; after live-reloading finishes call this function
		 :after-load  your.ns/start
		 ;; serve the public directory over http at port 8700
		 :http-root   &amp;quot;public&amp;quot;
		 :http-port   8700
		 :preloads    &amp;#91;devtools.preload&amp;#93;}
		}}}
&lt;/code&gt;&lt;/pre&gt;</description><pubDate>Fri, 25 Oct 2019 00:00:00 +0200</pubDate></item><item><guid>http://paolopiersanti.it/blog/posts-output/2018-03-04-pure-function-refactoring/</guid><link>http://paolopiersanti.it/blog/posts-output/2018-03-04-pure-function-refactoring/</link><title>Pure function refactoring</title><description>&lt;h2 id="a&amp;#95;pratical&amp;#95;example"&gt;A pratical example&lt;/h2&gt;&lt;h3 id="the&amp;#95;story"&gt;The story&lt;/h3&gt;&lt;p&gt;In my early days in Clojure I translated an application from Java, fine! It carried on since some days ago I was committed to implement new functionalities. Looking at the code I realized it was more a code conversion than a rewriting in the spirit and philosophy of the new programming language. The original Java/IDE/imperative mindset leaked through all the porting, &lt;i&gt;loops, state, functions tangled with side effects, and so on.&lt;/i&gt;&lt;/p&gt;&lt;p&gt;Here I want to focus in particular on the refactoring of an function which performed a task in a unclear and confused manner to a version of the function that perform the same task possibly concise and easily to reason about, a &lt;strong&gt;pure function&lt;/strong&gt;.&lt;/p&gt;&lt;h3 id="the&amp;#95;problem"&gt;The problem&lt;/h3&gt;&lt;p&gt;Launch a REPL and try to make some changes to the code below, just some business logic change, and you soon will realize how heavy coupled it is with different functionalities that you have to take care of before to execute it.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;there are db calls&lt;/li&gt;&lt;li&gt;there are log calls&lt;/li&gt;&lt;li&gt;there is a specialized log object&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;all of them producing side-effects and not required for the task at point.&lt;/p&gt;&lt;p&gt;The gist here is the following:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;you have order lines that must be reset in order to be scheduled for next billing cycle&lt;/li&gt;&lt;li&gt;each order line is subject to different business policy, shipping dates are renewed and so on...&lt;/li&gt;&lt;li&gt;finally the order header' s shipping date must be updated with the soonest order line' s shipping date&lt;/li&gt;&lt;li&gt;you would verify that giving an order detail to the function you get back order lines with correct  policies applyed&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Here is the code&lt;a href='#fn-1' id='fnref1'&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&amp;#40;defn reset!
  &amp;quot;Reset order state for the next billing.&amp;quot;
  &amp;#91;db elog order&amp;#93;

  ;; go through the order detail and reset each line
  ;; when the sequence is completed return the min shipping date

  &amp;#40;let &amp;#91;min-shipping-date
   &amp;#40;loop &amp;#91;xs order min-date &amp;#40;t/date-time 2039 1 1&amp;#41;&amp;#93;
	&amp;#40;if-let &amp;#91;line &amp;#40;first &amp;#40;seq xs&amp;#41;&amp;#41;&amp;#93;
	 &amp;#40;if &amp;#40;not= &amp;quot;ZSP&amp;quot; &amp;#40;:item-id line&amp;#41;&amp;#41; ; bypass zsp items
	  &amp;#40;let &amp;#91;line &amp;#40;reset-line line&amp;#41;&amp;#93;

	   ;; side-effects here !!!
	   &amp;#40;log/info &amp;quot;Processing order line&amp;quot; &amp;#40;str  &amp;#40;:order&amp;#95;id line&amp;#41; &amp;quot;/&amp;quot; &amp;#40;:order&amp;#95;line&amp;#95;id line&amp;#41;&amp;#41;&amp;#41;

	   ;; side-effects here too !!!
	   &amp;#40;j/update! db :ORDER&amp;#95;LINE line &amp;#91;&amp;quot;order&amp;#95;id=? AND order&amp;#95;line&amp;#95;id=?&amp;quot; &amp;#40;:order&amp;#95;id line&amp;#41; &amp;#40;:order&amp;#95;line&amp;#95;id line&amp;#41;&amp;#93;&amp;#41;

	   ;; do other things here, omitted for clarity
	   ;; ...

	   &amp;#40;recur &amp;#40;rest xs&amp;#41; &amp;#40;if &amp;#40;t/minus &amp;#40;:shipping&amp;#95;date line&amp;#41; min-date&amp;#41; &amp;#40;:shipping&amp;#95;date line&amp;#41; min-date&amp;#41;&amp;#41;&amp;#41;
	 &amp;#40;recur &amp;#40;rest xs&amp;#41; min-date&amp;#41;&amp;#41;
	min-date&amp;#41;&amp;#41;&amp;#93;&amp;#41;

	;; perform post operations after order detail reset

	;; side effects here !!!
	&amp;#40;j/update! db :ORDER {:shipping-date min-shipping-date} &amp;#91;&amp;quot;order&amp;#95;id=?&amp;quot; &amp;#40;:order&amp;#95;id line&amp;#41;&amp;#93;&amp;#41;

	;; loop again through the order lines to update zsp items
	&amp;#40;loop &amp;#91;xs order&amp;#93;
	  &amp;#40;when-let &amp;#91;line &amp;#40;first &amp;#40;seq xs&amp;#41;&amp;#41;&amp;#93;
		&amp;#40;when &amp;#40;= &amp;quot;ZSP&amp;quot; &amp;#40;:item-id line&amp;#41;&amp;#41;
		  &amp;#40;j/update! db :ORDER&amp;#95;LINE {:shipping-date min-shipping-date} &amp;#91;&amp;quot;order&amp;#95;id=? AND order&amp;#95;line&amp;#95;id=?&amp;quot; &amp;#40;:order&amp;#95;id line&amp;#41; &amp;#40;:order&amp;#95;line&amp;#95;id line&amp;#41;&amp;#93;&amp;#41;&amp;#41;
		  &amp;#40;recur &amp;#40;rest xs&amp;#41;&amp;#41;&amp;#41;&amp;#41;

	&amp;#40;let &amp;#91;msg &amp;#40;str &amp;quot;Resetting order shipping date to &amp;quot;
			  &amp;#40;fmt-date min-shipping-date&amp;#41;
			  &amp;quot; &amp;#91;&amp;quot; &amp;#40;mut/order-number order&amp;#41; &amp;quot;&amp;#93;&amp;quot;&amp;#41;&amp;#93;

		;; again side effects here !!!
		&amp;#40;.log elog &amp;#40;:customer&amp;#95;id order&amp;#41; :info msg&amp;#41;
		  &amp;#40;log/info msg&amp;#41;&amp;#41;

	 ;; do other things here, omitted for clarity
	 ;; ...

&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The function does several computations, it retains almost all of its procedural style roots, generating side-effects along the way and finally save the results to database. There is no easy way to play with it interactively at a REPL, the database calls and all other side-effects ops sprung around made it all harder than necessary to check if the code works properly.&lt;/p&gt;&lt;p&gt;My first reaction was wobbling among two possible ways to bypass the hurdle,&lt;/p&gt;&lt;ol&gt;&lt;li&gt;setup of a testing environment fully provided with a database,&lt;/li&gt;&lt;li&gt;mocking some methods to avoid the database and company at all,&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;while balancing out the pros and the cons of either one or the other the code smell was really strong... :) both the solutions were more cumbersome to implement let alone lazily accepting the smelling code the way as given.&lt;/p&gt;&lt;h3 id="the&amp;#95;solution"&gt;The solution&lt;/h3&gt;&lt;p&gt;The solution in the end was the simplest, as you certainly already figured it out. Apply the principles of good software programming, keep side-effects distinct from business logic, strive for pure functions, which incidentally are among the core tenets of functional programming. I do not need to test the database, looking at it if the db call persists the correct results. I just need to test the business logic.&lt;/p&gt;&lt;p&gt;Let's do it:&lt;/p&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&amp;#40;defn save
  &amp;#91;db elog min-shipping-date order&amp;#93;
  &amp;#40;doseq &amp;#91;line order&amp;#93;
	;; call the db update fn
	;; call log
	;; and so on
&amp;#41;&amp;#41;

&amp;#40;defn reset
  &amp;quot;Reset order state for the next billing.&amp;quot;
  &amp;#91;order&amp;#93;
  &amp;#40;let &amp;#91;{lines false zsp-lines true} &amp;#40;group-by #&amp;#40;= &amp;quot;ZSP&amp;quot; &amp;#40;get % :item&amp;#95;id&amp;#41;&amp;#41; order&amp;#41;                 ; split resettable lines
		lines                        &amp;#40;map reset-line lines&amp;#41;                                       ; do business logic
		min-shipping-date            &amp;#40;apply t/min-date &amp;#40;map :shipping-date lines&amp;#41;&amp;#41;                ; post retrieve the min shipping date
		zsp-lines                    &amp;#40;map #&amp;#40;assoc %1 :shipping&amp;#95;date min-shipping-date&amp;#41; zsp-lines&amp;#41; ; update zsp lines
		lines                        &amp;#40;reduce conj lines zsp-lines&amp;#41;&amp;#93;                               ; join order lines again

	 ;; returns a vector with min-shipping-date and updated order detail
	 &amp;#91;min-shipping-date lines&amp;#93;&amp;#41;&amp;#41;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The refactoring consisted in moving out in a new function the database and log stuff, passing it the data to persist.&lt;/p&gt;&lt;p&gt;The &lt;code&gt;reset&lt;/code&gt;'s function output can be provided to the &lt;code&gt;save&lt;/code&gt; function for persistence.&lt;/p&gt;&lt;p&gt;The original function is now decoupled from db dependency, can be growed interactively at the REPL, tests can be written without worrying about having a db or any else impediment in the developing stage.&lt;/p&gt;&lt;p&gt;You can pass some data and you get back a result that can be verifyed if it is correct. Database and logs are not involved anymore.&lt;/p&gt;&lt;p&gt;&lt;b&gt;And last but not least code size has wonderfully shrunken by a factor, and the intents are clearer IMHO.&lt;/b&gt;&lt;/p&gt;&lt;h3 id="in&amp;#95;conclusion"&gt;In conclusion&lt;/h3&gt;&lt;p&gt;It is not that in Java/IDE/imperative mindset you cannot write good software. In this example the refactoring had to be done with these tools too, &lt;i&gt;Separation Of Concerns&lt;/i&gt; and &lt;i&gt;Pure Functions&lt;/i&gt; are universal programming principles, even tough they are the workhorses of FP.&lt;/p&gt;&lt;p&gt;The problem IMHO is that you are more prone to adopt solutions that at first sight look convenient - like throwing some breakpoints in the IDE before critical code is reached to stop execution and inspect the current context, doing it endlessly - but at the end impacting the overall design, making it hard to evolve, test and read.&lt;/p&gt;&lt;p&gt;FP strongly pushes you towards &lt;i&gt;separations of concerns&lt;/i&gt;, and the result you come with up, lines of code that make just one thing, &lt;strong&gt;pure functions&lt;/strong&gt;, on what you can concentrate clearly without being distracted by other meanings, makes you feel more confident about the code you write.&lt;/p&gt;&lt;ol class='footnotes'&gt;&lt;li id='fn-1'&gt;Disclaimer: the code presented here is not the real one as it can not be divulgated, but it is meant to represent it as close to the original as possible.&lt;a href='#fnref1'&gt;&amp;#8617;&lt;/a&gt;&lt;/li&gt;&lt;/ol&gt;</description><pubDate>Sun, 04 Mar 2018 00:00:00 +0100</pubDate></item><item><guid>http://paolopiersanti.it/blog/posts-output/2014-02-15-mouse-speed-lubuntu/</guid><link>http://paolopiersanti.it/blog/posts-output/2014-02-15-mouse-speed-lubuntu/</link><title>Persist Mouse Speed In LXDE</title><description>&lt;h2 id="how-to&amp;#95;persist&amp;#95;mouse&amp;#95;speed&amp;#95;settings&amp;#95;between&amp;#95;system&amp;#95;restarts..."&gt;How-To persist mouse speed settings between system restarts...&lt;/h2&gt;&lt;p&gt;Edit the file /etc/xdg/lxsession/LXDE/autostart&lt;/p&gt;&lt;pre&gt;&lt;code class="bash"&gt;# sudo vi /etc/xdg/lxsession/LXDE/autostart
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Add the following line:&lt;/p&gt;&lt;pre&gt;&lt;code class="bash"&gt;@xset m &amp;lt;acceleration&amp;gt; &amp;lt;threshold&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;where &lt;code&gt;acceleration&lt;/code&gt; and &lt;code&gt;threshold&lt;/code&gt; are your defined values, expressed in decimal notation as &lt;code&gt;1.2&lt;/code&gt;.&lt;/p&gt;</description><pubDate>Sat, 15 Feb 2014 00:00:00 +0100</pubDate></item></channel></rss>