New Library for Berkeley DB
Hey all, I couldn't find a good set of bindings that wrapped most of the BDB's features so I wrote my own. This library covers most of its basic feature, wrapping cursors, transactions, and key value functionality in more idiomatic clojure. You can check it out on http://bitbucket.org/mebaran/bdb-clojure/. I'll be adding more documentation, some more tests and a lazy interface in the next couple of days. If anybody has any good ideas for an interface to index and persist and nested hashmaps while indexing their values by either word or number, I'll be much obliged I'm planning to try to use this as the basis for a more completely package for clojure data structure persistence. Any tips how to improve the library coe structure or further its development will be much appreciated. Hope it's useful to somebody, 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 -~--~~~~--~~--~--~---
Re: Package manager proposal
I like the name Clojure Archive. On another note, I always wondered why xml was such a requirement for Java dependency management. Couldn't we design some sort of url schema, that you could just pass to a package importer in the program. First time you run, it could fetch the packages or automatically check for upgrades etc. This could be managed in an external file if that seems safer. Just a simple manager that could wget the jars (which is all essentially that package managers like ruby gems do). On a slightly unrelated note, how might we index packages for exploration? I think that packages should be indexed both by descriptions provided by the author and by comments within the code itself, in the docstrings of the fn's. Eventually, maybe we could cherry pick namespaces and even pull specific functions! 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 -~--~~~~--~~--~--~---
Re: leiningen - a Clojure build tool
Was the name Leiningen inspired by the Esquire short story "Leiningen vs. Ants"? That would be a brilliantly obscure way to challenge the predominance of ant. Or did you have another reference in mind. Mark On Nov 18, 2:29 am, Phil Hagelberg wrote: > I'm pleased to announce the initial release of Leiningen. > > Leiningen is a build tool for Clojure designed to not set your hair on fire. > > Building Clojure projects with tools designed for Java can be an > exercise in frustration. If you use Ant, you end up copying around a > lot of the same tasks around between XML files on all your projects; > there's a lot of repetition. Maven avoids repetition, but provides > very little transparency into what's really going on behind the scenes > and forces you to become a Maven expert to script a nontrivial > build. Either way you end up writing far more XML than is necessary. > > With Leiningen, your build is described using Clojure. You can put any > code you like in your project.clj file; the only requirement is that > it includes a call to defproject. You can define your own tasks in > there if you need to, but the majority of projects should be able to > get by on the tasks that are provided with Leiningen. If you do find a > common task that you need to add, you can implement it as a plugin > rather than copying and pasting among each of your projects. > > Projects are defined with Clojure syntax, (not XML!) in project.clj: > > (defproject leiningen "0.5.0" > :description "A build tool designed not to set your hair on fire." > :main leiningen.core > :dependencies [[org.clojure/clojure "1.1.0-alpha-SNAPSHOT"] > [org.clojure/clojure-contrib "1.0-SNAPSHOT"] > [ant/ant-launcher "1.6.2"] > [org.apache.maven/maven-ant-tasks "2.0.10"]] > :dev-dependencies [[org.clojure/swank-clojure "1.0"]]) > > A number of tasks are provided: > > $ lein deps # install dependencies in lib/ > > $ lein test [PRED] # run the project's tests, optionally filtered on PRED > > $ lein compile # ahead-of-time compile into classes/ > > $ lein repl # launch a REPL with the project classpath configured > > $ lein clean # remove all build artifacts > > $ lein jar # create a jar of the project > > $ lein uberjar # create a standalone jar that contains all dependencies > > $ lein pom # output a pom.xml file for interop with Maven > > $ lein install # install in local repo (currently requires mvn) > > $ lein help [TASK] # show a list of tasks or help for a given TASK > > Leiningen is extensible, you can define new tasks in project.clj or in > plugins. Add your plugin as a dev-dependency of your project, and you'll > be able to call "lein $YOUR_COMMAND". See the lein-swank directory for > an example of a plugin. > > To install simply download the shell script, place it somewhere on your > $PATH, and run "lein self-install": > > http://github.com/technomancy/leiningen/raw/master/bin/lein > > Many people have expressed frustration at trying to use a tool designed > for Java with their Clojure projects, especially when dealing with > dependencies. I hope this can move things forward and ease the > pain. Note that it's still a very young project, (started about two > weeks ago), but in classic Clojure fashion it is able to leverage a lot > of functionality from other JVM tools. > > Please try it out and let me know how it works for your project! > > thanks, > Phil > > Bonus: Leiningen also integrates with the Clojars open-source > clojure-specific repository coming soon athttp://clojars.org. -- 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: STM style disk persistance
You might also want to check out Redis, which is supposed to act like disk persistent data structures in memory. The author just added a virtual memory module, so now Redis can handle datasets larger than the memory you assign it. Mark On Jun 22, 10:57 am, Timothy Baldridge wrote: > Greetings, > > I've recently started learning Clojure. For the past year or so I've > been using CouchDB, and am very happy with the MVCC disk storage > system it uses. Has anyone tried marrying the two system systems to > create a truly persistent data primitive where any "updates" to a map > is written to the disk? > > To me this seams like a awesome opportunity for Clojure. If we could > create maps/vectors/whatever and read/"write" to them and have their > contents somehow stored in on disk, complete with transactional style > support, clojure could basically have a built-in database system that > could be used in countless situations. > > So has anyone tried this? If not, I may just give it a whirl, and > others would be welcome to help. > > Timothy Baldridge > > -- > “One of the main causes of the fall of the Roman Empire was > that–lacking zero–they had no way to indicate successful termination > of their C programs.” > (Robert Firth) -- 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: On retrieving auto-generated IDs after INSERT
I have my own custom version where I bind the generated keys in the metadata of the returned seq. I think that's only valuable for clojure 1.2 though. The problem with returning an int is that many keys might be generated, though by the far the most common usage is simply an autoincrement column on id. Mark On Aug 11, 1:25 am, Shantanu Kumar wrote: > Noticed that thread earlier. I hope this fresh thread is noticed by > Stephen (C. Gilardi) and others and a consensus can be reached on this > to do in c.c.sql proper. > > Cheers, > Shantanu > > On Aug 11, 1:15 pm, Remco van 't Veer wrote: > > > There was a thread about this some months ago; > > > http://groups.google.nl/group/clojure/browse_thread/thread/e95d477830... > > > Somebody came up with his own version of insert-record: > > > http://gist.github.com/373564#LC62 > > > On 2010/08/11 09:10, Shantanu Kumar wrote: > > > > Hi, > > > > I need to retrieve auto-generated IDs after executing INSERT > > > statements (c.c.sql/insert-values ...). Inspecting c.c.sql sources > > > reveals that (in c.c.sql/do-prepared) a prepared statement is made > > > with the connection and then the SQL statement is run in that context. > > > It appears there is a standard API to retrieve the auto-generated IDs: > > > >http://download-llnw.oracle.com/javase/6/docs/api/java/sql/Statement() > > > > However, this method needs the (prepared) statement object to run. I > > > would suggest adding another "do-prepared-insert" method that does > > > same things as do-prepared but rather return the following: > > > > (.getGeneratedkeys stmt) > > > > Function "insert-values" may be made to call "do-prepared-insert" to > > > suit this. > > > > Cheers, > > > 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
Re: inserting into vector
(defn insert [v at el] (flatten (assoc v at [el (v at)])) You get a lazy seq back, so further operations are probably not as performant as they should be. But that would be as performant as a regular assoc for just that one operation. What you do from then on. Mark On Aug 26, 10:33 am, Chouser wrote: > On Thu, Aug 26, 2010 at 12:43 PM, David Nolen wrote: > > On Thu, Aug 26, 2010 at 11:53 AM, Chouser wrote: > > >> On Thu, Aug 26, 2010 at 9:44 AM, Jon Seltzer > >> wrote: > >> > I know what assoc does: > > >> > user=> (assoc [\a \b \c] 0 \d) ;please extend to much larger vector > >> > with index somewhere in the middle > >> > [\d \b \c] > > >> > but what if I want: > > >> > user=> (assoc-x [\a \b \c] 0 \d) ;is there an assoc-x > >> > [\a \d \b \c] > > >> > I don't see a function that does this. I'm sure I'm missing it. I, > >> > of course, know this could be done with a combination of other > >> > functions like subvec and/or into but it seems fundamental enough to > >> > have its function. > > >> The internal structure of vectors is such that this cannot be > >> done efficiently, which is why no function to do it is included > >> in clojure.core. You can do it inefficiently like this: > > >> (let [v '[a b c d e f] > >> i 3] > >> (into (subvec v 0 i) (cons 'X (subvec v i > >> ;=> [a b c X d e f] > > >> That's about as good as you're going to get with vectors, O(n) > >> where n is (- (count v) i). > > >> --Chouser > >>http://joyofclojure.com/ > > > How is the performance of your FingerTrees looking? ;) > > David > > I'm actually working on it again, now that the book is requiring less > time. When it's ready, I won't be shy about announcing it. :-) > > --Chouserhttp://joyofclojure.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: defrecord with "inheritance"
I think it's misleading to use inheritance to reduce code duplication. Inheritance is about indicating function typing and creating typed contracts, both of which are fairly un-idiomatic in Clojure. However, there is another way to prevent code duplication: use composition instead. Instead of having the Employee class mirror the attributes of the Person (which if you really wanted, you could easily do via a "defperson" like macro that would slug on extra fields), why not have an Employee carry a Person as one of its attributes? This approach is more similar to the Haskell/functional way of working with record types (I think Haskell's newtype operator works similarly under the covers). There is also an analogue to the decorator pattern in Java. In this case, you would specify a Personable protocol, which both Person and Employee implement; for all the basic operations, Employee would just defer to its internal person. Example: (defrecord Person [name birthday]) (defrecord Employee [title person]) (defprotocol Personable (name [this]) (age [this)) (extend-protocol Personable Person (name [this] (:name this)) (age [this] (date-dif (java.util.Date.) (:birthday this)) ;;date diff defined elsewhere Employee (name [this] (name (:person this)) (age [this] (age (:person this))) Arguably, if we were deferring to the current Java best practices and encapsulation, one should be creating interfaces of getters and setters rather than directly accessing instance variables anyway, making the extra protocol definition no more work than doing it correctly in modern Java. Best, Mark On Sunday, May 20, 2012 10:22:55 AM UTC-7, Warren Lynn wrote: > > So from what I read the philosophy of Clojure discourages inheritance > on concrete data types. However, maybe I am too entrenched in my OO > thinking, how do I define a new record type that includes all the data > members of another record type? I am thinking about the classic > Employee/Person example. > > If I can define a record of Employee with Person's data members > included, even that is not true inheritance (as no protocols of > "Person" will be automatically extended to "Employee"), I need that > for function re-use (so a function working on Person will > automatically work on Employee because Employee is guaranteed to have > all the data members in Person). > > Also, again, maybe I am too OO minded, is there a way inherit another > record type's protocol implementation? That seems to give the best > combination of both worlds (OO and functional), so you can either have > you own very customized combination of data type/protocols, or use the > very common OO pattern. Just like we have both the single-typed > dispatching (which is more OO like and covers a large portion of use > cases), and more advanced multimethods. > > 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
Re: defrecord with "inheritance"
Hey Luc, That's a cool casting strategy to cleanly build a standard way to get at the person piece of any type of applicable record. In the pure composition case, it's actually a nice solution to build functions know how to unpack the Person aspect of a subtype. However, I think which strategy is best depends very much on whether you plan to extensively change the protocol implementation between the the different related types. In the case where Employee simply carries extra information with regard to a person, I agree that it is nice simply to define a mechanism to extract the base type and just act on it directly. However if you wish to do something more complicated or override default behavior extensively, I think the encapsulated "newtyped" way is more convenient. For example, how about we build a little DSL to represent different types of Excel cells. In Excel, everything is represented as a float, so we have to keep track of the type separately. I think using a record type is a fairly natural way to encode this extra data on type of Cell, where I might have reached for inheritance in traditional OOP. (defprotocol Convertable (convert-cell [this])) (defrecord Cell [row col float-value]) (defrecord MoneyCell [cell]) (defrecord DateCell [cell]) (defrecord NumberCell [cell]) (extend-protocol Convertable NumberCell (convert-cell [this] (float (-> this :cell :float-value)) DateCell (convert-cell [this] (excel-date (-> this :cell :float-value)) ;; Translate an Excel datestamp to java.util.Date MoneyCell (convert-cell [this] (bigdec (convert-cell (Number (:cell this) ;;BigDecimals are for exact money handling. Blindly unpacking the Cell type (via a Cellable convention like in the Person example) would lose information we need to accurately describe the conversion process and call the best function. This strategy also leverages ones of the best aspects of protocols: how extensible they are to new types of data. If I ever decide to support a StringCell type or a BooleanCell, I would just be one extend-protocol away rather than having to rewrite some gnarly embedded cond to work with my new type of cell. Of course for operations that don't care about their type, creating a protocol to extract the cell and working directly with its attributes (such as manipulating row and position directly), makes a great deal of sense. Best, Mark On Monday, May 21, 2012 10:09:02 PM UTC-7, Luc wrote: > > Interesting demonstration, except for one thing, defining getters is a > waste of > time :) > > When you need to define accessors, you start to run into inefficient use > of > your time. It still a bearable workload in Java because of all this heavy > tooling that allows > to select for which fields accessors will be generated. > Without getters, you would also expose mutable stuff to the universe. > > However in Clojure the values are not mutable... Why bother defining > an accessor to a read-only value ? > > A better way would be something like: > > (defprotocol Personable > (person [this]) > (age [this] ) > > (defprotocol CensusOperators > (age [this])) > > (extend-protocol Personable > Person > (person [this] this) > Employee > (person [this] (:person this))) > > (extend-protocol CensusOperators > Person > (age [this] (date-dif (java.util.Date.) (:birthday this) > > Much more convenient to me. I can take anything and make it a person. > Even from a Clojure map just by extending it and returning a Person > instance. > You expose the Person abstraction when available instead of hiding it. > > Computed values like the age ? This is something that could be computed > for other entities like an animal. > > So you can write (age (person )) or (age (animal )). > > This is why I tell people to get out of their usual thinking process. Get > lazy, > playing hide and seek was fun at pre-school age but in your code and data > structures ? > > Luc P. > > > > I think it's misleading to use inheritance to reduce code duplication. > > Inheritance is about indicating function typing and creating typed > > contracts, both of which are fairly un-idiomatic in Clojure. > > > > However, there is another way to prevent code duplication: use > composition > > instead. Instead of having the Employee class mirror the attributes of > the > > Person (which if you really wanted, you could easily do via a > "defperson" > > like macro that would slug on extra fields), why not have an Employee > carry > > a Person as one of its attributes? This approach is more similar to the > > Haskell/functional way of working with record types (I think Haskell's > > newtype operator works similarly under the covers). There is also an > > analogue to the decorator pattern in Java. > > > > In this case, you would specify a Personable protocol, which both Person > > and Employee implement
Re: accessing multiple return values
I see two fairly straightforward paths to simulating multiple returns without breaking existing callers. Both take advantage of thread-local state and establish one convention for the caller: before calling the function again, every caller interested the extra return values must ask for these extra returned values before calling the function again. 1. Use and Abuse VarsThe multiple return idea sounds a lot like the global errno facility used commonly in C to communicate out of band errors that cannot be conveniently conveyed via the function's actually return, except with namespacing to help multiple functions cooperate for the scarce resources. That bit of magic can be pretty nasty and metadata usually solves the majority of cases needed to move that auxiliary information (errno changed from a simple global variable to a complicated macro with the advent of multi-threaded C applications). However, in cases that metadata simply is unavailable, one way might be to augment the run time system with a mapping of functions to a thread local store of this auxiliary information just like errno. Clojure already comes with batteries to handle this case called push- thread-bindings. Push-thread-bindings allows a function to arbitrarily associate data with predetermined vars, and get-thread- bindings provides a function to retreive the information stored in the thread. Then, all that would be necessary to establish multiple returns would be to establish a dynamic var associated with each function that wanted to be able to return multiple objects. The interested caller would just know to read this preveriously var (probably via macro) to get the extra data it wanted. The only downside is that, per the documentation, push-thread-bindings does not handle its own housekeeping: it requires the calling function to ensure that the thread bindings are cleaned up via pop-thread- bindings, called in a finally block. This, of course, is not ideal, because the function that establishes the extra information can't be sure when or even if its own caller will use it! A more magical push- thread-bindings that could clean up after itself upon thread completion is necessary. Essentially, it sounds like dynamic vars work basically the way you want. If there is a good way to garbage collect them when the thread dies, a couple macros will make implementation relatively straightforward. By the way, more flexibly handling dynamic vars seems to be part of a general goal for the future: http://dev.clojure.org/display/design/Improve+Binding. Directly using the ThreadLocal class might also provide you with all the machinery necessary to implement this idea and provide garbage collection for free on thread completion. 2. Use and Abuse Metadata on the FunctionSimilar to memoize, we could store extra return values in function's own metadata via an atom that mapped Java thread-id's to extra return values. To return an extra value, the function would simply grab its own metadata set an extra return value by thread-id. Callers wanting to access this extra data would be provided a macro to look this value up on demand, probably passing the function (something like (return-more! f)). Subsequent calls could just continually update this value. This essentially would emulate thread-local variables though, so the first approach is probably preferable. Either way, this sounds like it might be implementable via a nice little library without having to change the language at all, with very little namespace mucking required. Hope that helps,Mark On Jan 3, 12:24 pm, nchurch wrote: > > I think, I'll stop here. You won't convince me that this approach is > > practicable anytime soon. ;-) > > I certainly won't try too hard either. I'm not questioning here > whether it is immediately practicable to implement (maybe not, and in > case a very long discussion) but is it potentially useful? (A shorter > discussion.) > > In answer to your questions: > > The name of a returned value, of course, \does become part of the > interface. Perhaps library writers would want to have a discipline of > using their own internal names and then passing them out in one final > values call inside of a let. > > As to the second: the recursive (bar ...) call has no effect on any > foo-values used outside of it, whether before or after. This accords > with our expectation for how functions work. > > Think of Values as a magical macro that \at \runtime reaches outside > of the function it was used in and writes a little let inside the > calling function's scope. Is this possible? I don't think so. > Presumably it would have to be part of the language, just like Values > is part of Common Lisp. -- 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,
Re: Override print-method of struct
Instead of using a ref, you might consider using a closure, which seems a little more functional. So every child would simply store a function that when called would return the map of the parent, map you capture using a closure. This would also reduce your printing problems because functions just print their classname, and you would know that the function brings you back to the parent. I did this for a Neo4j wrapper I wrote to idiomatically represent traversing webs and trees. Would that help anyway? Then you wouldn't have to worry about messing with redefining prints or using alters. The thunk would be created as part of the process. Mark On Oct 13, 4:21 pm, andrei wrote: > That works, thanks! > > Yeah, I understand that it is not the best data structure to use. The > task is to create a tree, and it is needed to get all children and all > parents of specified node in this tree in a constant time. So, I > cannot see another way to do it except storing refs both from parents > to children and from children to parents. > > On Oct 14, 12:40 am, Laurent PETIT wrote: > > > > > You can add a :type metadata to your maps, and this can be catched by the > > (type) method of multimethods. > > > But if you have parent -> child -> parent -> child ... relationships, I > > guess that you're building a tree made of mixins of maps and refs to maps > > ... and indeed this should bell some rings in your head if you haven't > > already carefully balanced alternative choices ... > > > 2010/10/13 andrei > > > > How can I override print-method for a map, defined with defstruct? > > > > I have to create object hierarchy: one map is a parent for another, > > > i.e. it holds link to a child, and another is a child for the first > > > one, i.e. holds link to a parent. When I try to print it, I get > > > StackOverflowError since printer tries recursively print objects: > > > > parent -> child -> parent -> child -> > > > > The best solution I see is to override print-method or str, so the > > > printing will go normally. I found this topic: > > > >http://groups.google.com/group/clojure/browse_thread/thread/4a675222f... > > > > which shows how to override print-method for objects defined by > > > deftype, but is there a way to do same trick for maps? Maybe it is > > > possible to add some special tag to object's meta? Or to redefine > > > print-method in the only namespace? > > > > Or maybe I'm just looking at the wrong direction? > > > > -- > > > 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 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