it’s worse than all of these. Sorry for setting you guys on a wild goose chase
I had opened the wrong stack trace 🤦
The problem is that I am doing a format "…%.2f" (api call)
and when parsing the response json if the temperature happens to be exactly zero then the type is not a float
glad you found the actual problem!
Thank you!
Hi everyone, I've been using Clj commandline tools in Powershell on Windows and I entered the following into the commandline: user=> (require '[reader.snake :refer :all]) Execution error at user/eval213 (REPL:1). No namespace: reader.snake user=> (require '[examples.snake :refer :all]) nil user=> PS C:\Users\celap\Downloads\shcloj3-code\code> clj Clojure 1.10.2 user=> (require '[reader.snake :refer :all]) nil
Oops that was meant to be code blocked, anyway I am wondering why my first require of reader.snake didn't work but almost immediately after it did work
have you got a link to the repo?
you can create namespaces programmatically so its possible examples.snake does something like this
Ah I'm pretty beginner so not really understanding the repo thing - the code is on the page for the book in a zip file I will just link it
https://media.pragprog.com/titles/shcloj3/code/shcloj3-code.zip
There's a deps.edn in the folder root that I added paths to src/reader and src/examples in
Because it wasn't seeing those earlier when I tried requiring in code from the book
That's why you see the behavior above.
You tried to require a ns whose file wasn't on the path. You updated deps.edn
. You need to restart your REPL to pick up those changes.
I am not sure if the following explains it, but if you do a require
in a REPL that fails due to an error, there are some kinds of errors that still do cause the namespace to be created, and for the namespace to be added to a *loaded-libs*
Clojure var. If you then do a require
again with no special options, it will check *loaded-libs*
, see the namespace is there, and not attempt to read the file again, unless you do a require
with an option to force it to read the file again, e.g. (require 'examples.snake :reload)
, if I recall correctly.
*loaded-libs*
is there to prevent the otherwise common occurrence that later namespaces will require
namespace foo
, causing foo
to be loaded over and over again, including transitively everything that foo
requires.
Ah I think that might be it then - I did try to require the reader.snake file but it failed because I'd accidentally left some test code in the file but had deleted the defs for it, so it was like a symbol couldn't be found error thrown from the require, then I deleted the test code from the file, tried the require again which is where the code snippet I pasted starts from, it failed to find the namespace which confused me as it was working fine the previous day and I'd added paths to the folder in my deps (which I apparently don't even need) so I tried requiring the book's examples.snake (which is basically a copy of the code in a parallel folder) and it worked fine so I scratched my head, reloaded Clj and then the require of reader.snake worked fine, so yeah sounds just like what you describe, so that must be it, thank you, and thank you also Sean 😉
This probably explains many of the other times where I've had problems with not being able to 'see' namespaces/files where I could've sworn it was working fine earlier, if anyone's writing books for Clojure beginners I think this is something that should definitely be mentioned 🙂
This sort of thing is why it is so much better to work within an editor with a connected REPL, and then you aren't trying to type stuff into the REPL -- you're editing files and evaluating it directly into the running REPL.
Ah OK I see, many beginners' books if not the majority seem to assume working from the REPL though, so I think it would be a good idea to warn beginners about something like this
I learned something new though and reduced something magical to something I can understand, so feeling good thanks guys, wish you all a beautiful day 😉
Yeah, I think a lot of authors don't want to deal with the vast array of editors and plugins and getting those setup and configured.
Brave&True takes beginners through Emacs/CIDER setup -- which I don't think is a good idea (unless the beginner is already using Emacs perhaps!).
Maybe as more and more developers use VS Code, we'll start to see material that assumes VS Code (& Calva). That's certainly a pretty good beginner setup and the maintainer team is super-responsive and helpful.
What editor are you using @flyingpython? (I'm sure you've said before but I have a goldfish brain)
Ah yeah I'd say so, the VS Code numbers I saw on the last dev survey were huge, it seems to be rapidly approaching an industry standard, yeah I'm using Atom with your old REBL and Chlorine setup still and I occasionally use VS Code with Calva
I see Calva is getting some kind of interoperability with Clover now? So maybe I can use that setup with your new Clover config and Reveal?
Yeah, I'm using Calva for everything except actual REPL eval stuff -- which I'm using Clover for. And I'm using Reveal.
And that setup, for me, is identical on macOS (my work desktop) and Windows 10/WSL2/Ubuntu which is my personal laptop.
Oh that sounds cool, yeah I'll try switch to that sometime
https://github.com/seancorfield/vscode-clover-setup and https://github.com/seancorfield/dot-clojure (in particular for the Reveal extras in dev.clj
).
Thanks for the links, bookmarking them now
Installing Calva meant I could simplify my VS Code setup since it has its own paredit/rainbow parens etc -- so I stripped out three or four extensions after adding Calva. Then just edited Calva's settings to hide the nREPL UI (so I can use Clover's stuff instead).
Also, the hot keys for Atom/Chlorine work for VS Code/Clover if you follow my setup, so you don't even have to learn new key bindings 🙂
Ah OK so the hide REPL ui is the only setting thing you have to change in Calva when using it with Clover?
Yup.
Ah that is cool because I've grown accustomed to your keybindings and going back to Calva's felt really wrong 😛
Do you switch between multiple machines at all?
No I just have the one desktop machine which may be close to 10 years old now 😂
It is an amd phenom 2
From back when the very first quad core CPUs were hitting the market
Ah, OK. I asked because VS Code can automatically sync all your settings and all your extensions between all your machines 🙂 which I found very helpful when I went to set it up on a second machine (and it basically set itself up to match my first machine).
Oh yeah that's cool 🙂
Hi,
after tried several times, it still not connected, i figure out that i need
1. to define my :host-prefix "//FBI-HIDEOUT\\JUST_INTO_DS"
2. change my IPall port = 1433
3. make an inbound firewall for port 1433 (Instead I also turned my firewall off)
but still giving an error, please help address where's the mistake? I'm using SQL express for an exercise btw.
Execution error (SQLServerException) at com.microsoft.sqlserver.jdbc.SQLServerException/makeFromDriverError (SQLServerException.java:234).
The TCP/IP connection to the host FBI-HIDEOUT, port 1433 has failed. Error: "Connect timed out. Verify the connection properties. Make sure that an instance of SQL Server is running on the host and accepting TCP/IP connections at the port. Make sure that TCP connections to the port are not blocked by a firewall.".
But I had added the paths to the deps.edn yesterday and started the commandline and clj afresh today
I'm pretty sure "//FBI-HIDEOUT\\JUST_INTO_DS"
is your problem.
You shouldn't be mixing \\
and //
I think.
@seancorfield how should i write it?
(def db-sqlserver {:dbtype "sqlserver" :dbname "AdventureWorks"
:host-prefix "//FBI-HIDEOUT\\JUST_INTO_DS"
:port "1433"
:user "sa" :password "123456789"})
I didn't do anything else outside the terminal between typing in those different commands on the terminal so it seems a bit mysterious to me, I am sure this has happened to me before too, but I've also done a lot of silly newbie things so maybe it is just that again 😅
this repo is a little strange to me for some reason
user> (require 'reader.snake)
CompilerException java.lang.Exception: No namespace: examples.import-static, compiling:(reader/snake.clj:1:1)
user> (require 'examples.import-static)
nil
user> (require 'reader.snake)
nil
user>
Ah yeah I think there was a mistake in the require statement in that file that I had to correct - just look at the require for the import-static and it should be obvious
I think it used round brackets instead of the square ones or something like that
Are you sure you need :host-prefix
there? In the test suite for clojure.java.jdbc
, the MS SQL test from macOS to Windows uses :host "127.0.0.1\\SQLEXPRESS"
-- what is your setup with where you're running Clojure and where your MS SQL Server is running?
And you may need to add the paths to the folders in the deps file as it has no paths in it
I added src/examples, src/reader and src to my paths
my dependencies
:dependencies [[org.clojure/clojure "1.10.1"]
[com.layerware/hugsql-core "0.5.1"]
[com.layerware/hugsql-adapter-next-jdbc "0.5.1"]
[com.microsoft.sqlserver/mssql-jdbc "9.2.0.jre15"]
[mysql/mysql-connector-java "8.0.23"]
[honeysql "1.0.444"]
[seancorfield/next.jdbc "1.1.613"]]
I'm using windows 10, my MS SQL Server running from my own (not remote), i'm still practicing using SQL ExpressWhy are you using :host-prefix
? That's definitely not right (since :host
will default to "127.0.0.1"
and you don't want that weird string in front of that).
If the DB is running on localhost, you probably want :host "127.0.0.1\\JUST_INTO_DS"
(and remove :host-prefix
).
Not sure what FBI-HIDEOUT
is in that...?
(def db-sqlserver {:dbtype "sqlserver" :dbname "AdventureWorks"
:host "127.0.0.1\\JUST_INTO_DS"
:user "sa" :password "123456789"})
still give an error
Execution error (SQLServerException) at com.microsoft.sqlserver.jdbc.SQLServerException/makeFromDriverError (SQLServerException.java:234).
The TCP/IP connection to the host 127.0.0.1, port 1433 has failed. Error: "Connect timed out. Verify the connection properties. Make sure that an instance of SQL Server is running on the host and accepting TCP/IP connections at the port. Make sure that TCP connections to the port are not blocked by a firewall.".
i'll try to make another server instead of JUST_INTO_DS
That says that the JVM cannot connect to SQL Server running on localhost on the default port. Are you sure it's available on that IP address and not some other address?
I see 192.168.137.1
in that screenshot you posted.
i didn't make any changes, all is the default when establishing the server
The problem is that the source file src/reader/snake.clj
has
(:refer examples.import-static :refer :all])
but it should be
(:require [examples.import-static :refer :all]))
Until you make that change, you cannot (require 'reader.snake)
You don't need those paths added -- the deps.edn
file is correct as it stands.
Then maybe try :host "192.168.137.1\\JUST_INTO_DS"
is what I'm suggesting.
can't as well 😭🙏 I've tried that.
Then I have no idea how to help, sorry.
You'll have to find someone who a) uses Windows and b) uses MS SQL Server.
Sure no problem, you've helped me look into another different way... I'll try again... thank you so much.
If you were on macOS or Linux, I'd suggest using telnet
or nc
to diagnose the network connectivity, outside of the JVM, but I've no idea what to suggest for Windows.
I use WSL2 for all of my Clojure development on Windows (WSL2 running Ubuntu), and I use Docker for all of my MS SQL Server testing (and Microsoft's official Docker image for SQL Server is Linux-based).
yes this hangs only if javadoc
opened a new browser
OH GOSH... imagine looking up & down, left & right, back & forth.. lol the answer is to "restart" the server... waow, worth 2 days 2 night... ahahahahaha :rolling_on_the_floor_laughing:
I did already change the refer to the proper require form after receiving an error about it and then after that it couldn't find the files, a FileNotFound I think, so that's when I added the paths to the deps and then after that it worked fine for me until today when that happened with requiring the reader.snake
https://javarevisited.blogspot.com/2015/10/sql-server-jdbc-error-tcpip-connection-to-host-failed-port-1433.html#axzz6mcL0VpRF thank you @seancorfield @noisesmith @dpsutton
I always seem to get weird things like this from time to time, maybe it is a caching thing again?
if I build a jar is there a way todo the equivalent of -m app.commands I have an app with a webserver but it also has cli-matic embeded so in essence want to be able to run one of the cli-matic commands with out clj available
Is there a way to keep the nano seconds for a timestamp when using #inst?
User > #inst "2002-02-19T03:40:27.000404Z"
;; => #inst "2002-02-19T03:40:27.000-00:00"
no - the type being created there is ms precision
can you reffer to more info about this?
by default, #inst makes a https://docs.oracle.com/javase/8/docs/api/java/util/Date.html which has ms resolution
you could alternately construct https://docs.oracle.com/javase/8/docs/api/java/time/Instant.html s which have ns resolution
if you're looking for docs on #inst, see https://clojure.org/reference/reader#_built_in_tagged_literals
you can start clojure.main (the repl) from any jar with clojure: java -cp my.jar clojure.main
this won't have nice things like command line editing / history etc. but it is enough to run any code that clojure knows how to find and run
(ins)justin@abjection:~/foo-uber$ java -cp target/uberjar/foo-uber-0.1.0-SNAPSHOT-standalone.jar clojure.main -m foo.bar
Execution error (FileNotFoundException) at clojure.main/main (main.java:40).
Could not locate foo/bar__init.class, foo/bar.clj or foo/bar.cljc on classpath.
Full report at:
/tmp/clojure-18226576097563274172.edn
(ins)justin@abjection:~/foo-uber$ mkdir src/foo
(ins)justin@abjection:~/foo-uber$ cat > src/foo/bar.clj
(ns foo.bar)
(defn -main [& args]
(println "OK"))
(ins)justin@abjection:~/foo-uber$ java -cp src:target/uberjar/foo-uber-0.1.0-SNAPSHOT-standalone.jar clojure.main -m foo.bar
OK
tl;dr - yes you can use -m with an uberjarI have below string
Select * from table
WHERE
{
a.name="John"
}
I want to replace whatever comes from where
how can i achieve in clojure
fwiw, my first little project in clojure was because I was cold in my apartment. https://twitter.com/Grazfather/status/1361688395806879749
Really simple: oz and an i2c library to read from the sensor.
and just slurp to hit the API
@noisesmith thanks for that info good to know that's possible I will give it a try 🙂
I would like to split
Select * from table
WHERE
{
a.name="John"
}
as
Select * from table
WHERE
{
a.name="John"
}
anything other than (clojure.String/split stmt #"WHERE")
I've used this technique in production, making one jar with many namespaces with -main
functions to invoke, it can simplify things when a bunch of processes will all use the same deps
(that is, not using anything outside the jar, but having multiple entry points in that jar that can be run - kind of like what busybox is for embedded *nix)
using string manipulation on SQL should be avoided, you can look at honeysql
for example if you want to do generated queries
this is the source of "sql injection attacks", one of the most expensive errors in the industry
it really depends on whether your question is recognizing a pretty static template (anything inside of the { and } braces) or parsing arbitrary sql
for the latter, get an SQL parser, there must be multiple out there
but just because you parse most input correctly doesn't make any transformed result safe to run against data that matters
and regex operations are even worse
An anonymous function is both: (fn [a] (do-something a))
and #(do-something %)
- is there a name to differentiate the two “syntax styles”? I’m tempted to say “literal anonymous” v. “anonymous”.
The official Clojure docs call the #( ... )
syntax "anonymous function literal": https://clojure.org/reference/reader#_dispatch
I do not know of any special distinguishing name for a (fn [ ... ] ...)
expression.
indeed.
one is a standard invocation (of a macro), the other is a reader macro expanding to the same special form
(ins)user=> (macroexpand '(fn []))
(fn* ([]))
(ins)user=> '#()
(fn* [] ())
the extra ()
is a side effect of how that reader macro works
Nice and I’m thinking about new developers where for their benefit, it’s helpful to have a name to associate to a “style” to aid in their learning journey.
That’s amazing honestly
I generally refer to it as the “anonymous function shorthand” as verbose as that may be 😅
fair enough and makes sense!
good to know I just wanted a quick way of running a maintenance task running in a pod so this should work nicely.
can clojure do that? woww....
Hi, I have such use case. I have map which is single point of truth, and I have module with functions which operates on this map, something like this:
(defn get-something [db ...] ...)
(defn update-something [db ...] ...)
...
And I have two use cases, first simple where, app is single threaded,
second where app is mutlithtreaded and db is an atom.
For multithreaded version I've created new module and wrapped every function from the first module in 'swap!', deref etc.
for example
(defn update-something [db ...] (swap! db a/update-something ...))
...
The issue is that, every time I add something to the first module, I have to write 'wrapper' in second module.
Is there a way to avoid this duplication, and for example dynamically discover which version to use? Would multimethods be good fit here?Atoms are useful and useable in a single threaded environment. Could you use an atom for both cases?
I could, I'm just wondering if is there some 'elegant' solution, because in single threaded version using atom sounds like wasting cpu cycles (maybe I'm wrong about this....)
I don't think there's much to worry about perf wise. If it becomes a problem, you can always switch it out later. For me, I'd see using an atom in both cases as an elegant solution.
In single-threaded environment unless you are doing these swap!
calls millions of times per second, I doubt you'll notice a performance difference using it in a single-threaded program.
In a single-threaded program, the overhead of swap!
should be no more than one Clojure function call (the update function you pass to swap!
), a pointer-equality check, and a JVM compare-and-swap operation that should be optimized to a single CPU instruction if it is in a hot code path.
Is there a way to grab the metadata of a passed in value?
(defn get-fragments [comp]
(get-in (meta comp) [:helix/opts :apollo-cljs/fragments]))
All the examples I see show use of the exact symbol plus a reader macro
(meta #'Username)
Right now I'm trying to use the fn as (get-fragments Username)
But I just realized maybe passing in #'Username
would work instead. Doable, but not my ideal
Hello folks. I have a nested 3 lvl data, such as [[[1 2] [3 4]] [[5 6] [7 8]]]
. And I want to extract it to lvl 1 to become (1 2 3 4 5 6 7 8)
. I came up with
(->> [[[1 2] [3 4]] [[5 6] [7 8]]]
(apply concat)
(apply concat))
But what if the nesting will be more than 3 lvl in depth? And I don't like repeating my self with (apply concat)
. Is there more functional (contrived :)) approach to tackling the issue?You could use flatten
@qmstuart good to know, anyway flatten fits well with my issue
that exactly what I need, thank you
If Username
is a var that has whatever value you want to pass in to the function get-fragments
, calling (get-fragments Username)
passes the value of Username
, but not the Var object itself.
Clojure collections can have metadata 'attached' to them, and if Username
had a value that was say, a map, and that map had metadata attached to it, then calling (get-fragments Username)
would cause the (meta comp)
call inside of get-username
to get the metadata attached to that map.
If the metadata you want is on the var #'Username
, you can call (get-fragments #'Username)
to pass the var to get-fragments
, and then the (meta comp)
call will get the metadata on the Var, if any.
Okay thanks! Yes. Username is var (symbol made from a macro)
flatten might work if you only have vector of vectors, lists etc but for example if you have something like a set:
(let [xs [[1 2] [3 4] [5 6] [7 #{8 9 19}]]]
(flatten xs))
=> (1 2 3 4 5 6 7 #{19 9 8})
It won't work. AIUI, It will go into subitems if they return true for sequential?
So just be aware of this.atoms / swap! are indeed slow, you can use volatile! and vswap! in a single thread, or better yet use values as much as possible instead of holding and maintaining state. depending on app design / usage you could use an agent (guarentees that changes are serial but send returns before the change is applied) and/or some sort of queue consumer / data reducing pattern if the update patterns fit that
IMHO a data domain which treats multiple levels of nesting as equivalent to the flattened form is usually a design error, but flatten does do the specific thing you ask for
it's often a brittle element though, because we often want to refactor code that took an item to instead take collection types and flatten makes that break
Hi all, I’m having a bit of confusion regarding futures. I’m calling a process in the shell from my Clojure code and using a future to keep track of the streamed output. Here’s the code:
(defn start-server []
(sh/proc "/bin/sh" "-c" "c8 node index.js"))
(defn stop-server [process]
(let [output (future (sh/stream-to-string process :out))]
(sh/destroy process)
output))
When I run this, output has an error “Stream closed”. However, when I run these commands one by one in the REPL like so:
(def s (start-server))
(def o (future (sh/stream-to-string s :out)))
(sh/destroy s)
Then print out o, I correctly get the terminal output of the program between when I started and destroyed it.
Is there something about using “let” in the first example which makes the future not evaluate until after the sh/destroy call has been made? “Stream closed” should only occur if I try to call stream-to-string after destroying the process, but I can’t see why that would be happening hereA future is a separate thread, evaluation happens in parallel
Once the new new threading is running there is no defined ordering relationship between what is being executed in your two threads, so what you have is a race condition
So in other words the sh/stream-to-string
call might actually occur after the sh/destroy
call on the other thread… makes sense. Is there a better way to go about what I’m trying to do? (run a program, store its output as its running, then kill it)
or at a smaller scale - enforce ordering here?
I guess the question is, why are you calling stream-to-string in a different thread from destroy, if you want destroy to be called after stream-to-string
There are ways to do that, but the simplest thing is to put them both on the same thread, and the simplest way to do that is to stop using future
I used the future because stream-to-string seems to block indefinitely since it’s waiting for the process to end (which it doesn’t since I have to kill it manually using destroy)
so from my understanding I need to run it on a separate thread so that I’m able to call destroy when I need to
So how do you know when you need to call destroy?
I’m writing a tool to fuzz a nodejs API, so it starts the API using c8 (which prints code coverage metrics to the terminal), runs a bunch of commands against the API, then shuts it off and inspects the output to view code coverage metrics. So it would be programmatic (but hard to illustrate here)
in reality this may not be a problem since the time between calling stream-to-string and destroy will be at least a few minutes, so the chance of a race condition would be virtually impossible
So put (when X (destroy ...))
The figure out X
alright perfect - thanks for the help. Sorry for the silly question, talking it out really helped clear things up