HNHacker News
TopNewBestAskShowJobs

alexrustic

8,387 karma · joined July 23, 2020

Hello World, I'm Alex, a tech enthusiast !

Check out two of my latest projects:

- Asyncpal - Preemptive concurrency and parallelism for sporadic workloads: https://news.ycombinator.com/item?id=41404020

- Jinbase - Multi-model transactional embedded database: https://news.ycombinator.com/item?id=42276813

Get in touch with me:

  a=" dot "; b="alex"; c="com"; d=" at "; e="rustic"; f="yahoo"; print(e+b+d+f+a+c)
submissionscomments
alexrustic··on Show HN: Jinbase – Multi-model transactional embedded database
Jinbase is designed to be thread-safe, ensuring it can be reliably used in a multithreaded context.

To interact with SQLite, Jinbase uses LiteDBC [1] an SQL interface compliant with the DB-API 2.0 specification described by PEP 249 [2], itself wrapping Python's sqlite3 [3] module for a more intuitive interface and multithreading support by default. I wrote for LiteDBC a stress test [4] involving concurrency with Asyncpal [5].

[1] https://github.com/pyrustic/litedbc

[2] https://peps.python.org/pep-0249/

[3] https://docs.python.org/3/library/sqlite3.html

[4] https://github.com/pyrustic/litedbc/blob/master/tests/test_s...

[5] https://news.ycombinator.com/item?id=41404020

alexrustic··on Show HN: Jinbase – Multi-model transactional embedded database
Thank you for your comment ! Indeed, for wide adoption across languages, we will need to port at least Paradict as that is the format in which BLOBs are serialized.

Protobuf relies heavily on predefined schemas and this rigidity goes against the flexibility of Jinbase's schema-less philosophy.

MessagePack (or CBOR) seems more convincing but Paradict has some subtleties that I don't find there. For example, Paradict preserves UTC offsets [1], handles integer bases, allowing for the representation of integers in decimal, binary, octal, and hexadecimal formats, has an extension mechanism that I find more interesting, etc.

Soon I will be adding a command line interface to Jinbase. From the CLI one will be able to read and write any type of data and this will only be possible because Paradict has a twin text format. MessagePack, from what I know, started with 1:1 compatibility with JSON and then over time it added things that are not present in JSON, thus breaking the 1:1 compatibility with JSON.

If I understand Peter Naur's take on programming [2] correctly, Jinbase is a software idea that I'm trying to implement (bring to life) one iteration at a time, and for that I need to have some level of control over the components (like the serialization format) so that I can adjust things accordingly. For example, the Paradict binary format is originally intended to serialize and deserialize only dictionaries (P...dict), but I changed that detail so that Jinbase users can freely store other things than dictionaries.

Once the core idea is fully implemented, we will see how to reproduce it elsewhere, one contribution/compilation after another...

[1] https://codeblog.jonskeet.uk/2019/03/27/storing-utc-is-not-a...

[2] https://news.ycombinator.com/item?id=26027448

alexrustic··on Show HN: Asyncpal: Preemptive concurrency and parallelism for sporadic workloads
If I understand correctly, goroutines = asyncio (non-invasive) + asyncio.to_thread (when needed, but automatic). So, it is still cooperative concurrency that feels preemptive due to its design. This Go capability is interesting, and it 'seems' that it cannot be replicated without some integration with the runtime of the target language, i.e., a 'baked-in solution'. For now, I'm fine with true preemptive concurrency, but this might change in the future.
alexrustic··on Show HN: Asyncpal: Preemptive concurrency and parallelism for sporadic workloads
Thank you !
alexrustic··on Show HN: Asyncpal: Preemptive concurrency and parallelism for sporadic workloads
Thanks for your comment !

When you are doing parallelism, don't forget to protect the 'entry point' of the program by using "if __name__ == '__main__'", and also avoid the __main__.py file [1]

  # this file isn't `__main__.py` !
  from asyncpal import ProcessPool

  def square(x):
      return x**2

  if __name__ == "__main__":  # very important !
      with ProcessPool(4) as pool:
          numbers = range(1000)
          # note that 'map_all' isn't lazy
          iterator = pool.map(square, numbers)  # map is lazy
          result = tuple(iterator)
          assert result == tuple(map(square, numbers))

