Fork me on GitHub

@lgillette Just saw your message about RedShift and Sorry I didn't see it and respond earlier.


If you have the correct :host, :port, and credentials, I would expect that to work just fine.


By default, it uses this driver

"redshift"       ""
so I'm not certain you need to override the :classname (that's only given as an example that you can override it).


One issue is that you're using the PostgreSQL SSL factory there. Try removing that configuration entry. According to the Redshift documentation, it's not needed/supported...?


Also, if your application is connecting to both RedShift and PostgreSQL as well, you might need to add

:OpenSourceSubProtocolOverride true


Hi! I will soon start to learn clojure for work. May I ask if I can use Visual Studio Code for clojure? Thanks!


Welcome! There is a whole channel dedicated to the clojure ecosystem in vscode at #vscode


And you'll find folks in the #beginners channel are very very helpful as you're learning!


Cool! clj -Sdeps '{:deps {org.clojure/clojure {:mvn/version "1.10.0-beta1"}}}'


Are tap>, add-tap etc. designed for prepl or for general use?


Are you supposed to add taps by providing the var, if you want to be able to remove one? Can you remove all taps?

Alex Miller (Clojure team)12:10:39

As the docstrings for add-tap suggests, remember the function (instance, not the var) if you want to be able to remove it later. No remove-all now.

Alex Miller (Clojure team)12:10:51

Usually, you’ll be using add-tap interactively while logging / debugging so this is either trivial or unneeded


tap and prepl guides are required.

Alex Miller (Clojure team)12:10:02

Tap is very simple. I’m not sure whether a “guide” is worth doing

Alex Miller (Clojure team)12:10:46

And prepl is designed for tool-makers, not something most people will be using directly

Alex Miller (Clojure team)12:10:10

Both have docstrings with a bunch of additional info

Alex Miller (Clojure team)12:10:50

Will think about what enhanced docs are useful before GA


I think it’s good to have at least a useful example of when and how to use tap

👌 4

Makes one wonder: why prepl isn't a separate lib? I guess we aren't seeing the whole picture yet, might it be part of future plans?

Alex Miller (Clojure team)13:10:20

yes, tap and prepl are largely latent capabilities, laying the groundwork for other things in the future.

👌 4
Alex Miller (Clojure team)13:10:21

prepl is not a separate lib for the same reason the socket server stuff is not a separate lib (and tap is in core) - so that when you need to open up a remoteable debugging repl connection, everything is already there - you don’t need to rebuild your uber jar or redeploy or whatever


like asked on Apropos (youtube), is there a reason there’s only one global tapset?


@U04V15CAJ presumably because it's intended primarily for debugging?


Can you give an example of how this helps for debugging? In the place where you normally invoke a function like println, swap! to some debug atom, etc. you now invoke tap?


what is tap?


Let's stop tip tapping around the issue, someone should write a blog post 😛


Here is how I understood what is tap


1. tap is global accessable debuging port 2. it is possible to register any number of functions with 1 arg to process values from tap port. In order to register fn we can use add-tap function 3. tap> is non blocking fn that puts any value to a tap port. All registered functions will receive values from tap


4. functions which process values from tap can be pure or not. If fn is not pure iti is recommended to run I/O in separate thread (I think taht core.async rules here make sense)


@U064X3EF3 is this more or less correct?


@U097654L8 I understand how it works, but not when and why you should use it instead of putting debug lines in a function


@U04V15CAJ But what if you want to catch a bug which appears under some special conditions? Then you need to catch a data, that causes a bug and some context from app. Your code may be deployed on several servers in the cloud and app can produce millions of logs. I think tap + prepl is out of the box tool, that can help in this situation. Using tap + prepl you can avoid grep logs on remote servers, you can send data with a bug (not all logs) from multiple servers right to your notebook repl. Then you can discover what's wrong with your code, patch it and then using prepl send it back to app to see if bug is still there or not.

Alex Miller (Clojure team)13:10:12

you can use tap as an alternative to doing println debugging or logging to understand what is happening in your system

Alex Miller (Clojure team)13:10:58

it is useful like println in that it’s in core so you don’t need to change the requires in your code when you add it (and unlike logging which typically drags in a bunch of junk when you do so)

Alex Miller (Clojure team)13:10:45

it’s different and likely better than println or logging in that tap transfers data values, not strings


