Thursday, October 23, 2014

Art Between a Rock and a Hard Place

Next time you're visiting Bluemont Park in Arlington (perhaps to take in a round of Disc Golf, or maybe you're in search of a healthy vending machine snack), take some time to track down J.W. Mahoney's Named Stones art project. When you find it, you'll see a sign with this description:

Arlington artist J.W. Mahoney was one of four sculptors to participate in Onsite: '89: Bluemont Park Sculpture Project, a temporary outdoor sculpture exhibition. Although intended to be temporary, Mahoney’s work, Named Stones, which consists of eight rocks into which words are engraved, endures.

For a temporary art project, choosing to carve in stone was certainly an intriguing choice. Fortunately, most of the rocks are still there and in quite good condition. I ran by Amor and Psyche yesterday and grabbed a few pictures.

I love the relatively camouflaged nature of the project and how it leads to a sense of discovery when you realize what you thought were random rocks are in fact anything but.

Go, track them down. Here's Amor to whet your whistle.

Brain Candy v2.0 - Looking for a Creepiness Check

Two years ago I had a Halloween idea: why not hand out Play-Doh along with candy. The hope would be that this brain candy would foster creativity, versus just fostering cavities. To round out the idea, I thought I'd setup a photo upload site so folks could anonymously share their creations. Like most of my half baked ideas, it went nowhere.

And then, a few weeks ago I was walking through Wegmans and came across this offering from Play-Doh:

They just dropped this idea back in my lap.

So, I took up the cause again. Rather than an obscure tumblr address I went all out and registered sharemycreation.com. I'm still using the Tumblr platform though, as it makes it trivial to take in anonymous picture submissions. Finally, I printed off some labels with the hope of inspiring and explaining the project. Here's what I've ended up with:

I think the odds of anyone actually sharing any pictures of their creations are miniscule, but I just have to put it out there.

I still have a few days to reconsider this little project. What do you think? Have I crossed the line into creepiness? Or will parents see this as a harmless / fun diversion?

By the way, I intentionally kept the site and labels pretty vague, figuring I could hand them out in other contexts besides Halloween. Heck, maybe I could drop some off in the various improvised libraries around town, or just setup my own little Creativity Library. Yeah, how could that fail?

Finally, I've got to send some praise to Avery.com, the company that makes the labels I used. They have an online app that allowed me to create and print off the labels all without me leaving my web browser (and most importantly, without me having to fire up MS-Word).

Caption Me, Rucksack Edition

I managed to grab a snapshot of this group (troop? platoon? patrol? congregation? coalition? quiver? bevy?) of soldiers humping it down Columbia Pike at around 6:45am. This is crying out for a caption, no?

Wednesday, October 22, 2014

All Dressed Up For A Worthy Cause

This past weekend we attended the Arlington Free Clinic Gala, a cause we like to champion. It was held at the National Building Museum, which is quite the venue (as I always say: if it was good enough for Grover Cleveland's Inaugural Ball, it's good enough for me!). But the true star of the evening was my stunning wife.

Tuesday, October 21, 2014

Ancient Laptops and being a Heroic Boyfriend - Text Formatting inspired Stories

You might think a topic like text formatting would be pretty bland. Not so! I have not one, but two stories inspired by the topic. Allow me to share.

I can remember it vividly: I'm 13 years old and working away on my very own laptop. Specifically, a NEC PC-8500, with a whopping 64K (yes kilobytes!) of RAM. I'm typing up an essay for school in the WordStar word processor and having a heck of a time. Specifically, the paragraphs are all askew, with some lines being shorter than others. In the end, I'm left fighting with the computer trying to get the different lines to have somewhat equal length. What a pain.

Looking back, I was running into a fairly classic text formatting problem. Either WordStar had automatic word wrap and I was defeating it by hitting enter at the end of some lines, or it had a manual function to refill paragraphs that I didn't know how to operate. All I know is, this is one of my earliest memories of software appearing to be buggy, but actually performing as designed. Little did I know that I'd pretty much make this fight my life's work by becoming a programmer. Now, on a nearly daily basis I look at software and think "hmmm, it can't possibly be behaving that way...." And yet, it almost always is. And usually it's my fault!

Fast forward from middle school to college for the second story. I'm on Unix Talk with my long-distance girlfriend, and she starts telling me about the arduous task in front of her. She's manually re-formating a massive final lab report. It's taking her forever to adjust each line to the right length. I finally convince her to send me a copy. A minute or two later she receives it back, perfectly formatted. How'd I work this bit magic? Why thanks to the Unix fmt command.

You may be thinking, big deal, you formatted some text. Turns out, it was a big deal. That girlfriend is now my wife of almost 16 17 years. And when I started describing the story a few days ago, she immediately started mentioning details I'd forgotten. That little bit of unix-manship, is probably in the top 10 list of amazing things I've done for my wife. Never underestimate the power of the command line.

