Comments (8)
That's clear enough for me. I'll continue my development efforts following the design guidelines.
from dali-rp2.
Thanks for raising this: it allows me to clarify some of DaLI and RP2 design decisions. It also made me realize this is missing from the Design Guidelines section of the documentation, so I updated it.
One of the design principles of RP2 and DaLI is that all global state is immutable: of course in Python there is no such thing as global constants, so this boils down to convention more than anything else. In other words: any global state is initialized where it is declared and then never modified again. This convention is valid throughout the code and gives us the advantages of immutability for global state, even though Python itself doesn't support the concept at the language level.
The configuration dictionary is built bit by bit at runtime as main() parses the .ini file, so in my mind it doesn't fit the above description of an immutable global. This is why I left configuration as a pass-in variable. Hope this helps.
from dali-rp2.
Thanks for the clarification. I agree immutable objects have advantages over mutable objects and the configuration object is an ordinary dict which will be potentially exposed to changes wherever it is used. Those changes can happen regardless of whether the config is global or passed-in. My reason for wanting the global state is because it encourages developers to increase product flexibility by adding new configuration parameters in a low-cost way. We only need to change the code where the configuration is used, and don't need to change all the higher-level calling functions.
Is there a way we can get the best of both worlds? Can you think of a good way to construct an immutable configuration after parsing and validating the ini file?
from dali-rp2.
I'm not sure I understand your point: configuration parameters and sections can still be added easily today with the existing structure. There is no need to change higher level calling functions when adding parameters to the configuration. Could you elaborate?
from dali-rp2.
Maybe I'm thinking about this the wrong way, or was I unclear? Let me try again. Consider the function calling diagram below.
We have 5 modules: main, A, B, C, and the configuration module (not shown).
We have 6 functions: main, A1, A2, B1, B2, C.
We have 6 function calls shown by the arrows.
main -> A1 -> B1
\
C
/
main -> A2 -> B2
Imagine the code is initially designed such that the configuration object is built in main, but it is not used in any of the other functions shown, so it is not passed as a function argument to any of them.
Later, we decide to add configurable behavior to function C and nowhere else.
Regardless of whether the configuration object is global or not, we will modify the configuration module (not shown) and the main module to validate and add the new configuration parameters.
If the configuration object is global, we reference it in function C, but none of the function calls are modified because none of the function signatures are changed.
If the configuration object is not global, we will modify 4 additional functions A1, A2, B1, B2 and all 6 function calls to accept the configuration object as a function argument. None of those functions will use the configuration object in any way other than passing it along.
Since the function signatures change, all the unit tests for all the functions will also change to construct and pass-in the configuration object.
When the PR is submitted, the reviewer will need to examine the code changes in all the functions and tests, spread across multiple modules.
This is what I meant by changing the higher-level calling functions and why I like the low-cost approach of referencing a global object where the configurable behavior is needed.
Am I misunderstanding something?
from dali-rp2.
Let me use real code from the repository to explain what I mean and avoid ambiguity:
- the
input_loader()
function createsdali_configuration: Dict[str, Any] = DEFAULT_CONFIGURATION
, then - it initializes it the dictionary with info from the config file and passes it to a few functions, like for example
- the transaction resolver:
resolve_transactions(transactions, dali_configuration, args.read_spot_price_from_web)
- the transaction resolver is now free to use any information from dali_configuration it wants (e.g. the transaction hints section).
Now let's consider two cases:
- a parameter
foo
is added to the transaction hints section; - a new section
bar
is added to the configuration, containing new parameters.
In both of these cases no code needs to change in the transaction resolver or any other function (unless of course the function needs to use the new parameters/sections). When the PR adding 1. and 2. is submitted, the reviewer only has to review the actual changes to the configuration logic: function signatures are unaffected.
from dali-rp2.
Ok to close this issue?
from dali-rp2.
Closing.
from dali-rp2.
Related Issues (20)
- Implement aliases for assets on specific exchanges HOT 12
- Pricing for dates before asset is listed on Binance.com are inaccurate HOT 2
- Weigh vertexes in Djikstra based on monthly volume for the CCXT pair converter HOT 23
- Negative Transaction Fees and transaction_resolver errors HOT 11
- Asset missing from graph HOT 10
- 2 same uniqueID transactions in binance´s dust trade. HOT 3
- Spot price for XXX->YYY not found on any pair converter plugin HOT 7
- Kraken Rest API _initialize_markets broken HOT 3
- Bitbank withdrawals rest API HOT 4
- 2 transactions with same uniqueID in binance HOT 7
- Bitbank widthdrawals status CONFIRM_TIMEOUT
- ExchangeNotAvailable hang time HOT 2
- Override or fallback exchanges HOT 4
- Unrecognized dividends in binance HOT 4
- Missing fiat to crypto transactions in binance HOT 3
- Implement Binance Japan Data Loader Plugin HOT 1
- Unnecessary check in dali_main regarding missing NATIVE_FIAT.value
- Error with coinbase asking for apikey HOT 4
- ETH2 fetch price problem HOT 7
- LUNA->EUR not found HOT 5
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from dali-rp2.