Is this also a better alternative to storing values in some temporary atom for later inspection? I guess you could do that in one of the tap functions

Alex Miller (Clojure team)13:10:05

it’s better than println debugging in that it does not rely on you having *out* go someplace visible - you can independently hook up one or more taps that can get it to your eyes in whatever way is appropriate in your system

Alex Miller (Clojure team)13:10:44

@U04V15CAJ I don’t know if I’d say better - it’s a different tool. saving values off is possibly more useful if you are repl-connected


I always have a repl connected 🙂

Alex Miller (Clojure team)13:10:35

and to earlier question @U04V15CAJ - there’s one global tapset because that’s simpler. otherwise you’re building full pub/sub. You can get that if you want by writing tagged tap values and connecting a function that makes choices about what to do based on the tags

Alex Miller (Clojure team)13:10:47

but most people don’t need that and will never need to take that on


I guess you would have to think before hand to put tap calls where you would previously add logging, so not having a REPL means redeploying your code somewhere. I don’t see the full potential of this yet

Alex Miller (Clojure team)13:10:40

because tap drops by default, it’s totally fine to put them in beforehand

Alex Miller (Clojure team)13:10:52

you can dynamically add the tap later

Alex Miller (Clojure team)13:10:06

(which you can’t do with println)


yeah, but like with logging, you wish you had logged somewhere where you didn’t usually 😉


but that’s cool, just add a tap in case and hook some tap-fn later on… but then you still would need a REPL I guess

Alex Miller (Clojure team)13:10:29

but unlike logging, you don’t have to drag the logger crap into your code (as tap> is in core)

Alex Miller (Clojure team)13:10:50

unless you proactively have a tap-fn that responds to something you can do dynamically

Alex Miller (Clojure team)13:10:03

but that is very system dependent


anyone know a good library for text-to-speech?


on macosx there is the say terminal command. E.g $ say "hello world"

Bobbi Towers16:10:46

the best ones I've seen use the Google Translate engine, e.g. or the Read Aloud plugin for Chrome


find of the day


Common Lisp's format function is a wonder to behold when you first see it. Also a nightmare to read complex format strings if you are not familiar with them (and sometimes probably even if you are)


I remember seeing some impressive stuff utilizing that function. I can't recall exactly what it was though.


user=> (cl-format true "~(~@r~)~%" 124)


I am guessing that the topic of directives for Roman numeral formatting must have come up in some ANSI meetings for standardizing Common Lisp. I wonder what was said there. 🙂


siblings in spirit to the participants in the meeting where they decided to add :poop: to the unicode standard


Probably something like "it would be more work to take it out of the existing implementations than it is to standardize it"


(for Roman numerals, not the Unicode standard)


I have fixed a few bugs/oddities in Clojure's cl-format before, but I think I will let this one go: user=> (cl-format true "~(~@r~)~%" 0.1) => i


I'm hitting with a large core.match function and I can't quite figure out where the nested fns are coming from


Judging by macroexpand-all it's just a ton of let and try/catch which I'd expect don't compile to fn*s internally


I have positively verified that it is the number of clauses in core.match: compilation works as soon as I reduce it, and looking at target/ it is actually producing very long filenames


(I am trying to understand why it's producing all of these nested fns as compiled classes to see if I can somehow work around this)


and ideally not via a process that involves me writing a macro that compiles a subset of core.match down to switch statements 😄


( is another reproducer but doesn't really explain where the compile artifacts come from)


compiling this code leads to “Method too large!” . any ideas?


what version of clojure, what version of core.async, what version of the jvm, why are you requiring ioc-macros in a macro like that?


∵ dallben ~ ∴ clj -Rasync                                                                                          
Clojure 1.9.0
(defmacro aaa []
  (require 'clojure.core.async.impl.ioc-macros)

(defn bbb []
user=> user=>   (aaa))


are you sure that is actually the source of the problem?


my fault. it was a bug in clojure 1.7 works with 1.9


@lvh There aren't a huge number of people who know this stuff off the top of their head, but I have a vague recollection that do forms might cause the compiler to wrap their bodies in fn's


You probably saw a suggested workaround on the clojure-match-io-exception README about doing the compile inside a file system that allows longer file names? Not sure if such a sidestep of the problem is applicable in your situation.