Riff: A "mycelium-clj" for the Clojure ecosystem?

In a world of concrete objects, steel frameworks bring sense and order. In a forest of composable tools, libraries and open-ended schemas, it would be the mycelia. A frustrated yet optimistic man muses "Might such a thing come to be?".

Permalink

Following our first five LLM meetups

In May 2023, Scicloj started organizing a series of meetups around Large Language Models. This series was inpired by a few other projects in the Clojure community, such as Rupert’s initiative to work on models that may work well with Clojure language tasks, the related #clojurellm channel that was created by John Newman and Rupert, and the various libraries for LLMs and related services, that have been keep emerging mostly during 2023.

Permalink

Clojure Deref (Sept 29, 2023)

Welcome to the Clojure Deref! This is a weekly link/news roundup for the Clojure ecosystem (feed: RSS). Thanks to Anton Fonarev for link aggregation.

Libraries and Tools

New releases and tools this week:

  • openai-clojure 0.11.0 - Clojure functions to drive the OpenAI API

  • malli 0.13.0 - High-performance Data-Driven Data Specification Library for Clojure/Script

  • clj-depend 0.9.0 - A Clojure namespace dependency analyzer

  • neil 0.2.61 - A CLI to add common aliases and features to deps.edn-based projects

  • vault-clj 2.1.583 - Clojure client for Hashicorp’s Vault secret management system

  • aleph 0.7.0-alpha2 - Asynchronous communication for Clojure

  • bbin 0.2.1 - Install any Babashka script or project with one command

  • babashka 1.3.185 - Native, fast starting Clojure interpreter for scripting

  • next-jdbc 1.3.894 - A modern low-level Clojure wrapper for JDBC-based access to databases

  • clojure-ts-mode 0.2.0 - The next generation Clojure major mode for Emacs, powered by TreeSitter

  • automigrate 0.1.1 - Database auto-migration tool for Clojure

  • tiara 0.3.1 - A small data structure library

  • spike 0.0.2 - Simple SPARQL client for Clojure

  • asami 2.3.4 - A flexible graph store, written in Clojure

  • deps.clj 1.11.1.1413 - A faithful port of the clojure CLI bash script to Clojure

  • cli 0.7.53 - Turn Clojure functions into CLIs

Permalink

Penny game work in progress

Penny game work in progress

In the previous post I created a basic simulation of a manufacturing line. We ran the line for 100 iterations and looked at the total output. Total output gives us an indication of the line's revenue. For us, the line's output was:

(def steps
  (simulate initial-state update-state 100
    (fn [roll]
      (repeatedly 7 roll))))
(total-output steps)
290

But a manufacturing line also has expenses, among them its material input:

