Over the last 10 days, I've been reading "Programming in Scala" and writing some Scala code.
As you can see in my GitHub Scala playground, I am starting to really like this language - it is as fast as OCaml (thanks to JVM's HotSpot technology), protects me from my typos (and bugs!) with its strong and static type system, and best of all: enterprise-wise, it doesn't live in a remote "island" (like Haskell and OCaml) ... because it has the huge ecosystem of the JVM.
My only problem so far:
Even though I've figured out how to develop my Scala code under VIM with sbt-quickfix, or under Emacs with Ensime (and thus have autocompletion and error navigation), I have so far failed to find a way to debug my code, with the same ease that I do for Python:
bash$ python -m pdb ./someCode.py
All the entries Google points to, are basically saying: "use this IDE that I really like..."
There are reasons however - no point in enumerating them, you either know them or you don't - that people like me prefer (a) programmable editors and (b) a standalone debugger, available outside their editor.
If you are one of the few like-minded people that dislike IDEs and happen to use Scala, I'd be really interested to know how you debug - in fact I'd be interested to hear your entire workflow.
Mine, so far is:
Add the sbt-quickfix to my SBT's project/ folder (just look at my code in this GitHub repos)
Spawn sbt in a terminal, and run ~compile so that it automatically builds when I change something in my sources
VIM automatically receives errors and shows them.
When compilation is green, hit ENTER in the sbt terminal, type run
etc
Ensime is even better, allowing auto-completion as well:
sbt gen-ensime
Spawn emacs editing one of my .scala files, and M-x ensime
Use ensime-typecheck-all (mapped to F7 in my dotfiles) and when all is OK...
ensime-sbt-do-run
Here's to hoping I am not alone - and that someone out there will help me with standalone debugging, too... the last challenge before I fully embrace Scala :-)
Turns out ensime has a debugging mode, which I somehow missed. Paired with Emacs/evil, I've spent the last couple of days inside Emacs and Scala - and it all works perfectly... autocompletion, spawning sbt in a buffer when I want to run, and debugging.
My only remaining problem is about working with Ensime from inside screen-ed sessions, which is my usual modus operandi (over SSH connections). The markers of Ensime debugger's current line and breakpoint set are placed on the left fringe - which works fine in graphics mode Emacs, but isn't visible in text-mode Emacs. I've opened a ticket and the guys there apparently have a plan for a solution.
Related
I'm coming from VSCode to Neovim, and for the most part I've been able to accommodate/replicate the workflows and functionality I've gotten used to in VSCode in Vim. Right now, I'm stuck on replicating the Link functionality of the VSCode integrated terminal.
This lets you mouse over text like main.py or server.go:50 and ctrl-click to jump to that file or line location in your editor panes. This really helpful for jumping to the locations of compilation errors or test failures from their associated terminal output.
I've searched for existing plugins/solutions for this but haven't found any. Are there any that I've missed? Otherwise, what might be a good approach to scripting this myself?
I'm new to vimscripting, but I'd assume you could do some regex and with knowledge of the current working directory, you could infer the correct filepath to open.
Replicating one editor's workflow in another is not exactly a good idea as the two editors have—supposedly, if not why switch in the first place?—different feature sets or even paradigms. For instance, staying in insert mode all the time in Vim because that's what you are used to would make no sense because Vim derives most of its value from its modality… and you would probably also find examples in the other direction.
Case in point, compiling and jumping to errors in Vim typically doesn't involve the built-in :terminal at all. You are supposed to use the :help quickfix feature, which exists for that very purpose.
See :help 30.1 for a gentle introduction from the user manual.
Like a few of the askers on here, I'm new to Lisp. I'm going through the Practical Common Lisp book, but took a sidestep to see how easy it would be to set up a web app, so I've been following this tutorial, as well as the updated version here.
When I get to the point where I start the server, my REPL dies, and I can't then push anything onto the *dispatch-table*.
So basically, I have code working great in the REPL, adding objects to a list, retrieving them, etc., then I start the server using
(setf *web-server* (start (make-instance 'hunchentoot:acceptor :port 8080)))
which works great, and I can access it on http://localhost:8080. However when I access it, the logs print to the REPL and I'm unable from that point to actually use the REPL. So for example, following Adam Petersen's post, I can't then
(push (create-prefix-dispatcher "/retro-games.htm" 'retro-games) *dispatch-table*)
because the REPL is unresponsive. I've tried starting the server from different windows (i.e. from SBCL in terminal) but then it's unaware of the context I'm in - it doesn't understand the package I'm working on or any of my code.
I'm using a slightly non-standard setup; I'm on OSX and using Sublime Text 2 with SublimeREPL and SBCL (because I'm really not into Emacs and ST2 is great!). I've described how I put it all together here - but I'm really only posting that just in case, I'd be surprised if it's my setup causing problems as opposed to some basic thing I'm missing.
Anyway, I understand that I could go ahead and set up hunchentoot in a more production-like environment, and have seen some posts detailing that and accessing the REPL remotely, but I was hoping there would be something simpler for messing around with that I've just missed.
Make sure your SBCL was compiled with thread support. When running single-threaded, the Hunchentoot request handling loop does not return to the REPL.
Threading is not the default setting in the binaries from http://www.sbcl.org/ for Mac OS X. On Mac OS X, I usually download the sbcl.org binaries to get started, then download the sources and rebuild with ./make.sh --fancy to get a number of fancy features, including threads. See the INSTALL document in the sources for details.
I currently work on a big Fortran project with emacs, but I have the feeling that my current setup is inadequate to the task.
I use f90-mode with auto-complete (without fortran-specific setup, so I only have completion for opened files), and I really miss function header information on hover (as in elisp code), code-folding, lists of subroutines in the current buffer, lists of included files, info on the origin of subroutines and used variables (C-xC-f to open the source file?), …
How can I best add modern supporting functionality for fortran in my emacs?
Mostly I need tools which help me understanding the projects code.
The project uses its own build tool and copies files from different directories into a build directory before building, actually overwriting some files with different versions of the code, so I need a quite flexible tool which can cope with that.
There's a small Emacs plugin called Fortran-tags. It can find the definition of any variable or procedure under the cursor, so it's similar to Ctags, except that it is able to correctly identify all local and global variables and has some additional features. Also, it is developed with the focus on modern Fortran.
Using fortran-language-server (after installation simply start fortls in the terminal) and lsp-mode in emacs works perfectly.
I now found the f90-interface-browser in elpa.
If you use emacs 24 or later, you can just use
M-x package-list-packages
and then search for f90-interface-browser.
You write (or work on) large, modern fortran code bases. These
make heavy use of function overloading and generic interfaces. Your
brain is too small to remember what all the specialisers are
called. Therefore, your editor should help you.
I'm looking for a good Scala IDE.
I tried the Eclipse (Some time ago) and IntelliJ Idea (In these days) plugins but I am somehow dissatisfied by both of them. The first it was pretty slow and unstable, while I don't like too much IntelliJ Idea's interface.
Is there any alternative available?
I will work with a SBT project and what I am looking for is mainly syntax highlighting, autocompletion. It would be nice to have partial compilation of the source code as I am not used to Scala syntax and it would help me find errors as soon as I write them.
IMHO InteliJ is the best IDE for Scala at the moment. First I had also some problems with the different interface compared with Eclipse. But in the end you profite from the whole package included with IntelliJ. There is also an active scala plugin development.
What I like to do is split my terminal once horizontally, and then split the bottom pane once vertically.
In the top pane I have vim (emacs works too if you're an emacs person) with the NERDTree plugin (acts like the project folder/file browser in text editors). On the bottom left I have SBT continuous compilation (sbt ~compile). I use the bottom right pane to actually run code (tests, etc.).
Regarding auto-completion, you can try something like the Snipmate plugin for vim.
Also, as stated by Ivan, if you end up using emacs ENSIME seems to be widely liked - unfortunately there doesn't seem to be an ENSIME port for vim yet, at least to my knowledge.
With this setup, I edit in the top pane, and once I save a file, I get near immediate feedback by just glancing on the bottom left and know when I typo'ed something, or maybe my code is just plain wrong, stuff like that.
On a slightly related note, I used to use IDE's but they got too messy for my taste (back then I was writing C and C++) so I moved to just a text editor (e.g. Chocolat, Sublime Text 2) and used a terminal, and that was fine for me for about a year. Then this summer I really sat down and tried going vim only and I can honestly say I'm much more productive in my all terminal setup than what I was before. Just my 2 cents.
This all also has the added benefit of working on remote servers as well.
Scala IDE for Eclipse is under active development and evolving rapidly. You should give it a try now (I don't know what 'some time ago' means, but if it's more than 6 months you might be pleasantly surprised). Granted, I am biased since I am a committer.
You could try ENSIME for emacs. You can also use it with jEdit, Sublime Text 2, and probably more.
Personally I use Scala IDE 2.1 (for eclipse). It is a lot faster now, and it has gotten to the point where I actually want to use it, after being in a similar situation to you.
I am new to Clojure, and am beginning to experiment with building an application.
So far, everything I've seen about tutorials on compiling Clojure programs involves interactivity. For example, "load up the REPL and type (load-file "this-or-that") to run. This is fine, but it's not enough.
I am so used to the edit-compile-run idioms of languages like C or Delphi, that I am instinctively driven to make edits, then hit "M-x compile".
The problem is that "lein uberjar", which I understand is the equivalent to "make", is painfully slow to execute even for a hello world. So I'm going to have to figure out how this "interactive development" stuff works, stop using the uberjar like it's quick make, and save it only for the end of the day.
Another thing I noticed while building (using lein uberjar) is that the small GUI app I am working on pops up frames in the compilation process, as if they are executing while compiling. It just seems a bit counterintuitive to me; it is not quite as analogous to "make" as I had thought.
I know the Lisp way of developing things is interactively working in the REPL, and I am not trying to change that: I would like to adapt to this way of life. Unfortunately, I have seen little in the form of documentation on how to do so. For instance, how to reset the current state of the machine. It just seems kind of messy to just keep compiling individual snippets on the fly without being able to do some sort of reset.
Most tutorials I have seen on Clojure (and Lisp) in general seem to focus on hacking in the REPL. Best practices on the deployment of applications remains a mystery to me. My users are just going to be users; they are not going to be developers that are going to load files into a REPL.
So here is my question: any resources for good information or tutorials on the entire process of building a Clojure application, including deployment?
(Note: I have all of the prerequisites installed and working (e.g. Emacs, Slime, Leiningen, etc.), so this is not a question about that).
A couple of quick hints, then some links:
Don't use lein uberjar during development; prefer lein jar. The difference is that lein uberjar puts all your dependencies in the generated jar (including Clojure itself), so that your single jar is an entirely self contained package with your app inside; lein jar only jars your own code. The uberjar approach has obvious benefits for deployment, but for development, you should be able to just use the appropriate classpath when running your app, saving yourself the time necessary to prepare an uberjar. If you don't want to hand-manage the classpath for test runs, check out the lein run plugin.
Also, most likely the majority of your code should not actually be AOT compiled. AOT is necessary in some Java interop scenarios, but most of the time it brings one a slight boost in startup speed and annoying problems with binary compatibility with different releases of Clojure. I suppose the latter issue is not relevant to an uberjar-ed standalone app kind of project, but any library code at least should be left to be JIT-ed if at all possible. With Leiningen, you can put a :namespaces clause in the defproject form in project.clj to determine which namespaces are to be compiled; whatever you leave out will currently be JIT-ed by default. Older versions of Leiningen used to compile everything by default, which is actually a good reason to upgrade!
As for the windows popping out during compilation, I would guess that you're either running window-out-popping code during macro expansion time or outside of any function definition or similar construct. (Something like a (println "Foo!") at the top level.) That's just something you shouldn't do, I suppose -- unless you are planning to run your code as a script, anyway. To avoid the problem, wrap side-effecting code up in function definitions and provide an entry point to your application using the :main clause in project.clj. (If you say :main foo, then the -main function from the foo namespace will be used as the entry point to your app. That's the default, anyway, and at least the above mentioned lein run seems to have the name hardcoded -- not sure about lein itself.)
As for resetting the state of the REPL -- you can just restart it. With SLIME, M-x slime-restart-inferior-lisp will do just that while maintaining all other state of your Emacs session.
See also these discussions on the Clojure Google group:
Clojure for system administration
Prepping clojure for packaging (was: Re: Clojure for system administration)
Leiningen, Clojure and libraries: what am I missing?
No, you do not enter functions on the REPL.
You edit your source files, just as usual. The Lisp advantage is that you have the system running in the background at the same time, so you can compile individual functions from your source file and put them into the running system, or even replace them there.
If you use Slime, you press C-c C-c in your source file to compile and load the function at point. You can then switch to the REPL to test and explore, but anything you want to persist as source, you put into your source files.
Tutorials usually start by typing things on the REPL, because there is not much you need to set up for this, but serious development integrates the running system and source file management.
Just to illustrate, my usual workflow (I am using Common Lisp, but Clojure is similar) is like this:
Start Emacs
M-x slime to start Slime, the Lisp system, and connect the two via Swank
, (command) load-system foo to load the current project (compiling only if necessary) into the image
C-x b switch to a source buffer
C-c ~ make the source directory the current directory and the source package the current package of the REPL
Now, I'm set up with my system running in the background. Working is then:
change or add a function or class definition
C-c C-c to compile and load it into the image
switch to REPL, test
debug
There are no significant compilation pauses, because I never compile the whole thing at once, just individual definitions.