image

How does Gilt create connections with our millions of customers around the world? What is the difference between “personalization at Gilt” and “Gilt personae”? Who is “the Gilt customer,” and how does the Gilt team identify him and her? And how has Gilt used A/B testing to better serve our customers? Gilt CIO Steve Jacobs will address these and many other questions as the featured speaker of the NJ Tech Meetup's July 22 event!

As the C-level exec responsible for overseeing Gilt’s technology and product execution and strategy, Steve knows more about our technology infrastructure and day-to-day operations than almost anyone else at the company. If you’ve ever wanted to know more about the philosophy and thought processes behind Gilt’s great product features and offers, you don’t want to miss this talk!

With +3700 members, the NJ Tech Meetup is one of the largest and most active tech meetup groups in the NYC metro area. Tuesday’s event takes place at the Babbio Center at Stevens Institute of Technology in Hoboken, NJ and starts at 6:45 PM; just go here to RSVP. Hope to see you there!

Here’s Typesafe Senior Software Engineer/Scala In Depth author Josh Suereth earlier this week at Gilt’s NYC office, teaching his sbt workshop. Josh spent more than two hours covering settings, configurations, dependency management, and other topics. More than 50 non-Gilt technologists from the metro NYC area joined members of our engineering team for dinner and the class.

If you’re curious about sbt but couldn’t attend the workshop, check out Josh’s presentation from the 2014 Northeast Scala Symposium:

In addition to being Principal Systems Engineer at Gilt, Jonathan Leibiusky is also the creator of Jedis: the open-source, super-popular Redis Java client. Next Monday (July 21) Jon will present a talk on Jedis and Redis at the NYC Java Meetup Group’s July meetup, hosted at our NYC office. Jonathan will explain what Redis is, show the many different available data structures for Redis, and demonstrate how to use them from Jedis. He will also explain how to can build a Redis cluster (which is how Redis scales) and explain some of the recent updates he’s made to the Jedis project.

This will be a great tech talk! To RSVP, just go here.

image

Tonight marks the debut of Metis: Data Science, a brand-new meetup group for aspiring and practicing data scientists in NYC, and #gilttech is excited to be a part of it! Gilt Principal Data Scientist Igor Elbert will join Nell Thomas, Director of the Data Analyst Team at Etsy, and New York Times Graphics Editor Kevin Quealy in discussing their personal “data science passion projects and accomplishments.” Titled “Unleashing Data Science: Speakers, Food and Drinks,” the meetup takes place at Metis New York (79 Madison Ave. 3rd Floor) and begins at 6 PM; to RSVP, just go here!

image

#gilttech is excited and honored to host a talk by W. Eric L. Grimson PhD, the Chancellor for Academic Advancement at the Massachusetts Institute of Technology! On Thursday, July 17, we will present “MIT: Under the Dome,” an interactive discussion with Chancellor Grimson that will include a brief history of MIT and the breadth of the Institute’s impact around the world. Chancellor Grimson will also address MIT’s intention to liberate human potential for innovation, on campus and worldwide.

In addition to being an MIT faculty member since 1984 and a past chancellor (2011-2013), Chancellor Grimson has also served as Head of MIT’s Department of Electrical Engineering and Computer Science (2005-2011) and is a member of the school’s Computer Vision Group (Computer Science and Artificial Intelligence Laboratory), among other distinctions. He championed MITx and the formation of the Office of Digital Learning; teaches 6.00x, one of the first MITx courses, to more than 200,000 registrants; and has served as thesis supervisor to approximately 50 MIT PhDs.

Whether you’re a software engineer, a computer science student or just curious about the latest innovations underway at one of the world’s most elite academic institutions, this event will be a don’t-miss! Gilt’s NYC office will host the event; doors open at 6:30 PM. To RSVP, just go here.

Photo by Dominick Reuter, 2011

#gilttech’s excited to announce that Roland Tritsch will be the featured speaker at the next Dublin Scala Users Group meetup! Roland, who is Director of Business & Application Services at Fujitsu UK and Ireland, will present “Scala, Android & Bluetooth Low Energy: How to Make It All Work Together?" He’ll show us how to build Scala apps for Android and will then introduce the Scaloid framework as a way to do Scala development “the Scala way” on Android. As part of the presentation, we will build a simple BLE scanner (looking for beacons).