(defn total-input [steps]
  (transduce
    (map #(-> % :incoming (or 0)))
    + steps))
(total-input steps)
337

The difference between the number of pennies that have gone into the line and the number of pennies that have come out is a result of how many pennies are currently being worked on by the line. We can see how much work in progress there is for each step. At the beginning, there are 24 pennies in progress:

(defn work-in-progress [step]
  (reduce + (step :stations)))
(work-in-progress (first steps))
24

At the end, however, there are quite a few more:

(work-in-progress (last steps))
71

If we graph the amount of work in progress for each step, we can see it growing:

Work in progressStep 10Step 20Step 30Step 40Step 50Step 60Step 70Step 80Step 90Step 10001530456075

Work in progress is another expense faced by a manufacturing line; we need somewhere to store all that material, as well as people and equipment to move it around. Thus, if we want to optimize our line, we should not only maximize output but minimize work in progress. We'll experiment with more productive stations in the next post.

Permalink

Harmonising Elegance: The Art of Functional Programming in Software Design

Functional Programming (I will call FP in this post and further) is not just a coding style; it is an elegant programming paradigm which transformed the way I design and build software, since I got to know this. Mastering this can truly reform the way of your software development which will lead to more concise, maintainable and robust code in real world. We will discuss about the power of FP and it's beauty in software design.

Unveiling Functional Programming

FP is a programming paradigm which treats computation as the evolution of mathematical functions. If you remember from earlier maths class (f . g)(x) = f(g(x)) [read a f of g of x]. Similarly in FP we talk about immutability and purity of functions, which says pure functions don't have side effects and always returns same output for the same input. This leads more predictable code.

Key concepts of FP

1. Pure Functions

In FP, we write pure functions. Pure functions means they take inputs perform the steps mentioned over it and produce the output. They don't modify state or variable outside their scope, that makes the whole code predictable and easy to test under FP.

2. Immutable Data

In FP, We consider Data can not be changed once it is created; instead new data created or stored in a new variable with each transformation. This eliminates the need of complex state management.

3. First-Class Functions

In FP, functions are considered as first class citizen. You might be thinking what is it, It means we can assign functions to variables, pass them into another function as arguments and return from a function. This opens the door for powerful abstraction and composability. This helps a functional programming language to support Higher-Order Functions.

4. Higher-Order Functions

In FP, We create functions which can take another functions as arguments and/or return functions as result. Which helps us to create compositions for complex problems with ease of readability.

5. Recursion

In FP, we prefer using recursion over iterative loop approach, that looks more mathematical, we need not to maintain many other variables and the best thing is it doesn't lead memory leak for dynamically garbage collecting programming languages.

6. Referential Transparency

In FP, one can easily replace the whole function's execution with just it's value without changing the program's behaviour. That many times help in optimisation and many time in removing/replacing third party libraries from your code base because of pricing or some new launched libraries with additional features.

Benefits of FP in Software Design

These are the benefits I found using FP to design enterprise grade softwares

1. Plug and Play: Easily add or remove any third party plugins, or internal features from code as and when needed.

2. Conciseness: FP allows me to write complex operations in fewer lines with more readability of code.

3. Modularity: FP's focus on pure functions and immutability makes it easier to read, test and maintain. Plus everything is inside a small SPR function can be put separately in separate modules.

4. Safety: With immutability and pure functions it reduces the chances of bug and over that easy to debug because of no side effect you know which state has been changed by which function. You can check that function and fix that easily.

5. Parallelism: Functional code is inherently more parallelizable, taking advantage of multi-core processors and distributed computing.

6. Readability: FP code often reads like a series of transformations, which make it more readable and less error-prone.

Real World Applications of FP

FP is used extensively in real world applications. Programming Languages like Haskell, Clojure and Scala are designed with FP in mind. Which have gained popularity in various domains like, finance, healthcare and data processing.

Present era mainstream programming languages like Python, JavaScript and Java are evolving to accommodate FP widely and allowing developers to incorporate FP into their software incrementally.

When your team is not at the expertise level or familiar to FP and your project delivery timelines are tight you should refrain from using it. Definitely not fit for such domains which are highly depends on mutable states and side effects i.e. Game developments, Digital Signal Processing and Embedded Systems.

Till the next time keep Learning-Coding-and-Growing.

Previous Article: Mastering the Art of Software Design: An Overture to Object-Oriented Design

Permalink

Ep 092: Freeing Limits

Each week, we discuss a different topic about Clojure and functional programming.

If you have a question or topic you'd like us to discuss, tweet @clojuredesign, send an email to feedback@clojuredesign.club, or join the #clojuredesign-podcast channel on the Clojurians Slack.

This week, the topic is: "freedom through constraints." We bump into limiting constraints and learn to love their freedoms.

Our discussion includes:

  • Why expressiveness isn't everything.
  • Causes of combinatorial complexity.
  • The long-term benefits of decreased complexity.
  • Problems Clojure eliminates with its language design.
  • Why complexity feels so good when you're problem solving.
  • How the right limits create freedom.
  • Why Clojure's limiting constraints make it hard to switch from object-oriented programming.
  • Reasons software teams start using microservices.
  • Integrating around behavior vs integrating around data.
  • Awesome hair.

Selected quotes:

  • "Complexity really adds up the more you load it into your application."
  • "Clojure eliminates the time sink related to combinatorial complexity while giving you the ability to craft things faster."
  • "When you're inside a method of an object, there's all those delicious member variables, instance variables, that are just sitting there ready to be touched--ready to be modified--and you have to be super disciplined not do that."
  • "You feel so good because of all the systems you come up with, and all the structure, and all the rules. You notice patterns in the different rules, and you publish books about them, and you think, 'Wow! Look how productive we've been in coming up with all these ways of managing all this complexity! Programming is so hard!'"
  • "Limiting constraints create freedom through limitation."
  • "Sorry, I mutated it out from underneath us."
  • "Eventually, over time, [the OO system] grows and then it becomes unmanageable. It becomes ungovernable. There are no rules that you can actually have, so the only solution is to rewrite."
  • "You know it's a good metaphor when you can take it to the level where it starts falling apart."
  • "This is a big downside of Clojure: you don't just pick it up like your last four programming languages that were all from imperative land."
  • "It's not just a functional style that hangs out as a little part of your program. This is functional: top to bottom, ceiling to floor."
  • "You think of zucchini bread as a naturally mom-shaped problem."
  • "You have to discover another way to do it, and that can take time."
  • "It appeared again! Great! It's for me!"
  • "I just want my program to work, and some guy, with awesome hair, has told me that this is better, but I don't know how to get there!"

Links:

Permalink

Jointprob community updates - Probability Basics talk, Hierarchical Models followup

⭐ TL;DR: See you at the September standalone talk of the Jointprob – an intro to Probability basics. Also, please check out 🎥 the recording of the August talk by David MacGillivray about Bayesian Hierarchical Models. ⭐ Background # The Jointprob community was created by Scicloj during the summer of 2022, aspiring to be a space where friends of diverse backgrounds can learn & explore Bayesian statistics and probabilistic modeling.

Permalink

Converting CURL header to Clojure map

Code

;; curl_headers.clj

(use '[clojure.java.shell :only [sh]])
(require '[clojure.string :as str])

;; Got both below functions from 
;; https://stackoverflow.com/questions/31138653/clojure-idiomatic-way-to-write-split-first-and-split-last

(defn split-first [s re]
  (str/split s re 2))

(defn split-last [s re]
  (let [pattern (re-pattern (str re "(?!.*" re ")"))]
    (split-first s pattern)))

(defn string-to-map [s re]
  (let [[k v] (map #(str/trim %) (split-first s re))]
    {k v}))

(defn curl-header-to-map [s]
  (let [lines (str/split s #"\n")
        first_line (first lines)
        rest_of_lines (rest lines)
        [protocol status] (str/split first_line #"\s+")
        rest_of_lines_to_map (apply merge (map #(string-to-map % #":") rest_of_lines))]
    (merge {"protocol" protocol "status" status} rest_of_lines_to_map)))

;; curl -X HEAD -I https://something.com
;; (def curl-header (slurp "curl_output.txt"))

(defn curl-headers [url]
  (curl-header-to-map (:out (sh "curl" "-X" "HEAD" "-I" url))))

(curl-headers "https://something.com")

(get (curl-headers "https://something.com") "content-type")
(get (curl-headers "https://bafybeiglw52c2scnonhlemktgtmj4y3ufvsqg24bdf4fbqg7padhqpxz3q.ipfs.nftstorage.link/clohure_diary_round_logo.svg") "content-type")
(get (curl-headers "https://mindaslab.github.io/me.jpg") "content-type")

Permalink

Announcing 2023 Board Nominations

Clojurists Together is in the process of electing new board members to fill the four volunteer positions that are expiring this year. These positions are for two-year terms.

The board is responsible for governing the organization, selecting and administering the projects that are sponsored, and interacting with sponsors. It also facilitates decision-making and implementation for the future plans of Clojurists Together.

We received 7 applications from the Clojure Community. 2 are from current board members who would like to continue to serve. All of the candidates are talented Clojurists that we would love (and be honored) to have on our board.

The board has nominated all 7 candidates for the current board election (in alphabetical order of first names):

  • Chip Nowacek
  • Daniel Compton (current Treasurer/Secretary)
  • Felix Barbalet
  • Heather Moore-Farley (current board member)
  • Job Samwel Gateri Abellu
  • Max Penet
  • Vincenzo Chianese

Next Steps

All current Clojurists Together Members should have received a link to their ballot to vote via email. If you haven’t received a ballot by 3rd October (and you’ve checked your spam folder to see if it’s hiding there), please contact kdavis@clojuriststogether.org.

Voting will close on 7th October at midnight Pacific Time. The top four candidates, as voted on by members will win. We will announce the winners shortly afterward and you’ll be able to meet them at the Annual members meeting at 10 am Pacific time, October 10, 2023.

Your Vote is Important!! Please Vote!

Meet the Candidates

Chip Nowacek

https://clojurians.slack.com/archives/C0218CKTVEK/p1692842517062129

Company: Two Stewards, LLC.

Why you would like to join: The community has been so supportive. I want to give back where I can. I have no other ambitions. I don’t really know enough or have time enough to have any.
A short bio: Building a chatbot interface to a knowledge graph using the full Clojure/Script/Datomic stack. Using the tech because of the community ethos.


Daniel Compton

http://github.com/danielcompton
https://twitter.com/danielwithmusic

Company: Whimsical

Why you would like to join:
I am a co-founder of Clojurists Together. I have been involved with all of the funding rounds since the beginning and am currently the treasurer and secretary for Clojurists Together.

A short bio: Daniel Compton is a software engineer, working at Whimsical. He lives in a small town in New Zealand with his family. He was the co-founder of Clojurists Together and has been deeply involved with running Clojurists Together since the beginning.


Felix Barbalet

https://github.com/xlfe
https://psithur.com/blog/building-psithur-connect/

Company: Qantas Airways Ltd (Australia)

Why you would like to join: I’ve been using Clojure professionally for 3+ years now, and currently lead a team of Clojure engineers. Clojure has been the continuation of a life-long learning journey for me, and I don’t see that slowing down. The kind of things I’m interested in are figuring out how to raise the profile of Clojure as a smart choice for large enterprises all the way down to startups, and to help reduce the barriers to entry to Clojure as a profession. I want to see Clojure continue to grow and I’d love to see more corporate support to bring Clojure to more people.

A short bio: I’ve spent 15 years working as a technologist in a range of roles including analytics, data science, data engineering, software architecture and software engineering. I have experience across highly-regulated industries (Government), consulting and startups. I have a B Economics (Honours) with specialisation in advanced econometrics, statistics, game-theory and behavioral economics and a graduate certificate in Cyber Security.


Heather Moore-Farley

https://github.com/tophat8855

Why you would like to join: I’ve been on the board for the past 2 years and can keep it up. I know the work of board meetings and prep follow-up isn’t glamorous, but is really important for organizations to feel like they are going somewhere, and for increasing a feeling of community. I think it can be easy to feel like a lone developer working on a project, but knowing groups like CT are supporting projects can alleviate that a bit. And CT can’t support projects without a committee.

A short bio: Heather is a software engineer, knitter, and bicyclist. She has been coding with Clojure and Clojurescript full-time for 5 and a half years. In her 8 years of professional software development, she has both benefited from and contributed to open source projects.


Job Samwel Gateri Abellu

https://www.linkedin.com/in/job-s-27352545/

Company: Ezra World

Why you would like to join: I am excited about the opportunity to contribute to the Clojurists Together Committee for several reasons:

  • Passion for Clojure: I have a deep passion for the Clojure programming language and its ecosystem.
    Over the years, I have developed a strong technical expertise in Clojure through hands-on experience. Joining the committee would allow me to actively participate in the Clojure community and support its growth, which has been a significant part of my professional and personal journey.
  • Eager to Contribute to Open Source: While I haven’t yet contributed to open-source projects, I am genuinely eager to start. The mission of Clojurists Together resonates with me, and I see this as an opportunity to begin my journey of giving back to the open-source community, particularly within the Clojure ecosystem.
  • Commitment to Open Source: I firmly believe in the power of open source to drive innovation and solve complex problems collaboratively. Clojurists Together’s mission of providing financial support to open-source Clojure projects aligns with my values. I am enthusiastic about contributing to the sustainability of these projects and ensuring they continue to thrive.

I believe I am a good fit because of:

  • Technical Expertise: I bring a strong technical background in Clojure and ClojureScript, with hands-on experience in developing and maintaining projects. My technical skills and familiarity with the ecosystem will enable me to assess project proposals effectively and provide valuable insights.
  • Strategic Thinking: I have a track record of strategic thinking and problem-solving, which I believe will be valuable when assessing project proposals and making decisions that align with Clojurists Together’s goals and objectives.
  • Commitment and Dedication: I am dedicated to the long-term success of the Clojure community and the projects it supports. I understand the responsibilities that come with being a committee member, and I am committed to fulfilling them with dedication and integrity.
    In summary, my passion for Clojure, technical expertise, strategic thinking, and commitment to open source make me confident that I would be a valuable addition to the Clojurists Together Committee. While I haven’t contributed to open-source projects before, I am eager to start this journey and actively participate in supporting the Clojure ecosystem. I look forward to the opportunity to work alongside fellow committee members to further the mission of Clojurists Together.

A short bio: I am Job Samwel Gateri Abellu, a dedicated Clojure enthusiast with over 6 years of experience in this elegant and functional programming language. My journey into the world of Clojure began when a friend sought my assistance on a project, sparking a profound interest that has grown with each passing year.

My educational background includes a degree in Information Technology, with a major in software development. This academic foundation, combined with my hands-on experience, has allowed me to cultivate a robust skill set in Clojure. Throughout my career, I have leveraged this expertise to tackle complex challenges and develop innovative solutions.

Notably, my professional journey has primarily unfolded within the dynamic FinTech industry. My experience in this sector has provided me with invaluable insights into the intersection of technology and finance, making me well-equipped to understand and contribute to projects that bridge these domains.

While I am relatively new to open-source contributions, my unwavering passion for the Clojure ecosystem and my commitment to continuous learning make me an eager advocate for its sustainability and growth. I bring strategic thinking and a deep dedication to open source, aligning seamlessly with Clojurists Together’s mission.

If elected, I pledge to diligently collaborate with my fellow committee members to select and support projects that advance our shared goals, ensuring they continue to thrive and benefit the entire Clojure community. It is an honor to be considered for this role, and I am enthusiastic about the opportunity to make a meaningful impact on the Clojure community through Clojurists Together.


Max Penet

https://github.com/mpenet
https://twitter.com/mpenet

Company: Exoscale

Why you would like to join: I would like to have more of an impact on the community. I generally quite like to help out when possible, via the various discussion channels. I have also been the recipient of such help numerous times and it’s only fair I give back some of my time to help out. I think I might be a good fit given how long I have been involved in the community and how much I rely on the Clojure community to be healthy and thriving.

A short bio: I currently work as a software engineer for Exoscale, a European cloud provider that relies heavily on Clojure. I have been involved in the Clojure community and using Clojure professionally for more than a decade now, in various fields. I authored, contributed, and maintain a number of open-source libraries. I also tend to keep an eye on what’s happening at the community level almost daily, trying to be helpful when I can. More importantly, I really appreciate what CT is doing and would love to be able to help sustain that effort.


Vincenzo Chianese

https://www.linkedin.com/in/vncz/

Company: Microsoft

Why you would like to join: Have been using Clojure for a long time (unfortunately not at work), but I have been sitting in multiple committees (technical and not) and worked in technology for a long time. I have spoken to a lot of conferences and would love to help spread Clojure methodologies around.

A short bio: Vincenzo Chianese is an Italian Software Developer currently working as API Architect for Microsoft. He has been working in the API space for almost 10 years from building tools for API developers and architecting big systems.

Permalink

vim-slime

<!DOCTYPE html> <html> <head> <title>Tarn Barford</title> <meta charset="utf-8"/> <link rel="icon" type="image/x-icon" href="/favicon.ico"> <link href="/style.css" media="screen" rel="stylesheet" type="text/css" /> <link rel="alternate" type="application/atom+xml" title="Journals of Tarn Barford" href="/atom" /> <link href="/highlight.css" media="screen" rel="stylesheet" type="text/css" /> </head> <body> <div id="container"> <div id="header"> <div id="header"> <p>From the <a href="/journal">Journals</a> of <a href="/">Tarn Barford</a></p> <h1> vim-slime </h1> <p> Mar 26, 2012 </p> </div> </div> <div id="post_content"> <html><body><p>Today I found the awesomeness that is <a href="https://github.com/jpalardy/vim-slime">vim-slime</a>, it's been an exciting day for me. <a href="http://common-lisp.net/project/slime/">Slime</a> is the "The Superior Lisp Interaction Mode for Emacs", I can almost hear the emacs crowd laughing.</p> <p>For those that use vim and haven't used Slime, vim-slime or <a href="https://github.com/vim-scripts/VimClojure">something similar</a>, this is why it's awesome:</p> <p><strong>Text can be sent from any process to the stdin of a <a href="http://www.gnu.org/software/screen/">gnu screen</a> or <a href="http://tmux.sourceforge.net/">tmux</a> session. The process in this case is vim and the screen/tmux session is a terminal</strong>.</p> <p>Screen is a <a href="/journal/oh-screen-where-have-you-been">really neat</a> terminal multiplexer (you can run multiple terminals in a terminal window). The multiplexed shell processes are children of the screen process, which itself is not a child of the terminal window process. This means a screen process and its child processes keep running if you close the terminal window. Later you can re-connect to it, this is what makes vim-slime possible.</p> <p>Here is an screen shot, on the left is me in gVim writing some awful Clojure <a href="#footnote-1">[1]</a>. On the right is a screen buffer in which I started a Clojure REPL. When I want to try run some code I can send any vim text selection to the REPL in a keystroke (or two).</p> <p><img alt="vim slime screenshot" src="screenshot.jpg"/></p> <p>It doesn't have to be a Clojure REPL either, we can send anything to a screen shell. We could run git commands, find, grep, sed, etc. Like with the Clojure REPL we can even interact with any terminal programs that use STDIN.</p> <p>This concept can be taken even further, You can even connect to a tmux session over SSH and share a terminal or a <a href="http://remotepairprogramming.com/remote-pair-programming-with-tmux-and-vim-the">terminal program like vim to do remote pairing</a>!</p> <p>Hopefully remote pairing is the topic of my next post as there are a couple geographically distant people I know who are keen to do some pair hacking. I stand to learn a lot!</p> <p><a name="footnote-1">[1]</a> I learnt almost everything I know about Lisp from <a href="http://www.ccs.neu.edu/home/matthias/BTLS/">The Little Schemer</a>. Great book.</p></body></html> </div> <div id="comments"> </div> </div> <div id="footer"> <p>&nbsp;</p> <p>Questions, comments, suggestions? Email me, <a href="mailto:tarn@tarnbarford.net">tarn@tarnbarford.net</a> (<a href="/pgp.txt">public key</a>)</p> <p>&nbsp;</p> </div> </body> </html>

Permalink

Swipe Keyboard

<!DOCTYPE html> <html> <head> <title>Tarn Barford</title> <meta charset="utf-8"/> <link rel="icon" type="image/x-icon" href="/favicon.ico"> <link href="/style.css" media="screen" rel="stylesheet" type="text/css" /> <link rel="alternate" type="application/atom+xml" title="Journals of Tarn Barford" href="/atom" /> <link href="/highlight.css" media="screen" rel="stylesheet" type="text/css" /> <style> #swipe-canvas { position: relative; width: 900px; height: 300px; } #swipe-results { font-size: 30px; padding-left: 50px; padding-left: 50px; } #swipe-results ul { margin: 0px; padding: 0px; } #swipe-results li { float: left; background-color: #DDDDDD; list-style-type: none; padding: 10px; margin: 5px; border-radius: 5px; } #swipe { position: relative; } #swipe-loading { position: absolute; height: 50px; width: 300px; top: 85px; left: 300px; background-color: darkgray; border-radius: 10px; text-align: center; padding-top: 20px; border: black; border-width: 5px; } </style> </head> <body> <div id="container"> <div id="header"> <div id="header"> <p>From the <a href="/journal">Journals</a> of <a href="/">Tarn Barford</a></p> <h1> Swipe Keyboard </h1> <p> Apr 06, 2014 </p> </div> </div> <div id="post_content"> <html><body><p>When I first tried a <a href="http://www.swype.com/">Swype</a> keyboard I was impressed how effective it was. Even though I don't use the feature on my phone I was interested in how it could be built, so I <a href="https://github.com/tarnacious/swipe-keyboard">implemented this otherwise useless swipe-able keyboard</a> below. It probably doesn't work on mobile devices, but works on modern browsers with mouse pointers (although I've only really tried Chrome and Firefox).</p> <div id="swipe"> <canvas height="300px" id="swipe-canvas" width="900px"></canvas> <div id="swipe-results"></div> <div style="clear: both"></div> <h2 id="swipe-loading">Loading<noscript>Javascript is Required</noscript></h2> </div> <p>I initially tried to solve this using the technique Peter Norvig famously uses in his <a href="http://norvig.com/spell-correct.html]">spell checker</a>. He takes a sequence of characters and generates a set of word candidates by adding, removing and swapping characters in the original sequence, the generated candidates are removed if they are not found a dictionary. This can work but to be effective too many combinations need to be generated.</p> <p>If the dictionary is indexed into a <a href="http://en.wikipedia.org/wiki/Trie">trie</a> the number of combinations generated can be reduced significantly by traversing the trie and only generating valid letter combinations. This is a pretty bare implementation of that, it requires: </p> <ul> <li>The first and last characters of the initial sequence are used </li> <li>Intermediate characters in the initial sequence can be repeated or discarded </li> <li>No characters are added or swapped</li> </ul> <p>Basically, if you swipe through all the characters in a word in order, then the word will be found if it is in the index regardless how many characters are swiped in between. It is surprisingly quick and effective.</p> <p>This implementation uses <a href="https://raw.github.com/first20hours/google-10000-english/master/google-10000-english.txt">these 10000 words</a>, I intended to use digital books but never got around to it as these words demonstrate the concept well enough.</p> <p>This is the first thing I've written in <a href="https://github.com/clojure/clojurescript">ClojureScript</a> or <a href="https://github.com/clojure/clojurescript">Clojure</a>, so my code my vary from non-idiomatic to shamblolic. I initially used a <a href="http://clojuredocs.org/clojure_core/clojure.zip/zipper">zipper</a> to build the trie with immutable data structures, but found the indexing took to long with my zipper implementation so I <a href="https://github.com/tarnacious/swipe-keyboard/commit/6edd7b26e78121fbe8586b3f0ef54ca8277d9e32">switched to using native Javascript maps</a>.</p> <p>I found that <a href="https://github.com/clojure/core.async">core.async</a> library is really awesome, the <a href="http://docs.closure-library.googlecode.com/git/index.html">Google closure library</a> and <a href="https://developers.google.com/closure/compiler/">compiler</a> integration with <a href="http://leiningen.org/">Leiningen</a> the <a href="https://github.com/emezeske/lein-cljsbuild">cljsbuild plug-in</a> to be impressive. My main pains were the slow JVM start-up time, the advanced closure compiler build of the web worker script fails silently when run (but the main script works fine when compiled with the advanced compiler), and at times I felt some compile time type checking would be nice.</p> <p>I would like to extend this experiment to index the word occurrence counts and proceeding word counts in original text and rank the found words as most likely. Support casing, umlauts, special characters, spelling correction and compound words in the indexing and lookup. I think a live lookup while swiping would also be possible.</p> <p>Overall this was fun, turned out OK I think, and was a great learning experience.</p></body></html> </div> <div id="comments"> </div> </div> <div id="footer"> <p>&nbsp;</p> <p>Questions, comments, suggestions? Email me, <a href="mailto:tarn@tarnbarford.net">tarn@tarnbarford.net</a> (<a href="/pgp.txt">public key</a>)</p> <p>&nbsp;</p> </div> <script src="swipe.js" type="text/javascript"></script> </body> </html>

Permalink

Kotlin Discovered: Inline functions #Kotlin

You never touched Groovy, nor did you jump on the Scala train. Clojure never attracted you; and you heard about Ceylon long after the language had already died. You are one of those old-fashioned Java folks! But now, after all those years, you want to join the cool Kotlin kids. So, where to start? Let’s discover the language together by decompiling it to Java code. Today: Inline functions!

Permalink

Include interactive Clojure/script code snippets in a web page with SCI & friends

I have long dreamt about having interactive code snippets of Fulcro in my teaching materials. Showing people code they could modify and see it render right next to it. Fulcro is a ClojureScript library, but it uses some heavy macros - and those typically require JVM Clojure. Well, not anymore. I was able to rewrite them into Borkdude’s Small Clojure Interpreter (SCI) dialect of Clojure. I.e. I can ask SCI to evaluate a piece of code with these macros, which SCI will macro-expand into more cljs, and execute. With SCI, my Fulcro sci.configs, CodeMirror, and Nextjournal’s clojure-mode, I can have a beautiful in-page editor with code evaluation. And I will show you how to do the same, for your blog.

Permalink

Include interactive Clojure/script code snippets in a web page with SCI & friends

I have long dreamt about having interactive code snippets of Fulcro in my teaching materials. Showing people code they could modify and see it render right next to it. Fulcro is a ClojureScript library, but it uses some heavy macros - and those typically require JVM Clojure. Well, not anymore. I was able to rewrite them into Borkdude’s Small Clojure Interpreter (SCI) dialect of Clojure. I.e. I can ask SCI to evaluate a piece of code with these macros, which SCI will macro-expand into more cljs, and execute. With SCI, my Fulcro sci.configs, CodeMirror, and Nextjournal’s clojure-mode, I can have a beautiful in-page editor with code evaluation. And I will show you how to do the same, for your blog.

Permalink

The Penny Game

The Penny Game

In his book The Goal, Eliyahu Goldratt described a simulation of a manufacturing line using match sticks and dice, though I believe one of his later books used pennies instead of match sticks. I've called the simulation "the penny game" for years, so I'll stick with that term for this series.

The simulation, in brief, is that we have a number of sequential stations on a manufacturing line, and each station's capacity to move pennies to the next station isn't fixed but is determined by a roll of a die. Our job is to optimize the line. To facilitate experimentation, we'll run simulations with code rather than rolling dice and moving pennies manually.

We'll represent our manufacturing line as a list of numbers. Each position in the list is a station, and each number is how many pennies the respective station has to work on:

(def initial-state
  {:stations (repeat 6 4)})
{:stations (4 4 4 4 4 4)}

As with any simulation, we need function to update the simulation's state. Ours will take the previous state and a list indicating how many pennies each station can process. The number of pennies actually processed, however, depends not only on the station's production capacity but also on how many pennies it has in its queue; no station can process more pennies than it has to work on. The output of each station is added to the next station's queue. Here's the update function:

(defn update-state [{:keys [stations]} [incoming & capacities]]
  (let [processed (map min stations capacities)
        new-stations (map (fn [queue outgoing incoming]
                            (-> queue
                                (- outgoing)
                                (+ incoming)))
                          stations
                          processed
                          (cons incoming processed))]
    {:incoming incoming
     :capacities capacities
     :processed processed
     :stations new-stations}))

Notice that the second argument to this function, representing station productivity, has an extra value prepended to the beginning of it. That value represents how many pennies are added to the first station's queue, which is why it's cons'd onto the list of processed pennies, to be used as input to the first station.

I've included the number of incoming pennies, the capacities of each station, and how many pennies each station processed so we can later check the logic and do some analysis.

We can simulate the manufacturing line using iterate and a random number generator:

(defn simulate
  [initial-state update-state iterations generate-capacities]
  (let [rng (java.util.Random. 10)
        roll #(.nextInt rng 1 7)]
    (take (inc iterations)
      (iterate #(update-state % (generate-capacities roll))
               initial-state))))

We increment the number of iterations because iterate produces a sequence whose first item is our initial state.

To simulate the line, we provide our initial state, a number of iterations to run, and a function which provides a list of the incoming pennies and how many pennies each station is capable of processing in this step:

(simulate initial-state update-state 1
  (fn [roll]
    (repeatedly 7 roll)))
({:stations (4 4 4 4 4 4)}
 {:incoming 4,
  :capacities (1 4 1 5 5 2),
  :processed (1 4 1 4 4 2),
  :stations (7 1 7 1 4 6)})

We can check the results: the first station had 4 pennies, could only proccess 1, then it received 4 from the pennies coming into the line, so it now has 7 pennies. The second station had 4 pennies, processed 4, then received 1 from the previous station's output, giving it 1 penny. And so on.

Since we're trying to optimize the line, let's run the simulation for 100 steps and see the total output of the final station, which gives us the overall production of the entire line:

(defn total-output [steps]
  (transduce
    (map #(-> % :processed last (or 0)))
    + steps))
(total-output
  (simulate initial-state update-state 100
    (fn [roll]
      (repeatedly 7 roll))))
290

In the next post, we'll look at a metric in additional to total output that we should consider when optimizing our line.

Permalink

Copyright © 2009, Planet Clojure. No rights reserved.
Planet Clojure is maintained by Baishamapayan Ghose.
Clojure and the Clojure logo are Copyright © 2008-2009, Rich Hickey.
Theme by Brajeshwar.