2

I am trying to determine the system's OS with a lisp program running on emacs+slime, using code from the internet (because I am a newbie in lisp). In particular, I use the following code:

;; check OS type
(cond
 ((string-equal system-type "windows-nt") ; Microsoft Windows
  (progn
    (message "Microsoft Windows") )
  )
 ((string-equal system-type "darwin")   ; Mac OS X
  (progn
    (message "Mac OS X")
    )
  )
 ((string-equal system-type "gnu/linux") ; linux
  (progn
    (message "Linux") )
  )
)

(I found this code in this website.)

I put the code above in a file (02.lisp) and after the last parenthesis I press C-c C-c to compile it. But this gives me the following error:

Unbound variable: SYSTEM-TYPE

   [Condition of type UNBOUND-VARIABLE]

Same thing happens when I put the code directly in the top level. This happens both in my Windows computer where I am running the lisp program in a lispbox installation of emacs+slime, and in my Linux computer where I am running the lisp program in a standard debian installation of emacs+slime via apt-get.

Why am I getting this error, and what would be the right way to find out, in common lisp (so inside the .lisp program) which operating system it is in? Thank you very much in advance, and please keep in mind that I am very new to lisp+emacs, so apologies if this is a silly/confused question.

----Edit to add more details on my problem:

I want to be able to do this within the lisp program (02.lisp) because I would like to be able to load a database via this 02.lisp. So the code I was planning to actually use with the above way (which I now see is completely wrong, thanks to jch's answer), is the following:

(cond
 ((string-equal system-type "windows-nt") ; Microsoft Windows
  (progn
    (message "Microsoft Windows") 
    (with-open-file (in "g:/lisp programs/implications.db")
      (with-standard-io-syntax
    (setf *db* (read in))))
)
  )
  ((string-equal system-type "gnu/linux") ; linux
  (progn
    (message "Linux")
    (with-open-file (in "/media/NANO16GB/lisp programs/implications.db")
      (with-standard-io-syntax
    (setf *db* (read in)))
    )
  )))

I want to have this because I work on this program in two computers, depending where I am, and I want the program to load a database from my usb stick.

So the question is, how to determine which OS am I running the program in, within the .lisp program, in order to use the appropriate code to load the database. Of course, a different code, that helps me load the database in my situation, would help, but by now I'm interested in determining the OS from within the .lisp program, just because I can't find out how to do it.

-----------Solved: thanks to jch's comments, I got to the following code that works:

(cond
 ((string-equal (software-type) "Microsoft Windows") ; Microsoft Windows
  (progn
    (format t "Microsoft Windows") 
    (with-open-file (in "g:/lisp programs/implications.db")
      (with-standard-io-syntax
    (setf *db* (read in))))
)
  )
  ((string-equal (software-type) "Linux") ; linux
  (progn
    (format t "Linux")
     (with-open-file (in "/media/NANO16GB/lisp programs/implications.db")
      (with-standard-io-syntax
    (setf *db* (read in)))
    )
  )))
Community
  • 1
  • 1
Ioanna
  • 157
  • 1
  • 7

2 Answers2

3

If you're using Emacs with SLIME, you've got two Lisp implementations running at the same time:

  • Emacs Lisp, which is part of Emacs, which is case-sensitive and defines a function called message and a variable system-type;
  • Common Lisp, which is not case-sensitive, and doesn't define either.

Your problem is that you're trying to get the Common Lisp implementation to evaluate Emacs Lisp code. That is not going to work.

Emacs Lisp code should go into files which end in .el, and you evaluate an expression using C-x C-e. Common Lisp code should go into files which end in .lisp, and you tell SLIME to evaluate an expression using C-c C-c.

jch
  • 5,382
  • 22
  • 41
  • Thanks for your answer, this explains a lot! But I still need to determine the OS within the .lisp program, because which OS it is on will determine which of two codes will run. I will edit my question to be more specific about this. – Ioanna Oct 23 '14 at 16:16
  • 1
    I don't think there's an exact equivalent to `system-type`. My best guess would be `#+UNIX` and `#+Windows`. Check the value of `*features*` in both your Common Lisp implementatons. – jch Oct 23 '14 at 16:51
  • 1
    Thanks! That was a good pointer, I now know how to search properly, and found out that, in fact, there is a related question: http://stackoverflow.com/questions/4372568/how-can-i-determine-the-operating-system-and-hostname-using-common-lisp So I basically put (software-type) on each of the REPLs, and got "Microsoft Windows" on the one and "Linux" on the other. It works now! I'll put the full correct code on the end of the question. – Ioanna Oct 23 '14 at 17:13
3

If you use a recent version of ASDF, you can portably use the function uiop/os:detect-os, which returns a keyword, or the predicates uiop/os:os-unix-p, uiop/os:os-macosx-p, uiop/os:os-windows-p, and uiop/os:os-genera-p.

  • I am not using ASDF (if I do, I am not aware of it), but thank you for your answer, this portability of functions might come in handy. – Ioanna Oct 26 '14 at 09:06
  • Most likely you have a recent enough version (i. e. the 3rd) out of the box, so you could just try the functions in REPL, perhaps after `(require 'asdf)`. Originally ASDF is about organising the source code, but ASDF 3 also includes UIOP, a portable library for interacting with the OS, file system, and other most useful stuff. Instead of longer prefixes like `uiop/os` it's possible to use just `uiop:` or even `asdf:` in all the cases. – Stanislav Kondratyev Oct 26 '14 at 12:06