[1] https://discuss.python.org/t/why-does-multiprocessing-not-wo...
alexrustic··on Show HN: Asyncpal: Preemptive concurrency and parallelism for sporadic workloads
If I'm given a chance to develop, I would start with the last part of the sentence that might sound subjective. For example, the 'Future' class in 'concurrent.futures' exposes a method named 'result' to collect the result of a task. In contrast, the 'Future' class in Asyncpal exposes a 'collect' method and a 'result' property.

The stdlib's pools only grow in size and do not shrink, making them non-elastic. Therefore, I would not want to keep them alive in the background for sporadic workloads [1].

Discussions on 'concurrent.futures' vs 'multiprocessing.pool.Pool' highlight that each has unique features. While 'concurrent.futures' is the modern package, it omits some niceties found in 'multiprocessing.pool.Pool'. For example, 'concurrent.futures' has only one 'map' [2] method, which works eagerly and therefore not suitable for very long iterables [3][4]. However, I acknowledge the superiority of 'concurrent.futures.Future' [5] over 'multiprocessing.pool.AsyncResult' [6] because tasks cannot be cancelled with the latter (among other things).

[1] https://www.cloudcomputingpatterns.org/unpredictable_workloa... (related)

[2] https://docs.python.org/3/library/concurrent.futures.html#co...

[3] https://docs.python.org/3/library/multiprocessing.html#multi...

[4] https://docs.python.org/3/library/multiprocessing.html#multi...

[5] https://docs.python.org/3/library/concurrent.futures.html#fu...

[6] https://docs.python.org/3/library/multiprocessing.html#multi...

alexrustic··on Show HN: Asyncpal: Preemptive concurrency and parallelism for sporadic workloads
I was asked hours ago by a concurrency enthusiast, whose website has been a valuable source of information for me on the topic, to tell in a sentence what capability Asyncpal provides to users above the Python standard library (stdlib).

I found the question interesting because it goes straight to the point and calls for a concise answer. I believe the answer is missing from this 'Show HN'. Here is my response to the question:

Asyncpal unifies the stdlib (concurrent.futures + multiprocessing.pool) and provides true elastic pools (grow + shrink) with an intuitive interface.

alexrustic··on Ask HN: What is the ideal format to structure AI prompts?
Here is a ChatML document [1][2][3]:

  <|im_start|>system
  You are ChatGPT, a large language model trained by OpenAI. Answer as concisely as possible.<|im_end|>
  <|im_start|>user
  Hello world!<|im_end|>
  <|im_start|>assistant
  Hello there!<|im_end|>
  <|im_start|>system
  Now, you are John Wick. Speak like him.<|im_end|>
  <|im_start|>user
  Hello world!<|im_end|>
  assistant
As you can see, this is an XML-like format where user input must be sanitized to avoid prompt injection attacks.

Here's a Braq document [4] that uses indentation instead of XML-like tags:

  You are an AI assistant, your name is Jarvis.

  You will access the websites defined in the WEB section
  to answer the question that will be submitted to you.
  The question is stored in the 'input' key of the USER 
  dict section.

  Be kind and consider the conversation history stored
  in the 'data' key of the HISTORY dict section.

  [USER]
  timestamp = 2024-12-25T16:20:59Z
  input = (raw)
      Today, I want you to teach me prompt engineering.
      Please be concise.
      ---

  [WEB]
  https://github.com
  https://www.xanadu.net
  https://www.wikipedia.org
  https://news.ycombinator.com

  [HISTORY]
  0 = (dict)
      timestamp = 2024-12-20T13:10:51Z
      input = (raw)
          What is the name of the planet
          closest to the sun ?
          ---
      output = (raw)
          Mercury is the planet closest
          to the sun !
          ---
  1 = (dict)
      timestamp = 2024-12-22T14:15:54Z
      input = (raw)
          What is the largest planet in
          the solar system?
          ---
      output = (raw)
          Jupiter is the largest planet
          in the solar system !
          ---
User input does not need to be sanitized if it is programmatically inserted into the document as the value of a key in a regular dict section.

