HN user

abhirag

312 karma

[ my public key: https://keybase.io/abhirag; my proof: https://keybase.io/abhirag/sigs/uFY5p-Y3Fc9Jpy2S3f9nBdGV48xT-UaGpXcGlpUWFxM ]

Posts15
Comments122
View on HN

Location: Bangalore, India

Remote: Yes

Willing to relocate: Yes

Technologies: Rust (Tokio, Axum, Pingora), RocksDB, Python, Kubernetes, AWS/GCP, OpenTelemetry, NATS

Résumé/CV: https://abhirag.com/resume.pdf

Email: hey@abhirag.com

Systems engineer, ~5 years of Rust in production. Most recently:

- Helped build a distributed notification engine (3.3B notifications/day at 300k/sec, 99.9999% dispatch reliability)

- Feature store serving 60M daily requests at p99 < 5ms

- Pingora based L7 reverse proxy

- DBSP based stream analytics engine processing 3.3M events/sec on a single node

Open to anything interesting, especially where Rust is the primary language. Happy to chat!

I think macros can help when the syntax seems messy, that is where lisp shines the most. Have a look at extempore lang (https://extemporelang.github.io/) you might like it. Macros written by others can feel like magic, but a DSL you create might still feel the most intuitive. I get your point about hidden syntax though.

The only other language I am still curious about trying for livecoding is forth, for example Sporth(https://paulbatchelor.github.io/proj/sporth.html)

Hey, thanks for taking a look! I have messed around with Clojure (Overtone) and Sonic Pi (Ruby dialect) and normally prefer lisps for anything fun :)

Regarding advantages/disadvantages, Lisp is always very terse which helps and with structural editing juggling parens becomes a non-issue. Dev environment being fiddly and fragile is the biggest con, you need to put some effort upfront in that.

It hurts to hear stigma and Emacs together in a sentence but I guess you are referring to the arcane keybindings of Emacs. In that case I use native keybindings for editing in Emacs i.e. the old Cntrl-C, Cntrl-V, Cntrl-A, Cntrl-Z, Cntrl-S and vim keybindings for executing commands i.e. for things like running code. This is a great setup for beginners so do contact me if you need Emacs to be used with native keybindings :)

Just to give an example of what can be done using org-mode, this is the project I am using to grok Literate Programming -- http://ray_tracer.surge.sh/

The whole thing is generated using one org-mode file -- https://gitlab.com/snippets/1710454

and this org-mode file is the one I work in, it will eventually generate the source code in separate files too, once I have finished the project.

This is what my setup looks like -- https://i.imgur.com/mqi8vPR.png

Anyways I can't convince you to use it, but hopefully I can convince you to give it a try, it isn't easy but it is worth it :)

I would love discussing the literate ray tracer I have been working on and the literate programming workflow I have made for it. Couldn't find your email in the profile, mine is abhirag@outlook.com, would be great to discuss if I can improve my workflow further :)

I have used both Jupyter Notebooks and org mode with org-babel extensively and I agree with the OP regrading the fact that the org-babel workflow is vastly superior, OP did point out a few features which org mode workflow has and Jupyter Notebooks don't but I will try and provide a comprehensive list:

1. Plain text format, git and git diffs work

2. You can combine many languages in a single document, and every code block can be part of a separate session, as an analogy to Jupyter Notebooks, you can have multiple kernels backing a single notebook and you can decide what kernel you want the current code block to run in.

3. You can edit a code block in the major mode for that language, i.e. you get all the features of Emacs while editing code: documentation, auto-complete, snippets and anything Emacs can do, and Emacs can do a lot :)

4. You can have internal and external links to any part of the document (or any other org-mode file) within the editor which get exported as links in the HTML file too. Want to refer to a code block you used before, just name it and drop a link. Extremely useful in binding the whole document together.

5. Literate Programming support -- You can decide the order the concepts are introduced in according to the human reader, not according to the execution order the machine demands it to be in:

  #+NAME: named_code_block :eval no
  function_not_defined_yet()

  #NAME: complete_code_block
  def function_not_defined_yet():
      print("nice function innit?")
  
  <<named_code_block>>
  
The <<named_code_block>> gets expanded to whatever you defined it and you control the way you want to structure the document to be the most readable. You can keep working backed by a REPL in the initial stages and then extract(tangle in literate programming speak) to a file, again in the order you want using the <<named_code_block>> (NOWEB syntax). So one org-mode can generate your whole project if you wish so.

6. With the internal and external links and <<named_code_block>> (NOWEB syntax) the org-mode file is closer to being a hypertext file than Jupyter Notebook even though Jupyter Notebook is the one running in a browser.

I have covered only the major features of org-babel, I haven't even covered all the features. I love Jupyter Notebooks too, but org-babel is something else. I am currently working on a toy ray tracer in Clojure in literate programming style and loving every moment :)

