2015-08-16
| 04:02 | ttt_fff | has no one written a datomic clone out of respect for rich hickey ? |
| 04:57 | thearthur | ttt_fff It would also be a non trivial amount of work |
| 05:33 | wasamasa | lol, "out of respect" |
| 05:35 | oddcully | out of respect for the amount of work |
| 05:37 | wasamasa | I don't get it |
| 05:37 | wasamasa | sounds like you either want to go for duplicate effort for the heck of it or not pay for the existing solution |
| 05:39 | oddcully | guess paying is the issue. the same question was asked last week. suprisingly no contender showed up |
| 05:41 | oddcully | or maybe some demand, that such a base component must be OSS since the vendor could go out of business. |
| 05:41 | oddcully | well there will be a next time we can ask :*) |
| 05:53 | wasamasa | right |
| 07:12 | xtrntr | what does thsi error mean |
| 07:12 | xtrntr | Exception in thread "main" java.lang.RuntimeException: Unmatched delimiter: ) |
| 07:49 | kwladyka_ | xtrntr, you have too much or too less "(" or ")" |
| 07:49 | kwladyka | use editor with structural editing |
| 07:50 | kwladyka | like intellij idea |
| 07:51 | wasamasa | or emacs with paredit |
| 08:14 | hyPiRion | uh, so in EDN, the only way to encode the comma character (','), is by writing "\u002c"? |
| 08:15 | hyPiRion | Well I guess according to the spec, but I found it a bit strange that it's the only whitespace character without a more convenient name |
| 09:08 | pepijndevos | What is the neatest way to write a seq where each element might not be there? (remove nil? [(when x y) (when a b)]) |
| 09:48 | andrewchambers | Yo, is there an equivalent of slurp for binary data? |
| 09:48 | andrewchambers | I just need a byte array |
| 09:53 | justin_smith | andrewchambers: you can make a ByteBuffer, use .put repeatedly to fill it from the source, then call .array on it to get a byte array |
| 09:54 | justin_smith | andrewchambers: or use something like apache commons-io IOUtils |
| 09:59 | hyPiRion | andrewchambers: https://github.com/ztellman/byte-streams is good |
| 10:02 | vise890 | hi all. i'm messing around with core.logic and i'm trying to make a recursive goal. I'm using conde to differentiate between the recursive and base cases, but that blows the stack. is there an exclusive version of conde or am i missing something bigger? |
| 10:02 | vise890 | here's the code btw: http://pastebin.com/FcPm7MtC |
| 10:17 | crocket | Exceptions feel like a mistake. |
| 10:18 | crocket | My program crashed because an http request failed due to a network problem. |
| 10:18 | crocket | I had to catch IOException in my clojure program. |
| 10:18 | crocket | I didn't see it coming. |
| 11:54 | lodin_ | Is there any benchmark library that outputs relative performance, like http://perldoc.perl.org/Benchmark.html#EXAMPLES ? |
| 11:59 | sg2002 | lodin_: There's https://clojuredocs.org/clojure.core/time for simple use cases. |
| 11:59 | sg2002 | lodin_: For more complex you may want to look into https://github.com/ptaoussanis/timbre that has a macro called "profile". |
| 12:00 | lodin_ | sg2002: I'm currently using criterium for benchmarking. I'll check out timbre. |
| 12:02 | lodin_ | sg2002: timbre seems really useful for finding bottlenecks. Not really what I'm after though (but it will surely be useful later). |
| 12:03 | lodin_ | sg2002: I'm guessing that it wouldn't be too hard to write a comparison function from criterium's output, but I was guessing/hoping that someone had done that already. |
| 13:10 | luxbock | is there a prettier way to do this: ##(map (fn [[k v] i] {k (assoc v :bar i)}) {:a {:foo 1}, :b {:foo 1}, :c {:foo 1}} (range)) ? |
| 13:10 | lazybot | ⇒ ({:c {:bar 0, :foo 1}} {:b {:bar 1, :foo 1}} {:a {:bar 2, :foo 1}}) |
| 13:11 | luxbock | my actual use case is adding :id-keys for inner maps, where the outer map is a sorted-map, so I'm doing (into (empty my-sorted-map) XXX) |
| 13:34 | Hazel_eyes | Hi |
| 13:34 | Hazel_eyes | anyone care to chat? |
| 13:35 | luxbock | I feel like I'm far too OCD about the way my code gets indented |
| 13:35 | luxbock | https://gist.github.com/luxbock/e192b33d2d578ef8b696 |
| 13:35 | luxbock | clearly the second form is easier to read? |
| 13:35 | seangrov` | ,(let [gs #{{:a 10}}] (get-in gs [{:a 10}])) |
| 13:35 | clojurebot | {:a 10} |
| 13:36 | luxbock | I like Clojure's let and other binding forms but I wish `cond` would group its tests and results together with an additional set of parens/braces |
| 13:45 | seangrove | ,(let [ms #{{:a 10}}] (get-in ms [{:a 10}])) |
| 13:45 | clojurebot | {:a 10} |
| 13:45 | seangrove | ,(let [ms #{{:a 10}}] (update-in ms [{:a 10}] assoc :b 20)) |
| 13:45 | clojurebot | #error {\n :cause "clojure.lang.PersistentHashSet cannot be cast to clojure.lang.Associative"\n :via\n [{:type java.lang.ClassCastException\n :message "clojure.lang.PersistentHashSet cannot be cast to clojure.lang.Associative"\n :at [clojure.lang.RT assoc "RT.java" 785]}]\n :trace\n [[clojure.lang.RT assoc "RT.java" 785]\n [clojure.core$assoc__4130 invokeStatic "core.clj" 191]\n [clojure.cor... |
| 13:45 | seangrove | Is that obviously intuitive to other people, or does it seem like update-in should work? |
| 13:46 | seangrove | Asking because it seems convenient/nice, but there's probably a very solid reason why it doesn't work |
| 13:52 | justin_smith | seangrove: update-in works with things that have keys |
| 13:53 | seangrove | ,(update-in [0 0 0] [1] inc) |
| 13:53 | clojurebot | [0 1 0] |
| 13:54 | seangrove | justin_smith: Just not sure that a vector has a stronger notion of keys than a set does ;) |
| 13:58 | justin_smith | seangrove: according to clojure, it's an associative structure and the keys are indexes |
| 14:21 | justin_smith | ,(associative? []) |
| 14:21 | clojurebot | true |
| 14:21 | justin_smith | ,(associative? #{}) |
| 14:21 | clojurebot | false |
| 15:09 | seangrove | justin_smith: Sure, but would it make sense to implement Associative for sets? |
| 15:10 | seangrove | Seems like it'd be a win overall, but was trying to figure out if there was some guarantee that Associative demands (like Counted), that sets couldn't satisfy |
| 15:11 | justin_smith | sets are counted, maybe it's the lookup thing? |
| 15:11 | justin_smith | I mean they do membership test as if its lookup, but maybe that's not good enough? |
| 15:13 | seangrove | justin_smith: Sounds like a question for the ML! Or maybe the dev-ml |
| 15:15 | justin_smith | seangrove: what happens when you use update-in on a key and it turns into an existing key? |
| 15:16 | justin_smith | (update-in #{{:a 0} {:a 0 :b 1}} [{:a 0}] assoc :b 1) |
| 15:16 | justin_smith | I guess that's equivalent to removing a key |
| 15:16 | justin_smith | s/key/member |
| 15:17 | seangrove | justin_smith: Yeah, interesting question. |
| 15:17 | seangrove | Seems like removing a member would be intuitive enough (a bit strange perhaps) |
| 15:19 | seangrove | justin_smith: But overall, seems like a convenient, intuitive addition, no? |
| 15:20 | seangrove | Actually came across it because it would be very nice for some datomic operations |
| 15:21 | seangrove | Since all cardinality-many refs are sets |
| 16:04 | justin_smith | interesting |
| 16:05 | justin_smith | so it saves you having to use into [] for example |
| 16:16 | mcktrtl | In the clj-http docs it shows an example for using :retry-handler and says "Apache's http client automatically retries on IOExceptions" -- this means retry handler only works for some exceptions right, not all? |
| 16:35 | justin_smith | mcktrtl: it depends on what exceptions the client can throw, right? |
| 16:35 | mcktrtl | im specifically trying to retry when receiving status=504 |
| 16:36 | mcktrtl | its not working so I'm assuming IOExceptions means something else but I can't find what it means |
| 16:36 | justin_smith | what kind of exception does it throw when status is 504? |
| 16:38 | mcktrtl | ExceptionInfo clj-http: status 504 clj-http.client/wrap-exceptions/fn--10592 (client.clj:196) |
| 16:39 | justin_smith | since that isn't an IOException it seems like you would have to catch ExceptionInfo and check for status 504 |
| 16:40 | mcktrtl | what exactly is an ioexception out of curiosity? |
| 16:40 | justin_smith | it's a subclass of Exception |
| 16:40 | justin_smith | as is ExceptionInfo |
| 16:40 | mcktrtl | oh sorry, right, I meant like, what's a real life example of an event that would raise that |
| 16:40 | justin_smith | the idea is that if people use predictable subclasses, you can decide how to handle different errors smartly... |
| 16:40 | justin_smith | end of stream |
| 16:41 | justin_smith | lost connection |
| 16:41 | justin_smith | network not available would be another one |
| 16:41 | mcktrtl | ahh ok |
| 16:42 | justin_smith | but really, the event doesn't raise the error - somebody's code does, and we hope they are consistent enough to use IOException for events that are related to IO... |
| 16:44 | mcktrtl | hehe |
| 19:04 | slester | Is there an idiomatic way of going through a list of functions (that return either a tuple or false/nil) and exiting once a tuple is returned? |
| 19:07 | simon1234 | Hi there! I want to override the ILookUp interface when defining a record, is this possible? Been browsing and googling for some times now, but I don't how if this is possible, note: this is for Clojure (not clojurescript where ILookup is a protocol and not a java interface). Thanks, cheers! |
| 19:18 | amalloy | simon1234: no. records are maps; if you could muck with ILookup they wouldn't act like maps |
| 19:18 | amalloy | if you want a custom type that's totally from-scratch you can use deftype, which doesn't act like a map unless you do it yourself |
| 19:19 | simon1234 | amalloy: ok, I will give a look at deftype then, thanks! Though, it could make sense to derefine some interface to provide some specific implementation, maybe calling the (super) implementation if that makes tsense |
| 19:50 | justin_smith | slester: (first (keep #(%) [f g h ...])) - though this is not guaranteed not to run any functions after the first non-nil result |
| 19:52 | slester | justin_smith, interesting, thanks. I may end up having to refactor it to use something else, not sure how to tackle my issue haha |
| 19:52 | justin_smith | slester: (reduce (fn [_ f] (let [x (f)] (if (nil? x) nil (reduced x)))) nil [f g h ...]) this one would only call each function once, and not call any after the first non-nil result, but it's a bit uglier |
| 19:53 | justin_smith | slester: the difference is that you can't ever guarantee non-execution with laziness, so this version does not use laziness |
| 20:19 | crocket | How should I handle exceptions in clojure? Can I avoid it? |
| 20:33 | justin_smith | crocket: try/catch and I guess you can avoid code that throws exceptions? |
| 20:33 | crocket | justin_smith, I don't like exceptions |
| 20:33 | justin_smith | but some stuff is going to hit build ins that throw exceptions (like calling nil, or using a numeric method on nil) |
| 20:34 | justin_smith | crocket: the people who designed the vm don't agree |
| 20:34 | crocket | I used clj-http, and it threw a subclass of IOException which I didn't see coming. |
| 20:34 | crocket | Now, I'm looking for a replacement of clj-http that doesn't throw exceptions for network problems. |
| 20:35 | justin_smith | yes, I think clj-http throws stupid exceptions |
| 20:35 | crocket | Because clj-http uses an apache component which throws stupid exceptions. |
| 20:35 | crocket | http kit looks promising although it seems to throw Error and RuntimeException. |
| 20:35 | justin_smith | crocket: well, network problems are a different issue - the underlying network lib throws an exception if there is a network level error |
| 20:35 | crocket | like no route to host? |
| 20:36 | crocket | My program crashes because there was no route to host at the moment. |
| 20:36 | crocket | Very stupid |
| 20:36 | crocket | crashed* |
| 20:36 | justin_smith | crocket: the easy answer is never use clj-http outside of a try/catch block |
| 20:36 | crocket | I'm not sure what kind of exceptions clj-http will throw. |
| 20:36 | justin_smith | then catch all of them |
| 20:37 | crocket | Even, OutOfMemoryException? |
| 20:37 | justin_smith | there's no such thing, that's an error |
| 20:37 | crocket | There are many exceptions that you shouldn't catch. |
| 20:37 | justin_smith | no, there are errors you should not catch |
| 20:37 | justin_smith | there are no exceptions you should not catch |
| 20:37 | justin_smith | taht is the difference between exceptions and errors |
| 20:37 | crocket | OutOfMemoryException is a subclass of RuntimeException which is a subclass of Exception. |
| 20:37 | justin_smith | there is no such thing as OutOfMemoryException |
| 20:37 | justin_smith | it does not exist |
| 20:38 | justin_smith | you are thinking of OutOfMemoryError |
| 20:38 | crocket | Ok |
| 20:38 | justin_smith | there is no exception that is unsafe for catching |
| 20:38 | crocket | So, is it ok to catch just Exception? |
| 20:38 | crocket | Not sure, if it's ok to catch RuntimeException. |
| 20:38 | justin_smith | right, and that catches all subclasses, including the ones clj-http throws |
| 20:39 | justin_smith | crocket: this is the difference between Exception and Error. Catching RuntimeExceptions is fine http://docs.oracle.com/javase/7/docs/api/java/lang/RuntimeException.html |
| 20:40 | justin_smith | crocket: if you look at the known subclasses on that page, none of those are unsafe to catch and handle |
| 20:40 | crocket | ok |
| 20:41 | crocket | Do you know better error handling methods? |
| 20:41 | crocket | I mean theoretically |
| 20:41 | justin_smith | sure, Haskell has a nice setup, even common lisp has recoverable conditions |
| 20:42 | crocket | https://docs.oracle.com/javase/8/docs/api/java/lang/NullPointerException.html is a RuntimeException. |
| 20:42 | crocket | In theory, I can just catch and log NPE. |
| 20:42 | justin_smith | right |
| 20:42 | crocket | It doesn't seem to be a good idea to keep running after NPE. |
| 20:42 | justin_smith | ? |
| 20:43 | justin_smith | there's all sorts of reasonable cases for catching and handling an NPE |
| 20:43 | crocket | NPE indicates a programmer error that you should fix. |
| 20:43 | justin_smith | for example if I try to make a number out of some part of a response from a server |
| 20:43 | justin_smith | or if I load corrupted data from disk |
| 20:45 | crocket | not a valid reason to throw NPE |
| 20:45 | justin_smith | crocket: but it's a valid reason to get one given the tools we have |
| 20:51 | crocket | means it is a mistake in java. |
| 20:52 | justin_smith | sure, the whole thing is set up under the premise that exceptions are a useful way to cut short failed code paths, which is obviously something you disagree with |
| 20:53 | justin_smith | crocket: I'm going to try to remember the source, but basically there is a basic method in the jvm, for like counting array elements or finding an item, that works by iterating until it finds what it is looking for, then throwing an exception to break out of the loop |
| 21:19 | quizme | hi, i have some clojure code that I would like to execute from clojure. i guess the simplest naive thing to do would be execute the python from the command line and block until the script finished ? |
| 21:21 | weebz | quizme do you mean execute some python from clojure? |
| 21:21 | quizme | weebz yah |
| 21:21 | quizme | weebz what's the best way to orchestrate that? it's a job that needs to run everyday |
| 21:22 | quizme | weebz or maybe i should make a daemon in both clojure an python to read from a common redis work queue |
| 21:23 | weebz | I can't speak for best practice as I'm still somewhat new to clojure, but if you're you're just firing off a python script you can use clojure.java.shell |
| 21:23 | weebz | https://clojuredocs.org/clojure.java.shell/sh |
| 21:24 | quizme | weebz yeah ... |
| 21:24 | quizme | weebz ideally i would like to be able to "start from where it left off" cuz there might be a lot of items to process |
| 21:25 | quizme | weebz and have some web page to see what the status of the jobs is. |
| 21:26 | weebz | quizme I'm not really sure what you're specifically getting at. How to communicate back and forth between python and clojure? |
| 21:26 | weebz | Or how to orchestrate everything? |
| 21:28 | quizme | i would like to be able to spawn multiple python workers to make it more scalable. |
| 21:30 | quizme | so the multiple workers should not be working on th same job, and it should be able to communicate to the clojure process to do what needs to be done next. |
| 21:30 | quizme | basically i have a pipeline of steps. some of the steps are done in python and some of the steps are done in clojure. |
| 21:32 | quizme | for example, say i have a lot of users and each user has a lot of widgets, and my pipeline has to process all widgets of all users, and the pipeline consists of N steps. C steps are done in Clojure and P steps are done in Python, C + P = N. |
| 21:33 | TEttinger | quizme: might be a good use case for Jython, that JVM version of Python (specifically Python 2 I think) |
| 21:34 | TEttinger | since then you could call back and forth in the same program |
| 21:34 | quizme | Tettinger yeah... true.... |
| 21:35 | quizme | Tettinger that's not a bad idea |
| 21:35 | TEttinger | if you need to use something like SciPy or NumPy it probably doesn't have those |
| 21:35 | TEttinger | it might, I dunno |
| 21:35 | quizme | Tettinger oh yeah i need NumPy |
| 21:36 | TEttinger | I'll check if there's anyone who's already done something like this... |
| 21:36 | quizme | i don't know of any worker queue libraries that work both in python and clojure, but i don't want to get too complicated and bump up to RabbitMQ or anything like that. |
| 21:37 | TEttinger | oh boy. this is definitely in the "little bit complicated" realm, but http://codespeak.net/execnet/ |
| 21:38 | TEttinger | you could use this to communicate from your NumPy normal Python to a teensy Jython setup that's really part of your clojure app |
| 21:38 | TEttinger | (like lazybot has a JRuby plugin, even though lazybot is 100% clojure) |
| 21:39 | TEttinger | $jruby 3 ** 4 |
| 21:39 | TEttinger | $jr 3 ** 4 |
| 21:39 | TEttinger | hm, might not be enabled |
| 21:42 | TEttinger | quizme: there's also ZeroMQ, which has bindings everywhere, typically pretty idiomatic ones for modern languages like Clojure and Python. it isn't a messaging queue like RabbitMQ, and is probably better described as an improvement over plain sockets. |
| 21:42 | TEttinger | I think it's common these days for RPC-type stuff like you're talking about |
| 21:43 | quizme | tettinger hmm ... |
| 21:47 | TEttinger | communicating between VMs and other VMs or from VMs to non-VMs is traditionally a hard problem. |
| 21:49 | TEttinger | some languages are meant to support a specific kind of communication, like Lua being embedded in C (but C++ is less easy), or Clojure being able to call any JVM language. there's some weird experiments that the LLVM people did to run both Java and C# on one VM, and IKVM lets you compile JVM stuff into DLLs that .NET langs like C# can use |
| 21:49 | TEttinger | the first two examples work great! the second two, uh not so much |
| 21:50 | crocket | Interprocess communication tends to be independent of language. |
| 21:53 | TEttinger | crocket: yeah, I mean there's plain old TCP as an option for sending stuff between processes on different machines. the question is really I think what format the data should be in when the communication happens? |
| 21:53 | crocket | There are libraries for that |
| 21:53 | crocket | Apache avro, protocolbuffer, and so on |
| 21:54 | TEttinger | msgpack, thrift yeah |
| 22:35 | slester | justin_smith, is there any reason `(reduced (list 1 2 3))` would just return `1`? Pretty confused right now |
| 22:37 | slester | https://github.com/slester/amiss/blob/master/src/amiss/core.clj#L408-L415 is somehow returning just :soldier |
| 22:39 | amalloy | why on earth would you use a reduce and ignore the accumulator parameter to return either (reduced x) or false, instead of just using (first (filter f xs))? |
| 22:41 | slester | 'why on earth' is a bit harsh |
| 22:43 | slester | because I still want it to return false not '() |
| 22:43 | slester | and I need it to short-circuit when it has found something |
| 22:44 | amalloy | first and filter short circuits, of course. that's what laziness is for |
| 22:45 | slester | and if none match? |
| 22:46 | amalloy | then you get nil. you can convert nil to false, if that's important to you |
| 22:47 | amalloy | ,(first (filter even? (range))) |
| 22:47 | clojurebot | 0 |
| 22:47 | amalloy | ,(first (filter even? [1 3 5])) |
| 22:47 | clojurebot | nil |
| 22:47 | amalloy | ,(or (first (filter even? [1 3 5])) false) |
| 22:47 | clojurebot | false |
| 22:50 | amalloy | but since nil is treated the same as false in boolean contexts you can usually just leave it alone |
| 22:50 | slester | ok, it's converted, but that doesn't change that I'm getting out just a keyword instead of a list somehow |
| 22:56 | AWizzArd | Idea? [(class x) (class z)] => [[B [B] and (= (seq x) (seq z)) => true but (= x z) => false |
| 22:57 | AWizzArd | Two byte arrays with the same contents and the same order, but they are not = |
| 22:58 | AWizzArd | ,(= (byte-array 0) (byte-array 0)) |
| 22:58 | Bronsa | ,(= (object-array [1 1]) (object-array [1 1])) |
| 22:58 | clojurebot | false |
| 22:58 | clojurebot | false |
| 22:58 | Bronsa | clojurebot: hello? |
| 22:58 | clojurebot | BUENOS DING DONG DIDDLY DIOS, fRaUline Bronsa |
| 22:58 | Bronsa | lol |
| 22:59 | Bronsa | AWizzArd: arrays compare via identity |
| 22:59 | AWizzArd | Seems so. Didn’t expect that. |
| 23:00 | Bronsa | AWizzArd: that's a java-ism |
| 23:01 | Bronsa | ,(equals (object-array [1 2]) (object-array [1 2])) |
| 23:01 | clojurebot | #error {\n :cause "Unable to resolve symbol: equals in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: equals in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6704]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: equals in t... |
| 23:01 | Bronsa | ,(.equals (object-array [1 2]) (object-array [1 2])) |
| 23:01 | clojurebot | false |
| 23:04 | slaterr | ,'(1,2,3) |
| 23:04 | clojurebot | (1 2 3) |
| 23:04 | nakiya | hello |
| 23:05 | crocket | How does clojure cope with event callbacks without continuation? |
| 23:16 | slaterr | are there functions like this? |
| 23:17 | slaterr | (1 2 3) => (() (1) (1 2) (1 2 3)) |
| 23:17 | slaterr | (1 2 3) =>((1 2 3) (2 3) (3) ()) |
| 23:17 | crocket | A power set? |
| 23:18 | crocket | That looks similar to a power set. |
| 23:18 | slaterr | I think it is |
| 23:19 | slaterr | well actually it isn't |
| 23:20 | luxbock | #(take (inc (count %)) (iterate rest %)) would work for the second |
| 23:20 | crocket | That seems to involve recursion. |
| 23:22 | slaterr | ,(iterate rest '(1 2 3)) |
| 23:22 | clojurebot | ((1 2 3) (2 3) (3) () () ...) |
| 23:23 | slaterr | ,(iterate butlast '(1 2 3)) |
| 23:23 | clojurebot | ((1 2 3) (1 2) (1) nil nil ...) |
| 23:25 | crocket | 一、二、三、四..... |
| 23:27 | slaterr | not sure about an elegant way of solving the first. without busting out manual recursion |
| 23:32 | TEttinger | ,(reductions (fn [coll _] (rest coll)) '(1 2 3 4) '(1 2 3 4)) |
| 23:32 | clojurebot | ((1 2 3 4) (2 3 4) (3 4) (4) ()) |
| 23:34 | slaterr | neat |
| 23:36 | TEttinger | ,(reductions (fn [_ ct] (take ct '(1 2 3 4))) (range 5)) |
| 23:36 | clojurebot | (0 (1) (1 2) (1 2 3) (1 2 3 4)) |
| 23:36 | TEttinger | there's probably a much better way to do the second |
| 23:36 | TEttinger | ,(reductions (fn [_ ct] (take ct '(1 2 3 4))) () (range 1 5)) |
| 23:36 | clojurebot | (() (1) (1 2) (1 2 3) (1 2 3 4)) |
| 23:40 | nakiya | ,(+ 1 2) |
| 23:40 | clojurebot | 3 |
| 23:40 | slaterr | ,(reduction + '(1 2 3 4 5) |
| 23:40 | clojurebot | #<RuntimeException java.lang.RuntimeException: EOF while reading> |
| 23:40 | slaterr | ,(reductions + '(1 2 3 4 5) |
| 23:40 | clojurebot | #<RuntimeException java.lang.RuntimeException: EOF while reading> |
| 23:40 | slaterr | ,(reductions + '(1 2 3 4 5)) |
| 23:40 | clojurebot | (1 3 6 10 15) |
| 23:41 | TEttinger | ,(reductions conj () '(1 2 3 4)) |
| 23:41 | clojurebot | (() (1) (2 1) (3 2 1) (4 3 2 1)) |
| 23:41 | TEttinger | hm |
| 23:41 | TEttinger | ,(reductions conj [] '(1 2 3 4)) |
| 23:41 | clojurebot | ([] [1] [1 2] [1 2 3] [1 2 3 4]) |
| 23:41 | TEttinger | there we go |
| 23:42 | TEttinger | that would be the better way |
| 23:42 | slaterr | what is the difference between () and [] there? |
| 23:42 | slaterr | looks good |
| 23:42 | palinkas | hi guys, I have an interesting problem |
| 23:42 | TEttinger | () is a seq, can be created by calling seq on any other collection or by calling list with some elements, or even with '(1 2 3) if you want everything in it quoted |
| 23:43 | palinkas | I want to run multiple clojure runtimes in a single JVM |
| 23:43 | TEttinger | [] is a vector, can be created with [] literals like [1 2 3] , with (vector 1 2 3), or by converting using vec . |
| 23:43 | justin_smith | amalloy: the reason for trying reduce after giving a lazy answer was in case there was a hard requirement that further functions not be called |
| 23:43 | palinkas | one basic app, that can change behaviour dynamicly and I want to switch between the different version of the logic |
| 23:44 | palinkas | the logic won't be just a single namespace -> that's why I'd need multiple runtimes |
| 23:44 | TEttinger | seqs append to the beginning with conj, and do not support indexing by element efficiently (you can use nth to get an element, but it will be slower than a vector), but can be lazy and potentially infinite if so desired. |
| 23:45 | palinkas | I have also want to share some of the basic infrastructure between those clojure runtime (common classes, common logic implemented in java) |
| 23:46 | justin_smith | palinkas: there are experimental things for doing multiple clojures in one vm, I don't know how reliable any of them are. If you can find a way to do it via protocols instead (two different implementations of one protocol, switching out the implementation to get your optional behaviors), that will likely be much more robust. |
| 23:46 | TEttinger | vectors append to the end with conj, can be used as functions with an integer arg to get that element, like ([10 20 30] 0) returns 10, and tend to be more common in idiomatic clojure when describing data than quoted lists |
| 23:46 | TEttinger | make sense, slaterr? |
| 23:47 | TEttinger | there's a bit of trickiness regarding a seq and a lazyseq, which you will no doubt discover when you try to turn a lazyseq into a string |
| 23:47 | slaterr | yes. it adds an element at the point where it makes sense for the collection type |
| 23:47 | justin_smith | palinkas: protocols were made for precisely the scenario of being able to swap out different implementations without changing your code (except the part where the object implementing that protocol is introduced) |
| 23:47 | TEttinger | yep |
| 23:47 | TEttinger | and since seqs are linked lists, appending to the beginning makes sense |
| 23:48 | palinkas | my basic idea was: the users write some clojure files (clj namespaces), that can depend on each other (in some cases) |
| 23:48 | TEttinger | vectors are array-like I think. but I think that's more useful as a way to understand them than as their actual internals |
| 23:48 | justin_smith | palinkas: so you want a sandbox? |
| 23:49 | justin_smith | there are definitely ways to have sandboxed clojure envs |
| 23:50 | palinkas | so, it can happen that: v1 (ns.a - v1 , ns.b - v1 (requires ns.a should use v1)) -> user changes stuff -> v2 ( ns.a - v2 , ns.b - v3 (requires ns.a, should use v2 )) |
| 23:50 | palinkas | justin_smith: yes, pretty much |
| 23:50 | justin_smith | palinkas: because without a sandbox you are effectively giving root to every user |
| 23:51 | TEttinger | (important note, slaterr: vectors, seqs, the {} maps that should not be confused with the fn map, the #{} sets, and a few others like the sorted variants of maps and sets, are all immutable, so a function that is given one as an argument won't change the original after the function resolves, though that function could return a modified copy) |
| 23:51 | justin_smith | palinkas: you could probably do this with multiple clojail instances https://github.com/Raynes/clojail |
| 23:51 | crocket | (doc reductions) |
| 23:51 | clojurebot | "([f coll] [f init coll]); Returns a lazy seq of the intermediate values of the reduction (as per reduce) of coll by f, starting with init." |
| 23:51 | palinkas | justin_smith: thx, I'll check it out |
| 23:52 | crocket | TEttinger, () is a list. |
| 23:52 | justin_smith | ,(list? ()) |
| 23:52 | clojurebot | true |
| 23:52 | crocket | seq is an abstraction that a list and a vector implements. |
| 23:52 | crocket | ,(seq? []) |
| 23:52 | clojurebot | false |
| 23:52 | crocket | ouch |
| 23:53 | TEttinger | crocket: heh |
| 23:53 | justin_smith | yeah, () is also a seq |
| 23:53 | justin_smith | ,(seq? ()) |
| 23:53 | clojurebot | true |
| 23:53 | TEttinger | I know what I'm talking about here, crocket. |
| 23:53 | TEttinger | ,(let [coll (range 4)] (do (pr coll) (print " ") (map inc coll) (pr coll))) |
| 23:53 | clojurebot | (0 1 2 3) (0 1 2 3) |
| 23:54 | TEttinger | slaterr: coll doesn't change despite map returning a modified copy |
| 23:55 | slaterr | yes I get that. but I am still trying to decypher your message. maps, a collection, is different than map a function, is that what you meant? no clue what #{} is, or sorted variants of maps and sets |
| 23:56 | justin_smith | that's why I try to use hash-map to talk about the collection type |
| 23:57 | justin_smith | (type #{}) |
| 23:57 | justin_smith | ,(type #{}) |
| 23:57 | clojurebot | clojure.lang.PersistentHashSet |
| 23:57 | justin_smith | it's a set |
| 23:59 | TEttinger | cool stuff time! |
| 23:59 | TEttinger | ,(map inc '(1 2 3)) |
| 23:59 | clojurebot | (2 3 4) |