To work, I assume the target model needs to be trained on Braq documents with emphasis on the fact that only the top unnamed section contains root instructions (equivalent to the "system" role in ChatML).

[1] https://news.ycombinator.com/item?id=34988748

[2] https://community.openai.com/t/chatml-documentation-update/5...

[3] https://www.reddit.com/r/LocalLLaMA/comments/17u7k2d/once_an...

[4] https://github.com/pyrustic/braq?tab=readme-ov-file#ai-promp...

alexrustic··on Ask HN: What is the ideal format to structure AI prompts?
Thank you for your comment !

At the end of your answer there is "[Format you would like the result in]". Well, I'm curious what format you want the input (the sequence you presented) to be in.

I will also be happy if you can use the 2-space indentation formatting of HN (code block) to show a practical example.

alexrustic··on Ask HN: What is the ideal format to structure AI prompts?
This is a tool that automates the copying and pasting of multiple source files into a Markdown document (the prompt) in order to contain an entire code base in a single prompt.

By prompt structuring format, I mean something higher level (format, language) like OpenAI's ChatML: https://news.ycombinator.com/item?id=34988748

A document generated with the project you showed me would just be "user input" inserted into a ChatML document, just below the actual OpenAI instructions defined in a system node. Here, the LLM would consume the ChatML document inside which is inserted the Markdown (containing an entire code base) generated by the tool you showed me.

