Re: [ANN] New blog post on Perfumed Nightmare
Daniel Szmulewicz writes: > Greetings fellow Clojurians, > > I am excited to announce the publication of my latest in-depth blog > post on the topic of HTTP and web application development. Since I am > currently looking for work, I had the opportunity to dedicate my > mornings - when I’m at peak mental clarity - to creating this content > over the course of a week. Hi Daniel, Thanks for sharing your post on building a dependency-free, minimal HTTP server. In the same vein, I thought you (and perhaps some others on this mailing list) might be interested in seeing my dependency-free, minimal Gemini server, Space-Age. I built it several years ago when the Gemini protocol was just firming up, and I've had great fun in using it to run both my personal site and the software team wiki at my workplace. Since it is also written in Clojure without any dependencies on third party libraries, its socket management code looks quite a lot like yours but also includes features for encryption and authentication over SSL/TLS with X.509 certificates. Here's the link if anyone is interested: https://gitlab.com/lambdatronic/space-age The smallnet/smolnet is a real breath of fresh air after being inundated by the every increasing corporatization of the web over the last few decades. And from a learning perspective, working with much simpler, alternative communication protocols greatly increases accessibility for both users and developers and may even encourage you to whip up your own Gemini server or client as a weekend project. Have fun and happy hacking! Gary -- GPG Key ID: 7BC158ED Use `gpg --search-keys lambdatro...@gmail.com' to find me Protect yourself from surveillance: https://emailselfdefense.fsf.org === () ascii ribbon campaign - against html e-mail /\ www.asciiribbon.org - against proprietary attachments Why is HTML email a security nightmare? See https://useplaintext.email/ Please avoid sending me MS-Office attachments. See http://www.gnu.org/philosophy/no-word-attachments.html -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/clojure/87y18ty2zz.fsf%40gmail.com.
Re: Can't start figweel.main on other Linux-machine
ru writes: > I moved a working project from one Linux-machine to other. > And that's what I got: > > ru@ru-sitrol:~$ cd clojure/pro-figweel/ > ru@ru-sitrol:~/clojure/pro-figweel$ clojure -m figweel.main -b dev -r 8<-->8 Downloading from clojars and error messages elided 8<-->8 > "Could not locate figweel/main__init.class, figweel/main.clj or > figweel/main.cljc on classpath."}} > > > What can be reason of this? > Any help would be greatly appreciated. > > Sincerely, > Ru Hi Ru, You are the victim of a typo, I'm afraid. You forgot the "h" in "figwheel". The correct command should be: ``` ru@ru-sitrol:~/clojure/pro-figweel$ clojure -m figwheel.main -b dev -r ``` Have fun and happy hacking! Gary -- GPG Key ID: 7BC158ED Use `gpg --search-keys lambdatro...@gmail.com' to find me Protect yourself from surveillance: https://emailselfdefense.fsf.org === () ascii ribbon campaign - against html e-mail /\ www.asciiribbon.org - against proprietary attachments Why is HTML email a security nightmare? See https://useplaintext.email/ Please avoid sending me MS-Office attachments. See http://www.gnu.org/philosophy/no-word-attachments.html -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/clojure/87y1ehcuvx.fsf%40gmail.com.
[ANN] Job Opening for Full Stack Web Developer
Howdy Clojurians, Spatial Informatics Group (SIG) is seeking a new Full Stack Web Developer to build Clojure/Clojurescript web applications in the realm of environmental mapping and modeling. The position is fully remote, but applicants with work hours that correlate well with North American time zones are preferred. SIG is an environmental think-tank, comprised of around 35 core members with backgrounds in natural resource management, city and urban planning, wildland fire science, hydrologic modeling, carbon credit trading, forest management, remote sensing, computer science, and environmental mapping and modeling. Applicants should be comfortable building Clojure web apps built on a stack like Ring+Jetty+Reagent+Herb+OpenLayers+next.jdbc+Postgresql, building projects with the Clojure CLI tools (deps.edn), collaborating over Github/Gitlab with clean branch management and code reviews, and deploying to remote GNU/Linux VMs over SSH. Strong communication skills are a must since all of our work will be done online. Experience with GIS and geospatial analysis and data sharing with tools like GDAL/OGR, PostGIS, and GeoServer are a definite plus. Apply here: https://boards.greenhouse.io/spatialinformaticsgroup/jobs/4223818003 Learn more about SIG here: https://sig-gis.com/ Happy hacking, Gary -- GPG Key ID: 7BC158ED Use `gpg --search-keys lambdatronic' to find me Protect yourself from surveillance: https://emailselfdefense.fsf.org === () ascii ribbon campaign - against html e-mail /\ www.asciiribbon.org - against proprietary attachments Why is HTML email a security nightmare? See https://useplaintext.email/ Please avoid sending me MS-Office attachments. See http://www.gnu.org/philosophy/no-word-attachments.html -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/clojure/87h7p5dxak.fsf%40gmail.com.
Re: first time without state - and I'm lost
Hi Scaramaccai, Several posters in this thread have given you example code for how to solve your OAuth token problem in Clojure. Perhaps I can add to this discussion by pointing out the fundamentals of functional programming that can help you decide how to solve problems like this. *Loops -> Recursions and State -> Bindings* You asked how to handle state in a functional programming language. In some situations, it may be easiest to just store stateful values in a mutable container type like a ref, agent, or atom. This is not a strictly functional approach, but these are tools that Clojure provides to make a variety of programming tasks somewhat easier (in the Rich Hickey sense of the word). In many cases, this is neither necessary nor preferable. Instead, you can use the functional programming approach of emulating state change over time by passing your new derived values as arguments to the next step in a recursive function. That is, in FP "state change" happens on the stack (through function bindings and let bindings) rather than on the heap (through direct assignment to mutable containers). Consider these two approaches to computing the factorial function. *1. Imperative (loops + mutation)* (defn fact-imp [n] (let [result (atom 1)] (dotimes [i n] (swap! result * (inc i))) @result)) *2. Functional (recursion + fn bindings)* (defn fact-rec [n] (if (<= n 0) 1 (* n (fact-rec (dec n) These two implementations will return the same outputs for the same inputs. Note that in the functional approach, fact-rec computes the next value of the result and passes it as the input to itself rather than mutating a local variable as in the imperative case with fact-imp. Savvy readers will notice that fact-rec is not tail recursive and is therefore prone to stack overflow for large values of n. Rewriting it to work with loop+recur is left as an exercise for the reader. ;) The approach shown above is a typical solution for state that goes through a series of intermediate changes to produce a final result. A similar approach for the same issue is to model all the values that you would have stored one at a time in a stateful variable as an immutable sequence of values. This approach relies on lazy evaluation. To illustrate, I will once again implement factorial using this technique. *3. Functional (sequences + lazy evaluation)* (defn fact-lazy [n] (letfn [(next-step [[i x]] [(inc i) (* x (inc i))]) (fact-seq [pair] (lazy-seq (cons pair (fact-seq (next-step pair )] (second (nth (fact-seq [0 1]) n In this example, next-step derives the next state value from the current one. The fact-seq function returns a lazy sequence of all the [i factorial(i)] pairs from [0 1] to [infinity factorial(infinity)]. This sequence is obviously never fully realized since it would throw your application into an infinite recursion. We then use nth to grab the [n factorial(n)] pair off of the lazy sequence and second plucks out just factorial(n) to return as the result of our fact-lazy function. Once again, I never mutated any variables in place. I simply created a recursive algorithm that could derive the next value from the current value. Unlike the non-tail-recursive fact-rec above, this lazy sequence implementation is immune to stack overflow errors. However, fact-lazy will use more memory and more CPU cycles than fact-rec's eager implementation because it has to create and release the lazy sequence and intermediate vector pairs. These are all tradeoffs, which you would need to consider in determining the approach that might work best for your problem. *Hiding State* In the three approaches I showed to represent state change in your Clojure program, none of these went out of their way to either hide or share the state values over time. Here, you again have broadly two choices: *1. Global mutable variables* If you don't need to hide your application state, the best approach is just to store it in a global mutable container like a ref, agent, or atom. Then you can introspect or manipulate it from your REPL, and multiple functions in your program can all access it as needed. (def state (atom 0)) *2. Closures* If you need to hide your application state for some reason (and there are often less reasons to do this than you might imagine), then your best friend is a closure function. A closure is a function which "closes over" the bindings which exist when it is defined by capturing references to them in its free variables (i.e., variables which are not bound as function args or let args in the function body). Functions that return closures around mutable state can work a bit like OOP constructor functions, creating a function that behaves a bit like an object with internal stateful attributes. Welcome to OOP inverted! (defn get-token "Somehow get an OAuth token for this user+pass combination." [user pass] {:token "some-token" ; replace this with something real
Re: WebApp authentication and authorization - up-to-date information?
Hi folks, While it's not directly to your point, here is a pretty complete (IMHO) repository that I put together for getting you going with a new Clojure+Clojurescript website: https://gitlab.com/lambdatronic/clojure-webapp-template Just clone it and check out the README.md file for a description of the build and runtime software requirements, build aliases, and expected usage in development and production modes. All of the build config files are built around the tools.deps clojure command-line interface and use a modern version of figwheel for development. The deps.edn file contains aliases to: 1. Initialize a Postgresql database, including custom Clojure code that provides a simple "namespace"-like dependency system for your SQL files using a topo-sort procedure for dependency resolution. If you prefer to use a different database, you could easily tweak build_db.clj and create_db.sql to meet your needs. 2. Compile your CLJS code into app.js using advanced compilation settings (for production deployment). 3. Compile your CLJ code and launch an embedded Jetty web server on a port that you specify (or 8080 by default). 4. Launch Figwheel, compile your CLJS code into app.js using {optimizations :none} (for rapid development), launch an embedded Jetty web server on port 8080, and automatically hotload any live changes to your CLJS files into your browser session and live changes to CLJ files into your server (available on browser refresh). In addition, the Clojure code provides a pre-configured middleware stack with custom middlewares for request and response logging, exception handling, and parsing EDN params in the request object. There is also simple routing-handler function using plain old Clojure with some helper function to render HTML and EDN/JSON responses that you can extend or replace to meet your objectives. Super-cool features include a pre-configured system of routes, CLJ handlers, and asynchronous CLJS functions (using core.async) that allow you to trivially call SQL functions directly from Clojure (synchronously) and to call both CLJ and SQL functions from Clojurescript (asynchronously) using a similar calling syntax. All database interaction is done through Sean Corfield's excellent next.jdbc library. In my usual programming model, I encode any operations that should happen in the database as SQL functions in Postgresql. These are loaded by my `clojure -A:build-db only-functions` alias. Then from Clojure, I can call these SQL functions like so: ```clojure (call-sql "contact.get_user" user-id) ;;=> [{:name "Rich Hickey" :residence "Hammock"}] ``` Alternatively, I can call the same function from Clojurescript like so: ```clojure (def my-contact (atom nil)) (go (reset! my-contact ( [{:name "Rich Hickey" :residence "Hammock"}] ``` You can do the same thing with CLJ functions from CLJS like so: ```clojure (def cool-result (atom nil)) (go (reset! cool-result (http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/clojure/1954346f-ed06-4b66-a6d3-3d7ac5a4db87%40googlegroups.com.
Re: Any way to replace function body?
You have several options for this in Clojure. However, rebinding the same toplevel var that holds the original function is probably not the right way to do this if you want to be able to retrieve the old function value later. Consider the following approaches: 1. Define a single multi-arity function: (defn fetch-data ([arg1 arg2] (db/fetch-data ...)) ([arg1 arg2 & args] (let [result (fetch-data arg1 arg2)] ;; do something with the remaining args (transform-result result 2. Derive the second function by composition: (defn fetch-data [arg1 arg2] (db/fetch-data ...)) (def fetch-transformed-data (comp transform-result fetch-data)) 3. Use "let" to rebind the function's definition within a lexical scope: (defn fetch-data [arg1 arg2] (db/fetch-data ...)) ;; ...somewhere later in my program... (let [fetch-data (fn [arg1 arg2] (transform-result (fetch-data arg1 arg2)))] (fetch-transformed-data "foo" "bar")) ;; Note: While this works, it is pretty sketchy. You should probably just call the new local version of the function something else. 4. Use "binding" to rebind the function's definition within a dynamic scope: (defn ^:dynamic fetch-data [arg1 arg2] (db/fetch-data ...)) ;; ...somewhere later in my program... (let [fetch-data-orig fetch-data] (binding [fetch-data (fn [arg1 arg2] (transform-result (fetch-data-orig arg1 arg2)))] (fetch-data "foo" "bar"))) ;; Note: You can't use binding to create a self-referential (recursive) function or you will trigger an infinite recursion. Use let to close over the original value of fetch-data before referencing it within the body of the new function used with binding. There are probably several other approaches that you could experiment with as well if you wanted to look a bit farther afield. IMO, I would just go with the function composition solution. It's clear and concise and doesn't require you to remember the specifics of dealing with recursion in dynamic binding forms. Happy hacking! Gary On Saturday, January 19, 2019 at 2:58:29 PM UTC, Janko Muzykant wrote: > > Hi, > > Is there an way to replace body of existing (interned) function with own > code still being able to call original fn? > Suppose, I have a function: > > (defn fetch-data [arg1 arg2] > (db/fetch-data ...)) > > I would like to intern a slightly modified version of this fn. Something > like this: > > (defn fetch-data [& args] > (let [result (apply original-fetch-data args)] > (transform-result result))) > > The problem I see is how to keep the reference to original fetch-data fn > (here denoted by original-fetch-data), > so it could be still called in a altered version of fetch-data function. > > Best, > JM. > > > > -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: OK idea to replace conj and cons with "prepend" and "append" macros that have consistent behavior and return same types as args?
Thanks, Gary and Justin, for spotting my code mistakes. Serves me right for not double-checking the outputs at my REPL. :-P Anyway, my examples with vectors, maps, and sets were all correct using into. I goofed on lists, because the new elements are naturally always applied to the front of the list since that is the only way to do it efficiently. This really just reinforces what others have already said above that Clojure's standard library doesn't make it easy for you to do something inefficient (like adding elements to the end of a list. Anyway, having said that, I guess I'd just make the following adjusted recommendation then: 1. When appending/prepending to vectors, maps, or sets, use into as demonstrated above. 2. When appending/prepending to lists, use concat with the same syntax as was shown with into above. Note, of course, that concat returns a lazy sequence not a true linked list, but for the purposes of beginner instruction, this should probably be fine since it will print to the REPL like a list and provides the same API as a list going forward. Once again, good luck with your Clojure teaching, and happy hacking! ~Gary -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: Complete Web Development Setup Using Clojure CLI Tools
Thanks for the link! -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: OK idea to replace conj and cons with "prepend" and "append" macros that have consistent behavior and return same types as args?
Hi Christian, You are looking for "into", which is already part of the Clojure standard library. Appending: (into '(1 2) '(3)) ;=> (1 2 3) (into [1 2] [3]) ;=> [1 2 3] (into {:a 1 :b 2} {:c 3}) ;=> {:a 1, :b 2, :c 3} (into #{:a :b} #{:c}) ;=> #{:c :b :a} Prepending: (into '(1) '(2 3)) ;=> (1 2 3) (into [1] [2 3]) ;=> [1 2 3] (into {:a 1} {:b 2 :c 3}) ;=> {:a 1, :b 2, :c 3} (into #{:a} #{:b :c}) ;=> #{:c :b :a} The "into" function pours the contents of the second collection into the first collection, returning a collection of the same type as the first argument. That being said, I agree with Alex and James in this rather lengthy discussion. Clojure is unique among the Lisps in that it moved beyond having linked lists as the only first class data structure. Prior to Clojure, if you worked in a Lisp like Scheme or Common Lisp, you would design your program around the creation, traversal, and manipulation of linked lists using higher order functions and explicit recursions. The standard library in both languages is heavily focused on these list-related operations. After developing the initial version of your program, if you found that it was too slow or used too much memory, the accepted practice was to profile your application to identify the functions that were getting hammered the most and were using up the majority of your computing resources. You would then often end up rewriting those function bodies in an imperative fashion using loops and mutable data structures (i.e., arrays and hashtables). The "wisdom" here was that this would enable you to "first make it right, then make it fast". If even further performance was required from your program, you might then rewrite part of your program in C, build a foreign function interface (FFI) to link the C code into your Lisp program, and go from there. These were the Bad Old Days of Lisp(TM). What was IMHO quite possibly Rich's greatest contribution in the design of Clojure to the Lisp world was his decision to make additional data structures first class citizens of the language. Most importantly, he did so by creating Clojure's vectors, maps, and sets to be immutable, persistent, performant, recursively constructed, and representable as data literals. This was already a wonderful improvement over previous Lisps, but it created a new problem: How could we enjoy the pure delight of list-oriented programming that Lisp had always offered us now that the data structure space had been fragmented? A famous quote from Alan Perlis is a popular gem in the Lisp world, and it goes like so: "It is better to have 100 functions operate on one data structure than to have 10 functions operate on 10 data structures." Every Lisp had always satisfied this by simply giving programmers only one first class data structure to use: the linked list. As I already mentioned, the bulk of its standard library would then be built around list manipulation functions. Clojure needed a way to preserve this unified style of programming while still providing a collection of performant data structures for real-world programming. So how did Rich accomplish this? He created the "sequence abstraction". A sequence in Clojure serves a similar role to the linked list of previous Lisps in that it unifies the API for interacting with all of Clojure's first class data structures (list, vector, map, set). By calling the function "seq" on any data structure, you are given a list-like view of that collection that allows you to traverse it from beginning to end one element at a time and to add new elements to the beginning of it. These operations are called "first", "rest", and "cons", and they behave precisely as you would expect them to if you were calling them on a linked list. By using seq throughout the Clojure sequence library (i.e., the set of standard library functions responsible for creating, traversing, transforming, and manipulating sequences), Clojure is able to have single implementations of all of the common Lispy higher order list transformation functions. For example, we have "map", "filter", "reduce", "iterate", "take", "drop", "repeat", "cycle", and so on. The amazing thing is that these can all take any of Clojure's data structures as their inputs. So you can call map on a list, vector, map, or set without having to change the function signature. Without the sequence abstraction, we could need multiple functions for every data structure we wanted to support (e.g., map-list, map-vec, map-hash, map-set, filter-list, filter-vec, filter-hash, filter-set). This is precisely the kind of combinatorial explosion of the function space the Alan Perlis was warning us about. The tradeoff is that each of these higher order functions will then return a new sequence as its output. While this prints to the REPL like a list, please note that a sequence is not a list (except when it
Re: Complete Web Development Setup Using Clojure CLI Tools
Thanks, Chad. I have built quite a few toy and production full-stack Clojure web apps over the past 6 years or so using leiningen and boot. While both of these are great tools with a lot of programmer hours invested in them, I realized recently that neither of them are particularly easy to explain to a novice Clojure programmer, particularly when you are using them to configure a full stack web development environment. Since I hadn't yet tried doing any web dev with the Clojure CLI tools, this seemed like a good test project to get my feet wet. Despite the seemingly stripped-down set of options available in deps.edn (just :paths, :deps, and :aliases), it turned out that the :aliases feature really provides all you need to bootstrap a wide variety of build tasks directly into the clojure command. What I really like best about this approach is that I can now introduce new programmers to Clojure using command line conventions that they are likely already familiar with coming from many other popular languages like perl, python, ruby, or node. So now I can just type: ``` $ clojure ``` and get a REPL. Or I could type: ``` $ clojure script.clj ``` and I'm running a simple single-file Clojure program. If I need something more complicated, I can just define an alias for a build task a la carte and type: ``` $ clojure -A:my-task ``` Because taking this approach makes Clojure development look almost identical to building a program in any of the other languages I mentioned (and many more that I didn't), it makes the tooling very "easy" (in the Rich sense) for newbies that I need to train in our company. And when I want to play power-programmer, I get to have fun just cranking out new aliases for adventure and profit! And hey, if you've read along this far, here's a free alias for you to play with or modify to suit your needs: ``` :minify-css {:extra-deps {asset-minifier {:mvn/version "0.2.5"}} :main-opts ["-e" "(use,'asset-minifier.core),(minify-css,\"resources/public/css/style.css\",\"resources/public/css/style.min.css\")"]} ``` Have fun and happy hacking! Gary -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: Complete Web Development Setup Using Clojure CLI Tools
For those of you playing along at home, you may have noticed that there were two bugs in the code I presented above. I have since fixed those issues in the Gitlab repository that I linked to in my previous post. If you didn't just grab the repository, here are the fixes for you to add manually to your setups: Fix 1: Corrected deps.edn {:paths ["src/clj" "src/cljs" "resources"] :deps {org.clojure/clojure {:mvn/version "1.9.0"} org.clojure/clojurescript {:mvn/version "1.10.312"} ring {:mvn/version "1.7.0-RC1"} ring/ring-defaults{:mvn/version "0.3.2"} prone {:mvn/version "1.6.0"} compojure {:mvn/version "1.6.1"} hiccup{:mvn/version "1.0.5"} reagent {:mvn/version "0.8.1"}} :aliases {:run{:main-opts ["-m" "my-project.server"]} :cljsbuild {:main-opts ["-m" "cljs.main" "-co" "cljsbuild.edn" "-c"]} :figwheel {:extra-deps {org.clojure/tools.nrepl {:mvn/version "0.2.13"} cider/cider-nrepl {:mvn/version "0.17.0"} com.cemerick/piggieback {:mvn/version "0.2.2"} figwheel-sidecar{:mvn/version "0.5.14"}} :main-opts ["-e" "(use,'figwheel-sidecar.repl-api),(start-figwheel!)"]}}} The issue was that leaving src/cljs out of the :paths vector and adding it with :extra-paths in the :cljsbuild alias had left the :figwheel alias unable to load CLJS files at the CLJS REPL that it spawns. The above code corrects this problem. Fix 2: Corrected views.clj (ns my-project.views (:require [hiccup.page :refer [html5 include-css include-js]])) (defn render-page [] (html5 [:head [:title "My Project"] [:meta {:charset "utf-8"}] [:meta {:name "viewport" :content "width=device-width, initial-scale=1" }] (include-css "/css/style.css") (include-js "/cljs/app.js")] [:body [:div#app] [:script {:type "text/javascript"} "my_project.client.mount_root();"]])) In my initial post, I accidentally left out a closing square bracket in the render-page function. This block of code adds it back in. Okay, folks. That's it for now. Once again, you can just grab the corrected template from this Gitlab link if you are so inclined: https://gitlab.com/lambdatronic/clojure-webapp-template Over and out, Gary -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: Complete Web Development Setup Using Clojure CLI Tools
Hi again, folks. Just to make it easier for everyone to use this template right away, I put all these files into a public git repository on Gitlab. Here's the URL: https://gitlab.com/lambdatronic/clojure-webapp-template Happy hacking! ~Gary -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Complete Web Development Setup Using Clojure CLI Tools
Howdy Clojurians, I recently started developing a new Clojure+Clojurescript web application, and I wanted to see if I could set up my development environment using just the Clojure CLI tools. After a good deal of digging around through tutorials on a number of different websites and a fair amount of experimenting, I've managed to create a very simple (IMHO) configuration that provides me with both development and production mode CLJS->JS compilation, development and production mode ring handlers, and the always delightful FIgwheel development environment all from just the simple "clojure" command. Since I haven't seen this before, I thought I'd share it with all of you in case it helps someone else out there who doesn't need (or want) all of leiningen or boot to develop a simple web app. Here goes: Step 1: Create your project structure like so: ├── cljsbuild.edn ├── deps.edn ├── figwheel.edn ├── resources │ └── public │ ├── cljs │ ├── css │ │ ├── style.css │ ├── images │ └── js ├── src │ ├── clj │ │ └── my_project │ │ ├── handler.clj │ │ ├── server.clj │ │ ├── views.clj │ └── cljs │ └── my_project │ ├── client.cljs Step 2: Make the deps.edn file (replace :deps and my-project.server namespace as necessary for your project) {:paths ["src/clj" "resources"] :deps {org.clojure/clojure {:mvn/version "1.9.0"} org.clojure/clojurescript {:mvn/version "1.10.312"} ring {:mvn/version "1.7.0-RC1"} ring/ring-defaults{:mvn/version "0.3.2"} prone {:mvn/version "1.6.0"} compojure {:mvn/version "1.6.1"} hiccup{:mvn/version "1.0.5"} reagent {:mvn/version "0.8.1"}} :aliases {:run{:main-opts ["-m" "my-project.server"]} :cljsbuild {:extra-paths ["src/cljs"] :main-opts ["-m" "cljs.main" "-co" "cljsbuild.edn" "-c"]} :figwheel {:extra-deps {org.clojure/tools.nrepl {:mvn/version "0.2.13"} cider/cider-nrepl {:mvn/version "0.17.0"} com.cemerick/piggieback {:mvn/version "0.2.2"} figwheel-sidecar{:mvn/version "0.5.14"}} :main-opts ["-e" "(use,'figwheel-sidecar.repl-api),(start-figwheel!)"]}}} Step 3: Make the cljsbuild.edn file (replace :main for your project) {:main "my-project.client" :output-dir"resources/public/cljs" :output-to "resources/public/cljs/app.js" :source-map"resources/public/cljs/app.js.map" :optimizations :advanced :pretty-print false} Step 4: Make the figwheel.edn file (replace :ring-handler, :on-jsload, and :main for your project) {:nrepl-port 7000 :nrepl-middleware ["cider.nrepl/cider-middleware" "cemerick.piggieback/wrap-cljs-repl"] :server-port 3000 :ring-handler my-project.handler/development-app :http-server-root "public" :css-dirs ["resources/public/css"] :builds [{:id "dev" :source-paths ["src/cljs"] :figwheel {:on-jsload "my-project.client/mount-root"} :compiler {:main "my-project.client" :output-dir"resources/public/cljs/out" :output-to "resources/public/cljs/app.js" :asset-path"/cljs/out" :source-maptrue :optimizations :none :pretty-print true}}]} Step 5: Write server.clj (ns my-project.server (:require [ring.adapter.jetty :refer [run-jetty]] [my-project.handler :refer [development-app production-app]]) (:gen-class)) (defonce server (atom nil)) (defn start-server! [& [port mode]] (reset! server (run-jetty (case mode "dev" #'development-app "prod" #'production-app #'production-app) {:port (if port (Integer/parseInt port) 3000) :join? false}))) (defn stop-server! [] (when @server (.stop @server) (reset! server nil))) (def -main start-server!) Step 6: Write handler.clj (ns my-project.handler (:require [ring.middleware.defaults :refer [wrap-defaults site-defaults]] [ring.middleware.reload :refer [wrap-reload]] [prone.middleware :refer [wrap-exceptions]] [compojure.core :refer [defroutes GET]] [compojure.route :refer [not-found]] [my-project.views :refer [render-page]])) (defroutes routes (GET "/" [] (render-page)) (not-found "Not Found")) (def development-app (wrap-reload (wrap-exceptions (wrap-defaults #'routes site-defaults (def production-app (wrap-defaults #'routes site-defaults)) Step
Re: Anyone spent time with Kawa Scheme?
If you haven't given it a try yet, Clojurescript is really the goto for a lot of Clojure programmers when it comes to cover the CLI and Android use cases. Lumo and Planck are awesome Clojurescript runtimes that start up virtually instantaneously and make great choices for writing scripts. Clojurescript + React Native can create apps for Android, iOS and Windows. Have fun and happy hacking! Gary -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: Writing a text adventure in Clojure
Hi Will, Welcome to the wide world of functional programming, where data flows, and functions transmute without destroying their inputs. As some others in this thread have already suggested, a general approach to viewing any problem space from a functional perspective is to imagine your problem as a pipeline of data transformations from start to finish. To the greatest extent possible, try to represent your data transformations as pure functions over immutable arguments rather than holding any global state in a var and mutating it at each time step. In the context of a game program, consider depicting all of your game state as a single hierarchical map. Then thread this map through each function and return a new derived map as each output result. ```clojure (def world-state {:flags #{} :location :fancy-room :inventory #{:sledgehammer :car-keys :lamp} :rooms {:creepy-corridor {:name "Creepy Corridor" :description "Whoa! Spooky..." :items #{:halloween-mask :monkeys-paw :troll-doll}} :fancy-room {:name "Fancy Room" :description "The fanciest!" :items #{:chandelier :toy-poodle :looking-glass}} ...}}) ``` Let's imagine this is the initial world state. When your application starts up, it enters into the game loop (which would be a nice, friendly recursion, of course). In each round of the game loop, you call a sequence of functions to get the description of the current room, print it out, ask the user for the next command, process that command, and then recurse back to the top of the next iteration of the game loop. Although printing to stdout and reading from stdin are obviously side effecting functions, you should be able to keep your functions for retrieving the room description and processing the user's command as pure functions of the current world-state. Just make sure that the functions that process a user's command always return a new copy of the world-state value. When you want to save the game, just write out the world-state to an EDN file. By reading it back in again later, you can restore the game to exactly the same state it was in before. In response to your specific question about having a different room description after some event has happened, consider this approach: ```clojure (defn do-important-plot-changing-action [world-state] (-> world-state (update :flags conj :major-plot-point-reached) (assoc-in [:rooms :fancy-room :description] "Gosh! This room isn't nearly as fancy anymore!"))) ``` That is, the function just uses assoc, assoc-in, update, and update-in to modify the values in the new map and return it for use in future iterations of the game loop. And that's pretty much all there is to it. You just pass the changing world state down through the stack rather than mutating it in place on the heap. (Ultimately, the world-state data structure is, of course, actually stored on the heap, and you are just passing references to it through the stack, but I hope you get my meaning here.) Good luck and happy hacking! -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: Loop causing OutOfMemoryError: GC overhead limit exceeded ?
As Daniel pointed out, this could probably be done more idiomatically (and functionally) using sequence functions. Here is a quick shot at a rewrite without any atoms or mutable state in the same number of lines of code (18) as your original example. If some of the intermediate lazy sequences cause any noticeable performance slow-down, you could switch over to transducers pretty easily. (defn find-db-records-seq [db min-time max-time] (->> min-time (iterate #(plus-minutes % 30)) (take-while #(before? % max-time)) (partition 2 1 [max-time]) (reduce (fn [{:keys [num-processed records]} [min-t max-t]] (let [results (jdbc/query db ["select id, a, b, c from sometable where t > ? and t <= ? order by t" min-t max-t])] {:num-processed (+ num-processed (count results)) :records (into records (mapcat (fn [rows] (let [foo (make-foo rows)] (->> rows (filter (fn [{:keys [a b ]}] (relevant-record? foo a b))) (map (fn [{:keys [id a b c]}] {:id id :a a :d (compute-d a b c)}) (partition-all 200 results)))})) {:num-processed 0 :records []}))) Happy hacking! Gary -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: idiomatic way of counting loop iteration
Almost right. The iterate function is an infinite sequence generator, so (count (iterate f x)) will never return. If you want the iteration to terminate when cond is false (as in your original example), you're looking for this: (count (take-while cond (iterate (fn [[a b]] ... [new-a new-b]) [init-a init -b]))) Happy hacking! -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: How to do functional programming
A shell script written in a procedural style (e.g. with Bash or equivalent shell language) will frequently start out by declaring some global variables, then perform some conditional checks (if then else), throw in a few loops (for, while), and ultimately end up with some new values in those initially declared variables that you use as your program's output. If you are feeling particularly intrepid, you might factor out some repetitive operations into separate subroutines defined higher up in the file and then call them as necessary in those aforementioned conditional blocks and loops. The mental model behind this type of programming is the Universal Turing Machine. Your variables are some internal state that the program instructions are reading and writing, reading and writing, writing and reading until you get to the last instruction that returns some subset of the final variable values. The driving principle is that computation is accomplished by the free mutation of state. A program written in a functional style (e.g. with any Lisp, one of the MLs, Haskell, Clean, etc) begins with a chunk of data, which may either be hard-coded, input from the outside world, or generated internally with a function like "range" or "rand". This piece of data may or may not be stored in one or more global variables. However (and this is HUGE however), these are not generally mutated over the life of the program. That is to say, they are constants. More often than not, you won't even store the initial data in a global variable but will just feed it into a function that processes it and spits out some new data, which is then fed to another function that performs some other processing operation and again spits out some new data. Ultimately, the data that you produce is passed through an arbitrarily long pipeline of functions until the final result is produced and returned by the program. In practice, these function calls are rarely linear and are much more likely to form a branching call tree. But ultimately, the relevant branches of this tree will be traversed and executed in a depth first manner (unless lazy evaluation inserts its magic to reorder some of that computation behind the scenes) and you still get to a final output returned by the last function fall evaluated. The mental model behind this type of programming is Lambda Calculus. There is no mutable state anywhere in a pure functional program, and instead the intermediate results are passed through the call stack from function to function. In practice, because stack sizes are limited, most values passed between functions will be boxed references pointing to memory locations on the heap. However, as far as the functional programmer is concerned, there is no heap and there is no mutable state. Immutable values simply flow seamlessly from one function to the next until the program has finished. The driving principle is that computation is accomplished by transforming data through mapping a set of immutable inputs to an immutable output. Think f(x,y) = z. In order to accomplish this stateless pipeline of data transformations, functions much possess a property called "referential transparency". This means that a function must be able to calculate its outputs deterministically using only its inputs AND without modifying any of its inputs in the process. This property is preserved even when global variables are referenced within the body of a function as long as the values associated with those global variables are constants throughout the lifetime of the program. In practice, very few languages (outside of Haskell) actually try to be completely pure and allow no mutation of state whatsoever. Clojure opts to make all data immutable by default, but provides some special language features (refs, atoms, agents, volatiles) that you can use if you really do want to write an algorithm that involves some mutable state. Unless there is a performance bottleneck (as in numerical computing) or no other sensible way to model the domain (as in some web applications), making use of these features for mutable state is generally frowned upon. When they are really necessary and valuable, however, Clojure's language tools for accomplishing mutation are wonderful because they carefully protect it against concurrency clashes in multi-threated environments. To approach writing a functional program, first think about how to model the computation as a series of data transformations. Then build your program from the bottom up (prototyping and testing it in the REPL) by writing small, referentially transparent functions that describe the lower level operations that you will need. Then build higher level functions on top of those that build up your abstractions in a layer cake style until you reach your entry point function that either takes input data from the outside world or generates it internally and then starts the
Re: [ANN] leaflet-gorilla 0.1.2 released with GeoJSON support
I've been using PostGIS extensively at work for the past year or so and used it intermittently before then. To really get the most out of the system, I would strongly recommend grabbing a copy of PostGIS in Action, 2nd Edition by Regina O. Obe. I feel like I went from a casual user to a power user in one read-through. Happy hacking, ~Gary -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [ANN] leaflet-gorilla 0.1.2 released with GeoJSON support
Absolutely awesome! Finally, an easy-to-use renderer for PostGIS queries. Well done! -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: clojure, not the go to for data science
Please stop. The amount of misinformation you are spreading about Emacs on this mailing list is deeply irresponsible and belies a very clear lack of understanding about how this software works. All of your concerns about internationalization (supported), accessibility to text readers (emacspeak), resource limits (full system utilization), and compatibility with modern hardware, operating systems, and window managers (GTK interface) are unfounded. As it has been noted numerous times already by others, this thread is about Clojure and data science, not about your dislike of the Emacs user interface. Some people (such as myself) prefer a text-mode interface driven by keybindings over a mouse-driven graphical interface. That is an aesthetic and productivity-based choice. Please respect your fellow programmers and go write some software rather than continuing this diatribe. -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: Sum up second elemsts of pairs in a sequence by grouping by the first item in pair
Sometimes, all you need is the proper reduce formulation: (reduce (fn [m [k v]] (assoc m k (+ (m k 0) v))) {} keyvals) -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: Current best-of-breed JDBC libraries?
I actually prefer yesql for most of my Clojure-SQL interaction. Since a significant portion of my job involves me writing and optimizing SQL queries, I like being able to seamlessly switch between psql, org-babel's sql mode, and yesql with a simple cut and paste operation. For extra emacs sexiness, check out the yesql-ghosts package in MELPA. This automatically inserts all of the imported function signatures (as defns) as a text overlay below any (defqueries ...) form when a clojure buffer is in cider-mode. Keep on hackin' in the free world, ~Gary On Tuesday, February 24, 2015 at 9:04:36 AM UTC-5, Colin Yates wrote: Hi all, What are you all using for interacting with an RDBMS? In the past I looked at clojure.java.jdbc, honeysql and korma (and for querying, honeysql just rocks). I have lost touch a bit - any recommendations? Thanks. -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: CIDER vs Org Mode: Symbol's definition is void: nrepl-send-string-sync (workaround)
I've been using the following patch for quite some time now, and it works reasonably well. The table generation is pretty suboptimal though, so if anyone has an better version, I'd love to see it. (defun org-babel-execute:clojure (body params) Execute a block of Clojure code with Babel. (require 'cider) (let ((result (cider-eval-and-get-value (org-babel-expand-body:clojure body params))) (result-params (cdr (assoc :result-params params (org-babel-result-cond result-params result (condition-case nil (org-babel-script-escape result) (error result) -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: Is still idiomatic the ant simulation code?
Hi Yu, This is a pretty dense (and IMHO non-idiomatic) piece of Clojure code. Without reading the paste you provided, I can at least tell you what appears to be happening here, given Clojure's evaluation semantics: 1. The [move ...] expression creates a vector of three functions. 2. The [(if ...)] expression creates a vector of three values (presumably numeric) resulting from calls to the ranks function. 3. The (wrand ...) form calls wrand on the ranks vector to presumably produce an integer index into the [move ...] vector. 4. The [move ...] vector is called on wrand's result, which should return one of the three functions it contains. 5. The function returned from step 4 is called on loc. Happy hacking, ~Gary -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: futures and atoms and bears, oh my!
Looking at this code without further knowledge of the strategy function, my first guess is simply that your strategy function may not be returning a result which satisfies the valid-move? and legal-move? predicates thus throwing you into an infinite loop. Possibly the printf is being suppressed within the swap! operation, but some testing would be required to see if this is the case generally. The other obvious potential for a hiccup would be if all-directions is somehow growing with each iteration of make-move, thus preventing idx from ever exceeding its length. Not knowing what is going on inside all these functions makes this a rather tricky bit of guess work at best. Anyway, I'd try running get-move from the repl to see how likely it is to get stuck in an infinite loop. Good luck, ~Gary -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [ANN] clj-generators - generator magic inspired by Python
Gotcha. By all means then, hack away. ;-) -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: non-lazy clojure?
Fair enough. Fortunately, Clojure provides so many different tools to select from in creating you perfect recipe. ;-) I'm glad to hear that reducers ultimately provided you with some benefits over your previous concurrency approach. The one thing that seems rather odd to me though is that your group-size is 1. I'm presuming that the function you're r/mapping must take a substantial amount of time and resources for that to be efficient. Have you experimented with larger group sizes to avoid too much thread swapping? ~Gary -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [ANN] clj-generators - generator magic inspired by Python
What new features does this syntax provide over the existing infinite sequence generators? - lazy-seq - iterate - repeat - repeatedly - range I realize you provided a simple example for clarity, but perhaps you could illustrate something more complex that couldn't be done with the above functions easily. For example, the case you provided could be written as follows: (take 5 (iterate inc 1)) Thanks, ~Gary -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: non-lazy clojure?
Hey Lee, (vec ...) is NOT the same as (into [] ...) in this case. Whenever you use a reducing function, like r/map, r/filter, r/mapcat, and so on, you are not, in fact, performing any computations on the collection to which you apply it. These functions simply wrap the collection with a kind of delayed operation that will later be triggered by applying reduce to it. So, if I have a collection called samples, and I run (r/map inc samples), I just get a reducible object back. Same thing with a chain of these functions as in (r/filter odd? (r/map inc samples)). I just get back a reducible object (which itself is wrapping another reducible object). When you run reduce on this whole thing, each of the delayed operations are combined together into one giant reduce function, as if you had written something like this: (reduce + (r/filter odd? (r/map inc samples))) = (reduce (fn [sum sample] (let [sample' (inc sample)] (if (odd? sample') (+ sample' sum) sum))) 0 samples) This is the reason that you need to use (into [] ...) rather than (vec ...). Running vec on a reducible object will just throw a RuntimeException. When you use into, you will be applying reduce (since that's how it is implemented), and as long as you use into with a vector, map, or set, it will be run using transients for efficiency. Uses transients: (into [] (r/map inc (range 10))) (into {} (r/map #(vector % 0) (range 10))) (into #{}| (r/map inc (range 10))) Doesn't use transients (but still works). Note that the list will have been reversed because of the nature of list consing: (into () (r/map inc (range 10))) Alright, hopefully that's enough from me for now. Good luck with your program. ~Gary -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: non-lazy clojure?
Hey Lee, answers below. Also make sure to read my other post at 12:59pm today regarding the behavior of vec vs. into for reducible collections. On Wednesday, June 4, 2014 12:51:45 PM UTC-4, Lee wrote: Some quick notes and a question from my first look into this: - I watched a Rich Hickey reducers video, was riveted, and see that they are beautiful. I particularly appreciated his brief aside about how lazy seqs have independent utility. - In practice, for the little program I posted about previously, switching to reducers involved a couple of initially unexpected complications, some of now make sense to me but others of which don't fully: results of reducers sometimes have to be explicitly converted, e.g. with into []; r/map doesn't take multiple collections; I don't immediately see elegant reducer-based approaches to uses of for or repeat, etc. It's true that the library does have these limitations. You could, of course, just implement a for-like macro that uses the reducing operations under the hood. Easier (but less readable) is to just convert your for into the equivalent r/map and r/filter operations. When using repeat, make sure the result sequence will be finite and call vec on it directly. Then you can apply the reducing functions to it and still have a foldable collection. - My initial swapping of clojure.core.reducers functions for lazy seq (and agent-based parallel computing) functions seems to make my performance worse rather than better. I realize that there are several possible explanations for this and I have to look at my usage more carefully. It's definitely possible that I'm doing more than one thing wrong, but one question that this leads to is: Hard to say why this would be without seeing your code, but the first thing that comes to mind is that if you aren't calling fold or foldcat anywhere, then you won't be getting any parallelization from using reducers. So maybe your performance decrease is because you're now running single-threaded. - If I operate on a vector with a sequence of r/map and r/filter operations and finally with into [] to get back a vector, then I think that fold will be called within the call to into, and that parallelism should happen there... right? But if that's right, how do I control the group size that the call to fold uses in this case? I see how to specify the group size for a direct call to fold, but not for other function in the library. No, fold will not be called in into. The definition of into uses reduce, which is single-threaded. What you want is one of the following two formulations: (fold group-size cat append! foldable-collection) ;; if you want to specify the group size (foldcat foldable-collection) ;; if you are happy with the default 512 group size In both cases, the foldable-collection is just one of your (r/map f (r/filter p? initial-collection)) forms. For it to be foldable though, initial-collection needs to be a vector, map, or set (i.e., a tree-like collection). I hope that helps. ~Gary Thanks, -Lee -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: non-lazy clojure?
Hey Lee, I would second Jozef's suggestion that you look into using the reducers library when you need non-lazy sequence operations. Although a major motivation of Rich's work was clearly to enable easy parallel folding via fork/join, the fold function is only one of many in this library. Think instead that the main (philosophical) purpose of reducers is to decomplect the reducing operation from the data representation it is acting on. And of course, since reduce can be used to implement (virtually) any non-lazy sequence operation, it stands to reason that reducers should be fully capable of providing new implementations of many of these functions on top of reduce (which it does). Importantly, whenever you will be chaining sequence operations together, reducers should be more efficient than both the lazy sequence functions (e.g., map, filter) and the eager vector-returning functions (e.g., mapv, filterv). This is because a chain of reducing functions generate no intermediate representations. obligatory contrived example For example, let's say I wanted to sum the squares of all the even numbers in a sequence called samples. Using lazy functions: (reduce + (map #(* % %) (filter even? samples))) Using non-lazy functions (reduce + (mapv #(* % %) (filterv even? samples))) Using reducers (aliased as r): (reduce + (r/map #(* % %) (r/filter even? samples))) /obligatory contrived example If you need to collect the results of a sequence operation in a data structure rather than reducing them to an atomic value, simply use into rather than reduce (since into uses reduce under the hood). So to collect the squares of all the even numbers in the samples sequence, just do this: (into [] (r/map #(* % %) (r/filter even? samples))) As just one sample point, when I updated a statistical fire analysis algorithm that I wrote from using the lazy sequence functions to using the reducers library, I experience a full order of magnitude speedup. This sped up my runtime from ~6 hours to around 20 minutes. So please do yourself a favor and give this library a close look. It has made worlds of difference for some of my work. Good luck, ~Gary -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: Remote function calls / simple distributed computation
Check out Tim Baldridge's Hermod library: https://github.com/halgari/com.tbaldridge.hermod It's a very lightweight system that lets you create mailboxes (which listen on ports) on each of your independent JVMs. Then you can pass messages between them using core.async. This should give you most of the tools that you need to create arbitrarily complex coordination frameworks on top of it. Happy hacking! ~Gary On Sunday, May 25, 2014 12:30:19 PM UTC-4, David James wrote: What are the ways to do remote function calls with Clojure? Here is a *low-level list* I have so far: * Java Remote Method Invocation API: http://docs.oracle.com/javase/7/docs/technotes/guides/rmi/index.html * nREPL: https://github.com/clojure/tools.nrepl There are *higher-level tools*, too, such as: * Slacker https://github.com/sunng87/slacker What else should I add to the lists? Here is my goal. I'm exploring various ways to do distributed computation. Many distributed computation platforms (e.g. Storm, Hadoop) require (1) significant dev-ops setup (2) deployment via a JAR file (3) quite a bit of time lag to get things started. I was hoping to find lighter-weight, more responsive, ways to do distributed computation. I also consider this a learning exercise. I like PigPen's use of a custom `pmap` function to distributes work: https://github.com/Netflix/PigPen (But it requires Pig and Hadoop) It could be nifty to have a `pmap` that worked, say, over a set of machines connected via nREPL. Has this already been done? Thanks! -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [Axiom-developer] Heidegger, literate programming, and communication
Hi folks, I suspect I'm the Gary that Tim thought he was referring to since I've posted on several of his other LP-related threads (though not this one until now). I'm reading along and enjoying the back and forth as usual, but I'm sorry to say that I don't have much to add to this philosophical swordfight. As I've stated on other threads, I find LP quite useful to me, both in helping me remember later what my old code does (and WHY I wrote it that way in the first place) as well as helping me to write clearer and more parsimonious code in the first place (since I don't want to document a crazy web of unnecessary complexity if I can avoid it). All in all, my personal LP journey has been an interesting and reasonably productive one. And of course, using an expressive functional language like Clojure does allow me to keep my code snippets shorter and more isolated from one another. All good things for LP as well. I know that Tim likes to poke the mailing list occasionally and remind people that LP is the bee's knees and that they should really get on board with it. I also know that without fail one or more folks will quickly respond that LP doesn't provide enough value above docstrings, inline comments, autogenerated API docs, and the occasional blog post to invest the necessary time in developing new LP-mindful workflows. And, of course, someone will inevitably chime in with the rally cry clear code doesn't need documentation. I understand that really embracing LP does require relearning how to program in several fundamental respects, AND it makes it quite difficult to use many of the developer tools many folks in the Clojure community have come to rely on. This makes the task appear somewhere between challenging and onerous to many programmers (or so I would imagine from following Tim's threads over the past year). However, (speaking only for myself here) I think the maintenance benefits often outweigh the upfront investment for any piece of software I intend to keep around for more than a few months. So for me, it's a net good. For some folks it's not. I get that. Enough said. But really, at the end of the day, I'm just getting tired of listening to people razzing on LP for the reasons listed above. There ARE good tools out there for doing this kind of programming. People just have to invest time and energy into learning them. I regularly cite Emacs' Org-mode as providing most everything you might need to comfortably create LP programs without even writing one line of LaTeX or XML (if you're allergic to those languages). Obviously, as Tim points out, it's an almost trivial assignment to roll your own tangle and weave scripts in whatever language you like (and I've tried that route too). So guys, if you don't like the ideas behind LP or just feel like it is too much of a hassle to use, then I completely understand that you don't want to use it. But could we maybe call a truce on this mailing list on the topic? Perhaps instead of constantly being pulled into philosophical arguments, those of us who actually do enjoy exploring LP could then use this forum to discuss amongst ourselves what tools or references we are finding useful in our journey. Clearly some folks (Gregg included) are churning out some pretty neat looking tools to make LP easier to do in the Clojure world. I for one would love to see more lively discussion around that and not feel like we're just bear-baiting whenever we mention the forbidden paradigm of Literate Programming. My 2c, ~ (the actual) Gary -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [Axiom-developer] Heidegger, literate programming, and communication
On Thursday, May 22, 2014 6:20:39 PM UTC-4, Mars0i wrote: On Thursday, May 22, 2014 4:05:58 PM UTC-5, Gary Johnson wrote: Hi folks, I suspect I'm the Gary that Tim thought he was referring to since I've posted on several of his other LP-related threads (though not this one until now). I cede the name Gary to Gary. No worries. You can be Gary too if you'd like. It's a passable name, all things considered. ;-) But really, at the end of the day, I'm just getting tired of listening to people razzing on LP for the reasons listed above. For my part, I have never intended to criticize LP per se. When it sounds as if someone is arguing that everyone should use LP all the time (or something similar), I sometimes object. Hey, point taken. I'm certainly not out to force LP on anyone. I'm just here to soak up advice from the folks who have been using it for awhile. I'm happy keeping the kool-aid to myself, so to speak. :-P -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: Joy of Clojure question
Bridget and Guru are both right about the reason that \3 is found at position 13 in the string. However, the code you typed isn't valid Clojure, since the pos function expects pred to be a function of v. Thus, your pos call would need to look like this: (pos #(= % \3) :a 4 :b 1 :c 3 :d 4) = (13) ;; note that pos returns a list of all indeces matching pred Alternatively, you could have defined pos to simply perform equality matching on its first argument like so: (defn pos [val coll] (for [[i v] (index coll) :when (= val v)] i)) (pos \3 :a 4 :b 1 :c 3 :d 4) = (13) -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: Rethinking Literate Programming
Emacs org-mode provides a markdown-like language, which can be organized into a foldable outline (e.g., chapters, sections, subsections, subsubsections). Syntax is provided for headers, ordered/unordered lists, tables, inline images/figures, hyperlinks, footnotes, and (most importantly for LP) code blocks. In order to avoid having to scroll up and down forever to see your code spread through the document, you simply use TAB to fold/unfold the outline sections your are currently interested in. Pressing C-c ' within any code block automatically switches to Emacs' major mode for that language, showing only the code in its own temporary buffer. When you want to see all of your code at once, just tangle the document to a *.clj file and look at it in another buffer. Using auto-refresh on the tangled buffer provides an easy way to keep checking code changes in this way with minimal effort. When you are ready to weave the document into a nicely readable format, org-mode provides output filters to auto-generate latex articles, html webpages, OpenDocument files, latex beamer presentations, and quite a few others as well. This is just meant to clarify some of the LP-related features of this platform. Obviously, some emacs lisp hacking can extend it to do whatever else people want. -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: Rethinking Literate Programming
puzzler and Tim, Well said, gentlemen. As someone who has been using LP heavily for the past two years, I have certainly reaped many if not most of the benefits regularly argued in its favor (and of course, I've wrestled with all the usual tooling issues as well). While I agree with puzzler that many programmers probably don't write sufficiently novel software that would benefit from an LP style, quite a few of us do. In my case, much of my programming is aimed at environmental research, developing models and algorithms for describing and predicting natural processes and human interactions with them. In order for my work to be accepted and used for decision making (usually around land planning), it is absolutely crucial that I can transparently explain all the formulas used, literature cited, and conceptual steps taken to get from empirically measured data to modelled outputs. A literate programming style not only helps me to organize my thoughts better (both hierarchically and sequentially), but it provides me with a living (tangled) document that I can share with my non-programmer colleagues to get their domain-specific feedback about my choice of model assumptions, formulas, etc. This enables a level of collaboration that I simply could not achieve if I simply wrote the code directly. Finally, as a thoroughly unexpected side effect, some of my most complicated programs actually became much, much shorter when I rewrote them in an LP style (in terms of lines of code, of course). Part of this had to do with the available tooling (Org-mode's polyglot literate programming and reproducible research facilities are outstanding) and part of it simply came from having to write down my ideas in English first. This kept me from rushing into writing code and possibly getting lost in those collapsing tunnels to which Tim alluded. Instead, the additional hammock time that I took to think my way through how to present my solutions frequently led to Aha! moments in which I realized a simpler way to express the problem. Cliche, I know, but still results are results. Get Literate! (use only as necessary; LP may not be recommended for some patients due to increased blood pressure and carpal tunnel risk) ~Gary On Thursday, May 8, 2014 8:57:51 AM UTC-4, Gregg Reynolds wrote: The thread on documentation that Val started ( https://groups.google.com/forum/?hl=en#!topic/clojure/oh_bWL9_jI0) is getting a little long so I'm starting a related one specific to litprog. I've made a start on rethinking LP at https://github.com/mobileink/codegenres/wiki/Rethinking-Literate-Programming . A few key points: * Knuth's main early LP tool (WEB) was to a certain extent an attempt to fix deficiencies in Pascal, as Knuth himself explicitly acknowledged. Some aspects of Knuthian LP (KLP) may make sense for imperative languages with side effects; since it's hard to reason about programs written in such languages, added commentary is needed. But if you already know that functions are side-effect free and data are immutable, you no longer need that. * Programming language design has not evolved in the direction of LP, as we might have expected from some of Knuth's more grandiose pronouncements; instead they have evolved in the direction of greater expressivity, which obviates the need for many kinds of documentation. You can argue that LP was a fine thing in its day, but the world has moved on. * KLP is largely based on the personal aesthetic and psychological preferences of DE Knuth involving issues such as the proper order and mode of presentation of code. Those are normative issues, and there is no reason to take Knuth's preferences as gospel. In particular there is no justification for his claim that using LP methods leads to better code. It not only depends on what better means, it depends on what other methods are available. Just because writing Pascal in LP was better (for Knuth et al.) than writing plain Pascal does not mean this will always be the case in all languages. It doesn't generalize. (To a hammer, everything looks like a goto.) * There is (demonstrably) no reason to think that there is any natural or best order of presentation for code; there are only preferences, and everybody has one, if you catch my drift. The point again being that Knuth was not on to some kind of laws of programming. KLP is all about his preferred style, not about the Way Things Are. * KLP is sometimes contrasted with self-documenting code To get a grip on what that is and what we can expect from it we need to examine the notions of function, algorithm, and code. Then it looks like code does not in fact self-document, if documentation is taken to mean explanation. But it does express meaning, and sometimes expressivity is preferrable to explanation. Maybe that's terminological nit-picking, but sometimes coming up with the
Re: Reduce vs. Comp
Reduce is indeed a swiss-army knife for functional programming over sequences. Of course, in this particular case (i.e., apply a sequence of functions in order to an initial value), Clojure's threading operators are the idiomatic way to go. (- 6 (+ 12) (* -1)) Cheers, ~Gary -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: Concurrency, Parallelism, and State. And Zombies.
Great job on such a tricky chapter. I particularly enjoyed the hilarious examples in the spirit of Learn You a Haskell for Great Good. ~Gary On Wednesday, March 26, 2014 9:45:38 AM UTC-4, Daniel Higginbotham wrote: I've added a new chapter to Clojure for the Brave and True, Concurrency, Parallelism, and State. And Zombieshttp://www.braveclojure.com/concurrency/. Here's an excerpt: === In this chapter you'll learn what concurrency and parallelism are and why they matter. You'll learn about the challenges you'll face when writing parallel programs and about how Clojure's design helps to mitigate them. Finally, you'll learn a big boatload of tools and techniques for writing parallel programs yourself, including: futures, promises, delays, atoms, refs, vars, pmap, and core.reducers. Also, there will be zombies. === I hope you all find it useful and entertaining :) Daniel -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: Academy Award goes to a literate program
Awesome! Thanks for sharing the link, Tim. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: A ClojureScript Tutorial For Light Table Users
Great job, David. Looking very sharp! ~Gary -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: [ANN] Yesql 0.3.0 - Clojure SQL queries rethought.
defqueries for the win! Excellent minimal syntax choice, Kris. I'm using yesql in my current work project, and it's been a real delight to work with thus far. Being able to put multiple queries in one file just makes it that much sweeter. ~Gary On Tuesday, January 7, 2014 10:57:55 AM UTC-5, Kris Jenkins wrote: Yesql is a simple library for blending SQL queries Clojure together, cleanly. Here's how it workshttps://github.com/krisajenkins/yesql#rationale, and how to use it https://github.com/krisajenkins/yesql#example-usage. Project: https://github.com/krisajenkins/yesql Leiningen: [yesql 0.3.0] New since v0.2.x: Support for multiple queries in a single file. Feedback welcomed, Kris -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: [ClojureScript] Re: AnNN: ClojureScript 0.0-2120
Thanks, Tim. I somehow missed Brandon's exposition earlier in the thread. These features look great. Fantastic job, ClojureScript devs! -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: cider status
Just to inject another sample into the population: As another hacker who lives in Emacs, I found the nrepl - cider transition to be quite painless. It took me maybe an hour of reading the website docs, installing/uninstalling packages with package.el, and updating the relevant sections of my .emacs.d/init.el file. Not to poo-poo on anyone's parade, but it really did seem pretty straightforward to me. So maybe some of the pain points people are feeling have to do with general challenges with configuring Emacs rather than specific problems with following the online cider docs. As a final note, ac-nrepl is documented on the cider page as working with cider. The nrepl-ritz package incompatibility is the only real issue missing from the docs. On the other hand, it's come up repeatedly on this mailing list, so at least some of us are likely to be aware of it at this point. ~Gary On Friday, December 13, 2013 4:04:08 PM UTC-5, Bozhidar Batsov wrote: On Friday, December 13, 2013 at 7:17 PM, Sean Corfield wrote: On Thu, Dec 12, 2013 at 11:43 PM, Adrian Mowat adrian...@gmail.comjavascript: wrote: Is cider just a new release of nrepl.el or a different thing entirely? Well, it's a new release insofar as it's an updated version of nrepl.el. In order to switch to it, however, you have to remove nrepl.el _and all packages that depend on it_ (which packages are not specified in the upgrade instructions so that would be a hit'n'miss process) If someone is not clear it should be improved. I can’t know what problems people encounter is they don’t tell me. cider has both an issue tracker and it’s own mailing list. , then you install cider.el and then you also have to update various parts of .emac.d/init.el depending on how you had customized nrepl. And that part isn't really described in the upgrade instructions either so that's also pretty hit'n'miss. All configuration options are documented in the README, so I’d say updating the init.el is an easy task. And then you have to reinstall newer versions of the packages you deleted that depended on nrepl.el and hope you get versions that depend on cider.el instead (since there's no way of telling, based solely on their package description I suspect). The list of package dependencies is more informative than a package's name. And if you use Ritz, that hasn't been updated so you have to stay with nrepl.el anyway. Frankly, I think it was a mistake to rename it and rename various functions in it, forcing breakage on dependent packages (which have not changed their names as far as I can tell). You’re thinking short term, but you should be thinking long term. Nobody will remember this transition is a few months. I’m confident that in the greater scheme of things the rename was a good solution. I use ac-nrepl and the latest version still says it is for nrepl so I've no idea whether it will work with cider. I also use nrepl-ritz ac-nrepl supports only cider. but I could live without it. My nrepl-related init.el file contains: https://www.refheap.com/21729 and it's not clear how that would need changing and whether it would continue to work properly. Your eval-in-repl function is obsolete, since similar functionality lives in cider itself. I have no idea why you’re modifying clojure-mode’s keymap when you should be modifying cider-mode’s keymap instead (+ set-ns is bound to a keycombo by default). Consulting the Changelog would reveal that `nrepl-mode` is now named `cider-repl-mode` and `nrepl-interaction-mode` is now `cider-mode` (it’s basically the same in SLIME). The migration is really simple and I think that people are blowing this problem out of proportion. Of course, I basically live in Emacs, so this is obviously affecting my POV. Less experienced Emacs users might find even simple changes challenging. And this isn't just for me - my team all has the same base configuration of Emacs and so we'd have to go thru this switch process for each team member. As I said previously - if you’re not certain about something you should stop by either cider’s google group or the GitHub project. :-) -- Sean A Corfield -- (904) 302-SEAN An Architect's View -- http://corfield.org/ World Singles, LLC. -- http://worldsingles.com/ Perfection is the enemy of the good. -- Gustave Flaubert, French realist novelist (1821-1880) -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clo...@googlegroups.com javascript: Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+u...@googlegroups.com javascript: For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to a topic in the Google Groups Clojure
Re: AnNN: ClojureScript 0.0-2120
Wait a minute... #js data literal support added Holy $#%^!!! Where is this documented?! MUST...USE...NOW! -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: [ANN] Major update of modern-cljs
+1 to Bastien's comment. Your tutorials are by far the best introduction to web programming in Clojure and Clojurescript on the web. Thank you so much for keeping these up to date so that we can all benefit from them. ~Gary -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: ANN: Clojure High Performance Programming
This looks incredible! Just bought a copy. Congratulations, Shantanu! -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: [ANN] Yesql 0.2.1 - Clojure SQL queries rethought.
Hi Kris, I really like your approach, but I've also been feeling the burn a bit with having to store each SQL query in its own file (especially since my data exploration frequently leaves me cataloging hundreds of them). Take a look at the approach used in sql-phrasebook: https://github.com/ray1729/sql-phrasebook I'm hoping it will give you some ideas to extend Yesql to address this particular issue, ideally with a nicer syntax than that used in sql-phrasebook. Otherwise, I think Yesql is bound for great things! Cheers, ~Gary On Tuesday, November 12, 2013 5:14:14 AM UTC-5, Kris Jenkins wrote: It depends on which kind of composability you mean. If we're talking about a SELECT ... FROM ... here with a WHERE ... there, I don't see why not. It's a down-the-road feature, but I'm open to it. But the kind of composability that would get me excited is the cascalog/datalog kind. Where you could say, SELECT * FROM employee and mix that with SELECT * FROM deparment and get an automatic, sensibly-optimised join. That's real composibility, beyond mere string concatenation. No, I don't see Yesql ever supporting that. (There again, I haven't seen it from any of the Clojure-SQL-DSLs either. If you have, please point me to them. I'd be interested!) Cheers, Kris On Tuesday, 12 November 2013 03:35:46 UTC, John Hume wrote: For me, the one feature that can justify an internal DSL for generating SQL is the ability to compose queries. I assume that's not on the Yesql roadmap. On Nov 11, 2013 5:10 AM, Kris Jenkins krisaj...@gmail.com wrote: https://github.com/krisajenkins/yesql Yesql is a simple library for blending SQL Clojure together, cleanly. Here's how it works https://github.com/krisajenkins/yesql#rationale, and how to use it https://github.com/krisajenkins/yesql#example-usage. Feedback welcomed, Kris -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clo...@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+u...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+u...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Clojure for the Brave and True, an online book for beginners
Looks pretty solid. Great work so far. Also +1 for the Emacs coverage. Despite the fact that our surveys still show the majority of Clojure users develop in Emacs, this mailing list frequently exhibits an anything-but-Emacs tone. By all means add links to other editors for folks who are already using something else, but I for one think you made a smart choice there. Better to learn Emacs now than to learn it later after trying two or three other editors that don't quite cut it. Also, just a quick note, your Emacs search keybindings were incorrect in that chapter. C-s and C-r are just regular isearch-forward and isearch-backward. Regexp search keybindings (isearch-forward-regexp and isearch-backward-regexp) are C-M-s and C-M-r respectively. Over and out, ~Gary On Wednesday, September 4, 2013 12:24:15 PM UTC-4, Dima Sabanin wrote: Hi Daniel, Keep up the great work! I really enjoyed the material and how it's presented. Thanks, Dima On Mon, Sep 2, 2013 at 11:35 AM, Daniel Higginbotham nonrec...@gmail.comjavascript: wrote: Hi all, I've been putting together http://www.braveclojure.com/ and would love feedback. I've tried to make it entertaining and super beginner-friendly. Thanks! Daniel -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clo...@googlegroups.comjavascript: Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+u...@googlegroups.com javascript: For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+u...@googlegroups.com javascript:. For more options, visit https://groups.google.com/groups/opt_out. -- Best regards, Dima Sabanin http://twitter.com/dimasabanin -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Story
Tim, I'm with you 100% on the mind-blowing greatness of literate programming, but I do have to correct you on org-babel. It is actually a very nicely done LP development system. You write your content as you would a book or article, using sections and subsections, paragraphs, ordered and unordered lists, tables, embedded images, links, and so on. Code is placed within specially delimited blocks that specify the source language (thus triggering the appropriate emacs mode for syntax highlighting) as well as special rules for code and output export. Obviously, code blocks can (and should be) out of order in the Org document so as to enable clear exposition. When you are ready to test out the finished product, org-babel provides built in tangle and weave commands. I used your homebrew solution on axiom-developer.org a few years ago when I was first getting my feet wet with literate programming. However, org-babel provides several unique advantage IMHO over make+tangle.lisp+latex: 1. Org markup is much simpler and more visually recognizable than LaTeX although anything you can do with LaTeX, you can do in Org mode. This is because you can export an Org file to LaTeX and Org markup syntax allows for inline LaTeX code blocks if you want to do anything that is not already supported by the standard markup. 2. Org mode can export my Literate Program to many, many different formats with a simple keystroke. These include (but are not limited to) HTML, LaTeX, ASCII, and LibreOffice ODF. Thus my woven program can be distributed as a PDF file, Word Document, or webpage. 3. Org mode supports multiple programming languages within a single file. This allows me to chain together in the same document (and thus in the same exposition) a shell script written in Bash, a Python script for generating a graph, and a Clojure program for running a webserver. When I trigger the tangle procedure, each language's code is written out to its own file(s) and run through the correct interpreter or compiler. Amazingly, code blocks in different languages can even be annotated such that they pass values between one another like functions in a Lisp environment. 4. Org supports Live Code Evaluation. By simply placing my cursor (the point in Emacs jargon) within any code block in my Literate Program and pressing C-c C-c, Emacs will trigger an external shell for that language, recursively expand any code block references included within the selected code block (i.e., a local tangling procedure), send the expanded code to the external shell (be it an interpreter or compiler), evalutate the result, and pretty print this result into my LP file in an annotated RESULT block directly after the code block that I evaluated. If I tweak the code and reevaluate it, the RESULT block's contents are updated in place. This provides an in-document multi-language REPL-like experience. Note, of course, that the contents of these RESULT blocks may then be optionally woven into my formatted output, which is particularly useful in explaining the behavior of code with examples or in automatically generating tables or figures for illustrative purposes. There are many more features that Org mode supports that would take...well, the entire Org mode manual to explain. However, these LP features are really quite useful, and I do genuinely think more people interested in LP should give them a try. For more information, please check out the Babel section of the Org Mode manual: http://orgmode.org/worg/org-contrib/babel/intro.html I also HIGHLY recommend the 2012 journal article published on Org Mode's Babel features in the Journal of Statistical Software: *A Multi-Language Computing Environment for Literate Programming and Reproducible Research* by Eric Schulte, Dan Davison, Thomas Dye, Carsten Dominik http://www.jstatsoft.org/v46/i03 As you like to say, Tim... Get Literate! ~Gary On Wednesday, August 7, 2013 8:36:51 PM UTC-4, da...@axiom-developer.org wrote: Recently, I discovered the story literate programming tool for Clojure, which I prefer to marginalia: https://github.com/jedahu/story ... (snip) ... I had never heard of story, but ran across a mention of it while looking through the issues on marginalia's github site, so I decided to give it a try. It's similar to marginalia, in that it's not true literate programming -- it doesn't let you freely order your comments and code irrespective of how they appear in the final files, but is a tool for extracting long comments written in markdown in order to weave some sort of narrative explanation of why the code is written the way it is. The ability to freely order comments and code is actually vital to the idea of literate programming. The key idea is writing to communicate ideas to another person. This almost certainly involves reordering and restructuring code. The machinery
Re: Story
Again. I'm with you on this one, Tim. Fear not. You aren't the only crazy Clojure programmer putting the LP bug in people's ears. I must say, your work on creating a literate version of the Clojure source was really amazing. Any plans for maintaining it in the future as new Clojure releases keep rolling out? ~Gary On Thursday, August 8, 2013 12:00:26 PM UTC-4, da...@axiom-developer.org wrote: I'm with you 100% on the mind-blowing greatness of literate programming, Actually, it's not the technology of literate programming I'm on about. Rich Hickey comes up with marvelous and insightful ideas and reduces them to practice, like his work on reasonable big-O data structures or his work on software transactional memory. Or his work on ... Yet if you look at the code you see nothing. Which means that the next set of people who get to slice-and-dice the code after Rich will miss some of the insight and get it wrong. I've seen it happen in many places. The apprentice is rarely as good as the master. Not to cast stones at the rest of the Clojure group, I'm just using hasty-generalization, my favorite form of reasoning, from my experience. I find that literate programming is the only way to capture the insight and keep it where it belongs, adjacent and intermixed with the code, but written for humans-to-human communication. Clojure is heavy with great ideas and they need to be communicated intact. Tim Daly -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Story
I'm concerned that the ability to freely order comments and code will not interact well with Clojure's namespaces. With Clojure's namespaces, you can have things with the same name in two different namespaces. Functions local to a namespace are referred to in one way, whereas you need some sort of prefix to refer to one in a different namespace. These prefixes are often aliases, and the aliases may vary from one context to another, for example, in one namespace I may refer to clojure.string as `str` and in another namespace I may refer to it as `string`. snip How do you deal with this lack of context when you present your code in a way that is completely unrelated to the namespace organization of your files? Well, my experience thus far has led me down two different roads here. Sometimes, I follow the path you came to on your own, which is to use one section or chapter per namespace. Within that section/chapter I can reorganize my code into whatever order lends itself to the clearest explanation. Because I use org-babel, it can export each namespace section to its own file during the tangling process. It's straightforward to run the program through the REPL or leiningen at that point. The other approach that I have tried a few times now is to simply throw out the whole namespace construct entirely. After all, namespaces in functional programming mostly serve as simply a tool for collecting together functions and global vars that work together to accomplish some shared goal. If I am working on a literate program, it seems very natural for me to simply use sections/chapters to organize my functions by their purpose. The namespace then just becomes an unnecessary build construct. That is, I just tell org-babel to tangle the entire codebase to a single .clj file. Simple. Actually it isn't really a change in workflow but a change in mindset. Literate programming is not documentation, they are different ideas. Here's why I called it a change in workflow -- please correct me if I'm mistaken: Every time the subject of literate programming comes up, I ask one simple question: When you get a stacktrace, is the file/line number information correct? A year or two back when I asked this, you elaborated that for you, this was mostly a non-issue. You said you developed your code by sending over one tiny code block at a time to the REPL, rather than sending a whole file over, and you never used any debugging facilities. I consider that a change in workflow. I'm in the same boat with Tim. I try to test my functions one at a time through the REPL if possible. Whenever I have to make several modifications to different parts of the program at once, then I'll just re-evaluate the file and resume testing it one piece at a time. It is true that the stacktraces don't tend to get the file/line numbers right, but since Clojure stacktraces are good at naming the function where the error occured, I rarely find that to be an issue that C-s or C-r (isearch-forward/backward) can't solve in an instant. For Clojure specific efforts see http://daly.axiom-developer.org/clojure.pdf (PDF) http://daly.axiom-developer.org/clojure.pamphlet (source) This is a great example of using literate programming to document a program that is complete and stable. Have you successfully used literate programming in a program that is rapidly evolving? I have developed a rather large fire simulation toolkit using the LP model, and it was...interesting. Prior to that, I had only created shortish programs that were mostly just helping me to get my feet wet with the concepts and workflows of literate programming. When I worked on the fire program though, I ran into several new hurdles and successes. The benefit of LP was (not surprisingly) that my design errors really jumped right out at me when I tried to explain them in English. Previously, I had started hacking together this program in the usual non-LP way, but I started to get stuck in some of the messy statistical details. I backed up and started over using LP, and my code's organization really came together beautifully in a matter of a couple of days of hacking. The downside unfortunately was that I had never written a literate program at that scale before, and lacking Tim's 42 years of experience, I wasted a lot of time just trying to figure out basic code organization things like the ones you are asking in this thread: How do I deal with these namespace imports? What is the best way to organize toplevel chunk references? Should they be sequential or hierarchical? Can org-babel support multiple code blocks with the same name in the same way that Tim's tangle.lisp program does? (Hint: the answer is no) Why does tangling work with swank-clojure+SLIME but not with NREPL? (I had to patch that) How do I get org-mode to communicate with the Clojure REPL? (Note: it's documented :session
Re: changing a value in a vector of maps
Here's the code analogue of your find-assoc-in function for the approach Cedric is proposing. I actually came to the same solution before reading the responses to your post, so it's good to see that others also think this is a more memory efficient approach (obviously for larger vectors than the example). (defn my-find-assoc-in [[test-key update-key] [test-val update-val] mapvec] (reduce (fn [v idx] (if (= (get-in v [idx test-key]) test-val) (assoc-in v [idx update-key] update-val) v)) mapvec (range (count mapvec Happy hacking, ~Gary -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: -- macro proposal
Ugh. What a pointless thread. Someone could have just said: --- It's already in clojure 1.5. The form you are looking for is called as-. Your original example would be written like this: (as- 3 x (+ 1 x 4) (prn answer: x)) --- Done. Yeesh. On Sunday, July 14, 2013 12:34:02 PM UTC-4, Jeremy Heiler wrote: On Sat, Jul 13, 2013 at 9:08 PM, Daniel Dinnyes dinn...@gmail.comjavascript: wrote: Just made a quick search on `main arguments` on both Google and Wikipedia. Do you mean the arguments in `public static void main (String[] args)`? If not please provide some definition what do you mean by main arguments. Else the point is meaningless. He means the arguments you are threading. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: matching, assigning and branching in one form
The condp form is very nice and concise if you have multiple match clauses. If you are more generally just looking to perform a single match/assign/branch task, I'd recommend this little nugget of clojure wisdom: Forget ye not the hidden might of if-let. (if-let [[_ from to message] (re-find #^:(.*?)!.*PRIVMSG (.*) :(.*) msg)] (true-branch) (false-branch)) If you use an expression that returns a sequence with if-let, just wrap it in a call to seq, like so: (if-let [[a b c d] (seq (filter anything-good? some-coll))] (true-branch) (false-branch)) Happy hacking, ~Gary On Friday, June 21, 2013 11:43:50 AM UTC-4, Steven Arnold wrote: Hi, I am writing a simple IRC bot, pretty much just for fun, starting with a simple implementation originally posted by Nurullah Akkaya on his blog. It already does what it's supposed to, which is message a fortune from mod-fortune (shelling out) when someone asks it to. However, there's a bit of code I don't like. It looks like this: (cond (re-find #^:(.*?)!.*PRIVMSG (.*) :(.*) msg) (let [[_ from to message] (re-find #^:(.*?)!.*PRIVMSG (.*) :(.*) msg)] [...logic omitted...] What's happening is we're looking for a PRIVMSG, and if we find one, we scan the message again and pull out the chunks we're interested in, and use them in the logic part below. The problem is I don't like maintaining two regular expressions. I wish I could use it only once, and therefore change it only once if it needs to be modified. I'd prefer to see an expression that looks like this (for example): (cond (if-matched #^:(.*?)!.*PRIVMSG (.*) :(.*) msg [from to message] (true form) (optional false form))) The if-matched acts as a let block while pulling out groups and assigning to local variables at the same time. Also, it ignores the first match of re-find, which is the entire expression -- not generally useful to me. Maybe if-matched-groups would ignore the overall expression, and if-matched would include it. I suppose a macro might be the way to go to accomplish this, but I wonder if there are any Clojure tricks that could accomplish this short of a macro. Also, do any fellow Clojurians think a macro like this is a bad idea in general? Would you suggest taking a different tack to solve this problem? Thanks in advance! steven -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Need to render some entities moving across a grid
Hi there, I have an IMO fairly straightforward method for doing this that I wrote for use in my own flow modelling code. The idea is that you create a matrix (vector of vectors in my case) containing refs all initialized to some base value (e.g., 0). Then I wrap my with-animation macro around a call to the toplevel simulation function which will manipulate those refs internally. with-animation will spawn a JFrame that shows the matrix with a green (low) to red (high) color ramp with an automatically adjusting legend along the bottom. The image of the matrix is refreshed by its own thread once every *animation-sleep-ms*. All the drawing and refreshing code is available in a namespace within one of my own projects that I haven't yet broken into its own library, but I suppose I could do that easily enough if this approach sounded useful to you. Right now you can see the code I am talking about here: https://github.com/lambdatronic/clj-span/blob/master/src/clj_span/gui.clj You would just pull in that namespace and the ones it depends on (feel free to copy them from my project or make the whole thing a dependency of your code). Then you would call it like so: (with-animation :numbers 0.0 matrix1 matrix2 (run-my-simulation matrix1 matrix2)) The idea is that run-my-simulation (your code) will manipulate the refs in these two different matrices, and then with-animation (my code) will render them in two panels side-by-side with matching legends and color ramps, so you can see their differences. I had built it this way because I needed to compare flow results under two different scenarios and only wanted to run the simulation once with both scenarios happening in parallel. If you just needed to show a single matrix, it should be pretty obvious what to comment out of the with-animation macro. Good luck and happy hacking, ~Gary On Monday, June 17, 2013 3:17:01 AM UTC-4, vemv wrote: I'm implementing a program D. Hofstadter describes in *Fluid Concepts: * https://github.com/vemv/jumbo/* *Even in the original text, concurrency/parallelism is a crucial part of the domain so Clojure is super well-suited. While visualising the carried-in process is not a goal of the project, providing a rendering of the 'entities' of the modelled world would help a lot explaining my program to others (which I have to). The thing is - I haven't ever done significant graphics programming - I don't know e.g. what libraries to use, how to create smooth movements, keep the code high-level... and sadly I don't have a lot of time in my hands. Would anyone knowledgeable in the matter mind coding a quick-and-dirty solution for me? I could buy you a couple books in exchange hahaha. You'd have exactly one week, and I of course would provide all needed information/feedback. Feel free to reply here or contact me at vemv [at] vemv [dot] net. Thanks for your time! -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Macro for bailout-style programming
+1 for some- and some-. I use this all the time in my coding. They used to be -? and -? in clojure.core.incubator, so I'm extremely happy that they finally made their way into core proper. On Saturday, March 23, 2013 7:25:00 PM UTC-4, Evan Gamble wrote: The let? macro addresses such situations: https://github.com/egamble/let-else -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Clojure 1.5 print-table, org-mode babel, and org-mode HTML gen
+1 for org-babel. I put together an example project solving the Potter Kata on github several months ago, so if someone is looking for some examples of how you might do LP with org-babel, take a look at it here: https://github.com/lambdatronic/org-babel-example Happy hacking, ~Gary On Sunday, March 3, 2013 6:03:51 PM UTC-5, greg r wrote: Here's a little project I worked on: https://github.com/Greg-R/incanterchartcustom I'm just now learning git, so I hope the files are intact in the repository. I cloned to another machine and they appear to be OK. The Incanter chart PDF document shows what is possible with regard to documenting code and showing a nice export result. The repository also includes the source .org file. In theory, if you have everything set up correctly you can reproduce the PDF document exactly. Since it is generating PDF charts, there are lots of side-effects and whatever directory you are running in will get filled up with the chart files. I used LaTeX snippets within the org file to include the chart graphics in the exported tex file and thus the eventual PDF. I don't use C-c C-e p. This doesn't always work, and I prefer C-c C-e l which exports the .tex file only. I open the .tex file with the Texworks application which has worked really well for me for editing LaTeX documents. Texworks has the ability to jump between the PDF and the .tex file and vice-versa, which makes troubleshooting much easier. I did a bunch of data processing for work using org, Clojure, and Incanter to produce reports in PDF. I created several Leiningen projects to attack various aspects of the data manipulation. Then within Clojure code blocks in org, the various namespaces are used to process data at the appropriate points in the document. None of the output was inserted directly into the org file. That turned out to be impractical as some of the generated documents were hundreds of pages long. The Clojure/Incanter code chunks generated .tex files which were included in the exported output via LaTeX code blocks. Really in this case the org-babel system operated more as a document/code organizer than as a programming system. But what an organizer it is!!! I saved hundreds, maybe thousands of man hours of manual document generating. There were several technologies to learn to get it all to work in harmony: Clojure Incanter Emacs (24.2) (including some Elisp in the .emacs file) org babel Leiningen LaTeX Texworks nrepl (this will require some extra stuff in the .emacs file to get babel to work) It took a lot of work, but I think the org-babel system is really worth it! Regards, Greg On Saturday, March 2, 2013 11:52:07 PM UTC-5, Mark C wrote: Worked like a charm. Thanks! Babel is fun. I really like the idea of being able to code in multiple languages in one document - and have return values from one feed another. And I just found out you can include TeX too - just starting to play with that. I'd love to hear more about how you use clojure and org mode together. Mark -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: screencast: friend and creating a login form
Fantastic job! I wish something like this had been available when I built my first website with Friend. I ended up rolling my own workflows after giving up on tracking all the internals of interactive-form. ~Gary On Tuesday, January 29, 2013 3:55:13 PM UTC-5, Nelson Morris wrote: I've released a screencast on friend and using its interactive-form workflow to create a login form. http://www.clojurewebdevelopment.com/videos/friend-interactive-form I've got more in various stages of completion, so I'd be interested in hearing feedback. Thanks, Nelson Morris -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: [ANN] nrepl.el 0.1.6 released
Huzzah! The uphill climb continues apace! On Tuesday, January 29, 2013 10:07:54 PM UTC-5, Tim King wrote: I am pleased to announce that nrepl.el v0.1.6 has been released, and is now available on marmalade. Preview versions of the next release are available on Melpa. See the Readme on github (https://github.com/kingtim/nrepl.el) for installation and usage instructions. Notable changes since our last release: - Ported SLIME macroexpansion mode (see README for full documentation) - Updated macroexpansion to use pprint with code-dispatch - Eldoc argument highlighting - Simplify popup buffer quit/restore using `quit-window'. - Add nrepl-disconnected-hook and disable nrepl when disconnected. - Emit server log output at bottom of *nrepl-server* buffer. (Brian Rowe) - Reset nrepl-buffer-ns on nrepl-restart. Fixes issue #187. - Implement nrepl-mode as a derived mode. (Bozhidar Batsov) - fix #194 - stacktrace buffer was not respecting nrepl-popup-stacktraces (Bozhidar Batsov) - Get key bindings documentation into the minor mode descriptions (Ivan Necas) - Fix message formatting for results containing % (fixes issue #195). - Fix NPE in nrepl-jump (issue #124). (cola-zero) - Fix nrepl to work with fish shell (issue #192). (Dario Bertini) - Adjusted the javadoc keybinding and mentioned it in the README. (Bozhidar Batsov) - made the TAB command in the nrepl-mode buffers configurable (Bozhidar Batsov) - Added convenience function to report the version of nREPL in use. (fogus) - Fix issue #163 - exclude ns from nrepl-load-file. - Ignore killed and hangup events in sentinel (Chris Bilson) - Shift-Home and Shift-Ctrl-a in repl, which select just the user input when on the input line. (Ivan Kozik) - Clear the correct region when replacing the input line. (Ivan Kozik) - Fix issue #146. Include @ in nrepl-input-complete-p. - Handle stdout messages that arrive after status done - Various and sundry bug fixes and documentation additions and updates. Many thanks to all the contributed their time and energy by reporting issues, submitting patches and testing out bug fixes and features. Enjoy! Cheers, Tim -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: emacs - how to wean me off the family of Java IDEs
There's a MELPA package (use `M-x package-list-packages') called sr-speedbar that displays the speedbar in the same frame you are already working in. I just stick sr-speedbar-toggle on F11 and call it a day. YMMV. On Wednesday, January 16, 2013 1:45:35 PM UTC-5, Sean Corfield wrote: On Wed, Jan 16, 2013 at 8:33 AM, Amirouche Boubekki amirouche...@gmail.com javascript: wrote: - is there a decent project explorer. I really miss the tree on the left, editor on the right layout speedbar: «C-X speedbar» M-x speedbar - but that looks very interesting, thank you! It's kinda funky in full-screen mode on Mac OS X but it does satisfy the project explorer itch. -- Sean A Corfield -- (904) 302-SEAN An Architect's View -- http://corfield.org/ World Singles, LLC. -- http://worldsingles.com/ Perfection is the enemy of the good. -- Gustave Flaubert, French realist novelist (1821-1880) -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: ANN: bouncer, validation library for clojure
Right, I was testing against 1.5.0-RC1 and 1.5.0-RC2. Same problem occurred both times. I should have reported that in my initial bug report. Sorry about that. Also, thanks for the quick turnaround. I'll pull it and test it out. ~Gary On Monday, January 14, 2013 7:16:29 PM UTC-5, Leonardo Borges wrote: Sean pointed me to it in the other thread. I read the ticket and discussion - I personally don't feel it's abuse. To me it feels as natural a use of destructuring as any other. just my 2c. Leonardo Borges www.leonardoborges.com On Tue, Jan 15, 2013 at 11:14 AM, Toby Crawley to...@tcrawley.orgjavascript: wrote: This issue has already been reported and filed: http://dev.clojure.org/jira/browse/CLJ-1140 There's been some discussion around that issue on clojure-dev@ as to whether this is a regression or an abuse of destructuring. Leonardo Borges writes: Alright so the bug appears in Clojure 1.5.0-RC1 - I'm not sure whether this is a regression or intended behaviour so I'll send a separate email to the list about that. -- Toby Crawley http://immutant.org | http://torquebox.org -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clo...@googlegroups.comjavascript: Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+u...@googlegroups.com javascript: For more options, visit this group at http://groups.google.com/group/clojure?hl=en -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: ANN: bouncer, validation library for clojure
Worked like a charm. Thanks. On Tuesday, January 15, 2013 12:33:26 PM UTC-5, Gary Johnson wrote: Right, I was testing against 1.5.0-RC1 and 1.5.0-RC2. Same problem occurred both times. I should have reported that in my initial bug report. Sorry about that. Also, thanks for the quick turnaround. I'll pull it and test it out. ~Gary On Monday, January 14, 2013 7:16:29 PM UTC-5, Leonardo Borges wrote: Sean pointed me to it in the other thread. I read the ticket and discussion - I personally don't feel it's abuse. To me it feels as natural a use of destructuring as any other. just my 2c. Leonardo Borges www.leonardoborges.com On Tue, Jan 15, 2013 at 11:14 AM, Toby Crawley to...@tcrawley.orgwrote: This issue has already been reported and filed: http://dev.clojure.org/jira/browse/CLJ-1140 There's been some discussion around that issue on clojure-dev@ as to whether this is a regression or an abuse of destructuring. Leonardo Borges writes: Alright so the bug appears in Clojure 1.5.0-RC1 - I'm not sure whether this is a regression or intended behaviour so I'll send a separate email to the list about that. -- Toby Crawley http://immutant.org | http://torquebox.org -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clo...@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+u...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: ANN: bouncer, validation library for clojure
Hey Leonardo, There's a critical bug in 0.2.2-RC1 in the bouncers.core/wrap function. An IllegalArgumentException is triggered whenever a validator is not passed an explicit :message field. It looks like this was introduced in the process of trying to allow validators to take an arbitrary number of input args (a very good thing IMO). Here's a minimum case for replicating this error at your repl: (let [{:keys [message] :or {message foo}} '()] message) IllegalArgumentException No value supplied for key: null clojure.lang.PersistentHashMap.create (PersistentHashMap.java:77) This is being triggered in your wrap function when you apply map destructuring to the right-hand result of (split-with (complement keyword?) args). Anyway, here is a patched version of wrap that should fix the problem. FWIW, I also fixed the docstring typo erros - errors. (defn wrap Wraps pred in the context of validating a single value - `acc` is the map being validated - `pred` is a validator - `k`the path to the value to be validated in the associative structure acc - `args` any extra args to pred It only runs pred if: - the validator is optional *and* there is a non-nil value to be validated (this information is read from pred's metadata) - there are no previous errors for the given path Returns `acc` augmented with a namespace qualified ::errors keyword [acc [pred k args]] (let [pred (h/resolve-or-same pred) k (if (vector? k) k [k]) error-path (cons ::errors k) {:keys [default-message-format optional]} (meta pred) [args message-kv] (split-with (complement keyword?) args) message (get (apply hash-map message-kv) :message default-message-format) pred-subject (get-in acc k)] (if (or (and optional (nil? pred-subject)) (not (empty? (get-in acc error-path))) (apply pred pred-subject args)) acc (update-in acc error-path #(conj % (format message (name (peek k Cheers, ~Gary On Sunday, January 13, 2013 8:03:36 PM UTC-5, Leonardo Borges wrote: Thanks, really appreciate the kind words. I just pushed [bouncer 0.2.2-RC1] so feel free to give that a go :) Cheers, Leo Leonardo Borges www.leonardoborges.com On Fri, Jan 11, 2013 at 3:44 PM, faenvie fanny@gmx.de javascript:wrote: i took a look at it. bouncers DSL seems smart inside and out. Has an excellent Documentation too. Thanks for sharing it. -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clo...@googlegroups.comjavascript: Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+u...@googlegroups.com javascript: For more options, visit this group at http://groups.google.com/group/clojure?hl=en -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: ANN: bouncer, validation library for clojure
Thanks for releasing this library. I've written quite a few large command-line driven applications in Clojure thus far, and each one has used a slightly different homegrown approach as different core functionality became available (and the contrib libs kept mutating). Your state monad inspired approach definitely clicks with me, and I'll be looking forward to your future releases. Also, I agree with Stathis that there is a problem including the errors map in the original data structure under an unqualified keyword. Of course, if you change validate to not modify the input map that is being validated, then you no longer need a state monad to model the validation workflow. This could just as easily be done with a simple reduce. In this instance, I'd guess that just qualifying the ::errors keyword would probably stick closest to your original model. Maybe I'm totally missing the mark here though. Additionally, one thing that bit me when using validate with multiple tests was that there's no early exit strategy. For example, imagine I have written a test like the following: (def config-params {:input-dir some/directory/path :output-dir some/other/directory/path}) (defvalidator directory {:default-message-format %s must be a valid directory :optional false} [path] (.isDirectory ^File (clojure.java.io/file path))) (defvalidator readable {:default-message-format %s is not readable :optional false} [path] (.canRead ^File (clojure.java.io/file path))) (defvalidator writeable {:default-message-format %s is not writeable :optional false} [path] (.canRead ^File (clojure.java.io/file path))) (validate config-params :input-dir [required directory readable] :output-dir [required directory writeable]) The problem that I run into is that if for some reason :input-dir or :output-dir are not defined in config-params, then I get a NullPointException when .isDirectory is called in the directory validator. I can, of course, dodge this bullet by setting :optional true in the directory, readable, and writeable validators. However, as evidenced by the required validator's presence in my test vectors, I actually do want these fields to be present and to pass all tests. So the semantics sort of look a bit off to me in this instance. Another case that perhaps illustrates my point a little more clearly is this one: (defvalidator 10 {:default-message-format %s must be less than 10 :optional false} [x] ( x 10)) (validate {:foo I'm a string, but I should be a number} :foo [required number 10]) Here, I obviously get this exception: ClassCastException java.lang.String cannot be cast to java.lang.Number clojure.lang.Numbers.lt Again, my problem is that since number fails, I would like 10 to never be called. The :optional flag can't help me here because it only disables validators in the case of a nil input. So basically what I'm suggesting as an enhancement to your library is that whenever a field is being tested with a multi-validator vector, the first test to fail should prevent any other tests (to its right in the vector) from running. This would be similar in spirit to the behavior of the -? and -? thread-maybe macros in clojure.core.incubator. Okay, constructive criticism and all that aside, great work on this library again. Looking forward to the next release soon. ~Gary On Wednesday, January 9, 2013 4:24:14 PM UTC-5, Leonardo Borges wrote: Stathis, That's a very good point. I've been thinking about the usefulness of returning the errors map in the original map since the errors map itself is returned as the first element in the call to 'validate'. To be honest I'm tempted to remove that with the next release, making validate return a single value: the errors map. I'm happy for you to argue otherwise though. Do you think having the qualified keywords in the original map is still useful? I'll be releasing a new version over the weekend that will include this change. Thanks for the feedback Leonardo Borges www.leonardoborges.com On Jan 10, 2013 7:08 AM, Stathis Sideris sid...@gmail.com javascript: wrote: Hey Leonardo, This is very interesting, but I'd like to know whether it's possible to validate a map that contains an :errors key. Would bouncer overwrite this with its own :errors key? Should it not be using a fully-qualified keyword (as in ::errors) to avoid the clash? Thanks, Stathis On Friday, 4 January 2013 06:56:19 UTC, Leonardo Borges wrote: Hey guys, I extracted a small validation library from a side project I'm working on and bouncer is the result. While I do know there are a couple of validation libs out there already, I decided this was worth publishing mostly because: - That’s what I’m using in my current side project - It takes a fundamentally different implementation approach that is in itself worthy of exploration - If nothing else, this is yet another example of where Monads
Re: abysmal multicore performance, especially on AMD processors
Lee, My reading of this thread is not quite as pessimistic as yours. Here is my synthesis for the practical application developer in Clojure from reading and re-reading all of the posts above. Marshall and Cameron, please feel free to correct me if I screw anything up here royally. ;-) When running code in parallel, the fastest to slowest ways to allocate memory via Clojure (of those examined above) are: 1. Java array 2. Java linked list 3. conj onto a transient vector 4. cons onto a list 5. conj onto a vector 6. DO NOT conj onto a list EVER!!! And that's pretty much all there is to it until Marshall figures out how to hack the JVM to overcome this very subtle JIT deoptimization bug relating to polymorphic conj calls on Cons and PersistentList types. Good luck, ~Gary On Tuesday, December 11, 2012 10:37:50 AM UTC-5, Lee wrote: On Dec 11, 2012, at 4:37 AM, Marshall Bockrath-Vandegrift wrote: I’m not sure what the next steps are. Open a bug on the JVM? This is something one can attempt to circumvent on a case-by-case basis, but IHMO has significant negative implications for Clojure’s concurrency story. I've gotten a bit lost in some of the diagnoses and experimental results and analyses and suggestions -- all of which I really appreciate! -- but I'm trying to get clear in my mind what the current state of things is from an application perspective. Is the following a fair characterization pending further developments? --- If you have a cons-intensive task then even if it can be divided into completely independent, long-running subtasks, there is currently no known way to get significant speedups by running the subtasks on multiple cores within a single Clojure process. In some cases you will be able to get significant speedups by separating the subtasks completely and running them in separate Clojure processes running on separate JVM instances. But the speedups will be lost (mostly, and you might even experience slowdowns) if you try to run them from within a single Clojure process. --- Or have I missed a currently-available work-around among the many suggestions? I realize that even if this is the current situation it might change via fixes on any one of several fronts (and I hope that it does!), but is this indeed the current situation? Thanks so much, -Lee -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Interest in Scribble for Clojure?
Alright, Eli. You've piqued my interest. I'll have to take a closer look sometime soon. ~Gary On Wednesday, October 17, 2012 10:22:54 AM UTC-4, Eli Barzilay wrote: Gary Johnson gwjohnso at uvm.edu writes: I see. After taking a closer look, I can see that you could do LP in Scribble (Yeah, but again -- that's really not its main goal.) as well as also outputting some different kinds of documentation formats, such as Javadocs or standalone documents. The downside I'm seeing is that this all has to be programmed in Scheme Um, it is very intentionally a documentation system that is built on a proper langugae -- like latex and N other such language, only using a general langugae instead of the usual half-baked things... (I know that some people would consider that a disadvantage, and in that case you should definitely go with some non-language tool like markdown, (raw) markup, or some WYSIWYG thing.) and that you may have to do some IMO less than attractive backquoting to get at the underlying LaTeX if you want PDF outputs which use some of the existing LaTeX packages (math libs come to mind). That's almost never needed -- and when it is, it's generally an indication that some rendering feature should be added. At the scribble syntax level, the syntax is very lightweight, so that there's no issues of bad backquoting. I describe all of that in http://barzilay.org/misc/scribble-reader.pdf, and it's applicable to other languages -- not even sexpr-ish ones. My hope is that this can easily provide a proper language syntax for having lots of text. Markdown is another approach, but IME it suffers greatly when you get to unexpected corner cases (eg, non-trivial and non-uniform rules when you want to write some texts), and in other cases it starts simple and end up being horribly complicated (as in wikipedia source files, which started as a simple markdown thing, and now have a ton of conventions as well as a templating systems that require a wikipedia black belt if you get close to it.) I suggested Org-mode on this thread for these reasons: [...] That's all valid -- I'm just pointing out that there is a way to have a real language instead of relying on a generic tool that inevitably gets complicated when people discover that they want more out of it. But of course YMMV -- I'm just trying to convey the huge benefits we got by using such an in-language tool. -- ((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay: http://barzilay.org/ Maze is Life! -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Clojure turns 5
You have made my dissertation not only bearable but an absolute blast, Rich. Thank you for your pioneering spirit, endless calls for incorporating higher principles in programming, and just being that awesome, humble guy with the crazy hair. ~Gary On Tuesday, October 16, 2012 9:53:55 PM UTC-4, Rich Hickey wrote: I released Clojure 5 years ago today. It's been a terrific ride so far. Thanks to everyone who contributes to making Clojure, and its community, great. Rich -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Interest in Scribble for Clojure?
I see. After taking a closer look, I can see that you could do LP in Scribble as well as also outputting some different kinds of documentation formats, such as Javadocs or standalone documents. The downside I'm seeing is that this all has to be programmed in Scheme and that you may have to do some IMO less than attractive backquoting to get at the underlying LaTeX if you want PDF outputs which use some of the existing LaTeX packages (math libs come to mind). I suggested Org-mode on this thread for these reasons: 1. Many Clojure users are also Emacs users. 2. Org-mode is built into Emacs and requires no additional install. 3. Org-mode is not tied to any one language and already has a module for Clojure LP development. 4. It can output to ASCII, HTML, LaTeX, PDF, DocBook, OpenDocument Text, TaskJuggler, Freemind, and XOXO formats. 5. Tangling and in-file live evaluation are very neat features. 6. It can produce both standalone reports and websites depending on the chosen export module. 7. Inline LaTeX is directly supported without any special backquoting and exports correctly to both HTML and PDF outputs. Scribble definitely looks like a powerful language for programmatically generating documentation, and if someone wants to take on a Clojure port, I can see why that might be a very compelling idea. I just wanted to drop a pointer to a somewhat lower hanging fruit. Sorry to hijack your thread. ~Gary On Thursday, October 11, 2012 5:49:10 PM UTC-4, Eli Barzilay wrote: Gary Johnson gwjohnso at uvm.edu writes: A lot of scribble's features are geared towards providing tooling for Literate Programming, No, this is wrong. The LP that we have is based on Scribble, but it was done mainly as a demonstration of the benefits you get from having a real language for writing your documentation. That benefit (using a real langugae) is the central motivation for Scribble. Note also that it's very much unlike markdown, where you can't program your documentation language by design. -- ((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay: http://barzilay.org/ Maze is Life! -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Interest in Scribble for Clojure?
A lot of scribble's features are geared towards providing tooling for Literate Programming, and currently I'm way more than satisfied with org-babel. This has been built into Emacs by defaut since IIRC version 23.2 or so. Opening any file in org-mode (`M-x org-mode') immediately provides you with a full LP experience. You can weave your org file to a number of different output formats (HTML, PDF, and ODT being my favorites using `M-x org-export-as-*') with beautiful tables, figures, embedded images, properly formatted math (LaTeX!), and language-specific fontified code blocks. You can tangle your org file (i.e., automatically extract code blocks and rearrange them in a new source code only file(s)) to create an entire src/ directory with one command (`M-x org-babel-tangle'). And possible the coolest feature of all is that you can live evaluate any code block (by sending it to a Clojure REPL using nrepl or swank-clojure) by simply typing `C-c C-c' in any code block within the org file. This allows for the typical write, test, modify, test loop that Clojure programmers are used to. Just for the final coup de grace, you can use any number of different programming languages within the same org file and either tangle them out to their own files (.sh, .clj, .java, etc) for building up an entire system within org-mode, or you can live evaluate those blocks and have them automatically pass their results between blocks of different languages. So you could write some Clojure code to calculate the values in a tree in-memory, send that on to some python code that creates the graphviz code representation of the tree as a string, and have that chained right along to a dot code block that invokes graphviz to create the PDF image of your tree, which is then embedded dynamically into your org file when you weave it. I made a simple example program to illustrate the basics of using org-babel as a github project that you can find here: http://github.com/lambdatronic/org-babel-example The actual org-babel site can be found here: http://orgmode.org/worg/org-contrib/babel/index.html Get Literate. ~Gary On Wednesday, October 10, 2012 1:40:11 PM UTC-4, John Gabriele wrote: On Wednesday, October 10, 2012 11:32:22 AM UTC-4, Grant Rettke wrote: On Tue, Oct 9, 2012 at 1:00 PM, Michael Fogus mef...@gmail.com wrote: Any existing solutions or interest in something like this? There are no _public_ solutions as far as I know, So everyone has their private custom approaches I guess? I'm curious if people would share them. My guess is that most folks are just using Markdown: * most readme's for Clojure projects on github are markdown, * high-profile projects like Lein keep their docs in markdown, * fwict, Marginalia turns markdown-formatted comments and docstrings into html, * there appears that autodoc may at some point [^1] support markdown in docstring comments, and * most folks already know and use it (sometimes without knowing it :) ). [^1]: see http://tomfaulhaber.github.com/autodoc/ Things not implemented section ---John -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: ANN Drip: A fast JVM launcher
I'm getting the same multiple JVM starting behavior on Arch Linux using lein 2.0.0-preview10 and drip 0.1.7. Hmm... On Monday, September 17, 2012 2:57:00 AM UTC-4, Tassilo Horn wrote: Denis Labaye denis@gmail.com javascript: writes: I am still seeing a new JVM being started every drip run. I am testing Drip 0.1.7 with Lein 2 by running lein test 5 times in a row with LEIN_JAVA_CMD=drip in ~/.lein/leinrc, OS X, JDK 7. No multiple JVM started for me (at least in my trivial tests) drip 0.1.7 Same versions here, but after running just lein thrice in a project, I still have 3 JVMs in drip ps. It's the same when I run another lein command, e.g., lein jar or lein test. Bye, Tassilo -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Literate Programming in org-babel (ob-clojure.el) is broken under nrepl.el
Yep. Thanks for the patch, Ben. I had set org-babel-default-header-args:clojure to '((:noweb . tangle)) in my .emacs, so I was getting the benefit of automatic noweb expansion when tangling (but not weaving). It's all fun and games until you break someone else's setup! ;) ~Gary On Wednesday, September 12, 2012 11:46:14 PM UTC-4, Ben Mabey wrote: On 9/12/12 9:29 PM, Ben Mabey wrote: Thanks for the great example Gary! I've been meaning to try org-babel out for a while but never got around to it. I just tried your example and when I run org-babel-tangle the code blocks are not expanded into the source file, but rather the code block names are just inserted into the source destination (e.g. find-discounted-subsets instead of the actual function). Any ideas on what may be wrong? Do you have global settings that are perhaps making the tangle work differently on your setup? I was able to export the document to HTML just fine and execute the clojure code, so the only issue appears to be tangling. I found the problem was a missing :noweb argument: https://github.com/lambdatronic/org-babel-example/pull/1 -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Literate Programming in org-babel (ob-clojure.el) is broken under nrepl.el
I just put together a simple example repo on GitHub, containing a literate programming solution to the Potter Kata (http://codingdojo.org/cgi-bin/wiki.pl?KataPotter) using Emacs' org-babel mode. You can check it out here: https://github.com/lambdatronic/org-babel-example Also be sure to take a look at the canonical online org-babel docs: http://orgmode.org/worg/org-contrib/babel/ In particular the intro section: http://orgmode.org/worg/org-contrib/babel/intro.html And even though it's a little bit dated w.r.t. the current org-mode version in Emacs 24, this journal article on Org-Mode's literate programming and reproducible research features is really, really cool to work through (lots of nice code examples): http://www.jstatsoft.org/v46/i03 Happy hacking, ~Gary On Saturday, September 8, 2012 4:24:38 AM UTC-4, Denis Labaye wrote: On Thu, Sep 6, 2012 at 6:42 PM, lambdatronic gwjo...@uvm.edujavascript: wrote: For those people (like myself) who do a lot of Literate Programming in Emacs using Clojure and org-babel, migrating to nrepl and nrepl.el is somewhat non-trivial. This is because the existing Clojure support in org-babel (ob-clojure.el) relies on slime and swank-clojure when running org-babel-execute-src-block (which redirects to org-babel-execute:clojure in ob-clojure.el). So clearly this is actually an issue for both nrepl.el and ob-clojure.el, not simply one or the other. All the same, I've hacked together a simple workaround that fixes the problem and makes Literate Programming under nrepl possible once again. If there is some slick way this could be worked into nrepl.el's codebase that wouldn't break its existing behavior (as this does), I'd be excited to see it. Here we go: ;; Patch result table rendering bug in ob-clojure (NREPL version) (defun nrepl-send-request-sync (request) Send a request to the backend synchronously (discouraged). The result is a plist with keys :value, :stderr and :stdout. (with-current-buffer *nrepl-connection* (setq nrepl-sync-response nil) (nrepl-send-request request (nrepl-sync-request-handler (current-buffer))) (while (not (plist-get nrepl-sync-response :done)) (accept-process-output)) nrepl-sync-response)) (defun org-babel-execute:clojure (body params) Execute a block of Clojure code with Babel. (let ((result-plist (nrepl-send-string-sync (org-babel-expand-body:clojure body params) nrepl-buffer-ns)) (result-type (cdr (assoc :result-type params (org-babel-script-escape (cond ((eq result-type 'value) (plist-get result-plist :value)) ((eq result-type 'output) (plist-get result-plist :value)) (t(message Unknown :results type!)) Have fun! It seems to be very interesting, I am already using Emacs / org-mode / clojure a lot, I was aware of org-babel, but never used it. Would you have a simple example project (on github, ...) on how to bootstrap this ? Thanks, Denis -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clo...@googlegroups.comjavascript: Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+u...@googlegroups.com javascript: For more options, visit this group at http://groups.google.com/group/clojure?hl=en -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en