I pushed a new validation library for clojure to github yesterday. Check out clj-decline.
Why another validation library?
Well, why does validation suck so much?
Of course, dealing with user input is annoying anyway. But validation libraries always seem to want to do things in just the wrong way for the project you’re working on.
Let me count the ways:
- Also, validation does not mean “force this input into another type”. That’s not validation. Stick it somewhere else.
- They assume too much. If you can only validate a single value in a map, you’re useless. I need to check if a frobniz has either two wheebles or an odd number of crinks, and don’t try to stop me.
- I might need to validate something that isn’t a map. Maybe I want to check two maps. Maybe I need to check a single string or a file upload.
- They still assume too much. This may come as a shock, but not everyone speaks English on this planet. I have to support multiple languages in the same web app. Give me more options than pre-defined strings for errors, you lousy piece of American imperialist software! People of the earth, throw off your shackles and your “reality” TV shows!
- Macros, macros, macros all over the place. Yes, macros are cool, but no, I don’t want to stick every validation in a named var. If I wanted that, I could (def some-name (make-validation …)) so I don’t need your macro anyway. I want to use closures that validate for this specific user and now you’ve stopped me.
- Don’t be passive agressive. Validation is a user-centric feature. If I wanted to tell the user only their first error, I’d use exceptions. Don’t force the user to submit their form twenty times until they’ve fixed all their mistakes. Give them as much information as possible so they know what’s going on.
So, how does clj-decline fix all that?
It doesn’t. It just stays away from most of the above. clj-decline is simple. It validates arguments and returns errors. Everything else is up to the user or some other library. It’s completely functional, has no macros, no built-in predicates, nothing binds it to a web framework or anything else, and errors / messages can be anything you like. The only decision I made is that errors are grouped by key (which can also be anything you like).
< Functional Clojure >
I’ll be doing a short presentation on the basic higher-order (sequence) functions in clojure.core at the Amsterdam Clojurians meeting next Wednesday. This talk should be understandable and useful for Clojure newbies. If you’re interested, just show up around 7.
Update: quite a few people showed up to the meeting. I’ve put the slides on github, and here is the elisp code I used to present the slides.
This is part of the series on SLIME functions. See the introduction for information on what SLIME is.
Another very short post.
Now what is the name of that function again? Which namespace contains that variable?
slime-apropos; Default key-binding:
C-c C-d C-a and type the part of the name you remember and SLIME will list all matching globals/symbols in the running program.
I’ve forked off ring.middleware.multipart-params into a new library called ring.middleware.upload-progress
It’s a bit rough-and-ready for now, and it uses the session to store the shared state about current uploads, which is probably not the best way to go about it – I’m thinking about introducing a new lower-level mechanism for low-memory shared state based on clojure’s STM tools, since this kind of thing is interesting for more than just uploads – but it does work as long as you’re not doing anything too fancy (if you’re worried, you can use a separate session store just for this info).
For the interested: the code is at github.
I’ll get a clojars release done as soon as I’m satisfied this stuff is usable. Probably in the next few days.
I just released a few bits of image code that might be useful to more people.
clj-imajine can read, write and scale images. There’s also some minimal experimental pdf support. More features will be added when I need them or if someone else sends me a good pull request.
Also, Saul Hazledine got in touch with me to merge our changes of
clojure.contrib.sql and make it an official project. It’s called
clj-sql and differs from
clojure.contrib.sql mostly in that it makes it possible to use
:keywords-with-dashes as column names (for most operations, at least, so far) and that its support for auto-generated keys is much better, i.e. there is some!
By far the oldest board in this series. Production of these things started in 1985 and slightly modified versions are still being build by Unicomp (the Customizers are the closest to the standard IBM Model M, but always make sure you pick the Buckling Spring versions, see below).
I’ve been using a Model M keyboard for the last couple of years, and in many respects it’s the best keyboard I’ve ever used: it’s very sturdy, will last for decades (mine is 15 years old and still working fine) and the key switches are phenomenal.
This was one of the first keyboards with what’s now more or less the standard PC layout and it’s probably the reason that that layout became so popular. Probably not remarkable – even boring – these days, but on the whole it’s very well thought out and effective. Especially if you map the CAPS Lock key to Control (Unicomp sells models with CAPS and Left-CTRL swapped, but you can swap the keys on any OS and I don’t really see the point of looking at a keyboard when you’re typing on it).
Buckling Spring switch technology
The switches work via a so called “buckling spring” mechanism, which means every key is set on top of a fairly long spring that “collapses” sideways when you’ve pressed the key about half way down and activates the mechanical “hammer” attached to the bottom of the spring. You can easily feel when that is about to happen, and once it does you can feel the key “give” and it makes a very satisfying CLICK sound.
On this keyboard you simply can’t get fooled about whether you’ve pressed a key or not: the auditory and tactile feedback is very immediate.
As you can probably tell, I really like this keyboard, but there a few issues with it that are annoying:
This is a large keyboard, even for a full size standard layout: the MS Natural 4000 has a big wrist rest and a “split” main cluster and it’s still only marginally larger than the Model M.
Size is especially important if you’re a right handed mouse user. With the num-pad to the right, your mouse is quite a long way away from the main alphanumeric cluster where your hands are when you’re typing, which means that you’re not always using an optimal position for the mouse, the keyboard or both. You can tell these things were invented before PCs had mice.
There used to be Model M variants that didn’t have a numeric key pad, but production of those stopped somewhere in the early ’90s. Expect them to be expensive – if you can find one. Ebay US seems to have a few, but once you include shipping, you might want to consider something else if you live in Europe. Clickykeyboards (where that link is to) sells them for fairly reasonable prices, but they don’t seem to have them all that often – and you still have to pay shipping from the US.
The switches on these keyboards are very good, but also quite heavy: they require noticeably more force than most conventional keyboards. You get used to it, especially since the force is consistent over all keys, but for me, it’s just barely on the edge of “too heavy”.
The click sound, while satisfying, can get on your nerves late at night. Not that much of an issue for me, but sometimes you just wish it made a bit less noise. If you have coworkers or family in the same room, I expect they won’t like this keyboard much.
On the other hand, second hand full-size Model Ms are cheap and not that hard to get. New ones from Unicomp are also very competitively priced compared to other well-built keyboards with mechanical switches (the basic model is $69), even if you have to ship them across the Atlantic.
Previous episode: In search of a better keyboard – Early history.
Next episode: what now? (not finished, stay tuned).
When you’re typing as much as I do, sooner or later you realize that having a good keyboard is important. Years ago I was having issues with wrist-pain and switching keyboards was – for me – a very effective way of almost eliminating the problem.
But this is not about health issues directly. What I found is that the best way to stay healthy while working is to keep irritation to a minumum, and keyboards can do a lot of things that are just plainly annoying:
- Keys in wierd and/or hard to reach places
- Keys in half-size
- Keys that only work most of the time
- Keys that are much harder to press than the others
Looking at that list, there are two main things that can go wrong: keyboard layout and the key switch technology. I’m going to address both throughout this short series.
I’m going to present the main keyboards I’ve used in chronological order (that is; order that I used them), but I’m ignoring the very early stuff. Some were not that good (Commodore 64), some were horrible (Atari 400, I’m not even sure if I’d call that thing you’ve got a keyboard) and some were pretty nice (like the Amiga 500). My focus is on keyboards that are still available and useful to today’s PC or Mac user.
As an example of frustrating design, I present:
The MS Natural Elite
All in all it’s not a bad board; they’re cheap and they’re fairly pleasant to type on with light-weight keys, but all the navigation keys are in half-size AND in non-standard places (and yet close enough to the standard locations to get really confusing). Get used to pressing INSERT instead of END and fumbling for the cursor keys. Bad, ugly and unnessessary. Also, in my experience, they break after 3 years or so.
The MS Natural 4000
The successor to the Elite that solved most of the issues with the layout, but the modifier keys and especially the space bar were so heavy I found myself slamming my thumbs on them which can’t be good.
The extras, like the horrible multimedia “keys” and the vertical “joystick” or whatever that thing is, I won’t further address, since I never used them.
Also, it broke down after only a year. Not good at all for a keyboard that cost about 60 euros at the time.
By now I was getting frustrated by key switches, and I wanted something that would actually let me type in a consistent way and KNOW that I was really pressing a key when I thought I was, without me having to slam every one of them into the ground.
Which brings me to the next post: In search of a better keyboard; The IBM Model M.
This is part of the series on SLIME functions. See the introduction for information on what SLIME is.
Just a short post today.
slime-who-calls function (default binding “C-c C-w c”) lists every function that calls the given function (default argument is the symbol under the cursor). You can press ENTER on that list to go to the listed definition. Beats using M-x rgrep for convenience, but – at least with Clojure code – it doesn’t catch every call; second-order function calls aren’t caught.
For those readers using Clojure, you need a pretty recent version of swank-clojure for this to work – and it seems to also list function definitions with the same name as the argument, which I think isn’t correct.
As I noted in yesterday’s post,
slime-complete-symbol normally doesn’t complete locally bound “variables” (that is, function arguments and let bindings).
I’ve created a SLIME extension that does a pretty rough scan of the current top-level form and adds all the matching symbols in the form into the list of suggested completions. If you want to check it out, slime-complete-locals is available on github.
Also, if you missed the update on yesterday’s post, make sure you add the right forms to
smart-tab-completion-functions-alist – the key in that alist should be the MAJOR mode. So using slime-mode (like I did yesterday) will not work. It must be clojure-mode or whatever the major mode for your lisp editing is.