Re: [ANN] New blog post on Perfumed Nightmare

2024-05-01 Thread Gary Johnson
Daniel Szmulewicz  writes:

> Greetings fellow Clojurians,
>
> I am excited to announce the publication of my latest in-depth blog
> post on the topic of HTTP and web application development. Since I am
> currently looking for work, I had the opportunity to dedicate my
> mornings - when I’m at peak mental clarity - to creating this content
> over the course of a week.

Hi Daniel,

  Thanks for sharing your post on building a dependency-free, minimal
HTTP server. In the same vein, I thought you (and perhaps some others
on this mailing list) might be interested in seeing my
dependency-free, minimal Gemini server, Space-Age. I built it several
years ago when the Gemini protocol was just firming up, and I've had
great fun in using it to run both my personal site and the software
team wiki at my workplace.

Since it is also written in Clojure without any dependencies on third
party libraries, its socket management code looks quite a lot like
yours but also includes features for encryption and authentication
over SSL/TLS with X.509 certificates. Here's the link if anyone is
interested:

https://gitlab.com/lambdatronic/space-age

The smallnet/smolnet is a real breath of fresh air after being
inundated by the every increasing corporatization of the web over the
last few decades. And from a learning perspective, working with much
simpler, alternative communication protocols greatly increases
accessibility for both users and developers and may even encourage you
to whip up your own Gemini server or client as a weekend project.

Have fun and happy hacking!
  Gary

-- 
GPG Key ID: 7BC158ED
Use `gpg --search-keys lambdatro...@gmail.com' to find me
Protect yourself from surveillance: https://emailselfdefense.fsf.org
===
()  ascii ribbon campaign - against html e-mail
/\  www.asciiribbon.org   - against proprietary attachments

Why is HTML email a security nightmare? See https://useplaintext.email/

Please avoid sending me MS-Office attachments.
See http://www.gnu.org/philosophy/no-word-attachments.html

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/clojure/87y18ty2zz.fsf%40gmail.com.


Re: Can't start figweel.main on other Linux-machine

2023-11-28 Thread Gary Johnson
ru  writes:

> I moved a working project from one Linux-machine to other.
> And that's what I got:
>
> ru@ru-sitrol:~$ cd clojure/pro-figweel/
> ru@ru-sitrol:~/clojure/pro-figweel$ clojure -m figweel.main -b dev -r

8<-->8

  Downloading from clojars and error messages elided

8<-->8

> "Could not locate figweel/main__init.class, figweel/main.clj or
> figweel/main.cljc on classpath."}}
>
>
> What can be reason of this?
> Any help would be greatly appreciated.
>
> Sincerely,
>   Ru

Hi Ru,

  You are the victim of a typo, I'm afraid. You forgot the "h" in
"figwheel". The correct command should be:

```
ru@ru-sitrol:~/clojure/pro-figweel$ clojure -m figwheel.main -b dev -r
```

Have fun and happy hacking!
  Gary

-- 
GPG Key ID: 7BC158ED
Use `gpg --search-keys lambdatro...@gmail.com' to find me
Protect yourself from surveillance: https://emailselfdefense.fsf.org
===
()  ascii ribbon campaign - against html e-mail
/\  www.asciiribbon.org   - against proprietary attachments

Why is HTML email a security nightmare? See https://useplaintext.email/

Please avoid sending me MS-Office attachments.
See http://www.gnu.org/philosophy/no-word-attachments.html

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/clojure/87y1ehcuvx.fsf%40gmail.com.


[ANN] Job Opening for Full Stack Web Developer

2020-12-01 Thread Gary Johnson
Howdy Clojurians,

  Spatial Informatics Group (SIG) is seeking a new Full Stack Web
Developer to build Clojure/Clojurescript web applications in the realm
of environmental mapping and modeling.

The position is fully remote, but applicants with work hours that
correlate well with North American time zones are preferred.

SIG is an environmental think-tank, comprised of around 35 core members
with backgrounds in natural resource management, city and urban
planning, wildland fire science, hydrologic modeling, carbon credit
trading, forest management, remote sensing, computer science, and
environmental mapping and modeling.

Applicants should be comfortable building Clojure web apps built on a
stack like Ring+Jetty+Reagent+Herb+OpenLayers+next.jdbc+Postgresql,
building projects with the Clojure CLI tools (deps.edn), collaborating
over Github/Gitlab with clean branch management and code reviews, and
deploying to remote GNU/Linux VMs over SSH. Strong communication skills
are a must since all of our work will be done online.

Experience with GIS and geospatial analysis and data sharing with tools
like GDAL/OGR, PostGIS, and GeoServer are a definite plus.

Apply here:

  https://boards.greenhouse.io/spatialinformaticsgroup/jobs/4223818003

Learn more about SIG here:

  https://sig-gis.com/

Happy hacking,
  Gary

-- 
GPG Key ID: 7BC158ED
Use `gpg --search-keys lambdatronic' to find me
Protect yourself from surveillance: https://emailselfdefense.fsf.org
===
()  ascii ribbon campaign - against html e-mail
/\  www.asciiribbon.org   - against proprietary attachments

Why is HTML email a security nightmare? See https://useplaintext.email/

Please avoid sending me MS-Office attachments.
See http://www.gnu.org/philosophy/no-word-attachments.html

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/clojure/87h7p5dxak.fsf%40gmail.com.


Re: first time without state - and I'm lost

2020-06-04 Thread Gary Johnson
Hi Scaramaccai,

Several posters in this thread have given you example code for how
to solve your OAuth token problem in Clojure. Perhaps I can add to
this discussion by pointing out the fundamentals of functional
programming that can help you decide how to solve problems like
this.

*Loops -> Recursions and State -> Bindings*

You asked how to handle state in a functional programming language.

In some situations, it may be easiest to just store stateful values
in a mutable container type like a ref, agent, or atom. This is not
a strictly functional approach, but these are tools that Clojure
provides to make a variety of programming tasks somewhat easier (in
the Rich Hickey sense of the word).

In many cases, this is neither necessary nor preferable. Instead,
you can use the functional programming approach of emulating state
change over time by passing your new derived values as arguments to
the next step in a recursive function.

That is, in FP "state change" happens on the stack (through
function bindings and let bindings) rather than on the heap
(through direct assignment to mutable containers).

Consider these two approaches to computing the factorial function.

*1. Imperative (loops + mutation)*

(defn fact-imp [n]
  (let [result (atom 1)]
(dotimes [i n]
  (swap! result * (inc i)))
@result))

*2. Functional (recursion + fn bindings)*

(defn fact-rec [n]
  (if (<= n 0)
1
(* n (fact-rec (dec n)

These two implementations will return the same outputs for the same
inputs. Note that in the functional approach, fact-rec computes the
next value of the result and passes it as the input to itself
rather than mutating a local variable as in the imperative case
with fact-imp.

Savvy readers will notice that fact-rec is not tail recursive and is
therefore prone to stack overflow for large values of n. Rewriting
it to work with loop+recur is left as an exercise for the reader. ;)

The approach shown above is a typical solution for state that goes
through a series of intermediate changes to produce a final result.

A similar approach for the same issue is to model all the values
that you would have stored one at a time in a stateful variable as
an immutable sequence of values. This approach relies on lazy
evaluation.

To illustrate, I will once again implement factorial using this
technique.

*3. Functional (sequences + lazy evaluation)*

(defn fact-lazy [n]
  (letfn [(next-step [[i x]] [(inc i) (* x (inc i))])
  (fact-seq [pair] (lazy-seq (cons pair (fact-seq (next-step pair
)]
(second (nth (fact-seq [0 1]) n

In this example, next-step derives the next state value from the
current one. The fact-seq function returns a lazy sequence of all
the [i factorial(i)] pairs from [0 1] to [infinity
factorial(infinity)]. This sequence is obviously never fully
realized since it would throw your application into an infinite
recursion. We then use nth to grab the [n factorial(n)] pair off of
the lazy sequence and second plucks out just factorial(n) to return
as the result of our fact-lazy function.

Once again, I never mutated any variables in place. I simply
created a recursive algorithm that could derive the next value from
the current value. Unlike the non-tail-recursive fact-rec above,
this lazy sequence implementation is immune to stack overflow
errors. However, fact-lazy will use more memory and more CPU cycles
than fact-rec's eager implementation because it has to create and
release the lazy sequence and intermediate vector pairs. These are
all tradeoffs, which you would need to consider in determining the
approach that might work best for your problem.

*Hiding State*

In the three approaches I showed to represent state change in your
Clojure program, none of these went out of their way to either hide
or share the state values over time. Here, you again have broadly two 
choices:

*1. Global mutable variables*

If you don't need to hide your application state, the best approach
is just to store it in a global mutable container like a ref, agent,
or atom. Then you can introspect or manipulate it from your REPL,
and multiple functions in your program can all access it as needed.

(def state (atom 0))

*2. Closures*

If you need to hide your application state for some reason (and
there are often less reasons to do this than you might imagine),
then your best friend is a closure function. A closure is a
function which "closes over" the bindings which exist when it is
defined by capturing references to them in its free variables
(i.e., variables which are not bound as function args or let args
in the function body).

Functions that return closures around mutable state can work
a bit like OOP constructor functions, creating a function that
behaves a bit like an object with internal stateful attributes.
Welcome to OOP inverted!

(defn get-token
  "Somehow get an OAuth token for this user+pass combination."
  [user pass]
  {:token   "some-token" ; replace this with something real
   

Re: WebApp authentication and authorization - up-to-date information?

2020-03-24 Thread Gary Johnson
Hi folks,

While it's not directly to your point, here is a pretty complete (IMHO) 
repository that I put together for getting you going with a new 
Clojure+Clojurescript website:

https://gitlab.com/lambdatronic/clojure-webapp-template

Just clone it and check out the README.md file for a description of the 
build and runtime software requirements, build aliases, and expected usage 
in development and production modes. All of the build config files are 
built around the tools.deps clojure command-line interface and use a modern 
version of figwheel for development.

The deps.edn file contains aliases to:

1. Initialize a Postgresql database, including custom Clojure code that 
provides a simple "namespace"-like dependency system for your SQL files 
using a topo-sort procedure for dependency resolution. If you prefer to use 
a different database, you could easily tweak build_db.clj and create_db.sql 
to meet your needs.

2. Compile your CLJS code into app.js using advanced compilation settings 
(for production deployment).

3. Compile your CLJ code and launch an embedded Jetty web server on a port 
that you specify (or 8080 by default).

4. Launch Figwheel, compile your CLJS code into app.js using {optimizations 
:none} (for rapid development), launch an embedded Jetty web server on port 
8080, and automatically hotload any live changes to your CLJS files into 
your browser session and live changes to CLJ files into your server 
(available on browser refresh).

In addition, the Clojure code provides a pre-configured middleware stack 
with custom middlewares for request and response logging, exception 
handling, and parsing EDN params in the request object. There is also 
simple routing-handler function using plain old Clojure with some helper 
function to render HTML and EDN/JSON responses that you can extend or 
replace to meet your objectives.

Super-cool features include a pre-configured system of routes, CLJ 
handlers, and asynchronous CLJS functions (using core.async) that allow you 
to trivially call SQL functions directly from Clojure (synchronously) and 
to call both CLJ and SQL functions from Clojurescript (asynchronously) 
using a similar calling syntax. All database interaction is done through 
Sean Corfield's excellent next.jdbc library.

In my usual programming model, I encode any operations that should happen 
in the database as SQL functions in Postgresql. These are loaded by my 
`clojure -A:build-db only-functions` alias. Then from Clojure, I can call 
these SQL functions like so:

```clojure
(call-sql "contact.get_user" user-id)

;;=> [{:name "Rich Hickey" :residence "Hammock"}]
```

Alternatively, I can call the same function from Clojurescript like so:

```clojure
(def my-contact (atom nil))

