I took my first steps in the JavaScript world about 5 years ago. Since then, I've had some great times with the language! I made a whole bunch of apps, in a whole bunch of frameworks but always tried to make every project better than the previous one. This has led me on a rollercoaster of many different libraries, frameworks and tools. In this post I'd like to summarize how my personal standards for software development tools came to be, and why PureScript scores so well against those standards.
About 5 years ago, I was asked to write a full application from scratch. Until then I had worked on legacy systems in the financial sector. My client wanted this app to be an administrative interface to their data, but also wanted a customer facing component. I was NOT looking forward to making a network of distributed installed native applications, so I ended up making an HTML5 Single Page Application with Backbone.js and Ruby on Rails. The decision to make an SPA ended up being the right choice. Both my client and its customers were very happy with the approachability and instant access of the app.
The JavaScript-driven web was, and still is, the only platform that can offer this kind of zero-install software and discoverability. For me, it really is the best way to present software to end users. The reach, discoverability and zero-install philosophy of JavaScript is unparalleled. Nowadays, you can even build your whole software stack in JavaScript. It reaches from DB's and backends to frontends and mobile apps. There is a huge community constantly building and experimenting. Tech giants are funneling huge amounts of resources into making the JavaScript VM's ever faster and more feature-rich.
Takeaway 1: JavaScript as a platform and an ecosystem is pretty amazing.
Unfortunately, building this application was often very frustrating. Writing JavaScript felt so extremely brittle. I just slapped some code into a text editor and crossed my fingers that everything would be fine at runtime. After a few rounds of going back and forth between my client's features and the codebase, the effort to manually keep all my code consistent spiraled out of control. I had to keep so much stuff in my head at all times, I often felt depressed after a long night of coding. I write JavaScript for my day job everyday and it gets better, but I never feel writing JavaScript is easy or relaxing.
People often pick on JavaScript's rough edges. Stuff like {} + {} being NaN may be fun to shock people on Twitter with, but in practice it's rarely a problem. For me, the real problems are dynamic typing, runtime code introspection (eg: Function::toString), runtime code evaluation, mutability by default, implicit type coercion, etc. Some people love JavaScript for this dynamism, but it is not for me. It stresses me out. I need guidance and help and I'm looking everywhere to find it.
One of my music teachers once told me that when improvising, constraints make you more creative. This seems counter-intuitive: How can you be more creative when you're allowed to do less? Yet it works! It forces you to come up with radically new approaches. Things that you wouldn't think about if you were allowed to use everything you were using before. I feel the same way about making software: Constraining yourself (by using a type system or adhering to purity) seems harder at first, but your inherent creativity will lead you to new and sometimes better ways of making programs, within that safety net.
Takeaway 2: JavaScript is really hard to write applications in. Any kind of help we can get is more than welcome!
On the server side, I *hated* working with Ruby On Rails. I managed to coerce it to spit out what I wanted it to, but I felt and still feel the huge amount of magic, configuration and conventions coupled with zero help from any kind of static analysis/compiler made the experience more like chanting random spells out of an old spellbook than software engineering. I never doubted that if somebody knew every spell in the book they'd be a pretty badass wizard, it just wasn't the way I wanted to go on writing programs.
Many developers seem to love magic: "I type two lines of code here and my app now has oAuth authentication, sweet!". That is not me. I hate magic. I want to know how stuff works, so I can understand how my *complete* app works, at least at a conceptual level. This might make me slower at certain tasks than some programmers, but I'm fine with that. Trading this initial speedup for a better understanding of my app is worth it to me.
Takeaway 3: I don't want magic in my code. Explicit is better than implicit.
After finishing that app, I couldn't believe this was how modern software engineering worked. I knew I needed knowledge and experience, so I immersed myself into a whole bunch of different frameworks, libraries, tools, languages, ideologies, paradigms, you name it, to learn whatever I could about making *good apps*. I started out with familiar languages like Ruby, Java, Perl, ventured on into C# and Clojure and ended up at Haskell and PureScript.
My introduction to PureScript and Haskell came in the form of PureScript by Example. After a deep dive into this amazing book, I started to see the value of writing complete programs with functions. Haskell and PureScript are in many ways very similar, so concepts can often be translated one-to-one.
As I read more and more about FP and PureScript/Haskell, I came across "composition". To make complete programs with functions, composition is essential. For years I never understood what composition meant, but somehow it always felt important. Functional programmers LOVE to use this word. I heard FP celebs like Bodil Stokke, Bartosz Milewski and Erik Meijer rave about it, but never really understood what they were talking about. It made me feel so stupid. How could I be a real programmer if I couldn't figure out this "essential" part of my job?
After hours and hours of reading Bartosz's blog posts, watching YouTube talks and consciously trying to apply these concepts in my code, it finally clicked. Composition really is the essence of programming. To me, composition means being able to write logic in small and simple functions and using composition (formalized by Category Theory) to cleanly "stitch" these functions into the rest of the application. Since I understood that, I look for it in every part of my software toolkit.
Takeaway 4: Building programs with functions is the way to go for me, and composition is essential to make it work.
The journey so far has been interesting. Without further ado, I'd like to introduce PureScript, a language that was created by Phil Freeman and has really come into its own since 2015. I'll try to highlight the features I feel are most important and how they relate to the above:
This purity goes a long way to avoid "magic" making its entrance into your code. Any side effects need to be explicitly expressed in the type system, so you have a much better idea of what a certain function does just by looking at its signature.
This is obviously not a complete view of the PureScript language. A good starting point is www.purescript.org and Phil Freeman's PureScript by Example.
While writing this post I realized there's a lot more I wanted to say, but I tried to keep this one as short as I could. Stay tuned for more Web and Purescript articles!