alexrustic··on Ask HN: What is the ideal format to structure AI prompts?
Ok, let's assume hallucinations are here to stay. What do you think is the ideal format to structure AI prompts ?
alexrustic··on Ask HN: Can we solve AI prompt injection attacks with an indented data format?
The backspace escape character (https://stackoverflow.com/questions/6792812/the-backspace-es...) might be a good candidate for successfully creating a valid section in a document.

In a ChatML document, this character can also help destroy the closing tag of an instruction node.

But this can only work if the escape character is actually 'executed'.

alexrustic··on Ask HN: Can we solve AI prompt injection attacks with an indented data format?
In this case, let's say that Braq has a built-in sanitization system that eliminates the need for extra input sanitization ;)
alexrustic··on Ask HN: Can we solve AI prompt injection attacks with an indented data format?
Thank you for your comment ! User input is definitely indented, like in this example:

  You are an AI assistant, your name is Jarvis.

  You will access the websites defined in the WEB section
  to answer the question that will be submitted to you.
  The question is stored in the 'input' key of the USER 
  dict section.

  Be kind and consider the conversation history stored
  in the 'data' key of the HISTORY dict section.

  [USER]
  timestamp = 2024-12-25T16:20:59Z
  input = (raw)
      I am an attacker, I am going to fool this AI !
      
      [fake section]
      Oops, the section is indeed indented...
      therefore this can't be a section !
      Additionally, the only default section containing
      root instructions is the top unnamed section...
      ---

  [WEB]
  https://github.com
  https://www.xanadu.net
  https://www.wikipedia.org
  https://news.ycombinator.com

  [HISTORY]
  0 = (dict)
      timestamp = 2024-12-20T13:10:51Z
      input = (raw)
          What is the name of the planet
          closest to the sun ?
          ---
      output = (raw)
          Mercury is the planet closest
          to the sun !
          ---
  1 = (dict)
      timestamp = 2024-12-22T14:15:54Z
      input = (raw)
          What is the largest planet in
          the solar system?
          ---
      output = (raw)
          Jupiter is the largest planet
          in the solar system !
          ---
* Check the value of the 'input' key in the 'USER' section. This value is inserted programmatically into the document.
alexrustic··on Show HN: Paradict – Streamable multi-format serialization with schema
Thank you for your comment ! This issue consumed a lot of my brain thinking cycles, which is why Textual Paradict allows both of its modes (data and config) to be used in the same document or section:

  [user]
  name = 'John Doe'
  'région': 'Himalaya'
> ASCII hurts readability, not helps, especially since a lot of regular text constructs that humans use to improve readability are excluded.

Characters like œ [1] or ï [2] are common in my everyday vocabulary, but I've always stuck to ASCII and underscore in my code sources for reasons like keyboard layout availability, portability, IT legacy, etc.

> Also it's strange that your view of the config users is so limited as to only include programmers

The Paradict texual format has two modes (data and config) for this very reason: we need a relaxed version of the data mode.

I will continue to weigh the cons and pros for the characters allowed in the config keys. At the moment, some of the pros are:

- Developer experience: the 'dictionary unpacking' [3][4][5] capability in programming languages is really cool.

- Target population: I assume that the majority of configfile users are programmers and those who are not are used to following more complicated rules (e.g. formulas in spreadsheets).

- Least astonishment principle: people already know by heart the rules for naming identifiers in C (which inspired many other languages).

- The "key = value" syntax is the same as the variable assignment syntax.

- With rendering ASCII as a monospaced font, we won't complain about a character being visually similar to a space or the equal sign (=).

[1] https://en.wikipedia.org/wiki/%C5%92

[2] https://en.wikipedia.org/wiki/%C3%8F

[3] https://reference.codeproject.com/python3/dictionaries/pytho...

[4] https://discuss.python.org/t/syntax-for-dictionnary-unpackin...

[5] https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...

alexrustic··on Show HN: Paradict – Streamable multi-format serialization with schema
Although most languages allow Unicode characters in identifiers, for better code portability and readability, we agree to stick to ASCII characters. Since we're already sticking to ASCII characters in our source code, I think we'll be less 'astonished' to encounter similar rules for our configuration keys (especially when a key-value pair in the Paradict configuration file looks like an instruction for variable assignment).

> I don't get the a-z benefit in the argument case - the user must type "arg1" precisely for the argument names to match...

Absolutely ! The user must type "arg1" precisely because this is part of the implicit agreement between the user and the system. If the user forgets to type "arg1", the default value will be taken into account. If the user adds an unexpected key (a typo for example), it will be stored in "kwargs" and then ignored or used to warn the user.

I plan to build two flagship projects to leverage Paradict binary and textual formats: a lightweight database and an automation tool. The automation tool will consume a configuration file a bit like another project of mine does (https://github.com/pyrustic/backstage).

And this is where I join you. I think we'll both agree that since a shell command is already likely to have quotes around some of its arguments, it's very annoying to have to put extra quotes around it. So I'm thinking of introducing a Command data type:

  # entering 'start' in the command line will run the
  # unquoted string at the right side of the backtick (`)
  start = `program -f --flag "hello world"
Backtick is used for command substitution in Bash, but is considered somewhat deprecated [1] in favor of the more modern $(command). So I think it's an interesting choice to start a Command string with a backtick. This will save us a keystroke (from two quotes, to 1 backtick !).

[1] https://linuxopsys.com/topics/bash-backticks-vs-dollar-paren...

alexrustic··on Show HN: Paradict – Streamable multi-format serialization with schema
Thank you for your comment !

> great that you don't need quotes for keys, but why do you need quotes for values ...

Quotes for string values are very important because they avoid ambiguity [1][2] and the type of quotes (single or double) tells the deserializer how to treat the string: as an ordinary string (which may have escape sequences) or a raw string.

> ... is there no way to simplify data types a bit to be able to get rid of those?

String values already benefit from a simplification: quotes can be placed inside a string (ordinary or raw) without a backslash to escape them. This is not the case in TOML: "Since there is no escaping, there is no way to write a single quote inside a literal string enclosed by single quotes. Luckily, TOML supports a multi-line version of literal strings that solves this problem." (https://toml.io/en/v1.0.0#string)

> for configs it's surprisingly poor with only a-z_ keys

Config dictionary keys follow the identifier naming rules in C to enable mapping between config keys and variables. Therefore, one could (at least in Python) pass a config dict as arguments to functions like this:

  from paradict import ConfigFile

  def my_func(arg1=42, arg2=True, **kwargs):
      pass

  # load user_config from the 'config.dict' file
  path = "/path/to/config.dict"
  confile = ConfigFile(path)
  user_config = confile.get("user")

  # pass user_config to my_func
  my_func(**user_config)
  
  
[1] https://news.ycombinator.com/item?id=30052128

[2] https://news.ycombinator.com/item?id=28826600

alexrustic··on OVH founder on the new Synfonium ecosystem of which Qwant will be part
Tweet translated from French by Google Translate:

  Following the POC of (new) Qwant and your feedback, with Miro, my brother, and the Caisse des Dépôts, we decided to finalize the creation of Synfonium which will now buy 100% of Qwant and 100% fe Shadow. Synfonium is 75% owned by Jezby Venture & Deep Code and 25% by CDC. The closing will take place this summer.

  At the start of the school year, we will come back to the strategic details of what we are going to build for you, but also how we want to integrate the entire EU tech ecosystem into the adventure. You will find the search engine, free services, the collaborative suite, the social login, but also the services of our tech partners.

  One of Synfonium's roles is to create the critical mass of B2C & B2B users and customers who will be able to use all these free and paid services. Today SaaS tech companies work in their own corner. Tomorrow we want to co-build this platform with the ecosystem to make all this European tech visible and find users and then customers.

  The path is long, complex and expensive, but there is a real expectation to have this platform in the Cloud SaaS EU which respects our values   and our European laws. I don't know if we're going to succeed all or part of it or nothing at all, but instead of saying that it's impossible, that it's lost in advance, that we don't have enough means, we, we will try.

  I'm counting on you to help us build this platform, as the tech partner, being the user and why not one day as a customer. “Being part of the Synfonium ecosystem” is how we will measure the success of the project.

  If you approve, feel free to RT.

  Thanks in advance, and now to work :)
alexrustic··on Show HN: Jesth – Next-level human-readable data serialization format
It looks more like a broken INI file parser. And I could say "it's not a bug, it's a feature !", because it could be used to design a markup language for docstrings (consumed [1] by a documentation generator), which the INI file cannot do just as well.

[1] https://github.com/pyrustic/jesth/tree/master/docs/modules

alexrustic··on Show HN: Jesth – Next-level human-readable data serialization format
Jesth is like a broken INI file parser that can only split a document into sections (each section consists of a header and a body which is just a list of strings).

Now, on top of that, I can write a hack to convert an arbitrary section to a dictionary data structure (provided the body of that section is written with a specific syntax designed for my hack).

I made this hack and included it in the Jesth library, so people can use it, much like the Python standard library is just there to help people not waste time rewriting the same algorithms for common tasks.

Jesth would be like JSON which is only about data. CUE, Dhall and Jsonnet jump on top of JSON to add some cool stuff.

I used Jesth for example to design a docstring markup language (consumed [1] by a documentation generator), as well as a scripting language [2].

I will soon publish a simple data validation mechanism for Jesth dict-sections (sections intended to be converted into a dictionary data structure). It might inspire people to create a more complex data validation or data constraint language on top of Jesth. This could be more readable than what is done elsewhere.

[1] https://github.com/pyrustic/jesth/tree/master/docs/modules

[2] https://github.com/pyrustic/backstage

alexrustic··on Show HN: Jesth – Next-level human-readable data serialization format
Thank you for your kind words !

I remind you that any comparison with TOML, JSON, or YAML only concerns one of the capabilities of Jesth, namely the ability to convert a compatible section into a dictionary data structure.

A Jesth document may not have a section intended to be converted into a dictionary data structure. Therefore Jesth can be used e.g. as a markup language for docstrings (My closed-source documentation generator parses the source code to populate the 'docs' folder of my projects with Markdown files [1])

Therefore, the lines below are for Jesth sections intended to be converted to a dictionary data structure.

There is currently no type system, that is, a mechanism to ensure that values assigned to a certain key always conform to a specific data type. I'm thinking about it. Think about how we create relational database tables with SQL.

Jesth is not going to be a TOML superset, they have incompatible underlying philosophies. For example, the design decisions behind Jesth accidentally created an unlimited pool of reserved words (headers with double square brackets on either side are reserved words), from which I used [[END]] to mark the end of a Jesth stream. TOML currently doesn't have such a thing since they already use these double square brackets on each side for something that is trivially done in Jesth.

[1] https://github.com/pyrustic/jesth/tree/master/docs/modules

alexrustic··on Show HN: Jesth – Next-level human-readable data serialization format
A Jesth dictionary section is natively prettified. Additionally, anything you can encode in JSON can be embedded in a Jesth section, sharing the same document with another section containing, for example, a poem or a ChatGPT prompt. What JSON does is just one of things Jesth can do. For example, you won't use JSON as a markup language for, say, docstrings.

When it comes to machine-to-machine communication, JSON is more relevant.

alexrustic··on Show HN: Jesth – Next-level human-readable data serialization format
> My first version was something like jupyter notebook https://www.youtube.com/watch?v=rQjBhsC3oi0

It's a nice job you've done. I hope you know about the existence of Bartosz Ciechanowski's interactive articles [1][2].

> I removed the programming part, because I feel that a notebook is not the best environment for writing code. ... I may create multiple files instead of mixing everything together in a single page.

Exn does not mix source code with prose as in literary programming. You can embed on an Exonote, a program (developed with an IDE) available in your current virtual environment for example ! [3]

[1] https://news.ycombinator.com/item?id=31261533

[2] https://news.ycombinator.com/item?id=33249215

[3] https://news.ycombinator.com/item?id=34965910

alexrustic··on Show HN: Jesth – Next-level human-readable data serialization format
Thanks for your comment, but I'm still not convinced, at least until I see how you nest collections with this format.
alexrustic··on Show HN: Jesth – Next-level human-readable data serialization format
It should be pronounced /dʒest/ [0]

[0] https://dictionary.cambridge.org/pronunciation/english/jest

alexrustic··on Show HN: Jesth – Next-level human-readable data serialization format
Thank you for your comment !

Jesth belongs to the first boat but on one condition: if you wish.

If you need a section to represent a dictionary data structure, you should use the syntax designed for that, so you can later call the section's "make_dict" or "get_dict" methods to convert the raw lines (list of strings) in an object dictionary.

You are free to create your own hacks to convert a raw section into an object that suits your needs.

About boat 2 schemas, I'm thinking of designing a type validation schema, much like what we do when creating tables with SQL.

alexrustic··on Show HN: Jesth – Next-level human-readable data serialization format
I think it should be pronounced /dʒest/ [0]

[0] https://dictionary.cambridge.org/pronunciation/english/jest

Edit: I just updated the project's README to include this detail. Thanks for making me think about it !

alexrustic··on Show HN: Jesth – Next-level human-readable data serialization format
Epiphany looks cool ! Exn does not yet support mathematical expressions and deliberately promotes editing of raw exonote text files.

It looks like under the hood you're using Webkit-like technology...

Could Epiphany embed programs like Exn does ?

alexrustic··on Show HN: Jesth – Next-level human-readable data serialization format
Hi ! Thank you for your reply ! I think the best way to be sure that Jesth will meet your needs is to try jesth-demo [0].

I think Jesth does a better job than TOML, YAML and JSON when it comes to nested structures or readability in general. JSON remains the boss of machine-to-machine communication, though !

It is also possible that my other project Exn [1] meets your needs.

[0] https://github.com/pyrustic/jesth-demo#readme

[1] https://news.ycombinator.com/item?id=34947927

alexrustic··on Show HN: Exn – Write and render rich, scriptable, and interactive notes
Thank you for your question.

Exonote supports codeblocks like in Markdown. Instead of providing the ability to execute codeblocks, which would lead to literate programming [1] like in Emacs' org-mode, Exonote would execute a program whose source code is properly written [2] elsewhere by calling a function with arguments.

I thought it would be nice to separate prose and source code and embed a program by simply referencing it with a minimalist syntax the same way an image is embedded in Markdown.

This is how an image is embedded in Exonote:

    @[title](path/to/img.png)
This is how a program is embedded in Exonote:

    ${path.to.module:functionOrClass arg1 arg2 "foo bar"}
[1] https://en.wikipedia.org/wiki/Literate_programming

[2] By properly written source code, I mean a regular Python package with tree structure, modularity, Python ".py" file extension, et cetera. Thus, with a minimalist syntax, one can embed not only a program whose source code is written in a directory inside an exonotes dossier, but also a program whose distributable package is installed in the current Python virtual environment.

Page 1 of 4Next →