Re: slackpocalypse?

2017-05-19 Thread 'Lee Spector' via Clojure

FWIW my research group used Slack for a while, but we switched to Discourse 
close to two years ago and have been quite happy with it 
(https://push-language.hampshire.edu, although only a tiny subset is publicly 
viewable). 

We're a much smaller community, with different needs, but still, I can attest 
to Discourse being nice in several ways. Among other things, it seems to 
encourage more deliberative interactions than I generally see on Slack, with a 
better mix of rapid communication with longer-term documentation. 

 -Lee

> On May 19, 2017, at 1:01 PM, Mars0i  wrote:
> 
> I have no opinion, but fwiw the OCaml folks began experimenting with 
> Discourse about a week ago: https://discuss.ocaml.org.
> 
> This isn't really an IRC/Slack style platform, afaics, but the discussions 
> that led up to it included concern about Slack's message limit.  (These 
> discussions can be found on the Google OCaml Aggregation list starting last 
> summer.)

-- 
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 as a first programming language?

2016-12-04 Thread 'Lee Spector' via Clojure
> On Dec 4, 2016, at 7:17 PM, Nathan Smutz  wrote:
> I've heard there have been some attempts at error-mesaage translators.  Does 
> anyone have a recommendation?

Colin Fleming has done some nice work on this in Cursive. 

He gave a talk on it at Clojure Conj 2015: 
https://www.youtube.com/watch?v=kt4haSH2xcs

> If you're new to tooling, and want to try Clojure right away, I strongly 
> recomend Oakes' Nightcode.  [...] beginner-friendly parenthesis management 
> [...]

Nightcode used to be my recommendation for total newbies, and I used it in my 
courses to teach beginners. But in the current versions of Nightcode, parinfer 
is always on, which in my opinionated opinion is the antithesis of 
beginner-friendly parenthesis management. It is wonderfully clever and some 
people love it, but in my experience it's not at all beginner-friendly to 
interfere with the student's existing typing skills and expectations in the way 
that paredit does, or especially in the way that parinfer does.

I spend a fair bit of time evaluating and re-evaluating clojure environment 
options for new programmers. There are a bunch of really great tools out there, 
but from my perspective none of them currently quite nails all of the 
requirements in this area. FWIW my currently favored approach is to use a 
modified version of Gorilla REPL: 
https://groups.google.com/d/msg/clojure/Rqsc8j3rJS8/ehAw4ut4BwAJ. But I am 
always on the hunt for better alternatives, and I am currently planning to 
revisit Proto REPL (in Atom), following a nice talk on it by Jason Gilman at 
Clojure Conj 2016: https://www.youtube.com/watch?v=buPPGxOnBnk

 -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: more minimal clojurescript intro/app

2016-03-27 Thread Lee Spector

Thanks Alan, Pedro, and Colin! 

All of those look like good starting points, and I will explore them soon.

 -Lee


> On Sat, Mar 26, 2016 at 8:06 AM, Lee Spector <lspec...@hampshire.edu <>> 
> wrote:
> 
> Can anybody tell me or point me to a resource that will tell me how to get my 
> Clojure program running as a Clojurescript program in a web page? Ideally, I 
> would like to do this without learning a lot about Javascript or web 
> programming. I just want this existing, pure Clojure program to run in a 
> client's browser, running a computation and providing text output.

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


more minimal clojurescript intro/app

2016-03-26 Thread Lee Spector
Hi all,

I have a pure Clojure program and I would like to make it run in the browser on 
client machines. It has no dependencies other than Clojure, it does no Java 
interop, and it has no GUI. There's no database, no user interaction (except 
for starting the program), and no networking. It just computes something and 
prints text (which goes to the REPL in the Clojure version). From what I've 
read, it should run exactly the same in Clojurescript with no changes.

For the sake of argument -- and this isn't very far from the truth -- let's say 
that I have absolutely no web programming experience, and that I don't know how 
to run Clojurescript at all (although I've been using Clojure for many years). 
I can produce basic HTML files and I can put files on a server in a public 
directory with a known URL, but that's it in terms of web "programming." And 
let's suppose that I know absolutely nothing about Javascript.

Can anybody tell me or point me to a resource that will tell me how to get my 
Clojure program running as a Clojurescript program in a web page? Ideally, I 
would like to do this without learning a lot about Javascript or web 
programming. I just want this existing, pure Clojure program to run in a 
client's browser, running a computation and providing text output.

Searching for "minimal clojurescript" turns up things much less minimal, 
assuming that I know more about Javascript and/or web programming, and/or that 
I want something more sophisticated than I've outlined here.

If I can get this working then I will eventually want something *slightly* more 
complex in terms of user interaction: a text field on the page into which the 
user can type, and from which my program can read. But aside from this, and I 
guess a "Start" button, I need no GUI.

I would appreciate any pointers that anyone can provide!

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: Clojure as first language

2016-03-19 Thread Lee Spector

> On Mar 17, 2016, at 11:10 AM, blake watson <dsblakewat...@gmail.com> wrote:
> 
> On Sat, Mar 12, 2016 at 2:42 PM, Lee Spector <lspec...@hampshire.edu> wrote:
> 
> > Is "lein new app foo" that complicated?
> 
> If I understand Paul correctly—and am not just imposing my own similar 
> feelings on him—the problem is not that "lein new app foo" is complicated, 
> it's that it creates a directory structure that is complicated for the 
> beginner. Clojure is by far not the worst in this regard, but a new app 
> creates seven folders (root, doc, resources, src, test, src/root and 
> test/root) and nine files (.gitignore, .hgignore, CHANGELOG.md, LICENSE, 
> project.clj, README.md, intro.md, core.clj and core_test.clj). This is a lot 
> for someone just trying to grasp "Hello, world."

Understood and agreed. But I just show my students where core.clj is and say to 
ignore everything else, except project.clj which we'll use only to add 
dependencies to use libraries. This seems to be simple enough, in my 
experience. 

-- 
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 as first language

2016-03-12 Thread Lee Spector

> On Mar 11, 2016, at 9:43 PM, Paul Gowder  wrote:
> 
> 2.  The other big beginner barrier I feel is the tooling.  In lots of ways, 
> leiningen is amazing (particularly the automatic grabbing of dependencies), 
> but the forced project structure is really painful. It feels like a massive 
> barrier to not just be able to throw up some code and have it run without 
> having to set up a whole directory structure and all the rest.  (It would be 
> nice in particular to be able to use gorilla-REPL without having a project 
> for it---maybe with lein-try somehow??)  Been thinking about trying boot to 
> make this simpler, but since every library seems to be documented in terms of 
> leiningen, that means just means learning two tooling systems instead of just 
> one.  

Is "lein new app foo" that complicated?

I'm using just leiningen + Gorilla REPL for a class I'm teaching it now, and 
this doesn't seem to be a barrier. In fact I'm using a modified version of 
Gorilla REPL that can open any .clj file, and we've set things up so that "lein 
new gorilla-app foo" creates the Gorilla-enabled project. I'm very happy with 
the setup, and I haven't seen the student confusion that I've had with every 
other tooling setup. FYI here's a little auxiliary document that I give 
students to help get them going: 
http://faculty.hampshire.edu/lspector/temp/Secrets-of-Gorilla-REPL.pdf

One feature that needs to be added to the modified version of Gorilla REPL to 
make this useful more generally is "Save without markup," since currently any 
file that you open and then save will get markup added, which you won't want in 
many cases. 

 -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: Clojure as first language

2016-02-26 Thread Lee Spector
Gary: I'm not sure that's actually what I meant, although I'm not 100% sure 
what you mean so I'm not sure :-). FWIW I *do* always want to introduce "code 
is data" to my beginners, albeit with eval, not macros, and I'm generally not 
on board with the whole concept of restricted teaching languages for the 
contexts in which I teach, although I understand that others find them useful.

Terje: What I mean is just that if you type something like (map inc (range 10)) 
into a REPL you'll get (1 2 3 4 5 6 7 8 9 10), which sure looks like a list but 
is really a lazy sequence. In most cases it doesn't matter, as it behaves as it 
would if it were a list. But sometimes it does matter, e.g. (str '(1 2 3 4 5 6 
7 8 9 10)) => "(1 2 3 4 5 6 7 8 9 10)", whereas (str (map inc (range 10))) => 
"clojure.lang.LazySeq@c5d38b66". I can't recall other specific situations in 
which it matters right now, but usually when I teach a class using Clojure, 
students run into this and are pretty confused. Once they figure out what's 
going on they often think that doall will help, but it doesn't, and I show them 
that they can apply list to the lazy sequence to get a real list. As I said, I 
know this can't change, and it's not the biggest problem in the world. But the 
fact that different kinds of things have identical printed representations is a 
less-than-lovely aspect of the language for beginners, in my experience. One of 
the the few!

 -Lee