Roland has more than 25 years of experience building, running and fixing software engineering organisations and large distributed systems. His background includes positions at IONA Technologies, Gilt and HP. He likes computers, software and cycling, and these days is most interested in finding ways to make the “Internet of Things” work.

Roland’s an excellent speaker and teacher—we have first-hand knowledge of this!—so this will be a don’t-miss. Go here to RSVP!

More than 90 Dublin technologists came out to Docker Dublin’s inaugural meetup, co-organized by Gilt! Here’s Docker Dublin founder/organizer John Zanchetta kicking off the event:

image

And here’s Gilt Co-Founder and CTO Michael Bryzek, the main presenter of the night, describing how our engineering team has been using Docker and AWS to deliver immutable software releases to production:

image

The Docker Dublin group has tons of potential, and we’re very excited to be working with John to help the group expand. If you’d like to give a talk at an upcoming meetup, please send an email (include your suggested topic) via the DD meetup page. Then follow the group’s Twitter account to receive news and updates!

In making Gilt.com responsive to the mobile device, the Special Ops team identified several responsive patterns that we relied upon to “responsivize” our site layout. Identifying these patterns early on helped us to more confidently make subsequent responsive-related decisions. For our fourth responsive-related blog post, I would like to share how we discovered and implemented one of our favorite design patterns that we identified: the full-screen modal.

The Gilt iPhone app was the primary source of responsive design inspiration for our team. One of our iPhone app’s strongest design elements is its full-screen view for filtering, which differs greatly from the filtering layout on Gilt.com where filtering exists as a set of dropdowns on the sale page and a sticky sidebar on the search page.

The app’s filtering:

image.png

Gilt.com’s filtering:

Screen Shot 2014-07-08 at 5.08.21 PM.png

The full Gilt site’s filtering style fits well on both PC and tablet-sized screens, but is too large for mobile devices. This is one of the reasons our current mobile site (m.gilt.com) does not give users the filtering feature. With this in mind, our team emulated the Gilt iPhone app’s design by creating a full-screen view for filtering on mobile-sized screens. This pattern uses almost exclusively CSS (we use less.js) and therefore doesn’t add significant size to the pages’ payload.

Full-screen modal was simple to implement, so we decided to apply it in other places on the site—for example, in a product’s size chart. Here’s a JS Bin that demonstrates our implementation.

On narrow screens (a mobile device in landscape, for example) and tiny screens (a mobile device in portrait):

  •  Set the content’s wrapper element to
position: fixed
display: none

          by default, and set it to fit the entire screen

  • Add a call to action that’s visible only on narrow and tiny screens, and that, when clicked/touched, adds the class ‘content-open’ to either the content’s parent or to the content itself
  • Add CSS to display the content when the ‘content-open’ class is added
  • Add a no-scroll class to the body when the button is clicked that sets the whole page to
position: fixed

           this prevents the body from scrolling behind the open modal

  • Add a button/action in the open content modal which closes the content and returns the user to the full page

Special Ops believes that the best mobile user experiences permit users to focus on a page’s core content without being distracted by other features. With the full-screen modal, we abstracted away all the complexity of the filtering into a separate user experience and gave the abstracted feature the full-screen ‘real estate’ it deserves. Everything the user sees—a product, a list of products, etc.—is built around this simplified experience. Now that this pattern is well understood, we plan on continuing to use it in our future responsive design efforts.

Screen Shot 2014-07-06 at 11.07.35 AM.png

Screen Shot 2014-07-06 at 11.07.45 AM.png

In our last blog post on responsive design at Gilt, my colleague Greg Mazurek explained why we use in-selector CSS media-queries instead of blocks. The impetus for choosing this pattern was to make our code less brittle to future development. Today I’ll talk about how we’re applying the same principle to our testing practices.

We’ve thought a lot about how we can design our code to minimize—even prevent—unexpected adverse changes made during future development cycles. The Gilt engineering team uses automated testing for all of our apps, but in transitioning to a responsive design environment many of these tests have become inapplicable because page elements have been shifted, hidden, altered, or added. Furthermore, if a developer makes a change to a CSS property for a tablet experience, she needs to know whether this change might adversely affect the mobile web experience. A modified class name, a JavaScript side-effect, or a CSS specificity change are three possible negative consequences of such a change.

