How to determine file type in Lisp - common-lisp

Is there anything like file in shell for lisp to determine file type? If not, how do you determine file tpye?
In most case pathname-type is good enough, but sometimes you may run into some files doesn't have been correct named.

The functionality of file is available in libmagic:
As of version 4.00 of the Ian Darwin/Christos Zoulas version of file, the functionality of file is incorporated into a libmagic library that is accessible via C (and C-compatible) linking;[7][8] file is implemented using that library.
Wikipedia
And there is a binding for Common Lisp.
I had to install libmagic-dev on my system, and then:
CL-USER> (ql:quickload :magicffi)
...
(:MAGICFFI)
CL-USER> (magicffi:pathname-mime #P"/bin/ls")
"application/x-sharedlib; charset=binary"
See MAGICFFI.

Related

Why do I need to evaluate defpackage for a new REPL?

I use ADSF to organise my projects.
(asdf:defsystem :sender
:version "0.1.4"
:serial t
:depends-on (:cl-json :dexador :clsql :clsql-sqlite3)
:components ((:file "packages")
(:file "validation")
(:file "sender")))
But when I open a new repl (slime, emacs), I have to go to the packages.lisp file and evaluate the form before I can change the repl to that package with (in-package :sender).
Is there a way to make the slime repl remember my packages?
My current thinking is that I need to "run" adsf to load all my files. If so, how?
UPDATE:
Actually, I need to compile all the files manually before I can actively use them in the repl. I believe I am using asdf incorrectly.
From a .asd system definition, the steps would be:
compile the .asd file, so that you Lisp image knows about the system
C-c C-k or programmatically: (asdf:load-asd "system").
LOAD it somehow: (ql:quickload "system") to install dependencies
or (asdf:load-system "system"), but it will fail if your project has unknown dependencies, Quicklisp would download them.
avoid using cl:load for asdf systems, load-asd / load-system will do more complex stuff.
use it on the REPL. The package that was defined in a packages.lisp file should be available, because this file was declared in the .asd.
You can add stuff to your ~/.sbclrc (or similar for other implementations). Here I tell ASDF where a project lives, so I can quickload it without manually compiling the .asd before:
(pushnew "/home/vince/projets/ciel/" asdf:*central-registry* :test #'equal)
This is an "old" style not encouraged anymore by the ASDF documentation.
Or simply create a symlink for your project to ~/quicklisp/local-projects/ or ~/common-lisp/.
I wouldn't "load-system" my project in the init file, because that's a side effect that would show sometimes when I don't want it (like building an image: if that involves reading my init file, I'd have an unwanted system in it).
Saving a core image with a ton of dependencies is cool. Use it with sbcl --core …. The advantage is that it starts up instantly in the REPL, when loading all projects and dependencies would take a few seconds.
Pointers
ASDF
ASDF cookbook
ASDF manual
ASDF best practices
ASDF Build System explained
Overview
A system is an object which describes a library (or an application) which consists of: a name, a version, a list of files and subsystems, and a list of other systems it depends on. There is more.
If you want to have Lisp know a certain system, then we need to execute its defsystem form either manually or find it automatically. That ONLY makes the system definition known.
If you want to load the system's files, then you need to LOAD the SYSTEM. If you want to compile the system's files files, the you need to COMPILE the system.
So, if you want to use a package (which is a namespace), then you need to run the DEFPACKAGE form. If that form is describe in a file which is component of a system, then you need to load that system.
ASDF : a popular build system for Common Lisp
system -> library, application. It is a bunch of files and dependencies.
system definition -> not the system itself, but a description of it. Use DEFSYSTEM to describe a system
system operations -> like load-system, compile-system and others.
system registry -> Typically we want ASDF to find the systems by name. See the manual or a tutorial for ASDF.
lisp file -> some file we can compile or load
fasl file -> some compiled file we can load
package -> a namespace for symbols, that's actually a built-in feature for Common Lisp
Quicklisp -> a library manager with a selection of curated Common Lisp libraries/applications. The libraries can be loaded over the Internet. Be aware that there is little to no security when loading foreign code from the Internet.
Use a system, its components and dependencies
If you want to use a system you need to load it first. Manually or automatically.
That loading can be done automatically:
For example in an init-file for your Lisp you can load all systems you want/need. Alternative write a function which loads all systems you want.
saving an image. Some Lisps support saving an image. Thus one can load all interesting systems and then save an image. If one starts that image later, all those systems are already in memory. (side problem: getting newer versions loaded)

Where is the REQUIRE file situated in Julia?

I was looking for REQUIRE file using mate in shell command but couldn't find it.
It's related to Pkg..
shell> mate ~/.julia/
compiled/ clones/ prefs/ registries/
environments/ conda/ logs/ packages/
You are using Julia 0.7+.
Which means there is no REQUIRE files anywhere.
You may be looking for the Project.toml for the global (or other shared) environment.
You will find that (and it's matching Manifest.toml) in each subdirectory within the environments directory
See the Julia Docs for further reading on this topic.

OCaml: How can I get the path to the *current module* / my project's directory?

I'm new to OCaml, but I'm trying to figure out the equivalent of __filename, __dirname from Node. That is, I need to build a path relative to the file containing the code in question.
For reference, I'm working through Ghuloum's IACC: http://ell.io/tt$ocameel
I'm building my first compiler, and I have an utterly-simplistic ‘runtime’ file (in C — temporarily) adjacent to the compiler's source-code. I need to be able to pass the path to this file, as an argument (or a pre-compiled version, I suppose) to gcc or my linker, to have it linked against my compiler's output when I invoke the linker/assembler tooling.
(This may be a stupid question — I'm at a bit of an unknown-unknown here, “how does a compiler get the runtime to the linker”, or something like that. Any commentary about idiomatic solutions to this is welcome, even if it's not a direct answer to the above question!)
If you're running the source file directly via ocaml myfile.ml, Sys.argv.(0) will give you the path to the source file and you can use Filename.dirname to get the directory from that.
If you first compile the source file into an executable and then run the executable, Sys.argv.(0) will give you the name of the executable. In that scenario it's impossible to get the location of the source code (especially if you consider that the person running the executable might not even have the source code on their system).
If you set up your project structure, so that your sources live in src/, your compiled binary in bin/ and the compiled stdlib in lib/, you could just use Filename.dirname Sys.argv.(0) ^ "../lib" as the library path for gcc. This will work whether you run ocaml src/mycompiler.ml, bin/mycompiler or just mycompiler after installing everything to /usr/ or /usr/local/.

Loading quicklisp package for use in another lisp file

I have downloaded a large software project FriCAS which I have compiled from source and using SBCL. This was just a matter of using GNU .configure - I am a complete Lisp newbie.
However, in order to add some further functionality I have - by very carefully following directions - installed quicklisp and a few extra packages. So far so good.
Here's my issue: I am trying to compile an external lisp file for use in the system. I need to make quicklisp and its packages visible to the compiler. So I've copied my .sbclrc file to the top of my lisp file:
#-quicklisp
(let ((quicklisp-init (merge-pathnames "quicklisp/setup.lisp"
(user-homedir-pathname))))
(when (probe-file quicklisp-init)
(load quicklisp-init)))
I have followed this with
(eval-when (:compile-toplevel)
(ql:quickload "f2cl-lib"))
I have already installed f2cl-lib with quicklisp. However, my compiler (within FriCAS) immediately aborts with
; caught ERROR:
; READ error during COMPILE-FILE:
;
; Package QL does not exist.
I'm a bit stumped here - there's probably something trivial and obvious which is missing, but as I say from a newbie perspective I don't know what it is.
Looks like a FAQ. See also the documentation for eval-when.
The File Compiler
Remember, a file compiler compiles forms and does not execute them. It just generates code for later execution. Generally. Though, in Common Lisp there are some exceptions to this rule: for example a macro, used in the source code, will be run by the file compiler. But Common Lisp also allows us to tell the file compiler to execute code at compile time, that's one of the use cases of eval-when.
Your example simplified
If you have a file:
(load "file-which-creates-package-foo")
(eval-when (:compile-toplevel)
(foo:bar))
Then the file compiler will generate code for loading the file, but it will not load the file.
Next, the file compiler sees a second form, where the file compiler is instructed to execute a statement at compile time (and only at compile time), so (foo:bar) will be executed at compile time. But it is worse: Since the loading code has not been executed yet, the package FOO is unknown, and the form (foo:bar) will be read at compile time, the reader already complains at compile time that the package FOO does not exist.
The use of EVAL-WHEN
What you need to do, is to tell the file compiler to actually load the stuff it needs during compilation. The file already contains an eval-when form, so that should give you a hint: use eval-when. It has three situations:
:compile-toplevel -> the file compiler executes the enclosed forms
:load-toplevel -> the file compiler generates code so that the code will be executed when loading the code
:execute
Make sure that those situations are mentioned, when the code should be executed.
Possible solutions
So there are possible solutions:
as above, use EVAL-WHEN to be able to execute forms by the file compiler
write the loading code into a separate file and compile/load this file before you use the package. One could also add this file to a system such that it will be loaded by the compiling the system, before the using code will be compiled.

How to install new packages for common lisp without asdf-install

I am new to cl, and I just learned to install packages using asdf-install, but I don't know how it works, I wonder how the package can be installed manully, then I could understand the use of the files in the root directory of the source code, thanks.
Short answer: Just use quicklisp.
Long answer: if you want to understand, how the package, or - more precisely - ASDF system, is laid out, that's a good idea. Actually, there's nothing hard about that.
Every ASDF system should have a system definition file with .asd extension. This file names other file of the system with their paths relative to the .asd file, their types (by default: lisp source code) and dependencies. Your Lisp should know where to find the system definition file. In ASDF there are 2 ways to inform Lisp about it: adding the directory, in which you store the file or symlink to it, to asdf:*central-registry* list or setting up special configuration files (called source-registry - more on that in ASDF manual).
Now if you want to install the system by hand, just download its sources, extract them into some directory (like in /home/user/lib/lisp/ - you may get /home/user/lib/lisp/cl-ppcre-2.3.1/, inside which there's cl-ppcre.asd). To let your Lisp find out about it just (push "/home/user/lib/lisp/cl-ppcre-2.3.1/" asdf:*central-registry*) (and don't forget the trailing slash - it's required), and then you can load the system with (asdf:oos 'asdf:load-op :cl-ppcre).
You might also setup a special dir, where you'll symlink your existing systems, like /home/user/.lisp/ and add it to *central-registry* at Lisp startup type (e.g. in .sbclrc). Now if you want to temporarily override some of the system linked in this dir, say, with a newer version, you don't need to unlink anything - just push the path to alternative system to *central-registry*.
Quicklisp does all that for you and more...

Resources