Loading Clojure.core.match - exception

I'm new to Clojure and I'm wanting to use Clojure core.match:
https://github.com/clojure/core.match
I've setup my project with TextMate using the following bundle: https://github.com/swannodette/textmate-clojure
My project.clj is as follows:
(defproject Prototype "0.0.1-SNAPSHOT"
:description "Prototype ARS Implementation"
:dependencies [[clojure "1.3.0"] [org.clojure/core.match "0.2.0-alpha6"]])
In terminal, I executed:
cake deps
Which downloaded the correct version of Clojure and the Clojure.core.match jar files.
Now I'm editing my 'src/Prototype/core.clj' and I'm wanting to use the match functionality.
I've tried using both the provided code on the GitHub page:
;; when using HEAD
(use '[clojure.core.match :only [match]])
;; when using the latest released alpha
(use '[clojure.core.match.core :only [match]])
This is my current code:
(ns Prototype.core
(use '[clojure.core.match.core :only [match]]))
(println
(let [x [1 2]]
(match [x]
[[1 2]] "It worked!"
:else "It failed!")))
When I load the file into the cake repl; I get the following error:
lib names inside prefix lists must not contain periods
Any ideas?
Cheers.

(ns Prototype.core
(:use [clojure.core.match.core :only [match]]))
(println
(let [x [1 2]]
(match [x]
[[1 2]] "It worked!"
:else "It failed!")))
There's no need to quote in the ns form.
(I've assumed clojure.core.match.core was the correct namespace. If it doesn't work use clojure.core.match instead.)

Related

How to implement *load-fn* for :requires in bootstrapped clojurescript

(ns scratch
(:require [cljs.js :as cjs]))
;Let's setup a simple clojurescript string eval that supports namespaces:
(def current-ns 'cljs.user)
(def compiler-state (cjs/empty-state))
(defn eval-text [text]
(println string)
(cjs/eval-str compiler-state text current-ns
{:eval cjs/js-eval
:ns current-ns
:context :expr
:def-emits-var true}
(fn [result]
(set! current-ns (:ns result))
(println result))))
(eval-text "(ns a.a)")
(eval-text "(defn add [a b] (+ a b))")
(eval-text "(add 4 4)")
;I can refer to the function from another namespace explicitly with no problem
(eval-text "(ns x.x)")
(eval-text "(a.a/add 6 6)")
;However when I do
(eval-text "(ns b.b (:require [a.a :refer [add]]))")
On the last line I get:
{:error #error {:message Could not require a.a, :data {:tag :cljs/analysis-error}, :cause #object[Error Error: No *load-fn* set]}}
So I have to create my own https://cljs.github.io/api/cljs.js/#STARload-fnSTAR
and pass it into the :load compiler option to handle this :require even though the compiler state already knows about my namespace as I can call the fully qualified function from another namespace.. Correct?
What is the best way to do that?
Should I create maps that store namespace->source-code from previously evaled code and get namespace->analysis-cache from the compiler state and pass these into the :source and :cache callbacks of my custom load function?
Is there a better / more efficient way to do this?
I believe I found the answer:
The :load option of eval-str can be set to the following function:
(defn load-dep [opts cb]
(cb {:lang :js :source ""})
And it will quite happily resolve. This isn't really apparent from the documentation that the callback can return this value when the namespace/var is already in the compiler state so I'll leave the question here.

Opening leiningen project in emacs/cider raises classpath error

I'm learning Clojure with 'Clojure for the Brave and True' book and use emacs, cider and leiningen. I've created a project.
lein new app the-divine-cheese-code
Then I've added to source files to the project.
the-divine-cheese-code\src\the_divine_cheese_code\core.clj
the-divine-cheese-code\src\the_divine_cheese_code\visualization\svg.clj
In 'core.clj' I refer to the 'svg.clj' namespace.
the-divine-cheese-code\src\the_divine_cheese_code\core.clj
(ns the-divine-cheese-code.core)
;; Ensure that the SVG code is evaluated
(require 'the-divine-cheese-code.visualization.svg)
;; Refer the namespace so that you don't have to use the
;; fully qualified name to reference svg functions
(refer 'the-divine-cheese-code.visualization.svg)
(def heists [{:location "Cologne, Germany"
:cheese-name "Archbishop Hildebold's Cheese Pretzel"
:lat 50.95
:lng 6.97}
{:location "Zurich, Switzerland"
:cheese-name "The Standard Emmental"
:lat 47.37
:lng 8.55}
{:location "Marseille, France"
:cheese-name "Le Fromage de Cosquer"
:lat 43.30
:lng 5.37}
{:location "Zurich, Switzerland"
:cheese-name "The Lesser Emmental"
:lat 47.37
:lng 8.55}
{:location "Vatican City"
:cheese-name "The Cheese of Turin"
:lat 41.90
:lng 12.45}])
(defn -main
[& args]
(println (points heists)))
the-divine-cheese-code\src\the_divine_cheese_code\visualization\svg.clj
(ns the-divine-cheese-code.visualization.svg)
(defn latlng->point
"Convert lat/lng map to comma-separated string"
[latlng]
(str (:lat latlng) "," (:lng latlng)))
(defn points
[locations]
(clojure.string/join " " (map latlng->point locations)))
Here is the project's entire dir structure.
the-divine-cheese-code
the-divine-cheese-code\.gitignore
the-divine-cheese-code\.hgignore
the-divine-cheese-code\.nrepl-port
the-divine-cheese-code\CHANGELOG.md
the-divine-cheese-code\doc
the-divine-cheese-code\doc\intro.md
the-divine-cheese-code\LICENSE
the-divine-cheese-code\project.clj
the-divine-cheese-code\README.md
the-divine-cheese-code\resources
the-divine-cheese-code\src
the-divine-cheese-code\src\the_divine_cheese_code
the-divine-cheese-code\src\the_divine_cheese_code\core.clj
the-divine-cheese-code\src\the_divine_cheese_code\visualization
the-divine-cheese-code\src\the_divine_cheese_code\visualization\svg.clj
the-divine-cheese-code\target
the-divine-cheese-code\target\default
the-divine-cheese-code\target\default\classes
the-divine-cheese-code\target\default\classes\META-INF
the-divine-cheese-code\target\default\classes\META-INF\maven
the-divine-cheese-code\target\default\classes\META-INF\maven\the-divine-cheese-code
the-divine-cheese-code\target\default\classes\META-INF\maven\the-divine-cheese-code\the-divine-cheese-code
the-divine-cheese-code\target\default\classes\META-INF\maven\the-divine-cheese-code\the-divine-cheese-code\pom.properties
the-divine-cheese-code\target\default\repl-port
the-divine-cheese-code\target\default\stale
the-divine-cheese-code\target\default\stale\leiningen.core.classpath.extract-native-dependencies
the-divine-cheese-code\test
the-divine-cheese-code\test\the_divine_cheese_code
the-divine-cheese-code\test\the_divine_cheese_code\core_test.clj
When I run the project with 'lein run' it executes successfully. However, when I open the core.clj file with emacs/cider and try to compile it, I get classpath error.
CompilerException java.io.FileNotFoundException: Could not locate
the_divine_cheese_code/visualization/svg__init.class or
the_divine_cheese_code/visualization/svg.clj on classpath. Please check
that namespaces with dashes use underscores in the Clojure file name.,
compiling:(c:/temp/the-divine-cheese-code/src/the_divine_cheese_code/core.clj:2:1)
CIDER compiles sources sucessfully if I put them in the same directory (changing namespace correspondingly).
(ns the-divine-cheese-code.core)
(require 'the-divine-cheese-code.svg)
(refer 'the-divine-cheese-code.svg)
(def heists [{:location "Cologne, Germany"
...
So maybe the issue is dealt with OS. I use Windows 7, which is not primary OS for Emacs/CIDER.
After some experimenting I found that the CIDER works without :refer
(ns the-divine-cheese-code.core
(:require [the-divine-cheese-code.visualization.svg]))
This looks like a CIDER bug and 'lein run' predictably gives error in this case.
If I make it the right way
(ns the-divine-cheese-code.core
(:require [the-divine-cheese-code.visualization.svg :refer :all]))
the CIDER now gives another error:
Caused by java.lang.IllegalStateException
latlng->point already refers to:
#'the-divine-cheese-code.svg/latlng->point in namespace:
the-divine-cheese-code.core
Would suggest to use the options provided by the ns macro instead of naked require and refer statements - this is the recommended way of doing imports/requires in Clojure and most of the tooling is written with this way of managing namespaces in mind. Even if the below code still doesn't work in CIDER, it will be easier to diagnose it:
;; the-divine-cheese-code\src\the_divine_cheese_code\core.clj
(ns the-divine-cheese-code.core
(:require [the-divine-cheese-code.visualization.svg :refer :all]))
(def heists ...)
(defn- main ...)
In my case, the error went away after I renamed (to the same name) src/the_divine_cheese_code/ folder and it's contents recursively.
Not sure what caused the issue. My guess is that character encoding was screwed up. I created both the file and folder in Emacs and done the renaming in Double Commander.

How to 'turn on' cljs.spec

How do I make sure that clojure/cljs.spec is verifying function call arguments and return values?
Say I have this function:
(defn my-inc [x]
(inc x))
After which I have this:
(s/fdef my-inc
:args (s/cat :x number?)
:ret number?)
This code compiles because [cljs.spec.alpha :as s] has been required.
Now I call the function so as to hopefully generate an error:
(my-inc "Not a number")
I would like to see the fdef being used, and see the error message stating that my-inc cannot be called with a string. How do I make this happen in a very general way, for instance with a setting in project.clj or user.cljs?
With this code in user.cljs:
(:require
[cljs.spec.alpha :as s]
[cljs.spec.test.alpha :as ts])
(defn my-inc [x]
(inc x))
(s/fdef my-inc
:args (s/cat :x number?)
:ret number?)
(ts/instrument)
(defn x-1 []
(my-inc "Hi"))
I can call x-1 from the cljs/figwheel REPL, and get this failure message:
#error {:message "Call to #'cljs.user/my-inc did not conform to spec:\nIn: [0] val: \"Hi\" fails at: [:args :x] predicate: number?\n:cljs.spec.alpha/spec #object[cljs.spec.alpha.t_cljs$spec$alpha50572]\n:cljs.spec.alpha/value (\"Hi\")\n:cljs.spec.alpha/args (\"Hi\")\n:cljs.spec.alpha/failure :instrument\n", :data #:cljs.spec.alpha{:problems [{:path [:args :x], :pred cljs.core/number?, :val "Hi", :via [], :in [0]}], :spec #object[cljs.spec.alpha.t_cljs$spec$alpha50572], :value ("Hi"), :args ("Hi"), :failure :instrument}}
I can also get conformance errors when working with a real project running code in a browser. The errors show up in the developer's console on the browser.
Put (ts/instrument) at the bottom of user.cljs to turn instrumentation on for all namespaces for development.
Edit
Just in case you are hit by this problem: https://dev.clojure.org/jira/browse/CLJS-1792
- the fix is to include [org.clojure/test.check "0.10.0-alpha2"] (probably with a more recent version) in your project.clj dependencies.
You can use instrument to check args conformance for certain symbols or all vars.
When called without arguments, instrument wraps all instrumentable vars into a function that checks the args before delegating to the original function.

def'ine a value with a dynamic name

So I want to pass a function to the "name" portion of def.
The problem is:
"First argument to def must be a Symbol"
I'm trying to for instance do:
(def serverNumber 5)
(def (str "server" serverNumber) {:id serverNumber :value 4939})
But I can't find annnnnnny way to do this. Any help would be beyond appreciated :)
First, I have to note that this seems like a bad idea. Why are you trying to generate defs with dynamically-generated names? (As #pst already pointed out, maps are the usual solution for creating bindings with dynamically-generated identifiers.)
Assuming you have a legit reason for doing this (maybe it's part of some library functionality where you're generating defs for the user), you can accomplish this with a macro:
(defmacro def' [sym-exp & other-args]
`(def ~(-> sym-exp eval symbol) ~#other-args))
(def serverNumber 5)
(def' (str "server" serverNumber) {:id serverNumber :value 4939})
Note that this only works at the top level (since macros are run at compile time). If you want to do this in a function or something then you just need to use eval:
(defn def'' [sym-exp & other-args]
(eval `(def ~(-> sym-exp eval symbol) ~#other-args)))
If you just want to create a bunch of agents, maybe something like this will work:
(def servers
(vec (for [i (range 5)]
{:id i :value 4939})))
Then you can just access them by index:
(servers 0)
; => {:id 0, :value 4939}
The run-time equivalent of def is intern:
(intern *ns*
(symbol (str "server" server-number))
{:id server-number :value 4939})

loading configuration file in clojure as data structure

Is there a reader function in clojure to parse clojure data structure? My use case is to read configuration properties files and one value for a property should be a list. I'd like to be able to write this as:
file.properties:
property1 = ["value1" "value2"]
and in clojure:
(load-props "file.properties")
and get a map with value {property1, ["value1" "value2"]
Right now,m I'm doing the following, with the same input file "file.properties":
(defn load-props [filename]
(let [io (java.io.FileInputStream. filename)
prop (java.util.Properties.)]
(.load prop io)
(into {} prop)))
;; returns:
;; {"property1" "[\"valu1\", \"valu2\"]"}
(load-props "file.properties")
But I cannot get a way to parse the result to a clojure's vector. I'm basically looking for something like Erlang's file:consult/1 function. Any idea how to do this?
If you want to read java-style properties files, look at Dave Ray's answer - though properties files have many limitations.
If you are using Clojure 1.5 or later, I suggest you use edn, the extensible data notation used in Datomic - it's basically clojure data structures, with no arbitrary code execution, and the ability to add tags for things like instances or arbitrary types.
The simplest way to use it is via read-string and slurp:
(require 'clojure.edn)
(clojure.edn/read-string (slurp "filename.edn"))
That's it. Note that read-string only reads a single variable, so you should set up your configuration as a map:
{ :property1 ["value1" "value2"] }
Then:
(require 'clojure.edn)
(def config (clojure.edn/read-string (slurp "config.edn")))
(println (:property1 config))
returns
["value1" "value2"]
java.util.Properties implements Map so this can be done very easily without manually parsing properties files:
(require 'clojure.java.io)
(defn load-props
[file-name]
(with-open [^java.io.Reader reader (clojure.java.io/reader file-name)]
(let [props (java.util.Properties.)]
(.load props reader)
(into {} (for [[k v] props] [(keyword k) (read-string v)])))))
(load-props "test.properties")
;=> {:property3 {:foo 100, :bar :test}, :property2 99.9, :property1 ["foo" "bar"]}
In particular, properties files are more complicated than you think (comments, escaping, etc, etc) and java.util.Properties is very good at loading them.
Is there a reader function in clojure to parse clojure data structure?
Yes. It's called read. You can also use it to read configuration data.
A file props.clj containing
{:property1 ["value1" 2]
:property2 {:some "key"}}
can be read like this:
(ns somens.core
(:require [clojure.java.io :as io])
(:import [java.io PushbackReader]))
(def conf (with-open [r (io/reader "props.clj")]
(read (PushbackReader. r))))
When reading untrusted sources it might be a good idea to turn of *read-eval*:
(def conf (binding [*read-eval* false]
(with-open [r (io/reader "props.clj")]
(read (PushbackReader. r)))))
For writing configuration data back to a file you should look at print functions such as pr and friends.
contrib has functions for reading writing properties,
http://richhickey.github.com/clojure-contrib/java-utils-api.html#clojure.contrib.java-utils/as-properties
If this is for your own consumption then I would suggest reading/writing clojure data structures you can just print them to disk and read them.
(use '[clojure.contrib.duck-streams :only (read-lines)])
(import '(java.io StringReader PushbackReader))
(defn propline->map [line] ;;property1 = ["value1" "value2"] -> { :property1 ["value1" "value2"] }
(let [[key-str value-str] (seq (.split line "="))
key (keyword (.trim key-str))
value (read (PushbackReader. (StringReader. value-str)))]
{ key value } ))
(defn load-props [filename]
(reduce into (map propline->map (read-lines filename))))
DEMO
user=> (def prop (load-props "file.properties"))
#'user/prop
user=> (prop :property1)
["value1" "value2"]
user=> ((prop :property1) 1)
"value2"
UPDATE
(defn non-blank? [line] (if (re-find #"\S" line) true false))
(defn non-comment? [line] (if (re-find #"^\s*\#" line) false true))
(defn load-props [filename]
(reduce into (map propline->map (filter #(and (non-blank? %)(non-comment? %)) (read-lines filename)))))