thegeez blog2023-03-01T15:00:12Zhttps://thegeez.net/Gijs StuurmanPinball with Scittle/ClojureScript2023-03-01T23:00:00Zhttps://thegeez.net/2023/03/01/pinball_scittle.html<h1 id="post-title">Pinball with Scittle/ClojureScript</h1>
<p>The past few months I have been on some longer train rides. These rides had plenty of time to look outside the window to the nice scenery between Dresden and Prague. Other routes were more suitable for programming.</p>
<p>To program on my Android phone I installed the <a href="https://userland.tech/">UserLAnd</a> app, which can run a full Ubuntu environment (or other Linux variants), without special permissions or special hacks to the phone or Android system. In this Ubuntu installation I run Emacs for coding with Paredit on Clojure code. The UserLAnd app adds the "Ctrl" and "Alt"/"Meta" key to the Android touchscreen keyboard. Together with some custom configuration in Emacs this makes nice Paredit editing available on my phone.</p>
<a href="2023/03/01/pinball_scittle.html">Read more</a>SpotlightBoard.com: Calendar for standup and improv2023-01-31T23:00:00Zhttps://thegeez.net/2023/01/31/spotlightboard.html<h1 id="post-title">SpotlightBoard.com: Calendar for standup and improv</h1>
<p>My latest programming project is <a href="https://spotlightboard.com">spotlightboard.com</a>. This is a website to aggregate all the standup and improv events happening in Amsterdam. Users can add their own events and find events based on the calendar and filtering by tags. There's also a comment section for every event and a forum for discussions.</p>
<p>For this project I tried something different than my usual Clojure programming tools. Spotlightboard is made with <a href="https://elixir-lang.org">Elixir</a> and the <a href="https://phoenixframework.org">Phoenix web framework</a>. Because Elixir uses immutable datastructures and functional programming it is very easy to get started with for Clojure programmers. It is only a pity that its syntax is not sexp based.</p>
<a href="2023/01/31/spotlightboard.html">Read more</a>Serverless search on AWS Lambda with Janet and SQLite2022-01-11T23:00:00Zhttps://thegeez.net/2022/01/11/serverless_search_aws_lambda.html<h1 id="post-title">Serverless search on AWS Lambda with Janet and SQLite</h1>
<p>Recently I have been porting a simple app on AWS Lambda for posts and comments to use the <a href="https://janet-lang.org">Janet</a> programming language. A <a href="/2021/10/28/janet_web_app_aws_lambda.html">previous post</a> describes how Janet is a great fit to use with AWS Lambda. The web app now also supports search through the search bar in the header. An earlier version of the postings app was written in Clojure and had a search functionality backed by ElasticSearch/OpenSearch on AWS, which is described <a href="/2020/04/07/serverless_clojure_web_app_aws_lambda.html">in this post</a>.</p>
<p>Since postings is a demo app that is rarely used, it benefits from the serverless quality of being able to scale the compute resource usage down to zero. The storage resources are also minimal. Sadly OpenSearch does not follow this serverless model by requiring a provisioned cluster.</p>
<a href="2022/01/11/serverless_search_aws_lambda.html">Read more</a>Web app on AWS Lambda with Janet2021-10-28T23:00:00Zhttps://thegeez.net/2021/10/28/janet_web_app_aws_lambda.html<h1 id="post-title">Web app on AWS Lambda with Janet</h1>
<p><a href="https://janet-lang.org">Janet</a> is a small functional and imperative programming language. The language has some similarities to Clojure with its Lispy syntax, its data notation, and with its proper REPL for dynamic developing within a running system. Janet also compiles its runtime and VM to C and can therefore run almost anywhere.</p>
<p>All of Janet's features make it a good candidate to make AWS Lambda serverless functions with. This is because Janet programs start up and compile quickly, certainly when compared to a combination of Clojure and native-image compilation. <a href="https://iakerss4c6.execute-api.eu-central-1.amazonaws.com">Postings</a> is a simple forum web app on AWS Lambda behind an API Gateway and using DynamoDB as the database.</p>
<a href="2021/10/28/janet_web_app_aws_lambda.html">Read more</a>Rofolia: a self-hosted collaborative database/spreadsheet hybrid2021-06-01T23:00:00Zhttps://thegeez.net/2021/06/01/rofolia_self_host_spreadsheet_database.html<h1 id="post-title">Rofolia: a self-hosted collaborative database/spreadsheet hybrid</h1>
<p>My latest Clojure project is now available! <a href="https://rofolia.com">Rofolia</a> is a self-hosted collaborative database/spreadsheet hybrid. It is similar to Airtable and Google Sheets and supports links between tables, lookups, formula's and API access.</p>
<p>Try the demo at <a href="https://demo.rofolia.com">demo.rofolia.com</a> and check out the documentation at <a href="https://rofolia.com">Rofolia.com</a>.</p>
<a href="2021/06/01/rofolia_self_host_spreadsheet_database.html">Read more</a>Walkthrough of a spreadsheet/database-hybrid with Clojure(Script)2021-03-15T23:00:00Zhttps://thegeez.net/2021/03/15/spreadsheet_database_clojure_aws.html<h1 id="post-title">Walkthrough of a spreadsheet/database-hybrid with Clojure(Script)</h1>
<p>My latest project is a spreadsheet/database hybrid called <a href="https://mixgrid.thegeez.net">mixgrid</a>. Mixgrid is a record based database that is editable like a spreadsheet, similar to <a href="https://airtable.com/">Airtable</a>, <a href="https://stackby.com/">Stackby</a>, <a href="https://tables.area120.google.com/about#/">Google Tables</a> and <a href="https://www.microsoft.com/en-us/microsoft-365/microsoft-lists">Microsoft Lists</a>. While mixgrid is in its early stages it already supports some nice features:</p>
<ul>
<li>Real time collaboration</li>
<li>Link records between tables</li>
<li>Lookup values from linked records</li>
<li>Apply formulas per row</li>
<li>Undo & redo support</li>
<li>Sorting and nested grouping of rows</li>
</ul>
<a href="2021/03/15/spreadsheet_database_clojure_aws.html">Read more</a>Databrowser for Crux2020-07-16T23:00:00Zhttps://thegeez.net/2020/07/16/databrowser_crux.html<h1 id="post-title">Databrowser for Crux</h1>
<p>Databrowser is a web app to explore the data in a <a href="https://www.opencrux.com">Crux</a> database. It takes a lot of inspiration from the <a href="https://github.com/cognitect-labs/REBL-distro">REBL</a> tool, with added features for Crux documents, such as an easy way to enter time and dates and to view diffs. Here's a longer list of features:</p>
<ul>
<li>Write custom queries</li>
<li>Add Clojure code to your queries to shape the data</li>
<li>Support for collections of heterogeneous data</li>
<li>Group and sort the data in grids</li>
<li>Browse and view pane (similar to REBL)</li>
<li>Drill down into data through navigation</li>
<li>Full keyboard navigation support</li>
<li>Support for easy creation of time and date instances for bi-temporal queries</li>
<li>Support to view diffs of data</li>
</ul>
<a href="2020/07/16/databrowser_crux.html">Read more</a>Collaborate serverless-ly on ClojureScript: crepl is back2020-04-17T23:00:00Zhttps://thegeez.net/2020/04/17/crepl_is_back.html<h1 id="post-title">Collaborate serverless-ly on ClojureScript: crepl is back</h1>
<p><a href="https://crepl.thegeez.net">crepl</a> is a collaborative
editor written in Clojure and ClojureScript. In the editor you can
write and evaluate ClojureScript code. And you can work on the same code together, similar to Google Docs. crepl has been offline for quite some time as I did not have a place to deploy it to. Recently, I have been playing around with compiling Clojure with GraalVM's native-image and deploying on AWS Lambda. Because AWS Lambda works together with websockets via API Gateway the whole crepl infrastructure can be deployed in a serverless manner too!</p>
<p>Try out the serverless crepl here: <a href="https://crepl.thegeez.net">crepl.thegeez.net</a></p>
<a href="2020/04/17/crepl_is_back.html">Read more</a>Serverless Clojure web app on AWS Lambda2020-04-07T23:00:00Zhttps://thegeez.net/2020/04/07/serverless_clojure_web_app_aws_lambda.html<h1 id="post-title">Serverless Clojure web app on AWS Lambda</h1>
<p>The <a href="https://postings.thegeez.net">Postings</a> app is a simple
web application for posting text and comments. It is very old
fashioned because it serves html pages from a server, instead of being a big
ClojureScript or JavaScript application with Reagent or React. The
web app does use a tiny bit of JavaScript to load certain html pages
inline, following the ideas of <a href="https://github.com/turbolinks/turbolinks">turbolinks</a>. Everything works without JavaScript too. To post a comment
the server sends a page with a comment form in it and renders the
form inline for a nice user experience. Therefore there is no client side
state to manage for a nice developer experience, both of which are me.
</p>
<br /><a href="https://postings.thegeez.net"><img src="/images/postings_screenshot.png" /></a><a href="2020/04/07/serverless_clojure_web_app_aws_lambda.html">Read more</a>Serverless collaboration2019-03-03T23:00:00Zhttps://thegeez.net/2019/03/03/serverless_collab.html<h1 id="post-title">Serverless collaboration</h1>
<p>Previously I've worked on a collaborative tool, which worked like Google Docs. This project was
called <a href="/2017/02/11/crepl_atom_sync.html">crepl</a>. Because
I stopped paying for hosting of its server, that project is now
offline. That made me consider: what if a collaborative editor wouldn't need a
server?</p>
<p>The server in crepl was needed to handle the connections between all
the clients and the algorithm for collaborative editing
needed a central server. For both there are alternatives that do not
need a server.</p>
<a href="2019/03/03/serverless_collab.html">Read more</a>Fly over Amsterdam with ClojureScript2018-04-01T23:00:00Zhttps://thegeez.net/2018/04/01/flight.html<h1 id="post-title">Fly over Amsterdam with ClojureScript</h1>
<br />
<br />
<a href="2018/04/01/flight.html">Read more</a>Probabilistic programming example with
Anglican2017-11-13T23:00:00Zhttps://thegeez.net/2017/11/13/prob_prog_anglican_example.html<h1 id="post-title">Probabilistic programming example with
Anglican</h1>
<p>At the
last <a href="https://www.meetup.com/The-Amsterdam-Clojure-Meetup-Group/events/244651818/">Amsterdam
Clojure Meetup</a> there was a great demostration by Zhenhao Li
about <a href="http://www.robots.ox.ac.uk/~fwood/anglican">Anglican</a>. Anglican
is a probabilistic programming language integrated with
Clojure. I am a fan of the
book <a href="https://github.com/CamDavidsonPilon/Probabilistic-Programming-and-Bayesian-Methods-for-Hackers">Probabilistic
Programming and Bayesian Methods for Hackers</a> from which I solved
a problem in Clojure, about which I wrote here:
</p><p><a href="http://thegeez.net/2014/03/12/bayes_mcmc_clojure.html">Bayesian Inference with Markov Chain Monte Carlo in Clojure</a></p>
<p>Below is the solution to that problem using Anglican:</p><a href="2017/11/13/prob_prog_anglican_example.html">Read more</a>ClojureConj 2017 Baltimore: Learning Clojure and ClojureScript by Playing a
Card Game video2017-11-07T23:00:00Zhttps://thegeez.net/2017/11/07/clojure_conj_talk_playing_card_game.html<h1 id="post-title">ClojureConj 2017 Baltimore: Learning Clojure and ClojureScript by Playing a
Card Game video</h1>
<p>At ClojureConj 2017 I gave a talk titled: "Learning Clojure and
ClojureScript by Playing a Card Game". The recording of the talk is
now on
youtube:<br /><br />ClojureTV/ClojureConj 2017: <a href="https://www.youtube.com/watch?v=MzcgW9GIlQ0">Learning
Clojure and ClojureScript by Playing a Card Game</a></p>
<p>More information for each of those Gin Rummy projects as mentioned in the talk are in the links below:</p>
<a href="2017/11/07/clojure_conj_talk_playing_card_game.html">Read more</a>EuroClojure 2017 Berlin: crepl talk video2017-08-17T23:00:00Zhttps://thegeez.net/2017/08/17/crepl_euroclojure_2017_berlin.html<h1 id="post-title">EuroClojure 2017 Berlin: crepl talk video</h1>
<p>At <a href="http://2017.euroclojure.org/building-a-collaborative-web-app/">EuroClojure 2017</a> I gave a talk titled: "Building a collaborative
web app with ClojureScript". The recording of the talk is now on youtube:
<a href="https://www.youtube.com/watch?v=NunlGbJgp4A">crepl at
EuroClojure 2017 on ClojureTV</a></p>
<p>For more background about crepl and c3e check out these blogposts:
</p><ul>
<li><a href="http://thegeez.net/2017/02/03/crepl_collaborative_editor.html">crepl blogpost</a></li>
<li><a href="http://thegeez.net/2017/03/25/c3e_collaborative_clojure_cloud_editor.html">c3e
blogpost</a></li>
</ul><a href="2017/08/17/crepl_euroclojure_2017_berlin.html">Read more</a>Data wrangling with transducers for a machine learning problem2017-04-28T23:00:00Zhttps://thegeez.net/2017/04/28/data_transducers_machine_learning_clojure.html<h1 id="post-title">Data wrangling with transducers for a machine learning problem</h1>
<p>The transducers from the <a href="https://github.com/cgrand/xforms">net.cgrand.xforms</a> library are great to
transform and analyze data with in Clojure. This blogpost shows how
the xforms transducers can be used to do
data analysis for a machine learning problem from Kaggle, which is a data
science competition platform.</p>
<p>One of the competitions on Kaggle is
the <a href="https://www.kaggle.com/c/titanic">Titanic
competition</a>. For this competition you are given a dataset
about passengers aboard the Titanic, with data such as their age and how much
they paid for their ticket. In the training data you are also told
if the passenger survived. The goal of the competition is to predict
if a passenger survived or not for a test set of data.</p>
<a href="2017/04/28/data_transducers_machine_learning_clojure.html">Read more</a>Dutch Clojure Days 2017: crepl demo2017-04-13T23:00:00Zhttps://thegeez.net/2017/04/13/crepl_dutch_clojure_days_2017.html<h1 id="post-title">Dutch Clojure Days 2017: crepl demo</h1>
<p>At the <a href="http://clojuredays.org/">Dutch Clojure Days</a>
2017 in Amsterdam I gave a lightning talk about <a href="http://crepl.thegeez.net">crepl</a>. With crepl
you can write and run ClojureScript code together. I also introduced
<a href="http://c3e.thegeez.net">c3e</a>, which is a collaborative editor in the browser for full
projects with multiple files. The video for the talk is
below:</p>
<iframe width="560" height="315" src="https://www.youtube.com/embed/kzbnk-zmSN0" frameborder="0" allowfullscreen="allowfullscreen"></iframe>
<a href="2017/04/13/crepl_dutch_clojure_days_2017.html">Read more</a>crepl and c3e at Dutch Clojure Days 20172017-03-25T23:00:00Zhttps://thegeez.net/2017/03/25/c3e_collaborative_clojure_cloud_editor.html<h1 id="post-title">crepl and c3e at Dutch Clojure Days 2017</h1>
<p>Today was the 2017 edition
of <a href="http://clojuredays.org/">Dutch Clojure Days (DCD17)</a>, the
annual international gathering of Clojure enthusiasts and
practitioners in the Netherlands. At DCD17 I presented a lightning
talk about crepl.</p>
<p><a href="http://crepl.thegeez.net">crepl</a> is a collaborative
editor written in Clojure and ClojureScript. It's like Google Docs
where you can also run the ClojureScript you write in the
browser. And by using <a href="/2017/02/11/crepl_atom_sync.html">atom sync</a> you can also keep state in
sync with each browser running the code, which is useful when
working on code with UIs. These previous blogposts have more information about crepl
and its features:</p>
<a href="2017/03/25/c3e_collaborative_clojure_cloud_editor.html">Read more</a>Defn Podcast: Episode 182017-02-21T23:00:00Zhttps://thegeez.net/2017/02/21/defn_podcast.html<h1 id="post-title">Defn Podcast: Episode 18</h1>
<p>Last week I joined Ray and Vijay on the Defn Podcast. We talked
about Clojure as well as my latest
project: <a href="http://crepl.thegeez.net">crepl</a>. I had a great
time talking with them. You can listen to the episode below. Enjoy!</p>
<iframe width="100%" height="166" scrolling="no" frameborder="no" src="https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/tracks/308550288&color=ff5500&auto_play=false&hide_related=false&show_comments=true&show_user=true&show_reposts=false"></iframe>
<a href="2017/02/21/defn_podcast.html">Read more</a>crepl: Link to examples2017-02-20T23:00:00Zhttps://thegeez.net/2017/02/20/crepl_links_to_examples.html<h1 id="post-title">crepl: Link to examples</h1>
<p>
</p><p><a href="http://crepl.thegeez.net">crepl</a> is a collaborative
editor where you can write and
run ClojureScript together. You can now create links to new crepl
pads that will be loaded with the code from an external source. Once you are in a crepl you can invite others to join you by
sending them the url in the browser navigation bar. For
instance try out these examples:</p>
<ul>
<li>Solve 4Clojure problems together:<br />
<a href="http://crepl.thegeez.net/init-pad?4clojure=23">http://crepl.thegeez.net/init-pad?4clojure=23</a><br />
More information about 4Clojure in crepl
in <a href="/2017/02/06/crepl_import_4clojure_reagent.html">this
blogpost</a><br /><br /></li>
<li>A reagent app in crepl with SVG:<br />
<a href="http://crepl.thegeez.net/init-pad?source=https://gist.githubusercontent.com/thegeez/d930a7d15fc166a904edeb7e816f96f5/raw/e393ca1585fc15e2ee157615475c0d54d18a19d6/crepl_svg_smiley.cljs">http://crepl.thegeez.net/init-pad?source=https://gist.githubusercontent.com/thegeez/d930a7d15fc166a904edeb7e816f96f5/raw/e393ca1585fc15e2ee157615475c0d54d18a19d6/crepl_svg_smiley.cljs</a><br /><br />
</li>
<li>Using atom-sync to sync state and code in different crepls, with
an example Tic Tac Toe game:<br />
<a href="http://crepl.thegeez.net/init-pad?source=https://gist.githubusercontent.com/thegeez/15913d9fce7698738697fe58ee4e8a94/raw/98e91842b45f8f2620599e473a9e0f5d95943f7b/crepl_tic-tac-toe.clj">http://crepl.thegeez.net/init-pad?source=https://gist.githubusercontent.com/thegeez/15913d9fce7698738697fe58ee4e8a94/raw/98e91842b45f8f2620599e473a9e0f5d95943f7b/crepl_tic-tac-toe.clj</a><br />
More about atom-sync in <a href="/2017/02/11/crepl_atom_sync.html">this blogpost</a></li>
</ul><a href="2017/02/20/crepl_links_to_examples.html">Read more</a>crepl: Atom sync, share code and state2017-02-11T23:00:00Zhttps://thegeez.net/2017/02/11/crepl_atom_sync.html<h1 id="post-title">crepl: Atom sync, share code and state</h1>
<p>With <a href="http://crepl.thegeez.net">crepl</a> you can write and
run ClojureScript together. Any changes to the code are synced to
everybody instantly. Something like Google Docs for
ClojureScript. You can also use nice libraries such as Reagent to
make your own UI. An example of making UI's in crepl is in
this <a href="http://thegeez.net/2017/02/06/crepl_import_4clojure_reagent.html">blog
post</a>. However, anything you do in the UI, such as clicking a
button, would not be synced to everybody else. Because of
this the collaborative features for crepl where limited to code. But crepl now has a solution for this:</p>
<p>Crepl now has a "Atom sync" that keeps both your
code and state in sync and changes will show up instantly for everybody!</p>
<a href="2017/02/11/crepl_atom_sync.html">Read more</a>crepl: Import code, solve 4Clojure problems and
use reagent2017-02-06T23:00:00Zhttps://thegeez.net/2017/02/06/crepl_import_4clojure_reagent.html<h1 id="post-title">crepl: Import code, solve 4Clojure problems and
use reagent</h1>
<p>There have been some upgrades
to <a href="http://crepl.thegeez.net">crepl</a>. It is now possible
to import code, solve 4Clojure problems and create your own UI with
Reagent. It was already possible to <a href="/2017/02/05/crepl_run_continuously.html">run your code continuously</a> and
see the result of your code update instantly.</p>
<h2>Configure crepl with code</h2>
<a href="2017/02/06/crepl_import_4clojure_reagent.html">Read more</a>crepl: Run continuously2017-02-05T23:00:00Zhttps://thegeez.net/2017/02/05/crepl_run_continuously.html<h1 id="post-title">crepl: Run continuously</h1>
<p>With <a href="http://crepl.thegeez.net">crepl</a> you can write and
run ClojureScript code together. Everybody always sees the same
code, because all the changes are updated in everyones browser
simultaneously. However, everybody can only run the code in their
own browser. This is why the output of "Evaluate expression" is
inserted in the code. This way everybody is guaranteed to see the
same output.</p>
<textarea id="snippet-1">
(+ 3 4
(do (println "Some output")
5))
(comment ;; eval'd by Guest 83477 =>
12
;; [println] Some output
)
</textarea>
<a href="2017/02/05/crepl_run_continuously.html">Read more</a>crepl: Write and run ClojureScript code
together2017-02-03T23:00:00Zhttps://thegeez.net/2017/02/03/crepl_collaborative_editor.html<h1 id="post-title">crepl: Write and run ClojureScript code
together</h1>
<p><a href="https://crepl.thegeez.net">crepl</a> is a collaborative
editor written in Clojure and ClojureScript. In the editor you can
write and evaluate ClojureScript code. This is a fun and quick way
to try out some ClojureScript code. The real fun begins when you
get others to work on the same code with you by sending them the
URL. When multiple people are working on the same code at the same
time you will see their changes appear immediately and the output
of running the code will be shared with everybody. crepl is like
Google Docs that can also run ClojureScript!</p>
<p><a href="https://crepl.thegeez.net"><img src="/images/crepl_screenshot.png" style="border: 1px solid black;" /></a>
Two people working on the same ClojureScript code and seeing the same output.</p>
<a href="2017/02/03/crepl_collaborative_editor.html">Read more</a>A wiki made with Clojure, yada and Datomic
Client2017-01-04T23:00:00Zhttps://thegeez.net/2017/01/04/wiki_clojure_yada_datomic_client.html<h1 id="post-title">A wiki made with Clojure, yada and Datomic
Client</h1>
<p>At EuroClojure in Bratislava an unconference session was about
Clojure and REST. At this
session <a href="http://clojure-liberator.github.io/liberator/">Liberator</a>
and <a href="https://github.com/juxt/yada">yada</a> were discussed by their
authors. I have used Liberator previously, by not yada. A big
difference between the two is that yada is asynchronous. This is
useful when making calls to other services while handling a web
request.<br />
<a href="http://www.datomic.com/">Datomic</a> now has a new Client
API. With the Client API a Datomic database can be accessed as a
service, in a more idiomatic Clojure style than its old REST API. To
play around with yada and Datomic Client I made a wiki with it. As a
bonus the example yada project also
uses <a href="http://boot-clj.com/">Boot</a>, instead of Leiningen as
its build tool,
which I had not played around with either.</p>
<p>The code for clj-wiki is on
GitHub: <a href="https://github.com/thegeez/clj-wiki">https://github.com/thegeez/clj-wiki</a><br />
An example wiki is (temporarily) running at <a href="http://wiki.thegeez.net">http://wiki.thegeez.net</a></p>
<a href="2017/01/04/wiki_clojure_yada_datomic_client.html">Read more</a>Parsing with clojure.spec for the Advent of Code2016-12-09T23:00:00Zhttps://thegeez.net/2016/12/09/parsing_clojure_spec_advent_of_code.html<h1 id="post-title">Parsing with clojure.spec for the Advent of Code</h1>
<p><a href="http://adventofcode.com">Advent of Code</a> is a series of
code challenges in the form of an advent calender, counting down
to Christmas. The challenges have inputs in the form of
strings. Clojure.spec can be used to parse those inputs and turn
them into useful data. The gist below works through some examples:</p>
<script src="https://gist.github.com/thegeez/77aee6f0ebcf6a42aa7d893388502e40.js"></script>
Trello clone clone in Clojure2016-09-22T23:00:00Zhttps://thegeez.net/2016/09/22/trello_clone_clone_in_clojure.html<h1 id="post-title">Trello clone clone in Clojure</h1>
<p>The <a href="https://github.com/bigardone/phoenix-trello">Phoenix-Trello</a>
project is a Trello clone build with Elixir, Phoenix and
React. I like the dragging cards interface in Trello, so I made a
Trello clone clone in Clojure.</p>
<p>The code for the Clojure version is on GitHub: <a href="https://github.com/thegeez/clj-board">thegeez/clj-board</a>. The example is
running on Heroku: <a href="https://clj-board.herokuapp.com">https://clj-board.herokuapp.com</a></p>
<a href="2016/09/22/trello_clone_clone_in_clojure.html">Read more</a>Pedestal presentation and example app2016-09-01T23:00:00Zhttps://thegeez.net/2016/09/01/pedestal_presentation_video_app.html<h1 id="post-title">Pedestal presentation and example app</h1>
<p>At the <a href="http://www.ticketbase.com/events/dutch-clojure-days-2016">Dutch Clojure Days</a> 2016 in Amsterdam I gave a presentation on building
user facing web applications with Pedestal. The video for it is
below:</p>
<iframe width="560" height="315" src="https://www.youtube.com/embed/4BMGlELVW20" frameborder="0" allowfullscreen="allowfullscreen"></iframe>
<a href="2016/09/01/pedestal_presentation_video_app.html">Read more</a>Pedestal and w3a walkthrough: Build a CRUD app
with Clojure2016-02-15T23:00:00Zhttps://thegeez.net/2016/02/15/w3a_pedestal_walkthrough.html<h1 id="post-title">Pedestal and w3a walkthrough: Build a CRUD app
with Clojure</h1>
<p>This is a walkthrough on how to build a complete user facing web
application with Clojure on top
of <a href="http://pedestal.io">Pedestal</a>, with the help of the
<a href="https://github.com/thegeez/w3a">w3a</a> library. I have made various attempts at building web
applications with Pedestal and/or Clojure before. (such as
<a href="http://thegeez.net/2014/04/30/datascript_clojure_web_app.html">here</a>,
<a href="http://thegeez.net/2015/05/16/w3a_web_application_pedestal.html">here</a>
and <a href="http://thegeez.net/2015/10/12/gatherlist_pedestal_oauth.html">here</a>) The current version is good and useful enough to
make a guide for and hopefully serve as a starting point for other
Clojure web applications.</p>
<p>For me a complete user facing web application should have a
database, templating, forms, authentication and authorization. And
for development I like to get something I can click through as soon
as possible, as well as having a dynamic development process from
the REPL.</p>
<a href="2016/02/15/w3a_pedestal_walkthrough.html">Read more</a>Gatherlist: combining Pedestal & OAuth2015-10-12T23:00:00Zhttps://thegeez.net/2015/10/12/gatherlist_pedestal_oauth.html<h1 id="post-title">Gatherlist: combining Pedestal & OAuth</h1>
<p>Visiting conferences is nice. You'll find lots of new and old
friends and will leave with a whole list of new interesting ideas to
follow up on. It is also an opportunity to find out how much
browsing websites on a mobile phone sucks. Want to find today's
schedule on the conference mobile website? Sorry, the hamburger menu doesn't collapse and blocks the
program table. Want to find the venue address? Sorry, the hero image of
the host city's landscape is a static overlay on top of the Google
maps.</p>
<p>At conferences it is equally complicated to arrange an impromptu
meeting or eating arrangement between a larger group of people. It's
a hassle to exchange contact details with all of them, because not
everybody is on the same platform. The most common place for
these types of ad-hoc organizing that I have seen is on Twitter. But it's
almost impossible to follow a conversation between a lot of people
on Twitter, especially through the mobile website.</p>
<a href="2015/10/12/gatherlist_pedestal_oauth.html">Read more</a>Web application with Pedestal2015-05-16T23:00:00Zhttps://thegeez.net/2015/05/16/w3a_web_application_pedestal.html<h1 id="post-title">Web application with Pedestal</h1>
<p>As Frankie said, for web development in Clojure we
should <a href="http://frankiesardo.github.io/posts/2014-12-15-give-pedestal-another-chance.html">give Pedestal another chance</a>. So I set out to build a user facing web
application with <a href="http://pedestal.io">Pedestal</a>. To me a minimally useful user facing web application
should have a database, templating, forms, authentication and
authorization. And for development I like to get something
I can click through as soon as possible, as well as having a
dynamic development process from the REPL.
The <a href="https://github.com/thegeez/w3a">w3a</a> library
and <a href="https://github.com/thegeez/w3a-example">w3a-example</a> try to provide this, using
Pedestal as foundation. </p>
<h2>w3a-example</h2>
<a href="2015/05/16/w3a_web_application_pedestal.html">Read more</a>Turned off gin.thegeez.net2014-07-08T23:00:00Zhttps://thegeez.net/2014/07/08/gin_datomic_local.html<h1 id="post-title">Turned off gin.thegeez.net</h1>
<p>The server for <a href="/2014/06/12/gin_datomic.html">Gin Rummy
with Datomic</a> has been shut down. Playing over the network against
a human or AI opponent through the Datomic database is no longer
available. See the <a href="/2014/06/12/gin_datomic.html">blog
post</a> and code
at <a href="https://github.com/thegeez/gin">github.com/thegeez/gin</a>
to run the code yourself.</p>
<p>A ClojureScript-only version to play against the CLJS AI is
available here: <a href="/static/gin-static/lobby.html">Gin Rummy</a></p>
Gin Rummy with Datomic2014-06-12T23:00:00Zhttps://thegeez.net/2014/06/12/gin_datomic.html<h1 id="post-title">Gin Rummy with Datomic</h1>
<p>When I began to learn Clojure I found the <a href="http://docs.racket-lang.org/games/ginrummy.html">Gin Rummy</a> game in the <a href="http://racket-lang.org/">PLT
Racket/Scheme</a> programming environment. Gin is a simple card game and
it includes a simple AI for an opponent. This game has been the
basis for some previous hobby projects, specifically a <a href="/2012/03/20/racket_gin_clojurescript.html">ClojureScript
implementation</a> and
a <a href="/2012/06/01/ginbot_euroclojure.html">software robot</a>
to play the game. But the project I always wanted to make was a way
to play Gin over the internet. Some 5 years later it is finally
done:</p>
<p>At <a href="http://gin.thegeez.net/">gin.thegeez.net</a> you can
play the Gin card game against a ClojureScript AI, a remote Clojure AI or a remote human opponent.</p>
<a href="2014/06/12/gin_datomic.html">Read more</a>Datascript and Quiescent TodoMVC stand-alone2014-05-01T23:00:00Zhttps://thegeez.net/2014/05/01/datascript_quiescent_standalone.html<h1 id="post-title">Datascript and Quiescent TodoMVC stand-alone</h1>
<style type="text/css">
@charset "UTF-8";body,html{margin:0;padding:0}button{margin:0;padding:0;border:0;background:0 0;font-size:100%;vertical-align:baseline;font-family:inherit;color:inherit;-webkit-appearance:none;-ms-appearance:none;-o-appearance:none;appearance:none}body{color:#4d4d4d}button,input[type=checkbox]{outline:0}#todoapp{background:#fff;background:rgba(255,255,255,.9);margin:170px 0 40px;border:1px solid #ccc;position:relative;border-top-left-radius:2px;border-top-right-radius:2px;box-shadow:0 2px 6px 0 rgba(0,0,0,.2),0 25px 50px 0 rgba(0,0,0,.15)}#todoapp:before{content:'';border-left:1px solid #f5d6d6;border-right:1px solid #f5d6d6;width:2px;position:absolute;top:0;left:40px;height:100%}#todoapp input::-webkit-input-placeholder{font-style:italic}#todoapp input::-moz-placeholder{font-style:italic;color:#a9a9a9}#todoapp h1{position:absolute;top:-120px;width:100%;font-size:70px;font-weight:700;text-align:center;color:#b3b3b3;color:rgba(255,255,255,.3);text-shadow:-1px -1px rgba(0,0,0,.2);-webkit-text-rendering:optimizeLegibility;-moz-text-rendering:optimizeLegibility;-ms-text-rendering:optimizeLegibility;-o-text-rendering:optimizeLegibility;text-rendering:optimizeLegibility}#header{padding-top:15px;border-radius:inherit}#header:before{content:'';position:absolute;top:0;right:0;left:0;height:15px;z-index:2;border-bottom:1px solid #6c615c;background:#8d7d77;background:-webkit-gradient(linear,left top,left bottom,from(rgba(132,110,100,.8)),to(rgba(101,84,76,.8)));background:-webkit-linear-gradient(top,rgba(132,110,100,.8),rgba(101,84,76,.8));background:linear-gradient(top,rgba(132,110,100,.8),rgba(101,84,76,.8));filter:progid:DXImageTransform.Microsoft.gradient(GradientType=0, StartColorStr='#9d8b83', EndColorStr='#847670');border-top-left-radius:1px;border-top-right-radius:1px}#new-todo,.edit{position:relative;margin:0;width:100%;font-size:24px;font-family:inherit;line-height:1.4em;outline:0;color:inherit;padding:6px;border:1px solid #999;box-shadow:inset 0 -1px 5px 0 rgba(0,0,0,.2);-moz-box-sizing:border-box;-ms-box-sizing:border-box;-o-box-sizing:border-box;box-sizing:border-box;-webkit-font-smoothing:antialiased;-moz-font-smoothing:antialiased;-ms-font-smoothing:antialiased;-o-font-smoothing:antialiased;font-smoothing:antialiased}#new-todo{padding:16px 16px 16px 60px;border:none;background:rgba(0,0,0,.02);z-index:2;box-shadow:none}#main{position:relative;z-index:2;border-top:1px dotted #adadad}label[for=toggle-all]{display:none}#toggle-all{position:absolute;top:-42px;left:-4px;width:40px;text-align:center;border:none}#toggle-all:before{content:'»';font-size:28px;color:#d9d9d9;padding:0 25px 7px}#toggle-all:checked:before{color:#737373}#todo-list{margin:0;padding:0;list-style:none}#todo-list li{position:relative;font-size:24px;border-bottom:1px dotted #ccc}#todo-list li:last-child{border-bottom:none}#todo-list li.editing{border-bottom:none;padding:0}#todo-list li.editing .edit{display:block;width:506px;padding:13px 17px 12px;margin:0 0 0 43px}#todo-list li.editing .view{display:none}#todo-list li .toggle{text-align:center;width:40px;height:auto;position:absolute;top:0;bottom:0;margin:auto 0;border:none;-webkit-appearance:none;-ms-appearance:none;-o-appearance:none;appearance:none}#todo-list li .toggle:after{content:'✔';line-height:43px;font-size:20px;color:#d9d9d9;text-shadow:0 -1px 0 #bfbfbf}#todo-list li .toggle:checked:after{color:#85ada7;text-shadow:0 1px 0 #669991;bottom:1px;position:relative}#todo-list li label{white-space:pre;word-break:break-word;padding:15px 60px 15px 15px;margin-left:45px;display:block;line-height:1.2;-webkit-transition:color .4s;transition:color .4s}#todo-list li.completed label{color:#a9a9a9;text-decoration:line-through}#todo-list li .sync{position:absolute;top:20px;right:10px;bottom:0;width:40px;height:40px;margin:auto 0}#todo-list li .destroy{display:none;position:absolute;top:0;right:10px;bottom:0;width:40px;height:40px;margin:auto 0;font-size:22px;color:#a88a8a;-webkit-transition:all .2s;transition:all .2s}#todo-list li .destroy:hover{text-shadow:0 0 1px #000,0 0 10px rgba(199,107,107,.8);-webkit-transform:scale(1.3);-ms-transform:scale(1.3);transform:scale(1.3)}#todo-list li .destroy:after{content:'✖'}#todo-list li:hover .destroy{display:block}#todo-list li .edit{display:none}#todo-list li.editing:last-child{margin-bottom:-1px}#footer{color:#777;padding:0 15px;position:absolute;right:0;bottom:-31px;left:0;height:20px;z-index:1;text-align:center}#footer:before{content:'';position:absolute;right:0;bottom:31px;left:0;height:50px;z-index:-1;box-shadow:0 1px 1px rgba(0,0,0,.3),0 6px 0 -3px rgba(255,255,255,.8),0 7px 1px -3px rgba(0,0,0,.3),0 43px 0 -6px rgba(255,255,255,.8),0 44px 2px -6px rgba(0,0,0,.2)}#todo-count{float:left;text-align:left}#filters{margin:0;padding:0;list-style:none;position:absolute;right:0;left:0}#filters li{display:inline}#filters li a{color:#83756f;margin:2px;text-decoration:none}#filters li a.selected{font-weight:700}#clear-completed{float:right;position:relative;line-height:20px;text-decoration:none;background:rgba(0,0,0,.1);font-size:11px;padding:0 10px;border-radius:3px;box-shadow:0 -1px 0 0 rgba(0,0,0,.2)}#clear-completed:hover{background:rgba(0,0,0,.15);box-shadow:0 -1px 0 0 rgba(0,0,0,.3)}#info{margin:65px auto 0;color:#a6a6a6;font-size:12px;text-shadow:0 1px 0 rgba(255,255,255,.7);text-align:center}#info a{color:inherit}@media screen and (-webkit-min-device-pixel-ratio:0){#todo-list li .toggle,#toggle-all{background:0 0}#todo-list li .toggle{height:40px}#toggle-all{top:-56px;left:-15px;width:65px;height:41px;-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg);-webkit-appearance:none;appearance:none}}.hidden{display:none}hr{margin:20px 0;border:0;border-top:1px dashed #C5C5C5;border-bottom:1px dashed #F7F7F7}.learn a{font-weight:400;text-decoration:none;color:#b83f45}.learn a:hover{text-decoration:underline;color:#787e7e}.learn h3,.learn h4,.learn h5{margin:10px 0;font-weight:500;line-height:1.2;color:#000}.learn h3{font-size:24px}.learn h4{font-size:18px}.learn h5{margin-bottom:0;font-size:14px}.learn ul{padding:0;margin:0 0 30px 25px}.learn li{line-height:20px}.learn p{font-size:15px;font-weight:300;line-height:1.3;margin-top:0;margin-bottom:0}.quote{border:none;margin:20px 0 60px}.quote p{font-style:italic}.quote p:before{content:'“';font-size:50px;opacity:.15;position:absolute;top:-20px;left:3px}.quote p:after{content:'”';font-size:50px;opacity:.15;position:absolute;bottom:-42px;right:3px}.quote footer{position:absolute;bottom:-40px;right:0}.quote footer img{border-radius:3px}.quote footer a{margin-left:5px;vertical-align:middle}.speech-bubble{position:relative;padding:10px;background:rgba(0,0,0,.04);border-radius:5px}.speech-bubble:after{content:'';position:absolute;top:100%;right:30px;border:13px solid transparent;border-top-color:rgba(0,0,0,.04)}.learn-bar>.learn{position:absolute;width:272px;top:8px;left:-300px;padding:10px;border-radius:5px;background-color:rgba(255,255,255,.6);-webkit-transition-property:left;transition-property:left;-webkit-transition-duration:500ms;transition-duration:500ms}@media (min-width:899px){.learn-bar{width:auto;margin:0 0 0 300px}.learn-bar>.learn{left:8px}.learn-bar #todoapp{width:550px;margin:130px auto 40px}}#todo-error{margin-top:100px}
</style>
<p><a href="/2014/04/30/datascript_clojure_web_app.html">Yesterday</a>
I wrote about <a href="http://clj-crud.herokuapp.com/">clj-crud</a>
and its <a href="http://todomvc.com/">TodoMVC</a> implementation
with <a href="https://github.com/tonsky/datascript">Datascript</a>
and <a href="http://facebook.github.io/react/">React.js</a>/<a href="https://github.com/levand/quiescent">Quiescent</a>. Below is the same implementation, but
this time in advanced compilation and without using a back-end. Now you don't
have to log in to see the demo, but of course your todo list won't
be saved in a database either.</p>
<a href="2014/05/01/datascript_quiescent_standalone.html">Read more</a>Datascript and React.js for a Clojure web app2014-04-30T23:00:00Zhttps://thegeez.net/2014/04/30/datascript_clojure_web_app.html<h1 id="post-title">Datascript and React.js for a Clojure web app</h1>
<p>When building a web application with Clojure there are a lot of
building blocks to choose from. For ClojureScript there has been a
particularly interesting new offer with the release of <a href="https://github.com/tonsky/datascript">Datascript</a>.
Datascript is a way to manage application state in ClojureScript following
the database properties of <a href="http://www.datomic.com/">Datomic</a> (although not related to that
project in any way). Together with <a href="http://facebook.github.io/react/">React.js</a> to handle the rendering
of the user interface, this is a nice way to build dynamic,
data-driven browser front-ends. It also fits in nicely with an
example <a href="http://clj-crud.herokuapp.com/">todo</a> list application I have been working on.</p>
<h2>Datascript</h2>
<a href="2014/04/30/datascript_clojure_web_app.html">Read more</a>Using SendGrid with Clojure in The Next Web HackBattle2014-04-24T23:00:00Zhttps://thegeez.net/2014/04/24/tnw_hackbattle_sendgrid.html<h1 id="post-title">Using SendGrid with Clojure in The Next Web HackBattle</h1>
<p>This week is <a href="http://thenextweb.com/conference/europe/">The Next Web</a> conference in Amsterdam, where I participated
in the <a href="http://thenextweb.com/conference/europe/hack-battle/">HackBattle</a>. Like I did two years ago, I took
a project I am currently working on and tried to use one of the
HackBattle API partners. Last time I used <a href="http://thegeez.net/2012/05/16/the_next_web_rijksmuseum.html">BrowserChannel and the Rijksmuseum API</a>. The current project I am working on is
to complete the Clojure web application story by building a
back-end for a <a href="http://todomvc.com/">TodoMVC</a> ClojureScript front-end. I've integrated
<a href="http://sendgrid.com/docs/API_Reference/Webhooks/parse.html">SendGrid's
Inbound Parse Webhook</a> API to be able to add todos via email.</p>
<p>Using <a href="http://sendgrid.com">SendGrid</a> you can send an
email with your todo to add it to your todo
list, when you use your profile name in the subject line. On the
server side this was easily implemented by adding a POST handler and
setting some DNS settings properly.</p>
<a href="2014/04/24/tnw_hackbattle_sendgrid.html">Read more</a>Bayesian Inference with Markov Chain Monte Carlo
in Clojure2014-03-12T23:00:00Zhttps://thegeez.net/2014/03/12/bayes_mcmc_clojure.html<h1 id="post-title">Bayesian Inference with Markov Chain Monte Carlo
in Clojure</h1>
<p>I've been working through the
book <a href="https://github.com/CamDavidsonPilon/Probabilistic-Programming-and-Bayesian-Methods-for-Hackers">Probabilistic
Programming and Bayesian Methods for Hackers</a> (ProbHack)
by Cam Davidson-Pilon. This online book is an introduction to
bayesian methods and probabilistic programming for
programmers. Its main focus is Bayesian Inference with Markov Chain
Monte Carlo (BI-MCMC). The ProbHack book uses Python and the PyMC library. For my own
understanding of the inner-workings of BI-MCMC I ported the code to
Clojure in
the <a href="https://github.com/thegeez/bi-mcmc">bi-mcmc</a> (bi-mcmc) project on github. </p>
<h2>BI-MCMC Algorithm</h2>
<a href="2014/03/12/bayes_mcmc_clojure.html">Read more</a>Solving 4clojure problems in an editor2014-01-10T23:00:00Zhttps://thegeez.net/2014/01/10/4clojure_in_editor.html<h1 id="post-title">Solving 4clojure problems in an editor</h1>
<p>On
Twitter <a href="https://twitter.com/xeqixeqi/status/421323628190244865">xeqixeqi</a>
asked for a leiningen template to be able to solve to the problems
from <a href="http://www.4clojure.org">4clojure</a> in an editor rather
than the browser. He then solved this problem himself by building a
<a href="https://github.com/xeqi/foreclojure">lein template for
4clojure</a>.</p>
<p>I did most of the problems in emacs by copy-pasting the
test cases from each problem page. To turn the text on
4clojure into a runnable test I used this
utility: <a href="https://gist.github.com/thegeez/8352754">gist:
4clojure in editor</a>.</p>
Vintage JavaScript game restoration2013-12-30T23:00:00Zhttps://thegeez.net/2013/12/30/vintage_javascript_game_restoration.html<h1 id="post-title">Vintage JavaScript game restoration</h1>
<p>At a recent <a href="http://amsclj.nl/">Amsterdam Clojurians meetup</a> the topic was game
development. Some of the first code I played around with in high school were games
in JavaScript. These games were great as an introduction to programming
because all that is needed to play around with them is a browser, 'view source' and
notepad. My favorite JavaScript games then were made by
K. Moriyama. His site from 1996 is still available online today in
its original
form: <a href="http://plaza.harmonix.ne.jp/~jimmeans/">K. Moriyama's
Home Page</a>, including a matrix led visitor counter and gradient
word-art like header.</p>
<p>Mr. Moriyama took great care to make sure his games were playable
on most browsers, including Internet Explorer 4 and Netscape
Navigator 3. Sadly, current browsers cannot run the JavaScript
anymore. The game I like most
is <a href="http://plaza.harmonix.ne.jp/~jimmeans/falcon/">JS
Falcon</a>. To be able to play this game again I have dusted of the
old JavaScript. All that needed changing were some DOM traversal
paths and the main loop's update interval. The server-side high
score bookkeeping has been removed from this version.</p>
<a href="2013/12/30/vintage_javascript_game_restoration.html">Read more</a>Testing RxJava with executable marble
diagrams2013-03-25T23:00:00Zhttps://thegeez.net/2013/03/25/neflix_rxjava_marble.html<h1 id="post-title">Testing RxJava with executable marble
diagrams</h1>
<p>Reactive Extensions (Rx) from the .Net world are observable
sequences. In particular they are push based sequences, in contrast
to the pull based seq api in Clojure. Furthermore you can subscribe
to and
unsubscribe from observable sequences. This also makes observable
sequences a nice candidate to replace futures and callbacks in
asynchronous code.<br /><br />
For more information see any of the following resources:
</p><ul>
<li>Rx (Reactive Extensions) <a href="http://rx.codeplex.com/">.Net Source</a></li>
<li>Erik Meijer (Rx creator) explains Rx <a href="http://channel9.msdn.com/blogs/charles/erik-meijer-rx-in-15-minutes">video</a></li>
<li>Intro to Rx <a href="http://www.introtorx.com/">Free html ebook</a></li>
</ul>
<p>In particular the "Intro to Rx" book is a great resource. Every other
example will have you wishing to be able to use Rx in Clojure. Luckily
Netflix recently open sourced their Java variation of Rx called RxJava.</p><a href="2013/03/25/neflix_rxjava_marble.html">Read more</a>Haskell Picnic2013-01-20T23:00:00Zhttps://thegeez.net/2013/01/20/haskell_picnic.html<h1 id="post-title">Haskell Picnic</h1>
<p><a href="http://lisperati.com/haskell/">PicnicMob</a> is a Haskell
tutorial for beginners. It is different from many other
introductory tutorials as it has an interesting,
non-trivial algorithm as the subject and it produces pictures at every
step. Also you can't go wrong by reading something by Conrad Barski,
author of <a href="http://landoflisp.com/">Land of Lisp</a>.</p>
<p>I worked through the tutorial when I was still at university. The
picnic placement pictures I first generated are from 2009. I
revisited the tutorial to read up on the <a href="http://en.wikipedia.org/wiki/Simulated_annealing">simulated annealing</a>
algorithm that is used. Along the way I ported the code to Clojure and this code
is on GitHub <a href="https://gist.github.com/4580548">here</a>. The Clojure code follows the Haskell code quite
closely. As with the original tutorial the Clojure code is
inefficient with its use of datastructures and its algorithmic complexity.</p>
<a href="2013/01/20/haskell_picnic.html">Read more</a>October Amsterdam Clojure Presentation2012-10-28T23:00:00Zhttps://thegeez.net/2012/10/28/october_amsterdam_clojure.html<h1 id="post-title">October Amsterdam Clojure Presentation</h1>
<p>The slides from my presentation
at <a href="http://amsclj.nl/october.html">#OctAmsClj</a> are in the ams-clj repo: <a href="https://github.com/ams-clj/octamsclj-2012/">Simpler webapps with Clojure</a>.</p>
<p>The code for the example in the presentation is here: <a href="https://github.com/thegeez/amscljoct-example">amscljoct-example</a>.</p>
Count aggregator in Cascalog2012-08-26T23:00:00Zhttps://thegeez.net/2012/08/26/cascalog_clojure_count.html<h1 id="post-title">Count aggregator in Cascalog</h1>
<p>At my current job we use the excellent <a href="https://github.com/nathanmarz/cascalog">Cascalog</a> library. Cascalog
is a declarative query language for "Big Data" processing on top of
Hadoop. Cascalog queries get compiled into MapReduce tasks (through
the underlying <a href="http://www.cascading.org/">Cascading</a> library). This approach is a huge win over
writing MapReduce tasks yourself. The "Hello World" of MapReduce
tasks is the <a href="http://wiki.apache.org/hadoop/WordCount">word-count</a> example. However this example is a bit
deceptive as it consists of only one Map task and one Reduce task.
Most queries that we run require multiple MapReduce tasks chained
together. With Cascalog we write a query declaratively
while the underlying libraries take care to create (efficient!)
chains of MapReduce tasks.</p>
<p>In the beginning I struggled with writing Cascalog queries with
aggregators. The best example of this is the count aggregator. The
following code uses "count" in Cascalog and SQL.</p>
<a href="2012/08/26/cascalog_clojure_count.html">Read more</a>Testing clj-browserchannel2012-07-10T23:00:00Zhttps://thegeez.net/2012/07/10/test_selenium_browserchannel.html<h1 id="post-title">Testing clj-browserchannel</h1>
<p>The <a href="https://github.com/thegeez/clj-browserchannel">clj-browserchannel</a> project now also contains a test
project. The <a href="https://github.com/thegeez/clj-browserchannel/tree/master/test">test project</a> contains a small executable test that
tests the whole browserchannel stack, by using the <a href="https://github.com/thegeez/clj-browserchannel/tree/master/chat-demo">chat-demo</a>
application. The test project is meant to test the server-side
component of the BrowserChannel protocol in
clj-browserchannel. Together with the client-side implementation as
part of the Google Closure library this provides real-time
bi-directional communication for web apps.</p>
<p>The test is done by mimicking people chatting in the chat-demo
application. Testing the server component in clj-browserchannel by
itself is nearly impossible. This is because the server-side is
fully dependent on cooperation with the client-side to comply to
the BrowserChannel protocol. However both the protocol and the
client-side implementation are very sparsely documented. The
client-side implementation is a black box that can not easily be
mocked or stubbed. Therefore the approach is to do <a href="http://thinkrelevance.com/blog/2012/04/26/thinkrelevance-the-podcast-episode-010-stu-halloway">simulation testing</a>.</p>
<a href="2012/07/10/test_selenium_browserchannel.html">Read more</a>My understanding of reducers after
EuroClojure2012-06-12T23:00:00Zhttps://thegeez.net/2012/06/12/euroclojure_reducers.html<h1 id="post-title">My understanding of reducers after
EuroClojure</h1>
<p>At EuroClojure Rich Hickey gave a second, unscheduled talk about the new
reducers library. The talk clarified a few points for me, that I
didn't initially get from the explaining blogposts on
<a href="http://clojure.com/blog">clojure.com/blog</a>. For the <a href="http://www.meetup.com/The-Amsterdam-Clojure-Meetup-Group/">Amsterdam Clojure Meetup</a> I wrote down
these notes:</p>
<h2>Reducers vs seq/lazy-seq api</h2>
<a href="2012/06/12/euroclojure_reducers.html">Read more</a>Playing "Racket Gin Rummy in ClojureScript" with
Clojure2012-06-01T23:00:00Zhttps://thegeez.net/2012/06/01/ginbot_euroclojure.html<h1 id="post-title">Playing "Racket Gin Rummy in ClojureScript" with
Clojure</h1>
<p>In 2010 I built my first real Clojure application. It was a tool to
execute semantic specifications of modeling languages and was part of
my master thesis. Before I decided
to use Clojure for this tool I built a little program to test the
waters. This program was <a href="https://github.com/thegeez/clj-ginbot">GinBot</a>.</p>
<p>Whilst dabbling with functional programming languages I tried PLT
Scheme (now <a href="http://racket-lang.org">PLT Racket</a>). As part of the DrScheme editor came a couple
of example games. My favorite is the Gin Rummy card game. The object of this game is to make a hand of 10 cards,
consisting of a set of four cards and two sets of three cards. Players take turns and can choose to pick the top card of the
discard pile or a face down card from the deck. For more information see the
rules for Gin Rummy in the <a href="http://docs.racket-lang.org/games/ginrummy.html"> Racket
documentation</a>.</p>
<a href="2012/06/01/ginbot_euroclojure.html">Read more</a>BrowserChannel and the Rijksmuseum API at
The Next Web HackBattle2012-05-16T23:00:00Zhttps://thegeez.net/2012/05/16/the_next_web_rijksmuseum.html<h1 id="post-title">BrowserChannel and the Rijksmuseum API at
The Next Web HackBattle</h1>
<p>The
last <a href="http://thenextweb.com/conference/amsterdam/2012/">The
Next Web conference</a> in Amsterdam on the 23rd to 25th of April
2012 included a two
day <a href="http://thenextweb.com/conference/amsterdam/2012/hackbattle">HackBattle</a>. During
this HackBattle I built a website combining the API from the
<a href="http://www.rijksmuseum.nl/api">Rijksmuseum</a> with my
<a href="https://github.com/thegeez/clj-browserchannel">clj-browserchannel</a>
library.</p>
<p>The Rijksmuseum API contains all the works from the museum in
digital format, with loads of metadata. The website I build displays
a selection from these works and allows people to add 'notes' to the
paintings. When a note is placed, everybody looking at that painting
will see the note pop-up on the site. The idea behind this was that
this could be used in a group tour setting through the museum. Of
course the real-time aspect of the website is provided by
clj-browserchannel. This group tour aspect is also the motivation
behind the simple design of the website, which makes it usable on at
least Android smartphones.
</p>
<a href="2012/05/16/the_next_web_rijksmuseum.html">Read more</a>Why BrowserChannel?2012-04-03T23:00:00Zhttps://thegeez.net/2012/04/03/why_browserchannel.html<h1 id="post-title">Why BrowserChannel?</h1>
<p>After the release
of <a href="https://github.com/thegeez/clj-browserchannel-demo">clj-browserchannel-demo</a>,
I have been asked what BrowserChannel is exactly. This post will
hopefully clarify what BrowserChannel is and why it is a great fit
for ClojureScript and Clojure web applications.</p>
<p><a href="http://closure-library.googlecode.com/svn-history/r144/docs/closure_goog_net_browserchannel.js.html">BrowserChannel</a> is a protocol developed by Google. It provides cross-browser compatible, real-time, bi-directional communication
for various Google web apps, including Google Docs and GMail.</p>
<a href="2012/04/03/why_browserchannel.html">Read more</a>Racket Gin Rummy in ClojureScript2012-03-20T23:00:00Zhttps://thegeez.net/2012/03/20/racket_gin_clojurescript.html<h1 id="post-title">Racket Gin Rummy in ClojureScript</h1>
<p>A ClojureScript implementation of a simple card game. The game can
be played <a href="http://thegeez-gin.s3-website-eu-west-1.amazonaws.com/">here</a>.</p>
<p>The Racket programming environment comes with a couple of example
games written in Scheme. My favorite of these games is Gin
Rummy. The object of this game is to make a hand of 10 cards,
consisting of a set of four cards and two sets of three cards. A set
of cards are cards of the same rank (i.e. three Jacks) or subsequent
cards of the same suit (i.e. 8,9,10,J of hearts). An ace can be low
or high. The game has two players with ten cards each. In the middle
are the deck of cards faced down and a discard pile, with cards face
up. Players take turns and can choose to pick to top card of the
discard pile or a face down card from the deck. The chosen card has
to be exchanged for a card in the players hand, which is placed on
top of the discard pile. For more information see the
<a href="http://docs.racket-lang.org/games/ginrummy.html"> Racket documentation</a>.</p>
<a href="2012/03/20/racket_gin_clojurescript.html">Read more</a>Simple static blog with Clojure2012-03-15T23:00:00Zhttps://thegeez.net/2012/03/15/static_blog_on_github_with_enlive.html<h1 id="post-title">Simple static blog with Clojure</h1>
<p>This inaugural post for this Clojure blog describes how it is
created. This blog is hosted by GitHub Pages and the static pages are
generated by a minimal clone for Jekyll written in Clojure and
using Enlive. The code is by no means a replacement for Jekyll, but
can serve as a starting point for people wanting to do the same.</p>
<p>The code for the static pages generator is in the <a href="https://github.com/thegeez/clj-static-blog">clj-static-blog</a> project.</p>
<a href="2012/03/15/static_blog_on_github_with_enlive.html">Read more</a>