This is a macro in Clojure called `dotrace`. When you surround a piece of code with it, it pretty prints the call tree along with its inputs/outputs, which is incredibly useful for debugging recursive functions.
Many other languages cannot do this with user-level code.
Clojure can because its syntax is “just” data structures and can be processed and rewritten on the fly by code of your own choosing. Like `dotrace`!
Macros effectively extend the compiler into userland, and it’s one of the reasons Lisp is so easy to fall in love with it.*
I don’t know about Lisp, but here’s an attempt in Elixir:
t before number is rather useless I think, but it’s not important. Some integers have 4 digits and some only 3. Because of that the output could be more or less harder to read in some cases.
Nah, c’mon. I just wanted to suggest that embedding into an existing ecosystem (especially if provided by the language core team) might save you few keystrokes, because Kernel.dbg/2 might actually offload a ton of work from you, providing a common mechanism for fancy output and/or real debugging with pry.
Still, it looks already very good, but a bit alien, that’s what was my humble comment about
Alien?! Ever since I started with Elixir I kept wondering why don’t we get execution chains printed like that. They are much more intuitive to me, especially when there is recursion involved.
It’s good, no worries. I consider this a proof of concept, and not a very good one at that. It looks alien because of the Process registry for storing the trace depth, and the spawning of asynchronous Tasks. This brings with it the Process.sleep(10), where 10 is arbitrary, so that this doesn’t fail:
if Process.alive?(task.pid) do ... else ... end
I might get back to this at some point, when I learn more. I don’t know if this is a “proper” way of achieving the goal. If some “wizard” out there finds it worthwhile to develop further, feel free to send a PR–or to request the GitHub repo to be taken off my hands! @dimitarvp
My wizarding qualities are sadly very limited lately but I can give you a review on a next prototype when you have it. I also haven’t done macros in a while.
Sure. To me too. It does not make them elixirish, though. I prefer meerkats to mere cats, and yet this fact alone does not make a meerkat a less stranger pet.
Well, if only Common LISP had the OTP runtime. The LISP folks practically beat most of the computer science game ages ago, including allow one to easily devise business-specific DSLs that compile to quite well optimised LISP.
“It is an established fact that John McCarthy shared alien tech with the world in 1958 when he introduced us to Lisp. We continue that great tradition.”
Robert is the best, yeah. Only the strongest sense of humor might make a person survive through writing the whole OTP in bare C language. Back then, even Prolog was prohibited, let alone LISP.
Ecto, Ash, Phoenix + LiveView, any framework that needs Elixir macros.
Give me the incantation that I must put somewhere and let it all work. Without that I’m not doing any other career shifts (with the only exception that’s becoming more and more likely with time being Rust, because the supply in Elixir’s job market looks to have diminished severely in the last two years).
Never was that for me. I can tolerate and even get used to and love almost any syntax as long as the compile-time guarantees and runtime quality are both excellent.
No LISP ever had that. Maybe Racket these days, but there’s not many volunteers and their parallelism story was progressing at a snail’s pace last time I checked them out (2-ish years ago).