How to properly debug OCaml code? - functional-programming

Can I know how an experienced OCaml developer debugs his code?
What I am doing is just using Printf.printf. It is too troublesome as I have to comment them all out when I need a clean output.
How should I better control this debugging process? special annotation to switch those logging on or off?
thanks

You can use bolt for this purpose. It's a syntax extension.
Btw. Ocaml has a real debugger.

There is a feature of the OCaml debugger that you may not be aware of which is not commonly found with stateful programming and is called time travel. See section 16.4.4. Basically since all of the information from step to step is kept on the stack, by keeping the changes associated with each step saved during processing, one can move through the changes in time to see the values during that step. Think of it as running the program once logging all of the values at each step into a data store then indexing into that data store based on a step number to see the values at that step.

You can also use ocp-ppx-debug which will add a printf with the good location instead of adding them manually.
https://github.com/OCamlPro-Couderc/ocp-ppx-debug

Related

Static data storage on server-side

Why some data on server-side are still stored in DBC files, not in SQL-DB? In particular - spells (spells.dbc). What for?
We have a lot of bugs in spells and it's very hard to understand what's wrong with spell, but it's harder to find it spell...
Spells, Talents, achievements, etc... Are mostly found in DBC files because that is the way Blizzard did it back in the day. It's true that in 2019 this is a pretty outdated way to work indeed. Databases are getting stronger and more versatile and having hard-coded data is proving to be hard to work with. Hell, DBCs aren't really that heavy anyways and the reason why we haven't made this change yet is that... We have no other reason other than it being a task that takes a bit of time and It is monotonous to do.
We are aware that Trinity core has already made this change but they have far more contributors than we do if that serves as an excuse!
Nonetheless, this is already in our to-do list if you check the issue tracker at the main repository.
While It's true that we can't really edit DBC files because we would lose all the progress when re-extracted or lost the files, however, we can modify spells in a C++ file called SpellMgr.
There we have a function called SpellMgr::LoadDbcDataCorrections().
The main problem while doing this change is that we have to modify the core to support this change, and the function above contains a lot of corrections. Would need intense testing to make sure nothing is screwed up in the process.
In here by altering bits you can remove or add certain properties to the desired spells instead of touching the hard coded dbc files.
If you want an example, in this link, I have changed an Archimonde spell to have no cast time.
NOTE:
In this line, the commentary about damage can be miss leading but that's because I made a mistake and I haven't finished this pull request yet as of 18/04/2019.
The work has been started, notably by Kaev. I think at least 3 DBCs are now useless server side (but probably still needed client side, they are called DataBaseClient for a reason) like item.dbc.
Also, the original philosophy (for ALL cores, not just AC) was that we would not touch DBC because we don't do custom modifications, so there was no interest in having them server side.
But we wanted to change this and started to make them available directly in the DB, if you wish to help with that, it would be nice!
Why?
Because when emulation started, dbc fields were 90% unknown. So, developers created a parser for them that just required few code changes to support new fields as soon as their functionality was discovered.
Now that we've discovered 90% of required dbc fields and we've also created some great conversion tools for DBC<->SQL, it's just a matter of "effort".
SQL conversion is useful to avoid using of client data on server (you can totally overwrite them if you don't want to go against EULA) or just extends/customize them.
Here you are the issue about DBC->SQL conversion: https://github.com/azerothcore/azerothcore-wotlk/issues/584

Why do require to change code runtime?

I found many languages provides some way to change code runtime. Many people ask queries regarding how to change code in this or that language runtime. Here I mean by change code is that rewrite code itself at runtime by using reflection or something else.
I have around 6 year of experience in Java application development. I never come again any problem where I have to change code at time.
Can anyone explain why we require to change code at runtime?
I have experienced three huge benefits of changing code at runtime:
Fixing bugs in a production environment without shutting down the application server. This allowed us to fix bugs on just some part of the application without interrupting the whole system.
Possibility of changing the business rule without having to deploy a new version of the application. A quicker deploy of features.
Writing unit test is easier. For example, you can mock dependencies, add some desired behaviour to some objects and etc. Spock Framework does well this.
Of course, we had this benefits because we have a very well defined development process on how to proceed on this situations.
At times you may need to call a method based on the input, that was received earlier in the program.
It could be used for dynamic calculation of value based on the key index, where every key is calculated in a different way or calculation requires fetching required data from different sources. Instead of using switch statement you can invoke a method dynamically using methodName+indexOfTheKey.

Advanced compilation level - list of removed methods

I've started to use closure compiler and still hittin lot's of obstacles:)
I'm looking for the option that will output the list of removed methods/properties whatnot during the optimisation done by compiler - this would help me a lot when debugging the code.
There is no default option that lists removed symbols.
This should be possible by using a tool to highlight all of the lines that have mappings in a generated source map. Any line that has no mapping was dropped as dead code.
However I have not stumbled across a tool that would do this. It would be highly useful though and not specific to Closure-compiler.

Is it possible to include the os library in lua 4.0?

I'm stuck using the 4.0 version of lua which does not seem to support the os library. Is there a way to include this library into my project?
Or get another way to use the functionality contained within pertaining to date time calculations?
Preferably by using a *.lua file and not a *.c file since I don't have complete access to the code.
When I run the following line,
print(os.time{year=1970, month=1, day=1, hour=0})
I get an error stating:
attempt to index global 'os'(a nil value)
As #Colonel Thirty Two said it's not possible to use the os library. So the time() funciton is not available for me.
Adding to the (totally correct) currently accepted answer (that if "os" access was not allowed to you, you're generally done), there's some very slight chance the Original Programmer may have provided you with some alternative facilities to do your thing (fingers crossed). In a perfect world, those would be described in some kind of a User's Manual for your scripting environment. But if the manual was lost to time (or never existed in the first place), you might possibly try your luck at exploring any preloaded libraries by digging through the result of the globals() Basic Function. (At least I hope that's how it was done in 4.0 too.) That is, if the Original Programmer didn't block globals() for you too...

Classic ASP - Detect line number and file from which a function is called?

Our application is made in good (?) ol' classic ASP. Not ideal but it works and it's pretty stable - has been for 10-15 years. It is not particularly well documented in places, such as where a 'translation' (client-controlled piece of text) appears. All we have against a translation is a clientid and translationid, neither of which are particularly helpful. I've tried searching the (10s of thousands of lines of) core code for gettrans(1) (translation 1) and can see that doing this for another 3100 is going to be a nightmare, not to mention inaccurate as there are many functions which are called with a transid passed into them, and then they call gettrans(transid).
My last thought on this matter is the possibility that we could maybe detect, from gettrans, where a function is called from - not just the line number but the file name of the include (thankfully the includes are named usefully so figuring out where a translation is used should not be too hard!). I highly doubt that it would be possible to get the include name on the basis that includes are processed before ASP, but I'll settle for the overall filename and then we can combine the includes to get to the line of code and log the include file name.
I very much doubt this is possible and can't find anything on SO or Google. Does anyone know of any way to achieve this, or have any pointers on what I might try? Thanks in advance.
Regards,
Richard
Most you can achieve is getting the currently executing script, which can be obtained by:
Dim currentPage
currentPage = Request.ServerVariables("SCRIPT_NAME")
When inside included page it will give you the "parent" page.
However getting "callee" information is not possible with classic ASP as far as I know, so you will have to add another parameter to the function being called then change all calls to pass the parameter in order to identify where it comes from. Looks like someone did something similar and called it ASP Profiler, use it at your own risk of course. (Never tried myself)

Resources