On Sun, Apr 20, 2014 at 9:27 AM, Martin Michlmayr <[email protected]> wrote:
> Martin, can you share the status of beancount? I had a quick look last evening and it seems you've been very active > lately. I'm also impressed by the documentation. > Sure. The current version is a complete rewrite of my first iteration that was a Python clone of Ledger. I used the previous one for years and at some point realized a lot of he mistakes I had made in my experimentation, deleted a whole bunch of features (yes, removed), rewrote the entire thing from scratch with a simpler, more elegant design and a more regular syntax, in particular one that can be handled with a parser generator, so I could evolve it easier in the future, and a very modular design; you have a parser library for the language, a separate core/data structures library for the in-memory representation, along with some functional operations (e.g. closing a year, moving net income to the balance sheet, etc.), and a web application built on top of that. The dependency tree is clear, so you could e.g. write your own parser bit for it and reuse the rest. I made sure it would be trivial to write custom scripts that invoke the parser on a file to obtain the data structures so you could customize it. At the moment I'm doing two things: 1. I'm not adding any new features, rather I'm trying to cover all areas with tests before I add anything more. I have loads of ideas (see TODO file at the root), but I want full test coverage before adding new features, and then I'll stamp this as v2, so I'm restraining myself heavily, just writing tests when I work on it. Unfortunately, the inspiration for the rewrite was too strong for me to take time to do that right away, so I wrote everything in a relatively short amount of time, and now I'm eating my brussel sprouts and doing my homework (I'm really quite happy with the rewrite though, there's no hacking). I consider it stable, and I'm using this system exclusively for myself now, but I do want full test coverage before stamping it as v2.0. 2. I'm forking the import-related code to another project called Ledgerhub, which will work for Ledger, HLedger and Beancount syntax, and other similar systems if they materialize. I'll be removing the import code from Beancount as soon as that's done (I could probably do that now actually). Ledgerhub already works and that's what I'm using, but same story there, I'm working to cover it with unit tests before calling an "official" release. I think the Ledger documentation is more complete in terms of explaining the DE method; for Beancount v2's documentation, I want to do two things: - Provide lots of examples of transactions and how to deal with them. I think examples go a long way towards learning the double-entry method. I could have used examples myself. Now I want to take my experience with this system and write a little something to help others. - Document the design objects really well, so that other implementations can use that as a basic for alternative implementations in other languages. I think I nailed down some of the abstractions right this time and it be a good basis to build another implementation in, say, a functional language (my implementation is mostly "functional" Python BTW, using immutable data structures almost everywhere, collections.namedtuple). I haven't had time to actually run the tool yet, but I wanted to ask: > > - How compatible is the file format? It seems the statements to > define accounts are different. Is there any way we could all agree > one one file format, so it's easy to switch between the different > ledger implementations? > Not compatible. With v2 of Beancount I rewrote the syntax because I wanted it more homogeneous and regular (e.g. all directives begin with "YYYY-MM-DD directive-name ..." and I did not want to have any custom-parsing code, I wanted to write a BNF grammar for it instead. I think this should make it easy to implement parsers in other languages too. I also think it's a lot simpler than it used to be, see the cheatsheet. However, I think it would be very easy to write a converter from one syntax to the other, and vice-versa, given access to the native parser for the source language. For instance, it could be: maintain your input with Ledger, and write a converter using its Python bindings to spit out Beancount-compatible syntax. Or the other way around, maintain your ledger using Beancount, and write a script against the internal data structure to Ledger-compatible syntax (I know that this should be very easy, BTW, a single file script would take no more than a few hours to hack). Keep in mind that Ledger has more features, so it might not be possible to convert all of its syntax to Beancount, e.g. Beancount has no support for virtual postings for instance (and will not have them). Beancount v2 tries to do with a minimal amount of features, so in principle it should be easier to convert from Beancount to Ledger. Further, note that you don't necessarily have to generate a file in the other language.. it should be possible to create Beancount internal data structures directly, by invoking the Ledger parser on a Ledger input file and use the Python bindings to get the contents of its file and create the data structures. Then you could run the Beancount web app on this. You'd have to ignore the Ledger features Beancount doesn't support. I really don't think this would be difficult BTW. I haven't tried this yet, mainly because I don't have any real Ledger input to work with. I would love to do some cross-validation between the two systems at some point, I personally have 8 years of full transaction data at this point, and I'd like to see how it looks through Ledger, it would be fun, maybe I can use some of its reporting, so I think I will write a conversion script at some point in that direction. As far as agreeing on one syntax, I don't think it's worth the effort, I'm not sure actually. Beancount's approach is minimalist, and Ledger has a lot of features I don't want to support. And I really do want to be able to define the syntax via a parser generator. I do think it could be *possible* to define such a syntax that also supports both feature sets, with either implementation simply ignoring some of the unsupported directives of the other. This would take a lot of discussion and back-n-forth, and I think it might thwart experimentation. You're welcome to have a shot at it, like I said, you could easily plug in your own parser to create beancount.core.data objects. I veered away from Ledger-compatible syntax on Beancount v2 because I was trying to make mine very "regular" and simple - I'm really happy with the resulting syntax actually - and we had already both implemented features not available in the other system, so there was no point in trying to remain compatible anymore. - How good is support for multiple currencies? That's one of my > issues with ledger. > AFAIK Ledger supports multiple currencies quite well, what problem are you facing, specifically? Beancount is currency-agnostic as well - that was entirely inspired by John's ideas from Ledger - and I have used it with many currencies for many years. I declare CAD and USD as my "operating currencies" which *only* has an impact on reporting (I split out operating currencies in their own columns in the tables of the web interface). Otherwise, there's nothing special about any currency anywhere, no special treatment for any of the "commodities" used; I imposed that invariant on purpose in v2, I thikn it's elegant. The one problem that was tricky to solve with currencies is correct handling of "conversion error," with conversions using the @ price syntax, that is, not tracking commodities with cost, but for example, moving money between countries. A conversion transaction needs to be inserted in the balance sheet to account for this exactly. It works, but it's a bit tricky to explain and understand. Most people won't even have those anyway. - How active are you and are you interested in getting beancount to > work for others? If so, I'd be happy to give it a go and report > issues I run into. Very. On the one hand I'm a bit of a perfectionist, and I'm trying as much as possible to make it usable by others - there is nothing specific to me in the codebase, it's very generic, it works now, see the example file and check out the web front-end. On the other hand, I tend to work long hours in my "real job," so my weekend bandwidth is limited, and because it already works quite well I don't have as much feel an urgency in polishing it to make it complete complete (see TODO file). Admittedly, I'm also not very good at "selling" my projects... I just do them for myself. If it's useful to you, awesome. If not, well I still get to use it and I'm still happy. I do address comments when I get them and respond to them, especially bug reports. I fix all bugs. The main objection to new features I have is in the addition of complexity. I tend to want to avoid new default features unless they're generic and potentially useful to others, and well-defined, and so I could be annoyingly resistant to new features, unless they're convincingly generic and keep things simple. -- --- You received this message because you are subscribed to the Google Groups "Ledger" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/d/optout.
