Running test submodule as main hook - racket

Given this code:
#lang racket/base
(module+ test
(require rackunit rackunit/text-ui)
(provide suite)
(define suite
(test-suite
"test tests"
(test-equal? "test string test"
"string"
"string")))
(run-tests suite))
;(require 'test)
;(suite)
If the last two lines are left commented and the file is run with raco test test.rkt, will output
raco test: (submod "test.rkt" test)
1 success(es) 0 failure(s) 0 error(s) 1 test(s) run
0
1 test passed
Which is expected.
How can I make the file run its tests when it's run just as a script, not by raco?
I thought the two commented lines at the end would do what I want: import the submodule and then call the function,
(require 'test)
(suite)
but instead I get:
$ racket test.rkt
require: unknown module
module name: #<resolved-module-path:'test>
context...:
standard-module-name-resolver
Learn Racket in Y Minutes seems to say that 'test as a 'symbol is for submodules, but perhaps not.

Submodules declared with module+ and module* aren't available for require in their containing module because they can depend on their containing module, and cycles in the module dependency graph aren't allowed. (In contrast, submodules declared with module can't depend on their containing module, but their containing module can require them.)
Try adding a main submodule; that should get run when the file is run as a script:
(module+ main
(require (submod ".." test))
(run-tests suite))
BTW, the Racket convention is for the test submodule to run the tests, not just to define them. Adding a main submodule might make raco test stop working for your script; the fix would be to move the (run-tests suite) call to the test submodule instead.

Related

LISP MAKE-PATHNAME: Illegal :DIRECTORY argument

I download Semantic Network Processor project:
http://digital.cs.usu.edu/~vkulyukin/vkweb/software/snp/snp.html
and following it's read me,
By using CLISP interpreter I change the directory to the folder,
and do the following:
[3]> (load "snp-loader.lisp")
;; Loading file snp-loader.lisp ...
;; Loaded file snp-loader.lisp
T
[4]> (in-package "USER")
<PACKAGE COMMON-LISP-USER>
[5]> (snp-load-everything)
**- MAKE-PATHNAME: Illegal :DIRECTORY argument "D:\\snp-stable\\"**
The following restarts are available:
ABORT :R1 Abort main loop
can anybody tells me what's wrong or how I can fix it in order to make the project run?
In snp-loader.lisp, instead of directory-namestring, you need to call pathname-directory:
(defparameter parm-snp-load-dir
(pathname-directory *load-truename*))
But then another problem occurs later, when defining a method for expectations-on-token. In c-snp-with-vars.lisp, the docstring is malformed, which triggers an error. Join both strings:
(defmethod expectations-on-token ((this-snp c-snp-with-vars) (tok t))
"Overloaded expectations-on-token to process variables and tests.
Get all expectations waiting for the token tok."
`(,#(find-static-expectations this-snp tok)
,#(find-dynamic-expectations this-snp tok)))
Reload the snp-loader.lisp file, and retry (snp-load-everything). It should load properly.
Edit. I contacted the original author; the latest version of the code is now hosted on GitHub at https://github.com/VKEDCO/AI/tree/master/NL/SNP.

Import from module using prefix without exposing non-prefixed things

I'd like to be able to only import namespaced items from a module in Racket. The prefix-in function does allow me to access functions from the module using the prefix, but it doesn't hide the old name.
$ racket
Welcome to Racket v6.6.
> (require (prefix-in tcp: racket/tcp))
> tcp-accept
#<procedure:tcp-accept>
> tcp:tcp-accept
#<procedure:tcp-accept>
Is there a simple way to hide the unprefixed names?
The prefix-in form only imports the prefixed names, not the unprefixed ones. However, the racket language includes the racket/tcp module by default, so it is already imported when the REPL starts up. If you use #lang racket/base, instead, then tcp-accept won’t be imported, so the prefixed import will be the only imported identifier. You can simulate this using the -I racket/base option in the REPL:
$ racket -iI racket/base
Welcome to Racket v6.7.0.4.
> (require (prefix-in tcp: racket/tcp))
> tcp-accept
; tcp-accept: undefined;
; cannot reference undefined identifier
; [,bt for context]
> tcp:tcp-accept
#<procedure:tcp-accept>

How should I configure Vulkan for cider-jack-in?

I'm working through the newly released Vulkan Tutorial in Clojure with CIDER, and I've hit a bit of a snag. The example makefile project works perfectly, but I'm having trouble translating it into Clojure.
My build.boot file just specifies the :source-paths and adds LWJGL as a dependency:
(set-env!
:source-paths #{"src"}
:dependencies
(let [lwjgl-version "3.0.0"]
[['org.lwjgl/lwjgl lwjgl-version]
['org.lwjgl/lwjgl-platform lwjgl-version :classifier "natives-linux"]]))
Then, in src/example/core.clj, I have an extension-count function that uses vkEnumerateInstanceExtensionProperties as demonstrated in the original example:
(ns example.core
(:import (org.lwjgl.vulkan VK10)))
(defn extension-count []
(let [^String layer-name nil
property-count (int-array 1)]
(VK10/vkEnumerateInstanceExtensionProperties layer-name property-count nil)
(first property-count)))
Now, from Bash, I can set the relevant environment variables LD_LIBRARY_PATH and VK_LAYER_PATH as I start up a REPL:
$ VULKAN_SDK_PATH=~/VulkanSDK/1.0.21.1/x86_64 LD_LIBRARY_PATH=$VULKAN_SDK_PATH/lib VK_LAYER_PATH=$VULKAN_SDK_PATH/etc/explicit_layer.d boot repl
boot.user=> (require '[example.core :refer [extension-count]])
nil
boot.user=> (extension-count)
4
As you can see, everything works correctly. But of course, when I use cider-jack-in by C-c M-j instead, I get an UnsatisfiedLinkError because CIDER isn't setting those variables:
boot.user> (import (java.util.function Consumer)
(org.lwjgl.system Configuration))
org.lwjgl.system.Configuration
boot.user> (Configuration/setDebugStreamConsumer
(reify Consumer
(accept [_ message]
(println message))))
nil
boot.user> (require '[example.core :refer [extension-count]])
nil
boot.user> (extension-count)
[LWJGL] Failed to load a library. Possible solutions:
a) Set -Djava.library.path or -Dorg.lwjgl.librarypath to the directory that contains the shared libraries.
b) Add the JAR(s) containing the shared libraries to the classpath.
[LWJGL] Enable debug mode with -Dorg.lwjgl.util.Debug=true for better diagnostics.
java.lang.UnsatisfiedLinkError: Failed to locate library: libvulkan.so.1
Am I supposed to be setting java.library.path or org.lwjgl.librarypath, as suggested in the above error message, instead of LD_LIBRARY_PATH? I can set either of those variables from profile.boot:
(System/setProperty
"java.library.path"
(str (System/getProperty "user.home") "/VulkanSDK/1.0.21.1/x86_64/lib"))
Now when I try C-c M-j again, it works:
boot.user> (require '[example.core :refer [extension-count]])
nil
boot.user> (extension-count)
4
However, this still doesn't let me set VK_LAYER_PATH, which will be fairly important in the future:
We will start using validation layers in Vulkan and you need to tell the Vulkan library where to load these from using the VK_LAYER_PATH variable:
test: VulkanTest
LD_LIBRARY_PATH=$(VULKAN_SDK_PATH)/lib VK_LAYER_PATH=$(VULKAN_SDK_PATH)/etc/explicit_layer.d ./VulkanTest
How can I set these environment variables for cider-jack-in? I'd prefer not to have to manually configure CIDER's dependencies for a standalone repl in a separate terminal and then connect to it using cider-connect, but if there's no other option here, I guess that's what I'll have to do.

Proper way of defining packages using asdf:defsystem and quickproject

I'm a Lisp beginner trying to understand how to properly use Lisp package system while learning LTK for GUI programming, using SBCL 1.0.55.0.debian and Limp 0.3.4 (and Debian Wheezy if that matters). I have installed ASDF using aptitude package manager (packages cl-asdf & cl-common-lisp-controller), then I installed Quicklisp using the instructions on Quicklisp website (http://www.quicklisp.org/beta/index.html) (not from Debian repository) and then I have installed LTK with (ql:quickload 'ltk) in SBCL console.
hello-1.lisp (directly from LTK tutorial):
(defun hello-1()
(with-ltk ()
(let ((b (make-instance ’button
:master nil
:text "Press Me"
:command (lambda ()
(format t "Hello World!~&")))))
(pack b))))
If I compile this straight on in a new SBCL Lisp image, I get the message that WITH-LTK and PACK are undefined functions and 'BUTTON is undefined variable.
So, I found out that I need to load 'ltk first and then use in-package.I to be able to run it, I first have to use (ql:quickload 'ltk) and (in-package :ltk) in SBCL console. However, I still an error message that 'BUTTON is undefined variable.
* (ql:quickload 'ltk)
To load "ltk":
Load 1 ASDF system:
ltk
; Loading "ltk"
(LTK)
* (in-package :ltk)
#<PACKAGE "LTK">
* (compile-file "/home/user/code/lisp/hello-1.lisp")
; caught WARNING:
; undefined variable: ’BUTTON
;
; compilation unit finished
; Undefined variable:
; ’BUTTON
; caught 1 WARNING condition
; /home/user/code/lisp/hello-1.fasl written
; compilation finished in 0:00:00.009
#P"/home/user/code/lisp/hello-1.fasl"
T
T
*
Then, as this didn't work out as I wanted, I also attempted to define my own package definitions according to the answers of another question (Problems with ltk (common lisp)), Xach's blog entry "Making a small Lisp project with quickproject and Quicklisp" http://xach.livejournal.com/278047.html?thread=674335 and ASDF Manual (http://common-lisp.net/project/asdf/asdf/The-defsystem-form.html) using quickproject:make-project, but without success. Currently I have the following files:
package.lisp (compiles cleanly if I first (ql:quickload 'ltk) SBCL REPL):
(defpackage :hello-world-ltk-system
(:use :cl :asdf :ltk))
hello-world-ltk.asd (compiles cleanly after I have first compiled package.lisp):
(in-package :hello-world-ltk-system)
(asdf:defsystem :hello-world-ltk
:serial t
:description "Describe hello-world-ltk here"
:author "Your Name <your.name#example.com>"
:license "Specify license here"
:depends-on (:cl :asdf :ltk)
:components ((:file "package")
(:file "hello-world-ltk")))
hello-world-ltk.lisp (I get compile error The name "HELLO-WORLD-LTK" does not designate any package).
(require 'hello-world-ltk)
(in-package :hello-world-ltk)
(defun hello-world-1 ()
(with-ltk ()
(let ((b (make-instance 'button
:master nil
:text "Press me!"
:command (lambda ()
(format t "Hello world!~&")))))
(pack b))))
When I attempt to compile this hello-world-ltk.lisp after successfully compiling package.lisp and hello-world-ltk.asd (which all reside in the same directory) I get the following error:
; compiling (IN-PACKAGE :HELLO-WORLD-LTK)
debugger invoked on a SB-KERNEL:SIMPLE-PACKAGE-ERROR in thread
#<THREAD "initial thread" RUNNING {10029A0FA3}>:
The name "HELLO-WORLD-LTK" does not designate any package.
Type HELP for debugger help, or (SB-EXT:QUIT) to exit from SBCL.
restarts (invokable by number or by possibly-abbreviated name):
0: [ABORT] Exit debugger, returning to top level.
(SB-INT:%FIND-PACKAGE-OR-LOSE "HELLO-WORLD-LTK")
0]
(load "/home/user/code/lisp/hello-world-ltk/hello-world-ltk")
debugger invoked on a SIMPLE-ERROR in thread
#<THREAD "initial thread" RUNNING {10029A0FA3}>:
attempt to load an empty FASL file:
"/home/user/code/lisp/hello-world-ltk/hello-world-ltk.fasl"
Type HELP for debugger help, or (SB-EXT:QUIT) to exit from SBCL.
restarts (invokable by number or by possibly-abbreviated name):
0: [ABORT] Reduce debugger level (to debug level 1).
1: Exit debugger, returning to top level.
(SB-FASL::LOAD-AS-FASL
#<SB-SYS:FD-STREAM
for "file /home/user/code/lisp/hello-world-ltk/hello-world-ltk.fasl"
{1005291233}>
NIL
#<unavailable argument>)
0[2]
So, I'm quite lost here with all different ways to define packages, ASDF, Quicklisp, package.lisp, quickproject, asdf:defsystem, require and ql:quickload... quickproject:make-project looks promising, but I really don't know what's still wrong with my source files. I'm looking for a solution that should handle all the compilations and package loadings preferibly in one single command for the whole project and that should be extendable for bigger projects too.
Thank you for any help :)
The first problem in your code is that you use apostrophe (’) instead of tick ('). That's why you get undefined variable error, as ’button is read as variable name (it's not quoted).
Now regarding packages and systems. A package is defined with defpackage and it is a collection of symbols, which are used after the in-package form inside a file (or in interactive session). A package has internal and external (exported) symbols, that can be accessed as package::internal-symbol and package:external-symbol respectively. Packages can also import symbols from other packages. If you use-package, you import all its external symbols. While in-package switches the current package to the specified one and you start to define symbols in it (and it is not desirable to do such things in 3rd-party packages, like LTK). So if you want to use LTK symbols, like with-ltk or button, you just need to either use-package LTK or import these symbols from LTK in your defpackage form:
(defpackage :hello-world-ltk-system
(:use :cl)
(:import-from :ltk :with-ltk :button))
or simply import all LTK symbols (with use clause):
(defpackage :hello-world-ltk-system
(:use :cl :ltk))
Finally, systems and packages are totally unrelated things. A system is an instance of a class ASDF:SYSTEM, which holds information about physical files and their relations, so that they can be compiled and loaded appropriately. For your hello-world application I would suggest, that you don't bother about systems for now, and write all your code in one file. This file should start with a defpackage form, followed by in-package, and then the rest of your code.
When this file will grow large enough, that you'll see clear parts in it, you can factor out those parts into separate files. Then you'll have to create a system definition file, that will look like this:
(asdf:defsystem :hello-world
:depends-on (:ltk)
:serial t
:components ((:file "package")
(:file "first")
(:file "second")
...))
The "package.lisp" file will now hold your package definition.

Eval not working on unexpanded macro quote

In common lisp I can do this:
src-> (defmacro macro-hello ()
`"hello")
(eval '(macro-hello))
no problem.
In clojure:
(defmacro macro-hello []
`"hello")
(eval '(macro-hello))
gives me an error. Have I done something wrong?
Clojure Error:
Exception in thread "main" java.lang.Exception: Unable to resolve symbol: macro-hello in this context (NO_SOURCE_FILE:12)
at clojure.lang.Compiler.analyze(Compiler.java:4340)
at clojure.lang.Compiler.analyze(Compiler.java:4286)
at clojure.lang.Compiler$InvokeExpr.parse(Compiler.java:2767)
at clojure.lang.Compiler.analyzeSeq(Compiler.java:4498)
at clojure.lang.Compiler.analyze(Compiler.java:4325)
at clojure.lang.Compiler.analyze(Compiler.java:4286)
at clojure.lang.Compiler$BodyExpr$Parser.parse(Compiler.java:3862)
at clojure.lang.Compiler$FnMethod.parse(Compiler.java:3697)
at clojure.lang.Compiler$FnMethod.access$1100(Compiler.java:3574)
at clojure.lang.Compiler$FnExpr.parse(Compiler.java:2963)
at clojure.lang.Compiler.analyzeSeq(Compiler.java:4494)
at clojure.lang.Compiler.analyze(Compiler.java:4325)
at clojure.lang.Compiler.eval(Compiler.java:4530)
at clojure.core$eval__3990.invoke(core.clj:1728)
at com.yourcompany.defpackage$_main__4.invoke(defpackage.clj:12)
at clojure.lang.AFn.applyToHelper(AFn.java:171)
at clojure.lang.AFn.applyTo(AFn.java:164)
at com.yourcompany.defpackage.main(Unknown Source)
Caused by: java.lang.Exception: Unable to resolve symbol: macro-hello in this context
at clojure.lang.Compiler.resolveIn(Compiler.java:4682)
at clojure.lang.Compiler.resolve(Compiler.java:4628)
at clojure.lang.Compiler.analyzeSymbol(Compiler.java:4605)
at clojure.lang.Compiler.analyze(Compiler.java:4307)
... 17 more
Java Result: 1
[Edited]: added ending double quote
Your code works for me.
user> (defmacro macro-hello [] `"hello")
#'user/macro-hello
user> (eval '(macro-hello))
"hello"
This is via bleeding-edge Clojure. "Unable to resolve symbol" means it can't find the macro called macro-hello in the current namespace. Are you running this from the REPL or in a source file? I typed your statements at a REPL literally.
Not sure if this is a cause of problems for you, but please note the difference between ` and ' in Clojure. ` does namespace resolution and ' doesn't.
user> `macro-hello
user/macro-hello
user> 'macro-hello
macro-hello
This is different from Common Lisp's behavior. Backtick-quoting a String like `"hello" doesn't make much sense, since Strings don't belong to namespaces, but it also doesn't hurt anything.
(I'm assuming you made a typo in your Clojure code, with the missing double-quote.)
I like to work out of /opt on Mac and Linux boxes. To get the Clojure source. (% is Unix prompt)
% cd /opt
% git clone git://github.com/richhickey/clojure.git; #From Unix command line, you'll have an /opt/clojure dir
% cd /opt/clojure
% /opt/netbeans-6.7.1/java2/ant/bin/ant; # Run ant. It ships with Netbeans.
% cd /opt; # mkdir /opt if it's not there.
% git clone git://github.com/richhickey/clojure-contrib.git; # Get contrib
% /opt/netbeans-6.7.1/java2/ant/bin/ant -Dclojure.jar=../clojure/clojure.jar ; # Tell ant where clojure.jar is located
I rename jars to clojure.jar and clojure-contrib.jar
Copy these jars to your Netbean's project lib directory.