Hacklang command line program in strict mode - command-line

Is there any way to create command line programs in strict mode of Hack? As Hack's strict mode does not allow statements outside a function I can't call my main function.
(This is rather a theoretical question as it is easy to circumvent the problem by having a non-strict file to call the main function.)

It's currently not possible to write a project (command line program or otherwise) 100% in Hack strict mode due to this limitation. You will indeed need to have some bootstrap code in the toplevel ("pseudomain"), which strict currently just does not allow. The reason for this is that toplevel code is basically impossible to statically typecheck, since everything is a global and can be changed behind the scenes at any time by any code.
However the end result is silly and something we want to fix eventually -- there is, for example, no reason to prevent a single call to a function with no parameters, i.e., exactly what you need to immediately get out of pseudomain and into a function.

Related

Portacle Lisp : Slime-repl-sbcl prompt keep auto-scrolling back

as the title said, I am learning common lisp right now and using portacle, following Practical Common Lisp by Peter Seibel.
I found it quite annoying that the Slime-repl-sbcl buffer keep the writing at the end of the screen (using C-l or C-v doesn't help since once I try to execute an expression it will roll back to the end of the screen)
Is there anywhere to improve this? (should I just write on a text file and compile it? the only similar subject I found was about Cider repl and couldn't understand it, since I am still new to lisp)
Thank you for your time
I would like this fixed too. No solution yet. In slime-repl.el, I found:
scroll-conservatively (variable):
A value of zero means always recenter point if it moves off screen.
my test wasn't conclusive.
slime-display-output-buffer (function), which calls slime-repl-show-maximum-output, which role is to
Put the end of the buffer at the bottom of the window.
I rewrote slime-display-output-buffer without this call, but that wasn't conclusive either.
Maybe I tested badly.
(I'm making this answer a wiki)
You would indeed typically write in a source file, and compile each expression separately. Use the REPL only to test functions or do simple computations. To compile functions (or really, any toplevel expression), use C-c C-c - bound to slime-compile-defun by default - when the point (= your cursor) is inside the function's code. The REPL will then "know" of it, so you can test it there, but as it is now written in file, you can also modify it without having to copy/paste anything ! Just make sure to recompile functions that you modify !
If you want to compile/load entire files at once, look at the other compilation commands, e.g. slime-compile-and-load-file (see the SLIME manual, and its Compilation section)
For your problem: there is Emacs variable, named comint-scroll-to-bottom-on-input (or something along those lines, can't remember exactly ...) which enables the behaviour you are seeing, so that you don't have to scroll back to enter new expressions. It is possible that SLIME has another variable which configuring this behaviour for its REPL; in that case, it would probably be named almost the same, and you can set it to nil to disable it.
Finally, don't hesitate to look at the other tools provided by SLIME ! For example, it comes with an "inspector" (see the relevant section), that you can use instead of evaluating expressions such as *db* in the REPL. In that simple case, it makes no real difference, but if you start having - say - hash-tables or different structures/classes, it becomes an incredible tool for interactive development, to examine the internal of almost everything, redefine things directly from within the inspector without needing complex accessors, and so on.

Debugging live stack frames in Common Lisp ( SBCL) .How does the debugger/compiler implement this capability?

Lisp allows one to recompile segments of code during debugging producing live stack frames. I know that lisp is dynamic and that it's easy to rebind a symbol associated to a method. However Lisp also easily allows to redefine single forms inside a function. This is even more powerful and flexible than what C# and Java debuggers can do. Why and how does it work? Why modern languages do not provide the same level of sophisitication? Where I can find some papers or books so to learn more?
It's not magic. I did the same in the old days in assembly. I created a DOS TSR program that pointed the interrupts I could handle to my own location. When you did a division by zero or something like that it jumped into my program and the stack had all the previous programs stack and where it had gone wrong. I just provided a menu with ways to mend it so that it didn't exit with DOS default behaviour.
In CL you have like a default exception handler that calls a function that you can see your options on restarts. Restarts are like code within the scope of where the error originates with ways to mend the situation. It's possible to make something like this in any language that has exceptions and closures. The debugger and restarts become a part of the running program and thus it becomes more safe on the cost of less performance. Here is a JavaScript implementation.
There is a way to turn it off and it might make your programs faster in CL. The standard does not require to do anything so it's optional, but implementations do make unsafe fast code that might end up as a segmentation fault instead of the debugger.

Set arbitrary breakpoint in debugger

I have been using the perl interactive debugger (basically perl -d script)
I have a script that has quite a lot of modules imported and I need to debug a problem.
What I do is start the debugger and go over lines, stepping into where necessary.
But this is tedious as I need to step into many lines of code and function calls.
Question: Let's say that after going over the lines of code I eventually step into function A::B::C::foo() of some module where is the problem I am debugging.
Is there a way to set a break point in that function in the beginning of the debugging session so that I jump there directly instead of going over the code line by line until I reach there?
I know that I can add a break point in the same file my debugger is currently but how can I add a breakpoint in a line that is outside of the debugger's scope at this point (to some arbitrary file/module that eventually the debugger would have reached)?
Note:
Just to clarify: It is not like A::B::C::foo() is in line X of the script. It is eventually called after going down the call chain of a lot other functions in many modules
You can set a breakpoint to a subroutine with the documented b sub syntax. In this case, just use
b A::B::C::foo
c
You may set a break point by defining file name and then line number
b YourModule.pm:line_number
where line number is inside the module function you want to break at.
You can even put a breakpoint on a sub that hasn't been loaded/defined yet using the postpone option:
b postpone Name::Of::Sub::Yet::To::Be::Created

would it be worth it to use inline::C to speed up math

i have been working on a perl program to process large amounts of dna. It outputs exactly what i need however it takes much longer than i would like using NYTprof i have narrowed down the major problem areas to be the loop that adds my values together. would using inline::C to do the math make my program faster or should i accept the speed and move on? is there another way to improve the speed? here is my program and an input it would run as well as an executable with the default values entered already.
It's unlikely you'll get useful help here (this included). I can see various problems with your code, and none have to do with the choice of language.
use CPAN. If you're parsing genbank, then use some an appropriate module.
You're writing assembly in Perl, and neither Perl nor you are very good at that. It's near impossible to know what's going on when you don't pass parameters to subroutines, instead relying on globals all over the place. What do #X1, #X2, #Y1, #Y2 mean?
The following might be your problem: until ($ender - $starter > $tlength) { (line 153). According to your test case, these start by being 103, 1, and 200, and it's not clear when or if they change. Depending on what's in #te, it might or might not ever get out of the loop; I just can't tell from your code.
It would help if we knew, exactly, what are the parameters to add, the in-out invariants, and what it is returning.
That's all I got.
I second the recommendation of PDL made in a comment, if it's applicable. Or the use of a CPAN module tailored to your problem (again, if applicable).
I didn't see anything that looked unambiguously like "the loop that adds my values together" in that code; please, show just the code you are considering optimizing, ideally with just enough structure around it to actually run it.
So to answer your generic question generically, yes, Inline::C can be a useful tool for optimization if you are certain your performance problem is limited to what it actually can do for you. In using it, be aware that invoking your C code from Perl or vice versa is non-trivially expensive, so you have to have enough code translated to C to minimize the transitions.

How can I force unload a Perl module?

Hi I am using a perl script written by another person who is no longer in the company.
If I run the script as a stand alone, then the output are as expected. But when I call the script from another code repeatedly, the output is wrong except for the first time.
I suspect some variables are not initialised properly. When it is called standalone, each time it exits and all the variable values are initialised to defaults. But when called from another perl script, the modules and the variable values are probably carried over to the next call of the script.
Is there any way to flush out the called script from memory before I call it next time?
I tried enabling warning and it was throwing up 1000s of lines of warning...!
EDIT: How I am calling the other script:
The code looks like this:
do "processing.pl";
...
...
...
process(params); #A function in processing.pl
...
...
...
If you want to force the module to be reloaded, delete its entry from %INC and then reload it.
For example:
sub reload_module {
delete $INC{'Your/Silly/Module.pm'};
require Your::Silly::Module;
Your::Silly::Module->import;
}
Note that if this module relies on globals in other modules being set, those may need to be reloaded as well. There's no easy way to know without taking a peak at the code.
Hi I am using a perl script written by another person who is no longer in the company.
I tried enabling warning and it was throwing up 1000s of lines of warning...!
There's your problem right there. The script was not written properly, and should be rewritten.
Ask yourself this question: if it has 1000s of warnings when you enable strict checking, how can you be sure that it is doing the right thing? How can you be sure that it is not clobbering files, trashing data sets, making a mess of your filesystem? Chances are it is doing all of these things, either deliberately or accidentally.
I wouldn't trust running an error-filled script written by someone no longer with the company. I'd rewrite it and be sure that it was doing what I needed it to do.
Unloading a module is a more difficult task than simply removing the %INC entry of the module. Take a look at Class::Unload from CPAN.
If you don't want to rewrite/fix the script, I suggest calling the script via exec() or one of its varieties. While it is not very elegant to do, it will definitely fix your problem.
Are you sure that you need to reload the module? By using do, you are reading the source every time and executing it. What happens if you change that to require, which will only read and evaluate the source once?
Another possibility (just thinking aloud here) could be to do with the local directory? Are they running from the same place. Probably wouldn't work the first time though.
Another option is to use system ('doprocessing.pl');. Lazily, we do this with a few scripts to force re-initialisation of a number of classes/variables etc. And to force the log files to rotate properly.
edit: I have just re-read your question, and it would appear that you are not calling it like this.