#clojure logs

2015-01-11

00:00rritocharrdem: The way I see it, there are potentially an infinite number of possible operators and no language could ever include them all. It may be beneficial to algorithmic thinkers to develop such a capability in an algorithmlic language.
00:01rritocharrdem: I also believe, based on some proofs provided by a "friend" of mine, that it could provide a higher level of security, since without knowledge of the operators and their implementation, the language could have "perfect secracy".
00:01rritocharrdem: see http://rosuav.com/1/?id=683
00:03rritocharrdem: I don't particularly agree with all his conclusions, but the fact that the same source code can represent multiple different programs is a potential benefit for providing security.
00:06rritocharrdem: I do agree with one point though. As soon as you make operators that can be changed, source codes no longer contain any information, therefore meeting the condition of perfect secracy.
00:07rritocharrdem: Though, I"m not sure if that conclusion was in the document I sent, or in personal emails.
00:08andyfrritoch: Reading your original message, are you saying that you are having difficulty parsing a language, because the formal grammar of that language is changing during run time?
00:09rritochandyf: The grammar itself becomes ambigous is the problem, so either operators need to be replaced with functions prior to parsing or the parser itself needs to consult some algorithm to determine a resolution to those conflicts.
00:10andyfThere are parsing algorithms for context-free grammars that can handle ambiguous grammars. I believe Instaparse implements one such algorithm.
00:11andyfBut there can still be ambiguity of not knowing what an identifier means during parsing, so you don't even know what kind of token it should be in the parsing process.
00:12andyfIf the latter case, then those parsing algorithms I mentioned won't help you.
00:12rritochandyf: Thanks. I'll take a look at it. The simplest representation of the problem I found is the grammar rule "symbol spaces symbol spaces? semicolon" This could represent a variable declaration or a unary operation.
00:13andyfLisp using a 'everything is prefix notation, with parentheses around each operator/function, plus its arguments' makes some things easier to parse, certainly. Postfix notation has the same benefit.
00:13rritochandyf: During parsing the resolution can be provided, the problem is the resolution rules can't be defined by the grammar since they need to be determined algorithmically.
00:14rritochandyf: Unfortunatly I want to allow multiple inheritance in the language, if that wasn't the case than I'd simply be doing a search/replace, shifting the parenthesis, and sending it to the clojure runtime to handle.
00:14arrdemandyf: working on Grimoire ATM, adding support for platforms (clj, cljs, cljclr etc)
00:14andyfnot sure what you mean by a resolution rule there. Do you mean rules for deciding whether a particular 'lexical token' is, say, a number, variable, function, or something else?
00:14arrdemandyf: thoughts on how I should resolve a namespace qualified symbol to documentation in the case of implementations on multiple platforms?
00:15andyfarrdem: Nice.
00:15arrdemI'm thinking that I default to clj, and otherwise "first" wins
00:15rritochandyf: The parser I'm using, and I believe any LALR parser will report a conflict if it can't resolve an ambiguity on it's own.
00:16andyfLALR parsers are one class of algorithms that handle a subset of context free grammars. There are other algorithms that can handle all context free grammars, even handling ambiguity in those grammars (meaning that the algorithms can produce correct parse trees even if there is more than one parse tree that produces the parsed string).
00:16andyfLALR can't do that, though.
00:17arrdem&(sort ["clj" "cljclr" "cljs"])
00:17lazybot⇒ ("clj" "cljclr" "cljs")
00:18arrdemokay well that "just worked"
00:19arrdemaaand now I have to fix my datafiles because I've successuflly upgraded (and broken) all my clients.
00:19rritochandyf: Thanks, I'll look at instaparse. I wasn't aware that there was anything more advanced than LALR available
00:20rritochandyf: I simply need to be able to resolve conflicts via a method call from the parser, with that capability the language becomes possible, but I believe it is still computationally expensive.
00:20rritochandyf: At least during the compilation phase.
00:20arrdem.... shit
00:21arrdemaccidental git reset –hard
00:21arrdemthere goes my evening
00:21arrdemg'night gents
00:21andyfsorry, have company for a few mins -- will be back soon
00:29rritoch(inc andyf)
00:29lazybot⇒ 23
00:30ryancole(inc ryancole)
00:30lazybotYou can't adjust your own karma.
00:30ryancolefml
00:31rritochandyf: I haven't finished reviewing instaparse but from the description I think it is exactly what I need. Using a ambiguous grammer with say 255 recursion depth for operator precidence, and instaparse may solve the problems.
00:34rritochandyf: Once I figure out exactly how the ambiguity resolution process is implemented.
00:34ncthom91hey all. What's the customary approach to config files for clojure apps? For example, with javascript, config files are fairly typically a json file.
00:35ncthom91a clj file?
00:35ncthom91like project.clj for leinengen?
00:36arrdemncthom91: do you have a specific platform/app in mind or are you just asking generally
00:36ncthom91arrdem generally, though I guess I'm thinking about just running a web app that can be configured with a set of rules
00:37ncthom91basically a web app that can be pinged with post-receive hooks from a git repository, and the rules govern what to do with those events
00:37arrdemncthom91: TL;DR there is no standard. Everyone I know of rolls their own.
00:37ncthom91arrdem ah, interesting
00:38ncthom91arrdem how might I do it with a clj file? I notice leinengen specifies a `defproject` function?
00:40arrdemncthom91: there is no technique which I will commend with a straight face for loading a configuration from a .clj file. It's not unheard of to eval an arbitrary "config.clj" off of the classpath, or to read some "config.edn" off of the classpath but both have their downsides.
00:41ncthom91arrdem heh, ok. What approach would you take for my situation? Mind you, I'm *very* new to clojure
00:41arrdemncthom91: you just want to configure responses to webhooks?
00:41ncthom91yea basically
00:42arrdemis there some reason you can't write as a dispatch table in your program propper?
00:42rritochncthom91: I would suggest putting it on your classpath, in your resources folder, end-users could adjust their classpath to override the provided configuration file. Something like (read-string (slurp (clojure.java.io/reader (.openStream (clojure.java.io/resource "config.clj"))))
00:44rritochncthom91: It certainly isn't a best practice, but it is an easy "hack"
00:44ncthom91rritoch would I then have to eval/parse the clj file?
00:44ncthom91arrdem yea I guess I just wanted to make a generic server that someone could spin up on their own with a different rule set
00:45LanzafameOk feeling like I am missing the obvious solution here. Installing leiningen. It successfully installed to my ~/bin/ folder but the `lein [command]` is only executing from that folder. I have added it to my PATH (.profile), and then run `source .profile`. I just can't get it to execute from any other location? Please point out the stupid mistake I am making... (OS: Ubuntu 12.04 Vagrant VM)
00:45arrdemncthom91: then having an EDN file that specifies finite configurations would be my suggestion rather than having a full "configuration program" which is what rritoch's proposal allows.
00:45arrdemLanzafame: what's `echo $PATH` come out too for you?
00:46rritochncthom91: No, you only need to eval if your configuration file is a clojure form, if it is just data, like { :key "val" ...} than read-string will return a map.
00:47arrdemhaving read-eval'd the string, which allows arbitrary code execution
00:47Lanzafame"/home/vagrant/.rvm/gems/ruby-2.1.3/bin:/home/vagrant/.rvm/gems/ruby-2.1.3@global/bin:/home/vagrant/.rvm/rubies/ruby-2.1.3/bin:/home/vagrant/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/opt/vagrant_ruby/bin:/home/vagrant/.rvm/bin:/home/vagrant/.rvm/bin:/home/vagrant/bin/leiningen"
00:47arrdemuse tools.reader if you want a "safe" reader
00:48arrdemLanzafame: you don't have to add the file ~/bin/leiningen to your path
00:48arrdemLanzafame: otherwise that looks fine...
00:48ncthom91rritoch interesting thanks
00:48ncthom91arrdem do you knwo of any examples of writing/reading edn files?
00:49Lanzafamearrdem I didn't... Should I remove it?
00:49arrdemncthom91: for various (bad) reasons we don't have a "print-edn" operation, however pr-str is equivalent most™ of the time
00:50arrdemncthom91: you can use clojure.edn/read-string, but pr-str is the only way to "write" edn
00:50arrdem$grim clojure.edn/read-string
00:50lazybothttp://grimoire.arrdem.com/1.6.0/clojure.edn/read-string
00:50rritochncthom91: Just remember to close the stream when your done with it. The exact code I provided is a memory leak.
00:52rritochncthom91: I use similar code in my project.clj files to load my repository lists from a configuration file in my home directory.
00:53rritochncthom91: So in my case the memory leak isn't a problem since the code is only executed during compilation
00:54ncthom91rritoch cool, ok
01:17rritochandyf: It looks like I need to continue looking for a better parser. Instaparse is certainly better than what I'm using. I especially like the look-ahead features, but it trades processing time for memory usage (via the parses function) which with a highly ambiguous recursive structure it would only take a small source code to exhaust all memory resources.
01:17Lanzafamearrdem Solution: Uninstall from ~/bin/ and install in /usr/local/bin/... Contrary to the leiningen install docs, but that is life aye :)
01:18arrdemLanzafame: heh best of luck to you
01:19rritochandyf: What I really need is a LALR that utlizes callbacks to resolve any conflict instead of aborting the parse.
01:19Lanzafamearrdem thanks
01:31rritochI get the feeling I have just entered a bottomless pit. This all started with the need for a dynamic language, which brought me to lisp. The need for more features and preference for algorithmic syntax brought me to compiler design, not even the existing parsers provide the features I need. I suspect I should quit the project now before I end up having to design a new processor on an ASIC.
01:55dagda1_If I am returnign a lazy-seq here https://gist.github.com/dagda1/d99bf42f31e99ae3b07c is it possible to loop..recur lazily over the list or how do I avoid eager evaluation
01:56dagda1_will calling (rest se) on the lazy seq mean the whole thing is evaluated?
02:08tomjack(seq (rest s)) is, I believe, (next s)
02:09tomjackand it won't realize the whole thing
05:31hellofunkhypothetically what happens if you use pmap to process something in parallel, and then each item in the collection is a collection that is then also processed with pmap, would each thread be spinning off more threads, like a tree?
05:42kenrestivohas anyone else besides me tried to get core.async and swing to work together, and run into what appear to be eventqueue deadlocks?
05:43kenrestivoj.u.c.locks.LockSupport.park() is used by awt, it seems.
05:45kenrestivoand all this breaks only on a single-cpu machine. on a multi-core machine, everyting works perfectly.
06:23hellofunkamalloy: rather enjoying reading through the flatland utilities. cool stuff
07:05jonathanji don't understand gen-class
07:06jonathanj(ns foo.Bar (:gen-class :extends java.io.InputStream :main false))
07:06jonathanjhow do i use this foo.Bar thing i've supposedly defined?
07:09cljsn00bwhen I turn this into a def, the javascript generated by cljs crashes in node: (defn published [] (pub output #(get % "channel"))) any idea what could be causing this?
07:51AeroNotixdefine crashes
07:52cljsn00b(L.b ? L.b(aj) : L.call(null, aj)).call(null, Rh); ^ TypeError: Cannot read property 'call' of null
07:52cljsn00bsomething indecipherable
08:03Biofobicois (print "test") an expression?
08:04AimHereYes. It evaluates to 'nil' though
08:04AimHereThe side-effect may occasionally be useful
08:05Biofobico(+ 2 2) also an expression right?
08:05clojurebot4
08:05AimHereYes.
08:05AeroNotixBiofobico: it might be easier to ask what isn't an expression
08:06Biofobicoso why (do (print "test ") (+ 1 1)) evaluates the print?
08:06AeroNotixBiofobico: what do you think is happening?
08:06AimHere,(do (print "test") (+ 1 1))
08:06mi6x3mBiofobico: because print is in the function position
08:06clojurebottest2
08:06AeroNotixwhat does do, do?
08:06mi6x3mAeroNotix: do evaluates all of the provided forms
08:06mi6x3mone by one
08:07Biofobicofrom docs : Evaluates the expressions in order and returns the value of the last.
08:07AeroNotixmi6x3m: I know, duh
08:07AeroNotixmi6x3m: I wanted to guide Biofobico through it instead of just giving them the answer.
08:07mi6x3mAeroNotix: oh :D
08:07AimHere,(do (+ 100 100) (+ 2 2))
08:07clojurebot4
08:08dagda1_when I call rest on a lazy seq is the whole thing evaluated or what actually happens?
08:08AimHere,(rest (range))
08:08clojurebot(1 2 3 4 5 ...)
08:09AeroNotix,(class (rest (range)))
08:09clojurebotclojure.lang.ChunkedCons
08:09dagda1_I also see (seq (rest s)) used a lot
08:09AeroNotix(rest '(1))
08:09AeroNotix,(rest '(1))
08:09clojurebot()
08:09AeroNotix,(seq (rest '(1)))
08:09clojurebotnil
08:10AeroNotix,(if (rest '(1)) :t :f)
08:10clojurebot:t
08:10AeroNotix,(if (seq (rest '(1))) :t :f)
08:10clojurebot:f
08:10AeroNotixdagda1_: ^
08:11dagda1_what about (recur (rest s)) on a lazy seq?
08:11AeroNotixdagda1_: what about it?
08:11AeroNotixDoes it evaluate the lazy seq you mean?
08:12dagda1_AeroNotix: yes
08:12AeroNotixNo, it doesn't.
08:12dagda1_AeroNotix: that is interesting,
08:16Biofobicoso (do (* 2 2) (* 3 3)) returns 9 but (do (print "test ") (+ 2 2)) returns test 4. If do evaluates the expressions in order and returns the value of the last, shouldn't return only 4?
08:16Biofobicosorry if it is a stupid question, but clojure is my first programming language so bear with me please
08:17AeroNotixBiofobico: it does not return test 4
08:17AeroNotixit prints test and returns 4
08:18AeroNotixit may look in the repl as if it "returns" test4 but it does not
08:18AeroNotix,(do (print "test") (+ 2 2))
08:18clojurebottest4
08:18AeroNotix,(+ (do (print "test") (+ 2 2)) 1)
08:18clojurebottest5
08:18AeroNotixsee?
08:19AeroNotixif it "returned" test4 then the + operation would've failed.
08:19AeroNotix,(def v (do (print "test") (+ 2 2)))
08:19clojurebottest#'sandbox/v
08:19AeroNotix,v
08:19clojurebot4
08:19AeroNotixBiofobico: see^?
08:20AeroNotixthe print function has a *side-effect* (very important to understand, go look it up) of sending characters to the screen.
08:21Biofobicothank you
08:21Biofobicounderstand it now. the repl induced me into error
08:21AeroNotixnw
08:22Biofobicodoes that *side-effect* is in the docs?
08:22LanzafameHow would I go about sending weather api data from server-side (Clojure) to client-side (ClojureScript)? I use a handler to get the client's ip and process that through geolocation then a weather api to get json formatted data. I want to now send that through? Any help would be appreciated
08:25AeroNotixLanzafame: send it as the response from the request the client initiated?
08:25AeroNotixOtherwise, if you need a persistent connection and you want to do async communication or something, look into WebSockets.
08:26hellofunkLanzafame: simple ajax would be straightforward. i use the cljs-ajax library for this type of stuff: https://github.com/JulianBirch/cljs-ajax
08:27hellofunkLanzafame: websockets are a possiblity but require more overhead to setup and probably aren't needed for your task.
08:28LanzafameThanks for the pointers.
08:29tickingI always found websockets to be simpler to set up than ajax :P
08:29hellofunkticking: are you using http-kit?
08:55tickinghellofunk: yeah
08:57ticking_hellofunk: there are plenty of helper libs (sente, chord), but doing it by hand takes about 30-200 loc depending on how much bels and whistles you want (calback style or core async)
09:05lodin,(deftype Foo.bar []) (Foo.bar.)
09:05clojurebotsandbox.Foo.bar
09:06lodinWhich version is clojurebot running?
09:06lodin,(clojure-version)
09:06clojurebot"1.7.0-master-SNAPSHOT"
09:07Bronsa,(Foo.bar.)
09:07clojurebot#<CompilerException java.lang.ClassNotFoundException: Foo.bar, compiling:(NO_SOURCE_PATH:0:0)>
09:07Bronsalodin: "Foo.bar" is not a valid class name
09:07lodinBronsa: You can deftype it.
09:08lodinAnd you can resolve it.
09:08Bronsalodin: still not a valid class name
09:08lodinif you use ns-resolve.
09:08lodinBronsa: Good. :-)
09:14hellofunkticking: my understanding is that currently http-kit does not support secure websockets (wss:) and thus ajax is the only option if you want to encrypt the transfers.
09:14tickinghellofunk: yes true
09:14hellofunkticking: which may not matter to most people
09:14tickinghellofunk: yeah its annoying as heck
09:14hellofunkticking: and websockets without http-kit are pretty much a no-op if i understand correctly, unless you go down a rabbit whole of significant custom engineering on jetty
09:15hellofunk*hole
09:16tickinghellofunk: even with this? https://github.com/sunng87/ring-jetty9-adapter
09:16hellofunkticking: oh i haven't tried that, but remember reading about it. there are so few people actually using it, so made me nervous to dependon it
09:17tickingseems reasonably maintained though
09:17hellofunkticking: i wonder if secure sockets are available with that
09:18tickinghellofunk: I'm not sure how capable aleph is with wss but it's a very nice lib
09:18tickinghttps://github.com/ztellman/aleph
09:18tickinghellofunk: yeah, might work out of the box but I'm not sure
09:19hellofunkticking: do you have other reasons for preferring/using http-kit besides websockets?
09:21cljsn00bis there a way to make function calls partial by default?
09:22cljsn00bor is that a terrible idea?
09:22hellofunkcljsn00b: what do you mean "partial by default" ?
09:23cljsn00b((partial + 1) 1)
09:23opqdonutlike (#(+ %1 %2 %3) 7) would return a function taking two arguments
09:23opqdonutI think it'd be a pain in the ass when coupled with lack of typing
09:23tickinghellofunk: there has been some interesting discussions on this lately, ztellman (the guy behind lamina and aleph and a pretty smart guy) argued against it (when using websocket) because it lacks the ability to produce backpressure on connections https://groups.google.com/forum/#!msg/clojure/TVMQJwaij1U/ikNVo-58WggJ
09:23arrdemopqdonut: no we don't have currying. what you just typed would apply a function of three arguments with one argument.
09:24opqdonutarrdem: I know, see cljsn00b's question
09:24arrdemAh.
09:24opqdonutalso, due to how clojure is implemented on the jvm, it would cause lots of unnecessary closures that would need new optimizations to disappear
09:25razum2umopqdonut: but still, what's the "pain in the ass" if such will exist?
09:25tickingcljsn00b: you can build a macro that produces curryable functions, but that creates speciall functiosn that always call partial with not enough args and be pretty confusing, so yeah it's possible in a proof of concept scenatio
09:25opqdonutrazum2um: weird errors because you made a typo / forgot one argument 3 levels up the stack
09:25cljsn00bticking: alright
09:25arrdemyeah odds are you'll just increase source to sink distances :c
09:26hellofunkticking: i've always found sockets a bit unstable, i wonder if it's just me. lot of people love them. even the figwheel stuff which is cool when it works often hangs for me with socket errors. at least ajax is an old and dependable technique
09:26tickinghellofunk: yeah, if it works for you use it :D
09:27hellofunkticking: that thread you linked to is all greek to me. i don't know what backpressure is nor do i have a deep understanding of http and server architecture
09:28tickinghellofunk: the idea is, when a consumer can't keep up with the producer of messages, there should be some way to cause the producer to slow down
09:29hellofunkticking: i see. so if jetty provides a max of 50 simultaneousl requests (because there are about 50 threads in teh pool, one thread per request) and the server has more than 50 requests... hm, i wonder what happens in that case. the requests are tossed out by default unless you have a channel in place somewhere?
09:30hellofunkopqdonut: what FP languages would provide that default currying behavoir?
09:30hellofunkdoes Haskell maybe do that?
09:30opqdonuthellofunk: haskell & ML languages
09:30tickinghellofunk: haskell
09:30hellofunkinteresting i didn't know that
09:31opqdonutonce you get used to it, higher-order programming feels rather weird without it
09:31hellofunkopqdonut: so the explicit requirement in clojure to use partial slows you down?
09:31tickinghellofunk: The backpressure thing doesn't work for new connections, but for existing ones if you have a constant stream of data say from a websocket
09:31opqdonuthellofunk: or rather makes the code more verbose
09:31nuwanda_opqdonut: well, it's way less confusing in a strongly typed language
09:32opqdonutyeah, that's what I said earlier
09:32opqdonutI don't think it would be a good fit for clojure
09:32hellofunkopqdonut: so in Haskell, funcation calls with fewer than required arity actually result in a returned function, otherwise, a returned value from the function
09:32opqdonuthellofunk: yeah
09:32opqdonuthellofunk: also haskell is lazy so the evaluation just works differently in general
09:33opqdonut(graph reduction instead of function calls)
09:33hellofunkopqdonut: that is actually pretty cool. in a sense, a transducer seems to sort of do that, though i realize that's a different application
09:38hellofunkticking: interesting quote from that thread: "This means that any attempt to use http-kit in conjunction with core.async will be subtly but fundamentally broken"
09:38tickinghrhr yeah
09:39hellofunk"Arguably, even without core.async in the equation it's broken. This is not a good state of affairs."
09:39hellofunkwell, tell us how you really feel
09:41mavbozowell, if i'm a author of library that wraps REST api and using http-kit as client, should i use another http client library?
09:48hellofunkmavbozo: unless impossible i'd consider letting your library work with any server the user chooses, jetty or http-kit, etc
09:49mavbozohellofunk: i'm considering another simpler case, where my library is a wrapper for a http rest api, for example, twitter-rest-api
09:50mavbozoobviously, my library use a http-client library
09:50mavbozothere is a blocking http client--clj-http or non-blocking http-client, like http-kit
09:51mavbozoanother quote from that thread "using core.async should be an application-level decision, not one made for you by your libraries"
09:51mavbozomakes me question, should the nature of http-client (blocking/non-blocking) made by me--the author of library, or consumer of my library
09:53tickingI think a lot of people would disagree with that quote though :)
09:54hellofunkmavbozo: i certainly agree
09:54tvanhensAre there any other authentication libraries out there other than friend and buddy?
09:55mavbozoticking: but it is an interesting challenge for wanna-be library author, such as myself
09:56tickingyeah
09:57mavbozoprovide wrapper for a http rest api, but not depend on any http client library and let the consumer of my library choose their own http client to be used by my library
09:58lodinIf the library uses core.async and you don't want that in your application code, then you can make blocking wrappers, no?
10:00mi6x3mmavbozo: I am a wanna-be author also, just finishing my first clojure lib :)
10:00lodinMaybe not in the general case.
10:00lodinBut for things like http?
10:02mavbozolodin: maybe the library can provide 2 public function for blocking and non-blocking
10:03mavbozoexample, if you want to block use get-block, else get-nonblock
10:03lodinmavbozo: In cases where applicable I'd prefer passing the async output to a function that blocks.
10:04lodinLike I once wrote a chan->seq function that returned when the channel closed.
10:04lodinOr actually, I think it was lazy.
10:04hellofunkticking: look, Einstein disagreed with Bohr, even though he was wrong to do so. so there.
10:05lodinmavbozo: But the point is that the rest of the code didn't need to care about channels or go blocks.
10:17lodinIs foo_bar illegal as a namespace?
10:18dysfun,(ns foo_bar)
10:18clojurebotnil
10:18dysfunnope
10:18dysfunnot that i'd advise it
10:18lodinI know it works, but that question was about being legal. :-)
10:18dysfunwell if it works, it's legal
10:19dysfunbut be aware you may enrage your coworkers
10:19lodindysfun: Scroll up to my conversation with Bronsa about (deftype foo.bar []).
10:19dysfunheh
10:19dysfunagain, perfectly legal, and perfectly likely to make your coworkers violent
10:26hellofunkwhat are clojure's analogs to haskell's fold left and fold right? i assume reduce is foldr?
10:27arrdemyes, reduce is foldr, we have no foldl built in
10:27jackhilldysfun: I'm new to clojure, why would that make people upset? (I assume because it's confusing or difficult to work with, but I'm interested in what way it could be confusing, etc.)
10:27arrdemjackhill: because _ is not part of the "conventional" naming scheme.
10:28lodinjackhill: And in the namespace part of class names "-" is replaced with "_".
10:28arrdemhttps://github.com/bbatsov/clojure-style-guide#naming
10:29jackhillarrdem, lodin: ah, thank you!
10:30lodin,(do (in-ns 'foo-bar) (clojure.core/deftype T []))
10:30clojurebotfoo_bar.T
10:34lodin,(do (ns foo_bar) (deftype T []) (defn T? [x] (= x T)) (foo_bar/T? foo_bar.T))
10:34clojurebottrue
10:34lodin,(do (ns foo_bar) (deftype T []) (defn T? [x] (= x T)) (ns foo-bar) (deftype T []) (foo_bar/T? foo_bar.T))
10:34clojurebotfalse
10:34lodinjackhill: That's confusion. :-)
10:38si14_oh wow. is it by design?
10:38si14_https://www.irccloud.com/pastebin/SAfQGrJ6
10:40si14seems buggy to me tbh
10:42hellofunksi14: https://clojure.github.io/clojure/clojure.data-api.html#clojure.data/diff
10:43si14hellofunk: yeah, I've seen that. I don't see how #{} gets converted to nil
10:43arrdemsi14: "sets are never subdiffed"
10:44si14arrdem: there is no "nil" in the second map
10:44si14"subdiff" is a diff on elements
10:44arrdem&(= #{} nil)
10:44lazybot⇒ false
10:44mavbozo,(clojure.data/diff #{1 2 3} #{1 2})
10:44clojurebot#<ClassNotFoundException java.lang.ClassNotFoundException: clojure.data>
10:45si14 ,(do (require '[clojure.data]) (clojure.data/diff #{1 2 3} #{1 2}))
10:45clojurebot[#{3} nil #{1 2}]
10:46si14and "no subdiffing" rule is about this
10:46si14,(do (require '[clojure.data]) (clojure.data/diff #{#{1} #{2}} #{#{1 42} #{2}}))
10:46clojurebot[#{#{1}} #{#{1 42}} #{#{2}}]
10:47si14it didn't subdiff #{1 2}, as stated in docs
10:49lodinsil4: What output would you expect from your pasted example?
10:51si14(sorry, misplaced /me)
10:53lodinAnd what do you think about (diff #{1 2 3} #{1 2})?
10:54si14lodin: there is no items in b that are not in a, so it's fine
10:55si14lodin: whereas {:foo nil} is actually a *new value* of foo
10:55lodinsil: I think that :foo nil means that "there are no values in (:foo y) that are not in (:foo y)".
10:55si14,(do (require '[clojure.data]) (clojure.data/diff {:foo #{[:a :b]}} {:foo #{}}))
10:55clojurebot({:foo #{[:a :b]}} {:foo nil} nil)
10:55si14,(do (require '[clojure.data]) (clojure.data/diff {:foo #{[:a :b]}} {:foo nil}))
10:55clojurebot({:foo #{[:a :b]}} {:foo nil} nil)
10:56si14but
10:56si14 &(= #{} nil)
10:56lodinsi14: What should (diff #{1 2 3} #{}) return?
10:57si14lodin: as I said, it returns a thing that is logically sound (there is nothing in b that is not in a)
10:59lodinsi14: So there should be a :foo in both elements, because (:foo x) is not equal to (:foo y), right? (Assume (diff x y).)
10:59lodinsi14: And there is nothing in (:foo y) that is not in (:foo x), so (:foo y) should be nil, right?
11:00si14lodin: nope. #{nil} is more correct
11:00lodin(:foo y) for the output, that is.
11:00lodinsi14: But there's no nil in (:foo y).
11:00si14lodin: there is nothing *in the set* that is different
11:01si14nope, disregard this, I'm wrong
11:02lodinsi14: #{nil} would imply that (:foo y) has a nil, and (:foo x) doesn't.
11:03si14"there is nothing in (:foo y)" can be conveyed by #{}
11:03lodinsi14: But that doesn't match how (diff #{1 2} #{}) works.
11:03si14there is no possible misinterpretation in this case
11:04lodinsi14: There is.
11:04si14lodin: "top-level" difference doesn't match what's done in the "subtree", too, so it's a bad analogy
11:04lodinsi14: Try diffing {:foo 3} and {:foo #{}}.
11:05si14uhm. what's more common — changing value to nil or changing value to empty set?
11:05lodinsi14: How do you interpret the output of (diff {:foo 3} {:foo #{}})?
11:08si14lodin: I see your point. What do you think is more common — {:foo #{1 2 3}} → {:foo nil} (you can't differentiate the two with current behavior) or {:foo 3} → {:foo #{}} (the problem you are pointing at)?
11:08si14with current model it's a tradeoff, both behaviors are broken, but one breaks more common case
11:12lodinsi14: Yeah I know. nils are a problem. Is that what you meant by "changing to nil"?
11:13lodinThat is, some value happen to change to nil, and then you don't get a clue from diff?
11:14si14lodin: yes. "value changes to nil" is way more common than "value suddenly changes type to a set"
11:23lodinsi14: What if (diff #{1 2} #{}) returns [#{1 2} nil #{}]? (It would be the same for other containers as well.)
11:24hellofunkif anyone has some thoughts: https://github.com/clojure-emacs/clj-refactor.el/issues/110
11:26mmitchellanyone here using the Prismatic Schema lib? I'm trying to find the best way to create a "default" instance of a schema
11:26arrdemhellofunk: I'll paste mine if you paste yours
11:28si14lodin: it will return it then
11:28lodinsi14: ?
11:29si14mmitchell: can you give an example of what you mean?
11:31mmitchellsi14: sorry, actually now I realize I'm approaching this wrong. The data will already exist, all I need to do is validate
11:32si14mmitchell: ah, ok. Good luck with Schema, personally I like it a lot
11:33lodinsi14: Wouldn't returning (empty v) disambiguate both cases above?
11:34mmitchellsi14: Thanks! And good to know. I use it on a web api project, but it's been a few months since I've touched the code, so now trying to update to the latest schema version, and see what I can do to improve things. All of the code uses the schema records, but I'd like to see if I can get away with just defs
11:34si14lodin: I believe it would be better
11:34si14mmitchell: you may also like https://github.com/metosin/ring-swagger to get Swagger (http://swagger.io) integration
11:43mmitchellsi14: cool, thanks!
11:45mavbozosil4: i didn't know about swagger but it looks great
11:45mavbozo(inc sil4)
11:45lazybot⇒ 1
11:46mmitchell(inc sil4)
11:46lazybot⇒ 2
11:48seangrovednolen_: May be faster to talk about https://github.com/swannodette/mori/issues/129 here - What about mut.conj_f1, mut.conj_f2 to avoid the extra lookup? It's likely negligible, but I'm not sure there's a downside to it.
11:49dnolen_seangrove: this not how JS engines work, there isn't going to be an extra lookup
11:50seangrovednolen_: Ok, wasn't aware of that. Irrelevant then
11:51dnolen_seangrove: semantically there is a lookup but every major engine optimizes this away
11:51seangrovednolen_: I had a suspicion, but wasn't sure
11:53mavbozowhat are good books to understand more about backpressure?
11:55hellofunkmavbozo: check out #chiropractor
11:55arrdem(dec hellofunk) ;; that was just bad
11:55lazybot⇒ 0
11:55hellofunkaw come on
11:56hellofunk(dec arrdem) ;; for no sense of humor
11:56lazybot⇒ 40
11:56justin_smith(dec hellofunk)
11:56lazybot⇒ -1
11:56hellofunkgeez this is a touch crowd
11:56arrdemjustin_smith: it's early, not enough coffee and tests are failing for no obvious reason. bite me.
11:56hellofunk*tough.
11:56hellofunkbut, i'll be here all night. tips welcome
11:57justin_smitharrdem: err... you need coffee - yed you do
11:57mavbozo(inc hellofunk)
11:57lazybot⇒ 0
11:57mavbozofor sense of humor
11:57hellofunk(inc mavbozo) ;; right on
11:57lazybot⇒ 2
11:58si14mavbozo: it's "one", not "L" :)
11:58mavbozo(inc si14)
11:58lazybot⇒ 1
12:00arrdem(inc hellofunk)
12:00lazybot⇒ 1
12:01justin_smithhellofunk: decs for bad puns are s longstanding tradition, nothing personal
12:03hellofunkjustin_smith: well it should be the opposite. :)
12:16KristienIs there something like a lazy var? With delay I need @ and with memoize I need a call.
12:17mmitchellAnyone know if it's possible to add descriptions to prismatic.schema keys? I thought I saw someone talk about that once
12:18dnolen_Kristien: there is not
12:18KristienAnd Var is final so I guess it's impossible to achieve. :L
12:20KristienI'll use delay then. Thanks!
12:45instilledhi! how can i chain a vector of fns, e.g. [fn1 fn2 fn2 …] -> (fn1 (fn2 (fn3 …)))
12:47justin_smithinstilled: comp
12:47justin_smith,((apply comp (inc inc inc inc)) 0)
12:47instilledjustin_smith: cheers! i couldn't remember what it was called.
12:48clojurebot#<CompilerException clojure.lang.ArityException: Wrong number of args (3) passed to: core/inc--inliner--4221, compiling:(NO_SOURCE_PATH:0:0)>
12:48justin_smithinstilled: with a vector you want apply
12:48justin_smith,((apply comp [inc inc inc inc]) 0)
12:48clojurebot4
12:48instilledawesome! thanks a lot/
13:27KristienWhat's the reason case requires constant clauses?
13:27seangrovednolen_: For iterating over arities in a macro and putting out properties on a defn'd form that'll survive munging, is this the final form you're expecting the cljs side to look like? - e.g. (do (defn my-fn [] (cljs.core/my-fn)) (set! (.-fn1 my-fn) (fn [x] (cljs.core/my-fn x))))
13:30seangroveKristien: Maybe you want cond or condp if you don't want constant clauses?
13:30KristienYeah. But still.
13:32hellofunkisn't case more or less analogout to "switch" ?
13:32hellofunk*analogous
13:33KristienYeah, but I don't see why it shouldn't work on everything that = works on.
13:34hellofunkKristien: it's a macro, and: "The test-constants are not evaluated. They must be compile-time
13:34hellofunk literals"
13:35hellofunkanother key point: "Unlike cond and condp, case does a constant-time dispatch"
13:35seangrovehellofunk: Makes sense, yeah
13:38andyfKristien: compile-time constants enables case to generate very efficient 'jump tables', effectively, that do not depend on anything at run time other than the value in the first expression of the case.
13:39KristienWith a hypothetical case that uses = you can still do that if you can at compile detect that all cases are constants, which you can.
13:39andyfhaving variable values to compare to would not permit such an optimization, and in fact different invocations of case could have conflicting branches, e.g. what if two branches of the case had equal values? What would you want to happen then?
13:40hiredmanKristien: is you want to use = use cond or condp
13:40hiredmanif
13:41hiredmancase is just not for that
13:42Gaza(defn print-hello [nome] (print "Digo olá a " nome) (str "Olá " nome)) . What's the point of print if only the (str "Olá " nome) appears?
13:42andyfI can imagine creating a new construct that is 'between' case and cond/condp that optimizes to what case does if all test values are compile time constants, and behaves like condp with = if they are not. That isn't in Clojure, though.
13:48nuwanda_Gaza: the (str "Olá" nome) is the return value of the function, the print...prints :)
13:55seangrovednolen_: Actually, looks like just a normal (do (defn stdFn []...) (goog/exportSymbol "mori.stdFn.fn1" (fn [x] (stdFn x)))) would work well
13:55rberdeenis there a way to skip :prep-tasks for a leiningen task?
13:55rberdeenor some other way to ensure "cljx" always runs before "compile"?
14:20Gazaf(ns test) - what ns stands for here?
14:22tickingnamespace
14:22tickingcreates a namespace called test
14:22Gazafthank you
14:22tickingeverything below that in a file will be in that namespace
14:24Gazafis it like a container? like <div id="container">stuff here</div>
14:25nuwanda_what's your background in other programmming languages? Other analogies are simpler
14:26Gazafhave no background. Only html and css
14:28gfredericksa namespace is a collection of functions
14:28gfredericksa logical grouping
14:30Gazafso any clojure program must have a namespace in the beginning?
14:30gfredericksmore or less, yeah
14:31tickingGazaf: a clojure program consists of many namespaces
14:31tickingyou have one file per namespace usually
14:31tickingand thus a clojure program will consist of many files
14:32nuwanda_ticking: s/will/may/
14:32nuwanda_otherwise it may be a little confusing on the guy :)
14:32tickingyeah
14:35Gazafsay contact.html, blog.html, gallery.html.
14:35Gazafeach one needs to have a namespace
14:36Gazafis that it?
14:36GazafI trying to learn clojure for web dev so I tend to think that way
14:38nuwanda_Gazaf: generally speaking, yes, each clojure file will declare a namespace
14:47Gazafthank you. I guess things will became clearly as I dive in the language
15:02justin_smithGazaf: namesoaces make explici which definitions you are using. This makes code simoler to read, and prevents certain kinds of errors.
15:19ssiderishello, could anyone confirm whether with-redefs has any effect with core.async? I thought it would, but from my experimentation is seems that it doesn't
15:21justin_smithssideris: depends what you are redef'ing - many things in core.async are special macro markers and not vars you can redef
15:22justin_smithgo is a marvelous and frightening beast
15:24ssiderisjustin_smith: I'm redefing functions that were originally def'ed with defn
15:24ssiderissnippets:
15:24ssideris(defn aa [] (log/info 10))
15:25ssideris(with-redefs [aa (fn [] (log/info 33))] (aa))
15:25ssideris(with-redefs [aa (fn [] (log/info 33))] (thread (aa)))
15:25ssiderisbut I see the same behaviour with future:
15:25ssideris(with-redefs [aa (fn [] (log/info 33))] (future (aa)))
15:25ssideriswhich makes me think it's not core.async
15:26chouserthe effect of with-redefs is global, and goes away as soon as flow control leaves the with-redef's block
15:27ssiderischouser: that's what I thought, but in the last snippet I should be getting 33, right?
15:27ssiderisI get 10!
15:27chouseryou've set up a race condition
15:28ssiderisoh the future gets to it first?
15:29chouserapparently your redef is ending before the future fires. You can add a delay to tip the race the other direction.
15:29chouser(with-redefs [aa (fn [] 33)] (let [f (future (aa))] (Thread/sleep 100) f))
15:30ssiderisoh of course, the redef will exit right away
15:31chouserwell, the future will also happen "right away", so they're racing.
15:31chouserVarious unpredictable things like OS or JVM scheduling, garbage collection, etc. could tip the race either direction, potentially.
15:35justin_smith(inc chouser)
15:35lazybot⇒ 17
15:35ssiderissorry, but I'm not sure we your code works (and it does!): there is a delay after we've created the future, so it still starts immediately, right?
15:35ssideris*why
15:36chouseryes, the future happens "immediately" in both your code and mine.
15:37ssiderisso how do we avoid the race condition in yours?
15:37chouserMine delays the end of the redef block for a tenth of a second, which will usually be enough for the future to complete. Then when the redef block finishes, the value of aa goes back to normal.
15:38chouserI am NOT recommending this as a fix or as working code. In fact, just the opposite: this shows how fragile it would be to depend on *either* outcome.
15:39chouserThe race condition is there in both expressions, the sleep just handicaps the race in favor of the future.
15:39ssiderisok thanks, I get it now. So the lesson is: make sure the code you're running in with-redefs, blocks for the whole duration for which you need the redefined things
15:40chouserDepending on what you're trying to do, you may consider dynamic vars and 'binding' instead. I believe core.async go blocks capture dynamic value bindings so they may be more predictable.
15:40chouseroh yes, locks are a good way to exchange race conditions for deadlocks. :-)
15:40ssiderisI'm using real threads with (thread)
15:41ssiderisso I'm not sure if it would work
15:41chouserme either. I haven't played with the combination of dynamic vars, core.async, and real threads. Sounds a bit terrifying, actually.
15:42ssiderisI just want to stub out some functions to do a "dry-run" of my code
15:42ssiderisdo nothing instead of calling an API etc
15:43justin_smithwould having the with-redef deref a promise filled in the other thread (at its end of course) be too much of s hack?
15:44ssiderishm, like a signal to block it until everything is done, right?
15:45ssiderisit's possible, but it makes my (dry-run) macro way less generic
15:47ssiderisbut thanks in any case, I understand it now
15:47ssideris(inc chouser)
15:47lazybot⇒ 18
15:47justin_smithssideris: the deref eould ensure thst the with-redef block won't exit until someone delivers to the promise
15:47ssideris(inc justin_smith)
15:47lazybot⇒ 168
15:48kenrestivoi can attest that combining core.async with real threads, and with a library that does its own thread management, is... challenging.
15:49kenrestivoactually terrifying is a much better choice of word
15:49ssiderisjustin_smith: I get it, but it means the prod code would have to handle a promise that wouldn't be there otherwise
15:52kenrestivoactually i've been wrestling with almost a month with a heisenbug deadlock that appears on a single-core ARM but does not appear on a multi-core intel
15:53ssiderisI'm only using this as a dev tool to exercise my code, so the solution with sleep is probably ok
15:54kenrestivowhen i see code where someone put in a sleep() to deal with a race, i usually run away screaming.
15:55kenrestivowhen i've had to do it, it's usually with a comment that says "XXXX HACK FIX THIS"
15:57justin_smithssideris: a wrapper that takes a function and a promise as args, runs the function, then felivers to the promise
15:58justin_smith*delivers
15:59ssiderisjustin_smith: just a second, if the function is asynchronous, it will unblock to early, the promise will be delivered too early, and the redef block will exit too early
15:59ssideriswhich is exactly the same as the original problem
15:59SagiCZ1how do i imitate while in clojure? some loop that repeats until certain condition is met?
15:59SagiCZ1maybe while?
15:59Bronsa&(doc while)
15:59lazybot⇒ "Macro ([test & body]); Repeatedly executes body while test expression is true. Presumes some side-effect will cause test to become false/nil. Returns nil"
16:00BronsaSagiCZ1: or loop/recur (or even reduce) if you don't need side-effecting
16:00SagiCZ1thanks bronsa.. is calling a function of some remote api a side effect? probably yes huh
16:08justin_smithssideris: oh, yeah, you're right
16:17hellofunkjustin_smith: what does it mean to store and replay a ring request, i.e. via groundhog?
16:18justin_smithhellofunk: provide the ssme headers and body, to diagnose a bug or be sure it is fixed
16:19justin_smithhellofunk: thanks to the api, unless you have state outside the session driving things, the request should be perfectly replayable
16:20justin_smith*the ring api, that is
16:20hellofunkjustin_smith: interesting
16:22justin_smithhellofunk: it was developed as a way to turn backend bug reports into unit tests
16:39Bahmanhttp://www.bahmanm.com/blogs/responsibly-upgraded-your-lisp-machine
16:39BahmanJust to have a bit of fun.
16:39Bahman:-)
17:17dnolen_seangrove: sounds promising
17:20dnolen_cfleming: w/ a Maven project how do I setup a REPL? Is it the same as w/ a Cursive Leiningen project?
17:50espinhocan anyone point me a good beginner web development tutorial please?
17:51espinhofound this book https://pragprog.com/book/dswdcloj/web-development-with-clojure but im unsure if it is a good investment
17:52cflemingdnolen_: Almost, but you should use the "Use normal process" option rather than "Run with Leiningen"
18:05dnolen_cfleming: ok thanks
18:12hellofunkespinho: check out cemerick's youtube channel for web dev tutorial for beginners
18:13hellofunk$mail espinho espinho: check out cemerick's youtube channel for web dev tutorial for beginners
18:13lazybotMessage saved.
18:28whodidthiswhat's an easy way to execute a postgresql .sql file
18:31AeroNotixwhodidthis: try yesql
18:32whodidthisi mean the entire file
18:34AeroNotixwhodidthis: you'd just (slurp "/path/to/file") then and pass it to a psql execute call
18:41whodidthissweet, execute
18:51dnolen_pondering Google Closure Module support https://gist.github.com/swannodette/0eaf17815d49b7b77a95
18:51dnolen_feedback concerns welcome
18:56rhg135that's cool but having to write code to load your code seems a bit... pointless
18:59dnolen_rhg135: I don't see what needs to be written here other than ... script tags same as today.
19:00dnolen_rhg135: if you don't have a large ClojureScript application this isn't for you :)
19:00rhg135ah, then wouldn't the browser actually do MORE work? multi[le http requests
19:01dnolen_rhg135: for many applications 2, core & whatever is needed for a sub page.
19:01dnolen_rhg135: I don't think you've seen a large ClojureScript application
19:01dnolen_we're talking 140,000+ lines of generated JS
19:01dnolen_second request isn't going to matter than much
19:01dnolen_breaking up the build will
19:02rhg135ah now it makes sense, what clicked for me are multipage apps
19:02dnolen_rhg135: yep
19:03squeedeeDavid your dedication and sharing rocks man
19:03rhg135i've only worked on spas so i wouldn't know much
19:05squeedeeI wish labs NY would poach you and bring your attitude and skills to getting us out of plain-old-js.
19:13tickingis there a list of reusable om components somewhere? or are there only the three listed on oms website?
19:16cflemingsqueedee: Was I imagining a tweet from you asking about Cursive keybindings? I can't find it now.
19:16squeedeeI deleted it
19:17squeedeeI didnt realise most of its already set up
19:17squeedeefyi we met at conj. I was the Aussie at the unconf about #ifdef
19:18cflemingsqueedee: Ok - there's some doc here: https://cursiveclojure.com/userguide/keybindings.html and some explanation that hasn't made it into the doc yet at: https://github.com/cursiveclojure/cursive/issues/552#issuecomment-60475268
19:18squeedeecfleming: I did throw in a few bindings that made some sense. A little sad that I cant use alt-(
19:18cflemingYeah, I remember :-)
19:18cflemingsqueedee: Yeah, are you using JDK 7+? I think that changed there.
19:18squeedeeand alt-shift( and alt{ etc... lots of them dont bind at all (on a mac)
19:18squeedeei don't know to be honest
19:19cflemingIt's a JVM problem
19:19dnolen_gist updated with approach for dealing with avoiding enumeration of all transitive deps thanks to the-kenny, https://gist.github.com/swannodette/0eaf17815d49b7b77a95
19:19squeedeeYeah looks like i am
19:19squeedeecfleming: wow, thats annoying
19:20cflemingsqueedee: IIRC it was to bring Java in line with some Mac UI guidelines, I'd have to dig the link up
19:20squeedeeIm sitting in an airport on standby for a flight to SF. 2 weeks in SF, and im going to spend all my spare time getting better at clojure.
19:20cflemingsqueedee: But yeah, Java on the Mac is becoming more of a PITA
19:20squeedeecfleming: no big deal. I bound to ctrl instead
19:21squeedeeMaybe its how I'll make an argument to buy myself a surface pro 3 :P
19:21squeedee"coz my keybindings dont work"
19:21squeedeemy wife will understand
19:21squeedeei need a paredit trainer
19:22squeedeeI've had a mac for 4 years now, and I still cant move to the start or end of a line without several false starts first.
19:22tickingssideris: yeah but a surface has no unix aka most tools will suck
19:23tickingincredible hardware though :(
19:24the-kennydnolen_: Do I get that right? With 'modules' we could advance-compile some namespaces to file A, some to file B, and some to lib.js and then load lib.js once in a webworker (A) and once in the 'page' (B) without having to export all functions in lib.js explicitly?
19:26the-kenny(and use functions from lib.js in both A and B as if they were included in both)
19:26squeedeeticking I love the digitiser on the surface, it's like having a Cintiq built right in.
19:27dnolen_the-kenny: in truth everything is actually compiled together as far as I understand. it's one build that can be broken apart. so yes no exporting here.
19:27tickingsqueedee: yeah it's really great, but windows development is horrible most of the time unless doing .net
19:27squeedeeI havent tried in a while. I got a mac in the end because I was so annoyed with ruby dev in windows
19:28tickingsqueedee: I'm not sure how well linux is supported on that thing :(
19:28squeedeeI love .net but thats pretty limiting.
19:28tickingyeah
19:28squeedeecygwin was the order of the day back then
19:28squeedeeprobably still is
19:28squeedeei figure i just need one of each :D
19:29squeedeeit's not like I'd throw my macbook away :D
19:29the-kennydnolen_: so basically it's advance compilation, same shortened identifiers etc., but split into three files. Sounds quite good
19:29dnolen_the-kenny: yes that's exactly right, same as before you just get to define the split.
19:30dnolen_the-kenny: should really simplify a lot of patterns w/o futzing w/ multiple builds
19:30the-kennyYup, I needed exactly that a year ago :)
19:30the-kennyNot so much in our current project, but it might come to it
19:30tickingsqueedee: if clojurescript had an eval *cough* one could probably push all development into the browser and thus onto any device
19:30dnolen_the-kenny: one thing that's hard to cover here is foreign JS libs (non-Closure stuff)
19:30squeedeecfleming: this is what i ended up with: https://docs.google.com/document/d/1yyqDNGLJpzWZyF9SDZmPn_4NskrCrEMJ-Txah3SBOUY/edit?usp=sharing
19:30squeedeescuse the link-of-doom
19:31squeedeei hear both boot and lein work fairly well on windows. cfleming which platform do you do most of your dev on?
19:32the-kennydnolen_: why is that? Do you want to define different externs for each output?
19:32tickingsqueedee: mikera does all development on windows, in a pretty strange maven only environment I think
19:32squeedeemaven is yuck :P
19:33dnolen_the-kenny: in the example you might have "codemirror" as dep for the editor ns
19:33tickingsqueedee: yeah but core.matrix is pretty nice
19:33dnolen_the-kenny: in a single build it's easy to preamble codemirror ourselves, but for modules it's not as simple
19:34squeedeeticking: took me a while to understand the context. :D
19:34tickinghrhr
19:34squeedeei wish this airport had a desk and a 27" second monitor
19:34the-kennydnolen_: I understand. Tricky :/ Luckily I don't have to rely on external stuff yet.
19:35the-kennydnolen_: Btw. thank you very much for tackling the tooling stuff for ClojureScript. The last releases were really great
19:35squeedeesome people are just really ace eh
19:36squeedeeAlthough, he doesnt have kids. Thats my excuse for being no damn use.
19:37dnolen_the-kenny: no problem, lot more to do before I'm happy :)
19:37the-kennyhaha
19:37the-kennythat's the right way of thinking
19:42dnolen_the-kenny: actually foreign deps might not be such a problem after all due to CLJS-965
19:42dnolen_https://gist.github.com/swannodette/0eaf17815d49b7b77a95
19:42dnolen_something to stew on, night all
19:44the-kennygood night, I'm gonna head to bed too.
19:49squeedeeI just met a woman at the airport named dijkstra. A lot better looking than the mathematician, and not in slightest bit interested in talking to a nerd about proofs and path finding.
19:52AimHereSo much for that strategy for picking up women then
19:56cflemingsqueedee: Thanks, I'll take a look.
19:56cflemingsqueedee: I do all my dev on a mac.
19:57squeedeeOh I dont know why i got the impression you used windows
19:58cflemingsqueedee: No, I switched years ago, after a brief dabble with Linux
20:00squeedeeLinux desktop is just infuriating :D
20:06cflemingsqueedee: Yeah, although I liked the window management better than any other OS I've tried
20:06squeedeei always liked windows for that (win 7 especially)
20:07squeedeeI know a lot of its subjective
20:07squeedeeBut windows just felt consistant and relatively straight forward.
20:07squeedeeMac only becomes tolerable once you have shift-it or similar installed
20:50justin_smithright now my ui is literally bluetooth keyboard (full sized but very thin) logged into a linux server via a reverse port forward to a vps
20:51justin_smithI could have this UI with any usable OS (currently using a nokia cell phone that came with ssh installed(!))
20:52justin_smithhaha, keyboard is logged in, sic, I guess it just shows which part is most important here usability wise
20:55seangroveMan, struggling with this cljs.analyzer stuff
20:55seangroveDon't seem to be able to get the arity metadata about symbols like I'd expect
20:56seangroveOr rather, :arglists doesn't seem to be present
20:56justin_smithseangrove: isn't js really weird about argument count?
20:56justin_smithdunno if that's actually related or not...
20:56seangrovejustin_smith: This should be before it's in js-land
20:56seangroveStill at macro-expansion time
20:57justin_smithah, never mind then
20:57justin_smithso it's the jvm doing this analysis
20:57seangrove,(resolve count)
20:57seangrove,(resolve 'count)
20:57clojurebot#<ClassCastException java.lang.ClassCastException: clojure.core$count cannot be cast to clojure.lang.Symbol>
20:57clojurebot#'clojure.core/count
20:57seangrove,(meta (resolve 'concat))
20:57clojurebot{:ns #<Namespace clojure.core>, :name concat, :added "1.0", :file "clojure/core.clj", :static true, ...}
20:57seangrove,(:arglists (meta (resolve 'concat)))
20:57clojurebot([] [x] [x y] [x y & zs])
20:58toxmeisterhi! can i bother you with a macro question? i'm trying to rewrite some array lookups with this macro here: (defmacro foo [buf & body] `(let [b# ~buf] ~@(postwalk-replace {'x '(aget `b# 0)} body)))
20:58seangroveso, I'd expect the cljs.analyzer equivalent to be (:arglists (meta (cljs.analyzer/resolve-var 'concat)))
20:59toxmeisterthe macro is almost doing it's thing: e.g. (foo buf (+ x x)) results in: (clojure.core/let [b__8468__auto__ buf] (+ (aget (quote b__8467__auto__) 0) (aget (quote b__8467__auto__) 0)))
21:00toxmeisterhowever, how do i get rid of the quoting in the rewritten (aget) ??? i've tried so many things already...
21:00seangroveAh, ok, looks like it's not in :arglists, it's in a few other places - :method-params looks promising
21:00justin_smithyou want b# without the `
21:01justin_smithyou have a bunch of redundant ` in that macro actually
21:01justin_smithyou should only need the outermost
21:02justin_smitherr - wait, maybe you also want it in that postwalk arg, but not directly on b# that's for sure
21:04toxmeisterjustin_smith: thx, i know it's not right infront of the b#, but if i remove it i get a compile error... my general confusion is still how to deal with quoting inside a ~@ form.. does my head in every time and so not easy to find systematic docs for this
21:05justin_smithtoxmeister: if you need the ` on the postwalk arg, then you need ~b# to get the binding unquoted
21:06justin_smithbecause ##(do `b#) is not the value you want
21:06lazybot⇒ b__12184__auto__
21:06justin_smithyou want the thing that resolved to in the let form
21:08toxmeisterjustin_smith: hmmm... if i put the backquote for the whole aget form like this: (defmacro foo [buf & body] `(let [b# ~buf] ~@(postwalk-replace {'x `(aget b# 0)} body))) ...
21:08justin_smithand of course ##(quote `b#) is not much better
21:08lazybot⇒ (quote b__12194__auto__)
21:09justin_smithyou need to have a ~ before b# if you want to reference that let value
21:10toxmeisterjustin_smith: if i put a ~ before the b# in the above version it won't even compile
21:28gfrederickstoxmeister: you can't use the b# syntax if you're using it across different backtick instances
21:28gfredericksbecause:
21:28gfredericks,[`[b# b#] `b# `b#]
21:28clojurebot[[b__25__auto__ b__25__auto__] b__26__auto__ b__27__auto__]
21:29gfredericks^ they end up being different symbols
21:31toxmeistergfredericks: thanks! i just worked around it via an extra outer let like this: (defmacro foo [buf & body] (let [b (gensym)] `(let [~b ~buf] ~@(postwalk-replace {'x (list 'aget b 0)} body)))) - works at last! :)
21:31gfrederickstoxmeister: aw man I just did that too https://www.refheap.com/95992
21:31justin_smithI find it weird that you would need nested backtics at all...
21:32justin_smithbut I don't use macros much, so I could be missing something here
21:32gfrederickswell it's inherently code-walking
21:32gfredericksit's not nested backticks in the strictest sense
21:32gfrederickswhich I've never used in my life because it's scary and I don't understand it
21:33toxmeistergfredericks: hehe - like minds! :) here's to hoping i'll remember that in the future
21:33justin_smith&````````a
21:33hellofunkgfredericks: it is the scary code that is by far the most exciting and inspirational to all of us
21:34justin_smith$ping lazybot
21:34gfredericks~nested backticks are a code obfuscation technique that can only be used by ztellman
21:34clojurebotTitim gan éirí ort.
21:34gfrederickswait did that work
21:34gfredericks~nested backticks
21:34clojurebotHuh?
21:34gfredericks~nested backticks |are| a code obfuscation technique that can only be used by ztellman
21:34clojurebotAlles klar
21:34justin_smith,```a
21:34clojurebot(clojure.core/seq (clojure.core/concat (clojure.core/list (quote quote)) (clojure.core/list (quote sandbox/a))))
21:34justin_smith,````````````a
21:34toxmeistertrue words (both @hellofunk & @gfredericks)
21:35clojurebot#<OutOfMemoryError java.lang.OutOfMemoryError: Java heap space>
21:35justin_smithoh man, is `````````````````````` a bot dos?
21:35hellofunknow this is some art that is transpiring in here right now!
21:35gfredericksalways has been
21:35justin_smith,``````a
21:35clojurebot(clojure.core/seq (clojure.core/concat (clojure.core/list (quote clojure.core/seq)) (clojure.core/list (clojure.core/seq (clojure.core/concat (clojure.core/list (quote clojure.core/concat)) (clojure.core/list (clojure.core/seq (clojure.core/concat (clojure.core/list (quote clojure.core/list)) (clojure.core/list (clojure.core/seq #))))) (clojure.core/list (clojure.core/seq (clojure.core/concat (clo...
21:35justin_smithfascinating
21:35gfredericksI've been backticking the bots since aught twelve
21:35gfredericksjustin_smith: it's exponential
21:36hellofunkwhat the heck is going on. this is some quantum entanglement shit going on in here right now
21:36gfredericksbot backticking is like cow tipping
21:36justin_smithgfredericks: when you say that, I picture you in a cowboy hat, with a 3 inch diameter cigar hanging from your mouth "I remember it well, was the big bot roundup of '12..."
21:37hellofunkgfredericks: no it's not: no one has ever actually cow tipped.
21:37gfredericksit's only once a millennium that you get to refer to "aught twelve"
21:38hellofunkbelieve me i have searched far and wide. it is impossible to actually meet someone who has gone cow tipping. it is a great urban legend.
21:38jackjamesgreetings. transforming a map's keys: is one of these (or something else entirely) preferable? https://www.refheap.com/95994
21:39gfredericksjackjames: that second one isn't complete is it?
21:39gfredericksyou want an (apply hash-map ...) around it or something?
21:39justin_smithhellofunk: "urban"
21:40gfredericksin any case the first one is what we normally use in absence of a library; I use plumbing.core/map-key
21:40gfredericksmap-keys*
21:40jackjamesgfredericks: wow, yeah, definitely
21:42jackjamesgfredericks: somehow misread the parens for brackets at the repl so i thought it was magically giving me what i wanted. thanks much
21:48hellofunkwithout starting a lecture series, i'm curious about thoughts on the proper use of eval in clojure code... when where and why?
21:53gfredericksI don't think I've ever used it for production business code; but there are lots of other reasons to write code
21:54hellofunkgfredericks: seeking examples.
21:55gfredericksif you are generating code for some reason, testing that it evaluates to what you think requires eval
21:56hellofunksure, but i'm interested in the "generating code for some reason" part.... examples of those reasons
21:56gfrederickse.g., maybe you're the strange sort of person who does this in their free time: https://gist.github.com/gfredericks/96e284ce2d52b91d481e
21:57hellofunkgfredericks: rec-lazy-seq looks interesting
21:57andyfhellofunk: I haven't written a lot of Clojure projects, but the only one I can recall that uses eval is Eastwood, a Clojure lint tool, because it needs it (or would not check nearly as much as it does without it).
21:59hellofunkman can someone explain to me like i'm 5 years old what linting is
22:00andyflinting: Look for constructs in programs that might be mistakes, ones that a compiler usually doesn't catch, because the kinds of things caught aren't always mistakes.
22:01hellofunkandyf: i see. i should look at Eastwood to see exactly how one uses that meaningfully, i'm curious
22:20justin_smithhellofunk: linting is good at catching the kind of bugs thst make you facepalm
22:21hellofunknow.. i wonder if it would be too much to ask for an example of the type of bug linting catches?
22:25mfikeshellofunk: Regarding eval, there was a ML thread that appeared to make use of eval to gain a performance benefit in an interesting case: https://groups.google.com/forum/#!searchin/clojure/eval/clojure/mWrZhnFlhxs/RQz88fGeXTUJ
22:31hellofunkmfikes: for performance benefits, related is this macro observation that i've always been a bit curious about: https://gist.github.com/hellofunk/7d424d173125b5dc9640
22:35hellofunkthat is quite an interesting read
22:38justin_smithhellofunk: regarding linting bugs: file name / ns mismatch, wrong arg count, doc string in the wrong place, likely keyword typos