> On Feb 26, 2016, at 6:58 AM, Gary Verhaegen <gary.verhae...@gmail.com> wrote:
> 
> On Friday, 26 February 2016, Terje Dahl <te...@terjedahl.no 
> <mailto:te...@terjedahl.no>> wrote:
> Lee.
> 
> About the confusion with parens - do you mean that an output-ed list/seq 
> looks exactly like a callable s-expression?
> Please elaborate.
> 
> Terje
> 
> Yes. If you print the list (1 2 3) it prints as a callable form, and then you 
> have to get into reading, evaluation, etc.
> 
> Aphyr's Clojure tutorial series went there. IIRC the second or third chapter 
> was devoted to that.
> 
> On the other hand, in the Racket curriculum, they define limited subsets of 
> Scheme used as teaching languages; when the student first learns about lists, 
> they construct them using cons and they print as cons forms, i.e. the 
> (in-memory) list '(1 2) would print as
> 
> (cons 1 (cons 2 (cons (
> 
> This is the kind of simplifications that are done in the teaching languages 
> and that allow the course to avoid a number of advanced topics in the 
> beginning. It avoids a lot of confusion at the cost of a small lie and an 
> extra effort when you want to introduce macros and the "code is data" idea. 
> (Which you usually don't want to do in an introductory course anyway.)
> 
> For a short (and, I found, very enlightening) peek at the HTDP curriculum, 
> you can skim through the Systematic Program Design course by Gregor Kiczales 
> on edX:
> 
> https://www.edx.org/xseries/how-code-systematic-program-design 
> <https://www.edx.org/xseries/how-code-systematic-program-design>
> 
> This is by a wide margin the best introductory programming course I have ever 
> seen.
> 
> Re: ClojureBridge, the curriculum is on GitHub:
> 
> https://github.com/ClojureBridge/curriculum 
> <https://github.com/ClojureBridge/curriculum>
> 
> -- 
> 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 
> <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 
> <mailto:clojure+unsubscr...@googlegroups.com>.
> For more options, visit https://groups.google.com/d/optout 
> <https://groups.google.com/d/optout>.

--
Lee Spector, Professor of Computer Science
Director, Institute for Computational Intelligence
Hampshire College, Amherst, Massachusetts, USA
lspec...@hampshire.edu, http://hampshire.edu/lspector/, 413-559-5352

-- 
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...@googlegr

Re: Clojure as first language

2016-02-22 Thread Lee Spector

When I taught with DrScheme back in the day it was a very good experience 
overall, and while I haven't taught with DrRacket I understand that the team 
has continued to do great things, and that this is probably a perfect first 
environment for many teaching contexts. FWIW in my context the restricted 
language subsets were more of a hinderance than a help, but since we could get 
around them, and since everything else about the environment was so nice, I was 
quite happy with the experience overall.

But I nonetheless think that actual Clojure can also be a great first language. 
Although it would take a *lot* work to do all of the things that the PLT/Racket 
people have done, I think that we're already on the cusp of having sufficiently 
good Clojure environments for beginners. For me, I think we'll be over the 
threshold for teaching Clojure as a first language as soon as the "quick real 
start" story gets a little better, making it trivial for total newbies to set 
up an environment and start coding, with a few essential features like 
auto-re-indenting and as few unnecessary sources of confusion as possible. Once 
we're over that threshold (and many projects are quite close, but not yet quite 
there IMHO) I think that Clojure-first will be a reasonable path, and that 
things will then get even better as the work that people are doing on improved 
error messages etc. can be incorporated. 

So I hope that Clojure tool developers will continue to push in this direction 
too! 

 -Lee

PS if anyone is curious about how I've been using just lein + Gorilla REPL as a 
teaching environment, which I mentioned earlier, you might want to look at my 
brief notes at 
http://faculty.hampshire.edu/lspector/temp/Secrets-of-Gorilla-REPL.pdf. Note 
that this is still missing one key feature for more general use: Save Without 
Markup. Right now, any edited file will be "polluted" with markup, which would 
obviously be problematic in many situations. A student in my group is looking 
into adding this feature.


> On Feb 22, 2016, at 8:34 AM, Mark Engelberg  wrote:
> 
> Racket is a language that is explicitly designed for creating other 
> languages.  DrRacket is a remarkable pedagogical IDE.  For those who are 
> interested in providing a smooth learning path to Clojure, one of the best 
> ways to do that would be for our community to invest some effort in building 
> a "Clojure language mode" for DrRacket.  It wouldn't have to be incredibly 
> efficient, and wouldn't have to support the full range of Clojure constructs, 
> just a nice pedagogical subset of Clojure.
> 
> Racket-implemented languages interoperate with each other and with the IDE, 
> so beginning programmers could use DrRacket and get great error messages and 
> graphical stack traces in the IDE, as well as access to all its great 
> teachpack libraries (such as the functional graphics/animation library) and 
> the ability to use the various curricula designed by the PLT group.
> 
> The transition from Racket to Clojure already is fairly small, but this way, 
> beginners could then work through a tried-and-true curriculum using Cloure 
> syntax for a truly seamless transition to full-blown Clojure once they are 
> ready.
> 
> I believe this would be far easier and more useful than trying to build a 
> robust set of features for beginner programmers into Clojure (given that the 
> DrRacket team has already spent decades on this problem, so we're better off 
> figuring out how to leverage their work than trying to reinvent and 
> reimplement it).
> 

-- 
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 as first language

2016-02-21 Thread Lee Spector

I've given a fair bit of thought to this because I teach beginning programmers 
and I also teach Clojure, but my Clojure classes currently require at least one 
prior programming course. 

I'd love to start with Clojure, and to my mind the main obstacle is indeed that 
the programming environments that are available, while continually improving 
with respect to beginner-friendliness, aren't quite there. 

After switching among many of the alternatives over the last several years 
(during which I've been very grateful to the tool developers who have always 
been responsive and helpful), this semester I am trying something new, using 
just leiningen + a version of Gorilla REPL modified to allow the opening of any 
.clj file. So far I am really happy with this, which is working well for my 
class and also giving me more hope for teaching total novices Clojure in the 
future.

The need for occasional Java interop is also an issue, but in my experience 
it's a minor one that can be dealt with on a case by case basis.

And documentation that assumes too much knowledge can also be an issue, but 
again, this is improving and less of a problem, I think, than the programming 
environment issues.

One little feature of the core language itself that I find to be difficult for 
beginners is the way that regular parentheses () are used in printed values for 
different data types... But I know this can't change, and I don't know if 
anything can be done to make that less confusing.

 -Lee

PS I second the shout out to Elena Machkasova's work! 



> On Feb 21, 2016, at 6:45 AM, Val Waeselynck <val.vval...@gmail.com> wrote:
> 
> And of course, let's not forget about Clojure Bridge 
> <http://www.clojurebridge.org/>!
> 
> On Sunday, 21 February 2016 12:42:24 UTC+1, Val Waeselynck wrote:
> I believe there was a Clojure programming environment released exactly for 
> this... but can't see to find it on Google.
> 
> I too believe it is great for beginners, except for maybe 2 aspects:
> if Clojure is your first language, the 2nd language is likely to be painful 
> :) - I heard feedback about a guy who learned to program in Clojure and found 
> Python pretty messed up afterwards.
> because of Clojure's hosted nature, most learning resources today presume 
> some programming experience.
> You should maybe contact Chris Granger if you want to invest some time in 
> this, what with Light Table and Eve he's probably one of the persons who have 
> given this topic most thought.
> 
> See also the work of Elena Machkasova who has taught introductory CS classes 
> with Clojure: https://www.youtube.com/watch?v=k5erDyDPzgc 
> <https://www.youtube.com/watch?v=k5erDyDPzgc>.
> 
> I personally believe one of the most important features for learning is the 
> REPL. Declarative data notation plays a great role too, and built-in 
> documentation is the cherry on the cake.
> 
> Personal feedback: In France, in prep school, we learn programming with OCaml 
> - which is indeed great especially for the kind of mathematical / algorithmic 
> stuff we do, but I think Clojure has the advantage of targeting platforms 
> suited to a wider range of applications (including websites).
> 
> HTH,
> 
> On Sunday, 21 February 2016 11:45:44 UTC+1, Terje Dahl wrote:
> I believe that the simplicity of Clojure's syntax in combination with its 
> clean functional nature and prefix notation makes it ideal as a "first 
> language" for anyone who wants to start programming - including, and perhaps 
> especially kids.
> 
> Is there anything written about this? 
> Arguments ... experiences ... perhaps even research ...?
> 
> -- 
> 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 
> <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 
> <mailto:clojure+unsubscr...@googlegroups.com>.
> For more options, visit https://groups.google.com/d/optout 
> <https://groups.google.com/d/optout>.

--
Lee Spector, Professor of Computer Science
Director, Institute for Computational Intelligence
Hampshire College, Amherst, Massachusetts, USA
lspec...@hampshire.edu, http://hampshire.edu/lspector/, 413-559-5352

-- 
You received this message because

Re: [ANN] 2015 State of Clojure Community survey

2015-12-06 Thread Lee Spector

> On Dec 6, 2015, at 2:43 AM, Mars0i  wrote:
> 
> As in the past, many survey questions are not appropriately designed for 
> getting info about uses of Clojure in academic research.  I don't think 
> there's very much use of of Clojure for this purpose, but the survey won't be 
> able to track it.
> 
> ...
> fwiw, as I've remarked before, it would be good for Clojure if it were used 
> more often in academia, since any professor using Clojure has the potential 
> to turn many students on to it.
> 

I just want to second this. I also use Clojure for academic research and for 
teaching courses like AI, and I found several of the survey questions confusing 
in this context.

FWIW I know of at least a couple of others who are doing this as well, and I 
agree that it can be a good way to grow the community.

 -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: [ANN] 2015 State of Clojure Community survey

2015-12-06 Thread Lee Spector

On Dec 6, 2015, at 3:00 PM, Alex Miller  wrote:

> Almost all of the questions are optional - if they don't apply to your 
> scenario, you should skip the question.

FWIW if I recall correctly (it won't let me back in to check the questions now 
that I finished it) I think that some questions sort of apply but use 
terminology that implies an industrial context (like "in production"). Not a 
big deal but a bit confusing, and maybe if we want to encourage use in 
education and research these could be tweaked. 

> 
> What question would be useful to add re use in academia?

I'd personally be interested in knowing how many people are using Clojure for 
computer science courses, and which ones. Also, how many people are using 
Clojure for research, and in what fields. Also, what tools (e.g. IDEs, books, 
websites) are people using, and what do they think is missing, for research and 
education purposes.

I'm not sure how best to phrase survey questions for these issues.

 -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: crazy idea...

2015-11-28 Thread Lee Spector
gt; 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.
> 
> -- 
> 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.

--
Lee Spector, Professor of Computer Science
Acting Dean, School of Cognitive Science
Director, Institute for Computational Intelligence
Hampshire College, Amherst, Massachusetts, USA
lspec...@hampshire.edu, http://hampshire.edu/lspector/, 413-559-5352

-- 
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: usage of "and"

2015-09-07 Thread Lee Spector

> On Sep 7, 2015, at 7:58 AM, jongwon.choi  wrote:
> 
> Typo?
> 
>  (and cnt (pos? cnt))

Sometimes this kind of thing is reasonable if cnt might be nil, which would 
break pos?. 

So the expression says "cnt isn't nil (or false) and it's positive."

 -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: run Clojurescript via %magic in an iPython notebook?

2015-08-17 Thread Lee Spector

Thanks Peter -- I'll take a look at this stuff.

 -Lee

 On Aug 16, 2015, at 8:21 PM, Peter Denno pode...@gmail.com wrote:
 
 Hi,
 
 I'm interested in this too. However, I have virtually no experience with 
 Javascript. The place to begin the investigation, I think, is with the new, 
 more general implementation of iPython notebooks, Jupyter 
 (https://jupyter.org/). Note that there is even a Clojure kernel for Jupyter; 
 thus the ability for users to run clojure notebooks. But that's not what I'm 
 after. Like you, I'm interested in using Clojurescript in the notebook rather 
 than Javascript as means to add custom capabilities. Since Clojurescript 
 compiles to Javascript, I don't think getting things to work will be hard. 
 There are a few jupyter project repositories (very active and probably not 
 yet stable) for things that seem related. Take a look at the repositories 
 under the jupyter project, https://github.com/jupyter , but note that many of 
 these repositories are only a few weeks old. 
 
 Regarding the old implementation of iPython notebooks, there is a bit of a 
 tutorial on integrating notebooks with Javascript here : 
 https://jakevdp.github.io/blog/2013/06/01/ipython-notebook-javascript-python-communication/
   I tried it; it partially works. As the author points out, it is obsolete as 
 of iPython 2.0. The current release of iPython is 4.0.0. So it is useful for 
 thinking about the basic concepts.
 
 Reading some of the developer discussion on jupyter, it appears that they are 
 using a React-like framework called Phospor. This might be good for 
 Clojurscript development, enabling easier use of figwheel (which I've read 
 about, heard good things from other developers, but have not myself used yet.)
 
 Hope that helps, 
   Peter

-- 
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: Decomplecting Clojure

2015-08-13 Thread Lee Spector


Thanks Sebastian for the thoughtful and helpful document! I like it and have 
shared it with my group.

 On Aug 13, 2015, at 1:51 PM, Sebastian Bensusan sbe...@gmail.com wrote:
 
 
 I never thought of laziness! It's a good point. Retroactively I might add it 
 to the Functional Style section :)

You did a nice job of presenting both pros and cons for the other features of 
Clojure, and I expect there would be something similar for your entry on 
laziness but FWIW from my perspective the cons here are more significant 
than for any other feature (and I know that opinions will vary on this!).

I know that no language is perfect for everyone or every purpose, but at least 
from my perspective pervasive laziness is one of Clojure's very few true 
mistakes (sort of like my father-in-law says that eggplant is one of god's 
very few true mistakes).

Laziness is often glorious and elegant, and the way that it's everywhere by 
default in Clojure is quite cool. But in a not-purely-functional environment it 
can cause weird problems at unexpected times and in unexpected places. There 
are several ways to get into trouble -- there was a nice blog post on some of 
them years ago, maybe by Chas Emerick? -- but I think most of my own come from 
the not-purely-functional nature of synchronization, awaiting the completion of 
tasks dispatched to agents. Symptoms that I get include the saturation of only 
one core when I expect to be saturating all of them, and sometimes 
out-of-memory errors. I think the former are due to delayed lazy computations 
taking place at unexpected times, and that the latter come from GC not 
collecting things that it would know it could collect if the deferred 
computations were completed in a non-lazy way.

It has been hard to replicate or track down the sources of these problems, but 
they do always go away when I un-lazify everything -- coercing sequences to 
vectors, calling doall, changing every call to map to mapv, etc.

Because these problems are so hard to diagnose and think about, I've taken to 
pre-emptively avoiding laziness whenever possible, unless I really want it 
(which is relatively rare, for me). This can be a bit awkward, and it's one of 
the very few things that I feel like I have to apologize for when I introduce 
Clojure to students.

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


run Clojurescript via %magic in an iPython notebook?

2015-07-22 Thread Lee Spector

It is apparently possible to run javascript via magic commands in iPython 
notebooks (https://ipython.org/ipython-doc/3/interactive/magics.html).

I assume that this would make it possible also to use Clojurescript, but I 
don't know what would be involved. I have a fair bit of Clojure experience but 
little experience with Clojurescript or Javascript, and I'm new to iPython. 
Does anyone have experience with this or interest in looking into it?

I am familiar with the wonderful Gorilla REPL, which provides a similar 
notebook-like environment for Clojure (http://gorilla-repl.org), but my 
question here is in the context of a course in which I'll be teaching Python. 
It might be both fun and useful to sneak in a little Clojure/Clojurescript from 
time to time.

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-incanter statistical tests?

2015-06-02 Thread Lee Spector

Thanks Mike,

This looks very much like what I want, in principle, although in practice I'm 
interested in functions like t-test and chisq-test, which haven't yet made it 
into core.matrix.stats as far as I can see.

FWIW I'd be wary about just copying those things from Incanter, at least 
because of the comment This is wrong in the code for t-test in the most 
recent code that I can find (although I haven't been able to find the source 
code for 1.9.0, even though that's what I'm actually using, with leiningen 
retrieving it from clojars...).

 -Lee


 On Jun 2, 2015, at 10:55 AM, Mikera mike.r.anderson...@gmail.com wrote:
 
 I intended the core.matrix.stats to be used as a lightweight library as for 
 statistical functions of this nature, while remaining compatible with 
 Incanter and core.matrix. I agree something more lightweight than the whole 
 of Incanter is often required.
 
 https://github.com/clojure-numerics/core.matrix.stats
 
 Contributions welcome, possibly some could just be copy/pasted out of 
 Incanter.
 

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


non-incanter statistical tests?

2015-06-01 Thread Lee Spector

Does anyone know of a simple/minimal Clojure library, or just a chunk of 
Clojure source code that I could cut/paste, that implements basic statistical 
tests like t-tests and chi-squared tests? I don't want to use incanter but I'd 
also rather not write this stuff from scratch.

Thanks,

 -Lee

PS I'm not really looking to engage in debate about the pros/cons of incanter, 
but FWIW a couple of my reasons for not wanting to use it are: 1) Requiring 
incanter seems to be making my program launch an additional java process, which 
is mysterious and unwelcome, 2) I ran into division by zero errors which might 
be completely reasonable -- I haven't yet tracked down the arguments that 
produced the errors or figured out what should be done about them -- and when I 
tried to look into the code I found a lot more complexity than I was hoping to 
have to deal with, along with the comment ;;FIXME: This should never be *2!  
This is wrong..., which does not inspire confidence. I see that incanter does 
lots of cool things, and I don't want to put it down in any way, but for now I 
just want some statistical test code and I'd like to deal with as little else 
as possible.

-- 
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-incanter statistical tests?

2015-06-01 Thread Lee Spector
Thanks so much Marshall.

Adding -Djava.awt.headless=true to my :jvm-opts does indeed fix the 
additional java process problem, so that's helpful if I don't find an 
alternative to incanter.

The R options are interesting but probably not a good solution in my case; I'll 
be calling these tests millions of times and I'm guessing that the overhead 
would be a problem.

FWIW another issue I've had with incanter is confusion figuring out what 
dependency to use. This wasn't clear to me from the main incanter 
documentation, searching clojars for incanter returned a lot of things that I 
didn't know what to do with, and then I eventually found the github page (which 
you also suggest) which shows [incanter 1.5.6] under Include in Clojure 
project, which worked... But then, looking more carefully at the clojars 
result I see that there's also 1.9.0 and now I've switched to that, and it also 
works... But this all seems very weird because the project.clj in the github 
repository lists 1.5.7-SNAPSHOT, making me think that maybe 1.5.6 is the 
current stable version. To make matters worse I thought it might be better to 
use only the stats module and tried things like [incanter-stats 1.5.6] and 
[incanter/incanter-stats 1.5.6], but none of that worked and I guess now that 
maybe stats isn't a separate module? In namespaces I require only 
[incanter.stats :as stats] and that works, although it did trigger the swing 
stuff untill i added -Djava.awt.headless=true.

Anyway, I'm in somewhat better shape now but still confused about some things, 
uneasy about the comment in the source code indicating the wrongness of the 
t-test code, and hoping for something that will be easier to understand and 
work with... if there's any simpler option out there.

Thanks,

 -Lee


 On Jun 1, 2015, at 10:40 PM, Mars0i marsh...@logical.net wrote:
 
 One option would be to call R from Clojure.   I haven't tried this, and I 
 don't know how well it would fit your needs.
 
 Rincanter 
 http://joelboehland.com/posts/all-your-datasets-r-belong-to-us.html is 
 supposed to allow this.  Presumably it would bypass the Incanter functions 
 that you don't want to use.
 
 Rincanter is apparently a wrapper around JRI http://www.rforge.net/rJava/, 
 a Java library for calling R.  You could probably use that directly, without 
 using Rincanter.
 
 I can't figure out whether R-nREPL https://github.com/vspinu/R-nREPL is 
 also a possible solution, but maybe it is.
 
 
 About this:
 Requiring incanter seems to be making my program launch an additional java 
 process, which is mysterious and unwelcout ome:
 
 I think you're probably referring to the fact that some Incanter components 
 load Java's Swing library, which causes a little Java icon to appear (on my 
 Mac, at least).  Yeah, that is annoying, if you don't need graphical output.  
 But you can avoid it.
 
 First, I'd make sure that you are using the latest Incanter library, e.g. by 
 pasting the appropriate lines (see Incanter's github repo) into a Leiningen 
 project.clj file.  If you're using the standalone Incanter 
 application--sometimes that's older, and you will have less control over 
 what's loaded.  Second, only use or require the components you need--but you 
 probably need one of the ones that loads Swing by default.  Third (this is 
 the key):  Add 
 :jvm-opts [-Djava.awt.headless=true]
 to your Leiningen project.clj.  That will prevent the Swing icon from popping 
 up.  
 
 You might also want to ask for help on the numeric-clojure Google group or 
 the Incanter group, or filing issues on the Incanter github repo.  The latter 
 might not be your cup of tea, of course.
 
 (There's an open issue about the Swing popup that I filed (#255).  Incanter 
 is a huge project, and there are understandably lots of issues that the folks 
 working on it are trying to address, presumably as quickly as they can.)
 There 
 

-- 
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: Why does the following Clojure code take 10x the time the C# version does? How to improve the Clojure version?

2015-05-15 Thread Lee Spector
Thanks Jony -- very helpful!

 -Lee

 On May 15, 2015, at 7:52 AM, Jony Hudson jonyepsi...@gmail.com wrote:
 
 @puzzler -server is the default mostly, but Leiningen overrides some of the 
 important options that -server enables, as detailed by Alex.
 
 @Lee the first 15 minutes of this talk by Tom Crayford has some useful info 
 about performance and JVM options in it:
 
 https://skillsmatter.com/skillscasts/6148-opening-the-grimoire-some-things-about-clojure-performance
 
 For the record for my long-running workloads (which I suspect are _very_ 
 similar to yours) I use:
 
 :jvm-opts ^:replace [-server
  ;;-XX:+AggressiveOpts
  ;;-XX:+UseFastAccessorMethods
  ;;-XX:+UseCompressedOops
  -Xmx4g]
 
 The commented out options are in there so I don't forget them (I learned some 
 of them from Tom's talk), but I haven't found them to make any much 
 difference for my jobs.
 
 
 Jony

-- 
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] darwin and algebolic - genetic algorithms, and evolving mathematics

2015-05-15 Thread Lee Spector
Fantastic to see this Jony!

I look forward to checking it out in detail.

Those interested in genetic programming in Clojure might also want to check out:

- https://github.com/lspector/gp (minimalist tree-based genetic programming 
implementation, written for educational purposes but maybe useful for more)

- https://github.com/lspector/Clojush (long-running, active research project on 
an alternative approach to genetic programming)

If anyone else is working in this space I'd love to hear from you too.

 -Lee


 On May 15, 2015, at 4:57 PM, Jony Hudson jonyepsi...@gmail.com wrote:
 
 Hi All,
 
  it's my pleasure to share with you two libraries: darwin and algebolic.
 
 Algebolic is a library for evolving mathematical expressions. You can use it 
 to perform what's known as symbolic regression, where a symbolic mathematical 
 expression is found that fits a given dataset. More generally, you can use it 
 to evolve mathematical expressions that optimise any score function. The 
 expressions are implemented so they can be very quickly evaluated, as can 
 their derivatives which is useful in more advanced applications. We use it in 
 my research lab, for example, to evolve laws of physics directly from data.
 
 Repository: https://github.com/JonyEpsilon/algebolic
 Getting started example: 
 http://viewer.gorilla-repl.org/view.html?source=githubuser=JonyEpsilonrepo=algebolicpath=ws/demo/intro.clj
 
 Algebolic is powered by ...
 
 Darwin is a flexible framework for programming genetic algorithms, aimed at 
 research applications. It is representation agnostic, working just as well 
 for simple GA examples as it does for complex genetic programming problems. 
 It can be configured to perform both single- and multi-objective 
 optimisation, including the SPEA2 algorithm. It has facility for adaptive 
 evolution where the run parameters evolve in response to changes in the 
 population.
 
 Repository: https://github.com/JonyEpsilon/darwin
 Getting started example: 
 http://viewer.gorilla-repl.org/view.html?source=githubuser=JonyEpsilonrepo=darwinpath=ws/demo.clj
 
 
 Some of the code is research-quality and in particular the core data 
 structures in Darwin are a bit suspect. And the documentation is a bit sparse 
 in places. But it works and maybe someone will find it useful :-)
 
 Enjoy!
 
 
 Jony

-- 
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: Why does the following Clojure code take 10x the time the C# version does? How to improve the Clojure version?

2015-05-14 Thread Lee Spector
I'd like to get more guidance on how to specify :jvm-opts for maximum 
performance. I've received some help on this topic from people on this list in 
the past (thanks!), but I'm pretty sure that I'm still not doing things right.

I'm almost always interested in maximum performance for long-running, 
compute-intensive and memory-intensive processes, almost never caring much at 
all about startup time or anything else.

I also run my code on different machines, with different numbers of cores and 
amounts of memory, and would prefer to be able to put something in my 
project.clj that will do something reasonable regardless of what machine it's 
running on.

I run my code with lein run, and I'd like whatever I need to run fast to be 
in project.clj.

I don't know a lot about JVM options, and I've tried to figure out what to 
specify for :jvm-opts by asking questions here and web searches, but I'm not at 
all confident that I'm doing it right yet. And because my systems are also 
stochastic, it's not easy for me to do timing tests on the options I've tried. 

I think there are options relevant to memory and also garbage collection and 
maybe also compilation... and what else? I wish there was a simple switch to 
get maximum performance of the sort I've outlined here (or at least a 
reasonable stab at it), but I gather that there isn't.

Anyway, here's what I've been using recently, which just deals with memory and 
GC (and maybe not in the best way):

  :jvm-opts ~(let [mem-to-use (long (* (.getTotalPhysicalMemorySize
 
(java.lang.management.ManagementFactory/getOperatingSystemMXBean))
   0.8))]
   [(str -Xmx mem-to-use)
(str -Xms mem-to-use)
-XX:+UseG1GC])

After seeing Alex's post I thought that maybe I should add -server, as 
follows:

  :jvm-opts ~(let [mem-to-use (long (* (.getTotalPhysicalMemorySize
 
(java.lang.management.ManagementFactory/getOperatingSystemMXBean))
   0.8))]
   [(str -Xmx mem-to-use)
(str -Xms mem-to-use)
-XX:+UseG1GC
-server])

Is that right? Does it make sense? What does -server do? Also, should I also 
be using ^:replace?

I've looked in 
https://github.com/technomancy/leiningen/blob/master/sample.project.clj in 
hopes that this would say more about this stuff, but it doesn't say anything 
about -server or ^:replace.

Looking into the compilation options, it looks from 
https://github.com/technomancy/leiningen/wiki/Faster that I should be 
specifying:

:jvm-opts ^:replace []

This is also familiar to me from some earlier discussions. But how would I 
combine this with the memory/GC/server(?) options above?

A guess would be that maybe I should do this:

  :jvm-opts ^:replace
  ~(let [mem-to-use (long (* (.getTotalPhysicalMemorySize
 
(java.lang.management.ManagementFactory/getOperatingSystemMXBean))
   0.8))]
   [(str -Xmx mem-to-use)
(str -Xms mem-to-use)
-XX:+UseG1GC
-server
-XX:-TieredCompilation])

