Fork me on GitHub
#beginners
<
2020-01-04
>
joaoapel01:01:36

Hello, noob here 😀

seancorfield01:01:33

Welcome to Clojurians @joaoapel!

shin11:01:43

Hey everyone, trying to write data to a sqlite db, which works fine in the repl. but it doesn't when I run my program via lein run or as an uberjar, could it be related to some lazy evaluation stuff (using map to populate it)? the database file is created, but no entries are written to it

rahul08032711:01:29

try using ! instead of map. map should be used for functions not doing any IO and that returns something.

rahul08032711:01:08

its run! the url drops the ! for some reason 😕

shin11:01:53

thanks! will try it out

shin11:01:13

I tried to wrap my map in a "do" before, but that didn't seem to work either

shin12:01:52

run! does the trick 🙂

iagwanderson12:01:20

you could use doall to debug if the problem was related to the lazyness too

iagwanderson12:01:40

I often use doseq in these cases where the collection is not "long" or when I want to go faster I go to pmap instead. pmap is already eager and will execute in parallel. Sometimes, its most beneficial to me.

didibus18:01:52

You gotta be careful with side-effects running in parallel though

didibus18:01:39

do is used to turn an s-expr into an imperative program. Like (do (1) (2) (3)). doall is used to realize a lazy collection in order to perform its side-effects or simply force the computation to happen.

didibus18:01:35

So doall around the map would have worked as well. That said, it is still better practice to just avoid lazy sequence functions for side effects and use functions specially meant for them like run!

hi13513:01:24

Hello. I'm making a simple DSL in Clojure which happens to have a let keyword. I'm writing a function to generate example program (for testing). It should produce an s-expression of the form (let <names> <expr>). Therefore, I'm returning