(go
  (reset! my-contact ( [{:name "Rich Hickey" :residence "Hammock"}]
```

You can do the same thing with CLJ functions from CLJS like so:

```clojure
(def cool-result (atom nil))

(go
  (reset! cool-result (http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/clojure/1954346f-ed06-4b66-a6d3-3d7ac5a4db87%40googlegroups.com.


Re: Any way to replace function body?

2019-02-22 Thread Gary Johnson
You have several options for this in Clojure. However, rebinding the same 
toplevel var that holds the original function is probably not the right way 
to do this if you want to be able to retrieve the old function value later. 
Consider the following approaches:

1. Define a single multi-arity function:

(defn fetch-data
  ([arg1 arg2] (db/fetch-data ...))
  ([arg1 arg2 & args]
(let [result (fetch-data arg1 arg2)]
  ;; do something with the remaining args
  (transform-result result

2. Derive the second function by composition:

(defn fetch-data [arg1 arg2] (db/fetch-data ...))

(def fetch-transformed-data
  (comp transform-result fetch-data))

3. Use "let" to rebind the function's definition within a lexical scope:

(defn fetch-data [arg1 arg2] (db/fetch-data ...))

;; ...somewhere later in my program...
(let [fetch-data (fn [arg1 arg2] (transform-result (fetch-data arg1 arg2)))]
  (fetch-transformed-data "foo" "bar"))

;; Note: While this works, it is pretty sketchy. You should probably just 
call the new local version of the function something else.

4. Use "binding" to rebind the function's definition within a dynamic scope:

(defn ^:dynamic fetch-data [arg1 arg2] (db/fetch-data ...))

;; ...somewhere later in my program...
(let [fetch-data-orig fetch-data]
  (binding [fetch-data (fn [arg1 arg2] (transform-result (fetch-data-orig 
arg1 arg2)))]
(fetch-data "foo" "bar")))

;; Note: You can't use binding to create a self-referential (recursive) 
function or you will trigger an infinite recursion. Use let to close over 
the original value of fetch-data before referencing it within the body of 
the new function used with binding.


There are probably several other approaches that you could experiment with 
as well if you wanted to look a bit farther afield. IMO, I would just go 
with the function composition solution. It's clear and concise and doesn't 
require you to remember the specifics of dealing with recursion in dynamic 
binding forms.


Happy hacking!
  Gary



On Saturday, January 19, 2019 at 2:58:29 PM UTC, Janko Muzykant wrote:
>
> Hi,
>
> Is there an way to replace body of existing (interned) function with own 
> code still being able to call original fn? 
> Suppose, I have a function:
>
> (defn fetch-data [arg1 arg2]
>   (db/fetch-data ...))
>
> I would like to intern a slightly modified version of this fn. Something 
> like this:
>
> (defn fetch-data [& args]
>   (let [result (apply original-fetch-data args)]
> (transform-result result)))
>
> The problem I see is how to keep the reference to original fetch-data fn 
> (here denoted by original-fetch-data),
> so it could be still called in a altered version of fetch-data function.
>
> Best,
> JM.
>
>
>
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: OK idea to replace conj and cons with "prepend" and "append" macros that have consistent behavior and return same types as args?

2018-07-22 Thread Gary Johnson
Thanks, Gary and Justin, for spotting my code mistakes. Serves me right for 
not double-checking the outputs at my REPL. :-P

Anyway, my examples with vectors, maps, and sets were all correct using 
into. I goofed on lists, because the new elements are naturally always 
applied to the front of the list since that is the only way to do it 
efficiently. This really just reinforces what others have already said 
above that Clojure's standard library doesn't make it easy for you to do 
something inefficient (like adding elements to the end of a list.

Anyway, having said that, I guess I'd just make the following adjusted 
recommendation then:

1. When appending/prepending to vectors, maps, or sets, use into as 
demonstrated above.
2. When appending/prepending to lists, use concat with the same syntax as 
was shown with into above.

Note, of course, that concat returns a lazy sequence not a true linked 
list, but for the purposes of beginner instruction, this should probably be 
fine since it will print to the REPL like a list and provides the same API 
as a list going forward.

Once again, good luck with your Clojure teaching, and happy hacking!

~Gary

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Complete Web Development Setup Using Clojure CLI Tools

2018-07-20 Thread Gary Johnson
Thanks for the link!

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: OK idea to replace conj and cons with "prepend" and "append" macros that have consistent behavior and return same types as args?

2018-07-20 Thread Gary Johnson
Hi Christian,

You are looking for "into", which is already part of the Clojure standard 
library.

Appending:

(into '(1 2) '(3)) ;=>  (1 2 3)
(into [1 2] [3])   ;=>  [1 2 3]
(into {:a 1 :b 2} {:c 3})  ;=>  {:a 1, :b 2, :c 3}
(into #{:a :b} #{:c})  ;=>  #{:c :b :a}

Prepending:

(into '(1) '(2 3)) ;=>  (1 2 3)
(into [1] [2 3])   ;=>  [1 2 3]
(into {:a 1} {:b 2 :c 3})  ;=>  {:a 1, :b 2, :c 3}
(into #{:a} #{:b :c})  ;=>  #{:c :b :a}

The "into" function pours the contents of the second collection into the 
first collection, returning a collection of the same type as the first 
argument.

That being said, I agree with Alex and James in this rather lengthy 
discussion. Clojure is unique among the Lisps in that it moved beyond 
having linked lists as the only first class data structure.

Prior to Clojure, if you worked in a Lisp like Scheme or Common Lisp, you 
would design your program around the creation, traversal, and manipulation 
of linked lists using higher order functions and explicit recursions. The 
standard library in both languages is heavily focused on these list-related 
operations. After developing the initial version of your program, if you 
found that it was too slow or used too much memory, the accepted practice 
was to profile your application to identify the functions that were getting 
hammered the most and were using up the majority of your computing 
resources. You would then often end up rewriting those function bodies in 
an imperative fashion using loops and mutable data structures (i.e., arrays 
and hashtables). The "wisdom" here was that this would enable you to "first 
make it right, then make it fast". If even further performance was required 
from your program, you might then rewrite part of your program in C, build 
a foreign function interface (FFI) to link the C code into your Lisp 
program, and go from there. These were the Bad Old Days of Lisp(TM).

What was IMHO quite possibly Rich's greatest contribution in the design of 
Clojure to the Lisp world was his decision to make additional data 
structures first class citizens of the language. Most importantly, he did 
so by creating Clojure's vectors, maps, and sets to be immutable, 
persistent, performant, recursively constructed, and representable as data 
literals. This was already a wonderful improvement over previous Lisps, but 
it created a new problem: How could we enjoy the pure delight of 
list-oriented programming that Lisp had always offered us now that the data 
structure space had been fragmented? A famous quote from Alan Perlis is a 
popular gem in the Lisp world, and it goes like so:

"It is better to have 100 functions operate on one data structure than to 
have 10 functions operate on 10 data structures."

Every Lisp had always satisfied this by simply giving programmers only one 
first class data structure to use: the linked list. As I already mentioned, 
the bulk of its standard library would then be built around list 
manipulation functions. Clojure needed a way to preserve this unified style 
of programming while still providing a collection of performant data 
structures for real-world programming. So how did Rich accomplish this?

He created the "sequence abstraction". A sequence in Clojure serves a 
similar role to the linked list of previous Lisps in that it unifies the 
API for interacting with all of Clojure's first class data structures 
(list, vector, map, set). By calling the function "seq" on any data 
structure, you are given a list-like view of that collection that allows 
you to traverse it from beginning to end one element at a time and to add 
new elements to the beginning of it. These operations are called "first", 
"rest", and "cons", and they behave precisely as you would expect them to 
if you were calling them on a linked list.

By using seq throughout the Clojure sequence library (i.e., the set of 
standard library functions responsible for creating, traversing, 
transforming, and manipulating sequences), Clojure is able to have single 
implementations of all of the common Lispy higher order list transformation 
functions. For example, we have "map", "filter", "reduce", "iterate", 
"take", "drop", "repeat", "cycle", and so on. The amazing thing is that 
these can all take any of Clojure's data structures as their inputs. So you 
can call map on a list, vector, map, or set without having to change the 
function signature. Without the sequence abstraction, we could need 
multiple functions for every data structure we wanted to support (e.g., 
map-list, map-vec, map-hash, map-set, filter-list, filter-vec, filter-hash, 
filter-set). This is precisely the kind of combinatorial explosion of the 
function space the Alan Perlis was warning us about. The tradeoff is that 
each of these higher order functions will then return a new sequence as its 
output. While this prints to the REPL like a list, please note that a 
sequence is not a list (except when it i

Re: Complete Web Development Setup Using Clojure CLI Tools

2018-07-17 Thread Gary Johnson
Thanks, Chad.

I have built quite a few toy and production full-stack Clojure web apps 
over the past 6 years or so using leiningen and boot. While both of these 
are great tools with a lot of programmer hours invested in them, I realized 
recently that neither of them are particularly easy to explain to a novice 
Clojure programmer, particularly when you are using them to configure a 
full stack web development environment.

Since I hadn't yet tried doing any web dev with the Clojure CLI tools, this 
seemed like a good test project to get my feet wet. Despite the seemingly 
stripped-down set of options available in deps.edn (just :paths, :deps, and 
:aliases), it turned out that the :aliases feature really provides all you 
need to bootstrap a wide variety of build tasks directly into the clojure 
command.

What I really like best about this approach is that I can now introduce new 
programmers to Clojure using command line conventions that they are likely 
already familiar with coming from many other popular languages like perl, 
python, ruby, or node. So now I can just type:

```
$ clojure
```

and get a REPL. Or I could type:

```
$ clojure script.clj
```

and I'm running a simple single-file Clojure program. If I need something 
more complicated, I can just define an alias for a build task a la carte 
and type:

```
$ clojure -A:my-task
```

Because taking this approach makes Clojure development look almost 
identical to building a program in any of the other languages I mentioned 
(and many more that I didn't), it makes the tooling very "easy" (in the 
Rich sense) for newbies that I need to train in our company. And when I 
want to play power-programmer, I get to have fun just cranking out new 
aliases for adventure and profit!

And hey, if you've read along this far, here's a free alias for you to play 
with or modify to suit your needs:

```
:minify-css {:extra-deps {asset-minifier {:mvn/version "0.2.5"}}
:main-opts ["-e" 
"(use,'asset-minifier.core),(minify-css,\"resources/public/css/style.css\",\"resources/public/css/style.min.css\")"]}
```

Have fun and happy hacking!
  Gary

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Complete Web Development Setup Using Clojure CLI Tools

2018-07-10 Thread Gary Johnson
For those of you playing along at home, you may have noticed that there 
were two bugs in the code I presented above. I have since fixed those 
issues in the Gitlab repository that I linked to in my previous post. If 
you didn't just grab the repository, here are the fixes for you to add 
manually to your setups:

Fix 1: Corrected deps.edn

{:paths ["src/clj" "src/cljs" "resources"]

 :deps {org.clojure/clojure   {:mvn/version "1.9.0"}
org.clojure/clojurescript {:mvn/version "1.10.312"}
ring  {:mvn/version "1.7.0-RC1"}
ring/ring-defaults{:mvn/version "0.3.2"}
prone {:mvn/version "1.6.0"}
compojure {:mvn/version "1.6.1"}
hiccup{:mvn/version "1.0.5"}
reagent   {:mvn/version "0.8.1"}}

 :aliases {:run{:main-opts ["-m" "my-project.server"]}
   :cljsbuild  {:main-opts ["-m" "cljs.main" "-co" "cljsbuild.edn" 
"-c"]}
   :figwheel   {:extra-deps {org.clojure/tools.nrepl {:mvn/version 
"0.2.13"}
 cider/cider-nrepl   {:mvn/version 
"0.17.0"}
 com.cemerick/piggieback {:mvn/version 
"0.2.2"}
 figwheel-sidecar{:mvn/version 
"0.5.14"}}
:main-opts ["-e" 
"(use,'figwheel-sidecar.repl-api),(start-figwheel!)"]}}}

The issue was that leaving src/cljs out of the :paths vector and adding it 
with :extra-paths in the :cljsbuild alias had left the :figwheel alias 
unable to load CLJS files at the CLJS REPL that it spawns. The above code 
corrects this problem.

Fix 2: Corrected views.clj

(ns my-project.views
  (:require [hiccup.page :refer [html5 include-css include-js]]))

(defn render-page []
  (html5
   [:head
[:title "My Project"]
[:meta {:charset "utf-8"}]
[:meta {:name "viewport" :content "width=device-width, initial-scale=1"
}]
(include-css "/css/style.css")
(include-js "/cljs/app.js")]
   [:body
[:div#app]
[:script {:type "text/javascript"} "my_project.client.mount_root();"]]))


In my initial post, I accidentally left out a closing square bracket in the 
render-page function. This block of code adds it back in.


Okay, folks. That's it for now. Once again, you can just grab the corrected 
template from this Gitlab link if you are so inclined:

  https://gitlab.com/lambdatronic/clojure-webapp-template

Over and out,
  Gary

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Complete Web Development Setup Using Clojure CLI Tools

2018-07-09 Thread Gary Johnson
Hi again, folks. Just to make it easier for everyone to use this template 
right away, I put all these files into a public git repository on Gitlab. 
Here's the URL:

https://gitlab.com/lambdatronic/clojure-webapp-template

Happy hacking!
~Gary

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Complete Web Development Setup Using Clojure CLI Tools

2018-07-09 Thread Gary Johnson
Howdy Clojurians,

I recently started developing a new Clojure+Clojurescript web application, 
and I wanted to see if I could set up my development environment using just 
the Clojure CLI tools. After a good deal of digging around through 
tutorials on a number of different websites and a fair amount of 
experimenting, I've managed to create a very simple (IMHO) configuration 
that provides me with both development and production mode CLJS->JS 
compilation, development and production mode ring handlers, and the always 
delightful FIgwheel development environment all from just the simple 
"clojure" command. Since I haven't seen this before, I thought I'd share it 
with all of you in case it helps someone else out there who doesn't need 
(or want) all of leiningen or boot to develop a simple web app.

Here goes:

Step 1: Create your project structure like so:

├── cljsbuild.edn
├── deps.edn
├── figwheel.edn
├── resources
│   └── public
│   ├── cljs
│   ├── css
│   │ ├── style.css
│   ├── images
│   └── js
├── src
│   ├── clj
│   │   └── my_project
│   │   ├── handler.clj
│   │   ├── server.clj
│   │   ├── views.clj
│   └── cljs
│   └── my_project
│   ├── client.cljs

Step 2: Make the deps.edn file (replace :deps and my-project.server 
namespace as necessary for your project)

{:paths ["src/clj" "resources"]

 :deps {org.clojure/clojure   {:mvn/version "1.9.0"}
org.clojure/clojurescript {:mvn/version "1.10.312"}
ring  {:mvn/version "1.7.0-RC1"}
ring/ring-defaults{:mvn/version "0.3.2"}
prone {:mvn/version "1.6.0"}
compojure {:mvn/version "1.6.1"}
hiccup{:mvn/version "1.0.5"}
reagent   {:mvn/version "0.8.1"}}

 :aliases {:run{:main-opts ["-m" "my-project.server"]}
   :cljsbuild  {:extra-paths ["src/cljs"]
:main-opts ["-m" "cljs.main" "-co" "cljsbuild.edn" 
"-c"]}
   :figwheel   {:extra-deps {org.clojure/tools.nrepl {:mvn/version 
"0.2.13"}
 cider/cider-nrepl   {:mvn/version 
"0.17.0"}
 com.cemerick/piggieback {:mvn/version 
"0.2.2"}
 figwheel-sidecar{:mvn/version 
"0.5.14"}}
:main-opts ["-e" 
"(use,'figwheel-sidecar.repl-api),(start-figwheel!)"]}}}


Step 3: Make the cljsbuild.edn file (replace :main for your project)

{:main  "my-project.client"
 :output-dir"resources/public/cljs"
 :output-to "resources/public/cljs/app.js"
 :source-map"resources/public/cljs/app.js.map"
 :optimizations :advanced
 :pretty-print  false}

Step 4: Make the figwheel.edn file (replace :ring-handler, :on-jsload, and 
:main for your project)

{:nrepl-port   7000
 :nrepl-middleware ["cider.nrepl/cider-middleware"
"cemerick.piggieback/wrap-cljs-repl"]
 :server-port  3000
 :ring-handler my-project.handler/development-app
 :http-server-root "public"
 :css-dirs ["resources/public/css"]
 :builds [{:id   "dev"
   :source-paths ["src/cljs"]
   :figwheel {:on-jsload "my-project.client/mount-root"}
   :compiler {:main  "my-project.client"
  :output-dir"resources/public/cljs/out"
  :output-to "resources/public/cljs/app.js"
  :asset-path"/cljs/out"
  :source-maptrue
  :optimizations :none
  :pretty-print  true}}]}


Step 5: Write server.clj

(ns my-project.server
  (:require [ring.adapter.jetty :refer [run-jetty]]
[my-project.handler :refer [development-app production-app]])
  (:gen-class))

(defonce server (atom nil))

(defn start-server! [& [port mode]]
  (reset! server
  (run-jetty
   (case mode
 "dev"  #'development-app
 "prod" #'production-app
 #'production-app)
   {:port (if port (Integer/parseInt port) 3000)
:join? false})))

(defn stop-server! []
  (when @server
(.stop @server)
(reset! server nil)))

(def -main start-server!)


Step 6: Write handler.clj

(ns my-project.handler
  (:require [ring.middleware.defaults :refer [wrap-defaults site-defaults]]
[ring.middleware.reload :refer [wrap-reload]]
[prone.middleware :refer [wrap-exceptions]]
[compojure.core :refer [defroutes GET]]
[compojure.route :refer [not-found]]
[my-project.views :refer [render-page]]))

(defroutes routes
  (GET "/" [] (render-page))
  (not-found "Not Found"))

(def development-app (wrap-reload
  (wrap-exceptions
   (wrap-defaults #'routes site-defaults

(def production-app (wrap-defaults #'routes site-defaults))


Step 7:

Re: Anyone spent time with Kawa Scheme?

2018-04-04 Thread Gary Johnson
If you haven't given it a try yet, Clojurescript is really the goto for a 
lot of Clojure programmers when it comes to cover the CLI and Android use 
cases.

Lumo and Planck are awesome Clojurescript runtimes that start up virtually 
instantaneously and make great choices for writing scripts.

Clojurescript + React Native can create apps for Android, iOS and Windows.

Have fun and happy hacking!
  Gary

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Writing a text adventure in Clojure

2018-03-30 Thread Gary Johnson
Hi Will,

Welcome to the wide world of functional programming, where data flows, and 
functions transmute without destroying their inputs.

As some others in this thread have already suggested, a general approach to 
viewing any problem space from a functional perspective is to imagine your 
problem as a pipeline of data transformations from start to finish. To the 
greatest extent possible, try to represent your data transformations as 
pure functions over immutable arguments rather than holding any global 
state in a var and mutating it at each time step.

In the context of a game program, consider depicting all of your game state 
as a single hierarchical map. Then thread this map through each function 
and return a new derived map as each output result.

```clojure
(def world-state {:flags #{}
:location :fancy-room
:inventory #{:sledgehammer :car-keys :lamp}
:rooms {:creepy-corridor {:name "Creepy Corridor" 
:description "Whoa! Spooky..." :items #{:halloween-mask :monkeys-paw 
:troll-doll}}
:fancy-room {:name "Fancy Room" 
:description "The fanciest!" :items #{:chandelier :toy-poodle 
:looking-glass}}
...}})

```
Let's imagine this is the initial world state. When your application starts 
up, it enters into the game loop (which would be a nice, friendly 
recursion, of course). In each round of the game loop, you call a sequence 
of functions to get the description of the current room, print it out, ask 
the user for the next command, process that command, and then recurse back 
to the top of the next iteration of the game loop. Although printing to 
stdout and reading from stdin are obviously side effecting functions, you 
should be able to keep your functions for retrieving the room description 
and processing the user's command as pure functions of the current 
world-state. Just make sure that the functions that process a user's 
command always return a new copy of the world-state value. When you want to 
save the game, just write out the world-state to an EDN file. By reading it 
back in again later, you can restore the game to exactly the same state it 
was in before.

In response to your specific question about having a different room 
description after some event has happened, consider this approach:

```clojure
(defn do-important-plot-changing-action [world-state]
(-> world-state
 (update :flags conj :major-plot-point-reached)
 (assoc-in [:rooms :fancy-room :description] "Gosh! This room isn't 
nearly as fancy anymore!")))
```

That is, the function just uses assoc, assoc-in, update, and update-in to 
modify the values in the new map and return it for use in future iterations 
of the game loop. And that's pretty much all there is to it. You just pass 
the changing world state down through the stack rather than mutating it in 
place on the heap. (Ultimately, the world-state data structure is, of 
course, actually stored on the heap, and you are just passing references to 
it through the stack, but I hope you get my meaning here.)

Good luck and happy hacking!

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Loop causing OutOfMemoryError: GC overhead limit exceeded ?

2018-03-02 Thread Gary Johnson
As Daniel pointed out, this could probably be done more idiomatically (and 
functionally) using sequence functions. Here is a quick shot at a rewrite 
without any atoms or mutable state in the same number of lines of code (18) 
as your original example. If some of the intermediate lazy sequences cause 
any noticeable performance slow-down, you could switch over to transducers 
pretty easily.

(defn find-db-records-seq [db min-time max-time]
  (->> min-time
   (iterate #(plus-minutes % 30))
   (take-while #(before? % max-time))
   (partition 2 1 [max-time])
   (reduce (fn [{:keys [num-processed records]} [min-t max-t]]
 (let [results (jdbc/query db
   ["select id, a, b, c from 
sometable where t > ? and t <= ? order by t"
min-t max-t])]
   {:num-processed (+ num-processed (count results))
:records (into records
   (mapcat (fn [rows]
 (let [foo (make-foo rows)]
   (->> rows
(filter (fn [{:keys [a b
]}] (relevant-record? foo a b)))
(map (fn [{:keys [id a 
b c]}] {:id id :a a :d (compute-d a b c)})
   (partition-all 200 results)))}))
   {:num-processed 0 :records []})))


Happy hacking!
  Gary

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: idiomatic way of counting loop iteration

2016-09-12 Thread Gary Johnson
Almost right. The iterate function is an infinite sequence generator, so 
(count (iterate f x)) will never return.

If you want the iteration to terminate when cond is false (as in your 
original example), you're looking for this:

(count (take-while cond (iterate (fn [[a b]] ... [new-a new-b]) [init-a init
-b])))

Happy hacking!

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: How to do functional programming

2016-08-08 Thread Gary Johnson
A shell script written in a procedural style (e.g. with Bash or equivalent 
shell language) will frequently start out by declaring some global 
variables, then perform some conditional checks (if then else), throw in a 
few loops (for, while), and ultimately end up with some new values in those 
initially declared variables that you use as your program's output. If you 
are feeling particularly intrepid, you might factor out some repetitive 
operations into separate subroutines defined higher up in the file and then 
call them as necessary in those aforementioned conditional blocks and loops.

The mental model behind this type of programming is the Universal Turing 
Machine. Your variables are some internal state that the program 
instructions are reading and writing, reading and writing, writing and 
reading until you get to the last instruction that returns some subset of 
the final variable values. The driving principle is that computation is 
accomplished by the free mutation of state.

A program written in a functional style (e.g. with any Lisp, one of the 
MLs, Haskell, Clean, etc) begins with a chunk of data, which may either be 
hard-coded, input from the outside world, or generated internally with a 
function like "range" or "rand". This piece of data may or may not be 
stored in one or more global variables. However (and this is HUGE however), 
these are not generally mutated over the life of the program. That is to 
say, they are constants. More often than not, you won't even store the 
initial data in a global variable but will just feed it into a function 
that processes it and spits out some new data, which is then fed to another 
function that performs some other processing operation and again spits out 
some new data. Ultimately, the data that you produce is passed through an 
arbitrarily long pipeline of functions until the final result is produced 
and returned by the program. In practice, these function calls are rarely 
linear and are much more likely to form a branching call tree. But 
ultimately, the relevant branches of this tree will be traversed and 
executed in a depth first manner (unless lazy evaluation inserts its magic 
to reorder some of that computation behind the scenes) and you still get to 
a final output returned by the last function fall evaluated.

The mental model behind this type of programming is Lambda Calculus. There 
is no mutable state anywhere in a pure functional program, and instead the 
intermediate results are passed through the call stack from function to 
function. In practice, because stack sizes are limited, most values passed 
between functions will be boxed references pointing to memory locations on 
the heap. However, as far as the functional programmer is concerned, there 
is no heap and there is no mutable state. Immutable values simply flow 
seamlessly from one function to the next until the program has finished. 
The driving principle is that computation is accomplished by transforming 
data through mapping a set of immutable inputs to an immutable output. 
Think f(x,y) = z.

In order to accomplish this stateless pipeline of data transformations, 
functions much possess a property called "referential transparency". This 
means that a function must be able to calculate its outputs 
deterministically using only its inputs AND without modifying any of its 
inputs in the process. This property is preserved even when global 
variables are referenced within the body of a function as long as the 
values associated with those global variables are constants throughout the 
lifetime of the program.

In practice, very few languages (outside of Haskell) actually try to be 
completely pure and allow no mutation of state whatsoever. Clojure opts to 
make all data immutable by default, but provides some special language 
features (refs, atoms, agents, volatiles) that you can use if you really do 
want to write an algorithm that involves some mutable state. Unless there 
is a performance bottleneck (as in numerical computing) or no other 
sensible way to model the domain (as in some web applications), making use 
of these features for mutable state is generally frowned upon. When they 
are really necessary and valuable, however, Clojure's language tools for 
accomplishing mutation are wonderful because they carefully protect it 
against concurrency clashes in multi-threated environments.

To approach writing a functional program, first think about how to model 
the computation as a series of data transformations. Then build your 
program from the bottom up (prototyping and testing it in the REPL) by 
writing small, referentially transparent functions that describe the lower 
level operations that you will need. Then build higher level functions on 
top of those that build up your abstractions in a layer cake style until 
you reach your entry point function that either takes input data from the 
outside world or generates it internally and then starts the executi

Re: [ANN] leaflet-gorilla 0.1.2 released with GeoJSON support

2015-04-02 Thread Gary Johnson
I've been using PostGIS extensively at work for the past year or so and 
used it intermittently before then. To really get the most out of the 
system, I would strongly recommend grabbing a copy of "PostGIS in Action, 
2nd Edition" by Regina O. Obe. I feel like I went from a casual user to a 
power user in one read-through.

  Happy hacking,
~Gary

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: clojure, not the go to for data science

2015-04-02 Thread Gary Johnson
Please stop.

The amount of misinformation you are spreading about Emacs on this mailing 
list is deeply irresponsible and belies a very clear lack of understanding 
about how this software works. All of your concerns about 
internationalization (supported), accessibility to text readers 
(emacspeak), resource limits (full system utilization), and compatibility 
with modern hardware, operating systems, and window managers (GTK 
interface) are unfounded.

As it has been noted numerous times already by others, this thread is about 
Clojure and data science, not about your dislike of the Emacs user 
interface. Some people (such as myself) prefer a text-mode interface driven 
by keybindings over a mouse-driven graphical interface. That is an 
aesthetic and productivity-based choice. Please respect your fellow 
programmers and go write some software rather than continuing this diatribe.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [ANN] leaflet-gorilla 0.1.2 released with GeoJSON support

2015-04-02 Thread Gary Johnson
Absolutely awesome! Finally, an easy-to-use renderer for PostGIS queries. 
Well done!

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Sum up second elemsts of pairs in a sequence by grouping by the first item in pair

2015-03-20 Thread Gary Johnson
Sometimes, all you need is the proper reduce formulation:

  (reduce (fn [m [k v]] (assoc m k (+ (m k 0) v))) {} keyvals)

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Current best-of-breed JDBC libraries?

2015-02-24 Thread Gary Johnson
I actually prefer yesql for most of my Clojure<->SQL interaction.

Since a significant portion of my job involves me writing and optimizing 
SQL queries, I like being able to seamlessly switch between psql, 
org-babel's sql mode, and yesql with a simple cut and paste operation. For 
extra emacs sexiness, check out the yesql-ghosts package in MELPA. This 
automatically inserts all of the imported function signatures (as defns) as 
a text overlay below any (defqueries ...) form when a clojure buffer is in 
cider-mode.

Keep on hackin' in the free world,
  ~Gary

On Tuesday, February 24, 2015 at 9:04:36 AM UTC-5, Colin Yates wrote:
>
> Hi all,
>
> What are you all using for interacting with an RDBMS? In the past I looked 
> at clojure.java.jdbc, honeysql and korma (and for querying, honeysql just 
> rocks). I have lost touch a bit - any recommendations?
>
> Thanks.
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: CIDER vs Org Mode: "Symbol's definition is void: nrepl-send-string-sync" (workaround)

2014-08-10 Thread Gary Johnson
I've been using the following patch for quite some time now, and it works 
reasonably well. The table generation is pretty suboptimal though, so if 
anyone has an better version, I'd love to see it.

(defun org-babel-execute:clojure (body params)
>   "Execute a block of Clojure code with Babel."
>   (require 'cider)
>   (let ((result (cider-eval-and-get-value (org-babel-expand-body:clojure 
> body params)))
> (result-params (cdr (assoc :result-params params
> (org-babel-result-cond result-params
>   result
>   (condition-case nil (org-babel-script-escape result)
> (error result)
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Is still idiomatic the ant simulation code?

2014-07-28 Thread Gary Johnson
Hi Yu,

  This is a pretty dense (and IMHO non-idiomatic) piece of Clojure code. 
Without reading the paste you provided, I can at least tell you what 
appears to be happening here, given Clojure's evaluation semantics:

1. The [move ...] expression creates a vector of three functions.
2. The [(if ...)] expression creates a vector of three values (presumably 
numeric) resulting from calls to the ranks function.
3. The (wrand ...) form calls wrand on the ranks vector to presumably 
produce an integer index into the [move ...] vector.
4. The [move ...] vector is called on wrand's result, which should return 
one of the three functions it contains.
5. The function returned from step 4 is called on loc.

  Happy hacking,
~Gary

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: futures and atoms and bears, oh my!

2014-07-14 Thread Gary Johnson
Looking at this code without further knowledge of the strategy function, my 
first guess is simply that your strategy function may not be returning a 
result which satisfies the valid-move? and legal-move? predicates thus 
throwing you into an infinite loop. Possibly the printf is being suppressed 
within the swap! operation, but some testing would be required to see if 
this is the case generally. The other obvious potential for a hiccup would 
be if all-directions is somehow growing with each iteration of make-move, 
thus preventing idx from ever exceeding its length. Not knowing what is 
going on inside all these functions makes this a rather tricky bit of guess 
work at best. Anyway, I'd try running get-move from the repl to see how 
likely it is to get stuck in an infinite loop.

  Good luck,
~Gary

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [ANN] clj-generators - generator magic inspired by Python

2014-06-06 Thread Gary Johnson
Gotcha. By all means then, hack away. ;-)

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: non-lazy clojure?

2014-06-05 Thread Gary Johnson
Fair enough. Fortunately, Clojure provides so many different tools to 
select from in creating you perfect recipe. ;-)

I'm glad to hear that reducers ultimately provided you with some benefits 
over your previous concurrency approach.
The one thing that seems rather odd to me though is that your group-size is 
1. I'm presuming that the function you're r/mapping must take a substantial 
amount of time and resources for that to be efficient. Have you 
experimented with larger group sizes to avoid too much thread swapping?

  ~Gary

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: non-lazy clojure?

2014-06-04 Thread Gary Johnson
Hey Lee, answers below. Also make sure to read my other post at 12:59pm 
today regarding the behavior of vec vs. into for reducible collections.

On Wednesday, June 4, 2014 12:51:45 PM UTC-4, Lee wrote:
>
> Some quick notes and a question from my first look into this: 
>
> - I watched a Rich Hickey reducers video, was riveted, and see that they 
> are beautiful. I particularly appreciated his brief aside about how lazy 
> seqs have independent utility. 
>
> - In practice, for the little program I posted about previously, switching 
> to reducers involved a couple of initially unexpected complications, some 
> of now make sense to me but others of which don't fully: results of 
> reducers sometimes have to be explicitly converted, e.g. with "into []"; 
> r/map doesn't take multiple collections; I don't immediately see elegant 
> reducer-based approaches to uses of "for" or "repeat", etc. 
>
>
It's true that the library does have these limitations. You could, of 
course, just implement a for-like macro that uses the reducing operations 
under the hood. Easier (but less readable) is to just convert your for into 
the equivalent r/map and r/filter operations. When using repeat, make sure 
the result sequence will be finite and call vec on it directly. Then you 
can apply the reducing functions to it and still have a foldable collection.
 

> - My initial swapping of clojure.core.reducers functions for lazy seq (and 
> agent-based parallel computing) functions seems to make my performance 
> worse rather than better. I realize that there are several possible 
> explanations for this and I have to look at my usage more carefully. It's 
> definitely possible that I'm doing more than one thing wrong, but one 
> question that this leads to is: 
>
>
Hard to say why this would be without seeing your code, but the first thing 
that comes to mind is that if you aren't calling fold or foldcat anywhere, 
then you won't be getting any parallelization from using reducers. So maybe 
your performance decrease is because you're now running single-threaded.
 

> - If I operate on a vector with a sequence of r/map and r/filter 
> operations and finally with "into []" to get back a vector, then I think 
> that fold will be called within the call to into, and that parallelism 
> should happen there... right? But if that's right, how do I control the 
> group size that the call to fold uses in this case? I see how to specify 
> the group size for a direct call to fold, but not for other function in the 
> library. 
>
>
No, fold will not be called in into. The definition of into uses reduce, 
which is single-threaded. What you want is one of the following two 
formulations:

  (fold group-size cat append! foldable-collection)   ;; if you want to 
specify the group size

  (foldcat foldable-collection)  ;; if you are happy with the default 512 
group size

In both cases, the foldable-collection is just one of your (r/map f 
(r/filter p? initial-collection)) forms. For it to be foldable though, 
initial-collection needs to be a vector, map, or set (i.e., a tree-like 
collection).

I hope that helps.

  ~Gary 

> Thanks, 
>
>  -Lee

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: non-lazy clojure?

2014-06-04 Thread Gary Johnson
Hey Lee,

  (vec ...) is NOT the same as (into [] ...) in this case.

  Whenever you use a reducing function, like r/map, r/filter, r/mapcat, and 
so on, you are not, in fact, performing any computations on the collection 
to which you apply it. These functions simply wrap the collection with a 
kind of delayed operation that will later be triggered by applying reduce 
to it.

  So, if I have a collection called samples, and I run (r/map inc samples), 
I just get a reducible object back. Same thing with a chain of these 
functions as in (r/filter odd? (r/map inc samples)). I just get back a 
reducible object (which itself is wrapping another reducible object). When 
you run reduce on this whole thing, each of the delayed operations are 
combined together into one giant reduce function, as if you had written 
something like this:

  (reduce + (r/filter odd? (r/map inc samples)))
   => (reduce (fn [sum sample] (let [sample' (inc sample)] (if (odd? 
sample') (+ sample' sum) sum))) 0 samples)

  This is the reason that you need to use (into [] ...) rather than (vec 
...). Running vec on a reducible object will just throw a RuntimeException. 
When you use into, you will be applying reduce (since that's how it is 
implemented), and as long as you use into with a vector, map, or set, it 
will be run using transients for efficiency.

  Uses transients:

  (into [] (r/map inc (range 10)))
  (into {} (r/map #(vector % 0) (range 10)))
  (into #{}| (r/map inc (range 10)))

  Doesn't use transients (but still works). Note that the list will have 
been reversed because of the nature of list consing:
  (into () (r/map inc (range 10)))

Alright, hopefully that's enough from me for now. Good luck with your 
program.

  ~Gary

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [ANN] clj-generators - generator magic inspired by Python

2014-06-04 Thread Gary Johnson
What new features does this syntax provide over the existing infinite 
sequence generators?

- lazy-seq
- iterate
- repeat
- repeatedly
- range

I realize you provided a simple example for clarity, but perhaps you could 
illustrate something more complex that couldn't be done with the above 
functions easily. For example, the case you provided could be written as 
follows:

(take 5 (iterate inc 1))

  Thanks,
~Gary

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: non-lazy clojure?

2014-06-02 Thread Gary Johnson
Hey Lee,

  I would second Jozef's suggestion that you look into using the reducers 
library when you need non-lazy sequence operations. Although a major 
motivation of Rich's work was clearly to enable easy parallel folding via 
fork/join, the fold function is only one of many in this library. Think 
instead that the main (philosophical) purpose of reducers is to decomplect 
the reducing operation from the data representation it is acting on. And of 
course, since reduce can be used to implement (virtually) any non-lazy 
sequence operation, it stands to reason that reducers should be fully 
capable of providing new implementations of many of these functions on top 
of reduce (which it does).

  Importantly, whenever you will be chaining sequence operations together, 
reducers should be more efficient than both the lazy sequence functions 
(e.g., map, filter) and the eager vector-returning functions (e.g., mapv, 
filterv). This is because a chain of reducing functions generate no 
intermediate representations.


  For example, let's say I wanted to sum the squares of all the even 
numbers in a sequence called samples.

  Using lazy functions: (reduce + (map #(* % %) (filter even? samples)))

  Using non-lazy functions (reduce + (mapv #(* % %) (filterv even? 
samples)))

  Using reducers (aliased as r): (reduce + (r/map #(* % %) (r/filter even? 
samples)))


If you need to collect the results of a sequence operation in a data 
structure rather than reducing them to an atomic value, simply use into 
rather than reduce (since into uses reduce under the hood).

So to collect the squares of all the even numbers in the samples sequence, 
just do this:

  (into [] (r/map #(* % %) (r/filter even? samples)))

As just one sample point, when I updated a statistical fire analysis 
algorithm that I wrote from using the lazy sequence functions to using the 
reducers library, I experience a full order of magnitude speedup. This sped 
up my runtime from ~6 hours to around 20 minutes. So please do yourself a 
favor and give this library a close look. It has made worlds of difference 
for some of my work.

  Good luck,
~Gary

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Remote function calls / simple distributed computation

2014-05-27 Thread Gary Johnson
Check out Tim Baldridge's Hermod library: 
https://github.com/halgari/com.tbaldridge.hermod

It's a very lightweight system that lets you create mailboxes (which listen 
on ports) on each of your independent JVMs. Then you can pass messages 
between them using core.async. This should give you most of the tools that 
you need to create arbitrarily complex coordination frameworks on top of it.

  Happy hacking!
~Gary


On Sunday, May 25, 2014 12:30:19 PM UTC-4, David James wrote:
>
> What are the ways to do remote function calls with Clojure? Here is a 
> *low-level 
> list* I have so far:
> * Java Remote Method Invocation API: 
> http://docs.oracle.com/javase/7/docs/technotes/guides/rmi/index.html
> * nREPL: https://github.com/clojure/tools.nrepl
>
> There are *higher-level tools*, too, such as:
> * Slacker https://github.com/sunng87/slacker
>
> What else should I add to the lists?
>
> Here is my goal. I'm exploring various ways to do distributed computation. 
> Many distributed computation platforms (e.g. Storm, Hadoop) require (1) 
> significant dev-ops setup (2) deployment via a JAR file (3) quite a bit of 
> time lag to get things started. I was hoping to find lighter-weight, more 
> responsive, ways to do distributed computation. I also consider this a 
> learning exercise.
>
> I like PigPen's use of a custom `pmap` function to distributes work: 
> https://github.com/Netflix/PigPen (But it requires Pig and Hadoop)
>
> It could be nifty to have a `pmap` that worked, say, over a set of 
> machines connected via nREPL. Has this already been done?
>
> Thanks!
>
>
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [Axiom-developer] Heidegger, literate programming, and communication

2014-05-22 Thread Gary Johnson
On Thursday, May 22, 2014 6:20:39 PM UTC-4, Mars0i wrote:
>
> On Thursday, May 22, 2014 4:05:58 PM UTC-5, Gary Johnson wrote:
>>
>> Hi folks,
>>
>>   I suspect I'm the Gary that Tim thought he was referring to since I've 
>> posted on several of his other LP-related threads (though not this one 
>> until now). 
>>
>
> I cede the name "Gary" to Gary.
>

No worries. You can be Gary too if you'd like. It's a passable name, all 
things considered. ;-)
 

>  
>
>>   But really, at the end of the day, I'm just getting tired of listening 
>> to people razzing on LP for the reasons listed above. 
>>
>
> For my part, I have never intended to criticize LP per se.  When it sounds 
> as if someone is arguing that everyone should use LP all the time (or 
> something similar), I sometimes object. 
>

Hey, point taken. I'm certainly not out to force LP on anyone. I'm just 
here to soak up advice from the folks who have been using it for awhile. 
I'm happy keeping the kool-aid to myself, so to speak. :-P

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [Axiom-developer] Heidegger, literate programming, and communication

2014-05-22 Thread Gary Johnson
Hi folks,

  I suspect I'm the Gary that Tim thought he was referring to since I've 
posted on several of his other LP-related threads (though not this one 
until now). I'm reading along and enjoying the back and forth as usual, but 
I'm sorry to say that I don't have much to add to this philosophical 
swordfight.

  As I've stated on other threads, I find LP quite useful to me, both in 
helping me remember later what my old code does (and WHY I wrote it that 
way in the first place) as well as helping me to write clearer and more 
parsimonious code in the first place (since I don't want to document a 
crazy web of unnecessary complexity if I can avoid it). All in all, my 
personal LP journey has been an interesting and reasonably productive one. 
And of course, using an expressive functional language like Clojure does 
allow me to keep my code snippets shorter and more isolated from one 
another. All good things for LP as well.

  I know that Tim likes to poke the mailing list occasionally and remind 
people that LP is the bee's knees and that they should really get on board 
with it. I also know that without fail one or more folks will quickly 
respond that LP doesn't provide enough value above docstrings, inline 
comments, autogenerated API docs, and the occasional blog post to invest 
the necessary time in developing new LP-mindful workflows. And, of course, 
someone will inevitably chime in with the rally cry "clear code doesn't 
need documentation".

  I understand that really embracing LP does require relearning how to 
program in several fundamental respects, AND it makes it quite difficult to 
use many of the developer tools many folks in the Clojure community have 
come to rely on. This makes the task appear somewhere between challenging 
and onerous to many programmers (or so I would imagine from following Tim's 
threads over the past year). However, (speaking only for myself here) I 
think the maintenance benefits often outweigh the upfront investment for 
any piece of software I intend to keep around for more than a few months. 
So for me, it's a net good. For some folks it's not. I get that. Enough 
said.

  But really, at the end of the day, I'm just getting tired of listening to 
people razzing on LP for the reasons listed above. There ARE good tools out 
there for doing this kind of programming. People just have to invest time 
and energy into learning them. I regularly cite Emacs' Org-mode as 
providing most everything you might need to comfortably create LP programs 
without even writing one line of LaTeX or XML (if you're allergic to those 
languages). Obviously, as Tim points out, it's an almost trivial assignment 
to roll your own tangle and weave scripts in whatever language you like 
(and I've tried that route too). So guys, if you don't like the ideas 
behind LP or just feel like it is too much of a hassle to use, then I 
completely understand that you don't want to use it. But could we maybe 
call a truce on this mailing list on the topic?

  Perhaps instead of constantly being pulled into philosophical arguments, 
those of us who actually do enjoy exploring LP could then use this forum to 
discuss amongst ourselves what tools or references we are finding useful in 
our journey. Clearly some folks (Gregg included) are churning out some 
pretty neat looking tools to make LP easier to do in the Clojure world. I 
for one would love to see more lively discussion around that and not feel 
like we're just bear-baiting whenever we mention the forbidden paradigm of 
Literate Programming.

  My 2c,
~ (the actual) Gary

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Joy of Clojure question

2014-05-14 Thread Gary Johnson
Bridget and Guru are both right about the reason that \3 is found at 
position 13 in the string. However, the code you typed isn't valid Clojure, 
since the pos function expects pred to be a function of v. Thus, your pos 
call would need to look like this:

(pos #(= % \3) ":a 4 :b 1 :c 3 :d 4") => (13)  ;; note that pos returns a 
list of all indeces matching pred

Alternatively, you could have defined pos to simply perform equality 
matching on its first argument like so:

(defn pos [val coll]
  (for [[i v] (index coll) :when (= val v)] i))

(pos \3 ":a 4 :b 1 :c 3 :d 4") => (13)

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Rethinking Literate Programming

2014-05-11 Thread Gary Johnson
Emacs org-mode provides a markdown-like language, which can be organized 
into a foldable outline (e.g., chapters, sections, subsections, 
subsubsections). Syntax is provided for headers, ordered/unordered lists, 
tables, inline images/figures, hyperlinks, footnotes, and (most importantly 
for LP) code blocks. In order to avoid having to scroll up and down forever 
to see your code spread through the document, you simply use TAB to 
fold/unfold the outline sections your are currently interested in. Pressing 
C-c ' within any code block automatically switches to Emacs' major mode for 
that language, showing only the code in its own temporary buffer. When you 
want to see all of your code at once, just tangle the document to a *.clj 
file and look at it in another buffer. Using auto-refresh on the tangled 
buffer provides an easy way to keep checking code changes in this way with 
minimal effort. When you are ready to weave the document into a nicely 
readable format, org-mode provides output filters to auto-generate latex 
articles, html webpages, OpenDocument files, latex beamer presentations, 
and quite a few others as well.

This is just meant to clarify some of the LP-related features of this 
platform. Obviously, some emacs lisp hacking can extend it to do whatever 
else people want.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Rethinking Literate Programming

2014-05-09 Thread Gary Johnson
puzzler and Tim,

  Well said, gentlemen. As someone who has been using LP heavily for the 
past two years, I have certainly reaped many if not most of the benefits 
regularly argued in its favor (and of course, I've wrestled with all the 
usual tooling issues as well). While I agree with puzzler that many 
programmers probably don't write sufficiently novel software that would 
benefit from an LP style, quite a few of us do. In my case, much of my 
programming is aimed at environmental research, developing models and 
algorithms for describing and predicting natural processes and human 
interactions with them. In order for my work to be accepted and used for 
decision making (usually around land planning), it is absolutely crucial 
that I can transparently explain all the formulas used, literature cited, 
and conceptual steps taken to get from empirically measured data to 
modelled outputs. A literate programming style not only helps me to 
organize my thoughts better (both hierarchically and sequentially), but it 
provides me with a living (tangled) document that I can share with my 
non-programmer colleagues to get their domain-specific feedback about my 
choice of model assumptions, formulas, etc. This enables a level of 
collaboration that I simply could not achieve if I simply wrote the code 
directly. Finally, as a thoroughly unexpected side effect, some of my most 
complicated programs actually became much, much shorter when I rewrote them 
in an LP style (in terms of lines of code, of course). Part of this had to 
do with the available tooling (Org-mode's polyglot literate programming and 
reproducible research facilities are outstanding) and part of it simply 
came from having to write down my ideas in English first. This kept me from 
rushing into writing code and possibly getting lost in those "collapsing 
tunnels" to which Tim alluded. Instead, the additional "hammock time" that 
I took to think my way through how to present my solutions frequently led 
to "Aha!" moments in which I realized a simpler way to express the problem. 
Cliche, I know, but still results are results.

  Get Literate! (use only as necessary; LP may not be recommended for some 
patients due to increased blood pressure and carpal tunnel risk)
~Gary


On Thursday, May 8, 2014 8:57:51 AM UTC-4, Gregg Reynolds wrote:
>
> The thread on documentation that Val started (
> https://groups.google.com/forum/?hl=en#!topic/clojure/oh_bWL9_jI0) is 
> getting a little long so I'm starting a related one specific to litprog.
>
> I've made a start on rethinking LP at 
> https://github.com/mobileink/codegenres/wiki/Rethinking-Literate-Programming
> .
>
> A few key points:
>
> * Knuth's main early LP tool (WEB) was to a certain extent an attempt to 
> fix deficiencies in Pascal, as Knuth himself explicitly acknowledged.  Some 
> aspects of Knuthian LP (KLP) may make sense for imperative languages with 
> side effects; since it's hard to reason about programs written in such 
> languages, added commentary is needed.  But if you already know that 
> functions are side-effect free and data are immutable, you no longer need 
> that.  
> * Programming language design has not evolved in the direction of LP, as 
> we might have expected from some of Knuth's more grandiose pronouncements; 
> instead they have evolved in the direction of greater expressivity, which 
> obviates the need for many kinds of documentation.  You can argue that LP 
> was a fine thing in its day, but the world has moved on.
> * KLP is largely based on the personal aesthetic and psychological 
> preferences of DE Knuth involving issues such as the proper order and mode 
> of presentation of code.  Those are normative issues, and there is no 
> reason to take Knuth's preferences as gospel.  In particular there is no 
> justification for his claim that using LP "methods" leads to "better" 
> code.  It not only depends on what "better" means, it depends on what other 
> methods are available.  Just because writing Pascal in LP was better (for 
> Knuth et al.) than writing plain Pascal does not mean this will always be 
> the case in all languages.  It doesn't generalize.  (To a hammer, 
> everything looks like a goto.)
> * There is (demonstrably) no reason to think that there is any "natural" 
> or "best" order of presentation for code; there are only preferences, and 
> everybody has one, if you catch my drift.  The point again being that Knuth 
> was not on to some kind of laws of programming.  KLP is all about his 
> preferred style, not about the Way Things Are.  
> * KLP is sometimes contrasted with "self-documenting code" To get a grip 
> on what that is and what we can expect from it we need to examine the 
> notions of function, algorithm, and code.  Then it looks like code does not 
> in fact "self-document", if "documentation" is taken to mean explanation.  
> But it does express meaning, and sometimes expressivity is preferrable to 
> explanation.  Maybe that's t

Re: Reduce vs. Comp

2014-05-07 Thread Gary Johnson
Reduce is indeed a swiss-army knife for functional programming over 
sequences.
Of course, in this particular case (i.e., apply a sequence of functions in 
order to an initial value), Clojure's threading operators are the idiomatic 
way to go.

(->> 6 (+ 12) (* -1))

  Cheers,
~Gary

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Concurrency, Parallelism, and State. And Zombies.

2014-03-27 Thread Gary Johnson
Great job on such a tricky chapter. I particularly enjoyed the hilarious 
examples in the spirit of Learn You a Haskell for Great Good.

  ~Gary

On Wednesday, March 26, 2014 9:45:38 AM UTC-4, Daniel Higginbotham wrote:
>
> I've added a new chapter to Clojure for the Brave and True, "Concurrency, 
> Parallelism, and State. And 
> Zombies." 
> Here's an excerpt:
>
> ===
> In this chapter you'll learn what concurrency and parallelism are and why 
> they matter. You'll learn about the challenges you'll face when writing 
> parallel programs and about how Clojure's design helps to mitigate them. 
> Finally, you'll learn a big boatload of tools and techniques for writing 
> parallel programs yourself, including: futures, promises, delays, atoms, 
> refs, vars, pmap, and core.reducers. Also, there will be zombies.
> ===
>
> I hope you all find it useful and entertaining :)
>
> Daniel
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Academy Award goes to a literate program

2014-01-27 Thread Gary Johnson
Awesome! Thanks for sharing the link, Tim.

-- 
-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


Re: A ClojureScript Tutorial For Light Table Users

2014-01-16 Thread Gary Johnson
Great job, David. Looking very sharp!

  ~Gary

-- 
-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


Re: [ANN] Yesql 0.3.0 - Clojure & SQL queries rethought.

2014-01-07 Thread Gary Johnson
defqueries for the win!

Excellent minimal syntax choice, Kris. I'm using yesql in my current work 
project, and it's been a real delight to work with thus far. Being able to 
put multiple queries in one file just makes it that much sweeter.

  ~Gary

On Tuesday, January 7, 2014 10:57:55 AM UTC-5, Kris Jenkins wrote:
>
> Yesql is a simple library for blending SQL queries & Clojure together, 
> cleanly. Here's how it 
> works, 
> and how to use it .
>
> Project: https://github.com/krisajenkins/yesql
> Leiningen: [yesql "0.3.0"]
>
> New since v0.2.x: Support for multiple queries in a single file.
>
> Feedback welcomed,
> Kris
>

-- 
-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


Re: [ClojureScript] Re: AnNN: ClojureScript 0.0-2120

2013-12-20 Thread Gary Johnson
Thanks, Tim. I somehow missed Brandon's exposition earlier in the thread. These 
features look great. Fantastic job, ClojureScript devs!

-- 
-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


Re: AnNN: ClojureScript 0.0-2120

2013-12-16 Thread Gary Johnson
Wait a minute...

  #js data literal support added

Holy $#%^!!! Where is this documented?! MUST...USE...NOW!

-- 
-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


Re: cider status

2013-12-16 Thread Gary Johnson
Just to inject another sample into the population:

As another hacker who lives in Emacs, I found the nrepl -> cider transition 
to be quite painless. It took me maybe an hour of reading the website docs, 
installing/uninstalling packages with package.el, and updating the relevant 
sections of my .emacs.d/init.el file. Not to poo-poo on anyone's parade, 
but it really did seem pretty straightforward to me. So maybe some of the 
pain points people are feeling have to do with general challenges with 
configuring Emacs rather than specific problems with following the online 
cider docs.

As a final note, ac-nrepl is documented on the cider page as working with 
cider. The nrepl-ritz package incompatibility is the only real issue 
missing from the docs. On the other hand, it's come up repeatedly on this 
mailing list, so at least some of us are likely to be aware of it at this 
point.

  ~Gary

On Friday, December 13, 2013 4:04:08 PM UTC-5, Bozhidar Batsov wrote:
>
> On Friday, December 13, 2013 at 7:17 PM, Sean Corfield wrote:
>
> On Thu, Dec 12, 2013 at 11:43 PM, Adrian Mowat 
> > 
> wrote:
>
> Is cider just a new release of nrepl.el or a different thing entirely?
>
>
> Well, it's a "new release" insofar as it's an updated version of
> nrepl.el. In order to switch to it, however, you have to remove
> nrepl.el _and all packages that depend on it_ (which packages are not
> specified in the upgrade instructions so that would be a hit'n'miss
> process)
>
> If someone is not clear it should be improved. I can’t know what problems 
> people encounter is they don’t tell me. cider has both an issue tracker and 
> it’s own mailing list. 
>
> , then you install cider.el and then you also have to update
> various parts of .emac.d/init.el depending on how you had customized
> nrepl. And that part isn't really described in the upgrade
> instructions either so that's also pretty hit'n'miss. 
>
> All configuration options are documented in the README, so I’d say 
> updating the init.el is an easy task.
>  
>
> And then you
> have to reinstall newer versions of the packages you deleted that
> depended on nrepl.el and hope you get versions that depend on cider.el
> instead (since there's no way of telling, based solely on their
> package description I suspect).
>
> The list of package dependencies is more informative than a package's name.
>  
>
>
> And if you use Ritz, that hasn't been updated so you have to stay with
> nrepl.el anyway.
>
> Frankly, I think it was a mistake to rename it and rename various
> functions in it, forcing breakage on dependent packages (which have
> not changed their names as far as I can tell).
>
> You’re thinking short term, but you should be thinking long term. Nobody 
> will remember this transition is a few months. I’m confident that in the 
> greater scheme of things the rename was a good solution. 
>  
>
>
> I use ac-nrepl and the latest version still says it is for nrepl so
> I've no idea whether it will work with cider. I also use nrepl-ritz
>
> ac-nrepl supports only cider. 
>  
>
> but I could live without it. My nrepl-related init.el file contains:
>
> https://www.refheap.com/21729
>
> and it's not clear how that would need changing and whether it would
> continue to work properly.
>
> Your eval-in-repl function is obsolete, since similar functionality lives 
> in cider itself. 
> I have no idea why you’re modifying clojure-mode’s keymap when you should 
> be modifying cider-mode’s keymap instead (+ set-ns is bound to a keycombo 
> by default). Consulting the Changelog would reveal that `nrepl-mode` is now 
> named `cider-repl-mode` and `nrepl-interaction-mode` is now `cider-mode` 
> (it’s basically the same in SLIME). The migration is really simple and I 
> think that people are blowing this problem out of proportion. Of course, I 
> basically live in Emacs, so this is obviously affecting my POV. Less 
> experienced Emacs users might find even simple changes challenging.  
>
> And this isn't just for me - my team all has the same base
> configuration of Emacs and so we'd have to go thru this switch process
> for each team member.
>
>
> As I said previously - if you’re not certain about something you should 
> stop by either cider’s google group or the GitHub project. :-)
>  
>
> -- 
> Sean A Corfield -- (904) 302-SEAN
> An Architect's View -- http://corfield.org/
> World Singles, LLC. -- http://worldsingles.com/
>
> "Perfection is the enemy of the good."
> -- Gustave Flaubert, French realist novelist (1821-1880)
>
> -- 
> -- 
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clo...@googlegroups.com 
> Note that posts from new members are moderated - please be patient with 
> your first post.
> To unsubscribe from this group, send email to
> clojure+u...@googlegroups.com 
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
> --- 
> You received this message because you

Re: [ANN] Major update of modern-cljs

2013-11-21 Thread Gary Johnson
+1 to Bastien's comment.

Your tutorials are by far the best introduction to web programming in 
Clojure and Clojurescript on the web. Thank you so much for keeping these 
up to date so that we can all benefit from them.

  ~Gary

-- 
-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


Re: ANN: Clojure High Performance Programming

2013-11-21 Thread Gary Johnson
This looks incredible! Just bought a copy. Congratulations, Shantanu!

-- 
-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


Re: [ANN] Yesql 0.2.1 - Clojure & SQL queries rethought.

2013-11-18 Thread Gary Johnson
Hi Ray,

  Although the sql-phrasebook does capture much of the same philosophy 
behind Yesql (and has the excellent feature that we can store multiple SQL 
queries in the same file), its syntax is somewhat more unpleasant to my 
eyes than Yesql's macro api.

yesql

-
(defquery users-by-country "some/where/users_by_country.sql")
(users-by-country db-spec "GB")

sql-phrasebook
-
(def pb (sql-phrasebook "test/phrasebook.sql"))
(jdbc/query my-db (pb "select-users-by-id" {:user-ids [123 456 789]}))



I actually do really appreciate having the SQL queries in their own file 
because I do a lot of Literate Programming, and being able to simply tangle 
all my SQL code blocks into a single SQL file and then repurpose them from 
my Clojure app is extremely inviting.

This ability to separate out the SQL from my Clojure and pull it in a la 
carte to manipulate in my running app is one of those great breakthrough 
features that I think makes Enlive and Enfocus such awesome tools for 
collaborating with a team of non-Clojure developers.

  My 2c,
~Gary

P.S. Kris, perhaps you could adjust the defquery syntax to take a key for 
the SQL query you want to load from your external file. This could be part 
of the comment line prepended to the queries that you already use to 
autogenerate docstrings.

(defquery users-by-country "some/where/users_by_country.sql" :that-cool-query)




On Monday, November 18, 2013 6:26:05 AM UTC-5, Ray Miller wrote:
>
> Hi Gary et al,
>
> On 15 November 2013 23:55, Gary Johnson >wrote:
>
>> I really like your approach, but I've also been feeling the burn a bit 
>> with having to store each SQL query in its own file (especially since my 
>> data exploration frequently leaves me cataloging hundreds of them). Take a 
>> look at the approach used in sql-phrasebook:
>>
>>   https://github.com/ray1729/sql-phrasebook
>>
>>   I'm hoping it will give you some ideas to extend Yesql to address this 
>> particular issue, ideally with a nicer syntax than that used in 
>> sql-phrasebook. Otherwise, I think Yesql is bound for great things!
>>
>>
> Is it the syntax of the phrasebook you don't like, or the API for the 
> library?
>
> This was just something I put together quickly, so there's a lot of room 
> for improvement. The phrasebook parser is very simplistic and, although it 
> works for the simple cases where I've used it, I'm concerned it's not 
> robust. It's trivial to change the place-holder syntax from ${var-name} if 
> that's the problem.
>
> My biggest concern is more philosophical. Although there are advantages to 
> defining the queries in an SQL file, the code where you use them needs to 
> know the details of the query (what columns does it return? what bind 
> parameters are needed? is any post-processing aggregation needed?) So I 
> don't like the distance between the Clojure and SQL implied by a 
> phrasebook-based approach.
>
> My current thinking is to do something like:
>
> (defselect select-user
>   "SELECT user.* FROM user
>WHERE user_id = {{user_id}}")
>
> with appropriate syntactic sugar. This would return a function of a 
> database connection, which would return the rows. The next step would be to 
> support a post-processing option for the cases where you modify the 
> returned results in some way:
>
> (defselect select-user-roles
>   "SELECT user.*, role.name AS role_name
>FROM user
>LEFT OUTER JOIN user_role USING(user_id)
>LEFT OUTER JOIN role USING(role_id)
>ORDER BY user.user_id"
>   :post-process (fn [rows] (map (fn [user-rows]
>  (assoc (select-keys 
> (first user-rows) [:user_id :user_name]) 
>:roles (map 
> :role_name user-rows)) 
> (partition-by :user_id rows)))
>
> That way, the post-processing of the results is kept close to the query.
>
> Just some food for thought...
>
> Ray.
>

-- 
-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


Re: [ANN] Yesql 0.2.1 - Clojure & SQL queries rethought.

2013-11-15 Thread Gary Johnson
Hi Kris,

  I really like your approach, but I've also been feeling the burn a bit 
with having to store each SQL query in its own file (especially since my 
data exploration frequently leaves me cataloging hundreds of them). Take a 
look at the approach used in sql-phrasebook:

  https://github.com/ray1729/sql-phrasebook

  I'm hoping it will give you some ideas to extend Yesql to address this 
particular issue, ideally with a nicer syntax than that used in 
sql-phrasebook. Otherwise, I think Yesql is bound for great things!

  Cheers,
~Gary

On Tuesday, November 12, 2013 5:14:14 AM UTC-5, Kris Jenkins wrote:
>
> It depends on which kind of composability you mean. If we're talking about 
> a "SELECT ... FROM ..." here with a "WHERE ..." there, I don't see why not. 
> It's a down-the-road feature, but I'm open to it.
>
> But the kind of composability that would get me excited is the 
> cascalog/datalog kind. Where you could say, "SELECT * FROM employee" and 
> mix that with "SELECT * FROM deparment" and get an automatic, 
> sensibly-optimised join. That's real composibility, beyond mere string 
> concatenation. No, I don't see Yesql ever supporting that. (There again, I 
> haven't seen it from any of the Clojure-SQL-DSLs either. If you have, 
> please point me to them. I'd be interested!)
>
> Cheers,
> Kris
>
> On Tuesday, 12 November 2013 03:35:46 UTC, John Hume wrote:
>>
>> For me, the one feature that can justify an internal DSL for generating 
>> SQL is the ability to compose queries. I assume that's not on the Yesql 
>> roadmap. 
>> On Nov 11, 2013 5:10 AM, "Kris Jenkins"  wrote:
>>
>>> https://github.com/krisajenkins/yesql
>>>
>>> Yesql is a simple library for blending SQL & Clojure together, cleanly. 
>>> Here's how it works , 
>>> and how to use it .
>>>
>>> Feedback welcomed,
>>> Kris
>>>
>>> -- 
>>> -- 
>>> You received this message because you are subscribed to the Google
>>> Groups "Clojure" group.
>>> To post to this group, send email to clo...@googlegroups.com
>>> Note that posts from new members are moderated - please be patient with 
>>> your first post.
>>> To unsubscribe from this group, send email to
>>> clojure+u...@googlegroups.com
>>> For more options, visit this group at
>>> http://groups.google.com/group/clojure?hl=en
>>> --- 
>>> You received this message because you are subscribed to the Google 
>>> Groups "Clojure" group.
>>> To unsubscribe from this group and stop receiving emails from it, send 
>>> an email to clojure+u...@googlegroups.com.
>>> For more options, visit https://groups.google.com/groups/opt_out.
>>>
>>

-- 
-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


Re: Clojure for the Brave and True, an online book for beginners

2013-09-04 Thread Gary Johnson
Looks pretty solid. Great work so far.

Also +1 for the Emacs coverage. Despite the fact that our surveys still 
show the majority of Clojure users develop in Emacs, this mailing list 
frequently exhibits an anything-but-Emacs tone. By all means add links to 
other editors for folks who are already using something else, but I for one 
think you made a smart choice there. Better to learn Emacs now than to 
learn it later after trying two or three other editors that don't quite cut 
it.

Also, just a quick note, your Emacs search keybindings were incorrect in 
that chapter. C-s and C-r are just regular isearch-forward and 
isearch-backward. Regexp search keybindings (isearch-forward-regexp and 
isearch-backward-regexp) are C-M-s and C-M-r respectively.

  Over and out,
~Gary

On Wednesday, September 4, 2013 12:24:15 PM UTC-4, Dima Sabanin wrote:
>
> Hi Daniel,
>
> Keep up the great work! I really enjoyed the material and how it's 
> presented.
>
> Thanks,
> Dima
>
>
> On Mon, Sep 2, 2013 at 11:35 AM, Daniel Higginbotham 
> 
> > wrote:
>
>> Hi all,
>>
>> I've been putting together http://www.braveclojure.com/ and would love 
>> feedback. I've tried to make it entertaining and super beginner-friendly.
>>
>> Thanks!
>> Daniel
>>
>> -- 
>> -- 
>> You received this message because you are subscribed to the Google
>> Groups "Clojure" group.
>> To post to this group, send email to clo...@googlegroups.com
>> Note that posts from new members are moderated - please be patient with 
>> your first post.
>> To unsubscribe from this group, send email to
>> clojure+u...@googlegroups.com 
>> For more options, visit this group at
>> http://groups.google.com/group/clojure?hl=en
>> --- 
>> You received this message because you are subscribed to the Google Groups 
>> "Clojure" group.
>> To unsubscribe from this group and stop receiving emails from it, send an 
>> email to clojure+u...@googlegroups.com .
>> For more options, visit https://groups.google.com/groups/opt_out.
>>
>
>
>
> -- 
> Best regards,
> Dima Sabanin
> http://twitter.com/dimasabanin 
>

-- 
-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


Re: Story

2013-08-08 Thread Gary Johnson


> I'm concerned that the ability to freely order comments and code will not 
> interact well with Clojure's namespaces.  With Clojure's namespaces, you 
> can have things with the same name in two different namespaces.  Functions 
> local to a namespace are referred to in one way, whereas you need some sort 
> of prefix to refer to one in a different namespace.  These prefixes are 
> often aliases, and the aliases may vary from one context to another, for 
> example, in one namespace I may refer to clojure.string as `str` and in 
> another namespace I may refer to it as `string`.
>
 
 

How do you deal with this "lack of context" when you present your code in a 
> way that is completely unrelated to the namespace organization of your 
> files?
>
>
Well, my experience thus far has led me down two different roads here.

Sometimes, I follow the path you came to on your own, which is to use one 
section or chapter per namespace. Within that section/chapter I can 
reorganize my code into whatever order lends itself to the clearest 
explanation. Because I use org-babel, it can export each namespace section 
to its own file during the tangling process. It's straightforward to run 
the program through the REPL or leiningen at that point.

The other approach that I have tried a few times now is to simply throw out 
the whole namespace construct entirely. After all, namespaces in functional 
programming mostly serve as simply a tool for collecting together functions 
and global vars that work together to accomplish some shared goal. If I am 
working on a literate program, it seems very natural for me to simply use 
sections/chapters to organize my functions by their purpose. The namespace 
then just becomes an unnecessary build construct. That is, I just tell 
org-babel to tangle the entire codebase to a single .clj file. Simple.
 

> Actually it isn't really a change in workflow but a change in mindset.
>> Literate programming is not documentation, they are different ideas.
>>
>
> Here's why I called it a change in workflow -- please correct me if I'm 
> mistaken:
>
> Every time the subject of literate programming comes up, I ask one simple 
> question:  When you get a stacktrace, is the file/line number information 
> correct?  A year or two back when I asked this, you elaborated that for 
> you, this was mostly a non-issue.  You said you developed your code by 
> sending over one tiny code block at a time to the REPL, rather than sending 
> a whole file over, and you never used any debugging facilities.  I consider 
> that a change in workflow.
>

I'm in the same boat with Tim. I try to test my functions one at a time 
through the REPL if possible. Whenever I have to make several modifications 
to different parts of the program at once, then I'll just re-evaluate the 
file and resume testing it one piece at a time. It is true that the 
stacktraces don't tend to get the file/line numbers right, but since 
Clojure stacktraces are good at naming the function where the error 
occured, I rarely find that to be an issue that C-s or C-r 
(isearch-forward/backward) can't solve in an instant.
 

>  
>
>>
>> For Clojure specific efforts see
>> http://daly.axiom-developer.org/clojure.pdf (PDF)
>> http://daly.axiom-developer.org/clojure.pamphlet (source)
>>
>
> This is a great example of using literate programming to document a 
> program that is complete and stable.  Have you successfully used literate 
> programming in a program that is rapidly evolving?
>
>
I have developed a rather large fire simulation toolkit using the LP model, 
and it was...interesting. Prior to that, I had only created shortish 
programs that were mostly just helping me to get my feet wet with the 
concepts and workflows of literate programming. When I worked on the fire 
program though, I ran into several new hurdles and successes.

The benefit of LP was (not surprisingly) that my design errors really 
jumped right out at me when I tried to explain them in English. Previously, 
I had started hacking together this program in the usual non-LP way, but I 
started to get stuck in some of the messy statistical details. I backed up 
and started over using LP, and my code's organization really came together 
beautifully in a matter of a couple of days of hacking.

The downside unfortunately was that I had never written a literate program 
at that scale before, and lacking Tim's 42 years of experience, I wasted a 
lot of time just trying to figure out basic code organization things like 
the ones you are asking in this thread: How do I deal with these namespace 
imports? What is the best way to organize toplevel chunk references? Should 
they be sequential or hierarchical? Can org-babel support multiple code 
blocks with the same name in the same way that Tim's tangle.lisp program 
does? (Hint: the answer is no) Why does tangling work with 
swank-clojure+SLIME but not with NREPL? (I had to patch that) How do I get 
org-mode to communicate with the Clojur

Re: Story

2013-08-08 Thread Gary Johnson
Again. I'm with you on this one, Tim. Fear not. You aren't the only crazy 
Clojure programmer putting the LP bug in people's ears. I must say, your 
work on creating a literate version of the Clojure source was really 
amazing. Any plans for maintaining it in the future as new Clojure releases 
keep rolling out?

  ~Gary

On Thursday, August 8, 2013 12:00:26 PM UTC-4, da...@axiom-developer.org 
wrote:
>
> >   I'm with you 100% on the mind-blowing greatness of literate 
> >   programming, 
>
> Actually, it's not the technology of literate programming I'm on about. 
>
> Rich Hickey comes up with marvelous and insightful ideas and reduces 
> them to practice, like his work on reasonable big-O data structures 
> or his work on software transactional memory. Or his work on ... 
>
> Yet if you look at the code you see nothing. 
>
> Which means that the next set of people who get to slice-and-dice 
> the code after Rich will miss some of the insight and get it wrong. 
> I've seen it happen in many places. The apprentice is rarely as good 
> as the master. Not to cast stones at the rest of the Clojure group, 
> I'm just using hasty-generalization, my favorite form of reasoning, 
> from my experience. 
>
> I find that literate programming is the only way to capture the 
> insight and keep it where it belongs, adjacent and intermixed with 
> the code, but written for humans-to-human communication. Clojure 
> is heavy with great ideas and they need to be communicated intact. 
>
> Tim Daly 
>
>
>

-- 
-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.




Re: Story

2013-08-08 Thread Gary Johnson
Tim,

  I'm with you 100% on the mind-blowing greatness of literate programming, 
but I do have to correct you on org-babel. It is actually a very nicely 
done LP development system. You write your content as you would a book or 
article, using sections and subsections, paragraphs, ordered and unordered 
lists, tables, embedded images, links, and so on. Code is placed within 
specially delimited blocks that specify the source language (thus 
triggering the appropriate emacs mode for syntax highlighting) as well as 
special rules for code and output export. Obviously, code blocks can (and 
should be) out of order in the Org document so as to enable clear 
exposition. When you are ready to test out the finished product, org-babel 
provides built in tangle and weave commands.

  I used your homebrew solution on axiom-developer.org a few years ago when 
I was first getting my feet wet with literate programming. However, 
org-babel provides several unique advantage IMHO over 
make+tangle.lisp+latex:

  1. Org markup is much simpler and more visually recognizable than LaTeX 
although anything you can do with LaTeX, you can do in Org mode. This is 
because you can export an Org file to LaTeX and Org markup syntax allows 
for inline LaTeX code blocks if you want to do anything that is not already 
supported by the standard markup. 

  2. Org mode can export my Literate Program to many, many different 
formats with a simple keystroke. These include (but are not limited to) 
HTML, LaTeX, ASCII, and LibreOffice ODF. Thus my woven program can be 
distributed as a PDF file, Word Document, or webpage.

  3. Org mode supports multiple programming languages within a single file. 
This allows me to chain together in the same document (and thus in the same 
exposition) a shell script written in Bash, a Python script for generating 
a graph, and a Clojure program for running a webserver. When I trigger the 
tangle procedure, each language's code is written out to its own file(s) 
and run through the correct interpreter or compiler. Amazingly, code blocks 
in different languages can even be annotated such that they pass values 
between one another like functions in a Lisp environment.

  4. Org supports Live Code Evaluation. By simply placing my cursor (the 
point in Emacs jargon) within any code block in my Literate Program and 
pressing C-c C-c, Emacs will trigger an external shell for that language, 
recursively expand any code block references included within the selected 
code block (i.e., a local tangling procedure), send the expanded code to 
the external shell (be it an interpreter or compiler), evalutate the 
result, and pretty print this result into my LP file in an annotated RESULT 
block directly after the code block that I evaluated. If I tweak the code 
and reevaluate it, the RESULT block's contents are updated in place. This 
provides an in-document multi-language REPL-like experience. Note, of 
course, that the contents of these RESULT blocks may then be optionally 
woven into my formatted output, which is particularly useful in explaining 
the behavior of code with examples or in automatically generating tables or 
figures for illustrative purposes.

There are many more features that Org mode supports that would take...well, 
the entire Org mode manual to explain. However, these LP features are 
really quite useful, and I do genuinely think more people interested in LP 
should give them a try.

For more information, please check out the Babel section of the Org Mode 
manual:

  http://orgmode.org/worg/org-contrib/babel/intro.html

I also HIGHLY recommend the 2012 journal article published on Org Mode's 
Babel features in the Journal of Statistical Software:

*A Multi-Language Computing Environment for Literate Programming and 
Reproducible Research*
  by Eric Schulte, Dan Davison, Thomas Dye, Carsten Dominik

  http://www.jstatsoft.org/v46/i03


  As you like to say, Tim...

  Get Literate!
~Gary


On Wednesday, August 7, 2013 8:36:51 PM UTC-4, da...@axiom-developer.org 
wrote:
>
> > Recently, I discovered the "story" literate programming tool for 
> Clojure, 
> > which I prefer to marginalia: 
> > https://github.com/jedahu/story 
> > 
> > ... (snip) ... 
> > 
> > I had never heard of "story", but ran across a mention of it while 
> looking 
> > through the issues on marginalia's github site, so I decided to give it 
> a 
> > try.  It's similar to marginalia, in that it's not true literate 
> > programming -- it doesn't let you freely order your comments and code 
> > irrespective of how they appear in the final files, but is a tool for 
> > extracting long comments written in markdown in order to weave some sort 
> of 
> > narrative explanation of why the code is written the way it is. 
>
> The ability to freely order comments and code is actually vital to the 
> idea of literate programming. The key idea is writing to communicate 
> ideas to another person. This almost certainly involves reordering 
> a

Re: changing a value in a vector of maps

2013-07-31 Thread Gary Johnson
Here's the code analogue of your find-assoc-in function for the approach 
Cedric is proposing. I actually came to the same solution before reading 
the responses to your post, so it's good to see that others also think this 
is a more memory efficient approach (obviously for larger vectors than the 
example).

(defn my-find-assoc-in
  [[test-key update-key] [test-val update-val] mapvec]
  (reduce
   (fn [v idx] (if (= (get-in v [idx test-key]) test-val)
   (assoc-in v [idx update-key] update-val)
 v))
   mapvec
   (range (count mapvec


Happy hacking,
  ~Gary

-- 
-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.




Re: --> macro proposal

2013-07-16 Thread Gary Johnson
Ugh. What a pointless thread. Someone could have just said:

 ---
 It's already in clojure 1.5. The form you are looking for is called as->.
 Your original example would be written like this:

  (as-> 3 x (+ 1 x 4) (prn "answer:" x))
  ---

Done. Yeesh.

On Sunday, July 14, 2013 12:34:02 PM UTC-4, Jeremy Heiler wrote:
>
> On Sat, Jul 13, 2013 at 9:08 PM, Daniel Dinnyes 
> > 
> wrote: 
> > Just made a quick search on `main arguments` on both Google and 
> Wikipedia. 
> > Do you mean the arguments in `public static void main (String[] args)`? 
> If 
> > not please provide some definition what do you mean by main arguments. 
> Else 
> > the point is meaningless. 
>
> He means the arguments you are threading. 
>

-- 
-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.




Re: matching, assigning and branching in one form

2013-06-24 Thread Gary Johnson
The condp form is very nice and concise if you have multiple match clauses. 
If you are more generally just looking to perform a single 
match/assign/branch task, I'd recommend this little nugget of clojure 
wisdom: Forget ye not the hidden might of if-let.

(if-let [[_ from to message] (re-find #"^:(.*?)!.*PRIVMSG (.*) :(.*)" msg)]
  (true-branch)
  (false-branch))

If you use an expression that returns a sequence with if-let, just wrap it 
in a call to seq, like so:

(if-let [[a b c d] (seq (filter anything-good? some-coll))]
  (true-branch)
  (false-branch))

Happy hacking,
  ~Gary

On Friday, June 21, 2013 11:43:50 AM UTC-4, Steven Arnold wrote:
>
> Hi, I am writing a simple IRC bot, pretty much just for fun, starting with 
> a simple implementation originally posted by Nurullah Akkaya on his blog. 
>  It already does what it's supposed to, which is message a fortune from 
> mod-fortune (shelling out) when someone asks it to. 
>
> However, there's a bit of code I don't like.  It looks like this: 
>
>  (cond 
>(re-find #"^:(.*?)!.*PRIVMSG (.*) :(.*)" msg) 
>  (let [[_ from to message] (re-find #"^:(.*?)!.*PRIVMSG (.*) 
> :(.*)" msg)] 
>[...logic omitted...] 
>
> What's happening is we're looking for a PRIVMSG, and if we find one, we 
> scan the message again and pull out the chunks we're interested in, and use 
> them in the "logic" part below. 
>
> The problem is I don't like maintaining two regular expressions.  I wish I 
> could use it only once, and therefore change it only once if it needs to be 
> modified.  I'd prefer to see an expression that looks like this (for 
> example): 
>
> (cond 
>  (if-matched #"^:(.*?)!.*PRIVMSG (.*) :(.*)" msg 
>[from to message] 
>(true form) 
>(optional false form))) 
>
> The if-matched acts as a let block while pulling out groups and assigning 
> to local variables at the same time.  Also, it ignores the first "match" of 
> re-find, which is the entire expression -- not generally useful to me. 
>  Maybe if-matched-groups would ignore the overall expression, and 
> if-matched would include it. 
>
> I suppose a macro might be the way to go to accomplish this, but I wonder 
> if there are any Clojure tricks that could accomplish this short of a 
> macro.  Also, do any fellow Clojurians think a macro like this is a bad 
> idea in general?  Would you suggest taking a different tack to solve this 
> problem? 
>
> Thanks in advance! 
> steven

-- 
-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.




Re: Need to render some entities moving across a grid

2013-06-18 Thread Gary Johnson
Hi there,

  I have an IMO fairly straightforward method for doing this that I wrote 
for use in my own flow modelling code. The idea is that you create a matrix 
(vector of vectors in my case) containing refs all initialized to some base 
value (e.g., 0). Then I wrap my with-animation macro around a call to the 
toplevel simulation function which will manipulate those refs internally. 
with-animation will spawn a JFrame that shows the matrix with a green (low) 
to red (high) color ramp with an automatically adjusting legend along the 
bottom. The image of the matrix is refreshed by its own thread once every 
*animation-sleep-ms*. All the drawing and refreshing code is available in a 
namespace within one of my own projects that I haven't yet broken into its 
own library, but I suppose I could do that easily enough if this approach 
sounded useful to you.

Right now you can see the code I am talking about here:

  https://github.com/lambdatronic/clj-span/blob/master/src/clj_span/gui.clj

You would just pull in that namespace and the ones it depends on (feel free 
to copy them from my project or make the whole thing a dependency of your 
code). Then you would call it like so:

(with-animation :numbers 0.0 matrix1 matrix2
  (run-my-simulation matrix1 matrix2))

The idea is that run-my-simulation (your code) will manipulate the refs in 
these two different matrices, and then with-animation (my code) will render 
them in two panels side-by-side with matching legends and color ramps, so 
you can see their differences. I had built it this way because I needed to 
compare flow results under two different scenarios and only wanted to run 
the simulation once with both scenarios happening in parallel. If you just 
needed to show a single matrix, it should be pretty obvious what to comment 
out of the with-animation macro.

Good luck and happy hacking,
  ~Gary


On Monday, June 17, 2013 3:17:01 AM UTC-4, vemv wrote:
>
> I'm implementing a program D. Hofstadter describes in *Fluid Concepts: *
> https://github.com/vemv/jumbo/* *Even in the original text, 
> concurrency/parallelism is a crucial part of the domain so Clojure is super 
> well-suited.
>
> While visualising the carried-in process is not a goal of the project, 
> providing a rendering of the 'entities' of the modelled world would help a 
> lot explaining my program to others (which I have to).
>
> The thing is - I haven't ever done significant graphics programming - I 
> don't know e.g. what libraries to use, how to create smooth movements, keep 
> the code high-level... and sadly I don't have a lot of time in my hands.
>
> Would anyone knowledgeable in the matter mind coding a quick-and-dirty 
> solution for me? I could buy you a couple books in exchange hahaha. You'd 
> have exactly one week, and I of course would provide all needed 
> information/feedback.
>
> Feel free to reply here or contact me at vemv [at] vemv [dot] net.
>
> Thanks for your time!
>

-- 
-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.




Re: Macro for bailout-style programming

2013-03-24 Thread Gary Johnson
+1 for some-> and some->>.

I use this all the time in my coding. They used to be -?> and -?>> in 
clojure.core.incubator, so I'm extremely happy that they finally made their 
way into core proper.

On Saturday, March 23, 2013 7:25:00 PM UTC-4, Evan Gamble wrote:
>
> The let? macro addresses such situations: 
> https://github.com/egamble/let-else

-- 
-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.




Re: Clojure 1.5 print-table, org-mode babel, and org-mode HTML gen

2013-03-04 Thread Gary Johnson
+1 for org-babel. I put together an example project solving the Potter Kata 
on github several months ago, so if someone is looking for some examples of 
how you might do LP with org-babel, take a look at it here:

  https://github.com/lambdatronic/org-babel-example

  Happy hacking,
~Gary

On Sunday, March 3, 2013 6:03:51 PM UTC-5, greg r wrote:
>
> Here's a little project I worked on:
>
> https://github.com/Greg-R/incanterchartcustom
>
> I'm just now learning git, so I hope the files are intact in the 
> repository.  I cloned to another machine and they appear to be OK.
>
> The Incanter chart PDF document shows what is possible with regard to 
> documenting code and showing a nice export result.
> The repository also includes the source .org file.  In theory, if you have 
> everything set up correctly you can reproduce the
> PDF document exactly.  Since it is generating PDF charts, there are lots 
> of side-effects and whatever directory you are running
> in will get filled up with the chart files.  I used LaTeX snippets within 
> the org file to include the chart graphics in the exported tex
> file and thus the eventual PDF.
>
> I don't use C-c C-e p.  This doesn't always work, and I prefer C-c C-e l 
> which exports the .tex file only.  I open the .tex file with
> the Texworks application which has worked really well for me for editing 
> LaTeX documents.  Texworks has the ability to jump between
> the PDF and the .tex file and vice-versa, which makes troubleshooting much 
> easier.
>
> I did a bunch of data processing for work using org, Clojure, and Incanter 
> to produce reports in PDF.  I created several Leiningen projects
> to attack various aspects of the data manipulation.  Then within Clojure 
> code blocks in org, the various namespaces are used to process
> data at the appropriate points in the document.  None of the output was 
> inserted directly into the org file.  That turned out to be impractical
> as some of the generated documents were hundreds of pages long.  The 
> Clojure/Incanter code chunks generated .tex files which were included
> in the exported output via LaTeX code blocks.  Really in this case the 
> org-babel system operated more as a document/code organizer than
> as a programming system.  But what an organizer it is!!!  I saved 
> hundreds, maybe thousands of man hours of manual document generating.
>
> There were several technologies to learn to get it all to work in harmony:
>
> Clojure
> Incanter
> Emacs (24.2) (including some Elisp in the .emacs file)
> org
> babel
> Leiningen
> LaTeX
> Texworks
> nrepl (this will require some extra stuff in the .emacs file to get babel 
> to work)
>
> It took a lot of work, but I think the org-babel system is really worth it!
>
> Regards,
> Greg
>
> On Saturday, March 2, 2013 11:52:07 PM UTC-5, Mark C wrote:
>>
>> Worked like a charm. Thanks!
>>
>> Babel is fun. I really like the idea of being able to code in multiple 
>> languages in one document - and have return values from one feed another. 
>> And I just found out you can include TeX too - just starting to play with 
>> that. I'd love to hear more about how you use clojure and org mode together.
>>
>> Mark
>>>
>>>
>>>

-- 
-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.




Re: [ANN] nrepl.el 0.1.6 released

2013-01-30 Thread Gary Johnson
Huzzah! The uphill climb continues apace!

On Tuesday, January 29, 2013 10:07:54 PM UTC-5, Tim King wrote:
>
> I am pleased to announce that nrepl.el v0.1.6 has been released, and is 
> now available on marmalade.
>
> Preview versions of the next release are available on Melpa.
> See the Readme on github (https://github.com/kingtim/nrepl.el) for 
> installation and usage instructions.
>
> Notable changes since our last release:
> - Ported SLIME macroexpansion mode (see README for full documentation)
> - Updated macroexpansion to use pprint with code-dispatch
> - Eldoc argument highlighting
> - Simplify popup buffer quit/restore using `quit-window'.
> - Add nrepl-disconnected-hook and disable nrepl when disconnected.
> - Emit server log output at bottom of *nrepl-server* buffer. (Brian Rowe)
> - Reset nrepl-buffer-ns on nrepl-restart.  Fixes issue #187.
> - Implement nrepl-mode as a derived mode. (Bozhidar Batsov)
> - fix #194 - stacktrace buffer was not respecting nrepl-popup-stacktraces 
> (Bozhidar Batsov)
> - Get key bindings documentation into the minor mode descriptions (Ivan 
> Necas)
> - Fix message formatting for results containing "%" (fixes issue #195).
> - Fix NPE in nrepl-jump (issue #124).  (cola-zero)
> - Fix nrepl to work with fish shell (issue #192). (Dario Bertini)
> - Adjusted the javadoc keybinding and mentioned it in the README. 
> (Bozhidar Batsov)
> - made the TAB command in the nrepl-mode buffers configurable (Bozhidar 
> Batsov)
> - Added convenience function to report the version of nREPL in use. (fogus)
> - Fix issue #163 - exclude ns from nrepl-load-file.
> - Ignore "killed" and "hangup" events in sentinel (Chris Bilson)
> - Shift-Home and Shift-Ctrl-a in repl, which select just the user input 
> when on the input line. (Ivan Kozik)
> - Clear the correct region when replacing the input line. (Ivan Kozik)
> - Fix issue #146.  Include "@" in nrepl-input-complete-p.
> - Handle stdout messages that arrive after status "done"
> - Various and sundry bug fixes and documentation additions and updates.
>
> Many thanks to all the contributed their time and energy by 
> reporting issues, submitting patches and testing out bug fixes and features.
>
> Enjoy!
>
> Cheers,
> Tim
>
>

-- 
-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.




Re: screencast: friend and creating a login form

2013-01-30 Thread Gary Johnson
Fantastic job! I wish something like this had been available when I built 
my first website with Friend. I ended up rolling my own workflows after 
giving up on tracking all the internals of interactive-form.

  ~Gary

On Tuesday, January 29, 2013 3:55:13 PM UTC-5, Nelson Morris wrote:
>
> I've released a screencast on friend and using its interactive-form 
> workflow to create a login form. 
> http://www.clojurewebdevelopment.com/videos/friend-interactive-form 
>
> I've got more in various stages of completion, so I'd be interested in 
> hearing feedback. 
>
> Thanks, 
> Nelson Morris 
>

-- 
-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.




Re: emacs - how to wean me off the family of Java IDEs

2013-01-16 Thread Gary Johnson
There's a MELPA package (use `M-x package-list-packages') called 
sr-speedbar that displays the speedbar in the same frame you are already 
working in. I just stick sr-speedbar-toggle on F11 and call it a day. YMMV.

On Wednesday, January 16, 2013 1:45:35 PM UTC-5, Sean Corfield wrote:
>
> On Wed, Jan 16, 2013 at 8:33 AM, Amirouche Boubekki 
> > wrote: 
> >>  - is there a decent project explorer.  I really miss the "tree on the 
> >> left, editor on the right" layout 
> > speedbar: «C-X speedbar» 
>
> M-x speedbar - but that looks very interesting, thank you! It's kinda 
> funky in full-screen mode on Mac OS X but it does satisfy the project 
> explorer itch. 
> -- 
> Sean A Corfield -- (904) 302-SEAN 
> An Architect's View -- http://corfield.org/ 
> World Singles, LLC. -- http://worldsingles.com/ 
>
> "Perfection is the enemy of the good." 
> -- Gustave Flaubert, French realist novelist (1821-1880) 
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Re: ANN: bouncer, validation library for clojure

2013-01-15 Thread Gary Johnson
Worked like a charm. Thanks.

On Tuesday, January 15, 2013 12:33:26 PM UTC-5, Gary Johnson wrote:
>
> Right, I was testing against 1.5.0-RC1 and 1.5.0-RC2. Same problem 
> occurred both times. I should have reported that in my initial bug report. 
> Sorry about that. Also, thanks for the quick turnaround. I'll pull it and 
> test it out.
>
>   ~Gary
>
> On Monday, January 14, 2013 7:16:29 PM UTC-5, Leonardo Borges wrote:
>>
>> Sean pointed me to it in the other thread. I read the ticket and 
>> discussion - I personally don't feel it's abuse. To me it feels as natural 
>> a use of destructuring as any other.
>>
>> just my 2c.
>>
>> Leonardo Borges
>> www.leonardoborges.com
>>
>>
>> On Tue, Jan 15, 2013 at 11:14 AM, Toby Crawley wrote:
>>
>>> This issue has already been reported and filed:
>>> http://dev.clojure.org/jira/browse/CLJ-1140
>>>
>>> There's been some discussion around that issue on clojure-dev@ as to
>>> whether this is a regression or an abuse of destructuring.
>>>
>>> Leonardo Borges writes:
>>>
>>> > Alright so the bug appears in Clojure 1.5.0-RC1 - I'm not sure whether 
>>> this
>>> > is a regression or intended behaviour so I'll send a separate email to 
>>> the
>>> > list about that.
>>> >
>>>
>>>
>>> --
>>> Toby Crawley
>>> http://immutant.org | http://torquebox.org
>>>
>>> --
>>> You received this message because you are subscribed to the Google
>>> Groups "Clojure" group.
>>> To post to this group, send email to clo...@googlegroups.com
>>> Note that posts from new members are moderated - please be patient with 
>>> your first post.
>>> To unsubscribe from this group, send email to
>>> clojure+u...@googlegroups.com
>>> For more options, visit this group at
>>> http://groups.google.com/group/clojure?hl=en
>>>
>>
>>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Re: ANN: bouncer, validation library for clojure

2013-01-15 Thread Gary Johnson
Right, I was testing against 1.5.0-RC1 and 1.5.0-RC2. Same problem occurred 
both times. I should have reported that in my initial bug report. Sorry 
about that. Also, thanks for the quick turnaround. I'll pull it and test it 
out.

  ~Gary

On Monday, January 14, 2013 7:16:29 PM UTC-5, Leonardo Borges wrote:
>
> Sean pointed me to it in the other thread. I read the ticket and 
> discussion - I personally don't feel it's abuse. To me it feels as natural 
> a use of destructuring as any other.
>
> just my 2c.
>
> Leonardo Borges
> www.leonardoborges.com
>
>
> On Tue, Jan 15, 2013 at 11:14 AM, Toby Crawley 
> 
> > wrote:
>
>> This issue has already been reported and filed:
>> http://dev.clojure.org/jira/browse/CLJ-1140
>>
>> There's been some discussion around that issue on clojure-dev@ as to
>> whether this is a regression or an abuse of destructuring.
>>
>> Leonardo Borges writes:
>>
>> > Alright so the bug appears in Clojure 1.5.0-RC1 - I'm not sure whether 
>> this
>> > is a regression or intended behaviour so I'll send a separate email to 
>> the
>> > list about that.
>> >
>>
>>
>> --
>> Toby Crawley
>> http://immutant.org | http://torquebox.org
>>
>> --
>> You received this message because you are subscribed to the Google
>> Groups "Clojure" group.
>> To post to this group, send email to clo...@googlegroups.com
>> Note that posts from new members are moderated - please be patient with 
>> your first post.
>> To unsubscribe from this group, send email to
>> clojure+u...@googlegroups.com 
>> For more options, visit this group at
>> http://groups.google.com/group/clojure?hl=en
>>
>
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Re: ANN: bouncer, validation library for clojure

2013-01-14 Thread Gary Johnson
Hey Leonardo,

  There's a critical bug in 0.2.2-RC1 in the bouncers.core/wrap function. 
An IllegalArgumentException is triggered whenever a validator is not passed 
an explicit :message field. It looks like this was introduced in the 
process of trying to allow validators to take an arbitrary number of input 
args (a very good thing IMO). Here's a minimum case for replicating this 
error at your repl: 

(let [{:keys [message] :or {message "foo"}} '()] message)
IllegalArgumentException No value supplied for key: null  
clojure.lang.PersistentHashMap.create (PersistentHashMap.java:77)

This is being triggered in your wrap function when you apply map 
destructuring to the right-hand result of (split-with (complement keyword?) 
args). Anyway, here is a patched version of wrap that should fix the 
problem. FWIW, I also fixed the docstring typo "erros" -> "errors".

(defn wrap
  "Wraps pred in the context of validating a single value

  - `acc`  is the map being validated

  - `pred` is a validator

  - `k`the path to the value to be validated in the associative 
structure acc

  - `args` any extra args to pred

  It only runs pred if:

  - the validator is optional *and* there is a non-nil value to be 
validated (this information is read from pred's metadata)

  - there are no previous errors for the given path

  Returns `acc` augmented with a namespace qualified ::errors keyword
"
  [acc [pred k & args]]
  (let [pred (h/resolve-or-same pred)
k (if (vector? k) k [k])
error-path (cons ::errors k)
{:keys [default-message-format optional]} (meta pred)
[args message-kv] (split-with (complement keyword?) args)
message (get (apply hash-map message-kv) :message 
default-message-format)
pred-subject (get-in acc k)]
(if (or (and optional (nil? pred-subject))
(not (empty? (get-in acc error-path)))
(apply pred pred-subject args))
  acc
  (update-in acc error-path
 #(conj % (format message (name (peek k

Cheers,
  ~Gary


On Sunday, January 13, 2013 8:03:36 PM UTC-5, Leonardo Borges wrote:
>
> Thanks, really appreciate the kind words.
>
> I just pushed [bouncer "0.2.2-RC1"] so feel free to give that a go :)
>
> Cheers,
> Leo
>
> Leonardo Borges
> www.leonardoborges.com
>
>
> On Fri, Jan 11, 2013 at 3:44 PM, faenvie  >wrote:
>
>>
>> i took a look at it. bouncers DSL seems smart inside and out. 
>> Has an excellent Documentation too. Thanks for sharing it.
>>
>>  -- 
>> You received this message because you are subscribed to the Google
>> Groups "Clojure" group.
>> To post to this group, send email to clo...@googlegroups.com
>> Note that posts from new members are moderated - please be patient with 
>> your first post.
>> To unsubscribe from this group, send email to
>> clojure+u...@googlegroups.com 
>> For more options, visit this group at
>> http://groups.google.com/group/clojure?hl=en
>>
>
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Re: ANN: bouncer, validation library for clojure

2013-01-10 Thread Gary Johnson
Thanks for releasing this library. I've written quite a few large 
command-line driven applications in Clojure thus far, and each one has used 
a slightly different homegrown approach as different core functionality 
became available (and the contrib libs kept mutating). Your state monad 
inspired approach definitely clicks with me, and I'll be looking forward to 
your future releases.

Also, I agree with Stathis that there is a problem including the errors map 
in the original data structure under an unqualified keyword. Of course, if 
you change validate to not modify the input map that is being validated, 
then you no longer need a state monad to model the validation workflow. 
This could just as easily be done with a simple reduce. In this instance, 
I'd guess that just qualifying the ::errors keyword would probably stick 
closest to your original model. Maybe I'm totally missing the mark here 
though.

Additionally, one thing that bit me when using validate with multiple tests 
was that there's no early exit strategy. For example, imagine I have 
written a test like the following:

(def config-params {:input-dir "some/directory/path" :output-dir 
"some/other/directory/path"})

(defvalidator directory
  {:default-message-format "%s must be a valid directory" :optional false}
  [path]
  (.isDirectory ^File (clojure.java.io/file path)))

(defvalidator readable
  {:default-message-format "%s is not readable" :optional false}
  [path]
  (.canRead ^File (clojure.java.io/file path)))

(defvalidator writeable
  {:default-message-format "%s is not writeable" :optional false}
  [path]
  (.canRead ^File (clojure.java.io/file path)))

(validate config-params
  :input-dir [required directory readable]
  :output-dir [required directory writeable])

The problem that I run into is that if for some reason :input-dir or 
:output-dir are not defined in config-params, then I get a 
NullPointException when .isDirectory is called in the directory validator. 
I can, of course, dodge this bullet by setting :optional true in the 
directory, readable, and writeable validators. However, as evidenced by the 
required validator's presence in my test vectors, I actually do want these 
fields to be present and to pass all tests. So the semantics sort of look a 
bit off to me in this instance.

Another case that perhaps illustrates my point a little more clearly is 
this one:

(defvalidator <10 {:default-message-format "%s must be less than 10" 
:optional false} [x] (< x 10))

(validate {:foo "I'm a string, but I should be a number"}
  :foo [required number <10])

Here, I obviously get this exception: ClassCastException java.lang.String 
cannot be cast to java.lang.Number  clojure.lang.Numbers.lt

Again, my problem is that since number fails, I would like <10 to never be 
called. The :optional flag can't help me here because it only disables 
validators in the case of a nil input.

So basically what I'm suggesting as an enhancement to your library is that 
whenever a field is being tested with a multi-validator vector, the first 
test to fail should prevent any other tests (to its right in the vector) 
from running. This would be similar in spirit to the behavior of the -?> 
and -?>> thread-maybe macros in clojure.core.incubator.

Okay, constructive criticism and all that aside, great work on this library 
again. Looking forward to the next release soon.

  ~Gary

On Wednesday, January 9, 2013 4:24:14 PM UTC-5, Leonardo Borges wrote:
>
> Stathis, 
>
> That's a very good point. I've been thinking about the usefulness of 
> returning the errors map in the original map since the errors map itself is 
> returned as the first element in the call to 'validate'. 
>
> To be honest I'm tempted to remove that with the next release, making 
> validate return a single value: the errors map. 
>
> I'm happy for you to argue otherwise though. Do you think having the 
> qualified keywords in the original map is still useful? 
>
> I'll be releasing a new version over the weekend that will include this 
> change. 
>
> Thanks for the feedback
>
> Leonardo Borges
> www.leonardoborges.com
> On Jan 10, 2013 7:08 AM, "Stathis Sideris" > 
> wrote:
>
>> Hey Leonardo,
>>
>> This is very interesting, but I'd like to know whether it's possible to 
>> validate a map that contains an :errors key. Would bouncer overwrite this 
>> with its own :errors key? Should it not be using a fully-qualified keyword 
>> (as in ::errors) to avoid the clash?
>>
>> Thanks,
>>
>> Stathis
>>
>>
>> On Friday, 4 January 2013 06:56:19 UTC, Leonardo Borges wrote:
>>>
>>> Hey guys, 
>>>
>>> I extracted a small validation library from a side project I'm working 
>>> on and bouncer is the result. 
>>>
>>> While I do know there are a couple of validation libs out there 
>>> already, I decided this was worth publishing mostly because: 
>>>
>>> - That’s what I’m using in my current side project 
>>> - It takes a fundamentally different implementation approach that is 
>>> in itself worthy o

Re: abysmal multicore performance, especially on AMD processors

2012-12-11 Thread Gary Johnson
Lee,

  My reading of this thread is not quite as pessimistic as yours. Here is 
my synthesis for the practical application developer in Clojure from 
reading and re-reading all of the posts above. Marshall and Cameron, please 
feel free to correct me if I screw anything up here royally. ;-)

When running code in parallel, the fastest to slowest ways to allocate 
memory via Clojure (of those examined above) are:
1. Java array
2. Java linked list
3. conj onto a transient vector
4. cons onto a list
5. conj onto a vector
6. DO NOT conj onto a list EVER!!!

And that's pretty much all there is to it until Marshall figures out how to 
hack the JVM to overcome this very subtle JIT deoptimization bug relating 
to polymorphic conj calls on Cons and PersistentList types.

  Good luck,
~Gary


On Tuesday, December 11, 2012 10:37:50 AM UTC-5, Lee wrote:
>
> On Dec 11, 2012, at 4:37 AM, Marshall Bockrath-Vandegrift wrote: 
> > I’m not sure what the next steps are.  Open a bug on the JVM?  This is 
> > something one can attempt to circumvent on a case-by-case basis, but 
> > IHMO has significant negative implications for Clojure’s concurrency 
> > story. 
>
> I've gotten a bit lost in some of the diagnoses and experimental results 
> and analyses and suggestions -- all of which I really appreciate! -- but 
> I'm trying to get clear in my mind what the current state of things is from 
> an application perspective. 
>
> Is the following a fair characterization pending further developments? 
>
> --- 
> If you have a cons-intensive task then even if it can be divided into 
> completely independent, long-running subtasks, there is currently no known 
> way to get significant speedups by running the subtasks on multiple cores 
> within a single Clojure process. In some cases you will be able to get 
> significant speedups by separating the subtasks completely and running them 
> in separate Clojure processes running on separate JVM instances. But the 
> speedups will be lost (mostly, and you might even experience slowdowns) if 
> you try to run them from within a single Clojure process. 
> --- 
>
> Or have I missed a currently-available work-around among the many 
> suggestions? 
>
> I realize that even if this is the current situation it might change via 
> fixes on any one of several fronts (and I hope that it does!), but is this 
> indeed the  current situation? 
>
> Thanks so much, 
>
>  -Lee

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Re: Interest in Scribble for Clojure?

2012-10-18 Thread Gary Johnson
Alright, Eli. You've piqued my interest. I'll have to take a closer look 
sometime soon.

  ~Gary

On Wednesday, October 17, 2012 10:22:54 AM UTC-4, Eli Barzilay wrote:
>
> Gary Johnson  uvm.edu> writes: 
> > 
> > I see. After taking a closer look, I can see that you could do LP in 
> > Scribble 
>
> (Yeah, but again -- that's really not its main goal.) 
>
>
> > as well as also outputting some different kinds of documentation 
> > formats, such as Javadocs or standalone documents. The downside I'm 
> > seeing is that this all has to be programmed in Scheme 
>
> Um, it is very intentionally a documentation system that is built on a 
> proper langugae -- like latex and N other such language, only using a 
> general langugae instead of the usual half-baked things...  (I know 
> that some people would consider that a disadvantage, and in that case 
> you should definitely go with some non-language tool like markdown, 
> (raw) markup, or some WYSIWYG thing.) 
>
>
> > and that you may have to do some IMO less than attractive 
> > backquoting to get at the underlying LaTeX if you want PDF outputs 
> > which use some of the existing LaTeX packages (math libs come to 
> > mind). 
>
> That's almost never needed -- and when it is, it's generally an 
> indication that some rendering feature should be added.  At the 
> scribble syntax level, the syntax is very lightweight, so that there's 
> no issues of bad backquoting.  I describe all of that in 
> http://barzilay.org/misc/scribble-reader.pdf, and it's applicable to 
> other languages -- not even sexpr-ish ones.  My hope is that this can 
> easily provide a proper language syntax for having lots of text. 
> Markdown is another approach, but IME it suffers greatly when you get 
> to unexpected corner cases (eg, non-trivial and non-uniform rules when 
> you want to write some texts), and in other cases it starts simple and 
> end up being horribly complicated (as in wikipedia source files, which 
> started as a simple markdown thing, and now have a ton of conventions 
> as well as a templating systems that require a wikipedia black belt if 
> you get close to it.) 
>
>
> > I suggested Org-mode on this thread for these reasons: [...] 
>
> That's all valid -- I'm just pointing out that there is a way to have 
> a real language instead of relying on a generic tool that inevitably 
> gets complicated when people discover that they want more out of it. 
> But of course YMMV -- I'm just trying to convey the huge benefits we 
> got by using such an in-language tool. 
>
> -- 
>   ((lambda (x) (x x)) (lambda (x) (x x)))  Eli Barzilay: 
> http://barzilay.org/   Maze is Life! 
>
>
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Re: Clojure turns 5

2012-10-17 Thread Gary Johnson
You have made my dissertation not only bearable but an absolute blast, 
Rich. Thank you for your pioneering spirit, endless calls for incorporating 
higher principles in programming, and just being that awesome, humble guy 
with the crazy hair.

  ~Gary

On Tuesday, October 16, 2012 9:53:55 PM UTC-4, Rich Hickey wrote:
>
> I released Clojure 5 years ago today. It's been a terrific ride so far. 
>
> Thanks to everyone who contributes to making Clojure, and its community, 
> great. 
>
> Rich

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Re: Interest in Scribble for Clojure?

2012-10-12 Thread Gary Johnson
I see. After taking a closer look, I can see that you could do LP in 
Scribble as well as also outputting some different kinds of documentation 
formats, such as Javadocs or standalone documents. The downside I'm seeing 
is that this all has to be programmed in Scheme and that you may have to do 
some IMO less than attractive backquoting to get at the underlying LaTeX if 
you want PDF outputs which use some of the existing LaTeX packages (math 
libs come to mind).

I suggested Org-mode on this thread for these reasons:

1. Many Clojure users are also Emacs users.
2. Org-mode is built into Emacs and requires no additional install.
3. Org-mode is not tied to any one language and already has a module for 
Clojure LP development.
4. It can output to ASCII, HTML, LaTeX, PDF, DocBook, OpenDocument Text, 
TaskJuggler, Freemind, and XOXO formats.
5. Tangling and in-file live evaluation are very neat features.
6. It can produce both standalone reports and websites depending on the 
chosen export module.
7. Inline LaTeX is directly supported without any special backquoting and 
exports correctly to both HTML and PDF outputs.

Scribble definitely looks like a powerful language for programmatically 
generating documentation, and if someone wants to take on a Clojure port, I 
can see why that might be a very compelling idea. I just wanted to drop a 
pointer to a somewhat lower hanging fruit.

Sorry to hijack your thread.

  ~Gary

On Thursday, October 11, 2012 5:49:10 PM UTC-4, Eli Barzilay wrote:
>
> Gary Johnson  uvm.edu> writes: 
> > 
> > A lot of scribble's features are geared towards providing tooling for 
> > Literate Programming, 
>
> No, this is wrong.  The LP that we have is based on Scribble, but it was 
> done mainly as a demonstration of the benefits you get from having a 
> real language for writing your documentation.  That benefit (using a 
> real langugae) is the central motivation for Scribble.  Note also that 
> it's very much unlike markdown, where you can't program your 
> documentation language by design. 
>
> -- 
>   ((lambda (x) (x x)) (lambda (x) (x x)))  Eli Barzilay: 
> http://barzilay.org/   Maze is Life! 
>
>
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Re: Interest in Scribble for Clojure?

2012-10-10 Thread Gary Johnson
A lot of scribble's features are geared towards providing tooling for 
Literate Programming, and currently I'm way more than satisfied with 
org-babel. This has been built into Emacs by defaut since IIRC version 23.2 
or so. Opening any file in org-mode (`M-x org-mode') immediately provides 
you with a full LP experience. You can "weave" your org file to a number of 
different output formats (HTML, PDF, and ODT being my favorites using `M-x 
org-export-as-*') with beautiful tables, figures, embedded images, properly 
formatted math (LaTeX!), and language-specific fontified code blocks. You 
can "tangle" your org file (i.e., automatically extract code blocks and 
rearrange them in a new source code only file(s)) to create an entire src/ 
directory with one command (`M-x org-babel-tangle'). And possible the 
coolest feature of all is that you can live evaluate any code block (by 
sending it to a Clojure REPL using nrepl or swank-clojure) by simply typing 
`C-c C-c' in any code block within the org file. This allows for the 
typical "write, test, modify, test" loop that Clojure programmers are used 
to. Just for the final coup de grace, you can use any number of different 
programming languages within the same org file and either tangle them out 
to their own files (.sh, .clj, .java, etc) for building up an entire system 
within org-mode, or you can live evaluate those blocks and have them 
automatically pass their results between blocks of different languages. So 
you could write some Clojure code to calculate the values in a tree 
in-memory, send that on to some python code that creates the graphviz code 
representation of the tree as a string, and have that chained right along 
to a dot code block that invokes graphviz to create the PDF image of your 
tree, which is then embedded dynamically into your org file when you weave 
it.

I made a simple example program to illustrate the basics of using org-babel 
as a github project that you can find here:

  http://github.com/lambdatronic/org-babel-example

The actual org-babel site can be found here:

  http://orgmode.org/worg/org-contrib/babel/index.html

Get Literate.
  ~Gary

On Wednesday, October 10, 2012 1:40:11 PM UTC-4, John Gabriele wrote:
>
> On Wednesday, October 10, 2012 11:32:22 AM UTC-4, Grant Rettke wrote:
>>
>> On Tue, Oct 9, 2012 at 1:00 PM, Michael Fogus  wrote: 
>> >> Any existing solutions or interest in something like this? 
>> > 
>> > There are no _public_ solutions as far as I know, 
>>
>> So everyone has their private custom approaches I guess? I'm curious 
>> if people would share them. 
>>
>>
> My guess is that most folks are just using Markdown:
>
>   * most readme's for Clojure projects on github are markdown,
>   * high-profile projects like Lein keep their docs in markdown,
>   * fwict, Marginalia turns markdown-formatted comments and docstrings 
> into html,
>   * there appears that autodoc may at some point [^1] support markdown in 
> docstring comments, and
>   * most folks already know and use it (sometimes without knowing it :) ).
>
> [^1]: see http://tomfaulhaber.github.com/autodoc/ "Things not 
> implemented" section
>
> ---John
>
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Re: ANN Drip: A fast JVM launcher

2012-09-17 Thread Gary Johnson
I'm getting the same multiple JVM starting behavior on Arch Linux using 
lein 2.0.0-preview10 and drip 0.1.7. Hmm...


On Monday, September 17, 2012 2:57:00 AM UTC-4, Tassilo Horn wrote:
>
> Denis Labaye > writes: 
>
> >> I am still seeing a new JVM being started every drip run. I am 
> >> testing Drip 0.1.7 with Lein 2 by running lein test 5 times in a row 
> >> with LEIN_JAVA_CMD=drip in ~/.lein/leinrc, OS X, JDK 7. 
> > 
> > No multiple JVM started for me (at least in my trivial tests) 
> > 
> > drip 0.1.7 
>
> Same versions here, but after running just "lein" thrice in a project, I 
> still have 3 JVMs in "drip ps".  It's the same when I run another lein 
> command, e.g., "lein jar" or "lein test". 
>
> Bye, 
> Tassilo 
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Re: Literate Programming in org-babel (ob-clojure.el) is broken under nrepl.el

2012-09-14 Thread Gary Johnson
Yep. Thanks for the patch, Ben. I had set 
org-babel-default-header-args:clojure to '((:noweb . "tangle")) in my 
.emacs, so I was getting the benefit of automatic noweb expansion when 
tangling (but not weaving). It's all fun and games until you break someone 
else's setup!  ;)

  ~Gary

On Wednesday, September 12, 2012 11:46:14 PM UTC-4, Ben Mabey wrote:
>
>  On 9/12/12 9:29 PM, Ben Mabey wrote:
>  
> Thanks for the great example Gary!  I've been meaning to try org-babel out 
> for a while but never got around to it.
>
> I just tried your example and when I run org-babel-tangle the code blocks 
> are not expanded into the source file, but rather the code block names are 
> just inserted into the source destination (e.g. <> 
> instead of the actual function).  Any ideas on what may be wrong?  Do you 
> have global settings that are perhaps making the tangle work differently on 
> your setup?  I was able to export the document to HTML just fine and 
> execute the clojure code, so the only issue appears to be tangling.
>  
>
> I found the problem was a missing :noweb argument:
>
> https://github.com/lambdatronic/org-babel-example/pull/1
>  

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Re: Literate Programming in org-babel (ob-clojure.el) is broken under nrepl.el

2012-09-11 Thread Gary Johnson
I just put together a simple example repo on GitHub, containing a literate 
programming solution to the Potter Kata  
(http://codingdojo.org/cgi-bin/wiki.pl?KataPotter) using Emacs' org-babel 
mode. You can check it out here:

  https://github.com/lambdatronic/org-babel-example

Also be sure to take a look at the canonical online org-babel docs:

  http://orgmode.org/worg/org-contrib/babel/

In particular the intro section:

  http://orgmode.org/worg/org-contrib/babel/intro.html

And even though it's a little bit dated w.r.t. the current org-mode version 
in Emacs 24, this journal article on Org-Mode's literate programming and 
reproducible research features is really, really cool to work through (lots 
of nice code examples):

  http://www.jstatsoft.org/v46/i03

Happy hacking,
  ~Gary

On Saturday, September 8, 2012 4:24:38 AM UTC-4, Denis Labaye wrote:
>
>
>
> On Thu, Sep 6, 2012 at 6:42 PM, lambdatronic 
> > wrote:
>
>> For those people (like myself) who do a lot of Literate Programming in 
>> Emacs using Clojure and org-babel, migrating to nrepl and nrepl.el is 
>> somewhat non-trivial. This is because the existing Clojure support in 
>> org-babel (ob-clojure.el) relies on slime and swank-clojure when running 
>> org-babel-execute-src-block (which redirects to org-babel-execute:clojure 
>> in ob-clojure.el).
>>
>> So clearly this is actually an issue for both nrepl.el and ob-clojure.el, 
>> not simply one or the other. All the same, I've hacked together a simple 
>> workaround that fixes the problem and makes Literate Programming under 
>> nrepl possible once again. If there is some slick way this could be worked 
>> into nrepl.el's codebase that wouldn't break its existing behavior (as this 
>> does), I'd be excited to see it.
>>
>> Here we go:
>>
>> ;; Patch result table rendering bug in ob-clojure (NREPL version)
>> (defun nrepl-send-request-sync (request)
>>   "Send a request to the backend synchronously (discouraged).
>> The result is a plist with keys :value, :stderr and :stdout."
>>   (with-current-buffer "*nrepl-connection*"
>> (setq nrepl-sync-response nil)
>> (nrepl-send-request request (nrepl-sync-request-handler 
>> (current-buffer)))
>> (while (not (plist-get nrepl-sync-response :done))
>>   (accept-process-output))
>> nrepl-sync-response))
>>
>> (defun org-babel-execute:clojure (body params)
>>   "Execute a block of Clojure code with Babel."
>>   (let ((result-plist (nrepl-send-string-sync 
>> (org-babel-expand-body:clojure body params) nrepl-buffer-ns))
>> (result-type  (cdr (assoc :result-type params
>> (org-babel-script-escape
>>  (cond ((eq result-type 'value)  (plist-get result-plist :value))
>>((eq result-type 'output) (plist-get result-plist :value))
>>(t(message "Unknown :results 
>> type!"))
>>
>> Have fun!
>>
>
> It seems to be very interesting, I am already using Emacs / org-mode / 
> clojure a lot, I was aware of org-babel, but never used it.
> Would you have a simple example project (on github, ...) on how to 
> bootstrap this ? 
>
> Thanks, 
>
> Denis
>
>  
>
>>  -- 
>> You received this message because you are subscribed to the Google
>> Groups "Clojure" group.
>> To post to this group, send email to clo...@googlegroups.com
>> Note that posts from new members are moderated - please be patient with 
>> your first post.
>> To unsubscribe from this group, send email to
>> clojure+u...@googlegroups.com 
>> For more options, visit this group at
>> http://groups.google.com/group/clojure?hl=en
>
>
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en