Note that this guess involves changing a + to a - in the last line, which was 
suggested for the opposite purpose at 
https://github.com/technomancy/leiningen/wiki/Faster -- but I don't know if 
it's legitimate.

Is this a reasonable thing to do to get maximum performance for long-running, 
compute-intensive and memory-intensive processes?

Is the tiered compilation thing maybe already done by including -server?

I'm probably at least somewhat confused about several different issues here...

Any help or pointers would be appreciated.

Thanks,

 -Lee




 On May 14, 2015, at 3:47 PM, Alex Miller a...@puredanger.com wrote:
 
 Gah. Meant in project.clj:
 
 :jvm-opts ^:replace [-server]  ;; maybe also set max heap with  -Xmx1g in 
 there
 

-- 
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: Why does the following Clojure code take 10x the time the C# version does? How to improve the Clojure version?

2015-05-14 Thread Lee Spector
FWIW if I run with no :jvm-opts at all then I often crash with an out-of-memory 
error, so I do know that whatever happens by default doesn't do what I'm doing 
with respect to memory, at least.

I don't know what happens with respect to the other issues (tiered compilation 
and whatever else) by default, or with -server, etc.

 -Lee


 On May 14, 2015, at 4:59 PM, Colin Yates colin.ya...@gmail.com wrote:
 
 Now I feel even more of an ignoramus :)
 
 On 14 May 2015 21:57, Mark Engelberg mark.engelb...@gmail.com 
 mailto:mark.engelb...@gmail.com wrote:
 I know that remembering to put -server used to be a huge issue, but I 
 thought that on all recent versions of Java on all modern 64-bit machines, 
 -server is now the default.  I thought it was a non-issue at this point.  Is 
 that incorrect?
 
 On Thu, May 14, 2015 at 1:54 PM, Colin Yates colin.ya...@gmail.com 
 mailto:colin.ya...@gmail.com wrote:
 Probably not helpful, but I tend to rely on the jvm optimisations and just 
 -server. I figured this is an area where a little knowledge is a dangerous 
 thing.
 
 At the very least I would have a realistic benchmark suite to prove to myself 
 that these gains were worth it. In my experience the performance bottleneck 
 is always in design.
 
 Just my 2p, although with my self-confessed ignoramus status it is more like 
 0.5p :).
 
 On 14 May 2015 21:46, Lee Spector lspec...@hampshire.edu 
 mailto:lspec...@hampshire.edu wrote:
 I'd like to get more guidance on how to specify :jvm-opts for maximum 
 performance. I've received some help on this topic from people on this list 
 in the past (thanks!), but I'm pretty sure that I'm still not doing things 
 right.
 
 I'm almost always interested in maximum performance for long-running, 
 compute-intensive and memory-intensive processes, almost never caring much at 
 all about startup time or anything else.
 
 I also run my code on different machines, with different numbers of cores and 
 amounts of memory, and would prefer to be able to put something in my 
 project.clj that will do something reasonable regardless of what machine it's 
 running on.
 
 I run my code with lein run, and I'd like whatever I need to run fast to 
 be in project.clj.
 
 I don't know a lot about JVM options, and I've tried to figure out what to 
 specify for :jvm-opts by asking questions here and web searches, but I'm not 
 at all confident that I'm doing it right yet. And because my systems are also 
 stochastic, it's not easy for me to do timing tests on the options I've tried.
 
 I think there are options relevant to memory and also garbage collection and 
 maybe also compilation... and what else? I wish there was a simple switch to 
 get maximum performance of the sort I've outlined here (or at least a 
 reasonable stab at it), but I gather that there isn't.
 
 Anyway, here's what I've been using recently, which just deals with memory 
 and GC (and maybe not in the best way):
 
   :jvm-opts ~(let [mem-to-use (long (* (.getTotalPhysicalMemorySize
  
 (java.lang.management.ManagementFactory/getOperatingSystemMXBean))
0.8))]
[(str -Xmx mem-to-use)
 (str -Xms mem-to-use)
 -XX:+UseG1GC])
 
 After seeing Alex's post I thought that maybe I should add -server, as 
 follows:
 
   :jvm-opts ~(let [mem-to-use (long (* (.getTotalPhysicalMemorySize
  
 (java.lang.management.ManagementFactory/getOperatingSystemMXBean))
0.8))]
[(str -Xmx mem-to-use)
 (str -Xms mem-to-use)
 -XX:+UseG1GC
 -server])
 
 Is that right? Does it make sense? What does -server do? Also, should I 
 also be using ^:replace?
 
 I've looked in 
 https://github.com/technomancy/leiningen/blob/master/sample.project.clj 
 https://github.com/technomancy/leiningen/blob/master/sample.project.clj in 
 hopes that this would say more about this stuff, but it doesn't say anything 
 about -server or ^:replace.
 
 Looking into the compilation options, it looks from 
 https://github.com/technomancy/leiningen/wiki/Faster 
 https://github.com/technomancy/leiningen/wiki/Faster that I should be 
 specifying:
 
 :jvm-opts ^:replace []
 
 This is also familiar to me from some earlier discussions. But how would I 
 combine this with the memory/GC/server(?) options above?
 
 A guess would be that maybe I should do this:
 
   :jvm-opts ^:replace
   ~(let [mem-to-use (long (* (.getTotalPhysicalMemorySize
  
 (java.lang.management.ManagementFactory/getOperatingSystemMXBean))
0.8))]
[(str -Xmx mem-to-use)
 (str -Xms mem-to-use)
 -XX:+UseG1GC
 -server
 -XX:-TieredCompilation])
 
 Note that this guess involves changing

Re: Why does the following Clojure code take 10x the time the C# version does? How to improve the Clojure version?

2015-05-14 Thread Lee Spector
Thanks Colin and also Alex and Andy.

I'm trying to determine a reasonable way to do this without reading a book 
about it.

It sounds like I should use ^:replace, -server, and also -XX:-TieredCompilation 
(is that right, the way I've changed + to -?), and also -XX:+AggressiveOpts. 
Does it make sense to use all of these together?

And maybe I should get rid of -XX:+UseG1GC, since I'm not really sure if 
that's a good thing.

Assuming that none of those things use as big a chunk of RAM as is available, I 
guess I should keep my messy code for the memory options.

So that would mean that overall I'd do the following to maximize performance on 
long-running, compute-intensive, memory-intensive runs:

  :jvm-opts ^:replace ~(let [mem-to-use 
 (long (* (.getTotalPhysicalMemorySize

(java.lang.management.ManagementFactory/getOperatingSystemMXBean))
  0.8))]
 [(str -Xmx mem-to-use)
  (str -Xms mem-to-use)
  -server
  -XX:-TieredCompilation
  -XX:+AggressiveOpts])

Seem reasonable?

Thanks for all of the help!

 -Lee




 On May 14, 2015, at 8:19 PM, Colin Jones trptco...@gmail.com wrote:
 
 I can heartily recommend Java Performance: The Definitive Guide to anyone 
 interested in digging further into all the knobs you can set on the command 
 line: 
 http://www.amazon.com/Java-Performance-The-Definitive-Guide/dp/1449358454
 

-- 
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: Why does the following Clojure code take 10x the time the C# version does? How to improve the Clojure version?

2015-05-14 Thread Lee Spector

 On May 14, 2015, at 9:15 PM, Fluid Dynamics a2093...@trbvm.com wrote:
  
 Umm, the :replace metadata needs to be on the vector. Attaching it to the let 
 form won't do much of anything useful. So:
 
  :jvm-opts ~(let [mem-to-use
(long (* (.getTotalPhysicalMemorySize
   
 (java.lang.management.ManagementFactory/getOperatingSystemMXBean))
 0.8))]
^:replace [(str -Xmx mem-to-use)
   (str -Xms mem-to-use)
   -server
   -XX:-TieredCompilation
   -XX:+AggressiveOpts])

Thanks Fluid!

 -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: contains? on String

2015-05-12 Thread Lee Spector

 On May 12, 2015, at 4:28 PM, Fluid Dynamics a2093...@trbvm.com wrote:
 
 On Tuesday, May 12, 2015 at 3:34:46 PM UTC-4, Michael Gardner wrote:
 On May 12, 2015, at 1:54 PM, Shantanu Kumar kumar.s...@gmail.com 
 javascript: wrote: 
  I agree about the counter-intuitiveness. I'm only wondering whether the 
  error message is a bit misleading contains? not supported on type: 
  java.lang.String because of course (contains? hello 2) works fine. 
 
 Can anyone comment on why Strings are explicitly supported here?
 
 Strings and arrays support constant-time access by index. The thing that's 
 broken is contains? not supported on type: java.lang.String instead of nil 
 when a nonnumeric key is used. One gets nil with a nonnumeric key and a 
 PersistentVector, rather than an exception.

The contains? function is just badly named, spawning a couple of different 
kinds of confusion. 

I know it's not going to change -- the problems have been pointed out for years.

But FWIW I find it's usually best to pretend it doesn't exist, and when my 
students run into trouble with it I suggest that they do the same.

 -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: complex numbers in clojure

2015-04-27 Thread Lee Spector
 email to
 clojure+unsubscr...@googlegroups.com 
 mailto:clojure%2bunsubscr...@googlegroups.com
 For more options, visit this group at
 http://groups.google.com/group/clojure?hl=en 
 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 
 mailto:clojure+unsubscr...@googlegroups.com.
 For more options, visit https://groups.google.com/d/optout 
 https://groups.google.com/d/optout.
 
 
 -- 
 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 
 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 
 mailto:clojure+unsubscr...@googlegroups.com.
 For more options, visit https://groups.google.com/d/optout 
 https://groups.google.com/d/optout.

--
Lee Spector, Professor of Computer Science
Director, Institute for Computational Intelligence
Cognitive Science, Hampshire College
893 West Street, Amherst, MA 01002-3359
lspec...@hampshire.edu, http://hampshire.edu/lspector/
Phone: 413-559-5352, Fax: 413-559-5438

-- 
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-03-30 Thread Lee Spector
 On Mar 30, 2015, at 7:35 AM, Jony Hudson jonyepsi...@gmail.com wrote:
 
 I propose, instead of this discussion, everyone channels their energy into 
 writing an open-source data-science library, or blog post/article promoting 
 Clojure for data science. In their favourite editor, of course!
 
 
 Jony



That's a good idea, but I'd also like to say a bit more about the pro/con-emacs 
discussion, which I hope to be constructive.

I think I actually agree with most of the comments both by the emacs critics 
and the emacs proponents in this thread. Even the most intense ones, on both 
sides. But rather than worrying about who is more correct I want to point out 
that it's entirely possible, and would be gloriously beautiful, for an 
emacs-based Clojure environment to be produced that:

- Can be downloaded in a single click and run with one more click to do basic 
Clojure development with no further configuration, on Mac/Windows/Linux.

- Provides reasonably standard GUI elements (familiar to any computer user 
without reading a manual) for triggering core functionality and for discovering 
additional features.

As some have mentioned in this thread, a lot of work has been done on easing 
configuration (by people on this list among others) and there are some 
GUI-based packages out there, but as far as I know there's nothing that comes 
close to meeting both of the bullet points above. I think that most emacs-based 
folks either don't think this is possible or don't see it as a priority, but 
something like this must be possible (and there have been things close to this 
for other Lisps in the past), and  if it became a reality that I would switch 
to it for all of my coding and teaching and I'd evangelize it from the rooftops.

I'm not in a position to do development work on this myself, but I believe 
quite fervently that this would be a fabulous thing for the Clojure community.

I'd be happy to discuss this further off-list and/or beta-test projects aimed 
at these goals.

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


Easy-install/GUI emacs for Clojure (was: Re: clojure, not the go to for data science)

2015-03-30 Thread Lee Spector
[Forked the thread as per suggestion by Timothy Baldridge.]

On Mar 30, 2015, at 9:29 AM, Christian Weilbach whitesp...@polyc0l0r.net 
wrote:
 
 I have failed to setup Emacs for development and used Vim or Eclipse
 primarily before entering Clojure-land. emacs-live allowed me to just
 execute a shell script and get a decent Clojure environment which I
 have used for 2 years until I have reconfigured my emacs having a
 better understanding. Its emphasis on live-coding inspired by
 composing music is a very compelling. The only thing I had to add to
 emacs live was evil-mode, which wasn't too hard.

I agree that emacs-live is a great step forward! I explored it for a while and 
considered adopting it for my teaching and research work. (I'm not a software 
developer, I'm a computer science professor/researcher.) I didn't think it got 
quite far enough towards meeting my needs for me to make the leap, but it came 
the closest so far. Perhaps it'd be a good starting point for someone to take 
the next step.

FWIW I try to survey all of the options every year or so, and I currently teach 
with and mostly use Counterclockwise, although I sometimes recommend Nightcode 
for newbies. Both of these are great, and I'm immensely grateful to their 
developers. But if an emacs-based environment came along with the right 
usability features (see bullet points below) then I'd almost certainly switch 
to that.

 -Lee


 On 30.03.2015 15:12, Lee Spector wrote:
 On Mar 30, 2015, at 7:35 AM, Jony Hudson jonyepsi...@gmail.com
 wrote:
 
 I propose, instead of this discussion, everyone channels their
 energy into writing an open-source data-science library, or blog
 post/article promoting Clojure for data science. In their
 favourite editor, of course!
 
 
 Jony
 
 
 
 That's a good idea, but I'd also like to say a bit more about the
 pro/con-emacs discussion, which I hope to be constructive.
 
 I think I actually agree with most of the comments both by the
 emacs critics and the emacs proponents in this thread. Even the
 most intense ones, on both sides. But rather than worrying about
 who is more correct I want to point out that it's entirely
 possible, and would be gloriously beautiful, for an emacs-based
 Clojure environment to be produced that:
 
 - Can be downloaded in a single click and run with one more click
 to do basic Clojure development with no further configuration, on
 Mac/Windows/Linux.
 
 - Provides reasonably standard GUI elements (familiar to any
 computer user without reading a manual) for triggering core
 functionality and for discovering additional features.
 
 As some have mentioned in this thread, a lot of work has been done
 on easing configuration (by people on this list among others) and
 there are some GUI-based packages out there, but as far as I know
 there's nothing that comes close to meeting both of the bullet
 points above. I think that most emacs-based folks either don't
 think this is possible or don't see it as a priority, but something
 like this must be possible (and there have been things close to
 this for other Lisps in the past), and  if it became a reality that
 I would switch to it for all of my coding and teaching and I'd
 evangelize it from the rooftops.
 
 I'm not in a position to do development work on this myself, but I
 believe quite fervently that this would be a fabulous thing for the
 Clojure community.
 
 I'd be happy to discuss this further off-list and/or beta-test
 projects aimed at these goals.

-- 
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: State of the Art in Clojure Debugging

2015-03-30 Thread Lee Spector

Thanks for this Bozhidar.

I just took a look at clj-debugger https://github.com/razum2um/clj-debugger 
and am excited about several of its features, especially the ability to print 
locals.

Does anyone know if it supports (or could easily support -- I'd post an issue 
if it seems possible) a way to say something like (print-locals-on-exception 
(some-fn)) where nothing in some-fn actually calls break or anything else in 
clj-debugger, and where, if an exception is raised in the execution of some-fn, 
then the locals at the point of the exception get printed?

 -Lee


 On Mar 30, 2015, at 10:27 AM, Bozhidar Batsov bozhi...@batsov.com wrote:
 
 This is a newish REPL debugger that's editor agnostic - 
 https://github.com/razum2um/clj-debugger 
 https://github.com/razum2um/clj-debugger (and accidentally it's powering 
 CIDER's own debugger).
 
 I'm pretty sure Cursive has the most sophisticated debugger right now, so the 
 question is whether you dislike Intellij IDEA as much as Emacs. :-)
 

-- 
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 there a way to stop a long running expression in the REPL

2015-02-21 Thread Lee Spector

In case anybody is developing tools for this kind of thing, one of the things I 
most miss from Common Lisp is the ability to interrupt a running expression AND 
see the values of locals at the point of interruption. Fantastically useful for 
debugging. As far as I know there's no environment that lets you do this for 
Clojure. Seeing locals at the context of an exception (for each stack frame) is 
also fantastically useful and at the top of my wish list for the ecosystem... 
and while I've heard tell that there's a way to do this (Ritz?) if you run 
within emacs, I've never actually seen this in action and would love it if 
there was a more broadly accessible way to do this.

 -Lee



 On Feb 21, 2015, at 8:59 AM, Fluid Dynamics a2093...@trbvm.com wrote:
 
 It depends on what REPL/IDE you are using. In Counterclockwise there's an 
 icon on the REPL pane's upper right with a red box near a gear, third from 
 the left, which interrupts the currently running expression. Some other REPL 
 environments provide similar functionality, as other people have noted in 
 this thread, while others unfortunately don't provide a way short of 
 restarting the REPL (and losing anything you've def'd or defn'd at the REPL 
 in the process -- it's a good idea to keep a scratch file in Notepad or 
 somewhere and paste things there that don't belong in your source code but 
 which are convenient to run from time to time in the REPL, such as ad hoc 
 tests or convenience functions and defs for during development).

-- 
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: Dynamically creating defrecord

2015-01-17 Thread Lee Spector

 On Jan 17, 2015, at 6:04 PM, Matching Socks phill.w...@gmail.com wrote:
 
 Did you find something really wrong with defstruct?  Occasions when the basis 
 fields are not known to the programmer seem better met by defstruct than 
 defrecord.  And defstruct has not been deprecated in the API documentation.  
 The comment Note: Most uses of StructMaps would now be better served by 
 records[1] probably refers to times when you know the fields!  Is there 
 really a need to bend over backwards to switch natural defstruct usage over 
 to records?
 
 [1] http://clojure.org/data_structures http://clojure.org/data_structures

I had thought that there was something closer to deprecation of defstruct in 
the documentation, or at least that deprecation was advocated by lots of people 
when we discussed it there.

And then we did some speed tests in our application, and at least from the 
tests that we did, it appeared records were indeed faster by an amount that 
mattered for us.

 -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: Dynamically creating defrecord

2015-01-17 Thread Lee Spector

 On Jan 17, 2015, at 12:27 PM, Sven Richter sver...@googlemail.com wrote:
 
 I am trying to create record definitions dynamically during runtime. What I 
 would like to do is something like this:
 
 (defn mk-rec [record-name namespace arg-list]
   (eval '(do (ns namespace)
(defrecord record-name arg-list
 
 And then call it like this:
 (mk-rec A ns [a b c])
 (-ns.A 1 2 3 )
 
 I am trying out different things, but struggle to get it right or find some 
 tutorial for it.
 
 So if anyone is willing to share some working code I'd be really happy.

In case it may help I'll paste in below some related code from my Clojush 
project (https://github.com/lspector/Clojush 
https://github.com/lspector/Clojush).

The stuff commented out at the top is how I used to do it with defstruct, which 
I preferred, but that was a very unpopular perspective. The stuff below is how 
we do it now with defrecord.

 Best, 

 -Lee

;(defmacro define-push-state-structure []
;  `(defstruct push-state ~@push-types))

;(define-push-state-structure)

;(defn make-push-state
;  Returns an empty push state.
;  []
;  (struct-map push-state))

;; record-based states (apparently faster)

(defn keyword-symbol [kwd]
 Returns the symbol obtained by removing the : from a keyword.
 (symbol (name kwd)))

(defmacro define-push-state-record-type []
 `(defrecord ~'PushState [~@(map keyword-symbol push-types)]))

(define-push-state-record-type)

(let [empty-state (map-PushState {})]
  (defn make-push-state
Returns an empty push state.
[] empty-state))

-- 
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: Schrodinger's cat in clojure?

2014-10-11 Thread Lee Spector

On Oct 11, 2014, at 1:00 PM, Jan-Paul Bultmann janpaulbultm...@googlemail.com 
wrote:
 
 Therefor turning of laziness makes no real sense. You could say disable 
 the laziness of seqs,
 but that doesn't really make sense either. It's like disabling the FIFO 
 nature of a queue or a channel.
 If you don't want the properties of a seq, then use another data structure, 
 like a vector.

But a lot of the language's core features are most readily available for seqs. 

There's mapv and filterv, but there aren't built-in versions of lots of other 
seq functions for vectors, right? Or any of this for non-lazy lists, right?

Not that they'd be hard to write, I guess. But if you don't write them yourself 
and you want to avoid laziness then you end up peppering your code calls to vec 
or apply list or other things to wring out the laziness.

 -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: ANN: State of Clojure 2014 Survey - please contribute!!

2014-10-09 Thread Lee Spector

FWIW I'm another person using Clojure mostly for academic research. And for 
computer science education, e.g. I'm currently teaching a Clojure-based AI 
course. I'd be curious to know how many others of us are out there. And BTW I 
think that attention to users in these categories could help to grow the 
community.

 -Lee

On Oct 9, 2014, at 12:32 AM, Mars0i marsh...@logical.net wrote:

 Thanks for the survey!
 
 I have a couple of suggestions/questions:
 
 For domains, there are no categories for scientific or other research 
 applications.  For example, I mainly use Clojure for writing agent-based 
 models for academic research.  Would a set of categories in this area be 
 usedful?
 

-- 
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: [ccw-users] Re: [ANN] New release 0.28.1 of Counterclockwise

2014-10-04 Thread Lee Spector

What would this mean in practice for using the new drag/drop functionality to 
open Clojure projects, regardless of origin or history? Would some require an 
additional manual step to behave as proper Leiningen projects? 

This new functionality has been making life *much* better for me and for my 
students in the short time that it has existed, and it'd be a shame to lose 
some of the new functionality.

I don't even know if/when there is a .classpath or .project or any of other 
hidden files in the projects I've been opening and sharing, and I'd love to 
never have to worry about that again. Being able to drag anything with a 
project.clj to CCW and having it open and run correctly is just wonderful, and 
I think it greatly improves the usability of CCW, especially for newcomers to 
the ecosystem.

Maybe if some of that would no longer work automatically after the change that 
you are contemplating then the system could be made to ask whether to do the 
full conversion (what it does now in 0.28.1) or not in a dialog, rather than 
just doing or not doing it automatically and requiring a manual step later in 
some cases?

 -Lee

On Oct 4, 2014, at 2:10 AM, Laurent PETIT laurent.pe...@gmail.com wrote:

 Points taken. 
 After rethinking about this, thanks to your feedback, it seems indeed really 
 wrong to silently automatically override existing Java build paths. 
 
 I think I will confine the automatic leiningen conversion only for projects 
 which do not yet appear to be Java/just projects - those without a .classpath 
 file yet. 
 
 What do you think?
 
 Le samedi 4 octobre 2014, Howard Green hhgr...@ieee.org a écrit :
 So, I did the upgrade from 0.27.0 to 0.28.1 several hours ago... and 
 immediately made the startling discovery that every project in my workspace 
 with a project.clj file had been auto-converted to a Leiningen project!
 
 Under ideal circumstances, this would not have bothered me, as I like the 
 Lein support a lot; but a number of my long-running projects had substantial 
 discrepancies between the Eclipse build information and what was in 
 project.clj. Fortunately, my backup is pretty good... :-)
 
 I assume the problem arose here because the (innocuous) Automatic detection 
 of Clojure project option turned into the (dangerous) Automatic detection 
 of Clojure / Leiningen projects... and I did indeed have the former option 
 checked.  It might be nice to forcibly un-check the option as part of an 
 upgrade, as a way of preventing unforeseen consequences.
 
 Anyway, no real harm done. However, I think I'd suggest that during 
 conversion process it would be a good idea to retain the old .classpath file, 
 so there's an easy way to fully reverse the effects of a conversion, or maybe 
 abort the conversion if the Eclipse and Lein content didn't agree.
 
 --- Howard 
 
 
 On Sunday, September 28, 2014 12:50:58 PM UTC-7, laurent.petit wrote:
 Counterclockwise, the Eclipse Clojure development tool.
 
 Counterclockwise 0.28.1 has been released.
 
 Improvement over 0.28.0 based on user feedback. Thanks to all who helped 
 improve Counterclockwise by their constructive comments!
 
 - Drag  Drop from Github / Bitbucket / Google Code URLs works in Linux
 - Better User feedback for Drag  Drop folder actions
 - Added a check for missing `.classpath` file for Leiningen projects. 
 Automatically reconstruct the java build path if it is missing.
 
 
 ChangeLog
 =
 
 http://doc.ccw-ide.org/ChangeLog.html#_changes_between_counterclockwise_0_28_0_and_0_28_1
 
 Installation instructions
 ==
 
 http://doc.ccw-ide.org/documentation.html#_install_counterclockwise
 
 Cheers,
 
 -- 
 Laurent Petit
 
 -- 
 You received this message because you are subscribed to the Google Groups 
 counterclockwise-users group.
 To unsubscribe from this group and stop receiving emails from it, send an 
 email to clojuredev-users+unsubscr...@googlegroups.com.
 To post to this group, send email to clojuredev-us...@googlegroups.com.
 Visit this group at http://groups.google.com/group/clojuredev-users.
 For more options, visit https://groups.google.com/d/optout.
 

-- 
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] New release 0.28.1 of Counterclockwise

2014-10-04 Thread Lee Spector

Sounds great -- thanks Laurent.

 -Lee

On Oct 4, 2014, at 10:24 AM, Laurent PETIT laurent.pe...@gmail.com wrote:

 Hello lee,
 
 The drag and drop of projects with a project.clj file should not be affected :
 
 - if the project already has eclipse metadata (that's what .project and 
 .classpath files are), then ccw will rely on them and not try to overwrite 
 them. 
 - if the project has no eclipse metadata (or no metadata declaring a 
 classpath), then adding Lein support can only improve the situation, so it 
 would be done automatically. 
 
 So for projects imported from github wih no eclipse specific files, it will 
 continue to do the magic. 
 
 Le samedi 4 octobre 2014, Lee Spector lspec...@hampshire.edu a écrit :
 
 What would this mean in practice for using the new drag/drop functionality to 
 open Clojure projects, regardless of origin or history? Would some require an 
 additional manual step to behave as proper Leiningen projects?
 
 This new functionality has been making life *much* better for me and for my 
 students in the short time that it has existed, and it'd be a shame to lose 
 some of the new functionality.
 
 I don't even know if/when there is a .classpath or .project or any of other 
 hidden files in the projects I've been opening and sharing, and I'd love to 
 never have to worry about that again. Being able to drag anything with a 
 project.clj to CCW and having it open and run correctly is just wonderful, 
 and I think it greatly improves the usability of CCW, especially for 
 newcomers to the ecosystem.
 
 Maybe if some of that would no longer work automatically after the change 
 that you are contemplating then the system could be made to ask whether to do 
 the full conversion (what it does now in 0.28.1) or not in a dialog, rather 
 than just doing or not doing it automatically and requiring a manual step 
 later in some cases?
 
  -Lee
 
 On Oct 4, 2014, at 2:10 AM, Laurent PETIT laurent.pe...@gmail.com wrote:
 
  Points taken.
  After rethinking about this, thanks to your feedback, it seems indeed 
  really wrong to silently automatically override existing Java build paths.
 
  I think I will confine the automatic leiningen conversion only for projects 
  which do not yet appear to be Java/just projects - those without a 
  .classpath file yet.
 
  What do you think?
 
  Le samedi 4 octobre 2014, Howard Green hhgr...@ieee.org a écrit :
  So, I did the upgrade from 0.27.0 to 0.28.1 several hours ago... and 
  immediately made the startling discovery that every project in my workspace 
  with a project.clj file had been auto-converted to a Leiningen project!
 
  Under ideal circumstances, this would not have bothered me, as I like the 
  Lein support a lot; but a number of my long-running projects had 
  substantial discrepancies between the Eclipse build information and what 
  was in project.clj. Fortunately, my backup is pretty good... :-)
 
  I assume the problem arose here because the (innocuous) Automatic 
  detection of Clojure project option turned into the (dangerous) Automatic 
  detection of Clojure / Leiningen projects... and I did indeed have the 
  former option checked.  It might be nice to forcibly un-check the option as 
  part of an upgrade, as a way of preventing unforeseen consequences.
 
  Anyway, no real harm done. However, I think I'd suggest that during 
  conversion process it would be a good idea to retain the old .classpath 
  file, so there's an easy way to fully reverse the effects of a conversion, 
  or maybe abort the conversion if the Eclipse and Lein content didn't agree.
 
  --- Howard
 
 
  On Sunday, September 28, 2014 12:50:58 PM UTC-7, laurent.petit wrote:
  Counterclockwise, the Eclipse Clojure development tool.
 
  Counterclockwise 0.28.1 has been released.
 
  Improvement over 0.28.0 based on user feedback. Thanks to all who helped 
  improve Counterclockwise by their constructive comments!
 
  - Drag  Drop from Github / Bitbucket / Google Code URLs works in Linux
  - Better User feedback for Drag  Drop folder actions
  - Added a check for missing `.classpath` file for Leiningen projects. 
  Automatically reconstruct the java build path if it is missing.
 
 
  ChangeLog
  =
 
  http://doc.ccw-ide.org/ChangeLog.html#_changes_between_counterclockwise_0_28_0_and_0_28_1
 
  Installation instructions
  ==
 
  http://doc.ccw-ide.org/documentation.html#_install_counterclockwise
 
  Cheers,
 
  --
  Laurent Petit
 
  --
  You received this message because you are subscribed to the Google Groups 
  counterclockwise-users group.
  To unsubscribe from this group and stop receiving emails from it, send an 
  email to clojuredev-users+unsubscr...@googlegroups.com.
  To post to this group, send email to clojuredev-us...@googlegroups.com.
  Visit this group at http://groups.google.com/group/clojuredev-users.
  For more options, visit https://groups.google.com/d/optout.
 
 
 --
 You received this message because you

Re: [PSA] Clojars scp disabled until further notice

2014-09-27 Thread Lee Spector

I just want to chime in to note that not everyone who works in Clojure, and for 
whom Clojars is the obvious (only?) reasonable way to share libraries, is a 
professional developer. Some of us are, for example, researchers or students in 
a range of fields for which reading complex security stuff is not actually 
part of our jobs.

I've scheduled some time next week to sit down with a student and work through 
lein help gpg (thanks for the pointer, Phil!) and try to get lein deploy 
working (again -- we did try once but gave up when we hit errors that we didn't 
understand), so that we can resume use of Clojars in our work. I'm hopeful that 
it will go smoothly and that we'll be back up and running soon.

But in any case I wanted to warn against making too many assumptions about the 
user base (or potential user base).

 -Lee


On Sep 27, 2014, at 1:32 AM, Sean Corfield s...@corfield.org wrote:

 I grumbled about the GPG stuff when it came up but after a chat with
 Phil I decided this was something I just needed to learn as a
 developer. Sure, it means you have to read complex security stuff
 but we have to read lots of complex stuff as developers - that's just
 part of our job.
 
 I switched to lein deploy clojars a long time ago and, frankly, after
 that initial hour or two for a one-off setup, I never had to worry
 about GPG again.
 
 Perhaps #shellshock is a good opportunity for a lot more developers to
 learn some better security health?
 
 If Clojars' scp remains unavailable, will that pain be sufficient to
 switch library maintainers to https deploy? Or will those maintainers
 just stop making releases and abandon their libraries?
 
 Sean

-- 
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: [PSA] Clojars scp disabled until further notice

2014-09-27 Thread Lee Spector

Thanks Phil. We'll definitely look into :sign-releases false when we try to 
get this working next week.

 -Lee

On Sep 27, 2014, at 7:52 PM, Phil Hagelberg p...@hagelb.org wrote:

 Lee Spector lspec...@hampshire.edu writes:
 
 I just want to chime in to note that not everyone who works in
 Clojure, and for whom Clojars is the obvious (only?) reasonable way to
 share libraries, is a professional developer. Some of us are, for
 example, researchers or students in a range of fields for which
 reading complex security stuff is not actually part of our jobs.
 
 Makes sense.
 
 For clarification; while GPG is used by default for Leiningen deploys,
 it is not currently a requirement for either Leiningen or Clojars. You
 can always set :sign-releases false in your :repositories entry if your
 artifacts are intended for hobbyist or academic use rather than inside a
 production environment.
 
 -Phil


-- 
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: Use Require and Import

2014-09-21 Thread Lee Spector

On Sep 21, 2014, at 5:11 AM, Robert Tweed fistful.of.spann...@gmail.com wrote:
 In short: use 'use' in the repl or any time you're generally feeling lazy. 
 Don't use it in non-throwaway code.
 
 Use automatically refers everything in a namespace. This is handy if you 
 don't want to type out the names, but it creates two few problems:
 
 1. It increases the chances of a conflict when the same name appears in more 
 than one namespace.
 
 2. As an extension to (1) it creates forward compatibility problems, where 
 the namespaces you are importing change; so on day one your code works fine, 
 but on day 2 it doesn't, because someone (possibly outside your control) 
 added a new item to one of the namespaces you are importing with use, that 
 now conflicts with one of the others.
 
 3. It makes your code less readable, because if you use some foo, then 
 anyone that isn't familiar with foo won't know which namespace you imported 
 it from (or might think it came from a different namespace than it actually 
 did). When you explicitly refer each foo, bar, etc., it's easy to see 
 where they came from (by reading just your code and without having to go 
 searching around in other files).

I sort of agree with the bottom line here, but there are non-throwaway 
contexts in which (2) won't apply because you are only useing your own 
namespaces, and in which the overall project is small enough that the chances 
of conflict in (1) are acceptably small and the clutter of namespace 
annotations makes things less rather than more readable (contradicting (3)).

And the relative lack of ceremony of use is, IMHO, sometimes quite desirable. 

 -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: Use Require and Import

2014-09-21 Thread Lee Spector

 On Sep 21, 2014, at 12:31 PM, Robert Tweed fistful.of.spann...@gmail.com 
 wrote:

 The whole (ns) block is just boilerplate that you ignore until you need to 
 refer back to look something up, which is the only time it makes any 
 difference.

You can't ignore the boilerplate while you're writing it, which is a pain that 
I'd often prefer to avoid. 

You provide good reasons for preferring the approach that you advocate in the 
contexts in which you write programs.  But people write code for lots of 
reasons in lots of contexts, and in some of them the minimization of 
boilerplate and ceremony is quite valuable. And in some of them the clarity 
provided by namespace qualification is not worth the extra typing and clutter. 

YMMV, which is really my main point. 

 -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: Use Require and Import

2014-09-19 Thread Lee Spector


 On Sep 19, 2014, at 11:26 AM, John Gabriele jmg3...@gmail.com wrote:
 
 Don't use `use`. :)

Since the OP is new here I'll point out that that :) is probably a nod to the 
fact that there's a long history of controversy on the utility/evils of use. 
Some (like me) think there are programming contexts in which it is appropriate 
and importantly helpful. Others think it should be abolished. A lot more 
discussion can be found in the archives if you're really interested.

 -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: Schrodinger's cat in clojure?

2014-09-13 Thread Lee Spector

A man walks into a bar and says I used lazy evaluation and things were 
confusing. Bartender says You might have mixed it with I/O, but then again 
maybe you're getting tripped up by other some other not-purely-functional 
aspect of your program or the JVM, like GC or thread transitions.  

Okay, it's not as good a joke that way, but it may be more accurate.

While the OP's issue was IO-related, I've run into confusing laziness-related 
bugs, some of which were indeed Heisenbugs, that didn't have anything obvious 
to do with IO. I think some were related to GC not knowing that it could 
collect something, while others had to do with something lazy being realized in 
a different thread than I expected. For some, I've never really figured out 
what was happening, but I've nonetheless found that the problem went away when 
I switched map to mapv, or filter to filterv, etc. 

So now one of my first steps when I'm faced with a confusing bug is to stamp 
out all of the laziness except where I'm really doing things lazily on purpose, 
for a good reason. I've also come to think that the pervasiveness and 
defaultness of laziness in Clojure may not really be so wonderful after all. 
Laziness is beautiful when you want it, and when you do want it it's beautiful 
that so much of Clojure works with it so effortlessly and transparently, but it 
can also produce subtle problems when things aren't purely functional (which is 
a lot of the time, in my experience, sometimes for subtle reasons).

 -Lee


On Sep 13, 2014, at 9:32 AM, Stuart Halloway stuart.hallo...@gmail.com wrote:

 A man walks into a bar and says I used lazy evaluation and things were 
 confusing. Bartender says You mixed it with I/O without bothering to look 
 at the code.  :-)
 
 Your experiment uses pr-str, which uses a dynamically scoped resource *out* 
 in order to create its result.  Your observation uses println, which uses the 
 same dynamically scoped resource.  Mix in different evaluation strategies, 
 and races can lead to different outcomes. Here is a much smaller example:
 
 (pr-str [1 2])
 (pr-str (map #(doto % println) [1 2]))
 
 So this result is expected.  Beware I/O, and in the presence of I/O be very 
 careful in concluding that something is a value.  Your quoted-pr-str is not a 
 pure function, and so it does not make values.
 
 Regards,
 Stu
  

-- 
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: Interop nightmare

2014-09-08 Thread Lee Spector

On Sep 8, 2014, at 4:48 PM, Michael Klishin michael.s.klis...@gmail.com wrote:
 Sounds more like Just enough Java for Clojure. Which I think would have
 too small an audience to be worth the effort.

I'd buy it for sure. I bet that some of my students would too.

 -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: Interop nightmare

2014-09-08 Thread Lee Spector

On Sep 8, 2014, at 9:09 PM, Alan Busby thebu...@gmail.com wrote:

 On Tue, Sep 9, 2014 at 3:09 AM, Sean Corfield s...@corfield.org wrote:
  I find that it is quite difficult to use clojure unless one knows Java, 
  which I believe to be a barrier to new comers.
 
 I'm surprised every time I hear this. You can write a lot of Clojure without 
 having to do any interop so you can mostly ignore Java altogether unless you 
 specifically want to work with a Java library.
 
 I don't think any of my Clojure books mention how to convert a string to a 
 numeric, which is missing in Clojure and hence requires Java interop. That's 
 just one example of a fairly basic thing that would be a barrier to new 
 comers.

Do you mean this?:

= (read-string 1.23)
1.23

I manage to get by with very little Java interop, but I'd love to have more 
guidance for doing it when I need it.

 -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: [ANN] Gorilla REPL 0.3.3 - inline docs, CIDER compatibility

2014-09-01 Thread Lee Spector


On Sep 1, 2014, at 7:15 AM, Beau Fabry imf...@gmail.com wrote:

 Started looking into Gorilla for use at work today. Even prior to this 
 release I was incredibly impressed. Amazing work everyone involved.
  

inc

The new docs feature is a thing of beauty.

 -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: An Averaging function

2014-07-09 Thread Lee Spector

On Jul 9, 2014, at 8:48 PM, Stephen Feyrer stephen.fey...@gmail.com wrote:

 Hi,
 
 I tried to create the function below in a Lighttable instarepl.  In lieu of 
 any better idea for formatting, thestatements below indicate instarepl 
 output.
 
 (defn avged ([x]
 ((def sumed (reduce + x))  10 
 (def counted (count x))  4 
 (def result (/ sumed counted))  5/2 
 result
 )))
 
 (avged [1 2 3 4])  java.lang.ClassCastException: java.lang.Long cannot be 
 cast to clojure.lang.IFn
 Var.java:392 clojure.lang.Var.fn
 Var.java:423 clojure.lang.Var.invoke
 (Unknown Source) user/avged 
 
 The objective of this function is just a learning exercise.
 
 I have three questions:
 
 1. Why doesn't it work, return a value?

Hi Stephen,

The main reason it doesn't work is that the expression after the parameter list 
[x] is a list and will be interpreted as a function call, with the function 
being whatever is returned from the first thing in the list -- which in this 
case is the def sumed definition, which returns the defined var.

You could patch (not recommended!) this by adding do to the beginning of that 
list:

(defn avged 
  ([x]
(do 
  (def sumed (reduce + x)) 
  (def counted (count x))
  (def result (/ sumed counted)) 
  result)))

That will work, but it's not idiomatic clojure -- it is almost never idiomatic 
clojure to have a def or defn within another defn. Also, you've used the syntax 
that allows for multiple arglist/body pairs, although you only need one so the 
extra layer of parentheses isn't necessary.

Here's how I might write it somewhat more idiomatically:

(defn avged 
 [x]
 (let [sumed (reduce + x)
   counted (count x)
   result (/ sumed counted)]
   result))

= (avged [1 2 3 4])
5/2
= (float (avged [1 2 3 4]))
2.5


 
 2. What does the error message mean?  and seeing this or similar again, how 
 do I investigate to get a meaningful Clojure solution?

I think it means it's trying to call the value of sumed as a function. I'll 
leave it to others to suggest ways of understanding Clojure error messages (and 
just note for any of those others who have the ability to do something about 
this that it sure would be great to be able to get stack backtraces with values 
of locals regardless of IDE etc.).

 3.  Code Style, what can I do to improve readability and form?

Myself, I'd probably do it without any variables at all, and name everything 
more meaningfully, e.g.:

(defn average-numbers
  Returns the average of the provided numbers.
  [numbers]
  (/ (reduce + numbers)
 (count numbers)))

= (average-numbers [1 2 3 4])
5/2

 -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: An Averaging function

2014-07-09 Thread Lee Spector

On Jul 9, 2014, at 9:31 PM, Lee Spector lspec...@hampshire.edu wrote:
 You could patch (not recommended!) this by adding do to the beginning of 
 that list:

Or -- I now see, instead of adding the do you could just remove the outermost 
parentheses after the parameter list. But as Sam and I said this is a bad way 
to go anyway -- you want to avoid the nested defs.

 -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: map output to string

2014-07-08 Thread Lee Spector

Sometimes you have to manually stamp out laziness, for this among other reasons.

In some cases I apply the list function to do this:

= (str (map inc (range 10)))
clojure.lang.LazySeq@c5d38b66

= (str (apply list (map inc (range 10
(1 2 3 4 5 6 7 8 9 10)

 -Lee


 On 8 July 2014 09:49, Glen Rubin rubing...@gmail.com wrote:
 my-fn takes a number and a string as argument and outputs a string.  I am 
 using map-indexed and my-fn to comprehend a list of items with numbered index 
 as follows, 
  
  
 (map-indexed (fn [idx itm]  (my-fn idx itm)) '(list-of-crap))
  
 When i run this on the repl everything works well and I get a single long 
 string of output. But, I am trying to use the output of this function in a 
 report and it is not working in that context.
  
 The code to generate report looks something like this:
  
  (str
   string1
   string2
   string3
 (map-indexed (fn [idx itm] (my-fn idx itm)) '(listofcrap))
   string4etc...
 )
  
 The code above will just print out 'clojure-lazy-seq' instead of the string 
 output.  If I try:
  
 (apply str  (map-indexed (fn [idx itm] (my-fn idx itm)) '(listofcrap)))
  
 Then I get the last item from my list properly formated in the report, but 
 that's all.  How do I print out everything?  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: map output to string

2014-07-08 Thread Lee Spector

Hi Glen,

You haven't really provided what we would need to replicate your problem.

Specifically:

- You call but don't provide definitions for address or is-blank?

- You refer to unbound symbols some-string and another-string.

- You don't provide an input for report, or the top-level call you are making, 
that produces the problem.

In addition, your report function has an extra ) at the end.

I tried patching up everything in a minimal way but then I don't see a problem.

 -Lee

On Jul 8, 2014, at 10:38 PM, Glen Rubin rubing...@gmail.com wrote:

 I am still having difficulties with this, so let me clarify by showing some 
 sample code.
 
 
 My fn looks like this:
 
 (defn report [text]
 
 (str
  string1
  string2
 (apply str (map-indexed (fn [idx itm] (time-text idx itm)) (filtered-list 
 text))
 
  
 When I invoke spit in order to output a text file using the above funtion, I 
 only get the first item in my list (filtered-list text) outputted
 
 Here is the basic code for my fns used above:
 
 
 (defn filtered-list [text]
 (let
 [street (:str (address text))
  city (:city (address text))
  state (:state (address text))
 
 ;actually there's a bunch of other bindings, 3 will suffice for the example
 
 ]
 
   (remove nil?
   (conj '()   
 
 (if-not
 (blank? street)
   (str ADDRESS:  street))
 (if-not
 (blank? city)
   (str CITY:  city))
 (if-not
 (blank? state)
   (str STATE:  state))
 
 
 (defn time-text [time-idx text-var]
  (str some-string (hour-min time-idx) another-string))
 
 ;this uses the clojure time library
 (defn hour-min [idx]
 (format-local-time (plus (local-now) (minutes idx)) :hour-minute-second))
 On Tuesday, July 8, 2014 2:28:52 AM UTC-7, Lee wrote:
 
 
 Sometimes you have to manually stamp out laziness, for this among other 
 reasons. 
 
 In some cases I apply the list function to do this: 
 
 = (str (map inc (range 10))) 
 clojure.lang.LazySeq@c5d38b66 
 
 = (str (apply list (map inc (range 10 
 (1 2 3 4 5 6 7 8 9 10) 
 
  -Lee 
 
 
  On 8 July 2014 09:49, Glen Rubin rubi...@gmail.com wrote: 
  my-fn takes a number and a string as argument and outputs a string.  I am 
  using map-indexed and my-fn to comprehend a list of items with numbered 
  index as follows, 


  (map-indexed (fn [idx itm]  (my-fn idx itm)) '(list-of-crap)) 

  When i run this on the repl everything works well and I get a single long 
  string of output. But, I am trying to use the output of this function in a 
  report and it is not working in that context. 

  The code to generate report looks something like this: 

   (str 
string1 
string2 
string3 
  (map-indexed (fn [idx itm] (my-fn idx itm)) '(listofcrap)) 
string4etc... 
  ) 

  The code above will just print out 'clojure-lazy-seq' instead of the string 
  output.  If I try: 

  (apply str  (map-indexed (fn [idx itm] (my-fn idx itm)) '(listofcrap))) 

  Then I get the last item from my list properly formated in the report, but 
  that's all.  How do I print out everything?  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.

--
Lee Spector, Professor of Computer Science
Cognitive Science, Hampshire College
893 West Street, Amherst, MA 01002-3359
lspec...@hampshire.edu, http://hampshire.edu/lspector/
Phone: 413-559-5352, Fax: 413-559-5438

-- 
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: a data conversion question

2014-06-08 Thread Lee Spector

On Jun 8, 2014, at 3:12 PM, boz b...@cox.net wrote:

 Is there a better way to take this...
 
   [[:a [1 2]] 
[:b [3 4]]]
 
 and convert it to this...
 
   [[:a 1] 
[:a 2] 
[:b 3] 
[:b 4]]
 
 than using a loop like this...
 
   (defn doit [id v]
 (loop [a (first v) r (rest v) result []]
   (if a
 (recur (first r) (rest r) (conj result [id a]))
 result)))
 
 ???

Lots of possibilities, and your loop doesn't look to me like it's handling the 
ids right, but FWIW I might do something like:

(defn split-key-pairs [grouped-data]
   (vec (apply concat (for [[key vals] grouped-data]
(for [v vals] [key v])

= (split-key-pairs [[:a [1 2]] [:b [3 4]]])
[[:a 1] [:a 2] [:b 3] [:b 4]]

 -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: Advice on managing random number generators across threads

2014-06-06 Thread Lee Spector

I don't know if this will be helpful in your application, or even if it's the 
best approach for our own work (or if java 1.7 provides a simpler approach?), 
but FWIW one of my projects deals with the thread-local RNG issue via: 
https://clojars.org/clj-random

 -Lee

On Jun 6, 2014, at 12:28 PM, Mars0i marsh...@logical.net wrote:

 I'm writing an agent-based simulation framework, in which agents are Clojure 
 records called Persons.  There are 40-100 persons at present, but conceivably 
 the number could go up to 1000.  In each timestep, Persons' states are 
 functionally updated by mapping update functions across the collection of 
 Persons.  The application is designed to be able to run in a single thread, 
 or to be run in multiple threads, depending on whether I do the mapping using 
 map or pmap.  (The application is generally faster with pmap (and all I had 
 to do was add p), but I think there might be contexts in which 
 single-threaded operation is preferable.)
 
 At one point in the Person-update process, each Person randomly samples a 
 small number (1 to 50) of elements from some small collections (size 10 up to 
 the max number of persons).  When the application is multi-threaded, I'd 
 rather not have separate threads accessing the same random number generator.  
 (Java 1.7 allows a way of dealing with that, but for now I'd rather be 
 compatible with Java 1.6 as well.)
 
 Does the following solution make sense?
 
 1. During initialization, I'll get a random number generator from 
 java.util.Random, initialized with the system time or something else that 
 varies.
 
 2. I'll give each person a field :rng, and will initialize each one with a 
 sparate call to java.util.Random, with a seed determined by the RNG mentioned 
 in the previous line.  (After this I can let the inititial RNG to be garbage 
 collected.)
 
 3. During the steps in which each Person needs to sample from collections, 
 the code will get the RNG from the Person's :rng file, and use it to 
 determine what elements are sampled.  
 
 There is more than one way that I could implement step 3.  Here are some 
 options I'm considering:
 (a) Bind data.generators/*rnd* to the RNG, and then call functions in 
 data.generators.
 (b) Pass the Person's RNG to functions from bigml/sampling (which allow you 
 to pass in an RNG).
 (c) Write my own sampling functions that use the RNG from the Person.
 
 Further remarks:
 
 When the application is single-threaded, each Person will use a different 
 RNG, which isn't necessary, but it won't hurt, since the RNGs will have 
 different seeds, except that I waste memory by creating multiple RNGs.  When 
 the application is multi-threaded, I still don't need one RNG per person, 
 strictly speaking, since the number of threads will be much less than the 
 number of Persons.  However, giving each Person its own RNG is simpler.  It 
 means that my code can ignore  threads and let Clojure figure out how to 
 manage them.
 
 
 What do you think?  Thanks in advance for any help.

-- 
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 Lee Spector

A followup on these issues, after experimenting a bit with reducers, just for 
anyone who may be interested:

- Naive use of reducers in place of seq functions, throughout my program, got 
messy and led to some new problems with memory management, I think (or at least 
to jerkier execution over time). I realized that reducers probably shouldn't be 
used so indiscriminately.

- With more moderate use of reducers, and using fold, I do indeed see 
performance improvements relative to sequential code and also relative to the 
previous version of my code that used agents for concurrency. I don't actually 
seem to be getting much benefit from the way that reducers avoid building 
intermediate results -- all of the benefit appears to be due to using a 
combination of r/fold and one r/map to process collection elements 
concurrently. I've only done small numbers of tests and they all involve 
randomness, but I do see improvements on the order of 1/3.

- The best behaving/looking approach for me seems to be to stick with lazy 
sequence operations and aggressive de-lazifying for the bulk of my code 
(possibly cleaning some things up by defining my own forv, repeatv, etc., or 
possibly rewriting some of the core lazy sequence functions to not be lazy in 
the first place), but to use r/fold and r/map for concurrency for my top-level 
tasks. I'm getting the best results by using reducers only in one place, in my 
definition of a concurrent mapping function, which I then use only for 
top-level functions (never nested):

(defn pmapall
   [f coll]
   (if single-thread-mode
 (doall (map f coll))
 (r/fold 1 r/cat r/append! (r/map f coll

This replaces my previous agent-based version:

(defn pmapall
   [f coll]
   (if single-thread-mode
 (doall (map f coll))
 (let [agents (map #(agent % :error-handler 
   (fn [agnt except] (clojure.repl/pst except 1000) 
(System/exit 0))) 
   coll)]
   (dorun (map #(send % f) agents))
   (apply await agents)
   (doall (map deref agents)

The one that uses reducers is neater and seems to make my program run faster, 
although I'm not really sure why.

In any event, I'm using reducers now only as an alternative concurrency 
mechanism and solving my original problems by de-lazification.

 -Lee



On Jun 4, 2014, at 7:21 PM, Lee Spector lspec...@hampshire.edu wrote:

 
 On Jun 4, 2014, at 1:29 PM, Timothy Baldridge tbaldri...@gmail.com wrote:
 
 Although your original complaint was about clojure seqs being lazy. It 
 should be noted that reducers are also lazy down to the point of a fold or 
 reduce, so I'm not sure what you're really getting there. It wouldn't be 
 hard at all to write map, filter, remove, etc. in terms of list operations. 
 Perhaps that's what you're looking for? If I understand your original 
 complaint, you want map, filter, etc, to be eager.
 
 
 True, my original concern was (and my main concern still is) to avoid crashes 
 (in this case, stack overflow errors) that stem from unexpected (to me) 
 consequences of laziness.
 
 Those problems could indeed be solved by rewriting map and filter etc, or 
 (easier) by wringing out the laziness wherever it arises, e.g. by forcing 
 everything to be a vector (or a list, as you suggest). It's a little 
 cumbersome to do this everywhere, though, and I was wondering if there was an 
 existing library or approach for this issue.
 
 Then, however, it was suggested that I could have my cake and another kind of 
 cake too, by using reducers. The suggestion was that this could banish the 
 laziness-related issues while also providing significant performance 
 improvements. Sounds good to me! I'm still working on getting my current 
 project to behave well using reducers, but it seems promising.
 
 
 On the other hand, time spent learning how lazy seqs work, and the caveats 
 involved will make it easier for you to understand the code produced by the 
 rest of the community. So perhaps that's the better option. 
 
 I agree that it's important to understand lazy sequences, and I do think I 
 understand the core concepts reasonably well (and I've implemented lazy 
 evaluation in other languages, etc.). But I've also traced some really 
 annoying and hard to find bugs to unexpected (and sometimes never fully 
 explained) consequences of laziness, so I'd like to find the best ways to 
 avoid it when I don't really want it. If that best way turns out to make 
 things run faster too then that'd be fantastic.
 
 -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

Re: non-lazy clojure?

2014-06-05 Thread Lee Spector

Oops -- something was wrong with my benchmarks, and my improvements on the 
order of 1/3 was wrong. I still see improvements with r/fold as compared to my 
agent-based approach, but the difference now appears to be only something like 
1/20.

 -Lee

On Jun 5, 2014, at 7:19 PM, Lee Spector lspec...@hampshire.edu wrote:

 
 A followup on these issues, after experimenting a bit with reducers, just for 
 anyone who may be interested:
 
 - Naive use of reducers in place of seq functions, throughout my program, got 
 messy and led to some new problems with memory management, I think (or at 
 least to jerkier execution over time). I realized that reducers probably 
 shouldn't be used so indiscriminately.
 
 - With more moderate use of reducers, and using fold, I do indeed see 
 performance improvements relative to sequential code and also relative to the 
 previous version of my code that used agents for concurrency. I don't 
 actually seem to be getting much benefit from the way that reducers avoid 
 building intermediate results -- all of the benefit appears to be due to 
 using a combination of r/fold and one r/map to process collection elements 
 concurrently. I've only done small numbers of tests and they all involve 
 randomness, but I do see improvements on the order of 1/3.
 
 - The best behaving/looking approach for me seems to be to stick with lazy 
 sequence operations and aggressive de-lazifying for the bulk of my code 
 (possibly cleaning some things up by defining my own forv, repeatv, etc., or 
 possibly rewriting some of the core lazy sequence functions to not be lazy in 
 the first place), but to use r/fold and r/map for concurrency for my 
 top-level tasks. I'm getting the best results by using reducers only in one 
 place, in my definition of a concurrent mapping function, which I then use 
 only for top-level functions (never nested):
 
 (defn pmapall
   [f coll]
   (if single-thread-mode
 (doall (map f coll))
 (r/fold 1 r/cat r/append! (r/map f coll
 
 This replaces my previous agent-based version:
 
 (defn pmapall
   [f coll]
   (if single-thread-mode
 (doall (map f coll))
 (let [agents (map #(agent % :error-handler 
   (fn [agnt except] (clojure.repl/pst except 
 1000) (System/exit 0))) 
   coll)]
   (dorun (map #(send % f) agents))
   (apply await agents)
   (doall (map deref agents)
 
 The one that uses reducers is neater and seems to make my program run faster, 
 although I'm not really sure why.
 
 In any event, I'm using reducers now only as an alternative concurrency 
 mechanism and solving my original problems by de-lazification.
 
 -Lee
 
 
 
 On Jun 4, 2014, at 7:21 PM, Lee Spector lspec...@hampshire.edu wrote:
 
 
 On Jun 4, 2014, at 1:29 PM, Timothy Baldridge tbaldri...@gmail.com wrote:
 
 Although your original complaint was about clojure seqs being lazy. It 
 should be noted that reducers are also lazy down to the point of a fold or 
 reduce, so I'm not sure what you're really getting there. It wouldn't be 
 hard at all to write map, filter, remove, etc. in terms of list operations. 
 Perhaps that's what you're looking for? If I understand your original 
 complaint, you want map, filter, etc, to be eager.
 
 
 True, my original concern was (and my main concern still is) to avoid 
 crashes (in this case, stack overflow errors) that stem from unexpected (to 
 me) consequences of laziness.
 
 Those problems could indeed be solved by rewriting map and filter etc, or 
 (easier) by wringing out the laziness wherever it arises, e.g. by forcing 
 everything to be a vector (or a list, as you suggest). It's a little 
 cumbersome to do this everywhere, though, and I was wondering if there was 
 an existing library or approach for this issue.
 
 Then, however, it was suggested that I could have my cake and another kind 
 of cake too, by using reducers. The suggestion was that this could banish 
 the laziness-related issues while also providing significant performance 
 improvements. Sounds good to me! I'm still working on getting my current 
 project to behave well using reducers, but it seems promising.
 
 
 On the other hand, time spent learning how lazy seqs work, and the caveats 
 involved will make it easier for you to understand the code produced by the 
 rest of the community. So perhaps that's the better option. 
 
 I agree that it's important to understand lazy sequences, and I do think I 
 understand the core concepts reasonably well (and I've implemented lazy 
 evaluation in other languages, etc.). But I've also traced some really 
 annoying and hard to find bugs to unexpected (and sometimes never fully 
 explained) consequences of laziness, so I'd like to find the best ways to 
 avoid it when I don't really want it. If that best way turns out to make 
 things run faster too then that'd be fantastic.
 
 -Lee

--
Lee Spector, Professor of Computer Science
Cognitive Science, Hampshire College
893

Re: non-lazy clojure?

2014-06-05 Thread Lee Spector

On Jun 5, 2014, at 8:51 PM, Gary Johnson gwjoh...@uvm.edu wrote:

 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?

Yes, I've tried other group sizes and I get nearly no speedup over 
single-threaded code with the default group size (512). Group size 1 seems to 
be about as good as any other value i've tried.

 -Lee

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


Re: non-lazy clojure?

2014-06-04 Thread Lee Spector
 On Jun 2, 2014, at 7:14 PM, Gary Johnson gwjoh...@uvm.edu wrote:
 
 Hey Lee,
 
  I would second Jozef's suggestion that you look into using the reducers 
 library when you need non-lazy sequence operations. [etc]

On Jun 2, 2014, at 10:38 PM, Lee Spector lspec...@hampshire.edu wrote:

 
 Gary: That's compelling indeed, and I will look into it more!


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.

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

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

Thanks,

 -Lee

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


Re: non-lazy clojure?

2014-06-04 Thread Lee Spector

On Jun 4, 2014, at 12:59 PM, Gary Johnson gwjoh...@uvm.edu wrote:

 Hey Lee,
 
   (vec ...) is NOT the same as (into [] ...) in this case.
[etc]

Thanks Gary -- very clear and helpful.

 -Lee

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


Re: non-lazy clojure?

2014-06-04 Thread Lee Spector

On Jun 4, 2014, at 1:20 PM, Gary Johnson gwjoh...@uvm.edu wrote:

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

Definitely helpful. With the fold version, and messing with the group size, I'm 
seeing much higher multicore utilization and I think I'm seeing speedups too 
(although it's a little hard to measure because of randomness). I'm also having 
new problems (pauses that get worse over time... GC?) but I'll experiment more 
before I bother anyone else with those.

Thanks so much Gary,

 -Lee

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


Re: non-lazy clojure?

2014-06-04 Thread Lee Spector

On Jun 4, 2014, at 1:29 PM, Timothy Baldridge tbaldri...@gmail.com wrote:

 Although your original complaint was about clojure seqs being lazy. It should 
 be noted that reducers are also lazy down to the point of a fold or reduce, 
 so I'm not sure what you're really getting there. It wouldn't be hard at all 
 to write map, filter, remove, etc. in terms of list operations. Perhaps 
 that's what you're looking for? If I understand your original complaint, you 
 want map, filter, etc, to be eager.
 

True, my original concern was (and my main concern still is) to avoid crashes 
(in this case, stack overflow errors) that stem from unexpected (to me) 
consequences of laziness.

Those problems could indeed be solved by rewriting map and filter etc, or 
(easier) by wringing out the laziness wherever it arises, e.g. by forcing 
everything to be a vector (or a list, as you suggest). It's a little cumbersome 
to do this everywhere, though, and I was wondering if there was an existing 
library or approach for this issue.

Then, however, it was suggested that I could have my cake and another kind of 
cake too, by using reducers. The suggestion was that this could banish the 
laziness-related issues while also providing significant performance 
improvements. Sounds good to me! I'm still working on getting my current 
project to behave well using reducers, but it seems promising.

 
 On the other hand, time spent learning how lazy seqs work, and the caveats 
 involved will make it easier for you to understand the code produced by the 
 rest of the community. So perhaps that's the better option. 

I agree that it's important to understand lazy sequences, and I do think I 
understand the core concepts reasonably well (and I've implemented lazy 
evaluation in other languages, etc.). But I've also traced some really annoying 
and hard to find bugs to unexpected (and sometimes never fully explained) 
consequences of laziness, so I'd like to find the best ways to avoid it when I 
don't really want it. If that best way turns out to make things run faster too 
then that'd be fantastic.

 -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: stack backtraces for exceptions in agents?

2014-06-02 Thread Lee Spector

(fn [agnt except] (println except))

 -Lee


On Jun 2, 2014, at 3:38 PM, Sean Corfield s...@corfield.org wrote:

 The exception object should have a full stack trace in it - how are you 
 printing your exceptions?
 
 Sean
 
 On Jun 2, 2014, at 12:28 PM, Lee Spector lspec...@hampshire.edu wrote:
 In my single-threaded code, exceptions stop execution and print a stack 
 backtrace. This is less informative than I would like [1], but sometimes it 
 provides crucial clues.
 
 My multi-threaded code generally uses agents (just because that's the best 
 way I've found to get something that behaves like pmap but with better 
 multicore processor utilization [2]). By default, exceptions in agents are 
 silent, which is a default that I've always found to be perplexing. But if I 
 pass an :error-handler argument to agent (as in [2] below) then I can at 
 least see the exception... but execution doesn't halt and I don't get a 
 backtrace. That means that if I'm running in a multi-core mode (as I usually 
 am) then the first unfortunate thing is that I have to notice the printed 
 exception (because execution continues past it if I don't). But the even 
 more unfortunate thing is that I then get no backtrace. In order to get a 
 backtrace I have to re-run my whole system in single-threaded mode, and then 
 hope that I hit the same error (since my systems almost always involve a lot 
 of randomness).
 
 I figure it would be easy to put an exit in the :error-handler that would 
 quit the whole program, but I don't know how I could get the stack backtrace 
 for the triggering exception.
 
 Does anyone know how to get this?
 
 Thanks,
 
 -Lee 
 
 
 [1] Oh, how I long to see the values of locals up the stack in these 
 backtraces. I understand there are ways to get this but that they require 
 particular tool chains (emacs w/ritz?); my longing is for this kind of 
 functionality no matter how I launch my code, or at least when I launch it 
 via lein run. The lack of this feature is the #1 thing I miss in Clojure 
 relative to Common Lisp.
 
 [2] Specifically, pmap won't keep all cores busy if a thread that starts 
 later finishes earlier than one that starts earlier. Here's the code that I 
 use instead of pmap, which assumes there's a boolean-valued var called 
 single-thread-mode:
 (defn pmapall
 Like pmap but: 1) coll should be finite, 2) the returned sequence
  will not be lazy, 3) calls to f may occur in any order, to maximize
  multicore processor utilization, and 4) takes only one coll so far.
 [f coll]
 (if single-thread-mode
   (doall (map f coll))
   (let [agents (map #(agent % :error-handler (fn [agnt except] (println 
 except))) coll)]
 (dorun (map #(send % f) agents))
 (apply await agents)
 (doall (map deref agents)
 

--
Lee Spector, Professor of Computer Science
Cognitive Science, Hampshire College
893 West Street, Amherst, MA 01002-3359
lspec...@hampshire.edu, http://hampshire.edu/lspector/
Phone: 413-559-5352, Fax: 413-559-5438

-- 
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: stack backtraces for exceptions in agents?

2014-06-02 Thread Lee Spector

Beautiful.

In fact, if I specify an :error-handler of:

(fn [agnt except] (clojure.repl/pst except 1000) (System/exit 0))

Then it prints the backtrace and also terminates execution.

FWIW that would seem to me to be a better default than the current fail 
silently.

 -Lee


On Jun 2, 2014, at 3:39 PM, Andy Fingerhut andy.finger...@gmail.com wrote:

 Try out (clojure.repl/pst e 1000), where e is the exception you have caught.
 
 Andy
 
 
 On Mon, Jun 2, 2014 at 12:28 PM, Lee Spector lspec...@hampshire.edu wrote:
 
 In my single-threaded code, exceptions stop execution and print a stack 
 backtrace. This is less informative than I would like [1], but sometimes it 
 provides crucial clues.
 
 My multi-threaded code generally uses agents (just because that's the best 
 way I've found to get something that behaves like pmap but with better 
 multicore processor utilization [2]). By default, exceptions in agents are 
 silent, which is a default that I've always found to be perplexing. But if I 
 pass an :error-handler argument to agent (as in [2] below) then I can at 
 least see the exception... but execution doesn't halt and I don't get a 
 backtrace. That means that if I'm running in a multi-core mode (as I usually 
 am) then the first unfortunate thing is that I have to notice the printed 
 exception (because execution continues past it if I don't). But the even more 
 unfortunate thing is that I then get no backtrace. In order to get a 
 backtrace I have to re-run my whole system in single-threaded mode, and then 
 hope that I hit the same error (since my systems almost always involve a lot 
 of randomness).
 
 I figure it would be easy to put an exit in the :error-handler that would 
 quit the whole program, but I don't know how I could get the stack backtrace 
 for the triggering exception.
 
 Does anyone know how to get this?
 
 Thanks,
 
  -Lee
 
 
 [1] Oh, how I long to see the values of locals up the stack in these 
 backtraces. I understand there are ways to get this but that they require 
 particular tool chains (emacs w/ritz?); my longing is for this kind of 
 functionality no matter how I launch my code, or at least when I launch it 
 via lein run. The lack of this feature is the #1 thing I miss in Clojure 
 relative to Common Lisp.
 
 [2] Specifically, pmap won't keep all cores busy if a thread that starts 
 later finishes earlier than one that starts earlier. Here's the code that I 
 use instead of pmap, which assumes there's a boolean-valued var called 
 single-thread-mode:
 (defn pmapall
   Like pmap but: 1) coll should be finite, 2) the returned sequence
will not be lazy, 3) calls to f may occur in any order, to maximize
multicore processor utilization, and 4) takes only one coll so far.
   [f coll]
   (if single-thread-mode
 (doall (map f coll))
 (let [agents (map #(agent % :error-handler (fn [agnt except] (println 
 except))) coll)]
   (dorun (map #(send % f) agents))
   (apply await agents)
   (doall (map deref agents)
 

-- 
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: stack backtraces for exceptions in agents?

2014-06-02 Thread Lee Spector

PS I should have said thanks!.

 -Lee

On Jun 2, 2014, at 3:52 PM, Lee Spector lspec...@hampshire.edu wrote:

 
 Beautiful.
 
 In fact, if I specify an :error-handler of:
 
 (fn [agnt except] (clojure.repl/pst except 1000) (System/exit 0))
 
 Then it prints the backtrace and also terminates execution.
 
 FWIW that would seem to me to be a better default than the current fail 
 silently.
 
 -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.


non-lazy clojure?

2014-06-02 Thread Lee Spector

I've generally liked Clojure's pervasive laziness. It's cute and it sometimes 
permits lovely, elegant approaches to particular programming problems. And 
although I've long known that it can get you into trouble in a few unusual 
cases -- I think I recall seeing a nice blog post on issues related to 
binding and laziness by Chas Emerick several years ago -- it has generally 
seemed safe enough for most purposes. I figured that while it may not always 
provide benefits it should at least be mostly harmless.

However, after spending a couple of days tracking down a particularly confusing 
bug, and finding once again (this has happened to me at least a few times) that 
the bug was due to laziness that I never really wanted in the first place, I'm 
reconsidering.

I don't have a pared-down version of the bug that I was just dealing with (see 
below for a pointer to the non-pared-down version), but it goes away when I 
wring out all of the laziness. In this particular case I do so by calling vec 
or doall on the results of all of my calls to map and other functions function 
that produce lazy sequences (none of which I actually want to be lazy in this 
application). I was getting StackOverflowErrors and I have a half-baked 
half-theory that it was due to some bad interaction between laziness and 
garbage collection, with the JVM not realizing that it could reclaim lazy 
things that weren't yet fully evaluated. That doesn't make complete sense to 
me, and maybe that kind of bad interaction is not even possible -- I don't 
know. But I do know that all is well when I wring out all of the laziness.

One possible lesson from this experience (which was particularly frustrating, 
BTW, because the stack backtraces were particularly uninformative [1]) is that 
I should just be careful to surround any call to any function that produces a 
lazy sequence with something like vec that ensures that the laziness will be 
eliminated as soon as it is created -- except in those relatively rare cases 
where I really want the laziness. But this would be a pain, and ugly. I rely 
heavily on Clojure's sequence processing functions and I would hate to clutter 
up every call to every one of them or to have to reimplement my own non-lazy 
versions of everything.

Is there a more elegant way? Maybe somebody has already made non-lazy clones of 
all of the core functions that normally produce lazy sequences? And if so, 
maybe there's some clean way to cause my code to use the non-lazy versions 
unless specifically directed to use the lazy versions?

I realize that this is fighting with a core feature of Clojure, and that the 
idea will probably rub lots of folks the wrong way. But I've now been down this 
road a couple of times and I'm beginning to think that I'd spend less time 
tracking down mysterious bugs if I could avoid laziness more easily.

In case anybody is motivated to look into the specific bug that I was just 
dealing with, I've put the project at 
http://hampshire.edu/lspector/temp/world2D.zip. If you do lein run in its 
present state it will run fine, making little balls bounce around. (This is a 
very early version of some code that I plan to use both for teaching an AI 
class and for some ALife experiments...) But if you edit src/world2D/vec2D.clj, 
commenting out the definitions of *v, +v, and -v, and uncommenting the 
alternatives (which are the same except that they lack the calls to vec) then 
after running for a few seconds or a minute or so you'll get the stack overflow.

Thanks for any suggestions,

 -Lee


[1] The stack traces I was getting provide no information about where/what the 
offending lazy sequences are, since they don't show locals etc. I see no 
references to any of my own code, just a repeating sequence that starts:

StackOverflowError 
clojure.core/seq (core.clj:133)
clojure.core/map/fn--4211 (core.clj:2490)
clojure.lang.LazySeq.sval (LazySeq.java:42)
clojure.lang.LazySeq.seq (LazySeq.java:60)
clojure.lang.RT.seq (RT.java:484)
clojure.core/seq (core.clj:133)
clojure.core/map/fn--4211 (core.clj:2490)
clojure.lang.LazySeq.sval (LazySeq.java:42)
clojure.lang.LazySeq.seq (LazySeq.java:60)
clojure.lang.RT.seq (RT.java:484)
[etc]

-- 
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 Lee Spector

On Jun 2, 2014, at 4:51 PM, Softaddicts lprefonta...@softaddicts.ca wrote:

 mapv
 
 a bit shorter :)
 
 Luc P.

Thanks Luc. I have indeed migrated to mapv for many cases and I could have for 
the specific final fix for the example I posted. But there are lots of other 
fixes that I made earlier in the same project, some of which may also have 
been necessary. I also used filterv in some cases... but other places it was 
messier, e.g. with for.

 -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 Lee Spector

On Jun 2, 2014, at 4:52 PM, Phillip Lord phillip.l...@newcastle.ac.uk wrote:

 Funny, I posted an article of my Clojure gotcha's today 
 (http://www.russet.org.uk/blog/2991), and this is one of them. I've also had 
 very nasty bugs, in addition to the general hassle of wrapping a Java API 
 which works through side-effects.
 
 I created a few functions covering the most common ones (domap, dofor and so 
 on); having a comprehensive list somewhere in it's own namespace would be 
 quite useful.
 
 Phil

It'd be nice to have a solid library of non-lazy alternatives to the core 
sequence functions.

FWIW while I've often dealt with this issue by using vectors, either with an 
explicit vec or with mapv or filterv, it's often not necessary or helpful for 
me that my sequences are actually vectors. That is, they could often be lists 
or some other kind of sequence instead. It's hard for me to know for sure, but 
I think that in many cases a doall solves the same problem that a vec 
would. This seems to be the case, for example, for the code/fix that I posted.

 -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 Lee Spector

On Jun 2, 2014, at 4:52 PM, Jozef Wagner jozef.wag...@gmail.com wrote:

 Reducers [1] provide eager variants of some core seq functions (map, filter, 
 etc.). Note that they do not cache the result, so they recompute it every 
 time you use their result.
 
 [1] http://clojure.org/reducers

Thanks Josef. I haven't yet really looked into reducers, but it seems on first 
glance like it may be overkill for just dealing with this issue -- using 
fork/join and getting unneeded parallelism for routine sequence processing, 
just to ensure that one doesn't have laziness-related bugs. The recomputation 
also sounds potentially problematic.

But I do want to look into reducers for other purposes, so thanks for the 
pointer!

 -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 Lee Spector

Gary: That's compelling indeed, and I will look into it more!

Thanks,

 -Lee

PS would a call to vec do the same thing as into [] here?


On Jun 2, 2014, at 7:14 PM, Gary Johnson gwjoh...@uvm.edu wrote:

 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: why is this failing on a list

2014-05-04 Thread Lee Spector


On May 4, 2014, at 10:42 AM, Roelof Wobben rwob...@hotmail.com wrote:

 For 4clojure I have to find the second to last item.
 
 So I did this:
 
 (fn secondlast [v] 
   (get v (-(count v)1)))
 
 Now it's only failing at this test :  (= (__ (list 1 2 3 4 5)) 4)
 
 Can anyone tell me where I did take the wrong way.


The get function with integer keys works for vectors but not for lists:

= (get [7 8 9] 1)
8
= (get '(7 8 9) 1)
nil

So one option would be to call vec on the list before calling get:

= (get (vec '(7 8 9)) 1)
8

Another option would be to use nth instead of get.

 -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: Clojure equivalent of special common lisp vars: still looking for that zen place...

2014-05-03 Thread Lee Spector

On May 3, 2014, at 9:45 AM, Dave Tenny dave.te...@gmail.com wrote:
 
 The way I'm tempted to do this in clojure is
 
 (def ^{:dynamic true} *x* (atom 1))
 ... do stuff with @*x* ...
 (reset! *x* 2)
 ... do stuff with @*x* ...
 (binding [*x* (atom 3)] (do stuff with @*x*))


Having also come from Common Lisp and having once done things similar to your 
suggestion in Clojure, I got burned by the fact (I *think* it was a fact) that 
binding created thread-local bindings that reverted to global bindings inside 
of code executed in another thread, e.g. in a pmap buried somewhere within the 
code executed within the binding form. I found this to be unexpected and 
problematic.

Trying some simple examples with your outline, however, I don't see this 
happening. And I wonder if it's because of changes in more recent versions of 
Clojure related to ^{:dynamic true}.

Does anyone know if the reversion of binding-bound vars to global bindings 
when crossing thread boundaries has really been eliminated? Or am I just not 
seeing it because my examples have been too simple?

  -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: lein uberjar much faster as lein run

2014-04-22 Thread Lee Spector

On Apr 22, 2014, at 10:01 AM, Jony Hudson jonyepsi...@gmail.com wrote:

 I recall reading that `lein run` uses JVM options optimised for startup time, 
 not performance - as it's intended for use in development, not production. I 
 can't seem to find where I read that though ...

Somebody with actual knowledge of what's under the hood will undoubtedly be 
able to say more (and maybe correct me :-), but I've been led to believe that 
if you want things to run fast (at the expense of possibly longer startup time) 
with lein run then you actually want to use lein with-profile production 
run. 

FWIW (not much) I'd prefer that that be the default, or that there be a 
somewhat more obvious/memorable syntax (lein fast run?). 

In our limited testing  lein with-profile production run did indeed make a 
big difference, sometimes producing a ~2x speedup. This isn't as big as the 
difference that Cecil's getting with the uberjar though... and if we could get 
the ~5x speedup that he seems to be getting from uberjar then that would be 
fantastic. I guess we ought to just try that, but I'd appreciate any insights 
that knowledgable people here could provide on this.

 -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: Light table

2014-04-16 Thread Lee Spector

On Apr 16, 2014, at 10:48 PM, Mikera mike.r.anderson...@gmail.com wrote:

 On Thursday, 17 April 2014 03:57:56 UTC+8, Mike Haney wrote:
 The conventional wisdom seems to be that you will end up learning emacs 
 eventually if you spend any amount of time doing clojure or lisp, so you 
 might as well learn it from the start.  That is definitely the approach 
 taken in the braveclojure book, and he may be right, but I have no regrets 
 starting with lighttable.
 
 As a counter-example to the conventional wisdom, I have never really used 
 Emacs and I've being doing Clojure successfully for around 4 years now. I'm 
 sure Emacs is great for those who have taken the time to master it, but it 
 certainly isn't necessary to be productive in Clojure.
 
 I personally use Counterclockwise - this is mainly because I also do a lot of 
 Java work in Eclipse and it makes the polyglot integration much easier if you 
 aren't switching tools all the time.
 
 I'm also quite excited about the potential of things like Session or 
 Gorilla-REPL for exploratory / data science work. I like the way that the 
 Clojure ecosystem is developing a lot of innovative, plug-able components and 
 tools that enable different development styles.

A different kind of counter-example: I've used emacs a fair bit in my decades 
of Lisping and now years of Clojuring, but I now too use Counterclockwise.

IMHO emacs has tremendous and beautiful power but unnecessarily awful usability 
characteristics. I hope that some day someone will develop a Clojure 
environment with the former but without the later, possibly driven by emacs 
under the hood.

 -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: alternative syntax for Clojure? Haskell?

2014-04-06 Thread Lee Spector

On Apr 5, 2014, at 8:51 PM, Jason Felice jason.m.fel...@gmail.com wrote:

 I focus on expressivity, specifically because of the write-only phenomenom.  
 This isn't peculiar to clojure; this happened a lot in the Perl days (so much 
 so, that that's where I remember write-only code being coined). 

FWIW I think write-only code may have been used first for APL. If not, then 
it must have been for something even older.

There's a cute bit of write-only APL at http://catpad.net/michael/apl/. But APL 
can be really beautiful too.

 -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: Function from a symbolic expression

2014-03-31 Thread Lee Spector

On Mar 31, 2014, at 1:27 PM, A. Webb a.webb@gmail.com wrote:
 
 If you are working with quoted expressions, you'll have to eval in the macro 
 and take the one-time hit there
 
 (defmacro functionalise2
   [ex var]
   (let [arg (gensym)
 body (clojure.walk/postwalk-replace {var arg} ex)]
 `(fn [~arg] ~(eval body
 
 (def foo2 (functionalise2 '(+ 2 x) x))
 (foo2 40) ;= 42
 

Or if the reason that you're quoting is because that's a stand-in for an 
expression that will be generated dynamically then maybe you don't want to do 
it in a macro, but instead call eval on function-defining expression that 
includes your expression and takes an argument for the variable.

Easier shown than said:

(defn functionalise
  [ex var]
  (eval (list 'fn (vector var) ex)))

(def ex '(+ 1 x))

(def exf (functionalise ex 'x))

(exf 3) ;; = 4

This calls eval only once when you call functionalise, and doesn't do any tree 
walking.

FWIW this is the trick I use in the tiny genetic programming system at: 
https://github.com/lspector/gp/blob/master/src/gp/evolvefn.clj

 -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: Function from a symbolic expression

2014-03-31 Thread Lee Spector

On Mar 31, 2014, at 5:59 PM, François Rey fmj...@gmail.com wrote:
 Forget that, my code does not work with 'z too, obviously.
 Too late, time to go to bed for me

But my code *does* work with 'z as long as z is also the variable used in the 
expression, which is what I assume was intended:

(defn functionalise
  [ex var]
  (eval (list 'fn (vector var) ex)))

(def ex '(+ 1 z))

(def exf (functionalise ex 'z))

(exf 3) ;= 4

You could also generalize this for expressions with any number of variables, 
but again I'm assuming that you know what the names of the variables are.

 -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: How did you learn Clojure?

2014-03-21 Thread Lee Spector

A little thing but I use it in when teaching Clojure to newbies and maybe it'll 
be useful for others:

https://github.com/lspector/clojinc/blob/master/src/clojinc/core.clj

 -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: More functional Quil

2014-03-09 Thread Lee Spector

FWIW I'm not crazy about these suggestions because they seem to me to be mostly 
cosmetic, and actually negative if they end up leading to multiple incompatible 
modes of operation. The Processing model seems to me to be intrinsically 
imperative, and it's also well-known by lots of people and easy to understand. 
The current Quil scheme, which provides fairly direct access to Processing's 
existing model from Clojure, still allows us to write functional-style code for 
all of the interesting stuff that we do within/between calls to the imperative 
Processing calls. And it allows one to translate Processing ideas into Quil 
relatively easily. So I like it like it is :-).

 -Lee

On Mar 9, 2014, at 8:29 PM, Nikita Beloglazov wrote:

 Hi Pablo
 
 You can find similar old thread on Quil github repo: 
 https://github.com/quil/quil/pull/19 It may serve as good background what 
 other people considered to make Quil more functional-style.
 
 I like your suggestion though I would split your :draw function to 2 fns: an 
 :update function, which only purpose is to update state and :draw which draws 
 state and doesn't change the world at all. If this approach is implemented - 
 other handler functions like :mouse-move, :key-pressed are also need to 
 become update-like functions - they should take state as argument and return 
 new state.
 
 The only problem is that it is not backward compatible at all. But probably 
 we still can do it... We can add option :fun-mode? true (stands for 
 functional-mode) which enables all these changes - :draw takes state as 
 argument, new :update function is added for modifying state, all handlers 
 behave like :update. This option is enabled per-sketch. It requires 
 additional work on Quil internals, but I think it is doable. This option can 
 be implemented in coming quil 2.0 and it would be great feature to have. 
 
 One more thing we could do to make it more functional-like - pass changed 
 values to handlers directly. Currently when :key-pressed handler is called - 
 no argument is passed to the function and you need to use (key-code) or 
 (raw-key) functions to identify which key was pressed. I think this 
 parameters should be explicitly passed to the function.
 
 What do you think?
 
 Nikita

-- 
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 code for detecting overlap of 3d shapes (specifically tetrahedra)?

2014-02-25 Thread Lee Spector
On Feb 16, 2014, at 5:07 PM, Karsten Schmidt wrote:

 Yer welcome  please do let me know how this works out for you! I've
 updated the gist[1] to delay more parts of the whole computation and
 replace most occurrences of `reduce` with `loop` - altogether leading
 to an almost 2x faster result for the worst case scenario where all
 test clauses are checked. K.
 
 [1] https://gist.github.com/postspectacular/9021724



Hi Karsten,

I've noticed that intersect-tetrahedra? is sometimes asymmetric. Here's an 
example with randomly generated irregular tetrahedra, but I've noticed it for 
regular tetrahedra as well:

(def t1 [[166 560 158] [889 160 1] [95 683 998] [445 779 516]])

(def t2 [[292 823 490] [868 167 651] [190 869 459] [208 591 753]]) 

(intersect-tetrahedra? t1 t2)

= true

(intersect-tetrahedra? t2 t1)

= nil

Do you have any idea why this might be or how it could be fixed?

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/groups/opt_out.


Re: Clojure code for detecting overlap of 3d shapes (specifically tetrahedra)?

2014-02-15 Thread Lee Spector


On Feb 15, 2014, at 11:49 AM, Karsten Schmidt wrote:

 Hi Lee, I've already implemented the algorithm described in this paper
 and it will be part of my upcoming geometry library. To not keep you
 waiting for the release, I've extracted the relevant code and put up
 here:
 
 https://gist.github.com/postspectacular/9021724

[etc]


Hi Karsten,

Wow! That is *extremely* helpful! Thank you so much. I will experiment with it 
as soon as I can and let you know if I run into any issues, but it looks like 
you've done a fantastic job here, and I'm really grateful that you've done the 
work and released this part early.

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/groups/opt_out.


Clojure code for detecting overlap of 3d shapes (specifically tetrahedra)?

2014-02-13 Thread Lee Spector

Can anyone point to Clojure code for detecting when two 3d shapes overlap, when 
given the [x y z] vertices of the two shapes?

The specific case I care about will always involve two regular tetrahedra (each 
of which is specified by 4 vertices), which may allow for special 
simplifications or efficiencies, but I'd be happy to have a more general 
solution as long as it's not weirdly slow.

I know that there are some sophisticated algorithms for doing this sort of 
thing (e.g. [1]), but the the algorithms I've found aren't trivial and the only 
source code I've found is pretty messy and would take some work to translate 
(e.g. from C). 

And I figure that if anybody is doing 3d stuff in Clojure then the code for 
this is probably floating around somewhere... but I haven't been able to find 
it.

Does anyone know of (or want to write :-) code for this?

I guess that a Java solution would also be workable, if I the interop is 
straightforward enough, but it'd be nicer to have a working algorithm in 
Clojure.

Thanks,

 -Lee

[1] Fast tetrahedron-tetrahedron overlap algorithm. F. Ganovelli, F. Ponchio 
and C. Rocchini August 11, 2002. 
http://citeseerx.ist.psu.edu/viewdoc/download;jsessionid=862BA3F999652E3B0BC1E7A6A3E04D49?doi=10.1.1.114.2540rep=rep1type=pdf



-- 
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: Confused by Clojure floating-point differences (compared to other languages)

2014-02-07 Thread Lee Spector

On Feb 5, 2014, at 11:42 PM, Michał Marczyk wrote:

 This returns
 
 (.getTotalPhysicalMemorySize
 (java.lang.management.ManagementFactory/getOperatingSystemMXBean))
 
 You could use this in your project.clj, perhaps by including
 
 ~(str -Xms (quot (.getTotalPhysicalMemorySize ...) appropriate-number))
 
 in :jvm-opts.


Very cool. I had no idea I could do computation in project.clj. The following 
seems to work to allocate 80% of the a machine's RAM to my process (launched 
with lein trampoline with-profile production run):

  :jvm-opts [~(str -Xmx
   (long (* (.getTotalPhysicalMemorySize
  
(java.lang.management.ManagementFactory/getOperatingSystemMXBean))
0.8)))
 ~(str -Xms
   (long (* (.getTotalPhysicalMemorySize
  
(java.lang.management.ManagementFactory/getOperatingSystemMXBean))
0.8)))
 -XX:+UseParallelGC]

I'll ask more about the GC part in another thread.

 Also, you can absolutely use your own :jvm-opts with :replace.

How do I combine them? Does the big vector above just replace the [] in 
:jvm-opts ^:replace []?

Also, does this (the :replace part) in fact do the same thing as putting 
with-profile production on the command line? So if I do this I can simplify 
my command line to lein trampoline run?

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/groups/opt_out.


how to use the G1 garbage collector

2014-02-07 Thread Lee Spector

Does anyone know what to put in :jvm-opts in project.clj to use the G1 garbage 
collector? I see a lot about how G1 works and how to configure it in web search 
results, but not this little nugget of info.

Also, if anyone has any advice about GC for my use case I'd love to hear it. My 
use case is: generating lots and lots of garbage in long-running, 
CPU-intensive, multicore processes. I want to minimize overall runtime and 
don't much care about responsiveness at all.

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/groups/opt_out.


Re: how to use the G1 garbage collector

2014-02-07 Thread Lee Spector

On Feb 7, 2014, at 11:35 AM, Gary Trakhman wrote:

 I do it like this:
 
 in my .bashrc
 
 export JVM_OPTS=-XX:+UseG1GC
 export LEIN_JVM_OPTS=-XX:+UseG1GC
 
 
 You can verify that it's working by checking jvisualvm's view of the jvm-opts 
 on the relevant processes.  Running it system-wide has given me reduced 
 memory-pressure on my lappie with no downside.

Interesting, but this is for processes that I'll be running on remote machines 
and I'd like all of the configuration to be in the Clojure project (ideally) or 
on the command line.

 -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/groups/opt_out.


Re: how to use the G1 garbage collector

2014-02-07 Thread Lee Spector
On Feb 7, 2014, at 11:41 AM, Laurent PETIT wrote:

 What if you put -XX:+UseG1GC in :jvm-opts ?

Ah yes -- I should have seen that even though I may not want to take Gary's 
suggestion of putting it in .bashrc, he had given me the magic string to 
include in :jvm-opts too!

I will give that a try. 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
--- 
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: Confused by Clojure floating-point differences (compared to other languages)

2014-02-07 Thread Lee Spector
On Feb 7, 2014, at 11:45 AM, Andy Fingerhut wrote:

 You may also use a let form wrapped around your entire defproject if you want 
 to avoid the duplication of code present in your example.

Thanks -- I actually noticed that after I posted. I don't know why, but I never 
thought of project.clj as containing code that gets executed before. Opens up 
lots of possibilities, I think.

 -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/groups/opt_out.


Re: Confused by Clojure floating-point differences (compared to other languages)

2014-02-05 Thread Lee Spector

On Feb 5, 2014, at 6:05 PM, Alex Miller wrote:

 To override the default tiered compilation, add this to your project.clj:
 :jvm-opts ^:replace []

I was under the impression that one can get the same effect by running your 
program with:

lein trampoline with-profile production run [etc]

True? I *think* the text here implies this too: 
https://github.com/technomancy/leiningen/blob/master/doc/TUTORIAL.md

FWIW my goal is to be able to run a project with one command, starting with a 
project that contains only source code (with none of my code pre-compiled), and 
have it do whatever it has to do to launch (I don't much care how long the 
launch takes) and then run as fast as possible (often for hours or days, 
CPU-bound). I launch my current runs with a command line like the one above, 
and I do also specify :jvm-opts in project.clj, specificially:

:jvm-opts [-Xmx12g -Xms12g -XX:+UseParallelGC]

Except that I have to tweak those 12s manually for different machines... Is 
there any way to specify just use whatever's available?

Since I'm supplying other :jvm-opts I was under the impression that I couldn't 
do the ^:replace [] thing... So is with-profile production going to have the 
same effect?

BTW I would also love input on the GC option. I'm also not at all sure that one 
is the best, but I generate lots of garbage across large numbers of cores so it 
seemed like a good idea. But then I read something here about the G1 GC... is 
that likely to be better? If so, does anyone know the string to include in 
:jvm-opts to use it?

Thanks ( sorry to include so many questions!),

 -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/groups/opt_out.


Re: Confused by Clojure floating-point differences (compared to other languages)

2014-02-05 Thread Lee Spector

On Feb 5, 2014, at 8:50 PM, Bruce Adams wrote:
 Modern JVM's pick default heap sizes based on the physical memory in
 your machine. With more than 1GB of physical memory, initial heap is
 1/64 and maximum heap is 1/4 of physical memory.[1]
 
 For OpenJDK and Oracle, this command:
java -XX:+PrintFlagsFinal -version | grep HeapSize
 will show the initial and maximum heap sizes (along with a few other
 numbers).

Thanks Bruce. Do you happen to know if there's a way to specify different 
fractions? I'd like something more like 3/4 (or 7/8) than 1/4. Nothing else 
will be running on the machine (aside from the OS and maybe tiny other things), 
and I want it to take everything it might need. I realize I can hardcode 
specific sizes, but then I have to change it for every machine configuration it 
runs on, which is what I was hoping to avoid. I have 64GB on some of my 
machines, 12GB on others, etc., and I'd like to use most of what's available 
wherever I run, preferably without changing project.clj every time.
 
 Also, you may not want to set the initial heap size as large as the
 maximum heap size. Oracle[2] says (in part):
 
 Setting -Xms and -Xmx to the same value increases predictability by removing 
 the most important sizing decision from the virtual machine. However, the 
 virtual machine is then unable to compensate if you make a poor choice.

The choice of using the same, maximal limit for both -Xms and -Xmx, could only 
be poor in the sense of using more than the necessary memory, right? Since I'm 
happy to use every available byte and am only concerned about speed it seems 
like this should be okay.

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/groups/opt_out.


recursion in clojure.walk

2014-01-09 Thread Lee Spector

Perhaps this is well known to others, but on the chance that maybe it isn't I 
thought I'd share.

In clojure.walk both prewalk and postwalk use recursion in ways that will blow 
the stack for sufficiently deep nested structures. We had been using them 
happily until recently when things got too big, and then we had problems. 

For our application I was able to replace my previous walking with a call to 
prewalkseq as defined below (which is only for seqs and uses zippers to avoid 
the recursion -- and note that I'm using Michał Marczyk's recently patched 
version of seq-zip so that it doesn't do the wrong thing with embedded 
instances of ().)

(defn prewalkseq
  Like prewalk but only for seqs and uses zippers.
  [f s]
  (loop [z (seq-zip s)]
(if (zip/end? z)
  (zip/root z)
  (recur (zip/next (zip/replace z (f (zip/node z 

That's all I need at the moment, but it's not immediately obvious to me how 
this would be done for postwalk, and it would be nice if all of clojure.walk 
could be made safe for large structures.

 -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/groups/opt_out.


Re: recursion in clojure.walk

2014-01-09 Thread Lee Spector

On Jan 9, 2014, at 6:33 PM, Stuart Sierra wrote:

 I wrote clojure.walk, but I don't usually recommend it for anything but 
 casual use.
 
 clojure.walk very general, so it's not going to be the most efficient 
 approach. When you know more details about the data structure you're working 
 with, as in this case, you can make something that will be faster and more 
 space-efficient.
 
 -S

As someone who has gotten lots of productive casual use of it, I thank you!

I'm wondering, though -- shouldn't it be possible to build the same general 
functionality on something like zippers and iteration rather than recursion, so 
that the JVM recursion limit wouldn't be an issue?

It might also be nice to flag the issue somehow in the docs, since most of 
Clojure seems to avoid this kind of recursion/limit.

 -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/groups/opt_out.


Re: New release of Light Table (which is now open source!)

2014-01-08 Thread Lee Spector

On Jan 8, 2014, at 3:49 PM, Benjamin Yu wrote:

 Grats! I love the pain points that light table solves for me.

The inline documentation is pretty great once I discovered how to invoke it 
(which took a while... and while I really love a lot of the ideas in LightTable 
I have to say that it always takes me a while to figure out how to do basic 
things in the interface, which I find cryptically minimal...).

Does anyone know if there's a hidden way to turn off automatic bracket 
insertion or to get console output without namespace prefixes?

 -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/groups/opt_out.


Re: New release of Light Table (which is now open source!)

2014-01-08 Thread Lee Spector

On Jan 8, 2014, at 3:58 PM, Lee Spector wrote:
 The inline documentation is pretty great once I discovered how to invoke it 
 (which took a while... and while I really love a lot of the ideas in 
 LightTable I have to say that it always takes me a while to figure out how to 
 do basic things in the interface, which I find cryptically minimal...).
 
 Does anyone know if there's a hidden way to turn off automatic bracket 
 insertion or to get console output without namespace prefixes?


Also, any way to see a stack trace after an exception? 

(.printStackTrace *e) doesn't do it.

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/groups/opt_out.


Re: New release of Light Table (which is now open source!)

2014-01-08 Thread Lee Spector

On Jan 8, 2014, at 4:04 PM, Lee Spector wrote:
 
 Also, any way to see a stack trace after an exception? 
 
 (.printStackTrace *e) doesn't do it.

Ah -- sorry to be writing so quickly. I've discovered that clicking on the 
exception appears to give a stack trace. Nice! (But again, wasn't obvious to me 
at first.)

It'd be super sweet if this showed arguments and locals :-)

 -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/groups/opt_out.


Re: New release of Light Table (which is now open source!)

2014-01-08 Thread Lee Spector
On Jan 8, 2014, at 5:45 PM, Jamie Brandon wrote:

 You can disable the bracket insertion by disabling the keys that
 trigger it. Add this to your user.keymap:
 
 :- {:editor.keys.normal {\ [(:editor.repeat-pair \)]
  ( [(:editor.open-pair ()]
  ) [(:editor.close-pair ))]
  [ [(:editor.open-pair [)]
  { [(:editor.open-pair {)]
  ] [(:editor.close-pair ])]
  } [(:editor.close-pair })]
  backspace [:editor.backspace-pair]}}

Thanks Jamie. I managed to get this to work, so that's great. 

FWIW my perspective (esp as a teacher of newbies) it'd be nice if there was 
some sort of simple switch for this. It's sort of cumbersome to have to 
discover this, find the file, and add a bunch of code to get the keyboard to 
behave normally

 -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/groups/opt_out.


Re: New release of Light Table (which is now open source!)

2014-01-08 Thread Lee Spector

On Jan 8, 2014, at 8:50 PM, Sean Corfield wrote:
 On Jan 8, 2014, at 3:38 PM, Lee Spector lspec...@hampshire.edu wrote:
 FWIW my perspective (esp as a teacher of newbies) it'd be nice if there was 
 some sort of simple switch for this. It's sort of cumbersome to have to 
 discover this, find the file, and add a bunch of code to get the keyboard to 
 behave normally
 
 I suspect the majority of users think the default behavior is normal - and 
 desirable :)

Why would you suspect this? Conceivably it could be desirable (although I 
personally think it's awful), but normal? We all type all of the time in 
scores of applications and contexts, and in very few of them does the editor 
think it's smarter than us and add characters that we didn't ask for. (I guess 
there's autocorrect, but A: yuck, and B: this is different.) 

On the other hand, I'm a big fan of auto-indentation, so maybe my position 
isn't 100% consistent :-)

Still, when writing Clojure something like half the characters you type will be 
brackets, which means that if your editor does the auto-insert-bracket thing 
then it's constantly doing something different from when you type in any other 
context, either adding a closing bracket that you didn't ask for or, when you 
type a closing bracket, sometimes typing it and sometimes not, depending on the 
context.

For newbies, in particular, the idea that they should have to re-learn how to 
type on top of everything else that they have to learn doesn't strike me as 
particularly friendly.

I do realize that tastes vary. But FWIW I wouldn't voluntarily use an 
environment with automatic bracket insertion, and I wouldn't want to foist it 
on my students either. So even if it's on by default, it would be important to 
me that it be easy to turn off.

 -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/groups/opt_out.


Re: bug in clojure.zip when calling next on empty list node?

2013-12-31 Thread Lee Spector

On Dec 31, 2013, at 5:08 PM, Armando Blancas wrote:

 The implementation of seq-zip uses seq? as its branching predicate. As a 
 result the zipper goes down on () thinking it can have children:
 
 user= (seq? ())
 true
 user= (seq? {})
 false
 user= (seq? #{})
 false
 user= (seq? [])
 false

Does that mean that you think that the behavior is correct and expected?

It goes down () thinking it can have children -- fine -- but when there aren't 
any children shouldn't zip/next continue until it hits the next thing? Why 
should it land on a non-existent nil instead?

Compare:

Traversing '((1) 0) with zip/next we get 4 items: ((1) 0), (1), 1, 0

Traversing '(() 0) with zip/next we also get 4 items: (() 0), (), nil, 0

It seems to me that these shouldn't both give 4 things, since the second 
clearly contain one less thing. That alleged nil just isn't there. Note also 
that:

Traversing '((nil) 0)) with zip/next we also get 4 items: ((nil) 0), (nil), 
nil, 0

That one seems right to me -- there really IS a nil there this time. But the 
one with () doesn't.

If I'm alone in this then I guess I'll just write my own zip_really_next that 
does what I expect, but I'm curious if others also think that the current 
behavior is correct.

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/groups/opt_out.


Re: bug in clojure.zip when calling next on empty list node?

2013-12-31 Thread Lee Spector

On Dec 31, 2013, at 6:53 PM, Michał Marczyk wrote:

 Ticket with patch at
 
 http://dev.clojure.org/jira/browse/CLJ-1317

[and]
 Oh, and of course you can use the amended version now to obtain the
 expected results: ///


Thank you so much Michał!

 -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/groups/opt_out.


Re: bug in clojure.zip when calling next on empty list node?

2013-12-29 Thread Lee Spector

I realize that many people are on holiday, but I'm hoping to get some clarity 
about how to proceed with respect to this issue in the near future.

Can anyone tell if I'm right that this is a bug in clojure.zip? If so, then is 
the right thing to do to post an issue on JIRA?

I've re-included the crux of the issue [slightly edited and recombined] below.

Thanks,

 -Lee


On Dec 21, 2013, at 11:49 AM, Lee Spector wrote:
 When I step through a zipper made from a nested list via seq-zip, I get 
 extraneous nils after processing a nested (). 
 
 Is this somehow expected behavior, or a bug, or am I misunderstanding 
 something fundamental?
 
 The problem seems to arise only when an nested empty list is present, not 
 other nested lists [... deleted ...]
 
 Here's an illustration, stepping through '(() 0) with next and printing the 
 node at each step:
 
 (loop [z (zip/seq-zip '(() 0))]
  (if (zip/end? z)
:done
(do (println (zip/node z))
  (recur (zip/next z)
 
 That produces:
 
 (() 0)
 ()
 nil
 0
 :done
 
 I don't expect the nil to be there.

 [That is,] when traversing '(() 0) with zip/next, one should first visit the 
 root, then (), and then 0. But what actually happens is that between then () 
 and the 0 one lands on a non-existent nil node. So one ends up visiting 4 
 nodes when there are only 3, and the extra one is a nil.

-- 
-- 
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: In your opinion, what's the best, and what's the worst aspects of using Clojure?

2013-12-28 Thread Lee Spector

On Dec 27, 2013, at 11:33 PM, guns wrote:

 On Fri 27 Dec 2013 at 11:23:22PM -0500, Lee Spector wrote:
 
 On Dec 27, 2013, at 11:18 PM, guns wrote:
 
 (defmacro dump-locals [] ...
 `
 When and where do you call this?
 
 I call this inside of the closest function that raised the exception.

Ah, so you have to see an exception, edit your code to include a call to this, 
re-run, and get to the same exception.

So it will only help for exception-raising situations that are easy to repeat, 
which mine often are not.


 Like you mentioned, I've heard nrepl-ritz does this in emacs, and David
 Greenberg has something like this set up for vim:
 
 https://github.com/dgrnbrg/vim-redl

It would be really nice if this sort of thing -- dumping all locals when an 
exception is raised -- could be done in an IDE-independent way. FWIW my code is 
often running via lein run, and when one of those runs raises an exception 
I'd really like to get more information about what happened.

 -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/groups/opt_out.


Re: In your opinion, what's the best, and what's the worst aspects of using Clojure?

2013-12-28 Thread Lee Spector

On Dec 28, 2013, at 11:27 AM, Cedric Greevey wrote:
 
 It helps to go with the functional, immutable flow, in which case if you 
 get an unwanted exception it should *usually* have bubbled up from some 
 failing test. Add a dump-locals where suggested by the stack trace and rerun 
 the failing test and voila! That should do it for almost all non-exogenous 
 exceptions, leaving mainly things like network timeouts and other wonkiness 
 caused by factors outside of your code (and, often, outside of your control 
 anyway).

You've given me some interesting things to think about re: the role of testing, 
but I think that it may be hard to map your approach directly on to the kind of 
work that I do. 

I often work with stochastic simulations which run for days and for which 
repeatability is hard to engineer, especially in a multicore context. There's a 
lot of unpredictable dynamism and usually code is generated and run dynamically 
(and mutated and recombined; this is genetic programming). Even if you code 
functionally and immutably (which I try to do, to a reasonable extent), and 
stamp out all nondeterminism (which would be a pain), it may take days to 
re-create a situation.

So it'd be really nice if the system could just spit out more of the state that 
produced the exception in the first place, when it happens.

 -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/groups/opt_out.


Re: In your opinion, what's the best, and what's the worst aspects of using Clojure?

2013-12-28 Thread Lee Spector

On Dec 28, 2013, at 2:56 PM, Cedric Greevey wrote:
 Your requirements are unusual.
 
 That being said, you might want to consider:
 
 1. Using a PRNG with recordable seed, and sane concurrency semantics, to 
 achieve repeatability -- rerun with same seed to get identical replay of 
 events.
 
 2. If crashes are happening after days, add snapshotting -- some ability to 
 save the state of the whole simulation from time to time (including current 
 PRNG state). Use the last snapshot before a crash to investigate the crash. 
 Requires item 1, above, for rerunning from the same snapshot to produce 
 unvarying results.
 
 I'd suggest using a ref world, with a periodically waking thread that does a 
 (spit (dosync (dump-all-the-refs-to-some-data-structure))) or something. (If 
 retries become a big problem you'll need to add more coordination, maybe 
 using core.async to get everything else to take a breather during each state 
 dump.) You also need order-independence (which suggests a deterministic 
 breaking up of the world into the domains of different threads, with defined 
 interaction channels and times, and a separate PRNG per thread -- I'd suggest 
 a state-dumpable Mersenne Twister instance per thread, seeded at startup 
 using values from java.util.Random, itself seeded with a known startup seed).

I can see how and why all of the above would work. But it's a pretty big 
effort, for which I would have no other use, and which would be unnecessary for 
me if I could just see the values of locals on crashes, as I can with other 
Lisps.


-- 
-- 
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: In your opinion, what's the best, and what's the worst aspects of using Clojure?

2013-12-28 Thread Lee Spector

On Dec 28, 2013, at 3:11 PM, Cedric Greevey wrote:

 Adding to the above, in the specific context of genetic programming, I'd 
 suggest dividing the population into N subsets, one per core, and trialling 
 them in parallel to generate fitness scores; then parallel-mergesort to get a 
 ranked order; then (apply map vector (partition (/ num-to-keep num-cores) 
 (take num-to-keep sorted-population))) to cull all but the best num-to-keep 
 and distribute them across N new subsets with each subset a representative 
 sample of the range of fitness scores (so any correlation between trial speed 
 and fitness won't make some populations slow and stop), then apply any 
 recombination/crossovers to generate, say, M new genomes in each subset 
 (parallel, uses the static data from the previous round and per-thread PRNGs 
 to decide which pairs of survivors to use to make offspring added to that 
 thread's subpopulation), then apply mutation (parallel, each thread mutates 
 its own subpopulation), then next trial... No thread-order-of-action 
 dependencies this way. Snapshot once a round by saving the subpopulations and 
 per-thread PRNG internal states right before each fitness trial phase. 
 Snapshot should evolve deterministically if restored with the same values for 
 num-to-keep and num-cores and whatever other parameters. Last snapshot before 
 crash should crash the same way every time.

Some of what you're suggesting would have implications for evolutionary 
dynamics. Maybe good, maybe bad, some related to things that I and others have 
studied (e.g. various schemes for working with subpopulations), and some maybe 
incompatible with other experimental things that I may be working with. I'm a 
researcher in this area, so I do care about and have tried related things for 
various reasons, but I don't want my search/evolution algorithm design to be 
driven by inadequacies of my programming environment (e.g. difficulties in 
finding sources of crashes).

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


  1   2   3   4   5   >