On the topic of pretty covers, I love the covers of these two books a lot:

1. The Art of the Metaobject Protocol (https://mitpress.mit.edu/books/art-metaobject-protocol)

2. The Art of Prolog (https://www.amazon.com/Art-Prolog-Second-Programming-Techniq...)

but haven't been able to find any other motivation to buy them. Also I have never printed the Common Lisp Quick Reference(http://clqr.boundp.org/clqr-a4-booklet-all.pdf) because I always imagine it having a really pretty cover, and everything I try just falls short.

You are seeing the Trolley Problem Dilemma[https://en.wikipedia.org/wiki/Trolley_problem] in action. Majority of respondents when asked that problem would choose to let a few people die to save a larger number of people. Emphasis being on "let a few people die" and not "kill a few people", machines (i.e. lever in that problem and autonomous car in this scenario) somehow evoke a more logical and less emotional response, I guess machines create an emotional distance between the people who would die and the respondent. If the same respondents would somehow feel more responsible for the death, i.e. the machine is removed from the scenario the response would be much different.

Not implying that the lack of empathy is in anyway acceptable, but people should know that when machines are involved in such scenarios it is much easier for them to distance themselves emotionally, this is not new, weapons are a prime example of this. Maybe by knowing this dilemma people can react better to such tragedies.

I hope people show more empathy knowing this.

I have no intention of starting or getting into a flame war between Ruby and Python, both are great languages but I can help with the Python tooling a bit. The Python equivalent of rvm is pyenv (https://github.com/pyenv/pyenv/blob/master/README.md) and to install dependencies and handle virtual environments after that you can use pipenv (https://github.com/pypa/pipenv). Both of them together will get you almost similar experience to the Ruby tooling example you ended the post with.

I love why the lucky stiff's writing, I love POODR (http://www.poodr.com/) and the two languages have a lot in common if you just keep an open mind about it :)

But that isn't a limitation of lru_cache, for example the same higher order function when used in Clojure i.e. memoize with recur for tail recursion will not cause stack overflow. The stack build up is because python doesn't support tail call optimization, not a limitation of lru_cache, just wanted to make it clear because you can use similar higher order functions in other languages which support tail call optimization without any limitations. Deep recursion in Python without sys.setrecursionlimit() is probably not a good idea, memoization can't help you in that. My point was geared towards presenting this pattern of memoization using a higher order function + recursion as an alternative to dynamic programming and in languages with tco and immutable data structures it works beautifully :)

Don't dismiss one of my favorite higher order functions so soon :)

"Recursion + memoization provides most of the benefits of dynamic programming, including usually the same running time." -- Steven Skiena

lru_cache decorator is great for people who are happy to let the language handle the caching of results for them, and often leads to code which is much more concise than the dynamic programming approach. The limitation you are referring to is that the decorator uses a dictionary to cache results and that dictionary uses the arguments as keys so the arguments need to be hashable. That limitation can be avoided by using immutable data structures (Clojure also has a higher order function called memoize which does the same thing and has no limitations because the core data structures in Clojure are immutable) and although Python not having structural sharing can mean that this approach can hurt memory and GC efficiency a bit, but that trade-off is at least worth considering :)

Still have to keep the stack depth less than sys.getrecursionlimit() so no substitute for tail recursion but surely a substitute for dynamic programming in a lot of cases.

The beauty of Emacs lies in how configurable it is. I use Emacs in two modes, when editing a program I use native key bindings (Cntrl-c, Cntrl-v, Cntrl-a, Cntrl-z etc.) and to execute commands I use vim key bindings. I absolutely love this setup but many people here might absolutely hate it, but what matters is that Emacs doesn't care and can be used by people with diverse muscle memories :)

Custom css is supported for html export, from the docs at (https://orgmode.org/manual/CSS-support.html) --

The HTML export back-end includes a compact default style in each exported HTML file. To override the default style with another style, use these keywords in the Org file. They will replace the global defaults the HTML exporter uses.

#+HTML_HEAD: <link rel="stylesheet" type="text/css" href="style1.css" /> #+HTML_HEAD_EXTRA: <link rel="alternate stylesheet" type="text/css" href="style2.css" />

To just turn off the default style, customize org-html-head-include-default-style variable, or use this option line in the Org file.

#+OPTIONS: html-style:nil

Well done! I hope things are better now :) Quick suggestion: Include a line describing what the website does on the main page, users can go to the about page and figure it out but it would be better to have a quick intro of what the site is all about as soon as they visit it. You can probably remove it once the website is more well known but the title isn't self explanatory, so an intro would help.

Stack used? Probably Elixir+Phoenix judging from your post history, what are your impressions about that stack?

I use pinboard archival account for this use-case, but I think some readers here might find this site useful :)