Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Constraint: accounts with always positive / negative postings #108

Open
hrj opened this issue Sep 21, 2016 · 8 comments
Open

Constraint: accounts with always positive / negative postings #108

hrj opened this issue Sep 21, 2016 · 8 comments

Comments

@hrj
Copy link
Owner

hrj commented Sep 21, 2016

Some accounts should allow only positive (or only negative) postings.

Ideally, the user should be able to specify an arbitrary condition on the posting amount. Positive (or negative) are just special cases.

@hrj hrj added this to the Version 0.3.2 milestone Sep 21, 2016
@hrj hrj modified the milestone: Version 0.3.2 Nov 3, 2016
@z4f1r0v
Copy link
Contributor

z4f1r0v commented Nov 6, 2016

@hrj I'm on it :)

@hrj
Copy link
Owner Author

hrj commented Nov 7, 2016

Hey @alexanderzafirov. I suggest we discuss the changes before implementing them. We could avoid wasted effort if understanding is clearer.

To be honest, I have myself not thought deeply about how to implement some of these ideas. I have a hunch that we could unify several ideas if we design an expression evaluator and define an API that can be used in the configuration file.

There is already an expression evaluator available for use in .ledger files. We could define an API (pre-built functions and objects) for interacting with account and transaction info. With such an API, users could specify Txn-filters (refer #78) as well as constraints such as in this issue.

I also wonder whether creating our own mini-expression language is better or is it better to embed a fuller general purpose language, such as Javascript, Lua, or Scala!

@z4f1r0v
Copy link
Contributor

z4f1r0v commented Nov 8, 2016

Hey @hrj. That's a good idea. This looks like a bigger task than the previous ones so I definitely need some guidance as the domain is foreign to me. However, I am quite intrigued and willing to help so please be patient with me :)

Before we proceed with the actual task may I request of you some kind of high level diagram that describes the project and the key concepts - in Domain Driven Design (DDD) that would be called ubiquitous language.

Right now I am trying to comprehend quite a few things from both conceptual and implementation point of view. Let's start with the business use case:

Some accounts should allow only positive (or only negative) postings.

What are these postings? Is it the addition/subtraction of an amount?

the user should be able to specify an arbitrary condition on the posting amount.

What are these arbitrary conditions? Can you provide some examples, please?

Again I hope you are not discouraged by these questions and do find time to explain to me. I'm sure that once I have some background I can start looking around the code with a fresh pair of eyes. Thanks!

@hrj
Copy link
Owner Author

hrj commented Nov 9, 2016

Not at all; feel free to ask questions. I have been lagging in documenting the terminology and features of abandon.

What are these postings? Is it the addition/subtraction of an amount?

I should have used the word "post" rather than "posting". In abandon, we are using this terminology:

  • Post : The change (debit / credit) of a single account
  • Transaction: A dated set of a balanced posts. Balanced means the sum of all posts in a transaction should be zero.

For example, in the following ledger entry:

2016/Nov/1
  Cash          -100
  Bank

.. there is one transaction on 1st Nov 2016, containing two posts:

  1. Cash decremented by 100
  2. Bank incremented by 100

What are these arbitrary conditions? Can you provide some examples, please?

For example, user may want to have a constraint that all transactions should be within a date range. Or that the value of a post should be always positive for an account (the topic of this issue). There might be more unforeseen constraints.

@z4f1r0v
Copy link
Contributor

z4f1r0v commented Nov 9, 2016

That makes things clearer now.
As for the implementation thoughts you shared:

There is already an expression evaluator available for use in .ledger files.

Are you talking about Eval and Parser classes?

We could define an API (pre-built functions and objects) for interacting with account and transaction info. With such an API, users could specify Txn-filters (refer #78) as well as constraints such as in this issue.

What do you mean by pre-built functions and objects?

I also wonder whether creating our own mini-expression language is better or is it better to embed a fuller general purpose language, such as Javascript, Lua, or Scala!

Can you please elaborate more on this idea? I think that Scala is perfect for defining a DSL (mini-expression language) like the one you would like to have

@hrj
Copy link
Owner Author

hrj commented Nov 10, 2016

Are you talking about Eval and Parser classes?

Yes indeed, especially Eval.scala

What do you mean by pre-built functions and objects?

Basically, an API for the user. For example, the user might want to define the positive constraint as follows:

def constraint(txn) = txn.posts.forEach( p => if (p.accountName == "Income") p.amount > 0 else true)

(Check all posts for "Income" account to have a positive amount)

Can you please elaborate more on this idea? I think that Scala is perfect for defining a DSL (mini-expression language) like the one you would like to have

The main problem with embedding a general purpose language is that its syntax won't gel with the ledger syntax.

If we do embed a general purpose language, Scala would be my preference too, but it has a big run-time overhead since it is a compiled language.

Scripting languages would have lower warm-up time. Javascript can be easily supported in JVM (either via the inbuilt Nashorn engine, or via Rhino).

The other option is to continue enhancing the current Eval engine.

It will take some time to decide this. If you are eager to contribute code, please feel free to work on a simpler issue in parallel 😄

@z4f1r0v
Copy link
Contributor

z4f1r0v commented Nov 14, 2016

When I said that Scala is good for making DSLs, I supported the claim that the Eval engine should be expanded. I really don't know much about ledger but it seems to me more challenging - in a good way - and less cumbersome to explore the state space of solution by making the Eval engine better rather than throwing a general purpose language at a narrow use case.

If you agree with this statement let's have an incremental plan of attack. What should I tackle first?

@hrj
Copy link
Owner Author

hrj commented Nov 15, 2016

When I said that Scala is good for making DSLs, I supported the claim that the Eval engine should be expanded.

Ah, my apologies. I had read it in a different way.

.. making the Eval engine better rather than throwing a general purpose language at a narrow use case.
If you agree with this statement let's have an incremental plan of attack. What should I tackle first?

I agree with it. I think the systematic way of doing this would to be first propose a design for the features, that encompasses:

  • Types supported (integer, boolean, functions, maps, arrays, etc)

  • Syntax of the eval language

  • How a value / function can be defined in config files or command line parameter. If we support anonymous functions then we could support, for example, the following config file syntax:

    constraint += "def(txn) = blah.blah"
    

    To begin with, anonymous functions need not be supported; user would simply have to ensure that function names are unique.

  • Which features can be targeted through this effort? Constraints and Filters come to mind.

  • What API would be available to the user?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants