Re: Clojure needs a web framework with more momentum
On 05.05.2015 03:02, Daniel Compton wrote: What this may look like for Clojure in 2015 is probably very different than what it looked like for Ruby in 2004. It may be a traditional framework, a lein template, a standard pattern of code, a set of conventions and loosely coupled protocols, pretty much exactly what we have now, or something entirely different. I think the ideal* would be a single starting point (website/brand/platform), with a mix of literate programming and library store. It could be a bit like a checklist of general concerns like routing, authentication and so on, listing and comparing mature libraries for each of those. If a literate program explains what is to be achieved and how you go about it in code, this would extend that concept to library selection. This would be the place to find out if seemingly competing libraries happen to have different strengths. Where library authors explain their choices and may find ways to join forces. Where it will be made clear, if a library does happen to be the best in its field or simply stands alone. Yes, of course I do see problems around reaching consensus ;) The development branch of this resource should be a gathering point for the community to define current best practices. * ideal for newcomers to learn how to go about web development, where covering standards like blogs and stores are not only matters for themselves, but serve as basis for free-form exploration. Ideal for seasoned developers for collaborating on furthering the whole field. -- Thorsten Wilms thorwil's design for free software: http://thorwil.wordpress.com/ -- 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: Interest in a Full Featured Clojure Blog Engine
On 07/19/2013 08:46 PM, Timothy Washington wrote: There would just be a core data model of posts, assets and tags, that would exists as definitions, and could be pulled into a runtime soup. How about unifying everything that may be mapped to its own URL as "resource"? Such a resource would have a unique name (or path/name combination), created and modified timestamps, owner, permissions ... Such a data set would then be associated with an entity-type specific data set to store what's special to a post or a comment or an image ... -- Thorsten Wilms thorwil's design for free software: http://thorwil.wordpress.com/ -- -- 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: Interest in a Full Featured Clojure Blog Engine
On 07/18/2013 04:24 PM, Timothy Washington wrote: I know that I currently wish I had a Clojure weblog engine that I could stick into a site I'm building. If there's already something available, I'll obviously just use that. But otherwise, is this something that would be interesting to people? Oh yes. I put some effort into a blogging engine myself, but got sidetracked a lot. Repo: https://github.com/thorwil/tlog It's written as single account blog, but since I'm using Friend, that should be straightforward to change. For editing, I rely on Aloha (http://aloha-editor.org/). The unfinished comment system works only with JS enabled and has no spam protection or email notifications. Comments can be nested and the design is meant to encourage people to read previous comments, before they add their own (this at the cost of varying distance between a comment and its Reply field). Having Aloha-like editing, but without inheriting such a chunk of JS, rather using ClojureScript would rock. One of the more interesting parts might be how pages are assembled: https://github.com/thorwil/tlog/blob/master/src/tlog/render/html/assemble.clj#L83 Further down the road, I wanted to look into versioning, perhaps backed by git and realtime collaborative editing. I haven't be traveling, lately :} -- Thorsten Wilms thorwil's design for free software: http://thorwil.wordpress.com/ -- -- 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: Interactive form workflow with Friend, can't log in
On 11/13/2012 12:28 PM, Haim Ashkenazi wrote: Here's how you wrap your application with middleware (root-routes is your main routes: (def app (-> #'root-routes (friend/authenticate …) (wrap-keyword-params) (wrap-params) …)) Now following your example you can (web/start app) Thank you! I had something similar already, but my testing got thwarted by expecting too much of ring-reload. Now the following does the trick: (def secured-app (-> #'root-routes (friend/authenticate {:credential-fn (partial creds/bcrypt-credential-fn users) :workflows [(workflows/interactive-form)]}) wrap-keyword-params wrap-params (wrap-session {:store (immutant-session/servlet-store)}))) (web/start secured-app :reload true) Finding this example helped: https://github.com/marianoguerra/immutant-recipes/tree/master/friend-acl -- Thorsten Wilms thorwil's design for free software: http://thorwil.wordpress.com/ -- 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: question concerning macros by a newbie
On 11/13/2012 11:06 AM, Johannes wrote: I define a record (defrecord point [x y]) and the following macro: (defmacro drg [typename components] `(def ~(symbol (str typename "-" (str (first components (fn [~(symbol "obj")] (get ~(symbol "obj") ~(symbol (str ":" (str (first components But calling the macro results in an error message: user> (drg point [x y]) CompilerException java.lang.RuntimeException: Unable to resolve symbol: :x in this context, compiling:(NO_SOURCE_PATH:1) Can anyone tell me what my mistake is? I guess the problem is that you created :x using symbol, so it is not recognized as a key. But the whole approach, starting with creating names to def to inside a macro, is troublesome. This makes it hard to follow what's going on. If you provide a larger context of what you are trying to accomplish, I'm sure someone can suggest a much better approach. -- Thorsten Wilms thorwil's design for free software: http://thorwil.wordpress.com/ -- 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: Interactive form workflow with Friend, can't log in
On 11/12/2012 03:20 PM, Chas Emerick wrote: Looks like you're not using the keyword-params middleware, which Friend requires (among others). Please check the last paragraph in the 'Authentication' section here: https://github.com/cemerick/friend/#authentication Once you add that, then the interactive-form middleware will pick up the form data you're submitting. I tried to make sense of that in wrapping my main handler in authenticate in wrap-keyword-params, later also adding wrap-session, wrap-params and wrap-nested params. I still get a redirect to http://localhost:8080/login?&login_failed=Y&username= So please, how/where shall I *add* wrap-keyword-params (and the others?) exactly? -- Thorsten Wilms thorwil's design for free software: http://thorwil.wordpress.com/ -- 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
Interactive form workflow with Friend, can't log in
Hi! I'm trying to use Friend with the interactive form workflow. Whenever I try to login, I get a redirect to http://localhost:8080/login?&login_failed=Y&username= The body of the POST my form generates does include username and password. My code: https://www.refheap.com/paste/6569 This version does not specify encoding and thus falls back to some windows encoding, but a later version with a full html5 body with utf-8 shows the same result. Where's my mistake, or what can I do to further diagnose the problem? -- Thorsten Wilms thorwil's design for free software: http://thorwil.wordpress.com/ -- 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: Teaching beginners to program using an interactive ClojureScript REPL
On 07/16/2012 11:03 PM, Pascal Chatterjee wrote: The trickiest thing I've found so far is that, for simplicity, I've explained def as a function that takes a symbol and a value as arguments. I've then gone on to say that arguments to a function are evaluated before the function itself executes, which is true in general of course but not for special forms, like def. I don't really want to get into special forms vs functions right in the first chapter so for now I've just glossed over it and hoped no-one will notice :) Do you guys have any ideas on other ways to tackle it? I think you should not explain def as a function, as that is not a helpful simplification but rather just misleading. You could just explain how it behaves without mentioning special forms vs functions. Or you have to keep special forms out of the first chapter. This made me wonder; The Little Schemer starts with atoms, lists, s-expressions and I think the first mention of define is on page 16. -- Thorsten Wilms thorwil's design for free software: http://thorwil.wordpress.com/ -- 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: Lambda: A lniux distro for clojurists
On 05/24/2012 10:11 PM, banseljaj wrote: So I have decided to create a Linux Distro specifically for Clojure development. My own problem with specialist distros is that I'm interested in too many areas (and don't like to reboot). Just Clojure seems to be a *very* narrow focus. Is there anyone here who does not use other programming languages? I am still open to ideas. I intend to roll it as a complete distro, so I will love any and all input. It would be kinda fitting to have functional package management (http://nixos.org/nix/). I wonder if installing a distro could be similar to cloning a repo, later on allowing you to take all your local changes to apply them as patch to the next release version. -- Thorsten Wilms thorwil's design for free software: http://thorwil.wordpress.com/ -- 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: A New Core.logic Primer
On 03/14/2012 08:00 PM, David Nolen wrote: Thanks to Edmund Jackson we have a new primer for core.logic: https://github.com/clojure/core.logic/wiki/A-Core.logic-Primer Feedback appreciated! Hi! Does a run* expression evaluate to only the query-variable, while lvars introduced with fresh stay internal? "Finally we unify a and q leaving both with the value of their intersection: (1, 2, 3) intersection (3, 4, 5), (3)" I stumbled over this sentence because of the "(1, 2, 3) intersection (3, 4, 5), (3)" part. Sudden use of infix, with the result after a comma? Just writing (3) would be clearer. Regarding conde, I had to reread that section carefully. Consider to first explain conde with single-goal clauses, to then mention that each clause is actually a list of goals with AND-logic (simple case first, expand afterwards). In the "Conso (the Magnificent)" section, use of "return" inside of the code blocks is inconsistent with the rest of the article. I do not understand the explanations to the last 2 examples, even though I think I understand the logic. The use of list [1] and list [2] is not easy to read, how about writing out first and second list? I would think that: (run* [q] (conso q [2 3] [1 2 3])) returns (1); q is the element that when added as head to the first list, results in a list equal to the second list (if such an element exists). (run* [q] (conso 1 [2 q] [1 2 3])) returns (3); q is the element of the first list that when 1 is added as head to the first list results in a list equal to the second list (if such an element exists). So conso constraints whatever lvars are present in an attempt to unify the cons of its first 2 arguments with its third argument, restricting the arguments to be atom-or-list, list, list? Otherwise an enlightening and inspiring read, thank you! -- Thorsten Wilms thorwil's design for free software: http://thorwil.wordpress.com/ -- 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: i am so bored
On 01/14/2012 01:12 PM, Dennis Haupt wrote: clojure has caught my interest. in general, high level programming has. i played around with clojure a bit and would like to get something done that has at least some purpose. are there any small/new projects looking for help? Not a currently existing project, but one that could fill some very real needs: A platform for collaborative, multi-lingual documentation/book-writing. For example the Ubuntu Manual Project suffers from the barriers for potential contributors, that are the result from exposing Latex, bzr version management and being unable to start translation before the English version for a specific release of Ubuntu has been finished. The solution I imagine would allow - collaborative real-time editing comparable to Etherpad, but fulfilling the logical markup and structuring needs of book projects. - comparison/editing of 2 language version side by side. - to define ranges of text independent of paragraph boundaries to map blocks of meaning between translations. - Tracking of changes in a way that makes it feasible to update one translation from another translation in any order they come. I assume this would be a quite challenging and expandable project that could benefit from using Clojurescript. -- Thorsten Wilms thorwil's design for free software: http://thorwil.wordpress.com/ -- 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: Do you use Monads in your real clojure applications
On 01/04/2012 03:05 AM, Takahiro Hozumi wrote: In MVC pattern, Model should take responsibility for business logic. Therefore I write validate function for creating in the model. If creating a instance of the model should be safe, I must validate a parameter in the create function. My problem is that a controller have to validate a parameter twice in the validate function and the create function. Ring handler example (defn handler [{:keys [params] :as req}] (if (person/valid? params) {:status 200 :body (json/generate-string (person/create params))} {:status 400})) I think this might be suited to monads, which I don't fully understand. If you work with self-imposed restrictions that make you call functions with the same parameters twice in short order, you should reconsider those restrictions. If all the information you need from a validator is true/false, you can just call a model function. One that is written under the assumption that a certain requirement is met, before it is called. If the validator returns nil or some concrete piece of imformation, you just need to call it, store the result. Then you may call a model function with the result (if it is non-nil). Moustache makes that very straightforward: (defn integer [s] "returns nil if s does not represent an integer (try (Integer/parseInt s) (catch Exception e))) (app ["order" [id integer]] my-handler) ; for "/order/134" @id@ will be bind to 134 (not "134"), this route will not match "/order/abc". Example taken from https://github.com/cgrand/moustache -- Thorsten Wilms thorwil's design for free software: http://thorwil.wordpress.com/ -- 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 list syntax sugar: f(x) notation
On 12/26/2011 07:09 PM, Louis Yu Lu wrote: With some experiments, I found the code is more readable for me to use f(x) notation for function call, and (op x) for operator. Operator? It's all function calls! -- Thorsten Wilms thorwil's design for free software: http://thorwil.wordpress.com/ -- 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 example
On 11/20/2011 11:18 PM, Daniel Jomphe wrote: On Sunday, November 20, 2011 5:50:31 AM UTC-5, thorwil wrote: I'm following one or the other Free Software project where an incredible amount of discussions happen regarding work-flow and features. So much thought, so many decisions on details, but for the most part, the implementation is all that remains. But the research, concepts and conscious decisions regarding trade-offs could actually outlive any implementation, they are portable and could be argued to be more valuable. You raised my curiosity. Would you mind sharing a link? ;) My prime example would be Ardour (ardour.org). Almost all the action happens on IRC, where the lead developer has many interactions with a few other coders and users, among them professional sound-engineers who provide critical insight into certain scenarios/work-flows and the features of related hard-and software. Starting to be off-topic, so this is as far as I will take it on this list ;) -- Thorsten Wilms thorwil's design for free software: http://thorwil.wordpress.com/ -- 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 example
On 11/19/2011 10:21 PM, Daniel Jomphe wrote: With the tools available to us today, there's no reason why we at least shouldn't have everything needed to make literate programming more seamless, more natural. For example, while reading your toy example, I found myself wanting to ask a question or comment on your thoughts a few times. If your book had been displayed on a dynamic website geared towards literate programming, I might have been able to click on a paragraph and write my question/comment right there. And then, after a short conversation there, you would have integrated the fruits of our conversation directly into the end result. Thus each new reader would have been an occasion to improve the book. ...It's nothing surprising since this kind of review system already exists in some publishers' toolkits. Especially with support for discussions and iterations, such infrastructure could be used for design in general. I'm following one or the other Free Software project where an incredible amount of discussions happen regarding work-flow and features. So much thought, so many decisions on details, but for the most part, the implementation is all that remains. But the research, concepts and conscious decisions regarding trade-offs could actually outlive any implementation, they are portable and could be argued to be more valuable. So funny as it might sound, there's a need for literate design! -- Thorsten Wilms thorwil's design for free software: http://thorwil.wordpress.com/ -- 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: appengine-magic, directory not found, strange file: hierarchy
On 10/27/2011 02:45 PM, Paul Koerbitz wrote: are you sure you used OpenJDK before the upgrade? I remember having problems with OpenJDK + AppengineMagic which were resolved by switching to Sun's JDK (this was on Ubuntu 10.04). Switching to Oracle's version fixed it. I must have had it installed long before getting into Clojure, to then forget about it, on Ubuntu 10.04. Since there's apparently no package for 11.10, I followed http://www.webupd8.org/2011/09/how-to-install-oracle-java-7-jdk-in.html Thanks! -- Thorsten Wilms thorwil's design for free software: http://thorwil.wordpress.com/ -- 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
appengine-magic, directory not found, strange file: hierarchy
Hi! I recently upgraded my Linux distribution and while everything regarding Clojure, Leiningen, Emacs and my project should be like it was before, but I get the following error when trying to test my website project in a browser: --- HTTP ERROR 500 Problem accessing /. Reason: Directory does not exist: /media/sda4/app_engine/tlog-clj-gae/file:/usr/lib/jvm/java-6-openjdk/jre/lib/ext/pulse-java.jar!/../war Caused by: java.lang.Exception: Directory does not exist: /media/sda4/app_engine/tlog-clj-gae/file:/usr/lib/jvm/java-6-openjdk/jre/lib/ext/pulse-java.jar!/../war at ring.middleware.file$ensure_dir.invoke(file.clj:12) at ring.middleware.file$wrap_file.doInvoke(file.clj:22) at clojure.lang.RestFn.invoke(RestFn.java:425) at appengine_magic.core$wrap_war_static$fn__2337.invoke(core_local.clj:43) at appengine_magic.servlet$make_servlet_service_method$fn__1730.invoke(servlet.clj:99) at appengine_magic.servlet$servlet$fn__1733.invoke(servlet.clj:108) at appengine_magic.servlet.proxy$javax.servlet.http.HttpServlet$0.service(Unknown Source) at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511) at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1166) at com.google.appengine.api.blobstore.dev.ServeBlobFilter.doFilter(ServeBlobFilter.java:58) at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157) at com.google.apphosting.utils.servlet.TransactionCleanupFilter.doFilter(TransactionCleanupFilter.java:43) at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157) at appengine_magic.core$make_appengine_request_environment_filter$reify__2351.doFilter(core_local.clj:74) at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157) at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:388) at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182) at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765) at org.mortbay.jetty.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:230) at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152) at org.mortbay.jetty.Server.handle(Server.java:326) at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542) at org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:923) at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:547) at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:212) at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404) at org.mortbay.jetty.bio.SocketConnector$Connection.run(SocketConnector.java:228) at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:582) --- /usr/lib/jvm/java-6-openjdk/jre/lib/ext/pulse-java.jar does exist and has no specific relation to my project at all. Afterwards, I find the following hierarchy added in my project dir: /media/sda4/app_engine/tlog-clj-gae: tree file\:/ file:/ └── usr └── lib └── jvm └── java-6-openjdk └── jre └── lib └── ext └── war └── WEB-INF └── appengine-generated My project.clj: --- (defproject tlog "0.3.0-SNAPSHOT" :description "A blog for Google App Engine" :repositories {"sonatype-oss-public" "https://oss.sonatype.org/content/groups/public/"} :dependencies [[org.clojure/clojure "1.3.0"] [org.clojure/algo.monads "0.1.1-SNAPSHOT"] [org.clojure/math.numeric-tower "0.0.1"] [net.cgrand/moustache "1.0.0"] [hiccup "0.3.6"]] :dev-dependencies [[appengine-magic "0.4.6-SNAPSHOT"]]) --- Using Leiningen 1.6.1.1 on Java 1.6.0_23 OpenJDK 64-Bit Server VM, swank-clojure plugin 1.3.2. Starting Jetty via appengine-magic's serve. Any idea what's going on? -- Thorsten Wilms thorwil's design for free software: http://thorwil.wordpress.com/ -- 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: Rich Hickey: "Simple Made Easy" from Strange Loop 2011
On 10/21/2011 06:50 PM, Mark Engelberg wrote: Now I can finally articulate why: nil complects non-existence, false, and empty. How does nil represent empty? '() does not equal nil. It is also easy in the sense that it is more similar to what Lisp users (as opposed to Scheme) are used to from past experience. But it is decidedly less simple to have these ideas complected. AFAIK, Common Lisp does treat nil and empty lists as equivalent. Looks like a clear difference, not "more similar" to me. -- Thorsten Wilms thorwil's design for free software: http://thorwil.wordpress.com/ -- 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
Composing HTML rendering functions
Hi! Initially I created a mess of interlinked functions for rendering HTML via hiccup. I have few pages with parts that may vary or may be present or not based on whether the user is logged in as admin. With the desire to test for the role in a single place and for composing the views in a uniform way, I created a little framework and now wonder if I'm thinking too complicated, or if this seems sound. Can you suggest improvements or alternatives? The outcome is that I can define my views via defviews: https://github.com/thorwil/tlog-clj-gae/blob/4440f729001ef14ea63115c69f0c868bc59e4686/src/tlog/views/views.clj The roles are cumulative. Every view defined in this way expects a role and a map (from the datastore). The maps is handed through all elements in the vector (except if it happens to be a def). The html is assembled as value to :buildup. Every element may read and update/add arbitrary key-vals. All the slightly complicated business happens here: https://github.com/thorwil/tlog-clj-gae/blob/4440f729001ef14ea63115c69f0c868bc59e4686/src/tlog/views/compose.clj To allow the rather straightforward parts: https://github.com/thorwil/tlog-clj-gae/blob/4440f729001ef14ea63115c69f0c868bc59e4686/src/tlog/views/parts.clj The {:keys} specified are like slots. If one is nil, Hiccup makes it fall out. -- Thorsten Wilms thorwil's design for free software: http://thorwil.wordpress.com/ -- 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: advantage of dynamic typing
On 09/21/2011 01:51 AM, Laurent PETIT wrote: I would see no problem of e.g. having a way to explicitly declare, in the "public interface of the function" (as opposed to "derived implicitly from the current implementation detail of the function") the necessary constraints on the function arguments. And the guarantees on the function's result. Those could then allow more checks at compile time, without sacrificing genericity of the code. Something like Racket's contracts, perhaps? http://pre.racket-lang.org/docs/html/guide/contracts.html -- Thorsten Wilms thorwil's design for free software: http://thorwil.wordpress.com/ -- 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: small project to learn clojure
On 09/16/2011 11:50 PM, Dennis Haupt wrote: i feel compelled to do something more complex in clojure. not too big, but bigger than what fits in 100 lines and offers some chances to use macros. it should also be fun, maybe something like robocode. Something that is not primitive but may stay small or at least has clearly defined boundaries right from start ... if you rule out pure logic puzzles, this does point to games, I think. There are so many simple games, some of which must have been implemented a million times. You could try to do one of those, but with a twist, perhaps. Like a Pacman, but where you steer the ghosts (only one at a time, changing the direction it heads to). Dungeonmaster-Sokoban, where you have to push boxes to create a path that will lead to the hero's death, once he arrives. That without trapping your own worker. OR, you look for an existing project, where you could implement a missing feature. Ideally one where you could interact with the author/contributors via IRC. http://www.webnoir.org/ might be a candidate, where a comment system or tagging come to mind (I'm not affiliated and don't know if something like that is underway, already). -- Thorsten Wilms thorwil's design for free software: http://thorwil.wordpress.com/ -- 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: Rounding the edges of an Emacs beginner
On 09/14/2011 05:20 AM, Timothy Washington wrote: But now that I think about it, I can probably just pass a run jetty / ring form to swank to start it :) Let me know if I'm on the right path. I recently started using clojure-jack-in. lein repl made it easy to automatically execute a startup script, but complicated other things. You can of course start things from the slime-repl. For my appengine-magic using project, I tried a slime-eval-buffer on my "start.clj", which mostly works, except that datastore operations will not be available from the repl (raises "No API environment is registered for this thread"). Maybe it doesn't matter in other cases, just noting that slime-eval-buffer and entering forms on the repl are different in outcome, regarding threads. -- Thorsten Wilms thorwil's design for free software: http://thorwil.wordpress.com/ -- 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: Recursion for nested comments
A somewhat related problem within all this: In the following code, the recursive call of comments-rendition-recur leads to the compile-time error "java.lang.Exception: Unable to resolve symbol: comments-rendition-recur in this context (views.clj:181)", unless I use declare. views.clj:181 is the last line of the comments-rendition-recur defn. What's going on, here? Code also on http://paste.pocoo.org/show/463499/ --- (defhtml comment-rendition [{:keys [index parent author link body created updated time-stamps css-class]} children] [:div.comment time-stamps [:div {:class (str "comment-body " css-class)} [:p.meta [:a.comment-anchor {:name index :href (str "#" index)} (str "#" index " ")] [:span.author [:a {:href link} author] ":"]] body children]]) (defhtml comment-new-level [] [:div {:class "hyphenate editable start-blank new-level"} "foo"]) (declare comments-rendition-recur) (defn comments-rendition-recur "Recurse for nested Comments." [comments] (cons ;; comments are [parent children] lists: (map #(let [c (first %) cs (rest %)] (apply comment-rendition (if (empty? cs) ;; Create one level deeper, just for ;; the reply field: [c (comment-new-level)] ;; Recurse to handle cs: [(into c (derive-time-stamps c)) (comments-rendition-recur cs)]))) comments) ;; Place comment field like a last sibling: (html [:div {:class "hyphenate editable start-blank end"} (-> comments last first :parent)]))) (defhtml comments-rendition [comments] [:div#comments [:h3 "Comments"] [:noscript [:p "Without JavaScript, you cannot add comments, here!"]] (comments-rendition-recur comments)]) (defhtml tree-rendition [{:keys [comments] :as all}] (article-rendition (into all (derive-time-stamps all))) (comments-rendition comments)) -- Thorsten Wilms thorwil's design for free software: http://thorwil.wordpress.com/ -- 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
Recursion for nested comments
Hi! For a blogging software, I want to support nested comments. Rendered as nested s, to not have to define per level CSS classes. My data-gathering function calls itself to deliver a nested structure. On IRC I've been told that, since it happens via map, there is not necessarily a problem with an ever growing stack, but that it depends on how I use the result. Thing is, I have no clue what happens regarding the interaction of the model and the view code. Plus I'm wondering if I'm perhaps doing something silly, in having both model and view code recurse, or if that's just the nature of dealing with the nested structure. I considered making the model fn use loop/recur, but thinking about how to do an accumulator gives me nothing but headaches. So under which circumstances is such a naive recursion inside map, thus making it somehow lazy, a fine solution, and when would it break down? Can you think of significant improvements to the following code? From models.clj; comments have a parent property, with the ID of the article they refer to for first level comments, comment ID's for all following levels. ds/key-id is an appengine-magic function delivering those IDs: --- (defn comments "Retrieve all comments for the ID, then recurse to retrieve comments for the IDs of the just retrieved comments. The whole will be wrapped in ()." [id] (let [cs (comments-for-parent id)] (when (not (nil? cs)) (map #(cons % (comments (ds/key-id %))) cs (defn tree "Tree consisting of an Article and 0 to n Comments, via article-id. nil if there is no Article." [id] (let [a (article id) cs (comments id)] (if (nil? a) nil (into a {:comments cs} --- From views.clj, using Hiccup: --- (defhtml comment-rendition [{:keys [index parent author link body created updated time-stamps css-class]} children] [:div.comment time-stamps [:div {:class (str "comment-body " css-class)} [:p.meta [:span.index [:a {:href (str "/" index)} (str "#" index " ")]] [:span.author [:a {:href link} author] ":"]] body] children]) (defn comments-rendition-recur "Recurse for nested Comments." [comments] (map #(comment-rendition (into (first %) (derive-time-stamps (first %))) (let [children (rest %)] (when-not (empty? children) (comments-rendition-recur children comments)) (defhtml comments-rendition [comments] [:div#comments [:h3 "Comments"] (comments-rendition-recur comments)]) (defhtml tree-rendition [{:keys [comments] :as all}] (article-rendition (into all (derive-time-stamps all))) (comments-rendition comments)) Thanks! -- Thorsten Wilms thorwil's design for free software: http://thorwil.wordpress.com/ -- 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: is my understanding correct for function "identity"?
On 08/13/2011 06:45 PM, jaime wrote: The only reason that I can imagine is this: because we often use higher-order functions, these higher-order functions will accept functions as its parameters, in such a situation, when we want to use a higher-order function but don't want to pass any "real" functions to it, then we can use function like "identity" and "identity" here is just to fill the role of parameter of higher-order function. That's what I'm using it for. In a case where I have 2 places requiring the same code before and after one step only used in one case. It would be slightly more work, otherwise. Are there other functions for the same purpose? I don't see how there could be, for the very same purpose. Though you might want to consider splitting up functions some more, instead. -- Thorsten Wilms thorwil's design for free software: http://thorwil.wordpress.com/ -- 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: passing value to functions
On 07/28/2011 06:34 PM, Tuba Lambanog wrote: The determination of whether a called function will apply is left as a responsibility of the function itself, rather than the calling function. The motivation is that a function may be called from a number of places. Perhaps there's a better way? The called function cannot decide to not be applied, but it may either evaluate to its argument (assuming unary), or a value derived from that argument. I guess pattern matching would be nice here, but even without, you could perhaps split the conditions from the actions. Is there any reason to test additional rules after one matches, or would it be beneficial to stop after a match? That would make it similar to URL routing like e.g. Moustache does it. From your description, it did sound like you want to call the 2nd function with the original argument, not the result of the 1st function. But how would you accumulate all the results, then? -- Thorsten Wilms thorwil's design for free software: http://thorwil.wordpress.com/ -- 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: passing value to functions
On 07/28/2011 11:29 AM, Tuba Lambanog wrote: I'm trying to pass a variable through a series of functions, which may change the value of the variable. However, the next function in line uses the original value, rather than the changed value. Here's a pseudo-code of what I'm doing. I think you should provide more context. Why, if that is the case at all, do you want to pass an argument through functions that do not work with it? How many arguments does each fn in the line take (and what do they evaluate to)? Is it a fixed or a variable number of functions? Perhaps a sub-forum for beginners? Kind of embarrassing to ask here questions that are so newbie-ish. Really no reason to feel embarrassed and I doubt the experts here would like to monitor an additional space ... -- Thorsten Wilms thorwil's design for free software: http://thorwil.wordpress.com/ -- 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: monads > macros
On 07/12/2011 03:28 PM, James Keats wrote: I'm mildly concerned about macros being seen as the "secret weapon" of clojure(/lisp). In their place, i wish monads would get a wider attention and embrace. Do you want to suggest that it would be common that an issue can be solved with either a macro or a monad, or is it all about attention and how often one or the other is mentioned? At least some monads, even if not called so, are present in lots of languages. But good macro functionality is typical for lisps. It's not my perception that there is a lot of noise about macros, whereas articles about monads are like bunnies and have taken to the meta-level. -- Thorsten Wilms thorwil's design for free software: http://thorwil.wordpress.com/ -- 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 stack
On 05/19/2011 02:06 AM, Sean Corfield wrote: I've actually found the Clojure community to be one of the most welcoming and most helpful of almost any technology that I've picked up in about 30 years. YMMV, I guess, and I'm sure it depends on your programming background. Same here, except 30 years ago, the technology I may have picked up would have included pacifiers :) That said, setting things up to work with Clojure really feels like an investment, currently. http://try-clojure.org/ really helped me regarding motivation to get through it. I started using Emacs because of Clojure, after a failed attempt to set up CCW and I don't look back. After initially installing a Clojure package on Ubuntu, I then learned that it was totally unnecessary for a project using Leiningen ... Look at "([name doc-string? attr-map? [params*] body] [name doc- string? attr-map? ([params*] body) + attr-map?])". I'd instinctively expect something? to be optional and something* to mean zero or more. Basic regex and something I've seen in documentation for decades. I'm genuinely surprised you're asserting there are developers out there who would not know that (I'm not denying the possibility, just expressing surprise - it simply wouldn't have occurred to me). Despite using ? and * in bash, that was not clear to me. I even briefly thought about the use of ? to mark predicates, but of course that makes no sense, here. It's hard to get into the shoes of someone who doesn't know what you know. But all it takes in a case like this is about one or two sentences of explanation. It's also worth saying that there is a perfectly defensible position that says if you dumb down the documentation and offer too much hand-holding, you will get an influx of programmers whose skill level may lead to a lot of poor code that then gets Clojure a bad reputation as an unmaintainable, poorly performing language. Don't think it can happen? Look at Basic, CFML, PHP which all have a reputation for poorly structured code because of too many n00bs being able to pick them up easily and write bad code. I even heard complaints about there being way too many bad examples out there for Python. Inevitable, at some point, if a PL goes mainstream, I guess. Luckily, you just need enough users to build a healthy eco-system, not take over the world. -- Thorsten Wilms thorwil's design for free software: http://thorwil.wordpress.com/ -- 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 ideas repository / todo list
On 05/15/2011 06:10 AM, Vivek Khurana wrote: On Sun, May 15, 2011 at 2:47 AM, Islon Scherer wrote: Is there anyplace people post ideas of libraries/frameworks/functions that would be nice to be implemented in clojure? Why not post them to mailing list ? That means risking a stream of noise and results soon forgotten. A wiki page would be appropriate, but might lead to the problem of few ever being aware of it. Still, hard to resist ... * Hot code swapping * Framework for reversible text transformations * Wrapper around git or darcs for using them as storage backends * Event and action wiring similar to what Nitrogen does. See parts 4 and 5 at http://nitrogenproject.com/doc/tutorial.html. Though I wonder how that could be combined with Enlive, without friction. -- Thorsten Wilms thorwil's design for free software: http://thorwil.wordpress.com/ -- 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: Enlive update transformation
On 05/09/2011 10:15 PM, Thorsten Wilms wrote: I tried to turn that into a transformation: (defn substitute-token [& values] #(map (fn [m] (update-in m [:content] (fn [c] (apply (partial replace-str "token" %) c values)) Apparently I had my brain knotted, but raek and fliebel on IRC helped with untying some misconceptions :) So the solution for applying a function, (partial replace-str "token" to) in this case, on the content in html nodes as Enlive transformation is: (defn substitute-token "Replace text 'token' with to." [to] #(update-in % [:content] (fn [c] (apply (partial replace-str "token" to) c -- Thorsten Wilms thorwil's design for free software: http://thorwil.wordpress.com/ -- 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: [Enlive] Search for a node querying on attrs
On 05/04/2011 06:23 PM, Alfredo wrote: I want to extract only the content part. I recently had related issues, so: (def metas (en/html-snippet " ")) (en/select metas [[:meta (en/attr= :name "keywords")]]) (-> (en/select metas [[:meta (en/attr= :name "keywords")]]) first :attrs :content) -- Thorsten Wilms thorwil's design for free software: http://thorwil.wordpress.com/ -- 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: Appengine-magic and Text properties
On 03/31/2011 10:57 AM, Thorsten Wilms wrote: My Article entity has a "body" property for text. The default String property doesn't handle long text, so it needs to be a Text property. In https://github.com/thurn/ackbar, I found: --- (ns (:import (com.google.appengine.api.datastore EntityNotFoundException Text))) (ds/save! (Post. url title (Text. body) ts in-feed? category)) --- Turned out that I misinterpreted the error, it happens on retrieval, not saving, as my Submit handler triggers reloading the submission form ... So either (Text. body) or (ds/as-text) for saving, given a (:import (com.google.appengine.api.datastore Text) or (:require [appengine-magic.services.datastore :as ds]). (.getValue body) when reading. -- Thorsten Wilms thorwil's design for free software: http://thorwil.wordpress.com/ -- 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
Appengine-magic and Text properties
Hi! I'm using Clojure 1.2.0, Moustache 1.0.0-SNAPSHOT and Appengine-magic 0.4.0. My Article entity has a "body" property for text. The default String property doesn't handle long text, so it needs to be a Text property. In https://github.com/thurn/ackbar, I found: --- (ns (:import (com.google.appengine.api.datastore EntityNotFoundException Text))) (ds/save! (Post. url title (Text. body) ts in-feed? category)) --- This use of the Text constructor seems to be consistent with the Java documentation for App Engine. But if I do the same, I get: "java.lang.RuntimeException: java.lang.IllegalArgumentException: Don't know how to create ISeq from: com.google.appengine.api.datastore.Text" (One notable difference is that the ackbar I'm looking at uses appengine-magic 0.3.2.) I also tried ds/as-text as briefly mentioned on https://github.com/gcv/appengine-magic#readme, but same error message as above. (ds/as-text (Text. body)), too, but (Text. (ds/save body)) leads to: "com.google.appengine.api.datastore.Text cannot be cast to java.lang.String" Any ideas? -- Thorsten Wilms thorwil's design for free software: http://thorwil.wordpress.com/ -- 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: Macro compile vs run time, appengine-magic defentity
On 03/29/2011 10:51 PM, Meikel Brandmeyer wrote: [(with-meta key {:key true})] do not set ID/name. Which Clojure version are you using? If it is 1.2, try (with-meta key {:tag :key}). Clojure 1.2 and your are correct, thanks. I added a comment to remember that variant, for when I switch version. Or should I do so already, perhaps, given that all I use is appengine-magic, moustache and envlive, so far? -- Thorsten Wilms thorwil's design for free software: http://thorwil.wordpress.com/ -- 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: Macro compile vs run time, appengine-magic defentity
On 03/29/2011 10:52 AM, Meikel Brandmeyer wrote: Ah. Now things become clear. I haven't read the problem correctly. You want [(with-meta key {:key true})]. Thanks, but unfortunately, that builds, but does not set the named key (running number for the ID/name attribute, again). ['^:key key] or [`^:key ~key] do set ID/name, but key will be interpreted literally. ['^:key ~key] ; does not compile [^:key key] or [(with-meta key {:key true})] do not set ID/name. Any other ideas? At least, I found a solution for my "define that list only once" and "macros don't evaluate their arguments" problem: use of eval inside the macro definition: (ns tlog.models (:require [appengine-magic.services.datastore :as ds])) (def article-attrs '[title, body, created-t, updated-t]) (defmacro def-entity-and-attrs [type key attrs] `(ds/defentity ~type ~(vec (concat [(with-meta key {:key true})] (eval attrs) (def-entity-and-attrs Article slug article-attrs) -- Thorsten Wilms thorwil's design for free software: http://thorwil.wordpress.com/ -- 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: Macro compile vs run time, appengine-magic defentity
On 03/28/2011 10:29 PM, Alan wrote: If you need it quoted in the "def" context: (defmacro def-entity-and-attrs [entity-name key attrs-name attrs] `(do (def ~attrs-name '~attrs) (ds/defentity ~entity-name ~(vec (concat ['^:key key] attrs) Note the ' before attrs. Thank you, works! PS why is there a ' before ^:key? It doesn't seem to me like it does anything. It compiles without, bu then the datastore won't use that argument as named-key, but fabricate a running number, instead. Now the fun is: [^:key key] leads to a datastore field "slug", as that's the argument for key, but it won't be used as named-key for the record. [':key key] fixes the use-as-named-key issue, but leads to a field called "key", not "slug" (datastore viewer lists named-key attributes twice, once as ID/name, once with its given name). The following do not work at all: [`^:key ~key] `[^:key ~key] -- Thorsten Wilms thorwil's design for free software: http://thorwil.wordpress.com/ -- 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
Macro compile vs run time, appengine-magic defentity
Hi! Defining an entity with appengine-magic is straightforward: (ns tlog.models (:require [appengine-magic.services.datastore :as ds])) (ds/defentity Article [^:key slug, title, body, created-t, updated-t]) But there are several places (other files), where that list sans the first element would be handy and I would like to avoid copy-pasting [title, body, created-t, updated-t]. ds/defentity is a macro and won't work if it sees functions at compile time (I hope this way to put it is acceptable, but tell me if my mental model is lacking). amaloy helped me with an almost-solution. The following works: (defmacro def-entity-and-attrs [entity-name key attrs] `(ds/defentity ~entity-name ~(vec (concat ['^:key key] attrs (def-entity-and-attrs Article slug [title, body, created-t, updated-t]) But it was meant to be: (defmacro def-entity-and-attrs [entity-name key attrs-name attrs] `(do (def ~attrs-name ~attrs) (ds/defentity ~entity-name ~(vec (concat ['^:key key] attrs) (def-entity-and-attrs Article slug attrs-name [title, body, created-t, updated-t]) Fails with: "Unable to resolve symbol: title in this context" Or if I quote the vector: "clojure.lang.PersistentVector cannot be cast to clojure.lang.Symbol" I guess trying to access attrs-name from elsewhere would have been "fun", anyway. I would love to simply (def article-attrs '[title, body, created-t, updated-t]) and work with that. It's not the first time I run into a situation where things beg to be composited/concatenated, but can't be, at least not easily. Any ideas? -- Thorsten Wilms thorwil's design for free software: http://thorwil.wordpress.com/ -- 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: Implicit unpacking of a map
On 03/25/2011 11:37 AM, Ken Wesson wrote: Interesting, but you just listed title and body twice, where the goal was to not list them at all (except in the definition of Article and in the html form, of course, though theoretically, the form could be generated from a a bit richer single definition, I suppose). I extracted them from save-article to what's basically a Clojure-friendlier constructor for Article. Is there a reason for you to consider this goal supremely important? Yes, it was the whole reason to not be satisfied with just destructuring in the signature. To be concise, avoiding any repetition. While perhaps enlightening, anything that makes me end up writing more, not less, is not practical. By now I'm rather sure this would trigger an error, as nothing but an immediate call of Article. seems acceptable for ds/save!. Why do you say that? Either your ds-save! is a function that accepts Article objects, and that apply expression returns one; or else your ds-save! is a macro that accepts an s-expression that will become part of its expansion and which works if it evaluates to an Article object at run-time, which the apply expression does. I say that because of what Meikel said at http://groups.google.com/group/clojure/msg/2f2b97b627da2d1d?hl=en and because my experiments suggest so. If for some reason you've made it a macro that accepts an s-expression, but parses it itself and expects it to be a constructor invocation, then I suggest you rewrite it to accept any s-expression. Otherwise, the style should be separate parameters, e.g. (defmacro ds-save! [classname& ctor-args]) to make it simpler to implement and to make it clear to its users that it cannot take general-purpose sexps that return the appropriate Java type. But really, it should accept pure function invocations happening in its context, at least -- and the only possibly-impure thing in the apply/getseq/new-article chain there is the Article constructor invocation itself, which would be there anyway. I didn't write it, it's part of appengine-magic. It appears in a defprotocol and if I get this right, is mapped to a save!-helper function in a defprotocol. So at my current level, I really couldn't have written that :) https://github.com/gcv/appengine-magic/blob/v0.4.0/src/appengine_magic/services/datastore.clj -- Thorsten Wilms thorwil's design for free software: http://thorwil.wordpress.com/ -- 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: Implicit unpacking of a map
On 03/25/2011 01:34 AM, Ken Wesson wrote: What about this? First, use :title and :body keywords instead of "title" and "body" strings as keys in form-params. Then define this utility function: (defn get-seq [m& kws] ((apply juxt kws) m)) which takes a map and one or more keywords (cannot be other types of key) and returns a seq (actually a vector) of the corresponding values, in order; do this I don't get to chose the keys, with wrap-params I get whatever is used in the form as strings, inside a :form-params inside the request map. (defn new-article [path timestamp title body] (Article. path title body timestamp)) Interesting, but you just listed title and body twice, where the goal was to not list them at all (except in the definition of Article and in the html form, of course, though theoretically, the form could be generated from a a bit richer single definition, I suppose). so you can use apply. And then this: (defn save-article [path form-params timestamp] (ds/save! (apply new-article path timestamp (get-seq form-params :title :body By now I'm rather sure this would trigger an error, as nothing but an immediate call of Article. seems acceptable for ds/save!. Really not a big deal, just Java-interop making things un-lispy. is neat and tidy and easily extensible to added form-params later (add them to the end of new-article's arg list and to the get-seq keyword list in the same order; pass them to the amended Article constructor appropriately). -- Thorsten Wilms thorwil's design for free software: http://thorwil.wordpress.com/ -- 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: Implicit unpacking of a map
On 03/24/2011 09:38 PM, Alan wrote: A macro should work fine if you use ~@ instead of just ~. (defmacro save-article [path form-params timestamp] `(ds/save! (Article. ~path ~@(vals form-params) ~timestamp))) Thanks for the suggestion, but: Unknown location: error: java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Symbol (I doubt I managed to introduce a mistake, as it looks alright with macroexpand.) -- Thorsten Wilms thorwil's design for free software: http://thorwil.wordpress.com/ -- 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: Implicit unpacking of a map
On 03/24/2011 05:40 PM, Meikel Brandmeyer wrote: The problem is the constructor call. With plain old clojure functions you could use apply, but Java method and constructor calls must be hard-wired in the bytecode (and hence at compilation time) (if I understood this correctly). Guess that's why a macro, which I tried out of sheer curiosity, doesn't work, either. So there will be now way around explicitly specifying the map keys. Although you can relieve the pain a little with destructuring as Tassilo already showed. It can be shorted a bit using :strs. (defn save-article [path {:strs [title body]} timestamp] (ds/save! (Article. path title body timestamp))) I had been using destructuring, just not in the example, where I had to have a whole form-params. :strs makes that quite a bit nicer, thanks! Looking for a bit more info, I found: http://groups.google.com/group/clojure/browse_thread/thread/a9504c4c9b1a4d9b explaining :strs, :keys and :syms. -- Thorsten Wilms thorwil's design for free software: http://thorwil.wordpress.com/ -- 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
Implicit unpacking of a map
Hi! The following simplified code works: (defn save-article [path form-params timestamp] (ds/save! (Article. path (form-params "title") (form-params "body") timestamp But I would like to not handle the content of form-params explicitly. My naive attempt that shows that I still have troubles with the evaluation model: (ds/save! (flatten `(Article. path ~(vals form-params) timestamp))) Fails with: "java.lang.IllegalArgumentException: No implementation of method: :get-entity-object of protocol: #'appengine-magic.services.datastore/EntityProtocol found for class: clojure.lang.Symbol" I take that I created a list that looks like the function call that I need, but that is not evaluated as such. Throwing in eval doesn't help. Can you shed some light on this? How can I accomplish not having to make the content of form-params explicitly? (Not to save on typing, more for my understanding.) -- Thorsten Wilms thorwil's design for free software: http://thorwil.wordpress.com/ -- 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: Extra params for a handler inside Ring's wrap-params
On 03/23/2011 02:32 PM, Thorsten Wilms wrote: Hi! Routing, using ring.middleware.params and net.cgrand.moustache: (def tlog-app-handler (app ["admin" &] {:get (app ...snip...) :post (app wrap-params [[path not-empty] &] submit-article)} Thanks to wrap-params, I can destructure request params within submit-article. However, I also want to have "path". Without wrap-params, it would simply be: (app [[path not-empty] &] (submit-article path)) (app wrap-params [[path not-empty] &] (partial submit-article path)) results in "nth not supported on this type: PersistentHashMap" Should have been: (app [[path not-empty] &] (wrap-params (partial submit-article path))) Which works, then. Thanks to the fine folks in #clojure, I have another solution: (app [[path not-empty] &] (wrap-params (fn [req] (submit-article req path -- Thorsten Wilms thorwil's design for free software: http://thorwil.wordpress.com/ -- 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: Emacs with Lisp and Clojure.
On 03/23/2011 08:07 PM, mmwaikar wrote: Now when I try to install swank-clojure, I get the following message - File exists: /home/manoj/.emacs.d/elpa/clojure-mode-1.7.1/clojure- mode.el I vaguely recall that I had the same problem and solved it by simply moving the existing clojure-mode.el out of the way. You can delete it, if that works. But - 1) There is no auto indentation (so when I go to the next line, after say (defn some[]), it starts with the first col. in this new line) Could be the job of Paredit (I'm not sure what does what, here). -- Thorsten Wilms thorwil's design for free software: http://thorwil.wordpress.com/ -- 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
Extra params for a handler inside Ring's wrap-params
Hi! Routing, using ring.middleware.params and net.cgrand.moustache: (def tlog-app-handler (app ["admin" &] {:get (app ...snip...) :post (app wrap-params [[path not-empty] &] submit-article)} Thanks to wrap-params, I can destructure request params within submit-article. However, I also want to have "path". Without wrap-params, it would simply be: (app [[path not-empty] &] (submit-article path)) (app wrap-params [[path not-empty] &] (partial submit-article path)) results in "nth not supported on this type: PersistentHashMap" assoc-param (see http://mmcgrana.github.com/ring/middleware.params-api.html) looks like it could be what I need, but I can't find out how to use it in this context (what wraps what and what is the right "map"?) I realize that I could extract "path" from the request map, but I would prefer a solution where what has been taken apart already is used, instead of repeating that work. -- Thorsten Wilms thorwil's design for free software: http://thorwil.wordpress.com/ -- 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: lein appengine-prepare
nevermind, in the hours it's been since I send this mail, I fixed that issue (a stray :main in my project file and the need to run "lein clean". On 03/21/2011 10:26 AM, Thorsten Wilms wrote: Hi! After working with appengine-magic a bit, I wanted to use the datastore viewer to see what's happening. So I tried "lein appengine-prepare" (is there another way?). From https://github.com/gcv/appengine-magic#readme: Testing with dev_appserver.sh 1. lein appengine-prepare. This AOT-compiles the entry point servlet, makes a jar of your application, and copies it, along with all your library dependencies, to your application's resources/WEB-INF/lib/ directories. 2. Run dev_appserver.sh with a path to your application's resources/ directory. But it fails with: "java.lang.Exception: No such var: appengine-magic.core/default-war-root (core.clj:64)" ... -- Thorsten Wilms thorwil's design for free software: http://thorwil.wordpress.com/ -- 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
lein appengine-prepare
Hi! After working with appengine-magic a bit, I wanted to use the datastore viewer to see what's happening. So I tried "lein appengine-prepare" (is there another way?). From https://github.com/gcv/appengine-magic#readme: Testing with dev_appserver.sh 1. lein appengine-prepare. This AOT-compiles the entry point servlet, makes a jar of your application, and copies it, along with all your library dependencies, to your application's resources/WEB-INF/lib/ directories. 2. Run dev_appserver.sh with a path to your application's resources/ directory. But it fails with: "java.lang.Exception: No such var: appengine-magic.core/default-war-root (core.clj:64)" My core.clj:64: (ae/def-appengine-app tlog-app #'tlog-app-handler) is exactly like in the readme and another, functioning project called ackbar. appengine-magic.core does not contain default-war-root directly, but has (if (in-appengine-interactive-mode?) (load "core_local") (load "core_google")) core_local.clj defn's default-war-root, but core_google.clj doesn't. Now this can't be called an interactive use, but I wonder if this switch does exactly what it's supposed to. On rereading, I have to note that With regard to AOT-compilation, if your project needs it, then you must include .app_servlet in Leiningen's :aot directive. Otherwise, omit the :aot directive altogether. The lein appengine-prepare task will take care of AOT-compiling the entry point servlet and cleaning up afterwards. Doesn't make it exactly clear to me, whether this :aot directive is required for appengine-prepare, or not. Adding ":aot tlog.app_servlet" to me project file makes the "No such var" error go away, but: $: lein appengine-prepare preparing App Engine application tlog for deployment Exception in thread "main" java.lang.RuntimeException: java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Symbol (NO_SOURCE_FILE:0) at clojure.lang.Compiler.eval(Compiler.java:5440) at clojure.lang.Compiler.eval(Compiler.java:5391) at clojure.core$eval.invoke(core.clj:2382) at clojure.main$eval_opt.invoke(main.clj:235) at clojure.main$initialize.invoke(main.clj:254) at clojure.main$script_opt.invoke(main.clj:270) at clojure.main$main.doInvoke(main.clj:354) at clojure.lang.RestFn.invoke(RestFn.java:458) at clojure.lang.Var.invoke(Var.java:377) at clojure.lang.AFn.applyToHelper(AFn.java:174) at clojure.lang.Var.applyTo(Var.java:482) at clojure.main.main(main.java:37) Caused by: java.lang.RuntimeException: java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Symbol at clojure.lang.LazySeq.sval(LazySeq.java:47) at clojure.lang.LazySeq.seq(LazySeq.java:56) at clojure.lang.RT.seq(RT.java:450) at clojure.core$seq.invoke(core.clj:122) at leiningen.compile$find_namespaces_by_regex.invoke(compile.clj:36) at leiningen.compile$compilable_namespaces.invoke(compile.clj:51) at leiningen.compile$compile.invoke(compile.clj:249) at leiningen.appengine_prepare$appengine_prepare.invoke(appengine_prepare.clj:31) at clojure.lang.Var.invoke(Var.java:365) at clojure.lang.AFn.applyToHelper(AFn.java:163) at clojure.lang.Var.applyTo(Var.java:482) at clojure.core$apply.invoke(core.clj:542) at leiningen.core$apply_task.invoke(core.clj:191) at leiningen.core$_main.doInvoke(core.clj:250) at clojure.lang.RestFn.applyTo(RestFn.java:138) at clojure.core$apply.invoke(core.clj:542) at leiningen.core$_main.invoke(core.clj:255) at user$eval175.invoke(NO_SOURCE_FILE:1) at clojure.lang.Compiler.eval(Compiler.java:5424) ... 11 more Caused by: java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Symbol at clojure.lang.RT.seqFrom(RT.java:471) at clojure.lang.RT.seq(RT.java:452) at clojure.core$seq.invoke(core.clj:122) at clojure.core$filter$fn__3714.invoke(core.clj:2130) at clojure.lang.LazySeq.sval(LazySeq.java:42) ... 29 more This leaves me totally puzzled. Note that my project does compile, otherwise. So, do I need :aot, am I stumbling over a bug in appengine-magic, is it yet another case of having overlooked some detail ...? -- Thorsten Wilms thorwil's design for free software: http://thorwil.wordpress.com/ -- 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: Better Workflow with App Engine?
On 02/16/2011 05:10 PM, Rasmus Svensson wrote: With the web server up an running, I open up http://localhost:8080/ in my browser. Now, lets assume that I want to change the "Hello, world!" text to "Hello, Clojure-land!". I open the controller.clj file, edit the corresponding line and press C-M-x somewhere within the defn form to evaluate it. The change is then visible directly when refreshing the page in the browser. If I have written a new function in the controller namespace and want to try it in the repl, I first enter the namespace by pressing C-c M-p in the controller.clj file. The slime repl is now in that namespace, and I can, for instance, evaluate (my-app {:uri "/test", :request-method :get}). I must have read about C-M-x, but it didn't "click". Many thanks for your excellent answer, it's already making me a much happier camper :) -- Thorsten Wilms thorwil's design for free software: http://thorwil.wordpress.com/ -- 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
Better Workflow with App Engine?
Hi! I managed to get to a "Hello world" level using appengine-magic, plus an Emacs Swank/Slime setup. While I'm pretty sure I won't look back to Python regarding the language itself, I already miss the speed and simplicity of just saving, switching to a browser, reloading and seeing results. How would I best go about writing a script that starts swank, emacs (with project files), automatically connects slime and evaluates a few lines in the slime REPL (switch namespace, compile, run Jetty ...)? None of this should happen, if I just start Emacs to work on anything else. Would it be sensible/feasible to somehow hook compiling of the core to saving any .clj file in Emacs? Or would monitoring the filesystem and recompile on changes, daemon-style be better, and if so, how to accomplish that? -- Thorsten Wilms thorwil's design for free software: http://thorwil.wordpress.com/ -- 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