To deal with this potential problem, the Special Ops team has been writing Selenium-automated tests for responsive pages—more specifically, for each browser responsive breakpoint. (If you are unfamiliar with Selenium, it is a web testing framework that allows you to automate your web application within the browser. Its robust API interacts with your website the way a user would, and can handle automating most scenarios.) First, we have a browser resize itself to the breakpoint we want to test—for example, iPhones in portrait view fall under a maximum width of 479px, while in landscape its a minimum width of 480px, and a maximum width of 767px. With Selenium, via the web driver object, this is very easy to achieve.

Here is a small snippet of what that code might look like:

def resizeWindow(width: Int, height: Int)(implicit webDriver: WebDriver) = {
  webDriver.manage().window().setSize(new org.openqa.selenium.Dimension(width, height))
}

This reusable piece of code is what you’ll want to execute before the start of each test. Execute it before, not after, the initial page load, to ensure your site responds as it natively would at those breakpoints (rather than scaling your site down—which could cause inconsistencies with the view). Executing the code before the initial page load will also help you to ensure the automation doesn’t start before the browser has fully scaled down.

Example

To help you ensure that a page responds correctly to the appropriate viewport of the screen or device, here is a very basic test. It uses Selenium with ScalaTest and a dash of jQuery (there are many ways to test, but this is my preferred way):

describe("When resizing the browser to 479px and navigating to product listing page") {
  it("should fit all the elements within the 479px limit") {
    val expectedPageWidth = 479
    resizeWindow(width = expectedPageWidth, height = 800)
 
    webDriver.navigate().to("http://www.gilt.com/sale/men")
 
    // Using scrollWidth instead of width(), to get the true width of the html container
    val actualPageWidth = webDriver.asInstanceOf[JavascriptExecutor]
      .executeScript("return $('html')[0].scrollWidth;").asInstanceOf[Long]
 
    actualPageWidth.toInt should be <= expectedPageWidth
  }
}

(Note: Your page should not be scrollable to the right.)

That’s all there is to it. If you have no other test, at least this one will ensure your site is still responsive. But we highly recommend adding more specific tests that target the functionality of the site.

image

Lisp is an interesting language. Its emphasis on functional programming and properties such as homoiconicity make it quite different from other languages. Although it’s not suited for all developers, those who have experienced building large applications in other languages may appreciate the simplicity that Lisp provides.

When I ask other developers for their thoughts on Lisp, the most common response I receive is, “Why are there so many brackets?” As it turns out, Lisp’s brackets establish some consistency across the language that allows for some neat code-writing tricks. So neat, in fact, that they can make coding a Zen-like experience. Read these tips and you’ll soon be able to make onlookers wonder how you’re able to make code fly around the screen so quickly and elegantly—and with just a few keystrokes.

Lisp Refresher

For those of you who aren’t quite clear on Lisp syntax, here are a few basic things to know:

  • Everything is a list
  • The first element in every list is the “function call position”

That’s it! Easy, right? Let me show you a few examples written in Clojure (a dialect of Lisp) to make things more concrete. First, a standard “Hello World” example:


(println "Hello World")

In Clojure, you create lists by using rounded parentheses. The first element in this list is println, so we are calling a function called println with a single argument “Hello World”.

Next, we create a new function called inc:


(defn inc
  "Define a fn that increments a number by 1"
  [x] (+ x 1))

The first element (the one in function-call position) calls a special function called defn that allows us to create a new function. The other arguments are:

  • The name of the function we want to define—in this case, inc
  • A string comment that we can use as a human-readable description of what our function does
  • [x] is a vector of the arguments that our new function will receive
  • The body of our function

In this final example, we create a try-catch statement:


(try
  (/ 1 0)
  (catch ArithmeticException e (println "Kaboom!"))
  (finally (println "We’ve recovered!")))

We can start to see from this example how lists can be nested to provide richer programming capabilities. This nesting actually results in a tree structure (which in compilers is referred to as an ‘abstract syntax tree’) that provides the basis for some interesting coding workflows.

The Structure of Lisp

