Fork me on GitHub
Michael Stokley00:05:15

Error printing return value (ClassCastException) at clojure.core.logic.Choice/bind (logic.clj:1094).
clojure.lang.LazySeq cannot be cast to clojure.lang.IFn


map returns a lazy seq, core.logic programs are made up goals (== returns a goal, as does permuteo, etc) you cannot mix and match them like that


your map call is returning a lazy-seq of goals (because the maping function returns the goal returned from the unification)


so you need something that takes a seq of goals and returns a single goal, in this case conjunction of goals (the other option is a disjunction) which I don't entirely recall the name of


everyg or all


but you are likely to run into other issues too


your filter call won't work either


you just can't mix non-logic stuff into logic programs like that

Michael Stokley17:05:49

thanks @U0NCTKEV8 - makes sense.

Michael Stokley00:05:36

(l/run* [out-list]
  (let [lvars (repeatedly 3 l/lvar)
        pairs (map vector (list nil nil 3) lvars)
        important-pairs (filter (fn [[x _]] (not (nil? x))) pairs)]
    (l/fresh [lvars]
      (l/== out-list lvars)
      (l/permuteo (list 1 2 3) out-list)
      (map (fn [[x y]] (l/== x y)) important-pairs))))

Michael Stokley00:05:57

anyone know why that last map is throwing the above error?


which call to map?

Michael Stokley00:05:14

in the last line

Michael Stokley00:05:29

sorry, l is clojure.core.logic

Michael Stokley00:05:29

is important-pairs lazy or something, as produced by let?


filter is always lazy


I don't know enough about core.logic to get much further than that though, I thought it was macro based and I wouldn't expect those macros to work with lazy-seq args, but I could be totally off track here


i’m using sente, and on a successful server-update, i want to notify only the client that sent the update. but on a failed server-update, i want to notify all clients (all tabs) associated with a user. I believe the docs, which say >Each user-id may have zero or more connected clients at any given time but if connected-uids is just a set of uids, how does my app know which user-id (“alice” with several tabs, “bob” with 1), goes to which connected-uid (“uuid” “uuid” …. “uuid”)


maybe i have to track it myself? i can do that, but i naively thought “each user-id may have zero or more connected clients” meant sente had a place to but user-ids and connected clients.


when I used sente I did my own server side bookkeeping to map user ids to connected socket ids

👍 4

I don't think sente makes any assumptions about users and ids - for all it cares every socket connected could be anonymous / unauthenticated, or every socket could be the same user


yeah - unless you know you only have one server instance running ever, you do need something that spans multiple instances (eg. your db)


thanks again. rereading those paragraphs with the thought “sente doesn’t make any assumptions about users and ids” makes it more sense.


hey folks, is there any authentication client for clojure rest api project? I am starting to build a project and i need some help. Actually my first one.


exactly @U04V70XH6, thank very much 😄


I have an record implementing an specific protocol. I’d like to wrap the protocol calls to have certain behaviour before/after the protocol-function is called. How’d i go about it? I messed around with proxy; but that doesn’t seem right


I it working with reify. cool


Does anyone have a working example of GraphQL subscriptions in Lucinia?


perhaps better to ask in #graphql


Thanks for the tip!

David Savoie14:05:52

