cluefactory.com

| home | resume | license |

Prototype-based OO: Using Typescript in Perl Projects

865 words by Sean Levy written on 2024-02-27, last edit: 2024-02-27, tags: makemaker, npm, oo, perl, prototypes, toolchain, typescript | Next post: Do One Thing Well


Okay, yeah, even old beardos come to typescript eventually. It's kind of a bit like coming home for me, but I'm still living most of my time on the strange little island of Perl. I mean the rent is paid through the end of the century, so...

The Usual History Lesson

I was one of the original prototype-based OO people, being inspired by Smalltalk and especially Self. At CMU I and my colleague built an environment called the Basic Object System, a prototype-based environment written in C that could integrate seamlessly with C++ and other languages. It had a programming language called stitch, inspired by Self, in which our research group wrote systems in the area of corporate memory.

Early object-relational foundations and prototype-based OO was pretty much what I was about in the 90s. One of the key ideas in Self was applying type inference in a typeless language, by observing what types arguments to methods had at runtime and generating better and better machine code based on frequency of use and actual data types in play. The idea here was to compete head-on with hand-written C code in a high-level OO language. These ideas bore commercial fruit in the form of Java's JIT, which was built mostly by Self alumni from Stanford hired by Sun for precisely this reason.

So now flash forward 30 years and these same ideas are in play, but for another reason: giving the illusion of type-safety to a dynamic, untyped (for the most part) prototype-based language. Instead of performance, typescript is worried about correctness and above all else finding bugs.

Enter Perl

It's taken me the better part of a day, but I think I've figured out how to use npm/typescript in a Mojo-based project, with Perl (ExtUtils::MakeMaker) in the driver's seat.

I keep my assets (which now include .ts files) in my source tree and manage them with e.g. Mojo::Home. The secret to integrating typescript into my Perly world came down to the following few lines in my tsconfig.json

{
  "compilerOptions": {
    "baseUrl": "./lib/myorg/myproj/public",
    "outDir": "./blib",
    "rootDir": "./",
    "strict": true,
    "moduleResolution": "node",
    "experimentalDecorators": true,
    // ... other stuff for sure
  },
  "include": ["lib/myorg/myproj/public/**/*.ts"],
  "exclude": []
}

First, I follow the standard open-source naming convention of having an overriding organization/project name and then a subcomponent name underneath it (the myorg/myproj), obviously the above is not literally what I use.

Second, I'm still on a learning curve with npm; I used npm i typescript in my source directory to get a typescript environment bootstrapped, and perused the lit ts starter kit for inspiration, but my project is not a node project, so like most resources out there it has a lot of good stuff in it but also falls short.

Set All The Settings To Be Set

It turns out with just a couple tweaks, the tsconfig that came with the lit starter kit was good.

baseUrl

The baseUrl setting: until I did this all the imports in my modules were throwing spectacular errors, because they were all supposed to be relative to the docroot, and my public directory is precisely that.

outDir

Next, outDir: this caused the output of npx tsc to start landing in the right path under blib, which is created and managed by MakeMaker. This sort of gives them dual custody.

rootDir

This one was already set in the starter kit, but I think you get wildly wrong results if you don't set it to ./.

experimentalDecorators

Everyone tells you to set this. Everyone. But was it set? Was it?

MakeMaker, Dev Server, Time Waster Don't You Mess Around With Me

I don't really want a node-based dev server in the mix, I just use a simple out-of-band BSD makefile to manage a separate dev docroot where I can play around with stuff via the tender mercies of nginx and friends. Mojolicious also has plenty of dev-server magic available if I want that, but when I'm just debugging/developing the pretty face of one of my ugly little apps I don't really want much more than nginx and Firefox's dev tools.

I'm sure I'll eventually slide over to the dark side and start building stuff using node/npm more directly. There is now a JS version of the Mojo framework, which is strictly a server-side thing; it carries forward (I guess this is forward?) the ideas in Mojolicious to a brave new JS-oriented world.

Fun and Profit

I'm enjoying typescript, but I have to say there's nothing new here. It just feels like another turn of the wheel... we're sick of types and marvel at our wonderful, fluid, plastic typeless language, but then we end up needing types and add them back... lather, rinse, repeat, rhyme with the past while marching into the future.

I do recommend that Perl devs with significant JS code strongly consider switching to typescript. You have nothing to lose but the past.


Copyright © 2024 by Sean Levy<snl@cluefactory.com>. All Rights Reserved.