To illustrate what this abstract syntax tree looks like, let’s draw the try-catch example as a tree:
image
I’ve omitted the “finally” block to keep the illustration compact, but it should be clear now how we can visualize Lisp code as a tree. The workflow tips in this article revolve around making edits to this tree: navigating to parent nodes, moving a branch, removing levels, etc.

***I’ll provide these tips specifically for Vim, but there are equivalents in Emacs as well if you prefer that.***

Without further ado!

Tip #1: Give your brackets some color 

image

Rainbow Parentheses’ is a plugin for text editors that will change the color of your brackets depending on their depth in a list. This enables you to visually recognize the start and close of a particular list. Once we can visualize this, it becomes much easier to jump between depth levels.

In the above gif, the cursor starts inside the println then makes jumps upward to each parent node in the tree (println -> catch -> try). These jumps can be performed with the ParEdit plugin while in normal mode by pressing "(".

Tip #2: Keep your parens balanced

image

There’s nothing worse in Lisp than having unbalanced parentheses—especially if you have blocks of code that include several levels of nesting. Finding which block is missing a closing bracket can become a nightmare. Fortunately, ParEdit can prevent us from having this problem.

Say we have a try-catch-finally block and wish to delete the ‘finally’ clause. In Vim, we can easily remove this entire line when in normal mode by pressing ‘dd’. The problem is that if we do this, we will make our parentheses unbalanced by deleting the closing bracket of the try block (in the above gif, the closing red bracket).

The ParEdit plugin solves this by forcing our brackets to always remain balanced. With paredit enabled we can perform ‘dd’ to delete the line and delete everything except for any brackets necessary to maintain balance.

Tip #3: Learn motions. Master the brackets!

image

Vim provides motions right out of the box, with no additional plugins needed. The handiest motions for dealing with parentheses are “select in” and “select all.” These can perform actions on an entire list in just a few keystrokes. For example, say in our try-catch block we want to return positive infinity instead of print a message. Place the cursor inside the println list, issue a “select all,” and hit “c” for “change.” This will replace the entire println list in just three keystrokes.

Note that “select in” will select everything inside the parentheses, while “select all” will select everything inside the parentheses (including the parentheses themselves). This command will work with round brackets, curly brackets, square brackets and even quotations, making it useful in other non-Lisp languages as well.

Here’s a cheat sheet for using these commands:

  • viw - select in word
  • vi( - select in round bracket
  • vi{ - select in curly bracket
  • vi[ - select in square bracket
  • vi” - select in quote
  • ciw - change in word
  • ci( - change in round bracket
  • ci{ - change in curly bracket
  • ci[ - change in square bracket
  • ci” - change in quote
  •  va( - select all round bracket
  • va{ - select all curly bracket
  • va[ - select all square bracket
  • va” - select all quote
  •  ca( - change all round bracket
  • ca{ - change all curly bracket
  • ca[ - change all square bracket
  • ca” - change all quote

Tip #4: Nest with ease!

image

Say we want to assign the result of our try-catch statement to a variable name. This can be done in four easy steps:

  1. Place your cursor on either the opening or closing bracket of the try block (one of the red brackets)

  2. Hit “v%” to select everything up to and including the matching bracket

  3. Using the ParEdit plugin hit <Leader>w( to wrap the select text in another set of parentheses

  4. Inside the new parentheses, write the code to make the assignment

  5. (Optional) In the gif I have done an optional fifth step to re-indent the code by selecting the block and pressing the equal sign. “=” is a standard Vim command to re-indent.

Tip #5: Barf and Slurp!

image

 Barfing and slurping are terms used in the ParEdit plugin. These operations depend on the location of your cursor. Barfing will eject (“barf”) either the first or last element of the list where your cursor is placed. Slurping is the opposite: A slurp will find the first element to either the left or right of the list where your cursor is and slurp that element into the list.

In our try-catch example, say we create a new function called my-function. We then want to move the try-catch block inside this function so that we can call it later. Naively, we could select the try-catch block, then cut and paste it into the function body. Alternatively, in two keystrokes we can slurp the entire try-catch block into the function body! We can perform the opposite operation by then barfing the try-catch back out.

The concept might take a few minutes to sink in, but once you understand these operations you will be able to push code around like a pro.

Vim Plugins

Here are links for the vim plugins I used in the above demos:

(Lambda bird formation photo by Sigfrid Lundberg)