Just Juxt #4: Duplicate a Sequence (4clojure #32)

Dupe a seq with juxt

Write a function which duplicates each element of a sequence.

Here's a live testing area for you to play with. See if you can solve it with juxt. Then check out the answer below!

(ns live.test
  (:require [cljs.test :refer-macros [deftest is testing run-tests]]))
  
(defn dupseq [s]
  )

(deftest test-32
  (is (= (dupseq [1 2 3]) '(1 1 2 2 3 3)))
  (is (= (dupseq [:a :a :b :b]) '(:a :a :a :a :b :b :b :b)))
  (is (= (dupseq [[1 2] [3 4]]) '([1 2] [1 2] [3 4] [3 4])))
  (is (= (dupseq [44 33]) [44 44 33 33])))
  
(run-tests)

Here's the most common solution:

(defn dupseq [s]
  (interleave s s))
  
(run-tests)

Recall the docstring for interleave:

user=> (doc interleave)
-------------------------
clojure.core/interleave
([] [c1] [c1 c2] [c1 c2 & colls])
  Returns a lazy seq of the first item in each coll, then the second etc.

It's a fine solution, but I could argue that the intent behind interleaving a seq with itself is un-juxt-ified. Ha ha. But seriously... what if we (or the client) were to change our minds, and instead want to duplicate the seq but with some sort of transformation on the repeat. Not so far fetched...

We would have to rewrite the function!!

What if we could write it in such a way that we could more clearly adjust our transmogrifier settings:

Well... it turns out there is a way!! Here's the juxt-ification:

(defn dupseq [s]
  (mapcat (juxt identity identity) s))
  
(run-tests)

That's better! Now let's say we wanted to duplicate a list of numbers but increment the second group. We can easily change the second function passed to juxt:

(defn dupe-inc [s]
  (mapcat (juxt identity inc) s))
  
(dupe-inc '(1 1 2 2 3 3))

Pretty cool, huh? I would say that's a much more useful function!

Permalink

I Published an iOS App with ClojureScript and React Native

Outboard

For the past few years, I’ve kept a Notes.app list of restaurants, hikes, bars, and other things I’ve been meaning to visit. It was messy, not geographically-aware, and difficult to quickly add to. Not finding any satisfactory solutions elsewhere, I decided to scratch my own itch and build an app worth a spot on my home screen. Outboard is the result of the last five months of side project hacking, built in ClojureScript on React Native.

I’ve built a couple apps before using Objective-C and enjoy Swift as a language, so why this stack? Having become familiar with the functional reactive model as interpreted by Re-frame, it’s hard for me to approach UI implementation any other way now. Throw in hot reloading and the Clojure REPL, and ClojureScript on React Native was the obvious choice. What follows are the pros and cons I ran into along the way.

Pros

Functional Reactive Programming

At the risk of overselling this from the start, I simply do not run into bugs at the intersection of state and UI anymore. An entire class of defects I’ve struggled with over the last decade-plus of professional software development has virtually disappeared. No more slightly out-of-sync screens, no more links to dead data; all gone. In its place, a lightweight, low-ceremony, low-boilerplate framework in Re-frame that makes data manipulation straightforward and easy to understand when you return to old code in the future. In my opinion, Re-frame is the killer application of the Clojure philosophy on the front end.

REPL-driven Development

The ability to experiment with changes to the app’s layout or the running state in the iOS Simulator is transformative for speed of development. If I want to know what a particular set of data might look like laid out on a device, I can eval a single line in the REPL and the results are on-screen instantaneously. There is no comparison to re-compiling and manually updating data.

Hiccup Syntax

This is probably more of a personal preference borne of experience, but doing app layout with Flexbox and Hiccup is much easier for me to grapple with than XCode’s Interface Builder. I’ve never found Apple’s constraints system for managing different device sizes and resolutions intuitive, but Flexbox lets me leverage the (meager) web design experience I have to make reasonable responsive app designs.

Library Availability

The React Native community at this point in time spans a wide range of heavily-invested companies, resulting in a good stable of well-maintained libraries for additional functionality. A few I used:

All of these are Javascript-native but simple to integrate with ClojureScript.

Native Modules

Some things I needed to do did not have any React Native library already built, but building functionality for things like data storage in App Groups and geocoding addresses with MapKit in Swift and exposing it to the ClojureScript layer was straightforward and will be the subject of a further post.

Cons

It was not all sunshine and rainbows, though.

Tool Mismatch

By far the biggest problem I ran into was working on a deep stack where layers would change out from under each other, sometimes without warning. I love using ClojureScript, but it introduces another layer of abstraction on top of a shaky foundation of NPM, Javascript, and React Native, all of which are in a constant state of flux.

React Native’s Sharp Edges

React Native in particular is prone to frequent breaking changes. For the most part, I was able to sit on a locked version of React Native, but occasionally adding a library would require an upgrade to React Native itself. The upgrade process is exceptionally brittle, and requires manually git merging large Info.plist files.

Packager Issues

One acute pain point resulting from the tool mismatch issue is the React Native packager, Metro. ClojureScript uses an entirely different compiler and packager in Google Closure, and using the two together is inefficient; see for example this issue documenting out of memory and time issues when Metro slowly tries to package an already-packaged ClojureScript file. Even without the extra complications of Closure, Metro can be infuriating to work with — I once “solved” an issue with its cache after an hour of following dozens of posited solutions from a Github issue thread by simpling renaming the directory the project lived under.

Future Plans

I’m happy with my 1.0 release and using it daily, while making the occasional UI tweak or bugfix. I do have plans for big future features though.

Sync

The obvious next step is adding sync functionality, for users to share with others or with their own devices. Having the app’s data entirely represented in EDN with specs for all of it will hopefully make that sync service easier to reliably build.

Alternate Devices

I’d also like to add clients for the iPad and Desktop; again, being able to repurpose the data model with an appropriate UI layer on top should be helpful.

Conclusion

There are tradeoffs, but fully considered, I’d choose ClojureScript on React Native again in a heartbeat for this class of app. The speed and reliability of the heart of the development process are hard to beat, and outweigh the misaligned tools and occasional ecosystem immaturity issues.

Permalink

Just Juxt #3: Pack a Sequence (4clojure #31)

Pack a seq with juxt

Write a function which packs consecutive duplicates into sub-lists.

Here's a live testing area for you to play with. See if you can solve it with juxt. Then check out the answer below!

(ns live.test
  (:require [cljs.test :refer-macros [deftest is testing run-tests]]))
  
(defn pack [s]
  )

(deftest test-31
  (is (= (pack [1 1 2 1 1 1 3 3]) '((1 1) (2) (1 1 1) (3 3))))
  (is (= (pack [:a :a :b :b :c]) '((:a :a) (:b :b) (:c))))
  (is (= (pack [[1 2] [1 2] [3 4]]) '(([1 2] [1 2]) ([3 4])))))
  
(run-tests)

Here's how to do it:

(defn pack [[a & z :as s]]
  (when a
    (let [[p q] ((juxt take-while drop-while)
                 #(= a %) s)]
      (cons p (pack q)))))

We will now follow our established pattern of dismantling the fn to see how it works at each step. First by just showing how destructuring works in Clojure:

(let [[a & z :as s]
      [1 1 2 1 1 1 3 3]]
  s)

This binds our seq to a local variable s, and labels the first item a and the rest of the coll z:

(let [[a & z :as s]
      [1 1 2 1 1 1 3 3]]
  a)
(let [[a & z :as s] [1 1 2 1 1 1 3 3]]
  z)

This destructuring pattern is simply a way to call first and rest on our seq and give them all extremely concise names, a, z, and s.

Take a look at the meat of the solution, the juxt. It is used to create one of the let bindings:

((juxt take-while drop-while) #(= 1 %) [1 1 2 1 1 1 3 3])

What's with the double parens? It looks kinda weird, no?

The reason is that juxt returns a fn. Recall its docstring:

user=> (doc juxt)
-------------------------
clojure.core/juxt
([f] [f g] [f g h] [f g h & fs])
  Takes a set of functions and returns a fn that is the juxtaposition
  of those fns.  The returned fn takes a variable number of args, and
  returns a vector containing the result of applying each fn to the
  args (left-to-right).
  ((juxt a b c) x) => [(a x) (b x) (c x)]
((juxt a b c) x) => [(a x) (b x) (c x)]

The juxt returned our vector, [(1 1) (2 1 1 1 3 3)], containing a list with the first 2 dupes of our seq, followed by a list of the remaining items.

The trick is in our predicate fn, #(= a %), which is passed to take-while and drop-while via juxt.

Now for the next operation:

(cons '(1 1) (pack '(2 1 1 1 3 3)))

By way of (when a we are recursively ripping off the chunks of consecutive dupes and pack-ing them into a list! What a juxt-tastic endeavor!

Here we have seen juxt used in a new way, that is, to define a let binding to use destructuring. That's awesome!

And we'll have another party tomorrow! See you later.

Permalink

How can pure functions represent state change?

Pure functions have no effect besides returning an immutable value. If that’s true, then how can we use them to represent changing state?

Transcript

Eric Normand: If our functions are pure, meaning they don’t change anything outside of their scope, then how is it that we can use functions to represent change and to represent behaviors? Change over time?

Hi. My name is Eric Normand, and these are my thoughts on functional programming. Let’s imagine that we’re already good at making pure functions, doing a lot of work on our calculations.

We’re good at making pipelines, all that in-the-weeds functional programming stuff. Very important, but let’s say we’re already good at it. Why are we even using functions? What can we do with these functions now that we’re good at them? My answer is that we should be modeling behavior with functions. Let’s back up a step.

When I was younger, less experienced at programming, and first introduced to Java, if one of the requirements said that, “Well, this thing needs to be able to change over time,” I would probably just have made a setter method for that thing and just said, “Well, this is how you change it. You call this method, and it will mutate this value. It will just set it to something else.”

I think that that is about as much analysis as I ever did with what it means to change. I don’t think I’m alone in that because I hear people all the time asking like, “Isn’t the world mutable? Don’t we need mutable state? Because the world is mutable, how can you model things when things change? You need changeable things.”

I think that that misses the point. The point is this. If you just say, “Things change,” you haven’t really captured anything interesting. You haven’t said anything specific about how they change. When do they change? Why do they change?

You have this situation where we’ve got this general memory where a byte can take on any value between 0 and 255 that you want to put in there. You’re not constraining it at all based on the semantics, based on your domain, based on what you want that byte to represent.

What functions can let you do is define how things change. How do they do that? One way is because functions take an argument and they return a return value. We’re talking about pure functions right now.

They have an input and an output. They don’t change their input. We’re just not dealing with any mutation at all, pure functions. If you make that input the current state, the current value of the thing, you can make the output the next value of the thing.

You’re defining how it changes very precisely. It goes from this current thing to this new thing. Now, you can add another argument and do something like make that argument an event.

You say, “Well, when the state is like this and we get this event, then what is the output? What is the new state?” Or maybe it’s, “What is the new state?” You also turn another set of events that get called. They get dispatched.

This is the kind of modeling that we’re able to do in functional programming, is take this top-down approach of saying how the entire state changes based on the events we’re getting.

You’re defining it in such a way that it’s totally testable. You don’t have to set anything up. You just pass in a current state and an event, and you can test properties of the return value.

There’s nothing like, “Do I have to make a new mutable thing and like fiddle with its methods until it gets to the right state, and then test this one new method, and then check if it changed?”

It’s much more testable, but then there’s this other thing. There are so many questions and so many ways of thinking that mutation just doesn’t really allow us to do. You have to do a lot of work to work around.

One of those — I think it’s the best example — is to think about counterfactuals. Let’s say, we do have a real current state. This is the state of the system. The state of whatever thing, entity we’re representing, whatever it is.

We want to ask, “What would this thing look like after I receive this event? I haven’t received it, but what would it look like if I did?” That’s a lot like what a test is. It’s a counterfactual.

It’s not an actual production data. It’s not an actual production event, but we’re asking, “What happens in the system when I do this, and I expect it to look like this?” It’s a test. It’s often also very useful in your production system.

What would happen if I sent it 10,000 of these events? Would it overflow? One thing I did as an example is I had a state of the current screen. This is all the information you need for the screen, including the title of that screen and what back button to have on the top.

How did I figure out what label the back button would have? It didn’t just say back. It had the title of the previous screen. I actually ran the behavior function with the current screen and the back button event.

Then I would get back the next screen, which was the new screen, which was the back screen. I didn’t change the actual screen. It’s just the state. Then I can read off the title from there.

These are the things that become just easy when you’re dealing with pure functions. You’ve defined your behavior in your functions. You can imagine me doing it a different way, which would be the current screen has a mutable field called title. It has a mutable field called back button label.

I would have to go and set them manually from somewhere else and rely on the sequence of steps that got me there to calculate what each one should be. As opposed to representing the entire thing as data and then a behavior function.

This is the thing I’m working on for the book. I’ve been talking with my editor about not…I don’t want to reproduce a lot of the work out there. There’s a lot of good work actually on the functional programming in the small like how to do currying, how to make data transformation pipelines, map, filter, reduce, all those things.

Avoid getting down in the weeds there, but then what is there to talk about? I think it’s this kind of stuff. I’ve been reading books. No one is talking about using functions to model the behavior, which is something we do. It’s not like I’m making it up, but I’ve got a grip on it. I think it’s high-level enough to fit right in the book.

My name is Eric Normand. This is “Thoughts on Functional Programming.” If you want to get in touch with me, I love hearing from my listeners, answering questions. I’m @ericnormand on Twitter. You can also reach me over email, eric@lispcast.com. See you later.

The post How can pure functions represent state change? appeared first on LispCast.

Permalink

Public technical talks and slides

Over the years, I’ve put together a few public technical talks where the slides are accessible on this site. These are only really nice to view on desktop, and require the use of arrow keys to move around. Long-form notes are also available — generated by a sweet Sphinx and reStructuredText plugin. I figured I’d link to them all here so I don’t lose track:

Using even older slide software called S5, which is also based on reStructuredText, I also have a couple of Python training materials. I’ve given these materials as full-class trainings at various times, including a tutorial at PyCon on web development (the last link here).

Permalink

Parameterizing Datomic Ion Applications

Today's Datomic Cloud release provides an easy way to parameterize ion applications.

Rationale

At runtime, applications need access to configuration data such as the name of a Datomic database. There are several challenges to consider:

  • Configuration values have a lifecycle that is independent of application source code. They should not be hard-coded in the application, and should be managed separately from source code.
  • Applications need a way to obtain their configuration values at runtime.
  • Configuration values may be sensitive, and should not be stored or conveyed as plaintext.
Parameters are a solution to these challenges.

Ion Parameters

Before running your app, you store parameter values under hierarchical keys in AWS Systems Manager Parameter Store. At runtime, your app uses our new APIs to form the keys and read the values. This provides:
  • independent lifecycle for parameter values
  • encryption for sensitive data
  • granular IAM permissions

Get Started

To get started using Datomic's parameter support:

Permalink

Native/Browser SPA versions using ClojureScript and re-frame talk at SCBCN17

Last month I had the pleasure of giving a talk at the Software Craftsmanship Barcelona 2017 conference about what my colleague Francesc and I have been learning lately while working on the mobile and browser versions of a SPA using ClojureScript and re-frame.

I talked mainly about how re-frame's effects and coeffects, re-frame's subscriptions and modelling a UI as FSMs place you in a pit of success, i. e., a design that, according to Jeff Atwood, "makes it easy to do the right things and annoying (but not impossible) to do the wrong things".

It was my first talk in a big conference and I had some technical problems, so I was very nervous at the beginning. After a while I relaxed and felt better. In the end I received more questions than I expected and very nice feedback.

I'd like to thank Modesto for lending me his computer when mine crashed just before the talk and helping me relax.

This is the video of the talk, (thanks Autentia for recording all the talks and for being so kind to me when I was having technical difficulties). I hope you'll find it interesting:



and these are the slides that I've improved after the talk using Modesto's feedback (thanks!!): .

Thanks to Francesc and all the people in Clojure Developers Barcelona Group, Green Power Monitor and Codesai that contributed to improve the talk with their feedback. Also thanks to my colleague Antonio for "persuading" me to give a talk in a conference.

Finally, I'd also like to thank Software Craftsmanship Barcelona 2017 conference organizers for giving me the opportunity to talk at such a great conference and for all the effort they put to make this conference better, edition after edition.

Permalink

Not all watchers are created equal (or how to make yak shaving useful)

I’ve been hacking around with a Clojurescript project recently, and it resulted in a certain amount of yak shaving when I found the watcher system I was using was eating a lot of CPU. On the one hand, yak shaving is bad, because you’re doing other things that aren’t the core task you’d originally meant to do, but there are yaks and there are yaks. In my particular case, I try to make sure my yak shaving results in some improvements to open source projects I’m using and I’d like to encourage you to do the same (which technically makes this the 3rd in my series of “you should be contributing to open source” posts).

Some background first: ‘watchers’ are programs designed to ‘watch’ your source files and do something when they change e.g. run linters/test suites, reload source files in a server, hot-reload into a web browser, etc. They’re ubiquitous in a great many settings, especially for web work, but the linter/test suite case is useful for pretty much everything. There’s versions of them for most languages/frameworks out there, or they might even be built into your existing build tools, and I’d recommend their use for all development work these days.

There’s two core ways to build one: polling or event-based. Polling works by repeatedly checking modified times on files, and is easier to implement and more portable, but can end up being more CPU/IO-intensive especially with the fun trade-off between poll interval v.s. response time, which you want low enough to spot stuff earlier, but high enough to keep the overhead reasonable. Event-based options on the other hand work by asking the operating system to tell you about new changes. This is lightweight and fast, but needs OS-specific support. Most OSes have at least one option for this (epoll/inotify on Linux; ReadDirectoryChangesW on Windows; FSEvents on macOS, etc), but their models of what you can/can’t watch vary and have a tendency to get deprecated/replaced in later versions of an operating system.

I was using lein-auto to make some updates to my project (along with Figwheel which is another watcher in it’s own right), and this was fine until I Dockerised the project. Suddenly something was eating all my CPU even when nothing much was really happening. I eventually managed to narrow down the problem to lein-auto, which was rather surprising, until I read the source code and found out that it was using polling with a default 50ms interval. Apparently on a Mac, the Docker implementation and VM bits with a mounted volume mean that file system operations take a little bit longer than usual and so this was hammering my system.

Ok, let’s rewrite it with a watching implementation. Early work with this still appeared quite slow, and some searching later found me “Is Java 7 WatchService Slow for Anyone Else?” and a 6+ year old JDK bug basically just noting “polling is good enough for Macs, but we should look at this at some point for JDK 9” (for those keeping track, latest is JDK 10). Has anyone done better versions of this? Well, there’s the BarbaryWatchService which is an implementation of a very similar interface to the WatchService, but with proper FSEvents support. Sadly, this had bitrotted rather badly in the three years since it’s last commit, so I went through and fixed all of that, and hopefully the project will wake up at some point.

Of course, that wasn’t directly relevant since I was going to be running this process under Docker, and not directly running on a Mac at all, so I could just use the WatchService directly for my lein-auto changes. However, I’ve now (in the course of writing this) found a library called hawk that abstracts over both WatchService and BarbaryWatchService, although that has it’s own issues I might now have to have a look at as well.

Permalink

The Functional Style — Part 1

Functional programming is a very hot topic nowadays. People are increasingly interested in functional and hybrid-functional languages, such as Haskell, Scala, F#, and Clojure, and functional programming is one of the most popular requested topics for discussion in conferences and programming communities. Since you're reading this, maybe you are interested to find out more about it too; if so, this article series on functional style is meant for you. I have been motivated to write this because I feel that there is a need for more literature explaining how to program in the functional style. I want to illustrate this with helpful code examples and highlight some of the benefits from the functional style.

Functional programming is often discussed in very academic and mathematical terms, but I don't want to go there. That isn't how I learned it myself. I'm not a computer science graduate, and I was never formally taught it. I learned how to program at home, as many 90's adolescents did, and my learning has continued for more than 20 years with professional experience. Moreover, at no time have I ever felt like I knew everything I needed to know about functional programming. I have always been attentive to the current developments in my field and am keenly interested in its history. This series of articles is aimed at similar people — pragmatic programmers who love their field and learn best by writing code, who are humble enough to realize there is always more to learn, and practical enough to see the profit in doing so.

Permalink

Frontend Engineer, Clojurescript

Frontend Engineer, Clojurescript

Workframe | New York, NY

About Workframe

Workframe was founded in 2016 by Andy Parsons, Robert Moore, Matt Smith and Kevin Ryan (Double Click, Gilt, Business Insider, MongoDB, Zola). We're helmed by serial entrepreneurs, growing fast, and leveraging technology to revolutionize the commercial real estate (CRE) industry.

The Workframe team is eclectic, bringing its users a rapidly evolving platform that addresses challenges across the built environment. We are passionate business people, designers and engineers who thrive on delivering value to every CRE professional. Workframe's software as a service (SaaS) product drives efficient, space-centered communication and decision making across project teams and helps them derive insights and efficiency never before possible.

Our software enables tenants, landlords and brokers to navigate the CRE process from site selection to move-in using our innovative project management and visualization core technologies.

About the Role

We are seeking talented frontend software engineers to join us. Engineers on our team play a critical role in developing infrastructure, user-facing features and contributing to our development culture. We are enthusiastic participants in open source, stewarding the Artemis GraphQL client, among other projects. You will:

  • Work closely with the product and design team to get new features out fast
  • Build time-series and schedule visualizations
  • Learn and share functional programming techniques as we hone our tools and approaches
  • Attack hard UX problems
  • Help ensure uptime, performance and user experience are delivered without compromise

Our stack is:

  • Clojure/script
  • Storybook
  • React/Reagent/Re-frame
  • GraphQL
  • Datomic
  • AWS

We are proud to organize and host the Clojure NYC meetup group!

About You

At Workframe, we seek to hire outstanding individuals who embody our DESIGN principles: our people are Diligent, Engaged, Scrappy, Innovative, Genuine and Nurturing. You're a great fit if you enjoy tackling big problems head-on, take your work seriously (but not yourself), do your best when collaborating with others and thrive in a team-oriented environment.

Qualifications and Requirements

  • 2-5 years or more of software engineering experience
  • Exceptional communication and interpersonal skills
  • Love, or at least deep affection for functional programming
  • Ability to think on your feet and express yourself in code
  • Prior startup experience where rapid prototyping is balanced with solid, scalable platform engineering
  • Ability to thrive in a (lowercase) agile environment guided by just-enough process
  • Passion for quality software, techniques and processes to accomplish continuous improvement

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.