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 

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 

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 

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: [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: 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: 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: [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-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: 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-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.

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

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

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

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

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

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

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

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

  Good luck,
~Gary

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


Re: Remote function calls / simple distributed computation

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
Hi folks,

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

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

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

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

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

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

  My 2c,
~ (the actual) Gary

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


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

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: 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 terminological nit-picking, but sometimes coming 
 up with the 

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 
 Zombieshttp://www.braveclojure.com/concurrency/. 
 Here's an excerpt:

 ===
 In this chapter you'll learn what concurrency and parallelism are and why 
 they matter. You'll learn about the challenges you'll face when writing 
 parallel programs and about how Clojure's design helps to mitigate them. 
 Finally, you'll learn a big boatload of tools and techniques for writing 
 parallel programs yourself, including: futures, promises, delays, atoms, 
 refs, vars, pmap, and core.reducers. Also, there will be zombies.
 ===

 I hope you all find it useful and entertaining :)

 Daniel


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


Re: Academy Award goes to a literate program

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 
 workshttps://github.com/krisajenkins/yesql#rationale, 
 and how to use it https://github.com/krisajenkins/yesql#example-usage.

 Project: https://github.com/krisajenkins/yesql
 Leiningen: [yesql 0.3.0]

 New since v0.2.x: Support for multiple queries in a single file.

 Feedback welcomed,
 Kris


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


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

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: 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 
 adrian...@gmail.comjavascript: 
 wrote:

 Is cider just a new release of nrepl.el or a different thing entirely?


 Well, it's a new release insofar as it's an updated version of
 nrepl.el. In order to switch to it, however, you have to remove
 nrepl.el _and all packages that depend on it_ (which packages are not
 specified in the upgrade instructions so that would be a hit'n'miss
 process)

 If someone is not clear it should be improved. I can’t know what problems 
 people encounter is they don’t tell me. cider has both an issue tracker and 
 it’s own mailing list. 

 , then you install cider.el and then you also have to update
 various parts of .emac.d/init.el depending on how you had customized
 nrepl. And that part isn't really described in the upgrade
 instructions either so that's also pretty hit'n'miss. 

 All configuration options are documented in the README, so I’d say 
 updating the init.el is an easy task.
  

 And then you
 have to reinstall newer versions of the packages you deleted that
 depended on nrepl.el and hope you get versions that depend on cider.el
 instead (since there's no way of telling, based solely on their
 package description I suspect).

 The list of package dependencies is more informative than a package's name.
  


 And if you use Ritz, that hasn't been updated so you have to stay with
 nrepl.el anyway.

 Frankly, I think it was a mistake to rename it and rename various
 functions in it, forcing breakage on dependent packages (which have
 not changed their names as far as I can tell).

 You’re thinking short term, but you should be thinking long term. Nobody 
 will remember this transition is a few months. I’m confident that in the 
 greater scheme of things the rename was a good solution. 
  


 I use ac-nrepl and the latest version still says it is for nrepl so
 I've no idea whether it will work with cider. I also use nrepl-ritz

 ac-nrepl supports only cider. 
  

 but I could live without it. My nrepl-related init.el file contains:

 https://www.refheap.com/21729

 and it's not clear how that would need changing and whether it would
 continue to work properly.

 Your eval-in-repl function is obsolete, since similar functionality lives 
 in cider itself. 
 I have no idea why you’re modifying clojure-mode’s keymap when you should 
 be modifying cider-mode’s keymap instead (+ set-ns is bound to a keycombo 
 by default). Consulting the Changelog would reveal that `nrepl-mode` is now 
 named `cider-repl-mode` and `nrepl-interaction-mode` is now `cider-mode` 
 (it’s basically the same in SLIME). The migration is really simple and I 
 think that people are blowing this problem out of proportion. Of course, I 
 basically live in Emacs, so this is obviously affecting my POV. Less 
 experienced Emacs users might find even simple changes challenging.  

 And this isn't just for me - my team all has the same base
 configuration of Emacs and so we'd have to go thru this switch process
 for each team member.


 As I said previously - if you’re not certain about something you should 
 stop by either cider’s google group or the GitHub project. :-)
  

 -- 
 Sean A Corfield -- (904) 302-SEAN
 An Architect's View -- http://corfield.org/
 World Singles, LLC. -- http://worldsingles.com/

 Perfection is the enemy of the good.
 -- Gustave Flaubert, French realist novelist (1821-1880)

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

