2010-11-28
| 00:12 | KirinDave | Hum |
| 00:12 | KirinDave | What is the difference between defvar and def? |
| 00:14 | KirinDave | Does defvar just give a more convenient syntax for dropping vars for things like documentation purposes? |
| 00:24 | pppaul | (ns your.namespace.here |
| 00:24 | pppaul | (:require '[clojure.string :as str])) gives me an error |
| 00:24 | pppaul | java.lang.Exception: lib names inside prefix lists must not contain periods (NO_SOURCE_FILE:50) |
| 00:25 | pppaul | nm, i'm not supposed to quote the vector |
| 00:26 | pppaul | found it on this site: http://clojure.github.com/clojure/clojure.string-api.html#clojure.string/split |
| 01:12 | replaca | KirinDave: yeah, that's right. |
| 01:13 | KirinDave | replaca: Figured |
| 01:14 | replaca | KirinDave: I think that part of the thought is also that defvar is in itself documentation (that this is a ver and not a memoized function or some other thing you could do with def) |
| 01:16 | replaca | s/ver/var/ |
| 01:16 | sexpbot | <replaca> KirinDave: I think that part of the thought is also that defvar is in itself documentation (that this is a var and not a memoized function or some other thing you could do with def) |
| 01:30 | Guest43529 | quit |
| 01:54 | ossareh_ | I've a situation where I need to rewrite a function, I think the correct way to do this is with a defmacro. essentially something like this: (wrap-this (some-fn "x") (some-fn "y")) -> (some-fn "x" "y") (some-fn "y" "y") |
| 01:55 | ossareh_ | additionally I want to check whether the forms have a second argument and augment it if it is there. |
| 01:55 | ossareh_ | However when I do this I end up with the following output: Unable to resolve symbol: f__41681__auto__ in this context |
| 01:56 | ossareh_ | (defmacro add-arg [fn] (let [[f#] fn] (prn f#) `(f# "x"))) - called as (add-arg (prn)) |
| 01:56 | Raynes | You don't want to use gensym outside of syntax quote. |
| 01:57 | Raynes | Just name it f and then refer to it as ~f in the syntax quote. |
| 01:58 | ossareh_ | Thanks, Raynes! |
| 01:58 | Raynes | user=> (macroexpand '(add-arg (prn))) |
| 01:58 | Raynes | prn |
| 01:58 | Raynes | (f__2635__auto__ "x") |
| 01:59 | ossareh_ | cool - that works - let me work this into my larger requirement. |
| 01:59 | Raynes | Macroexpand is your best friend. Treat him well, and he'll always be there for you. |
| 02:04 | ossareh_ | ye - I rely on it pretty heavily, got caught out by the gensym stuff. |
| 02:05 | ossareh_ | is there something from your macroexpand output that should have triggered something for me? |
| 02:06 | Raynes | ossareh_: Well, now that I think about it, not really. Since you didn't know to not use gensym outside of syntax quote, it made perfect sense. |
| 02:52 | ossareh | and in the same vein (i.e. rewriting forms) what is the correct way to iterate [& forms] without executing each form? (defmacro add-arg [& forms] (for [[fn] forms] `(~fn "x"))) => (macroexpand '(add-arg (prn) (prn)) => ((prn "x") (prn "x")). Where as I want (prn "x") (prn "x") |
| 03:01 | ossareh | also, I chose to use for since using map (my first attempt) requires I ~@ forms which seems to then be executing the (prn) arguments |
| 03:13 | hoeck | ossareh: macros can only return a single expression |
| 03:15 | hoeck | ossareh: but it could expand into (do (prn "x") (prn "x")) |
| 03:16 | hoeck | and it doesn't matter what code map or for or whatever you are using in the macro, what matters is the right quoting and unquoting |
| 03:18 | hoeck | e.g. with map: (defmacro add-arg [& forms] `(do ~@(map (fn [fn] `(~fn "x")) forms))) |
| 03:18 | ossareh | ahh, the splice being up front... of course! |
| 03:24 | ossareh | thanks hoeck that did the trick :) |
| 03:26 | hoeck | ossareh: you're welcome :) |
| 04:53 | neotyk | Good morning! |
| 04:55 | LauJensen | Morning! |
| 04:57 | neotyk | How does one declare contract for interface from Clojure to Java? |
| 04:57 | neotyk | now I return map-of-maps |
| 04:58 | neotyk | but have no way to be sure that for new entities I will follow same syntax |
| 08:11 | lyonscf | hey guys, I |
| 08:11 | lyonscf | I'm having a little bit of trouble with webmine |
| 08:11 | lyonscf | I can't seem to find a resource for including the ilb |
| 08:12 | lyonscf | in the (use 'foo.bar.webmine) format |
| 08:16 | lyonscf | oh wait, nevermind |
| 08:17 | lyonscf | just read into the core |
| 08:17 | lyonscf | the namespace is webmine.core |
| 08:17 | lyonscf | Thanks anyway :) |
| 08:27 | @rhickey | anyone try *unchecked-math* yet? |
| 08:36 | fliebel | morning |
| 08:45 | jaley | hi guys! can anyone give me a little advice on how best to interoperate with Quartz (the scheduler) from clojure? I don't like that insists on constructing job objects itself from a provided class, because this way i think i'd need to write loads of boiler plate wrappers around clojure functions to get the callback... any suggestions? |
| 08:47 | raek | jaley: I don't have any experience with Quartz, but interop with cron4j is very simple: (doto (it.sauronsoftware.cron4j.Scheduler.) (.schedule "30 16 * * 1-5" #'some-function) .start) |
| 08:48 | raek | I don't know if cron4j provides what you are looking for, but using it requires minimal amount of boilerplate |
| 08:49 | jaley | raek: that looks simpler, thanks |
| 08:49 | raek | (the example runs some-function 16:30 every Monday-Friday) |
| 08:49 | jaley | raek: the problem i have with Quartz is that the interface to add a job is: addJob(JobDetail, Trigger, Class) - where the service creates the job instance based on the class you pass in |
| 08:50 | LOPP | why the quote on #'some-function |
| 08:50 | raek | I have an IRC bot that I like to hack on while it's running |
| 08:51 | LOPP | do you have to change the code if you stop using the quote? |
| 08:51 | jaley | raek: so with quartz i don't think i could avoid a load of gen-class... |
| 08:51 | raek | the var-quote lets me redefine that function and next time the task is executed, it will use the new version |
| 08:52 | raek | LOPP: I think you need to restart the scheduler (which is pretty simple too) if you want it to use the new version |
| 08:52 | raek | hrm, I might be wrong in this case. if you put the function in a datastructure, you need the var-quote |
| 08:53 | raek | but for function parameters... |
| 08:53 | LOPP | because I had to make special code to have functionality where I could use either var-quoted fns or normal fns |
| 08:53 | LOPP | for instance #() ones |
| 08:55 | raek | ok, it turns out that when passing the function directly as an argument, you don't need the var-quote |
| 08:56 | LOPP | these things confuse me :D |
| 08:57 | LOPP | I always have to determine need for quotes with testing |
| 09:02 | raek | I think that when a symbol represents a var, the compiler will compile in a reference to the var itself rather than its value |
| 09:02 | raek | locals introduced by let and function parameters are different |
| 09:04 | LOPP | I think of this in a different manner |
| 09:05 | LOPP | compiler evaluates vars whenever they are part of an expression |
| 09:06 | LOPP | that includes passing them as function parameter or adding them to a data structure |
| 09:06 | LOPP | so if I add a fn to a data structure, the var will get evaluated and value added to the list |
| 09:07 | LOPP | a function using the list of fns will get the same fn every time even if I change the function bound to the var |
| 09:08 | LOPP | when the var of fn is passed as an argument to the function, it gets evaluated to value each time it's called so changing function bound to var changes the behavious of the program |
| 09:08 | LOPP | anyway that;'s how I see it |
| 09:09 | lyonscf | What's the best practice for declaring static global vars? |
| 09:09 | lyonscf | Is it just a def at the top of the file? |
| 09:09 | raek | LOPP: makes sense |
| 09:11 | raek | lyonscf: a globally accessible value would be a simple def |
| 09:11 | lyonscf | thanks raek. :) |
| 09:11 | raek | what do you mean by "static"? |
| 09:11 | lyonscf | static meaning constant |
| 09:12 | lyonscf | but obviously the focus is on immutability in Clojure. |
| 09:14 | LOPP | I hear in 1.3 vars will be immutable by default |
| 09:14 | LOPP | so you'll basically get public static final stuff |
| 09:16 | raek | they can still be redefined, I think |
| 09:16 | raek | but they cannot be dynamically rebound with 'binding' |
| 09:19 | LOPP | doesn't that kinda defeat the purpose |
| 09:22 | raek | in 1.3, when a var is redefined, functions using it will be recompiled at the first time they are called after the redefinition, IIRC |
| 09:22 | raek | so there is some "var version" check on each function entry, I think |
| 09:23 | raek | redefining a var should only be done when correcting a running system, or during development, though |
| 09:25 | LOPP | doesn't that incur a performance penalty though |
| 09:25 | raek | it is a lot faster than the current implementation |
| 09:25 | raek | if I understand things correctly |
| 09:28 | raek | but yes, having a language allowing interactive development cannot be exactly as fast as a purely compiled language |
| 09:28 | raek | but the HotSpot JVM makes a really good job |
| 09:28 | raek | and the 1.3 stuff lets it do much more of its magic |
| 10:07 | LOPP | so you are saying that var version check is done now too |
| 10:16 | raek | I think think this is in the master branch now |
| 10:32 | jarpiain | references to non-:dynamic vars are compiled into calls to Var.getRawRoot() that just returns the private volatile instance field |
| 10:35 | jaley | not in the doc string, but does anyone know if there's a keyword option to add a watch function to an agent? |
| 10:36 | jaley | i mean for the agent function, of course. just to avoid needing add-watch |
| 11:31 | djpowell | is unchecked-math supposed to work with binding? |
| 11:32 | djpowell | (binding [*unchecked-math* true] (byte 200)) fails |
| 11:32 | djpowell | but (set! *unchecked-math* true) (byte 200) works |
| 11:35 | djpowell | ah - does it only affect what is compiled? |
| 11:35 | djpowell | ok that makes sense |
| 11:37 | djpowell | I think. I'm not sure how you would go about turning it on and resetting it tho? |
| 12:20 | zmyrgel | hi, how can I test if item implements protocol/ |
| 12:20 | zmyrgel | ? |
| 12:37 | kaiser | hi, guys |
| 12:37 | Guest43491 | i'd like to execute n times a function and get the last result...what's the best construction for this? |
| 12:38 | raek | is this for java interop? |
| 12:38 | Guest43491 | no |
| 12:40 | Guest43491 | in fact, i want to accomplish the following... |
| 12:40 | Guest43491 | i have a function 'a' |
| 12:40 | Guest43491 | and the result must be the input of the same function 'a' |
| 12:41 | Guest43491 | and i want to execute this function n times... |
| 12:41 | raek | sounds a bit like iterate |
| 12:41 | raek | ,(doc iterate) |
| 12:41 | Guest43491 | i have performance issues |
| 12:41 | raek | &(doc iterate) |
| 12:41 | sexpbot | ⟹ "([f x]); Returns a lazy sequence of x, (f x), (f (f x)) etc. f must be free of side-effects" |
| 12:41 | Guest43491 | so, i'm reading about lazy-seq with recursion... |
| 12:42 | Licenser | evening |
| 12:42 | Guest43491 | hmm...gonna try this iterate... |
| 12:43 | raek | &(take 10 (iterate inc 0)) |
| 12:43 | sexpbot | ⟹ (0 1 2 3 4 5 6 7 8 9) |
| 12:43 | Licenser | iterate passes the result of the current call to the next call |
| 12:45 | Guest43491 | thanks |
| 12:46 | raek | &(let [compose-n-times (fn [f n] (fn [x] (nth (iterate f x) n))), plus-10 (compose-n-times inc 10)] (plus-10 5)) |
| 12:46 | sexpbot | ⟹ 15 |
| 12:48 | opqdonut | &(let [compose-n-times (comp (partial reduce comp) repeat) plus-10 (compose-n-times 10 inc)] (plus-10 5)) |
| 12:48 | sexpbot | ⟹ 15 |
| 12:52 | slyrus_ | technomancy: thanks! |
| 12:58 | Guest43491 | thank you raek |
| 13:29 | miltondsilva | Hi |
| 13:32 | miltondsilva | I have a vector like [:f :- :push :f :pop] and would like to generate code like ((forward) (rotate) (push-matrix (forward))) do I need a macro to do this? |
| 13:33 | raek | no |
| 13:33 | chouser_ | no, though once you've generated the code you'll need either a macro or 'eval' to run it. |
| 13:34 | miltondsilva | hmmm ok but is it easier with one? I've never felt the need to use macros so I haven't learn how to used them |
| 13:34 | raek | you could do a function that interprets that vector and executes the functions |
| 13:35 | miltondsilva | I was trying to use strings and read-string + eval.. but somehow it's getting a bit ugly |
| 13:35 | raek | the :f and :- case should be pretty simple: |
| 13:37 | raek | (defmacro foo [x] (if (empty? x) nil `(do ~(case (first x) :f `(forward) :- `(rotate)) (foo ~(rest x))))) |
| 13:37 | raek | or somehing like that |
| 13:38 | raek | miltondsilva: there is no need to go through strings |
| 13:39 | raek | a macro is just an ordinary clojure function that takes unevaluated code expressions as its arguments and returns some new code |
| 13:39 | chouser | raek: replace "just" with "like" and I'll let it go. :-) |
| 13:40 | raek | right. |
| 13:40 | raek | the &env thingy? |
| 13:40 | chouser | yes, and &form |
| 13:41 | miltondsilva | hmm.. thanks I think I can do it now |
| 13:53 | Intertricity | Is there any documentation on using .Net in the clojure-clr implementaiton? |
| 13:54 | Intertricity | *implementation |
| 13:54 | Intertricity | like how to access dictionaries, or the system libraries |
| 13:55 | Raynes | chouser: Why is &form useful? |
| 13:58 | chouser | Raynes: I think primarily for pulling metadata off the form and the first symbol |
| 14:02 | jjido_ | can I tell Clojure to tell the JVM to reload a Java class? |
| 14:02 | chouser | you can generate a new class with the same name with deftype and defrecord, but otherwise no |
| 14:03 | jjido_ | ok |
| 14:03 | chouser | you may be able to use some other tool to do that, javarebel or whatever, but I don't know if anyone has gotten such things working with clojure |
| 14:04 | jjido_ | I will just restart the JVM no big deal. |
| 14:50 | Intertricity | wow clojure is hard xD |
| 14:51 | Intertricity | I have to chew on chunks of tutorials for a while to grasp the concept |
| 14:51 | Derander | Intertricity: have you had any experience w/ functional programming before? |
| 14:52 | Intertricity | Derander, not really, I just did basic C and Python before that |
| 14:53 | Derander | makes sense then :-) |
| 14:53 | Intertricity | hehe |
| 14:54 | Intertricity | With the beginnings of clojure on clr though, I want to try porting my .Net program over to clojure |
| 14:54 | Intertricity | I've been waiting for the clr implementation to start learning it |
| 14:54 | Derander | it's fun |
| 14:55 | Derander | not a java fan? |
| 14:55 | Intertricity | Derander, do you know where I can get docs on how to use clojure-clr to access the .Net libraries like system or dll's? |
| 14:55 | Intertricity | Derander, the library I use is all .Net unfortunately |
| 14:55 | Derander | no, unfortunately, I have no idea. I've never used clojure-clr. |
| 14:55 | Intertricity | aw nutbunnies |
| 14:56 | Intertricity | I was originally using ironpython |
| 14:56 | Intertricity | but I long to see parenthesis in my code xD |
| 14:56 | Derander | right |
| 14:56 | Derander | :P |
| 14:56 | raek | for interfacing with .net classes, I suspect it should work like java interop in "clojure-jvm" |
| 14:56 | Derander | that would be my guess too |
| 14:56 | hoeck | Intertricity: I only managed it to compile clojure-clr once and ran a simple hello-world windows dialog |
| 14:57 | Intertricity | hoeck, they have binaries available now |
| 14:57 | hoeck | Intertricity: and does it now run on mono? |
| 14:57 | Intertricity | I wouldn't know, sorry |
| 14:57 | raek | Intertricity: http://clojure.org/java_interop |
| 14:57 | Intertricity | raek, ty :) |
| 14:58 | hoeck | the interop seemed the same as on (java-)clojure, import classes and then call .methods on them |
| 14:58 | Intertricity | I dont' know much about java if any, I wonder if it's simlar to this to laod a dll? |
| 14:58 | Intertricity | *load |
| 15:01 | hoeck | Intertricity: how do you load a dll in .net? |
| 15:02 | Intertricity | clr.AddReference("System", "OpenMetaverse","OpenMetaverseTypes") |
| 15:02 | Intertricity | from OpenMetaverse import * |
| 15:02 | raek | in java-land, you start the jvm instance with a classpath option. the classpath is a list of directories and jar-files that contains .class-files |
| 15:02 | Intertricity | I see |
| 15:04 | Intertricity | Hm. well tihs is a little closer http://www.mail-archive.com/clojure@googlegroups.com/msg24944.html |
| 15:04 | Intertricity | but nothing about dll's |
| 15:08 | hoeck | Intertricity: the assemblies may reside in some dll, and on windows it may be enough when your dll is on the search path |
| 15:09 | Intertricity | hoeck, how would I define the path myself? I usually keep the library I'm working with close to my sourcefile atm |
| 15:09 | Intertricity | or if you have any past code that shows it, that would be even better >.> |
| 15:09 | Intertricity | I can't find docs or examples |
| 15:10 | hoeck | don't know about .net, but win32 dlls have to reside in %PATH% or . or win\system32\ or so |
| 15:11 | hoeck | If you have a working IronPython solution, the just try that (System.Reflection.Assembly/LoadWithPartialName "System.OpenMetaverse.OpenMetaverseTypes") |
| 15:12 | hoeck | followed by an (import '(System.OpenMetaverse OpenMetaverseTypes)) |
| 15:12 | hoeck | if IronPython finds that dll without tweaking, clojure-clr should do the same |
| 15:12 | Intertricity | hoeck, ty :) |
| 17:44 | jweiss_ | i'm trying to introduce clojure to co-workers in the most painless way possible. I think the labrepl tutorial is great, but I don't want them to go thru the pain of installing the prereqs until they're "hooked". I can host the labrepl webapp for them, but any suggestions how to host a repl? |
| 17:45 | jweiss_ | i checked out http://tryclj.licenser.net/ , but there's no cut/paste. |
| 17:45 | Raynes | jweiss: try-clojure.org is the actual domain. |
| 17:46 | Raynes | I use jquery-console which doesn't support copy and paste. |
| 17:46 | Raynes | In any case, there is no way to run a server-side REPL without sandboxing, and even then it may not be totally safe. |
| 17:47 | jweiss_ | Raynes: googling "try clojure" links to the address i pasted. but yeah i know that is not the official url |
| 17:47 | jweiss_ | Raynes: since it's just co-workers and I can run it on a vm, i'm not concerned with security |
| 17:48 | jweiss_ | \some paredit functionality would be nice |
| 17:48 | Raynes | That it would. It most likely wont happen though. At least, not while jquery-console is being used. |
| 17:50 | jweiss_ | Raynes: yeah, i wish there was a way to "webify" a slime session |
| 17:51 | jweiss_ | but i don't see how a browser is going to take over those keybindings |
| 17:51 | jweiss_ | trying to convince someone to use clojure without them knowing of paredit's existence, well, it doesn't help clojure's cause :) |
| 17:55 | lucian | Raynes: wouldn't a java applet work too? |
| 17:55 | Raynes | lucian: Yes, but applets are ugly and meh. |
| 17:55 | Raynes | http://github.com/Raynes/webrepl |
| 17:57 | lucian | Raynes: wouldn't it also be easier on the server? |
| 17:57 | Raynes | Yes, but applets are still ugly and meh. :p |
| 17:58 | jweiss_ | an applet would be pretty straightforward actually. still no paredit, but no need for security |
| 17:58 | lucian | Raynes: yeah, they do tend to be ugly |
| 17:58 | Raynes | jweiss: If you want, you're welcome to use webrepl. |
| 17:58 | Raynes | It's ugly as sin, but it'll do the trick. |
| 17:59 | jweiss_ | Raynes: let's see how ugly :) |
| 18:00 | jweiss_ | Raynes: how do i run it |
| 18:00 | Raynes | Aren't there instructions in the README? |
| 18:00 | jweiss_ | Raynes: no |
| 18:00 | jweiss_ | not the readme on the github page, anyway |
| 18:00 | Raynes | That sucks. I don't remember how to run it. |
| 18:00 | jweiss_ | hehe |
| 18:02 | jweiss_ | Raynes: i think you left JConsole out of the deps in project.clj |
| 18:02 | Raynes | It's included in the source. |
| 18:02 | jweiss_ | ah |
| 18:03 | jweiss_ | lein doesn't seem to know how to build it |
| 18:03 | Raynes | I would be more helpful, but I'm in the process of moving stuff to a new server. Trying to get sexpbot up and running there. |
| 18:03 | KirinDave | Hum. |
| 18:03 | jweiss_ | Raynes: that's ok, i'll figure something out :) |
| 18:04 | KirinDave | Is there any consensus on best practices in clojure for using protocols and deftype? |
| 18:04 | Raynes | jweiss: lein repl and then use webrepl.core, and then run -init |
| 18:04 | KirinDave | For example, what's the right way to make default behavior? |
| 18:04 | jweiss_ | Raynes: thx |
| 18:04 | KirinDave | I had hoped I could do something like: (extend-protocol tester Object (c [d] (a d))), (extend-protocol tester java.lang.Integer (a [b] (inc b))) |
| 18:05 | KirinDave | And have (c 1) return 2. |
| 18:06 | KirinDave | But it seems like if you omit a function definition from a protocol map for a given type, it won't try to call the method on a more general type. |
| 18:15 | brehaut | is there an XML-RPC library that works with ring? |
| 18:33 | Raynes | Oops. Forgot to run it in screen. ._. |
| 18:36 | dnolen | a much faster implementation of miniKanren for Clojure - https://github.com/swannodette/logos for the logic / relational programming fans. Lots of Clojure specific additions and tweaks. |
| 19:26 | markj9 | anyone have a minute to offer suggestions on why lein is now giving me this error http://pastie.org/1331111 |
| 19:51 | brehaut | what is the naming conventions for defrecord types? is it camel cased like a java class? |
| 20:16 | jweiss_ | anyone noticed that labrepl doesn't build anymore? it has a dev dep on autodoc-0.7.0, which depends on clojure-contrib 1.1.0-master-SNAPSHOT, which unsurprisingly is no longer available in the repo |
| 20:18 | Raynes | jweiss: :exclude it's autodoc dependency. |
| 20:19 | Raynes | jweiss: There is an example of using exclusions in sample.project.clj in the Leiningen repository. |
| 20:19 | jweiss_ | Raynes: i know how to fix it for myself. but i'm setting up my co-workers to check out the source from github and their source will be wrong |
| 20:19 | Raynes | Oh. |
| 20:19 | jweiss_ | i was wondering if there was a different command than lein deps i could run that would bypass the dev deps |
| 20:20 | jweiss_ | i suppose i could just build an uberjar and distribute that |
| 20:21 | jweiss_ | but i was hoping not to have to host anything |
| 20:21 | jweiss_ | i guess i could fork the project on guthub |
| 20:21 | jweiss_ | that's probably the easiest |
| 20:22 | KirinDave | Am i the only person a little frustrated by non-seq laziness in clojure? |
| 20:27 | replaca | KirinDave: what do you mean exactly by non-seq laziness? |
| 20:27 | replaca | KirinDave: you mena like vecors not being lazy? |
| 20:27 | replaca | s/mena/mean/ |
| 20:27 | sexpbot | <replaca> KirinDave: you mean like vecors not being lazy? |
| 20:28 | replaca | ok, I'm going to give up on typing now :) |
| 20:29 | KirinDave | replaca: Ha |
| 20:29 | KirinDave | replaca: I mean like how you have to force delays. |
| 20:30 | KirinDave | replaca: Yes, force is idempotent on non-delay objects, but then I'm writing force everywhere on the off chance client code sends my library a delay. |
| 20:30 | KirinDave | It'd be better if the force was implicit. |
| 20:31 | replaca | KirinDave: isn't that just the definition of a delay? "That which needs to be forced"? |
| 20:31 | KirinDave | replaca: Well i wish I had a (lazy ...) then |
| 20:31 | KirinDave | ,(doc lazy) |
| 20:31 | KirinDave | Damn it |
| 20:31 | KirinDave | The Secret™ fails again. |
| 20:31 | replaca | KirinDave: make it. |
| 20:32 | KirinDave | replaca: I am not sure how. |
| 20:32 | KirinDave | I suspect it's a pretty non-trivial thing. |
| 20:32 | KirinDave | Gonna have to go into the compiler to do it properly. |
| 20:33 | replaca | KirinDave: why, can't you just wrap a delay in an object that implements IDeref which does a force, then the regular deref? |
| 20:33 | KirinDave | replaca: Doesn't deref already force? |
| 20:33 | replaca | or am I misunderstanding your use case? |
| 20:34 | KirinDave | replaca: The fact that I have to explicitly force values means I need to expect laziness and just force everything before using it. |
| 20:34 | KirinDave | replaca: This clutters up the code pretty significantly. |
| 20:35 | KirinDave | I think from a library-writer's perspective, this means that you won't handle implicit client laziness very often without sacrificing a lot of code readability. |
| 20:35 | replaca | oh, I see |
| 20:35 | KirinDave | It'd be great if, if someone passed me in a delay to my library, it was auto-forced at the appropriate time. |
| 20:35 | replaca | yeah, you're right, I think |
| 20:35 | KirinDave | But like I said, I think it'd need compiler and stdlib support |
| 20:36 | KirinDave | If it was more like scala's lazy keyword, we'd see laziness used a lot more in clojure code, I think. |
| 20:36 | KirinDave | Part of the popularity of seqs is their magic. |
| 20:36 | KirinDave | You don't have to explicitly force seq values, that happens implicitly as you move along the seq. |
| 20:37 | replaca | so what you're after is "(let [foo (magic (bar baz))] foo)" to have bar called when foo is referenced? |
| 20:38 | KirinDave | Yes. |
| 20:38 | KirinDave | But _not_ if, say, foo is just passed as a function argument |
| 20:38 | KirinDave | Or put into a let. |
| 20:39 | KirinDave | It has to be "used" for some definition of used that is not just handling. |
| 20:39 | replaca | KirinDave: actually, you are explicitly forcing the seq: you call next |
| 20:39 | replaca | you're just so used to that that you don't consider it |
| 20:39 | KirinDave | replaca: Well, the stdlib supports that very aggressively. |
| 20:39 | replaca | yup. sure does |
| 20:39 | KirinDave | replaca: I probably have written "next" like 3 times in my clojure experience. |
| 20:40 | KirinDave | So delay could be the mechanism if the stdlib aggressively supported it. |
| 20:40 | KirinDave | It'd take an audit of the whole stdlib tho |
| 20:41 | KirinDave | It would also make clojure.lang.Delay the Invisible Man of the clojure library. :) |
| 20:41 | KirinDave | Because then #(class (delay 1)) would not be what people think it would be. |
| 20:41 | KirinDave | Derp, why'd I write #? |
| 20:41 | replaca | yeah, the decision about when to force is tough too. For how long to you jest keep all the dependent computions deferred and then do it. |
| 20:42 | replaca | Very much like Haskell when you drive it as far as you can |
| 20:42 | KirinDave | Yeah. That's why it'd need compiler support too. |
| 20:42 | KirinDave | Yeah, which would be nice. |
| 20:42 | KirinDave | I worry I am coming around to haskell. |
| 20:42 | KirinDave | I don't want to. I love the lisp legac. |
| 20:42 | KirinDave | s/c$/cy/ |
| 20:43 | KirinDave | ha |
| 20:43 | replaca | See I'd rather go with Haskell if I could convince myself it would be anywhere close to as productive as Clojure |
| 20:43 | KirinDave | I suck. |
| 20:43 | KirinDave | replaca: That is the issue, isn't it |
| 20:43 | replaca | KirinDave: completely. and I don't think that even being close is possible |
| 20:43 | replaca | KirinDave: but you can do some cool stuff |
| 20:44 | replaca | KirinDave: but these days I can't convince myself to write in any other language than Clojure |
| 20:44 | replaca | KirinDave: of course, I lack your appreciation for C# |
| 20:45 | replaca | :) |
| 22:30 | ossareh | how would you improve this? (reduce (fn [acc x] (assoc acc (clojure.contrib.string/as-str (first x)) (second x))) {} {:k "k" :v "v"}) |
| 22:30 | ossareh | I feel like there is a smarter way to do this - I just don't know enough of the stdlib to know what I should be mapping |
| 22:31 | brehaut | ossareh well to start you could desctructure your args |
| 22:31 | brehaut | (reduce (fn [acc [k v]] (assoc acc (clojure.contrib.string/as-str k) v)) {} {:k "k" :v "v"}) |
| 22:32 | ossareh | (reduce (fn [acc [k v]] (assoc acc (clojure.contrib.string/as-str k) v)) {} {:k "k" :v "v"}) |
| 22:32 | ossareh | ah |
| 22:32 | ossareh | heh |
| 22:32 | ossareh | :) |
| 22:36 | chouser | what does as-str do again? |
| 22:36 | brehaut | Like clojure.core/str, but if an argument is a keyword or symbol, |
| 22:36 | brehaut | its name will be used instead of its literal representation. |
| 22:36 | chouser | ,(name ":k") |
| 22:36 | chouser | er |
| 22:36 | chouser | & (name :k) |
| 22:36 | sexpbot | ⟹ "k" |
| 22:36 | chouser | & (name "k") |
| 22:36 | sexpbot | ⟹ "k" |
| 22:37 | chouser | like that? |
| 22:37 | brehaut | apparently so |
| 22:37 | ossareh | huh, didn't know about name |
| 22:37 | ossareh | thanks for that |
| 22:37 | ossareh | saves me a (use) :) |
| 22:38 | chouser | it wasn't always that way |
| 22:39 | ossareh | damn straight. I started just over a year ago and it was hard back then. |
| 22:39 | ossareh | you core people have nailed it, thanks chouser et al. |
| 22:41 | chouser | ossareh: you really want a map with keys matching the values? |
| 22:43 | ossareh | chouser: {:foo "bar"} => {"foo" "bar"} |
| 22:43 | chouser | ah |
| 22:43 | chouser | &(let [m {:k1 "k2" :v3 "v4"}] (zipmap (map name (keys m)) (vals m))) |
| 22:43 | sexpbot | ⟹ {"v3" "v4", "k1" "k2"} |
| 22:43 | chouser | not really any better |
| 22:43 | ossareh | form-dot-clj gives you :keywords, expects strings back. |
| 22:44 | ossareh | I know so little about zipmap - I prefer readability of the reduce solution. |
| 22:47 | chouser | & (apply conj {} (map (fn [[k v]] [(name k) v]) {:k1 "k2" :v3 "v4"})) |
| 22:47 | sexpbot | ⟹ {"v3" "v4", "k1" "k2"} |
| 22:48 | brehaut | chouser, is there an advantage to using apply conj over into there? |
| 22:48 | chouser | no! |
| 22:48 | chouser | use into |
| 22:48 | chouser | & (into {} (map (fn [[k v]] [(name k) v]) {:k1 "k2" :v3 "v4"})) |
| 22:48 | sexpbot | ⟹ {"k1" "k2", "v3" "v4"} |
| 22:48 | chouser | slipped my mind |
| 22:54 | brehaut | i wonder how common that pattern of (fn [[a b]] [(fun-a a) (fun-v b)]) is |
| 22:54 | brehaut | seems like it would be common enough to have something like (vec-apply fun-a fun-b) |
| 22:55 | brehaut | that is the mutant offspring of juxt and vec |
| 23:03 | Raynes | chouser: You? Making a mistake? Surely not! |
| 23:09 | Raynes | I must alert the Higher Order. |
| 23:10 | ossareh | lol @ ^ |