Notes on Bad Engineering Properties of Object-Oriented Languages

notes, papers

This post is a set of notes on Bad Engineering Properties of Object-Oriented Languages” by Luca Cardelli, available at the time of writing from Cardelli’s site.

This post is mostly intended for my own notes. You may not find it useful.

First, Cardelli opens by defining 6 areas in which one can informally evaluate a language’s effectiveness for software engineering.

He then comments on some areas in which “advancements in procedural programming” have created positive changes in those six areas. Of particular note;

Cardelli then lists ways in which Object Oriented languages fail or score poorly on the metrics in question:

Cardelli then states where work is happening and what still needs to be done:

Why Do We Accept Partial Functions?

How to Fix Slow Request Handling With AWS SAM Local

aws, sam

If you are developing AWS Lambda Functions, you will likely use AWS SAM Local for running your functions in a local development environment.

AWS SAM Local is a great tool. However, many users, including myself, run into very slow response times when first using AWS SAM Local, as documented in issue 134. Simlpe functions may be taking more than 6 or even 10 seconds to evaluate.

This is likely for one of two reasons:

  1. You are using a language with compiled-and-compressed code packages like Java’s JAR files.

  2. You have not configured your AWS credentials.

For (A), AWS SAM Local unpacks your compressed code package on every request. That process takes a few seconds, period. There are a few workarounds, which include manually unzipping your .jar and pointing at the unzipped files in your template.yaml’s CodeUri parameter.

However, if you are not using the C# or Java environments and are still experiencing slow requests, you are in (B), and you can solve this problem by configuring your AWS Credentials.

The documentation indicates that you can provide credentials in one of two ways:

  1. Specify AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables

  2. Configuring a profile in ~/.aws/credentials for Linux or MacOs

Nota Bene: When AWS SAM Local’s README refers to ~/.aws/credentials, there is an implication that you are using the AWS CLI v2, not the older v1, which stores information in ~/.aws/profile.

There are two gotchas with this documentation:

  1. While both solutions will speed up execution, specifying the environment variables is noticeably faster. I recommend you skip the AWS CLI configuration and just specify the environment variables.

  2. If you put your credentials in ~/.aws/credentials in a profile, you need to specify --profile <profile_name when you invoke sam for AWS SAM Local.

Note that for basic AWS SAM local operation, you do not need to specify valid AWS credentials - any old value, even the empty string, will do!

Using Google Closure Compiled Code for AWS Lambda Functions

clojurescript, javascript

Recently, I tried to get a development environment set up for developing a single page web application ClojureScript - but with a backend written to run on AWS Lambda functions, also in ClojureScript.

ClojureScript seems to use the Google Closure Compiler for compiling JavaScript. The Google Closure Compiler uses its own module and import/export/require system that is different from Node’s module system.

Because AWS Lambda expects your JS to export the handler functions for the Lambda function using the Node module system, I ended up with a real problem:

How do you require Google Closure-compiled ClojureScript into a node module?

The answer ended up being quite simple. Given that Closure is creating a compiled file with name functions.js, which in turn is exporting a namespace functions.core, you can create a new main.js file in the same directory as the compiled functions.js file with the following content:

1
2
var f = require("./functions.js");
module.exports = f.functions.core;

This took me longer than I care to admit to figure out, though that’s probably mostly a function of how little I deal with JavaScript module systems. Since thanks go to Matthew Stump’s post Writing NodeJS Modules in ClojureScript, which had the trick as part of it.

Clojure and ClojureScript Boot and Boot-reload Error

boot, clojure, clojurescript

Recently, I attempted to get started with the boot build system by running the boot-cljs-example repository.

On my system, while running the suggested build script:

1
boot serve -d target/ watch speak reload cljs-repl cljs -sO none

I ran into the following error:

1
2
3
4
5
6
7
8
james@james-desktop: boot serve -d target/ watch speak reload cljs-repl cljs -sO none
WARNING: test already refers to: #'clojure.core/test in namespace: boot.user, being replaced by: #'boot.user/test
             clojure.lang.ExceptionInfo: java.lang.NoClassDefFoundError: clojure/lang/IFn, compiling:(org/httpkit/server.clj:23:11)
    data: {:file "/tmp/boot.user6465695604758877332.clj", :line 21}
java.util.concurrent.ExecutionException: java.lang.NoClassDefFoundError: clojure/lang/IFn, compiling:(org/httpkit/server.clj:23:11)
clojure.lang.Compiler$CompilerException: java.lang.NoClassDefFoundError: clojure/lang/IFn, compiling:(org/httpkit/server.clj:23:11)
         java.lang.NoClassDefFoundError: clojure/lang/IFn
       java.lang.ClassNotFoundException: clojure.lang.IFn

To fix this: note that boot relies on a boot.properties file for version information and uses that instead of your system versions if set.

To fix the error above, change your BOOT_VERSION in boot.properties to be 2.7.2 instead of 2.5.5.

Happy coding! For extra information, see the version information below:

Version & System Notes

To do so, I installed the default version of boot as of the time of writing. The version output of this version is:

1
2
3
4
5
6
james@james-desktop:$ boot --version
#http://boot-clj.com
#Fri Dec 01 03:51:00 EST 2017
BOOT_CLOJURE_NAME=org.clojure/clojure
BOOT_CLOJURE_VERSION=1.8.0
BOOT_VERSION=2.7.2

Additionally, I am running Java 1.8. and node 7.10 via Ubuntu 16.04’s node package, but with nvm (node version manager) installed.