In honor of both those stories, I give you a Scheme implementation of fmt. Incidentally, this answers the first part of the Programming-Praxis Challenge, I've still got the second part to complete.

; http://programmingpraxis.com/2014/10/07/text-formatting/

(define (empty? str)
  (= (string-length str) 0))

(define (++ . args)
  (apply string-append
         (map 
           (lambda (any)
             (cond ((string? any) any)
                   ((number? any) (number->string any))
                   ((char? any) (string any))))
         args)))

(define (g options key . default)
  (cond ((assoc key options) => cdr)
        (else (if (null? default)
                  (error "Missing default: " key options)
                  (car default)))))
            
(define (read-token port)
  (let loop ((buffer ""))
    (let ((c (peek-char port)))
      (cond ((eof-object? c)
             (if (empty? buffer)
                 (cons 'eof (read-char port))
                 (cons 'word buffer)))
            ((equal? c #\newline)
             (if (empty? buffer)
                 (cons 'newline (read-char port))
                 (cons 'word buffer)))
            ((equal? c #\space)
             (if (empty? buffer)
                 (begin (read-char port) (loop buffer))
                 (begin (read-char port) (cons 'word buffer))))
            (else
              (loop (++ buffer (read-char port))))))))

(define (output line port opts)
  (let* ((width (g opts 'width 60))
         (align (g opts 'align 'left))
         (delta (- width (string-length line))))
    (case align
      ((left) (display line port))
      ((right)
       (display (make-string delta #\space) port)
       (display line port))
      ((center)
       (display (make-string (floor (/ delta 2)) #\space) port)
       (display line port)))
    (newline port)))
    
(define (handle-word word buffer out width loop opts)
 (let ((line (if (empty? buffer) "" (++ buffer " "))))
   (if (> (string-length (++ line word)) width)
       (begin
         (output buffer out opts)
         (loop word))
       (begin
         (loop (++ line word))))))


(define (fmt in out opts)
  (call-with-input-file in
    (lambda (pin)
      (call-with-output-file out
        (lambda (pout)
          (format pin pout opts))))))

(define (format in out opts)
  (let ((width (g opts 'width 60)))
    (let loop ((buffer ""))
      (let ((next (read-token in)))
        (case (car next)
          ((eof) (output buffer out opts))
          ((word)
           (handle-word (cdr next) buffer out width loop opts))
          ((newline)
           (let ((peek (read-token in)))
             (case (car peek)
               ((newline)
                (output  buffer out opts)
                (newline out)
                (loop ""))
               ((eof) (output buffer out opts))
               ((word)
                (handle-word (cdr peek) buffer out width loop opts))
               (else (error "Unknown peek token:" peek)))))
          (else (error "Unknown token:" next)))))))

(define in "/sdcard/Documents/input.txt")
(define out  "/sdcard/Documents/output.txt")
(define opts '((width . 30)))

(define (range low high)
  (let loop ((i low) (result '()))
    (if (> i high) (reverse result)
        (loop (+ 1 i) (cons i result)))))

(define-macro (repeat qty . body)
  `(for-each 
    (lambda (i) ,@body) (range 1 ,qty)))

Monday, October 20, 2014

What I Learned on The Trail

This marker wasn't intended to report the distance to the nearest bathroom, as I assumed. But was used to report the distance to Washington City. Or as most of us know it, Washington, D.C.

This graffiti wasn't authored by a fan of poetry, as I assumed to be the case. Instead, it was authored by a fan of Dave Mathews.

I can't find any evidence on the web (so it must not be true, right?), but didn't doors stamped with the word 'Globe' appear on the back of school buses? (As say, built by the Sheller-Globe Corp). If so, why would a door end up in the woods, off of 4 Mile Run?

And here are a few more photos I've snapped within the last week or so. Some are from the C & O Canal, and some are from 4 Mile Run.

Why Macros Matter

Imagine you're a Senior Developer at Big Co and while reviewing Junior Programmer Jimmy's latest set of check-ins you see the following code repeated a handful of times:

  return '$' + 
         new BigDecimal(value).
          setScale(2, BigDecimal.ROUND_HALF_UP).
          toPlainString();

You pull Jimmy aside and explain that the above should really be packed into a function (or method) rather than being written out long hand. In other words, it should read:

  return Format.money(value);

You explain that by doing this Jimmy and the team will gain at least three benefits:

  1. Fewer Bugs. Not only is the function call above shorter, but there's no chance to accidentally forget part of it, or put an erroneous value in place (for example, pass 3 to setScale). And if there was a typo, such as Format.mony, you'd get a clear error message rather than just an oddly formatted value.
  2. Clearer Code. In the original version of the code, the reader has to think in terms of numeric and string operations. If the programmer wasn't familiar with BigDecimal, they might have to open up the docs to see how it's used. In the more compact form, the intention is clear: a value is being prepared for display to a human.
  3. Easier Maintenance. From a maintenance perspective, having the code wrapped up in a single location means that it can be fixed or improved upon with ease. Let's say negative values should be rendered with parenthesis around the value. Making this change to Format.money is trivial, do a find a replace throughout a massive code base, no so much.

Finally, you explain to Jimmy that if he ever finds himself copying and pasting code around alarm bells should sound in his head and he should make the appropriate abstraction.

As an aside, the above can be considered a procedural abstraction. Naturally, programmers love them (and for their sanity, need them!). So much so, in fact, that even if a language doesn't provide an official mechanism for creating procedural abstractions (assembly language perhaps? Old school BASIC?), a clever programmer will find a way to simulate them. Sure, this facility may depend on GOTO and global variables, and it may be fragile and error prone, but it will get the job done.

A few weeks later, Jimmy comes bursting into your office. He eagerly explains that he paid attention to what you suggested and has come across a abstraction that the team should adopt. If they do so, thousands of lines of code will be cleaned up. He goes to the whiteboard to explain. Rather than coding like so:

  private int foo;
  public int getFoo() {
    return foo;
  }
  public void setFoo(int _foo) {
    this.foo = _foo;
  }

The team should write:

  property(int, foo);

After all, he explains, you'll get the same 3 benefits as above, though on a larger scale because we use this pattern all over the place.

You're then left with the unfortunate task of explaining to Jimmy that while he's right, it's not so simple. Yes, they should create such an abstraction, but their language of choice (in this case, Java, Circa 2000) doesn't allow for this. That's because what's called for here is a syntatic abstraction rather than a procedural one. In fact, very few languages give you this capability.

Still, programmers are a clever bunch. Just like our Geek Forefathers and Foremothers who made do before reliable procedural abstraction, those lacking syntactic abstraction will find a way. In Java, for example, the above problem may be solved by using the Eclipse to generate the code. In PHP, you could simulate the above using property overloading. And when all else fails, you could run your source code through GNU m4. However, at the end of the day, these methods are all relatively fragile when compared to true syntactic abstractions.

And what language provides such a capability? Why, Scheme does, and the facility goes by the innocuous sounding name macros.

Learn Scheme. Learn Macros. Learn what you've been missing out on.

Thanks to Grant for helping motivate me to write this post.

Wednesday, October 15, 2014

Gotcha of the Day: Creating macros from within Gambit Scheme on Android

One of the most powerful features of Scheme is the ability to create macros. That is, along with the procedural abstractions most languages allow you to create, you can also create syntactical ones (I've got at least one blog post worth of stuff to say about this, so I dare you to ask me more!). While working on a Scheme Challenge on my cell phone, I wanted a quick way to repeat some code. Specifically, something along the lines of:

 (repeat 10
   (display (read-token in)))

(That is, I wanted to read and print the next 10 tokens from the input port in)

This is an easy enough macro to write in syntax-rules so I got to work. I quickly ran into an issue: define-syntax wasn't defined in the Gambit instance I was using. I tried a few other guesses and finally gave up, figuring I'd poke around the manual when I had a chance.

Sure enough, the manual had an explanation: define-macro is available by default, whereas define-syntax requires an add on module. While I'm no fan of define-macro, for my purposes it would work fine. I went ahead and put the following in ex1.scm, the file containing my answer to the exercise I was working on:

(define (range low high)
  (let loop ((i low) (result '()))
    (if (> i high)
        (reverse result)
        (loop (+ 1 i) (cons i result)))))
        
(define-macro (repeat qty . body)
  `(for-each (lambda (i) ,@body) (range 1 ,qty)))

I then ran my (lex) procedure from the REPL. To my surprise, the file loaded.

I then went to test my code:

(repeat 10 (display i) (newline))

To which the interpreter rudely responded:

*** ERROR IN (stdin)@2.2 -- Unbound variable: repeat

What the heck?

After a couple of more attempts I realized that I could use repeat within ex1.scm, but any attempt to use it from the REPL resulted in an unbound variable. When in doubt, read (or in my case, re-re-read) the manual. Which explains:

The scope of a local macro definition extends from the definition to the end of the body of the surrounding binding construct. Macros defined at the top level of a Scheme module are only visible in that module. To have access to the macro definitions contained in a file, that file must be included using the include special form. Macros which are visible from the REPL are also visible during the compilation of Scheme source files.

(Emphasis added by me)

I updated my (lex) procedure to be defined as:

 (define (lex)
  (include "/sdcard/Documents/ex1.scm"))

And what do you know, it worked! The REPL can now see and use the repeat macro.

In the future, I may mess around with loading the syntax-case facility into Gambit. This actually doesn't look like a particularly hard thing to do, I just know that when I attempted to load this file my phone churned on it for quite a while before returning an error. That makes me think this may be asking for a bit much from my Android. Regardless, define-macro gives me plenty of power, and I'm using it on a small enough scale that its unhygienic nature shouldn't do too much damage (famous last words, right?).

Finally, two other useful bits of info if you're playing around with the Gambit REPL on Android:

1) If you hit run next to the "Start REPL Server" example you can use a program like netcat to connect to the REPL for your laptop. This let me fiddle around with Gambit on my phone while using my laptop's keyboard and display. This is a classic trick, but one that never ceases to amaze me when I use it.

2) If you type ,? at the REPL prompt you'll gain access to a number of debugging commands. I haven't quite figured out the various "REPL levels" yet (that is, what's meant when you have an error and Gambit changes the prompt to 2>). But I now know I can jump to the top level by typing ,t.

Tuesday, October 14, 2014

The Running Shoes I Want vs. The Running Shoes I Need

My dream pair of running shoes are minimalist, ultralight, highly breathable and as long as I'm making demands, affordable. Thing is, I own these shoes and to be perfectly blunt, they're awful. Problem is, they deliver on the promise they make: running with them is like running barefoot. Running barefoot is great. That is until you land on a tiny sharp stone. You know, the kind that your buddy in Nikes doesn't even notice. Depending on the size and shape of the rock, the result is somewhere between painful and dangerous.

So while I still keep an eye out for times when I can run in my ultralights, I knew I needed a sturdier shoe for both road and trail running. Enter the Merrell Men's Ascend Glove running shoe. It promised to be a minimal running shoe that was also trail friendly.

The Merrell's arrived and didn't strike me as being particular 'minimal.' Sure, they seemed relatively lightweight, and they have the 0mm drop between the heal and toe going for them. But still, I was skeptical.

I've now taken them out on multiple runs, walks and even used them to climb Old Rag. Any concerns I have, have since evaporated. I'm officially impressed.

The Merrell's are comfortable to run in and the mesh top provides noticeable breathability. I suppose they aren't ultralight, but they're certainly far lighter than Shira's trail runners. Most importantly, the soles are protective enough to let me tackle any terrain I want. From a rocky path to the construction zone at the end of our street, I no longer have to feel like I'm running through a mine field while out for a jog. They Just Work.

In the end, the 'Ascend Glove' appears to be the right balance of lightweight and minimal construction that I want, and the protection and functionality that I need.

Monday, October 13, 2014

Taking a Bite Out of Rochester

This past weekend Shira and I visited family in Rochester. Sunday arrived and we weren't quite sure what activity would work for everyone. After a bit of research, Shira suggested the Annual Apple Tasting Tour, an event nobody in the family had ever heard of. The goal is to visit a bunch of apple farms in the area (specifically in Wayne County) and, well, taste the apples. We figured the scenery alone would be worth the trip. So, we all crammed in the car and off we went.

We ended up making it to two farms and a distillery (more on that in a minute). For once, Rochester weather cooperated, and we were treated to a perfect fall day. Slightly crisp but with lots of sunshine. The apples were quite tasty, and the foliage along the way was downright stunning. While the notion of heading off to Wayne County evoked images of trekking out in the wilderness, it was actually all of about a 25 minute drive. It continues to amaze me how little of the Rochester area I've seen, even though I grew up there (or perhaps, because I grew up there).

An unexpected find in the area was Apple County Spirits, a distillery that specializes in fruit based spirits. They offered tastings of various hard ciders as well as an Apple Vodka and a couple of other hard alcohol choices; one from apples and one from pears. My Mom, whose favorite drink is hard cider, was in heaven. And then there's this thought: when Passover rolls around, most hard alcohol is off the menu because it contains grain. But these varieties come from fruit! With the right certification, they could be the perfect Passover option. Not to mention, without grain, they are gluten free. Regardless, my parents and I quite enjoyed the distillery.

We made one other stop along the way, though this one wasn't on the Tasting Tour. We stopped by our childhood Buddy, Aaron's house, which happens to be just a couple of miles from the farms we were visiting. It was a huge treat getting to catch up with him, and I'm still trying to fully process the fact that not only does he have a 2 story former barn as a garage and a riding lawnmower, but he's got chickens in the backyard! He even gave us a dozen fresh eggs to drive home the point. I'm impressed!

All in all, everyone had a great time. Apples were tasted, alcohol was drunk and I got to take lots of photos. It was a perfect day!

View Photos

LinkWithin

Related Posts with Thumbnails