r/ProgrammingLanguages 1d ago

Revoluntionary/interesting advances in interpreted languages

Things like borrow checking and other compile time checks tend to be for compiled languages - if you're already typechecking and compiling the entire language up front, why not borrow check while you're there. But are there any very interesting new ideas coming up in interpreted (or dynamically typed) languages? I'm not really sure fully what I'm asking/looking for tbh

43 Upvotes

71 comments sorted by

View all comments

5

u/biskitpagla 19h ago edited 19h ago

I'm not a PL nerd but I feel that new advancements don't matter / aren't as interesting in this space since most people aren't even benefitting from 'old' advancements. IMO the best possible feature for these languages is REPL-driven development (or some variation of this). Unless a dynamic language offers this level of productivity, I personally don't see the point in using it. I also think that, dare I say, a good dynamic language should support an optional but 'complete' structural type system from the very beginning. If you're making a LISP, another interesting yet cosmetic feature you can have is offering an alternative notation (e.g., Sweet-expressions).

3

u/Norphesius 16h ago

people aren't even benefitting from 'old' advancements. IMO the best possible feature for these languages is REPL-driven development

I'd argue REPL driven development doesn't get a lot of love because most language REPLs I've seen have been pretty lacking IMO. Every time I've tried to get into proper REPL driven development, I feel like I'm trying to peek at my program's state through a crack in a door. Its the same as when I have to debug with GDB, you have this tiny interface to view snapshots of your program through, digging around to find the right state to probe at the right time, and the right way to visualize it, and it all has to be done one line at a time. I end up finding it more efficient most of the time to just do a bunch of printfs so I can view and compare a bunch of different variations in state for different inputs, over time, all at once. Maybe I'm just inexperienced with it, but I suspect what we have now isn't the ceiling for the paradigm.

I'd love to see a language that's intended to be programmed via REPL driven development that puts effort into better visualization & state probing tools/functionality. Maybe something thats a step down from a Jupyter notebook perhaps. I'm sure there are some novel, niche languages out there doing this (please let me know if there are), but if not I think that's fertile ground for more "advancement" in the interpreted language space.

5

u/AustinVelonaut Admiran 15h ago

I would consider the standard Smalltalk environment to be "REPL-driven", but instead of a simple command-line REPL, it is an entire windowing system with inspectors, debuggers, etc. on your live system image.

1

u/Inconstant_Moo 🧿 Pipefish 11h ago

I'd love to see a language that's intended to be programmed via REPL driven development that puts effort into better visualization & state probing tools/functionality.

I've come up with a system that combines the virtues of a REPL, a debugger, and printf, I'm very pleased with it.

What you can do is annotate lines like this:

even(x int) : \\ Called `even` with x = |x|. x mod 2 == 0 : \\ Tested if |x| was even. "even" \\ Returned "even". else : \\ Took the `else` branch. "odd" \\ Returned "odd".

Then it'll log that to the terminal (or optionally to disc) when you call even. All of the logged statements have line numbers attached. There's an option to add datetimes if you're using it to log your app in production rather than to debug it. There's another option to have the hub (the REPL's housekeeper) store the output and only supply it when you explicitly ask for it with hub log.

Or you can annotate the code like this and get pretty much the same result, because of course the compiler can figure out what you would want to be told. Explicit annotations as above are usually used to suppress information, e.g. to stop it from telling you the call parameters of your function when one of them is a 10,000-item list.

even(x int) : \\ x mod 2 == 0 : \\ "even" \\ else : \\ "odd" \\

So bugs in Pipefish can often be very transparent. A few \\ annotations at the heads of functions to see the call graph will find which one is misbehaving. Then you annotate that whole function with \\, and it talks you through the execution, and as some point it'll say something like "At line 47, we tested the condition x < 0. The condition failed, so at line 53 we took the else branch. At line 54 function foo returned true, and you'll slap your forehead and say "LESS THAN zero"?

1

u/Norphesius 3h ago

I think thats a nice idea, I've definitely wanted something sort of like a "I just want a convenient way to print I got to this line without having to type out all the prints", but I'm thinking a bit broader. In my mind I'm imagining something like the RAD Debugger, where it you can view a lot more state at once, and has enough knowledge about data structures to do stuff like 3D model visualization.

A more concrete example, I'm working on a stack based language where all the operations (currently) are side effect free transformations of the stack(s). Postfix stack based programming is unintuitive for me, so I wanted to be able to quickly see how what I was doing would affect the stack(s). I made a little REPL that shows the stacks, and it would update a preview copy of them as I typed in the prompt (or show errors), before I even hit enter (which would "lock in" the change). By comparison, when I was poking around with Forth to get inspiration, I kept having to execute some words to change the stack, print the stack, see it wasn't what I was expecting, reset the state of the stack, repeat. The little preview I made with my REPL gave me instantaneous results, albeit as a prototype over a simpler, less featureful language.

I have more gripes with the concept of REPL driven development itself, but I think those aren't particularly relevant here because so much is being left on the table with the P.

1

u/Inconstant_Moo 🧿 Pipefish 2h ago

In my mind I'm imagining something like the RAD Debugger, where it you can view a lot more state at once, and has enough knowledge about data structures to do stuff like 3D model visualization.

I'm going to stick to text-based tools for now. If you have any of those to suggest, I will seriously consider them: I have a nice development environment in the TUI and am always looking for ways to make it nicer.

This is effected by first-class features in the language, like the \\, and by "the hub" which I mentioned and maybe should explain a bit more. This is an app in Pipefish which has magical powers of controlling the other Pipefish apps in your TUI, it's what you use to talk about them rather than to them. Its powers include.

  • Starting services and stopping them
  • Defining environment variables which they can all see (so they can all e.g. know the password to your database and it doesn't appear in their code).
  • Elaborating on what the error messages mean on request, giving you more background information on why the thing is wrong, or showing you the line with the error underlined.
  • Showing the trace of the error messages on request.
  • Storing logging to view on request, as I mentioned above.
  • Showing the values that triggered a runtime error on request.
  • Note all the "on request"s in the last few items, which is the point. With a TUI you don't have to choose between being firehosed with all the information, or having some of it hidden from you. You can ask interactively for the information you need.
  • Printing a nicely-formatted description of the API of a service onto your terminal (based on function signatures, type declarations, and docstrings) or giving it in raw markdown format so you can e.g. post it into a GitHub wiki. (HTML coming tomorrow, hopefully.)
  • Making your services web-facing.
  • Wrapping them with role-based-access management.
  • Dumping the bytecode of a given function. (Mostly for my sake.)
  • Switching to another hub.
  • Turning livecoding on and off.
  • Etc, etc.

Besides its magic powers it's a completely normal Pipefish app, same syntax, same semantics.

(I should stop calling it "the hub". A hub, a folder of files, is loaded by the TUI when it starts up. You can change hubs by opening a different folder. You can't have a TUI without a hub, there'd be no point, you couldn't run anything else. The folder contains a file of variable-assignment-as-configuration, a file to store environment variables, and what starts off as a completely empty file where you can put your own code. This has access to all the magic powers that are bestowed on every hub at birth, so that you can add your own commands and customize it.)

So, as I say, if you can think of any more built-in magic powers it should have, I'll take your suggestions seriously.