Hacker News new | ask | show | jobs
by artisin 989 days ago
I dig the core concept, particularly since I've been searching for a more efficient alternative to opening a blank DevTools window for executing various helper scripts. With that in mind, what about introducing a "Loose Mode" option of sorts, akin to a basic js interpreter? Granted, most of the tool's interactive functionalities probably wouldn't work in this simplified mode, but it would, in turn, expand the tool's overall versatility. Enabling you to use previously written scripts and/or experiment with code (such as copying an example snippet from the README) without having to first adapt it to a functional paradigm.
1 comments

I agree that enforcing strict purity in Leporello.js might limit its adoption among developers who prefer a more flexible approach. However, this initial focus on a pure functional subset allowed me to concentrate on the core idea – reimagining developer tools for functional programming from the ground up.

Exploring the development of a two-mode debugger that can seamlessly switch between traditional imperative debugging and Leporello.js-style debugging for pure functions in modern multiparadigm languages is indeed an intriguing research avenue.

Hope you don’t mind answering a few questions of mine.

What’s the functional subset of JS? Any literature on this subset? I don’t really know JS apart from hacking together a few scripts for fun.

If this is purely functional, does this mean we will need to use monads for IO like in Haskell?

Leporello.js follows a pragmatic functional approach. You can use IO functions and throw exceptions as you typically would, without the need for an IO monad or an Option monad. However, there is one critical limitation – you cannot mutate your data structures. Mutations are not allowed because they would make time-travel debugging impossible. For instance, the following code is forbidden:

  const point = {x: 1, y: 2}
  point.x = 2
And instead you should use this:

  const point = {x: 1, y: 2}
  const another_point = {...point, x : 2}
In Leporello.js, it's vital to avoid mutating data structures; instead, you create new ones. You can watch Rich Hickey's insightful talk [0], where he discusses the advantages of immutability in functional programming.

In many ways, Leporello.js bears a resemblance to Clojure. Clojure served as a source of inspiration for Leporello.js, to the extent that I even contemplated building Leporello.js for Clojure first.

[0] https://www.youtube.com/watch?v=-6BsiVyC1kM

The comma operator also seems forbidden. I guess there's never a need to use it in purely function code, but the code can still qualify as pure even allowing its use?

fib(6), fib(7) // scratch:9:6 - unexpected token

Currently, Leporello.js relies on my custom JavaScript parser, which, while functional, is not yet complete and exhibits some quirks. My plan is to replace it with a TypeScript parser, thereby providing full support for both JavaScript and TypeScript within Leporello.js. Additionally, I'm going to develop a VSCode extension, which will offer you all the features available in ts-server.
Sounds exciting. Looking forward to trying out the extension!