Recently, I had the pleasure of reading Work Is Work, an essay by Coda Hale on organizational design. Aside from providing a thought-provoking perspective on scaling organizational efforts, the post makes reference to two terms from anthropological field research that were new to me: emic and etic. Below, I’ll describe how these terms provide a useful framework for interpreting success stories.
Emic and Etic
When we read success stories, we often do so to help narrow down the solution space for a problem we’re facing. During that process, it can sometimes be easy to lose track of how important details of the story (its plot, setting, actors, etc.) are different from ours.
This framework has been valuable to me in two ways. It:
Provides shorthand terms for what are otherwise relatively difficult concepts to communicate.
A few days ago, I spent some time learning how to use Amazon’s Serverless Application Model (SAM) to schedule the recurring execution of Lambda functions. To help better cement my understanding, I assembled an overview of all the SAM template components necessary to schedule the periodic execution of a Go-based Lambda function. I also made note of how I used the SAM CLI to package and deploy everything to AWS.
Serverless Application Model
Amazon’s Serverless Application Model is a specification for translating SAM templates into CloudFormation templates. Much like macro expansion, it works through a textual transformation of the input SAM template into a template the CloudFormation engine can make sense of.
TestRole is a resource of type AWS::IAM::Role, which is a top-level CloudFormation resource. It creates an Identity and Access Management (IAM) role containing the permissions necessary for our Lambda function to do its thing. In this case, it simply encapsulates a canned IAM policy, AWSLambdaBasicExecutionRole. This policy allows the Lambda function to use the following CloudWatch API calls to log function output to CloudWatch Logs.
The next resource, TestFunction, is of type AWS::Serverless::Function. This is not a top-level CloudFormation resource. Instead, it is a SAM resource that expands into multiple top-level CloudFormation resources. Based on our usage, it expands into three:
AWS::Lambda::Function is the top-level CloudFormation resource to define an Amazon Lambda function. Because we want to schedule the function’s periodic execution, we include an Events property on our AWS::Serverless::Function resource. This allows us to define the function execution schedule within the context of the function’s properties. Behind-the-scenes, the Events property expands into a AWS::Events::Rule resource with an invocation rate of once per hour.
Lastly, in order for the CloudWatch Events API to invoke our function, it needs permissions to do so. AWS::Lambda::Permission grants CloudWatch Events the permission to invoke our function.
Package and ship
The AWS SAM CLI builds on top of the SAM specification by providing a single tool to manage the packaging and deployment of serverless applications. Installation is a bit out-of-scope for this post, but once you’ve managed to install the sam tool, the application deployment process occurs in three phases.
Lastly, use sam again to deploy the template through a CloudFormation stack named Test.
$ sam deploy --template-file packaged.yaml \--stack-name Test \--capabilities CAPABILITY_IAM
Waiting for changeset to be created..
Waiting for stack create/update to complete
Successfully created/updated stack - Test
Within an hour or so (it only takes a few minutes to deploy—the wait is for the function schedule to trigger), you should see something like the following in your function’s CloudWatch Logs log stream.
START RequestId: 5886a0f4-50a1-1cca-10b2-67f512fd83b1 Version: $LATEST
END RequestId: 5886a0f4-50a1-1cca-10b2-67f512fd83b1
REPORT RequestId: 5886a0f4-50a1-1cca-10b2-67f512fd83b1
Duration: 1.59 ms Billed Duration: 100 ms Memory Size: 128 MB Max Memory Used: 5 MB
For the past few weeks, I’ve been starting off my days with Haskell flavored code katas from Codewars. Today I started with the kata below and figured it would be a good exercise to walk through my solution.
Write a function that will return the count of distinct case-insensitive alphabetic characters and numeric digits that occur more than once in the input string. The input string can be assumed to contain only alphabets (both uppercase and lowercase) and numeric digits.
To help clarify the specifications for this kata, the Hspec test suite is below:
moduleCodwars.Kata.Duplicates.TestwhereimportCodwars.Kata.Duplicates(duplicateCount)importData.List(nub)importTest.HspecimportTest.QuickCheckmain=hspec$dodescribe"duplicateCount"$doit"should work for some small tests"$doduplicateCount""=?=0duplicateCount"abcde"=?=0duplicateCount"aabbcde"=?=2duplicateCount"aaBbcde"=?=2duplicateCount"Indivisibility"=?=1duplicateCount"Indivisibilities"=?=2duplicateCount['a'..'z']=?=0duplicateCount(['a'..'z']++['A'..'Z'])=?=26it"should work for some random lists"$doproperty$forAll(listOf$elements['a'..'z'])$\x->letxs=nubxinduplicateCount(concatMap(replicate2)xs)=?=lengthxswhere(=?=)=shouldBe
Sorting & Grouping
To start things off, we are given the following snippet:
Here, the . allows us to compose length and >1 together so that both can be applied to the [Char] provided to filter. The result rids the list of any characters that only occur once in the original input.
Lastly, we need the count of distinct characters from the input String that occur more than one, which is as simple as getting the length of the filtered list.