You've heard about REPL, didn't you? REPL stands for Read Eval Print Loop & it's a common name for platform/language-specific shells that give you the ability to do live programming with line-by-line evaluation as you finish each line. In plain, soldier's words - REPL 'scriptizes' your programming language of choice to give you sort-of-debug experience without limiting you to execution of just the statements you have pre-compiled in your source code.
Frankly speaking, I've seen many people ultra-enthusiastic about this idea (mainly Clojure & Node.js peeps, some Scala as well), but I didn't share their ecstasy. Coming from .NET world, in all my ignorance I was finding an idea of REPL merely an improvement over standard Visual Studio debugging capabilities: locals, watches, auto & most of all: immediate window.
Yea, immediate window - it's not 100% REPL (for instance: you can't create new constructs like classes), but it runs out of debugging sessions, what makes using it quite a REPL-alike experience. But I rarely used/use it, because I didn't need to - all other tools seemed suited much better for the job I needed them to do for me.
There may be a point ...
My feelings towards REPL have warmed up even more once I've sunk more into functional (I mean - idiomatic functional) languages.
And then it hit me:
For functional languages REPL isn't just a way to walk around limitations in IDEs & tooling. It just works much better (is suited more) than standard debug & inspect way of doing stuff. If you're following functional principles & you don't hoard mutable state in functions, REPL is just faster & easier, while also (obviously) far more flexible than usual debugging (in full context of running application). Mix it with chunking your code into properly sized functions & REPL becomes something like unit test real-time interactive composer of processing pipeline:
- you can call whatever piece of code you want
- you can create a helper or any other additional piece of code on-the-fly
- it's up to you what you want to serve as an input (data in)
- it's idempotent!
Toys, more toys
Another great example from Elixir's playground is Inspect protocol - it's sort of interface equivalent that's used (implemented in default Elixir data structures & implementable in whatever you want to create) to present data structure's internals in a human-readable way (for a programmer, not an end user), using inspect/2 function.
Eshell V7.1 (abort with ^G) Interactive Elixir (1.1.1) - press Ctrl+C to exit (type h() ENTER for help) iex(1)> fun1 = fn a -> a + 1 end #Function<6.54118792/1 in :erl_eval.expr/5> iex(2)> inspect fun1 "#Function<6.54118792/1 in :erl_eval.expr/5>" iex(3)> val1 = fun1.(1) 2 iex(4)> inspect val1 "2"
Aaand to be honest you don't need much more toys. Using basic stuff like this you can efficiently program using functional language without bloated, expensive IDEs & the rest of the mess we've got used to while using Object-Oriented languages / platforms.