include, kinda C style?

Discussion of Common Lisp
Post Reply
Kohath
Posts: 61
Joined: Mon Jul 07, 2008 8:06 pm
Location: Toowoomba, Queensland, Australia
Contact:

include, kinda C style?

Post by Kohath » Sun Feb 14, 2010 12:37 am

Has anyone seen something like this in Lisp? I was thinking of something like this for small projects, or projects I only want to play with.

Code: Select all

(defvar *included* nil "Temporarily holds all included file paths.
That is, holds all paths to files loaded with the include form.")

(defun include (path)
  "This is my simple utility function that you can use to include files
with automatic single-load-per-file functionality."
  (let^ (path (pathname path)
         firstone (not *included*))
    (unless (member path *included* :test #'equalp)
      (push path *included*)
      (load path))
    (when firstone
      (setf *included* nil))))
Usage would be to include all of the dependencies of the code in a file at the top, like this:

Code: Select all

(include "(partial) path to xyz")
(include "(partial) path to abc")
;;; use xyz and abc
I'm interested in thoughts, comments, and if anyone's seen it before...

ramarren
Posts: 613
Joined: Sun Jun 29, 2008 4:02 am
Location: Warsaw, Poland
Contact:

Re: include, kinda C style?

Post by ramarren » Sun Feb 14, 2010 2:08 am

C-style include doesn't make sense in Common Lisp, since it is an image based language. And what you did isn't C-style anyway, that would be a macro reading its expansion from a file I suppose, which doesn't really sound like a good idea.

What you did is most similar to REQUIRE/PROVIDE pair, at least on some implementation. There is a reason why it is deprecated. There are evaluation time problems, and no mechanism for automatic reloading of modified files. It is best to use ASDF, which really isn't that complicated.

Well, for simple, one-file utilities I have been using headers on top of file like:

Code: Select all

(eval-when (:compile-toplevel :load-toplevel :execute)
  (require :iterate)
  (require :alexandria)
  (require :gsll)
  (require :parse-number)
  (require :split-sequence))
This uses REQUIRE, but only because on many implementations (like SBCL, which I use) it is integrated with ASDF a shortcut for (asdf:oos 'asdf:load-op ...). See redshank for Emacs for automatic insertion of EVAL-WHEN, and many other things.

WeYu
Posts: 9
Joined: Sun Aug 10, 2008 1:14 pm

Re: include, kinda C style?

Post by WeYu » Sun Feb 14, 2010 2:20 am

Faslpath implements this. Have a look, feedback welcome.

It allows you to specify dependencies as a quoted list at the beginning of a file, like so:

Code: Select all

'("foo" "bar" :com.company.library-x)
It means foo.lisp and bar.lisp need to be compiled (if necessary) and loaded before compiling or loading this file.
Library-x will be searched for and loaded, sort of like in java. Granted, that's not exactly c-style, but pretty close.

Kohath
Posts: 61
Joined: Mon Jul 07, 2008 8:06 pm
Location: Toowoomba, Queensland, Australia
Contact:

Re: include, kinda C style?

Post by Kohath » Thu Mar 18, 2010 3:15 am

Thanks for your responses...

Ramarren - I agree that it doesn't have the power to match the flexibility of Lisp. Do you have an example of an evaluation time problem that you help me out with?

WeYu - Thanks for the pointer. I'll give it a look.

Warning! Rant follows...

It's slightly OT, but this idea came about because I've recently been trying to get ASDF working with Corman CL, and have come up to a couple of ANSI standard compliance issues. One is that method combination is not working in Corman CL. I'd like to add it, but it would take some time. Then I can use many libraries much more easily. I know that ASDF just uses the standard, but to me, a library like ASDF should use a relatively small subset of the lang, so that almost-standard implementations can still access the world of Lisp libraries... And even more OT, I like to use Corman CL because it has a nice (if not perfect) UI, at least much easier to pick up than Emacs (and it comes with a back end :mrgreen:). I never could get over the hump (sorry Lispbox). And my computer hasn't got enough RAM to open Eclipse in under 3 minutes. And ABLE is based on Tcl/Tk, which behaves unexpectedly on my computer. Ugh. Some of these issues may be resolved as time passes, but nothing seems to just work. It's a bit depressing.

As an aside, Autohotkey eases the pain a little - among other things, I use it to turn pressing '[' into '(' then ')' then a left arrow 'press' to get the cursor between the two parentheses, and changing Caps Lock into dash (it was backspace, but I'm a lisp programmer :roll:).

ramarren
Posts: 613
Joined: Sun Jun 29, 2008 4:02 am
Location: Warsaw, Poland
Contact:

Re: include, kinda C style?

Post by ramarren » Thu Mar 18, 2010 7:00 am

Kohath wrote:Ramarren - I agree that it doesn't have the power to match the flexibility of Lisp. Do you have an example of an evaluation time problem that you help me out with?
By evaluation time problem I mean that since functions are not executed during compilation, and since both REQUIRE and your INCLUDE are functions, their actions, that is, loading systems, will not be executed when compiling, and then file compilation will fail, because any references to those system will be unresolved. Using EVAL-WHEN avoids this problem.

Kohath
Posts: 61
Joined: Mon Jul 07, 2008 8:06 pm
Location: Toowoomba, Queensland, Australia
Contact:

Re: include, kinda C style?

Post by Kohath » Thu Mar 18, 2010 10:51 pm

Thanks heaps for clarifying that :). I thought it wasn't such a big issue :o, but breaking the ability to compile does seem wrong :D.

Jasper
Posts: 209
Joined: Fri Oct 10, 2008 8:22 am
Location: Eindhoven, The Netherlands
Contact:

Re: include, kinda C style?

Post by Jasper » Fri Mar 19, 2010 3:40 pm

WeYu wrote:Faslpath implements this. Have a look, feedback welcome.
Wasn't any cliki page for it, here is one for starters.

Came here to suggest making an alternative macro that makes asdf files and defpackage forms at the same time.Seems like faslpath is not entirely unlike it. Still, i think i prefer the idea of automatically making asdf files better, and i don't like the idea of having to change the names of packages to use fasl path, and asdf seems pretty standard atm, so using that might be handy.

How about implementing it by hooking it into defpackage. I considered going via a defpackage* or just some macro, but that would add a dependency; *macroexpand-hook*, but that seems like the wrong way to use that feature, how about just:

Code: Select all

(defvar *old-defpackage* (macro-function 'defpackage)
  "Default defpackage macro to be overridden. Won't overwrite itself when called twice because it is a defvar.")

(defun register-package (form)
;Hopefully can use *compile-file-truename*, *load-file-truename* *load-pathname* to figure out where the file is.
;Then make/overwrite .asd file in desired location.
  ...)

(defmacro cl::defpackage (&rest stuff)
  (register-package form)
  (funcall *old-defpackage* `(defpackage ,@stuff) nil))
Hmm now i think about it, i could make expression-hook do it, an expression hook can easily converted to a *macroexpand-hook* with

Code: Select all

(defun to-macroexpand-hook (expr-hook)
  (lambda (expander form env)
    (declare (ignore expander env))
    (funcall expr-hook form)))
Difference is that *expression-hook* is also called upon functions, variables, etc. (What is 'env' for anyway, don't we have special variables? I guess i will have to find out; found that there are libs i can't scan seemingly due to env being nil when expr-hook calls it.)

JamesF
Posts: 98
Joined: Thu Jul 10, 2008 7:14 pm

Re: include, kinda C style?

Post by JamesF » Mon Mar 22, 2010 4:04 pm

Sorry if this sounds obvious, but isn't this the problem that ASDF solves? It may not be a perfect solution, but it does a pretty good job.

Jasper
Posts: 209
Joined: Fri Oct 10, 2008 8:22 am
Location: Eindhoven, The Netherlands
Contact:

Re: include, kinda C style?

Post by Jasper » Tue Mar 23, 2010 2:09 pm

It certainly is good enough, but it could still be better; first you tell lisp what packages use what packages, then you have to tell it to asdf too. Would have been neater if packages themselves could tell more.

Post Reply