`(let ~names ~body)
The problem is, it ends up as:
('clojure.core/let ... ...)

hi13513:01:40

Can I unqualify the let symbol?

hi13513:01:42

Ah, ok, I just discovered ~'. Nevermind.

qythium13:01:15

you could also construct the form manually with list and no syntax-quotes

qythium13:01:27

(list 'let names body)

kamuela13:01:34

I think in most languages I'm working with I constantly ask myself about mindshare/library usage etc, but Clojure is perhaps the first language I truly enjoy, so I mostly think in terms of "well if it doesn't have it, I guess I'll have to write it myself"

didibus18:01:27

Good attitude. A language grows from people developing it. That's where there's a lot we can help with.

didibus18:01:02

That said, the secret weapon is that... If you don't have the time to write it yourself, you can just use a Java library for it instead.

didibus18:01:01

Which gives it a lot of buffer to slowly develop it's own libs and frameworks and tools, while still being a production ready language you can use for work since you can always lean in to Java

kamuela14:01:03

There's quite a lot of potential for Clojure to be the new Python in that respect, e.g. the "second best language to do anything in"

iagwanderson14:01:45

I recently had a very interesting case of adopting clojure at my company

iagwanderson14:01:53

we are using it for almost one year now

iagwanderson14:01:30

people used to python programming are truly enjoying the experience, I am thinking to do a "experience report" presentation some day

iagwanderson14:01:10

interesting fact, English was more a problem than Clojure if we talk about languages rsrsrs

alper14:01:54

I’m main in python and I’m adding FP because I know pretty much everything about Python after ~20 years. I would still recommend it though.

alper14:01:54

I looked at Haskell but concluded there wasn’t really a there there and ended up here. I’m really enjoying not to have to type functions ahead of time (or at all).

kamuela16:01:44

A there there?

alper16:01:28

Haskell seems to be difficult to use in the real world. The channel at the FP Slack is full of beginners struggling hard with it. The documentation is also really bad which the people there take to be a natural state of things. In general I guess it comes down to Haskell being a language for FP research and that’s what it will stay.

kamuela16:01:19

I've also done the back and forth between the two, and for me, I just find the S-expressions and "syntaxlessness" of Clojure more in-step with what my brain considers elegant. Java/JS interop, immutable data, and all the metaprogramming goodies are just extras to me

didibus18:01:01

I also know and saw quite a few people for whom learning Haskell to learn FP is actually a detriment. Because they quickly conflate FP for things that aren't core to it, like Hindley Milner types, and all the pseudo category theory stuff. I think Clojure is much better at teaching FP fundamentals, and if you want to explore with pseudo category theory there's libs for that.

didibus18:01:03

libraries*

alper19:01:22

There really is a library for everything. I noticed most of a golang and bit of prolog in the standard lib as well.

didibus19:01:14

Yup 😉 It's part of being a Lisp. You can extend the language using only libraries, where most other languages it could only be done with fundamental changes to the core language, Lisps allow quite a lot more to be done without needing to touch the parser/compiler at all

didibus19:01:39

If you look at Clojure's implementation, you'll actually see that a lot of it is in Clojure itself. All of those parts could have just been libraries.

shin15:01:42

https://github.com/ogrim/clojure-sqlite-example/blob/master/src/clojure_sqlite_example/core.clj I followed this to create a db, but it doesn't work if I put it in -main and run with lein run

iagwanderson15:01:46

I just executed here and it works fine:

Initializing NoDisassemble Transformer
{:timestamp 2020-01-04 15:19:57, :url , :title SQLite Example, :body Example using SQLite with Clojure}

iagwanderson15:01:07

Have you setup in your project.clj the :main path?

shin15:01:00

ahh my bad, I still had some code outside of a function in my code from testing which tried to query the db before it existed, sorry!

hi13517:01:24

Can I test with clojure.test against infinite recursion?

lennart.buit17:01:31

well; you’ll get a StackOverflowException when you recurse long enough. But why would you want to test against that particular case? A ‘normal’ unit test would already (implicitly) test that a function terminates normally right

hi13517:01:02

i'm writing a DSL and I'm testing that I actually can cause infinite recursion. normal test does indeed eventually fail but for small cases when I don't allocate much memory it's cumbersome to wait.

hi13517:01:47

but I guess it would be very hard to detect recursion analytically so... yeah, probably not possible

lennart.buit17:01:03

This stackoverflow: https://stackoverflow.com/questions/1030527/how-to-detect-an-infinite-loop-in-a-recursive-call suggests that by checking the received arguments you can detect cycles ‘soon enough’

didibus18:01:42

I think you can write a test which recurse and has no branching

didibus18:01:13

And just assert that it successfully called itself and then did the exact same thing one more time

didibus18:01:02

That's enough to know that your DSL can perform infinite recursion

glfinn8318:01:13

Anyone here write Clojure in VS Code? I'm not able to get code suggestions/completion working. I have both Calva and the Clojure plugins.

glfinn8318:01:49

Also, anyone here use Eclipse for Clojure?

alexmiller18:01:26

Eclipse Counterclockwise has not been in development for several years and I think few are using it at this point

pez18:01:36

@glfinn83 Calva or the Clojure extension, it's a choice you need to make. They overlap almost fully. (Calva can be seen as a large super set). Lacking suggestions and completions is most often due to not using jack-in, and instead connecting to a repl not started by Calva. Try with jack-in and see if that helps.

glfinn8319:01:00

Thanks @pez

shin19:01:20

does anybody know if this is possible to do from inside clojure? https://www.sqlitetutorial.net/sqlite-tutorial/sqlite-export-csv/

seancorfield19:01:19

@shin Do you mean "select all rows from a given table and write it to a CSV file"? Yes, that's pretty straightforward in Clojure.

shin19:01:29

@seancorfield that's right, can I use the sqlite things directly too?

seancorfield19:01:48

Not sure what you mean by "use the sqlite things directly"?

seancorfield19:01:29

Do you mean "run the command line sqlite tools from inside Clojure"?

seancorfield19:01:49

If so, look at clojure.java.shell for how to shell out and run command line stuff.

shin19:01:43

pretty much what's described inside the article, I think shell commands wouldn't work, since I want to compile it to an uberjar and it's not certain that sqlite is installed there

dpsutton20:01:37

the article describes using the program sqlite3 from the command line. you can use next.jdbc to select all of the data from sqlite and then write it to a csv file with clojure/data.csv. @shin does that answer your question?

erp1220:01:10

@shin I agree with @dpsutton if all you need is simple select * from ... queries to be written as csv. If you require more complicated queries, then I would strongly recommend you build your queries in Clojure with a tool like Honeysql (https://github.com/jkk/honeysql) which can then be handed off to jdbc for execution against the database.

deep-symmetry20:01:57

And I agree with your worry that trying to use shell commands in an uberjar where you can’t control the environment in which it will be used is unlikely to succeed.

shin20:01:10

it's a fairly simple query, I'll try data.csv then 🙂 thanks everybody

seancorfield20:01:51

If you have questions about the SQL side of that, I maintain both org.clojure/java.jdbc and seancorfield/next.jdbc and there's a #sql channel for deep dives on that.

seancorfield20:01:38

@shin You'll probably want jdbc/execute! (from next.jdbc) with {:builder-fn rs/as-unqualified-arrays} -- where rs is next.jdbc.result-set

seancorfield20:01:46

That will give you a vector of vectors as a result. The first vector will be the column names -- which will map to your CSV header line -- and the rest of the result will be all the rows.

shin20:01:12

thanks! I'll have a look