question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Make Automaton instances immutable

See original GitHub issue

@eliotwrobson I want to run something by you that I’ve been mulling over for the past week.

Part 1: Precomputing lambda closures was a good idea

When you integrated networkx into the library back in ed1cdffcccb90a03f1892147f42ea1a9f62414f6, you added logic to precompute+cache the lambda closures for an NFA (via self._lambda_closure_dict). Previously, these lambda closures were (arguably excessively) computed on the fly when reading input via my NFA._get_lambda_closure method.

Given the performance/efficiency consequences of my previous approach, I very much appreciate your contribution here (enough so that I am planning to expose this dictionary as part of the public API, as you may have noticed in my recent commits to develop).

Part 2: Internal Automaton state

However, your changes do introduce an interesting dilemma. You see, before Automata v6 was released with your precomputed lambda closure logic, NFA instances could be mutated without consequence just like every other Automaton instance in the library.

But now that lambda_closures (a derived attribute, in database terms) is in the picture, the NFA instance could end up in a situation where the user updates states, transitions, and/or input_symbols, leaving lambda_closures stale.

As I see it, there are three solutions to this stale lambda_closures situation if we want NFAs to remain fully mutable:

  1. We watch for changes to states, input_symbols, and transitions (which is a nested structure) and automatically recompute lambda_closures when any of the aforementioned attributes change; this is the ideal solution, but not sure how feasible it is to implement

  2. We require the user to explicitly recompute the lambda closures (via some public method) when they choose to mutate the NFA. This is not my favorite approach, as the precomputing of lambda closures is really an implementation detail the user should not be concerned with. But it would balance implementation simplicity with performance.

  3. We revert to caching nothing and computing the lambda closures on the fly when reading input; naturally, this would re-introduce a significant performance consequence, especially if you want to read many input strings with the same NFA instance

Of course, if we make NFAs fully immutable, then this problem goes away, and we don’t need to worry about recomputing lambda_closures post-instantiation.

Part 3: Mutable or immutable?

So far, my blurb above is focused primarily on NFAs, but I think it opens up a larger question about whether any automaton should be a mutable structure, or whether it should be immutable. My ultimate aim for this library is to have a consistent and friendly API that makes working with these data structures pleasant and practical. And right now, NFAs are inconsistent with the rest of the Automaton sub-types because NFAs have some additional internal state (i.e. lambda_closures) which must be managed.

Questions for you

Therefore, I will sum up my musings with a few questions regarding your own use of this library:

  1. How frequently are you reading input with the same automaton?
  2. How frequently (if ever) do you mutate an automaton after its instantiation?
  3. What are your thoughts about making all automata instances immutable?
  4. Anything else you want to add?

@abhinavsinha-adrino @Tagl If you guys happen to have a moment, I would love any feedback you have as well. This library isn’t any good if it doesn’t serve real-world use cases for working with these machines.

Much thanks in advance, Caleb

Issue Analytics

  • State:closed
  • Created a year ago
  • Comments:49 (49 by maintainers)

github_iconTop GitHub Comments

2reactions
caleb531commented, Oct 26, 2022

@eliotwrobson @Tagl Since the Immutability work itself is already complete, I decided to merge the immutability branch into develop. In accordance with this, I’ve switched the target branches of both your open PRs from immutability to develop.

I’ve also deleted the immutability branch, so develop is back to being the correct target branch for which to submit PRs going forward.

2reactions
Taglcommented, Oct 20, 2022

I have not been working with the library for quite some time. However, I never had to alter the automata I used after creation. I worked with them as if they were immutable. If I needed to mutate I would perform all mutations myself. Otherwise I used the union/intersect/etc. methods to mutate and construct more complicated DFAs. However I must note that I was working with permutation patterns so my bottleneck in performance (after improving the time complexity in the library) was more in regards to combinatorial explosion of the set of permutations rather than anything to do with the state machines. I think immutability is a good choice.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Immutable Infrastructure: Benefits, Comparisons & More
An immutable infrastructure refers to servers that are never changed after deployment. Learn best practices for handling immutable ...
Read more >
Mutable infrastructure - definition & overview - Sumo Logic
Immutable infrastructure as the underpinning component of the currently running version of the application makes the job of operations so much easier. If...
Read more >
Immutability and Builder Pattern - kean.blog
Modelling large immutable objects in Objective-C without creating telescoping initializers.
Read more >
Are you considering making your classes immutable? - Medium
An immutable class is a class whose instances' content cannot be modified once they have been created. That is to say, to make...
Read more >
Creating Mutable and Immutable Classes in Swift | Packt Hub
When we create an instance of a class that defines many public-stored properties, we create a mutable object, which is an object that...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found