Hi! I'm trying the simplest thing, launching a development environment with Figwheel-main and Clojure CLI. I'm following [the Figwheel tutorial]( to the letter, but when I launch clojure -m figwheel.main, a browser window opens, but no repl in the terminal (although there should be one started). I don't get any error messages either... Any advice? Thanks!


which browser? I only ask cause terminal doesn't popup for me on firefox but it does on chrome

David Savoie14:05:57

I'm using Chrome on Linux. I open a shell at the root of my project, in which I created the proper deps.edn file, then type in the starting command. The browser window opens, and it says I should be "returning to the REPL and typing", but there's no actiive repl running in the shell. Last message I have is Opening URL . 😕


Super noob question, I see a test that has a structure that looks like (deftest ^{:some-key "Some-value"} similar-to-key ...) What is the map all about?

Alex Miller (Clojure team)15:05:35

it's like in the name and everything :)


Is there any way to determine whether code is being executed by a go block? I'd like to conditionally apply <! or <!! based on whether I'm inside a go block.


Hey Folks, can someone help me to understand difference between compojure-api and pedestal?


@rschmukler given how the go block compiler works, that's not going to work


I figured as much, but I was hoping perhaps behind the scenes it set a thread variable or something (on the executor threads)


the portable thing is to create a go block in your function and return its channel


go blocks are cheap


Yeah, the problem is that it feels like a bit of a leaky abstraction


ie. Concurrency is an implementation detail - making the caller aware of its semantics feels dirty


changing behavior when inside vs. outside a go block is a much bigger leak


It'd be encapsulated by a function though. ie. callee's responsibility, instead of caller


core.async's model can't abstract that


But I do get why it's not done. Stringing channels through all my APIs just isn't worth it though. I'll see if I can find a different way.


using go works in both contexts - you never end up blocking a thread


channels are the price of the core.async model though


Where are my JVM fibers 😞


passing channels as arguments is the right thing to do


i don't know what the original problem is here


I understand that it can be done that way. But it forces everything into a different paradigm - namely, using channels instead of function application


using channels is a great way to decouple parts of your system


The problem is strictly semantic - not a big one, only seeing if there was a more elegant solution afforded somewhere.


you're not being specific about problems


what problems?


Okay, I'll try and explain


if you have a channel and need a blocking or callback function, use take! right?


I have a function which preforms a large computation and relies on an army of workers to execute it


Traditionally it is called from outside of a goblock (eg. the repl, a dedicated threadpool, whatever)


ie. the impl of do-work takes from a channel with all the results <!!


the scope of the go blocks is static, not dynamic


I want to clarify, I know how they work, I'm just trying to showcase how they can leak


Now, I've got a new system, also implemented with go blocks, each one calling do-work with slightly different arguments


The problem is now that these go blocks are calling a function (`do-work`) which actually blocks (instead of parking). So now I have to either create a function that returns the channel directly (not a big deal, but it forces the caller of the system to be aware of its concurrent implementation detail) or expose a variant that parks instead of blocks (again, leaking the internal implementation of what do-work does out to the caller, that also happens to be implemented with go blocks.


the parking variant will also need to return a channel


otherwise the caller cannot park


so just return a channel


do-work or a variant of it cannot park, even if called from a go block


it can only park if it has its own go block, which will require returning a channel


My point is, but for the fact that these systems share a goblock runtime, these variants would never exist. It's not a big deal at all, but it does force an all-or-nothing type of constraint on the system. Either channels are used at system boundaries, or they aren't - it's difficult for two independent systems which happen to be implemented w/ go routines (a strict implementation detail) to coordinate with functions.


I do buy that not much better can be done until fibers come to the JVM though


if you want to do core.async kinds of things without core.async then use callbacks


(which are terrible)


Yeah, this is definitely better than call backs


thanks for explaining


I don't think this is a <! vs <!! thing as much as a channels vs. not channels dilemma


or a function vs. machine dilemma

💯 4

Yep. Systems are hard 😛


e.g. make do-work start a do-work server that you send work to via a channel


True, but it's also a consequence of this specific implementation of do-work-servers. ie. Runtimes with actual support (again, not Clojure's fault, Project Loom for the JVM is coming) enable you to put the machines back behind the function boundary (either via a preemptive scheduler ala erlang) or full run-time level support (golang) where all functions end up "parking".


i still wouldn't put the focus on the execution machinery -- the essential thing here is conveyance


work being distributed, answers being collected


even with Project Loom we'll still want channels


Yes, they are a fantastic coordination mechanism


But, without the runtime handling parking, they leak. Ie. golang doesn't have <! and <!! because the runtime handles it for you


I won't even say leak, as it comes off too harshly - they just can't be mixed well with functions


which is my point, a lot of people start with a function calling and returning kind of design, and want to sprinkle in little bits of core.async and it is annoying because it isn't transparent


so like, you invoke functions and then park on the channel returned


instead of just invoking functions


which is kind of a dissonance, but if you approach core.async systems as more machines to start with, you get a model of calling (create-do-work-server) once at start up, and doing client/server style request response stuff


which is definitely not just invoking functions, but you don't get the dissonance


Absolutely - and erlang / Exlixir have that paradigm pretty strongly. But, because there is a preemptive scheduler, you can put the semantics of request / response back under functions.


Functions have a lot of advantages, at the highest level. They are highly composable, can be partially applied, can represent lazy execution (thunks), have great tooling for exploring their results, have great tooling for jumping to where they do, etc. Channels could have tooling at that level


Anyway, I appreciate everyone engaging. I'll return the channel and deal 😛


I know we love FP but functions can be automatic coupling


sounds like clickbait but call chain coupling is a real issue


A calls -> B calls -> C -> D -> E, etc


What's the issue with this? trying to follow the conversation here


Nevermind, looks like it is all in this talk linked below


I admit I'm failing to get the point being made here too


orchestration via channels can avoid that. There's a good talk from Rich Hickey that deals with this


Absolutely. I did Haskell for about a year professionally and it's the king of creating compositional coupling


@ghadi Are you referring to "The Language of the System"?


I haven't seen that one. I'll give it a go


near the end there's a part about direct vs. indirect that is relevant


Wonderful, thank you!


What http-server do you guys recommend? I have a really hard time deciding which one to go with. Clojure JVM.


Can someone point me in a direction on what I should think of when deciding between e.g Jetty, Http-kit, Aleph, Immutant..?


Also having a look at clojure-nginx


Performance, features, stability, project longevity are all important factors to consider. Personally, when all else is equal, I’ll reach for jetty as it’s popular and performant.


Start with the embedded Jetty, and if it doesn't satisfy your needs, try something else.


At work, we use Jetty in production for most everything.


(we used http-kit for a while but the integration with New Relic is lacking)


Thanks for the answer, since I have some experience with Jetty i'll use it for my production app. Previously I had a toy-project using Sente (for websockets) and immutant. 🙂


@U04V70XH6 are you using websockets together with jetty, and if so- which library? Or did you build one yourselves?

Griffin Lacek18:05:19

@UBN9SNVB4 One of my coworkers wrote this. pretty lightweight, but we’ve used it in a few projects!

👍 4

@UBN9SNVB4 We're not using WebSockets with Jetty. We're using Netty and http://Socket.IO in one app that is not Jetty-based tho'.


I really like for 'including' Clojure to Nginx, but it has little recent activity.

Kari Marttila20:05:31

While reading Programming Clojure, 3rd ed. I realized in page 70 that you can use clj command line tool as a substitute to my standard file tools find & grep. E.g. in code examples directory start clj and then: ` (import (def my-file (File. ".")) (def my-files (file-seq my-file)) (def my-file-names (map #(.getName %) my-files)) (require '[clojure.string :as clj-str]) (filter #(clj-str/includes? % "clojure") my-file-names) ; => ("clojure.js" "clojure-deps.xml") Yihaa! 🙂 Of course that's a lot more writing than: find . | grep clojure ... but using clj you have all the power of Clojure to manipulate the files further. I wonder if clojurians are really using clj like that (as a command line tool to manipulate files).


I think you would be interested in the Clojure/north talk related to this


I think someone has made some sort of bash script analogue for Clojure


I haven’t used it, but there is also


I agree though, it's awesome!

Kari Marttila20:05:22

Interesting, thanks for sharing! 🙂


specifically they were talking about lumo which is a CLI environment that executes ClojureScript

lambdalove 4

I tried to get info about ,,, at end of functions but without any success


(->> (range 10)
        (filter odd? ,,,))


In what context do you see that?


comas in clojure are whitespace


so that code is the same as (->> (range 10) (filter odd?))


the ,,, are used as a place holder


I've seen code like that in Alex's book when the rest of the code is unimportant for the example, for instance

Alex Miller (Clojure team)21:05:39

in this case, I don't think that's it

Alex Miller (Clojure team)21:05:20

some people call that the Fogus comma to mark where the values are threaded in examples


to illustrate how the ->> macro works

Dave Compton23:05:33

I'm trying to get started with clojurescript, so far unsuccessfully. Is there a good "how to" guide that someone could point me to? FWIW i'm on linux ubuntu 16.04 .


Having trouble getting CLJS installed?

Dave Compton23:05:42

To tell the truth I'm not sure. Is that what I'm supposed to install to compile a clojurescript file?

Dave Compton23:05:07

I have clj but not cljs

Dave Compton00:05:16

yes, and I was able to get a repl going. But what I was hoping to do is just to compile a file to javascript/html and load the results in the browser.

Dave Compton00:05:50

Can that be done?


Yup. The guide that mike showed will be able to do that. Here is another guide as well:


And if your interested in more examples of small web site projects to use as examples:

Dave Compton00:05:21

Thank you. Those pages look pretty helpful. I'll take a look .

Dave Compton00:05:14

You asked if I was having trouble getting CLJS installed. What is CLJS . I looked over the examples you showed me and they all seem to be using clj ( not cljs ) on the command line.

Dave Compton00:05:53

What is CLJS ? ( this time as a question ) 🙂


It's a programming language and a Clojure program that reads this language and spits out JavaScript 🙂 That's why you use clj and give it the path to the program ClojureScript and to your ClojureScript source files.


@UJSU0AR9U The idea is this: ClojureScript is a library that is run by Clojure. This is why you have to specify it as a dependency in the deps.edn file. So when you run clj -m cljs.main ... you are telling clojure to run the ClojureScript library. Then, whatever you feed cljs.main (e.g. a .cljs file) will be passed into the ClojureScript library and the compiled result, javascript, will be returned to you.

Dave Compton00:05:10

got it ( i think ). That's very helpful and informative.


So, installing CLJS is just adding it to your deps.edn file and then running clj -m cljs.main .... It will download it for you the first time you run it.

Dave Compton00:05:14

I'll take some time to go through . That looks like what I was looking for.

👍 8
Dave Compton00:05:06

With luck that will be enough to get me going. If not, I may be back with more questions later. Thanks again!

Dave Compton23:05:18

Or perhaps someone could just tell me how to get started.