#clojure logs

2016-01-22

00:14rhg135I'm an idiot; I had slf4j misconfigured and hence did not log the exception in my transducer...
00:36baritonehandsjustin_smith: Continuation from yesterday, https://github.com/baritonehands/avalon/blob/master/src/clj/avalon/models/crud.clj
00:36baritonehandshttps://github.com/baritonehands/avalon/blob/master/src/clj/avalon/models/memdb.clj
00:36baritonehandsStill not sure what to do with sate
00:36baritonehandsstate
02:13WickedShellpost upgrade to clj 1.8.0 I periodically get error messages that disappear after doing a lein clean; lein repl again. (lein version 2.5.3) It appears that lein isn't reliably rebuilding files based on dependencies. Is this expected or related to turning on direct linking?
04:43marianoguerrahi! I'm building an uberjar with lein uberjar but I want to have the ability to add some jars from the classpath at run time (jdbc drivers) by printing the classpath I can't get it to add another classpath than the current jar, any hint on how to do it?
05:01Glenjaminmarianoguerra: that's a limitation of `java -jar`, you have to add the uberjar to the classpath and specify the main class
05:05marianoguerraGlenjamin: you mean I have to run the non standalone jar, add the standalone jar in the classpath and specify the main class?
05:06Glenjaminyep: java -cp somejar.jar:uberjar.jar your.main.Class
05:07marianoguerraGlenjamin: it worked, thanks!
05:07Glenjamini ran into that exact issue last week :)
05:08marianoguerraGlenjamin: I was googling for the last half hour, many false positives with terms like lein uberjar and classpath :/
11:38tangled_zhi! I was wondering if anyone tried to combine using typed clojure with re-frame?
11:41tangled_zbecause re-frame puts all of its content into a single app-db elemement, and I have no idea how that would be typed.
11:42tangled_zby "content" i meant "state".
11:49dnolentangled_z: I think you mean Typed ClojureScript?
11:49dnolenif so, Typed ClojureScript has been maintained in a couple of years
11:51Glenjamindid you mean to say has?
12:16dnolener yeah I mean "hasn't"
12:48tangled_zdnolen: thanks for the reply! yeah, that's what i meant.
12:48tangled_zHmm, that's a shame.
12:48tangled_zI guess I'll use prismatic/schema then
12:52rcassidyanyone use paredit.vim? it seems to be mucking with being able to yank and delete to registers
13:14bjarcassidy: I was using vim-sexp and tpope's mappings for it
13:14bjahttps://github.com/tpope/vim-sexp-mappings-for-regular-people
13:15bjaI had no such problems with it messing with my registers
13:27rcassidybja: thanks, i'll check this out.
13:28rcassidyi've been used to the paredit mappings though, these are way different.... taking over the word movement operators seems both a great and awful idea.
13:29rcassidyoh man even the normal vim-sexp mappings are also pretty different. gah, muscle memory
13:32ridcullyyep paredit messes with a lot of things (., block edits, registers...). yet i prefer it as it makes a good job on keeping the file intact
16:04WorldsEndlessTrying to get some interop code to work, java has "Text.class" but it doesn't seem to have the same result as (class Text)
16:06ridcully,(= (class String) (.getClass String))
16:06clojurebottrue
16:06WorldsEndlessOk
16:08luma,(class String)
16:08clojurebotjava.lang.Class
16:09ridcully,String
16:09clojurebotjava.lang.String
16:19justin_smithWorldsEndless: java's Text.class is the same as clojure's Text (in case that is not clear here)
16:43xyhIf I have (ns interpreter.buffer) in 'interpreter/buffer.clj' how do I use it in 'interpreter/core.clj' ?
16:43justin_smith(ns interpreter.core (:require [interpreter.buffer :as buffer])) (buffer/foo ...)
16:45justin_smithyou can put anything after :as but the convention is just to grab the last part of the ns
16:46xyhrepl says :: FileNotFoundException Could not locate interpreter/buffer__init.class or interpreter/buffer.clj on classpath.
16:46justin_smithso if you did [interpreter.buffer :as b] you could call (b/foo ...)
16:46justin_smithxyh: was there an error in interpreter.buffer when you first tried to load it?
16:47justin_smithoh wait, no
16:47justin_smithxyh: are you using leiningen?
16:49xyhI am using the REPL in emacs (but not cider.el)
16:49justin_smithxyh: what kind of repl? clojure.jar, lein?
16:49xyhclojure.jar
16:50justin_smithxyh: start the repl like this: java -cp clojure.jar:path/to/code/ clojure.main
16:50justin_smithwhere path/to/code is the path leading to the directory containing the interpreter/ directory
16:51xyhoh, this path is included in classpath then ?
16:51justin_smithxyh: the deal is that when you use require, clojure looks for the code on the classpath, so the code has to be findable on that path
16:51justin_smithxyh: that's what -cp does, yeah
16:51xyhthx
16:52justin_smithxyh: also, once you start using other people's libs, you'll find it much easier to use lein or boot, but for starting I think it's great to use clojure.jar (and know when it's simpler to just use that)
17:07domgetterleiningen says "WARNING: You're currently running as root; probably by accident." but I'm not logged in as root, just an account with sudoer access. Is this something I should worry about or should I make an account that doesn't make lein say that?
17:08justin_smithdomgetter: huh, I have sudoer access and lein never tells me this...
17:08justin_smith(unless I'm root that is)
17:08domgetterhmm
17:09domgetteroh I'm a dummy. I ran sudo ./lein
17:39kwladykai want solve my old topic... i am looking solution to manage architecture in Clojure: 1) Change how functions work inside in any moment of project. For example function for save/read in DB. Or integration with ERP. 2) Change how functions work depend on configuration file. For example use another DB engine or another ERP system. 3) Do not pass nested injection dependency from function on level 1 to function on level 10 through level
17:39kwladyka 2,3,4,5,6,7,8,9 if only level 10 needs it. 4) I could change how system work in configuration file and it should be use in one main file to inject into system. One place to control dependency.
17:40kwladykaIn that moment i am thinking about defprotocol, Monads,Stuart Sierra compontent - somebody can say something clever in topic? :)
17:41ridcullyhave you looked into component, mount, ...
17:42ridcullyalso imho a _massive_ change like this does not happen to often in a project. it _could_ take away valuable dev time for nothing. or just take the time to pick the "
17:42kwladykaridcully yes and i am even more confuse :
17:42kwladyka:)
17:43ridcullyright" db in the beginning
17:43kwladykaofcourse but db is a good example
17:43kwladykait could be ERP system
17:43kwladykabut it is easier to think about DB because everybody know how it works
17:44kwladykaso.... in your experience which of these are the best for my point 1,2,3,4 ?
17:46ridcullytry them out and see what fits your needs. there is no "best"
17:47ridcullyif there would be a best we all would be using it it and nothing else would exist
17:49kwladykaok so i will reverse the question. Can definitely say some of this methods don't meet the conditions?
17:50justin_smithkwladyka: all conventional clojure approaches fail your criteria
17:50kwladykajustin_smith why?
17:51justin_smithkwladyka: because clojure doesn't have mainstream options for config based DI
17:54kwladykajustin_smith so what do you use when you want have good flexible architecture? What is your opinion? Business is changing and need from time to time change part of system from definition. For example we can imagine we want change ERP system and another system with integrations should be ready for that. Just change way of communication and all should works.
17:55justin_smithkwladyka: I define an interface, my code is all written in terms of using that interface, and then I change the implementation of that interface (or which one we realize) in the apropriate place in the code
17:55justin_smithwell, usually a protocol, but same concept
17:56justin_smiththe problem with doing this via the config is then everyone has to agree on a config system, and the magic by which the config system controls the code, and unless everyone decides on the same one it will be worse than not having one
17:57kwladykajustin_smith so don't you use monads, Stuart Sierra components or similar solutions?
17:57justin_smithkwladyka: I absolutely do use components, but they have nothing to do with what we were just talking about
17:57justin_smithstuartsierra's component is about managing lifecycles of stateful resources
17:58justin_smithI mean yeah you could also use it to pass implementations of some protocol to clients, but that's not special about his system, you could do that via regular functions or data atached to ring requests or magic top level vars or whatever
18:01justin_smithkwladyka: also, when you mention passing some object from a to b, and from b to c, c to d, d to e, all the way down but only e needs it, every namespace level var is an extra arg passed to every function in your codebase, at least in the former case you can pick which things you are passing
18:01kwladykaso the conclusion is.... defprotocol is probably the best
18:02justin_smithThat's what I'd use at least. And yeah, really clojure doesn't have the thing you are describing.
18:04kwladykajust looking the way to do really good architecture and i am doing loop in my head all the time about how it should work. I get lost somewhere in my head :)
18:07kwladykabut i learned more about how it shouldn't work ;) it is always something ;)
18:08justin_smithkwladyka: one comparison that I like to make is that a var, a dynamic threadbound var, a value in a config atom, and an argument passed explicitly to your function are all ways to get the right value to the place it is needed. It turns out that if you write the base level stuff in terms of explicitly passing an arg, you can use that to implement all of the others (and more). The others are not as flexible, and trying to use them other ways is a total
18:09justin_smithkwladyka: so on an app architecture level - when tying it all together - use whatever makes sense / whatever is simplest without hindering you
18:09justin_smithkwladyka: but in terms of putting together the parts that make up the whole, write it in terms of values explicitly passed in. That's 100% flexible and will be compatible with any system structure you ever decide to use.
18:10justin_smithso do all the details with explicitly passed in args, because it is easier, and then use whatever you want at the top level
18:14kwladykajustin_smith i have one problem with that. I don't want situation where something from function on level 1 is pass to function on level2,3,4,5,6,7,8,9 to use that in function on level 10. It makes a mess after some time. But maybe it has to be like that.
18:16justin_smithkwladyka: that's the price yes, but even that is simpler than what you would need to do if the code expects the thing to be a global and you need to bind it locally or use a different value in a specific context.
18:17justin_smithand it's not hard to write a wrapper that lets the higher level code just set a global or something, which the wrapper code passes in as args.
18:26amalloythink of the way ring handlers and middlewares work. there's all kinds of junk at the top level that is needed by stuff at the bottom level, and it all gets passed through by hand, but you don't "notice" because it's in one giant map
18:27amalloyas long as you make the thing your level-10 function needs be part of the big ol' "configuration" object that every layer is passing through anyway, it's no big hassle to add more stuff to that
18:27amalloyie, it only hurts once
18:28justin_smith"clojure: it only hurts once"
18:29ridcullyand ideas like "lets replace the db-url in config", pass it down and everything magically works, are pipe dreams
18:29justin_smithridcully: so that's never actually worked?
18:30justin_smithridcully: but remember he's not even talking about db-url, he's talking about which implementation of the db storage interface
18:30ridcullyhave you ever tested your stuff against h2 and the actualy production db is something "real"?
18:30kwladykajustin_smith bigger problem is after some time it make a mess in code. Imagine somebody change function 10 to not use some data passed into all this levels. And add something else. After some time when new person will see this code he wouldn't have any idea this parts of code/data are necessary and why it is that. Something deeper need this or somebody didn't remove it.
18:30kwladykaIt is what i want to avoid.
18:31kwladykaand mess on higher function pass to function below and after few function, few programmers and time....
18:31justin_smithkwladyka: do you delete random fields from classes because you don't know what they are for? why would you do this with function arguments?
18:31amalloykwladyka: that's why i'm saying you want one big parameter, instead of a lot of small ones, so that the intermediate functions don't need to know the details of what's being passed except the part they care about
18:31ridcullyjustin_smith: it (might) work on the level you suggested. domain-model. swap out "create customer" withing something else.
18:32kwladykajustin_smith because code after some time is unnecessary complex and hard to understand.
18:33kwladykais has to be clean from time to time, but when you change something on the bottom you don't clean everything higher all the time.
18:33justin_smithkwladyka: right, and exactly the same thing happens with methods on objects, and fields on objects, and entire interfaces - when people lose track of the design, things stick around because nobody knows what is needed and what isn't
18:34kwladykaamalloy it can be some kind of solution
18:34justin_smiththere's nothing special about using explicit args to pass values that is more likely to have that problem than any other factor of design
18:34justin_smithhell, I regularly find namespaces that just have no reason to exist any more
18:36kwladykaamalloy but from other hand you don't know what to pass then if there is only one big argument
18:36justin_smithkwladyka: sure you do - you pass that argument
18:37justin_smithkwladyka: what amalloy describes assumes that every function does this, all the way down to where you actually care about the values and pull them out of the map and use them
18:38justin_smithit leads to all of your "top level" functions that introduce major functionality always taking this one arg, and passing it along
18:38kwladykajustin_smith but if function on level 10 has arg called one-big-arg you don't what what this function really expect there.
18:39amalloykwladyka: compare this to, eg, clojure.java.jdb
18:39justin_smithkwladyka: welcome to shitty design
18:39amalloyjdbc
18:39amalloyall its interesting functions take as the first argument something called db
18:39amalloyand you know they all take a database
18:40amalloywhat's in a database? you don't even really need to know. i certainly don't. it's something that you produce by calling (connect) or whatever, and passing it the args describing how to find a db
18:40amalloythen later on, in its internal functions, it looks inside the db argument and finds whatever it needs
18:42kwladykaamalloy i am not sure it is the same. In this case db is generated by function from the same module to use in functions in the same module. But when you glue more things it is not so easy. It is not so compatible.
18:43justin_smithkwladyka: like I've been saying, there's nothing that will save you from bad design. But passing args explicitly solves a lot of problems caused by the other alternatives.
18:43kwladykaand still you pass only db connection there, it is one domain language and one part of something.
18:44kwladykajustin_smith it could be true. By "explicity" you mean more smaller arguments? Not one big?
18:45ridcullybut isn't the same true in the upper levels? e.g. take some "create-order" fn, that takes a customer to create the order for. the customer there most likely is some map with internal stuff, that allows that
18:45justin_smithkwladyka: by explicitly I mean using arguments and not using anything global or implicit
18:45justin_smithkwladyka: whether it's one arg or a bunch in a hash-map doesn't matter
18:46teeparkI'm going through @aphyr's "clojure from the ground up" and working on prblem 5 from https://aphyr.com/posts/305-clojure-from-the-ground-up-macros. this is where I am: https://gist.github.com/teepark/320c547d7fbd86ff8a8a
18:46teeparkI'm pretty sure my exactify is working the way I want
18:46teeparkbut can't figure out how to alias those operators
18:47justin_smithand all these objections about losing track of what the args are for apply equally to interfaces, classes, methods, namespaces, literally every aspect of code - if you have a bad design and forget what things are for, every single one of these is capable of being a mess, I don't know why you are picking on function arguments specifically
18:48kwladykajustin_smith i am thinking more about rotation in project and people how don't have any idea what people before did an especially why they wrote something
18:48teeparkthe macroexpansion tries to "(let [clojure.core/+ ...]" but I think I need it to not expand to the qualified name in the binding
18:48kwladykaso many misspells... sorry for that
18:48justin_smithkwladyka: name one thing, one abstraction concept or level of organization that wouldn't have that problem
18:49justin_smithteepark: ` always fully qualifies symbols
18:50justin_smithteepark: you can avoid this by not using ` or by escaping the symbols to prevent ` from qualifying them
18:51tomjackhmm, when I remove a couple dependencies, the startup time for `LEIN_OFFLINE=1 lein trampoline repl :headless` goes from absolutely fucking ridiculous to normal...
18:53justin_smith,(macroexpand `(let [~'+ -] (~'+ 1 1)))
18:53clojurebot(let* [+ clojure.core/-] (+ 1 1))
18:53amalloytomjack: what about LEIN_FAST_TRAMPOLINE=1? afaik that's still not a default option, although there was some talk of it
18:53amalloyof course that doesn't address your implicit question about why these deps slow things down, but maybe that speeds stuff up enough that it's fine
18:53justin_smith,(eval `(let [~'+ -] (~'+ 1 1)))
18:53clojurebot0
18:53tomjackoh, hmm, I didn't think to ablate trampoline
18:54justin_smithtomjack: I've found heavy macro usage can make a difference - the difference in startup with and without core.async is noticible for example
18:54teeparkjustin_smith: thanks. the ~'+ quoting was what I was missing
18:55justin_smithteepark: yup - the reason ` does that qualifying thing is this kind of macro is considered messy and is historically a huge source of bugs
18:55teeparkyeah I'd expect so
18:55justin_smithspooky action at a distance, code on the outside can change what code inside it means
18:55teeparknot something I'd expect to do outside of an exercise
18:55justin_smith:)
18:56tomjackLEIN_FAST_TRAMPOLINE does not appear to help, and `lein repl` appears to have the same problem. guess I will do the obvious thing and slap yourkit on it
18:56justin_smithtomjack: if fast trampoline doesn't help it's not the dep resolution that is the time sink
18:57justin_smithafter that I would suspect deep dep trees pulling up huge amounts of code to compile, or crazy macros that demand a lot from the compiler
18:57justin_smithbut yeah, yourkit will probably help
18:57tomjackI don't understand 'code to compile' or 'crazy macros'
18:58tomjackI've just got deps, I'm not loading any of the code in them, afaik
18:58justin_smithtomjack: oh, your repl starts in user?
18:58tomjackthe dep trees are crazy though
18:58tomjackyeah
18:58amalloyIME running yourkit while clojure starts up will not give you anything very useful
18:58amalloywhat are the deps that slow stuff down?
18:58justin_smithmost people have their repls set to start up loading their main ns
18:58amalloyi dunno about "most people"
18:58tomjackdeps into projects in my company's java monorepo
18:59tomjackmaybe lein takes linear time in the craziness of my dep tree, and it's just the dep tree which is absolutely fucking ridiculous
19:01justin_smithtomjack: but with FAST_TRAMPOLINE it isn't recalculating your deps
19:01justin_smithit just uses the cached deps after the first time
19:02justin_smithit literally puts classpath in a file, and if your project.clj has not changed since the last startup, it reuses that classpath from the file
19:03justin_smithunless you do something that would slow down lein in the process of even deciding if your project has changed, but that seems super weird...
19:03justin_smithtomjack: so to be clear did you run LEIN_FAST_TRAMPOLINE=truthy lein trampoline repl at least twice in a row before deciding it was starting slowly?
19:04justin_smithbecause if repl boots to user, that should start about as fast as a simple clojure.jar startup
19:04kwladykaThank you all guys for good discussion. It is 1 am so i am going sleep. Goodnight!
19:07tomjackah, twice, no
19:07tomjackthanks, I didn't wait for the first time to finish...
19:07tomjack(never heard of LEIN_FAST_TRAMPOLINE)
19:10justin_smithtomjack: yeah, it basically sets up a cache for classpath, it works
19:11justin_smithtomjack: the one gotcha to "lein trampoline repl" is I've seen startup errors from initial namespace load (when my repl loads up to my namespace) fall through the cracks - the repl says it is in my namespace but my code isn't loaded with no error message
19:11justin_smithbut if you expect to use user as your init ns, I can't think of a reason to ever not use trampoline
20:12KamuelaWhat's the preferred way to install Clojure on a Mac?
20:14justin_smithKamuela: put leiningen in your ~/bin/lein
20:14justin_smithKamuela: leiningen is a dependency manager and it will take care of everything else (it's a shell script)
20:15justin_smithKamuela: you can also just download clojure.jar and run that via java (any jvm 1.6 or newer works)
20:16pilneafter using lein, everything else just feels uncivilized >.< (well... rust, go, and stack (for haskell) actually feel pretty good too >.<)
20:17justin_smithyeah, lein is pretty amazing, pity about the startup time
20:17justin_smithbut usually the startup time is worth it
20:17justin_smithpilne: fun fact, people complain about clojure startup time a lot, but usually they don't realize most of that startup time is just leiningen
20:18pilneyeah, but unlike the rest (i think) of the jvm langs, startup time is really only a "once per coding session" thing for clojure (:
20:18justin_smithit's true, clojure does dynamism pretty well
20:19pilneit's funny, every time i'm thrown a programming problem now, 9/10 times there's already a "good way" to do it in clojure, and if there isn't, someone far more capable than I is "almost there" lol
20:19pilnei feel like clojure is extremely pragmatic, like.. ridiculously so (:
20:20justin_smitha very special mix of pragmatic while being unafraid to be unconventional (if there is an unconventional solution that is simpler than the normal thing)
20:20xyhwhy when I copy my code into the REPL it runs fine,
20:20xyhbut when I use 'lein run' to run it, or use 'clojure <file>' to run it,
20:20xyhit says 'StackOverflowError'
20:20justin_smithso you might need to spend some time learning some new concepts, but there's always a payoff
20:21xyhhow is this possible ...
20:21justin_smithxyh: interesting, I'm wondering if maybe realizing things early due to printing in the repl might be preventing a concat bomb
20:21pilneeh, for me at least, lisp/scheme just felt like coming home, i've been mentally fighting OOP stuff in c++/java/python for years (as in, struggling to compose things elegantly in those langauges)
20:21justin_smithxyh: when nested concat calls get deep enough, it can blow the stack when you first read the value
20:22justin_smithxyh: but in a repl, it's common to realize things due to printing values
20:22justin_smithxyh: this might not be it, but it's the first thing I think of that would be different in a repl and lein run and cause a stack overflow
20:22pilneis there a way to tweak my default jvm (or the one for *any* clojure repl) to have massive stack/heap, just for... science?
20:23justin_smithpilne: yes, when you start the jvm you can tell it how big the stack and heap should go
20:23justin_smithpilne: :jvm-opts in a leiningen project.clj will be passed along
20:23pilnebeautiful, tyvm
20:23pilnei should probably google more honestly though
20:23justin_smith:)
20:24pilnethis nightcode/nightmode standalone clojure ide looks like something i should throw on a puppylinux usb stick... you know... again for science (:
20:25Kamuelapilne: I’m using that
20:26Kamuelaand yeah I think I did do that lein thing, only problem is I think I used brew
20:26KamuelaMaybe I shouldn’t?
20:26KamuelaOnly reason I ask is because I think clojure is still 1.6.0 for me and I’ve been trying to figure out how to upgrade
20:26justin_smithKamuela: brew is good too, it's just newer and lein has more users
20:26justin_smithKamuela: in each project you can decide what clojure version it uses
20:26justin_smiththis is true if you use lein, boot, or even just clojure.jar
20:27Kamuelainteresting, so 1.6.0 is probably just a target in a config file then
20:27justin_smithright
20:27xyhwould you please try this :: https://www.refheap.com/113972
20:27xyhit should print the following two lines :
20:27pilnesince it seems like i'm starting a collection of clojures, how far back should one go (i've got 1.7 and 1.8 now)
20:27xyh16
20:27xyhbye bye ^-^/
20:28xyhtry copy (1) into REPL (2) run by 'clojure <file>'
20:28xyh* try (1) copy into REPL (2) run by 'clojure <file>'
20:30Kamuelaah i see, dependencies
20:31justin_smithxyh: it's getting a stack overflow error while compiling
20:32xyhah!~
20:32justin_smithoh right, because it calls that thing at the top level, never mind
20:32justin_smithxyh: it says "compiling" but it is really in that bottom line
20:32xyhyes maybe due to JIT
20:33justin_smithno, there's no JIT here
20:33justin_smithxyh: it's true, if I run clojure.jar and give it that file, it blows up, but if I start a clojure.jar repl, then paste in the contents of the file into the terminal, it is fine
20:33xyhoh! have you tryed copy the code into REPL ?
20:33xyhyes
20:34justin_smithright, it works if you paste into a repl, and breaks when loading from the file
20:34justin_smithbut it is definitely not a laziness issue
20:34justin_smithbecause you are not doing anything lazy here
20:36justin_smithxyh: one thing I am very suspicious of is your call to (recur) on line 67 - there is literally nothing other than an exception that will make that thing stop looping, right?
20:36xyhyes
20:37xyhbecause it is an interpreter
20:37justin_smithso that's your interpreter loop?
20:38xyhyes, one can view it this loop as 'return-stack interpreter'
20:38xyh* view this loop
20:43justin_smithxyh: change map tomapv on line 108 and it works
20:43justin_smith*to mapv
20:45justin_smithxyh: map is lazy, if you do not use the result it does not calculate a result, in a repl its result is getting realized as a side effect, when running the file directly the side effect does not happen, the laziness is not forced, and thus you have a lazy-bomb where you have too many layers of lazy ops to realize at once and your blow the stack
20:45xyhthank you justin_smith
20:45justin_smithxyh: mapv is not lazy, and thus you do some of the work ahead of time and don't blow the stack
20:45justin_smithxyh: np, laziness is weird and hard
20:46justin_smithxyh: it took a while to find your problem - that's seemingly the only place you are using laziness in the entire codebase, if you had used lazy functions in two places I wouldn't even know which one was the problem
20:46justin_smithhaha
20:47xyhI will go learn more about map and mapv in the doc
20:48justin_smithxyh: it's not specific to map at all
20:48justin_smithxyh: it's about how lazy-seq works
20:49xyhoh my ... not in the doc ?
20:49justin_smithit is in the doc! the doc for lazy-seq
20:49xyhok
20:49justin_smithbut the specific issue is explained well in a blog from stuartsierra
20:49justin_smithone moment...
20:50justin_smithxyh: this is why I mentioned concat at first - it's the same problem, it's a thing about lazy-seq, but it's most commonly seen with usage of concat http://stuartsierra.com/2015/04/26/clojure-donts-concat
20:51xyhgreat :)
20:52justin_smithxyh: stuartsierra explains how concat causes this problem via lazy-seq, but map also uses lazy-seq so it's the same issue you saw, really
20:53xyhthis is what I am doing, by the way :: https://github.com/cicada-language/threaded-code-interpreter
20:53xyhI have a clojure version now :: https://github.com/cicada-language/threaded-code-interpreter/tree/master/native-array-memory/clojure/interpreter
20:54justin_smithcool
20:54justin_smithI hope you enjoyed playing with clojure and got some hint of what you could learn from it
20:55xyhis there an OO framework in clojure ?
20:55justin_smithxyh: clojure compiles every function to jvm bytecode and you can directly access the jvm
20:56justin_smithalso, yes, you can use OO features in clojure code (eg. defrecord, defprotocol)
20:56justin_smithbut clojure stays pretty close to the features of the vm itself, which is implicitly OO
20:56pilnewas the patch discussed in one of the links on that concat page ever implemented into core? or was it shrugged off?
20:56justin_smithxyh: I definitely understand your code much better when I read the OCaml version
20:57xyhyes, I like type system too
20:57justin_smithpilne: no idea, but as he mentions, any usage of lazy-seq can hit this problem
20:57justin_smithxyh: yeah, ml family is the platonic ideal of the type system for sure :)
20:59pilnetrue justin_smith, i guess it is just smarter to explicitly not mix a lazy-seq into an eager context
20:59justin_smithxyh: you use hash tables in the OCaml version, but don't use them in clojure where we even have a syntax literal for them
21:00justin_smithpilne: well, we at least have to be smart about the eager / lazy boundary, yes.
21:00xyhyou mean primitive-function-record ?
21:01justin_smithxyh: in_host_name_record is the hash table in the OCaml version
21:01Kamuelathe reason I’m liking clojure is because it’s so incredibly consistent with its syntax
21:02xyhjustin_smith: in clojure it is (def name-jo-map (atom (hash-map)))
21:02justin_smithahh, - the idiomatic version of (hash-map) is just {}
21:02justin_smith,(= (hash-map) {})
21:02clojurebottrue
21:03justin_smithxyh: the hash-map function is only really used when the keys and vals are all in order in a collection and are not yet partitioned into two-element vectors
21:03justin_smiththen we do (apply hash-map coll)
21:04justin_smithotherwise there is pretty much always a more straightforward alternative to calling hash-map
21:04devnim spacing out: is there a built-in for getting the value of the max key (assume keys are numbers) in a map?
21:04xyhI see
21:05justin_smithdevn: (max-key key m)
21:05justin_smith,(apply max-key key {1 0 3 2 22 7})
21:05clojurebot[22 7]
21:05justin_smithwell, clearly I forgot apply the first itme there
21:06devnjustin_smith: lol, i think it's time i step away from the keyword
21:06devnkeyboard* (see?)
21:06devnI was messing with max/min-key, and that usage pattern totally escaped me
21:06devndidn't think to use clojure.core/key
21:07justin_smithdevn: now I want to find some useful one-line that uses max-key, key, and max
21:07justin_smithhaha
21:07justin_smith,(apply max (apply max-key key {1 0 3 2 22 7}))
21:07clojurebot22
21:07devnjustin_smith: yeah, it feels i dunno, weird
21:08justin_smith,(apply max (apply max-key key {1 0 3 2 22 420}))
21:08clojurebot420
21:08justin_smithlol, time to go home
21:08devni think you might be able to make it worse...
21:09pilneKamuela:: that is because of the whole "code is data" concept it brought from the lisp world, the syntax has to be consistent to enable easy parsing to make the magics happen (:
21:09justin_smithdevn: hmm, how many clojure.core functions have the form x-y where x and y are also core functions?
21:10devnjustin_smith: probably easy enough to discover with ns-publics
21:11Kamuelapilne: it’s great and my first lisp, the closest to functional I’ve experienced is JS with the new immutable/functional popular paradigms
21:13justin_smith,(->> 'clojure.core ns-publics keys (map name) (map #(clojure.string/split % #"-")) (filter #(> (count %) 1)) (filter #(every? (comp resolve symbol) (remove empty? %))))
21:13clojurebot(["chunk" "first"] ["when" "first"] ["find" "ns"] ["take" "last"] ["take" "nth"] ...)
21:13justin_smithdevn: ^ answering my own question, lol
21:13devnyou sonofa
21:13devni was just about there
21:14devnim not peeking!
21:14justin_smithlol
21:14devni might be way off, but i got 268
21:14justin_smithdevn: I looked only in clojure.core, and only for things that had hyphens in them in the first place
21:14devnforgot to go distinct
21:15devn94
21:15justin_smithdevn: in just clojure.core?
21:15devnyar
21:15pilneclojure wasn't the first language that really caught my eye when i got back into programming, but it is the one i keep coming back to, it and haskell have really caught my eye (although this startup little jvm language "lux" seems to be tempting me with the best of both those worlds >.<)
21:16justin_smithdevn: my favorite ["cond" ">"] - I never read cond-> as two clojure functions separated by a hyphen before
21:18devnjustin_smith: what about -> :D
21:18justin_smithhaha
21:18justin_smith"" is not a clojure function
21:18devnmy solution was so much more roundabout than yours
21:18devnit's making me ill
21:20justin_smithdevn: it's OK, I'm about to go home and get really stoned and my code will be terrible
21:20pilnenah man
21:20devn,(let [split-up (group-by #(.contains % "-") (map (comp str first) (ns-publics 'clojure.core))) [with-hyphens without-hyphens] (map #(get split-up %) [true false])] (for [x with-hyphens :let [fs (clojure.string/split x #"-")] f fs :when (some #{f} without-hyphens)] [x f]))
21:20clojurebot(["restart-agent" "agent"] ["sort-by" "sort"] ["chunk-first" "chunk"] ["chunk-first" "first"] ["tree-seq" "seq"] ...)
21:20pilneit will just be really really really abstract
21:21pilnei feel like clojure offers me a lot of what i really like about haskell without the handcuffs of forced purity.
21:21justin_smithpilne: s/handcuffs/helmet
21:22pilnelol
21:22justin_smith(I say this as someone who never wears a helmet when riding his bicycle)
21:22pilnemy first through was "hugging jacket"
21:22justin_smithbut really, haskell is protecting you from somethign there
21:22pilnei agree it is protecting oneself, but it is also not trivial to fully grasp/apply how to "get around that protection in a safe way" (at least for me)
21:22devnI totally abuse clojure.core/for (for [x xs :let [ys (get x :ys)] y ys :when (some #{y} #{:a :b :c})] [x y])
21:23devnhaskell is pretty rad. it's not my cup'o tea though, i'm afraid
21:24pilnesame, i enjoy haskell like i enjoy theoretical physics, from an armchair with a bong and a beer...
21:24devnwell, one of them is closer to actual science
21:25devnphilip waddler in his talk at strangeloop last year said: "real sciences don't have to put 'science' in their names"
21:25pilnelol
21:25justin_smithhaha, nice
21:25devni've been having a lot of conversations with some knowledgable static typing enthusiasts these past few months. i've even seen a couple clojure people start to be drawn into the light
21:26justin_smithOK, actually leaving the office now
21:26devnjustin_smith: come on back :)
21:28pilneeh, i'm more for dynamic with the option to static (via annotation or whatnot, as long as that annotation actually does some good at the compiler end...)
21:29pilnebut with ghci and haskell, i don't mind the static requirement on types, just the whole mutable-monad-magic stuff still twists my noggin
21:49staplerhi! on clojars.org I don't see any spot for me to put my public key
21:49staplerand lein wants me to do that so i can throw stuff on clojars
22:36justin_smithstapler: have you created your account?
22:44staplerjustin_smith: yes
22:50justin_smithstapler: wow, I can't find the public key upload in the current code...
22:50justin_smith*current site
22:50staplerbit broken, i know
22:55justin_smithstapler: yeah, looks like either a documentation bug or a functionality bug
23:30TimMcI wonder if that feature was disabled...
23:31justin_smithTimMc: they try to sign jars, so you'd think they would also host a copy of the public key that goes with it
23:33zimabluehey, does anyone know a good working example of boot with both a clojure backend and figwheel/browser repl?
23:34zimabluetenzing works for me but I don't know how to connect a backend to it