Fork me on GitHub
#beginners
<
2018-08-27
>
lspector00:08:39

Hi @seancorfield! I've used and really liked NightCode in the past, but now it involves mandatory parinfer, which is a problem. @sekao's Lightmod is also super exciting for me, but same problem. In this semester's case it'll be people with some programming experience, but my ideal environment would also work for total beginners. And I don't want to count on any experience with fancy setup or sysadmin stuff, etc.

seancorfield00:08:38

Interesting. What's the problem with parinfer? It seems like one of the better solutions to the paren-balancing/indenting problem.

lspector02:08:43

@seancorfield Parinfer adds and deletes brackets where users haven't typed or intended to delete them, which can be super confusing to beginners (and even non-beginners like me -- I can't work in it at all). Typing skills are maybe the one solid foundation for newcomers in a bewildering new world, and when you mess with that in baffling ways, and make it so users can't even type and have text behave as it does in every other editor, it can pull the rug out from under them and undermine all confidence. I think the best solution to the paren-balancing/indenting problem is one we've had for decades in many lisp environments: syntax-aware re-indentation upon command. Rainbow parens etc are also nice. But everything that messes with basic typing in unexpected ways creates more problems than it solves. This is true for beginners in my experience (I've been teaching beginners lisp for over 25 years) and also for anyone, like me, who often types/copies/pastes bits of code out of order, which paredit makes impossible and parinfer makes into a circus.

john14:08:01

Have you tried atom/protorepl? There's some special sauce in its implementation. Never seems to get in the way. I just tried the vscode parinfer one and it just get's in my way. Be sure to look for the buttery smooth atom one before giving up on parinfer

seancorfield02:08:39

I'm so used to editors that auto-complete (, [, {, etc that I guess it seems natural to me... But I can also see how an editor inserting characters is "magic" for beginners. No one seems to want to solve the editor problem without auto-completion tho'...

dpsutton02:08:08

would bhauman's rebel-readline maybe be a good starting point?

dpsutton02:08:29

then its on the command line so you can leave cursive/emacs/calva for self exploration and another day?

Ramzi02:08:10

What's the fastest way I can connect cljs to a clojure backend?

Ramzi03:08:50

I get that the cljs frontend makes an ajax call, but what catches it?

johnj04:08:45

the clojure backend? not sure I follow

Ramzi04:08:08

so clojurescript is javascript running clientside

Ramzi04:08:14

and clojure is java running server side

Ramzi04:08:22

depending on where i want to do the computations

Ramzi04:08:36

how can i call from the clientside to the server side for information, like, a database query or something

Ramzi04:08:10

or a function. how can i call a function on the server side from the client side

lspector04:08:54

@seancorfield, I agree that auto-completion of (, [, {, etc. is not that big of a deal. But with parinfer, you add or delete a space and brackets appear or disappear, possibly on different lines, changing the structure of your code. This "messes with typing" in a more extreme and unexpected way than autocompletion, which I agree is pretty easy to understand and deal with. For me and my students (some of whom used Nightcode last semester because of installation issues with other tools) parinfer often produces bizarre and disconcerting results.

lspector04:08:34

@seancorfield, on "No one seems to want to solve the editor problem without auto-completion tho'..." -- I think it is solved admirably well by every system that provides syntax-aware re-indentation, of which there are many. Some that I've used in Clojure are Gorilla REPL and Counterclockwise, and Clooj (long dead, I think) and older versions of Nightcode, etc. The gap right now is a well-maintained, current system that provides this solution along with beginner-friendly installation. From my recent surveys Gorilla REPL comes the closest, but I don't know if there's something new. I see some Jupyter-based approaches that look great in terms of installation and ease of use, but unless I'm missing it they provide no syntax-aware indentation.

lspector05:08:27

Thanks @dpsutton but I do need something that allows file editing. The leap to Emacs is a leap too far in terms of installation, setup, and learning curve. I follow and occasionally try Cursive, but again it's a big leap for beginners and is overkill with respect to our needs (which are pretty much just editing with syntax-aware re-indentation and a REPL). I don't remember having looked into calva and I don't know much about Visual Studio... Thanks for that lead, which I'll check out.

Ramzi05:08:17

How does ajaxing to a location run a function?

johnj05:08:40

@its.ramzi I think you should slow down and learn some fundamentals

Ramzi05:08:21

I've written an app before, where Ajax called JSP, and JSP called Java, and Java with Hibernate wrote to Postgres

Ramzi05:08:45

So without the JSP layer here I'm confused about how an Ajax call is supposed to reach Clojure.

seancorfield05:08:18

JSP is just part of the server. Same as Clojure.

Ramzi05:08:55

Can you help me write an app where an ajax call cljs side causes a sout clojure side?

johnj05:08:03

ajax calling jsp sounds weird, I think you are confused there

seancorfield05:08:31

Well, using "ajax" is a bit of an umbrella term.

Ramzi05:08:06

I imported jquery and am using $.ajax()

seancorfield05:08:19

The client code in the browser makes an HTTP request to a server and the server takes that HTTP request and processes it and sends back an HTTP response, which the client then deals with.

seancorfield05:08:30

And that's the same regardless of client or server technology.

Ramzi05:08:05

how can i go from a fresh Reagent checkout, to having an input cause a server side print out?

seancorfield05:08:27

Reagent is purely cljs / client side so your question doesn't really make sense to me.

Ramzi05:08:51

i thought when you launch it, it running an HttpServer made it serverside also

seancorfield05:08:05

But the server side is not Reagent.

Ramzi05:08:15

But it's part of the reagent project

johnj05:08:24

@its.ramzi that server is just for development

Ramzi05:08:33

the Jetty server?

Ramzi05:08:38

Jetty isn't a prod server?

seancorfield05:08:06

Sure, you can use Jetty in production.

johnj05:08:15

it is, I mean is a convenience for you to run your reagent code

seancorfield05:08:24

But I think you need to be clear about how HTTP request/response works in the big picture.

seancorfield05:08:53

There's nothing different about cljs/clj development compared to, say, JS / JSP / Java development in that respect.

prabhath605:08:57

Hi, I am trying to copy content to clipboard when a list item is clicked. I found a solution in javascript, which i tried to convert to clojurescript and failed.

var copyText = document.getElementById("myInput");
 
   /* Select the text field */
   copyText.select();

   /* Copy the text inside the text field */
   document.execCommand("Copy");
when i try to do something similar in clojurescipt it fails
app:emoji-search-clojurescript.core=> (.getElementById js/document "emoji-title-100")
#object[HTMLParagraphElement [object HTMLParagraphElement]]

app:emoji-search-clojurescript.core=> (.select (.getElementById js/document "emoji-title-100"))
#object[TypeError TypeError: document.getElementById(...).select is not a function]
How do i select the value and then copy it to clipboard.

Ramzi05:08:37

try js/select

Ramzi05:08:27

@seancorfield can you help me go from a fresh Reagent checkout to getting a server side print out?

prabhath605:08:28

app:emoji-search-clojurescript.core=> (js/select (.getElementById js/document "emoji-title-100"))
#object[ReferenceError ReferenceError: select is not defined]

seancorfield05:08:01

@its.ramzi I have no idea how to explain it to you beyond what I've already said.

seancorfield05:08:49

I think you might be better off starting with a simple server side console app and ignoring the whole client side stuff for now.

seancorfield05:08:47

Learn how to write a simple Clojure console program that interacts with a database. Then learn how to extend that to a Ring web app that produces HTML pages on the server. Then look at how to connect a Reagent front end to a REST API on the back end.

seancorfield05:08:22

@prabhath6 Maybe ask in #clojurescript since you're dealing with specifically front end stuff?

timmyjose06:08:06

Hello, I needed some help getting leiningen to work on macOS High Sierra (10.13)

timmyjose06:08:27

Please let me know if I need to ask this in a different channel!

timmyjose06:08:08

I have many JDKs installed, and my default currently is JDK 11ea...I installed leiningen using homebrew, and when I try to run lein repl, I get the following error messahe

timmyjose06:08:39

Exception in thread "Thread-1" java.io.IOException: Cannot run program "/Library/Java/JavaVirtualMachines/jdk-11.jdk/Contents/Home" (in directory "<elided>/testproj"): error=13, Permission denied at java.base/java.lang.ProcessBuilder.start(ProcessBuilder.java:1128) at java.base/java.lang.ProcessBuilder.start(ProcessBuilder.java:1071)

timmyjose06:08:00

I have lein in /usr/local/bin, and LEIN_HOME is owned by my user name

timmyjose06:08:25

I tried changing the JDK to 1.8 (of course, that didn't work either), and I tried running lein with sudo, and no luck

timmyjose06:08:08

I had also installed the clojure executable using homebrew, and running that starts up a REPL without any problem

timmyjose06:08:14

Is there something I am missing?

timmyjose06:08:26

Or should I install Java in a custom path owned by my user?

timmyjose06:08:30

My JDKs are:

timmyjose06:08:56

$ /usr/libexec/java_home -V Matching Java Virtual Machines (3): 11, x86_64: "Java SE 11-ea" /Library/Java/JavaVirtualMachines/jdk-11.jdk/Contents/Home 9, x86_64: "Java SE 9-ea" /Library/Java/JavaVirtualMachines/jdk-9.jdk/Contents/Home 1.8.0_112, x86_64: "Java SE 8" /Library/Java/JavaVirtualMachines/jdk1.8.0_112.jdk/Contents/Home

timmyjose06:08:46

So these are installed in directories owned by root, of course (not sure why this would be a problem though):

timmyjose06:08:54

$ ls -ld /Library/Java/JavaVirtualMachines/ drwxr-xr-x 5 root wheel 160 Aug 27 11:16 /Library/Java/JavaVirtualMachines/

timmyjose08:08:31

Is this group active?

tap09:08:19

@timmyjose What do you get when you run java -version?

tap09:08:51

I'm on 1.8, I heard (correct me if I'm wrong) that 1.9 and later aren't seamlessly working yet.

gaverhae09:08:49

@timmyjose I guess the easiest path forward would be to set java .18 as the default from the Java Control Panel?

gaverhae09:08:54

(open from System Preferences)

gaverhae09:08:46

If that doesn't work I'd suggest trying this: https://github.com/technomancy/leiningen/blob/master/sample.project.clj#L287-L289 in your ~/.lein/profiles.clj

gaverhae10:08:37

@its.ramzi Lots of web frameworks in other languages make it all work as by magic and don't really require you to understand what really happens. Clojure is a bit different in that its typical set of libraries for web development really just offer a very thin layer of Clojure data structures on top of HTTP concepts. Which means you really need to understand how HTTP works to be successful there; that's a bit of up-front work, but knowing HTTP will serve you well in any kind of web project.

timmyjose10:08:47

@tap I have tried with both 1.8 and 9 and 11ea ... the problem seems to be a weird permission problem for lein when it tries to spawn a process

timmyjose10:08:52

@gaverhae I set the default to 1.8/9/11ea and tried it just in case, but no luck... this seems to be some weird permission error when lein tries to spawn a process ... maybe some other folks on macOS have seen this issue before? I tried reinstalling lein as well, but no dice

timmyjose10:08:48

Okay, never mind... after rebooting the machine, it appears to be working now... no bloody idea why! 😛

timmyjose10:08:01

Thanks for your help though, @tap @gaverhae

timmyjose10:08:14

And one more thing - I joined a company where the main language used is Clojure. As such, I wanted to start learning it on my own before joining. I have a decade of (mostly) Java under my belt, and have some experience with Common Lisp. As such, could anyone recommend a good book/resource to learn it today? A few years back, I had played around a bit with Clojure, and I didn't particularly like Emerick or Holloway's style

schmee11:08:16

@timmyjose I highly recommend The Joy of Clojure, covers most of what you need to know including some more advanced topics

👍 1
timmyjose11:08:07

@schmee Okay, will check it out. Thanks! 🙂

Michael Stokley17:08:47

is there a way to express infinity? specifically, i'm looking for a more declarative way to express (or (nil? prev-best) (< (get cur "executionOrder") (get prev-best "executionOrder")))

noisesmith17:08:08

as in the value?

user=> ##Inf
##Inf

noisesmith17:08:50

see also ##-Inf

noisesmith17:08:19

user=> (= (/ 1.0 0.0) ##Inf)
true

hiredman17:08:38

I usually use Long/MAX_VALUE (which is definitely not infinity) because I try to avoid floating point

👍 1
Michael Stokley17:08:35

@noisesmith thank you. not sure why i couldn't find that in the docs 🙂

andy.fingerhut19:08:31

One reason is that it wasn't in many of the docs on Monday. It is now documented in a few places, such as:

noisesmith17:08:25

if you create an infinity in the repl, that reader literal is what it shows you

Michael Stokley17:08:30

ah - looks like it was introduced in 1.9?

Ramzi18:08:50

@john which of those connect a Clojurescript front end to a Clojure back end?

Ramzi18:08:13

Some look like they create the HTML server side and pass it up via HTTP or something.

Ramzi18:08:24

Whereas I want to use a Javascript library clientside.

Ramzi18:08:16

does this look incomplete to anyone else? https://github.com/prabhasp/slickgrid-cljs

danny18:08:05

I’m having some trouble testing routes in an app that uses compojure-api. One of the handlers is asynchronous and returns a channel. The server runs fine, but when running tests the async handler produces the following exception:

ERROR No implementation of method: :render of protocol: #'compojure.response/Renderable found for class: clojure.core.async.impl.channels.ManyToManyChannel
java.lang.IllegalArgumentException: No implementation of method: :render of protocol: #'compojure.response/Renderable found for class: clojure.core.async.impl.channels.ManyToManyChannel

danny18:08:37

Since i’m using lein-ring to run the server and build the uberjar and it works fine under those conditions, I assume I’ve missed some bit of configuration in the tests. If anyone could point me in the direction of some docs (or a solution!) it’d be much appreciated. I can’t find anything that looks relevant on the repos for compojure-api or ring

hiredman18:08:05

there is a source file somewhere that extends the Renderable protocol to a channel, and I bet that source file is loaded in the machinery that lein-ring generates, but not otherwise, so when run outside of lein ring (when testing) you get that error. so if you look through the compojure sources and find that file, and make sure to require that namespace in your tests, I suspect it will work

👍 1
john18:08:05

@its.ramzi Not sure. You should familiarize yourself with those too, though, regardless. As having a good understanding of the many options available to you for backend dev is important.

john18:08:21

This example, based on luminus, might be closer to what you're looking for though https://github.com/yogthos/pg-feed-demo

john18:08:42

It uses postgres, clojure and clojurescript SPA on the frontend

Ramzi18:08:00

@john, that looks to be just what I need, but all of the installation instructions are seeming daunting right now. I wish I had some other devs to task with this, but they're on other things. I need to talk to the manager to pull resources, but he hasn't been in in weeks.

Ramzi18:08:28

In the meanwhile, I am looking into Slickgrid, and thinking about how Slickgrid will play with Clojurescript.

Ramzi18:08:55

john are you typing?

john18:08:10

I don't normally advertise services for cognitect or any other companies for that matter, but if you've already landed the contract, you have a budget and you're in a time crunch, I'd definitely recommend reaching out to cognitect to help get you up and running. Or maybe solicit some support from an independent contractor in #remote-jobs. Most Clojurists get by fine learning from here on slack and online resources. But I'm not sure if that works with your timeline.

Ramzi18:08:56

we inherited a working program that is done with EmberJS, Java, and Postgres

pablore18:08:56

can I use transducers with clojure.lang.PersistentQueue ?

Ramzi18:08:08

No one knows Ember so I was looking to replace it with Clojurescript.

john18:08:57

That can either be really easier or really hard, depending on what aspects you're familiar with. Certain aspects of a migration like that would probably be difficult for most people.

john18:08:56

Like, I don't know rails and I'd be way slower to figure out how to migrate a rails system over to a ring/clojure one

andy.fingerhut18:08:21

@pablore I do not know, but I would recommend asking in the #clojure or maybe even #clojure-dev channel, as there may be others watching there who know.

andy.fingerhut18:08:21

I would guess that 'feeding' a PersistentQueue into a transducer should present no problem, but whether you can feed the output of the transducer into a PersistentQueue in such a way that it is created, without also creating an intermediate sequence, may also be something you wanted an answer to.

Ramzi19:08:05

Is there a better grid software for Clojurscript than Slickgrid?

Ramzi19:08:46

@john it says The first step is to create a schema for the app, and set the connection URL in the profiles.clj. Where is profiles.clj? If I have to make it, where do I put it?

Ramzi19:08:44

lein migratus create events-table says migratus is not a task

danny19:08:07

fwiw it looks like the options for getting around the Renderable error i was receiving are to provide an extension of the compojure.response.Renderable protocol for testing purposes, or to call the handler with respond and raise callbacks in the test code. Compojure-api provides implementations of compojure.response.Sendable for channels and aleph deferreds, but does not provide implementations for Renderable (which makes sense i think since it looks like Sendable is supposed to be for async while Renderable is for sync…). When using lein-ring you can tell the plugin to treat the handler as async which has it start a server with the :async? option set to true and I assume that makes it pass all requests with respond and raise, which makes compojure use the Sendable protocol, which is why the server ran fine while my test that used the handler with only a request argument (thus triggering the Renderable protocol) failed.

Ramzi19:08:52

Every guide I follow breaks at some point. Frustrating

Ramzi19:08:08

@john, I just bought an ebook called Clojure Web Development Essentials.

Ramzi19:08:16

Like the second instruction was to run lein ring server

Ramzi19:08:25

And I got that ring is not an instruction

john19:08:19

You need a basic baseline of understanding (what's a project.clj file?) to even start with some of these tutorials. And hearing folks talk about it in videos, socially, can sometimes shed a lot more anecdotal light on the subject that you'd get by hunting through texts.

👍 1
Ramzi19:08:22

Im trying to call a Clojure helloworld from clojurescript. this shouldnt be difficult

john19:08:57

I've heard good things about that book

john19:08:13

dang, that's pretty sweet

Ramzi19:08:00

i cant even check it out

dpsutton19:08:01

what do you mean Ramzi?

Ramzi19:08:26

lein new clj-ring-cljs-reagent-demo asdf Failed to resolve version for clj-ring-cljs-reagent-demo:lein-template:jar:RELEASE: Could not find metadata clj-ring-cljs-reagent-demo:lein-template/maven-metadata.xml in local (/home/dev-user/.m2/repository)

ikitommi20:08:33

@clarkenciel common trick on ring-cps testing is to create the respond and raise as (promise) and deref with timeout.

danny20:08:32

that’s good to know! thank you!

john20:08:53

@its.ramzi lein new does not search github

john20:08:39

It searches clojars. clj-ring-cljs-reagent-demo is not on clojars. You have to git clone ... that repo to work with its example material

dpsutton20:08:01

it uses a template. @its.ramzi just read through it. It explains how to get started

dpsutton20:08:09

> lein new reagent-frontend simple-frontend

Ramzi20:08:36

When I try running SIMPLESERVER_CONFIG_FILE=resources/simpleserver.properties lein with-profile +log-dev ring server-headless

Ramzi20:08:57

it says Error encountered performing task 'ring' with profile(s): 'base,system,user,provided,dev,log-dev' Task not found

Ramzi20:08:55

im not thinking clearly. maybe i should just go home

noisesmith20:08:15

in leiningen, new tasks are created by plugins

noisesmith20:08:47

so to run lein ring ... you need the lein-ring plugin (or something else that provides it) in your project.clj

Mario C.21:08:56

Something mysterious is happening and I can't pick up on why its happening

Mario C.21:08:19

I am using cheshire to convert a clj map to JSON

Mario C.21:08:12

I had a joda-time object and it would crash during encoding. So I had to add an encoder to convert that joda-time to a string. But now I got rid of the encoder and it still works.

Mario C.21:08:17

Why is that?

noisesmith21:08:42

did you leave your repl or process running? the encoders are a global stateful thing

Mario C.21:08:21

I quit my app and restarted it but I have a feeling it deals with something like that

Mario C.21:08:40

I was running with lein with-profile clj,dev run

Mario C.21:08:51

Then quitting with ctrl-c

noisesmith21:08:38

unless it's a question of compiled stuff that lein clean would take care of, that should have reset the state of the encoders

Mario C.21:08:47

I quit the app and ran lein clean and restarted and it still seems to be working

Mario C.21:08:35

Its being saved as a string so that tells me somehow the encoder is still active

dpsutton21:08:44

do you still use clj-time or anything like that?

Mario C.21:08:26

I am using clj-time

dpsutton21:08:32

did you recently add that?

dpsutton21:08:52

i think there's a namespace in that if included anywhere side effects things like this

noisesmith21:08:55

this ns extends clj-time joda instants to work as clojure instants https://github.com/clj-time/clj-time/blob/master/src/clj_time/instant.clj

dpsutton21:08:13

yeah that's what i was thinking of. it can be convenient but its very at a distance

noisesmith21:08:17

and I wouldn't be surprised if cheshire could work with that

Mario C.21:08:04

I did add clj-time recently to go back from string to a joda date

noisesmith21:08:59

yeah, I bet that's what's doing it

Mario C.21:08:08

Previously cheshire was going through the map and when it saw a jodatime it yelled and said it didn't know what to do with it. So I added the encoder and everything went dandy. So whats happening now that I got rid of the encoder?

Mario C.21:08:47

Does this mean I don't need the encoder at all anymore?

Michael Stokley21:08:14

I have a function here (fn [{:strs [variable operator value]}] (operator variable value)) that i'm swapping into an existing list ("to-be-replaced" {"variable" 1 "operator" + "value" 0})

Michael Stokley21:08:36

when i quote the function, it works

Michael Stokley21:08:57

when i syntax quote the function, i get a huge error about the call to clojure.core/fn not conforming to spec

hiredman21:08:41

syntax quote namespace qualifies symbols

hiredman21:08:13

most binding constructs need symbols that are not namespace qualified for names

Michael Stokley21:08:51

the binding construct here being the map deconstruction?

hiredman21:08:26

fn is a binding construct in that it establishes a binding of the argument names to the arguments in the scope of the body

hiredman21:08:34

so when you syntax quote you are not getting (fn [{:strs [variable operator value]}] (operator variable value)) but instead you are getting (clojure.core/fn [{:strs [whatever/variable whatever/operator whatever/value]}] (whatever/operator whatever/variable value))

hiredman21:08:01

where the namespace whatever is whatever namespace *ns* is bound to when the syntax quoted form is read by the reader

Space Guy21:08:09

When should I prefer "evaluating selected forms" (seen in editor plugins) vs "instarepl"/"eval whole file on save"? (figwheel/shadow-cljs)

hiredman21:08:41

the general work around for this is ~'

👍 1
hiredman21:08:50

which is escape from syntax quote and quote

Michael Stokley21:08:59

since ' works, maybe that's all i need

Michael Stokley21:08:09

nice, that did it!

noisesmith21:08:34

~'foo introduces the possibility of hygiene problems, so if possible it's good to use foo# instead

noisesmith21:08:48

but I guess that doesn't help in a keys destructure