Re: AnNN: ClojureScript 0.0-2120

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: [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-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 krisaj...@gmail.com wrote:

 https://github.com/krisajenkins/yesql

 Yesql is a simple library for blending SQL  Clojure together, cleanly. 
 Here's how it works https://github.com/krisajenkins/yesql#rationale, 
 and how to use it https://github.com/krisajenkins/yesql#example-usage.

 Feedback welcomed,
 Kris

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



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


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

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 
 nonrec...@gmail.comjavascript:
  wrote:

 Hi all,

 I've been putting together http://www.braveclojure.com/ and would love 
 feedback. I've tried to make it entertaining and super beginner-friendly.

 Thanks!
 Daniel

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




 -- 
 Best regards,
 Dima Sabanin
 http://twitter.com/dimasabanin 


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


Re: Story

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 
 and restructuring code. The machinery 

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


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

 
 snip

How do you deal with this lack of context when you present your code in a 
 way that is completely unrelated to the namespace organization of your 
 files?


Well, my experience thus far has led me down two different roads here.

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

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

 Actually it isn't really a change in workflow but a change in mindset.
 Literate programming is not documentation, they are different ideas.


 Here's why I called it a change in workflow -- please correct me if I'm 
 mistaken:

 Every time the subject of literate programming comes up, I ask one simple 
 question:  When you get a stacktrace, is the file/line number information 
 correct?  A year or two back when I asked this, you elaborated that for 
 you, this was mostly a non-issue.  You said you developed your code by 
 sending over one tiny code block at a time to the REPL, rather than sending 
 a whole file over, and you never used any debugging facilities.  I consider 
 that a change in workflow.


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

  


 For Clojure specific efforts see
 http://daly.axiom-developer.org/clojure.pdf (PDF)
 http://daly.axiom-developer.org/clojure.pamphlet (source)


 This is a great example of using literate programming to document a 
 program that is complete and stable.  Have you successfully used literate 
 programming in a program that is rapidly evolving?


I have developed a rather large fire simulation toolkit using the LP model, 
and it was...interesting. Prior to that, I had only created shortish 
programs that were mostly just helping me to get my feet wet with the 
concepts and workflows of literate programming. When I worked on the fire 
program though, I ran into several new hurdles and successes.

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

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

Re: changing a value in a vector of maps

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 
 dinn...@gmail.comjavascript: 
 wrote: 
  Just made a quick search on `main arguments` on both Google and 
 Wikipedia. 
  Do you mean the arguments in `public static void main (String[] args)`? 
 If 
  not please provide some definition what do you mean by main arguments. 
 Else 
  the point is meaningless. 

 He means the arguments you are threading. 


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




Re: matching, assigning and branching in one form

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: 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: [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: 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 
 amirouche...@gmail.com javascript: wrote: 
   - is there a decent project explorer.  I really miss the tree on the 
  left, editor on the right layout 
  speedbar: «C-X speedbar» 

 M-x speedbar - but that looks very interesting, thank you! It's kinda 
 funky in full-screen mode on Mac OS X but it does satisfy the project 
 explorer itch. 
 -- 
 Sean A Corfield -- (904) 302-SEAN 
 An Architect's View -- http://corfield.org/ 
 World Singles, LLC. -- http://worldsingles.com/ 

 Perfection is the enemy of the good. 
 -- Gustave Flaubert, French realist novelist (1821-1880) 


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

Re: ANN: bouncer, validation library for clojure

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 
 to...@tcrawley.orgjavascript:
  wrote:

 This issue has already been reported and filed:
 http://dev.clojure.org/jira/browse/CLJ-1140

 There's been some discussion around that issue on clojure-dev@ as to
 whether this is a regression or an abuse of destructuring.

 Leonardo Borges writes:

  Alright so the bug appears in Clojure 1.5.0-RC1 - I'm not sure whether 
 this
  is a regression or intended behaviour so I'll send a separate email to 
 the
  list about that.
 


 --
 Toby Crawley
 http://immutant.org | http://torquebox.org

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




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

Re: ANN: bouncer, validation library for clojure

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 to...@tcrawley.orgwrote:

 This issue has already been reported and filed:
 http://dev.clojure.org/jira/browse/CLJ-1140

 There's been some discussion around that issue on clojure-dev@ as to
 whether this is a regression or an abuse of destructuring.

 Leonardo Borges writes:

  Alright so the bug appears in Clojure 1.5.0-RC1 - I'm not sure whether 
 this
  is a regression or intended behaviour so I'll send a separate email to 
 the
  list about that.
 


 --
 Toby Crawley
 http://immutant.org | http://torquebox.org

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




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

Re: ANN: bouncer, validation library for clojure

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 fanny@gmx.de 
 javascript:wrote:


 i took a look at it. bouncers DSL seems smart inside and out. 
 Has an excellent Documentation too. Thanks for sharing it.

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




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

Re: ANN: bouncer, validation library for clojure

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 sid...@gmail.com javascript: 
 wrote:

 Hey Leonardo,

 This is very interesting, but I'd like to know whether it's possible to 
 validate a map that contains an :errors key. Would bouncer overwrite this 
 with its own :errors key? Should it not be using a fully-qualified keyword 
 (as in ::errors) to avoid the clash?

 Thanks,

 Stathis


 On Friday, 4 January 2013 06:56:19 UTC, Leonardo Borges wrote:

 Hey guys, 

 I extracted a small validation library from a side project I'm working 
 on and bouncer is the result. 

 While I do know there are a couple of validation libs out there 
 already, I decided this was worth publishing mostly because: 

 - That’s what I’m using in my current side project 
 - It takes a fundamentally different implementation approach that is 
 in itself worthy of exploration 
 - If nothing else, this is yet another example of where Monads 

Re: abysmal multicore performance, especially on AMD processors

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 gwjohnso at uvm.edu writes: 
  
  I see. After taking a closer look, I can see that you could do LP in 
  Scribble 

 (Yeah, but again -- that's really not its main goal.) 


  as well as also outputting some different kinds of documentation 
  formats, such as Javadocs or standalone documents. The downside I'm 
  seeing is that this all has to be programmed in Scheme 

 Um, it is very intentionally a documentation system that is built on a 
 proper langugae -- like latex and N other such language, only using a 
 general langugae instead of the usual half-baked things...  (I know 
 that some people would consider that a disadvantage, and in that case 
 you should definitely go with some non-language tool like markdown, 
 (raw) markup, or some WYSIWYG thing.) 


  and that you may have to do some IMO less than attractive 
  backquoting to get at the underlying LaTeX if you want PDF outputs 
  which use some of the existing LaTeX packages (math libs come to 
  mind). 

 That's almost never needed -- and when it is, it's generally an 
 indication that some rendering feature should be added.  At the 
 scribble syntax level, the syntax is very lightweight, so that there's 
 no issues of bad backquoting.  I describe all of that in 
 http://barzilay.org/misc/scribble-reader.pdf, and it's applicable to 
 other languages -- not even sexpr-ish ones.  My hope is that this can 
 easily provide a proper language syntax for having lots of text. 
 Markdown is another approach, but IME it suffers greatly when you get 
 to unexpected corner cases (eg, non-trivial and non-uniform rules when 
 you want to write some texts), and in other cases it starts simple and 
 end up being horribly complicated (as in wikipedia source files, which 
 started as a simple markdown thing, and now have a ton of conventions 
 as well as a templating systems that require a wikipedia black belt if 
 you get close to it.) 


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

 That's all valid -- I'm just pointing out that there is a way to have 
 a real language instead of relying on a generic tool that inevitably 
 gets complicated when people discover that they want more out of it. 
 But of course YMMV -- I'm just trying to convey the huge benefits we 
 got by using such an in-language tool. 

 -- 
   ((lambda (x) (x x)) (lambda (x) (x x)))  Eli Barzilay: 
 http://barzilay.org/   Maze is Life! 




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

Re: Clojure turns 5

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 gwjohnso at uvm.edu writes: 
  
  A lot of scribble's features are geared towards providing tooling for 
  Literate Programming, 

 No, this is wrong.  The LP that we have is based on Scribble, but it was 
 done mainly as a demonstration of the benefits you get from having a 
 real language for writing your documentation.  That benefit (using a 
 real langugae) is the central motivation for Scribble.  Note also that 
 it's very much unlike markdown, where you can't program your 
 documentation language by design. 

 -- 
   ((lambda (x) (x x)) (lambda (x) (x x)))  Eli Barzilay: 
 http://barzilay.org/   Maze is Life! 




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

Re: Interest in Scribble for Clojure?

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 mef...@gmail.com wrote: 
  Any existing solutions or interest in something like this? 
  
  There are no _public_ solutions as far as I know, 

 So everyone has their private custom approaches I guess? I'm curious 
 if people would share them. 


 My guess is that most folks are just using Markdown:

   * most readme's for Clojure projects on github are markdown,
   * high-profile projects like Lein keep their docs in markdown,
   * fwict, Marginalia turns markdown-formatted comments and docstrings 
 into html,
   * there appears that autodoc may at some point [^1] support markdown in 
 docstring comments, and
   * most folks already know and use it (sometimes without knowing it :) ).

 [^1]: see http://tomfaulhaber.github.com/autodoc/ Things not 
 implemented section

 ---John



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

Re: ANN Drip: A fast JVM launcher

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 denis@gmail.com javascript: writes: 

  I am still seeing a new JVM being started every drip run. I am 
  testing Drip 0.1.7 with Lein 2 by running lein test 5 times in a row 
  with LEIN_JAVA_CMD=drip in ~/.lein/leinrc, OS X, JDK 7. 
  
  No multiple JVM started for me (at least in my trivial tests) 
  
  drip 0.1.7 

 Same versions here, but after running just lein thrice in a project, I 
 still have 3 JVMs in drip ps.  It's the same when I run another lein 
 command, e.g., lein jar or lein test. 

 Bye, 
 Tassilo 


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

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

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. find-discounted-subsets 
 instead of the actual function).  Any ideas on what may be wrong?  Do you 
 have global settings that are perhaps making the tangle work differently on 
 your setup?  I was able to export the document to HTML just fine and 
 execute the clojure code, so the only issue appears to be tangling.
  

 I found the problem was a missing :noweb argument:

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

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

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

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 gwjo...@uvm.edujavascript:
  wrote:

 For those people (like myself) who do a lot of Literate Programming in 
 Emacs using Clojure and org-babel, migrating to nrepl and nrepl.el is 
 somewhat non-trivial. This is because the existing Clojure support in 
 org-babel (ob-clojure.el) relies on slime and swank-clojure when running 
 org-babel-execute-src-block (which redirects to org-babel-execute:clojure 
 in ob-clojure.el).

 So clearly this is actually an issue for both nrepl.el and ob-clojure.el, 
 not simply one or the other. All the same, I've hacked together a simple 
 workaround that fixes the problem and makes Literate Programming under 
 nrepl possible once again. If there is some slick way this could be worked 
 into nrepl.el's codebase that wouldn't break its existing behavior (as this 
 does), I'd be excited to see it.

 Here we go:

 ;; Patch result table rendering bug in ob-clojure (NREPL version)
 (defun nrepl-send-request-sync (request)
   Send a request to the backend synchronously (discouraged).
 The result is a plist with keys :value, :stderr and :stdout.
   (with-current-buffer *nrepl-connection*
 (setq nrepl-sync-response nil)
 (nrepl-send-request request (nrepl-sync-request-handler 
 (current-buffer)))
 (while (not (plist-get nrepl-sync-response :done))
   (accept-process-output))
 nrepl-sync-response))

 (defun org-babel-execute:clojure (body params)
   Execute a block of Clojure code with Babel.
   (let ((result-plist (nrepl-send-string-sync 
 (org-babel-expand-body:clojure body params) nrepl-buffer-ns))
 (result-type  (cdr (assoc :result-type params
 (org-babel-script-escape
  (cond ((eq result-type 'value)  (plist-get result-plist :value))
((eq result-type 'output) (plist-get result-plist :value))
(t(message Unknown :results 
 type!))

 Have fun!


 It seems to be very interesting, I am already using Emacs / org-mode / 
 clojure a lot, I was aware of org-babel, but never used it.
 Would you have a simple example project (on github, ...) on how to 
 bootstrap this ? 

 Thanks, 

 Denis

  

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




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