TermiC: Terminal C, Interactive C/C++ REPL shell created with bash
github.com
github.com
MIT had, decades ago, the Handy Board [1], which was like an Arduino for the 1990's. I built a few and really enjoyed the Interactive-C language [2] it employed (enjoyed).
That particular environment, a small hobby microcontroller, was an ideal one for interactive-ness. Want to determine some reasonable values for your ultrasonic distance sensor? Type a line of code in the monitor and you'll get back an analog value seemingly instantly.
The modern Arduino IDE could perhaps learn a thing from the Handy Board + Interactive-C IDE.
(I believe in fact the C was compiled to byte-code and then run on a thin interpreter on the Handy Board, but that's beside the point.)
(Also, tangentially, the 68HC11 was the first microcontroller I learned assembly for ... I have little experience with assembly but thoroughly enjoyed that command-set, that chip.)
See also: https://github.com/root-project/cling
recently i've been playing with clang-repl (i don't know anything about cling) and it exists like this^. yea it's there and there are some CI tests that are run and etc but if you think you're going to run real C++ programs through it, you're in for a disappointing day.
i'm not saying it'll never get there - i hope it does!
It doesn't help of course that ROOT itself is a horrible mess of massive internal state.
(When teaching I view high token count for hello world as a pitfall, starting with a REPL I can dive directly into computation before they start getting stuck on syntax)
So it's essentially saving you the trouble of having to put code into an "int main()" and putting declarations before it?
And then attempt to run the code after every line you type. Are there other examples of REPLs that work like this rather than all the state of execution being held in the REPL like I imagine Python does do it?
Can it Tab-complete identifiers I introduce in it? Actually, I suppose it's a single 115 LoC bash script, and I really don't mean to dunk on it, it's a neat little experiment. It just kinda made me wonder what REPLs are made for, for the first time. :D
Like I imagine a very basic "interactive" coding session (for any language) could also be achieved by having an editor open and saving after each line, or having that done automatically, and then in another terminal some script watches for those changes and compiles/interprets/runs it.
A REPL like python's is more like... having a debugger attached to your program, but it just sits at a breakpoint and let's you tell it what code to run next, and you can inspect variable contents and such.
Seems like languages that compile to machine code don't work all that well for REPLing, eh.
Say you have some buffer that you need to align on 4K blocks, you could quickly try out your "& ~0x1000" in the REPL. It may not be a convincing example, but you get the gist, sometimes you just want to quickly see the result of some one liners.
// test if we need a<<8|b
// or (a<<8)|b
// or ((int)a<<8)|b
// or (((int)a)<<8)|b
#include <cstdio>
#include <cstdint>
int main() { uint8_t a = 2; uint8_t b = 38; printf("%d\n", a<<8|b); }
More than half of the time is the uninteresting parts: writing the includes, creating a temp file, exiting to compile, forgetting a parenthesis, reediting and resaving, compiling again, running, deleting...In a REPL---particularly one with stdio/stdlib included by default---this would take 30 seconds but instead takes 3 or 4 minutes. It's not much, but tight feedback loops really, really keep you in a great mental state.
I think the biggest fail with most repls is the transition from the repl when you have that moment of "it worked" to having the working bits minus the stuff around it crammed into an idiomatic reusable thing. It is fairly easy in matlab, but I haven't found a workflow in Julia that does that well, tried dr. Doc strings, pluto, and vscode plugin. I'd welcome a rust repl too.
what does Matlab provide wrt this? Does its editor have refactoring assistance now?
> the idiomatic way to create a reusable module in julia is a lot heavier
do you mean package creation?
> I also run into issues of collisions between the new module and the lines I copied.
what kind of collisions do you mean?
what would your ideal tool for this look like? you select parts of your REPL history, ask for some name changes in it, give it a package name, and have it generate a package? any other features or steps that come to mind as potentially helpful?
Yes, package creation. The "right way" use create package.jl or whatever feels like a speedbump and requires setup.
When I import the newly created model, I have gotten name collisions with the playground remnants which you can't fully clear without restarting the repl.
That sounds like something I'd use, yeah. If you wanted to be fancy, you could make a function, putting uninitialized values into the argument list.
I imagine just about the same use case as running python3 interactively. Except, this is for C and C++.
Sort've like Compiler Explorer but on the command line.
Super cool.
Maybe this answers your own question, it’s a great reason to use a REPL, and this is a good analogy.
One thing REPLs are good for is the ability to interactively work through syntax errors. Type a line, it has a problem, so just do it again. It doesn’t have to completely stop and start over like a compiler. Syntax errors are not a big deal for a small test file, but can be very annoying if you’re working in a big project with a big build system.
I’d say not having to save a file, not having to write the command line to compile it to another file, not having to write the command line to run it (while usually leads me to write a small makefile if I have to do it more than a few times), all in addition to not having to wrap the code in “int main()” all adds up to a nice convenient way to run small snippets of C/C++. It might be extra useful to optionally auto-include the most common headers, and perhaps offer some shortcuts for common things.
I test little snippets all the time like printing the bits in a floating point number, or checking the syntax for struct packing, or dumping a quick table of numbers run through a function, stuff like that. It’s a pretty common occurrence for me to want to run a small amount of C++ code without any workflow overhead.
I also use Python and JavaScript REPLs all the time too for quick tests, even though they also take files, and compile them.(!) All language compile to machine code, so I’m not sure I agree that has to do with how well a language works in a REPL. Python’s really not that great in a REPL, IMO: you can’t easily paste copied code into it because the indentation is usually wrong.
It's... uhhh... not shellcheck-clean.
Cool project :)
Full circle!